test_spi_param.c 38 KB

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