1 // Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <stdint.h>
18 #include "ets_sys.h"
19 #include "soc/soc.h"
20 #include "soc/uart_reg.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 /** \defgroup uart_apis, uart configuration and communication related apis
27   * @brief uart apis
28   */
29 
30 /** @addtogroup uart_apis
31   * @{
32   */
33 
34 #define RX_BUFF_SIZE                     0x400
35 #define TX_BUFF_SIZE                     100
36 
37 //uart int enalbe register ctrl bits
38 #define UART_RCV_INTEN                   BIT0
39 #define UART_TRX_INTEN                   BIT1
40 #define UART_LINE_STATUS_INTEN           BIT2
41 
42 //uart int identification ctrl bits
43 #define UART_INT_FLAG_MASK               0x0E
44 
45 //uart fifo ctrl bits
46 #define UART_CLR_RCV_FIFO                BIT1
47 #define UART_CLR_TRX_FIFO                BIT2
48 #define UART_RCVFIFO_TRG_LVL_BITS        BIT6
49 
50 //uart line control bits
51 #define  UART_DIV_LATCH_ACCESS_BIT       BIT7
52 
53 //uart line status bits
54 #define  UART_RCV_DATA_RDY_FLAG          BIT0
55 #define  UART_RCV_OVER_FLOW_FLAG         BIT1
56 #define  UART_RCV_PARITY_ERR_FLAG        BIT2
57 #define  UART_RCV_FRAME_ERR_FLAG         BIT3
58 #define  UART_BRK_INT_FLAG               BIT4
59 #define  UART_TRX_FIFO_EMPTY_FLAG        BIT5
60 #define  UART_TRX_ALL_EMPTY_FLAG         BIT6   // include fifo and shift reg
61 #define  UART_RCV_ERR_FLAG               BIT7
62 
63 //send and receive message frame head
64 #define FRAME_FLAG                       0x7E
65 
66 typedef enum {
67     UART_LINE_STATUS_INT_FLAG  = 0x06,
68     UART_RCV_FIFO_INT_FLAG     = 0x04,
69     UART_RCV_TMOUT_INT_FLAG    = 0x0C,
70     UART_TXBUFF_EMPTY_INT_FLAG = 0x02
71 } UartIntType;   //consider bit0 for int_flag
72 
73 typedef enum {
74     RCV_ONE_BYTE      = 0x0,
75     RCV_FOUR_BYTE     = 0x1,
76     RCV_EIGHT_BYTE    = 0x2,
77     RCV_FOURTEEN_BYTE = 0x3
78 } UartRcvFifoTrgLvl;
79 
80 typedef enum {
81     FIVE_BITS  = 0x0,
82     SIX_BITS   = 0x1,
83     SEVEN_BITS = 0x2,
84     EIGHT_BITS = 0x3
85 } UartBitsNum4Char;
86 
87 typedef enum {
88     ONE_STOP_BIT      = 1,
89     ONE_HALF_STOP_BIT = 2,
90     TWO_STOP_BIT      = 3
91 } UartStopBitsNum;
92 
93 typedef enum {
94     NONE_BITS = 0,
95     ODD_BITS  = 2,
96     EVEN_BITS = 3
97 
98 } UartParityMode;
99 
100 typedef enum {
101     STICK_PARITY_DIS = 0,
102     STICK_PARITY_EN  = 2
103 } UartExistParity;
104 
105 typedef enum {
106     BIT_RATE_9600   = 9600,
107     BIT_RATE_19200  = 19200,
108     BIT_RATE_38400  = 38400,
109     BIT_RATE_57600  = 57600,
110     BIT_RATE_115200 = 115200,
111     BIT_RATE_230400 = 230400,
112     BIT_RATE_460800 = 460800,
113     BIT_RATE_921600 = 921600
114 } UartBautRate;
115 
116 typedef enum {
117     NONE_CTRL,
118     HARDWARE_CTRL,
119     XON_XOFF_CTRL
120 } UartFlowCtrl;
121 
122 typedef enum {
123     _EMPTY,
124     UNDER_WRITE,
125     WRITE_OVER
126 } RcvMsgBuffState;
127 
128 typedef struct {
129     uint8_t *pRcvMsgBuff;
130     uint8_t *pWritePos;
131     uint8_t *pReadPos;
132     uint8_t  TrigLvl;
133     RcvMsgBuffState BuffState;
134 } RcvMsgBuff;
135 
136 typedef struct {
137     uint32_t  TrxBuffSize;
138     uint8_t  *pTrxBuff;
139 } TrxMsgBuff;
140 
141 typedef enum {
142     BAUD_RATE_DET,
143     WAIT_SYNC_FRM,
144     SRCH_MSG_HEAD,
145     RCV_MSG_BODY,
146     RCV_ESC_CHAR,
147 } RcvMsgState;
148 
149 typedef struct {
150     UartBautRate     baut_rate;
151     UartBitsNum4Char data_bits;
152     UartExistParity  exist_parity;
153     UartParityMode   parity;    // chip size in byte
154     UartStopBitsNum  stop_bits;
155     UartFlowCtrl     flow_ctrl;
156     uint8_t          buff_uart_no;  //indicate which uart use tx/rx buffer
157     RcvMsgBuff       rcv_buff;
158 //    TrxMsgBuff       trx_buff;
159     RcvMsgState      rcv_state;
160     int              received;
161 } UartDevice;
162 
163 /**
164   * @brief Init uart device struct value and reset uart0/uart1 rx.
165   *        Please do not call this function in SDK.
166   *
167   * @param  rxBuffer, must be a pointer to RX_BUFF_SIZE bytes or NULL
168   *
169   * @return None
170   */
171 void uartAttach(void *rxBuffer);
172 
173 /**
174   * @brief Init uart0 or uart1 for UART download booting mode.
175   *        Please do not call this function in SDK.
176   *
177   * @param  uint8_t uart_no : 0 for UART0, else for UART1.
178   *
179   * @param  uint32_t clock : clock used by uart module, to adjust baudrate.
180   *
181   * @return None
182   */
183 void Uart_Init(uint8_t uart_no, uint32_t clock);
184 
185 /**
186   * @brief Modify uart baudrate.
187   *        This function will reset RX/TX fifo for uart.
188   *
189   * @param  uint8_t uart_no : 0 for UART0, 1 for UART1.
190   *
191   * @param  uint32_t DivLatchValue : (clock << 4)/baudrate.
192   *
193   * @return None
194   */
195 void uart_div_modify(uint8_t uart_no, uint32_t DivLatchValue);
196 
197 /**
198   * @brief Init uart0 or uart1 for UART download booting mode.
199   *        Please do not call this function in SDK.
200   *
201   * @param  uint8_t uart_no : 0 for UART0, 1 for UART1.
202   *
203   * @param  uint8_t is_sync : 0, only one UART module, easy to detect, wait until detected;
204   *                           1, two UART modules, hard to detect, detect and return.
205   *
206   * @return None
207   */
208 int uart_baudrate_detect(uint8_t uart_no, uint8_t is_sync);
209 
210 /**
211   * @brief Switch printf channel of uart_tx_one_char.
212   *        Please do not call this function when printf.
213   *
214   * @param  uint8_t uart_no : 0 for UART0, 1 for UART1.
215   *
216   * @return None
217   */
218 void uart_tx_switch(uint8_t uart_no);
219 
220 /**
221   * @brief Switch message exchange channel for UART download booting.
222   *        Please do not call this function in SDK.
223   *
224   * @param  uint8_t uart_no : 0 for UART0, 1 for UART1.
225   *
226   * @return None
227   */
228 void uart_buff_switch(uint8_t uart_no);
229 
230 /**
231   * @brief Output a char to printf channel, wait until fifo not full.
232   *
233   * @param  None
234   *
235   * @return OK.
236   */
237 STATUS uart_tx_one_char(uint8_t TxChar);
238 
239 /**
240   * @brief Output a char to message exchange channel, wait until fifo not full.
241   *        Please do not call this function in SDK.
242   *
243   * @param  None
244   *
245   * @return OK.
246   */
247 STATUS uart_tx_one_char2(uint8_t TxChar);
248 
249 /**
250   * @brief Wait until uart tx full empty.
251   *
252   * @param  uint8_t uart_no : 0 for UART0, 1 for UART1.
253   *
254   * @return None.
255   */
256 void uart_tx_flush(uint8_t uart_no);
257 
258 /**
259   * @brief Wait until uart tx full empty and the last char send ok.
260   *
261   * @param  uart_no : 0 for UART0, 1 for UART1, 2 for UART2
262   *
263   * The function defined in ROM code has a bug, so we define the correct version
264   * here for compatibility.
265   */
266 void uart_tx_wait_idle(uint8_t uart_no);
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 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, incude '\0'.
296   *
297   * @return OK.
298   */
299 STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen);
300 
301 /**
302   * @brief Process uart recevied 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 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 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 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 STATUS RcvMsg(uint8_t *pData, uint16_t MaxDataLen, uint8_t is_sync);
400 
401 /**
402   * @brief Check if this UART is in download connection.
403   *        Please do not call this function in SDK.
404   *
405   * @param  uint8_t uart_no : 0 for UART0, 1 for UART1.
406   *
407   * @return ETS_NO_BOOT = 0 for no.
408   *         SEL_UART_BOOT = BIT(1) for yes.
409   */
410 uint8_t UartConnCheck(uint8_t uart_no);
411 
412 /**
413   * @brief Initialize the USB ACM UART
414   * Needs to be fed a buffer of at least 128 bytes, plus any rx buffer you may want to have.
415   *
416   * @param cdc_acm_work_mem Pointer to work mem for CDC-ACM code
417   * @param cdc_acm_work_mem_len Length of work mem
418   */
419 void Uart_Init_USB(void *cdc_acm_work_mem, int cdc_acm_work_mem_len);
420 
421 
422 /**
423   * @brief Install handler to reset the chip when a RTS change has been detected on the CDC-ACM 'UART'.
424   */
425 void uart_usb_enable_reset_on_rts(void);
426 
427 
428 extern UartDevice UartDev;
429 
430 /**
431   * @}
432   */
433 
434 #ifdef __cplusplus
435 }
436 #endif
437