diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index c9c22d5d2b..ace090f804 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -309,6 +309,18 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * } mode = USBD_MODE_CDC2_MSC; #endif + #if MICROPY_HW_USB_CDC_NUM >= 3 + } else if (strcmp(mode_str, "3xVCP") == 0) { + if (args[2].u_int == -1) { + pid = USBD_PID_CDC3; + } + mode = USBD_MODE_CDC3; + } else if (strcmp(mode_str, "3xVCP+MSC") == 0) { + if (args[2].u_int == -1) { + pid = USBD_PID_CDC3_MSC; + } + mode = USBD_MODE_CDC3_MSC; + #endif } else if (strcmp(mode_str, "CDC+HID") == 0 || strcmp(mode_str, "VCP+HID") == 0) { if (args[2].u_int == -1) { pid = USBD_PID_CDC_HID; @@ -386,6 +398,9 @@ const pyb_usb_vcp_obj_t pyb_usb_vcp_obj[MICROPY_HW_USB_CDC_NUM] = { #if MICROPY_HW_USB_CDC_NUM >= 2 {{&pyb_usb_vcp_type}, &usb_device.usbd_cdc_itf[1]}, #endif + #if MICROPY_HW_USB_CDC_NUM >= 3 + {{&pyb_usb_vcp_type}, &usb_device.usbd_cdc_itf[2]}, + #endif }; STATIC void pyb_usb_vcp_init0(void) { diff --git a/ports/stm32/usb.h b/ports/stm32/usb.h index 6678e1e173..0aa50f9e77 100644 --- a/ports/stm32/usb.h +++ b/ports/stm32/usb.h @@ -38,6 +38,8 @@ #define USBD_PID_MSC (0x9803) #define USBD_PID_CDC2_MSC (0x9804) #define USBD_PID_CDC2 (0x9805) +#define USBD_PID_CDC3 (0x9806) +#define USBD_PID_CDC3_MSC (0x9807) typedef enum { PYB_USB_STORAGE_MEDIUM_NONE = 0, diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c index c2e86ccb5b..ed99700e99 100644 --- a/ports/stm32/usbd_conf.c +++ b/ports/stm32/usbd_conf.c @@ -385,7 +385,11 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) { if (pdev->id == USB_PHY_HS_ID) { // Set LL Driver parameters pcd_hs_handle.Instance = USB_OTG_HS; + #if MICROPY_HW_USB_CDC_NUM == 3 + pcd_hs_handle.Init.dev_endpoints = 8; + #else pcd_hs_handle.Init.dev_endpoints = 6; + #endif pcd_hs_handle.Init.use_dedicated_ep1 = 0; pcd_hs_handle.Init.ep0_mps = 0x40; pcd_hs_handle.Init.dma_enable = 0; @@ -431,13 +435,21 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) { HAL_PCD_Init(&pcd_hs_handle); // We have 1024 32-bit words in total to use here + #if MICROPY_HW_USB_CDC_NUM == 3 + HAL_PCD_SetRxFiFo(&pcd_hs_handle, 328); + #else HAL_PCD_SetRxFiFo(&pcd_hs_handle, 464); + #endif HAL_PCD_SetTxFiFo(&pcd_hs_handle, 0, 32); // EP0 HAL_PCD_SetTxFiFo(&pcd_hs_handle, 1, 256); // MSC / HID HAL_PCD_SetTxFiFo(&pcd_hs_handle, 2, 8); // CDC CMD HAL_PCD_SetTxFiFo(&pcd_hs_handle, 3, 128); // CDC DATA HAL_PCD_SetTxFiFo(&pcd_hs_handle, 4, 8); // CDC2 CMD HAL_PCD_SetTxFiFo(&pcd_hs_handle, 5, 128); // CDC2 DATA + #if MICROPY_HW_USB_CDC_NUM == 3 + HAL_PCD_SetTxFiFo(&pcd_hs_handle, 6, 8); // CDC3 CMD + HAL_PCD_SetTxFiFo(&pcd_hs_handle, 7, 128); // CDC3 DATA + #endif } #endif // MICROPY_HW_USB_HS diff --git a/ports/stm32/usbd_conf.h b/ports/stm32/usbd_conf.h index c5faf6c8c8..639b54d9f3 100644 --- a/ports/stm32/usbd_conf.h +++ b/ports/stm32/usbd_conf.h @@ -39,7 +39,7 @@ #include "py/mpconfig.h" -#define USBD_MAX_NUM_INTERFACES 4 +#define USBD_MAX_NUM_INTERFACES 5 #define USBD_MAX_NUM_CONFIGURATION 1 #define USBD_MAX_STR_DESC_SIZ 0x100 #if MICROPY_HW_USB_SELF_POWERED diff --git a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h index f20485a7c0..d4a218a4a6 100644 --- a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h +++ b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h @@ -19,7 +19,10 @@ #endif // Should be maximum of possible config descriptors that might be configured -#if MICROPY_HW_USB_CDC_NUM == 2 +#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 diff --git a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid0.h b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid0.h index 1cb879180d..63fe8ecefc 100644 --- a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid0.h +++ b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid0.h @@ -39,9 +39,11 @@ // Convenience macros for supported mode combinations #define USBD_MODE_CDC (USBD_MODE_IFACE_CDC(0)) #define USBD_MODE_CDC2 (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_CDC(1)) +#define USBD_MODE_CDC3 (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_CDC(1) | USBD_MODE_IFACE_CDC(2)) #define USBD_MODE_CDC_HID (USBD_MODE_IFACE_CDC(0) | USBD_MODE_IFACE_HID) #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_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) diff --git a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c index bfb5d3058a..d982fe8e6f 100644 --- a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c @@ -43,6 +43,13 @@ #define CDC2_MSC_TEMPLATE_MSC_DESC_OFFSET (9) #define CDC2_MSC_TEMPLATE_CDC_DESC_OFFSET (9 + 23 + 8) #define CDC2_MSC_TEMPLATE_CDC2_DESC_OFFSET (9 + 23 + (8 + 58) + 8) +#define CDC3_TEMPLATE_CDC_DESC_OFFSET (9 + 8) +#define CDC3_TEMPLATE_CDC2_DESC_OFFSET (9 + (8 + 58) + 8) +#define CDC3_TEMPLATE_CDC3_DESC_OFFSET (9 + (8 + 58) + (8 + 58) + 8) +#define CDC3_MSC_TEMPLATE_MSC_DESC_OFFSET (9) +#define CDC3_MSC_TEMPLATE_CDC_DESC_OFFSET (9 + 23 + 8) +#define CDC3_MSC_TEMPLATE_CDC2_DESC_OFFSET (9 + 23 + (8 + 58) + 8) +#define CDC3_MSC_TEMPLATE_CDC3_DESC_OFFSET (9 + 23 + (8 + 58) + (8 + 58) + 8) #define CDC_HID_TEMPLATE_CDC_DESC_OFFSET (49) #define CDC_TEMPLATE_CDC_DESC_OFFSET (9) #define CDC_DESC_OFFSET_INTR_INTERVAL (34) @@ -65,7 +72,9 @@ #define CDC_IFACE_NUM_ALONE (0) #define CDC_IFACE_NUM_WITH_MSC (1) #define CDC2_IFACE_NUM_WITH_CDC (2) +#define CDC3_IFACE_NUM_WITH_CDC (4) #define CDC2_IFACE_NUM_WITH_MSC (3) +#define CDC3_IFACE_NUM_WITH_MSC (5) #define CDC_IFACE_NUM_WITH_HID (1) #define MSC_IFACE_NUM_WITH_CDC (0) #define HID_IFACE_NUM_WITH_CDC (0) @@ -493,6 +502,31 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode } #endif + #if MICROPY_HW_USB_CDC_NUM >= 3 + case USBD_MODE_CDC3: { + n += make_cdc_desc(d + n, 1, CDC_IFACE_NUM_ALONE); + 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)); + n += make_cdc_desc_ep(d + n, 1, CDC3_IFACE_NUM_WITH_CDC, CDC_CMD_EP(2), CDC_OUT_EP(2), CDC_IN_EP(2)); + usbd->cdc[0]->iface_num = CDC_IFACE_NUM_ALONE; + usbd->cdc[1]->iface_num = CDC2_IFACE_NUM_WITH_CDC; + usbd->cdc[2]->iface_num = CDC3_IFACE_NUM_WITH_CDC; + num_itf = 6; + break; + } + + case USBD_MODE_CDC3_MSC: { + 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->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; + num_itf = 7; + break; + } + #endif + case USBD_MODE_CDC_HID: usbd->hid->desc = d + n; n += make_hid_desc(d + n, hid_info); @@ -973,6 +1007,21 @@ static uint8_t *USBD_CDC_MSC_HID_GetCfgDesc(USBD_HandleTypeDef *pdev, uint16_t * break; #endif + #if MICROPY_HW_USB_CDC_NUM >= 3 + case USBD_MODE_CDC3: + cdc_desc[0] = usbd->usbd_config_desc + CDC3_TEMPLATE_CDC_DESC_OFFSET; + cdc_desc[1] = usbd->usbd_config_desc + CDC3_TEMPLATE_CDC2_DESC_OFFSET; + cdc_desc[2] = usbd->usbd_config_desc + CDC3_TEMPLATE_CDC3_DESC_OFFSET; + break; + + case USBD_MODE_CDC3_MSC: + cdc_desc[0] = usbd->usbd_config_desc + CDC3_MSC_TEMPLATE_CDC_DESC_OFFSET; + cdc_desc[1] = usbd->usbd_config_desc + CDC3_MSC_TEMPLATE_CDC2_DESC_OFFSET; + cdc_desc[2] = usbd->usbd_config_desc + CDC3_MSC_TEMPLATE_CDC3_DESC_OFFSET; + msc_desc = usbd->usbd_config_desc + CDC3_MSC_TEMPLATE_MSC_DESC_OFFSET; + break; + #endif + case USBD_MODE_CDC_HID: cdc_desc[0] = usbd->usbd_config_desc + CDC_HID_TEMPLATE_CDC_DESC_OFFSET; break;