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