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