1 /*
2  * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "esp_log.h"
7 #include "esp_attr.h"
8 #include "soc/spi_periph.h"
9 #include "sdkconfig.h"
10 #include "test/test_common_spi.h"
11 #include "driver/spi_master.h"
12 #include "driver/spi_slave.h"
13 
14 #if !DISABLED_FOR_TARGETS(ESP32C3)
15 //There is only one GPSPI controller on ESP32C3, so single-board test is disabled.
16 
17 #ifndef MIN
18 #define MIN(a, b)((a) > (b)? (b): (a))
19 #endif
20 
21 /********************************************************************************
22  *      Test By Internal Connections
23  ********************************************************************************/
24 static void local_test_init(void** context);
25 static void local_test_deinit(void* context);
26 static void local_test_loop(const void *test_param, void* context);
27 
28 static const ptest_func_t local_test_func = {
29     .pre_test = local_test_init,
30     .post_test = local_test_deinit,
31     .loop = local_test_loop,
32     .def_param = spitest_def_param,
33 };
34 
35 #define TEST_SPI_LOCAL(name, param_set) \
36     PARAM_GROUP_DECLARE(name, param_set) \
37     TEST_SINGLE_BOARD(SPI_##name, param_set, "[spi][timeout=120]", &local_test_func)
38 
local_test_init(void ** arg)39 static void local_test_init(void** arg)
40 {
41     esp_log_level_set("gpio", ESP_LOG_WARN);
42     TEST_ASSERT(*arg==NULL);
43     *arg = malloc(sizeof(spitest_context_t));
44     spitest_context_t* context = (spitest_context_t*)*arg;
45     TEST_ASSERT(context!=NULL);
46     context->slave_context = (spi_slave_task_context_t){};
47     esp_err_t err = init_slave_context( &context->slave_context);
48     TEST_ASSERT(err == ESP_OK);
49 
50     xTaskCreate(spitest_slave_task, "spi_slave", 4096, &context->slave_context, 0, &context->handle_slave);
51 }
52 
local_test_deinit(void * arg)53 static void local_test_deinit(void* arg)
54 {
55     spitest_context_t* context = arg;
56     vTaskDelete(context->handle_slave);
57     context->handle_slave = 0;
58     deinit_slave_context(&context->slave_context);
59 }
60 
local_test_start(spi_device_handle_t * spi,int freq,const spitest_param_set_t * pset,spitest_context_t * context)61 static void local_test_start(spi_device_handle_t *spi, int freq, const spitest_param_set_t* pset, spitest_context_t* context)
62 {
63     //master config
64     spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
65     spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
66     spi_slave_interface_config_t slvcfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
67     //pin config & initialize
68     //we can't have two sets of iomux pins on the same pins
69     assert(!pset->master_iomux || !pset->slave_iomux);
70     if (pset->slave_iomux) {
71         //only in this case, use VSPI iomux pins
72         buscfg.miso_io_num =  SLAVE_IOMUX_PIN_MISO;
73         buscfg.mosi_io_num =  SLAVE_IOMUX_PIN_MOSI;
74         buscfg.sclk_io_num =  SLAVE_IOMUX_PIN_SCLK;
75         devcfg.spics_io_num = SLAVE_IOMUX_PIN_CS;
76         slvcfg.spics_io_num = SLAVE_IOMUX_PIN_CS;
77     } else {
78         buscfg.miso_io_num =  MASTER_IOMUX_PIN_MISO;
79         buscfg.mosi_io_num =  MASTER_IOMUX_PIN_MOSI;
80         buscfg.sclk_io_num =  MASTER_IOMUX_PIN_SCLK;
81         devcfg.spics_io_num = MASTER_IOMUX_PIN_CS;
82         slvcfg.spics_io_num = MASTER_IOMUX_PIN_CS;
83     }
84     //this does nothing, but avoid the driver from using iomux pins if required
85     buscfg.quadhd_io_num = (!pset->master_iomux && !pset->slave_iomux ? UNCONNECTED_PIN : -1);
86     devcfg.mode = pset->mode;
87     const int cs_pretrans_max = 15;
88     if (pset->dup == HALF_DUPLEX_MISO) {
89         devcfg.cs_ena_pretrans = cs_pretrans_max;
90         devcfg.flags |= SPI_DEVICE_HALFDUPLEX;
91     } else if (pset->dup == HALF_DUPLEX_MOSI) {
92         devcfg.cs_ena_pretrans = cs_pretrans_max;
93         devcfg.flags |= SPI_DEVICE_NO_DUMMY;
94     } else {
95         devcfg.cs_ena_pretrans = cs_pretrans_max;
96     }
97     const int cs_posttrans_max = 15;
98     devcfg.cs_ena_posttrans = cs_posttrans_max;
99     devcfg.input_delay_ns = pset->slave_tv_ns;
100     devcfg.clock_speed_hz = freq;
101     if (pset->master_limit != 0 && freq > pset->master_limit) devcfg.flags |= SPI_DEVICE_NO_DUMMY;
102 
103     //slave config
104     slvcfg.mode = pset->mode;
105     slave_pull_up(&buscfg, slvcfg.spics_io_num);
106 
107     int dma_chan = (pset->master_dma_chan == 0) ? 0 : SPI_DMA_CH_AUTO;
108     TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, dma_chan));
109     TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, spi));
110 
111     //slave automatically use iomux pins if pins are on VSPI_* pins
112     buscfg.quadhd_io_num = -1;
113     int slave_dma_chan = (pset->slave_dma_chan == 0) ? 0 : SPI_DMA_CH_AUTO;
114     TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &buscfg, &slvcfg, slave_dma_chan));
115 
116     //initialize master and slave on the same pins break some of the output configs, fix them
117     if (pset->master_iomux) {
118         spitest_gpio_output_sel(buscfg.mosi_io_num, FUNC_SPI, spi_periph_signal[TEST_SPI_HOST].spid_out);
119         spitest_gpio_output_sel(buscfg.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
120         spitest_gpio_output_sel(devcfg.spics_io_num, FUNC_SPI, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
121         spitest_gpio_output_sel(buscfg.sclk_io_num, FUNC_SPI, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
122     } else if (pset->slave_iomux) {
123         spitest_gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
124         spitest_gpio_output_sel(buscfg.miso_io_num, FUNC_SPI, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
125         spitest_gpio_output_sel(devcfg.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
126         spitest_gpio_output_sel(buscfg.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
127     } else {
128         spitest_gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
129         spitest_gpio_output_sel(buscfg.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
130         spitest_gpio_output_sel(devcfg.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
131         spitest_gpio_output_sel(buscfg.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
132     }
133 
134     if (context) {
135         //clear master receive buffer
136         memset(context->master_rxbuf, 0x66, sizeof(context->master_rxbuf));
137     }
138 }
139 
local_test_end(spi_device_handle_t spi)140 static void local_test_end(spi_device_handle_t spi)
141 {
142     master_free_device_bus(spi);
143     TEST_ASSERT(spi_slave_free(TEST_SLAVE_HOST) == ESP_OK);
144 }
145 
local_test_loop(const void * arg1,void * arg2)146 static void local_test_loop(const void* arg1, void* arg2)
147 {
148     const spitest_param_set_t *pset = arg1;
149     spitest_context_t *context = arg2;
150     spi_device_handle_t spi;
151     spitest_init_transactions(pset, context);
152     const int *timing_speed_array = pset->freq_list;
153 
154     ESP_LOGI(MASTER_TAG, "****************** %s ***************", pset->pset_name);
155     for (int i = 0; ; i++) {
156         const int freq = timing_speed_array[i];
157         if (freq==0) break;
158         if (pset->freq_limit && freq > pset->freq_limit) break;
159 
160         ESP_LOGI(MASTER_TAG, "==> %dkHz", freq / 1000);
161 
162         bool check_master_data = (pset->dup!=HALF_DUPLEX_MOSI &&
163                 (pset->master_limit==0 || freq <= pset->master_limit));
164         if (!check_master_data) ESP_LOGI(MASTER_TAG, "skip master data check");
165 
166         bool check_slave_data = (pset->dup!=HALF_DUPLEX_MISO);
167         if (!check_slave_data) ESP_LOGI(SLAVE_TAG, "skip slave data check");
168 
169         local_test_start(&spi, freq, pset, context);
170 
171         for (int k = 0; k < pset->test_size; k++) {
172             WORD_ALIGNED_ATTR uint8_t recvbuf[320+8];
173             slave_txdata_t *txdata = &context->slave_trans[k];
174             spi_slave_transaction_t slave_trans = {
175                 .tx_buffer = txdata->start,
176                 .rx_buffer = recvbuf,
177                 .length = txdata->len,
178             };
179             esp_err_t err = spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_trans, portMAX_DELAY);
180             TEST_ESP_OK(err);
181 
182             //wait for both master and slave end
183             spi_transaction_t *t = &context->master_trans[k];
184             int len = get_trans_len(pset->dup, t);
185             ESP_LOGI(MASTER_TAG, "  ==> #%d: len: %d", k, len);
186             //send master tx data
187 
188             err = spi_device_transmit(spi, t);
189             TEST_ESP_OK(err);
190 
191             spi_slave_transaction_t *ret_trans;
192             err = spi_slave_get_trans_result(TEST_SLAVE_HOST, &ret_trans, 5);
193             TEST_ESP_OK(err);
194             TEST_ASSERT_EQUAL(&slave_trans, ret_trans);
195 
196             uint32_t rcv_len = slave_trans.trans_len;
197             bool failed = false;
198 
199             //check master data
200             if (check_master_data && memcmp(slave_trans.tx_buffer, t->rx_buffer, (len + 7) / 8) != 0 ) {
201                 failed = true;
202             }
203 
204             //check slave data and length
205             //currently the rcv_len can be in range of [t->length-1, t->length+3]
206             if ( rcv_len < len - 1 || rcv_len > len + 4) {
207                 failed = true;
208             }
209             if (check_slave_data && memcmp(t->tx_buffer, slave_trans.rx_buffer, (len + 7) / 8) != 0 ) {
210                 failed = true;
211             }
212 
213             if (failed) {
214                 ESP_LOGI(SLAVE_TAG, "slave_recv_len: %d", rcv_len);
215                 spitest_master_print_data(t, len);
216 
217                 ESP_LOG_BUFFER_HEX("slave tx", slave_trans.tx_buffer, len);
218                 ESP_LOG_BUFFER_HEX("slave rx", slave_trans.rx_buffer, len);
219 
220                 //already failed, try to use the TEST_ASSERT to output the reason...
221                 TEST_ASSERT_EQUAL_HEX8_ARRAY(slave_trans.tx_buffer, t->rx_buffer, (len + 7) / 8);
222                 TEST_ASSERT_EQUAL_HEX8_ARRAY(t->tx_buffer, slave_trans.rx_buffer, (len + 7) / 8);
223                 TEST_ASSERT(rcv_len >= len - 1 && rcv_len <= len + 4);
224             }
225         }
226         local_test_end(spi);
227     }
228 }
229 
230 /************ Timing Test ***********************************************/
231 //TODO: esp32s2 has better timing performance
232 static spitest_param_set_t timing_pgroup[] = {
233 //signals are not fed to peripherals through iomux if the functions are not selected to iomux
234 #if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
235     {   .pset_name = "FULL_DUP, MASTER IOMUX",
236         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
237         .master_limit = SPI_MASTER_FREQ_13M,
238         .dup = FULL_DUPLEX,
239         .master_iomux = true,
240         .slave_iomux = false,
241         .slave_tv_ns = TV_INT_CONNECT_GPIO,
242     },
243     {   .pset_name = "FULL_DUP, SLAVE IOMUX",
244         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
245         .master_limit = SPI_MASTER_FREQ_13M,
246         .dup = FULL_DUPLEX,
247         .master_iomux = false,
248         .slave_iomux = true,
249         .slave_tv_ns = TV_INT_CONNECT,
250     },
251 #endif
252     {   .pset_name = "FULL_DUP, BOTH GPIO",
253         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
254         .master_limit = SPI_MASTER_FREQ_10M,
255         .dup = FULL_DUPLEX,
256         .master_iomux = false,
257         .slave_iomux = false,
258         .slave_tv_ns = TV_INT_CONNECT_GPIO,
259     },
260 //signals are not fed to peripherals through iomux if the functions are not selected to iomux
261 #if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
262     {   .pset_name = "MISO_DUP, MASTER IOMUX",
263         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
264         .master_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
265         .dup = HALF_DUPLEX_MISO,
266         .master_iomux = true,
267         .slave_iomux = false,
268         .slave_tv_ns = TV_INT_CONNECT_GPIO,
269     },
270     {   .pset_name = "MISO_DUP, SLAVE IOMUX",
271         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
272         //.freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
273         .dup = HALF_DUPLEX_MISO,
274         .master_iomux = false,
275         .slave_iomux = true,
276         .slave_tv_ns = TV_INT_CONNECT,
277     },
278 #endif
279     {   .pset_name = "MISO_DUP, BOTH GPIO",
280         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
281         //.freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
282         .dup = HALF_DUPLEX_MISO,
283         .master_iomux = false,
284         .slave_iomux = false,
285         .slave_tv_ns = TV_INT_CONNECT_GPIO,
286     },
287 //signals are not fed to peripherals through iomux if the functions are not selected to iomux
288 #if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
289     {   .pset_name = "MOSI_DUP, MASTER IOMUX",
290         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
291         //.freq_limit = ESP_SPI_SLAVE_MAX_READ_FREQ, //ESP_SPI_SLAVE_MAX_FREQ_SYNC,
292         .dup = HALF_DUPLEX_MOSI,
293         .master_iomux = true,
294         .slave_iomux = false,
295         .slave_tv_ns = TV_INT_CONNECT_GPIO,
296     },
297     {   .pset_name = "MOSI_DUP, SLAVE IOMUX",
298         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
299         //.freq_limit = ESP_SPI_SLAVE_MAX_READ_FREQ, //ESP_SPI_SLAVE_MAX_FREQ_SYNC,
300         .dup = HALF_DUPLEX_MOSI,
301         .master_iomux = false,
302         .slave_iomux = true,
303         .slave_tv_ns = TV_INT_CONNECT,
304     },
305 #endif
306     {   .pset_name = "MOSI_DUP, BOTH GPIO",
307         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
308         //.freq_limit = ESP_SPI_SLAVE_MAX_READ_FREQ, //ESP_SPI_SLAVE_MAX_FREQ_SYNC,
309         .dup = HALF_DUPLEX_MOSI,
310         .master_iomux = false,
311         .slave_iomux = false,
312         .slave_tv_ns = TV_INT_CONNECT_GPIO,
313     },
314 };
315 TEST_SPI_LOCAL(TIMING, timing_pgroup)
316 
317 /************ Mode Test ***********************************************/
318 #define FREQ_LIMIT_MODE SPI_MASTER_FREQ_16M
319 static int test_freq_mode_local[]={
320     1*1000*1000,
321     SPI_MASTER_FREQ_9M, //maximum freq MISO stable before next latch edge
322     SPI_MASTER_FREQ_13M,
323     SPI_MASTER_FREQ_16M,
324     SPI_MASTER_FREQ_20M,
325     SPI_MASTER_FREQ_26M,
326     SPI_MASTER_FREQ_40M,
327     0,
328 };
329 
330 //signals are not fed to peripherals through iomux if the functions are not selected to iomux
331 #ifdef CONFIG_IDF_TARGET_ESP32
332 #define LOCAL_MODE_TEST_SLAVE_IOMUX     true
333 
334 /*
335  * When DMA is enabled in mode 0 and 2, an special workaround is used. The MISO (slave's output) is
336  * half an SPI clock ahead, but then delay 3 apb clocks.
337 
338  * Compared to the normal timing, the MISO is not slower than when the frequency is below 13.3MHz,
339  * under which there's no need for the master to compensate the MISO signal. However compensation
340  * is required when the frequency is beyond 16MHz, at this time, an extra positive delay is added
341  * to the normal delay (3 apb clocks).
342  *
343  * It's is hard to tell the master driver that kind of delay logic. This magic delay value happens
344  * to compensate master timing beyond 16MHz.
345  *
346  * If the master or slave's timing is changed again, and the test no longer passes, above 16MHz,
347  * it's OK to use `master_limit` to disable master data check or skip the test above some
348  * frequencies above 10MHz (the design target value).
349  */
350 #define SLAVE_EXTRA_DELAY_DMA           12.5
351 #else
352 #define LOCAL_MODE_TEST_SLAVE_IOMUX     false
353 #define SLAVE_EXTRA_DELAY_DMA           0
354 #endif
355 
356 
357 static spitest_param_set_t mode_pgroup[] = {
358     {   .pset_name = "Mode 0",
359         .freq_list = test_freq_mode_local,
360         .master_limit = SPI_MASTER_FREQ_13M,
361         .dup = FULL_DUPLEX,
362         .mode = 0,
363         .master_iomux = false,
364         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
365         .slave_tv_ns = TV_INT_CONNECT,
366     },
367     {   .pset_name = "Mode 1",
368         .freq_list = test_freq_mode_local,
369         .freq_limit = SPI_MASTER_FREQ_26M,
370         .master_limit = SPI_MASTER_FREQ_13M,
371         .dup = FULL_DUPLEX,
372         .mode = 1,
373         .master_iomux = false,
374         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
375         .slave_tv_ns = TV_INT_CONNECT,
376     },
377     {   .pset_name = "Mode 2",
378         .freq_list = test_freq_mode_local,
379         .master_limit = SPI_MASTER_FREQ_13M,
380         .dup = FULL_DUPLEX,
381         .mode = 2,
382         .master_iomux = false,
383         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
384         .slave_tv_ns = TV_INT_CONNECT,
385     },
386     {   .pset_name = "Mode 3",
387         .freq_list = test_freq_mode_local,
388         .freq_limit = SPI_MASTER_FREQ_26M,
389         .master_limit = SPI_MASTER_FREQ_13M,
390         .dup = FULL_DUPLEX,
391         .mode = 3,
392         .master_iomux = false,
393         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
394         .slave_tv_ns = TV_INT_CONNECT,
395     },
396     {   .pset_name = "Mode 0, DMA",
397         .freq_list = test_freq_mode_local,
398         .master_limit = SPI_MASTER_FREQ_13M,
399         .dup = FULL_DUPLEX,
400         .mode = 0,
401         .slave_dma_chan = SPI_DMA_CH_AUTO,
402         .master_iomux = false,
403         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
404         .slave_tv_ns = TV_INT_CONNECT,
405         .length_aligned = true,
406     },
407     {   .pset_name = "Mode 1, DMA",
408         .freq_list = test_freq_mode_local,
409         .freq_limit = SPI_MASTER_FREQ_26M,
410         .master_limit = SPI_MASTER_FREQ_13M,
411         .dup = FULL_DUPLEX,
412         .mode = 1,
413         .slave_dma_chan = SPI_DMA_CH_AUTO,
414         .master_iomux = false,
415         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
416         .slave_tv_ns = TV_INT_CONNECT,
417         .length_aligned = true,
418     },
419     {   .pset_name = "Mode 2, DMA",
420         .freq_list = test_freq_mode_local,
421         .master_limit = SPI_MASTER_FREQ_13M,
422         .dup = FULL_DUPLEX,
423         .mode = 2,
424         .slave_dma_chan = SPI_DMA_CH_AUTO,
425         .master_iomux = false,
426         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
427         .slave_tv_ns = TV_INT_CONNECT,
428         .length_aligned = true,
429     },
430     {   .pset_name = "Mode 3, DMA",
431         .freq_list = test_freq_mode_local,
432         .freq_limit = SPI_MASTER_FREQ_26M,
433         .master_limit = SPI_MASTER_FREQ_13M,
434         .dup = FULL_DUPLEX,
435         .mode = 3,
436         .slave_dma_chan = SPI_DMA_CH_AUTO,
437         .master_iomux = false,
438         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
439         .slave_tv_ns = TV_INT_CONNECT,
440         .length_aligned = true,
441     },
442     /////////////////////////// MISO ////////////////////////////////////
443     {   .pset_name = "MISO, Mode 0",
444         .freq_list = test_freq_mode_local,
445         .dup = HALF_DUPLEX_MISO,
446         .mode = 0,
447         .master_iomux = false,
448         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
449         .slave_tv_ns = TV_INT_CONNECT,
450     },
451     {   .pset_name = "MISO, Mode 1",
452         .freq_list = test_freq_mode_local,
453         .dup = HALF_DUPLEX_MISO,
454         .mode = 1,
455         .master_iomux = false,
456         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
457         .slave_tv_ns = TV_INT_CONNECT,
458     },
459     {   .pset_name = "MISO, Mode 2",
460         .freq_list = test_freq_mode_local,
461         .dup = HALF_DUPLEX_MISO,
462         .mode = 2,
463         .master_iomux = false,
464         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
465         .slave_tv_ns = TV_INT_CONNECT,
466     },
467     {   .pset_name = "MISO, Mode 3",
468         .freq_list = test_freq_mode_local,
469         .dup = HALF_DUPLEX_MISO,
470         .mode = 3,
471         .master_iomux = false,
472         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
473         .slave_tv_ns = TV_INT_CONNECT,
474     },
475     {   .pset_name = "MISO, Mode 0, DMA",
476         .freq_list = test_freq_mode_local,
477         .dup = HALF_DUPLEX_MISO,
478         .mode = 0,
479         .slave_dma_chan = SPI_DMA_CH_AUTO,
480         .master_iomux = false,
481         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
482         .slave_tv_ns = TV_INT_CONNECT+SLAVE_EXTRA_DELAY_DMA,
483         .length_aligned = true,
484     },
485     {   .pset_name = "MISO, Mode 1, DMA",
486         .freq_list = test_freq_mode_local,
487         .dup = HALF_DUPLEX_MISO,
488         .mode = 1,
489         .slave_dma_chan = SPI_DMA_CH_AUTO,
490         .master_iomux = false,
491         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
492         .slave_tv_ns = TV_INT_CONNECT,
493         .length_aligned = true,
494     },
495     {   .pset_name = "MISO, Mode 2, DMA",
496         .freq_list = test_freq_mode_local,
497         .dup = HALF_DUPLEX_MISO,
498         .mode = 2,
499         .slave_dma_chan = SPI_DMA_CH_AUTO,
500         .master_iomux = false,
501         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
502         .slave_tv_ns = TV_INT_CONNECT+SLAVE_EXTRA_DELAY_DMA,
503         .length_aligned = true,
504     },
505     {   .pset_name = "MISO, Mode 3, DMA",
506         .freq_list = test_freq_mode_local,
507         .dup = HALF_DUPLEX_MISO,
508         .mode = 3,
509         .slave_dma_chan = SPI_DMA_CH_AUTO,
510         .master_iomux = false,
511         .slave_iomux = LOCAL_MODE_TEST_SLAVE_IOMUX,
512         .slave_tv_ns = TV_INT_CONNECT,
513         .length_aligned = true,
514     },
515 };
TEST_SPI_LOCAL(MODE,mode_pgroup)516 TEST_SPI_LOCAL(MODE, mode_pgroup)
517 
518 /**********************SPI master slave transaction length test*************/
519 /* Test SPI slave can receive different length of data in all 4 modes (permutations of
520  * CPOL/CPHA and when DMA is used or not).
521  * Length from 1 to 16 bytes are tested.
522 */
523 
524 #define MASTER_DATA_RAND_SEED 123
525 #define SLAVE_DATA_RAND_SEED 456
526 
527 TEST_CASE("Slave receive correct data", "[spi]")
528 {
529    // Initialize device handle and spi bus
530     uint32_t master_seed_send = MASTER_DATA_RAND_SEED;
531     uint32_t slave_seed_send = SLAVE_DATA_RAND_SEED;
532     uint32_t master_seed_cmp = slave_seed_send;
533     uint32_t slave_seed_cmp = master_seed_send;
534 
535     const int buf_size = 20;
536 
537     WORD_ALIGNED_ATTR uint8_t slave_sendbuf[buf_size];
538     WORD_ALIGNED_ATTR uint8_t slave_recvbuf[buf_size];
539     WORD_ALIGNED_ATTR uint8_t master_sendbuf[buf_size];
540     WORD_ALIGNED_ATTR uint8_t master_recvbuf[buf_size];
541 
542     uint8_t master_cmpbuf[buf_size];
543     uint8_t slave_cmpbuf[buf_size];
544 
545     for (int spi_mode = 0; spi_mode < 4; spi_mode++) {
546         for (int dma_chan = 0; dma_chan < 2; dma_chan++) {
547             spi_device_handle_t spi;
548             spitest_param_set_t test_param = {
549                 .dup = FULL_DUPLEX,
550                 .mode = spi_mode,
551                 .master_iomux = false,
552                 .slave_iomux = false,
553                 .master_dma_chan = 0,
554                 .slave_dma_chan = (dma_chan ? SPI_DMA_CH_AUTO: 0),
555             };
556             ESP_LOGI(SLAVE_TAG, "Test slave recv @ mode %d, dma enabled=%d", spi_mode, dma_chan);
557 
558             local_test_start(&spi, 1000*1000, &test_param, NULL);
559 
560             for (int round = 0; round < 20; round++) {
561                 // printf("trans %d\n", round);
562                 int master_trans_len = round + 1;
563                 const int slave_trans_len = 16;
564 
565                 memset(master_sendbuf, 0xcc, buf_size);
566                 memset(slave_sendbuf, 0x55, buf_size);
567                 memset(master_recvbuf, 0xaa, buf_size);
568                 memset(slave_recvbuf, 0xbb, buf_size);
569 
570                 for(int i = 0; i < master_trans_len; i++){
571                     master_sendbuf[i] = rand_r(&master_seed_send);
572                     slave_sendbuf[i] = rand_r(&slave_seed_send);
573                 }
574 
575                 spi_slave_transaction_t slave_trans = {
576                     .length = slave_trans_len * 8,
577                     .tx_buffer = slave_sendbuf,
578                     .rx_buffer = slave_recvbuf
579                 };
580                 esp_err_t ret= spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_trans, portMAX_DELAY);
581                 TEST_ESP_OK(ret);
582 
583                 spi_transaction_t master_trans = {
584                     .length = 8 * master_trans_len,
585                     .tx_buffer = master_sendbuf,
586                     .rx_buffer = master_recvbuf
587                 };
588                 ret = spi_device_transmit(spi, &master_trans);
589                 TEST_ESP_OK(ret);
590 
591                 spi_slave_transaction_t *out_trans;
592                 ret = spi_slave_get_trans_result(TEST_SLAVE_HOST, &out_trans, portMAX_DELAY);
593                 TEST_ESP_OK(ret);
594                 TEST_ASSERT_EQUAL_HEX32(&slave_trans, out_trans);
595 
596                 for(int i = 0; i < master_trans_len; i++){
597                     master_cmpbuf[i] = rand_r(&master_seed_cmp);
598                     slave_cmpbuf[i] = rand_r(&slave_seed_cmp);
599                 }
600 
601                 // esp_log_buffer_hex("master_send", master_sendbuf, buf_size);
602                 // esp_log_buffer_hex("slave_recv", slave_recvbuf, buf_size);
603 
604                 // esp_log_buffer_hex("slave_send", slave_sendbuf, buf_size);
605                 // esp_log_buffer_hex("master_recv", master_recvbuf, buf_size);
606 
607                 int master_expected_len = MIN(master_trans_len, slave_trans_len);
608                 TEST_ASSERT_EQUAL_HEX8_ARRAY(master_cmpbuf, master_recvbuf, master_expected_len);
609 
610                 int slave_expected_len;
611                 if (dma_chan) {
612                     slave_expected_len = (master_expected_len & (~3));
613                 } else {
614                     slave_expected_len = master_expected_len;
615                 }
616                 if (slave_expected_len) {
617                     TEST_ASSERT_EQUAL_HEX8_ARRAY(slave_cmpbuf, slave_recvbuf, slave_expected_len);
618                 }
619             }
620             local_test_end(spi);
621         }
622     }
623 }
624 
625 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
626 //These tests are ESP32 only due to lack of runners
627 /********************************************************************************
628  *      Test By Master & Slave (2 boards)
629  *
630  *  Wiring:
631  * | Master | Slave |
632  * | ------ | ----- |
633  * | 12     | 19    |
634  * | 13     | 23    |
635  * | 14     | 18    |
636  * | 15     | 5     |
637  * | GND    | GND   |
638  *
639  ********************************************************************************/
640 static void test_master_init(void** context);
641 static void test_master_deinit(void* context);
642 static void test_master_loop(const void *test_cfg, void* context);
643 
644 static const ptest_func_t master_test_func = {
645     .pre_test = test_master_init,
646     .post_test = test_master_deinit,
647     .loop = test_master_loop,
648     .def_param = spitest_def_param,
649 };
650 
651 static void test_slave_init(void** context);
652 static void test_slave_deinit(void* context);
653 static void test_slave_loop(const void *test_cfg, void* context);
654 
655 static const ptest_func_t slave_test_func = {
656     .pre_test = test_slave_init,
657     .post_test = test_slave_deinit,
658     .loop = test_slave_loop,
659     .def_param = spitest_def_param,
660 };
661 
662 #define TEST_SPI_MASTER_SLAVE(name, param_group, extra_tag) \
663     PARAM_GROUP_DECLARE(name, param_group) \
664     TEST_MASTER_SLAVE(name, param_group, "[spi_ms][test_env=Example_SPI_Multi_device][timeout=120]"#extra_tag, &master_test_func, &slave_test_func)
665 
666 /************ Master Code ***********************************************/
test_master_init(void ** arg)667 static void test_master_init(void** arg)
668 {
669     TEST_ASSERT(*arg==NULL);
670     *arg = malloc(sizeof(spitest_context_t));
671     spitest_context_t* context = *arg;
672     TEST_ASSERT(context!=NULL);
673     context->slave_context = (spi_slave_task_context_t){};
674     esp_err_t err = init_slave_context(&context->slave_context);
675     TEST_ASSERT(err == ESP_OK);
676 }
677 
test_master_deinit(void * arg)678 static void test_master_deinit(void* arg)
679 {
680     spitest_context_t* context = (spitest_context_t*)arg;
681     deinit_slave_context(&context->slave_context);
682 }
683 
test_master_start(spi_device_handle_t * spi,int freq,const spitest_param_set_t * pset,spitest_context_t * context)684 static void test_master_start(spi_device_handle_t *spi, int freq, const spitest_param_set_t* pset, spitest_context_t* context)
685 {
686     //master config
687     spi_bus_config_t buspset=SPI_BUS_TEST_DEFAULT_CONFIG();
688     buspset.miso_io_num = MASTER_IOMUX_PIN_MISO;
689     buspset.mosi_io_num = MASTER_IOMUX_PIN_MOSI;
690     buspset.sclk_io_num = MASTER_IOMUX_PIN_SCLK;
691     //this does nothing, but avoid the driver from using native pins
692     if (!pset->master_iomux) buspset.quadhd_io_num = UNCONNECTED_PIN;
693     spi_device_interface_config_t devpset=SPI_DEVICE_TEST_DEFAULT_CONFIG();
694     devpset.spics_io_num = MASTER_IOMUX_PIN_CS;
695     devpset.mode = pset->mode;
696     const int cs_pretrans_max = 15;
697     if (pset->dup==HALF_DUPLEX_MISO) {
698         devpset.cs_ena_pretrans = cs_pretrans_max;
699         devpset.flags |= SPI_DEVICE_HALFDUPLEX;
700     } else if (pset->dup == HALF_DUPLEX_MOSI) {
701         devpset.cs_ena_pretrans = cs_pretrans_max;
702         devpset.flags |= SPI_DEVICE_NO_DUMMY;
703     } else {
704         devpset.cs_ena_pretrans = cs_pretrans_max;//20;
705     }
706     const int cs_posttrans_max = 15;
707     devpset.cs_ena_posttrans = cs_posttrans_max;
708     devpset.input_delay_ns = pset->slave_tv_ns;
709     devpset.clock_speed_hz = freq;
710     if (pset->master_limit != 0 && freq > pset->master_limit) devpset.flags |= SPI_DEVICE_NO_DUMMY;
711 
712     int dma_chan = (pset->master_dma_chan == 0) ? 0 : SPI_DMA_CH_AUTO;
713     TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buspset, dma_chan));
714     TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devpset, spi));
715 
716     //prepare data for the slave
717     for (int i = 0; i < pset->test_size; i ++) {
718         /* in the single board, the data is send to the slave task, then to the driver.
719         * However, in this test we don't know the data received by the slave.
720         * So we send to the return queue of the slave directly.
721         */
722         //xQueueSend( slave_context.data_to_send, &slave_txdata[i], portMAX_DELAY );
723 
724         uint8_t slave_buffer[320+8];
725         int length;
726         if (pset->dup!=HALF_DUPLEX_MISO) {
727             length = context->master_trans[i].length;
728         } else {
729             length = context->master_trans[i].rxlength;
730         }
731         uint32_t* ptr = (uint32_t*)slave_buffer;
732         ptr[0] = length;
733         ptr[1] = (uint32_t)context->slave_trans[i].start;
734         if (context->master_trans[i].tx_buffer!=NULL) {
735             memcpy(ptr+2, context->master_trans[i].tx_buffer, (context->master_trans[i].length+7)/8);
736         }
737         //Send to return queue directly
738         xRingbufferSend(context->slave_context.data_received, slave_buffer, 8+(length+7)/8, portMAX_DELAY);
739     }
740     memset(context->master_rxbuf, 0x66, sizeof(context->master_rxbuf));
741 }
742 
test_master_loop(const void * arg1,void * arg2)743 static void test_master_loop(const void *arg1, void* arg2)
744 {
745     const spitest_param_set_t *test_cfg = (spitest_param_set_t*)arg1;
746     spitest_context_t* context = (spitest_context_t*)arg2;
747     spi_device_handle_t spi;
748     spitest_init_transactions(test_cfg, context);
749     const int *timing_speed_array = test_cfg->freq_list;
750 
751     ESP_LOGI(MASTER_TAG, "****************** %s ***************", test_cfg->pset_name);
752     for (int i=0; ; i++ ) {
753         const int freq = timing_speed_array[i];
754         if (freq==0) break;
755         if (test_cfg->freq_limit && freq > test_cfg->freq_limit) break;
756 
757         ESP_LOGI(MASTER_TAG, "==============> %dk", freq/1000);
758         test_master_start(&spi, freq, test_cfg, context);
759 
760         unity_wait_for_signal("slave ready");
761 
762         for( int j= 0; j < test_cfg->test_size; j ++ ) {
763             //wait for both master and slave end
764             ESP_LOGI( MASTER_TAG, "=> test%d", j );
765             //send master tx data
766             vTaskDelay(20);
767 
768             spi_transaction_t *t = &context->master_trans[j];
769             TEST_ESP_OK (spi_device_transmit(spi, t) );
770             int len = get_trans_len(test_cfg->dup, t);
771             spitest_master_print_data(t, len);
772 
773             size_t rcv_len;
774             slave_rxdata_t *rcv_data = xRingbufferReceive( context->slave_context.data_received, &rcv_len, portMAX_DELAY );
775             spitest_slave_print_data(rcv_data, false);
776 
777             //check result
778             bool check_master_data = (test_cfg->dup != HALF_DUPLEX_MOSI &&
779                         (test_cfg->master_limit == 0 || freq <= test_cfg->master_limit));
780             const bool check_slave_data = false;
781             const bool check_len = false;
782             if (!check_master_data) {
783                 ESP_LOGI(MASTER_TAG, "skip data check due to duplex mode or freq.");
784             } else {
785                 TEST_ESP_OK(spitest_check_data(len, t, rcv_data, check_master_data,
786                     check_len, check_slave_data));
787             }
788             //clean
789             vRingbufferReturnItem( context->slave_context.data_received, rcv_data );
790         }
791         master_free_device_bus(spi);
792     }
793 }
794 
795 /************ Slave Code ***********************************************/
test_slave_init(void ** arg)796 static void test_slave_init(void** arg)
797 {
798     TEST_ASSERT(*arg==NULL);
799     *arg = malloc(sizeof(spitest_context_t));
800     spitest_context_t* context = (spitest_context_t*)*arg;
801     TEST_ASSERT(context!=NULL);
802     context->slave_context = (spi_slave_task_context_t){};
803     esp_err_t err = init_slave_context( &context->slave_context );
804     TEST_ASSERT( err == ESP_OK );
805 
806     xTaskCreate( spitest_slave_task, "spi_slave", 4096, &context->slave_context, 0, &context->handle_slave);
807 }
808 
test_slave_deinit(void * arg)809 static void test_slave_deinit(void* arg)
810 {
811     spitest_context_t* context = (spitest_context_t*)arg;
812     vTaskDelete( context->handle_slave );
813     context->handle_slave = 0;
814 
815     deinit_slave_context(&context->slave_context);
816 }
817 
timing_slave_start(int speed,const spitest_param_set_t * pset,spitest_context_t * context)818 static void timing_slave_start(int speed, const spitest_param_set_t* pset, spitest_context_t *context)
819 {
820     //slave config
821     spi_bus_config_t slv_buscfg=SPI_BUS_TEST_DEFAULT_CONFIG();
822     slv_buscfg.miso_io_num = SLAVE_IOMUX_PIN_MISO;
823     slv_buscfg.mosi_io_num = SLAVE_IOMUX_PIN_MOSI;
824     slv_buscfg.sclk_io_num = SLAVE_IOMUX_PIN_SCLK;
825     //this does nothing, but avoid the driver from using native pins
826     if (!pset->slave_iomux) slv_buscfg.quadhd_io_num = UNCONNECTED_PIN;
827     spi_slave_interface_config_t slvcfg=SPI_SLAVE_TEST_DEFAULT_CONFIG();
828     slvcfg.spics_io_num = SLAVE_IOMUX_PIN_CS;
829     slvcfg.mode = pset->mode;
830     //Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected.
831     slave_pull_up(&slv_buscfg, slvcfg.spics_io_num);
832 
833     int slave_dma_chan = (pset->slave_dma_chan == 0) ? 0 : SPI_DMA_CH_AUTO;
834     TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &slv_buscfg, &slvcfg, slave_dma_chan));
835 
836     //prepare data for the master
837     for (int i = 0; i < pset->test_size; i++) {
838         if (pset->dup==FULL_DUPLEX) {
839             memcpy(context->master_trans[i].rx_buffer, context->slave_trans[i].start, (context->master_trans[i].length+7)/8);
840         } else if (pset->dup==HALF_DUPLEX_MISO) {
841             memcpy(context->master_trans[i].rx_buffer, context->slave_trans[i].start, (context->master_trans[i].rxlength+7)/8);
842         }
843     }
844 }
845 
test_slave_loop(const void * arg1,void * arg2)846 static void test_slave_loop(const void *arg1, void* arg2)
847 {
848     const spitest_param_set_t *pset = (spitest_param_set_t*)arg1;
849     spitest_context_t* context = (spitest_context_t*)arg2;
850     ESP_LOGI(SLAVE_TAG, "****************** %s ***************", pset->pset_name);
851     spitest_init_transactions(pset, context);
852 
853     const int *timing_speed_array = pset->freq_list;
854     for (int i=0; ; i++ ) {
855         const int freq = timing_speed_array[i];
856         if (freq==0) break;
857         if (pset->freq_limit != 0 && freq > pset->freq_limit) break;
858 
859         ESP_LOGI(MASTER_TAG, "==============> %dk", timing_speed_array[i]/1000);
860         //Initialize SPI slave interface
861         timing_slave_start(freq, pset, context);
862 
863         //prepare slave tx data
864         for (int i = 0; i < pset->test_size; i ++) {
865             xQueueSend( context->slave_context.data_to_send, &context->slave_trans[i], portMAX_DELAY );
866             //memcpy(context->master_trans[i].rx_buffer, context->slave_trans[i].start, (context->master_trans[i].length+7)/8);
867         }
868 
869         vTaskDelay(50/portTICK_PERIOD_MS);
870         unity_send_signal("slave ready");
871 
872         for( int i= 0; i < pset->test_size; i ++ ) {
873             //wait for both master and slave end
874             ESP_LOGI( MASTER_TAG, "===== test%d =====", i );
875             //send master tx data
876             vTaskDelay(20);
877 
878             spi_transaction_t *t = &context->master_trans[i];
879             int len = get_trans_len(pset->dup, t);
880             spitest_master_print_data(t, FULL_DUPLEX);
881 
882             size_t rcv_len;
883             slave_rxdata_t *rcv_data = xRingbufferReceive( context->slave_context.data_received, &rcv_len, portMAX_DELAY );
884             spitest_slave_print_data(rcv_data, true);
885 
886             //check result
887             const bool check_master_data = false;
888             bool check_slave_data = (pset->dup!=HALF_DUPLEX_MISO);
889             const bool check_len = true;
890             TEST_ESP_OK(spitest_check_data(len, t, rcv_data, check_master_data, check_len, check_slave_data));
891             //clean
892             vRingbufferReturnItem( context->slave_context.data_received, rcv_data );
893         }
894         TEST_ASSERT(spi_slave_free(TEST_SLAVE_HOST) == ESP_OK);
895     }
896 }
897 
898 /************ Timing Test ***********************************************/
899 static spitest_param_set_t timing_conf[] = {
900     {   .pset_name = "FULL_DUP, BOTH IOMUX",
901         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
902         .master_limit = SPI_MASTER_FREQ_16M,
903         .dup = FULL_DUPLEX,
904         .master_iomux= true,
905         .slave_iomux = true,
906         .slave_tv_ns = TV_WITH_ESP_SLAVE,
907     },
908     {   .pset_name = "FULL_DUP, MASTER IOMUX",
909         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
910         .master_limit = SPI_MASTER_FREQ_11M,
911         .dup = FULL_DUPLEX,
912         .master_iomux = true,
913         .slave_iomux = false,
914         .slave_tv_ns = TV_WITH_ESP_SLAVE_GPIO,
915     },
916     {   .pset_name = "FULL_DUP, SLAVE IOMUX",
917         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
918         .master_limit = SPI_MASTER_FREQ_11M,
919         .dup = FULL_DUPLEX,
920         .master_iomux = false,
921         .slave_iomux = true,
922         .slave_tv_ns = TV_WITH_ESP_SLAVE,
923     },
924     {   .pset_name = "FULL_DUP, BOTH GPIO",
925         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
926         .master_limit = SPI_MASTER_FREQ_9M,
927         .dup = FULL_DUPLEX,
928         .master_iomux = false,
929         .slave_iomux = false,
930         .slave_tv_ns = TV_WITH_ESP_SLAVE_GPIO,
931     },
932     {   .pset_name = "MOSI_DUP, BOTH IOMUX",
933         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
934         .dup = HALF_DUPLEX_MOSI,
935         .master_iomux= true,
936         .slave_iomux = true,
937         .slave_tv_ns = TV_WITH_ESP_SLAVE,
938     },
939     {   .pset_name = "MOSI_DUP, MASTER IOMUX",
940         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
941         .dup = HALF_DUPLEX_MOSI,
942         .master_iomux= true,
943         .slave_iomux = false,
944         .slave_tv_ns = TV_WITH_ESP_SLAVE_GPIO,
945     },
946     {   .pset_name = "MOSI_DUP, SLAVE IOMUX",
947         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
948         .dup = HALF_DUPLEX_MOSI,
949         .master_iomux= false,
950         .slave_iomux = true,
951         .slave_tv_ns = TV_WITH_ESP_SLAVE,
952     },
953     {   .pset_name = "MOSI_DUP, BOTH GPIO",
954         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
955         .dup = HALF_DUPLEX_MOSI,
956         .master_iomux= false,
957         .slave_iomux = false,
958         .slave_tv_ns = TV_WITH_ESP_SLAVE_GPIO,
959     },
960     {   .pset_name = "MISO_DUP, BOTH IOMUX",
961         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
962         .dup = HALF_DUPLEX_MISO,
963         .master_iomux = true,
964         .slave_iomux = true,
965         .slave_tv_ns = TV_WITH_ESP_SLAVE,
966     },
967     {   .pset_name = "MISO_DUP, MASTER IOMUX",
968         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
969         .dup = HALF_DUPLEX_MISO,
970         .master_iomux = true,
971         .slave_iomux = false,
972         .slave_tv_ns = TV_WITH_ESP_SLAVE_GPIO,
973     },
974     {   .pset_name = "MISO_DUP, SLAVE IOMUX",
975         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
976         .dup = HALF_DUPLEX_MISO,
977         .master_iomux = false,
978         .slave_iomux = true,
979         .slave_tv_ns = TV_WITH_ESP_SLAVE,
980     },
981     {   .pset_name = "MISO_DUP, BOTH GPIO",
982         .freq_limit = ESP_SPI_SLAVE_MAX_FREQ,
983         .dup = HALF_DUPLEX_MISO,
984         .master_iomux = false,
985         .slave_iomux = false,
986         .slave_tv_ns = TV_WITH_ESP_SLAVE_GPIO,
987     },
988 };
989 TEST_SPI_MASTER_SLAVE(TIMING, timing_conf, "")
990 
991 /************ Mode Test ***********************************************/
992 #define FREQ_LIMIT_MODE SPI_MASTER_FREQ_16M
993 //Set to this input delay so that the master will read with delay until 7M
994 #define DELAY_HCLK_UNTIL_7M    12.5*3
995 
996 static int test_freq_mode_ms[]={
997     100*1000,
998     6*1000*1000,
999     7*1000*1000,
1000     SPI_MASTER_FREQ_8M, //maximum freq MISO stable before next latch edge
1001     SPI_MASTER_FREQ_9M, //maximum freq MISO stable before next latch edge
1002     SPI_MASTER_FREQ_10M,
1003     SPI_MASTER_FREQ_11M,
1004     SPI_MASTER_FREQ_13M,
1005     SPI_MASTER_FREQ_16M,
1006     SPI_MASTER_FREQ_20M,
1007     0,
1008 };
1009 static int test_freq_20M_only[]={
1010     SPI_MASTER_FREQ_20M,
1011     0,
1012 };
1013 
1014 spitest_param_set_t mode_conf[] = {
1015     //non-DMA tests
1016     {   .pset_name = "mode 0, no DMA",
1017         .freq_list = test_freq_mode_ms,
1018         .master_limit = FREQ_LIMIT_MODE,
1019         .dup = FULL_DUPLEX,
1020         .master_iomux= true,
1021         .slave_iomux = true,
1022         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1023         .mode = 0,
1024     },
1025     {   .pset_name = "mode 1, no DMA",
1026         .freq_list = test_freq_mode_ms,
1027         .master_limit = FREQ_LIMIT_MODE,
1028         .dup = FULL_DUPLEX,
1029         .master_iomux= true,
1030         .slave_iomux = true,
1031         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1032         .mode = 1,
1033     },
1034     {   .pset_name = "mode 2, no DMA",
1035         .freq_list = test_freq_mode_ms,
1036         .master_limit = FREQ_LIMIT_MODE,
1037         .dup = FULL_DUPLEX,
1038         .master_iomux= true,
1039         .slave_iomux = true,
1040         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1041         .mode = 2,
1042     },
1043     {   .pset_name = "mode 3, no DMA",
1044         .freq_list = test_freq_mode_ms,
1045         .master_limit = FREQ_LIMIT_MODE,
1046         .dup = FULL_DUPLEX,
1047         .master_iomux= true,
1048         .slave_iomux = true,
1049         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1050         .mode = 3,
1051     },
1052     //the master can only read to 16MHz, use half-duplex mode to read at 20.
1053     {   .pset_name = "mode 0, no DMA, 20M",
1054         .freq_list = test_freq_20M_only,
1055         .dup = HALF_DUPLEX_MISO,
1056         .master_iomux= true,
1057         .slave_iomux = true,
1058         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1059         .mode = 0,
1060     },
1061     {   .pset_name = "mode 1, no DMA, 20M",
1062         .freq_list = test_freq_20M_only,
1063         .dup = HALF_DUPLEX_MISO,
1064         .master_iomux= true,
1065         .slave_iomux = true,
1066         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1067         .mode = 1,
1068     },
1069     {   .pset_name = "mode 2, no DMA, 20M",
1070         .freq_list = test_freq_20M_only,
1071         .dup = HALF_DUPLEX_MISO,
1072         .master_iomux= true,
1073         .slave_iomux = true,
1074         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1075         .mode = 2,
1076     },
1077     {   .pset_name = "mode 3, no DMA, 20M",
1078         .freq_list = test_freq_20M_only,
1079         .dup = HALF_DUPLEX_MISO,
1080         .master_iomux= true,
1081         .slave_iomux = true,
1082         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1083         .mode = 3,
1084     },
1085     //DMA tests
1086     {   .pset_name = "mode 0, DMA",
1087         .freq_list = test_freq_mode_ms,
1088         .master_limit = FREQ_LIMIT_MODE,
1089         .dup = FULL_DUPLEX,
1090         .master_iomux= true,
1091         .slave_iomux = true,
1092         .slave_tv_ns = DELAY_HCLK_UNTIL_7M,
1093         .mode = 0,
1094         .master_dma_chan = SPI_DMA_CH_AUTO,
1095         .slave_dma_chan = SPI_DMA_CH_AUTO,
1096         .length_aligned = true,
1097     },
1098     {   .pset_name = "mode 1, DMA",
1099         .freq_list = test_freq_mode_ms,
1100         .master_limit = FREQ_LIMIT_MODE,
1101         .dup = FULL_DUPLEX,
1102         .master_iomux= true,
1103         .slave_iomux = true,
1104         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1105         .mode = 1,
1106         .master_dma_chan = SPI_DMA_CH_AUTO,
1107         .slave_dma_chan = SPI_DMA_CH_AUTO,
1108         .length_aligned = true,
1109     },
1110     {   .pset_name = "mode 2, DMA",
1111         .freq_list = test_freq_mode_ms,
1112         .master_limit = FREQ_LIMIT_MODE,
1113         .dup = FULL_DUPLEX,
1114         .master_iomux= true,
1115         .slave_iomux = true,
1116         .slave_tv_ns = DELAY_HCLK_UNTIL_7M,
1117         .mode = 2,
1118         .master_dma_chan = SPI_DMA_CH_AUTO,
1119         .slave_dma_chan = SPI_DMA_CH_AUTO,
1120         .length_aligned = true,
1121     },
1122     {   .pset_name = "mode 3, DMA",
1123         .freq_list = test_freq_mode_ms,
1124         .master_limit = FREQ_LIMIT_MODE,
1125         .dup = FULL_DUPLEX,
1126         .master_iomux= true,
1127         .slave_iomux = true,
1128         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1129         .mode = 3,
1130         .master_dma_chan = SPI_DMA_CH_AUTO,
1131         .slave_dma_chan = SPI_DMA_CH_AUTO,
1132         .length_aligned = true,
1133     },
1134     //the master can only read to 16MHz, use half-duplex mode to read at 20.
1135     {   .pset_name = "mode 0, DMA, 20M",
1136         .freq_list = test_freq_20M_only,
1137         .dup = HALF_DUPLEX_MISO,
1138         .master_iomux= true,
1139         .slave_iomux = true,
1140         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1141         .mode = 0,
1142         .master_dma_chan = SPI_DMA_CH_AUTO,
1143         .slave_dma_chan = SPI_DMA_CH_AUTO,
1144     },
1145     {   .pset_name = "mode 1, DMA, 20M",
1146         .freq_list = test_freq_20M_only,
1147         .dup = HALF_DUPLEX_MISO,
1148         .master_iomux= true,
1149         .slave_iomux = true,
1150         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1151         .mode = 1,
1152         .master_dma_chan = SPI_DMA_CH_AUTO,
1153         .slave_dma_chan = SPI_DMA_CH_AUTO,
1154     },
1155     {   .pset_name = "mode 2, DMA, 20M",
1156         .freq_list = test_freq_20M_only,
1157         .dup = HALF_DUPLEX_MISO,
1158         .master_iomux= true,
1159         .slave_iomux = true,
1160         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1161         .mode = 2,
1162         .master_dma_chan = SPI_DMA_CH_AUTO,
1163         .slave_dma_chan = SPI_DMA_CH_AUTO,
1164     },
1165     {   .pset_name = "mode 3, DMA, 20M",
1166         .freq_list = test_freq_20M_only,
1167         .dup = HALF_DUPLEX_MISO,
1168         .master_iomux= true,
1169         .slave_iomux = true,
1170         .slave_tv_ns = TV_WITH_ESP_SLAVE,
1171         .mode = 3,
1172         .master_dma_chan = SPI_DMA_CH_AUTO,
1173         .slave_dma_chan = SPI_DMA_CH_AUTO,
1174     },
1175 };
1176 TEST_SPI_MASTER_SLAVE(MODE, mode_conf, "")
1177 
1178 #endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
1179 
1180 #endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
1181