test_ahb_arb.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. #include <esp_types.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "esp32/rom/ets_sys.h"
  5. #include "esp32/rom/lldesc.h"
  6. #include "esp32/rom/gpio.h"
  7. #include "driver/periph_ctrl.h"
  8. #include "freertos/FreeRTOS.h"
  9. #include "freertos/task.h"
  10. #include "freertos/semphr.h"
  11. #include "freertos/queue.h"
  12. #include "freertos/xtensa_api.h"
  13. #include "unity.h"
  14. #include "soc/uart_periph.h"
  15. #include "soc/dport_reg.h"
  16. #include "soc/gpio_periph.h"
  17. #include "soc/i2s_periph.h"
  18. #define DPORT_I2S0_CLK_EN (BIT(4))
  19. #define DPORT_I2S0_RST (BIT(4))
  20. /*
  21. This test tests the s32c1i instruction when the AHB bus is also used. To create some AHB traffic, we use the I2S interface
  22. to copy bytes over from one memory location to another. DO NOT USE the i2s routines inhere, they've been trial-and-error'ed until
  23. the point where they happened to do what I want.
  24. */
  25. static void lcdIfaceInit(void)
  26. {
  27. periph_module_enable(PERIPH_I2S0_MODULE);
  28. //Init pins to i2s functions
  29. SET_PERI_REG_MASK(GPIO_ENABLE_W1TS_REG, (1 << 11) | (1 << 3) | (1 << 0) | (1 << 2) | (1 << 5) | (1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20)); //ENABLE GPIO oe_enable
  30. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, 0);
  31. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, 0);
  32. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, 0);
  33. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO16_U, 0);
  34. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U, 0);
  35. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO18_U, 0);
  36. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO19_U, 0);
  37. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO20_U, 0);
  38. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 2); //11
  39. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO26_U, 0); //RS
  40. WRITE_PERI_REG(GPIO_FUNC0_OUT_SEL_CFG_REG, (148 << GPIO_FUNC0_OUT_SEL_S));
  41. WRITE_PERI_REG(GPIO_FUNC2_OUT_SEL_CFG_REG, (149 << GPIO_FUNC0_OUT_SEL_S));
  42. WRITE_PERI_REG(GPIO_FUNC5_OUT_SEL_CFG_REG, (150 << GPIO_FUNC0_OUT_SEL_S));
  43. WRITE_PERI_REG(GPIO_FUNC16_OUT_SEL_CFG_REG, (151 << GPIO_FUNC0_OUT_SEL_S));
  44. WRITE_PERI_REG(GPIO_FUNC17_OUT_SEL_CFG_REG, (152 << GPIO_FUNC0_OUT_SEL_S));
  45. WRITE_PERI_REG(GPIO_FUNC18_OUT_SEL_CFG_REG, (153 << GPIO_FUNC0_OUT_SEL_S));
  46. WRITE_PERI_REG(GPIO_FUNC19_OUT_SEL_CFG_REG, (154 << GPIO_FUNC0_OUT_SEL_S));
  47. WRITE_PERI_REG(GPIO_FUNC20_OUT_SEL_CFG_REG, (155 << GPIO_FUNC0_OUT_SEL_S));
  48. WRITE_PERI_REG(GPIO_FUNC26_OUT_SEL_CFG_REG, (156 << GPIO_FUNC0_OUT_SEL_S)); //RS
  49. WRITE_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG_REG, (I2S0O_WS_OUT_IDX << GPIO_FUNC0_OUT_SEL_S));
  50. // WRITE_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG, (I2S0O_BCK_OUT_IDX<<GPIO_GPIO_FUNC0_OUT_SEL_S));
  51. //GPIO_SET_GPIO_FUNC11_OUT_INV_SEL(1); //old
  52. WRITE_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG_REG, READ_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG_REG) | GPIO_FUNC11_OUT_INV_SEL);
  53. //Reset I2S subsystem
  54. CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET | I2S_TX_RESET);
  55. SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET | I2S_TX_RESET);
  56. CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET | I2S_TX_RESET);
  57. WRITE_PERI_REG(I2S_CONF_REG(0), 0);//I2S_SIG_LOOPBACK);
  58. WRITE_PERI_REG(I2S_CONF2_REG(0), 0);
  59. WRITE_PERI_REG(I2S_SAMPLE_RATE_CONF_REG(0),
  60. (16 << I2S_RX_BITS_MOD_S) |
  61. (16 << I2S_TX_BITS_MOD_S) |
  62. (1 << I2S_RX_BCK_DIV_NUM_S) |
  63. (1 << I2S_TX_BCK_DIV_NUM_S));
  64. WRITE_PERI_REG(I2S_CLKM_CONF_REG(0),
  65. I2S_CLKA_ENA | I2S_CLK_EN |
  66. (1 << I2S_CLKM_DIV_A_S) |
  67. (1 << I2S_CLKM_DIV_B_S) |
  68. (1 << I2S_CLKM_DIV_NUM_S));
  69. WRITE_PERI_REG(I2S_FIFO_CONF_REG(0),
  70. (32 << I2S_TX_DATA_NUM_S) | //Low watermark for IRQ
  71. (32 << I2S_RX_DATA_NUM_S));
  72. WRITE_PERI_REG(I2S_CONF1_REG(0), I2S_RX_PCM_BYPASS | I2S_TX_PCM_BYPASS);
  73. WRITE_PERI_REG(I2S_CONF_CHAN_REG(0), (2 << I2S_TX_CHAN_MOD_S) | (2 << I2S_RX_CHAN_MOD_S));
  74. //Invert WS to active-low
  75. SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_RIGHT_FIRST | I2S_RX_RIGHT_FIRST);
  76. WRITE_PERI_REG(I2S_TIMING_REG(0), 0);
  77. }
  78. static volatile lldesc_t dmaDesc[2];
  79. static void finishDma(void)
  80. {
  81. //No need to finish if no DMA transfer going on
  82. if (!(READ_PERI_REG(I2S_FIFO_CONF_REG(0))&I2S_DSCR_EN)) {
  83. return;
  84. }
  85. //Wait till fifo done
  86. while (!(READ_PERI_REG(I2S_INT_RAW_REG(0))&I2S_TX_REMPTY_INT_RAW)) ;
  87. //Wait for last bytes to leave i2s xmit thing
  88. //ToDo: poll bit in next hw
  89. // for (i=0; i<(1<<8); i++);
  90. while (!(READ_PERI_REG(I2S_STATE_REG(0))&I2S_TX_IDLE));
  91. //Reset I2S for next transfer
  92. CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_START | I2S_RX_START);
  93. CLEAR_PERI_REG_MASK(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START | I2S_INLINK_START);
  94. SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_RESET | I2S_TX_FIFO_RESET | I2S_RX_RESET | I2S_RX_FIFO_RESET);
  95. CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_RESET | I2S_TX_FIFO_RESET | I2S_RX_RESET | I2S_RX_FIFO_RESET);
  96. // for (i=0; i<(1<<8); i++);
  97. while ((READ_PERI_REG(I2S_STATE_REG(0))&I2S_TX_FIFO_RESET_BACK));
  98. }
  99. /*
  100. This is a very, very, very hacked up LCD routine which ends up basically doing a memcpy from sbuf to rbuf.
  101. */
  102. static void sendRecvBufDma(uint16_t *sbuf, uint16_t *rbuf, int len)
  103. {
  104. //Fill DMA descriptor
  105. dmaDesc[0].length = len * 2;
  106. dmaDesc[0].size = len * 2;
  107. dmaDesc[0].owner = 1;
  108. dmaDesc[0].sosf = 0;
  109. dmaDesc[0].buf = (uint8_t *)sbuf;
  110. dmaDesc[0].offset = 0; //unused in hw
  111. dmaDesc[0].empty = 0;
  112. dmaDesc[0].eof = 1;
  113. dmaDesc[1].length = len * 2;
  114. dmaDesc[1].size = len * 2;
  115. dmaDesc[1].owner = 1;
  116. dmaDesc[1].sosf = 0;
  117. dmaDesc[1].buf = (uint8_t *)rbuf;
  118. dmaDesc[1].offset = 0; //unused in hw
  119. dmaDesc[1].empty = 0;
  120. dmaDesc[1].eof = 1;
  121. //Reset DMA
  122. SET_PERI_REG_MASK(I2S_LC_CONF_REG(0), I2S_IN_RST | I2S_OUT_RST | I2S_AHBM_RST | I2S_AHBM_FIFO_RST);
  123. CLEAR_PERI_REG_MASK(I2S_LC_CONF_REG(0), I2S_IN_RST | I2S_OUT_RST | I2S_AHBM_RST | I2S_AHBM_FIFO_RST);
  124. //Reset I2S FIFO
  125. SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET | I2S_TX_RESET | I2S_TX_FIFO_RESET | I2S_RX_FIFO_RESET);
  126. CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET | I2S_TX_RESET | I2S_TX_FIFO_RESET | I2S_RX_FIFO_RESET);
  127. //Set desc addr
  128. CLEAR_PERI_REG_MASK(I2S_OUT_LINK_REG(0), I2S_OUTLINK_ADDR);
  129. SET_PERI_REG_MASK(I2S_OUT_LINK_REG(0), ((uint32_t)(&dmaDesc[0]))&I2S_OUTLINK_ADDR);
  130. CLEAR_PERI_REG_MASK(I2S_IN_LINK_REG(0), I2S_INLINK_ADDR);
  131. SET_PERI_REG_MASK(I2S_IN_LINK_REG(0), ((uint32_t)(&dmaDesc[1]))&I2S_INLINK_ADDR);
  132. SET_PERI_REG_MASK(I2S_FIFO_CONF_REG(0), I2S_DSCR_EN); //Enable DMA mode
  133. WRITE_PERI_REG(I2S_RXEOF_NUM_REG(0), len);
  134. //Enable and configure DMA
  135. WRITE_PERI_REG(I2S_LC_CONF_REG(0), I2S_OUT_DATA_BURST_EN |
  136. I2S_OUT_EOF_MODE | I2S_OUTDSCR_BURST_EN | I2S_OUT_DATA_BURST_EN |
  137. I2S_INDSCR_BURST_EN | I2S_MEM_TRANS_EN);
  138. //Start transmission
  139. SET_PERI_REG_MASK(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START);
  140. SET_PERI_REG_MASK(I2S_IN_LINK_REG(0), I2S_INLINK_START);
  141. SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_START | I2S_RX_START);
  142. //Clear int flags
  143. WRITE_PERI_REG(I2S_INT_CLR_REG(0), 0xFFFFFFFF);
  144. }
  145. #define DMALEN (2048-2)
  146. static void tskLcd(void *pvParameters)
  147. {
  148. uint16_t *sbuf = malloc(DMALEN * 2);
  149. uint16_t *rbuf = malloc(DMALEN * 2);
  150. uint16_t xorval = 0;
  151. int x;
  152. lcdIfaceInit();
  153. // lcdFlush();
  154. while (1) {
  155. for (x = 0; x < DMALEN; x++) {
  156. sbuf[x] = x ^ xorval;
  157. }
  158. for (x = 0; x < DMALEN; x++) {
  159. rbuf[x] = 0; //clear rbuf
  160. }
  161. sendRecvBufDma(sbuf, rbuf, DMALEN);
  162. vTaskDelay(20 / portTICK_PERIOD_MS);
  163. finishDma();
  164. for (x = 0; x < DMALEN; x++) if (rbuf[x] != (x ^ xorval)) {
  165. printf("Rxbuf err! pos %d val %x xor %x", x, (int)rbuf[x], (int)xorval);
  166. }
  167. printf(".");
  168. fflush(stdout);
  169. xorval++;
  170. }
  171. }
  172. void test_s32c1i_lock(volatile int *lockvar, int lockval, int unlockval, volatile int *ctr);
  173. static volatile int ctr = 0, state = 0;
  174. static volatile int lock = 0;
  175. static void tskOne(void *pvParameters)
  176. {
  177. int x;
  178. int err = 0, run = 0;
  179. while (1) {
  180. ctr = 0; lock = 0;
  181. state = 1;
  182. for (x = 0; x < 16 * 1024; x++) {
  183. test_s32c1i_lock(&lock, 1, 0, &ctr);
  184. }
  185. vTaskDelay(60 / portTICK_PERIOD_MS);
  186. state = 2;
  187. if (ctr != 16 * 1024 * 2) {
  188. printf("Lock malfunction detected! Ctr=0x%x instead of %x\n", ctr, 16 * 1024 * 2);
  189. err++;
  190. }
  191. run++;
  192. printf("Run %d err %d\n", run, err);
  193. vTaskDelay(20 / portTICK_PERIOD_MS);
  194. }
  195. }
  196. #define FB2ADDR 0x40098000
  197. static void tskTwo(void *pvParameters)
  198. {
  199. int x;
  200. int *p = (int *)FB2ADDR;
  201. int *s = (int *)test_s32c1i_lock;
  202. void (*test_s32c1i_lock2)(volatile int * lockvar, int lockval, int unlockval, volatile int * ctr) = (void *)FB2ADDR;
  203. volatile int w;
  204. int delay;
  205. for (x = 0; x < 100; x++) {
  206. *p++ = *s++; //copy routine to different pool
  207. }
  208. while (1) {
  209. while (state != 1) ;
  210. for (x = 0; x < 16 * 1024; x++) {
  211. test_s32c1i_lock2(&lock, 2, 0, &ctr);
  212. //Some random delay to increase chance of weirdness
  213. if ((x & 0x1f) == 0) {
  214. delay = rand() & 0x1f;
  215. for (w = 0; w < delay; w++);
  216. }
  217. }
  218. while (state != 2);
  219. }
  220. }
  221. TEST_CASE("S32C1I vs AHB test (needs I2S)", "[hw][ignore]")
  222. {
  223. int i;
  224. TaskHandle_t th[3];
  225. state = 0;
  226. printf("Creating tasks\n");
  227. xTaskCreatePinnedToCore(tskTwo , "tsktwo" , 2048, NULL, 3, &th[1], 1);
  228. xTaskCreatePinnedToCore(tskOne , "tskone" , 2048, NULL, 3, &th[0], 0);
  229. xTaskCreatePinnedToCore(tskLcd , "tsklcd" , 2048, NULL, 3, &th[2], 0);
  230. // Let stuff run for 20s
  231. while (1) {
  232. vTaskDelay(20000 / portTICK_PERIOD_MS);
  233. }
  234. //Shut down all the tasks
  235. for (i = 0; i < 3; i++) {
  236. vTaskDelete(th[i]);
  237. }
  238. }