Browse Source

stm32/usb: Use a table of allowed values to simplify usb_mode get/set.

This reduces code size and code duplication, and fixes `pyb.usb_mode()` so
that it now returns the correct string when in multi-VCP mode (before, it
would return None when in one of these modes).

Signed-off-by: Damien George <damien@micropython.org>
pull/8026/head
Damien George 3 years ago
parent
commit
196d26848a
  1. 14
      ports/stm32/qstrdefsport.h
  2. 125
      ports/stm32/usb.c

14
ports/stm32/qstrdefsport.h

@ -38,7 +38,19 @@ Q(/)
#if MICROPY_HW_ENABLE_USB #if MICROPY_HW_ENABLE_USB
// for usb modes // for usb modes
Q(MSC+HID) Q(VCP)
Q(MSC)
Q(VCP+MSC) Q(VCP+MSC)
Q(VCP+HID) 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 #endif

125
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 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) { STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { enum {
ARG_mode, ARG_port, ARG_vid, ARG_pid, 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) #if defined(USE_HOST_MODE)
return MP_OBJ_NEW_QSTR(MP_QSTR_host); return MP_OBJ_NEW_QSTR(MP_QSTR_host);
#else #else
uint8_t mode = USBD_GetMode(&usb_device.usbd_cdc_msc_hid_state); uint8_t mode = USBD_GetMode(&usb_device.usbd_cdc_msc_hid_state) & USBD_MODE_IFACE_MASK;
switch (mode & USBD_MODE_IFACE_MASK) { for (size_t i = 0; i < MP_ARRAY_SIZE(pyb_usb_mode_table); ++i) {
case USBD_MODE_CDC: const pyb_usb_mode_table_t *m = &pyb_usb_mode_table[i];
return MP_OBJ_NEW_QSTR(MP_QSTR_VCP); if (mode == m->usbd_mode) {
case USBD_MODE_MSC: return MP_OBJ_NEW_QSTR(m->qst);
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;
} }
return mp_const_none;
#endif #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 // get the VID, PID and USB mode
// note: PID=-1 means select PID based on 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; uint16_t vid = args[ARG_vid].u_int;
mp_int_t pid = args[ARG_pid].u_int; mp_int_t pid = args[ARG_pid].u_int;
uint8_t mode; uint8_t mode = 0;
if (strcmp(mode_str, "CDC+MSC") == 0 || strcmp(mode_str, "VCP+MSC") == 0) { for (size_t i = 0; i < MP_ARRAY_SIZE(pyb_usb_mode_table); ++i) {
if (pid == -1) { const pyb_usb_mode_table_t *m = &pyb_usb_mode_table[i];
pid = MICROPY_HW_USB_PID_CDC_MSC; if (strcmp(mode_str, qstr_str(m->qst)) == 0
} || (m->deprecated_str != NULL && strcmp(mode_str, m->deprecated_str) == 0)) {
mode = USBD_MODE_CDC_MSC; if (pid == -1) {
} else if (strcmp(mode_str, "VCP+MSC+HID") == 0) { pid = m->default_pid;
if (pid == -1) { }
pid = MICROPY_HW_USB_PID_CDC_MSC_HID; mode = m->usbd_mode;
} break;
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; goto bad_mode;
} }

Loading…
Cancel
Save