stm32/usb: Add support for VCP+MSC+HID mode, incl 2xVCP and 3xVCP.
This commit is contained in:
parent
cfec054073
commit
6705767da1
@ -97,6 +97,14 @@ STATIC const uint8_t usbd_fifo_size_cdc1[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
// RX; EP0(in), MSC/HID, CDC_CMD, CDC_DATA, HID
|
||||
STATIC const uint8_t usbd_fifo_size_cdc1_msc_hid[] = {
|
||||
32, 8, 16, 4, 12, 8, 0,
|
||||
#if MICROPY_HW_USB_HS
|
||||
116, 8, 64, 4, 56, 8, 0, 0, 0, 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if MICROPY_HW_USB_CDC_NUM >= 2
|
||||
// RX; EP0(in), MSC/HID, CDC_CMD, CDC_DATA, CDC2_CMD, CDC2_DATA
|
||||
STATIC const uint8_t usbd_fifo_size_cdc2[] = {
|
||||
@ -105,6 +113,14 @@ STATIC const uint8_t usbd_fifo_size_cdc2[] = {
|
||||
116, 8, 64, 2, 32, 2, 32, 0, 0, 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
// RX; EP0(in), MSC/HID, CDC_CMD, CDC_DATA, CDC2_CMD/HID, CDC2_DATA, HID
|
||||
STATIC const uint8_t usbd_fifo_size_cdc2_msc_hid[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, // FS: can't support 2xVCP+MSC+HID
|
||||
#if MICROPY_HW_USB_HS
|
||||
102, 8, 64, 2, 32, 8, 32, 8, 0, 0,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_USB_CDC_NUM >= 3
|
||||
@ -115,6 +131,14 @@ STATIC const uint8_t usbd_fifo_size_cdc3[] = {
|
||||
82, 8, 64, 2, 32, 2, 32, 2, 32, 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
// RX; EP0(in), MSC/HID, CDC_CMD, CDC_DATA, CDC2_CMD/HID, CDC2_DATA, CDC3_CMD/HID, CDC3_DATA, HID
|
||||
STATIC const uint8_t usbd_fifo_size_cdc3_msc_hid[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, // FS: can't support 3x VCP mode
|
||||
#if MICROPY_HW_USB_HS
|
||||
82, 8, 64, 2, 25, 8, 25, 8, 25, 8,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -242,14 +266,27 @@ bool pyb_usb_dev_init(int dev_id, uint16_t vid, uint16_t pid, uint8_t mode, size
|
||||
#endif
|
||||
|
||||
const uint8_t *fifo_size = usbd_fifo_size_cdc1;
|
||||
#if MICROPY_HW_USB_IS_MULTI_OTG
|
||||
if ((mode & USBD_MODE_MSC_HID) == USBD_MODE_MSC_HID) {
|
||||
fifo_size = usbd_fifo_size_cdc1_msc_hid;
|
||||
}
|
||||
#endif
|
||||
#if MICROPY_HW_USB_CDC_NUM >= 3
|
||||
if (mode & USBD_MODE_IFACE_CDC(2)) {
|
||||
fifo_size = usbd_fifo_size_cdc3;
|
||||
if ((mode & USBD_MODE_MSC_HID) == USBD_MODE_MSC_HID) {
|
||||
fifo_size = usbd_fifo_size_cdc3_msc_hid;
|
||||
} else {
|
||||
fifo_size = usbd_fifo_size_cdc3;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
#if MICROPY_HW_USB_CDC_NUM >= 2
|
||||
if (mode & USBD_MODE_IFACE_CDC(1)) {
|
||||
fifo_size = usbd_fifo_size_cdc2;
|
||||
if ((mode & USBD_MODE_MSC_HID) == USBD_MODE_MSC_HID) {
|
||||
fifo_size = usbd_fifo_size_cdc2_msc_hid;
|
||||
} else {
|
||||
fifo_size = usbd_fifo_size_cdc2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -414,6 +451,11 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
|
||||
pid = USBD_PID_CDC_MSC;
|
||||
}
|
||||
mode = USBD_MODE_CDC_MSC;
|
||||
} else if (strcmp(mode_str, "VCP+MSC+HID") == 0) {
|
||||
if (pid == -1) {
|
||||
pid = USBD_PID_CDC_MSC_HID;
|
||||
}
|
||||
mode = USBD_MODE_CDC_MSC_HID;
|
||||
#if MICROPY_HW_USB_CDC_NUM >= 2
|
||||
} else if (strcmp(mode_str, "VCP+VCP") == 0) {
|
||||
if (pid == -1) {
|
||||
@ -425,6 +467,11 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
|
||||
pid = USBD_PID_CDC2_MSC;
|
||||
}
|
||||
mode = USBD_MODE_CDC2_MSC;
|
||||
} else if (strcmp(mode_str, "2xVCP+MSC+HID") == 0) {
|
||||
if (pid == -1) {
|
||||
pid = USBD_PID_CDC2_MSC_HID;
|
||||
}
|
||||
mode = USBD_MODE_CDC2_MSC_HID;
|
||||
#endif
|
||||
#if MICROPY_HW_USB_CDC_NUM >= 3
|
||||
} else if (strcmp(mode_str, "3xVCP") == 0) {
|
||||
@ -437,6 +484,11 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
|
||||
pid = USBD_PID_CDC3_MSC;
|
||||
}
|
||||
mode = USBD_MODE_CDC3_MSC;
|
||||
} else if (strcmp(mode_str, "3xVCP+MSC+HID") == 0) {
|
||||
if (pid == -1) {
|
||||
pid = USBD_PID_CDC3_MSC_HID;
|
||||
}
|
||||
mode = USBD_MODE_CDC3_MSC_HID;
|
||||
#endif
|
||||
} else if (strcmp(mode_str, "CDC+HID") == 0 || strcmp(mode_str, "VCP+HID") == 0) {
|
||||
if (pid == -1) {
|
||||
|
@ -40,6 +40,9 @@
|
||||
#define USBD_PID_CDC2 (0x9805)
|
||||
#define USBD_PID_CDC3 (0x9806)
|
||||
#define USBD_PID_CDC3_MSC (0x9807)
|
||||
#define USBD_PID_CDC_MSC_HID (0x9808)
|
||||
#define USBD_PID_CDC2_MSC_HID (0x9809)
|
||||
#define USBD_PID_CDC3_MSC_HID (0x980a)
|
||||
|
||||
typedef enum {
|
||||
PYB_USB_STORAGE_MEDIUM_NONE = 0,
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
|
||||
#define USBD_MAX_NUM_INTERFACES 5
|
||||
#define USBD_MAX_NUM_INTERFACES 8
|
||||
#define USBD_MAX_NUM_CONFIGURATION 1
|
||||
#define USBD_MAX_STR_DESC_SIZ 0x100
|
||||
#if MICROPY_HW_USB_SELF_POWERED
|
||||
|
@ -18,16 +18,8 @@
|
||||
#endif
|
||||
|
||||
// Should be maximum of possible config descriptors that might be configured
|
||||
#if MICROPY_HW_USB_CDC_NUM == 3
|
||||
// Maximum is MSC+CDC+CDC+CDC
|
||||
#define MAX_TEMPLATE_CONFIG_DESC_SIZE (9 + 23 + (8 + 58) + (8 + 58) + (8 + 58))
|
||||
#elif MICROPY_HW_USB_CDC_NUM == 2
|
||||
// Maximum is MSC+CDC+CDC
|
||||
#define MAX_TEMPLATE_CONFIG_DESC_SIZE (9 + 23 + (8 + 58) + (8 + 58))
|
||||
#else
|
||||
// Maximum is HID+CDC
|
||||
#define MAX_TEMPLATE_CONFIG_DESC_SIZE (9 + 32 + (8 + 58))
|
||||
#endif
|
||||
// Maximum is: 9 + MSC + NxCDC + HID
|
||||
#define MAX_TEMPLATE_CONFIG_DESC_SIZE (9 + (23) + MICROPY_HW_USB_CDC_NUM * (8 + 58) + (9 + 9 + 7 + 7))
|
||||
|
||||
// CDC, MSC and HID packet sizes
|
||||
#define MSC_FS_MAX_PACKET (64)
|
||||
@ -118,7 +110,7 @@ typedef struct _usbd_cdc_msc_hid_state_t {
|
||||
USBD_HandleTypeDef *pdev;
|
||||
|
||||
uint8_t usbd_mode;
|
||||
uint8_t usbd_config_desc_size;
|
||||
uint16_t usbd_config_desc_size;
|
||||
|
||||
#if MICROPY_HW_USB_MSC
|
||||
USBD_MSC_BOT_HandleTypeDef MSC_BOT_ClassData;
|
||||
|
@ -44,6 +44,9 @@
|
||||
#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_CDC3_MSC (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_CDC(1) | USBD_MODE_IFACE_CDC(2) | USBD_MODE_IFACE_MSC)
|
||||
#define USBD_MODE_CDC_MSC_HID (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_MSC | USBD_MODE_IFACE_HID)
|
||||
#define USBD_MODE_CDC2_MSC_HID (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_CDC(1) | USBD_MODE_IFACE_MSC | USBD_MODE_IFACE_HID)
|
||||
#define USBD_MODE_CDC3_MSC_HID (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_CDC(1) | USBD_MODE_IFACE_CDC(2) | USBD_MODE_IFACE_MSC | USBD_MODE_IFACE_HID)
|
||||
#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)
|
||||
|
@ -61,9 +61,11 @@
|
||||
#define HID_DESC_OFFSET_PROTOCOL (7)
|
||||
#define HID_DESC_OFFSET_SUBDESC (9)
|
||||
#define HID_DESC_OFFSET_REPORT_DESC_LEN (16)
|
||||
#define HID_DESC_OFFSET_IN_EP (20)
|
||||
#define HID_DESC_OFFSET_MAX_PACKET_LO (22)
|
||||
#define HID_DESC_OFFSET_MAX_PACKET_HI (23)
|
||||
#define HID_DESC_OFFSET_POLLING_INTERVAL (24)
|
||||
#define HID_DESC_OFFSET_OUT_EP (27)
|
||||
#define HID_DESC_OFFSET_MAX_PACKET_OUT_LO (29)
|
||||
#define HID_DESC_OFFSET_MAX_PACKET_OUT_HI (30)
|
||||
#define HID_DESC_OFFSET_POLLING_INTERVAL_OUT (31)
|
||||
@ -79,6 +81,9 @@
|
||||
#define MSC_IFACE_NUM_WITH_CDC (0)
|
||||
#define HID_IFACE_NUM_WITH_CDC (0)
|
||||
#define HID_IFACE_NUM_WITH_MSC (1)
|
||||
#define HID_IFACE_NUM_WITH_CDC_MSC (3)
|
||||
#define HID_IFACE_NUM_WITH_CDC2_MSC (5)
|
||||
#define HID_IFACE_NUM_WITH_CDC3_MSC (7)
|
||||
|
||||
#define CDC_IN_EP(i) (0x83 + 2 * (i))
|
||||
#define CDC_OUT_EP(i) (0x03 + 2 * (i))
|
||||
@ -88,6 +93,12 @@
|
||||
#define HID_OUT_EP_WITH_CDC (0x01)
|
||||
#define HID_IN_EP_WITH_MSC (0x83)
|
||||
#define HID_OUT_EP_WITH_MSC (0x03)
|
||||
#define HID_IN_EP_WITH_CDC_MSC (0x84)
|
||||
#define HID_OUT_EP_WITH_CDC_MSC (0x04)
|
||||
#define HID_IN_EP_WITH_CDC2_MSC (0x86)
|
||||
#define HID_OUT_EP_WITH_CDC2_MSC (0x06)
|
||||
#define HID_IN_EP_WITH_CDC3_MSC (0x88)
|
||||
#define HID_OUT_EP_WITH_CDC3_MSC (0x08)
|
||||
|
||||
#define USB_DESC_TYPE_ASSOCIATION (0x0b)
|
||||
|
||||
@ -448,8 +459,9 @@ static size_t make_cdc_desc_ep(uint8_t *dest, int need_iad, uint8_t iface_num, u
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_USB_HID
|
||||
static size_t make_hid_desc(uint8_t *dest, USBD_HID_ModeInfoTypeDef *hid_info) {
|
||||
static size_t make_hid_desc(uint8_t *dest, USBD_HID_ModeInfoTypeDef *hid_info, uint8_t iface_num) {
|
||||
memcpy(dest, hid_class_desc_data, sizeof(hid_class_desc_data));
|
||||
dest[2] = iface_num;
|
||||
dest[HID_DESC_OFFSET_SUBCLASS] = hid_info->subclass;
|
||||
dest[HID_DESC_OFFSET_PROTOCOL] = hid_info->protocol;
|
||||
dest[HID_DESC_OFFSET_REPORT_DESC_LEN] = hid_info->report_desc_len;
|
||||
@ -461,6 +473,15 @@ static size_t make_hid_desc(uint8_t *dest, USBD_HID_ModeInfoTypeDef *hid_info) {
|
||||
dest[HID_DESC_OFFSET_POLLING_INTERVAL_OUT] = hid_info->polling_interval;
|
||||
return sizeof(hid_class_desc_data);
|
||||
}
|
||||
|
||||
#if MICROPY_HW_USB_MSC
|
||||
static size_t make_hid_desc_ep(uint8_t *dest, USBD_HID_ModeInfoTypeDef *hid_info, uint8_t iface_num, uint8_t in_ep, uint8_t out_ep) {
|
||||
size_t n = make_hid_desc(dest, hid_info, iface_num);
|
||||
dest[HID_DESC_OFFSET_IN_EP] = in_ep;
|
||||
dest[HID_DESC_OFFSET_OUT_EP] = out_ep;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// return the saved usb mode
|
||||
@ -489,6 +510,21 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode
|
||||
usbd->cdc[0]->iface_num = CDC_IFACE_NUM_WITH_MSC;
|
||||
num_itf = 3;
|
||||
break;
|
||||
|
||||
#if MICROPY_HW_USB_HID
|
||||
case USBD_MODE_CDC_MSC_HID:
|
||||
n += make_msc_desc(d + n);
|
||||
n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_WITH_MSC);
|
||||
usbd->hid->desc = d + n;
|
||||
n += make_hid_desc_ep(d + n, hid_info, HID_IFACE_NUM_WITH_CDC_MSC, HID_IN_EP_WITH_CDC_MSC, HID_OUT_EP_WITH_CDC_MSC);
|
||||
usbd->cdc[0]->iface_num = CDC_IFACE_NUM_WITH_MSC;
|
||||
usbd->hid->in_ep = HID_IN_EP_WITH_CDC_MSC;
|
||||
usbd->hid->out_ep = HID_OUT_EP_WITH_CDC_MSC;
|
||||
usbd->hid->iface_num = HID_IFACE_NUM_WITH_CDC_MSC;
|
||||
usbd->hid->report_desc = hid_info->report_desc;
|
||||
num_itf = 4;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_USB_CDC_NUM >= 2
|
||||
@ -511,6 +547,23 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode
|
||||
num_itf = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
case USBD_MODE_CDC2_MSC_HID: {
|
||||
n += make_msc_desc(d + n);
|
||||
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, CDC_CMD_EP(1), CDC_OUT_EP(1), CDC_IN_EP(1));
|
||||
usbd->hid->desc = d + n;
|
||||
n += make_hid_desc_ep(d + n, hid_info, HID_IFACE_NUM_WITH_CDC2_MSC, HID_IN_EP_WITH_CDC2_MSC, HID_OUT_EP_WITH_CDC2_MSC);
|
||||
usbd->cdc[0]->iface_num = CDC_IFACE_NUM_WITH_MSC;
|
||||
usbd->cdc[1]->iface_num = CDC2_IFACE_NUM_WITH_MSC;
|
||||
usbd->cdc[2]->iface_num = CDC3_IFACE_NUM_WITH_MSC;
|
||||
usbd->hid->in_ep = HID_IN_EP_WITH_CDC2_MSC;
|
||||
usbd->hid->out_ep = HID_OUT_EP_WITH_CDC2_MSC;
|
||||
usbd->hid->iface_num = HID_IFACE_NUM_WITH_CDC2_MSC;
|
||||
usbd->hid->report_desc = hid_info->report_desc;
|
||||
num_itf = 6;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -538,13 +591,31 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode
|
||||
num_itf = 7;
|
||||
break;
|
||||
}
|
||||
|
||||
case USBD_MODE_CDC3_MSC_HID: {
|
||||
n += make_msc_desc(d + n);
|
||||
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, CDC_CMD_EP(1), CDC_OUT_EP(1), CDC_IN_EP(1));
|
||||
n += make_cdc_desc_ep(d + n, 1, CDC3_IFACE_NUM_WITH_MSC, CDC_CMD_EP(2), CDC_OUT_EP(2), CDC_IN_EP(2));
|
||||
usbd->hid->desc = d + n;
|
||||
n += make_hid_desc_ep(d + n, hid_info, HID_IFACE_NUM_WITH_CDC3_MSC, HID_IN_EP_WITH_CDC3_MSC, HID_OUT_EP_WITH_CDC3_MSC);
|
||||
usbd->cdc[0]->iface_num = CDC_IFACE_NUM_WITH_MSC;
|
||||
usbd->cdc[1]->iface_num = CDC2_IFACE_NUM_WITH_MSC;
|
||||
usbd->cdc[2]->iface_num = CDC3_IFACE_NUM_WITH_MSC;
|
||||
usbd->hid->in_ep = HID_IN_EP_WITH_CDC3_MSC;
|
||||
usbd->hid->out_ep = HID_OUT_EP_WITH_CDC3_MSC;
|
||||
usbd->hid->iface_num = HID_IFACE_NUM_WITH_CDC3_MSC;
|
||||
usbd->hid->report_desc = hid_info->report_desc;
|
||||
num_itf = 8;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_USB_HID
|
||||
case USBD_MODE_CDC_HID:
|
||||
usbd->hid->desc = d + n;
|
||||
n += make_hid_desc(d + n, hid_info);
|
||||
n += make_hid_desc(d + n, hid_info, HID_IFACE_NUM_WITH_CDC);
|
||||
n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_WITH_HID);
|
||||
usbd->cdc[0]->iface_num = CDC_IFACE_NUM_WITH_HID;
|
||||
usbd->hid->in_ep = HID_IN_EP_WITH_CDC;
|
||||
|
Loading…
Reference in New Issue
Block a user