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:
parent
a4f1d82757
commit
0c29502ad9
|
@ -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.
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
#endif
|
{{&pyb_usb_vcp_type}, &usb_device.usbd_cdc_itf[1]},
|
||||||
|
#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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
if (cdc->connect_state == USBD_CDC_CONNECT_STATE_CONNECTING) {
|
usbd_cdc_itf_t *cdc = (usbd_cdc_itf_t*)usbd->cdc[i];
|
||||||
cdc->connect_state = USBD_CDC_CONNECT_STATE_CONNECTED;
|
if (cdc->connect_state == USBD_CDC_CONNECT_STATE_CONNECTING) {
|
||||||
usbd_cdc_try_tx(cdc);
|
cdc->connect_state = USBD_CDC_CONNECT_STATE_CONNECTED;
|
||||||
|
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,18 +528,13 @@ 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) {
|
||||||
// CDC VCP component
|
if ((usbd->usbd_mode & USBD_MODE_IFACE_CDC(i)) && usbd->cdc[i]) {
|
||||||
|
// 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))) {
|
||||||
return USBD_OK;
|
usbd->cdc[i]->tx_in_progress = 0;
|
||||||
#if MICROPY_HW_USB_ENABLE_CDC2
|
usbd_cdc_tx_ready(usbd->cdc[i]);
|
||||||
} else if ((usbd->usbd_mode & USBD_MODE_CDC2) && (epnum == (CDC2_IN_EP & 0x7f) || epnum == (CDC2_CMD_EP & 0x7f))) {
|
return USBD_OK;
|
||||||
usbd->cdc2->tx_in_progress = 0;
|
}
|
||||||
usbd_cdc_tx_ready(usbd->cdc2);
|
}
|
||||||
return USBD_OK;
|
|
||||||
#endif
|
if ((usbd->usbd_mode & USBD_MODE_IFACE_MSC) && epnum == (MSC_IN_EP & 0x7f)) {
|
||||||
} 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 */
|
|
||||||
size_t len = USBD_LL_GetRxDataSize (pdev, epnum);
|
|
||||||
|
|
||||||
/* USB data will be immediately processed, this allow next USB traffic being
|
for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
|
||||||
NAKed till the end of the application Xfer */
|
if ((usbd->usbd_mode & USBD_MODE_IFACE_CDC(i)) && epnum == (CDC_OUT_EP(i) & 0x7f)) {
|
||||||
return usbd_cdc_receive(usbd->cdc, len);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if MICROPY_HW_USB_ENABLE_CDC2
|
if ((usbd->usbd_mode & USBD_MODE_IFACE_MSC) && epnum == (MSC_OUT_EP & 0x7f)) {
|
||||||
} 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,49 +948,47 @@ 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);
|
||||||
msc_desc[13] = LOBYTE(mp);
|
msc_desc[13] = LOBYTE(mp);
|
||||||
|
|
Loading…
Reference in New Issue