test_common_spi.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include "test/test_common_spi.h"
  2. #include "driver/spi_slave.h"
  3. #include "esp_log.h"
  4. int test_freq_default[]=TEST_FREQ_DEFAULT();
  5. const char MASTER_TAG[] = "test_master";
  6. const char SLAVE_TAG[] = "test_slave";
  7. DRAM_ATTR uint8_t spitest_master_send[] = {
  8. 0x93, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43,
  9. 0x74,
  10. 0x93, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43,
  11. 0x74,
  12. 0x93, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43,
  13. 0x74,
  14. };
  15. DRAM_ATTR uint8_t spitest_slave_send[] = {
  16. 0xaa, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0,
  17. 0xda,
  18. 0xaa, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0,
  19. 0xda,
  20. 0xaa, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0,
  21. 0xda,
  22. };
  23. void spitest_def_param(void* arg)
  24. {
  25. spitest_param_set_t *param_set=(spitest_param_set_t*)arg;
  26. param_set->test_size = 8;
  27. if (param_set->freq_list==NULL) param_set->freq_list = test_freq_default;
  28. }
  29. /**********************************************************************************
  30. * functions for slave task
  31. *********************************************************************************/
  32. esp_err_t init_slave_context(spi_slave_task_context_t *context)
  33. {
  34. context->data_to_send = xQueueCreate( 16, sizeof( slave_txdata_t ));
  35. if ( context->data_to_send == NULL ) {
  36. return ESP_ERR_NO_MEM;
  37. }
  38. context->data_received = xRingbufferCreate( 1024, RINGBUF_TYPE_NOSPLIT );
  39. if ( context->data_received == NULL ) {
  40. return ESP_ERR_NO_MEM;
  41. }
  42. context->spi=VSPI_HOST;
  43. return ESP_OK;
  44. }
  45. void deinit_slave_context(spi_slave_task_context_t *context)
  46. {
  47. TEST_ASSERT( context->data_to_send != NULL );
  48. vQueueDelete( context->data_to_send );
  49. context->data_to_send = NULL;
  50. TEST_ASSERT( context->data_received != NULL );
  51. vRingbufferDelete( context->data_received );
  52. context->data_received = NULL;
  53. }
  54. /* The task requires a queue and a ringbuf, which should be initialized before task starts.
  55. Send ``slave_txdata_t`` to the queue to make the task send data;
  56. the task returns data got to the ringbuf, which should have sufficient size.
  57. */
  58. void spitest_slave_task(void* arg)
  59. {
  60. spi_slave_task_context_t* context = (spi_slave_task_context_t*) arg;
  61. QueueHandle_t queue = context->data_to_send;
  62. RingbufHandle_t ringbuf = context->data_received;
  63. uint8_t recvbuf[320+8];
  64. slave_txdata_t txdata;
  65. ESP_LOGI( SLAVE_TAG, "slave up" );
  66. //never quit, but blocked by the queue, waiting to be killed, when no more send from main task.
  67. while( 1 ) {
  68. BaseType_t ret = xQueueReceive( queue, &txdata, portMAX_DELAY );
  69. assert(ret);
  70. spi_slave_transaction_t t = {};
  71. t.length = txdata.len;
  72. t.tx_buffer = txdata.start;
  73. t.rx_buffer = recvbuf+8;
  74. //loop until trans_len != 0 to skip glitches
  75. do {
  76. TEST_ESP_OK( spi_slave_transmit( context->spi, &t, portMAX_DELAY ) );
  77. } while ( t.trans_len <= 2 );
  78. memcpy(recvbuf, &t.trans_len, sizeof(uint32_t));
  79. *(uint8_t**)(recvbuf+4) = (uint8_t*)txdata.start;
  80. ESP_LOGI( SLAVE_TAG, "received: %d", t.trans_len );
  81. xRingbufferSend( ringbuf, recvbuf, 8+(t.trans_len+7)/8, portMAX_DELAY );
  82. }
  83. }
  84. void slave_pull_up(const spi_bus_config_t* cfg, int spics_io_num)
  85. {
  86. gpio_set_pull_mode(cfg->mosi_io_num, GPIO_PULLUP_ONLY);
  87. gpio_set_pull_mode(cfg->sclk_io_num, GPIO_PULLUP_ONLY);
  88. gpio_set_pull_mode(spics_io_num, GPIO_PULLUP_ONLY);
  89. }
  90. /**********************************************************************************
  91. * functions for slave task
  92. *********************************************************************************/
  93. static int test_len[] = {1, 3, 5, 7, 9, 11, 33, 64};
  94. void spitest_init_transactions(const spitest_param_set_t *cfg, spitest_context_t* context)
  95. {
  96. spi_transaction_t* trans = context->master_trans;
  97. uint8_t *rx_buf_ptr = context->master_rxbuf;
  98. const spi_dup_t dup = cfg->dup;
  99. for (int i = 0; i < cfg->test_size; i++) {
  100. const void* tx_buffer = spitest_master_send + i%8;
  101. int length = 8*test_len[i];
  102. if (cfg->length_aligned) length = (length+31)&(~31);
  103. if (dup == HALF_DUPLEX_MISO) {
  104. trans[i] = (spi_transaction_t) {
  105. .rx_buffer = rx_buf_ptr,
  106. .rxlength = length,
  107. };
  108. } else if (dup == HALF_DUPLEX_MOSI) {
  109. trans[i] = (spi_transaction_t) {
  110. .tx_buffer = tx_buffer,
  111. .length = length,
  112. };
  113. } else {
  114. trans[i] = (spi_transaction_t) {
  115. .tx_buffer = tx_buffer,
  116. .length = length,
  117. .rx_buffer = rx_buf_ptr,
  118. };
  119. }
  120. rx_buf_ptr = (uint8_t*)( (uint32_t)(rx_buf_ptr + (length+7)/8 + 3) & (~3));
  121. const void* slave_tx = spitest_slave_send + (cfg->slave_unaligned_addr? i%3: (i%3)*4);
  122. //prepare slave tx data
  123. context->slave_trans[i] = (slave_txdata_t) {
  124. .start = slave_tx,
  125. .len = 512,
  126. };
  127. if (cfg->slave_dma_chan != 0) context->slave_trans[i].len = 1024;
  128. }
  129. }
  130. void spitest_master_print_data(spi_transaction_t *t, int rxlength)
  131. {
  132. if (t->tx_buffer) ESP_LOG_BUFFER_HEX( "master tx", t->tx_buffer, t->length/8 );
  133. if (t->rx_buffer) ESP_LOG_BUFFER_HEX( "master rx", t->rx_buffer, rxlength/8 );
  134. }
  135. void spitest_slave_print_data(slave_rxdata_t *t, bool print_rxdata)
  136. {
  137. int rcv_len = (t->len+7)/8;
  138. ESP_LOGI(SLAVE_TAG, "trans_len: %d", t->len);
  139. ESP_LOG_BUFFER_HEX("slave tx", t->tx_start, rcv_len);
  140. if (print_rxdata) ESP_LOG_BUFFER_HEX("slave rx", t->data, rcv_len);
  141. }
  142. esp_err_t spitest_check_data(int len, spi_transaction_t *master_t, slave_rxdata_t *slave_t, bool check_master_data, bool check_slave_len, bool check_slave_data)
  143. {
  144. //currently the rcv_len can be in range of [t->length-1, t->length+3]
  145. if (check_slave_len) {
  146. uint32_t rcv_len = slave_t->len;
  147. TEST_ASSERT(rcv_len >= len - 1 && rcv_len <= len + 4);
  148. }
  149. //if (dup!=HALF_DUPLEX_MOSI) {
  150. if (check_master_data) {
  151. TEST_ASSERT_EQUAL_HEX8_ARRAY(slave_t->tx_start, master_t->rx_buffer, (len + 7) / 8);
  152. }
  153. //if (dup!=HALF_DUPLEX_MISO) {
  154. if (check_slave_data) {
  155. TEST_ASSERT_EQUAL_HEX8_ARRAY(master_t->tx_buffer, slave_t->data, (len + 7) / 8);
  156. }
  157. return ESP_OK;
  158. }
  159. void master_free_device_bus(spi_device_handle_t spi)
  160. {
  161. TEST_ESP_OK( spi_bus_remove_device(spi) );
  162. TEST_ESP_OK( spi_bus_free(TEST_SPI_HOST) );
  163. }
  164. void spitest_gpio_output_sel(uint32_t gpio_num, int func, uint32_t signal_idx)
  165. {
  166. PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], func);
  167. GPIO.func_out_sel_cfg[gpio_num].func_sel=signal_idx;
  168. }