mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(usb/host): Calculate FIFO sizes based on USB configuration
This commit is contained in:
parent
2f6e45c79b
commit
f57ef07e14
@ -176,7 +176,7 @@ typedef struct {
|
||||
uint32_t *periodic_frame_list; /**< Pointer to scheduling frame list */
|
||||
usb_hal_frame_list_len_t frame_list_len; /**< Length of the periodic scheduling frame list */
|
||||
//FIFO related
|
||||
const usb_dwc_hal_fifo_config_t *fifo_config; /**< FIFO sizes configuration */
|
||||
usb_dwc_hal_fifo_config_t fifo_config; /**< FIFO sizes configuration */
|
||||
union {
|
||||
struct {
|
||||
uint32_t dbnc_lock_enabled: 1; /**< Debounce lock enabled */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -32,75 +32,6 @@ extern "C" {
|
||||
|
||||
#define USB_DWC_QTD_LIST_MEM_ALIGN 512
|
||||
#define USB_DWC_FRAME_LIST_MEM_ALIGN 512 // The frame list needs to be 512 bytes aligned (contrary to the databook)
|
||||
/*
|
||||
Although we have a 256 lines, only 200 lines are useable due to EPINFO_CTL.
|
||||
Todo: Check sizes again and express this macro in terms of DWC config options (IDF-7384)
|
||||
*/
|
||||
#define USB_DWC_FIFO_TOTAL_USABLE_LINES 200
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
------------------------------ DWC Configuration -------------------------------
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Default FIFO sizes (see 2.1.2.4 for programming guide)
|
||||
*
|
||||
* RXFIFO
|
||||
* - Recommended: ((LPS/4) * 2) + 2
|
||||
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 48 - 48 = 104
|
||||
* - Worst case can accommodate two packets of 204 bytes, or one packet of 408
|
||||
* NPTXFIFO
|
||||
* - Recommended: (LPS/4) * 2
|
||||
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 3 = 48
|
||||
* - Worst case can accommodate three packets of 64 bytes or one packet of 192
|
||||
* PTXFIFO
|
||||
* - Recommended: (LPS/4) * 2
|
||||
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 3 = 48
|
||||
* - Worst case can accommodate three packets of 64 bytes or one packet of 192
|
||||
*/
|
||||
#define USB_DWC_FIFO_RX_LINES_DEFAULT 104
|
||||
#define USB_DWC_FIFO_NPTX_LINES_DEFAULT 48
|
||||
#define USB_DWC_FIFO_PTX_LINES_DEFAULT 48
|
||||
|
||||
/**
|
||||
* @brief FIFO sizes that bias to giving RX FIFO more capacity
|
||||
*
|
||||
* RXFIFO
|
||||
* - Recommended: ((LPS/4) * 2) + 2
|
||||
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 32 - 16 = 152
|
||||
* - Worst case can accommodate two packets of 300 bytes or one packet of 600 bytes
|
||||
* NPTXFIFO
|
||||
* - Recommended: (LPS/4) * 2
|
||||
* - Actual: Assume LPS is 64, and 1 packets: (64/4) * 1 = 16
|
||||
* - Worst case can accommodate one packet of 64 bytes
|
||||
* PTXFIFO
|
||||
* - Recommended: (LPS/4) * 2
|
||||
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 2 = 32
|
||||
* - Worst case can accommodate two packets of 64 bytes or one packet of 128
|
||||
*/
|
||||
#define USB_DWC_FIFO_RX_LINES_BIASRX 152
|
||||
#define USB_DWC_FIFO_NPTX_LINES_BIASRX 16
|
||||
#define USB_DWC_FIFO_PTX_LINES_BIASRX 32
|
||||
|
||||
/**
|
||||
* @brief FIFO sizes that bias to giving Periodic TX FIFO more capacity (i.e., ISOC OUT)
|
||||
*
|
||||
* RXFIFO
|
||||
* - Recommended: ((LPS/4) * 2) + 2
|
||||
* - Actual: Assume LPS is 64, and 2 packets: ((64/4) * 2) + 2 = 34
|
||||
* - Worst case can accommodate two packets of 64 bytes or one packet of 128
|
||||
* NPTXFIFO
|
||||
* - Recommended: (LPS/4) * 2
|
||||
* - Actual: Assume LPS is 64, and 1 packets: (64/4) * 1 = 16
|
||||
* - Worst case can accommodate one packet of 64 bytes
|
||||
* PTXFIFO
|
||||
* - Recommended: (LPS/4) * 2
|
||||
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 34 - 16 = 150
|
||||
* - Worst case can accommodate two packets of 300 bytes or one packet of 600 bytes
|
||||
*/
|
||||
#define USB_DWC_FIFO_RX_LINES_BIASTX 34
|
||||
#define USB_DWC_FIFO_NPTX_LINES_BIASTX 16
|
||||
#define USB_DWC_FIFO_PTX_LINES_BIASTX 150
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
------------------------------- Global Registers -------------------------------
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -21,40 +21,7 @@
|
||||
#define BENDPOINTADDRESS_NUM_MSK 0x0F //Endpoint number mask of the bEndpointAddress field of an endpoint descriptor
|
||||
#define BENDPOINTADDRESS_DIR_MSK 0x80 //Endpoint direction mask of the bEndpointAddress field of an endpoint descriptor
|
||||
|
||||
#define CORE_REG_GSNPSID 0x4F54400A
|
||||
#define CORE_REG_GHWCFG1 0x00000000
|
||||
#define CORE_REG_GHWCFG2 0x224DD930
|
||||
#define CORE_REG_GHWCFG3 0x00C804B5
|
||||
#define CORE_REG_GHWCFG4 0xD3F0A030
|
||||
|
||||
// ----------------------- Configs -------------------------
|
||||
|
||||
/**
|
||||
* @brief Default FIFO sizes (see 2.1.2.4 for programming guide)
|
||||
*/
|
||||
const usb_dwc_hal_fifo_config_t fifo_config_default = {
|
||||
.rx_fifo_lines = USB_DWC_FIFO_RX_LINES_DEFAULT,
|
||||
.nptx_fifo_lines = USB_DWC_FIFO_NPTX_LINES_DEFAULT,
|
||||
.ptx_fifo_lines = USB_DWC_FIFO_PTX_LINES_DEFAULT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief FIFO sizes that bias to giving RX FIFO more capacity
|
||||
*/
|
||||
const usb_dwc_hal_fifo_config_t fifo_config_bias_rx = {
|
||||
.rx_fifo_lines = USB_DWC_FIFO_RX_LINES_BIASRX,
|
||||
.nptx_fifo_lines = USB_DWC_FIFO_NPTX_LINES_BIASRX,
|
||||
.ptx_fifo_lines = USB_DWC_FIFO_PTX_LINES_BIASRX,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief FIFO sizes that bias to giving Periodic TX FIFO more capacity (i.e., ISOC OUT)
|
||||
*/
|
||||
const usb_dwc_hal_fifo_config_t fifo_config_bias_ptx = {
|
||||
.rx_fifo_lines = USB_DWC_FIFO_RX_LINES_BIASTX,
|
||||
.nptx_fifo_lines = USB_DWC_FIFO_NPTX_LINES_BIASTX,
|
||||
.ptx_fifo_lines = USB_DWC_FIFO_PTX_LINES_BIASTX,
|
||||
};
|
||||
#define CORE_REG_GSNPSID 0x4F54400A //Release number of USB_DWC used in Espressif's SoCs
|
||||
|
||||
// -------------------- Configurable -----------------------
|
||||
|
||||
@ -193,22 +160,49 @@ void usb_dwc_hal_core_soft_reset(usb_dwc_hal_context_t *hal)
|
||||
|
||||
void usb_dwc_hal_set_fifo_bias(usb_dwc_hal_context_t *hal, const usb_hal_fifo_bias_t fifo_bias)
|
||||
{
|
||||
const usb_dwc_hal_fifo_config_t *fifo_config;
|
||||
/*
|
||||
* EPINFO_CTL is located at the end of FIFO, its size is fixed in HW.
|
||||
* The reserved size is always the worst-case, which is device mode that requires 4 locations per EP direction (including EP0).
|
||||
* Here we just read the FIFO size from HW register, to avoid any ambivalence
|
||||
*/
|
||||
uint32_t ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4;
|
||||
usb_dwc_ll_ghwcfg_get_hw_config(hal->dev, &ghwcfg1, &ghwcfg2, &ghwcfg3, &ghwcfg4);
|
||||
const uint16_t fifo_size_lines = ((usb_dwc_ghwcfg3_reg_t)ghwcfg3).dfifodepth;
|
||||
|
||||
/*
|
||||
* Recommended FIFO sizes (see 2.1.2.4 for programming guide)
|
||||
*
|
||||
* RXFIFO: ((LPS/4) * 2) + 2
|
||||
* NPTXFIFO: (LPS/4) * 2
|
||||
* PTXFIFO: (LPS/4) * 2
|
||||
*
|
||||
* Recommended sizes fit 2 packets of each type. For S2 and S3 we can't fit even one MPS ISOC packet (1023 FS and 1024 HS).
|
||||
* So the calculations below are compromises between the available FIFO size and optimal performance.
|
||||
*/
|
||||
usb_dwc_hal_fifo_config_t fifo_config;
|
||||
switch (fifo_bias) {
|
||||
// Define minimum viable (fits at least 1 MPS) FIFO sizes for non-biased FIFO types
|
||||
// Allocate the remaining size to the biased FIFO type
|
||||
case USB_HAL_FIFO_BIAS_DEFAULT:
|
||||
fifo_config = &fifo_config_default;
|
||||
fifo_config.nptx_fifo_lines = OTG_DFIFO_DEPTH / 4;
|
||||
fifo_config.ptx_fifo_lines = OTG_DFIFO_DEPTH / 8;
|
||||
fifo_config.rx_fifo_lines = fifo_size_lines - fifo_config.ptx_fifo_lines - fifo_config.nptx_fifo_lines;
|
||||
break;
|
||||
case USB_HAL_FIFO_BIAS_RX:
|
||||
fifo_config = &fifo_config_bias_rx;
|
||||
fifo_config.nptx_fifo_lines = OTG_DFIFO_DEPTH / 16;
|
||||
fifo_config.ptx_fifo_lines = OTG_DFIFO_DEPTH / 8;
|
||||
fifo_config.rx_fifo_lines = fifo_size_lines - fifo_config.ptx_fifo_lines - fifo_config.nptx_fifo_lines;
|
||||
break;
|
||||
case USB_HAL_FIFO_BIAS_PTX:
|
||||
fifo_config = &fifo_config_bias_ptx;
|
||||
fifo_config.rx_fifo_lines = OTG_DFIFO_DEPTH / 8 + 2; // 2 extra lines are allocated for status information. See USB-OTG Programming Guide, chapter 2.1.2.1
|
||||
fifo_config.nptx_fifo_lines = OTG_DFIFO_DEPTH / 16;
|
||||
fifo_config.ptx_fifo_lines = fifo_size_lines - fifo_config.nptx_fifo_lines - fifo_config.rx_fifo_lines;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
HAL_ASSERT((fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines + fifo_config->ptx_fifo_lines) <= USB_DWC_FIFO_TOTAL_USABLE_LINES);
|
||||
HAL_ASSERT((fifo_config.rx_fifo_lines + fifo_config.nptx_fifo_lines + fifo_config.ptx_fifo_lines) <= fifo_size_lines);
|
||||
//Check that none of the channels are active
|
||||
for (int i = 0; i < OTG_NUM_HOST_CHAN; i++) {
|
||||
if (hal->channels.hdls[i] != NULL) {
|
||||
@ -216,14 +210,14 @@ void usb_dwc_hal_set_fifo_bias(usb_dwc_hal_context_t *hal, const usb_hal_fifo_bi
|
||||
}
|
||||
}
|
||||
//Set the new FIFO lengths
|
||||
usb_dwc_ll_grxfsiz_set_fifo_size(hal->dev, fifo_config->rx_fifo_lines);
|
||||
usb_dwc_ll_gnptxfsiz_set_fifo_size(hal->dev, fifo_config->rx_fifo_lines, fifo_config->nptx_fifo_lines);
|
||||
usb_dwc_ll_hptxfsiz_set_ptx_fifo_size(hal->dev, fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines, fifo_config->ptx_fifo_lines);
|
||||
usb_dwc_ll_grxfsiz_set_fifo_size(hal->dev, fifo_config.rx_fifo_lines);
|
||||
usb_dwc_ll_gnptxfsiz_set_fifo_size(hal->dev, fifo_config.rx_fifo_lines, fifo_config.nptx_fifo_lines);
|
||||
usb_dwc_ll_hptxfsiz_set_ptx_fifo_size(hal->dev, fifo_config.rx_fifo_lines + fifo_config.nptx_fifo_lines, fifo_config.ptx_fifo_lines);
|
||||
//Flush the FIFOs
|
||||
usb_dwc_ll_grstctl_flush_nptx_fifo(hal->dev);
|
||||
usb_dwc_ll_grstctl_flush_ptx_fifo(hal->dev);
|
||||
usb_dwc_ll_grstctl_flush_rx_fifo(hal->dev);
|
||||
hal->fifo_config = fifo_config;
|
||||
hal->fifo_config = fifo_config; // Implicit struct copy
|
||||
hal->flags.fifo_sizes_set = 1;
|
||||
}
|
||||
|
||||
@ -232,7 +226,7 @@ void usb_dwc_hal_get_mps_limits(usb_dwc_hal_context_t *hal, usb_hal_fifo_mps_lim
|
||||
HAL_ASSERT(hal && mps_limits);
|
||||
HAL_ASSERT(hal->flags.fifo_sizes_set);
|
||||
|
||||
const usb_dwc_hal_fifo_config_t *fifo_config = hal->fifo_config;
|
||||
const usb_dwc_hal_fifo_config_t *fifo_config = &(hal->fifo_config);
|
||||
mps_limits->in_mps = (fifo_config->rx_fifo_lines - 2) * 4; // Two lines are reserved for status quadlets internally by USB_DWC
|
||||
mps_limits->non_periodic_out_mps = fifo_config->nptx_fifo_lines * 4;
|
||||
mps_limits->periodic_out_mps = fifo_config->ptx_fifo_lines * 4;
|
||||
|
Loading…
Reference in New Issue
Block a user