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