00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <CDCDEEMPort.h>
00043 #include <CDCDescriptors.h>
00044 #include <USBLib_Trace.h>
00045 #include <string.h>
00046 #include "../../../../utils/utility.h"
00047
00048
00049
00050
00051
00052
00053 typedef struct _CDCDParseData {
00054
00055 CDCDEEMPort * pCdcd;
00056
00057 USBInterfaceDescriptor * pIfDesc;
00058
00059 } CDCDParseData;
00060
00061
00062
00063
00064
00065
00066 #define DATAPACKETSIZE (1536)
00067
00068
00069 #define DATABUFFERSIZE (DATAPACKETSIZE+2)
00070
00071
00072 #define USB_TX_BUFFERS 64
00073
00074
00075 static uint8_t gRxBuffer[DATABUFFERSIZE];
00076
00077
00078 static uint8_t gUsbTxBuffers[USB_TX_BUFFERS * DATAPACKETSIZE];
00079 static uint32_t gUsbTxBufferSizes[USB_TX_BUFFERS];
00080 static int gUsbTxHeadIdx = 0;
00081 static int gUsbTxTailIdx = 0;
00082 static uint8_t gUsbTxMutex = 0;
00083
00084
00085 static TransferCallback gRxCallback;
00086 static void *gRxCallbackArg;
00087 static void *gRxData;
00088 static uint32_t gRxDataSize;
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 static uint32_t _Interfaces_Parse(USBGenericDescriptor *pDesc,
00100 CDCDParseData * pArg)
00101 {
00102 CDCDEEMPort *pCdcd = pArg->pCdcd;
00103
00104
00105 if (pDesc->bLength == 0)
00106 return USBRC_PARAM_ERR;
00107
00108
00109 if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00110 USBInterfaceDescriptor *pIf = (USBInterfaceDescriptor*)pDesc;
00111
00112
00113 if (pCdcd->bInterfaceNdx == 0xFF) {
00114
00115 if (pIf->bInterfaceClass ==
00116 CDCCommunicationInterfaceDescriptor_CLASS) {
00117 pCdcd->bInterfaceNdx = pIf->bInterfaceNumber;
00118 pCdcd->bNumInterface = 1;
00119 }
00120 pArg->pIfDesc = pIf;
00121 }
00122 else if (pCdcd->bInterfaceNdx <= pIf->bInterfaceNumber
00123 && pCdcd->bInterfaceNdx + pCdcd->bNumInterface
00124 > pIf->bInterfaceNumber) {
00125 pArg->pIfDesc = pIf;
00126 }
00127 }
00128
00129
00130 if (pArg->pIfDesc == 0)
00131 return 0;
00132
00133
00134 if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT) {
00135 USBEndpointDescriptor *pEp = (USBEndpointDescriptor*)pDesc;
00136 switch(pEp->bmAttributes & 0x3) {
00137 case USBEndpointDescriptor_BULK:
00138 if (pEp->bEndpointAddress & 0x80)
00139 pCdcd->bBulkInPIPE = pEp->bEndpointAddress & 0x7F;
00140 else {
00141 pCdcd->bBulkOutPIPE = pEp->bEndpointAddress;
00142 pCdcd->wBulkOutMaxPacketSize = pEp->wMaxPacketSize;
00143 }
00144 }
00145 }
00146
00147 if ( pCdcd->bInterfaceNdx != 0xFF
00148 && pCdcd->bBulkInPIPE != 0
00149 && pCdcd->bBulkOutPIPE != 0)
00150 return USBRC_FINISHED;
00151
00152 return 0;
00153 }
00154
00155
00156
00157
00158 static void _TransferCallback(const CDCDEEMPort * pCdcd,
00159 uint8_t status,
00160 uint32_t received,
00161 uint32_t remaining)
00162 {
00163
00164 if (status == USBD_STATUS_SUCCESS)
00165 {
00166 uint32_t offset = 0;
00167
00168
00169 if ((received == DATAPACKETSIZE) && (remaining > 0))
00170 {
00171 TRACE_WARNING("_UsbDataReceived: %u bytes discarded\n\r",
00172 (unsigned int)remaining);
00173 }
00174
00175 while (received >= 2)
00176 {
00177 uint16_t header;
00178
00179 header = gRxBuffer[offset] + (gRxBuffer[offset + 1] << 8);
00180 offset += 2;
00181 received -= 2;
00182
00183 if (header & (1 << 15))
00184 {
00185
00186 if (header & (1 << 14))
00187 break;
00188
00189 int cmd = (header >> 11) & 7;
00190 unsigned int param = header & 0x7ff;
00191
00192 switch (cmd)
00193 {
00194 case 0:
00195
00196 TRACE_WARNING("Received Echo EEM command\n\r");
00197 if (received < param)
00198 break;
00199 header = (1 << 15) + (1 << 11);
00200
00201 TRACE_WARNING("Sending EchoReply EEM command\n\r");
00202 gRxBuffer[offset - 2] = header & 0xff;
00203 gRxBuffer[offset - 1] = (header >> 8) & 0xff;
00204 while (CDCDEEMPort_Write(pCdcd, &gRxBuffer[offset - 2],
00205 param + 2, NULL, 0) != USBD_STATUS_SUCCESS);
00206
00207 break;
00208 case 1:
00209
00210 TRACE_WARNING("Unexpected EchoReply EEM command received\n\r");
00211 break;
00212 case 2:
00213
00214 TRACE_WARNING("Unexpected SuspendHint EEM command received\n\r");
00215 break;
00216 case 3:
00217
00218 TRACE_WARNING("Unexpected ResponseHint EEM command received\n\r");
00219 break;
00220 case 4:
00221
00222 TRACE_WARNING("Unexpected ResponseCompleteHint EEM command received\n\r");
00223 break;
00224 case 5:
00225
00226 TRACE_WARNING("Unexpected Tickle EEM command received\n\r");
00227 break;
00228 default:
00229
00230 TRACE_WARNING("Unexpected unknown EEM command %d received\n\r", cmd);
00231 break;
00232 }
00233 }
00234 else
00235 {
00236 uint16_t len = header & 0x3fff;
00237
00238 if (received < len || len < 4)
00239 return;
00240
00241
00242
00243
00244 if (gRxCallback)
00245 {
00246 if (gRxDataSize + 4 > len)
00247 {
00248 memcpy(gRxData, gRxBuffer + offset, len - 4);
00249 gRxCallback(gRxCallbackArg, USBD_STATUS_SUCCESS, len - 4, 0);
00250 }
00251 }
00252
00253 offset += len;
00254 received -= len;
00255 }
00256 }
00257
00258
00259 if (received > 0)
00260 {
00261 TRACE_WARNING("_UsbDataReceived: %u bytes ignored\n\r", (unsigned int)remaining);
00262 }
00263 }
00264 else
00265 {
00266 TRACE_WARNING("_UsbDataReceived: Transfer error\n\r");
00267 }
00268 }
00269
00270 static int _UsbTxBufferPush(void)
00271 {
00272 int idx;
00273 if (gUsbTxHeadIdx == ((gUsbTxTailIdx - 1 + USB_TX_BUFFERS) % USB_TX_BUFFERS))
00274 return -1;
00275 idx = gUsbTxHeadIdx;
00276 gUsbTxHeadIdx = (gUsbTxHeadIdx + 1) % USB_TX_BUFFERS;
00277 gUsbTxBufferSizes[idx] = 0;
00278 return idx;
00279 }
00280
00281 static int _UsbTxBufferPop(void)
00282 {
00283 int idx;
00284 if (gUsbTxHeadIdx == gUsbTxTailIdx)
00285 return -1;
00286 if (gUsbTxBufferSizes[gUsbTxTailIdx] == 0)
00287 return -1;
00288 idx = gUsbTxTailIdx;
00289 gUsbTxTailIdx = (gUsbTxTailIdx + 1) % USB_TX_BUFFERS;
00290 return idx;
00291 }
00292
00293 static int _UsbTxBufferPeek(void)
00294 {
00295 if (gUsbTxHeadIdx == gUsbTxTailIdx)
00296 return -1;
00297 if (gUsbTxBufferSizes[gUsbTxTailIdx] == 0)
00298 return -1;
00299 return gUsbTxTailIdx;
00300 }
00301
00302 static void _FlushUsbTxBuffers(const uint8_t *pipe);
00303
00304 static void _UsbDataSent(void *pipe,
00305 uint8_t status,
00306 uint32_t received,
00307 uint32_t remaining)
00308 {
00309 int bufIdx;
00310
00311
00312 (void)status;
00313 (void)received;
00314 (void)remaining;
00315
00316 bufIdx = _UsbTxBufferPop();
00317 if (bufIdx >= 0)
00318 TRACE_INFO("%u USB_TX_DEQUEUE(%d)\n\r", (unsigned int)GetTicks(), bufIdx);
00319
00320
00321 __disable_irq();
00322 ReleaseMutex(gUsbTxMutex);
00323 __enable_irq();
00324
00325
00326 _FlushUsbTxBuffers((const uint8_t *)pipe);
00327 }
00328
00329 static void _FlushUsbTxBuffers(const uint8_t *pipe)
00330 {
00331 int bufIdx;
00332 uint32_t timeout = 0x7ff;
00333
00334
00335 __disable_irq();
00336 if (LockMutex(gUsbTxMutex, timeout) != 0)
00337 {
00338 __enable_irq();
00339 return;
00340 }
00341 __enable_irq();
00342
00343 if ((bufIdx = _UsbTxBufferPeek()) >= 0)
00344 {
00345 TRACE_INFO("%u USB_TX_SEND(%d,%u)\n\r", (unsigned int)GetTicks(), bufIdx, gUsbTxBufferSizes[bufIdx]);
00346
00347
00348 while (USBD_Write(*pipe, &gUsbTxBuffers[DATAPACKETSIZE * bufIdx],
00349 gUsbTxBufferSizes[bufIdx], _UsbDataSent, (void*)pipe) != USBD_STATUS_SUCCESS) {}
00350 }
00351 else
00352 {
00353
00354 __disable_irq();
00355 ReleaseMutex(gUsbTxMutex);
00356 __enable_irq();
00357 }
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 void CDCDEEMPort_Initialize(CDCDEEMPort * pCdcd,
00374 USBDDriver * pUsbd,
00375 uint8_t firstInterface,uint8_t numInterface)
00376 {
00377 TRACE_INFO("CDCDEEMPort_Initialize\n\r");
00378
00379
00380 pCdcd->pUsbd = pUsbd;
00381 pCdcd->bInterfaceNdx = firstInterface;
00382 pCdcd->bNumInterface = numInterface;
00383 pCdcd->bBulkInPIPE = 0;
00384 pCdcd->bBulkOutPIPE = 0;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 USBGenericDescriptor *CDCDEEMPort_ParseInterfaces(
00397 CDCDEEMPort *pCdcd,
00398 USBGenericDescriptor *pDescriptors,
00399 uint32_t dwLength)
00400 {
00401 CDCDParseData parseData;
00402
00403 parseData.pCdcd = pCdcd;
00404 parseData.pIfDesc = 0;
00405
00406 return USBGenericDescriptor_Parse(
00407 pDescriptors, dwLength,
00408 (USBDescriptorParseFunction)_Interfaces_Parse,
00409 &parseData);
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 uint32_t CDCDEEMPort_RequestHandler(
00421 CDCDEEMPort *pCdcd,
00422 const USBGenericRequest *request)
00423 {
00424 if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS)
00425 return USBRC_PARAM_ERR;
00426
00427 TRACE_INFO_WP("Cdce ");
00428
00429
00430 if (request->wIndex >= pCdcd->bInterfaceNdx &&
00431 request->wIndex < pCdcd->bInterfaceNdx + pCdcd->bNumInterface) {
00432 }
00433 else {
00434 return USBRC_PARAM_ERR;
00435 }
00436
00437
00438 switch (USBGenericRequest_GetRequest(request)) {
00439
00440 default:
00441
00442 return USBRC_PARAM_ERR;
00443 }
00444
00445 return USBRC_SUCCESS;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 uint32_t CDCDEEMPort_Read(const CDCDEEMPort * pCdcd,
00461 void * pData, uint32_t dwSize,
00462 TransferCallback fCallback, void * pArg)
00463 {
00464 if (pCdcd->bBulkOutPIPE == 0)
00465 return USBRC_PARAM_ERR;
00466
00467 gRxCallback = fCallback;
00468 gRxCallbackArg = pArg;
00469 gRxData = pData;
00470 gRxDataSize = dwSize;
00471 return USBD_Read(pCdcd->bBulkOutPIPE,
00472 gRxBuffer, DATABUFFERSIZE,
00473 (TransferCallback)_TransferCallback, pArg);
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 uint32_t CDCDEEMPort_Write(const CDCDEEMPort * pCdcd,
00492 void * pData, uint32_t dwSize,
00493 TransferCallback fCallback, void * pArg)
00494 {
00495 int bufIdx;
00496 uint8_t *buffer;
00497 uint32_t len;
00498
00499
00500 (void)fCallback;
00501 (void)pArg;
00502
00503 if (pCdcd->bBulkInPIPE == 0)
00504 return USBRC_PARAM_ERR;
00505
00506 bufIdx = _UsbTxBufferPush();
00507 if (bufIdx >= 0)
00508 {
00509 buffer = &gUsbTxBuffers[DATAPACKETSIZE * bufIdx];
00510
00511
00512 len = dwSize;
00513 uint16_t eemHdr = (len + 4) & 0x3fff;
00514 buffer[0] = eemHdr & 0xff;
00515 buffer[1] = (eemHdr >> 8) & 0xff;
00516 memcpy(buffer + 2, pData, len);
00517 len += 2;
00518 buffer[len] = 0xde;
00519 buffer[len+1] = 0xad;
00520 buffer[len+2] = 0xbe;
00521 buffer[len+3] = 0xef;
00522 len += 4;
00523
00524
00525 if (len % pCdcd->wBulkOutMaxPacketSize == 0) {
00526 memset(buffer + len, 0, 2);
00527 len += 2;
00528 }
00529
00530 gUsbTxBufferSizes[bufIdx] = len;
00531
00532 _FlushUsbTxBuffers(&pCdcd->bBulkInPIPE);
00533 }
00534 else
00535 {
00536
00537 }
00538
00539 return USBRC_SUCCESS;
00540 }
00541
00542