test(sdio): dual board test sd host p4 + sdio slave c5

This commit is contained in:
armando
2025-04-23 16:01:30 +08:00
parent 69164ed912
commit 6e2d52c802
13 changed files with 157 additions and 40 deletions

View File

@ -1,16 +1,10 @@
set(srcs "essl.c") idf_component_register(SRCS "essl.c"
"essl_sdio.c"
if(CONFIG_SOC_GPSPI_SUPPORTED) "essl_spi.c"
list(APPEND srcs "essl_spi.c") "essl_sdio_defs.c"
endif() INCLUDE_DIRS "include"
REQUIRES "sdmmc"
if(CONFIG_SOC_SDIO_SLAVE_SUPPORTED) "driver"
list(APPEND srcs "essl_sdio.c" "essl_sdio_defs.c") PRIV_INCLUDE_DIRS "."
endif() "include/esp_serial_slave_link"
idf_component_register(
SRCS "${srcs}"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "." "include/esp_serial_slave_link"
REQUIRES sdmmc driver
) )

View File

@ -45,9 +45,10 @@ void test_prepare_buffer_pool(size_t pool_size, uint32_t flags);
* *
* @param offset A random offset * @param offset A random offset
* @param size Buffer size * @param size Buffer size
* @param alignment Alignment
* @param[out] out_buffer Out buffer * @param[out] out_buffer Out buffer
*/ */
void test_get_buffer_from_pool(uint32_t offset, size_t size, void **out_buffer); void test_get_buffer_from_pool(uint32_t offset, size_t size, size_t alignment, void **out_buffer);
/** /**
* Destroy the pool * Destroy the pool

View File

@ -43,10 +43,10 @@ void test_prepare_buffer_pool(size_t pool_size, uint32_t flags)
test_fill_random_to_buffer(199, s_pool, pool_size); test_fill_random_to_buffer(199, s_pool, pool_size);
} }
void test_get_buffer_from_pool(uint32_t offset, size_t size, void **out_buffer) void test_get_buffer_from_pool(uint32_t offset, size_t size, size_t alignment, void **out_buffer)
{ {
//to make sure the out_buffer is within the pool //to make sure the out_buffer is within the pool
offset = ((offset % (s_pool_size - size)) + 3) & ~3; offset = ((offset % (s_pool_size - size)) + (alignment - 1)) & ~(alignment - 1);
// TEST_ASSERT(offset + size < (uint32_t)s_pool + s_pool_size) // TEST_ASSERT(offset + size < (uint32_t)s_pool + s_pool_size)
*out_buffer = (void *)(s_pool + offset); *out_buffer = (void *)(s_pool + offset);

View File

@ -1,7 +1,7 @@
components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc: components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc:
enable: enable:
- if: IDF_TARGET == "esp32" - if: IDF_TARGET in ["esp32", "esp32p4"]
reason: always use ESP32 SDMMC as host reason: runners use ESP32 / ESP32P4 SDMMC as host
depends_components: depends_components:
- sdmmc - sdmmc
- esp_driver_sdmmc - esp_driver_sdmmc

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | | Supported Targets | ESP32 | ESP32-P4 |
| ----------------- | ----- | | ----------------- | ----- | -------- |
# SDIO Cross Chips Test Apps: SDMMC Host App # SDIO Cross Chips Test Apps: SDMMC Host App

View File

@ -0,0 +1,15 @@
menu "SDIO Slave Test Host Configuration"
choice TEST_SDIO_SLAVE_TARGET
prompt "SDIO Slave Chip"
default TEST_SDIO_SLAVE_TARGET_ESP32
help
SDIO Slave chip target
config TEST_SDIO_SLAVE_TARGET_ESP32
bool "SDIO Slave ESP32"
config TEST_SDIO_SLAVE_TARGET_ESP32C6
bool "SDIO Slave ESP32C6"
config TEST_SDIO_SLAVE_TARGET_ESP32C5
bool "SDIO Slave ESP32C5"
endchoice
endmenu

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -32,6 +32,15 @@ static const char *TAG = "test_sdio_sdhost";
#define TEST_INT_MASK_ALL 0xff #define TEST_INT_MASK_ALL 0xff
#define TEST_REG_ADDR_MAX 60 #define TEST_REG_ADDR_MAX 60
#define TEST_TIMEOUT_MAX UINT32_MAX #define TEST_TIMEOUT_MAX UINT32_MAX
#define TEST_WIDTH 4
#if CONFIG_TEST_SDIO_SLAVE_TARGET_ESP32C5
#define TEST_PIN_CLK 33
#define TEST_PIN_CMD 4
#define TEST_PIN_D0 32
#define TEST_PIN_D1 23
#define TEST_PIN_D2 53
#define TEST_PIN_D3 5
#endif
typedef struct { typedef struct {
uint32_t host_flags; uint32_t host_flags;
@ -48,6 +57,11 @@ static void s_master_init(test_sdio_param_t *host_param, essl_handle_t *out_hand
{ {
sdmmc_host_t host_config = (sdmmc_host_t)SDMMC_HOST_DEFAULT(); sdmmc_host_t host_config = (sdmmc_host_t)SDMMC_HOST_DEFAULT();
host_config.flags = host_param->host_flags; host_config.flags = host_param->host_flags;
#if CONFIG_TEST_SDIO_SLAVE_TARGET_ESP32C5
//On P4-SDMMC + C5 SDIO test runner environment, hardware delay needs to be considered
host_config.input_delay_phase = SDMMC_DELAY_PHASE_2;
#endif
if (host_config.flags & SDMMC_HOST_FLAG_4BIT) { if (host_config.flags & SDMMC_HOST_FLAG_4BIT) {
ESP_LOGI(TAG, "Probe using SD 4-bit..."); ESP_LOGI(TAG, "Probe using SD 4-bit...");
} else if (host_config.flags & SDMMC_HOST_FLAG_1BIT) { } else if (host_config.flags & SDMMC_HOST_FLAG_1BIT) {
@ -59,6 +73,16 @@ static void s_master_init(test_sdio_param_t *host_param, essl_handle_t *out_hand
//init sdmmc host //init sdmmc host
TEST_ESP_OK(sdmmc_host_init()); TEST_ESP_OK(sdmmc_host_init());
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
#if CONFIG_TEST_SDIO_SLAVE_TARGET_ESP32C5
slot_config.width = TEST_WIDTH;
slot_config.clk = TEST_PIN_CLK;
slot_config.cmd = TEST_PIN_CMD;
slot_config.d0 = TEST_PIN_D0;
slot_config.d1 = TEST_PIN_D1;
slot_config.d2 = TEST_PIN_D2;
slot_config.d3 = TEST_PIN_D3;
#endif
TEST_ESP_OK(sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config)); TEST_ESP_OK(sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config));
//host init slave //host init slave
@ -127,7 +151,6 @@ TEST_CASE("SDIO_SDMMC: test interrupt", "[sdio]")
//tests all 8 interrupts of the slave, in which int 7 is used to terminate the test on the slave. //tests all 8 interrupts of the slave, in which int 7 is used to terminate the test on the slave.
for (int i = 0; i < 8; i ++) { for (int i = 0; i < 8; i ++) {
esp_rom_printf("to essl_send_slave_intr\n");
TEST_ESP_OK(essl_send_slave_intr(handle, BIT(i), TEST_TIMEOUT_MAX)); TEST_ESP_OK(essl_send_slave_intr(handle, BIT(i), TEST_TIMEOUT_MAX));
//the slave should return interrupt with the same bit in 10 ms //the slave should return interrupt with the same bit in 10 ms
TEST_ESP_OK(essl_wait_int(handle, 10)); TEST_ESP_OK(essl_wait_int(handle, 10));
@ -223,8 +246,13 @@ TEST_CASE("SDIO_SDMMC: test reset", "[sdio]")
/*--------------------------------------------------------------- /*---------------------------------------------------------------
SDMMC_SDIO: test fixed addr SDMMC_SDIO: test fixed addr
---------------------------------------------------------------*/ ---------------------------------------------------------------*/
#include "soc/soc.h" #if CONFIG_TEST_SDIO_SLAVE_TARGET_ESP32C5
#define HOST_SLCHOST_CONF_W0_REG (0x60018000 + 0x6C)
#elif DR_REG_SLCHOST_BASE
#define HOST_SLCHOST_CONF_W0_REG (DR_REG_SLCHOST_BASE + 0x6C) #define HOST_SLCHOST_CONF_W0_REG (DR_REG_SLCHOST_BASE + 0x6C)
#else
#define HOST_SLCHOST_CONF_W0_REG 0
#endif
TEST_CASE("SDIO_SDMMC: test fixed addr", "[sdio]") TEST_CASE("SDIO_SDMMC: test fixed addr", "[sdio]")
{ {
@ -318,7 +346,11 @@ static void test_from_host(bool check_data)
for (int j = 0; j < TEST_TRANS_NUMS; j++) { for (int j = 0; j < TEST_TRANS_NUMS; j++) {
ESP_LOGD(TAG, "j: %d", j); ESP_LOGD(TAG, "j: %d", j);
test_get_buffer_from_pool(j, TEST_RX_BUFFER_SIZE, &tx_buf_ptr); size_t alignment = 4;
#if CONFIG_IDF_TARGET_ESP32P4
alignment = 64;
#endif
test_get_buffer_from_pool(j, TEST_RX_BUFFER_SIZE, alignment, &tx_buf_ptr);
ESP_LOG_BUFFER_HEX_LEVEL(TAG, tx_buf_ptr, TEST_RX_BUFFER_SIZE, TEST_HEX_LOG_LEVEL); ESP_LOG_BUFFER_HEX_LEVEL(TAG, tx_buf_ptr, TEST_RX_BUFFER_SIZE, TEST_HEX_LOG_LEVEL);
TEST_ESP_OK(essl_send_packet(handle, tx_buf_ptr, TEST_RX_BUFFER_SIZE, TEST_TIMEOUT_MAX)); TEST_ESP_OK(essl_send_packet(handle, tx_buf_ptr, TEST_RX_BUFFER_SIZE, TEST_TIMEOUT_MAX));
} }
@ -383,8 +415,12 @@ static void test_to_host(bool check_data)
if (check_data) { if (check_data) {
size_t compared_len = 0; size_t compared_len = 0;
size_t alignment = 4;
#if CONFIG_IDF_TARGET_ESP32P4
alignment = 64;
#endif
do { do {
test_get_buffer_from_pool(offset, TEST_RX_BUFFER_SIZE, &tx_buf_ptr); test_get_buffer_from_pool(offset, TEST_RX_BUFFER_SIZE, alignment, &tx_buf_ptr);
TEST_ASSERT_EQUAL_HEX8_ARRAY(tx_buf_ptr, &host_rx_buffer[compared_len], TEST_RX_BUFFER_SIZE); TEST_ASSERT_EQUAL_HEX8_ARRAY(tx_buf_ptr, &host_rx_buffer[compared_len], TEST_RX_BUFFER_SIZE);
compared_len += TEST_RX_BUFFER_SIZE; compared_len += TEST_RX_BUFFER_SIZE;
offset += TEST_RX_BUFFER_SIZE; offset += TEST_RX_BUFFER_SIZE;
@ -418,6 +454,11 @@ TEST_CASE("SDIO_SDMMC: test to host", "[sdio]")
test_to_host(true); test_to_host(true);
} }
TEST_CASE("SDIO_SDMMC: test to host (Performance)", "[sdio_speed]")
{
test_to_host(false);
}
TEST_CASE("SDIO_SDMMC: test sleep retention", "[sdio_retention]") TEST_CASE("SDIO_SDMMC: test sleep retention", "[sdio_retention]")
{ {
essl_handle_t handle = NULL; essl_handle_t handle = NULL;
@ -431,8 +472,3 @@ TEST_CASE("SDIO_SDMMC: test sleep retention", "[sdio_retention]")
s_send_finish_test(handle); s_send_finish_test(handle);
s_master_deinit(); s_master_deinit();
} }
TEST_CASE("SDIO_SDMMC: test to host (Performance)", "[sdio_speed]")
{
test_to_host(false);
}

View File

@ -0,0 +1 @@
CONFIG_TEST_SDIO_SLAVE_TARGET_ESP32C5=y

View File

@ -29,8 +29,16 @@ esp32_c6_param = [
] ]
] ]
esp32p4_c5_param = [
[
f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}',
'esp32p4|esp32c5',
]
]
esp32_param_default = [pytest.param(*param) for param in parameter_expand(esp32_32_param, ['default|default'])] esp32_param_default = [pytest.param(*param) for param in parameter_expand(esp32_32_param, ['default|default'])]
c6_param_default = [pytest.param(*param) for param in parameter_expand(esp32_c6_param, ['default|default'])] c6_param_default = [pytest.param(*param) for param in parameter_expand(esp32_c6_param, ['default|default'])]
c5_param_default = [pytest.param(*param) for param in parameter_expand(esp32p4_c5_param, ['esp32p4_esp32c5|default'])]
c6_param_retention = [pytest.param(*param) for param in parameter_expand(esp32_c6_param, ['default|sleep_retention'])] c6_param_retention = [pytest.param(*param) for param in parameter_expand(esp32_c6_param, ['default|sleep_retention'])]
@ -74,6 +82,19 @@ def test_sdio_esp32_esp32(dut: Tuple[IdfDut, IdfDut]) -> None:
test_sdio_flow(dut) test_sdio_flow(dut)
@pytest.mark.sdio_multidev_p4_c5
@pytest.mark.parametrize(
'count',
[
2,
],
indirect=True,
)
@pytest.mark.parametrize('app_path, target, config', c5_param_default, indirect=True)
def test_sdio_esp32p4_esp32c5(dut: Tuple[IdfDut, IdfDut]) -> None:
test_sdio_flow(dut)
# From host speed tests # From host speed tests
def test_sdio_speed_frhost_flow(dut: Tuple[IdfDut, IdfDut], expected_4b_speed: int, expected_1b_speed: int) -> None: def test_sdio_speed_frhost_flow(dut: Tuple[IdfDut, IdfDut], expected_4b_speed: int, expected_1b_speed: int) -> None:
dut[1].expect('Press ENTER to see the list of tests') dut[1].expect('Press ENTER to see the list of tests')
@ -120,6 +141,19 @@ def test_sdio_speed_frhost_esp32_esp32(dut: Tuple[IdfDut, IdfDut]) -> None:
test_sdio_speed_frhost_flow(dut, 12200, 4000) test_sdio_speed_frhost_flow(dut, 12200, 4000)
@pytest.mark.sdio_multidev_p4_c5
@pytest.mark.parametrize(
'count',
[
2,
],
indirect=True,
)
@pytest.mark.parametrize('app_path, target, config', c5_param_default, indirect=True)
def test_sdio_speed_frhost_esp32p4_esp32c5(dut: Tuple[IdfDut, IdfDut]) -> None:
test_sdio_speed_frhost_flow(dut, 10000, 4000)
# To host speed tests # To host speed tests
def test_sdio_speed_tohost_flow(dut: Tuple[IdfDut, IdfDut], expected_4b_speed: int, expected_1b_speed: int) -> None: def test_sdio_speed_tohost_flow(dut: Tuple[IdfDut, IdfDut], expected_4b_speed: int, expected_1b_speed: int) -> None:
dut[1].expect('Press ENTER to see the list of tests') dut[1].expect('Press ENTER to see the list of tests')
@ -166,6 +200,19 @@ def test_sdio_speed_tohost_esp32_esp32(dut: Tuple[IdfDut, IdfDut]) -> None:
test_sdio_speed_tohost_flow(dut, 12200, 4000) test_sdio_speed_tohost_flow(dut, 12200, 4000)
@pytest.mark.sdio_multidev_p4_c5
@pytest.mark.parametrize(
'count',
[
2,
],
indirect=True,
)
@pytest.mark.parametrize('app_path, target, config', c5_param_default, indirect=True)
def test_sdio_speed_tohost_esp32p4_esp32c5(dut: Tuple[IdfDut, IdfDut]) -> None:
test_sdio_speed_tohost_flow(dut, 9000, 4000)
# Retention tests # Retention tests
def test_sdio_retention(dut: Tuple[IdfDut, IdfDut]) -> None: def test_sdio_retention(dut: Tuple[IdfDut, IdfDut]) -> None:
dut[1].expect('Press ENTER to see the list of tests') dut[1].expect('Press ENTER to see the list of tests')

