1 /*
2 * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #pragma once
7
8 #include "esp_types.h"
9 #include "esp_attr.h"
10 #include "ets_sys.h"
11 #include "soc/soc.h"
12 #include "soc/uart_periph.h"
13 #include "soc/uart_reg.h"
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 /** \defgroup uart_apis, uart configuration and communication related apis
20 * @brief uart apis
21 */
22
23 /** @addtogroup uart_apis
24 * @{
25 */
26
27 #define RX_BUFF_SIZE 0x100
28 #define TX_BUFF_SIZE 100
29
30 //uart int enable register ctrl bits
31 #define UART_RCV_INTEN BIT0
32 #define UART_TRX_INTEN BIT1
33 #define UART_LINE_STATUS_INTEN BIT2
34
35 //uart int identification ctrl bits
36 #define UART_INT_FLAG_MASK 0x0E
37
38 //uart fifo ctrl bits
39 #define UART_CLR_RCV_FIFO BIT1
40 #define UART_CLR_TRX_FIFO BIT2
41 #define UART_RCVFIFO_TRG_LVL_BITS BIT6
42
43 //uart line control bits
44 #define UART_DIV_LATCH_ACCESS_BIT BIT7
45
46 //uart line status bits
47 #define UART_RCV_DATA_RDY_FLAG BIT0
48 #define UART_RCV_OVER_FLOW_FLAG BIT1
49 #define UART_RCV_PARITY_ERR_FLAG BIT2
50 #define UART_RCV_FRAME_ERR_FLAG BIT3
51 #define UART_BRK_INT_FLAG BIT4
52 #define UART_TRX_FIFO_EMPTY_FLAG BIT5
53 #define UART_TRX_ALL_EMPTY_FLAG BIT6 // include fifo and shift reg
54 #define UART_RCV_ERR_FLAG BIT7
55
56 //send and receive message frame head
57 #define FRAME_FLAG 0x7E
58
59 typedef enum {
60 UART_LINE_STATUS_INT_FLAG = 0x06,
61 UART_RCV_FIFO_INT_FLAG = 0x04,
62 UART_RCV_TMOUT_INT_FLAG = 0x0C,
63 UART_TXBUFF_EMPTY_INT_FLAG = 0x02
64 } UartIntType; //consider bit0 for int_flag
65
66 typedef enum {
67 RCV_ONE_BYTE = 0x0,
68 RCV_FOUR_BYTE = 0x1,
69 RCV_EIGHT_BYTE = 0x2,
70 RCV_FOURTEEN_BYTE = 0x3
71 } UartRcvFifoTrgLvl;
72
73 typedef enum {
74 FIVE_BITS = 0x0,
75 SIX_BITS = 0x1,
76 SEVEN_BITS = 0x2,
77 EIGHT_BITS = 0x3
78 } UartBitsNum4Char;
79
80 typedef enum {
81 ONE_STOP_BIT = 1,
82 ONE_HALF_STOP_BIT = 2,
83 TWO_STOP_BIT = 3
84 } UartStopBitsNum;
85
86 typedef enum {
87 NONE_BITS = 0,
88 ODD_BITS = 2,
89 EVEN_BITS = 3
90
91 } UartParityMode;
92
93 typedef enum {
94 STICK_PARITY_DIS = 0,
95 STICK_PARITY_EN = 2
96 } UartExistParity;
97
98 typedef enum {
99 BIT_RATE_9600 = 9600,
100 BIT_RATE_19200 = 19200,
101 BIT_RATE_38400 = 38400,
102 BIT_RATE_57600 = 57600,
103 BIT_RATE_115200 = 115200,
104 BIT_RATE_230400 = 230400,
105 BIT_RATE_460800 = 460800,
106 BIT_RATE_921600 = 921600
107 } UartBautRate;
108
109 typedef enum {
110 NONE_CTRL,
111 HARDWARE_CTRL,
112 XON_XOFF_CTRL
113 } UartFlowCtrl;
114
115 typedef enum {
116 EMPTY_,
117 UNDER_WRITE,
118 WRITE_OVER
119 } RcvMsgBuffState;
120
121 typedef struct {
122 uint8_t *pRcvMsgBuff;
123 uint8_t *pWritePos;
124 uint8_t *pReadPos;
125 uint8_t TrigLvl;
126 RcvMsgBuffState BuffState;
127 } RcvMsgBuff;
128
129 typedef struct {
130 uint32_t TrxBuffSize;
131 uint8_t *pTrxBuff;
132 } TrxMsgBuff;
133
134 typedef enum {
135 BAUD_RATE_DET,
136 WAIT_SYNC_FRM,
137 SRCH_MSG_HEAD,
138 RCV_MSG_BODY,
139 RCV_ESC_CHAR,
140 } RcvMsgState;
141
142 typedef struct {
143 UartBautRate baut_rate;
144 UartBitsNum4Char data_bits;
145 UartExistParity exist_parity;
146 UartParityMode parity; // chip size in byte
147 UartStopBitsNum stop_bits;
148 UartFlowCtrl flow_ctrl;
149 uint8_t buff_uart_no; //indicate which uart use tx/rx buffer
150 uint8_t tx_uart_no;
151 RcvMsgBuff rcv_buff;
152 // TrxMsgBuff trx_buff;
153 RcvMsgState rcv_state;
154 int received;
155 } UartDevice;
156
157 /**
158 * @brief Init uart device struct value and reset uart0/uart1 rx.
159 * Please do not call this function in SDK.
160 *
161 * @param None
162 *
163 * @return None
164 */
165 void uartAttach(void);
166
167 /**
168 * @brief Init uart0 or uart1 for UART download booting mode.
169 * Please do not call this function in SDK.
170 *
171 * @param uint8_t uart_no : 0 for UART0, else for UART1.
172 *
173 * @param uint32_t clock : clock used by uart module, to adjust baudrate.
174 *
175 * @return None
176 */
177 void Uart_Init(uint8_t uart_no, uint32_t clock);
178
179 /**
180 * @brief Modify uart baudrate.
181 * This function will reset RX/TX fifo for uart.
182 *
183 * @param uint8_t uart_no : 0 for UART0, 1 for UART1.
184 *
185 * @param uint32_t DivLatchValue : (clock << 4)/baudrate.
186 *
187 * @return None
188 */
189 void uart_div_modify(uint8_t uart_no, uint32_t DivLatchValue);
190
191 /**
192 * @brief Init uart0 or uart1 for UART download booting mode.
193 * Please do not call this function in SDK.
194 *
195 * @param uint8_t uart_no : 0 for UART0, 1 for UART1.
196 *
197 * @param uint8_t is_sync : 0, only one UART module, easy to detect, wait until detected;
198 * 1, two UART modules, hard to detect, detect and return.
199 *
200 * @return None
201 */
202 int uart_baudrate_detect(uint8_t uart_no, uint8_t is_sync);
203
204 /**
205 * @brief Switch printf channel of uart_tx_one_char.
206 * Please do not call this function when printf.
207 *
208 * @param uint8_t uart_no : 0 for UART0, 1 for UART1.
209 *
210 * @return None
211 */
212 void uart_tx_switch(uint8_t uart_no);
213
214 /**
215 * @brief Switch message exchange channel for UART download booting.
216 * Please do not call this function in SDK.
217 *
218 * @param uint8_t uart_no : 0 for UART0, 1 for UART1.
219 *
220 * @return None
221 */
222 void uart_buff_switch(uint8_t uart_no);
223
224 /**
225 * @brief Output a char to printf channel, wait until fifo not full.
226 *
227 * @param None
228 *
229 * @return OK.
230 */
231 ETS_STATUS uart_tx_one_char(uint8_t TxChar);
232
233 /**
234 * @brief Output a char to message exchange channel, wait until fifo not full.
235 * Please do not call this function in SDK.
236 *
237 * @param None
238 *
239 * @return OK.
240 */
241 ETS_STATUS uart_tx_one_char2(uint8_t TxChar);
242
243 /**
244 * @brief Wait until uart tx full empty.
245 *
246 * @param uint8_t uart_no : 0 for UART0, 1 for UART1.
247 *
248 * @return None.
249 */
250 void uart_tx_flush(uint8_t uart_no);
251
252 /**
253 * @brief Wait until uart tx full empty and the last char send ok.
254 *
255 * @param uart_no : 0 for UART0, 1 for UART1, 2 for UART2
256 *
257 * The function defined in ROM code has a bug, so we define the correct version
258 * here for compatibility.
259 */
uart_tx_wait_idle(uint8_t uart_no)260 static inline void IRAM_ATTR uart_tx_wait_idle(uint8_t uart_no) {
261 uint32_t status;
262 do {
263 status = READ_PERI_REG(UART_STATUS_REG(uart_no));
264 /* either tx count or state is non-zero */
265 } while ((status & (UART_ST_UTX_OUT_M | UART_TXFIFO_CNT_M)) != 0);
266 }
267
268 /**
269 * @brief Get an input char from message channel.
270 * Please do not call this function in SDK.
271 *
272 * @param uint8_t *pRxChar : the pointer to store the char.
273 *
274 * @return OK for successful.
275 * FAIL for failed.
276 */
277 ETS_STATUS uart_rx_one_char(uint8_t *pRxChar);
278
279 /**
280 * @brief Get an input char from message channel, wait until successful.
281 * Please do not call this function in SDK.
282 *
283 * @param None
284 *
285 * @return char : input char value.
286 */
287 char uart_rx_one_char_block(void);
288
289 /**
290 * @brief Get an input string line from message channel.
291 * Please do not call this function in SDK.
292 *
293 * @param uint8_t *pString : the pointer to store the string.
294 *
295 * @param uint8_t MaxStrlen : the max string length, include '\0'.
296 *
297 * @return OK.
298 */
299 ETS_STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen);
300
301 /**
302 * @brief Process uart received information in the interrupt handler.
303 * Please do not call this function in SDK.
304 *
305 * @param void *para : the message receive buffer.
306 *
307 * @return None
308 */
309 void uart_rx_intr_handler(void *para);
310
311 /**
312 * @brief Get an char from receive buffer.
313 * Please do not call this function in SDK.
314 *
315 * @param RcvMsgBuff *pRxBuff : the pointer to the struct that include receive buffer.
316 *
317 * @param uint8_t *pRxByte : the pointer to store the char.
318 *
319 * @return OK for successful.
320 * FAIL for failed.
321 */
322 ETS_STATUS uart_rx_readbuff( RcvMsgBuff *pRxBuff, uint8_t *pRxByte);
323
324 /**
325 * @brief Get all chars from receive buffer.
326 * Please do not call this function in SDK.
327 *
328 * @param uint8_t *pCmdLn : the pointer to store the string.
329 *
330 * @return OK for successful.
331 * FAIL for failed.
332 */
333 ETS_STATUS UartGetCmdLn(uint8_t *pCmdLn);
334
335 /**
336 * @brief Get uart configuration struct.
337 * Please do not call this function in SDK.
338 *
339 * @param None
340 *
341 * @return UartDevice * : uart configuration struct pointer.
342 */
343 UartDevice *GetUartDevice(void);
344
345 /**
346 * @brief Send an packet to download tool, with SLIP escaping.
347 * Please do not call this function in SDK.
348 *
349 * @param uint8_t *p : the pointer to output string.
350 *
351 * @param int len : the string length.
352 *
353 * @return None.
354 */
355 void send_packet(uint8_t *p, int len);
356
357 /**
358 * @brief Receive an packet from download tool, with SLIP escaping.
359 * Please do not call this function in SDK.
360 *
361 * @param uint8_t *p : the pointer to input string.
362 *
363 * @param int len : If string length > len, the string will be truncated.
364 *
365 * @param uint8_t is_sync : 0, only one UART module;
366 * 1, two UART modules.
367 *
368 * @return int : the length of the string.
369 */
370 int recv_packet(uint8_t *p, int len, uint8_t is_sync);
371
372 /**
373 * @brief Send an packet to download tool, with SLIP escaping.
374 * Please do not call this function in SDK.
375 *
376 * @param uint8_t *pData : the pointer to input string.
377 *
378 * @param uint16_t DataLen : the string length.
379 *
380 * @return OK for successful.
381 * FAIL for failed.
382 */
383 ETS_STATUS SendMsg(uint8_t *pData, uint16_t DataLen);
384
385 /**
386 * @brief Receive an packet from download tool, with SLIP escaping.
387 * Please do not call this function in SDK.
388 *
389 * @param uint8_t *pData : the pointer to input string.
390 *
391 * @param uint16_t MaxDataLen : If string length > MaxDataLen, the string will be truncated.
392 *
393 * @param uint8_t is_sync : 0, only one UART module;
394 * 1, two UART modules.
395 *
396 * @return OK for successful.
397 * FAIL for failed.
398 */
399 ETS_STATUS RcvMsg(uint8_t *pData, uint16_t MaxDataLen, uint8_t is_sync);
400
401 extern UartDevice UartDev;
402
403 /**
404 * @}
405 */
406
407 #ifdef __cplusplus
408 }
409 #endif
410