From 2dd14289c36037696ddd4e65b72da2ff07f65b26 Mon Sep 17 00:00:00 2001 From: Chen Jichang Date: Fri, 17 Jul 2026 15:54:36 +0800 Subject: [PATCH] ci(parlio_rx): fixed the parlio rx spi test case --- .../esp32c5/parlio_retention.c | 3 +- .../esp32c6/parlio_retention.c | 3 +- .../esp32h2/parlio_retention.c | 3 +- .../esp32h21/parlio_retention.c | 3 +- .../esp32h4/parlio_retention.c | 3 +- .../esp32p4/parlio_retention.c | 3 +- .../esp32s31/parlio_retention.c | 3 +- components/esp_driver_parlio/linker.lf | 2 + .../esp_driver_parlio/src/parlio_common.c | 25 +++ .../esp_driver_parlio/src/parlio_priv.h | 13 ++ components/esp_driver_parlio/src/parlio_rx.c | 18 +- .../test_apps/parlio/main/test_parlio_rx.c | 201 +++--------------- .../test_apps/parlio/pytest_parlio_unity.py | 19 +- .../esp32c5/include/hal/parlio_ll.h | 2 + .../esp32c6/include/hal/parlio_ll.h | 2 + .../esp32h2/include/hal/parlio_ll.h | 2 + .../esp32h4/include/hal/parlio_ll.h | 2 + .../esp32p4/include/hal/parlio_ll.h | 2 + 18 files changed, 110 insertions(+), 199 deletions(-) diff --git a/components/esp_driver_parlio/esp32c5/parlio_retention.c b/components/esp_driver_parlio/esp32c5/parlio_retention.c index 27ca647e5f6..58618351af7 100644 --- a/components/esp_driver_parlio/esp32c5/parlio_retention.c +++ b/components/esp_driver_parlio/esp32c5/parlio_retention.c @@ -15,7 +15,8 @@ */ #define PARLIO_RETENTION_REGS_CNT 8 #define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0) -static const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_cnt = PARLIO_RETENTION_REGS_CNT; static const regdma_entries_config_t parlio_regs_retention[] = { // backup stage: save configuration registers // restore stage: restore the configuration registers diff --git a/components/esp_driver_parlio/esp32c6/parlio_retention.c b/components/esp_driver_parlio/esp32c6/parlio_retention.c index 02e21f48a2c..b23321efb27 100644 --- a/components/esp_driver_parlio/esp32c6/parlio_retention.c +++ b/components/esp_driver_parlio/esp32c6/parlio_retention.c @@ -13,7 +13,8 @@ */ #define PARLIO_RETENTION_REGS_CNT 6 #define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0) -static const uint32_t parlio_regs_map[4] = {0x2f, 0x0, 0x100, 0x0}; +const uint32_t parlio_regs_map[4] = {0x2f, 0x0, 0x100, 0x0}; +const uint32_t parlio_regs_cnt = PARLIO_RETENTION_REGS_CNT; static const regdma_entries_config_t parlio_regs_retention[] = { // backup stage: save configuration registers // restore stage: restore the configuration registers diff --git a/components/esp_driver_parlio/esp32h2/parlio_retention.c b/components/esp_driver_parlio/esp32h2/parlio_retention.c index 27ca647e5f6..58618351af7 100644 --- a/components/esp_driver_parlio/esp32h2/parlio_retention.c +++ b/components/esp_driver_parlio/esp32h2/parlio_retention.c @@ -15,7 +15,8 @@ */ #define PARLIO_RETENTION_REGS_CNT 8 #define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0) -static const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_cnt = PARLIO_RETENTION_REGS_CNT; static const regdma_entries_config_t parlio_regs_retention[] = { // backup stage: save configuration registers // restore stage: restore the configuration registers diff --git a/components/esp_driver_parlio/esp32h21/parlio_retention.c b/components/esp_driver_parlio/esp32h21/parlio_retention.c index 218a7772c0a..d36f46425b8 100644 --- a/components/esp_driver_parlio/esp32h21/parlio_retention.c +++ b/components/esp_driver_parlio/esp32h21/parlio_retention.c @@ -15,7 +15,8 @@ */ #define PARLIO_RETENTION_REGS_CNT 8 #define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0) -static const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_cnt = PARLIO_RETENTION_REGS_CNT; static const regdma_entries_config_t parlio_regs_retention[] = { [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PARLIO_LINK(0x00), \ diff --git a/components/esp_driver_parlio/esp32h4/parlio_retention.c b/components/esp_driver_parlio/esp32h4/parlio_retention.c index 27ca647e5f6..58618351af7 100644 --- a/components/esp_driver_parlio/esp32h4/parlio_retention.c +++ b/components/esp_driver_parlio/esp32h4/parlio_retention.c @@ -15,7 +15,8 @@ */ #define PARLIO_RETENTION_REGS_CNT 8 #define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0) -static const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_cnt = PARLIO_RETENTION_REGS_CNT; static const regdma_entries_config_t parlio_regs_retention[] = { // backup stage: save configuration registers // restore stage: restore the configuration registers diff --git a/components/esp_driver_parlio/esp32p4/parlio_retention.c b/components/esp_driver_parlio/esp32p4/parlio_retention.c index 324e5ba095a..f51303a08ca 100644 --- a/components/esp_driver_parlio/esp32p4/parlio_retention.c +++ b/components/esp_driver_parlio/esp32p4/parlio_retention.c @@ -15,7 +15,8 @@ */ #define PARLIO_RETENTION_REGS_CNT 8 #define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0) -static const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_cnt = PARLIO_RETENTION_REGS_CNT; static const regdma_entries_config_t parlio_regs_retention[] = { // backup stage: save configuration registers // restore stage: restore the configuration registers diff --git a/components/esp_driver_parlio/esp32s31/parlio_retention.c b/components/esp_driver_parlio/esp32s31/parlio_retention.c index 25059e32683..6d5dec4d179 100644 --- a/components/esp_driver_parlio/esp32s31/parlio_retention.c +++ b/components/esp_driver_parlio/esp32s31/parlio_retention.c @@ -15,7 +15,8 @@ */ #define PARLIO_RETENTION_REGS_CNT 8 #define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0) -static const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +const uint32_t parlio_regs_cnt = PARLIO_RETENTION_REGS_CNT; static const regdma_entries_config_t parlio_regs_retention[] = { // backup stage: save configuration registers // restore stage: restore the configuration registers diff --git a/components/esp_driver_parlio/linker.lf b/components/esp_driver_parlio/linker.lf index 9cbf57ed74a..952757a1df5 100644 --- a/components/esp_driver_parlio/linker.lf +++ b/components/esp_driver_parlio/linker.lf @@ -15,6 +15,8 @@ entries: parlio_rx: parlio_rx_mount_transaction_buffer (noflash) parlio_rx: parlio_rx_set_delimiter_config (noflash) parlio_rx: parlio_rx_unit_receive_from_isr (noflash) + parlio_rx: parlio_rx_unit_trigger_fake_eof (noflash) + parlio_common: parlio_sw_retention (noflash) [mapping:parlio_driver_gdma_link] archive: libesp_driver_dma.a diff --git a/components/esp_driver_parlio/src/parlio_common.c b/components/esp_driver_parlio/src/parlio_common.c index 7f42005f42a..3083406fca7 100644 --- a/components/esp_driver_parlio/src/parlio_common.c +++ b/components/esp_driver_parlio/src/parlio_common.c @@ -53,6 +53,10 @@ parlio_group_t *parlio_acquire_group_handle(int group_id) #endif // PARLIO_USE_RETENTION_LINK // hal layer initialize parlio_hal_init(&group->hal); +#if SOC_PAU_SUPPORTED && SOC_PARLIO_SUPPORT_SLEEP_RETENTION + memcpy(group->regs_map, parlio_regs_map, sizeof(group->regs_map)); + group->regs_cnt = parlio_regs_cnt; +#endif group->dma_align = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); group->dma_align = group->dma_align < 4 ? 4 : group->dma_align; } @@ -197,6 +201,27 @@ void parlio_create_retention_module(parlio_group_t *group) } #endif // PARLIO_USE_RETENTION_LINK +void parlio_sw_retention(parlio_group_t *group, uint32_t *reg_dump, bool save) +{ + parlio_hal_context_t *hal = &group->hal; + portENTER_CRITICAL_SAFE(&group->spinlock); + volatile uint32_t *reg_base_addr = (volatile uint32_t *)hal->regs; + int idx = 0; + for (int i = 0; i < 4; i++) { + for (uint32_t map = group->regs_map[i], offset = 32 * i; map; map >>= 1, offset++) { + if (map & 0x01) { + if (save) { + reg_dump[idx] = reg_base_addr[offset]; + } else { + reg_base_addr[offset] = reg_dump[idx]; + } + idx++; + } + } + } + portEXIT_CRITICAL_SAFE(&group->spinlock); +} + #if CONFIG_PARLIO_ENABLE_DEBUG_LOG __attribute__((constructor)) static void parlio_override_default_log_level(void) diff --git a/components/esp_driver_parlio/src/parlio_priv.h b/components/esp_driver_parlio/src/parlio_priv.h index 142c5bf49c8..51f3f3b182f 100644 --- a/components/esp_driver_parlio/src/parlio_priv.h +++ b/components/esp_driver_parlio/src/parlio_priv.h @@ -79,6 +79,8 @@ typedef struct { } parlio_retention_desc_t; extern const parlio_retention_desc_t parlio_retention_infos[PARLIO_LL_GET(INST_NUM)]; +extern const uint32_t parlio_regs_map[4]; +extern const uint32_t parlio_regs_cnt; #endif // SOC_PARLIO_SUPPORT_SLEEP_RETENTION #define PARLIO_DMA_DESCRIPTOR_BUFFER_MAX_SIZE 4095 @@ -128,6 +130,8 @@ typedef struct parlio_group_t { int group_id; // group ID, index from 0 portMUX_TYPE spinlock; // to protect per-group register level concurrent access parlio_hal_context_t hal; // hal layer context + uint32_t regs_map[4]; // register map for software retention + uint32_t regs_cnt; // register count for software retention uint32_t dma_align; // DMA buffer alignment parlio_unit_base_handle_t tx_units[PARLIO_LL_GET(TX_UNITS_PER_INST)]; // tx unit handles parlio_unit_base_handle_t rx_units[PARLIO_LL_GET(RX_UNITS_PER_INST)]; // rx unit handles @@ -211,6 +215,15 @@ esp_err_t parlio_register_unit_to_group(parlio_unit_base_handle_t unit); */ void parlio_unregister_unit_from_group(parlio_unit_base_handle_t unit); +/** + * @brief Retain the Parallel IO registers by software + * + * @param[in] group The parlio group handle + * @param[in] reg_dump The register dump buffer + * @param[in] save If true, save the registers; if false, restore the registers + */ +void parlio_sw_retention(parlio_group_t *group, uint32_t *reg_dump, bool save); + #if PARLIO_USE_RETENTION_LINK esp_err_t parlio_create_sleep_retention_link_cb(void *arg); void parlio_create_retention_module(parlio_group_t *group); diff --git a/components/esp_driver_parlio/src/parlio_rx.c b/components/esp_driver_parlio/src/parlio_rx.c index 4bc92783a37..840414ec41f 100644 --- a/components/esp_driver_parlio/src/parlio_rx.c +++ b/components/esp_driver_parlio/src/parlio_rx.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -376,6 +376,13 @@ static bool parlio_rx_default_desc_done_callback(gdma_channel_handle_t dma_chan, /* Get the finished node from the current node */ void *finished_buffer = gdma_link_get_buffer(rx_unit->dma_link, rx_unit->curr_node_id); size_t finished_length = gdma_link_get_length(rx_unit->dma_link, rx_unit->curr_node_id); + if (finished_buffer == NULL || finished_length == 0) { + ESP_EARLY_LOGW(TAG, "finished buffer is NULL or length is 0"); + /* Should not happen unless the force EOF is triggered, keep software tracking synchronized */ + rx_unit->curr_node_id++; + rx_unit->curr_node_id %= rx_unit->node_num; + return false; + } #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE esp_err_t ret = ESP_OK; size_t sync_size = finished_length; @@ -1155,8 +1162,9 @@ esp_err_t parlio_rx_unit_trigger_fake_eof(parlio_rx_unit_handle_t rx_unit, bool parlio_hal_context_t *hal = &rx_unit->base.group->hal; portENTER_CRITICAL_SAFE(&s_rx_spinlock); - /* Save the current register values */ - parl_io_dev_t save_curr_regs = *(parl_io_dev_t *)hal->regs; + /* Retain the current register values by the software */ + uint32_t reg_dump[rx_unit->base.group->regs_cnt]; + parlio_sw_retention(rx_unit->base.group, reg_dump, true); /* Reset the hardware FSM of the parlio module */ PERIPH_RCC_ATOMIC() { parlio_ll_reset_register(rx_unit->base.group->group_id); @@ -1166,8 +1174,8 @@ esp_err_t parlio_rx_unit_trigger_fake_eof(parlio_rx_unit_handle_t rx_unit, bool parlio_ll_rx_set_clock_source(hal->regs, PARLIO_CLK_SRC_DEFAULT); } portEXIT_CRITICAL_SAFE(&s_rx_spinlock); - /* Restore the register values and clock source*/ - memcpy(hal->regs, &save_curr_regs, sizeof(parl_io_dev_t)); + /* Restore the register values and clock source */ + parlio_sw_retention(rx_unit->base.group, reg_dump, false); parlio_ll_rx_update_config(hal->regs); PERIPH_RCC_ATOMIC() { parlio_ll_rx_set_clock_source(hal->regs, rx_unit->clk_src); diff --git a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c index b1cd80042ac..47fdbabab00 100644 --- a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c +++ b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c @@ -156,31 +156,7 @@ static void pulse_delimiter_sender_task_i2s(void *args) } } -static void cs_high(spi_transaction_t *trans) -{ - gpio_set_level(TEST_VALID_GPIO, 1); -} - -static void cs_low(spi_transaction_t *trans) -{ - gpio_set_level(TEST_VALID_GPIO, 0); -} - -#define TEST_SPI_CLK_FREQ 100000 - -static void connect_signal_internally(uint32_t gpio, uint32_t sigo, uint32_t sigi) -{ - gpio_config_t gpio_conf = { - .pin_bit_mask = BIT64(gpio), - .mode = GPIO_MODE_INPUT_OUTPUT, - .intr_type = GPIO_INTR_DISABLE, - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .pull_up_en = GPIO_PULLUP_DISABLE, - }; - gpio_config(&gpio_conf); - esp_rom_gpio_connect_out_signal(gpio, sigo, false, false); - esp_rom_gpio_connect_in_signal(gpio, sigi, false); -} +#define TEST_SPI_CLK_FREQ 24000000 static void level_delimiter_sender_task_spi(void *args) { @@ -194,41 +170,16 @@ static void level_delimiter_sender_task_spi(void *args) .sclk_io_num = TEST_CLK_GPIO, .quadwp_io_num = -1, .quadhd_io_num = -1, - .max_transfer_sz = 2048, }; spi_device_interface_config_t dev_cfg = { - .command_bits = 0, - .address_bits = 0, .clock_speed_hz = TEST_SPI_CLK_FREQ, - .mode = 0, - .duty_cycle_pos = 128, - .spics_io_num = is_large_trans ? -1 : TEST_VALID_GPIO, + .spics_io_num = TEST_VALID_GPIO, .queue_size = 5, - .flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_POSITIVE_CS, - .pre_cb = is_large_trans ? NULL : cs_high, - .post_cb = is_large_trans ? NULL : cs_low, }; //Initialize the SPI bus and add device TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, SPI_DMA_CH_AUTO)); TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &dev_handle)); - // Initialize CS gpio - gpio_set_level(TEST_VALID_GPIO, 0); // output enable set in following code - - // Connect SPI signals to parlio rx signals - gpio_reset_pin(TEST_CLK_GPIO); - gpio_reset_pin(TEST_VALID_GPIO); - gpio_reset_pin(TEST_DATA0_GPIO); - connect_signal_internally(TEST_CLK_GPIO, - spi_periph_signal[TEST_SPI_HOST].spiclk_out, - soc_parlio_signals[0].rx_units[0].clk_in_sig); - connect_signal_internally(TEST_VALID_GPIO, - spi_periph_signal[TEST_SPI_HOST].spics_out[0], - soc_parlio_signals[0].rx_units[0].data_sigs[TEST_VALID_SIG]); - connect_signal_internally(TEST_DATA0_GPIO, - spi_periph_signal[TEST_SPI_HOST].spid_out, - soc_parlio_signals[0].rx_units[0].data_sigs[0]); - // Prepare the data the be transmitted uint8_t *data = NULL; size_t data_size = TEST_EOF_DATA_LEN; @@ -251,24 +202,38 @@ static void level_delimiter_sender_task_spi(void *args) .user = NULL, }; - // Transmit data every 1ms, until the main test thread finished receiving + // Transmit data every 2ms, until the main test thread finished receiving if (is_large_trans) { while (!((*task_flags) & TEST_TASK_FINISHED_BIT)) { + // Wait for receiver to be ready before starting transmission if (!((*task_flags) & TEST_TASK_RECV_READY_BIT)) { - gpio_set_level(TEST_VALID_GPIO, 1); - for (int i = 0; i < 80; i++) { - TEST_ESP_OK(spi_device_transmit(dev_handle, &t)); - } - gpio_set_level(TEST_VALID_GPIO, 0); - *task_flags |= TEST_TASK_DATA_READY_BIT; + vTaskDelay(1); + continue; } - vTaskDelay(pdMS_TO_TICKS(1)); + *task_flags &= ~(TEST_TASK_RECV_READY_BIT); + TEST_ESP_OK(spi_device_acquire_bus(dev_handle, portMAX_DELAY)); + for (int i = 0; i < TEST_TASK_LARGE_TRANS_SIZE;) { + if (TEST_TASK_LARGE_TRANS_SIZE - i < data_size) { + t.flags = 0; + t.length = (TEST_TASK_LARGE_TRANS_SIZE - i) * 8; + t.rxlength = 0; + } else { + t.flags = SPI_TRANS_CS_KEEP_ACTIVE; + t.length = data_size * 8; + t.rxlength = 0; + } + TEST_ESP_OK(spi_device_transmit(dev_handle, &t)); + i += t.length >> 3; + } + *task_flags |= TEST_TASK_DATA_READY_BIT; + spi_device_release_bus(dev_handle); + vTaskDelay(pdMS_TO_TICKS(5)); } } else { while (!((*task_flags) & TEST_TASK_FINISHED_BIT)) { TEST_ESP_OK(spi_device_transmit(dev_handle, &t)); - vTaskDelay(pdMS_TO_TICKS(1)); *task_flags |= TEST_TASK_DATA_READY_BIT; + vTaskDelay(pdMS_TO_TICKS(2)); } } @@ -350,18 +315,22 @@ static bool test_delimiter(parlio_rx_delimiter_handle_t deli, bool free_running_ return is_success; } -#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-9806 fix the bit shift issue in other target // This test case uses level delimiter TEST_CASE("parallel_rx_unit_level_delimiter_test_via_spi", "[parlio_rx]") { parlio_rx_level_delimiter_config_t lvl_deli_cfg = { .valid_sig_line_id = TEST_VALID_SIG, +#if CONFIG_IDF_TARGET_ESP32C6 + // C6 needs to lag half cycle behind to get the correct data + .sample_edge = PARLIO_SAMPLE_EDGE_NEG, +#else .sample_edge = PARLIO_SAMPLE_EDGE_POS, +#endif .bit_pack_order = PARLIO_BIT_PACK_ORDER_MSB, .eof_data_len = TEST_EOF_DATA_LEN, .timeout_ticks = 0, .flags = { - .active_low_en = 0, + .active_low_en = 1, }, }; parlio_rx_delimiter_handle_t deli = NULL; @@ -370,7 +339,6 @@ TEST_CASE("parallel_rx_unit_level_delimiter_test_via_spi", "[parlio_rx]") TEST_ESP_OK(parlio_del_rx_delimiter(deli)); TEST_ASSERT(is_success); } -#endif // This test case uses pulse delimiter TEST_CASE("parallel_rx_unit_pulse_delimiter_test_via_i2s", "[parlio_rx]") @@ -580,7 +548,6 @@ TEST_CASE("parallel_rx_unit_receive_external_memory_test", "[parlio_rx]") TEST_CASE("parallel_rx_unit_receive_timeout_test", "[parlio_rx]") { printf("init a gpio to simulate valid signal\r\n"); - TEST_ESP_OK(gpio_reset_pin(TEST_VALID_GPIO)); gpio_config_t test_gpio_conf = { .mode = GPIO_MODE_OUTPUT, .pin_bit_mask = BIT64(TEST_VALID_GPIO), @@ -921,109 +888,3 @@ TEST_CASE("parallel_rx_unit_infinite_transaction_switch_test", "[parlio_rx]") free(payload1); free(payload2); } - -/** - * @brief This ISR is to indicate the SPI transaction finished - */ -static void test_gpio_neg_edge_intr(void *arg) -{ - parlio_rx_unit_handle_t rx_unit = (parlio_rx_unit_handle_t)arg; - bool need_yield = false; - parlio_rx_unit_trigger_fake_eof(rx_unit, &need_yield); - if (need_yield) { - portYIELD_FROM_ISR(); - } -} - -TEST_CASE("parallel_rx_unit_force_trigger_eof_test", "[parlio_rx][release_only]") -{ - parlio_rx_unit_handle_t rx_unit = NULL; - - parlio_rx_unit_config_t config = TEST_DEFAULT_UNIT_CONFIG(PARLIO_CLK_SRC_EXTERNAL, 1000000); - config.flags.free_clk = 0; - config.max_recv_size = TEST_TASK_LARGE_TRANS_SIZE; - TEST_ESP_OK(parlio_new_rx_unit(&config, &rx_unit)); - - parlio_rx_level_delimiter_config_t lvl_deli_cfg = { - .valid_sig_line_id = TEST_VALID_SIG, - .sample_edge = PARLIO_SAMPLE_EDGE_POS, - .bit_pack_order = PARLIO_BIT_PACK_ORDER_MSB, - /* Normally the EOF won't be triggered for the level delimiter that eof_data_len larger than 64KB */ - .eof_data_len = TEST_TASK_LARGE_TRANS_SIZE, - .timeout_ticks = 0, - .flags = { - .active_low_en = 0, - }, - }; - parlio_rx_delimiter_handle_t deli = NULL; - TEST_ESP_OK(parlio_new_rx_level_delimiter(&lvl_deli_cfg, &deli)); - - parlio_rx_event_callbacks_t cbs = { - .on_receive_done = test_parlio_rx_done_callback, - }; - test_data_t test_data = { - .partial_recv_cnt = 0, - .recv_done_cnt = 0, - }; - TEST_ESP_OK(parlio_rx_unit_register_event_callbacks(rx_unit, &cbs, &test_data)); - TEST_ESP_OK(parlio_rx_unit_enable(rx_unit, true)); - - TaskHandle_t sender_task; - /* The flag to transport finish information between main test thread and the sender thread - * Set it as static to make sure it'll be valid in another thread */ - static uint32_t task_flags = TEST_TASK_LARGE_TRANS_BIT; - xTaskCreate(level_delimiter_sender_task_spi, "sender task", 4096, &task_flags, 5, &sender_task); - - parlio_receive_config_t recv_config = { - .delimiter = deli, - .flags.partial_rx_en = false, - }; - uint8_t *recv_buff = NULL; - uint32_t alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); - alignment = alignment < 4 ? 4 : alignment; - size_t buff_size = ALIGN_UP(TEST_TASK_LARGE_TRANS_SIZE, alignment); - recv_buff = heap_caps_aligned_calloc(alignment, 1, buff_size, TEST_PARLIO_DMA_MEM_ALLOC_CAPS); - TEST_ASSERT_NOT_NULL(recv_buff); - - gpio_set_intr_type(TEST_VALID_GPIO, GPIO_INTR_NEGEDGE); - gpio_install_isr_service(0); - gpio_isr_handler_add(TEST_VALID_GPIO, test_gpio_neg_edge_intr, rx_unit); - gpio_intr_enable(TEST_VALID_GPIO); - - uint32_t recv_cnt = 3; - for (int i = 0; i < recv_cnt; i++) { - TEST_ESP_OK(parlio_rx_unit_receive(rx_unit, recv_buff, buff_size, &recv_config)); - printf("[%d] recv ready\n", i); - task_flags |= TEST_TASK_RECV_READY_BIT; - while (!task_flags & TEST_TASK_DATA_READY_BIT) { - vTaskDelay(1); - } - task_flags &= ~TEST_TASK_DATA_READY_BIT; - printf("[%d] send done\n", i); - TEST_ESP_OK(parlio_rx_unit_wait_all_done(rx_unit, 10000)); - task_flags &= ~TEST_TASK_RECV_READY_BIT; - printf("[%d] recv done\n", i); - } - // Indicate the test finished, no need to send data - task_flags |= TEST_TASK_FINISHED_BIT; - - bool is_success = true; - is_success &= test_data.recv_done_cnt == recv_cnt; - - gpio_intr_disable(TEST_VALID_GPIO); - gpio_isr_handler_remove(TEST_VALID_GPIO); - gpio_uninstall_isr_service(); - // Waiting for the sender task quit - while (task_flags) { - vTaskDelay(1); - } - // Delete the sender task - vTaskDelete(sender_task); - free(recv_buff); - - TEST_ESP_OK(parlio_rx_unit_disable(rx_unit)); - TEST_ESP_OK(parlio_del_rx_delimiter(deli)); - TEST_ESP_OK(parlio_del_rx_unit(rx_unit)); - - TEST_ASSERT(is_success); -} diff --git a/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py b/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py index f4cb6144b30..e7ad6f99a37 100644 --- a/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py +++ b/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py @@ -11,20 +11,6 @@ from pytest_embedded_idf.utils import soc_filtered_targets 'config', [ 'cache_safe', - ], - indirect=True, -) -@idf_parametrize( - 'target', soc_filtered_targets('SOC_PARLIO_SUPPORTED == 1 and IDF_TARGET not in ["esp32c5"]'), indirect=['target'] -) -def test_parlio_cache_safe(dut: Dut) -> None: - dut.run_all_single_board_cases(group='!release_only') - - -@pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ 'release', ], indirect=True, @@ -49,9 +35,8 @@ def test_parlio(dut: Dut) -> None: soc_filtered_targets('SOC_PARLIO_SUPPORTED == 1 and SOC_PSRAM_DMA_CAPABLE == 1 and SOC_FLASH_ENC_SUPPORTED == 1'), indirect=['target'], ) -@pytest.mark.temp_skip_ci(targets=['esp32h4'], reason='no runner yet') def test_parlio_with_flash_encryption(dut: Dut) -> None: - dut.run_all_single_board_cases(group='!release_only') + dut.run_all_single_board_cases() @pytest.mark.generic @@ -64,7 +49,7 @@ def test_parlio_with_flash_encryption(dut: Dut) -> None: ) @idf_parametrize('target', ['esp32c5'], indirect=['target']) def test_parlio_esp32c5(dut: Dut) -> None: - dut.run_all_single_board_cases(group='!release_only') + dut.run_all_single_board_cases() @pytest.mark.generic diff --git a/components/esp_hal_parlio/esp32c5/include/hal/parlio_ll.h b/components/esp_hal_parlio/esp32c5/include/hal/parlio_ll.h index 625682370ce..7c8e66ecbac 100644 --- a/components/esp_hal_parlio/esp32c5/include/hal/parlio_ll.h +++ b/components/esp_hal_parlio/esp32c5/include/hal/parlio_ll.h @@ -74,6 +74,7 @@ static inline void parlio_ll_enable_bus_clock(int group_id, bool enable) * * @param group_id The group id of the parlio module */ +__attribute__((always_inline)) static inline void parlio_ll_reset_register(int group_id) { (void)group_id; @@ -89,6 +90,7 @@ static inline void parlio_ll_reset_register(int group_id) * @param dev Parallel IO register base address * @param src Clock source */ +__attribute__((always_inline)) static inline void parlio_ll_rx_set_clock_source(parl_io_dev_t *dev, parlio_clock_source_t src) { (void)dev; diff --git a/components/esp_hal_parlio/esp32c6/include/hal/parlio_ll.h b/components/esp_hal_parlio/esp32c6/include/hal/parlio_ll.h index 3d80520b395..9788456bfaf 100644 --- a/components/esp_hal_parlio/esp32c6/include/hal/parlio_ll.h +++ b/components/esp_hal_parlio/esp32c6/include/hal/parlio_ll.h @@ -72,6 +72,7 @@ static inline void parlio_ll_enable_bus_clock(int group_id, bool enable) * * @param group_id The group id of the parlio module */ +__attribute__((always_inline)) static inline void parlio_ll_reset_register(int group_id) { (void)group_id; @@ -87,6 +88,7 @@ static inline void parlio_ll_reset_register(int group_id) * @param dev Parallel IO register base address * @param src Clock source */ +__attribute__((always_inline)) static inline void parlio_ll_rx_set_clock_source(parl_io_dev_t *dev, parlio_clock_source_t src) { (void)dev; diff --git a/components/esp_hal_parlio/esp32h2/include/hal/parlio_ll.h b/components/esp_hal_parlio/esp32h2/include/hal/parlio_ll.h index 29f6efd1a18..489d2ff42a2 100644 --- a/components/esp_hal_parlio/esp32h2/include/hal/parlio_ll.h +++ b/components/esp_hal_parlio/esp32h2/include/hal/parlio_ll.h @@ -76,6 +76,7 @@ static inline void parlio_ll_enable_bus_clock(int group_id, bool enable) * * @param group_id The group id of the parlio module */ +__attribute__((always_inline)) static inline void parlio_ll_reset_register(int group_id) { (void)group_id; @@ -91,6 +92,7 @@ static inline void parlio_ll_reset_register(int group_id) * @param dev Parallel IO register base address * @param src Clock source */ +__attribute__((always_inline)) static inline void parlio_ll_rx_set_clock_source(parl_io_dev_t *dev, parlio_clock_source_t src) { (void)dev; diff --git a/components/esp_hal_parlio/esp32h4/include/hal/parlio_ll.h b/components/esp_hal_parlio/esp32h4/include/hal/parlio_ll.h index f2e2d7fe48c..5593cae1810 100644 --- a/components/esp_hal_parlio/esp32h4/include/hal/parlio_ll.h +++ b/components/esp_hal_parlio/esp32h4/include/hal/parlio_ll.h @@ -74,6 +74,7 @@ static inline void parlio_ll_enable_bus_clock(int group_id, bool enable) * * @param group_id The group id of the parlio module */ +__attribute__((always_inline)) static inline void parlio_ll_reset_register(int group_id) { (void)group_id; @@ -89,6 +90,7 @@ static inline void parlio_ll_reset_register(int group_id) * @param dev Parallel IO register base address * @param src Clock source */ +__attribute__((always_inline)) static inline void parlio_ll_rx_set_clock_source(parl_io_dev_t *dev, parlio_clock_source_t src) { (void)dev; diff --git a/components/esp_hal_parlio/esp32p4/include/hal/parlio_ll.h b/components/esp_hal_parlio/esp32p4/include/hal/parlio_ll.h index b7d48178258..8130f6ec7bb 100644 --- a/components/esp_hal_parlio/esp32p4/include/hal/parlio_ll.h +++ b/components/esp_hal_parlio/esp32p4/include/hal/parlio_ll.h @@ -92,6 +92,7 @@ static inline void _parlio_ll_enable_bus_clock(int group_id, bool enable) * * @param group_id The group id of the parlio module */ +__attribute__((always_inline)) static inline void _parlio_ll_reset_register(int group_id) { (void)group_id; @@ -114,6 +115,7 @@ static inline void _parlio_ll_reset_register(int group_id) * @param dev Parallel IO register base address * @param src Clock source */ +__attribute__((always_inline)) static inline void _parlio_ll_rx_set_clock_source(parl_io_dev_t *dev, parlio_clock_source_t src) { (void)dev;