View File

@ -0,0 +1,13 @@
menu "SDIO Slave Test Slave Configuration"
choice TEST_SDIO_HOST_TARGET
prompt "SDIO Host Chip"
default TEST_SDIO_HOST_TARGET_ESP32
help
SDIO Host chip target
config TEST_SDIO_HOST_TARGET_ESP32
bool "SDIO Host ESP32"
config TEST_SDIO_HOST_TARGET_ESP32P4
bool "SDIO Host ESP32P4"
endchoice
endmenu

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -218,7 +218,11 @@ static void test_from_host(bool check_data)
ESP_LOG_BUFFER_HEX_LEVEL(TAG, buf, TEST_RX_BUFFER_SIZE, TEST_HEX_LOG_LEVEL); ESP_LOG_BUFFER_HEX_LEVEL(TAG, buf, TEST_RX_BUFFER_SIZE, TEST_HEX_LOG_LEVEL);
if (check_data) { if (check_data) {
test_get_buffer_from_pool(j, TEST_RX_BUFFER_SIZE, &tx_buf_ptr); size_t alignment = 4;
#if CONFIG_TEST_SDIO_HOST_TARGET_ESP32P4
alignment = 64;
#endif
test_get_buffer_from_pool(j, TEST_RX_BUFFER_SIZE, alignment, &tx_buf_ptr);
ESP_LOG_BUFFER_HEX_LEVEL("Expect data", tx_buf_ptr, TEST_RX_BUFFER_SIZE, TEST_HEX_LOG_LEVEL); ESP_LOG_BUFFER_HEX_LEVEL("Expect data", tx_buf_ptr, TEST_RX_BUFFER_SIZE, TEST_HEX_LOG_LEVEL);
TEST_ASSERT_EQUAL_HEX8_ARRAY(tx_buf_ptr, buf, rcv_len); TEST_ASSERT_EQUAL_HEX8_ARRAY(tx_buf_ptr, buf, rcv_len);
} }
@ -279,7 +283,11 @@ static void test_to_host(void)
TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, err); TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, err);
} while (QUEUE_FULL()); } while (QUEUE_FULL());
test_get_buffer_from_pool(offset, TEST_RX_BUFFER_SIZE, &tx_buf_ptr); size_t alignment = 4;
#if CONFIG_TEST_SDIO_HOST_TARGET_ESP32P4
alignment = 64;
#endif
test_get_buffer_from_pool(offset, TEST_RX_BUFFER_SIZE, alignment, &tx_buf_ptr);
TEST_ESP_OK(sdio_slave_send_queue((uint8_t *)tx_buf_ptr, TEST_RX_BUFFER_SIZE, NULL, portMAX_DELAY)); TEST_ESP_OK(sdio_slave_send_queue((uint8_t *)tx_buf_ptr, TEST_RX_BUFFER_SIZE, NULL, portMAX_DELAY));
s_test_slv_ctx.queued_cnt++; s_test_slv_ctx.queued_cnt++;
@ -305,6 +313,11 @@ TEST_CASE("SDIO_Slave: test to host", "[sdio]")
test_to_host(); test_to_host();
} }
TEST_CASE("SDIO_Slave: test to host (Performance)", "[sdio_speed]")
{
test_to_host();
}
#if SOC_PAU_SUPPORTED #if SOC_PAU_SUPPORTED
#include "esp_private/sleep_sys_periph.h" #include "esp_private/sleep_sys_periph.h"
#include "esp_private/sleep_retention.h" #include "esp_private/sleep_retention.h"
@ -329,8 +342,3 @@ TEST_CASE("SDIO_Slave: test sleep retention", "[sdio_retention]")
TEST_ASSERT_EQUAL_INT32(true, peripheral_domain_pd_allowed()); TEST_ASSERT_EQUAL_INT32(true, peripheral_domain_pd_allowed());
} }
#endif #endif
TEST_CASE("SDIO_Slave: test to host (Performance)", "[sdio_speed]")
{
test_to_host();
}

View File

@ -0,0 +1 @@
CONFIG_TEST_SDIO_HOST_TARGET_ESP32P4=y

View File

@ -138,6 +138,7 @@ ENV_MARKERS = {
'twai_network': 'multiple runners form a TWAI network.', 'twai_network': 'multiple runners form a TWAI network.',
'sdio_master_slave': 'Test sdio multi board, esp32+esp32', 'sdio_master_slave': 'Test sdio multi board, esp32+esp32',
'sdio_multidev_32_c6': 'Test sdio multi board, esp32+esp32c6', 'sdio_multidev_32_c6': 'Test sdio multi board, esp32+esp32c6',
'sdio_multidev_p4_c5': 'Test sdio multi board, esp32p4+esp32c5',
'usj_device': 'Test usb_serial_jtag and usb_serial_jtag is used as serial only (not console)', 'usj_device': 'Test usb_serial_jtag and usb_serial_jtag is used as serial only (not console)',
'twai_std': 'twai runner with all twai supported targets connect to usb-can adapter', 'twai_std': 'twai runner with all twai supported targets connect to usb-can adapter',
'lp_i2s': 'lp_i2s runner tested with hp_i2s', 'lp_i2s': 'lp_i2s runner tested with hp_i2s',