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 #include <HIDDFunction.h>
00042 #include <USBDescriptors.h>
00043 #include <HIDDescriptors.h>
00044
00045 #include <USBLib_Trace.h>
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #define _PU8(v) ((uint8_t*)(&(v)))
00059
00060
00061
00062
00063 #define _Word(a) (_PU8(a)[0] + (_PU8(a)[1] << 8))
00064
00065
00066
00067
00068
00069
00070 typedef struct _HIDDParseData {
00071 HIDDFunction *pHidd;
00072 USBInterfaceDescriptor *pIfDesc;
00073 } HIDDParseData;
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 static uint32_t HIDDFunction_GetDescriptor(HIDDFunction *pHidd,
00094 uint8_t bType,
00095 uint32_t wLength)
00096 {
00097 HIDDescriptor1 *pHidDescriptor = (HIDDescriptor1 *)pHidd->pHidDescriptor;
00098 uint16_t wDescriptorLength;
00099
00100 TRACE_INFO_WP("gDesc{%x) ", bType);
00101
00102 switch (bType) {
00103
00104 case HIDGenericDescriptor_REPORT:
00105
00106
00107
00108
00109
00110
00111 wDescriptorLength = (pHidDescriptor->bDescriptorLength0[0] )
00112 + (pHidDescriptor->bDescriptorLength0[1] << 8);
00113
00114 if (wLength > wDescriptorLength)
00115 wLength = wDescriptorLength;
00116
00117 TRACE_INFO_WP("Report(%d) ", (int)wLength);
00118
00119 USBD_Write(0, pHidd->pReportDescriptor, wLength, 0, 0);
00120 break;
00121
00122 case HIDGenericDescriptor_HID:
00123
00124
00125 if (wLength > sizeof(HIDDescriptor1))
00126 wLength = sizeof(HIDDescriptor1);
00127
00128 TRACE_INFO_WP("HID(%d) ", (int)wLength);
00129
00130 USBD_Write(0, pHidDescriptor, wLength, 0, 0);
00131 break;
00132
00133 default:
00134 return USBRC_PARAM_ERR;
00135 }
00136
00137 return USBRC_SUCCESS;
00138 }
00139
00140
00141
00142
00143
00144
00145
00146 static HIDDReport *HIDDFunction_FindReport(const HIDDFunction *pHidd,
00147 uint8_t bType,
00148 uint8_t bID)
00149 {
00150 HIDDReport **pReportList;
00151 int32_t listSize, i;
00152
00153 switch (bType) {
00154 case HIDReportRequest_INPUT:
00155 pReportList = pHidd->pInputList;
00156 listSize = pHidd->bInputListSize;
00157 break;
00158
00159 case HIDReportRequest_OUTPUT:
00160 pReportList = pHidd->pOutputList;
00161 listSize = pHidd->bOutputListSize;
00162 break;
00163
00164
00165 default:
00166 TRACE_INFO("Report %x.%x not support\n\r", bType, bID);
00167 return 0;
00168 }
00169
00170
00171 if (pReportList == 0)
00172 return 0;
00173
00174
00175 for (i = 0; i < listSize; i ++) {
00176 if (bID == pReportList[i]->bID)
00177 return pReportList[i];
00178 }
00179
00180
00181 return 0;
00182 }
00183
00184
00185
00186
00187
00188
00189 static void HIDDFunction_GetIdle(HIDDFunction *pHidd,
00190 uint8_t bID)
00191 {
00192 HIDDReport *pReport = HIDDFunction_FindReport(pHidd,
00193 HIDReportRequest_INPUT,
00194 bID);
00195 TRACE_INFO_WP("gIdle(%x) ", bID);
00196
00197 if (pReport == 0) {
00198 USBD_Stall(0);
00199 return;
00200 }
00201
00202 USBD_Write(0, &pReport->bIdleRate, 1, 0, 0);
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212 static void HIDDFunction_SetIdle(HIDDFunction *pHidd,
00213 uint8_t bID,
00214 uint8_t bIdleRate)
00215 {
00216 HIDDReport *pReport = HIDDFunction_FindReport(pHidd,
00217 HIDReportRequest_INPUT,
00218 bID);
00219 bIdleRate = bIdleRate;
00220 TRACE_INFO_WP("sIdle(%x<%x) ", bID, bIdleRate);
00221
00222 if (pReport == 0) {
00223 USBD_Stall(0);
00224 return;
00225 }
00226
00227 USBD_Write(0, 0, 0, 0, 0);
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237 static void _GetReportCallback(HIDDReport *pReport,
00238 uint8_t status,
00239 uint32_t transferred,
00240 uint32_t remaining)
00241 {
00242 status = status; remaining = remaining;
00243 pReport->wTransferred = transferred;
00244
00245 if (pReport->fCallback)
00246 pReport->fCallback(HIDD_EC_GETREPORT, pReport->pArg);
00247
00248 USBD_Read(0, 0, 0, 0, 0);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258 static void HIDDFunction_GetReport(HIDDFunction *pHidd,
00259 uint8_t bType,
00260 uint8_t bID,
00261 uint8_t wLength)
00262 {
00263 HIDDReport *pReport = HIDDFunction_FindReport(pHidd,
00264 bType,
00265 bID);
00266 TRACE_INFO_WP("gReport(%x.%x) ", bType, bID);
00267
00268 if (pReport == 0) {
00269 USBD_Stall(0);
00270 return;
00271 }
00272
00273 if (wLength >= pReport->wMaxSize)
00274 wLength = pReport->wMaxSize;
00275
00276 USBD_Write(0, pReport->bData, wLength,
00277 (TransferCallback)_GetReportCallback, pReport);
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287 static void _SetReportCallback(HIDDReport *pReport,
00288 uint8_t status,
00289 uint32_t transferred,
00290 uint32_t remaining)
00291 {
00292 remaining = remaining; status = status;
00293 pReport->wTransferred = transferred;
00294
00295 if (pReport->fCallback)
00296 pReport->fCallback(HIDD_EC_SETREPORT, pReport->pArg);
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306 static void HIDDFunction_SetReport(HIDDFunction *pHidd,
00307 uint8_t bType,
00308 uint8_t bID,
00309 uint8_t wLength)
00310 {
00311 HIDDReport *pReport = HIDDFunction_FindReport(pHidd,
00312 bType,
00313 bID);
00314 TRACE_INFO_WP("sReport(%x.%x) ", bType, bID);
00315
00316 if (pReport == 0) {
00317 USBD_Stall(0);
00318 return;
00319 }
00320
00321 if (wLength >= pReport->wMaxSize)
00322 wLength = pReport->wMaxSize;
00323
00324 USBD_Read(0, pReport->bData, wLength,
00325 (TransferCallback)_SetReportCallback, pReport);
00326 }
00327
00328
00329
00330
00331
00332
00333 static uint32_t HIDDFunction_Parse(USBGenericDescriptor *pDesc,
00334 HIDDParseData *pArg)
00335 {
00336
00337 if (pArg->pIfDesc == 0) {
00338 if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00339 USBInterfaceDescriptor *pIf = (USBInterfaceDescriptor *)pDesc;
00340
00341
00342
00343 if (pIf->bInterfaceClass == HIDInterfaceDescriptor_CLASS
00344 && pIf->bNumEndpoints >= 1) {
00345
00346 if (pArg->pHidd->bInterface == 0xFF) {
00347 pArg->pHidd->bInterface = pIf->bInterfaceNumber;
00348 pArg->pIfDesc = pIf;
00349 }
00350
00351 else if (pArg->pHidd->bInterface == pIf->bInterfaceNumber)
00352 pArg->pIfDesc = pIf;
00353 }
00354 }
00355 }
00356
00357 else {
00358
00359 if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00360
00361 return USBRC_PARTIAL_DONE;
00362 }
00363
00364 else if (pDesc->bDescriptorType == HIDGenericDescriptor_HID)
00365 pArg->pHidd->pHidDescriptor = (HIDDescriptor *)pDesc;
00366
00367 else if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT) {
00368 USBEndpointDescriptor *pEp = (USBEndpointDescriptor *)pDesc;
00369
00370 if (pEp->bEndpointAddress & 0x80)
00371 pArg->pHidd->bPipeIN = pEp->bEndpointAddress & 0x7F;
00372 else
00373 pArg->pHidd->bPipeOUT = pEp->bEndpointAddress;
00374 }
00375
00376
00377 if (pArg->pHidd->bInterface != 0xFF
00378 && pArg->pHidd->bPipeIN != 0xFF
00379 && pArg->pHidd->bPipeOUT != 0xFF)
00380 return USBRC_FINISHED;
00381 }
00382
00383 return 0;
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393 static void HIDDFunction_ReportReceived(HIDDFunction *pHidd,
00394 uint8_t status,
00395 uint32_t transferred,
00396 uint32_t remaining)
00397 {
00398 HIDDReport *pOut = pHidd->pOutputList[pHidd->bCurrOutput];
00399 remaining = remaining;
00400
00401 if (status != USBRC_SUCCESS) {
00402
00403 TRACE_ERROR("HIDDFun::ReadReport: %x\n\r", status);
00404 return;
00405 }
00406
00407
00408 pOut->wTransferred = transferred;
00409
00410
00411 if (pOut->fCallback)
00412 pOut->fCallback(HIDD_EC_REPORTCHANGED, pOut->pArg);
00413
00414
00415 pHidd->bCurrOutput ++;
00416
00417 if (pHidd->bCurrOutput >= pHidd->bOutputListSize)
00418 pHidd->bCurrOutput = 0;
00419
00420
00421 USBD_Read(pHidd->bPipeOUT,
00422 pHidd->pOutputList[pHidd->bCurrOutput]->bData,
00423 pHidd->pOutputList[pHidd->bCurrOutput]->wMaxSize,
00424 (TransferCallback)HIDDFunction_ReportReceived,
00425 (void *)pHidd);
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435 static void HIDDFunction_ReportSent(HIDDFunction *pHidd,
00436 uint8_t status,
00437 uint32_t transferred,
00438 uint32_t remaining)
00439 {
00440 HIDDReport *pIn = pHidd->pInputList[pHidd->bCurrInput];
00441 remaining = remaining;
00442
00443 if (status != USBRC_SUCCESS) {
00444
00445 TRACE_ERROR("HIDDFun::WriteReport: %x\n\r", status);
00446 return;
00447 }
00448
00449
00450 pIn->wTransferred = transferred;
00451
00452
00453 if (pIn->fCallback)
00454 pIn->fCallback(HIDD_EC_REPORTSENT, pIn->pArg);
00455
00456
00457 pHidd->bCurrInput ++;
00458
00459 if (pHidd->bCurrInput >= pHidd->bInputListSize)
00460 pHidd->bCurrInput = 0;
00461
00462
00463 USBD_Write(pHidd->bPipeIN,
00464 pHidd->pInputList[pHidd->bCurrInput]->bData,
00465 pHidd->pInputList[pHidd->bCurrInput]->wMaxSize,
00466 (TransferCallback)HIDDFunction_ReportReceived,
00467 (void *)pHidd);
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 void HIDDFunction_Initialize(HIDDFunction *pHidd,
00488 USBDDriver *pUsbd, uint8_t bInterfaceNb,
00489 const uint8_t *pReportDescriptor,
00490 HIDDReport *pInputList[], uint8_t bInputListSize,
00491 HIDDReport *pOutputList[], uint8_t bOutputListSize)
00492 {
00493 TRACE_INFO("HIDDFunction_Initialize\n\r");
00494
00495 pHidd->pUsbd = pUsbd;
00496 pHidd->pReportDescriptor = (uint8_t *)pReportDescriptor;
00497 pHidd->pHidDescriptor = 0;
00498
00499 pHidd->bInterface = bInterfaceNb;
00500 pHidd->bPipeIN = 0xFF;
00501 pHidd->bPipeOUT = 0xFF;
00502 pHidd->bProtocol = HIDProtocol_REPORT;
00503
00504 pHidd->pInputList = pInputList;
00505 pHidd->pOutputList = pOutputList;
00506 pHidd->bInputListSize = bInputListSize;
00507 pHidd->bOutputListSize = bOutputListSize;
00508 pHidd->bCurrInput = 0;
00509 pHidd->bCurrOutput = 0;
00510
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 USBGenericDescriptor *HIDDFunction_ParseInterface(HIDDFunction *pHidd,
00522 USBGenericDescriptor *pDescriptors,
00523 uint32_t dwLength)
00524 {
00525 HIDDParseData data;
00526 pHidd->bPipeIN = 0xFF;
00527 pHidd->bPipeOUT = 0xFF;
00528 data.pHidd = pHidd;
00529 data.pIfDesc = 0;
00530 return USBGenericDescriptor_Parse(pDescriptors,
00531 dwLength,
00532 (USBDescriptorParseFunction)HIDDFunction_Parse,
00533 (void *)&data);
00534 }
00535
00536
00537
00538
00539
00540
00541 uint32_t HIDDFunction_StartPollingOutputs(HIDDFunction *pHidd)
00542 {
00543
00544 if (pHidd->bOutputListSize == 0
00545 || pHidd->pOutputList == 0)
00546 return USBRC_PARAM_ERR;
00547
00548
00549 return USBD_Read(pHidd->bPipeOUT,
00550 pHidd->pOutputList[pHidd->bCurrOutput]->bData,
00551 pHidd->pOutputList[pHidd->bCurrOutput]->wMaxSize,
00552 (TransferCallback)HIDDFunction_ReportReceived,
00553 (void *)pHidd);
00554 }
00555
00556
00557
00558
00559
00560
00561 uint32_t HIDDFunction_StartSendingInputs(HIDDFunction *pHidd)
00562 {
00563
00564 if (pHidd->bInputListSize == 0
00565 || pHidd->pInputList == 0)
00566 return USBRC_PARAM_ERR;
00567
00568
00569 return USBD_Write(pHidd->bPipeIN,
00570 pHidd->pInputList[pHidd->bCurrInput]->bData,
00571 pHidd->pInputList[pHidd->bCurrInput]->wMaxSize,
00572 (TransferCallback)HIDDFunction_ReportSent,
00573 (void *)pHidd);
00574 }
00575
00576
00577
00578
00579
00580
00581 uint32_t HIDDFunction_RequestHandler(HIDDFunction *pHidd,
00582 const USBGenericRequest *request)
00583 {
00584 uint32_t reqCode = (request->bmRequestType << 8)
00585 | (request->bRequest);
00586
00587 switch (reqCode) {
00588
00589 case USBGenericRequest_GETDESCRIPTOR|(0x81<<8):
00590 return HIDDFunction_GetDescriptor(
00591 pHidd,
00592 USBGetDescriptorRequest_GetDescriptorType(request),
00593 USBGenericRequest_GetLength(request));
00594
00595
00596 case USBGenericRequest_CLEARFEATURE|(0x02<<8):
00597 if (USBFeatureRequest_GetFeatureSelector(request)
00598 == USBFeatureRequest_ENDPOINTHALT) {
00599 uint8_t ep = USBGenericRequest_GetEndpointNumber(request);
00600
00601 if (USBD_IsHalted(ep)) {
00602
00603 USBD_Unhalt(ep);
00604
00605
00606 if (ep == pHidd->bPipeOUT)
00607 HIDDFunction_StartPollingOutputs(pHidd);
00608
00609
00610 USBD_Write(0, 0, 0, 0, 0);
00611 }
00612
00613 break;
00614 }
00615
00616 return USBRC_PARAM_ERR;
00617
00618
00619 case USBGenericRequest_SETDESCRIPTOR|(0x01<<8):
00620
00621 USBD_Stall(0);
00622 break;
00623
00624
00625 case (0xa1<<8)|HIDGenericRequest_GETIDLE:
00626 HIDDFunction_GetIdle(pHidd,
00627 HIDReportRequest_GetReportId(request));
00628 break;
00629
00630
00631 case (0x21<<8)|HIDGenericRequest_SETIDLE:
00632 HIDDFunction_SetIdle(pHidd,
00633 HIDReportRequest_GetReportId(request),
00634 HIDIdleRequest_GetIdleRate(request));
00635 break;
00636
00637
00638 case (0xa1<<8)|HIDGenericRequest_GETREPORT:
00639 HIDDFunction_GetReport(pHidd,
00640 HIDReportRequest_GetReportType(request),
00641 HIDReportRequest_GetReportId(request),
00642 USBGenericRequest_GetLength(request));
00643 break;
00644
00645
00646 case (0x21<<8)|HIDGenericRequest_SETREPORT:
00647 HIDDFunction_SetReport(pHidd,
00648 HIDReportRequest_GetReportType(request),
00649 HIDReportRequest_GetReportId(request),
00650 USBGenericRequest_GetLength(request));
00651 break;
00652
00653
00654 case (0xa1<<8)|HIDGenericRequest_SETPROTOCOL:
00655 pHidd->bProtocol = request->wValue;
00656 USBD_Write(0, 0, 0, 0, 0);
00657 break;
00658
00659
00660 case (0x21<<8)|HIDGenericRequest_GETPROTOCOL:
00661 USBD_Write(0, &pHidd->bProtocol, 1, 0, 0);
00662 break;
00663
00664 default:
00665 return USBRC_PARAM_ERR;
00666 }
00667
00668 return USBRC_SUCCESS;
00669 }
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679 uint32_t HIDDFunction_Read(const HIDDFunction *pHidd,
00680 void *pData,
00681 uint32_t dwLength,
00682 TransferCallback fCallback,
00683 void *pArg)
00684 {
00685 return USBD_Read(pHidd->bPipeIN,
00686 pData, dwLength,
00687 fCallback, pArg);
00688 }
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 uint32_t HIDDFunction_Write(const HIDDFunction *pHidd,
00699 void *pData,
00700 uint32_t dwLength,
00701 TransferCallback fCallback,
00702 void *pArg)
00703 {
00704 return USBD_Write(pHidd->bPipeIN,
00705 pData, dwLength,
00706 fCallback, pArg);
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 void HIDDFunction_InitializeReport(HIDDReport *pReport,
00718 uint16_t wSize,
00719 uint8_t bID,
00720 HIDDReportEventCallback fCallback,
00721 void *pArg)
00722 {
00723 pReport->wMaxSize = wSize;
00724 pReport->wTransferred = 0;
00725 pReport->bIdleRate = 0x7F;
00726 pReport->bDelay = 0;
00727 pReport->bID = bID;
00728
00729 pReport->fCallback = fCallback;
00730 pReport->pArg = pArg;
00731 }
00732
00733
00734