Skip to content

Commit 196d268

Browse files
committed
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>
1 parent d49df42 commit 196d268

File tree

2 files changed

+61
-78
lines changed

2 files changed

+61
-78
lines changed

ports/stm32/qstrdefsport.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,19 @@ Q(/)
3838

3939
#if MICROPY_HW_ENABLE_USB
4040
// for usb modes
41-
Q(MSC+HID)
41+
Q(VCP)
42+
Q(MSC)
4243
Q(VCP+MSC)
4344
Q(VCP+HID)
45+
Q(VCP+MSC+HID)
46+
#if MICROPY_HW_USB_CDC_NUM >= 2
47+
Q(2xVCP)
48+
Q(2xVCP+MSC)
49+
Q(2xVCP+MSC+HID)
50+
#endif
51+
#if MICROPY_HW_USB_CDC_NUM >= 3
52+
Q(3xVCP)
53+
Q(3xVCP+MSC)
54+
Q(3xVCP+MSC+HID)
55+
#endif
4456
#endif

ports/stm32/usb.c

Lines changed: 48 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,35 @@ usbd_cdc_itf_t *usb_vcp_get(int idx) {
396396
pyb.usb_mode(..., port=2) # for second USB port
397397
*/
398398

399+
typedef struct _pyb_usb_mode_table_t {
400+
uint8_t usbd_mode;
401+
uint16_t qst;
402+
const char *deprecated_str;
403+
uint16_t default_pid;
404+
} pyb_usb_mode_table_t;
405+
406+
// These are all the modes supported by USBD_SelectMode.
407+
// Note: there are some names (eg CDC, VCP+VCP) which are supported for backwards compatibility.
408+
STATIC const pyb_usb_mode_table_t pyb_usb_mode_table[] = {
409+
{ USBD_MODE_CDC, MP_QSTR_VCP, "CDC", MICROPY_HW_USB_PID_CDC },
410+
{ USBD_MODE_MSC, MP_QSTR_MSC, NULL, MICROPY_HW_USB_PID_MSC },
411+
{ USBD_MODE_CDC_MSC, MP_QSTR_VCP_plus_MSC, "CDC+MSC", MICROPY_HW_USB_PID_CDC_MSC },
412+
{ USBD_MODE_CDC_HID, MP_QSTR_VCP_plus_HID, "CDC+HID", MICROPY_HW_USB_PID_CDC_HID },
413+
{ USBD_MODE_CDC_MSC_HID, MP_QSTR_VCP_plus_MSC_plus_HID, NULL, MICROPY_HW_USB_PID_CDC_MSC_HID },
414+
415+
#if MICROPY_HW_USB_CDC_NUM >= 2
416+
{ USBD_MODE_CDC2, MP_QSTR_2xVCP, "VCP+VCP", MICROPY_HW_USB_PID_CDC2 },
417+
{ USBD_MODE_CDC2_MSC, MP_QSTR_2xVCP_plus_MSC, "VCP+VCP+MSC", MICROPY_HW_USB_PID_CDC2_MSC },
418+
{ USBD_MODE_CDC2_MSC_HID, MP_QSTR_2xVCP_plus_MSC_plus_HID, NULL, MICROPY_HW_USB_PID_CDC2_MSC_HID },
419+
#endif
420+
421+
#if MICROPY_HW_USB_CDC_NUM >= 3
422+
{ USBD_MODE_CDC3, MP_QSTR_3xVCP, NULL, MICROPY_HW_USB_PID_CDC3 },
423+
{ USBD_MODE_CDC3_MSC, MP_QSTR_3xVCP_plus_MSC, NULL, MICROPY_HW_USB_PID_CDC3_MSC },
424+
{ USBD_MODE_CDC3_MSC_HID, MP_QSTR_3xVCP_plus_MSC_plus_HID, NULL, MICROPY_HW_USB_PID_CDC3_MSC_HID },
425+
#endif
426+
};
427+
399428
STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
400429
enum {
401430
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 *
430459
#if defined(USE_HOST_MODE)
431460
return MP_OBJ_NEW_QSTR(MP_QSTR_host);
432461
#else
433-
uint8_t mode = USBD_GetMode(&usb_device.usbd_cdc_msc_hid_state);
434-
switch (mode & USBD_MODE_IFACE_MASK) {
435-
case USBD_MODE_CDC:
436-
return MP_OBJ_NEW_QSTR(MP_QSTR_VCP);
437-
case USBD_MODE_MSC:
438-
return MP_OBJ_NEW_QSTR(MP_QSTR_MSC);
439-
case USBD_MODE_HID:
440-
return MP_OBJ_NEW_QSTR(MP_QSTR_HID);
441-
case USBD_MODE_CDC_MSC:
442-
return MP_OBJ_NEW_QSTR(MP_QSTR_VCP_plus_MSC);
443-
case USBD_MODE_CDC_HID:
444-
return MP_OBJ_NEW_QSTR(MP_QSTR_VCP_plus_HID);
445-
case USBD_MODE_MSC_HID:
446-
return MP_OBJ_NEW_QSTR(MP_QSTR_MSC_plus_HID);
447-
default:
448-
return mp_const_none;
462+
uint8_t mode = USBD_GetMode(&usb_device.usbd_cdc_msc_hid_state) & USBD_MODE_IFACE_MASK;
463+
for (size_t i = 0; i < MP_ARRAY_SIZE(pyb_usb_mode_table); ++i) {
464+
const pyb_usb_mode_table_t *m = &pyb_usb_mode_table[i];
465+
if (mode == m->usbd_mode) {
466+
return MP_OBJ_NEW_QSTR(m->qst);
467+
}
449468
}
469+
return mp_const_none;
450470
#endif
451471
}
452472

@@ -483,70 +503,21 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
483503

484504
// get the VID, PID and USB mode
485505
// note: PID=-1 means select PID based on mode
486-
// note: we support CDC as a synonym for VCP for backward compatibility
487506
uint16_t vid = args[ARG_vid].u_int;
488507
mp_int_t pid = args[ARG_pid].u_int;
489-
uint8_t mode;
490-
if (strcmp(mode_str, "CDC+MSC") == 0 || strcmp(mode_str, "VCP+MSC") == 0) {
491-
if (pid == -1) {
492-
pid = MICROPY_HW_USB_PID_CDC_MSC;
493-
}
494-
mode = USBD_MODE_CDC_MSC;
495-
} else if (strcmp(mode_str, "VCP+MSC+HID") == 0) {
496-
if (pid == -1) {
497-
pid = MICROPY_HW_USB_PID_CDC_MSC_HID;
498-
}
499-
mode = USBD_MODE_CDC_MSC_HID;
500-
#if MICROPY_HW_USB_CDC_NUM >= 2
501-
} else if (strcmp(mode_str, "VCP+VCP") == 0) {
502-
if (pid == -1) {
503-
pid = MICROPY_HW_USB_PID_CDC2;
504-
}
505-
mode = USBD_MODE_CDC2;
506-
} else if (strcmp(mode_str, "VCP+VCP+MSC") == 0) {
507-
if (pid == -1) {
508-
pid = MICROPY_HW_USB_PID_CDC2_MSC;
509-
}
510-
mode = USBD_MODE_CDC2_MSC;
511-
} else if (strcmp(mode_str, "2xVCP+MSC+HID") == 0) {
512-
if (pid == -1) {
513-
pid = MICROPY_HW_USB_PID_CDC2_MSC_HID;
514-
}
515-
mode = USBD_MODE_CDC2_MSC_HID;
516-
#endif
517-
#if MICROPY_HW_USB_CDC_NUM >= 3
518-
} else if (strcmp(mode_str, "3xVCP") == 0) {
519-
if (pid == -1) {
520-
pid = MICROPY_HW_USB_PID_CDC3;
521-
}
522-
mode = USBD_MODE_CDC3;
523-
} else if (strcmp(mode_str, "3xVCP+MSC") == 0) {
524-
if (pid == -1) {
525-
pid = MICROPY_HW_USB_PID_CDC3_MSC;
526-
}
527-
mode = USBD_MODE_CDC3_MSC;
528-
} else if (strcmp(mode_str, "3xVCP+MSC+HID") == 0) {
529-
if (pid == -1) {
530-
pid = MICROPY_HW_USB_PID_CDC3_MSC_HID;
531-
}
532-
mode = USBD_MODE_CDC3_MSC_HID;
533-
#endif
534-
} else if (strcmp(mode_str, "CDC+HID") == 0 || strcmp(mode_str, "VCP+HID") == 0) {
535-
if (pid == -1) {
536-
pid = MICROPY_HW_USB_PID_CDC_HID;
537-
}
538-
mode = USBD_MODE_CDC_HID;
539-
} else if (strcmp(mode_str, "CDC") == 0 || strcmp(mode_str, "VCP") == 0) {
540-
if (pid == -1) {
541-
pid = MICROPY_HW_USB_PID_CDC;
542-
}
543-
mode = USBD_MODE_CDC;
544-
} else if (strcmp(mode_str, "MSC") == 0) {
545-
if (pid == -1) {
546-
pid = MICROPY_HW_USB_PID_MSC;
508+
uint8_t mode = 0;
509+
for (size_t i = 0; i < MP_ARRAY_SIZE(pyb_usb_mode_table); ++i) {
510+
const pyb_usb_mode_table_t *m = &pyb_usb_mode_table[i];
511+
if (strcmp(mode_str, qstr_str(m->qst)) == 0
512+
|| (m->deprecated_str != NULL && strcmp(mode_str, m->deprecated_str) == 0)) {
513+
if (pid == -1) {
514+
pid = m->default_pid;
515+
}
516+
mode = m->usbd_mode;
517+
break;
547518
}
548-
mode = USBD_MODE_MSC;
549-
} else {
519+
}
520+
if (mode == 0) {
550521
goto bad_mode;
551522
}
552523

0 commit comments

Comments
 (0)