diff options
Diffstat (limited to 'stmhal/usbdev/class/src')
-rw-r--r-- | stmhal/usbdev/class/src/usbd_cdc_msc_hid.c | 81 |
1 files changed, 75 insertions, 6 deletions
diff --git a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c index d50934ada..d13657023 100644 --- a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c @@ -27,10 +27,10 @@ #include "usbd_ioreq.h" #include "usbd_cdc_msc_hid.h" -#define MAX_TEMPLATE_CONFIG_DESC_SIZE (100) // should be maximum of all template config desc's +#define MAX_TEMPLATE_CONFIG_DESC_SIZE (107) // should be maximum of all template config desc's #define CDC_TEMPLATE_CONFIG_DESC_SIZE (67) #define CDC_MSC_TEMPLATE_CONFIG_DESC_SIZE (98) -#define CDC_HID_TEMPLATE_CONFIG_DESC_SIZE (100) +#define CDC_HID_TEMPLATE_CONFIG_DESC_SIZE (107) #define CDC_HID_TEMPLATE_HID_DESC_OFFSET (9) #define HID_DESC_OFFSET_SUBCLASS (6) #define HID_DESC_OFFSET_PROTOCOL (7) @@ -39,6 +39,9 @@ #define HID_DESC_OFFSET_MAX_PACKET_LO (22) #define HID_DESC_OFFSET_MAX_PACKET_HI (23) #define HID_DESC_OFFSET_POLLING_INTERVAL (24) +#define HID_DESC_OFFSET_MAX_PACKET_OUT_LO (29) +#define HID_DESC_OFFSET_MAX_PACKET_OUT_HI (30) +#define HID_DESC_OFFSET_POLLING_INTERVAL_OUT (31) #define HID_SUBDESC_LEN (9) #define CDC_IFACE_NUM_ALONE (0) @@ -48,7 +51,9 @@ #define HID_IFACE_NUM_WITH_CDC (0) #define HID_IFACE_NUM_WITH_MSC (1) #define HID_IN_EP_WITH_CDC (0x81) +#define HID_OUT_EP_WITH_CDC (0x01) #define HID_IN_EP_WITH_MSC (0x83) +#define HID_OUT_EP_WITH_MSC (0x03) #define USB_DESC_TYPE_ASSOCIATION (0x0b) @@ -77,11 +82,14 @@ typedef struct { uint32_t IdleState; uint32_t AltSetting; HID_StateTypeDef state; + uint8_t *RxBuffer; + uint32_t RxLength; } USBD_HID_HandleTypeDef; static uint8_t usbd_mode; static uint8_t cdc_iface_num; static uint8_t hid_in_ep; +static uint8_t hid_out_ep; static uint8_t hid_iface_num; static uint8_t usbd_config_desc_size; static uint8_t *hid_desc; @@ -89,6 +97,7 @@ static const uint8_t *hid_report_desc; static USBD_CDC_ItfTypeDef *CDC_fops; static USBD_StorageTypeDef *MSC_fops; +static USBD_HID_ItfTypeDef *HID_fops; static USBD_CDC_HandleTypeDef CDC_ClassData; static USBD_MSC_BOT_HandleTypeDef MSC_BOT_ClassData; @@ -274,7 +283,7 @@ static const uint8_t cdc_hid_template_config_desc[CDC_HID_TEMPLATE_CONFIG_DESC_S USB_DESC_TYPE_INTERFACE, // bDescriptorType: interface descriptor HID_IFACE_NUM_WITH_CDC, // bInterfaceNumber: Number of Interface 0x00, // bAlternateSetting: Alternate setting - 0x01, // bNumEndpoints + 0x02, // bNumEndpoints 0x03, // bInterfaceClass: HID Class 0x01, // bInterfaceSubClass: 0=no sub class, 1=boot 0x02, // nInterfaceProtocol: 0=none, 1=keyboard, 2=mouse @@ -300,6 +309,15 @@ static const uint8_t cdc_hid_template_config_desc[CDC_HID_TEMPLATE_CONFIG_DESC_S HIBYTE(USBD_HID_MOUSE_MAX_PACKET), 0x08, // bInterval: Polling interval + // Endpoint OUT descriptor + 0x07, // bLength: Endpoint descriptor length + USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint descriptor type + HID_OUT_EP_WITH_CDC, // bEndpointAddress: OUT + 0x03, // bmAttributes: Interrupt endpoint type + LOBYTE(USBD_HID_MOUSE_MAX_PACKET), // wMaxPacketSize + HIBYTE(USBD_HID_MOUSE_MAX_PACKET), + 0x08, // bInterval: Polling interval + //========================================================================== // Interface Association for CDC VCP 0x08, // bLength: 8 bytes @@ -581,6 +599,7 @@ int USBD_SelectMode(uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info) { memcpy(usbd_config_desc, cdc_hid_template_config_desc, sizeof(cdc_hid_template_config_desc)); cdc_iface_num = CDC_IFACE_NUM_WITH_HID; hid_in_ep = HID_IN_EP_WITH_CDC; + hid_out_ep = HID_OUT_EP_WITH_CDC; hid_iface_num = HID_IFACE_NUM_WITH_CDC; hid_desc = usbd_config_desc + CDC_HID_TEMPLATE_HID_DESC_OFFSET; break; @@ -595,6 +614,7 @@ int USBD_SelectMode(uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info) { // not implemented case USBD_MODE_MSC_HID: hid_in_ep = HID_IN_EP_WITH_MSC; + hid_out_ep = HID_OUT_EP_WITH_MSC; hid_iface_num = HID_IFACE_NUM_WITH_MSC; break; */ @@ -612,6 +632,9 @@ int USBD_SelectMode(uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info) { hid_desc[HID_DESC_OFFSET_MAX_PACKET_LO] = hid_info->max_packet_len; hid_desc[HID_DESC_OFFSET_MAX_PACKET_HI] = 0; hid_desc[HID_DESC_OFFSET_POLLING_INTERVAL] = hid_info->polling_interval; + hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_LO] = hid_info->max_packet_len; + hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_HI] = 0; + hid_desc[HID_DESC_OFFSET_POLLING_INTERVAL_OUT] = hid_info->polling_interval; hid_report_desc = hid_info->report_desc; } @@ -681,16 +704,28 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { if (usbd_mode & USBD_MODE_HID) { // HID component - // get max packet length from descriptor - uint16_t mps = + // get max packet lengths from descriptor + uint16_t mps_in = hid_desc[HID_DESC_OFFSET_MAX_PACKET_LO] | (hid_desc[HID_DESC_OFFSET_MAX_PACKET_HI] << 8); + uint16_t mps_out = + hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_LO] + | (hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_HI] << 8); // Open EP IN USBD_LL_OpenEP(pdev, hid_in_ep, USBD_EP_TYPE_INTR, - mps); + mps_in); + + // Open EP OUT + USBD_LL_OpenEP(pdev, + hid_out_ep, + USBD_EP_TYPE_INTR, + mps_out); + + // Prepare Out endpoint to receive next packet + USBD_LL_PrepareReceive(pdev, hid_out_ep, HID_ClassData.RxBuffer, mps_out); HID_ClassData.state = HID_IDLE; } @@ -730,6 +765,7 @@ static uint8_t USBD_CDC_MSC_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) // close endpoints USBD_LL_CloseEP(pdev, hid_in_ep); + USBD_LL_CloseEP(pdev, hid_out_ep); } return 0; @@ -931,6 +967,9 @@ static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) } else if ((usbd_mode & USBD_MODE_MSC) && epnum == (MSC_OUT_EP & 0x7f)) { MSC_BOT_DataOut(pdev, epnum); return USBD_OK; + } else if ((usbd_mode & USBD_MODE_HID) && epnum == (hid_out_ep & 0x7f)) { + HID_ClassData.RxLength = USBD_LL_GetRxDataSize(pdev, epnum); + HID_fops->Receive(HID_ClassData.RxBuffer, HID_ClassData.RxLength); } return USBD_OK; @@ -1008,6 +1047,36 @@ uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef * } } +uint8_t USBD_HID_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_HID_ItfTypeDef *fops) { + if (fops == NULL) { + return USBD_FAIL; + } else { + HID_fops = fops; + return USBD_OK; + } +} + +uint8_t USBD_HID_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) { + HID_ClassData.RxBuffer = pbuff; + return USBD_OK; +} + +// prepare OUT endpoint for reception +uint8_t USBD_HID_ReceivePacket(USBD_HandleTypeDef *pdev) { + // Suspend or Resume USB Out process + if (pdev->dev_speed == USBD_SPEED_HIGH) { + return USBD_FAIL; + } + + // Prepare Out endpoint to receive next packet + uint16_t mps_out = + hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_LO] + | (hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_HI] << 8); + USBD_LL_PrepareReceive(pdev, hid_out_ep, HID_ClassData.RxBuffer, mps_out); + + return USBD_OK; +} + int USBD_HID_CanSendReport(USBD_HandleTypeDef *pdev) { return pdev->dev_state == USBD_STATE_CONFIGURED && HID_ClassData.state == HID_IDLE; } |