diff --git a/firmware/components/mainboard/stmf446retx/Inc/mainboard_usb.h b/firmware/components/mainboard/stmf446retx/Inc/mainboard_usb.h new file mode 100644 index 00000000..26551697 --- /dev/null +++ b/firmware/components/mainboard/stmf446retx/Inc/mainboard_usb.h @@ -0,0 +1,160 @@ +/** + ****************************************************************************** + * @file usbd_hid.h + * @author MCD Application Team + * @brief Header file for the usbd_hid_core.c file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_HID_H +#define __USB_HID_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_HID + * @brief This file is the Header file for usbd_hid.c + * @{ + */ + + +/** @defgroup USBD_HID_Exported_Defines + * @{ + */ +#ifndef HID_EPIN_ADDR +#define HID_EPIN_ADDR 0x81U +#endif /* HID_EPIN_ADDR */ +#define HID_EPIN_SIZE 0x0EU + +#define USB_HID_CONFIG_DESC_SIZ 34U +#define USB_HID_DESC_SIZ 9U +#define HID_MOUSE_REPORT_DESC_SIZE 0x2DU + +#define HID_DESCRIPTOR_TYPE 0x21U +#define HID_REPORT_DESC 0x22U + +#ifndef HID_HS_BINTERVAL +#define HID_HS_BINTERVAL 0x07U +#endif /* HID_HS_BINTERVAL */ + +#ifndef HID_FS_BINTERVAL +#define HID_FS_BINTERVAL 0x0AU +#endif /* HID_FS_BINTERVAL */ + +#define USBD_HID_REQ_SET_PROTOCOL 0x0BU +#define USBD_HID_REQ_GET_PROTOCOL 0x03U + +#define USBD_HID_REQ_SET_IDLE 0x0AU +#define USBD_HID_REQ_GET_IDLE 0x02U + +#define USBD_HID_REQ_SET_REPORT 0x09U +#define USBD_HID_REQ_GET_REPORT 0x01U +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ +typedef enum +{ + USBD_HID_IDLE = 0, + USBD_HID_BUSY, +} USBD_HID_StateTypeDef; + + +typedef struct +{ + uint32_t Protocol; + uint32_t IdleState; + uint32_t AltSetting; + USBD_HID_StateTypeDef state; +} USBD_HID_HandleTypeDef; + +/* + * HID Class specification version 1.1 + * 6.2.1 HID Descriptor + */ + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdHID; + uint8_t bCountryCode; + uint8_t bNumDescriptors; + uint8_t bHIDDescriptorType; + uint16_t wItemLength; +} __PACKED USBD_HIDDescTypeDef; + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_HID; +#define USBD_HID_CLASS &USBD_HID +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len, uint8_t ClassId); +#else +uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len); +#endif /* USE_USBD_COMPOSITE */ +uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HID_H */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/firmware/components/mainboard/stmf446retx/Src/main.c b/firmware/components/mainboard/stmf446retx/Src/main.c index ab0c8ef4..5b40c90a 100644 --- a/firmware/components/mainboard/stmf446retx/Src/main.c +++ b/firmware/components/mainboard/stmf446retx/Src/main.c @@ -20,7 +20,7 @@ #include "main.h" #include "can.h" #include "usb_device.h" -#include "usbd_hid.h" +#include "mainboard_usb.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ @@ -122,7 +122,7 @@ int main(void) HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING); HAL_Delay(50); /* USER CODE END 2 */ - + /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) @@ -131,6 +131,7 @@ int main(void) /* USER CODE END WHILE */ for(int col = 0; col < COLS; col++){ HAL_GPIO_WritePin(col_pins[col].PORT, col_pins[col].PIN, GPIO_PIN_SET); + HAL_Delay(1); for(int row = 0; row < ROWS; row++){ if(HAL_GPIO_ReadPin(row_pins[row].PORT, row_pins[row].PIN)){ addHIDReport(matrix[row][col], 1); diff --git a/firmware/components/mainboard/stmf446retx/Src/mainboard_usb.c b/firmware/components/mainboard/stmf446retx/Src/mainboard_usb.c new file mode 100644 index 00000000..4df85dbf --- /dev/null +++ b/firmware/components/mainboard/stmf446retx/Src/mainboard_usb.c @@ -0,0 +1,673 @@ +/** + ****************************************************************************** + * @file usbd_hid.c + * @author MCD Application Team + * @brief This file provides the HID core functions. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * @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 + * + ****************************************************************************** + */ + +/* 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_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); +#ifndef USE_USBD_COMPOSITE +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); +#endif /* USE_USBD_COMPOSITE */ +/** + * @} + */ + +/** @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, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else + USBD_HID_GetHSCfgDesc, + USBD_HID_GetFSCfgDesc, + USBD_HID_GetOtherSpeedCfgDesc, + USBD_HID_GetDeviceQualifierDesc, +#endif /* USE_USBD_COMPOSITE */ +}; + +#ifndef USE_USBD_COMPOSITE +/* USB HID device FS 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 */ +#if (USBD_SELF_POWERED == 1U) + 0xE0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0xA0, /* bmAttributes: Bus Powered according to user configuration */ +#endif /* USBD_SELF_POWERED */ + USBD_MAX_POWER, /* MaxPower (mA) */ + + /************** 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 */ + 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x00, /* 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 Bytes max */ + 0x00, + HID_FS_BINTERVAL, /* bInterval: Polling Interval */ + /* 34 */ +}; +#endif /* USE_USBD_COMPOSITE */ + +/* 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, +}; + +#ifndef USE_USBD_COMPOSITE +/* 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, +}; +#endif /* USE_USBD_COMPOSITE */ + +__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = +{ +// 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */ +// 0x09, 0x05, /* Usage (Gamepad) */ +// 0xA1, 0x01, /* Collection (Application) */ + +// // --- Buttons: 13 total --- +// 0x05, 0x09, // USAGE_PAGE (Button) +// 0x19, 0x01, // USAGE_MINIMUM (Button 1) +// 0x29, 0x0D, // USAGE_MAXIMUM (Button 13) +// 0x15, 0x00, // LOGICAL_MINIMUM (0) +// 0x25, 0x01, // LOGICAL_MAXIMUM (1) +// 0x75, 0x01, // REPORT_SIZE (1 bit per button) +// 0x95, 0x0D, // REPORT_COUNT (13 bits total) +// 0x81, 0x02, // INPUT (Data,Var,Abs) + +// // --- Padding (3 bits) --- +// 0x75, 0x01, // REPORT_SIZE (1) +// 0x95, 0x03, // REPORT_COUNT (3 bits) +// 0x81, 0x03, // INPUT (Const,Var,Abs) + +// // --- Encoders (3 x int8_t) --- +// 0x05, 0x01, // USAGE_PAGE (Generic Desktop) +// 0x09, 0x30, // USAGE (X) +// 0x09, 0x31, // USAGE (Y) +// 0x09, 0x32, // USAGE (Z) +// 0x15, 0x81, // LOGICAL_MINIMUM (-127) +// 0x25, 0x7F, // LOGICAL_MAXIMUM (127) +// 0x75, 0x08, // REPORT_SIZE (8 bits) +// 0x95, 0x03, // REPORT_COUNT (3 axes) +// 0x81, 0x02, // INPUT (Data,Var,Abs) + +// 0xC0 /* End Collection */ + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x06, // Usage (Keyboard) + 0xA1, 0x01, // Collection (Application) + + // Modifiers (8 bits) + 0x05, 0x07, // Usage Page (Keyboard/Keypad) + 0x19, 0xE0, // Usage Minimum (224) - Left Control + 0x29, 0xE7, // Usage Maximum (231) - Right GUI + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1 bit) + 0x95, 0x08, // Report Count (8 bits) + 0x81, 0x02, // Input (Data, Variable, Absolute) + + // Reserved byte (8 bits) + 0x75, 0x08, // Report Size (8 bits) + 0x95, 0x01, // Report Count (1) + 0x81, 0x01, // Input (Constant) + + // Key bitfield (96 bits = 12 bytes) + 0x05, 0x07, // Usage Page (Keyboard/Keypad) + 0x19, 0x04, // Usage Minimum (4) — 'A' key + 0x29, 0x63, // Usage Maximum (99) — 96 keys total (4 to 99) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1 bit) + 0x95, 0x60, // Report Count (96 bits) + 0x81, 0x02, // Input (Data, Variable, Absolute) + + 0xC0 // End Collection +}; + +static uint8_t HIDInEpAdd = HID_EPIN_ADDR; + +/** + * @} + */ + +/** @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) +{ + UNUSED(cfgidx); + + USBD_HID_HandleTypeDef *hhid; + + hhid = (USBD_HID_HandleTypeDef *)USBD_malloc(sizeof(USBD_HID_HandleTypeDef)); + + if (hhid == NULL) + { + pdev->pClassDataCmsit[pdev->classId] = NULL; + return (uint8_t)USBD_EMEM; + } + + pdev->pClassDataCmsit[pdev->classId] = (void *)hhid; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = HID_HS_BINTERVAL; + } + else /* LOW and FULL-speed endpoints */ + { + pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = HID_FS_BINTERVAL; + } + + /* Open EP IN */ + (void)USBD_LL_OpenEP(pdev, HIDInEpAdd, USBD_EP_TYPE_INTR, HID_EPIN_SIZE); + pdev->ep_in[HIDInEpAdd & 0xFU].is_used = 1U; + + hhid->state = USBD_HID_IDLE; + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_HID_DeInit + * 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) +{ + UNUSED(cfgidx); + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + /* Close HID EPs */ + (void)USBD_LL_CloseEP(pdev, HIDInEpAdd); + pdev->ep_in[HIDInEpAdd & 0xFU].is_used = 0U; + pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = 0U; + + /* Free allocated memory */ + if (pdev->pClassDataCmsit[pdev->classId] != NULL) + { + (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; + } + + return (uint8_t)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->pClassDataCmsit[pdev->classId]; + USBD_StatusTypeDef ret = USBD_OK; + uint16_t len; + uint8_t *pbuf; + uint16_t status_info = 0U; + + if (hhid == NULL) + { + return (uint8_t)USBD_FAIL; + } + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + case USBD_HID_REQ_SET_PROTOCOL: + hhid->Protocol = (uint8_t)(req->wValue); + break; + + case USBD_HID_REQ_GET_PROTOCOL: + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U); + break; + + case USBD_HID_REQ_SET_IDLE: + hhid->IdleState = (uint8_t)(req->wValue >> 8); + break; + + case USBD_HID_REQ_GET_IDLE: + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U); + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&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; + } + (void)USBD_CtlSendData(pdev, pbuf, len); + break; + + case USB_REQ_GET_INTERFACE : + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&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; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + + return (uint8_t)ret; +} + + +/** + * @brief USBD_HID_SendReport + * Send HID Report + * @param pdev: device instance + * @param buff: pointer to report + * @param ClassId: The Class ID + * @retval status + */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len, uint8_t ClassId) +{ + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else +uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len) +{ + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#endif /* USE_USBD_COMPOSITE */ + + if (hhid == NULL) + { + return (uint8_t)USBD_FAIL; + } + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, ClassId); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (hhid->state == USBD_HID_IDLE) + { + hhid->state = USBD_HID_BUSY; + (void)USBD_LL_Transmit(pdev, HIDInEpAdd, report, len); + } + } + + return (uint8_t)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; + + /* 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)); +} + +#ifndef USE_USBD_COMPOSITE +/** + * @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) +{ + USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR); + + if (pEpDesc != NULL) + { + pEpDesc->bInterval = HID_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; +} + +/** + * @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) +{ + USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR); + + if (pEpDesc != NULL) + { + pEpDesc->bInterval = HID_HS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; +} + +/** + * @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) +{ + USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR); + + if (pEpDesc != NULL) + { + pEpDesc->bInterval = HID_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; +} +#endif /* USE_USBD_COMPOSITE */ + +/** + * @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) +{ + UNUSED(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->pClassDataCmsit[pdev->classId])->state = USBD_HID_IDLE; + + return (uint8_t)USBD_OK; +} + +#ifndef USE_USBD_COMPOSITE +/** + * @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 = (uint16_t)sizeof(USBD_HID_DeviceQualifierDesc); + + return USBD_HID_DeviceQualifierDesc; +} +#endif /* USE_USBD_COMPOSITE */ +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ +