From 25d3509986aadb8f2a0d4d87d75b64223087512a Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 1 Aug 2019 21:49:17 +1000 Subject: [PATCH] stm32/usbd: Make USB device FIFO sizes dynamically configurable. Allows to optimise and configure the FIFO sizes depending on the USB device configuration selected at runtime, eg VCP+MSC vs 3xVCP+MSC. --- ports/stm32/mboot/main.c | 9 +++- ports/stm32/usb.c | 58 ++++++++++++++++++++++- ports/stm32/usbd_conf.c | 62 +++++++------------------ ports/stm32/usbd_conf.h | 10 ++++ ports/stm32/usbdev/core/inc/usbd_core.h | 2 +- ports/stm32/usbdev/core/src/usbd_core.c | 2 + 6 files changed, 96 insertions(+), 47 deletions(-) diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index f6b89004d..fcd43edc7 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -1088,6 +1088,13 @@ typedef struct _pyb_usbdd_obj_t { #define MBOOT_USB_PID 0xDF11 #endif +static const uint8_t usbd_fifo_size[] = { + 32, 8, 16, 8, 16, 0, 0, // FS: RX, EP0(in), 5x IN endpoints + #if MICROPY_HW_USB_HS + 116, 8, 64, 4, 64, 0, 0, 0, 0, 0, // HS: RX, EP0(in), 8x IN endpoints + #endif +}; + __ALIGN_BEGIN static const uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = { USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, @@ -1315,7 +1322,7 @@ static void pyb_usbdd_start(pyb_usbdd_obj_t *self) { while (!(PWR->CR3 & PWR_CR3_USB33RDY)) { } #endif - USBD_LL_Init(&self->hUSBDDevice, 0); + USBD_LL_Init(&self->hUSBDDevice, 0, usbd_fifo_size); USBD_LL_Start(&self->hUSBDDevice); self->started = true; } diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 3308f0744..791a6472a 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -75,6 +75,50 @@ typedef struct _usb_device_t { usb_device_t usb_device = {0}; pyb_usb_storage_medium_t pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_NONE; +#if !MICROPY_HW_USB_IS_MULTI_OTG + +// Units of FIFO size arrays below are 4x 16-bit words = 8 bytes +// There are 512x 16-bit words it total to use here (when using PCD_SNG_BUF) + +// EP0(out), EP0(in), MSC/HID(out), MSC/HID(in), unused, CDC_CMD(in), CDC_DATA(out), CDC_DATA(in) +STATIC const uint8_t usbd_fifo_size_cdc1[] = {16, 16, 16, 16, 0, 16, 16, 16}; + +#else + +// Units of FIFO size arrays below are 4x 32-bit words = 16 bytes +// FS: there are 320x 32-bit words in total to use here +// HS: there are 1024x 32-bit words in total to use here + +// RX; EP0(in), MSC/HID, CDC_CMD, CDC_DATA +STATIC const uint8_t usbd_fifo_size_cdc1[] = { + 32, 8, 16, 8, 16, 0, 0, // FS: RX, EP0(in), 5x IN endpoints + #if MICROPY_HW_USB_HS + 116, 8, 64, 4, 64, 0, 0, 0, 0, 0, // HS: RX, EP0(in), 8x IN endpoints + #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[] = { + 32, 8, 16, 4, 8, 4, 8, + #if MICROPY_HW_USB_HS + 116, 8, 64, 2, 32, 2, 32, 0, 0, 0, + #endif +}; +#endif + +#if MICROPY_HW_USB_CDC_NUM >= 3 +// RX; EP0(in), MSC/HID, CDC_CMD, CDC_DATA, CDC2_CMD, CDC2_DATA, CDC3_CMD, CDC3_DATA +STATIC const uint8_t usbd_fifo_size_cdc3[] = { + 0, 0, 0, 0, 0, 0, 0, // FS: can't support 3x VCP mode + #if MICROPY_HW_USB_HS + 82, 8, 64, 2, 32, 2, 32, 2, 32, 0, + #endif +}; +#endif + +#endif + #if MICROPY_HW_USB_HID // predefined hid mouse data STATIC const mp_obj_str_t pyb_usb_hid_mouse_desc_obj = { @@ -197,8 +241,20 @@ bool pyb_usb_dev_init(int dev_id, uint16_t vid, uint16_t pid, uint8_t mode, size USBD_MSC_RegisterStorage(&usb_dev->usbd_cdc_msc_hid_state, (USBD_StorageTypeDef*)&usbd_msc_fops); #endif + const uint8_t *fifo_size = usbd_fifo_size_cdc1; + #if MICROPY_HW_USB_CDC_NUM >= 3 + if (mode & USBD_MODE_IFACE_CDC(2)) { + 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; + } + #endif + // start the USB device - USBD_LL_Init(usbd, (mode & USBD_MODE_HIGH_SPEED) != 0); + USBD_LL_Init(usbd, (mode & USBD_MODE_HIGH_SPEED) != 0, fifo_size); USBD_LL_Start(usbd); usb_dev->enabled = true; } diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c index 275ec15aa..d30f28b2f 100644 --- a/ports/stm32/usbd_conf.c +++ b/ports/stm32/usbd_conf.c @@ -361,7 +361,7 @@ void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) { * @param pdev: Device handle * @retval USBD Status */ -USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) { +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed, const uint8_t *fifo_size) { #if MICROPY_HW_USB_FS if (pdev->id == USB_PHY_FS_ID) { #if defined(STM32WB) @@ -401,35 +401,19 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) { // Initialize LL Driver HAL_PCD_Init(&pcd_fs_handle); + // Set FIFO buffer sizes #if !MICROPY_HW_USB_IS_MULTI_OTG - // We have 512 16-bit words it total to use here (when using PCD_SNG_BUF) - HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x00, PCD_SNG_BUF, 64); // EP0 - HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x80, PCD_SNG_BUF, 128); // EP0 - HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x01, PCD_SNG_BUF, 192); // MSC / HID - HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x81, PCD_SNG_BUF, 256); // MSC / HID - HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x02, PCD_SNG_BUF, 320); // unused - HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x82, PCD_SNG_BUF, 320); // CDC CMD - HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x03, PCD_SNG_BUF, 384); // CDC DATA - HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x83, PCD_SNG_BUF, 448); // CDC DATA + uint32_t fifo_offset = USBD_PMA_RESERVE; // need to reserve some data at start of FIFO + for (size_t i = 0; i < USBD_PMA_NUM_FIFO; ++i) { + uint16_t ep_addr = ((i & 1) * 0x80) | (i >> 1); + HAL_PCDEx_PMAConfig(&pcd_fs_handle, ep_addr, PCD_SNG_BUF, fifo_offset); + fifo_offset += fifo_size[i] * 4; + } #else - - // We have 320 32-bit words in total to use here - #if MICROPY_HW_USB_CDC_NUM == 2 - HAL_PCD_SetRxFiFo(&pcd_fs_handle, 128); - 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, 2, 16); // CDC CMD - HAL_PCD_SetTxFiFo(&pcd_fs_handle, 3, 32); // CDC DATA - HAL_PCD_SetTxFiFo(&pcd_fs_handle, 4, 16); // CDC2 CMD - HAL_PCD_SetTxFiFo(&pcd_fs_handle, 5, 32); // CDC2 DATA - #else - HAL_PCD_SetRxFiFo(&pcd_fs_handle, 128); - 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, 2, 32); // CDC CMD - HAL_PCD_SetTxFiFo(&pcd_fs_handle, 3, 64); // CDC DATA - #endif - + HAL_PCD_SetRxFiFo(&pcd_fs_handle, fifo_size[0] * 4); + for (size_t i = 0; i < USBD_FS_NUM_TX_FIFO; ++i) { + HAL_PCD_SetTxFiFo(&pcd_fs_handle, i, fifo_size[1 + i] * 4); + } #endif } #endif @@ -486,22 +470,12 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) { // Initialize LL Driver 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 + // Set FIFO buffer sizes + fifo_size += USBD_FS_NUM_FIFO; // skip over FS FIFO size values + HAL_PCD_SetRxFiFo(&pcd_hs_handle, fifo_size[0] * 4); + for (size_t i = 0; i < USBD_HS_NUM_TX_FIFO; ++i) { + HAL_PCD_SetTxFiFo(&pcd_hs_handle, i, fifo_size[1 + i] * 4); + } } #endif // MICROPY_HW_USB_HS diff --git a/ports/stm32/usbd_conf.h b/ports/stm32/usbd_conf.h index 639b54d9f..83629bfc4 100644 --- a/ports/stm32/usbd_conf.h +++ b/ports/stm32/usbd_conf.h @@ -49,6 +49,16 @@ #endif #define USBD_DEBUG_LEVEL 0 +// For MCUs with a device-only USB peripheral +#define USBD_PMA_RESERVE (64) +#define USBD_PMA_NUM_FIFO (8) + +// For MCUs with multiple OTG USB peripherals +#define USBD_FS_NUM_TX_FIFO (6) +#define USBD_FS_NUM_FIFO (1 + USBD_FS_NUM_TX_FIFO) +#define USBD_HS_NUM_TX_FIFO (9) +#define USBD_HS_NUM_FIFO (1 + USBD_HS_NUM_TX_FIFO) + #endif // MICROPY_INCLUDED_STM32_USBD_CONF_H /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/ports/stm32/usbdev/core/inc/usbd_core.h b/ports/stm32/usbdev/core/inc/usbd_core.h index 5494be3a2..d3925fc6b 100644 --- a/ports/stm32/usbdev/core/inc/usbd_core.h +++ b/ports/stm32/usbdev/core/inc/usbd_core.h @@ -111,7 +111,7 @@ USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); /* USBD Low Level Driver */ -USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev, int high_speed); +USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev, int high_speed, const uint8_t *fifo_size); USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev); diff --git a/ports/stm32/usbdev/core/src/usbd_core.c b/ports/stm32/usbdev/core/src/usbd_core.c index f235b24ee..4c69a77eb 100644 --- a/ports/stm32/usbdev/core/src/usbd_core.c +++ b/ports/stm32/usbdev/core/src/usbd_core.c @@ -85,6 +85,7 @@ * @{ */ +#if 0 /** * @brief USBD_Init * Initailizes the device stack and load the class driver @@ -122,6 +123,7 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef * return USBD_OK; } +#endif /** * @brief USBD_DeInit