SAMV71 Xplained Ultra Software Package 1.5

HIDDFunction.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /** \file
00031  *  Implementation of the HIDDFunction class methods.
00032  */
00033 /** \addtogroup usbd_hid
00034  * @{
00035  */
00036 
00037 /*------------------------------------------------------------------------------
00038  *         Headers
00039  *------------------------------------------------------------------------------*/
00040 
00041 #include <HIDDFunction.h>
00042 #include <USBDescriptors.h>
00043 #include <HIDDescriptors.h>
00044 
00045 #include <USBLib_Trace.h>
00046 
00047 /*------------------------------------------------------------------------------
00048  *         Definitions
00049  *------------------------------------------------------------------------------*/
00050 
00051 /*------------------------------------------------------------------------------
00052  *         Macros
00053  *------------------------------------------------------------------------------*/
00054 
00055 /**
00056  * Get byte pointer
00057  */
00058 #define _PU8(v)  ((uint8_t*)(&(v)))
00059 
00060 /**
00061  * Get word from un-aligned value
00062  */
00063 #define _Word(a) (_PU8(a)[0] + (_PU8(a)[1] << 8))
00064 
00065 /*------------------------------------------------------------------------------
00066  *         Types
00067  *------------------------------------------------------------------------------*/
00068 
00069 /** Parse data extention for descriptor parsing  */
00070 typedef struct _HIDDParseData {
00071     HIDDFunction *pHidd;
00072     USBInterfaceDescriptor *pIfDesc;
00073 } HIDDParseData;
00074 
00075 /** Parse data extension for HID descriptor */
00076 
00077 /*------------------------------------------------------------------------------
00078  *         Internal variables
00079  *------------------------------------------------------------------------------*/
00080 
00081 /*------------------------------------------------------------------------------
00082  *         Internal functions
00083  *------------------------------------------------------------------------------*/
00084 
00085 /**
00086  *  Returns the descriptor requested by the host.
00087  * \param pHidd   Pointer to HIDDFunction instance
00088  * \param bType   Descriptor type.
00089  * \param wLength Maximum number of bytes to send.
00090  * \return USBRC_SUCCESS if the request has been handled by this function,
00091  *         otherwise USBRC_PARAM_ERR.
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         /* Adjust length and send report descriptor */
00107 
00108         //wDescriptorLength = pHidDescriptor->wDescriptorLength0;
00109         //wDescriptorLength = _Word(&pHidDescriptor->wDescriptorLength0);
00110         //wDescriptorLength = _Word(pHidDescriptor->bDescriptorLength0);
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         /* Adjust length and send HID descriptor */
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  * Return expected report header pointer.
00142  * \param pHidd Pointer to HIDDFunction instance
00143  * \param bType Report type.
00144  * \param bID   Report ID.
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     /* No other reports supported */
00165     default:
00166         TRACE_INFO("Report %x.%x not support\n\r", bType, bID);
00167         return 0;
00168     }
00169 
00170     /* No list */
00171     if (pReportList == 0)
00172         return 0;
00173 
00174     /* Find report in the list */
00175     for (i = 0; i < listSize; i ++) {
00176         if (bID == pReportList[i]->bID)
00177             return pReportList[i];
00178     }
00179 
00180     /* Not found */
00181     return 0;
00182 }
00183 
00184 /**
00185  * Sends the current Idle rate of the input report to the host.
00186  * \param pHidd Pointer to HIDDFunction instance
00187  * \param bID   Report ID
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  * Retrieves the new idle rate of the input report from the USB host.
00207  * \param pHidd     Pointer to HIDDFunction instance
00208  * \param bType     Report type
00209  * \param bID       Report ID
00210  * \param bIdleRate Report idle rate.
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  * Callback function when GetReport request data sent to host
00232  * \param pReport Pointer to report information.
00233  * \param status  Result status
00234  * \param transferred Number of bytes transferred
00235  * \param remaining Number of bytes that are not transferred yet
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  * Sends the requested report to the host.
00253  * \param pHidd   Pointer to HIDDFunction instance
00254  * \param bType   Report type.
00255  * \param bID     Report ID.
00256  * \param wLength Maximum number of bytes to send.
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  * Callback function when GetReport request data sent to host
00282  * \param pReport Pointer to report information.
00283  * \param status  Result status
00284  * \param transferred Number of bytes transferred
00285  * \param remaining Number of bytes that are not transferred yet
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  * Reads the requested report from the host.
00301  * \param pHidd   Pointer to HIDDFunction instance
00302  * \param bType   Report type.
00303  * \param bID     Report ID.
00304  * \param wLength Maximum number of bytes to read.
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  * Parse descriptors: Interface, Interrupt IN/OUT.
00330  * \param desc Pointer to descriptor list.
00331  * \param arg  Argument, pointer to HIDDParseData instance.
00332  */
00333 static uint32_t HIDDFunction_Parse(USBGenericDescriptor *pDesc,
00334                                    HIDDParseData *pArg)
00335 {
00336     /* Find HID Interface */
00337     if (pArg->pIfDesc == 0) {
00338         if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00339             USBInterfaceDescriptor *pIf = (USBInterfaceDescriptor *)pDesc;
00340 
00341             /* Right interface for HID:
00342                    HID Class + at least 1 endpoint */
00343             if (pIf->bInterfaceClass == HIDInterfaceDescriptor_CLASS
00344                 && pIf->bNumEndpoints >= 1) {
00345                 /* Obtain new interface setting */
00346                 if (pArg->pHidd->bInterface == 0xFF) {
00347                     pArg->pHidd->bInterface = pIf->bInterfaceNumber;
00348                     pArg->pIfDesc = pIf;
00349                 }
00350                 /* Find specific interface setting */
00351                 else if (pArg->pHidd->bInterface == pIf->bInterfaceNumber)
00352                     pArg->pIfDesc = pIf;
00353             }
00354         }
00355     }
00356     /* Interface end */
00357     else {
00358         /* Start another interface ? */
00359         if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00360             /* Terminate the parse */
00361             return USBRC_PARTIAL_DONE;
00362         }
00363         /* Parse HID descriptor */
00364         else if (pDesc->bDescriptorType == HIDGenericDescriptor_HID)
00365             pArg->pHidd->pHidDescriptor = (HIDDescriptor *)pDesc;
00366         /* Parse endpoints */
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         /* Check if all data is OK */
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  * Callback function when interrupt OUT data received from host
00388  * \param pHidd  Pointer to HIDDFunction instance
00389  * \param status Result status
00390  * \param transferred Number of bytes transferred
00391  * \param remaining Number of bytes that are not transferred yet
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     /* Transfered information */
00408     pOut->wTransferred = transferred;
00409 
00410     /* Data Change callback */
00411     if (pOut->fCallback)
00412         pOut->fCallback(HIDD_EC_REPORTCHANGED, pOut->pArg);
00413 
00414     /* Proceed to next output report */
00415     pHidd->bCurrOutput ++;
00416 
00417     if (pHidd->bCurrOutput >= pHidd->bOutputListSize)
00418         pHidd->bCurrOutput = 0;
00419 
00420     /* Start reading a report */
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  * Callback function when interrupt IN data sent to host
00430  * \param pHidd  Pointer to HIDDFunction instance
00431  * \param status Result status
00432  * \param transferred Number of bytes transferred
00433  * \param remaining Number of bytes that are not transferred yet
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     /* Transfered information */
00450     pIn->wTransferred = transferred;
00451 
00452     /* Report Sent Callback */
00453     if (pIn->fCallback)
00454         pIn->fCallback(HIDD_EC_REPORTSENT, pIn->pArg);
00455 
00456     /* Proceed to next output report */
00457     pHidd->bCurrInput ++;
00458 
00459     if (pHidd->bCurrInput >= pHidd->bInputListSize)
00460         pHidd->bCurrInput = 0;
00461 
00462     /* Start writing a report */
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  *         Exported functions
00473  *------------------------------------------------------------------------------*/
00474 
00475 /**
00476  * Initialize the USB Device HID function, for general HID device support.
00477  * \param pHidd             Pointer to HIDDFunction instance.
00478  * \param pUsbd             Pointer to USBDDriver instance.
00479  * \param bInterfaceNb      Interface number,
00480  *                          can be 0xFF to obtain from descriptors.
00481  * \param pReportDescriptor Pointer to report descriptor.
00482  * \param pInputList        Pointer to an HID input report list
00483  * \param bInputListSize    HID input report list size
00484  * \param pOutputList       Pointer to an HID output report list
00485  * \param bOutputListSize   HID output report list size
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;    /* Non-boot protocol */
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  * Parse the USB HID Function Interface.
00515  * Only first interface and its endpoints parsed.
00516  * \param pHidd Pointer to HIDDFunction instance.
00517  * \param pDescriptors Pointer to descriptor list.
00518  * \param dwLength     Descriptor list block length in bytes.
00519  * \return Pointer to next descriptor. 0 means no other descriptor.
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  * Start polling interrupt OUT pipe
00538  * (output report, host to device) if there is.
00539  * \param pHidd Pointer to HIDDFunction instance.
00540  */
00541 uint32_t HIDDFunction_StartPollingOutputs(HIDDFunction *pHidd)
00542 {
00543     /* No report, do nothing */
00544     if (pHidd->bOutputListSize == 0
00545         || pHidd->pOutputList == 0)
00546         return USBRC_PARAM_ERR;
00547 
00548     /* Start reading a report */
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  * Start sending reports via interrupt IN pipe
00558  * (input report, device to host) if there is.
00559  * \param pHidd Pointer to HIDDFunction instance.
00560  */
00561 uint32_t HIDDFunction_StartSendingInputs(HIDDFunction *pHidd)
00562 {
00563     /* No report, do nothing */
00564     if (pHidd->bInputListSize == 0
00565         || pHidd->pInputList == 0)
00566         return USBRC_PARAM_ERR;
00567 
00568     /* Start sending a report */
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  * Handles HID-specific SETUP request sent by the host.
00578  * \param pHidd Pointer to HIDDFunction instance.
00579  * \param request Pointer to a USBGenericRequest instance
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     /* Get_Descriptor */
00589     case USBGenericRequest_GETDESCRIPTOR|(0x81<<8):
00590         return HIDDFunction_GetDescriptor(
00591                    pHidd,
00592                    USBGetDescriptorRequest_GetDescriptorType(request),
00593                    USBGenericRequest_GetLength(request));
00594 
00595     /* Clear_Feature (EP) */
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                 /* Unhalt EP */
00603                 USBD_Unhalt(ep);
00604 
00605                 /* Restart Polling OUT */
00606                 if (ep == pHidd->bPipeOUT)
00607                     HIDDFunction_StartPollingOutputs(pHidd);
00608 
00609                 /* and send a zero-length packet */
00610                 USBD_Write(0, 0, 0, 0, 0);
00611             }
00612 
00613             break; /* Handled success */
00614         }
00615 
00616         return USBRC_PARAM_ERR;
00617 
00618     /* Set_Descriptor */
00619     case USBGenericRequest_SETDESCRIPTOR|(0x01<<8):
00620         /* Optional, not implemented */
00621         USBD_Stall(0);
00622         break;
00623 
00624     /* Get_Idle */
00625     case (0xa1<<8)|HIDGenericRequest_GETIDLE:
00626         HIDDFunction_GetIdle(pHidd,
00627                              HIDReportRequest_GetReportId(request));
00628         break;
00629 
00630     /* Set_Idle */
00631     case (0x21<<8)|HIDGenericRequest_SETIDLE:
00632         HIDDFunction_SetIdle(pHidd,
00633                              HIDReportRequest_GetReportId(request),
00634                              HIDIdleRequest_GetIdleRate(request));
00635         break;
00636 
00637     /* Get_Report */
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     /* Set_Report */
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     /* Get_Protocol */
00654     case (0xa1<<8)|HIDGenericRequest_SETPROTOCOL:
00655         pHidd->bProtocol = request->wValue;
00656         USBD_Write(0, 0, 0, 0, 0);
00657         break;
00658 
00659     /* Set_Protocol */
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  * Read raw data through USB interrupt OUT EP.
00673  * \param pHidd     Pointer to HIDDFunction instance.
00674  * \param pData     Pointer to the data buffer.
00675  * \param dwLength  The data length.
00676  * \param fCallback Callback function invoked when transferring done.
00677  * \param pArg Pointer to additional arguments.
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  * Write raw data through USB interrupt IN EP.
00692  * \param pHidd     Pointer to HIDDFunction instance.
00693  * \param pData     Pointer to the data sent.
00694  * \param dwLength  The data length.
00695  * \param fCallback Callback function invoked when transferring done.
00696  * \param pArg Pointer to additional arguments.
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  * Initialize a report.
00711  * \param pReport   Pointer to HIDDReport instance.
00712  * \param wSize     Size of the report data.
00713  * \param bID       Report ID.
00714  * \param fCallback Callback function for report events.
00715  * \param pArg      Pointer to event handler arguments.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines