1 /*
2 * Copyright (c) 2021-2022 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(UART_SOC_HAS_FINE_FIFO_THR) && (UART_SOC_HAS_FINE_FIFO_THR == 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(UART_SOC_HAS_RXLINE_IDLE_DETECTION) && (UART_SOC_HAS_RXLINE_IDLE_DETECTION == 1)
119 uart_intr_rx_line_idle = UART_IER_ERXIDLE_MASK,
120 #endif
121 #if defined(UART_SOC_HAS_TXLINE_IDLE_DETECTION) && (UART_SOC_HAS_TXLINE_IDLE_DETECTION == 1)
122 uart_intr_tx_line_idle = UART_IER_ETXIDLE_MASK,
123 #endif
124 #if defined(UART_SOC_HAS_ADDR_MATCH) && (UART_SOC_HAS_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(UART_SOC_HAS_RXLINE_IDLE_DETECTION) && (UART_SOC_HAS_RXLINE_IDLE_DETECTION == 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(UART_SOC_HAS_RXLINE_IDLE_DETECTION) && (UART_SOC_HAS_RXLINE_IDLE_DETECTION == 1)
196 uart_rxline_idle_config_t rxidle_config; /**< RX Idle configuration */
197 #endif
198 #if defined(UART_SOC_HAS_TXLINE_IDLE_DETECTION) && (UART_SOC_HAS_TXLINE_IDLE_DETECTION == 1)
199 uart_rxline_idle_config_t txidle_config; /**< TX Idle configuration */
200 #endif
201 #if defined(UART_SOC_HAS_RXEN_CFG) && (UART_SOC_HAS_RXEN_CFG == 1)
202 bool rx_enable; /**< RX Enable configuration */
203 #endif
204 } uart_config_t;
205
206 #if defined(UART_SOC_HAS_TRIG_MODE) && (UART_SOC_HAS_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(UART_SOC_HAS_FCCR_REG) && (UART_SOC_HAS_FCCR_REG == 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(UART_SOC_HAS_FCCR_REG) && (UART_SOC_HAS_FCCR_REG == 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(UART_SOC_HAS_FCCR_REG) && (UART_SOC_HAS_FCCR_REG == 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(UART_SOC_HAS_RXLINE_IDLE_DETECTION) && (UART_SOC_HAS_RXLINE_IDLE_DETECTION == 1)
453
454 /* if UART_SOC_HAS_IIR2_REG = 1, the IIR2 register exists, should use IIR2 to get/clear rx idle status */
455 #if !defined(UART_SOC_HAS_IIR2_REG) || (UART_SOC_HAS_IIR2_REG == 0)
456 /**
457 * @brief Determine whether UART RX Line is idle
458 * @param [in] ptr UART base address
459 */
uart_is_rxline_idle(UART_Type * ptr)460 static inline bool uart_is_rxline_idle(UART_Type *ptr)
461 {
462 return ((ptr->IIR & UART_IIR_RXIDLE_FLAG_MASK) != 0U) ? true : false;
463 }
464
465 /**
466 * @brief Clear UART RX Line Idle Flag
467 * @param [in] ptr UART base address
468 */
uart_clear_rxline_idle_flag(UART_Type * ptr)469 static inline void uart_clear_rxline_idle_flag(UART_Type *ptr)
470 {
471 ptr->IIR = UART_IIR_RXIDLE_FLAG_MASK; /* Write-1-Clear Logic */
472 ptr->FCR = ptr->GPR;
473 }
474 #endif
475
476 /**
477 * @brief Enable UART RX Idle Line detection logic
478 * @param [in] ptr UART base address
479 */
uart_enable_rxline_idle_detection(UART_Type * ptr)480 static inline void uart_enable_rxline_idle_detection(UART_Type *ptr)
481 {
482 ptr->IDLE_CFG |= UART_IDLE_CFG_RX_IDLE_EN_MASK;
483 }
484
485 /**
486 * @brief Disable UART RX Idle Line detection logic
487 *
488 * @param [in] ptr UART base address
489 */
uart_disable_rxline_idle_detection(UART_Type * ptr)490 static inline void uart_disable_rxline_idle_detection(UART_Type *ptr)
491 {
492 ptr->IDLE_CFG &= ~UART_IDLE_CFG_RX_IDLE_EN_MASK;
493 }
494
495 /**
496 * @brief Configure UART RX Line detection
497 * @param [in] ptr UART base address
498 * @param [in] rxidle_config RXLine IDLE detection configuration
499 * @retval status_success if no error occurs
500 */
501 hpm_stat_t uart_init_rxline_idle_detection(UART_Type *ptr, uart_rxline_idle_config_t rxidle_config);
502
503 #endif
504
505 #if defined(UART_SOC_HAS_IIR2_REG) && (UART_SOC_HAS_IIR2_REG == 1)
506 /**
507 * @brief Determine whether UART TX Line is idle
508 * @param [in] ptr UART base address
509 */
uart_is_txline_idle(UART_Type * ptr)510 static inline bool uart_is_txline_idle(UART_Type *ptr)
511 {
512 return ((ptr->IIR2 & UART_IIR2_TXIDLE_FLAG_MASK) != 0U) ? true : false;
513 }
514
515 /**
516 * @brief Clear UART TX Line Idle Flag
517 * @param [in] ptr UART base address
518 */
uart_clear_txline_idle_flag(UART_Type * ptr)519 static inline void uart_clear_txline_idle_flag(UART_Type *ptr)
520 {
521 ptr->IIR2 = UART_IIR2_TXIDLE_FLAG_MASK; /* Write-1-Clear Logic */
522 }
523
524 /**
525 * @brief Determine whether UART RX Line is idle
526 * @param [in] ptr UART base address
527 */
uart_is_rxline_idle(UART_Type * ptr)528 static inline bool uart_is_rxline_idle(UART_Type *ptr)
529 {
530 return ((ptr->IIR2 & UART_IIR2_RXIDLE_FLAG_MASK) != 0U) ? true : false;
531 }
532
533 /**
534 * @brief Clear UART RX Line Idle Flag
535 * @param [in] ptr UART base address
536 */
uart_clear_rxline_idle_flag(UART_Type * ptr)537 static inline void uart_clear_rxline_idle_flag(UART_Type *ptr)
538 {
539 ptr->IIR2 = UART_IIR2_RXIDLE_FLAG_MASK; /* Write-1-Clear Logic */
540 }
541 #endif
542
543 #if defined(UART_SOC_HAS_TXLINE_IDLE_DETECTION) && (UART_SOC_HAS_TXLINE_IDLE_DETECTION == 1)
544 /**
545 * @brief Enable UART TX Idle Line detection logic
546 * @param [in] ptr UART base address
547 */
uart_enable_txline_idle_detection(UART_Type * ptr)548 static inline void uart_enable_txline_idle_detection(UART_Type *ptr)
549 {
550 ptr->IDLE_CFG |= UART_IDLE_CFG_TX_IDLE_EN_MASK;
551 }
552
553 /**
554 * @brief Disable UART TX Idle Line detection logic
555 *
556 * @param [in] ptr UART base address
557 */
uart_disable_txline_idle_detection(UART_Type * ptr)558 static inline void uart_disable_txline_idle_detection(UART_Type *ptr)
559 {
560 ptr->IDLE_CFG &= ~UART_IDLE_CFG_TX_IDLE_EN_MASK;
561 }
562
563 /**
564 * @brief Configure UART TX Line detection
565 * @param [in] ptr UART base address
566 * @param [in] txidle_config TXLine IDLE detection configuration
567 * @retval status_success if no error occurs
568 */
569 hpm_stat_t uart_init_txline_idle_detection(UART_Type *ptr, uart_rxline_idle_config_t txidle_config);
570
571 #endif
572
573
574
575 /**
576 * @brief Get status
577 *
578 * @param [in] ptr UART base address
579 * @retval current status
580 */
uart_get_status(UART_Type * ptr)581 static inline uint8_t uart_get_status(UART_Type *ptr)
582 {
583 return ptr->LSR;
584 }
585
586 /**
587 * @brief Check uart status according to the given status mask
588 *
589 * @param [in] ptr UART base address
590 * @param mask Status mask value to be checked against
591 * @retval true if any bit in given mask is set
592 * @retval false if none of any bit in given mask is set
593 */
uart_check_status(UART_Type * ptr,uart_stat_t mask)594 static inline bool uart_check_status(UART_Type *ptr, uart_stat_t mask)
595 {
596 return ((ptr->LSR & mask) != 0U) ? true : false;
597 }
598
599 /**
600 * @brief Get default config
601 *
602 * @param [in] ptr UART base address
603 * @param config Pointer to the buffer to save default values
604 */
605 void uart_default_config(UART_Type *ptr, uart_config_t *config);
606
607 /**
608 * @brief Initialization
609 *
610 * @param [in] ptr UART base address
611 * @param config Pointer to config struct
612 * @retval status_success only if it succeeds
613 */
614 hpm_stat_t uart_init(UART_Type *ptr, uart_config_t *config);
615
616 /**
617 * @brief Send one byte after checking thresh hold status
618 *
619 * @param [in] ptr UART base address
620 * @param c Byte to be sent
621 * @retval status_success only if it succeeds
622 */
623 hpm_stat_t uart_send_byte(UART_Type *ptr, uint8_t c);
624
625 /**
626 * @brief Receive one byte after checking data ready status
627 *
628 * @param [in] ptr UART base address
629 * @param c Pointer to buffer to save the byte received on UART
630 * @retval status_success only if it succeeds
631 */
632 hpm_stat_t uart_receive_byte(UART_Type *ptr, uint8_t *c);
633
634 /**
635 * @brief Set uart signal output level
636 *
637 * @param [in] ptr UART base address
638 * @param signal Target signal
639 * @param level Target signal level
640 */
641 void uart_set_signal_level(UART_Type *ptr,
642 uart_signal_t signal,
643 uart_signal_level_t level);
644
645 /**
646 * @brief Flush sending buffer/fifo
647 *
648 * @param [in] ptr UART base address
649 * @retval status_success only if it succeeds
650 */
651 hpm_stat_t uart_flush(UART_Type *ptr);
652
653 /**
654 * @brief Receive bytes blocking
655 *
656 * @param [in] ptr UART base address
657 * @param buf Pointer to the buffer to save received data
658 * @param size_in_byte Size in byte to be sent
659 * @retval status_success only if it succeeds
660 */
661 hpm_stat_t uart_receive_data(UART_Type *ptr, uint8_t *buf, uint32_t size_in_byte);
662
663 /**
664 * @brief Send bytes blocking
665 *
666 * @param [in] ptr UART base address
667 * @param buf Pointer to the buffer to be sent
668 * @param size_in_byte Size in byte to be sent
669 * @retval status_success only if it succeeds
670 */
671 hpm_stat_t uart_send_data(UART_Type *ptr, uint8_t *buf, uint32_t size_in_byte);
672
673 /**
674 * @brief Sets UART baudrate.
675 *
676 * This function configures the UART module baud rate. This function is used to update
677 * the UART module baud rate after the UART module is initialized by the uart_init.
678 *
679 * @param ptr UART base address
680 * @param baudrate UART baudrate to be set
681 * @param src_clock_hz UART clock source frequency in Hz.
682 * @retval status_uart_no_suitable_baudrate_parameter_found Baudrate is not supported in the current clock source
683 * @retval status_success Set baudrate succeeded.
684 */
685 hpm_stat_t uart_set_baudrate(UART_Type *ptr, uint32_t baudrate, uint32_t src_clock_hz);
686
687
688 #if defined(UART_SOC_HAS_TRIG_MODE) && (UART_SOC_HAS_TRIG_MODE == 1)
689 /**
690 * @brief uart configure transfer trigger mode
691 *
692 * This function can configure uart to send data in fifo after being triggered
693 *
694 * @param ptr UART base address
695 * @param uart_trig_config_t config
696 */
697 void uart_config_transfer_trig_mode(UART_Type *ptr, uart_trig_config_t *config);
698
699 /**
700 * @brief uart software trigger transmit
701 *
702 * This function immediately triggers the transfer, the transfer configed by uart_config_transfer_trig_mode()
703 *
704 * @param ptr UART base address
705 */
uart_software_trig_transfer(UART_Type * ptr)706 static inline void uart_software_trig_transfer(UART_Type *ptr)
707 {
708 ptr->MOTO_CFG &= ~UART_MOTO_CFG_HWTRG_EN_MASK;
709 ptr->MOTO_CFG |= UART_MOTO_CFG_SWTRG_MASK;
710 }
711
712 /**
713 * @brief uart enable hardware trigger mode
714 *
715 * This function enable hardware trigger the transfer, the transfer start when hardware event occured
716 *
717 * @param ptr UART base address
718 * @param enable true for enable, false for disable
719 */
uart_enable_hardware_trig_transfer(UART_Type * ptr,bool enable)720 static inline void uart_enable_hardware_trig_transfer(UART_Type *ptr, bool enable)
721 {
722 if (enable) {
723 ptr->MOTO_CFG |= UART_MOTO_CFG_HWTRG_EN_MASK;
724 } else {
725 ptr->MOTO_CFG &= ~UART_MOTO_CFG_HWTRG_EN_MASK;
726 }
727 }
728
729 /**
730 * @brief UART get data count in rx fifo
731 *
732 * @param ptr UART base address
733 * @retval data count
734 */
uart_get_data_count_in_rx_fifo(UART_Type * ptr)735 static inline uint8_t uart_get_data_count_in_rx_fifo(UART_Type *ptr)
736 {
737 return UART_LSR_RFIFO_NUM_GET(ptr->LSR);
738 }
739
740 /**
741 * @brief UART get data count in tx fifo
742 *
743 * @param ptr UART base address
744 * @retval data count
745 */
uart_get_data_count_in_tx_fifo(UART_Type * ptr)746 static inline uint8_t uart_get_data_count_in_tx_fifo(UART_Type *ptr)
747 {
748 return UART_LSR_TFIFO_NUM_GET(ptr->LSR);
749 }
750 #endif
751
752 #if defined(UART_SOC_HAS_ADDR_MATCH) && (UART_SOC_HAS_ADDR_MATCH == 1)
753 /**
754 * @brief uart enable 9bit transmit mode
755 *
756 * @param ptr UART base address
757 * @param enable true for enable, false for disable
758 */
uart_enable_9bit_transmit_mode(UART_Type * ptr,bool enable)759 static inline void uart_enable_9bit_transmit_mode(UART_Type *ptr, bool enable)
760 {
761 if (enable) {
762 ptr->ADDR_CFG |= UART_ADDR_CFG_TXEN_9BIT_MASK
763 | UART_ADDR_CFG_RXEN_ADDR_MSB_MASK
764 | UART_ADDR_CFG_RXEN_9BIT_MASK;
765 } else {
766 ptr->ADDR_CFG &= ~(UART_ADDR_CFG_TXEN_9BIT_MASK
767 | UART_ADDR_CFG_RXEN_ADDR_MSB_MASK
768 | UART_ADDR_CFG_RXEN_9BIT_MASK);
769 }
770 }
771
772 /**
773 * @brief uart enable address0 match
774 *
775 * @param ptr UART base address
776 * @param addr address value
777 */
uart_enable_address0_match(UART_Type * ptr,uint8_t addr)778 static inline void uart_enable_address0_match(UART_Type *ptr, uint8_t addr)
779 {
780 ptr->ADDR_CFG &= ~UART_ADDR_CFG_ADDR0_MASK;
781 ptr->ADDR_CFG |= UART_ADDR_CFG_A0_EN_MASK | UART_ADDR_CFG_ADDR0_SET(addr);
782 }
783
784 /**
785 * @brief uart enable address1 match
786 *
787 * @param ptr UART base address
788 * @param addr address value
789 */
uart_enable_address1_match(UART_Type * ptr,uint8_t addr)790 static inline void uart_enable_address1_match(UART_Type *ptr, uint8_t addr)
791 {
792 ptr->ADDR_CFG &= ~UART_ADDR_CFG_ADDR1_MASK;
793 ptr->ADDR_CFG |= UART_ADDR_CFG_A1_EN_MASK | UART_ADDR_CFG_ADDR1_SET(addr);
794 }
795
796 /**
797 * @brief uart disable address0 match
798 *
799 * @param ptr UART base address
800 */
uart_disable_address0_match(UART_Type * ptr)801 static inline void uart_disable_address0_match(UART_Type *ptr)
802 {
803 ptr->ADDR_CFG &= ~UART_ADDR_CFG_A0_EN_MASK;
804 }
805
806 /**
807 * @brief uart disable address1 match
808 *
809 * @param ptr UART base address
810 */
uart_disable_address1_match(UART_Type * ptr)811 static inline void uart_disable_address1_match(UART_Type *ptr)
812 {
813 ptr->ADDR_CFG &= ~UART_ADDR_CFG_A1_EN_MASK;
814 }
815
816 /**
817 * @brief uart disable address match(address0 and address1)
818 *
819 * @param ptr UART base address
820 */
uart_disable_address_match(UART_Type * ptr)821 static inline void uart_disable_address_match(UART_Type *ptr)
822 {
823 ptr->ADDR_CFG &= ~(UART_ADDR_CFG_A0_EN_MASK | UART_ADDR_CFG_A1_EN_MASK);
824 }
825
826 #endif
827
828 #ifdef __cplusplus
829 }
830 #endif
831 /**
832 * @}
833 */
834
835 #endif /* HPM_UART_DRV_H */
836