1/* Cypress West Bridge API header file (cyaslowlevel.h) 2## =========================== 3## Copyright (C) 2010 Cypress Semiconductor 4## 5## This program is free software; you can redistribute it and/or 6## modify it under the terms of the GNU General Public License 7## as published by the Free Software Foundation; either version 2 8## of the License, or (at your option) any later version. 9## 10## This program is distributed in the hope that it will be useful, 11## but WITHOUT ANY WARRANTY; without even the implied warranty of 12## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13## GNU General Public License for more details. 14## 15## You should have received a copy of the GNU General Public License 16## along with this program; if not, write to the Free Software 17## Foundation, Inc., 51 Franklin Street 18## Fifth Floor, Boston, MA 02110-1301, USA. 19## =========================== 20*/ 21 22#ifndef _INCLUDED_CYASLOWLEVEL_H_ 23#define _INCLUDED_CYASLOWLEVEL_H_ 24 25/*@@Low Level Communications 26 27 Summary 28 The low level communications module is responsible for 29 communications between the West Bridge device and the P 30 port processor. Communications is organized as a series 31 of requests and subsequent responses. For each request 32 there is a one and only one response. Requests may go 33 from the West Bridge device to the P port processor, or 34 from the P Port processor to the West Bridge device. 35 36 Description 37 Requests are issued across what is called a context. A 38 context is a single channel of communications from one 39 processor to another processor. There can be only a single 40 request outstanding on a context at a given time. Contexts 41 are used to identify subsystems that can only process a 42 single request at a time, but are independent of other 43 contexts in the system. For instance, there is a context 44 for communicating storage commands from the P port processor 45 to the West Bridge device. There is also a context for 46 communicating USB commands from the P port processor to the 47 West Bridge device. 48 49 Requests and responses are identical with the exception of 50 the type bit in the request/response header. If the type 51 bit is one, the packet is a request. If this bit is zero, 52 the packet is a response. Also encoded within the header of 53 the request/response is the code. The code is a command 54 code for a request, or a response code for a response. For 55 a request, the code is a function of the context. The code 56 0 has one meaning for the storage context and a different 57 meaning for the USB context. The code is treated differently 58 in the response. If the code in the response is less than 16, 59 then the meaning of the response is global across all 60 contexts. If the response is greater than or equal to 16, 61 then the response is specific to the associated context. 62 63 Requests and responses are transferred between processors 64 through the mailbox registers. It may take one or more cycles 65 to transmit a complete request or response. The context is 66 encoded into each cycle of the transfer to insure the 67 receiving processor can route the data to the appropriate 68 context for processing. In this way, the traffic from multiple 69 contexts can be multiplexed into a single data stream through 70 the mailbox registers by the sending processor, and 71 demultiplexed from the mailbox registers by the receiving 72 processor. 73 74 * Firmware Assumptions * 75 The firmware assumes that mailbox contents will be consumed 76 immediately. Therefore for multi-cycle packets, the data is 77 sent in a tight polling loop from the firmware. This implies 78 that the data must be read from the mailbox register on the P 79 port side and processed immediately or performance of the 80 firmware will suffer. In order to insure this is the case, 81 the data from the mailboxes is read and stored immediately 82 in a per context buffer. This occurs until the entire packet 83 is received at which time the request packet is processed. 84 Since the protocol is designed to allow for only one 85 outstanding packet at a time, the firmware can never be in a 86 position of waiting on the mailbox registers while the P port 87 is processing a request. Only after the response to the 88 previous request is sent will another request be sent. 89*/ 90 91#include "cyashal.h" 92#include "cyasdevice.h" 93 94#include "cyas_cplus_start.h" 95 96/* 97 * Constants 98 */ 99#define CY_AS_REQUEST_RESPONSE_CODE_MASK (0x00ff) 100#define CY_AS_REQUEST_RESPONSE_CONTEXT_MASK (0x0F00) 101#define CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT (8) 102#define CY_AS_REQUEST_RESPONSE_TYPE_MASK (0x4000) 103#define CY_AS_REQUEST_RESPONSE_LAST_MASK (0x8000) 104#define CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG (0x1000) 105 106/* 107 * These macros extract the data from a 16 bit value 108 */ 109#define cy_as_mbox_get_code(c) \ 110 ((uint8_t)((c) & CY_AS_REQUEST_RESPONSE_CODE_MASK)) 111#define cy_as_mbox_get_context(c) \ 112 ((uint8_t)(((c) & CY_AS_REQUEST_RESPONSE_CONTEXT_MASK) \ 113 >> CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT)) 114#define cy_as_mbox_is_last(c) \ 115 ((c) & CY_AS_REQUEST_RESPONSE_LAST_MASK) 116#define cy_as_mbox_is_request(c) \ 117 (((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) != 0) 118#define cy_as_mbox_is_response(c) \ 119 (((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) == 0) 120 121/* 122 * These macros (not yet written) pack data into or extract data 123 * from the m_box0 field of the request or response 124 */ 125#define cy_as_ll_request_response__set_code(req, code) \ 126 ((req)->box0 = \ 127 ((req)->box0 & ~CY_AS_REQUEST_RESPONSE_CODE_MASK) | \ 128 (code & CY_AS_REQUEST_RESPONSE_CODE_MASK)) 129 130#define cy_as_ll_request_response__get_code(req) \ 131 cy_as_mbox_get_code((req)->box0) 132 133#define cy_as_ll_request_response__set_context(req, context) \ 134 ((req)->box0 |= ((context) << \ 135 CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT)) 136 137#define cy_as_ll_request_response__set_clear_storage_flag(req) \ 138 ((req)->box0 |= CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG) 139 140#define cy_as_ll_request_response__get_context(req) \ 141 cy_as_mbox_get_context((req)->box0) 142 143#define cy_as_ll_request_response__is_last(req) \ 144 cy_as_mbox_is_last((req)->box0) 145 146#define CY_an_ll_request_response___set_last(req) \ 147 ((req)->box0 |= CY_AS_REQUEST_RESPONSE_LAST_MASK) 148 149#define cy_as_ll_request_response__is_request(req) \ 150 cy_as_mbox_is_request((req)->box0) 151 152#define cy_as_ll_request_response__set_request(req) \ 153 ((req)->box0 |= CY_AS_REQUEST_RESPONSE_TYPE_MASK) 154 155#define cy_as_ll_request_response__set_response(req) \ 156 ((req)->box0 &= ~CY_AS_REQUEST_RESPONSE_TYPE_MASK) 157 158#define cy_as_ll_request_response__is_response(req) \ 159 cy_as_mbox_is_response((req)->box0) 160 161#define cy_as_ll_request_response__get_word(req, offset) \ 162 ((req)->data[(offset)]) 163 164#define cy_as_ll_request_response__set_word(req, offset, \ 165 value) ((req)->data[(offset)] = value) 166 167typedef enum cy_as_remove_request_result_t { 168 cy_as_remove_request_sucessful, 169 cy_as_remove_request_in_transit, 170 cy_as_remove_request_not_found 171} cy_as_remove_request_result_t; 172 173/* Summary 174 Start the low level communications module 175 176 Description 177*/ 178cy_as_return_status_t 179cy_as_ll_start( 180 cy_as_device *dev_p 181 ); 182 183cy_as_return_status_t 184cy_as_ll_stop( 185 cy_as_device *dev_p 186 ); 187 188 189cy_as_ll_request_response * 190cy_as_ll_create_request( 191 cy_as_device *dev_p, 192 uint16_t code, 193 uint8_t context, 194 /* Length of the request in 16 bit words */ 195 uint16_t length 196 ); 197 198void 199cy_as_ll_init_request( 200 cy_as_ll_request_response *req_p, 201 uint16_t code, 202 uint16_t context, 203 uint16_t length); 204 205void 206cy_as_ll_init_response( 207 cy_as_ll_request_response *req_p, 208 uint16_t length); 209 210void 211cy_as_ll_destroy_request( 212 cy_as_device *dev_p, 213 cy_as_ll_request_response *); 214 215cy_as_ll_request_response * 216cy_as_ll_create_response( 217 cy_as_device *dev_p, 218 /* Length of the request in 16 bit words */ 219 uint16_t length 220 ); 221 222cy_as_remove_request_result_t 223cy_as_ll_remove_request( 224 cy_as_device *dev_p, 225 cy_as_context *ctxt_p, 226 cy_as_ll_request_response *req_p, 227 cy_bool force 228 ); 229void 230cy_as_ll_remove_all_requests(cy_as_device *dev_p, 231 cy_as_context *ctxt_p); 232 233void 234cy_as_ll_destroy_response( 235 cy_as_device *dev_p, 236 cy_as_ll_request_response *); 237 238cy_as_return_status_t 239cy_as_ll_send_request( 240 /* The West Bridge device */ 241 cy_as_device *dev_p, 242 /* The request to send */ 243 cy_as_ll_request_response *req, 244 /* Storage for a reply, must be sure it is of sufficient size */ 245 cy_as_ll_request_response *resp, 246 /* If true, this is a sync request */ 247 cy_bool sync, 248 /* Callback to call when reply is received */ 249 cy_as_response_callback cb 250); 251 252cy_as_return_status_t 253cy_as_ll_send_request_wait_reply( 254 /* The West Bridge device */ 255 cy_as_device *dev_p, 256 /* The request to send */ 257 cy_as_ll_request_response *req, 258 /* Storage for a reply, must be sure it is of sufficient size */ 259 cy_as_ll_request_response *resp 260); 261 262/* Summary 263 This function registers a callback function to be called when a 264 request arrives on a given context. 265 266 Description 267 268 Returns 269 * CY_AS_ERROR_SUCCESS 270*/ 271extern cy_as_return_status_t 272cy_as_ll_register_request_callback( 273 cy_as_device *dev_p, 274 uint8_t context, 275 cy_as_response_callback cb 276 ); 277 278/* Summary 279 This function packs a set of bytes given by the data_p pointer 280 into a request, reply structure. 281*/ 282extern void 283cy_as_ll_request_response__pack( 284 /* The destintation request or response */ 285 cy_as_ll_request_response *req, 286 /* The offset of where to pack the data */ 287 uint32_t offset, 288 /* The length of the data to pack in bytes */ 289 uint32_t length, 290 /* The data to pack */ 291 void *data_p 292 ); 293 294/* Summary 295 This function unpacks a set of bytes from a request/reply 296 structure into a segment of memory given by the data_p pointer. 297*/ 298extern void 299cy_as_ll_request_response__unpack( 300 /* The source of the data to unpack */ 301 cy_as_ll_request_response *req, 302 /* The offset of the data to unpack */ 303 uint32_t offset, 304 /* The length of the data to unpack in bytes */ 305 uint32_t length, 306 /* The destination of the unpack operation */ 307 void *data_p 308 ); 309 310/* Summary 311 This function sends a status response back to the West Bridge 312 device in response to a previously send request 313*/ 314extern cy_as_return_status_t 315cy_as_ll_send_status_response( 316 /* The West Bridge device */ 317 cy_as_device *dev_p, 318 /* The context to send the response on */ 319 uint8_t context, 320 /* The success/failure code to send */ 321 uint16_t code, 322 /* Flag to clear wait on storage context */ 323 uint8_t clear_storage); 324 325/* Summary 326 This function sends a response back to the West Bridge device. 327 328 Description 329 This function sends a response back to the West Bridge device. 330 The response is sent on the context given by the 'context' 331 variable. The code for the response is given by the 'code' 332 argument. The data for the response is given by the data and 333 length arguments. 334*/ 335extern cy_as_return_status_t 336cy_as_ll_send_data_response( 337 /* The West Bridge device */ 338 cy_as_device *dev_p, 339 /* The context to send the response on */ 340 uint8_t context, 341 /* The response code to use */ 342 uint16_t code, 343 /* The length of the data for the response */ 344 uint16_t length, 345 /* The data for the response */ 346 void *data 347); 348 349/* Summary 350 This function removes any requests of the given type 351 from the given context. 352 353 Description 354 This function removes requests of a given type from the 355 context given via the context number. 356*/ 357extern cy_as_return_status_t 358cy_as_ll_remove_ep_data_requests( 359 /* The West Bridge device */ 360 cy_as_device *dev_p, 361 cy_as_end_point_number_t ep 362 ); 363 364#include "cyas_cplus_end.h" 365 366#endif /* _INCLUDED_CYASLOWLEVEL_H_ */ 367