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