From d8ac58b4d46f9b5661bfe4f5febf723472bb6680 Mon Sep 17 00:00:00 2001 From: wanlei Date: Fri, 17 Feb 2023 12:00:16 +0800 Subject: [PATCH] spi: add high freq test on different spi config --- .../include/test_spi_utils.h | 15 +- .../test_apps/spi/param/main/CMakeLists.txt | 2 +- .../test_apps/spi/param/main/test_spi_param.c | 682 ++++++++++++++++++ .../spi/slave_hd/main/test_spi_slave_hd.c | 10 - .../include/esp32/idf_performance_target.h | 1 + .../include/esp32c2/idf_performance_target.h | 1 + .../include/esp32c3/idf_performance_target.h | 1 + .../include/esp32c6/idf_performance_target.h | 1 + .../include/esp32h2/idf_performance_target.h | 1 + .../include/esp32h4/idf_performance_target.h | 1 + .../include/esp32s2/idf_performance_target.h | 1 + .../include/esp32s3/idf_performance_target.h | 1 + 12 files changed, 704 insertions(+), 13 deletions(-) diff --git a/components/driver/test_apps/components/test_driver_utils/include/test_spi_utils.h b/components/driver/test_apps/components/test_driver_utils/include/test_spi_utils.h index d8cb5aa3e4..9b574840ec 100644 --- a/components/driver/test_apps/components/test_driver_utils/include/test_spi_utils.h +++ b/components/driver/test_apps/components/test_driver_utils/include/test_spi_utils.h @@ -165,6 +165,17 @@ .flags=0,\ } +//default device config for slave hd devices +#define SPI_SLOT_TEST_DEFAULT_CONFIG() {\ + .spics_io_num = PIN_NUM_CS, \ + .flags = 0, \ + .mode = 0, \ + .command_bits = 8,\ + .address_bits = 8,\ + .dummy_bits = 8,\ + .queue_size = 10,\ + } + typedef enum { FULL_DUPLEX = 0, HALF_DUPLEX_MISO = 1, @@ -252,8 +263,8 @@ esp_err_t spitest_check_data(int len, spi_transaction_t *master_t, slave_rxdata_ #define spitest_cmp_or_dump(expected, actual, len) ({\ int r = memcmp(expected, actual, len);\ if (r != 0) {\ - ESP_LOG_BUFFER_HEXDUMP("expected", expected, len, ESP_LOG_INFO);\ - ESP_LOG_BUFFER_HEXDUMP("actual", actual, len, ESP_LOG_WARN);\ + ESP_LOG_BUFFER_HEXDUMP("actual ", actual, len, ESP_LOG_WARN);\ + ESP_LOG_BUFFER_HEXDUMP("expecte", expected, len, ESP_LOG_INFO);\ TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, len);\ }\ r;\ diff --git a/components/driver/test_apps/spi/param/main/CMakeLists.txt b/components/driver/test_apps/spi/param/main/CMakeLists.txt index 5c5d75a19b..802e5b84a0 100644 --- a/components/driver/test_apps/spi/param/main/CMakeLists.txt +++ b/components/driver/test_apps/spi/param/main/CMakeLists.txt @@ -9,6 +9,6 @@ set(srcs # the component can be registered as WHOLE_ARCHIVE idf_component_register( SRCS ${srcs} - PRIV_REQUIRES test_utils driver test_driver_utils + PRIV_REQUIRES test_utils driver test_driver_utils esp_serial_slave_link WHOLE_ARCHIVE ) diff --git a/components/driver/test_apps/spi/param/main/test_spi_param.c b/components/driver/test_apps/spi/param/main/test_spi_param.c index cdd201f498..316a87b037 100644 --- a/components/driver/test_apps/spi/param/main/test_spi_param.c +++ b/components/driver/test_apps/spi/param/main/test_spi_param.c @@ -12,6 +12,11 @@ #include "driver/spi_master.h" #include "driver/spi_slave.h" +#if SOC_SPI_SUPPORT_SLAVE_HD_VER2 +#include "esp_serial_slave_link/essl_spi.h" +#include "driver/spi_slave_hd.h" +#endif + #if (TEST_SPI_PERIPH_NUM >= 2) //These will only be enabled on chips with 2 or more SPI peripherals @@ -1186,3 +1191,680 @@ TEST_SPI_MASTER_SLAVE(MODE, mode_conf, "") #endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3, ESP32C2) #endif // #if (TEST_SPI_PERIPH_NUM >= 2) + + +#define TEST_STEP_LEN 96 +#define TEST_STEP 2 +static int s_spi_bus_freq[] = { + IDF_PERFORMANCE_MAX_SPI_CLK_FREQ/10, + IDF_PERFORMANCE_MAX_SPI_CLK_FREQ/7, + IDF_PERFORMANCE_MAX_SPI_CLK_FREQ/4, + IDF_PERFORMANCE_MAX_SPI_CLK_FREQ/2, + IDF_PERFORMANCE_MAX_SPI_CLK_FREQ, +}; + +//------------------------------------------- Full Duplex with DMA Freq test -------------------------------------- +static void test_master_fd_dma(void){ + spi_device_handle_t dev0; + uint8_t *master_send = heap_caps_malloc(TEST_STEP_LEN, MALLOC_CAP_DMA); + uint8_t *master_recive = heap_caps_malloc(TEST_STEP_LEN, MALLOC_CAP_DMA); + uint8_t *master_expect = heap_caps_malloc(TEST_STEP_LEN, MALLOC_CAP_DEFAULT); + + for(uint8_t is_gpio=0; is_gpio<2; is_gpio++){ + for(uint8_t mode=0; mode<4; mode++){ + spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); + if (is_gpio) buscfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS; + TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); + + for(uint8_t speed_level=0; speed_level = 10*1000*1000)) continue; //On esp32 with GPIO Matrix, clk freq <= 10MHz + devcfg.cs_ena_pretrans = 2; + devcfg.input_delay_ns = 12.5*2; +#endif + TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &dev0)); + printf("Next trans: %s\tmode:%d\t@%.2f MHz\n", (is_gpio)?"GPIO_Matrix":"IOMUX", mode, s_spi_bus_freq[speed_level]/1000000.f); + + 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); + + uint32_t test_trans_len = TEST_STEP_LEN; + spi_transaction_t trans_cfg = { + .tx_buffer = master_send, + .rx_buffer = master_recive, + .length = test_trans_len * 8, + }; + unity_wait_for_signal("Slave ready"); + TEST_ESP_OK(spi_device_transmit(dev0, &trans_cfg)); + + ESP_LOG_BUFFER_HEX("master tx", master_send, test_trans_len); + ESP_LOG_BUFFER_HEX_LEVEL("master rx", master_recive, test_trans_len, ESP_LOG_DEBUG); + ESP_LOG_BUFFER_HEX_LEVEL("master exp", master_expect, test_trans_len, ESP_LOG_DEBUG); + spitest_cmp_or_dump(master_expect, master_recive, test_trans_len); + } + TEST_ESP_OK(spi_bus_remove_device(dev0)); + } + TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST)); + } + } + free(master_send); + free(master_recive); + free(master_expect); +} + +static void test_slave_fd_dma(void){ + uint8_t *slave_send = heap_caps_malloc(TEST_STEP_LEN, MALLOC_CAP_DMA); + uint8_t *slave_recive = heap_caps_malloc(TEST_STEP_LEN, MALLOC_CAP_DMA); + uint8_t *slave_expect = heap_caps_malloc(TEST_STEP_LEN, MALLOC_CAP_DEFAULT); + + for(uint8_t is_gpio=0; is_gpio<2; is_gpio++){ + spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); + if (is_gpio) buscfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS; + for(uint8_t mode=0; mode<4; mode++){ + spi_slave_interface_config_t slvcfg = SPI_SLAVE_TEST_DEFAULT_CONFIG(); + slvcfg.mode = mode; + TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO)); + for(uint8_t speed_level=0; speed_level = 10*1000*1000)) continue; //On esp32 with GPIO Matrix, clk freq <= 10MHz +#endif + printf("Next trans: %s\tmode:%d\t@%.2f MHz\n", (is_gpio)?"GPIO_Matrix":"IOMUX", mode, s_spi_bus_freq[speed_level]/1000000.f); + 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); + + uint32_t test_trans_len = TEST_STEP_LEN; + spi_slave_transaction_t trans_cfg = { + .tx_buffer = slave_send, + .rx_buffer = slave_recive, + .length = test_trans_len * 8, + }; + unity_send_signal("Slave ready"); + TEST_ESP_OK(spi_slave_transmit(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY)); + + ESP_LOG_BUFFER_HEX("slave tx", slave_send, test_trans_len); + ESP_LOG_BUFFER_HEX_LEVEL("slave rx", slave_recive, test_trans_len, ESP_LOG_DEBUG); + ESP_LOG_BUFFER_HEX_LEVEL("slave exp", slave_expect, test_trans_len, ESP_LOG_DEBUG); + spitest_cmp_or_dump(slave_expect, slave_recive, test_trans_len); + } + } + TEST_ESP_OK(spi_slave_free(TEST_SPI_HOST)); + } + } + free(slave_send); + free(slave_recive); + free(slave_expect); +} + +TEST_CASE_MULTIPLE_DEVICES("TEST_SPI_Freq_FD_DMA", "[spi_ms][timeout=30]", test_master_fd_dma, test_slave_fd_dma); + + +//------------------------------------------- Full Duplex no DMA Freq test -------------------------------------- +static void test_master_fd_no_dma(void){ + spi_device_handle_t dev0; + uint8_t *master_send = heap_caps_malloc(SOC_SPI_MAXIMUM_BUFFER_SIZE, MALLOC_CAP_DMA); + uint8_t *master_recive = heap_caps_malloc(SOC_SPI_MAXIMUM_BUFFER_SIZE, MALLOC_CAP_DMA); + uint8_t *master_expect = heap_caps_malloc(SOC_SPI_MAXIMUM_BUFFER_SIZE, MALLOC_CAP_DEFAULT); + + for(uint8_t is_gpio=0; is_gpio<2; is_gpio++){ + for(uint8_t mode=0; mode<4; mode++){ + spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); + if (is_gpio) buscfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS; + TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_DISABLED)); + + for(uint8_t speed_level=0; speed_level = 10*1000*1000)) continue; //On esp32 with GPIO Matrix, clk freq <= 10MHz + devcfg.cs_ena_pretrans = 2, + devcfg.input_delay_ns = 12.5*2, +#endif + TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &dev0)); + printf("Next trans: %s\tmode:%d\t@%.2f MHz\n", (is_gpio)?"GPIO_Matrix":"IOMUX", mode, s_spi_bus_freq[speed_level]/1000000.f); + + 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); + + uint32_t test_trans_len = SOC_SPI_MAXIMUM_BUFFER_SIZE; + spi_transaction_t trans_cfg = { + .tx_buffer = master_send, + .rx_buffer = master_recive, + .length = test_trans_len * 8, + }; + unity_wait_for_signal("Slave ready"); + TEST_ESP_OK(spi_device_transmit(dev0, &trans_cfg)); + + ESP_LOG_BUFFER_HEX("master tx", master_send, test_trans_len); + ESP_LOG_BUFFER_HEX_LEVEL("master rx", master_recive, test_trans_len, ESP_LOG_DEBUG); + ESP_LOG_BUFFER_HEX_LEVEL("master exp", master_expect, test_trans_len, ESP_LOG_DEBUG); + spitest_cmp_or_dump(master_expect, master_recive, test_trans_len); + } + TEST_ESP_OK(spi_bus_remove_device(dev0)); + } + TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST)); + } + } + free(master_send); + free(master_recive); + free(master_expect); +} + +static void test_slave_fd_no_dma(void){ + uint8_t *slave_send = heap_caps_malloc(SOC_SPI_MAXIMUM_BUFFER_SIZE, MALLOC_CAP_DMA); + uint8_t *slave_recive = heap_caps_malloc(SOC_SPI_MAXIMUM_BUFFER_SIZE, MALLOC_CAP_DMA); + uint8_t *slave_expect = heap_caps_malloc(SOC_SPI_MAXIMUM_BUFFER_SIZE, MALLOC_CAP_DEFAULT); + + for(uint8_t is_gpio=0; is_gpio<2; is_gpio++){ + spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); + if (is_gpio) buscfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS; + for(uint8_t mode=0; mode<4; mode++){ + spi_slave_interface_config_t slvcfg = SPI_SLAVE_TEST_DEFAULT_CONFIG(); + slvcfg.mode = mode; + TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_DISABLED)); + + for(uint8_t speed_level=0; speed_level = 10*1000*1000)) continue; //On esp32 with GPIO Matrix, clk freq <= 10MHz +#endif + printf("Next trans: %s\tmode:%d\t@%.2f MHz\n", (is_gpio)?"GPIO_Matrix":"IOMUX", mode, s_spi_bus_freq[speed_level]/1000000.f); + 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); + + uint32_t test_trans_len = SOC_SPI_MAXIMUM_BUFFER_SIZE; + spi_slave_transaction_t trans_cfg = { + .tx_buffer = slave_send, + .rx_buffer = slave_recive, + .length = test_trans_len * 8, + }; + unity_send_signal("Slave ready"); + TEST_ESP_OK(spi_slave_transmit(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY)); + + ESP_LOG_BUFFER_HEX("slave tx", slave_send, test_trans_len); + ESP_LOG_BUFFER_HEX_LEVEL("slave rx", slave_recive, test_trans_len, ESP_LOG_DEBUG); + ESP_LOG_BUFFER_HEX_LEVEL("slave exp", slave_expect, test_trans_len, ESP_LOG_DEBUG); + spitest_cmp_or_dump(slave_expect, slave_recive, test_trans_len); + } + } + TEST_ESP_OK(spi_slave_free(TEST_SPI_HOST)); + } + } + free(slave_send); + free(slave_recive); + free(slave_expect); +} + +TEST_CASE_MULTIPLE_DEVICES("TEST_SPI_Freq_FD_no_DMA", "[spi_ms][timeout=30]", test_master_fd_no_dma, test_slave_fd_no_dma); + + +#if SOC_SPI_SUPPORT_SLAVE_HD_VER2 +//------------------------------------------- Half Duplex with DMA Freq test -------------------------------------- +static void test_master_hd_dma(void){ + spi_device_handle_t dev0; + uint8_t *master_send = heap_caps_malloc(TEST_STEP_LEN, MALLOC_CAP_DMA); + uint8_t *master_recive = heap_caps_malloc(TEST_STEP_LEN, MALLOC_CAP_DMA); + uint8_t *master_expect = heap_caps_malloc(TEST_STEP_LEN, MALLOC_CAP_DEFAULT); + + for(uint8_t is_gpio=0; is_gpio<2; is_gpio++){ + for(uint8_t mode=0; mode<4; mode++){ + spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); + if (is_gpio) buscfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS; + TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); + + for(uint8_t speed_level=0; speed_level