Skip to content

Commit

Permalink
Merge branch 'bugfix/fix_spi_hd_quad_issue_esp32c3' into 'master'
Browse files Browse the repository at this point in the history
essl_spi: fix wrong dummy cycle under quad spi mode ant add a test to verify spi quad mod

Closes IDF-5182 and IDF-5181

See merge request espressif/esp-idf!18680
  • Loading branch information
Gao Xu committed Aug 30, 2022
2 parents f8c3d09 + ec649b0 commit 0da21ac
Show file tree
Hide file tree
Showing 17 changed files with 777 additions and 224 deletions.
25 changes: 25 additions & 0 deletions .gitlab/ci/target-test.yml
Expand Up @@ -990,6 +990,31 @@ UT_S2_SPI_DUAL:
- ESP32S2_IDF
- Example_SPI_Multi_device

UT_S2_SPI_QUAD:
extends: .unit_test_esp32s2_template
tags:
- ESP32S2_IDF
- Example_SPI_Quad_Multi_device

UT_S3_SPI_QUAD:
extends: .unit_test_esp32s3_template
tags:
- ESP32S3_IDF
- Example_SPI_Quad_Multi_device

UT_C2_SPI_QUAD:
extends: .unit_test_esp32c2_template
tags:
- ESP32C2_IDF
- Example_SPI_Quad_Multi_device
- xtal_40mhz

UT_C3_SPI_QUAD:
extends: .unit_test_esp32c3_template
tags:
- ESP32C3_IDF
- Example_SPI_Quad_Multi_device

UT_S2_SDSPI:
extends: .unit_test_esp32s2_template
tags:
Expand Down
7 changes: 7 additions & 0 deletions components/driver/test/include/test/test_common_spi.h
Expand Up @@ -298,6 +298,13 @@ void same_pin_func_sel(spi_bus_config_t bus, spi_device_interface_config_t dev,

/**
* 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_
4 changes: 2 additions & 2 deletions components/driver/test/test_common_spi.c
Expand Up @@ -245,7 +245,7 @@ void get_tx_buffer(uint32_t seed, uint8_t *master_send_buf, uint8_t *slave_send_
{
srand(seed);
for (int i = 0; i < send_buf_size; i++) {
slave_send_buf[i] = rand();
master_send_buf[i] = rand();
slave_send_buf[i] = rand() % 256;
master_send_buf[i] = rand() % 256;
}
}
164 changes: 148 additions & 16 deletions components/driver/test/test_spi_slave_hd.c
Expand Up @@ -16,16 +16,14 @@
#include "soc/spi_periph.h"
#include "driver/spi_master.h"
#include "esp_serial_slave_link/essl_spi.h"


#if (TEST_SPI_PERIPH_NUM >= 2)
//These will be only enabled on chips with 2 or more SPI peripherals
#include "test/test_common_spi.h"

#if SOC_SPI_SUPPORT_SLAVE_HD_VER2
#include "driver/spi_slave_hd.h"

#if (TEST_SPI_PERIPH_NUM >= 2) //These will be only enabled on chips with 2 or more SPI peripherals

#include "esp_rom_gpio.h"
#include "unity.h"
#include "test/test_common_spi.h"

#define TEST_DMA_MAX_SIZE 4092
#define TEST_BUFFER_SIZE 256 ///< buffer size of each wrdma buffer in fifo mode
Expand Down Expand Up @@ -57,7 +55,6 @@ typedef struct {
spi_slave_hd_data_t rx_data;
} testhd_context_t;


static uint32_t get_hd_flags(void)
{
#if !defined(SLAVE_SUPPORT_QIO)
Expand Down Expand Up @@ -595,13 +592,9 @@ TEST_CASE("test spi slave hd segment mode, master too long", "[spi][spi_slv_hd]"
master_free_device_bus(spi);
}

#endif //SOC_SPI_SUPPORT_SLAVE_HD_VER2
#endif //#if (TEST_SPI_PERIPH_NUM >= 2)


#if (TEST_SPI_PERIPH_NUM == 1)
#if SOC_SPI_SUPPORT_SLAVE_HD_VER2
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//These tests are for chips which only have 1 SPI controller
/********************************************************************************
* Test By Master & Slave (2 boards)
Expand All @@ -616,9 +609,6 @@ TEST_CASE("test spi slave hd segment mode, master too long", "[spi][spi_slv_hd]"
* GND | GND | GND |
*
********************************************************************************/
#include "driver/spi_slave_hd.h"
#include "unity.h"
#include "test/test_common_spi.h"

static void hd_master(void)
{
Expand Down Expand Up @@ -749,6 +739,148 @@ static void hd_slave(void)
}

TEST_CASE_MULTIPLE_DEVICES("SPI Slave HD: segment mode, master sends too long", "[spi_ms][test_env=Example_SPI_Multi_device]", hd_master, hd_slave);
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(...)
#endif //#if SOC_SPI_SUPPORT_SLAVE_HD_VER2
#endif //#if (TEST_SPI_PERIPH_NUM == 1)

/**
* TODO IDF-5483
**/
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)

#define BUF_SIZE 256

static void hd_master_quad(void){
spi_bus_config_t bus_cfg = {
.miso_io_num = PIN_NUM_MISO,
.mosi_io_num = PIN_NUM_MOSI,
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = PIN_NUM_WP,
.quadhd_io_num = PIN_NUM_HD
};

TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, SPI_DMA_CH_AUTO));

spi_device_handle_t spi;
spi_device_interface_config_t dev_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
dev_cfg.flags = SPI_DEVICE_HALFDUPLEX;
dev_cfg.command_bits = 8;
dev_cfg.address_bits = 8;
dev_cfg.dummy_bits = 8;
dev_cfg.clock_speed_hz = 100 * 1000;

TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi));

WORD_ALIGNED_ATTR uint8_t *master_send_buf = heap_caps_malloc(BUF_SIZE, MALLOC_CAP_DMA);
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);

unity_wait_for_signal("slave ready");
essl_spi_wrdma(spi, master_send_buf, BUF_SIZE / 2, -1, SPI_TRANS_MODE_QIO);

unity_wait_for_signal("slave ready");
essl_spi_wrdma(spi, master_send_buf + BUF_SIZE / 2, BUF_SIZE / 2, -1, SPI_TRANS_MODE_QIO);

unity_wait_for_signal("slave ready");
essl_spi_rddma(spi, master_recv_buf, BUF_SIZE / 2, -1, SPI_TRANS_MODE_QIO);

unity_wait_for_signal("slave ready");
essl_spi_rddma(spi, master_recv_buf+ BUF_SIZE / 2, BUF_SIZE / 2, -1, SPI_TRANS_MODE_QIO);

ESP_LOG_BUFFER_HEX("slave send", slave_send_buf, BUF_SIZE);
ESP_LOG_BUFFER_HEX("master recv", master_recv_buf, BUF_SIZE);

TEST_ASSERT_EQUAL_HEX8_ARRAY(slave_send_buf, master_recv_buf, BUF_SIZE);

free(master_recv_buf);
free(master_send_buf);
free(slave_send_buf);

master_free_device_bus(spi);
}

static void hd_slave_quad(void){

spi_bus_config_t bus_cfg = {
.miso_io_num = PIN_NUM_MISO,
.mosi_io_num = PIN_NUM_MOSI,
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = PIN_NUM_WP,
.quadhd_io_num = PIN_NUM_HD,
.max_transfer_sz = 14000 * 30
};

spi_slave_hd_slot_config_t slave_hd_cfg = {
.spics_io_num = PIN_NUM_CS,
.dma_chan = SPI_DMA_CH_AUTO,
.flags = 0,
.mode = 0,
.command_bits = 8,
.address_bits = 8,
.dummy_bits = 8,
.queue_size = 10,
};
TEST_ESP_OK(spi_slave_hd_init(TEST_SLAVE_HOST, &bus_cfg, &slave_hd_cfg));

WORD_ALIGNED_ATTR uint8_t *slave_send_buf = heap_caps_malloc(BUF_SIZE, MALLOC_CAP_DMA);
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);

int trans_len = BUF_SIZE / 2;
spi_slave_hd_data_t slave_trans[4] = {
//recv, the buffer size should be aligned to 4
{
.data = slave_recv_buf,
.len = (trans_len + 3) & (~3),
},
{
.data = slave_recv_buf+BUF_SIZE/2,
.len = (trans_len + 3) & (~3),
},
//send
{
.data = slave_send_buf,
.len = (trans_len + 3) & (~3),
},
{
.data = slave_send_buf+BUF_SIZE/2,
.len = (trans_len + 3) & (~3),
},
};

for (int i = 0; i < 2; i ++) {
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_RX, &slave_trans[i], portMAX_DELAY));
unity_send_signal("slave ready");
}
for (int i = 2; i < 4; i ++) {
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &slave_trans[i], portMAX_DELAY));
unity_send_signal("slave ready");
}
for (int i = 0; i < 2; i ++) {
spi_slave_hd_data_t *ret_trans;
TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_RX, &ret_trans, portMAX_DELAY));
}
for (int i = 2; i < 4; i ++) {
spi_slave_hd_data_t *ret_trans;
TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &ret_trans, portMAX_DELAY));
}

ESP_LOG_BUFFER_HEX("master send", master_send_buf, BUF_SIZE);
ESP_LOG_BUFFER_HEX("slave recv", slave_recv_buf, BUF_SIZE);

TEST_ASSERT_EQUAL_HEX8_ARRAY(master_send_buf, slave_recv_buf, BUF_SIZE);

free(slave_recv_buf);
free(slave_send_buf);
free(master_send_buf);

spi_slave_hd_deinit(TEST_SLAVE_HOST);
}

TEST_CASE_MULTIPLE_DEVICES("SPI quad hd test ", "[spi_ms][test_env=Example_SPI_Quad_Multi_device]", hd_master_quad, hd_slave_quad);

#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)

#endif //SOC_SPI_SUPPORT_SLAVE_HD_VER2

0 comments on commit 0da21ac

Please sign in to comment.