stm32/usb: Refactor CDC VCP code to enable N CDC interfaces.

The board config option MICROPY_HW_USB_ENABLE_CDC2 is now changed to
MICROPY_HW_USB_CDC_NUM, and the latter should be defined to the maximum
number of CDC interfaces to support (defaults to 1).
This commit is contained in:
Damien George 2019-05-18 23:01:36 +10:00
parent a4f1d82757
commit 0c29502ad9
9 changed files with 183 additions and 225 deletions

View File

@ -558,10 +558,6 @@ soft_reset:
#if MICROPY_HW_ENABLE_USB #if MICROPY_HW_ENABLE_USB
pyb_usb_init0(); pyb_usb_init0();
// Activate USB_VCP(0) on dupterm slot 1 for the REPL
MP_STATE_VM(dupterm_objs[1]) = MP_OBJ_FROM_PTR(&pyb_usb_vcp_obj);
usb_vcp_attach_to_repl(&pyb_usb_vcp_obj, true);
#endif #endif
// Initialise the local flash filesystem. // Initialise the local flash filesystem.

View File

@ -264,6 +264,10 @@
#define MICROPY_HW_MAX_CAN (1) #define MICROPY_HW_MAX_CAN (1)
#endif #endif
// Configure maximum number of CDC VCP interfaces
#ifndef MICROPY_HW_USB_CDC_NUM
#define MICROPY_HW_USB_CDC_NUM (1)
#endif
// Pin definition header file // Pin definition header file
#define MICROPY_PIN_DEFS_PORT_H "pin_defs_stm32.h" #define MICROPY_PIN_DEFS_PORT_H "pin_defs_stm32.h"

View File

