diff --git a/ports/stm32/qstrdefsport.h b/ports/stm32/qstrdefsport.h index bc07f2752a..e7d84cbec0 100644 --- a/ports/stm32/qstrdefsport.h +++ b/ports/stm32/qstrdefsport.h @@ -38,7 +38,19 @@ Q(/) #if MICROPY_HW_ENABLE_USB // for usb modes -Q(MSC+HID) +Q(VCP) +Q(MSC) Q(VCP+MSC) Q(VCP+HID) +Q(VCP+MSC+HID) +#if MICROPY_HW_USB_CDC_NUM >= 2 +Q(2xVCP) +Q(2xVCP+MSC) +Q(2xVCP+MSC+HID) +#endif +#if MICROPY_HW_USB_CDC_NUM >= 3 +Q(3xVCP) +Q(3xVCP+MSC) +Q(3xVCP+MSC+HID) +#endif #endif diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 1ed45592e9..9a9600f89d 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -396,6 +396,35 @@ usbd_cdc_itf_t *usb_vcp_get(int idx) { pyb.usb_mode(..., port=2) # for second USB port */ +typedef struct _pyb_usb_mode_table_t { + uint8_t usbd_mode; + uint16_t qst; + const char *deprecated_str; + uint16_t default_pid; +} pyb_usb_mode_table_t; + +// These are all the modes supported by USBD_SelectMode. +// Note: there are some names (eg CDC, VCP+VCP) which are supported for backwards compatibility. +STATIC const pyb_usb_mode_table_t pyb_usb_mode_table[] = { + { USBD_MODE_CDC, MP_QSTR_VCP, "CDC", MICROPY_HW_USB_PID_CDC }, + { USBD_MODE_MSC, MP_QSTR_MSC, NULL, MICROPY_HW_USB_PID_MSC }, + { USBD_MODE_CDC_MSC, MP_QSTR_VCP_plus_MSC, "CDC+MSC", MICROPY_HW_USB_PID_CDC_MSC }, + { USBD_MODE_CDC_HID, MP_QSTR_VCP_plus_HID, "CDC+HID", MICROPY_HW_USB_PID_CDC_HID }, + { USBD_MODE_CDC_MSC_HID, MP_QSTR_VCP_plus_MSC_plus_HID, NULL, MICROPY_HW_USB_PID_CDC_MSC_HID }, + + #if MICROPY_HW_USB_CDC_NUM >= 2 + { USBD_MODE_CDC2, MP_QSTR_2xVCP, "VCP+VCP", MICROPY_HW_USB_PID_CDC2 }, + { USBD_MODE_CDC2_MSC, MP_QSTR_2xVCP_plus_MSC, "VCP+VCP+MSC", MICROPY_HW_USB_PID_CDC2_MSC }, + { USBD_MODE_CDC2_MSC_HID, MP_QSTR_2xVCP_plus_MSC_plus_HID, NULL, MICROPY_HW_USB_PID_CDC2_MSC_HID }, + #endif + + #if MICROPY_HW_USB_CDC_NUM >= 3 + { USBD_MODE_CDC3, MP_QSTR_3xVCP, NULL, MICROPY_HW_USB_PID_CDC3 }, + { USBD_MODE_CDC3_MSC, MP_QSTR_3xVCP_plus_MSC, NULL, MICROPY_HW_USB_PID_CDC3_MSC }, + { USBD_MODE_CDC3_MSC_HID, MP_QSTR_3xVCP_plus_MSC_plus_HID, NULL, MICROPY_HW_USB_PID_CDC3_MSC_HID }, + #endif +}; + STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_mode, ARG_port, ARG_vid, ARG_pid, @@ -430,23 +459,14 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * #if defined(USE_HOST_MODE) return MP_OBJ_NEW_QSTR(MP_QSTR_host); #else - uint8_t mode = USBD_GetMode(&usb_device.usbd_cdc_msc_hid_state); - switch (mode & USBD_MODE_IFACE_MASK) { - case USBD_MODE_CDC: - return MP_OBJ_NEW_QSTR(MP_QSTR_VCP); - case USBD_MODE_MSC: - return MP_OBJ_NEW_QSTR(MP_QSTR_MSC); - case USBD_MODE_HID: - return MP_OBJ_NEW_QSTR(MP_QSTR_HID); - case USBD_MODE_CDC_MSC: - return MP_OBJ_NEW_QSTR(MP_QSTR_VCP_plus_MSC); - case USBD_MODE_CDC_HID: - return MP_OBJ_NEW_QSTR(MP_QSTR_VCP_plus_HID); - case USBD_MODE_MSC_HID: - return MP_OBJ_NEW_QSTR(MP_QSTR_MSC_plus_HID); - default: - return mp_const_none; + uint8_t mode = USBD_GetMode(&usb_device.usbd_cdc_msc_hid_state) & USBD_MODE_IFACE_MASK; + for (size_t i = 0; i < MP_ARRAY_SIZE(pyb_usb_mode_table); ++i) { + const pyb_usb_mode_table_t *m = &pyb_usb_mode_table[i]; + if (mode == m->usbd_mode) { + return MP_OBJ_NEW_QSTR(m->qst); + } } + return mp_const_none; #endif } @@ -483,70 +503,21 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * // get the VID, PID and USB mode // note: PID=-1 means select PID based on mode - // note: we support CDC as a synonym for VCP for backward compatibility uint16_t vid = args[ARG_vid].u_int; mp_int_t pid = args[ARG_pid].u_int; - uint8_t mode; - if (strcmp(mode_str, "CDC+MSC") == 0 || strcmp(mode_str, "VCP+MSC") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC_MSC; + uint8_t mode = 0; + for (size_t i = 0; i < MP_ARRAY_SIZE(pyb_usb_mode_table); ++i) { + const pyb_usb_mode_table_t *m = &pyb_usb_mode_table[i]; + if (strcmp(mode_str, qstr_str(m->qst)) == 0 + || (m->deprecated_str != NULL && strcmp(mode_str, m->deprecated_str) == 0)) { + if (pid == -1) { + pid = m->default_pid; + } + mode = m->usbd_mode; + break; } - mode = USBD_MODE_CDC_MSC; - } else if (strcmp(mode_str, "VCP+MSC+HID") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC_MSC_HID; - } - mode = USBD_MODE_CDC_MSC_HID; - #if MICROPY_HW_USB_CDC_NUM >= 2 - } else if (strcmp(mode_str, "VCP+VCP") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC2; - } - mode = USBD_MODE_CDC2; - } else if (strcmp(mode_str, "VCP+VCP+MSC") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC2_MSC; - } - mode = USBD_MODE_CDC2_MSC; - } else if (strcmp(mode_str, "2xVCP+MSC+HID") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC2_MSC_HID; - } - mode = USBD_MODE_CDC2_MSC_HID; - #endif - #if MICROPY_HW_USB_CDC_NUM >= 3 - } else if (strcmp(mode_str, "3xVCP") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC3; - } - mode = USBD_MODE_CDC3; - } else if (strcmp(mode_str, "3xVCP+MSC") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC3_MSC; - } - mode = USBD_MODE_CDC3_MSC; - } else if (strcmp(mode_str, "3xVCP+MSC+HID") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC3_MSC_HID; - } - mode = USBD_MODE_CDC3_MSC_HID; - #endif - } else if (strcmp(mode_str, "CDC+HID") == 0 || strcmp(mode_str, "VCP+HID") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC_HID; - } - mode = USBD_MODE_CDC_HID; - } else if (strcmp(mode_str, "CDC") == 0 || strcmp(mode_str, "VCP") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_CDC; - } - mode = USBD_MODE_CDC; - } else if (strcmp(mode_str, "MSC") == 0) { - if (pid == -1) { - pid = MICROPY_HW_USB_PID_MSC; - } - mode = USBD_MODE_MSC; - } else { + } + if (mode == 0) { goto bad_mode; }