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.
This commit is contained in:
parent
9e68eec8ea
commit
53200247b7
@ -645,7 +645,7 @@ soft_reset:
|
|||||||
#if MICROPY_HW_ENABLE_USB
|
#if MICROPY_HW_ENABLE_USB
|
||||||
// init USB device to default setting if it was not already configured
|
// init USB device to default setting if it was not already configured
|
||||||
if (!(pyb_usb_flags & PYB_USB_FLAG_USB_MODE_CALLED)) {
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ void pyb_usb_init0(void) {
|
|||||||
pyb_usb_vcp_init0();
|
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;
|
usb_device_t *usb_dev = &usb_device;
|
||||||
if (!usb_dev->enabled) {
|
if (!usb_dev->enabled) {
|
||||||
// only init USB once in the device's power-lifetime
|
// 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
|
// Configure the MSC interface
|
||||||
const void *lu[1];
|
const void *msc_unit_default[1];
|
||||||
|
if (msc_n == 0) {
|
||||||
|
msc_n = 1;
|
||||||
|
msc_unit = msc_unit_default;
|
||||||
switch (pyb_usb_storage_medium) {
|
switch (pyb_usb_storage_medium) {
|
||||||
#if MICROPY_HW_ENABLE_SDCARD
|
#if MICROPY_HW_ENABLE_SDCARD
|
||||||
case PYB_USB_STORAGE_MEDIUM_SDCARD:
|
case PYB_USB_STORAGE_MEDIUM_SDCARD:
|
||||||
lu[0] = &pyb_sdcard_type;
|
msc_unit_default[0] = &pyb_sdcard_type;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
lu[0] = &pyb_flash_type;
|
msc_unit_default[0] = &pyb_flash_type;
|
||||||
break;
|
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);
|
USBD_MSC_RegisterStorage(&usb_dev->usbd_cdc_msc_hid_state, (USBD_StorageTypeDef*)&usbd_msc_fops);
|
||||||
|
|
||||||
// start the USB device
|
// 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) {
|
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[] = {
|
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_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_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_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)} },
|
{ 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
|
#if USBD_SUPPORT_HS_MODE
|
||||||
{ MP_QSTR_high_speed, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
{ 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;
|
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
|
// get hid info if user selected such a mode
|
||||||
USBD_HID_ModeInfoTypeDef hid_info;
|
USBD_HID_ModeInfoTypeDef hid_info;
|
||||||
if (mode & USBD_MODE_IFACE_HID) {
|
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
|
#endif
|
||||||
|
|
||||||
// init the USB device
|
// 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;
|
goto bad_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
MP_DECLARE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj); // deprecated
|
||||||
|
|
||||||
void pyb_usb_init0(void);
|
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);
|
void pyb_usb_dev_deinit(void);
|
||||||
bool usb_vcp_is_enabled(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
|
int usb_vcp_recv_byte(uint8_t *c); // if a byte is available, return 1 and put the byte in *c, else return 0
|
||||||
|
@ -33,8 +33,6 @@
|
|||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
#include "sdcard.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
|
// This flag is needed to support removal of the medium, so that the USB drive
|
||||||
// can be unmounted and won't be remounted automatically.
|
// can be unmounted and won't be remounted automatically.
|
||||||
#define FLAGS_STARTED (0x01)
|
#define FLAGS_STARTED (0x01)
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#ifndef MICROPY_INCLUDED_STM32_USBD_MSC_INTERFACE_H
|
#ifndef MICROPY_INCLUDED_STM32_USBD_MSC_INTERFACE_H
|
||||||
#define 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;
|
extern const USBD_StorageTypeDef usbd_msc_fops;
|
||||||
|
|
||||||
void usbd_msc_init_lu(size_t lu_n, const void *lu_data);
|
void usbd_msc_init_lu(size_t lu_n, const void *lu_data);
|
||||||
|
Loading…
Reference in New Issue
Block a user