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