Merge branch 'fix/spi_enable_p4_c5_test_v5.3' into 'release/v5.3'

fix(driver_spi): enable p4 test (v5.3)

See merge request espressif/esp-idf!34281
This commit is contained in:
morris
2024-12-06 17:03:38 +08:00
17 changed files with 132 additions and 147 deletions

View File

@ -94,12 +94,7 @@
#define WIRE_DELAY 12.5
#endif //CONFIG_IDF_TARGET_ESP32
#define GET_DMA_CHAN(HOST) (HOST)
#define TEST_DMA_CHAN_MASTER GET_DMA_CHAN(TEST_SPI_HOST)
#define TEST_DMA_CHAN_SLAVE GET_DMA_CHAN(TEST_SLAVE_HOST)
#define FUNC_SPI 1
#define FUNC_SPI SPI2_FUNC_NUM
#define FUNC_GPIO PIN_FUNC_GPIO
//Delay information

View File

@ -91,6 +91,7 @@ void spitest_slave_task(void* arg)
t.length = txdata.len;
t.tx_buffer = txdata.start;
t.rx_buffer = recvbuf + 8;
t.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO;
//loop until trans_len != 0 to skip glitches
do {
TEST_ESP_OK(spi_slave_transmit(context->spi, &t, portMAX_DELAY));
@ -231,6 +232,7 @@ void spitest_gpio_input_sel(uint32_t gpio_num, int func, uint32_t signal_idx)
esp_rom_gpio_connect_in_signal(gpio_num, signal_idx, 0);
}
#if (TEST_SPI_PERIPH_NUM >= 2)
//Note this cs_dev_id is the ID of the connected devices' ID, e.g. if 2 devices are connected to the bus,
//then the cs_dev_id 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_dev_id)
@ -247,3 +249,4 @@ void same_pin_func_sel(spi_bus_config_t bus, spi_device_interface_config_t dev,
spitest_gpio_output_sel(bus.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
spitest_gpio_input_sel(bus.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiclk_in);
}
#endif //(TEST_SPI_PERIPH_NUM >= 2)

View File

@ -211,7 +211,7 @@ struct spi_device_t {
static spi_host_t* bus_driver_ctx[SOC_SPI_PERIPH_NUM] = {};
static const char *SPI_TAG = "spi_master";
#define SPI_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE_ISR(a, ret_val, SPI_TAG, str)
#define SPI_CHECK(a, str, ret_val, ...) ESP_RETURN_ON_FALSE_ISR(a, ret_val, SPI_TAG, str, ##__VA_ARGS__)
#if SOC_PERIPH_CLK_CTRL_SHARED
#define SPI_MASTER_PERI_CLOCK_ATOMIC() PERIPH_RCC_ATOMIC()
@ -409,7 +409,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
if (dev_config->clock_source) {
clk_src = dev_config->clock_source;
}
esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clock_source_hz);
#if SPI_LL_SUPPORT_CLK_SRC_PRE_DIV
SPI_CHECK((dev_config->clock_speed_hz > 0) && (dev_config->clock_speed_hz <= MIN(clock_source_hz / 2, (80 * 1000000))), "invalid sclk speed", ESP_ERR_INVALID_ARG);

View File

@ -9,36 +9,20 @@
components/esp_driver_spi/test_apps/master:
disable:
- if: SOC_GPSPI_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: not supported # TODO: IDF-8942
<<: *spi_depends_default
components/esp_driver_spi/test_apps/param:
disable:
- if: SOC_GPSPI_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: not supported # TODO: IDF-8942
<<: *spi_depends_default
components/esp_driver_spi/test_apps/slave:
disable:
- if: SOC_GPSPI_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: not supported # TODO: IDF-8942
<<: *spi_depends_default
components/esp_driver_spi/test_apps/slave_hd:
disable:
- if: SOC_GPSPI_SUPPORTED != 1
- if: SOC_SPI_SUPPORT_SLAVE_HD_VER2 != 1
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: not supported # TODO: IDF-8942
<<: *spi_depends_default

View File

@ -68,12 +68,11 @@
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 54
#elif CONFIG_IDF_TARGET_ESP32P4
//TODO: IDF-8313 update after chips back and PLL setup
#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 10*1000*1000
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 1000
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 1000
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 1000
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 1000
#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 26*1000*1000
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 44
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 28
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 26
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 12
#elif CONFIG_IDF_TARGET_ESP32C5
#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 40*1000*1000

View File

@ -16,6 +16,6 @@ endif()
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(
SRCS ${srcs}
PRIV_REQUIRES esp_driver_spi spi_flash
PRIV_REQUIRES esp_driver_spi spi_flash esp_timer
WHOLE_ARCHIVE
)

View File

@ -10,7 +10,9 @@
#include "sdkconfig.h"
#include "driver/spi_master.h"
#include "driver/spi_slave.h"
#include "sys/param.h"
#include "driver/gpio.h"
#include "hal/spi_ll.h" // for SPI_LL_SUPPORT_CLK_SRC_PRE_DIV
#include "soc/gpio_periph.h"
#include "soc/spi_periph.h"
#include "soc/soc_memory_layout.h"
@ -19,6 +21,7 @@
#include "esp_private/esp_clk.h"
#include "esp_heap_caps.h"
#include "esp_clk_tree.h"
#include "esp_timer.h"
#include "esp_log.h"
#include "test_utils.h"
#include "test_spi_utils.h"
@ -29,7 +32,7 @@ const static char TAG[] = "test_spi";
// There is no input-only pin except on esp32 and esp32s2
#define TEST_SOC_HAS_INPUT_ONLY_PINS (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2)
static void check_spi_pre_n_for(spi_clock_source_t clock_source, int clk, int pre, int n)
static void check_spi_pre_n_for(int clk, int pre, int n)
{
spi_device_handle_t handle;
@ -37,7 +40,6 @@ static void check_spi_pre_n_for(spi_clock_source_t clock_source, int clk, int pr
.command_bits = 0,
.address_bits = 0,
.dummy_bits = 0,
.clock_source = clock_source,
.clock_speed_hz = clk,
.duty_cycle_pos = 128,
.mode = 0,
@ -72,108 +74,98 @@ static void check_spi_pre_n_for(spi_clock_source_t clock_source, int clk, int pr
*
* For each item:
* {freq, pre, n}
*
* Only test on SPI_CLK_SRC_DEFAULT here
*/
#define TEST_CLK_TIMES 8
struct test_clk_param_group_t {
uint32_t clk_param_80m[TEST_CLK_TIMES][3];
uint32_t clk_param_48m[TEST_CLK_TIMES][3];
uint32_t clk_param_40m[TEST_CLK_TIMES][3];
uint32_t clk_param_32m[TEST_CLK_TIMES][3];
uint32_t clk_param_17m[TEST_CLK_TIMES][3];
uint32_t clk_param_7m[TEST_CLK_TIMES][3];
} test_clk_param = {
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 16, 50}, {333333, 4, 60}, {800000, 2, 50}, {900000, 2, 44}, {8000000, 1, 10}, {20000000, 1, 4}, {26000000, 1, 3} },
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 8, 60}, {333333, 3, 48}, {800000, 1, 60}, {5000000, 1, 10}, {12000000, 1, 4}, {18000000, 1, 3}, {26000000, 1, 2} },
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 8, 50}, {333333, 2, 60}, {800000, 1, 50}, {900000, 1, 44}, {8000000, 1, 5}, {10000000, 1, 4}, {20000000, 1, 2} },
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 5, 64}, {333333, 2, 48}, {800000, 1, 40}, {2000000, 1, 16}, {8000000, 1, 4}, {15000000, 1, 2}, {20000000, 1, 2} },
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 5, 35}, {333333, 1, 53}, {800000, 1, 22}, {900000, 1, 19}, {8000000, 1, 2}, {10000000, 1, 2}, {15000000, 1, 1} },
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 2, 35}, {333333, 1, 21}, {800000, 1, 9}, {900000, 1, 8}, {1100000, 1, 6}, {4000000, 1, 2,}, {7000000, 1, 1} },
};
uint32_t clk_param_80m[TEST_CLK_TIMES][3] = {{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 16, 50}, {333333, 4, 60}, {800000, 2, 50}, {900000, 2, 44}, {8000000, 1, 10}, {20000000, 1, 4}, {26000000, 1, 3} };
uint32_t clk_param_48m[TEST_CLK_TIMES][3] = {{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 8, 60}, {333333, 3, 48}, {800000, 1, 60}, {5000000, 1, 10}, {12000000, 1, 4}, {18000000, 1, 3}, {26000000, 1, 2} };
uint32_t clk_param_40m[TEST_CLK_TIMES][3] = {{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 8, 50}, {333333, 2, 60}, {800000, 1, 50}, {2000000, 1, 20}, {5000000, 1, 8}, {12000000, 1, 3}, {18000000, 1, 2} };
TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
{
spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
uint32_t clock_source_hz;
// Test main clock source
#if SOC_SPI_SUPPORT_CLK_PLL_F80M
esp_clk_tree_src_get_freq_hz(SPI_CLK_SRC_PLL_F80M, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source PLL_80M = %ld\n", clock_source_hz);
TEST_ASSERT((80 * 1000 * 1000) == clock_source_hz);
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_PLL_F80M, test_clk_param.clk_param_80m[i][0], test_clk_param.clk_param_80m[i][1], test_clk_param.clk_param_80m[i][2]);
}
#endif
#if SOC_SPI_SUPPORT_CLK_PLL_F48M
esp_clk_tree_src_get_freq_hz(SPI_CLK_SRC_PLL_F48M, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source PLL_48M = %ld\n", clock_source_hz);
TEST_ASSERT((48 * 1000 * 1000) == clock_source_hz);
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_PLL_F48M, test_clk_param.clk_param_48m[i][0], test_clk_param.clk_param_48m[i][1], test_clk_param.clk_param_48m[i][2]);
}
#endif
#if SOC_SPI_SUPPORT_CLK_AHB
esp_clk_tree_src_get_freq_hz(SPI_CLK_SRC_AHB, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source AHB = %ld\n", clock_source_hz);
TEST_ASSERT((48 * 1000 * 1000) == clock_source_hz);
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_AHB, test_clk_param.clk_param_48m[i][0], test_clk_param.clk_param_48m[i][1], test_clk_param.clk_param_48m[i][2]);
}
#endif
#if SOC_SPI_SUPPORT_CLK_PLL_F40M
esp_clk_tree_src_get_freq_hz(SPI_CLK_SRC_PLL_F40M, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source PLL_40M = %ld\n", clock_source_hz);
TEST_ASSERT((40 * 1000 * 1000) == clock_source_hz);
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_PLL_F40M, test_clk_param.clk_param_40m[i][0], test_clk_param.clk_param_40m[i][1], test_clk_param.clk_param_40m[i][2]);
}
#endif
#if SOC_SPI_SUPPORT_CLK_APB
esp_clk_tree_src_get_freq_hz(SPI_CLK_SRC_APB, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source APB = %ld\n", clock_source_hz);
TEST_ASSERT((80 * 1000 * 1000) == clock_source_hz);
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_APB, test_clk_param.clk_param_80m[i][0], test_clk_param.clk_param_80m[i][1], test_clk_param.clk_param_80m[i][2]);
}
#endif
// Test XTAL clock source
#if SOC_SPI_SUPPORT_CLK_XTAL
esp_clk_tree_src_get_freq_hz(SPI_CLK_SRC_XTAL, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source XTAL = %ld\n", clock_source_hz);
if ((40 * 1000 * 1000) == clock_source_hz) {
esp_clk_tree_src_get_freq_hz(SPI_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source SPI_CLK_SRC_DEFAULT = %ld\n", clock_source_hz);
if ((80 * 1000 * 1000) == clock_source_hz) {
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_XTAL, test_clk_param.clk_param_40m[i][0], test_clk_param.clk_param_40m[i][1], test_clk_param.clk_param_40m[i][2]);
check_spi_pre_n_for(clk_param_80m[i][0], clk_param_80m[i][1], clk_param_80m[i][2]);
}
} else if ((48 * 1000 * 1000) == clock_source_hz) {
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(clk_param_48m[i][0], clk_param_48m[i][1], clk_param_48m[i][2]);
}
} else if ((40 * 1000 * 1000) == clock_source_hz) {
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(clk_param_40m[i][0], clk_param_40m[i][1], clk_param_40m[i][2]);
}
}
if ((32 * 1000 * 1000) == clock_source_hz) {
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_XTAL, test_clk_param.clk_param_32m[i][0], test_clk_param.clk_param_32m[i][1], test_clk_param.clk_param_32m[i][2]);
}
}
#endif
// Test RC fast osc clock source
TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST));
}
// Test All clock source
#define TEST_CLK_BYTE_LEN 10000
#define TEST_TRANS_TIME_BIAS_RATIO (float)2.0/100 // think 2% transfer time bias as acceptable
TEST_CASE("SPI Master clk_source and divider accuracy", "[spi]")
{
int64_t start = 0, end = 0;
spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
buscfg.max_transfer_sz = TEST_CLK_BYTE_LEN;
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
// prepare trans
uint8_t *sendbuf = heap_caps_malloc(TEST_CLK_BYTE_LEN, MALLOC_CAP_DMA);
spi_transaction_t trans = {};
trans.tx_buffer = sendbuf;
trans.length = TEST_CLK_BYTE_LEN * 8;
uint8_t spi_clk_sour[] = SOC_SPI_CLKS;
uint32_t clock_source_hz;
for (uint8_t sour_idx = 0; sour_idx < sizeof(spi_clk_sour); sour_idx++) {
esp_clk_tree_src_get_freq_hz(spi_clk_sour[sour_idx], ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTesting unknown clock source @%ld Hz\n", clock_source_hz);
#if SPI_LL_SUPPORT_CLK_SRC_PRE_DIV
clock_source_hz /= 2; //targets support pre-div will divide clock by 2 before SPI peripheral
#endif
for (uint8_t test_time = 0; test_time < 8; test_time ++) {
spi_device_handle_t handle;
spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
devcfg.clock_source = spi_clk_sour[sour_idx];
devcfg.clock_speed_hz = MIN(IDF_PERFORMANCE_MAX_SPI_CLK_FREQ, clock_source_hz) >> test_time;
devcfg.flags |= SPI_DEVICE_HALFDUPLEX; //esp32 half duplex to work on high freq
#if SOC_SPI_SUPPORT_CLK_RC_FAST
esp_clk_tree_src_get_freq_hz(SPI_CLK_SRC_RC_FAST, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source RC_FAST = %ld\n", clock_source_hz);
if ((17500000) == clock_source_hz) {
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_RC_FAST, test_clk_param.clk_param_17m[i][0], test_clk_param.clk_param_17m[i][1], test_clk_param.clk_param_17m[i][2]);
}
}
if ((7000000) == clock_source_hz) {
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_RC_FAST, test_clk_param.clk_param_7m[i][0], test_clk_param.clk_param_7m[i][1], test_clk_param.clk_param_7m[i][2]);
}
}
if (devcfg.clock_source == SPI_CLK_SRC_RC_FAST) {
devcfg.clock_speed_hz /= 2; //rc_fast have bad accuracy, test at low speed
}
#endif
TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &handle));
// one trans first to trigger lazy load
TEST_ESP_OK(spi_device_polling_transmit(handle, &trans));
// calculate theoretical transaction time by actual freq and trans length
int real_freq_khz;
spi_device_get_actual_freq(handle, &real_freq_khz);
// (byte_len * 8 / real_freq_hz) * 1000 000, (unit)us
int trans_cost_us_predict = (float)TEST_CLK_BYTE_LEN * 8 * 1000 / real_freq_khz;
// transaction and measure time
start = esp_timer_get_time();
TEST_ESP_OK(spi_device_polling_transmit(handle, &trans));
end = esp_timer_get_time();
int trans_cost = end - start;
int time_tolerance = trans_cost_us_predict * TEST_TRANS_TIME_BIAS_RATIO;
printf("real_freq %dk predict_cost %d real_cost_us %d diff %d tolerance %d us\n", real_freq_khz, trans_cost_us_predict, trans_cost, (trans_cost - trans_cost_us_predict), time_tolerance);
TEST_ASSERT_LESS_THAN_UINT32(time_tolerance, abs(trans_cost - trans_cost_us_predict));
TEST_ESP_OK(spi_bus_remove_device(handle));
}
}
free(sendbuf);
TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST));
}
@ -1250,6 +1242,7 @@ static void slave_only_tx_trans(uint8_t *slv_send_buf, uint32_t length)
{
ESP_LOGI(SLAVE_TAG, "FD DMA, Only TX");
spi_slave_transaction_t trans = {0};
trans.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO;
trans.tx_buffer = slv_send_buf;
trans.length = length * 8;
unity_send_signal("Slave ready");
@ -1261,6 +1254,7 @@ static void slave_only_rx_trans(uint8_t *slv_recv_buf, uint8_t *mst_send_buf, ui
{
ESP_LOGI(SLAVE_TAG, "FD DMA, Only RX");
spi_slave_transaction_t trans = {};
trans.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO;
trans.tx_buffer = NULL;
trans.rx_buffer = slv_recv_buf;
trans.length = length * 8;
@ -1275,6 +1269,7 @@ static void slave_both_trans(uint8_t *slv_send_buf, uint8_t *slv_recv_buf, uint8
{
ESP_LOGI(SLAVE_TAG, "FD DMA, Both TX and RX:");
spi_slave_transaction_t trans = {0};
trans.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO;
trans.tx_buffer = slv_send_buf;
trans.rx_buffer = slv_recv_buf;
trans.length = length * 8;
@ -1491,6 +1486,8 @@ TEST_CASE("spi_speed", "[spi]")
#define DUMMY_CS_PINS() {25, 26, 27}
#elif CONFIG_IDF_TARGET_ESP32H2
#define DUMMY_CS_PINS() {9, 10, 11, 12, 22, 25}
#elif CONFIG_IDF_TARGET_ESP32P4
#define DUMMY_CS_PINS() {20, 21, 22, 23, 24, 25}
#else
#define DUMMY_CS_PINS() {0, 1, 4, 5, 8, 9}
#endif //CONFIG_IDF_TARGET_ESP32
@ -1575,6 +1572,7 @@ void test_add_device_slave(void)
slave_trans.length = sizeof(slave_sendbuf) * 8;
slave_trans.tx_buffer = slave_sendbuf;
slave_trans.rx_buffer = slave_recvbuf;
slave_trans.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO;
for (uint8_t i = 0; i < SOC_SPI_MAX_CS_NUM; i++) {
memset(slave_recvbuf, 0, sizeof(slave_recvbuf));
@ -1698,7 +1696,6 @@ static IRAM_ATTR void test_master_iram(void)
spi_flash_enable_interrupts_caches_and_other_cpu();
ESP_LOG_BUFFER_HEX("master tx", ret_trans->tx_buffer, TEST_MASTER_IRAM_TRANS_LEN);
ESP_LOG_BUFFER_HEX("master rx", ret_trans->rx_buffer, TEST_MASTER_IRAM_TRANS_LEN);
spitest_cmp_or_dump(master_exp, trans_cfg.rx_buffer, TEST_MASTER_IRAM_TRANS_LEN);
// Test polling trans api once -------------------------------
@ -1710,13 +1707,12 @@ static IRAM_ATTR void test_master_iram(void)
spi_flash_enable_interrupts_caches_and_other_cpu();
ESP_LOG_BUFFER_HEX("master tx", ret_trans->tx_buffer, TEST_MASTER_IRAM_TRANS_LEN);
ESP_LOG_BUFFER_HEX("master rx", ret_trans->rx_buffer, TEST_MASTER_IRAM_TRANS_LEN);
spitest_cmp_or_dump(master_exp, trans_cfg.rx_buffer, TEST_MASTER_IRAM_TRANS_LEN);
free(master_send);
free(master_recv);
free(master_exp);
spi_bus_remove_device(dev_handle);
TEST_ESP_OK(spi_bus_remove_device(dev_handle));
spi_bus_free(TEST_SPI_HOST);
}
@ -1734,20 +1730,19 @@ 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;
slave_trans.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO;
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");
spi_slave_transmit(TEST_SPI_HOST, &slave_trans, portMAX_DELAY);
TEST_ESP_OK(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);
spitest_cmp_or_dump(slave_expect, slave_recvbuf, TEST_MASTER_IRAM_TRANS_LEN);
unity_send_signal("Slave ready");
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);
TEST_ESP_OK(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);
spitest_cmp_or_dump(slave_expect, slave_recvbuf, TEST_MASTER_IRAM_TRANS_LEN);
free(slave_sendbuf);

View File

@ -4,7 +4,6 @@ import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 support TBD') # TODO: IDF-8942
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic
@ -28,7 +27,6 @@ def test_master_esp_flash(case_tester) -> None: # type: ignore
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 support TBD') # TODO: IDF-8942
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic_multi_device

View File

@ -109,6 +109,10 @@ static void local_test_start(spi_device_handle_t *spi, int freq, const spitest_p
devcfg.flags |= SPI_DEVICE_NO_DUMMY;
}
#if CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-8313, update P4 defaulte clock source
devcfg.clock_source = SPI_CLK_SRC_SPLL;
#endif
//slave config
slvcfg.mode = pset->mode;
slave_pull_up(&buscfg, slvcfg.spics_io_num);
@ -192,6 +196,7 @@ static void local_test_loop(const void *arg1, void *arg2)
.tx_buffer = txdata->start,
.rx_buffer = recvbuf,
.length = txdata->len,
.flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO,
};
esp_err_t err = spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_trans, portMAX_DELAY);
TEST_ESP_OK(err);
@ -247,8 +252,7 @@ static void local_test_loop(const void *arg1, void *arg2)
/************ Timing Test ***********************************************/
//TODO: esp32s2 has better timing performance
static spitest_param_set_t timing_pgroup[] = {
//signals are not fed to peripherals through iomux if the functions are not selected to iomux
#if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
#if (SLAVE_IOMUX_PIN_MISO != -1) //SPI3 slave has iomux pin
{
.pset_name = "FULL_DUP, MASTER IOMUX",
.freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
@ -277,8 +281,7 @@ static spitest_param_set_t timing_pgroup[] = {
.slave_iomux = false,
.slave_tv_ns = TV_INT_CONNECT_GPIO,
},
//signals are not fed to peripherals through iomux if the functions are not selected to iomux
#if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
#if (SLAVE_IOMUX_PIN_MISO != -1) //SPI3 slave has iomux pin
{
.pset_name = "MISO_DUP, MASTER IOMUX",
.freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
@ -307,8 +310,7 @@ static spitest_param_set_t timing_pgroup[] = {
.slave_iomux = false,
.slave_tv_ns = TV_INT_CONNECT_GPIO,
},
//signals are not fed to peripherals through iomux if the functions are not selected to iomux
#if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
#if (SLAVE_IOMUX_PIN_MISO != -1) //SPI3 slave has iomux pin
{
.pset_name = "MOSI_DUP, MASTER IOMUX",
.freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
@ -616,7 +618,8 @@ TEST_CASE("Slave receive correct data", "[spi]")
spi_slave_transaction_t slave_trans = {
.length = slave_trans_len * 8,
.tx_buffer = slave_sendbuf,
.rx_buffer = slave_recvbuf
.rx_buffer = slave_recvbuf,
.flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO,
};
esp_err_t ret = spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_trans, portMAX_DELAY);
TEST_ESP_OK(ret);
@ -1276,7 +1279,9 @@ static int s_spi_bus_freq[] = {
IDF_PERFORMANCE_MAX_SPI_CLK_FREQ / 7,
IDF_PERFORMANCE_MAX_SPI_CLK_FREQ / 4,
IDF_PERFORMANCE_MAX_SPI_CLK_FREQ / 2,
#if !CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-8313, update P4 defaulte clock source
IDF_PERFORMANCE_MAX_SPI_CLK_FREQ,
#endif
};
//------------------------------------------- Full Duplex with DMA Freq test --------------------------------------
@ -1489,6 +1494,7 @@ static void test_slave_fd_no_dma(void)
.tx_buffer = slave_send,
.rx_buffer = slave_receive,
.length = test_trans_len * 8,
.flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO,
};
unity_send_signal("Slave ready");
TEST_ESP_OK(spi_slave_transmit(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY));
@ -1593,6 +1599,7 @@ static void test_slave_hd_dma(void)
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &slave_trans, portMAX_DELAY));
slave_trans.data = slave_receive;
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, &slave_trans, portMAX_DELAY));
TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &ret_trans, portMAX_DELAY));
TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, &ret_trans, portMAX_DELAY));
ESP_LOG_BUFFER_HEX("slave tx", slave_send, test_trans_len);
@ -1694,6 +1701,7 @@ static void test_slave_hd_no_dma(void)
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &slave_trans, portMAX_DELAY));
slave_trans.data = slave_receive;
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, &slave_trans, portMAX_DELAY));
TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &ret_trans, portMAX_DELAY));
TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, &ret_trans, portMAX_DELAY));
ESP_LOG_BUFFER_HEX("slave tx", slave_send, test_trans_len);
@ -1957,6 +1965,7 @@ static void test_slave_sio_no_dma(void)
.length = SOC_SPI_MAXIMUM_BUFFER_SIZE * 8,
.tx_buffer = slave_send,
.rx_buffer = slave_receive,
.flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO,
};
unity_send_signal("Slave ready");
TEST_ESP_OK(spi_slave_transmit(TEST_SPI_HOST, &trans, portMAX_DELAY));

View File

@ -4,9 +4,7 @@ import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 support TBD') # TODO: IDF-8942
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic
def test_param_single_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
@ -16,9 +14,7 @@ def test_param_single_dev(case_tester) -> None: # type: ignore
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 support TBD') # TODO: IDF-8942
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic_multi_device
@pytest.mark.parametrize('count', [2,], indirect=True)
def test_param_multi_dev(case_tester) -> None: # type: ignore

View File

@ -562,6 +562,7 @@ static IRAM_ATTR void test_slave_isr_iram(void)
}
TEST_CASE_MULTIPLE_DEVICES("SPI_Slave: Test_ISR_IRAM_disable_cache", "[spi_ms]", test_slave_iram_master_normal, test_slave_isr_iram);
#if !SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //isr option is not supported in this condition
static uint32_t isr_trans_cnt, isr_trans_test_fail;
static IRAM_ATTR void test_trans_in_isr_post_trans_cbk(spi_slave_transaction_t *curr_trans)
{
@ -725,6 +726,7 @@ static IRAM_ATTR void spi_queue_reset_in_isr(void)
spi_slave_free(TEST_SPI_HOST);
}
TEST_CASE_MULTIPLE_DEVICES("SPI_Slave: Test_Queue_Reset_in_ISR", "[spi_ms]", test_slave_iram_master_normal, spi_queue_reset_in_isr);
#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
#endif // CONFIG_SPI_SLAVE_ISR_IN_IRAM
#if (SOC_CPU_CORES_NUM > 1) && (!CONFIG_FREERTOS_UNICORE)

View File

@ -4,7 +4,6 @@ import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 support TBD') # TODO: IDF-8942
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic
@ -17,7 +16,6 @@ def test_slave_single_dev(case_tester) -> None: # type: ignore
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 support TBD') # TODO: IDF-8942
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic_multi_device

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -857,19 +857,23 @@ static void hd_slave_quad(void)
{
.data = slave_recv_buf,
.len = (trans_len + 3) & (~3),
.flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO,
},
{
.data = slave_recv_buf + BUF_SIZE / 2,
.len = (trans_len + 3) & (~3),
.flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO,
},
//send
{
.data = slave_send_buf,
.len = (trans_len + 3) & (~3),
.flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO,
},
{
.data = slave_send_buf + BUF_SIZE / 2,
.len = (trans_len + 3) & (~3),
.flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO,
},
};
@ -903,7 +907,7 @@ static void hd_slave_quad(void)
spi_slave_hd_deinit(TEST_SLAVE_HOST);
}
TEST_CASE_MULTIPLE_DEVICES("SPI quad hd test ", "[spi_ms][test_env=generic_multi_device]", hd_master_quad, hd_slave_quad);
TEST_CASE_MULTIPLE_DEVICES("SPI quad hd test", "[spi_ms][test_env=generic_multi_device]", hd_master_quad, hd_slave_quad);
#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
@ -943,6 +947,7 @@ void slave_run_append(void)
slave_rx_trans[append_idx].data = heap_caps_aligned_calloc(4, 1, TEST_TRANS_LEN, MALLOC_CAP_DMA);
TEST_ASSERT_NOT_NULL(slave_rx_trans[append_idx].data);
slave_rx_trans[append_idx].len = trans_len;
slave_rx_trans[append_idx].flags |= SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO;
TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, &slave_rx_trans[append_idx], portMAX_DELAY));
}
@ -984,6 +989,7 @@ void slave_run_append(void)
}
slave_tx_trans[append_idx].data = slave_rx_trans[append_idx].data;
slave_tx_trans[append_idx].len = trans_len;
slave_tx_trans[append_idx].flags |= SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO;
prepare_data(slave_tx_trans[append_idx].data, trans_len, -3);
TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &slave_tx_trans[append_idx], portMAX_DELAY));
}

View File

@ -25,6 +25,7 @@ def test_slave_hd_single_dev(case_tester) -> None: # type: ignore
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.esp32p4
@pytest.mark.generic_multi_device
@pytest.mark.parametrize('count', [2,], indirect=True)
def test_slave_hd_multi_dev(case_tester) -> None: # type: ignore

View File

@ -19,7 +19,7 @@ extern "C" {
*
* 2) External 40MHz Crystal Clock: XTAL
*
* 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referrred as SOSC in TRM or reg. description)
* 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description)
*
* This RC oscillator generates a ~136kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock
* can be computed in runtime through calibration.

View File

@ -19,7 +19,7 @@ extern "C" {
*
* 2) External 32MHz Crystal Clock: XTAL
*
* 3) Internal 136kHz RC Oscillator: RC_SLOW (usually referrred as SOSC in TRM or reg. description)
* 3) Internal 136kHz RC Oscillator: RC_SLOW (usually referred as SOSC in TRM or reg. description)
*
* This RC oscillator generates a ~136kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock
* can be computed in runtime through calibration.
@ -332,7 +332,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of SPI
*/
#define SOC_SPI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_PLL_F48M}
#define SOC_SPI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F48M, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of SPI clock source.

View File

@ -73,7 +73,6 @@ const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = {
.spiclk_in = SPI3_CK_PAD_IN_IDX,
.spid_out = SPI3_D_PAD_OUT_IDX,
.spiq_out = SPI3_QO_PAD_OUT_IDX,
//SPI3 doesn't have wp and hd signals
.spiwp_out = SPI3_WP_PAD_OUT_IDX,
.spihd_out = SPI3_HOLD_PAD_OUT_IDX,
.spid_in = SPI3_D_PAD_IN_IDX,