@ -55,6 +55,8 @@
#endif #endif
#endif #endif
STATIC void pyb_usb_vcp_init0(void);
// this will be persistent across a soft-reset // this will be persistent across a soft-reset
mp_uint_t pyb_usb_flags = 0; mp_uint_t pyb_usb_flags = 0;
@ -62,10 +64,7 @@ typedef struct _usb_device_t {
uint32_t enabled; uint32_t enabled;
USBD_HandleTypeDef hUSBDDevice; USBD_HandleTypeDef hUSBDDevice;
usbd_cdc_msc_hid_state_t usbd_cdc_msc_hid_state; usbd_cdc_msc_hid_state_t usbd_cdc_msc_hid_state;
usbd_cdc_itf_t usbd_cdc_itf; usbd_cdc_itf_t usbd_cdc_itf[MICROPY_HW_USB_CDC_NUM];
#if MICROPY_HW_USB_ENABLE_CDC2
usbd_cdc_itf_t usbd_cdc2_itf;
#endif
usbd_hid_itf_t usbd_hid_itf; usbd_hid_itf_t usbd_hid_itf;
} usb_device_t; } usb_device_t;
@ -111,16 +110,15 @@ const mp_rom_obj_tuple_t pyb_usb_hid_keyboard_obj = {
}; };
void pyb_usb_init0(void) { void pyb_usb_init0(void) {
usb_device.usbd_cdc_itf.attached_to_repl = false; for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
#if MICROPY_HW_USB_ENABLE_CDC2 usb_device.usbd_cdc_itf[i].attached_to_repl = false;
usb_device.usbd_cdc2_itf.attached_to_repl = false; }
#endif
MP_STATE_PORT(pyb_hid_report_desc) = MP_OBJ_NULL; MP_STATE_PORT(pyb_hid_report_desc) = MP_OBJ_NULL;
pyb_usb_vcp_init0();
} }
bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_HID_ModeInfoTypeDef *hid_info) { bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, uint8_t mode, USBD_HID_ModeInfoTypeDef *hid_info) {
bool high_speed = (mode & USBD_MODE_HIGH_SPEED) != 0;
mode &= 0x7f;
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
@ -132,15 +130,15 @@ bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_H
usbd->pDesc = (USBD_DescriptorsTypeDef*)&USBD_Descriptors; usbd->pDesc = (USBD_DescriptorsTypeDef*)&USBD_Descriptors;
usbd->pClass = &USBD_CDC_MSC_HID; usbd->pClass = &USBD_CDC_MSC_HID;
usb_dev->usbd_cdc_msc_hid_state.pdev = usbd; usb_dev->usbd_cdc_msc_hid_state.pdev = usbd;
usb_dev->usbd_cdc_msc_hid_state.cdc = &usb_dev->usbd_cdc_itf.base; for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
#if MICROPY_HW_USB_ENABLE_CDC2 usb_dev->usbd_cdc_msc_hid_state.cdc[i] = &usb_dev->usbd_cdc_itf[i].base;
usb_dev->usbd_cdc_msc_hid_state.cdc2 = &usb_dev->usbd_cdc2_itf.base; }
#endif
usb_dev->usbd_cdc_msc_hid_state.hid = &usb_dev->usbd_hid_itf.base; usb_dev->usbd_cdc_msc_hid_state.hid = &usb_dev->usbd_hid_itf.base;
usbd->pClassData = &usb_dev->usbd_cdc_msc_hid_state; usbd->pClassData = &usb_dev->usbd_cdc_msc_hid_state;
// configure the VID, PID and the USBD mode (interfaces it will expose) // configure the VID, PID and the USBD mode (interfaces it will expose)
USBD_SetVIDPIDRelease(&usb_dev->usbd_cdc_msc_hid_state, vid, pid, 0x0200, mode == USBD_MODE_CDC); int cdc_only = (mode & USBD_MODE_IFACE_MASK) == USBD_MODE_CDC;
USBD_SetVIDPIDRelease(&usb_dev->usbd_cdc_msc_hid_state, vid, pid, 0x0200, cdc_only);
if (USBD_SelectMode(&usb_dev->usbd_cdc_msc_hid_state, mode, hid_info) != 0) { if (USBD_SelectMode(&usb_dev->usbd_cdc_msc_hid_state, mode, hid_info) != 0) {
return false; return false;
} }
@ -157,7 +155,7 @@ bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_H
} }
// start the USB device // start the USB device
USBD_LL_Init(usbd, high_speed); USBD_LL_Init(usbd, (mode & USBD_MODE_HIGH_SPEED) != 0);
USBD_LL_Start(usbd); USBD_LL_Start(usbd);
usb_dev->enabled = true; usb_dev->enabled = true;
} }
@ -179,22 +177,17 @@ bool usb_vcp_is_enabled(void) {
} }
int usb_vcp_recv_byte(uint8_t *c) { int usb_vcp_recv_byte(uint8_t *c) {
return usbd_cdc_rx(&usb_device.usbd_cdc_itf, c, 1, 0); return usbd_cdc_rx(&usb_device.usbd_cdc_itf[0], c, 1, 0);
} }
void usb_vcp_send_strn(const char *str, int len) { void usb_vcp_send_strn(const char *str, int len) {
if (usb_device.enabled) { if (usb_device.enabled) {
usbd_cdc_tx_always(&usb_device.usbd_cdc_itf, (const uint8_t*)str, len); usbd_cdc_tx_always(&usb_device.usbd_cdc_itf[0], (const uint8_t*)str, len);
} }
} }
usbd_cdc_itf_t *usb_vcp_get(int idx) { usbd_cdc_itf_t *usb_vcp_get(int idx) {
#if MICROPY_HW_USB_ENABLE_CDC2 return &usb_device.usbd_cdc_itf[idx];
if (idx == 1) {
return &usb_device.usbd_cdc2_itf;
}
#endif
return &usb_device.usbd_cdc_itf;
} }
/******************************************************************************/ /******************************************************************************/
@ -243,7 +236,7 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
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);
switch (mode) { switch (mode & USBD_MODE_IFACE_MASK) {
case USBD_MODE_CDC: case USBD_MODE_CDC:
return MP_OBJ_NEW_QSTR(MP_QSTR_VCP); return MP_OBJ_NEW_QSTR(MP_QSTR_VCP);
case USBD_MODE_MSC: case USBD_MODE_MSC:
@ -298,13 +291,13 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
// note: we support CDC as a synonym for VCP for backward compatibility // note: we support CDC as a synonym for VCP for backward compatibility
uint16_t vid = args[1].u_int; uint16_t vid = args[1].u_int;
uint16_t pid = args[2].u_int; uint16_t pid = args[2].u_int;
usb_device_mode_t mode; uint8_t mode;
if (strcmp(mode_str, "CDC+MSC") == 0 || strcmp(mode_str, "VCP+MSC") == 0) { if (strcmp(mode_str, "CDC+MSC") == 0 || strcmp(mode_str, "VCP+MSC") == 0) {
if (args[2].u_int == -1) { if (args[2].u_int == -1) {
pid = USBD_PID_CDC_MSC; pid = USBD_PID_CDC_MSC;
} }
mode = USBD_MODE_CDC_MSC; mode = USBD_MODE_CDC_MSC;
#if MICROPY_HW_USB_ENABLE_CDC2 #if MICROPY_HW_USB_CDC_NUM >= 2
} else if (strcmp(mode_str, "VCP+VCP") == 0) { } else if (strcmp(mode_str, "VCP+VCP") == 0) {
if (args[2].u_int == -1) { if (args[2].u_int == -1) {
pid = USBD_PID_CDC2; pid = USBD_PID_CDC2;
@ -337,7 +330,7 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
// 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_HID) { if (mode & USBD_MODE_IFACE_HID) {
mp_obj_t *items; mp_obj_t *items;
mp_obj_get_array_fixed_n(args[3].u_obj, 5, &items); mp_obj_get_array_fixed_n(args[3].u_obj, 5, &items);
hid_info.subclass = mp_obj_get_int(items[0]); hid_info.subclass = mp_obj_get_int(items[0]);
@ -388,13 +381,21 @@ typedef struct _pyb_usb_vcp_obj_t {
usbd_cdc_itf_t *cdc_itf; usbd_cdc_itf_t *cdc_itf;
} pyb_usb_vcp_obj_t; } pyb_usb_vcp_obj_t;
const pyb_usb_vcp_obj_t pyb_usb_vcp_obj = {{&pyb_usb_vcp_type}, &usb_device.usbd_cdc_itf}; const pyb_usb_vcp_obj_t pyb_usb_vcp_obj[MICROPY_HW_USB_CDC_NUM] = {
#if MICROPY_HW_USB_ENABLE_CDC2 {{&pyb_usb_vcp_type}, &usb_device.usbd_cdc_itf[0]},
STATIC const pyb_usb_vcp_obj_t pyb_usb_vcp2_obj = {{&pyb_usb_vcp_type}, &usb_device.usbd_cdc2_itf}; #if MICROPY_HW_USB_CDC_NUM >= 2
{{&pyb_usb_vcp_type}, &usb_device.usbd_cdc_itf[1]},
#endif #endif
};
STATIC void pyb_usb_vcp_init0(void) {
// Activate USB_VCP(0) on dupterm slot 1 for the REPL
MP_STATE_VM(dupterm_objs[1]) = MP_OBJ_FROM_PTR(&pyb_usb_vcp_obj[0]);
usb_vcp_attach_to_repl(&pyb_usb_vcp_obj[0], true);
}
STATIC void pyb_usb_vcp_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { STATIC void pyb_usb_vcp_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
int id = ((pyb_usb_vcp_obj_t*)MP_OBJ_TO_PTR(self_in))->cdc_itf - &usb_device.usbd_cdc_itf; int id = ((pyb_usb_vcp_obj_t*)MP_OBJ_TO_PTR(self_in))->cdc_itf - &usb_device.usbd_cdc_itf[0];
mp_printf(print, "USB_VCP(%u)", id); mp_printf(print, "USB_VCP(%u)", id);
} }
@ -411,12 +412,8 @@ STATIC mp_obj_t pyb_usb_vcp_make_new(const mp_obj_type_t *type, size_t n_args, s
// TODO raise exception if USB is not configured for VCP // TODO raise exception if USB is not configured for VCP
int id = (n_args == 0) ? 0 : mp_obj_get_int(args[0]); int id = (n_args == 0) ? 0 : mp_obj_get_int(args[0]);
if (id == 0) { if (0 <= id && id < MICROPY_HW_USB_CDC_NUM) {
return MP_OBJ_FROM_PTR(&pyb_usb_vcp_obj); return MP_OBJ_FROM_PTR(&pyb_usb_vcp_obj[id]);
#if MICROPY_HW_USB_ENABLE_CDC2
} else if (id == 1) {
return MP_OBJ_FROM_PTR(&pyb_usb_vcp2_obj);
#endif
} else { } else {
mp_raise_ValueError(NULL); mp_raise_ValueError(NULL);
} }
@ -457,7 +454,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_usb_vcp_isconnected_obj, pyb_usb_vcp_isconn
// deprecated in favour of USB_VCP.isconnected // deprecated in favour of USB_VCP.isconnected
STATIC mp_obj_t pyb_have_cdc(void) { STATIC mp_obj_t pyb_have_cdc(void) {
return pyb_usb_vcp_isconnected(MP_OBJ_FROM_PTR(&pyb_usb_vcp_obj)); return pyb_usb_vcp_isconnected(MP_OBJ_FROM_PTR(&pyb_usb_vcp_obj[0]));
} }
MP_DEFINE_CONST_FUN_OBJ_0(pyb_have_cdc_obj, pyb_have_cdc); MP_DEFINE_CONST_FUN_OBJ_0(pyb_have_cdc_obj, pyb_have_cdc);

View File

@ -58,14 +58,13 @@ extern const struct _mp_rom_obj_tuple_t pyb_usb_hid_mouse_obj;
extern const struct _mp_rom_obj_tuple_t pyb_usb_hid_keyboard_obj; extern const struct _mp_rom_obj_tuple_t pyb_usb_hid_keyboard_obj;
extern const mp_obj_type_t pyb_usb_vcp_type; extern const mp_obj_type_t pyb_usb_vcp_type;
extern const mp_obj_type_t pyb_usb_hid_type; extern const mp_obj_type_t pyb_usb_hid_type;
extern const pyb_usb_vcp_obj_t pyb_usb_vcp_obj;
MP_DECLARE_CONST_FUN_OBJ_KW(pyb_usb_mode_obj); MP_DECLARE_CONST_FUN_OBJ_KW(pyb_usb_mode_obj);
MP_DECLARE_CONST_FUN_OBJ_0(pyb_have_cdc_obj); // deprecated 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, usb_device_mode_t mode, USBD_HID_ModeInfoTypeDef *hid_info); bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, uint8_t mode, 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

View File

@ -217,18 +217,13 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
} else { } else {
usbd_cdc_msc_hid_state_t *usbd = ((USBD_HandleTypeDef*)hpcd->pData)->pClassData; usbd_cdc_msc_hid_state_t *usbd = ((USBD_HandleTypeDef*)hpcd->pData)->pClassData;
hpcd->Instance->GINTMSK &= ~USB_OTG_GINTMSK_SOFM; hpcd->Instance->GINTMSK &= ~USB_OTG_GINTMSK_SOFM;
usbd_cdc_itf_t *cdc = (usbd_cdc_itf_t*)usbd->cdc; for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
usbd_cdc_itf_t *cdc = (usbd_cdc_itf_t*)usbd->cdc[i];
if (cdc->connect_state == USBD_CDC_CONNECT_STATE_CONNECTING) { if (cdc->connect_state == USBD_CDC_CONNECT_STATE_CONNECTING) {
cdc->connect_state = USBD_CDC_CONNECT_STATE_CONNECTED; cdc->connect_state = USBD_CDC_CONNECT_STATE_CONNECTED;
usbd_cdc_try_tx(cdc); usbd_cdc_try_tx(cdc);
} }
#if MICROPY_HW_USB_ENABLE_CDC2
cdc = (usbd_cdc_itf_t*)usbd->cdc2;
if (cdc->connect_state == USBD_CDC_CONNECT_STATE_CONNECTING) {
cdc->connect_state = USBD_CDC_CONNECT_STATE_CONNECTED;
usbd_cdc_try_tx(cdc);
} }
#endif
} }
} }

