test_spi_param.c 44 KB

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