diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 35a5c9e79b4..2fc80dfe77c 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -378,6 +378,8 @@ usbd_cdc_itf_t *usb_vcp_get(int idx) { pyb.usb_mode(None) # disable USB pyb.usb_mode('VCP') # enable with VCP interface pyb.usb_mode('VCP+MSC') # enable with VCP and MSC interfaces + pyb.usb_mode('HID') # enable with HID interface + pyb.usb_mode('MSC+HID') # enable with MSC and HID interfaces pyb.usb_mode('VCP+HID') # enable with VCP and HID, defaulting to mouse protocol pyb.usb_mode('VCP+HID', vid=0xf055, pid=0x9800) # specify VID and PID pyb.usb_mode('VCP+HID', hid=pyb.hid_mouse) @@ -544,6 +546,20 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * pid = USBD_PID_CDC; } mode = USBD_MODE_CDC; + #if MICROPY_HW_USB_HID + } else if (strcmp(mode_str, "HID") == 0) { + if (pid == -1) { + pid = USBD_PID_HID; + } + mode = USBD_MODE_HID; + #if MICROPY_HW_USB_MSC + } else if (strcmp(mode_str, "MSC+HID") == 0) { + if (pid == -1) { + pid = USBD_PID_MSC_HID; + } + mode = USBD_MODE_MSC_HID; + #endif + #endif } else if (strcmp(mode_str, "MSC") == 0) { if (pid == -1) { pid = USBD_PID_MSC; diff --git a/ports/stm32/usb.h b/ports/stm32/usb.h index f69af86e5b3..ff3232a29f3 100644 --- a/ports/stm32/usb.h +++ b/ports/stm32/usb.h @@ -43,6 +43,8 @@ #define USBD_PID_CDC_MSC_HID (0x9808) #define USBD_PID_CDC2_MSC_HID (0x9809) #define USBD_PID_CDC3_MSC_HID (0x980a) +#define USBD_PID_HID (0x980b) +#define USBD_PID_MSC_HID (0x980c) typedef enum { PYB_USB_STORAGE_MEDIUM_NONE = 0, diff --git a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c index f206dc2e91e..c7d91d2b94e 100644 --- a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c @@ -504,6 +504,19 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode num_itf = 1; break; + #if MICROPY_HW_USB_HID + case USBD_MODE_MSC_HID: + n += make_msc_desc(d + n); + usbd->hid->desc = d + n; + n += make_hid_desc_ep(d + n, hid_info, HID_IFACE_NUM_WITH_MSC, HID_IN_EP_WITH_MSC, HID_OUT_EP_WITH_MSC); + usbd->hid->in_ep = HID_IN_EP_WITH_MSC; + usbd->hid->out_ep = HID_OUT_EP_WITH_MSC; + usbd->hid->iface_num = HID_IFACE_NUM_WITH_MSC; + usbd->hid->report_desc = hid_info->report_desc; + num_itf = 2; + break; + #endif + case USBD_MODE_CDC_MSC: n += make_msc_desc(d + n); n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_WITH_MSC); @@ -612,6 +625,18 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode #endif #if MICROPY_HW_USB_HID + case USBD_MODE_HID: + // Standalone HID uses the same interface and endpoints as the HID part + // of CDC+HID (interface 0 and endpoint 1), so reuse that layout here. + usbd->hid->desc = d + n; + n += make_hid_desc(d + n, hid_info, HID_IFACE_NUM_WITH_CDC); + usbd->hid->in_ep = HID_IN_EP_WITH_CDC; + usbd->hid->out_ep = HID_OUT_EP_WITH_CDC; + usbd->hid->iface_num = HID_IFACE_NUM_WITH_CDC; + usbd->hid->report_desc = hid_info->report_desc; + num_itf = 1; + break; + case USBD_MODE_CDC_HID: usbd->hid->desc = d + n; n += make_hid_desc(d + n, hid_info, HID_IFACE_NUM_WITH_CDC); @@ -631,15 +656,6 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode num_itf = 2; break; - /* - // 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; - */ - default: // mode not supported return -1; @@ -1122,6 +1138,7 @@ static uint8_t *USBD_CDC_MSC_HID_GetCfgDesc(USBD_HandleTypeDef *pdev, uint16_t * uint8_t *msc_desc = NULL; switch (usbd->usbd_mode & USBD_MODE_IFACE_MASK) { #if MICROPY_HW_USB_MSC + case USBD_MODE_MSC_HID: case USBD_MODE_MSC: msc_desc = usbd->usbd_config_desc + MSC_TEMPLATE_MSC_DESC_OFFSET; break;