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
00121 pArg->pIfDesc = pIf;
00122 } else if (pCdcd->bInterfaceNdx <= pIf->bInterfaceNumber
00123 && pCdcd->bInterfaceNdx + pCdcd->bNumInterface
00124 > pIf->bInterfaceNumber)
00125 pArg->pIfDesc = pIf;
00126 }
00127
00128
00129 if (pArg->pIfDesc == 0)
00130 return 0;
00131
00132
00133 if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT) {
00134 USBEndpointDescriptor *pEp = (USBEndpointDescriptor *)pDesc;
00135
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 uint32_t offset = 0;
00166
00167
00168 if ((received == DATAPACKETSIZE) && (remaining > 0)) {
00169 TRACE_WARNING("_UsbDataReceived: %u bytes discarded\n\r",
00170 (unsigned int)remaining);
00171 }
00172
00173 while (received >= 2) {
00174 uint16_t header;
00175
00176 header = gRxBuffer[offset] + (gRxBuffer[offset + 1] << 8);
00177 offset += 2;
00178 received -= 2;
00179
00180 if (header & (1 << 15)) {
00181
00182 if (header & (1 << 14))
00183 break;
00184
00185 int cmd = (header >> 11) & 7;
00186 unsigned int param = header & 0x7ff;
00187
00188 switch (cmd) {
00189 case 0:
00190
00191 TRACE_WARNING("Received Echo EEM command\n\r");
00192
00193 if (received < param)
00194 break;
00195
00196 header = (1 << 15) + (1 << 11);
00197
00198 TRACE_WARNING("Sending EchoReply EEM command\n\r");
00199 gRxBuffer[offset - 2] = header & 0xff;
00200 gRxBuffer[offset - 1] = (header >> 8) & 0xff;
00201
00202 while (CDCDEEMPort_Write(pCdcd, &gRxBuffer[offset - 2],
00203 param + 2, NULL, 0) != USBD_STATUS_SUCCESS);
00204
00205 break;
00206
00207 case 1:
00208
00209 TRACE_WARNING("Unexpected EchoReply EEM command received\n\r");
00210 break;
00211
00212 case 2:
00213
00214 TRACE_WARNING("Unexpected SuspendHint EEM command received\n\r");
00215 break;
00216
00217 case 3:
00218
00219 TRACE_WARNING("Unexpected ResponseHint EEM command received\n\r");
00220 break;
00221
00222 case 4:
00223
00224 TRACE_WARNING("Unexpected ResponseCompleteHint EEM command received\n\r");
00225 break;
00226
00227 case 5:
00228
00229 TRACE_WARNING("Unexpected Tickle EEM command received\n\r");
00230 break;
00231
00232 default:
00233
00234 TRACE_WARNING("Unexpected unknown EEM command %d received\n\r", cmd);
00235 break;
00236 }
00237 } else {
00238 uint16_t len = header & 0x3fff;
00239
00240 if (received < len || len < 4)
00241 return;
00242
00243
00244
00245
00246 if (gRxCallback) {
00247 if (gRxDataSize + 4 > len) {
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 TRACE_WARNING("_UsbDataReceived: %u bytes ignored\n\r",
00261 (unsigned int)remaining);
00262 }
00263 } else {
00264 TRACE_WARNING("_UsbDataReceived: Transfer error\n\r");
00265 }
00266 }
00267
00268 static int _UsbTxBufferPush(void)
00269 {
00270 int idx;
00271
00272 if (gUsbTxHeadIdx == ((gUsbTxTailIdx - 1 + USB_TX_BUFFERS) % USB_TX_BUFFERS))
00273 return -1;
00274
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
00285 if (gUsbTxHeadIdx == gUsbTxTailIdx)
00286 return -1;
00287
00288 if (gUsbTxBufferSizes[gUsbTxTailIdx] == 0)
00289 return -1;
00290
00291 idx = gUsbTxTailIdx;
00292 gUsbTxTailIdx = (gUsbTxTailIdx + 1) % USB_TX_BUFFERS;
00293 return idx;
00294 }
00295
00296 static int _UsbTxBufferPeek(void)
00297 {
00298 if (gUsbTxHeadIdx == gUsbTxTailIdx)
00299 return -1;
00300
00301 if (gUsbTxBufferSizes[gUsbTxTailIdx] == 0)
00302 return -1;
00303
00304 return gUsbTxTailIdx;
00305 }
00306
00307 static void _FlushUsbTxBuffers(const uint8_t *pipe);
00308
00309 static void _UsbDataSent(void *pipe,
00310 uint8_t status,
00311 uint32_t received,
00312 uint32_t remaining)
00313 {
00314 int bufIdx;
00315
00316
00317 (void)status;
00318 (void)received;
00319 (void)remaining;
00320
00321 bufIdx = _UsbTxBufferPop();
00322
00323 if (bufIdx >= 0) {
00324 TRACE_INFO("%u USB_TX_DEQUEUE(%d)\n\r", (unsigned int)GetTicks(), bufIdx);
00325 }
00326
00327
00328 __disable_irq();
00329 ReleaseMutex(gUsbTxMutex);
00330 __enable_irq();
00331
00332
00333 _FlushUsbTxBuffers((const uint8_t *)pipe);
00334 }
00335
00336 static void _FlushUsbTxBuffers(const uint8_t *pipe)
00337 {
00338 int bufIdx;
00339 uint32_t timeout = 0x7ff;
00340
00341
00342 __disable_irq();
00343
00344 if (LockMutex(gUsbTxMutex, timeout) != 0) {
00345 __enable_irq();
00346 return;
00347 }
00348
00349 __enable_irq();
00350
00351 if ((bufIdx = _UsbTxBufferPeek()) >= 0) {
00352 TRACE_INFO("%u USB_TX_SEND(%d,%u)\n\r", (unsigned int)GetTicks(), bufIdx,
00353 (unsigned int)gUsbTxBufferSizes[bufIdx]);
00354
00355
00356 while (USBD_Write(*pipe, &gUsbTxBuffers[DATAPACKETSIZE * bufIdx],
00357 gUsbTxBufferSizes[bufIdx], _UsbDataSent,
00358 (void *)pipe) != USBD_STATUS_SUCCESS) {}
00359 } else {
00360
00361 __disable_irq();
00362 ReleaseMutex(gUsbTxMutex);
00363 __enable_irq();
00364 }
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 void CDCDEEMPort_Initialize(CDCDEEMPort *pCdcd,
00381 USBDDriver *pUsbd,
00382 uint8_t firstInterface, uint8_t numInterface)
00383 {
00384 TRACE_INFO("CDCDEEMPort_Initialize\n\r");
00385
00386
00387 pCdcd->pUsbd = pUsbd;
00388 pCdcd->bInterfaceNdx = firstInterface;
00389 pCdcd->bNumInterface = numInterface;
00390 pCdcd->bBulkInPIPE = 0;
00391 pCdcd->bBulkOutPIPE = 0;
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 USBGenericDescriptor *CDCDEEMPort_ParseInterfaces(
00404 CDCDEEMPort *pCdcd,
00405 USBGenericDescriptor *pDescriptors,
00406 uint32_t dwLength)
00407 {
00408 CDCDParseData parseData;
00409
00410 parseData.pCdcd = pCdcd;
00411 parseData.pIfDesc = 0;
00412
00413 return USBGenericDescriptor_Parse(
00414 pDescriptors, dwLength,
00415 (USBDescriptorParseFunction)_Interfaces_Parse,
00416 &parseData);
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 uint32_t CDCDEEMPort_RequestHandler(
00428 CDCDEEMPort *pCdcd,
00429 const USBGenericRequest *request)
00430 {
00431 if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS)
00432 return USBRC_PARAM_ERR;
00433
00434 TRACE_INFO_WP("Cdce ");
00435
00436
00437 if (request->wIndex >= pCdcd->bInterfaceNdx &&
00438 request->wIndex < pCdcd->bInterfaceNdx + pCdcd->bNumInterface) {
00439 } else
00440 return USBRC_PARAM_ERR;
00441
00442
00443 switch (USBGenericRequest_GetRequest(request)) {
00444
00445 default:
00446
00447 return USBRC_PARAM_ERR;
00448 }
00449
00450 return USBRC_SUCCESS;
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 uint32_t CDCDEEMPort_Read(const CDCDEEMPort *pCdcd,
00466 void *pData, uint32_t dwSize,
00467 TransferCallback fCallback, void *pArg)
00468 {
00469 if (pCdcd->bBulkOutPIPE == 0)
00470 return USBRC_PARAM_ERR;
00471
00472 gRxCallback = fCallback;
00473 gRxCallbackArg = pArg;
00474 gRxData = pData;
00475 gRxDataSize = dwSize;
00476 return USBD_Read(pCdcd->bBulkOutPIPE,
00477 gRxBuffer, DATABUFFERSIZE,
00478 (TransferCallback)_TransferCallback, pArg);
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 uint32_t CDCDEEMPort_Write(const CDCDEEMPort *pCdcd,
00497 void *pData, uint32_t dwSize,
00498 TransferCallback fCallback, void *pArg)
00499 {
00500 int bufIdx;
00501 uint8_t *buffer;
00502 uint32_t len;
00503
00504
00505 (void)fCallback;
00506 (void)pArg;
00507
00508 if (pCdcd->bBulkInPIPE == 0)
00509 return USBRC_PARAM_ERR;
00510
00511 bufIdx = _UsbTxBufferPush();
00512
00513 if (bufIdx >= 0) {
00514 buffer = &gUsbTxBuffers[DATAPACKETSIZE * bufIdx];
00515
00516
00517 len = dwSize;
00518 uint16_t eemHdr = (len + 4) & 0x3fff;
00519 buffer[0] = eemHdr & 0xff;
00520 buffer[1] = (eemHdr >> 8) & 0xff;
00521 memcpy(buffer + 2, pData, len);
00522 len += 2;
00523 buffer[len] = 0xde;
00524 buffer[len + 1] = 0xad;
00525 buffer[len + 2] = 0xbe;
00526 buffer[len + 3] = 0xef;
00527 len += 4;
00528
00529
00530 if (len % pCdcd->wBulkOutMaxPacketSize == 0) {
00531 memset(buffer + len, 0, 2);
00532 len += 2;
00533 }
00534
00535 gUsbTxBufferSizes[bufIdx] = len;
00536
00537 _FlushUsbTxBuffers(&pCdcd->bBulkInPIPE);
00538 } else {
00539
00540 }
00541
00542 return USBRC_SUCCESS;
00543 }
00544
00545