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 <CDCDSerialPort.h>
00043 #include <CDCDescriptors.h>
00044 #include <USBLib_Trace.h>
00045 #include <chip.h>
00046
00047
00048
00049
00050
00051 typedef struct _CDCDParseData {
00052
00053 CDCDSerialPort *pCdcd;
00054
00055 USBInterfaceDescriptor *pIfDesc;
00056
00057 } CDCDParseData;
00058
00059
00060
00061
00062
00063
00064 static CDCLineCoding lineCoding;
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 static uint32_t _Interfaces_Parse(USBGenericDescriptor *pDesc,
00075 CDCDParseData *pArg)
00076 {
00077 CDCDSerialPort *pCdcd = pArg->pCdcd;
00078
00079
00080 if (pDesc->bLength == 0)
00081 return USBRC_PARAM_ERR;
00082
00083
00084 if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00085 USBInterfaceDescriptor *pIf = (USBInterfaceDescriptor *)pDesc;
00086
00087
00088 if (pCdcd->bInterfaceNdx == 0xFF) {
00089
00090 if (pIf->bInterfaceClass ==
00091 CDCCommunicationInterfaceDescriptor_CLASS) {
00092 pCdcd->bInterfaceNdx = pIf->bInterfaceNumber;
00093 pCdcd->bNumInterface = 2;
00094 }
00095
00096 else if (pIf->bInterfaceClass == CDCDataInterfaceDescriptor_CLASS) {
00097 pCdcd->bInterfaceNdx = pIf->bInterfaceNumber;
00098 pCdcd->bNumInterface = 1;
00099 }
00100
00101 pArg->pIfDesc = pIf;
00102 } else if (pCdcd->bInterfaceNdx <= pIf->bInterfaceNumber
00103 && pCdcd->bInterfaceNdx + pCdcd->bNumInterface
00104 > pIf->bInterfaceNumber)
00105 pArg->pIfDesc = pIf;
00106 }
00107
00108
00109 if (pArg->pIfDesc == 0)
00110 return 0;
00111
00112
00113 if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT) {
00114 USBEndpointDescriptor *pEp = (USBEndpointDescriptor *)pDesc;
00115
00116 switch (pEp->bmAttributes & 0x3) {
00117 case USBEndpointDescriptor_INTERRUPT:
00118 if (pEp->bEndpointAddress & 0x80)
00119 pCdcd->bIntInPIPE = pEp->bEndpointAddress & 0x7F;
00120
00121 break;
00122
00123 case USBEndpointDescriptor_BULK:
00124 if (pEp->bEndpointAddress & 0x80)
00125 pCdcd->bBulkInPIPE = pEp->bEndpointAddress & 0x7F;
00126 else
00127 pCdcd->bBulkOutPIPE = pEp->bEndpointAddress;
00128 }
00129 }
00130
00131 if (pCdcd->bInterfaceNdx != 0xFF
00132 && pCdcd->bBulkInPIPE != 0
00133 && pCdcd->bBulkOutPIPE != 0)
00134 return USBRC_FINISHED;
00135
00136 return 0;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145 static void _SetLineCodingCallback(CDCDSerialPort *pCdcd)
00146 {
00147 uint32_t exec = 1;
00148
00149 if (pCdcd->fEventHandler) {
00150 uint32_t rc = pCdcd->fEventHandler(
00151 CDCDSerialPortEvent_SETLINECODING,
00152 (uint32_t)(&lineCoding),
00153 pCdcd->pEventArg);
00154
00155 if (rc == USBD_STATUS_SUCCESS) {
00156 pCdcd->lineCoding.dwDTERate = lineCoding.dwDTERate;
00157 pCdcd->lineCoding.bCharFormat = lineCoding.bCharFormat;
00158 pCdcd->lineCoding.bParityType = lineCoding.bParityType;
00159 pCdcd->lineCoding.bDataBits = lineCoding.bDataBits;
00160 } else
00161 exec = 0;
00162 }
00163
00164 if (exec)
00165 USBD_Write(0, 0, 0, 0, 0);
00166 else
00167 USBD_Stall(0);
00168 }
00169
00170
00171
00172
00173
00174 static void _SetLineCoding(CDCDSerialPort *pCdcd)
00175 {
00176 TRACE_INFO_WP("sLineCoding ");
00177
00178 USBD_Read(0,
00179 (void *) & (lineCoding),
00180 sizeof(CDCLineCoding),
00181 (TransferCallback)_SetLineCodingCallback,
00182 (void *)pCdcd);
00183 }
00184
00185
00186
00187
00188
00189
00190 static void _GetLineCoding(CDCDSerialPort *pCdcd)
00191 {
00192 TRACE_INFO_WP("gLineCoding ");
00193
00194 USBD_Write(0,
00195 (void *)&(pCdcd->lineCoding),
00196 sizeof(CDCLineCoding),
00197 0,
00198 0);
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208 static void _SetControlLineState(
00209 CDCDSerialPort *pCdcd,
00210 const USBGenericRequest *request)
00211 {
00212 #if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
00213 uint8_t DTR, RTS;
00214
00215 DTR = ((request->wValue & CDCControlLineState_DTR) > 0);
00216 RTS = ((request->wValue & CDCControlLineState_RTS) > 0);
00217 TRACE_INFO_WP("sControlLineState(%d, %d) ", DTR, RTS);
00218 #endif
00219
00220 pCdcd->bControlLineState = (uint8_t)request->wValue;
00221 USBD_Write(0, 0, 0, 0, 0);
00222
00223 if (pCdcd->fEventHandler)
00224 pCdcd->fEventHandler(CDCDSerialPortEvent_SETCONTROLLINESTATE,
00225 (uint32_t)pCdcd->bControlLineState,
00226 pCdcd->pEventArg);
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 void CDCDSerialPort_Initialize(CDCDSerialPort *pCdcd,
00243 USBDDriver *pUsbd,
00244 CDCDSerialPortEventHandler fEventHandler,
00245 void *pArg,
00246 uint8_t firstInterface, uint8_t numInterface)
00247 {
00248 TRACE_INFO("CDCDSerialPort_Initialize\n\r");
00249
00250
00251 pCdcd->fEventHandler = fEventHandler;
00252 pCdcd->pEventArg = pArg;
00253
00254
00255 pCdcd->fTransCLK = 0;
00256 pCdcd->pTansArg = 0;
00257
00258
00259 pCdcd->pUsbd = pUsbd;
00260 pCdcd->bInterfaceNdx = firstInterface;
00261 pCdcd->bNumInterface = numInterface;
00262 pCdcd->bIntInPIPE = 0;
00263 pCdcd->bBulkInPIPE = 0;
00264 pCdcd->bBulkOutPIPE = 0;
00265
00266
00267 pCdcd->bControlLineState = 0;
00268 pCdcd->wSerialState = 0;
00269 CDCLineCoding_Initialize(&(pCdcd->lineCoding),
00270 115200,
00271 CDCLineCoding_ONESTOPBIT,
00272 CDCLineCoding_NOPARITY,
00273 8);
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 USBGenericDescriptor *CDCDSerialPort_ParseInterfaces(
00286 CDCDSerialPort *pCdcd,
00287 USBGenericDescriptor *pDescriptors,
00288 uint32_t dwLength)
00289 {
00290 CDCDParseData parseData;
00291
00292 parseData.pCdcd = pCdcd;
00293 parseData.pIfDesc = 0;
00294
00295 return USBGenericDescriptor_Parse(
00296 pDescriptors, dwLength,
00297 (USBDescriptorParseFunction)_Interfaces_Parse,
00298 &parseData);
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 uint32_t CDCDSerialPort_RequestHandler(
00310 CDCDSerialPort *pCdcd,
00311 const USBGenericRequest *request)
00312 {
00313 if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS)
00314 return USBRC_PARAM_ERR;
00315
00316 TRACE_INFO_WP("Cdcs ");
00317
00318
00319 if (request->wIndex >= pCdcd->bInterfaceNdx &&
00320 request->wIndex < pCdcd->bInterfaceNdx + pCdcd->bNumInterface) {
00321 } else
00322 return USBRC_PARAM_ERR;
00323
00324
00325 switch (USBGenericRequest_GetRequest(request)) {
00326
00327 case CDCGenericRequest_SETLINECODING:
00328
00329 _SetLineCoding(pCdcd);
00330 break;
00331
00332 case CDCGenericRequest_GETLINECODING:
00333
00334 _GetLineCoding(pCdcd);
00335 break;
00336
00337 case CDCGenericRequest_SETCONTROLLINESTATE:
00338
00339 _SetControlLineState(pCdcd, request);
00340 break;
00341
00342 default:
00343
00344 return USBRC_PARAM_ERR;
00345 }
00346
00347 return USBRC_SUCCESS;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 uint32_t CDCDSerialPort_Read(const CDCDSerialPort *pCdcd,
00363 void *pData, uint32_t dwSize,
00364 TransferCallback fCallback, void *pArg)
00365 {
00366 if (pCdcd->bBulkOutPIPE == 0)
00367 return USBRC_PARAM_ERR;
00368
00369 return USBD_Read(pCdcd->bBulkOutPIPE,
00370 pData, dwSize,
00371 fCallback, pArg);
00372 }
00373
00374
00375
00376
00377
00378
00379 static void _UsbDataSent_ZLP(CDCDSerialPort *pCdcd)
00380 {
00381 USBD_Write(pCdcd->bBulkInPIPE, 0, 0, pCdcd->fTransCLK, pCdcd->pTansArg);
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 uint32_t CDCDSerialPort_Write(CDCDSerialPort *pCdcd,
00399 void *pData, uint32_t dwSize,
00400 TransferCallback fCallback, void *pArg)
00401 {
00402 uint32_t result;
00403 Usbhs *pUdp = USBHS;
00404 uint32_t endpointSize;
00405
00406 if (pCdcd->bBulkInPIPE == 0)
00407 return USBRC_PARAM_ERR;
00408
00409 endpointSize = USBHS_GetEpSize(pUdp, pCdcd->bBulkInPIPE);
00410
00411 if (dwSize % endpointSize == 0) {
00412 pCdcd->fTransCLK = fCallback;
00413 pCdcd->pTansArg = pArg;
00414 result = USBD_Write(pCdcd->bBulkInPIPE,
00415 pData, dwSize,
00416 (TransferCallback)_UsbDataSent_ZLP, (void *)pCdcd);
00417 } else {
00418 result = USBD_Write(pCdcd->bBulkInPIPE,
00419 pData, dwSize,
00420 fCallback, pArg);
00421
00422 }
00423
00424 return result;
00425 }
00426
00427
00428
00429
00430
00431 uint8_t CDCDSerialPort_GetControlLineState(const CDCDSerialPort *pCdcd)
00432 {
00433 return pCdcd->bControlLineState;
00434 }
00435
00436
00437
00438
00439
00440
00441 void CDCDSerialPort_GetLineCoding(const CDCDSerialPort *pCdcd,
00442 CDCLineCoding *pLineCoding)
00443 {
00444 if (pLineCoding) {
00445 pLineCoding->dwDTERate = pCdcd->lineCoding.dwDTERate;
00446 pLineCoding->bCharFormat = pCdcd->lineCoding.bCharFormat;
00447 pLineCoding->bParityType = pCdcd->lineCoding.bParityType;
00448 pLineCoding->bDataBits = pCdcd->lineCoding.bDataBits;
00449 }
00450 }
00451
00452
00453
00454
00455
00456 uint16_t CDCDSerialPort_GetSerialState(const CDCDSerialPort *pCdcd)
00457 {
00458 return pCdcd->wSerialState;
00459 }
00460
00461
00462
00463
00464
00465
00466 void CDCDSerialPort_SetSerialState(CDCDSerialPort *pCdcd,
00467 uint16_t wSerialState)
00468 {
00469 if (pCdcd->bIntInPIPE == 0)
00470 return;
00471
00472
00473
00474 if (pCdcd->wSerialState != wSerialState) {
00475
00476 pCdcd->wSerialState = wSerialState;
00477 USBD_Write(pCdcd->bIntInPIPE,
00478 &(pCdcd->wSerialState),
00479 2,
00480 0,
00481 0);
00482
00483
00484 pCdcd->wSerialState &= ~(CDCSerialState_OVERRUN
00485 | CDCSerialState_PARITY
00486 | CDCSerialState_FRAMING
00487 | CDCSerialState_RINGSIGNAL
00488 | CDCSerialState_BREAK);
00489 }
00490 }
00491
00492
00493