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