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