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