2727#include "usbd_ioreq.h"
2828#include "usbd_cdc_msc_hid.h"
2929
30- #define MAX_TEMPLATE_CONFIG_DESC_SIZE (100 ) // should be maximum of all template config desc's
30+ #define MAX_TEMPLATE_CONFIG_DESC_SIZE (107 ) // should be maximum of all template config desc's
3131#define CDC_TEMPLATE_CONFIG_DESC_SIZE (67)
3232#define CDC_MSC_TEMPLATE_CONFIG_DESC_SIZE (98)
33- #define CDC_HID_TEMPLATE_CONFIG_DESC_SIZE (100 )
33+ #define CDC_HID_TEMPLATE_CONFIG_DESC_SIZE (107 )
3434#define CDC_HID_TEMPLATE_HID_DESC_OFFSET (9)
3535#define HID_DESC_OFFSET_SUBCLASS (6)
3636#define HID_DESC_OFFSET_PROTOCOL (7)
3939#define HID_DESC_OFFSET_MAX_PACKET_LO (22)
4040#define HID_DESC_OFFSET_MAX_PACKET_HI (23)
4141#define HID_DESC_OFFSET_POLLING_INTERVAL (24)
42+ #define HID_DESC_OFFSET_MAX_PACKET_OUT_LO (29)
43+ #define HID_DESC_OFFSET_MAX_PACKET_OUT_HI (30)
44+ #define HID_DESC_OFFSET_POLLING_INTERVAL_OUT (31)
4245#define HID_SUBDESC_LEN (9)
4346
4447#define CDC_IFACE_NUM_ALONE (0)
4851#define HID_IFACE_NUM_WITH_CDC (0)
4952#define HID_IFACE_NUM_WITH_MSC (1)
5053#define HID_IN_EP_WITH_CDC (0x81)
54+ #define HID_OUT_EP_WITH_CDC (0x01)
5155#define HID_IN_EP_WITH_MSC (0x83)
5256
5357#define USB_DESC_TYPE_ASSOCIATION (0x0b)
@@ -82,6 +86,7 @@ typedef struct {
8286static uint8_t usbd_mode ;
8387static uint8_t cdc_iface_num ;
8488static uint8_t hid_in_ep ;
89+ static uint8_t hid_out_ep ;
8590static uint8_t hid_iface_num ;
8691static uint8_t usbd_config_desc_size ;
8792static uint8_t * hid_desc ;
@@ -274,7 +279,7 @@ static const uint8_t cdc_hid_template_config_desc[CDC_HID_TEMPLATE_CONFIG_DESC_S
274279 USB_DESC_TYPE_INTERFACE , // bDescriptorType: interface descriptor
275280 HID_IFACE_NUM_WITH_CDC , // bInterfaceNumber: Number of Interface
276281 0x00 , // bAlternateSetting: Alternate setting
277- 0x01 , // bNumEndpoints
282+ 0x02 , // bNumEndpoints
278283 0x03 , // bInterfaceClass: HID Class
279284 0x01 , // bInterfaceSubClass: 0=no sub class, 1=boot
280285 0x02 , // nInterfaceProtocol: 0=none, 1=keyboard, 2=mouse
@@ -300,6 +305,15 @@ static const uint8_t cdc_hid_template_config_desc[CDC_HID_TEMPLATE_CONFIG_DESC_S
300305 HIBYTE (USBD_HID_MOUSE_MAX_PACKET ),
301306 0x08 , // bInterval: Polling interval
302307
308+ // Endpoint OUT descriptor
309+ 0x07 , // bLength: Endpoint descriptor length
310+ USB_DESC_TYPE_ENDPOINT , // bDescriptorType: Endpoint descriptor type
311+ HID_OUT_EP_WITH_CDC , // bEndpointAddress: OUT
312+ 0x03 , // bmAttributes: Interrupt endpoint type
313+ LOBYTE (USBD_HID_MOUSE_MAX_PACKET ), // wMaxPacketSize
314+ HIBYTE (USBD_HID_MOUSE_MAX_PACKET ),
315+ 0x08 , // bInterval: Polling interval
316+
303317 //==========================================================================
304318 // Interface Association for CDC VCP
305319 0x08 , // bLength: 8 bytes
@@ -581,6 +595,7 @@ int USBD_SelectMode(uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info) {
581595 memcpy (usbd_config_desc , cdc_hid_template_config_desc , sizeof (cdc_hid_template_config_desc ));
582596 cdc_iface_num = CDC_IFACE_NUM_WITH_HID ;
583597 hid_in_ep = HID_IN_EP_WITH_CDC ;
598+ hid_out_ep = HID_OUT_EP_WITH_CDC ;
584599 hid_iface_num = HID_IFACE_NUM_WITH_CDC ;
585600 hid_desc = usbd_config_desc + CDC_HID_TEMPLATE_HID_DESC_OFFSET ;
586601 break ;
@@ -612,6 +627,9 @@ int USBD_SelectMode(uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info) {
612627 hid_desc [HID_DESC_OFFSET_MAX_PACKET_LO ] = hid_info -> max_packet_len ;
613628 hid_desc [HID_DESC_OFFSET_MAX_PACKET_HI ] = 0 ;
614629 hid_desc [HID_DESC_OFFSET_POLLING_INTERVAL ] = hid_info -> polling_interval ;
630+ hid_desc [HID_DESC_OFFSET_MAX_PACKET_OUT_LO ] = hid_info -> max_packet_len ;
631+ hid_desc [HID_DESC_OFFSET_MAX_PACKET_OUT_HI ] = 0 ;
632+ hid_desc [HID_DESC_OFFSET_POLLING_INTERVAL_OUT ] = hid_info -> polling_interval ;
615633 hid_report_desc = hid_info -> report_desc ;
616634 }
617635
@@ -681,16 +699,28 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
681699 if (usbd_mode & USBD_MODE_HID ) {
682700 // HID component
683701
684- // get max packet length from descriptor
685- uint16_t mps =
702+ // get max packet lengths from descriptor
703+ uint16_t mps_in =
686704 hid_desc [HID_DESC_OFFSET_MAX_PACKET_LO ]
687705 | (hid_desc [HID_DESC_OFFSET_MAX_PACKET_HI ] << 8 );
706+ uint16_t mps_out =
707+ hid_desc [HID_DESC_OFFSET_MAX_PACKET_OUT_LO ]
708+ | (hid_desc [HID_DESC_OFFSET_MAX_PACKET_OUT_HI ] << 8 );
688709
689710 // Open EP IN
690711 USBD_LL_OpenEP (pdev ,
691712 hid_in_ep ,
692713 USBD_EP_TYPE_INTR ,
693- mps );
714+ mps_in );
715+
716+ // Open EP OUT
717+ USBD_LL_OpenEP (pdev ,
718+ hid_out_ep ,
719+ USBD_EP_TYPE_INTR ,
720+ mps_out );
721+
722+ // Prepare Out endpoint to receive next packet
723+ USBD_LL_PrepareReceive (pdev , hid_out_ep , CDC_ClassData .RxBuffer , mps_out );
694724
695725 HID_ClassData .state = HID_IDLE ;
696726 }
@@ -730,6 +760,7 @@ static uint8_t USBD_CDC_MSC_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
730760
731761 // close endpoints
732762 USBD_LL_CloseEP (pdev , hid_in_ep );
763+ USBD_LL_CloseEP (pdev , hid_out_ep );
733764 }
734765
735766 return 0 ;
0 commit comments