1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include "esp_err.h"
9 #include "driver/uart.h"
10 #include "esp_rom_uart.h"
11 
12 #define ROM_UART_DRIVER_ENABLE 0
13 
14 #if ROM_UART_DRIVER_ENABLE
15 static uint8_t scope_uart_num = 0;
16 static int8_t uart_used = 0;
17 #else
18 static uint8_t scope_uart_num = 255;
19 static int8_t uart_used = -1;
20 #endif
21 static int scope_tx_io_num = 0;
22 static int scope_rx_io_num = 0;
23 static int scope_debug_baud_rate = 256000;
24 static unsigned char datascope_output_buffer[42] = {0};    // Data buff.
25 
26 /**
27  * @brief Translate a float data to four unsigned char data for uart TX.
28  * @param target target float data address.
29  * @param buf save translated data.
30  * @param offset the start position in buf.
31  * @return
32  *     - void
33  */
float_to_byte(float * target,unsigned char * buf,unsigned char offset)34 static void float_to_byte(float *target, unsigned char *buf, unsigned char offset)
35 {
36     memcpy(buf + offset, (uint8_t*)target, 4);
37 }
38 
39 /**
40  * @brief Add data to channel buff.
41  * @param Data target data.
42  * @param Channel target channel (1 - 10).
43  * @return
44  *     - void
45  */
datascope_get_channel_data(float data,unsigned char channel)46 static void datascope_get_channel_data(float data, unsigned char channel)
47 {
48     if ( (channel > 10) || (channel == 0) ) {
49         return;
50     } else {
51         switch (channel) {
52             case 1:  float_to_byte(&data,datascope_output_buffer, channel*4-3); break;
53             case 2:  float_to_byte(&data,datascope_output_buffer, channel*4-3); break;
54             case 3:  float_to_byte(&data,datascope_output_buffer, channel*4-3); break;
55             case 4:  float_to_byte(&data,datascope_output_buffer, channel*4-3); break;
56             case 5:  float_to_byte(&data,datascope_output_buffer, channel*4-3); break;
57             case 6:  float_to_byte(&data,datascope_output_buffer, channel*4-3); break;
58             case 7:  float_to_byte(&data,datascope_output_buffer, channel*4-3); break;
59             case 8:  float_to_byte(&data,datascope_output_buffer, channel*4-3); break;
60             case 9:  float_to_byte(&data,datascope_output_buffer, channel*4-3); break;
61             case 10: float_to_byte(&data,datascope_output_buffer, channel*4-3); break;
62         }
63     }
64 }
65 
66 /**
67  * @brief Transform float data to DataScopeV1.0 data format.
68  * @param channel_num the number of channel that wait to be translated.
69  * @return
70  *     - The number of the UART TX data.
71  */
datascope_data_generate(unsigned char channel_num)72 static unsigned char datascope_data_generate(unsigned char channel_num)
73 {
74     if ( (channel_num > 10) || (channel_num == 0) ) {
75         return 0;
76     } else {
77         datascope_output_buffer[0] = '$';  //frame header
78         switch(channel_num) {
79             case 1:   datascope_output_buffer[channel_num*4+1] = channel_num*4+1; return channel_num*4+2; break;
80             case 2:   datascope_output_buffer[channel_num*4+1] = channel_num*4+1; return channel_num*4+2; break;
81             case 3:   datascope_output_buffer[channel_num*4+1] = channel_num*4+1; return channel_num*4+2; break;
82             case 4:   datascope_output_buffer[channel_num*4+1] = channel_num*4+1; return channel_num*4+2; break;
83             case 5:   datascope_output_buffer[channel_num*4+1] = channel_num*4+1; return channel_num*4+2; break;
84             case 6:   datascope_output_buffer[channel_num*4+1] = channel_num*4+1; return channel_num*4+2; break;
85             case 7:   datascope_output_buffer[channel_num*4+1] = channel_num*4+1; return channel_num*4+2; break;
86             case 8:   datascope_output_buffer[channel_num*4+1] = channel_num*4+1; return channel_num*4+2; break;
87             case 9:   datascope_output_buffer[channel_num*4+1] = channel_num*4+1; return channel_num*4+2; break;
88             case 10:  datascope_output_buffer[channel_num*4+1] = channel_num*4+1; return channel_num*4+2; break;
89         }
90     }
91     return 0;
92 }
93 
94 /**
95  * @brief Send touch sensor data to HMI in PC via UART.
96  * @param uart_num Choose uart port (0, 1).
97  * @param data The addr of the touch sensor data.
98  * @param channel_num The number of channel that wait to be translated.
99  * @return
100  *     - ESP_FAIL Error
101  *     - The number of the UART TX data.
102  */
test_tp_print_to_scope(float * data,unsigned char channel_num)103 int test_tp_print_to_scope(float *data, unsigned char channel_num)
104 {
105     uint8_t uart_num = scope_uart_num;
106 
107     if (uart_num >= UART_NUM_MAX) {
108         return ESP_FAIL;
109     }
110     if ( (channel_num > 10) || (channel_num == 0) || (NULL == data) ) {
111         return ESP_FAIL;
112     }
113     for(uint8_t i = 0 ; i < channel_num; i++)  {
114         datascope_get_channel_data(data[i] , i+1); //  write data x into channel 1~10.
115     }
116     unsigned char out_len = datascope_data_generate(channel_num); //  Generate n number data.
117     unsigned char *out_data = datascope_output_buffer;
118     // Init uart.
119     if(uart_num != uart_used) {
120         return 0;
121     } else {
122 #if ROM_UART_DRIVER_ENABLE
123         esp_rom_uart_tx_wait_idle(uart_num);   // Default print uart mumber is 0.
124         for(int i=0; i<out_len; i++) {
125             esp_rom_uart_tx_one_char(out_data[i]);
126         }
127         return out_len;
128 #else
129         uart_wait_tx_done(uart_num, portMAX_DELAY);
130         return uart_write_bytes(uart_num, (const char *)out_data, out_len);
131 #endif
132     }
133 }
134 
135 /**
136   * @brief  Enable scope debug function. Print the touch sensor raw data to "DataScope" tool via UART.
137   *         "DataScope" tool is touch sensor tune tool. User can monitor the data of each touch channel,
138   *         evaluate the touch system's touch performance (sensitivity, SNR, stability, channel coupling)
139   *         and determine the threshold for each channel.
140   *
141   * @attention 1. Choose a UART port that will only be used for scope debug.
142   * @attention 2. Use this feature only during the testing phase.
143   * @attention 3. "DataScope" tool can be downloaded from Espressif's official website.
144   *
145   * @param  uart_num The uart port to send touch sensor raw data.
146   * @param  tx_io_num set UART TXD IO.
147   * @param  rx_io_num set UART RXD IO.
148   * @param  baud_rate set debug port baud rate.
149   *
150   * @return
151   *     - ESP_OK: succeed
152   *     - ESP_FAIL: the param uart_num is error
153   */
test_tp_scope_debug_init(uint8_t uart_num,int tx_io_num,int rx_io_num,int baud_rate)154 esp_err_t test_tp_scope_debug_init(uint8_t uart_num, int tx_io_num, int rx_io_num, int baud_rate)
155 {
156 #if ROM_UART_DRIVER_ENABLE
157     esp_rom_uart_tx_wait_idle(0);   // Default print uart mumber is 0.
158     if(uart_num != 0) {
159         esp_rom_uart_set_as_console(uart_num);
160     }
161 #else
162     if(uart_used == uart_num) {
163         return ESP_FAIL;
164     }
165     if (uart_num >= UART_NUM_MAX) {
166         return ESP_FAIL;
167     }
168     scope_uart_num = uart_num;
169     scope_tx_io_num = tx_io_num;
170     scope_rx_io_num = rx_io_num;
171     scope_debug_baud_rate = baud_rate;
172     uart_config_t uart_config = {
173         .baud_rate = scope_debug_baud_rate,
174         .data_bits = UART_DATA_8_BITS,
175         .parity = UART_PARITY_DISABLE,
176         .stop_bits = UART_STOP_BITS_1,
177         .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
178     };
179     uart_param_config(uart_num, &uart_config);
180     // Set UART pins using UART0 default pins i.e. no changes
181     uart_set_pin(uart_num, scope_tx_io_num, scope_rx_io_num,
182             UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
183     uart_driver_install(uart_num, 1024, 2048, 0, NULL, 0);
184     uart_used = uart_num;
185 #endif
186     return ESP_OK;
187 }
188