/** ****************************************************************************** * @file usbd_hid.c * @author MCD Application Team * @brief This file provides the HID core functions. * * @verbatim * * =================================================================== * HID Class Description * =================================================================== * This module manages the HID class V1.11 following the "Device Class Definition * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". * This driver implements the following aspects of the specification: * - The Boot Interface Subclass * - The Mouse protocol * - Usage Page : Generic Desktop * - Usage : Joystick * - Collection : Application * * @note In HS mode and when the DMA is used, all variables and data structures * dealing with the DMA during the transaction process should be 32-bit aligned. * * * @endverbatim * ****************************************************************************** * @attention * *

© Copyright (c) 2017 STMicroelectronics International N.V. * All rights reserved.

* * Redistribution and use in source and binary forms, with or without * modification, are permitted, provided that the following conditions are met: * * 1. Redistribution of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific written permission. * 4. This software, including modifications and/or derivative works of this * software, must execute solely and exclusively on microcontroller or * microprocessor devices manufactured by or for STMicroelectronics. * 5. Redistribution and use of this software other than as permitted under * this license is void and will automatically terminate your rights under * this license. * * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* BSPDependencies - "stm32xxxxx_{eval}{discovery}{nucleo_144}.c" - "stm32xxxxx_{eval}{discovery}_io.c" EndBSPDependencies */ /* Includes ------------------------------------------------------------------*/ #include "usbd_hid.h" #include "usbd_ctlreq.h" /** @addtogroup STM32_USB_DEVICE_LIBRARY * @{ */ /** @defgroup USBD_HID * @brief usbd core module * @{ */ /** @defgroup USBD_HID_Private_TypesDefinitions * @{ */ /** * @} */ /** @defgroup USBD_HID_Private_Defines * @{ */ /** * @} */ /** @defgroup USBD_HID_Private_Macros * @{ */ /** * @} */ /** @defgroup USBD_HID_Private_FunctionPrototypes * @{ */ static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static uint8_t *USBD_HID_GetFSCfgDesc (uint16_t *length); static uint8_t *USBD_HID_GetHSCfgDesc (uint16_t *length); static uint8_t *USBD_HID_GetOtherSpeedCfgDesc (uint16_t *length); static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length); static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_HID_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum); /** * @} */ /** @defgroup USBD_HID_Private_Variables * @{ */ USBD_ClassTypeDef USBD_HID = { USBD_HID_Init, USBD_HID_DeInit, USBD_HID_Setup, NULL, /*EP0_TxSent*/ NULL, /*EP0_RxReady*/ USBD_HID_DataIn, /*DataIn*/ USBD_HID_DataOut, /*DataOut*/ NULL, /*SOF */ NULL, NULL, USBD_HID_GetHSCfgDesc, USBD_HID_GetFSCfgDesc, USBD_HID_GetOtherSpeedCfgDesc, USBD_HID_GetDeviceQualifierDesc, }; #define USBD_HID_CfgHSDesc USBD_HID_OtherSpeedCfgDesc #define USBD_HID_CfgFSDesc USBD_HID_OtherSpeedCfgDesc /* USB HID device FS Configuration Descriptor */ /*__ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =*/ /*{*/ /*0x09, [> bLength: Configuration Descriptor size <]*/ /*USB_DESC_TYPE_CONFIGURATION, [> bDescriptorType: Configuration <]*/ /*USB_HID_CONFIG_DESC_SIZ,*/ /*[> wTotalLength: Bytes returned <]*/ /*0x00,*/ /*0x01, [>bNumInterfaces: 1 interface<]*/ /*0x01, [>bConfigurationValue: Configuration value<]*/ /*0x00, //iConfiguration: Index of string descriptor describing*/ /*//the configuration*/ /*0xE0, [>bmAttributes: bus powered and Support Remote Wake-up <]*/ /*0x32, [>MaxPower 100 mA: this current is used for detecting Vbus<]*/ /*[>************* Descriptor of Joystick Mouse interface ***************<]*/ /*[> 09 <]*/ /*0x09, [>bLength: Interface Descriptor size<]*/ /*USB_DESC_TYPE_INTERFACE,[>bDescriptorType: Interface descriptor type<]*/ /*0x00, [>bInterfaceNumber: Number of Interface<]*/ /*0x00, [>bAlternateSetting: Alternate setting<]*/ /*0x01, [>bNumEndpoints<]*/ /*0x03, [>bInterfaceClass: HID<]*/ /*0x01, [>bInterfaceSubClass : 1=BOOT, 0=no boot<]*/ /*0x02, [>nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse<]*/ /*0, [>iInterface: Index of string descriptor<]*/ /*[>******************* Descriptor of Joystick Mouse HID *******************<]*/ /*[> 18 <]*/ /*0x09, [>bLength: HID Descriptor size<]*/ /*HID_DESCRIPTOR_TYPE, [>bDescriptorType: HID<]*/ /*0x11, [>bcdHID: HID Class Spec release number<]*/ /*0x01,*/ /*0x00, [>bCountryCode: Hardware target country<]*/ /*0x01, [>bNumDescriptors: Number of HID class descriptors to follow<]*/ /*0x22, [>bDescriptorType<]*/ /*HID_MOUSE_REPORT_DESC_SIZE,[>wItemLength: Total length of Report descriptor<]*/ /*0x00,*/ /*[>******************* Descriptor of Mouse endpoint *******************<]*/ /*[> 27 <]*/ /*0x07, [>bLength: Endpoint Descriptor size<]*/ /*USB_DESC_TYPE_ENDPOINT, [>bDescriptorType:<]*/ /*HID_EPIN_ADDR, [>bEndpointAddress: Endpoint Address (IN)<]*/ /*0x03, [>bmAttributes: Interrupt endpoint<]*/ /*HID_EPIN_SIZE, [>wMaxPacketSize: 4 Byte max <]*/ /*0x00,*/ /*HID_FS_BINTERVAL, [>bInterval: Polling Interval <]*/ /*[> 34 <]*/ /*};*/ /* USB HID device HS Configuration Descriptor */ /*__ALIGN_BEGIN static uint8_t USBD_HID_CfgHSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =*/ /*{*/ /*0x09, [> bLength: Configuration Descriptor size <]*/ /*USB_DESC_TYPE_CONFIGURATION, [> bDescriptorType: Configuration <]*/ /*USB_HID_CONFIG_DESC_SIZ,*/ /*[> wTotalLength: Bytes returned <]*/ /*0x00,*/ /*0x01, [>bNumInterfaces: 1 interface<]*/ /*0x01, [>bConfigurationValue: Configuration value<]*/ /*0x00, //iConfiguration: Index of string descriptor describing*/ /*the configuration**/ /*0xE0, [>bmAttributes: bus powered and Support Remote Wake-up <]*/ /*0x32, [>MaxPower 100 mA: this current is used for detecting Vbus<]*/ /*[>************* Descriptor of Joystick Mouse interface ***************<]*/ /*[> 09 <]*/ /*0x09, [>bLength: Interface Descriptor size<]*/ /*USB_DESC_TYPE_INTERFACE,[>bDescriptorType: Interface descriptor type<]*/ /*0x00, [>bInterfaceNumber: Number of Interface<]*/ /*0x00, [>bAlternateSetting: Alternate setting<]*/ /*0x01, [>bNumEndpoints<]*/ /*0x03, [>bInterfaceClass: HID<]*/ /*0x01, [>bInterfaceSubClass : 1=BOOT, 0=no boot<]*/ /*0x02, [>nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse<]*/ /*0, [>iInterface: Index of string descriptor<]*/ /*[>******************* Descriptor of Joystick Mouse HID *******************<]*/ /*[> 18 <]*/ /*0x09, [>bLength: HID Descriptor size<]*/ /*HID_DESCRIPTOR_TYPE, [>bDescriptorType: HID<]*/ /*0x11, [>bcdHID: HID Class Spec release number<]*/ /*0x01,*/ /*0x00, [>bCountryCode: Hardware target country<]*/ /*0x01, [>bNumDescriptors: Number of HID class descriptors to follow<]*/ /*0x22, [>bDescriptorType<]*/ /*HID_MOUSE_REPORT_DESC_SIZE,[>wItemLength: Total length of Report descriptor<]*/ /*0x00,*/ /*[>******************* Descriptor of Mouse endpoint *******************<]*/ /*[> 27 <]*/ /*0x07, [>bLength: Endpoint Descriptor size<]*/ /*USB_DESC_TYPE_ENDPOINT, [>bDescriptorType:<]*/ /*HID_EPIN_ADDR, [>bEndpointAddress: Endpoint Address (IN)<]*/ /*0x03, [>bmAttributes: Interrupt endpoint<]*/ /*HID_EPIN_SIZE, [>wMaxPacketSize: 4 Byte max <]*/ /*0x00,*/ /*HID_HS_BINTERVAL, [>bInterval: Polling Interval <]*/ /*[> 34 <]*/ /*};*/ /* USB HID device Other Speed Configuration Descriptor */ /*__ALIGN_BEGIN static uint8_t USBD_HID_OtherSpeedCfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =*/ /*{*/ /*0x09, [> bLength: Configuration Descriptor size <]*/ /*USB_DESC_TYPE_CONFIGURATION, [> bDescriptorType: Configuration <]*/ /*USB_HID_CONFIG_DESC_SIZ,*/ /*[> wTotalLength: Bytes returned <]*/ /*0x00,*/ /*0x01, [>bNumInterfaces: 1 interface<]*/ /*0x01, [>bConfigurationValue: Configuration value<]*/ /*0x00, //iConfiguration: Index of string descriptor describing*/ /*//the configuration*/ /*0xE0, [>bmAttributes: bus powered and Support Remote Wake-up <]*/ /*0x32, [>MaxPower 100 mA: this current is used for detecting Vbus<]*/ /*[>************* Descriptor of Joystick Mouse interface ***************<]*/ /*[> 09 <]*/ /*0x09, [>bLength: Interface Descriptor size<]*/ /*USB_DESC_TYPE_INTERFACE,[>bDescriptorType: Interface descriptor type<]*/ /*0x00, [>bInterfaceNumber: Number of Interface<]*/ /*0x00, [>bAlternateSetting: Alternate setting<]*/ /*0x01, [>bNumEndpoints<]*/ /*0x03, [>bInterfaceClass: HID<]*/ /*0x01, [>bInterfaceSubClass : 1=BOOT, 0=no boot<]*/ /*0x02, [>nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse<]*/ /*0, [>iInterface: Index of string descriptor<]*/ /*[>******************* Descriptor of Joystick Mouse HID *******************<]*/ /*[> 18 <]*/ /*0x09, [>bLength: HID Descriptor size<]*/ /*HID_DESCRIPTOR_TYPE, [>bDescriptorType: HID<]*/ /*0x11, [>bcdHID: HID Class Spec release number<]*/ /*0x01,*/ /*0x00, [>bCountryCode: Hardware target country<]*/ /*0x01, [>bNumDescriptors: Number of HID class descriptors to follow<]*/ /*0x22, [>bDescriptorType<]*/ /*HID_MOUSE_REPORT_DESC_SIZE,[>wItemLength: Total length of Report descriptor<]*/ /*0x00,*/ /*[>******************* Descriptor of Mouse endpoint *******************<]*/ /*[> 27 <]*/ /*0x07, [>bLength: Endpoint Descriptor size<]*/ /*USB_DESC_TYPE_ENDPOINT, [>bDescriptorType:<]*/ /*HID_EPIN_ADDR, [>bEndpointAddress: Endpoint Address (IN)<]*/ /*0x03, [>bmAttributes: Interrupt endpoint<]*/ /*HID_EPIN_SIZE, [>wMaxPacketSize: 4 Byte max <]*/ /*0x00,*/ /*HID_FS_BINTERVAL, [>bInterval: Polling Interval <]*/ /*[> 34 <]*/ /*};*/ __ALIGN_BEGIN static uint8_t USBD_HID_OtherSpeedCfgDesc[] __ALIGN_END = { 0x09, // bLength USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ 0x29,// wTotalLength(LSB) 0x00,// wTotalLength(MSB) 1,// bNumInterfaces 1,// bConfigurationValue 0,// iConfiguration 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */ 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ //Interface 0 Descriptor 0x09, /*bLength: Interface Descriptor size*/ USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ 0,// bInterfaceNumber 0,// bAlternateSetting 2,// bNumEndpoints 3,// bInterfaceClass: HID (Human Interface Device) 0,// bInterfaceSubClass 0,// bInterfaceProtocol 0,// iInterface //HID Descriptor 0x09, /*bLength: HID Descriptor size*/ HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ 0x11,// bcdHID (LSB) 0x01,// bcdHID (MSB) 0,// bCountryCode 1,// bNumDescriptors 0x22, /*bDescriptorType, HID report type*/ ( 34 ), // wDescriptorLength(LSB) ( 34 )>>8, // wDescriptorLength(MSB) //Endpoint 2 IN Descriptor 7,// bLength USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ HID_EPIN_ADDR,// bEndpointAddress input 0x03,// bAttrib interrupt type HID_PACKET_SIZE,// wMaxPacketSize (LSB) 0x00,// wMaxPacketSize (MSB) HID_FS_BINTERVAL,// bInterval //Endpoint 3 OUT Descriptor 7,// bLength USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ HID_EPOUT_ADDR,// bEndpointAddress output 0x03,// bAttrib, interrupt type HID_PACKET_SIZE,// wMaxPacketSize (LSB) 0x00,// wMaxPacketSize (MSB) HID_FS_BINTERVAL, /*bInterval: Polling Interval */ }; /* USB HID device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = { /* 18 */ 0x09, /*bLength: HID Descriptor size*/ HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ 0x11, /*bcdHID: HID Class Spec release number*/ 0x01, 0x00, /*bCountryCode: Hardware target country*/ 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ 0x22, /*bDescriptorType*/ HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ 0x00, }; /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { USB_LEN_DEV_QUALIFIER_DESC, USB_DESC_TYPE_DEVICE_QUALIFIER, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, }; /*__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =*/ /*{*/ /*0x05, 0x01,*/ /*0x09, 0x02,*/ /*0xA1, 0x01,*/ /*0x09, 0x01,*/ /*0xA1, 0x00,*/ /*0x05, 0x09,*/ /*0x19, 0x01,*/ /*0x29, 0x03,*/ /*0x15, 0x00,*/ /*0x25, 0x01,*/ /*0x95, 0x03,*/ /*0x75, 0x01,*/ /*0x81, 0x02,*/ /*0x95, 0x01,*/ /*0x75, 0x05,*/ /*0x81, 0x01,*/ /*0x05, 0x01,*/ /*0x09, 0x30,*/ /*0x09, 0x31,*/ /*0x09, 0x38,*/ /*0x15, 0x81,*/ /*0x25, 0x7F,*/ /*0x75, 0x08,*/ /*0x95, 0x03,*/ /*0x81, 0x06,*/ /*0xC0, 0x09,*/ /*0x3c, 0x05,*/ /*0xff, 0x09,*/ /*0x01, 0x15,*/ /*0x00, 0x25,*/ /*0x01, 0x75,*/ /*0x01, 0x95,*/ /*0x02, 0xb1,*/ /*0x22, 0x75,*/ /*0x06, 0x95,*/ /*0x01, 0xb1,*/ /*0x01, 0xc0*/ /*};*/ /*__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =*/ /*{*/ /*0x06, 0xd0, 0xf1,// USAGE_PAGE (FIDO Alliance)*/ /*0x09, 0x01,// USAGE (Keyboard)*/ /*0xa1, 0x01,// COLLECTION (Application)*/ /*0x09, 0x20, // USAGE (Input Report Data)*/ /*0x15, 0x00, // LOGICAL_MINIMUM (0)*/ /*0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)*/ /*0x75, 0x08, // REPORT_SIZE (8)*/ /*0x95, HID_PACKET_SIZE, // REPORT_COUNT (64)*/ /*0x81, 0x02, // INPUT (Data,Var,Abs)*/ /*0x09, 0x21, // USAGE(Output Report Data)*/ /*0x15, 0x00, // LOGICAL_MINIMUM (0)*/ /*0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)*/ /*0x75, 0x08, // REPORT_SIZE (8)*/ /*0x95, HID_PACKET_SIZE, // REPORT_COUNT (64)*/ /*0x91, 0x02, // OUTPUT (Data,Var,Abs)*/ /*0xc0,// END_COLLECTION*/ /*};*/ #define _DEBUG() printf("%d\r\n", __LINE__) /** * @} */ /** @defgroup USBD_HID_Private_Functions * @{ */ /** * @brief USBD_HID_Init * Initialize the HID interface * @param pdev: device instance * @param cfgidx: Configuration index * @retval status */ static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { /* Open EP IN */ _DEBUG(); USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE); USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE); pdev->ep_in[HID_EPIN_ADDR & 0xFU].is_used = 1U; pdev->pClassData = USBD_malloc(sizeof (USBD_HID_HandleTypeDef)); if (pdev->pClassData == NULL) { return USBD_FAIL; } ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; return USBD_OK; } /** * @brief USBD_HID_Init * DeInitialize the HID layer * @param pdev: device instance * @param cfgidx: Configuration index * @retval status */ static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { _DEBUG(); /* Close HID EPs */ USBD_LL_CloseEP(pdev, HID_EPIN_ADDR); pdev->ep_in[HID_EPIN_ADDR & 0xFU].is_used = 0U; /* FRee allocated memory */ if(pdev->pClassData != NULL) { USBD_free(pdev->pClassData); pdev->pClassData = NULL; } return USBD_OK; } /** * @brief USBD_HID_Setup * Handle the HID specific requests * @param pdev: instance * @param req: usb requests * @retval status */ static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef*) pdev->pClassData; uint16_t len = 0U; uint8_t *pbuf = NULL; uint16_t status_info = 0U; USBD_StatusTypeDef ret = USBD_OK; _DEBUG(); switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : switch (req->bRequest) { case HID_REQ_SET_PROTOCOL: hhid->Protocol = (uint8_t)(req->wValue); break; case HID_REQ_GET_PROTOCOL: USBD_CtlSendData (pdev, (uint8_t *)(void *)&hhid->Protocol, 1U); break; case HID_REQ_SET_IDLE: hhid->IdleState = (uint8_t)(req->wValue >> 8); break; case HID_REQ_GET_IDLE: USBD_CtlSendData (pdev, (uint8_t *)(void *)&hhid->IdleState, 1U); break; default: USBD_CtlError (pdev, req); ret = USBD_FAIL; printf("HID setup error %d\r\n", __LINE__); break; } break; case USB_REQ_TYPE_STANDARD: switch (req->bRequest) { case USB_REQ_GET_STATUS: if (pdev->dev_state == USBD_STATE_CONFIGURED) { USBD_CtlSendData (pdev, (uint8_t *)(void *)&status_info, 2U); } else { USBD_CtlError (pdev, req); ret = USBD_FAIL; } break; case USB_REQ_GET_DESCRIPTOR: if(req->wValue >> 8 == HID_REPORT_DESC) { len = MIN(HID_MOUSE_REPORT_DESC_SIZE , req->wLength); pbuf = HID_MOUSE_ReportDesc; } else if(req->wValue >> 8 == HID_DESCRIPTOR_TYPE) { pbuf = USBD_HID_Desc; len = MIN(USB_HID_DESC_SIZ, req->wLength); } else { USBD_CtlError (pdev, req); ret = USBD_FAIL; break; } USBD_CtlSendData (pdev, pbuf, len); break; case USB_REQ_GET_INTERFACE : if (pdev->dev_state == USBD_STATE_CONFIGURED) { USBD_CtlSendData (pdev, (uint8_t *)(void *)&hhid->AltSetting, 1U); } else { USBD_CtlError (pdev, req); ret = USBD_FAIL; } break; case USB_REQ_SET_INTERFACE : if (pdev->dev_state == USBD_STATE_CONFIGURED) { hhid->AltSetting = (uint8_t)(req->wValue); } else { USBD_CtlError (pdev, req); ret = USBD_FAIL; } break; default: USBD_CtlError (pdev, req); ret = USBD_FAIL; printf("HID setup error %d\r\n", __LINE__); break; } break; default: USBD_CtlError (pdev, req); ret = USBD_FAIL; printf("HID setup error %d\r\n", __LINE__); break; } return ret; } /** * @brief USBD_HID_SendReport * Send HID Report * @param pdev: device instance * @param buff: pointer to report * @retval status */ uint8_t USBD_HID_SendReport (USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len) { USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef*)pdev->pClassData; _DEBUG(); if (pdev->dev_state == USBD_STATE_CONFIGURED ) { if(hhid->state == HID_IDLE) { hhid->state = HID_BUSY; USBD_LL_Transmit (pdev, HID_EPIN_ADDR, report, len); } } return USBD_OK; } /** * @brief USBD_HID_GetPollingInterval * return polling interval from endpoint descriptor * @param pdev: device instance * @retval polling interval */ uint32_t USBD_HID_GetPollingInterval (USBD_HandleTypeDef *pdev) { uint32_t polling_interval = 0U; _DEBUG(); /* HIGH-speed endpoints */ if(pdev->dev_speed == USBD_SPEED_HIGH) { /* Sets the data transfer polling interval for high speed transfers. Values between 1..16 are allowed. Values correspond to interval of 2 ^ (bInterval-1). This option (8 ms, corresponds to HID_HS_BINTERVAL */ polling_interval = (((1U <<(HID_HS_BINTERVAL - 1U))) / 8U); } else /* LOW and FULL-speed endpoints */ { /* Sets the data transfer polling interval for low and full speed transfers */ polling_interval = HID_FS_BINTERVAL; } return ((uint32_t)(polling_interval)); } /** * @brief USBD_HID_GetCfgFSDesc * return FS configuration descriptor * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ static uint8_t *USBD_HID_GetFSCfgDesc (uint16_t *length) { _DEBUG(); *length = sizeof (USBD_HID_CfgFSDesc); return USBD_HID_CfgFSDesc; } /** * @brief USBD_HID_GetCfgHSDesc * return HS configuration descriptor * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ static uint8_t *USBD_HID_GetHSCfgDesc (uint16_t *length) { _DEBUG(); *length = sizeof (USBD_HID_CfgHSDesc); return USBD_HID_CfgHSDesc; } /** * @brief USBD_HID_GetOtherSpeedCfgDesc * return other speed configuration descriptor * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ static uint8_t *USBD_HID_GetOtherSpeedCfgDesc (uint16_t *length) { _DEBUG(); *length = sizeof (USBD_HID_OtherSpeedCfgDesc); return USBD_HID_OtherSpeedCfgDesc; } /** * @brief USBD_HID_DataIn * handle data IN Stage * @param pdev: device instance * @param epnum: endpoint index * @retval status */ static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) { _DEBUG(); /* Ensure that the FIFO is empty before a new transfer, this condition could be caused by a new transfer before the end of the previous transfer */ ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; return USBD_OK; } static uint8_t USBD_HID_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) { _DEBUG(); /* Ensure that the FIFO is empty before a new transfer, this condition could be caused by a new transfer before the end of the previous transfer */ ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; return USBD_OK; } /** * @brief DeviceQualifierDescriptor * return Device Qualifier descriptor * @param length : pointer data length * @retval pointer to descriptor buffer */ static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length) { _DEBUG(); *length = sizeof (USBD_HID_DeviceQualifierDesc); return USBD_HID_DeviceQualifierDesc; } /** * @} */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/