1 /*
2 * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "sdkconfig.h"
7
8 #if CONFIG_IDF_TARGET_ESP32
9
10 #include <stdio.h>
11
12 #include "esp_types.h"
13 #include "freertos/FreeRTOS.h"
14 #include "freertos/task.h"
15 #include "freertos/semphr.h"
16 #include "freertos/queue.h"
17 #include "freertos/xtensa_api.h"
18 #include "unity.h"
19 #include "soc/uart_periph.h"
20 #include "soc/dport_reg.h"
21 #include "hal/gpio_hal.h"
22 #include "driver/gpio.h"
23
24
25 /*
26 This test tests the 'fast' peripherial bus at 0x3ff40000. This bus is connected directly to the core, and as such
27 can receive 'speculative' reads, that is, reads that may or may not actually be executed in the code flow. This
28 may mess with any FIFOs mapped in the region: if a byte gets dropped due to a missed speculative read, the fifo
29 may advance to the next byte anyway.
30
31 This code tests reading/writing from the UART1 FIFO, using both cores. For this to work, it's required that the
32 UARTs RX and TX lines are connected.
33 */
34
35
36 void test_fastbus_cp(int fifo_addr, unsigned char *buf, int len, int *dummy);
37
38 static volatile int state = 0;
39 static volatile int xor = 0;
40 static unsigned char res[128];
41
tskOne(void * pvParameters)42 static void tskOne(void *pvParameters)
43 {
44 int run = 0, err = 0;
45 int x;
46 int ct[256];
47 volatile int w;
48 int dummy;
49 while (1) {
50 state = 1;
51 for (x = 0; x < 64; x++) {
52 WRITE_PERI_REG(UART_FIFO_REG(1), x ^ xor);
53 }
54 for (w = 0; w < (1 << 14); w++); //delay
55 state = 2;
56 test_fastbus_cp(UART_FIFO_REG(1), &res[0], 64, &dummy);
57 for (w = 0; w < (1 << 10); w++); //delay
58 for (x = 0; x < 255; x++) {
59 ct[x] = 0; //zero ctrs
60 }
61 for (x = 0; x < 128; x++) {
62 ct[(int)res[x]^xor]++; //count values
63 }
64 for (x = 0; x < 255; x++) { //check counts
65 if (ct[x] != (x < 128 ? 1 : 0)) {
66 //Disregard first few loops; there may be crap in the fifo.
67 if (run > 2) {
68 err++;
69 printf("Error! Received value %d %d times!\n", x, ct[x]);
70 }
71 }
72 }
73 run++;
74 if ((run & 255) == 0) {
75 printf("Loop %d errct %d\n", run, err);
76 }
77 xor = (xor + 1) & 0xff;
78 }
79 }
80
81 #define FB2ADDR 0x40098000
82
tskTwo(void * pvParameters)83 static void tskTwo(void *pvParameters)
84 {
85 int x;
86 int dummy;
87 int *p = (int *)FB2ADDR;
88 int *s = (int *)test_fastbus_cp;
89 for (x = 0; x < 100; x++) {
90 *p++ = *s++;
91 }
92 void (*test_fastbus_cp2)(int fifo_addr, unsigned char * buf, int len, int * dummy) = (void *)FB2ADDR;
93
94
95 while (1) {
96 while (state != 1) ;
97 for (x = 64; x < 128; x++) {
98 WRITE_PERI_REG(UART_FIFO_REG(1), x ^ xor);
99 }
100 while (state != 2);
101 test_fastbus_cp2(UART_FIFO_REG(1), &res[64], 64, &dummy);
102 }
103 }
104
105
106 // TODO: split this thing into separate orthogonal tests
107 TEST_CASE("Fast I/O bus test", "[hw][ignore]")
108 {
109 int i;
110 if ((REG_UART_BASE(0) >> 16) != 0x3ff4) {
111 printf("Error! Uart base isn't on fast bus.\n");
112 TEST_ASSERT(0);
113 }
114
115 gpio_pullup_dis(10);
116 gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA2_U, FUNC_SD_DATA2_U1RXD);
117 gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_SD_DATA3_U, FUNC_SD_DATA3_U1TXD);
118
119 int reg_val = (1 << UART_RXFIFO_FULL_THRHD_S);
120 WRITE_PERI_REG(UART_CONF1_REG(1), reg_val);
121 WRITE_PERI_REG(UART_CLKDIV_REG(1), 0x30); //semi-random
122 // CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(1), UART_TXFIFO_EMPTY_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
123
124 TaskHandle_t th[2];
125 printf("Creating tasks\n");
126 xTaskCreatePinnedToCore(tskOne , "tskone" , 2048, NULL, 3, &th[0], 0);
127 xTaskCreatePinnedToCore(tskTwo , "tsktwo" , 2048, NULL, 3, &th[1], 1);
128
129 // Let stuff run for 20s
130 while (1) {
131 vTaskDelay(20000 / portTICK_PERIOD_MS);
132 }
133
134 //Shut down all the tasks
135 for (i = 0; i < 2; i++) {
136 vTaskDelete(th[i]);
137 }
138 xt_ints_off(1 << ETS_UART0_INUM);
139 }
140
141 #endif // CONFIG_IDF_TARGET_ESP32
142