test_spi_param.c 43 KB

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