aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George2019-06-11 16:10:52 +1000
committerDamien George2019-06-11 16:22:09 +1000
commit53200247b779358ffa03e1b7a8d1e9964befc234 (patch)
tree709d93c91e263cbbdb0fd50edb050acd9877cc26
parent9e68eec8eac1188eab0bc059560b877928783978 (diff)
stm32/usb: Add "msc" kw-arg to pyb.usb_mode to select MSC logical units.
With this the user can select multiple logical units to expose over USB MSC at once, eg: pyb.usb_mode('VCP+MSC', msc=(pyb.Flash(), pyb.SDCard())). The default behaviour is the original behaviour of just one unit at a time.
-rw-r--r--ports/stm32/main.c2
-rw-r--r--ports/stm32/usb.c57
-rw-r--r--ports/stm32/usb.h2
-rw-r--r--ports/stm32/usbd_msc_interface.c2
-rw-r--r--ports/stm32/usbd_msc_interface.h2
5 files changed, 47 insertions, 18 deletions
diff --git a/ports/stm32/main.c b/ports/stm32/main.c
index 3852ff9b0..44e29921b 100644
--- a/ports/stm32/main.c
+++ b/ports/stm32/main.c
@@ -645,7 +645,7 @@ soft_reset:
#if MICROPY_HW_ENABLE_USB
// init USB device to default setting if it was not already configured
if (!(pyb_usb_flags & PYB_USB_FLAG_USB_MODE_CALLED)) {
- pyb_usb_dev_init(USBD_VID, USBD_PID_CDC_MSC, USBD_MODE_CDC_MSC, NULL);
+ pyb_usb_dev_init(USBD_VID, USBD_PID_CDC_MSC, USBD_MODE_CDC_MSC, 0, NULL, NULL);
}
#endif
diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c
index 158265411..3e432fc8e 100644
--- a/ports/stm32/usb.c
+++ b/ports/stm32/usb.c
@@ -120,7 +120,7 @@ void pyb_usb_init0(void) {
pyb_usb_vcp_init0();
}
-bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, uint8_t mode, USBD_HID_ModeInfoTypeDef *hid_info) {
+bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, uint8_t mode, size_t msc_n, const void *msc_unit, USBD_HID_ModeInfoTypeDef *hid_info) {
usb_device_t *usb_dev = &usb_device;
if (!usb_dev->enabled) {
// only init USB once in the device's power-lifetime
@@ -146,18 +146,22 @@ bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, uint8_t mode, USBD_HID_ModeInf
}
// Configure the MSC interface
- const void *lu[1];
- switch (pyb_usb_storage_medium) {
- #if MICROPY_HW_ENABLE_SDCARD
- case PYB_USB_STORAGE_MEDIUM_SDCARD:
- lu[0] = &pyb_sdcard_type;
- break;
- #endif
- default:
- lu[0] = &pyb_flash_type;
- break;
+ const void *msc_unit_default[1];
+ if (msc_n == 0) {
+ msc_n = 1;
+ msc_unit = msc_unit_default;
+ switch (pyb_usb_storage_medium) {
+ #if MICROPY_HW_ENABLE_SDCARD
+ case PYB_USB_STORAGE_MEDIUM_SDCARD:
+ msc_unit_default[0] = &pyb_sdcard_type;
+ break;
+ #endif
+ default:
+ msc_unit_default[0] = &pyb_flash_type;
+ break;
+ }
}
- usbd_msc_init_lu(1, lu);
+ usbd_msc_init_lu(msc_n, msc_unit);
USBD_MSC_RegisterStorage(&usb_dev->usbd_cdc_msc_hid_state, (USBD_StorageTypeDef*)&usbd_msc_fops);
// start the USB device
@@ -226,11 +230,12 @@ usbd_cdc_itf_t *usb_vcp_get(int idx) {
*/
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_vid, ARG_pid, ARG_hid, ARG_high_speed };
+ enum { ARG_mode, ARG_vid, ARG_pid, ARG_msc, ARG_hid, ARG_high_speed };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
{ MP_QSTR_vid, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = USBD_VID} },
{ MP_QSTR_pid, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
+ { MP_QSTR_msc, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_empty_tuple_obj)} },
{ MP_QSTR_hid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&pyb_usb_hid_mouse_obj)} },
#if USBD_SUPPORT_HS_MODE
{ MP_QSTR_high_speed, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
@@ -347,6 +352,30 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
goto bad_mode;
}
+ // Get MSC logical units
+ size_t msc_n = 0;
+ const void *msc_unit[USBD_MSC_MAX_LUN];
+ if (mode & USBD_MODE_IFACE_MSC) {
+ mp_obj_t *items;
+ mp_obj_get_array(args[ARG_msc].u_obj, &msc_n, &items);
+ if (msc_n > USBD_MSC_MAX_LUN) {
+ mp_raise_ValueError("too many logical units");
+ }
+ for (size_t i = 0; i < msc_n; ++i) {
+ mp_obj_type_t *type = mp_obj_get_type(items[i]);
+ if (type == &pyb_flash_type
+ || type == &pyb_sdcard_type
+ #if MICROPY_HW_ENABLE_MMCARD
+ || type == &pyb_mmcard_type
+ #endif
+ ) {
+ msc_unit[i] = type;
+ } else {
+ mp_raise_ValueError("unsupported logical unit");
+ }
+ }
+ }
+
// get hid info if user selected such a mode
USBD_HID_ModeInfoTypeDef hid_info;
if (mode & USBD_MODE_IFACE_HID) {
@@ -372,7 +401,7 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
#endif
// init the USB device
- if (!pyb_usb_dev_init(vid, pid, mode, &hid_info)) {
+ if (!pyb_usb_dev_init(vid, pid, mode, msc_n, msc_unit, &hid_info)) {
goto bad_mode;
}
diff --git a/ports/stm32/usb.h b/ports/stm32/usb.h
index 0aa50f9e7..b1c8b476a 100644
--- a/ports/stm32/usb.h
+++ b/ports/stm32/usb.h
@@ -66,7 +66,7 @@ MP_DECLARE_CONST_FUN_OBJ_0(pyb_have_cdc_obj); // deprecated
MP_DECLARE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj); // deprecated
void pyb_usb_init0(void);
-bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, uint8_t mode, USBD_HID_ModeInfoTypeDef *hid_info);
+bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, uint8_t mode, size_t msc_n, const void *msc_unit, USBD_HID_ModeInfoTypeDef *hid_info);
void pyb_usb_dev_deinit(void);
bool usb_vcp_is_enabled(void);
int usb_vcp_recv_byte(uint8_t *c); // if a byte is available, return 1 and put the byte in *c, else return 0
diff --git a/ports/stm32/usbd_msc_interface.c b/ports/stm32/usbd_msc_interface.c
index 0148fc7c6..1f9f68ed8 100644
--- a/ports/stm32/usbd_msc_interface.c
+++ b/ports/stm32/usbd_msc_interface.c
@@ -33,8 +33,6 @@
#include "storage.h"
#include "sdcard.h"
-#define USBD_MSC_MAX_LUN (2)
-
// This flag is needed to support removal of the medium, so that the USB drive
// can be unmounted and won't be remounted automatically.
#define FLAGS_STARTED (0x01)
diff --git a/ports/stm32/usbd_msc_interface.h b/ports/stm32/usbd_msc_interface.h
index 9d25a72a3..411c707ca 100644
--- a/ports/stm32/usbd_msc_interface.h
+++ b/ports/stm32/usbd_msc_interface.h
@@ -26,6 +26,8 @@
#ifndef MICROPY_INCLUDED_STM32_USBD_MSC_INTERFACE_H
#define MICROPY_INCLUDED_STM32_USBD_MSC_INTERFACE_H
+#define USBD_MSC_MAX_LUN (2)
+
extern const USBD_StorageTypeDef usbd_msc_fops;
void usbd_msc_init_lu(size_t lu_n, const void *lu_data);