SAMV71 Xplained Ultra Software Package 1.3

HIDDFunction.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         ATMEL Microcontroller Software Support
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2010, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
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             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             /* Adjust length and send HID descriptor */
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  * Return expected report header pointer.
00141  * \param pHidd Pointer to HIDDFunction instance
00142  * \param bType Report type.
00143  * \param bID   Report ID.
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     /* No other reports supported */
00161     default:
00162         TRACE_INFO("Report %x.%x not support\n\r", bType, bID);
00163         return 0;
00164     }
00165     /* No list */
00166     if (pReportList == 0)
00167         return 0;
00168     /* Find report in the list */
00169     for (i = 0; i < listSize; i ++) {
00170         if (bID == pReportList[i]->bID)
00171             return pReportList[i];
00172     }
00173     /* Not found */
00174     return 0;
00175 }
00176 
00177 /**
00178  * Sends the current Idle rate of the input report to the host.
00179  * \param pHidd Pointer to HIDDFunction instance
00180  * \param bID   Report ID
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  * Retrieves the new idle rate of the input report from the USB host.
00198  * \param pHidd     Pointer to HIDDFunction instance
00199  * \param bType     Report type
00200  * \param bID       Report ID
00201  * \param bIdleRate Report idle rate.
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  * Callback function when GetReport request data sent to host
00221  * \param pReport Pointer to report information.
00222  * \param status  Result status
00223  * \param transferred Number of bytes transferred
00224  * \param remaining Number of bytes that are not transferred yet
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  * Sends the requested report to the host.
00241  * \param pHidd   Pointer to HIDDFunction instance
00242  * \param bType   Report type.
00243  * \param bID     Report ID.
00244  * \param wLength Maximum number of bytes to send.
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  * Callback function when GetReport request data sent to host
00268  * \param pReport Pointer to report information.
00269  * \param status  Result status
00270  * \param transferred Number of bytes transferred
00271  * \param remaining Number of bytes that are not transferred yet
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  * Reads the requested report from the host.
00287  * \param pHidd   Pointer to HIDDFunction instance
00288  * \param bType   Report type.
00289  * \param bID     Report ID.
00290  * \param wLength Maximum number of bytes to read.
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  * Parse descriptors: Interface, Interrupt IN/OUT.
00316  * \param desc Pointer to descriptor list.
00317  * \param arg  Argument, pointer to HIDDParseData instance.
00318  */
00319 static uint32_t HIDDFunction_Parse(USBGenericDescriptor * pDesc,
00320                                    HIDDParseData * pArg)
00321 {
00322     /* Find HID Interface */
00323     if (pArg->pIfDesc == 0) {
00324         if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00325             USBInterfaceDescriptor *pIf = (USBInterfaceDescriptor*)pDesc;
00326             /* Right interface for HID:
00327                    HID Class + at least 1 endpoint */
00328             if (pIf->bInterfaceClass == HIDInterfaceDescriptor_CLASS
00329                 && pIf->bNumEndpoints >= 1) {
00330                 /* Obtain new interface setting */
00331                 if (pArg->pHidd->bInterface == 0xFF) {
00332                     pArg->pHidd->bInterface = pIf->bInterfaceNumber;
00333                     pArg->pIfDesc = pIf;
00334                 }
00335                 /* Find specific interface setting */
00336                 else if (pArg->pHidd->bInterface == pIf->bInterfaceNumber) {
00337                     pArg->pIfDesc = pIf;
00338                 }
00339             }
00340         }
00341     }
00342     /* Interface end */
00343     else {
00344         /* Start another interface ? */
00345         if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00346             /* Terminate the parse */
00347             return USBRC_PARTIAL_DONE;
00348         }
00349         /* Parse HID descriptor */
00350         else if (pDesc->bDescriptorType == HIDGenericDescriptor_HID) {
00351             pArg->pHidd->pHidDescriptor = (HIDDescriptor*)pDesc;
00352         }
00353         /* Parse endpoints */
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         /* Check if all data is OK */
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  * Callback function when interrupt OUT data received from host
00373  * \param pHidd  Pointer to HIDDFunction instance
00374  * \param status Result status
00375  * \param transferred Number of bytes transferred
00376  * \param remaining Number of bytes that are not transferred yet
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     /* Transfered information */
00392     pOut->wTransferred = transferred;
00393 
00394     /* Data Change callback */
00395     if (pOut->fCallback)
00396         pOut->fCallback(HIDD_EC_REPORTCHANGED, pOut->pArg);
00397 
00398     /* Proceed to next output report */
00399     pHidd->bCurrOutput ++;
00400     if (pHidd->bCurrOutput >= pHidd->bOutputListSize)
00401         pHidd->bCurrOutput = 0;
00402 
00403     /* Start reading a report */
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  * Callback function when interrupt IN data sent to host
00413  * \param pHidd  Pointer to HIDDFunction instance
00414  * \param status Result status
00415  * \param transferred Number of bytes transferred
00416  * \param remaining Number of bytes that are not transferred yet
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     /* Transfered information */
00432     pIn->wTransferred = transferred;
00433 
00434     /* Report Sent Callback */
00435     if (pIn->fCallback)
00436         pIn->fCallback(HIDD_EC_REPORTSENT, pIn->pArg);
00437 
00438     /* Proceed to next output report */
00439     pHidd->bCurrInput ++;
00440     if (pHidd->bCurrInput >= pHidd->bInputListSize)
00441         pHidd->bCurrInput = 0;
00442 
00443     /* Start writing a report */
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  *         Exported functions
00454  *------------------------------------------------------------------------------*/
00455 
00456 /**
00457  * Initialize the USB Device HID function, for general HID device support.
00458  * \param pHidd             Pointer to HIDDFunction instance.
00459  * \param pUsbd             Pointer to USBDDriver instance.
00460  * \param bInterfaceNb      Interface number,
00461  *                          can be 0xFF to obtain from descriptors.
00462  * \param pReportDescriptor Pointer to report descriptor.
00463  * \param pInputList        Pointer to an HID input report list
00464  * \param bInputListSize    HID input report list size
00465  * \param pOutputList       Pointer to an HID output report list
00466  * \param bOutputListSize   HID output report list size
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;    /* Non-boot protocol */
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  * Parse the USB HID Function Interface.
00496  * Only first interface and its endpoints parsed.
00497  * \param pHidd Pointer to HIDDFunction instance.
00498  * \param pDescriptors Pointer to descriptor list.
00499  * \param dwLength     Descriptor list block length in bytes.
00500  * \return Pointer to next descriptor. 0 means no other descriptor.
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  * Start polling interrupt OUT pipe
00519  * (output report, host to device) if there is.
00520  * \param pHidd Pointer to HIDDFunction instance.
00521  */
00522 uint32_t HIDDFunction_StartPollingOutputs(HIDDFunction * pHidd)
00523 {
00524     /* No report, do nothing */
00525     if (pHidd->bOutputListSize == 0
00526         || pHidd->pOutputList == 0)
00527         return USBRC_PARAM_ERR;
00528 
00529     /* Start reading a report */
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  * Start sending reports via interrupt IN pipe
00539  * (input report, device to host) if there is.
00540  * \param pHidd Pointer to HIDDFunction instance.
00541  */
00542 uint32_t HIDDFunction_StartSendingInputs(HIDDFunction * pHidd)
00543 {
00544     /* No report, do nothing */
00545     if (pHidd->bInputListSize == 0
00546         || pHidd->pInputList == 0)
00547         return USBRC_PARAM_ERR;
00548     /* Start sending a report */
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  * Handles HID-specific SETUP request sent by the host.
00558  * \param pHidd Pointer to HIDDFunction instance.
00559  * \param request Pointer to a USBGenericRequest instance
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     /* Get_Descriptor */
00569     case USBGenericRequest_GETDESCRIPTOR|(0x81<<8):
00570         return HIDDFunction_GetDescriptor(
00571                     pHidd,
00572                     USBGetDescriptorRequest_GetDescriptorType(request),
00573                     USBGenericRequest_GetLength(request));
00574     /* Clear_Feature (EP) */
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                 /* Unhalt EP */
00581                 USBD_Unhalt(ep);
00582                 /* Restart Polling OUT */
00583                 if (ep == pHidd->bPipeOUT) {
00584                     HIDDFunction_StartPollingOutputs(pHidd);
00585                 }
00586                 /* and send a zero-length packet */
00587                 USBD_Write(0, 0, 0, 0, 0);
00588             }
00589             break; /* Handled success */
00590         }
00591         return USBRC_PARAM_ERR;
00592     /* Set_Descriptor */
00593     case USBGenericRequest_SETDESCRIPTOR|(0x01<<8):
00594         /* Optional, not implemented */
00595         USBD_Stall(0);
00596         break;
00597     /* Get_Idle */
00598     case (0xa1<<8)|HIDGenericRequest_GETIDLE:
00599         HIDDFunction_GetIdle(pHidd,
00600                              HIDReportRequest_GetReportId(request));
00601         break;
00602     /* Set_Idle */
00603     case (0x21<<8)|HIDGenericRequest_SETIDLE:
00604         HIDDFunction_SetIdle(pHidd,
00605                              HIDReportRequest_GetReportId(request),
00606                              HIDIdleRequest_GetIdleRate(request));
00607         break;
00608     /* Get_Report */
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     /* Set_Report */
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     /* Get_Protocol */
00623     case (0xa1<<8)|HIDGenericRequest_SETPROTOCOL:
00624         pHidd->bProtocol = request->wValue;
00625         USBD_Write(0, 0, 0, 0, 0);
00626         break;
00627     /* Set_Protocol */
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  * Read raw data through USB interrupt OUT EP.
00640  * \param pHidd     Pointer to HIDDFunction instance.
00641  * \param pData     Pointer to the data buffer.
00642  * \param dwLength  The data length.
00643  * \param fCallback Callback function invoked when transferring done.
00644  * \param pArg Pointer to additional arguments.
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  * Write raw data through USB interrupt IN EP.
00659  * \param pHidd     Pointer to HIDDFunction instance.
00660  * \param pData     Pointer to the data sent.
00661  * \param dwLength  The data length.
00662  * \param fCallback Callback function invoked when transferring done.
00663  * \param pArg Pointer to additional arguments.
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  * Initialize a report.
00678  * \param pReport   Pointer to HIDDReport instance.
00679  * \param wSize     Size of the report data.
00680  * \param bID       Report ID.
00681  * \param fCallback Callback function for report events.
00682  * \param pArg      Pointer to event handler arguments.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines