2 ******************************************************************************
3 * @file usbd_hid_core.c
4 * @author MCD Application Team
7 * @brief This file provides the HID core functions.
11 * ===================================================================
12 * HID Class Description
13 * ===================================================================
14 * This module manages the HID class V1.11 following the "Device Class Definition
15 * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
16 * This driver implements the following aspects of the specification:
17 * - The Boot Interface Subclass
18 * - The Mouse protocol
19 * - Usage Page : Generic Desktop
21 * - Collection : Application
23 * @note In HS mode and when the DMA is used, all variables and data structures
24 * dealing with the DMA during the transaction process should be 32-bit aligned.
29 ******************************************************************************
32 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
33 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
34 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
35 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
36 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
37 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
39 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
40 ******************************************************************************
43 /* Includes ------------------------------------------------------------------*/
44 #include "usbd_hid_core.h"
45 #include "usbd_desc.h"
49 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
54 /** @defgroup USBD_HID
55 * @brief usbd core module
59 /** @defgroup USBD_HID_Private_TypesDefinitions
67 /** @defgroup USBD_HID_Private_Defines
76 /** @defgroup USBD_HID_Private_Macros
86 /** @defgroup USBD_HID_Private_FunctionPrototypes
91 static uint8_t USBD_HID_Init (void *pdev,
94 static uint8_t USBD_HID_DeInit (void *pdev,
97 static uint8_t USBD_HID_Setup (void *pdev,
100 static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length);
102 static uint8_t USBD_HID_DataIn (void *pdev, uint8_t epnum);
107 /** @defgroup USBD_HID_Private_Variables
111 USBD_Class_cb_TypeDef USBD_HID_cb =
117 NULL, /*EP0_RxReady*/
118 USBD_HID_DataIn, /*DataIn*/
124 #ifdef USB_OTG_HS_CORE
125 USBD_HID_GetCfgDesc, /* use same config as per FS */
129 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
130 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
131 #pragma data_alignment=4
133 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
134 __ALIGN_BEGIN static uint32_t USBD_HID_AltSet __ALIGN_END = 0;
136 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
137 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
138 #pragma data_alignment=4
140 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
141 __ALIGN_BEGIN static uint32_t USBD_HID_Protocol __ALIGN_END = 0;
143 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
144 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
145 #pragma data_alignment=4
147 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
148 __ALIGN_BEGIN static uint32_t USBD_HID_IdleState __ALIGN_END = 0;
150 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
151 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
152 #pragma data_alignment=4
154 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
155 /* USB HID device Configuration Descriptor */
156 __ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
158 0x09, /* bLength: Configuration Descriptor size */
159 USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
160 USB_HID_CONFIG_DESC_SIZ,
161 /* wTotalLength: Bytes returned */
163 0x01, /*bNumInterfaces: 1 interface*/
164 0x01, /*bConfigurationValue: Configuration value*/
165 0x00, /*iConfiguration: Index of string descriptor describing
167 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */
168 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
170 /************** Descriptor of Joystick Mouse interface ****************/
172 0x09, /*bLength: Interface Descriptor size*/
173 USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
174 0x00, /*bInterfaceNumber: Number of Interface*/
175 0x00, /*bAlternateSetting: Alternate setting*/
176 0x01, /*bNumEndpoints*/
177 0x03, /*bInterfaceClass: HID*/
178 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
179 0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
180 0, /*iInterface: Index of string descriptor*/
181 /******************** Descriptor of Joystick Mouse HID ********************/
183 0x09, /*bLength: HID Descriptor size*/
184 HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
185 0x11, /*bcdHID: HID Class Spec release number*/
187 0x00, /*bCountryCode: Hardware target country*/
188 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
189 0x22, /*bDescriptorType*/
190 HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
192 /******************** Descriptor of Mouse endpoint ********************/
194 0x07, /*bLength: Endpoint Descriptor size*/
195 USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
197 HID_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/
198 0x03, /*bmAttributes: Interrupt endpoint*/
199 HID_IN_PACKET, /*wMaxPacketSize: 4 Byte max */
201 0x0A, /*bInterval: Polling Interval (10 ms)*/
205 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
206 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
207 #pragma data_alignment=4
209 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
210 __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
264 /** @defgroup USBD_HID_Private_Functions
269 * @brief USBD_HID_Init
270 * Initialize the HID interface
271 * @param pdev: device instance
272 * @param cfgidx: Configuration index
275 static uint8_t USBD_HID_Init (void *pdev,
295 * @brief USBD_HID_Init
296 * DeInitialize the HID layer
297 * @param pdev: device instance
298 * @param cfgidx: Configuration index
301 static uint8_t USBD_HID_DeInit (void *pdev,
305 DCD_EP_Close (pdev , HID_IN_EP);
306 DCD_EP_Close (pdev , HID_OUT_EP);
313 * @brief USBD_HID_Setup
314 * Handle the HID specific requests
315 * @param pdev: instance
316 * @param req: usb requests
319 static uint8_t USBD_HID_Setup (void *pdev,
323 uint8_t *pbuf = NULL;
325 switch (req->bmRequest & USB_REQ_TYPE_MASK)
327 case USB_REQ_TYPE_CLASS :
328 switch (req->bRequest)
332 case HID_REQ_SET_PROTOCOL:
333 USBD_HID_Protocol = (uint8_t)(req->wValue);
336 case HID_REQ_GET_PROTOCOL:
337 USBD_CtlSendData (pdev,
338 (uint8_t *)&USBD_HID_Protocol,
342 case HID_REQ_SET_IDLE:
343 USBD_HID_IdleState = (uint8_t)(req->wValue >> 8);
346 case HID_REQ_GET_IDLE:
347 USBD_CtlSendData (pdev,
348 (uint8_t *)&USBD_HID_IdleState,
353 USBD_CtlError (pdev, req);
358 case USB_REQ_TYPE_STANDARD:
359 switch (req->bRequest)
361 case USB_REQ_GET_DESCRIPTOR:
362 if( req->wValue >> 8 == HID_REPORT_DESC)
364 len = MIN(HID_MOUSE_REPORT_DESC_SIZE , req->wLength);
365 pbuf = HID_MOUSE_ReportDesc;
367 else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE)
370 //#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
371 // pbuf = USBD_HID_Desc;
373 pbuf = USBD_HID_CfgDesc + 0x12;
375 len = MIN(USB_HID_DESC_SIZ , req->wLength);
378 USBD_CtlSendData (pdev,
384 case USB_REQ_GET_INTERFACE :
385 USBD_CtlSendData (pdev,
386 (uint8_t *)&USBD_HID_AltSet,
390 case USB_REQ_SET_INTERFACE :
391 USBD_HID_AltSet = (uint8_t)(req->wValue);
399 * @brief USBD_HID_SendReport
401 * @param pdev: device instance
402 * @param buff: pointer to report
405 uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev,
409 if (pdev->dev.device_status == USB_OTG_CONFIGURED )
411 DCD_EP_Tx (pdev, HID_IN_EP, report, len);
417 * @brief USBD_HID_GetCfgDesc
418 * return configuration descriptor
419 * @param speed : current device speed
420 * @param length : pointer data length
421 * @retval pointer to descriptor buffer
423 static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length)
425 *length = sizeof (USBD_HID_CfgDesc);
426 return USBD_HID_CfgDesc;
430 * @brief USBD_HID_DataIn
431 * handle data IN Stage
432 * @param pdev: device instance
433 * @param epnum: endpoint index
436 static uint8_t USBD_HID_DataIn (void *pdev,
440 /* Ensure that the FIFO is empty before a new transfer, this condition could
441 be caused by a new transfer before the end of the previous transfer */
442 DCD_EP_Flush(pdev, HID_IN_EP);
460 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/