View File

@ -334,7 +334,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) {
if (pdev->id == USB_PHY_FS_ID) { if (pdev->id == USB_PHY_FS_ID) {
// Set LL Driver parameters // Set LL Driver parameters
pcd_fs_handle.Instance = USB_OTG_FS; pcd_fs_handle.Instance = USB_OTG_FS;
#if MICROPY_HW_USB_ENABLE_CDC2 #if MICROPY_HW_USB_CDC_NUM == 2
pcd_fs_handle.Init.dev_endpoints = 6; pcd_fs_handle.Init.dev_endpoints = 6;
#else #else
pcd_fs_handle.Init.dev_endpoints = 4; pcd_fs_handle.Init.dev_endpoints = 4;
@ -364,7 +364,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) {
HAL_PCD_Init(&pcd_fs_handle); HAL_PCD_Init(&pcd_fs_handle);
// We have 320 32-bit words in total to use here // We have 320 32-bit words in total to use here
#if MICROPY_HW_USB_ENABLE_CDC2 #if MICROPY_HW_USB_CDC_NUM == 2
HAL_PCD_SetRxFiFo(&pcd_fs_handle, 128); HAL_PCD_SetRxFiFo(&pcd_fs_handle, 128);
HAL_PCD_SetTxFiFo(&pcd_fs_handle, 0, 32); // EP0 HAL_PCD_SetTxFiFo(&pcd_fs_handle, 0, 32); // EP0
HAL_PCD_SetTxFiFo(&pcd_fs_handle, 1, 64); // MSC / HID HAL_PCD_SetTxFiFo(&pcd_fs_handle, 1, 64); // MSC / HID

View File

@ -18,12 +18,13 @@
#define USBD_SUPPORT_HS_MODE (0) #define USBD_SUPPORT_HS_MODE (0)
#endif #endif
// Needed for the CDC+MSC+HID state and should be maximum of all template // Should be maximum of possible config descriptors that might be configured
// config descriptors defined in usbd_cdc_msc_hid.c #if MICROPY_HW_USB_CDC_NUM == 2
#if MICROPY_HW_USB_ENABLE_CDC2 // Maximum is MSC+CDC+CDC
#define MAX_TEMPLATE_CONFIG_DESC_SIZE (9 + 23 + (8 + 58) + (8 + 58)) #define MAX_TEMPLATE_CONFIG_DESC_SIZE (9 + 23 + (8 + 58) + (8 + 58))
#else #else
#define MAX_TEMPLATE_CONFIG_DESC_SIZE (107) // Maximum is HID+CDC
#define MAX_TEMPLATE_CONFIG_DESC_SIZE (9 + 32 + (8 + 58))
#endif #endif
// CDC, MSC and HID packet sizes // CDC, MSC and HID packet sizes
@ -124,10 +125,7 @@ typedef struct _usbd_cdc_msc_hid_state_t {
__ALIGN_BEGIN uint8_t usbd_str_desc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; __ALIGN_BEGIN uint8_t usbd_str_desc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
__ALIGN_BEGIN uint8_t usbd_config_desc[MAX_TEMPLATE_CONFIG_DESC_SIZE] __ALIGN_END; __ALIGN_BEGIN uint8_t usbd_config_desc[MAX_TEMPLATE_CONFIG_DESC_SIZE] __ALIGN_END;
usbd_cdc_state_t *cdc; usbd_cdc_state_t *cdc[MICROPY_HW_USB_CDC_NUM];
#if MICROPY_HW_USB_ENABLE_CDC2
usbd_cdc_state_t *cdc2;
#endif
usbd_hid_state_t *hid; usbd_hid_state_t *hid;
} usbd_cdc_msc_hid_state_t; } usbd_cdc_msc_hid_state_t;

View File

@ -29,18 +29,22 @@
// these are exports for the CDC/MSC/HID interface that are independent // these are exports for the CDC/MSC/HID interface that are independent
// from any other definitions/declarations // from any other definitions/declarations
// only CDC_MSC and CDC_HID are available // These can be or'd together (but not all combinations may be available)
typedef enum { #define USBD_MODE_IFACE_MASK (0x7f)
USBD_MODE_CDC = 0x01, #define USBD_MODE_IFACE_CDC(i) (0x01 << (i))
USBD_MODE_MSC = 0x02, #define USBD_MODE_IFACE_HID (0x10)
USBD_MODE_HID = 0x04, #define USBD_MODE_IFACE_MSC (0x20)
USBD_MODE_CDC2 = 0x08, #define USBD_MODE_HIGH_SPEED (0x80)
USBD_MODE_CDC_MSC = USBD_MODE_CDC | USBD_MODE_MSC,
USBD_MODE_CDC_HID = USBD_MODE_CDC | USBD_MODE_HID, // Convenience macros for supported mode combinations
USBD_MODE_MSC_HID = USBD_MODE_MSC | USBD_MODE_HID, #define USBD_MODE_CDC (USBD_MODE_IFACE_CDC(0))
USBD_MODE_CDC2_MSC = USBD_MODE_CDC | USBD_MODE_MSC | USBD_MODE_CDC2, #define USBD_MODE_CDC2 (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_CDC(1))
USBD_MODE_HIGH_SPEED = 0x80, // or with one of the above #define USBD_MODE_CDC_HID (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_HID)
} usb_device_mode_t; #define USBD_MODE_CDC_MSC (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_MSC)
#define USBD_MODE_CDC2_MSC (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_CDC(1) | USBD_MODE_IFACE_MSC)
#define USBD_MODE_HID (USBD_MODE_IFACE_HID)
#define USBD_MODE_MSC (USBD_MODE_IFACE_MSC)
#define USBD_MODE_MSC_HID (USBD_MODE_IFACE_MSC | USBD_MODE_IFACE_HID)
typedef struct _USBD_HID_ModeInfoTypeDef { typedef struct _USBD_HID_ModeInfoTypeDef {
uint8_t subclass; // 0=no sub class, 1=boot uint8_t subclass; // 0=no sub class, 1=boot

View File

@ -38,6 +38,8 @@
#define MSC_TEMPLATE_MSC_DESC_OFFSET (9) #define MSC_TEMPLATE_MSC_DESC_OFFSET (9)
#define CDC_MSC_TEMPLATE_MSC_DESC_OFFSET (9) #define CDC_MSC_TEMPLATE_MSC_DESC_OFFSET (9)
#define CDC_MSC_TEMPLATE_CDC_DESC_OFFSET (40) #define CDC_MSC_TEMPLATE_CDC_DESC_OFFSET (40)
#define CDC2_TEMPLATE_CDC_DESC_OFFSET (9 + 8)
#define CDC2_TEMPLATE_CDC2_DESC_OFFSET (9 + (8 + 58) + 8)
#define CDC2_MSC_TEMPLATE_MSC_DESC_OFFSET (9) #define CDC2_MSC_TEMPLATE_MSC_DESC_OFFSET (9)
#define CDC2_MSC_TEMPLATE_CDC_DESC_OFFSET (9 + 23 + 8) #define CDC2_MSC_TEMPLATE_CDC_DESC_OFFSET (9 + 23 + 8)
#define CDC2_MSC_TEMPLATE_CDC2_DESC_OFFSET (9 + 23 + (8 + 58) + 8) #define CDC2_MSC_TEMPLATE_CDC2_DESC_OFFSET (9 + 23 + (8 + 58) + 8)
@ -69,13 +71,9 @@
#define HID_IFACE_NUM_WITH_CDC (0) #define HID_IFACE_NUM_WITH_CDC (0)
#define HID_IFACE_NUM_WITH_MSC (1) #define HID_IFACE_NUM_WITH_MSC (1)
#define CDC_IN_EP (0x83) #define CDC_IN_EP(i) (0x83 + 2 * (i))
#define CDC_OUT_EP (0x03) #define CDC_OUT_EP(i) (0x03 + 2 * (i))
#define CDC_CMD_EP (0x82) #define CDC_CMD_EP(i) (0x82 + 2 * (i))
#define CDC2_IN_EP (0x85)
#define CDC2_OUT_EP (0x05)
#define CDC2_CMD_EP (0x84)
#define HID_IN_EP_WITH_CDC (0x81) #define HID_IN_EP_WITH_CDC (0x81)
#define HID_OUT_EP_WITH_CDC (0x01) #define HID_OUT_EP_WITH_CDC (0x01)
@ -232,7 +230,7 @@ static const uint8_t cdc_class_desc_data[CDC_CLASS_DESC_SIZE] = {
// Endpoint CMD Descriptor // Endpoint CMD Descriptor
0x07, // bLength: Endpoint Descriptor size 0x07, // bLength: Endpoint Descriptor size
USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint
CDC_CMD_EP, // bEndpointAddress CDC_CMD_EP(0), // bEndpointAddress
0x03, // bmAttributes: Interrupt 0x03, // bmAttributes: Interrupt
LOBYTE(CDC_CMD_PACKET_SIZE), // wMaxPacketSize: LOBYTE(CDC_CMD_PACKET_SIZE), // wMaxPacketSize:
HIBYTE(CDC_CMD_PACKET_SIZE), HIBYTE(CDC_CMD_PACKET_SIZE),
@ -253,7 +251,7 @@ static const uint8_t cdc_class_desc_data[CDC_CLASS_DESC_SIZE] = {
// Endpoint OUT Descriptor // Endpoint OUT Descriptor
0x07, // bLength: Endpoint Descriptor size 0x07, // bLength: Endpoint Descriptor size
USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint
CDC_OUT_EP, // bEndpointAddress CDC_OUT_EP(0), // bEndpointAddress
0x02, // bmAttributes: Bulk 0x02, // bmAttributes: Bulk
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),// wMaxPacketSize: LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),// wMaxPacketSize:
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
@ -262,7 +260,7 @@ static const uint8_t cdc_class_desc_data[CDC_CLASS_DESC_SIZE] = {
// Endpoint IN Descriptor // Endpoint IN Descriptor
0x07, // bLength: Endpoint Descriptor size 0x07, // bLength: Endpoint Descriptor size
USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint
CDC_IN_EP, // bEndpointAddress CDC_IN_EP(0), // bEndpointAddress
0x02, // bmAttributes: Bulk 0x02, // bmAttributes: Bulk
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),// wMaxPacketSize: LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),// wMaxPacketSize:
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
@ -421,7 +419,7 @@ static size_t make_cdc_desc(uint8_t *dest, int need_iad, uint8_t iface_num) {
return need_iad ? 8 + 58 : 58; return need_iad ? 8 + 58 : 58;
} }
#if MICROPY_HW_USB_ENABLE_CDC2 #if MICROPY_HW_USB_CDC_NUM >= 2
static size_t make_cdc_desc_ep(uint8_t *dest, int need_iad, uint8_t iface_num, uint8_t cmd_ep, uint8_t out_ep, uint8_t in_ep) { static size_t make_cdc_desc_ep(uint8_t *dest, int need_iad, uint8_t iface_num, uint8_t cmd_ep, uint8_t out_ep, uint8_t in_ep) {
size_t n = make_cdc_desc(dest, need_iad, iface_num); size_t n = make_cdc_desc(dest, need_iad, iface_num);
if (need_iad) { if (need_iad) {
@ -461,7 +459,7 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode
size_t n = HEAD_DESC_SIZE; size_t n = HEAD_DESC_SIZE;
uint8_t *d = usbd->usbd_config_desc; uint8_t *d = usbd->usbd_config_desc;
uint8_t num_itf = 0; uint8_t num_itf = 0;
switch (usbd->usbd_mode) { switch (usbd->usbd_mode & USBD_MODE_IFACE_MASK) {
case USBD_MODE_MSC: case USBD_MODE_MSC:
n += make_msc_desc(d + n); n += make_msc_desc(d + n);
num_itf = 1; num_itf = 1;
@ -470,19 +468,16 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode
case USBD_MODE_CDC_MSC: case USBD_MODE_CDC_MSC:
n += make_msc_desc(d + n); n += make_msc_desc(d + n);
n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_WITH_MSC); n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_WITH_MSC);
usbd->cdc->iface_num = CDC_IFACE_NUM_WITH_MSC; usbd->cdc[0]->iface_num = CDC_IFACE_NUM_WITH_MSC;
num_itf = 3; num_itf = 3;
break; break;
#if MICROPY_HW_USB_ENABLE_CDC2 #if MICROPY_HW_USB_CDC_NUM >= 2
case USBD_MODE_CDC2: { case USBD_MODE_CDC2: {
// Ensure the first interface is also enabled
usbd->usbd_mode |= USBD_MODE_CDC;
n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_ALONE); n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_ALONE);
n += make_cdc_desc_ep(d + n, 1, CDC2_IFACE_NUM_WITH_CDC, CDC2_CMD_EP, CDC2_OUT_EP, CDC2_IN_EP); n += make_cdc_desc_ep(d + n, 1, CDC2_IFACE_NUM_WITH_CDC, CDC_CMD_EP(1), CDC_OUT_EP(1), CDC_IN_EP(1));
usbd->cdc->iface_num = CDC_IFACE_NUM_ALONE; usbd->cdc[0]->iface_num = CDC_IFACE_NUM_ALONE;
usbd->cdc2->iface_num = CDC2_IFACE_NUM_WITH_CDC; usbd->cdc[1]->iface_num = CDC2_IFACE_NUM_WITH_CDC;
num_itf = 4; num_itf = 4;
break; break;
} }
@ -490,9 +485,9 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode
case USBD_MODE_CDC2_MSC: { case USBD_MODE_CDC2_MSC: {
n += make_msc_desc(d + n); n += make_msc_desc(d + n);
n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_WITH_MSC); n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_WITH_MSC);
n += make_cdc_desc_ep(d + n, 1, CDC2_IFACE_NUM_WITH_MSC, CDC2_CMD_EP, CDC2_OUT_EP, CDC2_IN_EP); n += make_cdc_desc_ep(d + n, 1, CDC2_IFACE_NUM_WITH_MSC, CDC_CMD_EP(1), CDC_OUT_EP(1), CDC_IN_EP(1));
usbd->cdc->iface_num = CDC_IFACE_NUM_WITH_MSC; usbd->cdc[0]->iface_num = CDC_IFACE_NUM_WITH_MSC;
usbd->cdc2->iface_num = CDC2_IFACE_NUM_WITH_MSC; usbd->cdc[1]->iface_num = CDC2_IFACE_NUM_WITH_MSC;
num_itf = 5; num_itf = 5;
break; break;
} }
@ -502,7 +497,7 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode
usbd->hid->desc = d + n; usbd->hid->desc = d + n;
n += make_hid_desc(d + n, hid_info); n += make_hid_desc(d + n, hid_info);
n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_WITH_HID); n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_WITH_HID);
usbd->cdc->iface_num = CDC_IFACE_NUM_WITH_HID; usbd->cdc[0]->iface_num = CDC_IFACE_NUM_WITH_HID;
usbd->hid->in_ep = HID_IN_EP_WITH_CDC; usbd->hid->in_ep = HID_IN_EP_WITH_CDC;
usbd->hid->out_ep = HID_OUT_EP_WITH_CDC; usbd->hid->out_ep = HID_OUT_EP_WITH_CDC;
usbd->hid->iface_num = HID_IFACE_NUM_WITH_CDC; usbd->hid->iface_num = HID_IFACE_NUM_WITH_CDC;
@ -512,7 +507,7 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode
case USBD_MODE_CDC: case USBD_MODE_CDC:
n += make_cdc_desc(d + n, 0, CDC_IFACE_NUM_ALONE); n += make_cdc_desc(d + n, 0, CDC_IFACE_NUM_ALONE);
usbd->cdc->iface_num = CDC_IFACE_NUM_ALONE; usbd->cdc[0]->iface_num = CDC_IFACE_NUM_ALONE;
num_itf = 2; num_itf = 2;
break; break;
@ -533,17 +528,12 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode
make_head_desc(d, n, num_itf); make_head_desc(d, n, num_itf);
usbd->usbd_config_desc_size = n; usbd->usbd_config_desc_size = n;
if (usbd->usbd_mode & USBD_MODE_CDC) { for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
usbd->cdc->in_ep = CDC_IN_EP; if (usbd->usbd_mode & USBD_MODE_IFACE_CDC(i)) {
usbd->cdc->out_ep = CDC_OUT_EP; usbd->cdc[i]->in_ep = CDC_IN_EP(i);
usbd->cdc[i]->out_ep = CDC_OUT_EP(i);
} }
#if MICROPY_HW_USB_ENABLE_CDC2
if (usbd->usbd_mode & USBD_MODE_CDC2) {
usbd->cdc2->in_ep = CDC2_IN_EP;
usbd->cdc2->out_ep = CDC2_OUT_EP;
} }
#endif
return 0; return 0;
} }
@ -578,19 +568,14 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData; usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData;
if (usbd->usbd_mode & USBD_MODE_CDC) { // CDC VCP component(s)
// CDC VCP component for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
usbd_cdc_state_init(pdev, usbd, usbd->cdc, CDC_CMD_EP); if (usbd->usbd_mode & USBD_MODE_IFACE_CDC(i)) {
usbd_cdc_state_init(pdev, usbd, usbd->cdc[i], CDC_CMD_EP(i));
}
} }
#if MICROPY_HW_USB_ENABLE_CDC2 if (usbd->usbd_mode & USBD_MODE_IFACE_MSC) {
if (usbd->usbd_mode & USBD_MODE_CDC2) {
// CDC VCP #2 component
usbd_cdc_state_init(pdev, usbd, usbd->cdc2, CDC2_CMD_EP);
}
#endif
if (usbd->usbd_mode & USBD_MODE_MSC) {
// MSC component // MSC component
int mp = usbd_msc_max_packet(pdev); int mp = usbd_msc_max_packet(pdev);
@ -611,7 +596,7 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
MSC_BOT_Init(pdev); MSC_BOT_Init(pdev);
} }
if (usbd->usbd_mode & USBD_MODE_HID) { if (usbd->usbd_mode & USBD_MODE_IFACE_HID) {
// HID component // HID component
// get max packet lengths from descriptor // get max packet lengths from descriptor
@ -644,31 +629,20 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
static uint8_t USBD_CDC_MSC_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { static uint8_t USBD_CDC_MSC_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData; usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData;
if ((usbd->usbd_mode & USBD_MODE_CDC) && usbd->cdc) { for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
if ((usbd->usbd_mode & USBD_MODE_IFACE_CDC(i)) && usbd->cdc[i]) {
// CDC VCP component // CDC VCP component
usbd_cdc_deinit(usbd->cdc); usbd_cdc_deinit(usbd->cdc[i]);
// close endpoints // close endpoints
USBD_LL_CloseEP(pdev, CDC_IN_EP); USBD_LL_CloseEP(pdev, CDC_IN_EP(i));
USBD_LL_CloseEP(pdev, CDC_OUT_EP); USBD_LL_CloseEP(pdev, CDC_OUT_EP(i));
USBD_LL_CloseEP(pdev, CDC_CMD_EP); USBD_LL_CloseEP(pdev, CDC_CMD_EP(i));
}
} }
#if MICROPY_HW_USB_ENABLE_CDC2 if (usbd->usbd_mode & USBD_MODE_IFACE_MSC) {
if ((usbd->usbd_mode & USBD_MODE_CDC2) && usbd->cdc2) {
// CDC VCP #2 component
usbd_cdc_deinit(usbd->cdc2);
// close endpoints
USBD_LL_CloseEP(pdev, CDC2_IN_EP);
USBD_LL_CloseEP(pdev, CDC2_OUT_EP);
USBD_LL_CloseEP(pdev, CDC2_CMD_EP);
}
#endif
if (usbd->usbd_mode & USBD_MODE_MSC) {
// MSC component // MSC component
// close endpoints // close endpoints
@ -679,7 +653,7 @@ static uint8_t USBD_CDC_MSC_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
MSC_BOT_DeInit(pdev); MSC_BOT_DeInit(pdev);
} }
if (usbd->usbd_mode & USBD_MODE_HID) { if (usbd->usbd_mode & USBD_MODE_IFACE_HID) {
// HID component // HID component
// close endpoints // close endpoints
@ -717,35 +691,35 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp
switch (req->bmRequest & USB_REQ_RECIPIENT_MASK) { switch (req->bmRequest & USB_REQ_RECIPIENT_MASK) {
case USB_REQ_RECIPIENT_INTERFACE: { case USB_REQ_RECIPIENT_INTERFACE: {
uint16_t iface = req->wIndex; uint16_t iface = req->wIndex;
if ((mode & USBD_MODE_CDC) && iface == usbd->cdc->iface_num) { if ((mode & USBD_MODE_IFACE_MSC) && iface == MSC_IFACE_NUM_WITH_CDC) {
recipient = USBD_MODE_CDC;
cdc = usbd->cdc;
#if MICROPY_HW_USB_ENABLE_CDC2
} else if ((mode & USBD_MODE_CDC2) && iface == usbd->cdc2->iface_num) {
recipient = USBD_MODE_CDC;
cdc = usbd->cdc2;
#endif
} else if ((mode & USBD_MODE_MSC) && iface == MSC_IFACE_NUM_WITH_CDC) {
recipient = USBD_MODE_MSC; recipient = USBD_MODE_MSC;
} else if ((mode & USBD_MODE_HID) && iface == usbd->hid->iface_num) { } else if ((mode & USBD_MODE_IFACE_HID) && iface == usbd->hid->iface_num) {
recipient = USBD_MODE_HID; recipient = USBD_MODE_HID;
} else {
for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
if ((mode & USBD_MODE_IFACE_CDC(i)) && iface == usbd->cdc[i]->iface_num) {
recipient = USBD_MODE_CDC;
cdc = usbd->cdc[i];
break;
}
}
} }
break; break;
} }
case USB_REQ_RECIPIENT_ENDPOINT: { case USB_REQ_RECIPIENT_ENDPOINT: {
uint8_t ep = req->wIndex & 0x7f; uint8_t ep = req->wIndex & 0x7f;
if ((mode & USBD_MODE_CDC) && (ep == CDC_OUT_EP || ep == (CDC_CMD_EP & 0x7f))) { if ((mode & USBD_MODE_IFACE_MSC) && ep == MSC_OUT_EP) {
recipient = USBD_MODE_CDC;
cdc = usbd->cdc;
#if MICROPY_HW_USB_ENABLE_CDC2
} else if ((mode & USBD_MODE_CDC2) && (ep == CDC2_OUT_EP || ep == (CDC2_CMD_EP & 0x7f))) {
recipient = USBD_MODE_CDC;
cdc = usbd->cdc2;
#endif
} else if ((mode & USBD_MODE_MSC) && ep == MSC_OUT_EP) {
recipient = USBD_MODE_MSC; recipient = USBD_MODE_MSC;
} else if ((mode & USBD_MODE_HID) && ep == usbd->hid->out_ep) { } else if ((mode & USBD_MODE_IFACE_HID) && ep == usbd->hid->out_ep) {
recipient = USBD_MODE_HID; recipient = USBD_MODE_HID;
} else {
for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
if ((mode & USBD_MODE_IFACE_CDC(i)) && (ep == CDC_OUT_EP(i) || ep == (CDC_CMD_EP(i) & 0x7f))) {
recipient = USBD_MODE_CDC;
cdc = usbd->cdc[i];
break;
}
}
} }
break; break;
} }
@ -894,36 +868,32 @@ static uint8_t EP0_TxSent(USBD_HandleTypeDef *pdev) {
static uint8_t USBD_CDC_MSC_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) { static uint8_t USBD_CDC_MSC_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) {
usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData; usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData;
if (usbd->cdc != NULL && usbd->cdc->cur_request != 0xff) { for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
usbd_cdc_control(usbd->cdc, usbd->cdc->cur_request, (uint8_t*)usbd->cdc->ctl_packet_buf, usbd->cdc->cur_length); if (usbd->cdc[i] != NULL && usbd->cdc[i]->cur_request != 0xff) {
usbd->cdc->cur_request = 0xff; usbd_cdc_control(usbd->cdc[i], usbd->cdc[i]->cur_request, (uint8_t*)usbd->cdc[i]->ctl_packet_buf, usbd->cdc[i]->cur_length);
usbd->cdc[i]->cur_request = 0xff;
} }
#if MICROPY_HW_USB_ENABLE_CDC2
if (usbd->cdc2 != NULL && usbd->cdc2->cur_request != 0xff) {
usbd_cdc_control(usbd->cdc2, usbd->cdc2->cur_request, (uint8_t*)usbd->cdc2->ctl_packet_buf, usbd->cdc2->cur_length);
usbd->cdc2->cur_request = 0xff;
} }
#endif
return USBD_OK; return USBD_OK;
} }
static uint8_t USBD_CDC_MSC_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { static uint8_t USBD_CDC_MSC_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) {
usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData; usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData;
if ((usbd->usbd_mode & USBD_MODE_CDC) && (epnum == (CDC_IN_EP & 0x7f) || epnum == (CDC_CMD_EP & 0x7f))) {
usbd->cdc->tx_in_progress = 0; for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
usbd_cdc_tx_ready(usbd->cdc); if ((usbd->usbd_mode & USBD_MODE_IFACE_CDC(i)) && (epnum == (CDC_IN_EP(i) & 0x7f) || epnum == (CDC_CMD_EP(i) & 0x7f))) {
usbd->cdc[i]->tx_in_progress = 0;
usbd_cdc_tx_ready(usbd->cdc[i]);
return USBD_OK; return USBD_OK;
#if MICROPY_HW_USB_ENABLE_CDC2 }
} else if ((usbd->usbd_mode & USBD_MODE_CDC2) && (epnum == (CDC2_IN_EP & 0x7f) || epnum == (CDC2_CMD_EP & 0x7f))) { }
usbd->cdc2->tx_in_progress = 0;
usbd_cdc_tx_ready(usbd->cdc2); if ((usbd->usbd_mode & USBD_MODE_IFACE_MSC) && epnum == (MSC_IN_EP & 0x7f)) {
return USBD_OK;
#endif
} else if ((usbd->usbd_mode & USBD_MODE_MSC) && epnum == (MSC_IN_EP & 0x7f)) {
MSC_BOT_DataIn(pdev, epnum); MSC_BOT_DataIn(pdev, epnum);
return USBD_OK; return USBD_OK;
} else if ((usbd->usbd_mode & USBD_MODE_HID) && epnum == (usbd->hid->in_ep & 0x7f)) { }
if ((usbd->usbd_mode & USBD_MODE_IFACE_HID) && epnum == (usbd->hid->in_ep & 0x7f)) {
/* Ensure that the FIFO is empty before a new transfer, this condition could /* Ensure that the FIFO is empty before a new transfer, this condition could
be caused by a new transfer before the end of the previous transfer */ be caused by a new transfer before the end of the previous transfer */
usbd->hid->state = HID_IDLE; usbd->hid->state = HID_IDLE;
@ -935,26 +905,23 @@ static uint8_t USBD_CDC_MSC_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) {
usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData; usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData;
if ((usbd->usbd_mode & USBD_MODE_CDC) && epnum == (CDC_OUT_EP & 0x7f)) {
/* Get the received data length */ for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
if ((usbd->usbd_mode & USBD_MODE_IFACE_CDC(i)) && epnum == (CDC_OUT_EP(i) & 0x7f)) {
size_t len = USBD_LL_GetRxDataSize(pdev, epnum); size_t len = USBD_LL_GetRxDataSize(pdev, epnum);
// USB data will be immediately processed, and next USB traffic is NAKed until it's done
return usbd_cdc_receive(usbd->cdc[i], len);
}
}
/* USB data will be immediately processed, this allow next USB traffic being if ((usbd->usbd_mode & USBD_MODE_IFACE_MSC) && epnum == (MSC_OUT_EP & 0x7f)) {
NAKed till the end of the application Xfer */
return usbd_cdc_receive(usbd->cdc, len);
#if MICROPY_HW_USB_ENABLE_CDC2
} else if ((usbd->usbd_mode & USBD_MODE_CDC2) && epnum == (CDC2_OUT_EP & 0x7f)) {
size_t len = USBD_LL_GetRxDataSize(pdev, epnum);
return usbd_cdc_receive(usbd->cdc2, len);
#endif
} else if ((usbd->usbd_mode & USBD_MODE_MSC) && epnum == (MSC_OUT_EP & 0x7f)) {
MSC_BOT_DataOut(pdev, epnum); MSC_BOT_DataOut(pdev, epnum);
return USBD_OK; return USBD_OK;
} else if ((usbd->usbd_mode & USBD_MODE_HID) && epnum == (usbd->hid->out_ep & 0x7f)) { }
if ((usbd->usbd_mode & USBD_MODE_IFACE_HID) && epnum == (usbd->hid->out_ep & 0x7f)) {
size_t len = USBD_LL_GetRxDataSize(pdev, epnum); size_t len = USBD_LL_GetRxDataSize(pdev, epnum);
usbd_hid_receive(usbd->hid, len); return usbd_hid_receive(usbd->hid, len);
} }
return USBD_OK; return USBD_OK;
@ -981,48 +948,46 @@ static uint8_t *USBD_CDC_MSC_HID_GetCfgDesc(USBD_HandleTypeDef *pdev, uint16_t *
usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData; usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData;
#if USBD_SUPPORT_HS_MODE #if USBD_SUPPORT_HS_MODE
uint8_t *cdc_desc = NULL; uint8_t *cdc_desc[MICROPY_HW_USB_CDC_NUM] = {0};
#if MICROPY_HW_USB_ENABLE_CDC2
uint8_t *cdc2_desc = NULL;
#endif
uint8_t *msc_desc = NULL; uint8_t *msc_desc = NULL;
switch (usbd->usbd_mode) { switch (usbd->usbd_mode & USBD_MODE_IFACE_MASK) {
case USBD_MODE_MSC: case USBD_MODE_MSC:
msc_desc = usbd->usbd_config_desc + MSC_TEMPLATE_MSC_DESC_OFFSET; msc_desc = usbd->usbd_config_desc + MSC_TEMPLATE_MSC_DESC_OFFSET;
break; break;
case USBD_MODE_CDC_MSC: case USBD_MODE_CDC_MSC:
cdc_desc = usbd->usbd_config_desc + CDC_MSC_TEMPLATE_CDC_DESC_OFFSET; cdc_desc[0] = usbd->usbd_config_desc + CDC_MSC_TEMPLATE_CDC_DESC_OFFSET;
msc_desc = usbd->usbd_config_desc + CDC_MSC_TEMPLATE_MSC_DESC_OFFSET; msc_desc = usbd->usbd_config_desc + CDC_MSC_TEMPLATE_MSC_DESC_OFFSET;
break; break;
#if MICROPY_HW_USB_ENABLE_CDC2 #if MICROPY_HW_USB_CDC_NUM >= 2
case USBD_MODE_CDC2:
cdc_desc[0] = usbd->usbd_config_desc + CDC2_TEMPLATE_CDC_DESC_OFFSET;
cdc_desc[1] = usbd->usbd_config_desc + CDC2_TEMPLATE_CDC2_DESC_OFFSET;
break;
case USBD_MODE_CDC2_MSC: case USBD_MODE_CDC2_MSC:
cdc_desc = usbd->usbd_config_desc + CDC2_MSC_TEMPLATE_CDC_DESC_OFFSET; cdc_desc[0] = usbd->usbd_config_desc + CDC2_MSC_TEMPLATE_CDC_DESC_OFFSET;
cdc2_desc = usbd->usbd_config_desc + CDC2_MSC_TEMPLATE_CDC2_DESC_OFFSET; cdc_desc[1] = usbd->usbd_config_desc + CDC2_MSC_TEMPLATE_CDC2_DESC_OFFSET;
msc_desc = usbd->usbd_config_desc + CDC2_MSC_TEMPLATE_MSC_DESC_OFFSET; msc_desc = usbd->usbd_config_desc + CDC2_MSC_TEMPLATE_MSC_DESC_OFFSET;
break; break;
#endif #endif
case USBD_MODE_CDC_HID: case USBD_MODE_CDC_HID:
cdc_desc = usbd->usbd_config_desc + CDC_HID_TEMPLATE_CDC_DESC_OFFSET; cdc_desc[0] = usbd->usbd_config_desc + CDC_HID_TEMPLATE_CDC_DESC_OFFSET;
break; break;
case USBD_MODE_CDC: case USBD_MODE_CDC:
cdc_desc = usbd->usbd_config_desc + CDC_TEMPLATE_CDC_DESC_OFFSET; cdc_desc[0] = usbd->usbd_config_desc + CDC_TEMPLATE_CDC_DESC_OFFSET;
break; break;
} }
// configure CDC descriptors, if needed // configure CDC descriptors, if needed
if (cdc_desc != NULL) { for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
usbd_cdc_desc_config_max_packet(pdev, cdc_desc); if (cdc_desc[i] != NULL) {
usbd_cdc_desc_config_max_packet(pdev, cdc_desc[i]);
} }
#if MICROPY_HW_USB_ENABLE_CDC2
if (cdc2_desc != NULL) {
usbd_cdc_desc_config_max_packet(pdev, cdc2_desc);
} }
#endif
if (msc_desc != NULL) { if (msc_desc != NULL) {
uint32_t mp = usbd_msc_max_packet(pdev); uint32_t mp = usbd_msc_max_packet(pdev);