test_spi_param.c 44 KB

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