forked from espressif/esp-idf
feat(uhci): Add length receive threshold support
This commit is contained in:
@@ -24,6 +24,7 @@ typedef struct {
|
|||||||
size_t max_transmit_size; /*!< Maximum transfer size in one transaction, in bytes. This decides the number of DMA nodes will be used for each transaction */
|
size_t max_transmit_size; /*!< Maximum transfer size in one transaction, in bytes. This decides the number of DMA nodes will be used for each transaction */
|
||||||
size_t max_receive_internal_mem; /*!< Maximum transfer size in one transaction, in bytes. Each DMA node can point to a maximum of 4096 bytes. This value determines the number of DMA nodes used for each transaction. When your transfer size is large enough, it is recommended to set this value greater than 4096 to facilitate efficient ping-pong operations, such as 10 * 1024. */
|
size_t max_receive_internal_mem; /*!< Maximum transfer size in one transaction, in bytes. Each DMA node can point to a maximum of 4096 bytes. This value determines the number of DMA nodes used for each transaction. When your transfer size is large enough, it is recommended to set this value greater than 4096 to facilitate efficient ping-pong operations, such as 10 * 1024. */
|
||||||
size_t dma_burst_size; /*!< DMA burst size, in bytes */
|
size_t dma_burst_size; /*!< DMA burst size, in bytes */
|
||||||
|
size_t max_packet_receive; /*!< Max receive size, auto stop receiving after reach this value, only valid when `length_eof` set true */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint16_t rx_brk_eof: 1; /*!< UHCI will end payload receive process when NULL frame is received by UART. */
|
uint16_t rx_brk_eof: 1; /*!< UHCI will end payload receive process when NULL frame is received by UART. */
|
||||||
|
@@ -26,3 +26,5 @@ entries:
|
|||||||
gdma_link: gdma_link_mount_buffers (noflash)
|
gdma_link: gdma_link_mount_buffers (noflash)
|
||||||
gdma_link: gdma_link_get_head_addr (noflash)
|
gdma_link: gdma_link_get_head_addr (noflash)
|
||||||
gdma: gdma_start (noflash)
|
gdma: gdma_start (noflash)
|
||||||
|
gdma: gdma_stop (noflash)
|
||||||
|
gdma: gdma_reset (noflash)
|
||||||
|
@@ -149,6 +149,10 @@ static bool uhci_gdma_rx_callback_done(gdma_channel_handle_t dma_chan, gdma_even
|
|||||||
need_yield |= uhci_ctrl->rx_dir.on_rx_trans_event(uhci_ctrl, &evt_data, uhci_ctrl->user_data);
|
need_yield |= uhci_ctrl->rx_dir.on_rx_trans_event(uhci_ctrl, &evt_data, uhci_ctrl->user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stop the transaction when EOF is detected. In case for length EOF, there is no further more callback to be invoked.
|
||||||
|
gdma_stop(uhci_ctrl->rx_dir.dma_chan);
|
||||||
|
gdma_reset(uhci_ctrl->rx_dir.dma_chan);
|
||||||
|
|
||||||
uhci_ctrl->rx_dir.rx_fsm = UHCI_RX_FSM_ENABLE;
|
uhci_ctrl->rx_dir.rx_fsm = UHCI_RX_FSM_ENABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,6 +334,7 @@ esp_err_t uhci_receive(uhci_controller_handle_t uhci_ctrl, uint8_t *read_buffer,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
ESP_LOGD(TAG, "The DMA node %d has %d byte", i, uhci_ctrl->rx_dir.buffer_size_per_desc_node[i]);
|
ESP_LOGD(TAG, "The DMA node %d has %d byte", i, uhci_ctrl->rx_dir.buffer_size_per_desc_node[i]);
|
||||||
|
ESP_RETURN_ON_FALSE(uhci_ctrl->rx_dir.buffer_size_per_desc_node[i] != 0, ESP_ERR_INVALID_STATE, TAG, "Allocate dma node length is 0, please reconfigure the buffer_size");
|
||||||
read_buffer += uhci_ctrl->rx_dir.buffer_size_per_desc_node[i];
|
read_buffer += uhci_ctrl->rx_dir.buffer_size_per_desc_node[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,6 +456,9 @@ esp_err_t uhci_new_controller(const uhci_controller_config_t *config, uhci_contr
|
|||||||
|
|
||||||
uhci_controller_handle_t uhci_ctrl = (uhci_controller_handle_t)heap_caps_calloc(1, sizeof(uhci_controller_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
uhci_controller_handle_t uhci_ctrl = (uhci_controller_handle_t)heap_caps_calloc(1, sizeof(uhci_controller_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||||
ESP_RETURN_ON_FALSE(uhci_ctrl, ESP_ERR_NO_MEM, TAG, "no mem for uhci controller handle");
|
ESP_RETURN_ON_FALSE(uhci_ctrl, ESP_ERR_NO_MEM, TAG, "no mem for uhci controller handle");
|
||||||
|
if (config->rx_eof_flags.length_eof) {
|
||||||
|
ESP_RETURN_ON_FALSE(config->max_packet_receive < UHCI_LL_MAX_RECEIVE_PACKET_THRESHOLD, ESP_ERR_INVALID_ARG, TAG, "max receive packet is over threshold");
|
||||||
|
}
|
||||||
|
|
||||||
atomic_init(&uhci_ctrl->tx_dir.tx_fsm, UHCI_TX_FSM_ENABLE);
|
atomic_init(&uhci_ctrl->tx_dir.tx_fsm, UHCI_TX_FSM_ENABLE);
|
||||||
atomic_init(&uhci_ctrl->rx_dir.rx_fsm, UHCI_TX_FSM_ENABLE);
|
atomic_init(&uhci_ctrl->rx_dir.rx_fsm, UHCI_TX_FSM_ENABLE);
|
||||||
@@ -509,6 +517,7 @@ esp_err_t uhci_new_controller(const uhci_controller_config_t *config, uhci_contr
|
|||||||
}
|
}
|
||||||
if (config->rx_eof_flags.length_eof) {
|
if (config->rx_eof_flags.length_eof) {
|
||||||
uhci_ll_rx_set_eof_mode(uhci_ctrl->hal.dev, UHCI_RX_LEN_EOF);
|
uhci_ll_rx_set_eof_mode(uhci_ctrl->hal.dev, UHCI_RX_LEN_EOF);
|
||||||
|
uhci_ll_rx_set_packet_threshold(uhci_ctrl->hal.dev, config->max_packet_receive);
|
||||||
}
|
}
|
||||||
if (config->rx_eof_flags.rx_brk_eof) {
|
if (config->rx_eof_flags.rx_brk_eof) {
|
||||||
uhci_ll_rx_set_eof_mode(uhci_ctrl->hal.dev, UHCI_RX_BREAK_CHR_EOF);
|
uhci_ll_rx_set_eof_mode(uhci_ctrl->hal.dev, UHCI_RX_BREAK_CHR_EOF);
|
||||||
|
@@ -32,6 +32,6 @@ components/esp_driver_uart/test_apps/uart_vfs:
|
|||||||
components/esp_driver_uart/test_apps/uhci:
|
components/esp_driver_uart/test_apps/uhci:
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_UHCI_SUPPORTED != 1
|
- if: SOC_UHCI_SUPPORTED != 1
|
||||||
- if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1
|
- if: CONFIG_NAME == "psram" and SOC_AHB_GDMA_SUPPORT_PSRAM != 1
|
||||||
depends_components:
|
depends_components:
|
||||||
- esp_driver_uart
|
- esp_driver_uart
|
||||||
|
@@ -246,7 +246,7 @@ TEST_CASE("UHCI write and receive with length eof", "[uhci]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_SPIRAM
|
#if CONFIG_SPIRAM
|
||||||
#if CONFIG_IDF_TARGET_ESP32S3
|
#if SOC_AHB_GDMA_SUPPORT_PSRAM
|
||||||
static void uhci_receive_test_in_psram(void *arg)
|
static void uhci_receive_test_in_psram(void *arg)
|
||||||
{
|
{
|
||||||
uhci_controller_handle_t uhci_ctrl = ((uhci_controller_handle_t *)arg)[0];
|
uhci_controller_handle_t uhci_ctrl = ((uhci_controller_handle_t *)arg)[0];
|
||||||
|
@@ -55,7 +55,6 @@ static inline void uhci_ll_reset_register(int group_id)
|
|||||||
static inline void uhci_ll_init(uhci_dev_t *hw)
|
static inline void uhci_ll_init(uhci_dev_t *hw)
|
||||||
{
|
{
|
||||||
typeof(hw->conf0) conf0_reg;
|
typeof(hw->conf0) conf0_reg;
|
||||||
hw->conf0.clk_en = 1;
|
|
||||||
conf0_reg.val = 0;
|
conf0_reg.val = 0;
|
||||||
conf0_reg.clk_en = 1;
|
conf0_reg.clk_en = 1;
|
||||||
hw->conf0.val = conf0_reg.val;
|
hw->conf0.val = conf0_reg.val;
|
||||||
|
@@ -52,7 +52,6 @@ static inline void uhci_ll_reset_register(int group_id)
|
|||||||
static inline void uhci_ll_init(uhci_dev_t *hw)
|
static inline void uhci_ll_init(uhci_dev_t *hw)
|
||||||
{
|
{
|
||||||
typeof(hw->conf0) conf0_reg;
|
typeof(hw->conf0) conf0_reg;
|
||||||
hw->conf0.clk_en = 1;
|
|
||||||
conf0_reg.val = 0;
|
conf0_reg.val = 0;
|
||||||
conf0_reg.clk_en = 1;
|
conf0_reg.clk_en = 1;
|
||||||
hw->conf0.val = conf0_reg.val;
|
hw->conf0.val = conf0_reg.val;
|
||||||
|
@@ -516,7 +516,7 @@ examples/peripherals/uart/uart_dma_ota:
|
|||||||
disable:
|
disable:
|
||||||
- if: SOC_UHCI_SUPPORTED != 1
|
- if: SOC_UHCI_SUPPORTED != 1
|
||||||
disable_test:
|
disable_test:
|
||||||
- if: IDF_TARGET in ["esp32p4"]
|
- if: IDF_TARGET in ["esp32p4", "esp32c5"]
|
||||||
temporary: true
|
temporary: true
|
||||||
reason: Lack runners
|
reason: Lack runners
|
||||||
|
|
||||||
|
@@ -42,7 +42,7 @@ def send_file_via_uart(port: str, baud_rate: int, file_path: str, packet_size: i
|
|||||||
],
|
],
|
||||||
indirect=True,
|
indirect=True,
|
||||||
)
|
)
|
||||||
@idf_parametrize('target', ['esp32c6', 'esp32c3', 'esp32s3'], indirect=['target'])
|
@idf_parametrize('target', ['esp32c6', 'esp32c3', 'esp32s3', 'esp32h2'], indirect=['target'])
|
||||||
def test_uart_dma_ota(dut: Dut) -> None:
|
def test_uart_dma_ota(dut: Dut) -> None:
|
||||||
dut.expect_exact('uhci-example: OTA process started')
|
dut.expect_exact('uhci-example: OTA process started')
|
||||||
# We OTA the same binary to another partition and switch to there.
|
# We OTA the same binary to another partition and switch to there.
|
||||||
|
@@ -0,0 +1,2 @@
|
|||||||
|
CONFIG_IDF_TARGET="esp32h2"
|
||||||
|
CONFIG_UART_RX_IO=23
|
Reference in New Issue
Block a user