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.
pull/1/head
Damien George 2019-08-01 21:49:17 +10:00
parent 8485b72d0d
commit 25d3509986
6 changed files with 96 additions and 47 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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****/

View File

@ -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);

View File

@ -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