1 // Copyright 2015-2019 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 /*******************************************************************************
16  * NOTICE
17  * The hal is not public api, don't use in application code.
18  * See readme.md in hal/include/hal/readme.md
19  ******************************************************************************/
20 
21 // The HAL layer for UART.
22 // There is no parameter check in the hal layer, so the caller must ensure the correctness of the parameters.
23 
24 #pragma once
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #include "hal/uart_ll.h"
31 #include "hal/uart_types.h"
32 
33 /**
34  * Context that should be maintained by both the driver and the HAL
35  */
36 typedef struct {
37     uart_dev_t *dev;
38 } uart_hal_context_t;
39 
40 /**
41  * @brief Clear the UART interrupt status
42  *
43  * @param  hal Context of the HAL layer
44  * @param  mask The interrupt status mask to be cleared. Using the ORred mask of `UART_INTR_RXFIFO_FULL ... UART_INTR_CMD_CHAR_DET`
45  *
46  * @return None
47  */
48 #define uart_hal_clr_intsts_mask(hal, mask)  uart_ll_clr_intsts_mask((hal)->dev, mask)
49 
50 /**
51  * @brief Disable the UART interrupt
52  *
53  * @param  hal Context of the HAL layer
54  * @param  mask The interrupt mask to be disabled. Using the ORred mask of `UART_INTR_RXFIFO_FULL ... UART_INTR_CMD_CHAR_DET`
55  *
56  * @return None
57  */
58 #define uart_hal_disable_intr_mask(hal, mask)  uart_ll_disable_intr_mask((hal)->dev, mask)
59 
60 /**
61  * @brief Enable the UART interrupt
62  *
63  * @param  hal Context of the HAL layer
64  * @param  mask The UART interrupt mask to be enabled. Using the ORred mask of `UART_INTR_RXFIFO_FULL ... UART_INTR_CMD_CHAR_DET`
65  *
66  * @return None
67  */
68 #define uart_hal_ena_intr_mask(hal, mask)  uart_ll_ena_intr_mask((hal)->dev, mask)
69 
70 /**
71  * @brief Get the UART interrupt status
72  *
73  * @param  hal Context of the HAL layer
74  *
75  * @return UART interrupt status
76  */
77 #define uart_hal_get_intsts_mask(hal)  uart_ll_get_intsts_mask((hal)->dev)
78 
79 /**
80  * @brief Get status of enabled interrupt
81  *
82  * @param  hal Context of the HAL layer
83  *
84  * @return UART Interrupt enabled value
85  */
86 #define uart_hal_get_intr_ena_status(hal) uart_ll_get_intr_ena_status((hal)->dev)
87 
88 /**
89  * @brief Get the UART pattern char configuration
90  *
91  * @param  hal Context of the HAL layer
92  * @param  cmd_char Pointer to accept UART AT cmd char
93  * @param  char_num Pointer to accept the `UART_CHAR_NUM` configuration
94  *
95  * @return None
96  */
97 #define uart_hal_get_at_cmd_char(hal, cmd_char, char_num)  uart_ll_get_at_cmd_char((hal)->dev, cmd_char, char_num)
98 
99 /**
100  * @brief Set the UART rst signal active level
101  *
102  * @param  hal Context of the HAL layer
103  * @param  active_level The rts active level. The active level is low if set to 0. The active level is high if set to 1
104  *
105  * @return None
106  */
107 #define uart_hal_set_rts(hal, active_level)  uart_ll_set_rts_active_level((hal)->dev, active_level)
108 
109 /**
110  * @brief Get the txfifo writeable length(in byte)
111  *
112  * @param  hal Context of the HAL layer
113  *
114  * @return UART txfifo writeable length
115  */
116 #define uart_hal_get_txfifo_len(hal)  uart_ll_get_txfifo_len((hal)->dev)
117 
118 /**
119  * @brief Check if the UART sending state machine is in the IDLE state.
120  *
121  * @param  hal Context of the HAL layer
122  *
123  * @return True if the state machine is in the IDLE state, otherwise false will be returned.
124  */
125 #define uart_hal_is_tx_idle(hal)  uart_ll_is_tx_idle((hal)->dev)
126 
127 /**
128  * @brief  Configure the UART core reset
129  *
130  * @param  hal Context of the HAL layer
131  * @param  Set true to enable the core reset, otherwise set it false
132  *
133  * @return None
134  */
135 #define uart_hal_set_reset_core(hal, core_rst_en)  uart_ll_set_reset_core((hal)->dev, core_rst_en)
136 
137 /**
138  * @brief  Read data from the UART rxfifo
139  *
140  * @param[in] hal Context of the HAL layer
141  * @param[in] buf Pointer to the buffer used to store the read data. The buffer size should be large than 128 byte
142  * @param[inout] inout_rd_len As input, the size of output buffer to read (set to 0 to read all available data).
143  *                            As output, returns the actual size written into the output buffer.
144  *
145  * @return None
146  */
147 void uart_hal_read_rxfifo(uart_hal_context_t *hal, uint8_t *buf, int *inout_rd_len);
148 
149 /**
150  * @brief  Write data into the UART txfifo
151  *
152  * @param  hal Context of the HAL layer
153  * @param  buf Pointer of the data buffer need to be written to txfifo
154  * @param  data_size The data size(in byte) need to be written
155  * @param  write_size The size has been written
156  *
157  * @return None
158  */
159 void uart_hal_write_txfifo(uart_hal_context_t *hal, const uint8_t *buf, uint32_t data_size, uint32_t *write_size);
160 
161 /**
162  * @brief  Reset the UART txfifo
163  * @note   On ESP32, this function is reserved for UART1 and UART2.
164  *
165  * @param  hal Context of the HAL layer
166  *
167  * @return None
168  */
169 void uart_hal_txfifo_rst(uart_hal_context_t *hal);
170 
171 /**
172  * @brief  Reset the UART rxfifo
173  *
174  * @param  hal Context of the HAL layer
175  *
176  * @return None
177  */
178 void uart_hal_rxfifo_rst(uart_hal_context_t *hal);
179 
180 /**
181  * @brief Init the UART hal and set the UART to the default configuration.
182  *
183  * @param  hal Context of the HAL layer
184  * @param  uart_num The uart port number, the max port number is (UART_NUM_MAX -1)
185  *
186  * @return None
187  */
188 void uart_hal_init(uart_hal_context_t *hal, uart_port_t uart_num);
189 
190 /**
191  * @brief Set the UART source clock type
192  * @param  hal Context of the HAL layer
193  * @param  sclk The UART source clock type.
194  *
195  * @return None
196  */
197 void uart_hal_set_sclk(uart_hal_context_t *hal, uart_sclk_t sclk);
198 
199 /**
200  * @brief Get the UART source clock type
201  *
202  * @param  hal Context of the HAL layer
203  * @param  sclk The poiter to accept the UART source clock type
204  *
205  * @return None
206  */
207 void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk);
208 
209 /**
210  * @brief  Configure the UART baud-rate and select the source clock
211  *
212  * @param  hal Context of the HAL layer
213  * @param  baud_rate The baud-rate to be set
214  *
215  * @return None
216  */
217 void uart_hal_set_baudrate(uart_hal_context_t *hal, uint32_t baud_rate);
218 
219 /**
220  * @brief  Configure the UART stop bit
221  *
222  * @param  hal Context of the HAL layer
223  * @param  stop_bit The stop bit to be set
224  *
225  * @return None
226  */
227 void uart_hal_set_stop_bits(uart_hal_context_t *hal, uart_stop_bits_t stop_bit);
228 
229 /**
230  * @brief Configure the UART data bit
231  *
232  * @param  hal Context of the HAL layer
233  * @param  data_bit The data bit to be set
234  *
235  * @return None
236  */
237 void uart_hal_set_data_bit_num(uart_hal_context_t *hal, uart_word_length_t data_bit);
238 
239 /**
240  * @brief Configure the UART parity mode
241  *
242  * @param  hal Context of the HAL layer
243  * @param  parity_mode The UART parity mode to be set
244  *
245  * @return None
246  */
247 void uart_hal_set_parity(uart_hal_context_t *hal, uart_parity_t parity_mode);
248 
249 /**
250  * @brief Configure the UART hardware flow control
251  *
252  * @param  hal Context of the HAL layer
253  * @param  flow_ctrl The flow control mode to be set
254  * @param  rx_thresh The rts flow control signal will be active if the data length in rxfifo is large than this value
255  *
256  * @return None
257  */
258 void uart_hal_set_hw_flow_ctrl(uart_hal_context_t *hal, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh);
259 
260 /**
261  * @brief Configure the UART AT cmd char detect function. When the receiver receives a continuous AT cmd char, it will produce a interrupt
262  *
263  * @param  hal Context of the HAL layer
264  * @param  at_cmd The AT cmd char detect configuration
265  *
266  * @return None.
267  */
268 void uart_hal_set_at_cmd_char(uart_hal_context_t *hal, uart_at_cmd_t *at_cmd);
269 
270 /**
271  * @brief Set the timeout value of the UART receiver
272  *
273  * @param  hal Context of the HAL layer
274  * @param  tout The timeout value for receiver to receive a data
275  *
276  * @return None
277  */
278 void uart_hal_set_rx_timeout(uart_hal_context_t *hal, const uint8_t tout);
279 
280 /**
281  * @brief Set the UART dtr signal active level
282  *
283  * @param  hal Context of the HAL layer
284  * @param  active_level The dtr active level. The active level is low if set to 0. The active level is high if set to 1
285  *
286  * @return None
287  */
288 void uart_hal_set_dtr(uart_hal_context_t *hal, int active_level);
289 
290 /**
291  * @brief Set the UART software flow control
292  *
293  * @param  hal Context of the HAL layer
294  * @param  flow_ctrl The software flow control configuration
295  * @param  sw_flow_ctrl_en Set true to enable the software flow control, otherwise set it false
296  *
297  * @return None
298  */
299 void uart_hal_set_sw_flow_ctrl(uart_hal_context_t *hal, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en);
300 
301 /**
302  * @brief Set the UART tx idle number
303  *
304  * @param  hal Context of the HAL layer
305  * @param  idle_num The cycle number betwin the two transmission
306  *
307  * @return None
308  */
309 void uart_hal_set_tx_idle_num(uart_hal_context_t *hal, uint16_t idle_num);
310 
311 /**
312  * @brief Set the UART rxfifo full threshold
313  *
314  * @param  hal Context of the HAL layer
315  * @param  full_thrhd The rxfifo full threshold. If the `UART_RXFIFO_FULL` interrupt is enabled and
316  *         the data length in rxfifo is more than this value, it will generate `UART_RXFIFO_FULL` interrupt
317  *
318  * @return None
319  */
320 void uart_hal_set_rxfifo_full_thr(uart_hal_context_t *hal, uint32_t full_thrhd);
321 
322 /**
323  * @brief Set the UART txfifo empty threshold
324  *
325  * @param  hal Context of the HAL layer
326  * @param  empty_thrhd The txfifo empty threshold to be set. If the `UART_TXFIFO_EMPTY` interrupt is enabled and
327  *         the data length in txfifo is less than this value, it will generate `UART_TXFIFO_EMPTY` interrupt
328  *
329  * @return None
330  */
331 void uart_hal_set_txfifo_empty_thr(uart_hal_context_t *hal, uint32_t empty_thrhd);
332 
333 /**
334  * @brief Configure the UART to send a number of break(NULL) chars
335  *
336  * @param  hal Context of the HAL layer
337  * @param  break_num The number of the break char need to be send
338  *
339  * @return None
340  */
341 void uart_hal_tx_break(uart_hal_context_t *hal, uint32_t break_num);
342 
343 /**
344  * @brief Configure the UART wake up function.
345  *     Note that RXD cannot be input through GPIO Matrix but only through IO_MUX when use this function
346  *
347  * @param  hal Context of the HAL layer
348  * @param  wakeup_thrd The wake up threshold to be set. The system will be woken up from light-sleep when the input RXD edge changes more times than `wakeup_thrd+2`
349  *
350  * @return None
351  */
352 void uart_hal_set_wakeup_thrd(uart_hal_context_t *hal, uint32_t wakeup_thrd);
353 
354 /**
355  * @brief Configure the UART mode
356  *
357  * @param  hal Context of the HAL layer
358  * @param  mode The UART mode to be set
359  *
360  * @return None
361  */
362 void uart_hal_set_mode(uart_hal_context_t *hal, uart_mode_t mode);
363 
364 /**
365  * @brief Configure the UART hardware to inverse the signals
366  *
367  * @param  hal Context of the HAL layer
368  * @param  inv_mask The sigal mask needs to be inversed. Use the ORred mask of type `uart_signal_inv_t`
369  *
370  * @return None
371  */
372 void uart_hal_inverse_signal(uart_hal_context_t *hal, uint32_t inv_mask);
373 
374 /**
375  * @brief Get the UART wakeup threshold configuration
376  *
377  * @param  hal Context of the HAL layer
378  * @param  wakeup_thrd Pointer to accept the value of UART wakeup threshold configuration
379  *
380  * @return None
381  */
382 void uart_hal_get_wakeup_thrd(uart_hal_context_t *hal, uint32_t *wakeup_thrd);
383 
384 /**
385  * @brief Get the UART data bit configuration
386  *
387  * @param  hal Context of the HAL layer
388  * @param  data_bit Pointer to accept the value of UART data bit configuration
389  *
390  * @return None
391  */
392 void uart_hal_get_data_bit_num(uart_hal_context_t *hal, uart_word_length_t *data_bit);
393 
394 /**
395  * @brief Get the UART stop bit configuration
396  *
397  * @param  hal Context of the HAL layer
398  * @param  stop_bit Pointer to accept the value of UART stop bit configuration
399  *
400  * @return None
401  */
402 void uart_hal_get_stop_bits(uart_hal_context_t *hal, uart_stop_bits_t *stop_bit);
403 
404 /**
405  * @brief Get the UART parity mode configuration
406  *
407  * @param  hal Context of the HAL layer
408  * @param  parity_mode Pointer to accept the UART parity mode configuration
409  *
410  * @return None
411  */
412 void uart_hal_get_parity(uart_hal_context_t *hal, uart_parity_t *parity_mode);
413 
414 /**
415  * @brief Get the UART baud-rate configuration
416  *
417  * @param  hal Context of the HAL layer
418  * @param  baud_rate Pointer to accept the current baud-rate
419  *
420  * @return None
421  */
422 void uart_hal_get_baudrate(uart_hal_context_t *hal, uint32_t *baud_rate);
423 
424 /**
425  * @brief Get the hw flow control configuration
426  *
427  * @param  hal Context of the HAL layer
428  * @param  flow_ctrl Pointer to accept the UART flow control configuration
429  *
430  * @return None
431  */
432 void uart_hal_get_hw_flow_ctrl(uart_hal_context_t *hal, uart_hw_flowcontrol_t *flow_ctrl);
433 
434 /**
435  * @brief Check if the UART is in hw RS485 half duplex mode
436  *
437  * @param  hal Context of the HAL layer
438  *
439  * @return True if hw RS485 half duplex mode is enabled, otherwise false will be returned
440  */
441 bool uart_hal_is_mode_rs485_half_duplex(uart_hal_context_t *hal);
442 
443 /**
444  * @brief Check if the UART rts flow control is enabled
445  *
446  * @param  hal Context of the HAL layer
447  *
448  * @return True if rts flow control is enabled, otherwise false will be returned
449  */
450 bool uart_hal_is_hw_rts_en(uart_hal_context_t *hal);
451 
452 /**
453  * @brief Configure TX signal loop back to RX module, just for the testing purposes
454  *
455  * @param  hal Context of the HAL layer
456  * @param  loop_back_en Set ture to enable the loop back function, else set it false.
457  *
458  * @return None
459  */
460 void uart_hal_set_loop_back(uart_hal_context_t *hal, bool loop_back_en);
461 
462 /**
463  * @brief  Calculate uart symbol bit length, as defined in configuration.
464  *
465  * @param  hw Beginning address of the peripheral registers.
466  *
467  * @return number of bits per UART symbol.
468  */
469 uint8_t uart_hal_get_symb_len(uart_hal_context_t *hal);
470 
471 /**
472  * @brief  Get UART maximum timeout threshold.
473  *
474  * @param  hw Beginning address of the peripheral registers.
475  *
476  * @return maximum timeout threshold value for target.
477  */
478 uint16_t uart_hal_get_max_rx_timeout_thrd(uart_hal_context_t *hal);
479 
480 /**
481  * @brief  Get the timeout threshold value set for receiver.
482  *
483  * @param  hw Beginning address of the peripheral registers.
484  *
485  * @return tout_thr The timeout value. If timeout is disabled then returns 0.
486  */
487 #define uart_hal_get_rx_tout_thr(hal) uart_ll_get_rx_tout_thr((hal)->dev)
488 
489 /**
490  * @brief  Get the length of readable data in UART rxfifo.
491  *
492  * @param  hw Beginning address of the peripheral registers.
493  *
494  * @return The readable data length in rxfifo.
495  */
496 #define uart_hal_get_rxfifo_len(hal) uart_ll_get_rxfifo_len((hal)->dev)
497 
498 #ifdef __cplusplus
499 }
500 #endif
501