1 /*
2  * Copyright (c) 2021-2022-2024 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_UART_DRV_H
9 #define HPM_UART_DRV_H
10 #include "hpm_common.h"
11 #include "hpm_uart_regs.h"
12 #include "hpm_soc_feature.h"
13 
14 /**
15  *
16  * @brief UART driver APIs
17  * @defgroup uart_interface UART driver APIs
18  * @ingroup io_interfaces
19  * @{
20  */
21 
22 /**
23  * @brief UART status
24  */
25 enum {
26     status_uart_no_suitable_baudrate_parameter_found = MAKE_STATUS(status_group_uart, 1),
27 };
28 
29 /* @brief Parity */
30 typedef enum parity {
31     parity_none = 0,
32     parity_odd,
33     parity_even,
34     parity_always_1,
35     parity_always_0,
36 } parity_setting_t;
37 
38 /* @brief Stop bits */
39 typedef enum num_of_stop_bits {
40     stop_bits_1 = 0,
41     stop_bits_1_5,
42     stop_bits_2,
43 } num_of_stop_bits_t;
44 
45 /* @brief Word length */
46 typedef enum word_length {
47     word_length_5_bits = 0,
48     word_length_6_bits,
49     word_length_7_bits,
50     word_length_8_bits,
51 } word_length_t;
52 
53 /* @brief UART fifo trigger levels */
54 typedef enum uart_fifo_trg_lvl {
55 #if defined(HPM_IP_FEATURE_UART_FINE_FIFO_THRLD) && (HPM_IP_FEATURE_UART_FINE_FIFO_THRLD == 1)
56     uart_fifo_1_byte  = 0,
57     uart_fifo_2_bytes = 1,
58     uart_fifo_3_bytes = 2,
59     uart_fifo_4_bytes = 3,
60     uart_fifo_5_bytes = 4,
61     uart_fifo_6_bytes = 5,
62     uart_fifo_7_bytes = 6,
63     uart_fifo_8_bytes = 7,
64     uart_fifo_9_bytes = 8,
65     uart_fifo_10_bytes = 9,
66     uart_fifo_11_bytes = 10,
67     uart_fifo_12_bytes = 11,
68     uart_fifo_13_bytes = 12,
69     uart_fifo_14_bytes = 13,
70     uart_fifo_15_bytes = 14,
71     uart_fifo_16_bytes = 15,
72 
73     uart_rx_fifo_trg_not_empty = uart_fifo_1_byte,
74     uart_rx_fifo_trg_gt_one_quarter = uart_fifo_4_bytes,
75     uart_rx_fifo_trg_gt_half = uart_fifo_8_bytes,
76     uart_rx_fifo_trg_gt_three_quarters = uart_fifo_12_bytes,
77 
78     uart_tx_fifo_trg_not_full = uart_fifo_16_bytes,
79     uart_tx_fifo_trg_lt_three_quarters = uart_fifo_12_bytes,
80     uart_tx_fifo_trg_lt_half = uart_fifo_8_bytes,
81     uart_tx_fifo_trg_lt_one_quarter = uart_fifo_4_bytes,
82 #else
83     uart_rx_fifo_trg_not_empty = 0,
84     uart_rx_fifo_trg_gt_one_quarter = 1,
85     uart_rx_fifo_trg_gt_half = 2,
86     uart_rx_fifo_trg_gt_three_quarters = 3,
87 
88     uart_tx_fifo_trg_not_full = 0,
89     uart_tx_fifo_trg_lt_three_quarters = 1,
90     uart_tx_fifo_trg_lt_half = 2,
91     uart_tx_fifo_trg_lt_one_quarter = 3,
92 #endif
93 } uart_fifo_trg_lvl_t;
94 
95 /* @brief UART signals */
96 typedef enum uart_signal {
97     uart_signal_rts = UART_MCR_RTS_MASK,
98 } uart_signal_t;
99 
100 /* @brief UART signal levels */
101 typedef enum uart_signal_level {
102     uart_signal_level_high,
103     uart_signal_level_low,
104 } uart_signal_level_t;
105 
106 /* @brief UART modem status */
107 typedef enum uart_modem_stat {
108     uart_modem_stat_cts = UART_MSR_CTS_MASK,
109     uart_modem_stat_dcts_changed = UART_MSR_DCTS_MASK,
110 } uart_modem_stat_t;
111 
112 /* @brief UART interrupt enable masks */
113 typedef enum uart_intr_enable {
114     uart_intr_rx_data_avail_or_timeout = UART_IER_ERBI_MASK,
115     uart_intr_tx_slot_avail = UART_IER_ETHEI_MASK,
116     uart_intr_rx_line_stat = UART_IER_ELSI_MASK,
117     uart_intr_modem_stat = UART_IER_EMSI_MASK,
118 #if defined(HPM_IP_FEATURE_UART_RX_IDLE_DETECT) && (HPM_IP_FEATURE_UART_RX_IDLE_DETECT == 1)
119     uart_intr_rx_line_idle = UART_IER_ERXIDLE_MASK,
120 #endif
121 #if defined(HPM_IP_FEATURE_UART_9BIT_MODE) && (HPM_IP_FEATURE_UART_9BIT_MODE == 1)
122     uart_intr_tx_line_idle = UART_IER_ETXIDLE_MASK,
123 #endif
124 #if defined(HPM_IP_FEATURE_UART_ADDR_MATCH) && (HPM_IP_FEATURE_UART_ADDR_MATCH == 1)
125     uart_intr_addr_match = UART_IER_EADDRM_MASK,
126     uart_intr_addr_match_and_rxidle = UART_IER_EADDRM_IDLE_MASK,
127     uart_intr_addr_datalost = UART_IER_EDATLOST_MASK,
128 #endif
129 } uart_intr_enable_t;
130 
131 /* @brief UART interrupt IDs */
132 typedef enum uart_intr_id {
133     uart_intr_id_modem_stat = 0x0,
134     uart_intr_id_tx_slot_avail = 0x2,
135     uart_intr_id_rx_data_avail = 0x4,
136     uart_intr_id_rx_line_stat = 0x6,
137     uart_intr_id_rx_timeout = 0xc,
138 } uart_intr_id_t;
139 
140 /* @brief UART status */
141 typedef enum uart_stat {
142     uart_stat_data_ready = UART_LSR_DR_MASK, /* rx data ready in fifo */
143     uart_stat_overrun_error = UART_LSR_OE_MASK,
144     uart_stat_parity_error = UART_LSR_PE_MASK,
145     uart_stat_framing_error = UART_LSR_FE_MASK,
146     uart_stat_line_break = UART_LSR_LBREAK_MASK,
147     uart_stat_tx_slot_avail = UART_LSR_THRE_MASK,
148     uart_stat_transmitter_empty = UART_LSR_TEMT_MASK,
149     uart_stat_rx_fifo_error = UART_LSR_ERRF_MASK,
150 } uart_stat_t;
151 
152 /**
153  * @brief UART modem config
154  */
155 typedef struct uart_modem_config {
156     bool auto_flow_ctrl_en;     /**< Auto flow control enable flag */
157     bool loop_back_en;          /**< Loop back enable flag */
158     bool set_rts_high;          /**< Set signal RTS level high flag */
159 } uart_modem_config_t;
160 
161 #if defined(HPM_IP_FEATURE_UART_RX_IDLE_DETECT) && (HPM_IP_FEATURE_UART_RX_IDLE_DETECT == 1)
162 /**
163  * @brief UART Idle detection conditions, suitable for RX and TX
164  */
165 typedef enum hpm_uart_rxline_idle_cond {
166     uart_rxline_idle_cond_rxline_logic_one = 0,         /**< Treat as idle if the RX Line high duration exceeds threshold */
167     uart_rxline_idle_cond_state_machine_idle = 1        /**< Treat as idle if the RX state machine idle state duration exceeds threshold */
168 } uart_rxline_idle_cond_t;
169 
170 /**
171  * @brief UART Idle config, suitable for RX and TX
172  */
173 typedef struct hpm_uart_rxline_idle_detect_config {
174     bool detect_enable;                 /**< RX Line Idle detection flag */
175     bool detect_irq_enable;             /**< Enable RX Line Idle detection interrupt */
176     uart_rxline_idle_cond_t idle_cond;  /**< RX Line Idle detection condition */
177     uint8_t threshold;                  /**< UART RX Line Idle detection threshold, in terms of bits */
178 } uart_rxline_idle_config_t;
179 #endif
180 
181 /**
182  * @brief UART config
183  */
184 typedef struct hpm_uart_config {
185     uint32_t src_freq_in_hz;                    /**< Source clock frequency in Hz */
186     uint32_t baudrate;                          /**< Baudrate */
187     uint8_t num_of_stop_bits;                   /**< Number of stop bits */
188     uint8_t word_length;                        /**< Word length */
189     uint8_t parity;                             /**< Parity */
190     uint8_t tx_fifo_level;                      /**< TX Fifo level */
191     uint8_t rx_fifo_level;                      /**< RX Fifo level */
192     bool dma_enable;                            /**< DMA Enable flag */
193     bool fifo_enable;                           /**< Fifo Enable flag */
194     uart_modem_config_t modem_config;           /**< Modem config */
195 #if defined(HPM_IP_FEATURE_UART_RX_IDLE_DETECT) && (HPM_IP_FEATURE_UART_RX_IDLE_DETECT == 1)
196     uart_rxline_idle_config_t  rxidle_config;   /**< RX Idle configuration */
197 #endif
198 #if defined(HPM_IP_FEATURE_UART_9BIT_MODE) && (HPM_IP_FEATURE_UART_9BIT_MODE == 1)
199     uart_rxline_idle_config_t  txidle_config;   /**< TX Idle configuration */
200 #endif
201 #if defined(HPM_IP_FEATURE_UART_RX_EN) && (HPM_IP_FEATURE_UART_RX_EN == 1)
202     bool rx_enable;                             /**< RX Enable configuration */
203 #endif
204 } uart_config_t;
205 
206 #if defined(HPM_IP_FEATURE_UART_TRIG_MODE) && (HPM_IP_FEATURE_UART_TRIG_MODE == 1)
207 typedef struct {
208     uint16_t stop_bit_len;
209     bool en_stop_bit_insert;
210     bool hardware_trig;
211     bool trig_mode;
212     bool trig_clr_rxfifo;
213 } uart_trig_config_t;
214 #endif
215 
216 typedef struct {
217     uint8_t tx_fifo_level;                      /**< TX Fifo level */
218     uint8_t rx_fifo_level;                      /**< RX Fifo level */
219     bool reset_tx_fifo;                         /**< reset tx Fifo */
220     bool reset_rx_fifo;                         /**< reset rx Fifo */
221     bool dma_enable;                            /**< DMA Enable flag */
222     bool fifo_enable;                           /**< Fifo Enable flag */
223 } uart_fifo_ctrl_t;
224 
225 #ifdef __cplusplus
226 extern "C" {
227 #endif
228 
229 /**
230  * @brief Get fifo size
231  *
232  * @param [in] ptr UART base address
233  * @retval size of Fifo
234  */
uart_get_fifo_size(UART_Type * ptr)235 static inline uint8_t uart_get_fifo_size(UART_Type *ptr)
236 {
237     return 16 << ((ptr->CFG & UART_CFG_FIFOSIZE_MASK) >> UART_CFG_FIFOSIZE_SHIFT);
238 }
239 
240 /**
241  * @brief uart config fifo control
242  *
243  * @note fifo control register(FCR) is WO access, if support FCCR register, it is RW access.
244  *
245  * @param [in] ptr UART base address
246  * @param [in] ctrl uart_fifo_ctrl_t
247  */
248 void uart_config_fifo_ctrl(UART_Type *ptr, uart_fifo_ctrl_t *ctrl);
249 
250 /**
251  * @brief uart clear rx fifo by reading data
252  *
253  * @note read out all data in rx fifo, the uart_intr_rx_data_avail_or_timeout is cleared
254  * when RBR register is read
255  *
256  * @param [in] ptr UART base address
257  */
uart_clear_rx_fifo(UART_Type * ptr)258 static inline void uart_clear_rx_fifo(UART_Type *ptr)
259 {
260     while (ptr->LSR & UART_LSR_DR_MASK) {
261         ptr->RBR;
262     }
263 }
264 
265 /**
266  * @brief Reset TX Fifo
267  *
268  * @param [in] ptr UART base address
269  */
uart_reset_tx_fifo(UART_Type * ptr)270 static inline void uart_reset_tx_fifo(UART_Type *ptr)
271 {
272 #if defined(HPM_IP_FEATURE_UART_FCRR) && (HPM_IP_FEATURE_UART_FCRR == 1)
273     ptr->FCRR |= UART_FCRR_TFIFORST_MASK;
274 #else
275     ptr->FCR = UART_FCR_TFIFORST_MASK | (ptr->GPR);
276 #endif
277 }
278 
279 /**
280  * @brief Reset RX Fifo
281  *
282  * @param [in] ptr UART base address
283  */
uart_reset_rx_fifo(UART_Type * ptr)284 static inline void uart_reset_rx_fifo(UART_Type *ptr)
285 {
286 #if defined(HPM_IP_FEATURE_UART_FCRR) && (HPM_IP_FEATURE_UART_FCRR == 1)
287     ptr->FCRR |= UART_FCRR_RFIFORST_MASK;
288 #else
289     ptr->FCR = UART_FCR_RFIFORST_MASK | (ptr->GPR);
290 #endif
291 }
292 
293 /**
294  * @brief [in] Reset both TX and RX Fifo
295  *
296  * @param [in] ptr UART base address
297  */
uart_reset_all_fifo(UART_Type * ptr)298 static inline void uart_reset_all_fifo(UART_Type *ptr)
299 {
300 #if defined(HPM_IP_FEATURE_UART_FCRR) && (HPM_IP_FEATURE_UART_FCRR == 1)
301     ptr->FCRR |= UART_FCRR_TFIFORST_MASK | UART_FCRR_RFIFORST_MASK;
302 #else
303     ptr->FCR = UART_FCR_RFIFORST_MASK | UART_FCR_TFIFORST_MASK | (ptr->GPR);
304 #endif
305 }
306 
307 /**
308  * @brief Enable modem loopback
309  *
310  * @param [in] ptr UART base address
311  */
uart_modem_enable_loopback(UART_Type * ptr)312 static inline void uart_modem_enable_loopback(UART_Type *ptr)
313 {
314     ptr->MCR |= UART_MCR_LOOP_MASK;
315 }
316 
317 /**
318  * @brief Disable modem loopback
319  *
320  * @param [in] ptr UART base address
321  */
uart_modem_disable_loopback(UART_Type * ptr)322 static inline void uart_modem_disable_loopback(UART_Type *ptr)
323 {
324     ptr->MCR &= ~UART_MCR_LOOP_MASK;
325 }
326 
327 /**
328  * @brief Disable modem auto flow control
329  *
330  * @param [in] ptr UART base address
331  */
332 
uart_modem_disable_auto_flow_control(UART_Type * ptr)333 static inline void uart_modem_disable_auto_flow_control(UART_Type *ptr)
334 {
335     ptr->MCR &= ~UART_MCR_AFE_MASK;
336 }
337 
338 /**
339  * @brief Enable modem auto flow control
340  *
341  * @param [in] ptr UART base address
342  */
uart_modem_enable_auto_flow_control(UART_Type * ptr)343 static inline void uart_modem_enable_auto_flow_control(UART_Type *ptr)
344 {
345     ptr->MCR |= UART_MCR_AFE_MASK;
346 }
347 
348 /**
349  * @brief Configure modem
350  *
351  * @param [in] ptr UART base address
352  * @param config Pointer to modem config struct
353  */
uart_modem_config(UART_Type * ptr,uart_modem_config_t * config)354 static inline void uart_modem_config(UART_Type *ptr, uart_modem_config_t *config)
355 {
356     ptr->MCR = UART_MCR_AFE_SET(config->auto_flow_ctrl_en)
357         | UART_MCR_LOOP_SET(config->loop_back_en)
358         | UART_MCR_RTS_SET(!config->set_rts_high);
359 }
360 
361 /**
362  * @brief Get modem status
363  *
364  * @param [in] ptr UART base address
365  * @retval Current modem status
366  */
uart_get_modem_status(UART_Type * ptr)367 static inline uint8_t uart_get_modem_status(UART_Type *ptr)
368 {
369     return ptr->MSR;
370 }
371 
372 /**
373  * @brief Write byte to TX
374  *
375  * @param ptr UART base address
376  * @param c data to be sent
377  */
uart_write_byte(UART_Type * ptr,uint8_t c)378 static inline void uart_write_byte(UART_Type *ptr, uint8_t c)
379 {
380     ptr->THR = UART_THR_THR_SET(c);
381 }
382 
383 
384 /**
385  * @brief Read byte from RX
386  *
387  * @param ptr UART base address
388  * @retval RX byte
389  */
uart_read_byte(UART_Type * ptr)390 static inline uint8_t uart_read_byte(UART_Type *ptr)
391 {
392     return (ptr->RBR & UART_RBR_RBR_MASK);
393 }
394 
395 /**
396  * @brief Check modem status with given mask
397  *
398  * @param [in] ptr UART base address
399  * @param mask Status mask value to be checked against
400  * @retval true if any bit in given mask is set
401  * @retval false if none of any bit in given mask is set
402  */
uart_check_modem_status(UART_Type * ptr,uart_modem_stat_t mask)403 static inline bool uart_check_modem_status(UART_Type *ptr, uart_modem_stat_t mask)
404 {
405     return ((ptr->MSR & mask) != 0U) ? true : false;
406 }
407 
408 /**
409  * @brief Disable IRQ with mask
410  *
411  * @param [in] ptr UART base address
412  * @param irq_mask IRQ mask value to be disabled
413  */
uart_disable_irq(UART_Type * ptr,uart_intr_enable_t irq_mask)414 static inline void uart_disable_irq(UART_Type *ptr, uart_intr_enable_t irq_mask)
415 {
416     ptr->IER &= ~irq_mask;
417 }
418 
419 /**
420  * @brief Enable IRQ with mask
421  *
422  * @param [in] ptr UART base address
423  * @param irq_mask IRQ mask value to be enabled
424  */
uart_enable_irq(UART_Type * ptr,uart_intr_enable_t irq_mask)425 static inline void uart_enable_irq(UART_Type *ptr, uart_intr_enable_t irq_mask)
426 {
427     ptr->IER |= irq_mask;
428 }
429 
430 /**
431  * @brief Get Enabled IRQ
432  *
433  * @param [in] ptr UART base address
434  * @return enabled irq
435  */
uart_get_enabled_irq(UART_Type * ptr)436 static inline uint32_t uart_get_enabled_irq(UART_Type *ptr)
437 {
438     return ptr->IER;
439 }
440 
441 /**
442  * @brief Get interrupt identification
443  *
444  * @param [in] ptr UART base address
445  * @retval interrupt id
446  */
uart_get_irq_id(UART_Type * ptr)447 static inline uint8_t uart_get_irq_id(UART_Type *ptr)
448 {
449     return (ptr->IIR & UART_IIR_INTRID_MASK);
450 }
451 
452 #if defined(HPM_IP_FEATURE_UART_RX_IDLE_DETECT) && (HPM_IP_FEATURE_UART_RX_IDLE_DETECT == 1)
453 
454 /* if HPM_IP_FEATURE_UART_E00018_FIX = 1, the IIR2 register exists, should use IIR2 to get/clear rx idle status */
455 #if !defined(HPM_IP_FEATURE_UART_E00018_FIX) || (HPM_IP_FEATURE_UART_E00018_FIX == 0)
456 /**
457  * @brief Determine whether UART RX Line is idle
458  * @param [in] ptr UART base address
459  * @retval false if uart RX line is not idle
460  */
uart_is_rxline_idle(UART_Type * ptr)461 static inline bool uart_is_rxline_idle(UART_Type *ptr)
462 {
463     return ((ptr->IIR & UART_IIR_RXIDLE_FLAG_MASK) != 0U) ? true : false;
464 }
465 
466 /**
467  * @brief Clear UART RX Line Idle Flag
468  * @param [in] ptr UART base address
469  */
uart_clear_rxline_idle_flag(UART_Type * ptr)470 static inline void uart_clear_rxline_idle_flag(UART_Type *ptr)
471 {
472     ptr->IIR = UART_IIR_RXIDLE_FLAG_MASK; /* Write-1-Clear Logic */
473     ptr->FCR = ptr->GPR;
474 }
475 #endif
476 
477 /**
478  * @brief Enable UART RX Idle Line detection logic
479  * @param [in] ptr UART base address
480  */
uart_enable_rxline_idle_detection(UART_Type * ptr)481 static inline void uart_enable_rxline_idle_detection(UART_Type *ptr)
482 {
483     ptr->IDLE_CFG |= UART_IDLE_CFG_RX_IDLE_EN_MASK;
484 }
485 
486 /**
487  * @brief Disable UART RX Idle Line detection logic
488  *
489  * @param [in] ptr UART base address
490  */
uart_disable_rxline_idle_detection(UART_Type * ptr)491 static inline void uart_disable_rxline_idle_detection(UART_Type *ptr)
492 {
493     ptr->IDLE_CFG &= ~UART_IDLE_CFG_RX_IDLE_EN_MASK;
494 }
495 
496 /**
497  * @brief Configure UART RX Line detection
498  * @param [in] ptr UART base address
499  * @param [in] rxidle_config RXLine IDLE detection configuration
500  * @retval status_success if no error occurs
501  */
502 hpm_stat_t uart_init_rxline_idle_detection(UART_Type *ptr, uart_rxline_idle_config_t rxidle_config);
503 
504 #endif
505 
506 #if defined(HPM_IP_FEATURE_UART_E00018_FIX) && (HPM_IP_FEATURE_UART_E00018_FIX == 1)
507 /**
508  * @brief Determine whether UART TX Line is idle
509  * @param [in] ptr UART base address
510  * @retval false if uart TX line is not idle
511  */
uart_is_txline_idle(UART_Type * ptr)512 static inline bool uart_is_txline_idle(UART_Type *ptr)
513 {
514     return ((ptr->IIR2 & UART_IIR2_TXIDLE_FLAG_MASK) != 0U) ? true : false;
515 }
516 
517 /**
518  * @brief Clear UART TX Line Idle Flag
519  * @param [in] ptr UART base address
520  */
uart_clear_txline_idle_flag(UART_Type * ptr)521 static inline void uart_clear_txline_idle_flag(UART_Type *ptr)
522 {
523     ptr->IIR2 = UART_IIR2_TXIDLE_FLAG_MASK; /* Write-1-Clear Logic */
524 }
525 
526 /**
527  * @brief Determine whether UART RX Line is idle
528  * @param [in] ptr UART base address
529  * @retval false if uart RX line is not idle
530  */
uart_is_rxline_idle(UART_Type * ptr)531 static inline bool uart_is_rxline_idle(UART_Type *ptr)
532 {
533     return ((ptr->IIR2 & UART_IIR2_RXIDLE_FLAG_MASK) != 0U) ? true : false;
534 }
535 
536 /**
537  * @brief Clear UART RX Line Idle Flag
538  * @param [in] ptr UART base address
539  */
uart_clear_rxline_idle_flag(UART_Type * ptr)540 static inline void uart_clear_rxline_idle_flag(UART_Type *ptr)
541 {
542     ptr->IIR2 = UART_IIR2_RXIDLE_FLAG_MASK; /* Write-1-Clear Logic */
543 }
544 #endif
545 
546 #if defined(HPM_IP_FEATURE_UART_9BIT_MODE) && (HPM_IP_FEATURE_UART_9BIT_MODE == 1)
547 /**
548  * @brief Enable UART TX Idle Line detection logic
549  * @param [in] ptr UART base address
550  */
uart_enable_txline_idle_detection(UART_Type * ptr)551 static inline void uart_enable_txline_idle_detection(UART_Type *ptr)
552 {
553     ptr->IDLE_CFG |= UART_IDLE_CFG_TX_IDLE_EN_MASK;
554 }
555 
556 /**
557  * @brief Disable UART TX Idle Line detection logic
558  *
559  * @param [in] ptr UART base address
560  */
uart_disable_txline_idle_detection(UART_Type * ptr)561 static inline void uart_disable_txline_idle_detection(UART_Type *ptr)
562 {
563     ptr->IDLE_CFG &= ~UART_IDLE_CFG_TX_IDLE_EN_MASK;
564 }
565 
566 /**
567  * @brief Configure UART TX Line detection
568  * @param [in] ptr UART base address
569  * @param [in] txidle_config TXLine IDLE detection configuration
570  * @retval status_success if no error occurs
571  */
572 hpm_stat_t uart_init_txline_idle_detection(UART_Type *ptr, uart_rxline_idle_config_t txidle_config);
573 
574 #endif
575 
576 
577 
578 /**
579  * @brief Get status
580  *
581  * @param [in] ptr UART base address
582  * @retval current status
583  */
uart_get_status(UART_Type * ptr)584 static inline uint32_t uart_get_status(UART_Type *ptr)
585 {
586     return ptr->LSR;
587 }
588 
589 /**
590  * @brief Check uart status according to the given status mask
591  *
592  * @note maybe clear other bits, such as PE/OE/LBREAK/ERRF bit. use uart_get_status API if you need to get these bits
593  * @param [in] ptr UART base address
594  * @param mask Status mask value to be checked against
595  * @retval true if any bit in given mask is set
596  * @retval false if none of any bit in given mask is set
597  */
uart_check_status(UART_Type * ptr,uart_stat_t mask)598 static inline bool uart_check_status(UART_Type *ptr, uart_stat_t mask)
599 {
600     return ((ptr->LSR & mask) != 0U) ? true : false;
601 }
602 
603 /**
604  * @brief Get default config
605  *
606  * @param [in] ptr UART base address
607  * @param config Pointer to the buffer to save default values
608  */
609 void uart_default_config(UART_Type *ptr, uart_config_t *config);
610 
611 /**
612  * @brief Initialization
613  *
614  * @param [in] ptr UART base address
615  * @param config Pointer to config struct
616  * @retval status_success only if it succeeds
617  */
618 hpm_stat_t uart_init(UART_Type *ptr, uart_config_t *config);
619 
620 /**
621  * @brief Send one byte after checking thresh hold status
622  *
623  * @param [in] ptr UART base address
624  * @param c Byte to be sent
625  * @retval status_success only if it succeeds
626  */
627 hpm_stat_t uart_send_byte(UART_Type *ptr, uint8_t c);
628 
629 /**
630  * @brief Receive one byte after checking data ready status
631  *
632  * @param [in] ptr UART base address
633  * @param c Pointer to buffer to save the byte received on UART
634  * @retval status_success only if it succeeds
635  */
636 hpm_stat_t uart_receive_byte(UART_Type *ptr, uint8_t *c);
637 
638 /**
639  * @brief Try to receive one byte without checking data ready status
640  *
641  * @param [in] ptr UART base address
642  * @param c Pointer to buffer to save the byte received on UART
643  * @retval status_success only if it succeeds
644  */
645 hpm_stat_t uart_try_receive_byte(UART_Type *ptr, uint8_t *c);
646 
647 /**
648  * @brief Set uart signal output level
649  *
650  * @param [in] ptr UART base address
651  * @param signal Target signal
652  * @param level Target signal level
653  */
654 void uart_set_signal_level(UART_Type *ptr,
655                            uart_signal_t signal,
656                            uart_signal_level_t level);
657 
658 /**
659  * @brief Flush sending buffer/fifo
660  *
661  * @param [in] ptr UART base address
662  * @retval status_success only if it succeeds
663  */
664 hpm_stat_t uart_flush(UART_Type *ptr);
665 
666 /**
667  * @brief Receive bytes blocking
668  *
669  * @param [in] ptr UART base address
670  * @param buf Pointer to the buffer to save received data
671  * @param size_in_byte Size in byte to be sent
672  * @retval status_success only if it succeeds
673  */
674 hpm_stat_t uart_receive_data(UART_Type *ptr, uint8_t *buf, uint32_t size_in_byte);
675 
676 /**
677  * @brief Send bytes blocking
678  *
679  * @param [in] ptr UART base address
680  * @param buf Pointer to the buffer to be sent
681  * @param size_in_byte Size in byte to be sent
682  * @retval status_success only if it succeeds
683  */
684 hpm_stat_t uart_send_data(UART_Type *ptr, uint8_t *buf, uint32_t size_in_byte);
685 
686 /**
687  * @brief Sets UART baudrate.
688  *
689  * This function configures the UART module baud rate. This function is used to update
690  * the UART module baud rate after the UART module is initialized by the uart_init.
691  *
692  * @param ptr UART base address
693  * @param baudrate UART baudrate to be set
694  * @param src_clock_hz UART clock source frequency in Hz.
695  * @retval status_uart_no_suitable_baudrate_parameter_found Baudrate is not supported in the current clock source
696  * @retval status_success Set baudrate succeeded.
697  */
698 hpm_stat_t uart_set_baudrate(UART_Type *ptr, uint32_t baudrate, uint32_t src_clock_hz);
699 
700 
701 #if defined(HPM_IP_FEATURE_UART_TRIG_MODE) && (HPM_IP_FEATURE_UART_TRIG_MODE == 1)
702 /**
703  * @brief uart configure transfer trigger mode
704  *
705  * This function can configure uart to send data in fifo after being triggered
706  *
707  * @param ptr UART base address
708  * @param config uart_trig_config_t config
709  */
710 void uart_config_transfer_trig_mode(UART_Type *ptr, uart_trig_config_t *config);
711 
712 /**
713  * @brief uart software trigger transmit
714  *
715  * This function immediately triggers the transfer, the transfer configed by uart_config_transfer_trig_mode()
716  *
717  * @param ptr UART base address
718  */
uart_software_trig_transfer(UART_Type * ptr)719 static inline void uart_software_trig_transfer(UART_Type *ptr)
720 {
721     ptr->MOTO_CFG &= ~UART_MOTO_CFG_HWTRG_EN_MASK;
722     ptr->MOTO_CFG |= UART_MOTO_CFG_SWTRG_MASK;
723 }
724 
725 /**
726  * @brief uart enable hardware trigger mode
727  *
728  * This function enable hardware trigger the transfer, the transfer start when hardware event occured
729  *
730  * @param ptr UART base address
731  * @param enable true for enable, false for disable
732  */
uart_enable_hardware_trig_transfer(UART_Type * ptr,bool enable)733 static inline void uart_enable_hardware_trig_transfer(UART_Type *ptr, bool enable)
734 {
735     if (enable) {
736         ptr->MOTO_CFG |= UART_MOTO_CFG_HWTRG_EN_MASK;
737     } else {
738         ptr->MOTO_CFG &= ~UART_MOTO_CFG_HWTRG_EN_MASK;
739     }
740 }
741 
742 /**
743  * @brief UART get data count in rx fifo
744  *
745  * @param ptr UART base address
746  * @retval data count
747  */
uart_get_data_count_in_rx_fifo(UART_Type * ptr)748 static inline uint8_t uart_get_data_count_in_rx_fifo(UART_Type *ptr)
749 {
750     return UART_LSR_RFIFO_NUM_GET(ptr->LSR);
751 }
752 
753 /**
754  * @brief UART get data count in tx fifo
755  *
756  * @param ptr UART base address
757  * @retval data count
758  */
uart_get_data_count_in_tx_fifo(UART_Type * ptr)759 static inline uint8_t uart_get_data_count_in_tx_fifo(UART_Type *ptr)
760 {
761     return UART_LSR_TFIFO_NUM_GET(ptr->LSR);
762 }
763 #endif
764 
765 #if defined(HPM_IP_FEATURE_UART_ADDR_MATCH) && (HPM_IP_FEATURE_UART_ADDR_MATCH == 1)
766 /**
767  * @brief uart enable 9bit transmit mode
768  *
769  * @param ptr UART base address
770  * @param enable true for enable, false for disable
771  */
uart_enable_9bit_transmit_mode(UART_Type * ptr,bool enable)772 static inline void uart_enable_9bit_transmit_mode(UART_Type *ptr, bool enable)
773 {
774     if (enable) {
775         ptr->ADDR_CFG |= UART_ADDR_CFG_TXEN_9BIT_MASK
776                             | UART_ADDR_CFG_RXEN_ADDR_MSB_MASK
777                             | UART_ADDR_CFG_RXEN_9BIT_MASK;
778     } else {
779         ptr->ADDR_CFG &= ~(UART_ADDR_CFG_TXEN_9BIT_MASK
780                             | UART_ADDR_CFG_RXEN_ADDR_MSB_MASK
781                             | UART_ADDR_CFG_RXEN_9BIT_MASK);
782     }
783 }
784 
785 /**
786  * @brief uart enable address0 match
787  *
788  * @param ptr UART base address
789  * @param addr address value
790  */
uart_enable_address0_match(UART_Type * ptr,uint8_t addr)791 static inline void uart_enable_address0_match(UART_Type *ptr, uint8_t addr)
792 {
793     ptr->ADDR_CFG &= ~UART_ADDR_CFG_ADDR0_MASK;
794     ptr->ADDR_CFG |= UART_ADDR_CFG_A0_EN_MASK | UART_ADDR_CFG_ADDR0_SET(addr);
795 }
796 
797 /**
798  * @brief uart enable address1 match
799  *
800  * @param ptr UART base address
801  * @param addr address value
802  */
uart_enable_address1_match(UART_Type * ptr,uint8_t addr)803 static inline void uart_enable_address1_match(UART_Type *ptr, uint8_t addr)
804 {
805     ptr->ADDR_CFG &= ~UART_ADDR_CFG_ADDR1_MASK;
806     ptr->ADDR_CFG |= UART_ADDR_CFG_A1_EN_MASK | UART_ADDR_CFG_ADDR1_SET(addr);
807 }
808 
809 /**
810  * @brief uart disable address0 match
811  *
812  * @param ptr UART base address
813  */
uart_disable_address0_match(UART_Type * ptr)814 static inline void uart_disable_address0_match(UART_Type *ptr)
815 {
816     ptr->ADDR_CFG &= ~UART_ADDR_CFG_A0_EN_MASK;
817 }
818 
819 /**
820  * @brief uart disable address1 match
821  *
822  * @param ptr UART base address
823  */
uart_disable_address1_match(UART_Type * ptr)824 static inline void uart_disable_address1_match(UART_Type *ptr)
825 {
826     ptr->ADDR_CFG &= ~UART_ADDR_CFG_A1_EN_MASK;
827 }
828 
829 /**
830  * @brief uart disable address match(address0 and address1)
831  *
832  * @param ptr UART base address
833  */
uart_disable_address_match(UART_Type * ptr)834 static inline void uart_disable_address_match(UART_Type *ptr)
835 {
836     ptr->ADDR_CFG &= ~(UART_ADDR_CFG_A0_EN_MASK | UART_ADDR_CFG_A1_EN_MASK);
837 }
838 
839 /**
840  * @brief Determine whether address match for 9bit mode
841  * @param [in] ptr UART base address
842  * @retval false if uart address is not match
843  */
uart_is_addr_match(UART_Type * ptr)844 static inline bool uart_is_addr_match(UART_Type *ptr)
845 {
846     return ((ptr->IIR2 & UART_IIR2_ADDR_MATCH_MASK) != 0U) ? true : false;
847 }
848 
849 /**
850  * @brief Clear UART address match Flag
851  * @param [in] ptr UART base address
852  */
uart_clear_addr_match_flag(UART_Type * ptr)853 static inline void uart_clear_addr_match_flag(UART_Type *ptr)
854 {
855     ptr->IIR2 = UART_IIR2_ADDR_MATCH_MASK; /* Write-1-Clear Logic */
856 }
857 
858 /**
859  * @brief Determine whether address match and rx idle for 9bit mode
860  * @param [in] ptr UART base address
861  * @retval false if uart address is not match and not rx idle
862  */
uart_is_addr_match_and_rxidle(UART_Type * ptr)863 static inline bool uart_is_addr_match_and_rxidle(UART_Type *ptr)
864 {
865     return ((ptr->IIR2 & UART_IIR2_ADDR_MATCH_IDLE_MASK) != 0U) ? true : false;
866 }
867 
868 /**
869  * @brief Clear UART address match and rxidle Flag
870  * @param [in] ptr UART base address
871  */
uart_clear_addr_match_and_rxidle_flag(UART_Type * ptr)872 static inline void uart_clear_addr_match_and_rxidle_flag(UART_Type *ptr)
873 {
874     ptr->IIR2 = UART_IIR2_ADDR_MATCH_IDLE_MASK; /* Write-1-Clear Logic */
875 }
876 
877 /**
878  * @brief Determine whether data lost for 9bit mode
879  * @param [in] ptr UART base address
880  * @retval false if uart data is not lost
881  */
uart_is_data_lost(UART_Type * ptr)882 static inline bool uart_is_data_lost(UART_Type *ptr)
883 {
884     return ((ptr->IIR2 & UART_IIR2_DATA_LOST_MASK) != 0U) ? true : false;
885 }
886 
887 /**
888  * @brief Clear UART data lost Flag
889  * @param [in] ptr UART base address
890  */
uart_clear_data_lost_flag(UART_Type * ptr)891 static inline void uart_clear_data_lost_flag(UART_Type *ptr)
892 {
893     ptr->IIR2 = UART_IIR2_DATA_LOST_MASK; /* Write-1-Clear Logic */
894 }
895 #endif
896 
897 /**
898  * @brief   Write RTS level for uart modem mode
899  *
900  * @param [in] ptr UART base address
901  * @param high RTS set to high when it is set to true
902  */
uart_modem_write_rts_pin(UART_Type * ptr,uint8_t high)903 static inline void uart_modem_write_rts_pin(UART_Type *ptr, uint8_t high)
904 {
905     if (high == true) {
906         ptr->MCR &= ~UART_MCR_RTS_MASK;
907     } else {
908         ptr->MCR |= UART_MCR_RTS_MASK;
909     }
910 }
911 
912 #ifdef __cplusplus
913 }
914 #endif
915 /**
916  * @}
917  */
918 
919 #endif    /* HPM_UART_DRV_H */
920