1 /*
2 * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 /*
7 Tests for the spi_master device driver
8 */
9
10 #include <esp_types.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <malloc.h>
14 #include <string.h>
15 #include "freertos/FreeRTOS.h"
16 #include "freertos/task.h"
17 #include "freertos/semphr.h"
18 #include "freertos/queue.h"
19 #include "unity.h"
20 #include "driver/spi_master.h"
21 #include "driver/spi_slave.h"
22 #include "esp_heap_caps.h"
23 #include "esp_log.h"
24 #include "soc/spi_periph.h"
25 #include "test_utils.h"
26 #include "test/test_common_spi.h"
27 #include "soc/gpio_periph.h"
28 #include "sdkconfig.h"
29 #include "../cache_utils.h"
30 #include "soc/soc_memory_layout.h"
31 #include "driver/spi_common_internal.h"
32
33 const static char TAG[] = "test_spi";
34
35 // There is no input-only pin on esp32c3 and esp32s3
36 #define TEST_SOC_HAS_INPUT_ONLY_PINS (!DISABLED_FOR_TARGETS(ESP32C3, ESP32S3))
37
check_spi_pre_n_for(int clk,int pre,int n)38 static void check_spi_pre_n_for(int clk, int pre, int n)
39 {
40 esp_err_t ret;
41 spi_device_handle_t handle;
42
43 spi_device_interface_config_t devcfg = {
44 .command_bits = 0,
45 .address_bits = 0,
46 .dummy_bits = 0,
47 .clock_speed_hz = clk,
48 .duty_cycle_pos = 128,
49 .mode = 0,
50 .spics_io_num = PIN_NUM_CS,
51 .queue_size = 3
52 };
53 char sendbuf[16] = "";
54 spi_transaction_t t;
55 memset(&t, 0, sizeof(t));
56
57 ret = spi_bus_add_device(TEST_SPI_HOST, &devcfg, &handle);
58 TEST_ASSERT(ret == ESP_OK);
59
60 t.length = 16 * 8;
61 t.tx_buffer = sendbuf;
62 ret = spi_device_transmit(handle, &t);
63
64 spi_dev_t *hw = spi_periph_signal[TEST_SPI_HOST].hw;
65
66 printf("Checking clk rate %dHz. expect pre %d n %d, got pre %d n %d\n", clk, pre, n, hw->clock.clkdiv_pre + 1, hw->clock.clkcnt_n + 1);
67
68 TEST_ASSERT(hw->clock.clkcnt_n + 1 == n);
69 TEST_ASSERT(hw->clock.clkdiv_pre + 1 == pre);
70
71 ret = spi_bus_remove_device(handle);
72 TEST_ASSERT(ret == ESP_OK);
73 }
74
75 TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
76 {
77 spi_bus_config_t buscfg = {
78 .mosi_io_num = PIN_NUM_MOSI,
79 .miso_io_num = PIN_NUM_MISO,
80 .sclk_io_num = PIN_NUM_CLK,
81 .quadwp_io_num = -1,
82 .quadhd_io_num = -1
83 };
84 esp_err_t ret;
85 ret = spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO);
86 TEST_ASSERT(ret == ESP_OK);
87
88 check_spi_pre_n_for(26000000, 1, 3);
89 check_spi_pre_n_for(20000000, 1, 4);
90 check_spi_pre_n_for(8000000, 1, 10);
91 check_spi_pre_n_for(800000, 2, 50);
92 check_spi_pre_n_for(100000, 16, 50);
93 check_spi_pre_n_for(333333, 4, 60);
94 check_spi_pre_n_for(900000, 2, 44);
95 check_spi_pre_n_for(1, SOC_SPI_MAX_PRE_DIVIDER, 64); //Actually should generate the minimum clock speed, 152Hz
96 check_spi_pre_n_for(26000000, 1, 3);
97
98 ret = spi_bus_free(TEST_SPI_HOST);
99 TEST_ASSERT(ret == ESP_OK);
100 }
101
setup_spi_bus_loopback(int clkspeed,bool dma)102 static spi_device_handle_t setup_spi_bus_loopback(int clkspeed, bool dma)
103 {
104 spi_bus_config_t buscfg = {
105 .mosi_io_num = PIN_NUM_MOSI,
106 .miso_io_num = PIN_NUM_MOSI,
107 .sclk_io_num = PIN_NUM_CLK,
108 .quadwp_io_num = -1,
109 .quadhd_io_num = -1,
110 .max_transfer_sz = 4096 * 3
111 };
112 spi_device_interface_config_t devcfg = {
113 .command_bits = 0,
114 .address_bits = 0,
115 .dummy_bits = 0,
116 .clock_speed_hz = clkspeed,
117 .duty_cycle_pos = 128,
118 .mode = 0,
119 .spics_io_num = PIN_NUM_CS,
120 .queue_size = 3,
121 };
122 spi_device_handle_t handle;
123
124 TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, dma ? SPI_DMA_CH_AUTO : 0));
125 TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &handle));
126 //connect MOSI to two devices breaks the output, fix it.
127 spitest_gpio_output_sel(PIN_NUM_MOSI, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
128 printf("Bus/dev inited.\n");
129 return handle;
130 }
131
spi_test(spi_device_handle_t handle,int num_bytes)132 static int spi_test(spi_device_handle_t handle, int num_bytes)
133 {
134 esp_err_t ret;
135 int x;
136 bool success = true;
137 srand(num_bytes);
138 char *sendbuf = heap_caps_malloc((num_bytes + 3) & (~3), MALLOC_CAP_DMA);
139 char *recvbuf = heap_caps_malloc((num_bytes + 3) & (~3), MALLOC_CAP_DMA);
140 for (x = 0; x < num_bytes; x++) {
141 sendbuf[x] = rand() & 0xff;
142 recvbuf[x] = 0x55;
143 }
144
145 spi_transaction_t t;
146 memset(&t, 0, sizeof(t));
147 t.length = num_bytes * 8;
148 t.tx_buffer = sendbuf;
149 t.rx_buffer = recvbuf;
150 t.addr = 0xA00000000000000FL;
151 t.cmd = 0x55;
152
153 printf("Transmitting %d bytes...\n", num_bytes);
154 ret = spi_device_transmit(handle, &t);
155 TEST_ASSERT(ret == ESP_OK);
156
157 srand(num_bytes);
158 for (x = 0; x < num_bytes; x++) {
159 if (sendbuf[x] != (rand() & 0xff)) {
160 printf("Huh? Sendbuf corrupted at byte %d\n", x);
161 TEST_ASSERT(0);
162 }
163 if (sendbuf[x] != recvbuf[x]) {
164 break;
165 }
166 }
167 if (x != num_bytes) {
168 int from = x - 16;
169 if (from < 0) {
170 from = 0;
171 }
172 success = false;
173 printf("Error at %d! Sent vs recved: (starting from %d)\n", x, from);
174 for (int i = 0; i < 32; i++) {
175 if (i + from < num_bytes) {
176 printf("%02X ", sendbuf[from + i]);
177 }
178 }
179 printf("\n");
180 for (int i = 0; i < 32; i++) {
181 if (i + from < num_bytes) {
182 printf("%02X ", recvbuf[from + i]);
183 }
184 }
185 printf("\n");
186 }
187
188 if (success) {
189 printf("Success!\n");
190 }
191 free(sendbuf);
192 free(recvbuf);
193 return success;
194 }
195
196 TEST_CASE("SPI Master test", "[spi]")
197 {
198 bool success = true;
199 printf("Testing bus at 80KHz\n");
200 spi_device_handle_t handle = setup_spi_bus_loopback(80000, true);
201 success &= spi_test(handle, 16); //small
202 success &= spi_test(handle, 21); //small, unaligned
203 success &= spi_test(handle, 36); //aligned
204 success &= spi_test(handle, 128); //aligned
205 success &= spi_test(handle, 129); //unaligned
206 success &= spi_test(handle, 4096 - 2); //multiple descs, edge case 1
207 success &= spi_test(handle, 4096 - 1); //multiple descs, edge case 2
208 success &= spi_test(handle, 4096 * 3); //multiple descs
209
210 master_free_device_bus(handle);
211
212 printf("Testing bus at 80KHz, non-DMA\n");
213 handle = setup_spi_bus_loopback(80000, false);
214 success &= spi_test(handle, 4); //aligned
215 success &= spi_test(handle, 16); //small
216 success &= spi_test(handle, 21); //small, unaligned
217 success &= spi_test(handle, 32); //small
218 success &= spi_test(handle, 47); //small, unaligned
219 success &= spi_test(handle, 63); //small
220 success &= spi_test(handle, 64); //small, unaligned
221
222 master_free_device_bus(handle);
223
224 printf("Testing bus at 26MHz\n");
225 handle = setup_spi_bus_loopback(20000000, true);
226
227 success &= spi_test(handle, 128); //DMA, aligned
228 success &= spi_test(handle, 4096 * 3); //DMA, multiple descs
229 master_free_device_bus(handle);
230
231 printf("Testing bus at 900KHz\n");
232 handle = setup_spi_bus_loopback(9000000, true);
233
234 success &= spi_test(handle, 128); //DMA, aligned
235 success &= spi_test(handle, 4096 * 3); //DMA, multiple descs
236 master_free_device_bus(handle);
237 TEST_ASSERT(success);
238 }
239
240
241 TEST_CASE("SPI Master test, interaction of multiple devs", "[spi]")
242 {
243 esp_err_t ret;
244 bool success = true;
245 spi_device_interface_config_t devcfg = {
246 .command_bits = 0,
247 .address_bits = 0,
248 .dummy_bits = 0,
249 .clock_speed_hz = 1000000,
250 .duty_cycle_pos = 128,
251 .mode = 0,
252 .spics_io_num = PIN_NUM_CS,
253 .queue_size = 3,
254 };
255 spi_device_handle_t handle1 = setup_spi_bus_loopback(80000, true);
256 spi_device_handle_t handle2;
257 spi_bus_add_device(TEST_SPI_HOST, &devcfg, &handle2);
258
259 printf("Sending to dev 1\n");
260 success &= spi_test(handle1, 7);
261 printf("Sending to dev 1\n");
262 success &= spi_test(handle1, 15);
263 printf("Sending to dev 2\n");
264 success &= spi_test(handle2, 15);
265 printf("Sending to dev 1\n");
266 success &= spi_test(handle1, 32);
267 printf("Sending to dev 2\n");
268 success &= spi_test(handle2, 32);
269 printf("Sending to dev 1\n");
270 success &= spi_test(handle1, 63);
271 printf("Sending to dev 2\n");
272 success &= spi_test(handle2, 63);
273 printf("Sending to dev 1\n");
274 success &= spi_test(handle1, 5000);
275 printf("Sending to dev 2\n");
276 success &= spi_test(handle2, 5000);
277
278
279 ret = spi_bus_remove_device(handle2);
280 TEST_ASSERT(ret == ESP_OK);
281 master_free_device_bus(handle1);
282 TEST_ASSERT(success);
283 }
284
285 #if TEST_SOC_HAS_INPUT_ONLY_PINS //There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
test_master_pins(int mosi,int miso,int sclk,int cs)286 static esp_err_t test_master_pins(int mosi, int miso, int sclk, int cs)
287 {
288 esp_err_t ret;
289 spi_bus_config_t cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
290 cfg.mosi_io_num = mosi;
291 cfg.miso_io_num = miso;
292 cfg.sclk_io_num = sclk;
293
294 spi_device_interface_config_t master_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
295 master_cfg.spics_io_num = cs;
296
297 ret = spi_bus_initialize(TEST_SPI_HOST, &cfg, SPI_DMA_CH_AUTO);
298 if (ret != ESP_OK) {
299 return ret;
300 }
301
302 spi_device_handle_t spi;
303 ret = spi_bus_add_device(TEST_SPI_HOST, &master_cfg, &spi);
304 if (ret != ESP_OK) {
305 spi_bus_free(TEST_SPI_HOST);
306 return ret;
307 }
308
309 master_free_device_bus(spi);
310 return ESP_OK;
311 }
312
test_slave_pins(int mosi,int miso,int sclk,int cs)313 static esp_err_t test_slave_pins(int mosi, int miso, int sclk, int cs)
314 {
315 esp_err_t ret;
316 spi_bus_config_t cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
317 cfg.mosi_io_num = mosi;
318 cfg.miso_io_num = miso;
319 cfg.sclk_io_num = sclk;
320
321 spi_slave_interface_config_t slave_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
322 slave_cfg.spics_io_num = cs;
323
324 ret = spi_slave_initialize(TEST_SLAVE_HOST, &cfg, &slave_cfg, SPI_DMA_CH_AUTO);
325 if (ret != ESP_OK) {
326 return ret;
327 }
328
329 spi_slave_free(TEST_SLAVE_HOST);
330 return ESP_OK;
331 }
332
333 TEST_CASE("spi placed on input-only pins", "[spi]")
334 {
335 TEST_ESP_OK(test_master_pins(PIN_NUM_MOSI, PIN_NUM_MISO, PIN_NUM_CLK, PIN_NUM_CS));
336 TEST_ASSERT(test_master_pins(INPUT_ONLY_PIN, PIN_NUM_MISO, PIN_NUM_CLK, PIN_NUM_CS) != ESP_OK);
337 TEST_ESP_OK(test_master_pins(PIN_NUM_MOSI, INPUT_ONLY_PIN, PIN_NUM_CLK, PIN_NUM_CS));
338 TEST_ASSERT(test_master_pins(PIN_NUM_MOSI, PIN_NUM_MISO, INPUT_ONLY_PIN, PIN_NUM_CS) != ESP_OK);
339 TEST_ASSERT(test_master_pins(PIN_NUM_MOSI, PIN_NUM_MISO, PIN_NUM_CLK, INPUT_ONLY_PIN) != ESP_OK);
340 TEST_ESP_OK(test_slave_pins(PIN_NUM_MOSI, PIN_NUM_MISO, PIN_NUM_CLK, PIN_NUM_CS));
341 TEST_ESP_OK(test_slave_pins(INPUT_ONLY_PIN, PIN_NUM_MISO, PIN_NUM_CLK, PIN_NUM_CS));
342 TEST_ASSERT(test_slave_pins(PIN_NUM_MOSI, INPUT_ONLY_PIN, PIN_NUM_CLK, PIN_NUM_CS) != ESP_OK);
343 TEST_ESP_OK(test_slave_pins(PIN_NUM_MOSI, PIN_NUM_MISO, INPUT_ONLY_PIN, PIN_NUM_CS));
344 TEST_ESP_OK(test_slave_pins(PIN_NUM_MOSI, PIN_NUM_MISO, PIN_NUM_CLK, INPUT_ONLY_PIN));
345 }
346
347 //There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
348 #endif //#if TEST_SOC_HAS_INPUT_ONLY_PINS
349
350 TEST_CASE("spi bus setting with different pin configs", "[spi]")
351 {
352 spi_bus_config_t cfg;
353 uint32_t flags_o;
354 uint32_t flags_expected;
355
356 ESP_LOGI(TAG, "test 6 iomux output pins...");
357 flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_IOMUX_PINS | SPICOMMON_BUSFLAG_QUAD;
358 cfg = (spi_bus_config_t) {
359 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
360 .max_transfer_sz = 8, .flags = flags_expected
361 };
362 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
363 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
364 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
365 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
366
367 ESP_LOGI(TAG, "test 4 iomux output pins...");
368 flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_IOMUX_PINS | SPICOMMON_BUSFLAG_DUAL;
369 cfg = (spi_bus_config_t) {
370 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
371 .max_transfer_sz = 8, .flags = flags_expected
372 };
373 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
374 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
375 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
376 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
377
378 ESP_LOGI(TAG, "test 6 output pins...");
379 flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_QUAD | SPICOMMON_BUSFLAG_GPIO_PINS;
380 //swap MOSI and MISO
381 cfg = (spi_bus_config_t) {
382 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
383 .max_transfer_sz = 8, .flags = flags_expected
384 };
385 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
386 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
387 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
388 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
389
390 ESP_LOGI(TAG, "test 4 output pins...");
391 flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_DUAL | SPICOMMON_BUSFLAG_GPIO_PINS;
392 //swap MOSI and MISO
393 cfg = (spi_bus_config_t) {
394 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
395 .max_transfer_sz = 8, .flags = flags_expected
396 };
397 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
398 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
399 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
400 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
401
402 #if TEST_SOC_HAS_INPUT_ONLY_PINS //There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
403 ESP_LOGI(TAG, "test master 5 output pins and MOSI on input-only pin...");
404 flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_WPHD | SPICOMMON_BUSFLAG_GPIO_PINS;
405 cfg = (spi_bus_config_t) {
406 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = INPUT_ONLY_PIN, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
407 .max_transfer_sz = 8, .flags = flags_expected
408 };
409 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
410 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
411
412 ESP_LOGI(TAG, "test slave 5 output pins and MISO on input-only pin...");
413 flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_WPHD | SPICOMMON_BUSFLAG_GPIO_PINS;
414 cfg = (spi_bus_config_t) {
415 .mosi_io_num = INPUT_ONLY_PIN, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
416 .max_transfer_sz = 8, .flags = flags_expected
417 };
418 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
419 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
420
421 ESP_LOGI(TAG, "test master 3 output pins and MOSI on input-only pin...");
422 flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_GPIO_PINS;
423
424 cfg = (spi_bus_config_t) {
425 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = INPUT_ONLY_PIN, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
426 .max_transfer_sz = 8, .flags = flags_expected
427 };
428 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
429 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
430
431 ESP_LOGI(TAG, "test slave 3 output pins and MISO on input-only pin...");
432 flags_expected = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_GPIO_PINS;
433 cfg = (spi_bus_config_t) {
434 .mosi_io_num = INPUT_ONLY_PIN, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
435 .max_transfer_sz = 8, .flags = flags_expected
436 };
437 TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
438 TEST_ASSERT_EQUAL_HEX32( flags_expected, flags_o );
439 //There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
440 #endif //#if TEST_SOC_HAS_INPUT_ONLY_PINS
441
442 ESP_LOGI(TAG, "check native flag for 6 output pins...");
443 flags_expected = SPICOMMON_BUSFLAG_IOMUX_PINS;
444 //swap MOSI and MISO
445 cfg = (spi_bus_config_t) {
446 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
447 .max_transfer_sz = 8, .flags = flags_expected
448 };
449 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
450 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
451
452 ESP_LOGI(TAG, "check native flag for 4 output pins...");
453 flags_expected = SPICOMMON_BUSFLAG_IOMUX_PINS;
454 //swap MOSI and MISO
455 cfg = (spi_bus_config_t) {
456 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
457 .max_transfer_sz = 8, .flags = flags_expected
458 };
459 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
460 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
461
462 #if TEST_SOC_HAS_INPUT_ONLY_PINS //There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
463 ESP_LOGI(TAG, "check dual flag for master 5 output pins and MISO/MOSI on input-only pin...");
464 flags_expected = SPICOMMON_BUSFLAG_DUAL | SPICOMMON_BUSFLAG_GPIO_PINS;
465 cfg = (spi_bus_config_t) {
466 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = INPUT_ONLY_PIN, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
467 .max_transfer_sz = 8, .flags = flags_expected
468 };
469 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
470 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
471 cfg = (spi_bus_config_t) {
472 .mosi_io_num = INPUT_ONLY_PIN, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
473 .max_transfer_sz = 8, .flags = flags_expected
474 };
475 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
476 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
477
478 ESP_LOGI(TAG, "check dual flag for master 3 output pins and MISO/MOSI on input-only pin...");
479 flags_expected = SPICOMMON_BUSFLAG_DUAL | SPICOMMON_BUSFLAG_GPIO_PINS;
480 cfg = (spi_bus_config_t) {
481 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = INPUT_ONLY_PIN, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
482 .max_transfer_sz = 8, .flags = flags_expected
483 };
484 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
485 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
486 cfg = (spi_bus_config_t) {
487 .mosi_io_num = INPUT_ONLY_PIN, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
488 .max_transfer_sz = 8, .flags = flags_expected
489 };
490 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
491 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
492 //There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
493 #endif //#if TEST_SOC_HAS_INPUT_ONLY_PINS
494
495 ESP_LOGI(TAG, "check sclk flag...");
496 flags_expected = SPICOMMON_BUSFLAG_SCLK;
497 cfg = (spi_bus_config_t) {
498 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = -1, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
499 .max_transfer_sz = 8, .flags = flags_expected
500 };
501 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
502 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
503
504 ESP_LOGI(TAG, "check mosi flag...");
505 flags_expected = SPICOMMON_BUSFLAG_MOSI;
506 cfg = (spi_bus_config_t) {
507 .mosi_io_num = -1, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
508 .max_transfer_sz = 8, .flags = flags_expected
509 };
510 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
511 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
512
513 ESP_LOGI(TAG, "check miso flag...");
514 flags_expected = SPICOMMON_BUSFLAG_MISO;
515 cfg = (spi_bus_config_t) {
516 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = -1, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
517 .max_transfer_sz = 8, .flags = flags_expected
518 };
519 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
520 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
521
522 ESP_LOGI(TAG, "check quad flag...");
523 flags_expected = SPICOMMON_BUSFLAG_QUAD;
524 cfg = (spi_bus_config_t) {
525 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
526 .max_transfer_sz = 8, .flags = flags_expected
527 };
528 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
529 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
530 cfg = (spi_bus_config_t) {
531 .mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = -1,
532 .max_transfer_sz = 8, .flags = flags_expected
533 };
534 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
535 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
536 }
537
538 TEST_CASE("SPI Master no response when switch from host1 (SPI2) to host2 (SPI3)", "[spi]")
539 {
540 //spi config
541 spi_bus_config_t bus_config;
542 spi_device_interface_config_t device_config;
543 spi_device_handle_t spi;
544 spi_host_device_t host;
545
546 memset(&bus_config, 0, sizeof(spi_bus_config_t));
547 memset(&device_config, 0, sizeof(spi_device_interface_config_t));
548
549 bus_config.miso_io_num = -1;
550 bus_config.mosi_io_num = PIN_NUM_MOSI;
551 bus_config.sclk_io_num = PIN_NUM_CLK;
552 bus_config.quadwp_io_num = -1;
553 bus_config.quadhd_io_num = -1;
554
555 device_config.clock_speed_hz = 50000;
556 device_config.mode = 0;
557 device_config.spics_io_num = -1;
558 device_config.queue_size = 1;
559 device_config.flags = SPI_DEVICE_TXBIT_LSBFIRST | SPI_DEVICE_RXBIT_LSBFIRST;
560
561 struct spi_transaction_t transaction = {
562 .flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA,
563 .length = 16,
564 .rx_buffer = NULL,
565 .tx_data = {0x04, 0x00}
566 };
567
568 //initialize for first host
569 host = TEST_SPI_HOST;
570
571 TEST_ESP_OK(spi_bus_initialize(host, &bus_config, SPI_DMA_CH_AUTO));
572 TEST_ESP_OK(spi_bus_add_device(host, &device_config, &spi));
573
574 printf("before first xmit\n");
575 TEST_ESP_OK(spi_device_transmit(spi, &transaction));
576 printf("after first xmit\n");
577
578 TEST_ESP_OK(spi_bus_remove_device(spi));
579 TEST_ESP_OK(spi_bus_free(host));
580
581 //for second host and failed before
582 host = TEST_SLAVE_HOST;
583 TEST_ESP_OK(spi_bus_initialize(host, &bus_config, SPI_DMA_CH_AUTO));
584 TEST_ESP_OK(spi_bus_add_device(host, &device_config, &spi));
585
586 printf("before second xmit\n");
587 // the original version (bit mis-written) stucks here.
588 TEST_ESP_OK(spi_device_transmit(spi, &transaction));
589 // test case success when see this.
590 printf("after second xmit\n");
591
592 TEST_ESP_OK(spi_bus_remove_device(spi));
593 TEST_ESP_OK(spi_bus_free(host));
594 }
595
596 DRAM_ATTR static uint32_t data_dram[80] = {0};
597 //force to place in code area.
598 static const uint8_t data_drom[320 + 3] = {
599 0xD8, 0xD1, 0x0A, 0xB8, 0xCE, 0x67, 0x1B, 0x11, 0x17, 0xA0, 0xDA, 0x89, 0x55, 0xC1, 0x40, 0x0F, 0x55, 0xEB, 0xF7, 0xEC, 0xF0, 0x3C, 0x0F, 0x4D, 0x2B, 0x9E, 0xBF, 0xCD, 0x57, 0x2C, 0x48, 0x1A,
600 0x8B, 0x47, 0xC5, 0x01, 0x0C, 0x05, 0x80, 0x30, 0xF4, 0xEA, 0xE5, 0x92, 0x56, 0x97, 0x98, 0x78, 0x21, 0x34, 0xA1, 0xBC, 0xAE, 0x93, 0x7E, 0x96, 0x08, 0xE6, 0x54, 0x6A, 0x6C, 0x67, 0xCF, 0x58,
601 0xEE, 0x15, 0xA8, 0xB6, 0x32, 0x8C, 0x85, 0xF7, 0xE9, 0x88, 0x5E, 0xB1, 0x76, 0xE4, 0xB2, 0xC7, 0x0F, 0x57, 0x51, 0x7A, 0x2F, 0xAB, 0x12, 0xC3, 0x37, 0x99, 0x4E, 0x67, 0x75, 0x28, 0xE4, 0x1D,
602 0xF8, 0xBA, 0x22, 0xCB, 0xA1, 0x18, 0x4C, 0xAB, 0x5F, 0xC9, 0xF3, 0xA2, 0x39, 0x92, 0x44, 0xE6, 0x7B, 0xE3, 0xD0, 0x16, 0xC5, 0xC2, 0xCB, 0xD9, 0xC0, 0x7F, 0x06, 0xBF, 0x3E, 0xCE, 0xE1, 0x26,
603 0xD5, 0x3C, 0xAD, 0x0E, 0xC1, 0xC7, 0x7D, 0x0D, 0x56, 0x85, 0x6F, 0x32, 0xC8, 0x63, 0x8D, 0x12, 0xAB, 0x1E, 0x81, 0x7B, 0xF4, 0xF1, 0xA9, 0xAF, 0xD9, 0x74, 0x60, 0x05, 0x3D, 0xCC, 0x0C, 0x34,
604 0x11, 0x44, 0xAE, 0x2A, 0x13, 0x2F, 0x04, 0xC3, 0x59, 0xF0, 0x54, 0x07, 0xBA, 0x26, 0xD9, 0xFB, 0x80, 0x95, 0xC0, 0x14, 0xFA, 0x27, 0xEF, 0xD3, 0x58, 0xB8, 0xE4, 0xA2, 0xE3, 0x5E, 0x94, 0xB3,
605 0xCD, 0x2C, 0x4F, 0xAC, 0x3B, 0xD1, 0xCA, 0xBE, 0x61, 0x71, 0x7B, 0x62, 0xEB, 0xF0, 0xFC, 0xEF, 0x22, 0xB7, 0x3F, 0x56, 0x65, 0x19, 0x61, 0x73, 0x1A, 0x4D, 0xE4, 0x23, 0xE5, 0x3A, 0x91, 0x5C,
606 0xE6, 0x1B, 0x5F, 0x0E, 0x10, 0x94, 0x7C, 0x9F, 0xCF, 0x75, 0xB3, 0xEB, 0x42, 0x4C, 0xCF, 0xFE, 0xAF, 0x68, 0x62, 0x3F, 0x9A, 0x3C, 0x81, 0x3E, 0x7A, 0x45, 0x92, 0x79, 0x91, 0x4F, 0xFF, 0xDE,
607 0x25, 0x18, 0x33, 0xB9, 0xA9, 0x3A, 0x3F, 0x1F, 0x4F, 0x4B, 0x5C, 0x71, 0x82, 0x75, 0xB0, 0x1F, 0xE9, 0x98, 0xA3, 0xE2, 0x65, 0xBB, 0xCA, 0x4F, 0xB7, 0x1D, 0x23, 0x43, 0x16, 0x73, 0xBD, 0x83,
608 0x70, 0x22, 0x7D, 0x0A, 0x6D, 0xD3, 0x77, 0x73, 0xD0, 0xF4, 0x06, 0xB2, 0x19, 0x8C, 0xFF, 0x58, 0xE4, 0xDB, 0xE9, 0xEC, 0x89, 0x6A, 0xF4, 0x0E, 0x67, 0x12, 0xEC, 0x11, 0xD2, 0x1F, 0x8D, 0xD7,
609 };
610
611 TEST_CASE("SPI Master DMA test, TX and RX in different regions", "[spi]")
612 {
613 #ifdef CONFIG_SPIRAM
614 //test psram if enabled
615 ESP_LOGI(TAG, "testing PSRAM...");
616 uint32_t *data_malloc = (uint32_t *)heap_caps_malloc(324, MALLOC_CAP_SPIRAM);
617 TEST_ASSERT(esp_ptr_external_ram(data_malloc));
618 #else
619 uint32_t *data_malloc = (uint32_t *)heap_caps_malloc(324, MALLOC_CAP_DMA);
620 TEST_ASSERT(esp_ptr_in_dram(data_malloc));
621 #endif
622 TEST_ASSERT(data_malloc != NULL);
623 TEST_ASSERT(esp_ptr_in_dram(data_dram));
624 TEST_ASSERT(esp_ptr_in_drom(data_drom));
625 ESP_LOGI(TAG, "dram: %p", data_dram);
626 ESP_LOGI(TAG, "drom: %p, malloc: %p", data_drom, data_malloc);
627
628 #ifndef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
629 uint32_t *data_iram = (uint32_t *)heap_caps_malloc(324, MALLOC_CAP_EXEC);
630 TEST_ASSERT(data_iram != NULL);
631 TEST_ASSERT(esp_ptr_executable(data_iram) || esp_ptr_in_iram(data_iram) || esp_ptr_in_diram_iram(data_iram));
632 ESP_LOGI(TAG, "iram: %p", data_iram);
633 #endif
634
635 srand(52);
636 for (int i = 0; i < 320 / 4; i++) {
637 #ifndef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
638 data_iram[i] = rand();
639 #endif
640 data_dram[i] = rand();
641 data_malloc[i] = rand();
642 }
643
644 esp_err_t ret;
645 spi_device_handle_t spi;
646 spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
647 buscfg.miso_io_num = PIN_NUM_MOSI;
648 spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
649
650 //Initialize the SPI bus
651 TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
652 //Attach the LCD to the SPI bus
653 TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &spi));
654 //connect MOSI to two devices breaks the output, fix it.
655 spitest_gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
656
657 #define TEST_REGION_SIZE 5
658 static spi_transaction_t trans[TEST_REGION_SIZE];
659 int x;
660 memset(trans, 0, sizeof(trans));
661
662 #ifndef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
663 trans[0].length = 320 * 8,
664 trans[0].tx_buffer = data_iram;
665 trans[0].rx_buffer = data_malloc + 1;
666
667 trans[1].length = 320 * 8,
668 trans[1].tx_buffer = data_dram;
669 trans[1].rx_buffer = data_iram;
670
671 trans[2].length = 320 * 8,
672 trans[2].tx_buffer = data_drom;
673 trans[2].rx_buffer = data_iram;
674 #endif
675
676 trans[3].length = 320 * 8,
677 trans[3].tx_buffer = data_malloc + 2;
678 trans[3].rx_buffer = data_dram;
679
680 trans[4].length = 4 * 8,
681 trans[4].flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA;
682 uint32_t *ptr = (uint32_t *)trans[4].rx_data;
683 *ptr = 0x54545454;
684 ptr = (uint32_t *)trans[4].tx_data;
685 *ptr = 0xbc124960;
686
687 //Queue all transactions.
688 #ifndef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
689 for (x = 0; x < TEST_REGION_SIZE; x++) {
690 #else
691 for (x = 3; x < TEST_REGION_SIZE; x++) {
692 #endif
693 ESP_LOGI(TAG, "transmitting %d...", x);
694 ret = spi_device_transmit(spi, &trans[x]);
695 TEST_ASSERT(ret == ESP_OK);
696 if (trans[x].flags & SPI_TRANS_USE_RXDATA) {
697 TEST_ASSERT_EQUAL_HEX8_ARRAY(trans[x].tx_data, trans[x].rx_data, 4);
698 } else {
699 TEST_ASSERT_EQUAL_HEX32_ARRAY(trans[x].tx_buffer, trans[x].rx_buffer, trans[x].length / 8 / 4);
700 }
701 }
702 TEST_ASSERT(spi_bus_remove_device(spi) == ESP_OK);
703 TEST_ASSERT(spi_bus_free(TEST_SPI_HOST) == ESP_OK);
704 free(data_malloc);
705 #ifndef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
706 free(data_iram);
707 #endif
708 }
709
710 //this part tests 3 DMA issues in master mode, full-duplex in IDF2.1
711 // 1. RX buffer not aligned (start and end)
712 // 2. not setting rx_buffer
713 // 3. setting rx_length != length
714 TEST_CASE("SPI Master DMA test: length, start, not aligned", "[spi]")
715 {
716 uint8_t tx_buf[320] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43};
717 uint8_t rx_buf[320];
718
719 spi_device_handle_t spi;
720 spi_bus_config_t buscfg = {
721 .miso_io_num = PIN_NUM_MOSI,
722 .mosi_io_num = PIN_NUM_MOSI,
723 .sclk_io_num = PIN_NUM_CLK,
724 .quadwp_io_num = -1,
725 .quadhd_io_num = -1
726 };
727 spi_device_interface_config_t devcfg = {
728 .clock_speed_hz = 10 * 1000 * 1000, //Clock out at 10 MHz
729 .mode = 0, //SPI mode 0
730 .spics_io_num = PIN_NUM_CS, //CS pin
731 .queue_size = 7, //We want to be able to queue 7 transactions at a time
732 .pre_cb = NULL,
733 };
734 //Initialize the SPI bus
735 TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
736 //Attach the LCD to the SPI bus
737 TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &spi));
738
739 //connect MOSI to two devices breaks the output, fix it.
740 spitest_gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
741
742 memset(rx_buf, 0x66, 320);
743
744 for ( int i = 0; i < 8; i ++ ) {
745 memset( rx_buf, 0x66, sizeof(rx_buf));
746
747 spi_transaction_t t = {};
748 t.length = 8 * (i + 1);
749 t.rxlength = 0;
750 t.tx_buffer = tx_buf + 2 * i;
751 t.rx_buffer = rx_buf + i;
752
753 if ( i == 1 ) {
754 //test set no start
755 t.rx_buffer = NULL;
756 } else if ( i == 2 ) {
757 //test rx length != tx_length
758 t.rxlength = t.length - 8;
759 }
760 spi_device_transmit( spi, &t );
761
762 for ( int i = 0; i < 16; i ++ ) {
763 printf("%02X ", rx_buf[i]);
764 }
765 printf("\n");
766
767 if ( i == 1 ) {
768 // no rx, skip check
769 } else if ( i == 2 ) {
770 //test rx length = tx length-1
771 TEST_ASSERT_EQUAL_HEX8_ARRAY(t.tx_buffer, t.rx_buffer, t.length / 8 - 1 );
772 } else {
773 //normal check
774 TEST_ASSERT_EQUAL_HEX8_ARRAY(t.tx_buffer, t.rx_buffer, t.length / 8 );
775 }
776 }
777
778 TEST_ASSERT(spi_bus_remove_device(spi) == ESP_OK);
779 TEST_ASSERT(spi_bus_free(TEST_SPI_HOST) == ESP_OK);
780 }
781
782
783 #if !DISABLED_FOR_TARGETS(ESP32C3) //There is only one GPSPI controller, so single-board test is disabled.
bitswap(uint8_t in)784 static uint8_t bitswap(uint8_t in)
785 {
786 uint8_t out = 0;
787 for (int i = 0; i < 8; i++) {
788 out = out >> 1;
789 if (in & 0x80) {
790 out |= 0x80;
791 }
792 in = in << 1;
793 }
794 return out;
795 }
796
test_cmd_addr(spi_slave_task_context_t * slave_context,bool lsb_first)797 void test_cmd_addr(spi_slave_task_context_t *slave_context, bool lsb_first)
798 {
799 spi_device_handle_t spi;
800
801 ESP_LOGI(MASTER_TAG, ">>>>>>>>> TEST %s FIRST <<<<<<<<<<<", lsb_first ? "LSB" : "MSB");
802
803 //initial master, mode 0, 1MHz
804 spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
805 buscfg.quadhd_io_num = UNCONNECTED_PIN;
806 TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
807 spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
808 devcfg.clock_speed_hz = 1 * 1000 * 1000;
809 if (lsb_first) {
810 devcfg.flags |= SPI_DEVICE_BIT_LSBFIRST;
811 }
812 TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &spi));
813
814 //connecting pins to two peripherals breaks the output, fix it.
815 spitest_gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
816 spitest_gpio_output_sel(buscfg.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
817 spitest_gpio_output_sel(devcfg.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
818 spitest_gpio_output_sel(buscfg.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
819
820 for (int i = 0; i < 8; i++) {
821 //prepare slave tx data
822 slave_txdata_t slave_txdata = (slave_txdata_t) {
823 .start = spitest_slave_send + 4 * (i % 3),
824 .len = 256,
825 };
826 xQueueSend(slave_context->data_to_send, &slave_txdata, portMAX_DELAY);
827
828 vTaskDelay(50);
829 //prepare master tx data
830 int cmd_bits = (i + 1) * 2;
831 int addr_bits =
832 #ifdef CONFIG_IDF_TARGET_ESP32
833 56 - 8 * i;
834 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
835 //ESP32S2 only supportes up to 32 bits address
836 28 - 4 * i;
837 #endif
838 int round_up = (cmd_bits + addr_bits + 7) / 8 * 8;
839 addr_bits = round_up - cmd_bits;
840
841 spi_transaction_ext_t trans = (spi_transaction_ext_t) {
842 .base = {
843 .flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
844 .addr = 0x456789abcdef0123,
845 .cmd = 0x9876,
846 },
847 .command_bits = cmd_bits,
848 .address_bits = addr_bits,
849 };
850
851 ESP_LOGI( MASTER_TAG, "===== test%d =====", i );
852 ESP_LOGI(MASTER_TAG, "cmd_bits: %d, addr_bits: %d", cmd_bits, addr_bits);
853 TEST_ESP_OK(spi_device_transmit(spi, (spi_transaction_t *)&trans));
854 //wait for both master and slave end
855
856 size_t rcv_len;
857 slave_rxdata_t *rcv_data = xRingbufferReceive(slave_context->data_received, &rcv_len, portMAX_DELAY);
858 rcv_len -= 8;
859 uint8_t *buffer = rcv_data->data;
860
861 ESP_LOGI(SLAVE_TAG, "trans_len: %d", rcv_len);
862 TEST_ASSERT_EQUAL(rcv_len, (rcv_data->len + 7) / 8);
863 TEST_ASSERT_EQUAL(rcv_data->len, cmd_bits + addr_bits);
864 ESP_LOG_BUFFER_HEX("slave rx", buffer, rcv_len);
865
866 uint16_t cmd_expected = trans.base.cmd & (BIT(cmd_bits) - 1);
867 uint64_t addr_expected = trans.base.addr & ((1ULL << addr_bits) - 1);
868
869 uint8_t *data_ptr = buffer;
870 uint16_t cmd_got = *(uint16_t *)data_ptr;
871 data_ptr += cmd_bits / 8;
872 cmd_got = __builtin_bswap16(cmd_got);
873 cmd_got = cmd_got >> (16 - cmd_bits);
874 int remain_bits = cmd_bits % 8;
875
876 uint64_t addr_got = *(uint64_t *)data_ptr;
877 data_ptr += 8;
878 addr_got = __builtin_bswap64(addr_got);
879 addr_got = (addr_got << remain_bits);
880 addr_got |= (*data_ptr >> (8 - remain_bits));
881 addr_got = addr_got >> (64 - addr_bits);
882
883 if (lsb_first) {
884 cmd_got = __builtin_bswap16(cmd_got);
885 addr_got = __builtin_bswap64(addr_got);
886
887 uint8_t *swap_ptr = (uint8_t *)&cmd_got;
888 swap_ptr[0] = bitswap(swap_ptr[0]);
889 swap_ptr[1] = bitswap(swap_ptr[1]);
890 cmd_got = cmd_got >> (16 - cmd_bits);
891
892 swap_ptr = (uint8_t *)&addr_got;
893 for (int j = 0; j < 8; j++) {
894 swap_ptr[j] = bitswap(swap_ptr[j]);
895 }
896 addr_got = addr_got >> (64 - addr_bits);
897 }
898
899 ESP_LOGI(SLAVE_TAG, "cmd_got: %04X, addr_got: %08X%08X", cmd_got, (uint32_t)(addr_got >> 32), (uint32_t)addr_got);
900
901 TEST_ASSERT_EQUAL_HEX16(cmd_expected, cmd_got);
902 if (addr_bits > 0) {
903 TEST_ASSERT_EQUAL_HEX32(addr_expected, addr_got);
904 TEST_ASSERT_EQUAL_HEX32(addr_expected >> 8, addr_got >> 8);
905 }
906
907 //clean
908 vRingbufferReturnItem(slave_context->data_received, rcv_data);
909 }
910
911 TEST_ASSERT(spi_bus_remove_device(spi) == ESP_OK);
912 TEST_ASSERT(spi_bus_free(TEST_SPI_HOST) == ESP_OK);
913 }
914
915 TEST_CASE("SPI master variable cmd & addr test", "[spi]")
916 {
917 spi_slave_task_context_t slave_context = {};
918 esp_err_t err = init_slave_context( &slave_context );
919 TEST_ASSERT( err == ESP_OK );
920 TaskHandle_t handle_slave;
921 xTaskCreate( spitest_slave_task, "spi_slave", 4096, &slave_context, 0, &handle_slave);
922
923 //initial slave, mode 0, no dma
924 int dma_chan = 0;
925 int slave_mode = 0;
926 spi_bus_config_t slv_buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
927 spi_slave_interface_config_t slvcfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
928 slvcfg.mode = slave_mode;
929 //Initialize SPI slave interface
930 TEST_ESP_OK( spi_slave_initialize(TEST_SLAVE_HOST, &slv_buscfg, &slvcfg, dma_chan) );
931
932 test_cmd_addr(&slave_context, false);
933 test_cmd_addr(&slave_context, true);
934
935 vTaskDelete( handle_slave );
936 handle_slave = 0;
937
938 deinit_slave_context(&slave_context);
939
940 TEST_ASSERT(spi_slave_free(TEST_SLAVE_HOST) == ESP_OK);
941
942 ESP_LOGI(MASTER_TAG, "test passed.");
943 }
944
test_dummy(spi_device_handle_t spi,int dummy_n,uint8_t * data_to_send,int len)945 void test_dummy(spi_device_handle_t spi, int dummy_n, uint8_t *data_to_send, int len)
946 {
947 ESP_LOGI(TAG, "testing dummy n=%d", dummy_n);
948 WORD_ALIGNED_ATTR uint8_t slave_buffer[len + (dummy_n + 7) / 8];
949 spi_slave_transaction_t slave_t = {
950 .tx_buffer = slave_buffer,
951 .rx_buffer = slave_buffer,
952 .length = len * 8 + ((dummy_n + 7) & (~8)) + 32, //receive more bytes to avoid slave discarding data
953 };
954 TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_t, portMAX_DELAY));
955
956 vTaskDelay(50);
957
958 spi_transaction_ext_t t = {
959 .base = {
960 .tx_buffer = data_to_send,
961 .length = (len + 1) * 8, //send one more byte force slave receive all data
962 .flags = SPI_TRANS_VARIABLE_DUMMY,
963 },
964 .dummy_bits = dummy_n,
965 };
966 TEST_ESP_OK(spi_device_transmit(spi, (spi_transaction_t *)&t));
967
968 spi_slave_transaction_t *ret_slave;
969 TEST_ESP_OK(spi_slave_get_trans_result(TEST_SLAVE_HOST, &ret_slave, portMAX_DELAY));
970 TEST_ASSERT(ret_slave == &slave_t);
971
972 ESP_LOG_BUFFER_HEXDUMP("rcv", slave_buffer, len + 4, ESP_LOG_INFO);
973 int skip_cnt = dummy_n / 8;
974 int dummy_remain = dummy_n % 8;
975 uint8_t *slave_ptr = slave_buffer;
976 if (dummy_remain > 0) {
977 for (int i = 0; i < len; i++) {
978 slave_ptr[0] = (slave_ptr[skip_cnt] << dummy_remain) | (slave_ptr[skip_cnt + 1] >> (8 - dummy_remain));
979 slave_ptr++;
980 }
981 } else {
982 for (int i = 0; i < len; i++) {
983 slave_ptr[0] = slave_ptr[skip_cnt];
984 slave_ptr++;
985 }
986 }
987 TEST_ASSERT_EQUAL_HEX8_ARRAY(data_to_send, slave_buffer, len);
988 }
989
990 TEST_CASE("SPI master variable dummy test", "[spi]")
991 {
992 spi_device_handle_t spi;
993 spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
994 spi_device_interface_config_t dev_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
995 dev_cfg.flags = SPI_DEVICE_HALFDUPLEX;
996
997 TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, 0));
998 TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi));
999
1000 spi_slave_interface_config_t slave_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
1001 TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slave_cfg, 0));
1002
1003 spitest_gpio_output_sel(bus_cfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
1004 spitest_gpio_output_sel(bus_cfg.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
1005 spitest_gpio_output_sel(dev_cfg.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
1006 spitest_gpio_output_sel(bus_cfg.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
1007
1008 uint8_t data_to_send[] = {0x12, 0x34, 0x56, 0x78};
1009
1010 test_dummy(spi, 0, data_to_send, sizeof(data_to_send));
1011 test_dummy(spi, 1, data_to_send, sizeof(data_to_send));
1012 test_dummy(spi, 2, data_to_send, sizeof(data_to_send));
1013 test_dummy(spi, 3, data_to_send, sizeof(data_to_send));
1014 test_dummy(spi, 4, data_to_send, sizeof(data_to_send));
1015 test_dummy(spi, 8, data_to_send, sizeof(data_to_send));
1016 test_dummy(spi, 12, data_to_send, sizeof(data_to_send));
1017 test_dummy(spi, 16, data_to_send, sizeof(data_to_send));
1018
1019 spi_slave_free(TEST_SLAVE_HOST);
1020 master_free_device_bus(spi);
1021 }
1022
1023 /**
1024 * This test is to check when the first transaction of the HD master is to send data without receiving data via DMA,
1025 * then if the master could receive data correctly.
1026 *
1027 * Because an old version ESP32 silicon issue, there is a workaround to enable and start the RX DMA in FD/HD mode in
1028 * this condition (TX without RX). And if RX DMA is enabled and started in HD mode, because there is no correctly
1029 * linked RX DMA descriptor, there will be an inlink_dscr_error interrupt emerging, which will influence the following
1030 * RX transactions.
1031 *
1032 * This bug is fixed by triggering this workaround only in FD mode.
1033 *
1034 */
1035 TEST_CASE("SPI master hd dma TX without RX test", "[spi]")
1036 {
1037 spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
1038 TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, SPI_DMA_CH_AUTO));
1039
1040 spi_device_handle_t spi;
1041 spi_device_interface_config_t dev_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
1042 dev_cfg.flags = SPI_DEVICE_HALFDUPLEX;
1043 dev_cfg.clock_speed_hz = 4 * 1000 * 1000;
1044 TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi));
1045
1046 spi_slave_interface_config_t slave_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
1047 TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slave_cfg, SPI_DMA_CH_AUTO));
1048
1049 same_pin_func_sel(bus_cfg, dev_cfg, 0);
1050
1051 uint32_t buf_size = 32;
1052 uint8_t *mst_send_buf = heap_caps_malloc(buf_size, MALLOC_CAP_DMA);
1053 uint8_t *mst_recv_buf = heap_caps_calloc(buf_size, 1, MALLOC_CAP_DMA);
1054 uint8_t *slv_send_buf = heap_caps_malloc(buf_size, MALLOC_CAP_DMA);
1055 uint8_t *slv_recv_buf = heap_caps_calloc(buf_size, 1, MALLOC_CAP_DMA);
1056
1057 srand(199);
1058 for (int i = 0; i < buf_size; i++) {
1059 mst_send_buf[i] = rand();
1060 }
1061
1062 //1. Master sends without receiving, no rx_buffer is set
1063 spi_slave_transaction_t slave_trans = {
1064 .rx_buffer = slv_recv_buf,
1065 .length = buf_size * 8,
1066 };
1067 TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_trans, portMAX_DELAY));
1068
1069 spi_transaction_t master_trans = {
1070 .tx_buffer = mst_send_buf,
1071 .length = buf_size * 8,
1072 };
1073 TEST_ESP_OK(spi_device_transmit(spi, &master_trans));
1074
1075 spi_slave_transaction_t *ret_slave;
1076 TEST_ESP_OK(spi_slave_get_trans_result(TEST_SLAVE_HOST, &ret_slave, portMAX_DELAY));
1077
1078 spitest_cmp_or_dump(mst_send_buf, slv_recv_buf, buf_size);
1079
1080 //2. Master receives data
1081 for (int i = 100; i < 110; i++) {
1082
1083 srand(i);
1084 for (int j = 0; j < buf_size; j++) {
1085 slv_send_buf[j] = rand();
1086 }
1087 slave_trans = (spi_slave_transaction_t) {};
1088 slave_trans.tx_buffer = slv_send_buf;
1089 slave_trans.length = buf_size * 8;
1090 TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_trans, portMAX_DELAY));
1091
1092 vTaskDelay(50);
1093
1094 master_trans = (spi_transaction_t) {};
1095 master_trans.rx_buffer = mst_recv_buf;
1096 master_trans.rxlength = buf_size * 8;
1097 TEST_ESP_OK(spi_device_transmit(spi, &master_trans));
1098
1099 TEST_ESP_OK(spi_slave_get_trans_result(TEST_SLAVE_HOST, &ret_slave, portMAX_DELAY));
1100
1101 spitest_cmp_or_dump(slv_send_buf, mst_recv_buf, buf_size);
1102 }
1103
1104 free(mst_send_buf);
1105 free(mst_recv_buf);
1106 free(slv_send_buf);
1107 free(slv_recv_buf);
1108 spi_slave_free(TEST_SLAVE_HOST);
1109 master_free_device_bus(spi);
1110 }
1111
1112 //There is only one GPSPI controller, so single-board test is disabled.
1113 #endif //#if !DISABLED_FOR_TARGETS(ESP32C3)
1114
1115 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32) //TODO: IDF-3494
1116 #define FD_TEST_BUF_SIZE 32
1117 #define TEST_NUM 4
1118 #define FD_SEED1 199
1119 #define FD_SEED2 29
1120 #define FD_SEED3 48
1121 #define FD_SEED4 327
1122
master_only_tx_trans(spi_device_handle_t spi,uint8_t * mst_send_buf,uint32_t length)1123 static void master_only_tx_trans(spi_device_handle_t spi, uint8_t *mst_send_buf, uint32_t length)
1124 {
1125 ESP_LOGI(MASTER_TAG, "FD DMA, Only TX:");
1126 spi_transaction_t trans = {0};
1127 trans.tx_buffer = mst_send_buf;
1128 trans.length = length * 8;
1129 unity_wait_for_signal("Slave ready");
1130 TEST_ESP_OK(spi_device_transmit(spi, &trans));
1131 ESP_LOG_BUFFER_HEX("MASTER TX:", mst_send_buf, length);
1132 }
1133
master_only_rx_trans(spi_device_handle_t spi,uint8_t * mst_recv_buf,uint8_t * slv_send_buf,uint32_t length)1134 static void master_only_rx_trans(spi_device_handle_t spi, uint8_t *mst_recv_buf, uint8_t *slv_send_buf, uint32_t length)
1135 {
1136 ESP_LOGI(MASTER_TAG, "FD DMA, Only RX:");
1137 spi_transaction_t trans = {0};
1138 trans.tx_buffer = NULL;
1139 trans.rx_buffer = mst_recv_buf;
1140 trans.length = length * 8;
1141 unity_wait_for_signal("Slave ready");
1142 TEST_ESP_OK(spi_device_transmit(spi, &trans));
1143 ESP_LOG_BUFFER_HEX("MASTER RX:", mst_recv_buf, length);
1144 TEST_ASSERT_EQUAL_HEX8_ARRAY(slv_send_buf, mst_recv_buf, length);
1145 }
1146
master_both_trans(spi_device_handle_t spi,uint8_t * mst_send_buf,uint8_t * mst_recv_buf,uint8_t * slv_send_buf,uint32_t length)1147 static void master_both_trans(spi_device_handle_t spi, uint8_t *mst_send_buf, uint8_t *mst_recv_buf, uint8_t *slv_send_buf, uint32_t length)
1148 {
1149 ESP_LOGI(MASTER_TAG, "FD DMA, Both TX and RX:");
1150 spi_transaction_t trans = {0};
1151 trans.tx_buffer = mst_send_buf;
1152 trans.rx_buffer = mst_recv_buf;
1153 trans.length = length * 8;
1154 unity_wait_for_signal("Slave ready");
1155 TEST_ESP_OK(spi_device_transmit(spi, &trans));
1156 ESP_LOG_BUFFER_HEX("MASTER TX:", mst_send_buf, length);
1157 ESP_LOG_BUFFER_HEX("MASTER RX:", mst_recv_buf, length);
1158 TEST_ASSERT_EQUAL_HEX8_ARRAY(slv_send_buf, mst_recv_buf, length);
1159 }
1160
fd_master(void)1161 static void fd_master(void)
1162 {
1163 spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
1164 TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, SPI_DMA_CH_AUTO));
1165
1166 spi_device_handle_t spi;
1167 spi_device_interface_config_t dev_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
1168 TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi));
1169
1170 unity_send_signal("Master ready");
1171
1172 uint8_t *mst_send_buf = heap_caps_malloc(FD_TEST_BUF_SIZE, MALLOC_CAP_DMA);
1173 uint8_t *mst_recv_buf = heap_caps_calloc(FD_TEST_BUF_SIZE, 1, MALLOC_CAP_DMA);
1174 uint8_t *slv_send_buf = heap_caps_malloc(FD_TEST_BUF_SIZE, MALLOC_CAP_DMA);
1175
1176 //Master FD DMA, RX without TX Test
1177 for (int i = 0; i < TEST_NUM; i++) {
1178 // 1. Master FD DMA, only receive, with NULL tx_buffer
1179 get_tx_buffer(FD_SEED1+i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1180 memset(mst_recv_buf, 0x0, FD_TEST_BUF_SIZE);
1181 master_only_rx_trans(spi, mst_recv_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1182
1183 //2. Master FD DMA with TX and RX
1184 get_tx_buffer(FD_SEED2+i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1185 memset(mst_recv_buf, 0x0, FD_TEST_BUF_SIZE);
1186 master_both_trans(spi, mst_send_buf, mst_recv_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1187 }
1188
1189 //Master FD DMA, TX without RX Test
1190 for (int i = 0; i < TEST_NUM; i++) {
1191 // 1. Master FD DMA, only send, with NULL rx_buffer
1192 get_tx_buffer(FD_SEED3+i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1193 master_only_tx_trans(spi, mst_send_buf, FD_TEST_BUF_SIZE);
1194
1195 //2. Master FD DMA with TX and RX
1196 get_tx_buffer(FD_SEED4+i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1197 memset(mst_recv_buf, 0x0, FD_TEST_BUF_SIZE);
1198 master_both_trans(spi, mst_send_buf, mst_recv_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1199 }
1200
1201 free(mst_send_buf);
1202 free(mst_recv_buf);
1203 free(slv_send_buf);
1204 master_free_device_bus(spi);
1205 }
1206
slave_only_tx_trans(uint8_t * slv_send_buf,uint32_t length)1207 static void slave_only_tx_trans(uint8_t *slv_send_buf, uint32_t length)
1208 {
1209 ESP_LOGI(SLAVE_TAG, "FD DMA, Only TX");
1210 spi_slave_transaction_t trans = {0};
1211 trans.tx_buffer = slv_send_buf;
1212 trans.length = length * 8;
1213 unity_send_signal("Slave ready");
1214 TEST_ESP_OK(spi_slave_transmit(SPI2_HOST, &trans, portMAX_DELAY));
1215 ESP_LOG_BUFFER_HEX("SLAVE TX:", slv_send_buf, length);
1216 }
1217
slave_only_rx_trans(uint8_t * slv_recv_buf,uint8_t * mst_send_buf,uint32_t length)1218 static void slave_only_rx_trans(uint8_t *slv_recv_buf, uint8_t *mst_send_buf, uint32_t length)
1219 {
1220 ESP_LOGI(SLAVE_TAG, "FD DMA, Only RX");
1221 spi_slave_transaction_t trans = {};
1222 trans.tx_buffer = NULL;
1223 trans.rx_buffer = slv_recv_buf;
1224 trans.length = length * 8;
1225 unity_send_signal("Slave ready");
1226 TEST_ESP_OK(spi_slave_transmit(SPI2_HOST, &trans, portMAX_DELAY));
1227 ESP_LOG_BUFFER_HEX("SLAVE RX:", slv_recv_buf, length);
1228 TEST_ASSERT_EQUAL(length * 8, trans.trans_len);
1229 TEST_ASSERT_EQUAL_HEX8_ARRAY(mst_send_buf, slv_recv_buf, length);
1230 }
1231
slave_both_trans(uint8_t * slv_send_buf,uint8_t * slv_recv_buf,uint8_t * mst_send_buf,uint32_t length)1232 static void slave_both_trans(uint8_t *slv_send_buf, uint8_t *slv_recv_buf, uint8_t *mst_send_buf, uint32_t length)
1233 {
1234 ESP_LOGI(SLAVE_TAG, "FD DMA, Both TX and RX:");
1235 spi_slave_transaction_t trans = {0};
1236 trans.tx_buffer = slv_send_buf;
1237 trans.rx_buffer = slv_recv_buf;
1238 trans.length = length * 8;
1239 unity_send_signal("Slave ready");
1240 TEST_ESP_OK(spi_slave_transmit(SPI2_HOST, &trans, portMAX_DELAY));
1241 ESP_LOG_BUFFER_HEX("SLAVE TX:", slv_send_buf, length);
1242 ESP_LOG_BUFFER_HEX("SLAVE RX:", slv_recv_buf, length);
1243 TEST_ASSERT_EQUAL_HEX8_ARRAY(mst_send_buf, slv_recv_buf, length);
1244 }
1245
fd_slave(void)1246 static void fd_slave(void)
1247 {
1248 spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
1249 spi_slave_interface_config_t slvcfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
1250
1251 TEST_ESP_OK(spi_slave_initialize(SPI2_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO));
1252
1253 unity_wait_for_signal("Master ready");
1254
1255 uint8_t *slv_send_buf = heap_caps_malloc(FD_TEST_BUF_SIZE, MALLOC_CAP_DMA);
1256 uint8_t *slv_recv_buf = heap_caps_calloc(FD_TEST_BUF_SIZE, 1, MALLOC_CAP_DMA);
1257 uint8_t *mst_send_buf = heap_caps_malloc(FD_TEST_BUF_SIZE, MALLOC_CAP_DMA);
1258
1259 for (int i = 0; i < TEST_NUM; i++) {
1260 //1. Slave TX without RX (rx_buffer == NULL)
1261 get_tx_buffer(FD_SEED1+i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1262 slave_only_tx_trans(slv_send_buf, FD_TEST_BUF_SIZE);
1263
1264 //2. Slave both TX and RX
1265 get_tx_buffer(FD_SEED2+i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1266 memset(slv_recv_buf, 0x0, FD_TEST_BUF_SIZE);
1267 slave_both_trans(slv_send_buf, slv_recv_buf, mst_send_buf, FD_TEST_BUF_SIZE);
1268 }
1269
1270 for (int i = 0; i < TEST_NUM; i++) {
1271 // 1. Slave RX without TX (tx_buffer == NULL)
1272 get_tx_buffer(FD_SEED3+i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1273 memset(slv_recv_buf, 0x0, FD_TEST_BUF_SIZE);
1274 slave_only_rx_trans(slv_recv_buf, mst_send_buf, FD_TEST_BUF_SIZE);
1275
1276 //2. Slave both TX and RX
1277 get_tx_buffer(FD_SEED4+i, mst_send_buf, slv_send_buf, FD_TEST_BUF_SIZE);
1278 memset(slv_recv_buf, 0x0, FD_TEST_BUF_SIZE);
1279 slave_both_trans(slv_send_buf, slv_recv_buf, mst_send_buf, FD_TEST_BUF_SIZE);
1280 }
1281
1282 free(slv_send_buf);
1283 free(slv_recv_buf);
1284 free(mst_send_buf);
1285 TEST_ASSERT(spi_slave_free(SPI2_HOST) == ESP_OK);
1286 }
1287
1288 TEST_CASE_MULTIPLE_DEVICES("SPI Master: FD, DMA, Master Single Direction Test", "[spi_ms][test_env=Example_SPI_Multi_device]", fd_master, fd_slave);
1289 #endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32) //TODO: IDF-3494
1290
1291 /********************************************************************************
1292 * Test SPI transaction interval
1293 ********************************************************************************/
1294 //Disabled since the check in portENTER_CRITICAL in esp_intr_enable/disable increase the delay
1295 #ifndef CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
1296
1297 #define RECORD_TIME_PREPARE() uint32_t __t1, __t2
1298 #define RECORD_TIME_START() do {__t1 = esp_cpu_get_ccount();}while(0)
1299 #define RECORD_TIME_END(p_time) do{__t2 = esp_cpu_get_ccount(); *p_time = (__t2-__t1);}while(0)
1300 #ifdef CONFIG_IDF_TARGET_ESP32
1301 #define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ)
1302 #elif CONFIG_IDF_TARGET_ESP32S2
1303 #define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ)
1304 #elif CONFIG_IDF_TARGET_ESP32S3
1305 #define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ)
1306 #elif CONFIG_IDF_TARGET_ESP32C3
1307 #define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ)
1308 #endif
1309
speed_setup(spi_device_handle_t * spi,bool use_dma)1310 static void speed_setup(spi_device_handle_t *spi, bool use_dma)
1311 {
1312 spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
1313 spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
1314 devcfg.queue_size = 8; //We want to be able to queue 7 transactions at a time
1315
1316 //Initialize the SPI bus and the device to test
1317 TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, (use_dma ? SPI_DMA_CH_AUTO : 0)));
1318 TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, spi));
1319 }
1320
sorted_array_insert(uint32_t * array,int * size,uint32_t item)1321 static void sorted_array_insert(uint32_t *array, int *size, uint32_t item)
1322 {
1323 int pos;
1324 for (pos = *size; pos > 0; pos--) {
1325 if (array[pos - 1] < item) {
1326 break;
1327 }
1328 array[pos] = array[pos - 1];
1329 }
1330 array[pos] = item;
1331 (*size)++;
1332 }
1333
1334 #define TEST_TIMES 11
1335
spi_transmit_measure(spi_device_handle_t spi,spi_transaction_t * trans,uint32_t * t_flight)1336 static IRAM_ATTR NOINLINE_ATTR void spi_transmit_measure(spi_device_handle_t spi, spi_transaction_t *trans, uint32_t *t_flight)
1337 {
1338 RECORD_TIME_PREPARE();
1339 spi_device_transmit(spi, trans); // prime the flash cache
1340 RECORD_TIME_START();
1341 spi_device_transmit(spi, trans);
1342 RECORD_TIME_END(t_flight);
1343 }
1344
spi_transmit_polling_measure(spi_device_handle_t spi,spi_transaction_t * trans,uint32_t * t_flight)1345 static IRAM_ATTR NOINLINE_ATTR void spi_transmit_polling_measure(spi_device_handle_t spi, spi_transaction_t *trans, uint32_t *t_flight)
1346 {
1347 spi_flash_disable_interrupts_caches_and_other_cpu(); //this can test the code are all in the IRAM at the same time
1348 RECORD_TIME_PREPARE();
1349 spi_device_polling_transmit(spi, trans); // prime the flash cache
1350 RECORD_TIME_START();
1351 spi_device_polling_transmit(spi, trans);
1352 RECORD_TIME_END(t_flight);
1353 spi_flash_enable_interrupts_caches_and_other_cpu();
1354 }
1355
1356 TEST_CASE("spi_speed", "[spi]")
1357 {
1358 uint32_t t_flight;
1359 //to get rid of the influence of randomly interrupts, we measured the performance by median value
1360 uint32_t t_flight_sorted[TEST_TIMES];
1361 esp_err_t ret;
1362 int t_flight_num = 0;
1363
1364 spi_device_handle_t spi;
1365 const bool use_dma = true;
1366 WORD_ALIGNED_ATTR spi_transaction_t trans = {
1367 .length = 1 * 8,
1368 .flags = SPI_TRANS_USE_TXDATA,
1369 };
1370
1371 //first work with DMA
1372 speed_setup(&spi, use_dma);
1373
1374 //record flight time by isr, with DMA
1375 t_flight_num = 0;
1376 for (int i = 0; i < TEST_TIMES; i++) {
1377 spi_transmit_measure(spi, &trans, &t_flight);
1378 sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
1379 }
1380 for (int i = 0; i < TEST_TIMES; i++) {
1381 ESP_LOGI(TAG, "%.2lf", GET_US_BY_CCOUNT(t_flight_sorted[i]));
1382 }
1383 #ifndef CONFIG_SPIRAM
1384 TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_NO_POLLING, "%d us", (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2]));
1385 #endif
1386
1387 //acquire the bus to send polling transactions faster
1388 ret = spi_device_acquire_bus(spi, portMAX_DELAY);
1389 TEST_ESP_OK(ret);
1390
1391 //record flight time by polling and with DMA
1392 t_flight_num = 0;
1393 for (int i = 0; i < TEST_TIMES; i++) {
1394 spi_transmit_polling_measure(spi, &trans, &t_flight);
1395 sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
1396 }
1397 for (int i = 0; i < TEST_TIMES; i++) {
1398 ESP_LOGI(TAG, "%.2lf", GET_US_BY_CCOUNT(t_flight_sorted[i]));
1399 }
1400 #ifndef CONFIG_SPIRAM
1401 TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_POLLING, "%d us", (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2]));
1402 #endif
1403
1404 //release the bus
1405 spi_device_release_bus(spi);
1406
1407 master_free_device_bus(spi);
1408
1409 speed_setup(&spi, !use_dma);
1410
1411 //record flight time by isr, without DMA
1412 t_flight_num = 0;
1413 for (int i = 0; i < TEST_TIMES; i++) {
1414 spi_transmit_measure(spi, &trans, &t_flight);
1415 sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
1416 }
1417 for (int i = 0; i < TEST_TIMES; i++) {
1418 ESP_LOGI(TAG, "%.2lf", GET_US_BY_CCOUNT(t_flight_sorted[i]));
1419 }
1420 #ifndef CONFIG_SPIRAM
1421 TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_NO_POLLING_NO_DMA, "%d us", (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2]));
1422 #endif
1423
1424 //acquire the bus to send polling transactions faster
1425 ret = spi_device_acquire_bus(spi, portMAX_DELAY);
1426 TEST_ESP_OK(ret);
1427 //record flight time by polling, without DMA
1428 t_flight_num = 0;
1429 for (int i = 0; i < TEST_TIMES; i++) {
1430 spi_transmit_polling_measure(spi, &trans, &t_flight);
1431 sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
1432 }
1433 for (int i = 0; i < TEST_TIMES; i++) {
1434 ESP_LOGI(TAG, "%.2lf", GET_US_BY_CCOUNT(t_flight_sorted[i]));
1435 }
1436 #ifndef CONFIG_SPIRAM
1437 TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_POLLING_NO_DMA, "%d us", (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2]));
1438 #endif
1439
1440 //release the bus
1441 spi_device_release_bus(spi);
1442 master_free_device_bus(spi);
1443 }
1444 #endif // CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
1445