From b30c02afa078f7713faa14087ae28433dee49027 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 Mar 2014 00:30:37 +0000 Subject: stmhal: Get USB enumerating a CDC device. Enumerates CDC device over USB, but doesn't transmit/receive yet. --- stmhal/usbdev/class/HID/Inc/usbd_hid.h | 136 +++++++++ stmhal/usbdev/class/HID/Src/usbd_hid.c | 509 +++++++++++++++++++++++++++++++++ 2 files changed, 645 insertions(+) create mode 100644 stmhal/usbdev/class/HID/Inc/usbd_hid.h create mode 100644 stmhal/usbdev/class/HID/Src/usbd_hid.c (limited to 'stmhal/usbdev/class/HID') diff --git a/stmhal/usbdev/class/HID/Inc/usbd_hid.h b/stmhal/usbdev/class/HID/Inc/usbd_hid.h new file mode 100644 index 000000000..811de0b5a --- /dev/null +++ b/stmhal/usbdev/class/HID/Inc/usbd_hid.h @@ -0,0 +1,136 @@ +/** + ****************************************************************************** + * @file usbd_hid_core.h + * @author MCD Application Team + * @version V2.0.0 + * @date 18-February-2014 + * @brief header file for the usbd_hid_core.c file. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#ifndef __USB_HID_CORE_H_ +#define __USB_HID_CORE_H_ + +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_HID + * @brief This file is the Header file for USBD_msc.c + * @{ + */ + + +/** @defgroup USBD_HID_Exported_Defines + * @{ + */ +#define HID_EPIN_ADDR 0x81 +#define HID_EPIN_SIZE 0x04 + +#define USB_HID_CONFIG_DESC_SIZ 34 +#define USB_HID_DESC_SIZ 9 +#define HID_MOUSE_REPORT_DESC_SIZE 74 + +#define HID_DESCRIPTOR_TYPE 0x21 +#define HID_REPORT_DESC 0x22 + + +#define HID_REQ_SET_PROTOCOL 0x0B +#define HID_REQ_GET_PROTOCOL 0x03 + +#define HID_REQ_SET_IDLE 0x0A +#define HID_REQ_GET_IDLE 0x02 + +#define HID_REQ_SET_REPORT 0x09 +#define HID_REQ_GET_REPORT 0x01 +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ +typedef enum +{ + HID_IDLE = 0, + HID_BUSY, +} +HID_StateTypeDef; + + +typedef struct +{ + uint32_t Protocol; + uint32_t IdleState; + uint32_t AltSetting; + HID_StateTypeDef state; +} +USBD_HID_HandleTypeDef; +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_HID; +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_HID_SendReport (USBD_HandleTypeDef *pdev, + uint8_t *report, + uint16_t len); + +uint8_t *USBD_HID_DeviceQualifierDescriptor (uint16_t *length); + +/** + * @} + */ + +#endif // __USB_HID_CORE_H_ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stmhal/usbdev/class/HID/Src/usbd_hid.c b/stmhal/usbdev/class/HID/Src/usbd_hid.c new file mode 100644 index 000000000..11dca78d5 --- /dev/null +++ b/stmhal/usbdev/class/HID/Src/usbd_hid.c @@ -0,0 +1,509 @@ +/** + ****************************************************************************** + * @file usbd_hid.c + * @author MCD Application Team + * @version V2.0.0 + * @date 18-February-2014 + * @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 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_hid.h" +#include "usbd_desc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_OTG_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_GetCfgDesc (uint16_t *length); + +static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length); + +static uint8_t USBD_HID_DataIn (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*/ + NULL, /*DataOut*/ + NULL, /*SOF */ + NULL, + NULL, + USBD_HID_GetCfgDesc, + USBD_HID_GetCfgDesc, + USBD_HID_GetCfgDesc, + USBD_HID_GetDeviceQualifierDesc, +}; + +/* USB HID device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[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, + 0x0A, /*bInterval: Polling Interval (10 ms)*/ + /* 34 */ +} ; + +/* 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 +}; + +/** + * @} + */ + +/** @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) +{ + uint8_t ret = 0; + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + HID_EPIN_ADDR, + USBD_EP_TYPE_INTR, + HID_EPIN_SIZE); + + pdev->pClassData = USBD_malloc(sizeof (USBD_HID_HandleTypeDef)); + + if(pdev->pClassData == NULL) + { + ret = 1; + } + else + { + ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; + } + return ret; +} + +/** + * @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) +{ + /* Close HID EPs */ + USBD_LL_CloseEP(pdev, + HID_EPIN_SIZE); + + /* 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) +{ + uint16_t len = 0; + uint8_t *pbuf = NULL; + USBD_HID_HandleTypeDef *hhid = pdev->pClassData; + + 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 *)&hhid->Protocol, + 1); + break; + + case HID_REQ_SET_IDLE: + hhid->IdleState = (uint8_t)(req->wValue >> 8); + break; + + case HID_REQ_GET_IDLE: + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->IdleState, + 1); + break; + + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + 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); + } + + USBD_CtlSendData (pdev, + pbuf, + len); + + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->AltSetting, + 1); + break; + + case USB_REQ_SET_INTERFACE : + hhid->AltSetting = (uint8_t)(req->wValue); + break; + } + } + return USBD_OK; +} + +/** + * @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 = pdev->pClassData; + + 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_GetCfgDesc + * return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_HID_GetCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; +} + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_HID_DeviceQualifierDescriptor (uint16_t *length) +{ + *length = sizeof (USBD_HID_DeviceQualifierDesc); + return USBD_HID_DeviceQualifierDesc; +} + + +/** + * @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) +{ + + /* 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) +{ + *length = sizeof (USBD_HID_DeviceQualifierDesc); + return USBD_HID_DeviceQualifierDesc; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -- cgit v1.2.3