mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(sdio): sdio cross chip test app
This commit is contained in:
parent
907a7d9977
commit
faa6e51086
@ -725,6 +725,37 @@ pytest_components_esp32_sdio:
|
||||
artifacts: false
|
||||
tags: [ esp32, sdio_master_slave ]
|
||||
|
||||
pytest_components_esp32_esp32c6_sdio:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32-sdio
|
||||
needs:
|
||||
- job: build_pytest_components_esp32
|
||||
artifacts: false
|
||||
- job: build_pytest_components_esp32c6
|
||||
artifacts: false
|
||||
tags: [ esp32c6, sdio_multidev_32_c6 ]
|
||||
script:
|
||||
- retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases
|
||||
# get runner env config file
|
||||
- retry_failed git clone $TEST_ENV_CONFIG_REPO
|
||||
- python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs
|
||||
# using runner tags as markers to filter the test cases
|
||||
# Runner tags are comma separated, replace the comma with " and " for markers
|
||||
- job_tags=$(python tools/ci/python_packages/gitlab_api.py get_job_tags $CI_PROJECT_ID --job_id $CI_JOB_ID)
|
||||
- markers=$(echo $job_tags | sed -e "s/,/ and /g")
|
||||
# download the artifacts, requires esp32 and esp32c6 chips
|
||||
- run_cmd python tools/ci/artifacts_handler.py download --job-name "build_pytest_components_esp32"
|
||||
- run_cmd python tools/ci/artifacts_handler.py download --job-name "build_pytest_components_esp32c6"
|
||||
- run_cmd pytest $TEST_DIR
|
||||
-m \"${markers}\"
|
||||
--junitxml=XUNIT_RESULT.xml
|
||||
--ignore-result-files known_failure_cases/known_failure_cases.txt
|
||||
--parallel-count ${CI_NODE_TOTAL:-1}
|
||||
--parallel-index ${CI_NODE_INDEX:-1}
|
||||
${PYTEST_EXTRA_FLAGS}
|
||||
--app-info-filepattern \"list_job_*.txt\"
|
||||
|
||||
pytest_components_esp32_ip101:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
|
@ -123,13 +123,15 @@ components/driver/test_apps/rs485:
|
||||
temporary: true
|
||||
reason: lack of runners
|
||||
|
||||
components/driver/test_apps/sdio:
|
||||
components/driver/test_apps/sdio/sdio_common_tests/host_sdmmc:
|
||||
enable:
|
||||
- if: IDF_TARGET == "esp32"
|
||||
temporary: false
|
||||
reason: always use ESP32 SDMMC as host
|
||||
|
||||
components/driver/test_apps/sdio/sdio_common_tests/sdio:
|
||||
disable:
|
||||
- if: SOC_SDIO_SLAVE_SUPPORTED != 1
|
||||
disable_test:
|
||||
- if: IDF_TARGET == "esp32c6"
|
||||
temporary: true
|
||||
reason: lack of runners
|
||||
|
||||
components/driver/test_apps/sigma_delta:
|
||||
disable:
|
||||
|
@ -1,5 +1,5 @@
|
||||
idf_component_register(
|
||||
SRCS test_spi_utils.c param_test.c
|
||||
SRCS test_spi_utils.c param_test.c test_dualboard_utils.c
|
||||
INCLUDE_DIRS include
|
||||
REQUIRES driver unity
|
||||
)
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Fill tx_buffers used in dual-board test with random numbers
|
||||
*
|
||||
* dut0_buffer and dut1_buffer will be filled with random data
|
||||
*
|
||||
* this can be used by a fullduplex dualboard transaction
|
||||
*
|
||||
* @param seed Random number seed
|
||||
* @param dut0_buffer TX buffer used by dut0
|
||||
* @param dut1_buffer TX buffer used by dut1
|
||||
* @param buffer_size Buffer size
|
||||
*/
|
||||
void test_fill_random_to_buffers_dualboard(uint32_t seed, uint8_t *dut0_buffer, uint8_t *dut1_buffer, size_t buffer_size);
|
||||
|
||||
|
||||
/**
|
||||
* Fill tx buffer with random numbers
|
||||
*
|
||||
* @param seed Random number seed
|
||||
* @param buffer Buffer
|
||||
* @param buffer_size Buffer size
|
||||
*/
|
||||
void test_fill_random_to_buffer(uint32_t seed, uint8_t *buffer, size_t buffer_size);
|
||||
|
||||
|
||||
/**
|
||||
* Calloc a pool, filled with random numbers
|
||||
*
|
||||
* @param pool_size Size of the pool
|
||||
* @param flags Calloc flags, see `esp_heap_caps.h`
|
||||
*/
|
||||
void test_prepare_buffer_pool(size_t pool_size, uint32_t flags);
|
||||
|
||||
/**
|
||||
* Get a buffer from the pool
|
||||
*
|
||||
* @param offset A random offset
|
||||
* @param size Buffer size
|
||||
* @param[out] out_buffer Out buffer
|
||||
*/
|
||||
void test_get_buffer_from_pool(uint32_t offset, size_t size, void **out_buffer);
|
||||
|
||||
/**
|
||||
* Destroy the pool
|
||||
*/
|
||||
void test_destroy_buffer_pool(void);
|
@ -22,6 +22,7 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "test_dualboard_utils.h"
|
||||
|
||||
// All the tests using the header should use this definition as much as possible,
|
||||
// so that the working host can be changed easily in the future.
|
||||
@ -292,15 +293,4 @@ void spitest_gpio_input_sel(uint32_t gpio_num, int func, uint32_t signal_idx);
|
||||
//then the cs_num of the 1st and 2nd devices are 0 and 1 respectively.
|
||||
void same_pin_func_sel(spi_bus_config_t bus, spi_device_interface_config_t dev, uint8_t cs_num);
|
||||
|
||||
/**
|
||||
* This function is used to get tx_buffer used in dual-board test
|
||||
* `master_send_buf` and `slave_send_buf` will be fulfilled with same random numbers with the seed of `seed`.
|
||||
*
|
||||
* @param seed Random number seed
|
||||
* @param master_send_buf Master TX buffer
|
||||
* @param slave_send_buf Slave TX buffer
|
||||
* @param send_buf_size Buffer size
|
||||
*/
|
||||
void get_tx_buffer(uint32_t seed, uint8_t *master_send_buf, uint8_t *slave_send_buf, int send_buf_size);
|
||||
|
||||
#endif //_TEST_COMMON_SPI_H_
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "test_dualboard_utils.h"
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Fill buffer with random numbers
|
||||
---------------------------------------------------------------*/
|
||||
void test_fill_random_to_buffers_dualboard(uint32_t seed, uint8_t *dut0_buffer, uint8_t *dut1_buffer, size_t buffer_size)
|
||||
{
|
||||
srand(seed);
|
||||
for (int i = 0; i < buffer_size; i++) {
|
||||
dut1_buffer[i] = rand() % 256;
|
||||
dut0_buffer[i] = rand() % 256;
|
||||
}
|
||||
}
|
||||
|
||||
void test_fill_random_to_buffer(uint32_t seed, uint8_t *buffer, size_t buffer_size)
|
||||
{
|
||||
srand(seed);
|
||||
for (int i = 0; i < buffer_size; i++) {
|
||||
buffer[i] = rand() % 256;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Create a pool with random numbers, get buffer from pool
|
||||
---------------------------------------------------------------*/
|
||||
static uint8_t *s_pool;
|
||||
static size_t s_pool_size;
|
||||
|
||||
void test_prepare_buffer_pool(size_t pool_size, uint32_t flags)
|
||||
{
|
||||
s_pool_size = pool_size;
|
||||
s_pool = (uint8_t *)heap_caps_calloc(1, pool_size, flags);
|
||||
TEST_ASSERT(s_pool);
|
||||
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)
|
||||
{
|
||||
//to make sure the out_buffer is within the pool
|
||||
offset = ((offset % (s_pool_size - size)) + 3) & ~3;
|
||||
// TEST_ASSERT(offset + size < (uint32_t)s_pool + s_pool_size)
|
||||
|
||||
*out_buffer = (void *)(s_pool + offset);
|
||||
}
|
||||
|
||||
void test_destroy_buffer_pool(void)
|
||||
{
|
||||
free(s_pool);
|
||||
s_pool = NULL;
|
||||
s_pool_size = 0;
|
||||
}
|
@ -240,12 +240,3 @@ void same_pin_func_sel(spi_bus_config_t bus, spi_device_interface_config_t dev,
|
||||
GPIO.func_in_sel_cfg[FSPIQ_IN_IDX].sig_in_sel = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void get_tx_buffer(uint32_t seed, uint8_t *master_send_buf, uint8_t *slave_send_buf, int send_buf_size)
|
||||
{
|
||||
srand(seed);
|
||||
for (int i = 0; i < send_buf_size; i++) {
|
||||
slave_send_buf[i] = rand() % 256;
|
||||
master_send_buf[i] = rand() % 256;
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +0,0 @@
|
||||
| Supported Targets | ESP32 | ESP32-C6 |
|
||||
| ----------------- | ----- | -------- |
|
@ -1,13 +0,0 @@
|
||||
set(srcs
|
||||
"test_app_main.c"
|
||||
"test_sdio.c"
|
||||
"test_sdmmc_sdspi_init.cpp"
|
||||
)
|
||||
|
||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(
|
||||
SRCS ${srcs}
|
||||
PRIV_REQUIRES test_utils test_driver_utils driver esp_timer sdmmc esp_serial_slave_link
|
||||
WHOLE_ARCHIVE
|
||||
)
|
@ -1,814 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_spi_utils.h"
|
||||
#include "esp_serial_slave_link/essl_sdio.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "esp_timer.h"
|
||||
#include "ccomp_timer.h"
|
||||
#include "driver/spi_common.h"
|
||||
#include "driver/sdspi_host.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
|
||||
#if SOC_SDMMC_HOST_SUPPORTED && SOC_SDIO_SLAVE_SUPPORTED
|
||||
#include "soc/sdio_slave_pins.h"
|
||||
#include "driver/sdio_slave.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
|
||||
#define TIMEOUT_MAX UINT32_MAX
|
||||
#define INT_MASK_ALL 0xff
|
||||
#define SDIO_SLAVE_QUEUE_SIZE 20
|
||||
#define RX_BUFFER_SIZE 2048
|
||||
#define RX_BUFFER_NUM 10
|
||||
#define TX_BUFFER_SIZE 2048
|
||||
#define REG_ADDR_MAX 60
|
||||
//the test should run accross the boundary, i.e. over 0x100000 bytes.
|
||||
//TEST_CNT > 512
|
||||
#define TEST_CNT 10000
|
||||
|
||||
#define TEST_SDSPI_HOST SPI2_HOST
|
||||
#define TEST_SDSPI_DMACHAN 1
|
||||
|
||||
#define TEST_RESET_DATA_LEN 10
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a)<(b)? (a): (b))
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
SDIO_1BIT = 0,
|
||||
SDIO_4BIT = 1,
|
||||
SDIO_SPI = 2,
|
||||
} sdio_mode_t;
|
||||
|
||||
typedef void (*sdio_test_func)(essl_handle_t handle);
|
||||
|
||||
typedef struct {
|
||||
const char test_name[16];
|
||||
sdio_mode_t sdio_mode;
|
||||
uint32_t freq;
|
||||
bool check_data;
|
||||
bool packet_mode;
|
||||
} sdio_test_config_t;
|
||||
|
||||
|
||||
sdio_test_config_t test_cfg_array[] = {
|
||||
//the first item will be the default config used by all tests
|
||||
{
|
||||
.test_name = "HS4B",
|
||||
.sdio_mode = SDIO_4BIT,
|
||||
.freq = SDMMC_FREQ_HIGHSPEED,
|
||||
.check_data = true,
|
||||
},
|
||||
{
|
||||
.test_name = "HS1B",
|
||||
.sdio_mode = SDIO_1BIT,
|
||||
.freq = SDMMC_FREQ_HIGHSPEED,
|
||||
.check_data = true,
|
||||
},
|
||||
{
|
||||
.test_name = "SPI",
|
||||
.sdio_mode = SDIO_SPI,
|
||||
.freq = SDMMC_FREQ_HIGHSPEED,
|
||||
.check_data = true,
|
||||
},
|
||||
//the performance test is only done when psram is not enabled
|
||||
#if !CONFIG_SPIRAM && !CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
|
||||
{
|
||||
.test_name = "HS4B (perf)",
|
||||
.sdio_mode = SDIO_4BIT,
|
||||
.freq = SDMMC_FREQ_HIGHSPEED,
|
||||
},
|
||||
{
|
||||
.test_name = "HS1B (perf)",
|
||||
.sdio_mode = SDIO_1BIT,
|
||||
.freq = SDMMC_FREQ_HIGHSPEED,
|
||||
},
|
||||
{
|
||||
.test_name = "SPI (perf)",
|
||||
.sdio_mode = SDIO_SPI,
|
||||
.freq = SDMMC_FREQ_HIGHSPEED,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
sdio_test_config_t packet_config = {
|
||||
.test_name = "HS4B packet",
|
||||
.sdio_mode = SDIO_4BIT,
|
||||
.freq = SDMMC_FREQ_HIGHSPEED,
|
||||
.check_data = true,
|
||||
.packet_mode = true,
|
||||
};
|
||||
|
||||
const sdio_test_config_t* default_config = &test_cfg_array[0];
|
||||
|
||||
#define TEST_SIZE (sizeof(test_cfg_array)/sizeof(sdio_test_config_t))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Master
|
||||
******************************************************************************/
|
||||
|
||||
static sdmmc_card_t s_card;
|
||||
|
||||
typedef void (*test_func_t)(essl_handle_t handle, const sdio_test_config_t* config);
|
||||
|
||||
static void init_sdmmc_host(void);
|
||||
static void init_essl(essl_handle_t *out_handle, const sdio_test_config_t *conf);
|
||||
static void deinit_essl(essl_handle_t handle, const sdio_test_config_t *conf);
|
||||
|
||||
static void test_framework_master(test_func_t test_func, const sdio_test_config_t* config)
|
||||
{
|
||||
unity_send_signal("Master ready");
|
||||
unity_wait_for_signal("Slave ready");
|
||||
ESP_LOGI(MASTER_TAG, "### Testing %s... ####", config->test_name);
|
||||
essl_handle_t handle;
|
||||
esp_err_t err;
|
||||
init_essl(&handle, config);
|
||||
|
||||
err = essl_init(handle, TIMEOUT_MAX);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
(*test_func)(handle, config);
|
||||
|
||||
deinit_essl(handle, config);
|
||||
}
|
||||
|
||||
static void init_sdmmc_host(void)
|
||||
{
|
||||
esp_err_t err;
|
||||
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||
err = sdmmc_host_init();
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
err = sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config);
|
||||
TEST_ESP_OK(err);
|
||||
}
|
||||
|
||||
static void init_essl(essl_handle_t *out_handle, const sdio_test_config_t *conf)
|
||||
{
|
||||
sdmmc_host_t config;
|
||||
esp_err_t err;
|
||||
spi_bus_config_t bus_config;
|
||||
/* Probe */
|
||||
|
||||
switch (conf->sdio_mode) {
|
||||
case SDIO_4BIT:
|
||||
ESP_LOGI(MASTER_TAG, "Probe using SD 4-bit...");
|
||||
config = (sdmmc_host_t)SDMMC_HOST_DEFAULT();
|
||||
config.flags = SDMMC_HOST_FLAG_4BIT;
|
||||
config.max_freq_khz = conf->freq;
|
||||
init_sdmmc_host();
|
||||
break;
|
||||
case SDIO_1BIT:
|
||||
ESP_LOGI(MASTER_TAG, "Probe using SD 1-bit...");
|
||||
config = (sdmmc_host_t)SDMMC_HOST_DEFAULT();
|
||||
config.flags = SDMMC_HOST_FLAG_1BIT;
|
||||
config.max_freq_khz = conf->freq;
|
||||
init_sdmmc_host();
|
||||
break;
|
||||
case SDIO_SPI:
|
||||
bus_config = (spi_bus_config_t) {
|
||||
.mosi_io_num = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD,
|
||||
.miso_io_num = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0,
|
||||
.sclk_io_num = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CLK,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
};
|
||||
err = spi_bus_initialize(TEST_SDSPI_HOST, &bus_config, TEST_SDSPI_DMACHAN);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
sdspi_device_config_t device_config = SDSPI_DEVICE_CONFIG_DEFAULT();
|
||||
device_config.host_id = TEST_SDSPI_HOST;
|
||||
device_config.gpio_cs = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3;
|
||||
device_config.gpio_int= SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1;
|
||||
|
||||
err = gpio_install_isr_service(0);
|
||||
TEST_ASSERT(err == ESP_OK || err == ESP_ERR_INVALID_STATE);
|
||||
|
||||
sdspi_dev_handle_t sdspi_handle;
|
||||
err = sdspi_host_init();
|
||||
TEST_ESP_OK(err);
|
||||
err = sdspi_host_init_device(&device_config, &sdspi_handle);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
ESP_LOGI(MASTER_TAG, "Probe using SPI...");
|
||||
|
||||
config = (sdmmc_host_t)SDSPI_HOST_DEFAULT();
|
||||
config.slot = sdspi_handle;
|
||||
break;
|
||||
}
|
||||
|
||||
sdmmc_card_t *card = &s_card;
|
||||
//wait for at least 5 seconds
|
||||
int retry_times = 5;
|
||||
do {
|
||||
if (sdmmc_card_init(&config, card) == ESP_OK) {
|
||||
break;
|
||||
}
|
||||
ESP_LOGW(MASTER_TAG, "slave init failed, retry...");
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
} while (--retry_times);
|
||||
TEST_ASSERT_MESSAGE(retry_times != 0, "Initializing slave failed.");
|
||||
essl_sdio_config_t ser_config = {
|
||||
.card = card,
|
||||
.recv_buffer_size = RX_BUFFER_SIZE,
|
||||
};
|
||||
err = essl_sdio_init_dev(out_handle, &ser_config);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
err = essl_init(*out_handle, TIMEOUT_MAX);
|
||||
TEST_ESP_OK(err);
|
||||
}
|
||||
|
||||
static void deinit_essl(essl_handle_t handle, const sdio_test_config_t *conf)
|
||||
{
|
||||
esp_err_t err;
|
||||
essl_sdio_deinit_dev(handle);
|
||||
if (conf->sdio_mode == SDIO_SPI) {
|
||||
gpio_uninstall_isr_service();
|
||||
|
||||
err = sdspi_host_deinit();
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
err = spi_bus_free(TEST_SDSPI_HOST);
|
||||
TEST_ESP_OK(err);
|
||||
} else {
|
||||
err = sdmmc_host_deinit();
|
||||
TEST_ESP_OK(err);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_finish_test(essl_handle_t handle)
|
||||
{
|
||||
//the slave needs a signal to quite the test
|
||||
essl_send_slave_intr(handle, BIT(7), TIMEOUT_MAX);
|
||||
}
|
||||
|
||||
static void test_int(essl_handle_t handle, const sdio_test_config_t* config)
|
||||
{
|
||||
esp_err_t err;
|
||||
err = essl_set_intr_ena(handle, INT_MASK_ALL, TIMEOUT_MAX);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
err = essl_wait_int(handle, 0);
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_ERR_TIMEOUT, err);
|
||||
|
||||
//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 ++) {
|
||||
uint32_t int_st;
|
||||
err = essl_send_slave_intr(handle, BIT(i), TIMEOUT_MAX);
|
||||
TEST_ESP_OK(err);
|
||||
//the slave should return interrupt with the same bit in 10 ms
|
||||
err = essl_wait_int(handle, 10);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
err = essl_get_intr(handle, NULL, &int_st, TIMEOUT_MAX);
|
||||
TEST_ESP_OK(err);
|
||||
//check and clear the returned interrupt
|
||||
TEST_ASSERT_EQUAL_HEX(BIT(i), int_st);
|
||||
err = essl_clear_intr(handle, int_st, TIMEOUT_MAX);
|
||||
TEST_ESP_OK(err);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_sdio_interrupt_master(void)
|
||||
{
|
||||
test_framework_master(test_int, default_config);
|
||||
}
|
||||
|
||||
static void test_reg(essl_handle_t handle, const sdio_test_config_t* config)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint8_t data[REG_ADDR_MAX];
|
||||
srand(850);
|
||||
|
||||
//initialize the buffer
|
||||
for (int i = 0; i < REG_ADDR_MAX; i++) {
|
||||
data[i] = rand();
|
||||
err = essl_write_reg(handle, i, data[i], NULL, 10);
|
||||
TEST_ESP_OK(err);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 512; i++) {
|
||||
//randomly write one
|
||||
int offset = rand() % REG_ADDR_MAX;
|
||||
uint8_t data_write = rand();
|
||||
data[offset] = data_write;
|
||||
|
||||
err = essl_write_reg(handle, offset, data_write, NULL, 10);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
//randomly read another one and compare
|
||||
offset = rand() % REG_ADDR_MAX;
|
||||
uint8_t data_read;
|
||||
err = essl_read_reg(handle, offset, &data_read, 10);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8(data[offset], data_read);
|
||||
}
|
||||
|
||||
send_finish_test(handle);
|
||||
}
|
||||
|
||||
static void test_sdio_reg_master(void)
|
||||
{
|
||||
test_framework_master(test_reg, default_config);
|
||||
}
|
||||
|
||||
static uint8_t tx_buffer[TX_BUFFER_SIZE*2];
|
||||
static uint8_t rcv_buffer[RX_BUFFER_SIZE*RX_BUFFER_NUM];
|
||||
|
||||
static void init_tx_buffer(void)
|
||||
{
|
||||
srand(776);
|
||||
for (int i = 0; i < sizeof(tx_buffer); i++) {
|
||||
tx_buffer[i] = rand();
|
||||
}
|
||||
}
|
||||
|
||||
static void get_master_send_data(int offset, uint8_t** out_start, int* out_len)
|
||||
{
|
||||
int page_cnt = offset / TX_BUFFER_SIZE;
|
||||
int offset_in_page = offset % TX_BUFFER_SIZE;
|
||||
srand(page_cnt);
|
||||
int page_offset = (rand() % (sizeof(tx_buffer) - (TX_BUFFER_SIZE) + 1)) & (~3);
|
||||
*out_start = &tx_buffer[page_offset + offset_in_page];
|
||||
*out_len = TX_BUFFER_SIZE - offset_in_page;
|
||||
}
|
||||
|
||||
static void log_performance_tohost(uint32_t speed, const sdio_test_config_t* config)
|
||||
{
|
||||
if (!config->check_data) {
|
||||
switch (config->sdio_mode) {
|
||||
case SDIO_4BIT:
|
||||
TEST_PERFORMANCE_CCOMP_GREATER_THAN(SDIO_THROUGHPUT_KBSEC_TOHOST_4BIT, "%" PRIu32, speed);
|
||||
break;
|
||||
case SDIO_1BIT:
|
||||
TEST_PERFORMANCE_CCOMP_GREATER_THAN(SDIO_THROUGHPUT_KBSEC_TOHOST_1BIT, "%" PRIu32, speed);
|
||||
break;
|
||||
case SDIO_SPI:
|
||||
TEST_PERFORMANCE_CCOMP_GREATER_THAN(SDIO_THROUGHPUT_KBSEC_TOHOST_SPI, "%" PRIu32, speed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_tp_tohost_master(essl_handle_t handle, const sdio_test_config_t* config)
|
||||
{
|
||||
esp_err_t err;
|
||||
int expected_length = TEST_CNT * TX_BUFFER_SIZE;
|
||||
int recv_size = 4096;
|
||||
init_tx_buffer();
|
||||
//wait for the slave to get ready
|
||||
vTaskDelay(20);
|
||||
|
||||
int remain_length = expected_length;
|
||||
int offset = 0;
|
||||
|
||||
// Two counters are used. The `esp_timer_get_time()` is for the typical time, and the
|
||||
// `ccomp_timer` is for performance test to reduce influence caused by cache miss.
|
||||
int64_t pre_us = esp_timer_get_time();
|
||||
err = ccomp_timer_start();
|
||||
assert(err == ESP_OK);
|
||||
// though the flow is the same, the check of config->check_data influences the throughput much, put it outside
|
||||
if (config->check_data) {
|
||||
do {
|
||||
size_t rcv_len;
|
||||
err = essl_get_packet(handle, rcv_buffer, recv_size, &rcv_len, TIMEOUT_MAX);
|
||||
TEST_ASSERT(err == ESP_OK || err == ESP_ERR_NOT_FINISHED);
|
||||
TEST_ASSERT_LESS_OR_EQUAL(remain_length, rcv_len);
|
||||
|
||||
//compare until all received data are used
|
||||
int compared_len = 0;
|
||||
do {
|
||||
//get the expected master sent data, there may be several segments, so get and compare
|
||||
//several times
|
||||
uint8_t* cmp_start;
|
||||
int seg_len;
|
||||
get_master_send_data(offset, &cmp_start, &seg_len);
|
||||
|
||||
int cmp_len = MIN(rcv_len-compared_len, seg_len);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(cmp_start, &rcv_buffer[compared_len], cmp_len);
|
||||
|
||||
compared_len += cmp_len;
|
||||
offset += cmp_len;
|
||||
} while (compared_len < rcv_len);
|
||||
|
||||
remain_length -= rcv_len;
|
||||
} while (remain_length > 0);
|
||||
} else {
|
||||
do {
|
||||
size_t rcv_len;
|
||||
err = essl_get_packet(handle, rcv_buffer, recv_size, &rcv_len, TIMEOUT_MAX);
|
||||
TEST_ASSERT(err == ESP_OK || err == ESP_ERR_NOT_FINISHED);
|
||||
TEST_ASSERT_LESS_OR_EQUAL(remain_length, rcv_len);
|
||||
|
||||
offset += rcv_len;
|
||||
remain_length -= rcv_len;
|
||||
} while (remain_length > 0);
|
||||
}
|
||||
int64_t c_time_ms = ccomp_timer_stop()/1000;
|
||||
int64_t end_us = esp_timer_get_time();
|
||||
|
||||
uint32_t total_time_ms = (end_us - pre_us)/1000;
|
||||
ESP_LOGI(MASTER_TAG, "test done, total time: %" PRIu32 " ms (%d ms compensated), bytes transferred: %d", total_time_ms, (int)c_time_ms, expected_length);
|
||||
|
||||
uint32_t throughput_byte_per_ms = expected_length / c_time_ms;
|
||||
ESP_LOGI(MASTER_TAG, "Throughput: compensated %.2lf MB/s, typical %.2lf MB/s",
|
||||
throughput_byte_per_ms/1000., expected_length/(total_time_ms*1000.));
|
||||
log_performance_tohost(throughput_byte_per_ms, config);
|
||||
|
||||
send_finish_test(handle);
|
||||
}
|
||||
|
||||
static void log_performance_frhost(uint32_t speed, const sdio_test_config_t* config)
|
||||
{
|
||||
if (!config->check_data) {
|
||||
switch (config->sdio_mode) {
|
||||
case SDIO_4BIT:
|
||||
TEST_PERFORMANCE_CCOMP_GREATER_THAN(SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT, "%" PRIu32, speed);
|
||||
break;
|
||||
case SDIO_1BIT:
|
||||
TEST_PERFORMANCE_CCOMP_GREATER_THAN(SDIO_THROUGHPUT_KBSEC_FRHOST_1BIT, "%" PRIu32, speed);
|
||||
break;
|
||||
case SDIO_SPI:
|
||||
TEST_PERFORMANCE_CCOMP_GREATER_THAN(SDIO_THROUGHPUT_KBSEC_FRHOST_SPI, "%" PRIu32, speed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_tp_frhost_master(essl_handle_t handle, const sdio_test_config_t* config)
|
||||
{
|
||||
esp_err_t err;
|
||||
int expected_length = TEST_CNT * TX_BUFFER_SIZE;
|
||||
init_tx_buffer();
|
||||
//wait for the slave to get ready
|
||||
vTaskDelay(20);
|
||||
|
||||
int remain_length = expected_length;
|
||||
int offset = 0;
|
||||
|
||||
// Two counters are used. The `esp_timer_get_time()` is for the typical time, and the
|
||||
// `ccomp_timer` is for performance test to reduce influence caused by cache miss.
|
||||
int64_t pre_us = esp_timer_get_time();
|
||||
err = ccomp_timer_start();
|
||||
assert(err == ESP_OK);
|
||||
do {
|
||||
int send_len;
|
||||
uint8_t* send_start;
|
||||
get_master_send_data(offset, &send_start, &send_len);
|
||||
TEST_ASSERT_EQUAL(TX_BUFFER_SIZE, send_len);
|
||||
|
||||
err = essl_send_packet(handle, send_start, send_len, TIMEOUT_MAX);
|
||||
TEST_ASSERT(err == ESP_OK);
|
||||
|
||||
remain_length -= send_len;
|
||||
offset += send_len;
|
||||
} while (remain_length > 0);
|
||||
|
||||
int64_t c_time_ms = ccomp_timer_stop()/1000;
|
||||
int64_t end_us = esp_timer_get_time();
|
||||
|
||||
uint32_t total_time_ms = (end_us - pre_us)/1000;
|
||||
ESP_LOGI(MASTER_TAG, "test done, total time: %" PRIu32 " ms (%d ms compensated), bytes transferred: %d", total_time_ms, (int)c_time_ms, expected_length);
|
||||
|
||||
uint32_t throughput_byte_per_ms = expected_length / c_time_ms;
|
||||
ESP_LOGI(MASTER_TAG, "Throughput: compensated %.2lf MB/s, typical %.2lf MB/s",
|
||||
throughput_byte_per_ms/1000., expected_length/(total_time_ms*1000.));
|
||||
log_performance_frhost(throughput_byte_per_ms, config);
|
||||
|
||||
send_finish_test(handle);
|
||||
}
|
||||
|
||||
void test_reset_master(essl_handle_t handle, const sdio_test_config_t* config)
|
||||
{
|
||||
init_tx_buffer();
|
||||
//wait for the slave to stop, reset and start again
|
||||
vTaskDelay(10);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
WORD_ALIGNED_ATTR uint8_t buffer[TEST_RESET_DATA_LEN];
|
||||
size_t read_len;
|
||||
esp_err_t err = essl_get_packet(handle, buffer, TEST_RESET_DATA_LEN, &read_len, portMAX_DELAY);
|
||||
if (err == ESP_ERR_NOT_FINISHED) {
|
||||
TEST_ASSERT_LESS_THAN(10, i);
|
||||
err = ESP_OK;
|
||||
}
|
||||
TEST_ESP_OK(err);
|
||||
TEST_ASSERT_EQUAL(TEST_RESET_DATA_LEN, read_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(tx_buffer + 4*i, buffer, read_len);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
esp_err_t err = essl_send_packet(handle, tx_buffer + i * 8, TEST_RESET_DATA_LEN, portMAX_DELAY);
|
||||
TEST_ESP_OK(err);
|
||||
}
|
||||
|
||||
send_finish_test(handle);
|
||||
}
|
||||
|
||||
void test_sdio_reset_master(void)
|
||||
{
|
||||
test_framework_master(test_reset_master, &packet_config);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Slave
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int queued_cnt;
|
||||
bool s_finished;
|
||||
} slave_context_t;
|
||||
|
||||
typedef void (*test_func_slave_t)(slave_context_t *context, const sdio_test_config_t* config);
|
||||
|
||||
static slave_context_t slave_context;
|
||||
|
||||
static void event_cb(uint8_t event)
|
||||
{
|
||||
ESP_EARLY_LOGI(SLAVE_TAG, "event: %d", event);
|
||||
sdio_slave_send_host_int(event);
|
||||
if (event == 7) slave_context.s_finished = true;
|
||||
}
|
||||
|
||||
|
||||
static void wait_for_finish(slave_context_t *ctx)
|
||||
{
|
||||
while (!ctx->s_finished) {
|
||||
vTaskDelay(10);
|
||||
}
|
||||
//wait for host to read the respond from slave
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
static void test_framework_slave(test_func_slave_t test_func, const sdio_test_config_t* config)
|
||||
{
|
||||
unity_wait_for_signal("Master ready");
|
||||
slave_context.s_finished = false;
|
||||
esp_err_t err;
|
||||
sdio_slave_config_t slave_config = {
|
||||
.sending_mode = (config->packet_mode? SDIO_SLAVE_SEND_PACKET: SDIO_SLAVE_SEND_STREAM),
|
||||
.send_queue_size = SDIO_SLAVE_QUEUE_SIZE,
|
||||
.recv_buffer_size = RX_BUFFER_SIZE,
|
||||
.event_cb = event_cb,
|
||||
};
|
||||
err = sdio_slave_initialize(&slave_config);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
err = sdio_slave_start();
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
unity_send_signal("Slave ready");
|
||||
|
||||
test_func(&slave_context, config);
|
||||
|
||||
sdio_slave_stop();
|
||||
sdio_slave_deinit();
|
||||
}
|
||||
|
||||
static void test_int_slave(slave_context_t* ctx, const sdio_test_config_t* config)
|
||||
{
|
||||
wait_for_finish(ctx);
|
||||
}
|
||||
|
||||
static void test_sdio_interrupt_slave(void)
|
||||
{
|
||||
test_framework_slave(test_int_slave, default_config);
|
||||
}
|
||||
|
||||
static void test_tp_tohost_slave(slave_context_t* ctx, const sdio_test_config_t* config)
|
||||
{
|
||||
#define QUEUE_FULL() (ctx->queued_cnt == SDIO_SLAVE_QUEUE_SIZE)
|
||||
#define QUEUE_EMPTY() (ctx->queued_cnt == 0)
|
||||
|
||||
init_tx_buffer();
|
||||
esp_err_t err;
|
||||
int offset = 0;
|
||||
for (int i = 0; i < TEST_CNT; i++) {
|
||||
do {
|
||||
void* arg;
|
||||
//when the queue is full, do a blocking wait for 10ms, otherwise non-blocking
|
||||
err = sdio_slave_send_get_finished(&arg, QUEUE_FULL()? 1: 0);
|
||||
if (err == ESP_OK) {
|
||||
ctx->queued_cnt --;
|
||||
continue;
|
||||
}
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, err);
|
||||
} while (QUEUE_FULL());
|
||||
|
||||
uint8_t* start;
|
||||
int send_len;
|
||||
get_master_send_data(offset, &start, &send_len);
|
||||
TEST_ASSERT_EQUAL(TX_BUFFER_SIZE, send_len);
|
||||
|
||||
err = sdio_slave_send_queue(start, send_len, NULL, portMAX_DELAY);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
ctx->queued_cnt++;
|
||||
offset += TX_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
while (!QUEUE_EMPTY()) {
|
||||
void* arg;
|
||||
err = sdio_slave_send_get_finished(&arg, portMAX_DELAY);
|
||||
TEST_ESP_OK(err);
|
||||
ctx->queued_cnt--;
|
||||
}
|
||||
|
||||
wait_for_finish(ctx);
|
||||
}
|
||||
|
||||
static void slave_parepare_recv_buffer(void)
|
||||
{
|
||||
for (int i = 0; i < RX_BUFFER_NUM; i++) {
|
||||
sdio_slave_buf_handle_t buf_handle = sdio_slave_recv_register_buf(&rcv_buffer[i*RX_BUFFER_SIZE]);
|
||||
esp_err_t err = sdio_slave_recv_load_buf(buf_handle);
|
||||
TEST_ESP_OK(err);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void test_tp_frhost_slave(slave_context_t *ctx, const sdio_test_config_t* config)
|
||||
{
|
||||
esp_err_t err;
|
||||
init_tx_buffer();
|
||||
slave_parepare_recv_buffer();
|
||||
|
||||
int offset = 0;
|
||||
for (int i = 0; i < TEST_CNT; i++) {
|
||||
sdio_slave_buf_handle_t buf_handle;
|
||||
uint8_t* buf;
|
||||
size_t rcv_len;
|
||||
|
||||
err = sdio_slave_recv(&buf_handle, &buf, &rcv_len, portMAX_DELAY);
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
if (config->check_data) {
|
||||
//compare until all received data are used
|
||||
int compared_len = 0;
|
||||
do {
|
||||
//get the expected master sent data, there may be several segments, so get and compare
|
||||
//several times
|
||||
uint8_t* cmp_start;
|
||||
int seg_len;
|
||||
get_master_send_data(offset, &cmp_start, &seg_len);
|
||||
|
||||
int cmp_len = MIN(rcv_len-compared_len, seg_len);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(cmp_start, &buf[compared_len], cmp_len);
|
||||
|
||||
compared_len += cmp_len;
|
||||
offset += cmp_len;
|
||||
} while (compared_len < rcv_len);
|
||||
} else {
|
||||
offset += rcv_len;
|
||||
}
|
||||
|
||||
err = sdio_slave_recv_load_buf(buf_handle);
|
||||
TEST_ESP_OK(err);
|
||||
}
|
||||
wait_for_finish(ctx);
|
||||
}
|
||||
|
||||
static void slave_tx_rx_short_data(void)
|
||||
{
|
||||
esp_err_t err;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
err = sdio_slave_send_queue(tx_buffer + 4*i, TEST_RESET_DATA_LEN, (void*)i, portMAX_DELAY);
|
||||
TEST_ESP_OK(err);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
uint8_t* addr;
|
||||
size_t size;
|
||||
sdio_slave_buf_handle_t recv_handle;
|
||||
err = sdio_slave_recv(&recv_handle, &addr, &size, portMAX_DELAY);
|
||||
TEST_ESP_OK(err);
|
||||
TEST_ASSERT_EQUAL(TEST_RESET_DATA_LEN, size);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(tx_buffer+i*8, addr, size);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
void* arg;
|
||||
err = sdio_slave_send_get_finished(&arg, portMAX_DELAY);
|
||||
TEST_ESP_OK(err);
|
||||
TEST_ASSERT_EQUAL(i, arg);
|
||||
}
|
||||
}
|
||||
|
||||
void test_reset_slave(slave_context_t *context, const sdio_test_config_t* config)
|
||||
{
|
||||
sdio_slave_stop();
|
||||
|
||||
esp_err_t err = sdio_slave_reset();
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
err = sdio_slave_start();
|
||||
TEST_ESP_OK(err);
|
||||
|
||||
init_tx_buffer();
|
||||
|
||||
slave_parepare_recv_buffer();
|
||||
|
||||
slave_tx_rx_short_data();
|
||||
|
||||
wait_for_finish(context);
|
||||
}
|
||||
|
||||
void test_sdio_reset_slave(void)
|
||||
{
|
||||
test_framework_slave(test_reset_slave, &packet_config);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("sdio interrupt", "[sdio][test_env=sdio_master_slave]", test_sdio_interrupt_master, test_sdio_interrupt_slave);
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("sdio register", "[sdio][test_env=sdio_master_slave]", test_sdio_reg_master, test_sdio_interrupt_slave);
|
||||
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
TEST_CASE_MULTIPLE_DEVICES("sdio reset", "[sdio][test_env=sdio_master_slave]", test_sdio_reset_master, test_sdio_reset_slave);
|
||||
#else
|
||||
//Currently there is weird issue on the runner, when tested with single core config, seems to relate to receiving
|
||||
TEST_CASE_MULTIPLE_DEVICES("sdio reset", "[sdio][test_env=sdio_master_slave][ignore]", test_sdio_reset_master, test_sdio_reset_slave);
|
||||
#endif
|
||||
|
||||
|
||||
static void test_sdio_frhost_master(const void* pset, void* context)
|
||||
{
|
||||
test_framework_master(test_tp_frhost_master, pset);
|
||||
}
|
||||
|
||||
static void test_sdio_frhost_slave(const void* pset, void* context)
|
||||
{
|
||||
test_framework_slave(test_tp_frhost_slave, pset);
|
||||
}
|
||||
|
||||
static void test_sdio_tohost_master(const void* pset, void* context)
|
||||
{
|
||||
test_framework_master(test_tp_tohost_master, pset);
|
||||
}
|
||||
|
||||
static void test_sdio_tohost_slave(const void* pset, void* context)
|
||||
{
|
||||
test_framework_slave(test_tp_tohost_slave, pset);
|
||||
}
|
||||
|
||||
|
||||
static void null_pre(void** arg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void null_post(void* arg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ptest_func_t frhost_master = {
|
||||
.pre_test = null_pre,
|
||||
.loop = test_sdio_frhost_master,
|
||||
.post_test = null_post,
|
||||
};
|
||||
|
||||
ptest_func_t frhost_slave = {
|
||||
.pre_test = null_pre,
|
||||
.loop = test_sdio_frhost_slave,
|
||||
.post_test = null_post,
|
||||
};
|
||||
|
||||
PARAM_GROUP_DECLARE_TYPE(IO_MODE, sdio_test_config_t, test_cfg_array);
|
||||
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
TEST_MASTER_SLAVE(SDIO_FRHOST, test_cfg_array, "[sdio][timeout=180][test_env=sdio_master_slave]", &frhost_master, &frhost_slave);
|
||||
#else
|
||||
//Currently there is weird issue on the runner, when tested with single core config, seems to relate to receiving
|
||||
TEST_MASTER_SLAVE(SDIO_FRHOST, test_cfg_array, "[sdio][timeout=180][test_env=sdio_master_slave][ignore]", &frhost_master, &frhost_slave);
|
||||
#endif
|
||||
|
||||
ptest_func_t tohost_master = {
|
||||
.pre_test = null_pre,
|
||||
.loop = test_sdio_tohost_master,
|
||||
.post_test = null_post,
|
||||
};
|
||||
|
||||
ptest_func_t tohost_slave = {
|
||||
.pre_test = null_pre,
|
||||
.loop = test_sdio_tohost_slave,
|
||||
.post_test = null_post,
|
||||
};
|
||||
|
||||
TEST_MASTER_SLAVE(SDIO_TOHOST, test_cfg_array, "[sdio][timeout=180][test_env=sdio_master_slave]", &tohost_master, &tohost_slave);
|
||||
|
||||
#endif //SOC_SDMMC_HOST_SUPPORTED && SOC_SDIO_SLAVE_SUPPORTED
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#if SOC_SDMMC_HOST_SUPPORTED
|
||||
#include "driver/sdmmc_host.h"
|
||||
#endif
|
||||
|
||||
#include "driver/sdspi_host.h"
|
||||
|
||||
|
||||
/**
|
||||
* Check that C-style designated initializers are valid in C++ file.
|
||||
*/
|
||||
static void test_initializers() __attribute__((unused));
|
||||
|
||||
static void test_initializers()
|
||||
{
|
||||
#if SOC_SDMMC_HOST_SUPPORTED
|
||||
sdmmc_host_t sdmmc_host = SDMMC_HOST_DEFAULT();
|
||||
(void) sdmmc_host;
|
||||
sdmmc_slot_config_t sdmmc_slot = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||
(void) sdmmc_slot;
|
||||
#endif
|
||||
sdmmc_host_t sdspi_host = SDSPI_HOST_DEFAULT();
|
||||
(void) sdspi_host;
|
||||
sdspi_device_config_t sdspi_dev = SDSPI_DEVICE_CONFIG_DEFAULT();
|
||||
(void) sdspi_dev;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.sdio_master_slave
|
||||
@pytest.mark.parametrize('count', [2,], indirect=True)
|
||||
def test_sdio_multi_dev(case_tester) -> None: # type: ignore
|
||||
case_tester.run_all_multi_dev_cases(reset=True, timeout=180)
|
@ -0,0 +1,7 @@
|
||||
# SDIO Cross Chips Test Apps
|
||||
|
||||
This folder contains SDIO related tests. This folder contains two sub-folders:
|
||||
- host_sdmmc: this fodler contains the ESP32 SDMMC test app which works as the host to test the SDIO Slave peripheral
|
||||
- sdio: this fodler contains the ESP SDIO Slave test apps
|
||||
|
||||
Tests in this folder are all dual-board tests.
|
@ -0,0 +1,13 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
set(COMPONENTS main)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS
|
||||
"$ENV{IDF_PATH}/tools/unit-test-app/components"
|
||||
"$ENV{IDF_PATH}/components/driver/test_apps/components"
|
||||
)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(host_sdmmc)
|
@ -0,0 +1,6 @@
|
||||
| Supported Targets | ESP32 |
|
||||
| ----------------- | ----- |
|
||||
|
||||
# SDIO Cross Chips Test Apps: SDMMC Host App
|
||||
|
||||
This test app is using ESP32 SDMMC as the host to test the SDIO Slave peripherals among ESP chips.
|
@ -0,0 +1,6 @@
|
||||
set(srcs "test_app_main.c"
|
||||
"test_sdio_sdhost.c")
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
PRIV_REQUIRES unity test_driver_utils driver esp_serial_slave_link sdmmc test_utils esp_timer
|
||||
WHOLE_ARCHIVE)
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_utils.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
// Some resources are lazy allocated, the threadhold is left for that case
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (700)
|
||||
|
||||
static size_t before_free_8bit;
|
||||
static size_t before_free_32bit;
|
||||
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
|
||||
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
/* _____ ____ ________ _____ ____ __ _____ _________
|
||||
/ ___// __ \/ _/ __ \ / ___// __ \/ |/ / |/ / ____/
|
||||
\__ \/ / / // // / / / \__ \/ / / / /|_/ / /|_/ / /
|
||||
___/ / /_/ // // /_/ / ___/ / /_/ / / / / / / / /___
|
||||
/____/_____/___/\____/ /____/_____/_/ /_/_/ /_/\____/
|
||||
|
||||
*/
|
||||
|
||||
printf(" _____ ____ ________ _____ ____ __ _____ _________\n");
|
||||
printf(" / ___// __ \\/ _/ __ \\ / ___// __ \\/ |/ / |/ / ____/\n");
|
||||
printf(" \\__ \\/ / / // // / / / \\__ \\/ / / / /|_/ / /|_/ / / \n");
|
||||
printf(" ___/ / /_/ // // /_/ / ___/ / /_/ / / / / / / / /___ \n");
|
||||
printf("/____/_____/___/\\____/ /____/_____/_/ /_/_/ /_/\\____/ \n");
|
||||
printf(" \n");
|
||||
|
||||
|
||||
|
||||
unity_run_menu();
|
||||
}
|
@ -0,0 +1,359 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file uses ESP32 SDMMC peripheral to test SDIO Slave peripheral SD modes
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_timer.h"
|
||||
#include "ccomp_timer.h"
|
||||
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
#include "esp_serial_slave_link/essl_sdio.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#include "test_utils.h"
|
||||
#include "idf_performance.h"
|
||||
#include "test_dualboard_utils.h"
|
||||
#include "../../sdio_common_test.h"
|
||||
|
||||
static const char *TAG = "test_sdio_sdhost";
|
||||
|
||||
#define TEST_HEX_LOG_LEVEL ESP_LOG_DEBUG
|
||||
#define TEST_INT_MASK_ALL 0xff
|
||||
#define TEST_REG_ADDR_MAX 60
|
||||
#define TEST_TIMEOUT_MAX UINT32_MAX
|
||||
|
||||
typedef struct {
|
||||
uint32_t host_flags;
|
||||
uint32_t max_freq_khz;
|
||||
bool check_data;
|
||||
} test_sdio_param_t;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Host Init Settings
|
||||
---------------------------------------------------------------*/
|
||||
static sdmmc_card_t s_card;
|
||||
|
||||
static void s_master_init(test_sdio_param_t *host_param, essl_handle_t *out_handle)
|
||||
{
|
||||
sdmmc_host_t host_config = (sdmmc_host_t)SDMMC_HOST_DEFAULT();
|
||||
host_config.flags = host_param->host_flags;
|
||||
if (host_config.flags == SDMMC_HOST_FLAG_4BIT) {
|
||||
ESP_LOGI(TAG, "Probe using SD 4-bit...");
|
||||
} else if (host_config.flags == SDMMC_HOST_FLAG_1BIT) {
|
||||
ESP_LOGI(TAG, "Probe using SD 1-bit...");
|
||||
}
|
||||
host_config.max_freq_khz = host_param->max_freq_khz;
|
||||
ESP_LOGI(TAG, "Host max_freq_khz: %d", host_config.max_freq_khz);
|
||||
|
||||
//init sdmmc host
|
||||
TEST_ESP_OK(sdmmc_host_init());
|
||||
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||
TEST_ESP_OK(sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config));
|
||||
|
||||
//host init slave
|
||||
sdmmc_card_t *card = &s_card;
|
||||
//wait for at least 5 seconds
|
||||
int retry_times = 5;
|
||||
do {
|
||||
if (sdmmc_card_init(&host_config, card) == ESP_OK) {
|
||||
break;
|
||||
}
|
||||
ESP_LOGW(TAG, "slave init failed, retry...");
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
} while (--retry_times);
|
||||
TEST_ASSERT_MESSAGE(retry_times != 0, "Initializing slave failed.");
|
||||
|
||||
//init essl sdmmc host
|
||||
essl_sdio_config_t essl_sdio_config = {
|
||||
.card = card,
|
||||
.recv_buffer_size = TEST_RX_BUFFER_SIZE,
|
||||
};
|
||||
TEST_ESP_OK(essl_sdio_init_dev(out_handle, &essl_sdio_config));
|
||||
|
||||
TEST_ESP_OK(essl_init(*out_handle, TEST_TIMEOUT_MAX));
|
||||
}
|
||||
|
||||
//trigger event 7 to indicate Slave to stop the test
|
||||
static void s_send_finish_test(essl_handle_t handle)
|
||||
{
|
||||
//the slave needs a signal to quite the test
|
||||
essl_send_slave_intr(handle, BIT(7), TEST_TIMEOUT_MAX);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Function Tests
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
SDMMC_SDIO: test interrupt
|
||||
---------------------------------------------------------------*/
|
||||
TEST_CASE("SDIO_SDMMC: test interrupt", "[sdio]")
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
essl_handle_t handle = NULL;
|
||||
test_sdio_param_t test_param = {
|
||||
.host_flags = SDMMC_HOST_FLAG_4BIT,
|
||||
.max_freq_khz = SDMMC_FREQ_HIGHSPEED,
|
||||
};
|
||||
//essl init and sdmmc init
|
||||
s_master_init(&test_param, &handle);
|
||||
|
||||
TEST_ESP_OK(essl_set_intr_ena(handle, TEST_INT_MASK_ALL, TEST_TIMEOUT_MAX));
|
||||
ret = essl_wait_int(handle, 0);
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_ERR_TIMEOUT, ret);
|
||||
|
||||
//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 ++) {
|
||||
esp_rom_printf("to essl_send_slave_intr\n");
|
||||
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
|
||||
TEST_ESP_OK(essl_wait_int(handle, 10));
|
||||
|
||||
uint32_t int_st;
|
||||
TEST_ESP_OK(essl_get_intr(handle, NULL, &int_st, TEST_TIMEOUT_MAX));
|
||||
|
||||
//check and clear the returned interrupt
|
||||
TEST_ASSERT_EQUAL_HEX(BIT(i), int_st);
|
||||
TEST_ESP_OK(essl_clear_intr(handle, int_st, TEST_TIMEOUT_MAX));
|
||||
}
|
||||
|
||||
sdmmc_host_deinit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
SDMMC_SDIO: test register
|
||||
---------------------------------------------------------------*/
|
||||
TEST_CASE("SDIO_SDMMC: test register", "[sdio]")
|
||||
{
|
||||
essl_handle_t handle = NULL;
|
||||
test_sdio_param_t test_param = {
|
||||
.host_flags = SDMMC_HOST_FLAG_4BIT,
|
||||
.max_freq_khz = SDMMC_FREQ_HIGHSPEED,
|
||||
};
|
||||
//essl init and sdmmc init
|
||||
s_master_init(&test_param, &handle);
|
||||
|
||||
uint32_t init_val = 30;
|
||||
srand(850);
|
||||
//initialize the registers
|
||||
for (int i = 0; i < TEST_REG_ADDR_MAX; i++) {
|
||||
TEST_ESP_OK(essl_write_reg(handle, i, init_val, NULL, 10));
|
||||
}
|
||||
|
||||
for (int i = 0; i < TEST_REG_ADDR_MAX; i++) {
|
||||
uint8_t data_write = rand() % 0xFF;
|
||||
TEST_ESP_OK(essl_write_reg(handle, i, data_write, NULL, 10));
|
||||
|
||||
uint8_t data_read = 0;
|
||||
TEST_ESP_OK(essl_read_reg(handle, i, &data_read, 10));
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8(data_write, data_read);
|
||||
}
|
||||
|
||||
s_send_finish_test(handle);
|
||||
sdmmc_host_deinit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
SDMMC_SDIO: test reset
|
||||
---------------------------------------------------------------*/
|
||||
TEST_CASE("SDIO_SDMMC: test reset", "[sdio]")
|
||||
{
|
||||
essl_handle_t handle = NULL;
|
||||
test_sdio_param_t test_param = {
|
||||
.host_flags = SDMMC_HOST_FLAG_4BIT,
|
||||
.max_freq_khz = SDMMC_FREQ_HIGHSPEED,
|
||||
};
|
||||
//essl init and sdmmc init
|
||||
s_master_init(&test_param, &handle);
|
||||
|
||||
//wait for the slave to stop, reset and start again
|
||||
vTaskDelay(10);
|
||||
|
||||
//rx
|
||||
WORD_ALIGNED_ATTR uint8_t slave_tx_buffer[TEST_RESET_DATA_LEN] = {};
|
||||
WORD_ALIGNED_ATTR uint8_t host_rx_buffer[TEST_RESET_DATA_LEN] = {};
|
||||
size_t read_len = 0;
|
||||
for (int i = 0; i < TEST_RESET_BUF_NUMS; i++) {
|
||||
test_fill_random_to_buffer(i, slave_tx_buffer, TEST_RESET_DATA_LEN);
|
||||
esp_err_t ret = essl_get_packet(handle, host_rx_buffer, TEST_RESET_DATA_LEN, &read_len, portMAX_DELAY);
|
||||
if (ret == ESP_ERR_NOT_FINISHED) {
|
||||
printf("not finished\n");
|
||||
ret = ESP_OK;
|
||||
}
|
||||
TEST_ESP_OK(ret);
|
||||
TEST_ASSERT_EQUAL(TEST_RESET_DATA_LEN, read_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(slave_tx_buffer, host_rx_buffer, read_len);
|
||||
}
|
||||
|
||||
//tx
|
||||
WORD_ALIGNED_ATTR uint8_t host_tx_buffer[TEST_RESET_BUF_NUMS][TEST_RESET_DATA_LEN] = {};
|
||||
for (int i = 0; i < TEST_RESET_BUF_NUMS; i++) {
|
||||
test_fill_random_to_buffer(i, host_tx_buffer[i], TEST_RESET_DATA_LEN);
|
||||
TEST_ESP_OK(essl_send_packet(handle, host_tx_buffer[i], TEST_RESET_DATA_LEN, TEST_TIMEOUT_MAX));
|
||||
}
|
||||
|
||||
s_send_finish_test(handle);
|
||||
sdmmc_host_deinit();
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Transaction Tests
|
||||
---------------------------------------------------------------*/
|
||||
test_sdio_param_t test_param_lists[TEST_TARNS_PARAM_NUMS] = {
|
||||
{
|
||||
.host_flags = SDMMC_HOST_FLAG_4BIT,
|
||||
.max_freq_khz = SDMMC_FREQ_HIGHSPEED,
|
||||
},
|
||||
{
|
||||
.host_flags = SDMMC_HOST_FLAG_1BIT,
|
||||
.max_freq_khz = SDMMC_FREQ_HIGHSPEED,
|
||||
},
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
SDMMC_SDIO: test from host
|
||||
---------------------------------------------------------------*/
|
||||
static void test_from_host(bool check_data)
|
||||
{
|
||||
test_prepare_buffer_pool(TEST_RX_BUFFER_SIZE * 4, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
|
||||
for (int i = 0; i < TEST_TARNS_PARAM_NUMS; i++) {
|
||||
ESP_LOGI(TAG, "host mode: %s", (test_param_lists[i].host_flags == SDMMC_HOST_FLAG_4BIT) ? "4BIT Mode" : "1BIT Mode");
|
||||
ESP_LOGI(TAG, "host speed: %"PRIu32" kHz", test_param_lists[i].max_freq_khz);
|
||||
|
||||
essl_handle_t handle = NULL;
|
||||
s_master_init(&test_param_lists[i], &handle);
|
||||
|
||||
// Two counters are used. The `esp_timer_get_time()` is for the typical time, and the
|
||||
// `ccomp_timer` is for performance test to reduce influence caused by cache miss.
|
||||
int64_t pre_us = esp_timer_get_time();
|
||||
TEST_ESP_OK(ccomp_timer_start());
|
||||
uint32_t expected_length = TEST_TRANS_NUMS * TEST_RX_BUFFER_SIZE;
|
||||
|
||||
void *tx_buf_ptr = NULL;
|
||||
for (int j = 0; j < TEST_TRANS_NUMS; j++) {
|
||||
ESP_LOGD(TAG, "j: %d", j);
|
||||
|
||||
test_get_buffer_from_pool(j, TEST_RX_BUFFER_SIZE, &tx_buf_ptr);
|
||||
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));
|
||||
}
|
||||
|
||||
int64_t c_time_ms = ccomp_timer_stop() / 1000;
|
||||
int64_t end_us = esp_timer_get_time();
|
||||
|
||||
uint32_t total_time_ms = (end_us - pre_us) / 1000;
|
||||
ESP_LOGI(TAG, "test done, total time: %" PRIu32 " ms (%d ms compensated), bytes transferred: %"PRIu32, total_time_ms, (int)c_time_ms, expected_length);
|
||||
|
||||
uint32_t throughput_byte_per_ms = expected_length / c_time_ms;
|
||||
ESP_LOGI(TAG, "Throughput: compensated %"PRIu32"KB/s (%.2lf MB/s), typical %.2lf MB/s",
|
||||
throughput_byte_per_ms, throughput_byte_per_ms / 1000., expected_length / (total_time_ms * 1000.));
|
||||
|
||||
esp_rom_delay_us(50 * 1000);
|
||||
s_send_finish_test(handle);
|
||||
sdmmc_host_deinit();
|
||||
}
|
||||
|
||||
test_destroy_buffer_pool();
|
||||
}
|
||||
|
||||
TEST_CASE("SDIO_SDMMC: test from host", "[sdio]")
|
||||
{
|
||||
test_from_host(true);
|
||||
}
|
||||
|
||||
TEST_CASE("SDIO_SDMMC: test from host (Performance)", "[sdio_speed]")
|
||||
{
|
||||
test_from_host(false);
|
||||
}
|
||||
|
||||
|
||||
static void test_to_host(bool check_data)
|
||||
{
|
||||
//prepare buffer
|
||||
test_prepare_buffer_pool(TEST_RX_BUFFER_SIZE * 21, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
int recv_size = 4096;
|
||||
uint8_t *host_rx_buffer = (uint8_t *)heap_caps_calloc(1, recv_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
|
||||
for (int i = 0; i < TEST_TARNS_PARAM_NUMS; i++) {
|
||||
ESP_LOGI(TAG, "host mode: %s", (test_param_lists[i].host_flags == SDMMC_HOST_FLAG_4BIT) ? "4BIT Mode" : "1BIT Mode");
|
||||
ESP_LOGI(TAG, "host speed: %"PRIu32" kHz", test_param_lists[i].max_freq_khz);
|
||||
|
||||
essl_handle_t handle = NULL;
|
||||
s_master_init(&test_param_lists[i], &handle);
|
||||
|
||||
esp_err_t ret;
|
||||
int offset = 0;
|
||||
void *tx_buf_ptr = NULL;
|
||||
uint32_t expected_length = TEST_TRANS_NUMS * TEST_RX_BUFFER_SIZE;
|
||||
int remain_length = expected_length;
|
||||
|
||||
// Two counters are used. The `esp_timer_get_time()` is for the typical time, and the
|
||||
// `ccomp_timer` is for performance test to reduce influence caused by cache miss.
|
||||
int64_t pre_us = esp_timer_get_time();
|
||||
TEST_ESP_OK(ccomp_timer_start());
|
||||
do {
|
||||
size_t rcv_len;
|
||||
ret = essl_get_packet(handle, host_rx_buffer, recv_size, &rcv_len, TEST_TIMEOUT_MAX);
|
||||
TEST_ASSERT(ret == ESP_OK || ret == ESP_ERR_NOT_FINISHED);
|
||||
TEST_ASSERT_LESS_OR_EQUAL(remain_length, rcv_len);
|
||||
|
||||
if (check_data) {
|
||||
size_t compared_len = 0;
|
||||
do {
|
||||
test_get_buffer_from_pool(offset, TEST_RX_BUFFER_SIZE, &tx_buf_ptr);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(tx_buf_ptr, &host_rx_buffer[compared_len], TEST_RX_BUFFER_SIZE);
|
||||
compared_len += TEST_RX_BUFFER_SIZE;
|
||||
offset += TEST_RX_BUFFER_SIZE;
|
||||
} while (compared_len < rcv_len);
|
||||
}
|
||||
|
||||
remain_length -= rcv_len;
|
||||
} while (remain_length > 0);
|
||||
|
||||
int64_t c_time_ms = ccomp_timer_stop()/1000;
|
||||
int64_t end_us = esp_timer_get_time();
|
||||
|
||||
uint32_t total_time_ms = (end_us - pre_us)/1000;
|
||||
ESP_LOGI(TAG, "test done, total time: %" PRIu32 " ms (%d ms compensated), bytes transferred: %"PRIu32, total_time_ms, (int)c_time_ms, expected_length);
|
||||
|
||||
uint32_t throughput_byte_per_ms = expected_length / c_time_ms;
|
||||
ESP_LOGI(TAG, "Throughput: compensated %"PRIu32"KB/s %.2lf MB/s, typical %.2lf MB/s",
|
||||
throughput_byte_per_ms, throughput_byte_per_ms/1000., expected_length/(total_time_ms*1000.));
|
||||
|
||||
esp_rom_delay_us(50 * 1000);
|
||||
s_send_finish_test(handle);
|
||||
sdmmc_host_deinit();
|
||||
}
|
||||
|
||||
free(host_rx_buffer);
|
||||
test_destroy_buffer_pool();
|
||||
}
|
||||
|
||||
TEST_CASE("SDIO_SDMMC: test to host", "[sdio]")
|
||||
{
|
||||
test_to_host(true);
|
||||
}
|
||||
|
||||
TEST_CASE("SDIO_SDMMC: test to host (Performance)", "[sdio_speed]")
|
||||
{
|
||||
test_to_host(false);
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
# don't delete.
|
||||
# used for CI to compile a default config when 'sdkconfig.ci.xxxx' is exist
|
@ -0,0 +1,133 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import os.path
|
||||
from typing import Tuple
|
||||
|
||||
import pytest
|
||||
from pytest_embedded_idf import IdfDut
|
||||
|
||||
|
||||
# Normal tests
|
||||
def test_sdio_flow(dut:Tuple[IdfDut, IdfDut]) -> None:
|
||||
dut[1].expect('Press ENTER to see the list of tests')
|
||||
dut[1].write('[sdio]')
|
||||
dut[1].expect('test_sdio: slave ready')
|
||||
|
||||
dut[0].expect('Press ENTER to see the list of tests')
|
||||
dut[0].write('[sdio]')
|
||||
|
||||
dut[1].expect_unity_test_output()
|
||||
dut[0].expect_unity_test_output()
|
||||
|
||||
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.sdio_multidev_32_c6
|
||||
@pytest.mark.parametrize('count', [2,], indirect=True)
|
||||
@pytest.mark.parametrize('app_path, target', [
|
||||
pytest.param(
|
||||
f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}',
|
||||
'esp32|esp32c6'),
|
||||
], indirect=True)
|
||||
def test_sdio_esp32_esp32c6(dut:Tuple[IdfDut, IdfDut]) -> None:
|
||||
test_sdio_flow(dut)
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.sdio_master_slave
|
||||
@pytest.mark.parametrize('count', [2,], indirect=True)
|
||||
@pytest.mark.parametrize('app_path, target', [
|
||||
pytest.param(
|
||||
f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}',
|
||||
'esp32|esp32'),
|
||||
], indirect=True)
|
||||
def test_sdio_esp32_esp32(dut:Tuple[IdfDut, IdfDut]) -> None:
|
||||
test_sdio_flow(dut)
|
||||
|
||||
|
||||
# From host speed tests
|
||||
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].write('"SDIO_Slave: test from host (Performance)"')
|
||||
dut[1].expect('test_sdio: slave ready')
|
||||
|
||||
dut[0].expect('Press ENTER to see the list of tests')
|
||||
dut[0].write('"SDIO_SDMMC: test from host (Performance)"')
|
||||
|
||||
dut[0].expect('Probe using SD 4-bit')
|
||||
res = dut[0].expect(r'Throughput: compensated (\d+)')
|
||||
frhost_speed_4bit = res.group(1).decode('utf8')
|
||||
assert (int(frhost_speed_4bit) > expected_4b_speed)
|
||||
|
||||
dut[0].expect('Probe using SD 1-bit')
|
||||
res = dut[0].expect(r'Throughput: compensated (\d+)')
|
||||
frhost_speed_1bit = res.group(1).decode('utf8')
|
||||
assert (int(frhost_speed_1bit) > expected_1b_speed)
|
||||
|
||||
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.sdio_multidev_32_c6
|
||||
@pytest.mark.parametrize('count', [2,], indirect=True)
|
||||
@pytest.mark.parametrize('app_path, target', [
|
||||
pytest.param(
|
||||
f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}',
|
||||
'esp32|esp32c6'),
|
||||
], indirect=True)
|
||||
def test_sdio_speed_frhost_esp32_esp32c6(dut:Tuple[IdfDut, IdfDut]) -> None:
|
||||
test_sdio_speed_frhost_flow(dut, 10000, 4000)
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.sdio_master_slave
|
||||
@pytest.mark.parametrize('count', [2,], indirect=True)
|
||||
@pytest.mark.parametrize('app_path, target', [
|
||||
pytest.param(
|
||||
f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}',
|
||||
'esp32|esp32'),
|
||||
], indirect=True)
|
||||
def test_sdio_speed_frhost_esp32_esp32(dut:Tuple[IdfDut, IdfDut]) -> None:
|
||||
test_sdio_speed_frhost_flow(dut, 12200, 4000)
|
||||
|
||||
|
||||
# To host speed tests
|
||||
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].write('"SDIO_Slave: test to host (Performance)"')
|
||||
dut[1].expect('test_sdio: slave ready')
|
||||
|
||||
dut[0].expect('Press ENTER to see the list of tests')
|
||||
dut[0].write('"SDIO_SDMMC: test to host (Performance)"')
|
||||
|
||||
dut[0].expect('Probe using SD 4-bit')
|
||||
res = dut[0].expect(r'Throughput: compensated (\d+)')
|
||||
tohost_speed_4bit = res.group(1).decode('utf8')
|
||||
assert (int(tohost_speed_4bit) > expected_4b_speed)
|
||||
|
||||
dut[0].expect('Probe using SD 1-bit')
|
||||
res = dut[0].expect(r'Throughput: compensated (\d+)')
|
||||
tohost_speed_1bit = res.group(1).decode('utf8')
|
||||
assert (int(tohost_speed_1bit) > expected_1b_speed)
|
||||
|
||||
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.sdio_multidev_32_c6
|
||||
@pytest.mark.parametrize('count', [2,], indirect=True)
|
||||
@pytest.mark.parametrize('app_path, target', [
|
||||
pytest.param(
|
||||
f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}',
|
||||
'esp32|esp32c6'),
|
||||
], indirect=True)
|
||||
def test_sdio_speed_tohost_esp32_esp32c6(dut:Tuple[IdfDut, IdfDut]) -> None:
|
||||
test_sdio_speed_tohost_flow(dut, 9000, 4000)
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.sdio_master_slave
|
||||
@pytest.mark.parametrize('count', [2,], indirect=True)
|
||||
@pytest.mark.parametrize('app_path, target', [
|
||||
pytest.param(
|
||||
f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}',
|
||||
'esp32|esp32'),
|
||||
], indirect=True)
|
||||
def test_sdio_speed_tohost_esp32_esp32(dut:Tuple[IdfDut, IdfDut]) -> None:
|
||||
test_sdio_speed_tohost_flow(dut, 12200, 4000)
|
@ -10,4 +10,4 @@ set(EXTRA_COMPONENT_DIRS
|
||||
)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(sdio_test)
|
||||
project(sdio)
|
@ -0,0 +1,6 @@
|
||||
| Supported Targets | ESP32 | ESP32-C6 |
|
||||
| ----------------- | ----- | -------- |
|
||||
|
||||
# SDIO Cross Chips Test Apps: SDIO Slave App
|
||||
|
||||
This test app is to test ESP SDIO Slave peripheral.
|
@ -0,0 +1,6 @@
|
||||
set(srcs "test_app_main.c"
|
||||
"test_sdio_slave.c")
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
PRIV_REQUIRES test_driver_utils driver
|
||||
WHOLE_ARCHIVE)
|
@ -1,19 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_utils.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (200)
|
||||
// Some resources are lazy allocated, the threadhold is left for that case
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (300)
|
||||
|
||||
static size_t before_free_8bit;
|
||||
static size_t before_free_32bit;
|
||||
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
@ -22,27 +23,28 @@ void setUp(void)
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
|
||||
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
printf("\n");
|
||||
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
|
||||
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// _____ _ _ _
|
||||
// |_ _|__ ___| |_ ___ __| (_) ___
|
||||
// | |/ _ \/ __| __| / __|/ _` | |/ _ `.
|
||||
// | | __/\__ \ |_ \__ \ (_| | | (_) |
|
||||
// |_|\___||___/\__| |___/\__,_|_|\___/
|
||||
/*
|
||||
_____ ____ ________ _____ __
|
||||
/ ___// __ \/ _/ __ \ / ___// /___ __ _____
|
||||
\__ \/ / / // // / / / \__ \/ / __ `/ | / / _ \
|
||||
___/ / /_/ // // /_/ / ___/ / / /_/ /| |/ / __/
|
||||
/____/_____/___/\____/ /____/_/\__,_/ |___/\___/
|
||||
|
||||
printf(" _____ _ _ _ \n");
|
||||
printf(" |_ _|__ ___| |_ ___ __| (_) ___ \n");
|
||||
printf(" | |/ _ \\/ __| __| / __|/ _` | |/ _ \\ \n");
|
||||
printf(" | | __/\\__ \\ |_ \\__ \\ (_| | | (_) |\n");
|
||||
printf(" |_|\\___||___/\\__| |___/\\__,_|_|\\___/ \n");
|
||||
*/
|
||||
|
||||
printf(" _____ ____ ________ _____ __ \n");
|
||||
printf(" / ___// __ \\/ _/ __ \\ / ___// /___ __ _____ \n");
|
||||
printf(" \\__ \\/ / / // // / / / \\__ \\/ / __ `/ | / / _ \\\n");
|
||||
printf(" ___/ / /_/ // // /_/ / ___/ / / /_/ /| |/ / __/\n");
|
||||
printf("/____/_____/___/\\____/ /____/_/\\__,_/ |___/\\___/\n");
|
||||
|
||||
unity_run_menu();
|
||||
}
|
@ -0,0 +1,303 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file uses ESP32 SDMMC peripheral to test SDIO Slave peripheral SD modes
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "driver/sdio_slave.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/sdio_slave_pins.h"
|
||||
|
||||
#include "test_dualboard_utils.h"
|
||||
#include "../../sdio_common_test.h"
|
||||
|
||||
#define TEST_HEX_LOG_LEVEL ESP_LOG_DEBUG
|
||||
#define TEST_SDIO_SLAVE_QUEUE_SIZE 20
|
||||
|
||||
static const char *TAG = "test_sdio";
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Slave Init Settings
|
||||
---------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
int queued_cnt;
|
||||
bool s_finished;
|
||||
} s_test_slv_ctx_t;
|
||||
|
||||
static s_test_slv_ctx_t s_test_slv_ctx;
|
||||
|
||||
//callback to event 7, indicating test finish in these tests
|
||||
static void s_event_cb(uint8_t event)
|
||||
{
|
||||
ESP_EARLY_LOGI(TAG, "event: %d", event);
|
||||
sdio_slave_send_host_int(event);
|
||||
if (event == 7) {
|
||||
s_test_slv_ctx.s_finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void wait_for_finish(s_test_slv_ctx_t *ctx)
|
||||
{
|
||||
while (!ctx->s_finished) {
|
||||
vTaskDelay(10);
|
||||
}
|
||||
//wait for host to read the respond from slave
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
static void s_slave_init(sdio_slave_sending_mode_t mode)
|
||||
{
|
||||
s_test_slv_ctx.s_finished = false;
|
||||
s_test_slv_ctx.queued_cnt = 0;
|
||||
|
||||
sdio_slave_config_t slave_config = {
|
||||
.sending_mode = mode,
|
||||
.send_queue_size = TEST_SDIO_SLAVE_QUEUE_SIZE,
|
||||
.recv_buffer_size = TEST_RX_BUFFER_SIZE,
|
||||
.event_cb = s_event_cb,
|
||||
};
|
||||
TEST_ESP_OK(sdio_slave_initialize(&slave_config));
|
||||
}
|
||||
|
||||
|
||||
#include "esp_rom_sys.h"
|
||||
/*---------------------------------------------------------------
|
||||
Function Tests
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
SDMMC_SDIO: test interrupt
|
||||
---------------------------------------------------------------*/
|
||||
TEST_CASE("SDIO_Slave: test interrupt", "[sdio]")
|
||||
{
|
||||
s_slave_init(SDIO_SLAVE_SEND_STREAM);
|
||||
TEST_ESP_OK(sdio_slave_start());
|
||||
ESP_LOGI(TAG, "slave ready");
|
||||
|
||||
wait_for_finish(&s_test_slv_ctx);
|
||||
|
||||
sdio_slave_stop();
|
||||
sdio_slave_deinit();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
SDMMC_SDIO: test register
|
||||
---------------------------------------------------------------*/
|
||||
TEST_CASE("SDIO_Slave: test register", "[sdio]")
|
||||
{
|
||||
s_slave_init(SDIO_SLAVE_SEND_STREAM);
|
||||
TEST_ESP_OK(sdio_slave_start());
|
||||
ESP_LOGI(TAG, "slave ready");
|
||||
|
||||
wait_for_finish(&s_test_slv_ctx);
|
||||
|
||||
sdio_slave_stop();
|
||||
sdio_slave_deinit();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
SDMMC_SDIO: test reset
|
||||
---------------------------------------------------------------*/
|
||||
TEST_CASE("SDIO_Slave: test reset", "[sdio]")
|
||||
{
|
||||
s_slave_init(SDIO_SLAVE_SEND_PACKET);
|
||||
TEST_ESP_OK(sdio_slave_start());
|
||||
ESP_LOGI(TAG, "slave ready");
|
||||
|
||||
sdio_slave_stop();
|
||||
TEST_ESP_OK(sdio_slave_reset());
|
||||
TEST_ESP_OK(sdio_slave_start());
|
||||
|
||||
//tx
|
||||
WORD_ALIGNED_ATTR uint8_t slave_tx_buffer[TEST_RESET_BUF_NUMS][TEST_RESET_DATA_LEN] = {};
|
||||
for (int i = 0; i < TEST_RESET_BUF_NUMS; i++) {
|
||||
test_fill_random_to_buffer(i, slave_tx_buffer[i], TEST_RESET_DATA_LEN);
|
||||
TEST_ESP_OK(sdio_slave_send_queue(slave_tx_buffer[i], TEST_RESET_DATA_LEN, (void *)i, portMAX_DELAY));
|
||||
}
|
||||
|
||||
//rx
|
||||
sdio_slave_buf_handle_t buf_handle[TEST_RESET_BUF_NUMS] = {};
|
||||
WORD_ALIGNED_ATTR uint8_t slave_rx_buffer[TEST_RESET_BUF_NUMS][TEST_RESET_DATA_LEN] = {};
|
||||
|
||||
for (int i = 0; i < TEST_RESET_BUF_NUMS; i++) {
|
||||
buf_handle[i] = sdio_slave_recv_register_buf(slave_rx_buffer[i]);
|
||||
TEST_ASSERT(buf_handle[i]);
|
||||
TEST_ESP_OK(sdio_slave_recv_load_buf(buf_handle[i]));
|
||||
}
|
||||
|
||||
for (int i = 0; i < TEST_RESET_BUF_NUMS; i++) {
|
||||
void* arg;
|
||||
TEST_ESP_OK(sdio_slave_send_get_finished(&arg, portMAX_DELAY));
|
||||
TEST_ASSERT_EQUAL(i, arg);
|
||||
}
|
||||
|
||||
|
||||
WORD_ALIGNED_ATTR uint8_t host_tx_buffer[TEST_RESET_DATA_LEN] = {};
|
||||
for (int i = 0; i < TEST_RESET_BUF_NUMS; i++) {
|
||||
test_fill_random_to_buffer(i, host_tx_buffer, TEST_RESET_DATA_LEN);
|
||||
uint8_t* addr;
|
||||
size_t size;
|
||||
sdio_slave_buf_handle_t recv_handle;
|
||||
TEST_ESP_OK(sdio_slave_recv(&recv_handle, &addr, &size, portMAX_DELAY));
|
||||
TEST_ASSERT_EQUAL(TEST_RESET_DATA_LEN, size);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(host_tx_buffer, addr, size);
|
||||
}
|
||||
|
||||
wait_for_finish(&s_test_slv_ctx);
|
||||
|
||||
sdio_slave_stop();
|
||||
sdio_slave_deinit();
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Transaction Tests
|
||||
---------------------------------------------------------------*/
|
||||
#define TEST_SLAVE_TRANS_BUF_NUMS 10
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
From Host Tests
|
||||
---------------------------------------------------------------*/
|
||||
static void test_from_host(bool check_data)
|
||||
{
|
||||
//prepare buffer
|
||||
test_prepare_buffer_pool(TEST_RX_BUFFER_SIZE * 4, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
uint8_t *slave_rx_buffer[TEST_SLAVE_TRANS_BUF_NUMS] = {};
|
||||
for (int i = 0; i < TEST_SLAVE_TRANS_BUF_NUMS; i++) {
|
||||
slave_rx_buffer[i] = (uint8_t *)heap_caps_calloc(1, TEST_RX_BUFFER_SIZE, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
TEST_ASSERT(slave_rx_buffer[i]);
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < TEST_TARNS_PARAM_NUMS; i++) {
|
||||
//slave init
|
||||
s_slave_init(SDIO_SLAVE_SEND_STREAM);
|
||||
TEST_ESP_OK(sdio_slave_start());
|
||||
ESP_LOGI(TAG, "slave ready");
|
||||
|
||||
//slave load rx buffer
|
||||
sdio_slave_buf_handle_t buf_handle[TEST_SLAVE_TRANS_BUF_NUMS] = {};
|
||||
for (int j = 0; j < TEST_SLAVE_TRANS_BUF_NUMS; j++) {
|
||||
buf_handle[j] = sdio_slave_recv_register_buf(slave_rx_buffer[j]);
|
||||
TEST_ASSERT(buf_handle[j]);
|
||||
TEST_ESP_OK(sdio_slave_recv_load_buf(buf_handle[j]));
|
||||
}
|
||||
|
||||
void *tx_buf_ptr = NULL;
|
||||
for (int j = 0; j < TEST_TRANS_NUMS; j++) {
|
||||
ESP_LOGD(TAG, "j: %d", j);
|
||||
|
||||
sdio_slave_buf_handle_t used_buf_handle = NULL;
|
||||
uint8_t* buf = NULL;
|
||||
size_t rcv_len = 0;
|
||||
|
||||
TEST_ESP_OK(sdio_slave_recv(&used_buf_handle, &buf, &rcv_len, portMAX_DELAY));
|
||||
ESP_LOGD(TAG, "rcv_len: 0d%d", rcv_len);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(TAG, buf, TEST_RX_BUFFER_SIZE, TEST_HEX_LOG_LEVEL);
|
||||
|
||||
if (check_data) {
|
||||
test_get_buffer_from_pool(j, TEST_RX_BUFFER_SIZE, &tx_buf_ptr);
|
||||
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_ESP_OK(sdio_slave_recv_load_buf(used_buf_handle));
|
||||
}
|
||||
|
||||
|
||||
wait_for_finish(&s_test_slv_ctx);
|
||||
sdio_slave_stop();
|
||||
sdio_slave_deinit();
|
||||
}
|
||||
|
||||
for (int i = 0; i < TEST_SLAVE_TRANS_BUF_NUMS; i++) {
|
||||
free(slave_rx_buffer[i]);
|
||||
}
|
||||
test_destroy_buffer_pool();
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("SDIO_Slave: test from host", "[sdio]")
|
||||
{
|
||||
test_from_host(true);
|
||||
}
|
||||
|
||||
TEST_CASE("SDIO_Slave: test from host (Performance)", "[sdio_speed]")
|
||||
{
|
||||
test_from_host(false);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
To Host Tests
|
||||
---------------------------------------------------------------*/
|
||||
#define QUEUE_FULL() (s_test_slv_ctx.queued_cnt == TEST_SDIO_SLAVE_QUEUE_SIZE)
|
||||
#define QUEUE_EMPTY() (s_test_slv_ctx.queued_cnt == 0)
|
||||
|
||||
static void test_to_host(void)
|
||||
{
|
||||
//prepare buffer
|
||||
test_prepare_buffer_pool(TEST_RX_BUFFER_SIZE * 21, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
|
||||
for (int i = 0; i < TEST_TARNS_PARAM_NUMS; i++) {
|
||||
//slave init
|
||||
s_slave_init(SDIO_SLAVE_SEND_STREAM);
|
||||
TEST_ESP_OK(sdio_slave_start());
|
||||
ESP_LOGI(TAG, "slave ready");
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
int offset = 0;
|
||||
void *tx_buf_ptr = NULL;
|
||||
for (int j = 0; j < TEST_TRANS_NUMS; j++) {
|
||||
do {
|
||||
void* arg;
|
||||
//when the queue is full, do a blocking wait for 10ms, otherwise non-blocking
|
||||
err = sdio_slave_send_get_finished(&arg, QUEUE_FULL()? 1: 0);
|
||||
if (err == ESP_OK) {
|
||||
s_test_slv_ctx.queued_cnt --;
|
||||
continue;
|
||||
}
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, err);
|
||||
} while (QUEUE_FULL());
|
||||
|
||||
test_get_buffer_from_pool(offset, TEST_RX_BUFFER_SIZE, &tx_buf_ptr);
|
||||
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++;
|
||||
offset += TEST_RX_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
while (!QUEUE_EMPTY()) {
|
||||
void* arg;
|
||||
TEST_ESP_OK(sdio_slave_send_get_finished(&arg, portMAX_DELAY));
|
||||
s_test_slv_ctx.queued_cnt--;
|
||||
}
|
||||
|
||||
|
||||
wait_for_finish(&s_test_slv_ctx);
|
||||
sdio_slave_stop();
|
||||
sdio_slave_deinit();
|
||||
}
|
||||
|
||||
test_destroy_buffer_pool();
|
||||
}
|
||||
|
||||
TEST_CASE("SDIO_Slave: test to host", "[sdio]")
|
||||
{
|
||||
test_to_host();
|
||||
}
|
||||
|
||||
TEST_CASE("SDIO_Slave: test to host (Performance)", "[sdio_speed]")
|
||||
{
|
||||
test_to_host();
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
# don't delete.
|
||||
# used for CI to compile a default config when 'sdkconfig.ci.xxxx' is exist
|
@ -0,0 +1,2 @@
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_ESP_TASK_WDT=n
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define TEST_RX_BUFFER_SIZE 2048
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Function Tests
|
||||
---------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------
|
||||
SDMMC_SDIO: test reset
|
||||
---------------------------------------------------------------*/
|
||||
#define TEST_RESET_DATA_LEN 12
|
||||
#define TEST_RESET_BUF_NUMS 10
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Transaction Tests
|
||||
---------------------------------------------------------------*/
|
||||
#define TEST_TARNS_PARAM_NUMS 2
|
||||
/*---------------------------------------------------------------
|
||||
SDMMC_SDIO: test from host
|
||||
---------------------------------------------------------------*/
|
||||
#define TEST_TRANS_NUMS 10000
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1217,12 +1217,12 @@ static void fd_master(void)
|
||||
//Master FD DMA, RX without TX Test
|
||||
for (int i = 0; i < TEST_NUM; i++) {
|
||||
// 1. Master FD DMA, only receive, with NULL tx_buffer
|
||||
get_tx_buffer(FD_SEED1 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(FD_SEED1 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
memset(mst_recv_buf, 0x0, FD_TEST_BUF_SIZE);
|
||||
master_only_rx_trans(spi, mst_recv_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
|
||||
//2. Master FD DMA with TX and RX
|
||||
get_tx_buffer(FD_SEED2 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(FD_SEED2 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
memset(mst_recv_buf, 0x0, FD_TEST_BUF_SIZE);
|
||||
master_both_trans(spi, mst_send_buf, mst_recv_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
}
|
||||
@ -1230,11 +1230,11 @@ static void fd_master(void)
|
||||
//Master FD DMA, TX without RX Test
|
||||
for (int i = 0; i < TEST_NUM; i++) {
|
||||
// 1. Master FD DMA, only send, with NULL rx_buffer
|
||||
get_tx_buffer(FD_SEED3 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(FD_SEED3 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
master_only_tx_trans(spi, mst_send_buf, FD_TEST_BUF_SIZE);
|
||||
|
||||
//2. Master FD DMA with TX and RX
|
||||
get_tx_buffer(FD_SEED4 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(FD_SEED4 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
memset(mst_recv_buf, 0x0, FD_TEST_BUF_SIZE);
|
||||
master_both_trans(spi, mst_send_buf, mst_recv_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
}
|
||||
@ -1299,23 +1299,23 @@ static void fd_slave(void)
|
||||
|
||||
for (int i = 0; i < TEST_NUM; i++) {
|
||||
//1. Slave TX without RX (rx_buffer == NULL)
|
||||
get_tx_buffer(FD_SEED1 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(FD_SEED1 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
slave_only_tx_trans(slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
|
||||
//2. Slave both TX and RX
|
||||
get_tx_buffer(FD_SEED2 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(FD_SEED2 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
memset(slv_recv_buf, 0x0, FD_TEST_BUF_SIZE);
|
||||
slave_both_trans(slv_send_buf, slv_recv_buf, mst_send_buf, FD_TEST_BUF_SIZE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < TEST_NUM; i++) {
|
||||
// 1. Slave RX without TX (tx_buffer == NULL)
|
||||
get_tx_buffer(FD_SEED3 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(FD_SEED3 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
memset(slv_recv_buf, 0x0, FD_TEST_BUF_SIZE);
|
||||
slave_only_rx_trans(slv_recv_buf, mst_send_buf, FD_TEST_BUF_SIZE);
|
||||
|
||||
//2. Slave both TX and RX
|
||||
get_tx_buffer(FD_SEED4 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(FD_SEED4 + i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
|
||||
memset(slv_recv_buf, 0x0, FD_TEST_BUF_SIZE);
|
||||
slave_both_trans(slv_send_buf, slv_recv_buf, mst_send_buf, FD_TEST_BUF_SIZE);
|
||||
}
|
||||
@ -1530,7 +1530,7 @@ void test_add_device_master(void)
|
||||
TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &devs[i]));
|
||||
|
||||
memset(master_recvbuf, 0, sizeof(master_recvbuf));
|
||||
get_tx_buffer(21, master_sendbuf, master_expect, TEST_TRANS_LEN);
|
||||
test_fill_random_to_buffers_dualboard(21, master_sendbuf, master_expect, TEST_TRANS_LEN);
|
||||
|
||||
unity_send_signal("Master ready");
|
||||
unity_wait_for_signal("Slave ready");
|
||||
@ -1573,7 +1573,7 @@ void test_add_device_slave(void)
|
||||
|
||||
for (uint8_t i = 0; i < SOC_SPI_MAX_CS_NUM; i++) {
|
||||
memset(slave_recvbuf, 0, sizeof(slave_recvbuf));
|
||||
get_tx_buffer(21, slave_expect, slave_sendbuf, TEST_TRANS_LEN);
|
||||
test_fill_random_to_buffers_dualboard(21, slave_expect, slave_sendbuf, TEST_TRANS_LEN);
|
||||
|
||||
unity_wait_for_signal("Master ready");
|
||||
unity_send_signal("Slave ready");
|
||||
@ -1671,7 +1671,7 @@ static IRAM_ATTR void test_master_iram(void)
|
||||
uint8_t *master_send = heap_caps_malloc(TEST_MASTER_IRAM_TRANS_LEN, MALLOC_CAP_DMA);
|
||||
uint8_t *master_recv = heap_caps_calloc(1, TEST_MASTER_IRAM_TRANS_LEN, MALLOC_CAP_DMA);
|
||||
uint8_t *master_exp = heap_caps_malloc(TEST_MASTER_IRAM_TRANS_LEN, MALLOC_CAP_DEFAULT);
|
||||
get_tx_buffer(211, master_send, master_exp, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
test_fill_random_to_buffers_dualboard(211, master_send, master_exp, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
spi_transaction_t trans_cfg = {
|
||||
.tx_buffer = master_send,
|
||||
.rx_buffer = master_recv,
|
||||
@ -1698,7 +1698,7 @@ static IRAM_ATTR void test_master_iram(void)
|
||||
|
||||
// Test polling trans api once -------------------------------
|
||||
unity_wait_for_signal("Slave ready");
|
||||
get_tx_buffer(119, master_send, master_exp, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
test_fill_random_to_buffers_dualboard(119, master_send, master_exp, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
spi_device_polling_transmit(dev_handle, &trans_cfg);
|
||||
@ -1729,7 +1729,7 @@ static void test_iram_slave_normal(void)
|
||||
slave_trans.length = TEST_MASTER_IRAM_TRANS_LEN * 8;
|
||||
slave_trans.tx_buffer = slave_sendbuf;
|
||||
slave_trans.rx_buffer = slave_recvbuf;
|
||||
get_tx_buffer(211, slave_expect, slave_sendbuf, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
test_fill_random_to_buffers_dualboard(211, slave_expect, slave_sendbuf, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
|
||||
unity_wait_for_signal("Master ready");
|
||||
unity_send_signal("Slave ready");
|
||||
@ -1739,7 +1739,7 @@ static void test_iram_slave_normal(void)
|
||||
spitest_cmp_or_dump(slave_expect, slave_recvbuf, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
|
||||
unity_send_signal("Slave ready");
|
||||
get_tx_buffer(119, slave_expect, slave_sendbuf, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
test_fill_random_to_buffers_dualboard(119, slave_expect, slave_sendbuf, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
spi_slave_transmit(TEST_SPI_HOST, &slave_trans, portMAX_DELAY);
|
||||
ESP_LOG_BUFFER_HEX("slave tx", slave_sendbuf, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
ESP_LOG_BUFFER_HEX("slave rx", slave_recvbuf, TEST_MASTER_IRAM_TRANS_LEN);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -1314,7 +1314,7 @@ static void test_master_fd_dma(void)
|
||||
unity_send_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(master_recive, 0x00, TEST_STEP_LEN);
|
||||
get_tx_buffer(119 + mode + speed_level + i, master_send, master_expect, TEST_STEP_LEN);
|
||||
test_fill_random_to_buffers_dualboard(119 + mode + speed_level + i, master_send, master_expect, TEST_STEP_LEN);
|
||||
|
||||
uint32_t test_trans_len = TEST_STEP_LEN;
|
||||
spi_transaction_t trans_cfg = {
|
||||
@ -1365,7 +1365,7 @@ static void test_slave_fd_dma(void)
|
||||
unity_wait_for_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(slave_recive, 0x00, TEST_STEP_LEN);
|
||||
get_tx_buffer(119 + mode + speed_level + i, slave_expect, slave_send, TEST_STEP_LEN);
|
||||
test_fill_random_to_buffers_dualboard(119 + mode + speed_level + i, slave_expect, slave_send, TEST_STEP_LEN);
|
||||
|
||||
uint32_t test_trans_len = TEST_STEP_LEN;
|
||||
spi_slave_transaction_t trans_cfg = {
|
||||
@ -1429,7 +1429,7 @@ static void test_master_fd_no_dma(void)
|
||||
unity_send_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(master_recive, 0x00, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
get_tx_buffer(211 + mode + speed_level + i, master_send, master_expect, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(211 + mode + speed_level + i, master_send, master_expect, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
|
||||
uint32_t test_trans_len = SOC_SPI_MAXIMUM_BUFFER_SIZE;
|
||||
spi_transaction_t trans_cfg = {
|
||||
@ -1481,7 +1481,7 @@ static void test_slave_fd_no_dma(void)
|
||||
unity_wait_for_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(slave_recive, 0x00, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
get_tx_buffer(211 + mode + speed_level + i, slave_expect, slave_send, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(211 + mode + speed_level + i, slave_expect, slave_send, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
|
||||
uint32_t test_trans_len = SOC_SPI_MAXIMUM_BUFFER_SIZE;
|
||||
spi_slave_transaction_t trans_cfg = {
|
||||
@ -1536,7 +1536,7 @@ static void test_master_hd_dma(void)
|
||||
unity_send_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(master_recive, 0x00, TEST_STEP_LEN);
|
||||
get_tx_buffer(985 + mode + speed_level + i, master_send, master_expect, TEST_STEP_LEN);
|
||||
test_fill_random_to_buffers_dualboard(985 + mode + speed_level + i, master_send, master_expect, TEST_STEP_LEN);
|
||||
|
||||
uint32_t test_trans_len = TEST_STEP_LEN;
|
||||
unity_wait_for_signal("Slave ready");
|
||||
@ -1580,7 +1580,7 @@ static void test_slave_hd_dma(void)
|
||||
unity_wait_for_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(slave_recive, 0x00, TEST_STEP_LEN);
|
||||
get_tx_buffer(985 + mode + speed_level + i, slave_expect, slave_send, TEST_STEP_LEN);
|
||||
test_fill_random_to_buffers_dualboard(985 + mode + speed_level + i, slave_expect, slave_send, TEST_STEP_LEN);
|
||||
uint32_t test_trans_len = TEST_STEP_LEN;
|
||||
|
||||
spi_slave_hd_data_t *ret_trans, slave_trans = {
|
||||
@ -1637,7 +1637,7 @@ static void test_master_hd_no_dma(void)
|
||||
unity_send_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(master_recive, 0x00, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
get_tx_buffer(911 + mode + speed_level + i, master_send, master_expect, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(911 + mode + speed_level + i, master_send, master_expect, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
|
||||
uint32_t test_trans_len = SOC_SPI_MAXIMUM_BUFFER_SIZE;
|
||||
unity_wait_for_signal("Slave ready");
|
||||
@ -1681,7 +1681,7 @@ static void test_slave_hd_no_dma(void)
|
||||
unity_wait_for_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(slave_recive, 0x00, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
get_tx_buffer(911 + mode + speed_level + i, slave_expect, slave_send, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(911 + mode + speed_level + i, slave_expect, slave_send, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
uint32_t test_trans_len = SOC_SPI_MAXIMUM_BUFFER_SIZE;
|
||||
|
||||
spi_slave_hd_data_t *ret_trans, slave_trans = {
|
||||
@ -1756,7 +1756,7 @@ static void test_master_sio_dma(void)
|
||||
unity_send_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(master_recive, 0x00, TEST_STEP_LEN);
|
||||
get_tx_buffer(110 + mode + speed_level + i, master_send, master_expect, TEST_STEP_LEN);
|
||||
test_fill_random_to_buffers_dualboard(110 + mode + speed_level + i, master_send, master_expect, TEST_STEP_LEN);
|
||||
spi_transaction_t trans = {};
|
||||
if (sio_master_in) {
|
||||
// master input only
|
||||
@ -1818,7 +1818,7 @@ static void test_slave_sio_dma(void)
|
||||
unity_wait_for_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(slave_recive, 0x00, TEST_STEP_LEN);
|
||||
get_tx_buffer(110 + mode + speed_level + i, slave_expect, slave_send, TEST_STEP_LEN);
|
||||
test_fill_random_to_buffers_dualboard(110 + mode + speed_level + i, slave_expect, slave_send, TEST_STEP_LEN);
|
||||
spi_slave_transaction_t trans = {
|
||||
.length = TEST_STEP_LEN * 8,
|
||||
.tx_buffer = slave_send,
|
||||
@ -1888,7 +1888,7 @@ static void test_master_sio_no_dma(void)
|
||||
unity_send_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(master_recive, 0x00, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
get_tx_buffer(122 + mode + speed_level + i, master_send, master_expect, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(122 + mode + speed_level + i, master_send, master_expect, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
spi_transaction_t trans = {};
|
||||
if (sio_master_in) {
|
||||
// master input only
|
||||
@ -1951,7 +1951,7 @@ static void test_slave_sio_no_dma(void)
|
||||
unity_wait_for_signal("Master ready");
|
||||
for (int i = 0; i < TEST_STEP; i++) {
|
||||
memset(slave_recive, 0x00, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
get_tx_buffer(122 + mode + speed_level + i, slave_expect, slave_send, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(122 + mode + speed_level + i, slave_expect, slave_send, SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
spi_slave_transaction_t trans = {
|
||||
.length = SOC_SPI_MAXIMUM_BUFFER_SIZE * 8,
|
||||
.tx_buffer = slave_send,
|
||||
|
@ -409,7 +409,7 @@ static void test_slave_iram_master_normal(void)
|
||||
uint8_t *master_send = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DMA);
|
||||
uint8_t *master_recv = heap_caps_calloc(1, TEST_BUFFER_SZ, MALLOC_CAP_DMA);
|
||||
uint8_t *master_exp = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DEFAULT);
|
||||
get_tx_buffer(1001, master_send, master_exp, TEST_BUFFER_SZ);
|
||||
test_fill_random_to_buffers_dualboard(1001, master_send, master_exp, TEST_BUFFER_SZ);
|
||||
spi_transaction_t trans_cfg = {
|
||||
.tx_buffer = master_send,
|
||||
.rx_buffer = master_recv,
|
||||
@ -490,7 +490,7 @@ static IRAM_ATTR void test_slave_isr_iram(void)
|
||||
uint8_t *slave_iram_send = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
uint8_t *slave_iram_recv = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
uint8_t *slave_iram_exp = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
get_tx_buffer(1001, slave_iram_exp, slave_iram_send, TEST_BUFFER_SZ);
|
||||
test_fill_random_to_buffers_dualboard(1001, slave_iram_exp, slave_iram_send, TEST_BUFFER_SZ);
|
||||
spi_slave_transaction_t trans_cfg[TEST_IRAM_TRANS_NUM] = {0};
|
||||
|
||||
unity_wait_for_signal("Master ready");
|
||||
@ -570,7 +570,7 @@ static IRAM_ATTR void spi_slave_trans_in_isr(void)
|
||||
uint8_t *slave_isr_send = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
uint8_t *slave_isr_recv = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
uint8_t *slave_isr_exp = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
get_tx_buffer(1001, slave_isr_exp, slave_isr_send, TEST_BUFFER_SZ);
|
||||
test_fill_random_to_buffers_dualboard(1001, slave_isr_exp, slave_isr_send, TEST_BUFFER_SZ);
|
||||
spi_slave_transaction_t trans_cfg = {
|
||||
.tx_buffer = slave_isr_send,
|
||||
.rx_buffer = slave_isr_recv,
|
||||
@ -654,8 +654,8 @@ static IRAM_ATTR void spi_queue_reset_in_isr(void)
|
||||
uint8_t *slave_isr_recv = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
uint8_t *dummy_data = heap_caps_aligned_alloc(64, 64 * 2, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
uint8_t *slave_isr_exp = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
get_tx_buffer(1001, slave_isr_exp, slave_isr_send, TEST_BUFFER_SZ);
|
||||
get_tx_buffer(1001, dummy_data, dummy_data + 64, 64);
|
||||
test_fill_random_to_buffers_dualboard(1001, slave_isr_exp, slave_isr_send, TEST_BUFFER_SZ);
|
||||
test_fill_random_to_buffers_dualboard(1001, dummy_data, dummy_data + 64, 64);
|
||||
spi_slave_transaction_t trans_cfg = {
|
||||
.tx_buffer = slave_isr_send,
|
||||
.rx_buffer = slave_isr_recv,
|
||||
|
@ -49,7 +49,7 @@ static void test_master(void)
|
||||
mst_tx_buf[i] = heap_caps_calloc(TEST_BUF_SIZE, 1, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
mst_rx_buf[i] = heap_caps_calloc(TEST_BUF_SIZE, 1, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
slv_tx_buf[i] = heap_caps_calloc(TEST_BUF_SIZE, 1, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
get_tx_buffer(test_seed, mst_tx_buf[i], slv_tx_buf[i], TEST_BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(test_seed, mst_tx_buf[i], slv_tx_buf[i], TEST_BUF_SIZE);
|
||||
}
|
||||
|
||||
//Trans0
|
||||
@ -133,7 +133,7 @@ static void test_slave(void)
|
||||
slv_tx_buf[i] = heap_caps_calloc(TEST_BUF_SIZE, 1, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
slv_rx_buf[i] = heap_caps_calloc(TEST_BUF_SIZE, 1, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
mst_tx_buf[i] = heap_caps_calloc(TEST_BUF_SIZE, 1, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
get_tx_buffer(test_seed, mst_tx_buf[i], slv_tx_buf[i], TEST_BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(test_seed, mst_tx_buf[i], slv_tx_buf[i], TEST_BUF_SIZE);
|
||||
}
|
||||
|
||||
spi_slave_transaction_t trans[TEST_TIMES] = {};
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "test_spi_utils.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "esp_serial_slave_link/essl_spi.h"
|
||||
#include "test_dualboard_utils.h"
|
||||
|
||||
#if SOC_SPI_SUPPORT_SLAVE_HD_VER2
|
||||
#include "driver/spi_slave_hd.h"
|
||||
@ -649,7 +650,7 @@ static void hd_master(void)
|
||||
WORD_ALIGNED_ATTR uint8_t *master_recv_buf = calloc(1, send_buf_size * 2);
|
||||
//This buffer is used for 2-board test and should be assigned totally the same as the ``hd_slave`` does.
|
||||
WORD_ALIGNED_ATTR uint8_t *slave_send_buf = malloc(send_buf_size * 2);
|
||||
get_tx_buffer(199, master_send_buf, slave_send_buf, send_buf_size * 2);
|
||||
test_fill_random_to_buffers_dualboard(199, master_send_buf, slave_send_buf, send_buf_size * 2);
|
||||
|
||||
//This is the same as the ``hd_slave`` sets.
|
||||
int trans_len[] = {5, send_buf_size};
|
||||
@ -700,7 +701,7 @@ static void hd_slave(void)
|
||||
WORD_ALIGNED_ATTR uint8_t *slave_recv_buf = calloc(1, send_buf_size * 2);
|
||||
//This buffer is used for 2-board test and should be assigned totally the same as the ``hd_master`` does.
|
||||
WORD_ALIGNED_ATTR uint8_t *master_send_buf = malloc(send_buf_size * 2);
|
||||
get_tx_buffer(199, master_send_buf, slave_send_buf, send_buf_size * 2);
|
||||
test_fill_random_to_buffers_dualboard(199, master_send_buf, slave_send_buf, send_buf_size * 2);
|
||||
|
||||
//make the first transaction shorter than the actual trans length of the master, so that the second one will be loaded while the master is still doing the first transaction.
|
||||
int trans_len[] = {5, send_buf_size};
|
||||
@ -793,7 +794,7 @@ static void hd_master_quad(void)
|
||||
WORD_ALIGNED_ATTR uint8_t *master_recv_buf = heap_caps_calloc(BUF_SIZE, 1, MALLOC_CAP_DMA);
|
||||
//This buffer is used for 2-board test and should be assigned totally the same as the ``hd_slave`` does.
|
||||
WORD_ALIGNED_ATTR uint8_t *slave_send_buf = heap_caps_malloc(BUF_SIZE, MALLOC_CAP_DMA);
|
||||
get_tx_buffer(199, master_send_buf, slave_send_buf, BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(199, master_send_buf, slave_send_buf, BUF_SIZE);
|
||||
|
||||
unity_send_signal("Master ready");
|
||||
unity_wait_for_signal("slave ready");
|
||||
@ -848,7 +849,7 @@ static void hd_slave_quad(void)
|
||||
WORD_ALIGNED_ATTR uint8_t *slave_recv_buf = heap_caps_calloc(BUF_SIZE, 1, MALLOC_CAP_DMA);
|
||||
//This buffer is used for 2-board test and should be assigned totally the same as the ``hd_master`` does.
|
||||
WORD_ALIGNED_ATTR uint8_t *master_send_buf = heap_caps_malloc(BUF_SIZE, MALLOC_CAP_DMA);
|
||||
get_tx_buffer(199, master_send_buf, slave_send_buf, BUF_SIZE);
|
||||
test_fill_random_to_buffers_dualboard(199, master_send_buf, slave_send_buf, BUF_SIZE);
|
||||
|
||||
int trans_len = BUF_SIZE / 2;
|
||||
spi_slave_hd_data_t slave_trans[4] = {
|
||||
|
@ -45,3 +45,31 @@
|
||||
|
||||
#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER 3
|
||||
#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3 3
|
||||
|
||||
//SDIO
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_4BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_4BIT 12200
|
||||
#endif
|
||||
|
||||
#if !CONFIG_FREERTOS_SMP // IDF-5224
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT 11000 // TODO: IDF-5490
|
||||
#endif
|
||||
#else
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT 12200
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_1BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_1BIT 4000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_1BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_1BIT 4000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_SPI
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_SPI 1000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_SPI
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_SPI 1000
|
||||
#endif
|
||||
|
@ -30,3 +30,23 @@
|
||||
#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16 10
|
||||
#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64 10
|
||||
#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3 10
|
||||
|
||||
//SDIO
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_4BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_4BIT 9000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT 10000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_1BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_1BIT 4000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_1BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_1BIT 4000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_SPI
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_SPI 1000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_SPI
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_SPI 1000
|
||||
#endif
|
||||
|
@ -95,33 +95,6 @@
|
||||
#define IDF_PERFORMANCE_MAX_ISR_EXIT_CYCLES 565
|
||||
#endif
|
||||
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_4BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_4BIT 12200
|
||||
#endif
|
||||
|
||||
#if !CONFIG_FREERTOS_SMP // IDF-5224
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT 11000 // TODO: IDF-5490
|
||||
#endif
|
||||
#else
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_4BIT 12200
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_1BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_1BIT 4000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_1BIT
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_1BIT 4000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_SPI
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_TOHOST_SPI 1000
|
||||
#endif
|
||||
#ifndef IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_SPI
|
||||
#define IDF_PERFORMANCE_MIN_SDIO_THROUGHPUT_KBSEC_FRHOST_SPI 1000
|
||||
#endif
|
||||
|
||||
//time to perform the task selection plus context switch (from task)
|
||||
#ifndef IDF_PERFORMANCE_MAX_SCHEDULING_TIME
|
||||
#define IDF_PERFORMANCE_MAX_SCHEDULING_TIME 2000
|
||||
|
@ -105,7 +105,8 @@ ENV_MARKERS = {
|
||||
'wifi_two_dut': 'tests should be run on runners which has two wifi duts connected.',
|
||||
'generic_multi_device': 'generic multiple devices whose corresponding gpio pins are connected to each other.',
|
||||
'twai_network': 'multiple runners form a TWAI network.',
|
||||
'sdio_master_slave': 'Test sdio multi board.',
|
||||
'sdio_master_slave': 'Test sdio multi board, esp32+esp32',
|
||||
'sdio_multidev_32_c6': 'Test sdio multi board, esp32+esp32c6',
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user