• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
13 /**
14  *
15  * @brief UART driver APIs
16  * @defgroup uart_interface UART driver APIs
17  * @ingroup io_interfaces
18  * @{
19  */
20 
21 /**
22  * @brief UART status
23  */
24 enum {
25     status_uart_no_suitable_baudrate_parameter_found = MAKE_STATUS(status_group_uart, 1),
26 };
27 
28 /* @brief Parity */
29 typedef enum parity {
30     parity_none = 0,
31     parity_odd,
32     parity_even,
33     parity_always_1,
34     parity_always_0,
35 } parity_setting_t;
36 
37 /* @brief Stop bits */
38 typedef enum num_of_stop_bits {
39     stop_bits_1 = 0,
40     stop_bits_1_5,
41     stop_bits_2,
42 } num_of_stop_bits_t;
43 
44 /* @brief Word length */
45 typedef enum word_length {
46     word_length_5_bits = 0,
47     word_length_6_bits,
48     word_length_7_bits,
49     word_length_8_bits,
50 } word_length_t;
51 
52 /* @brief UART fifo trigger levels */
53 typedef enum uart_fifo_trg_lvl {
54     uart_rx_fifo_trg_not_empty = 0,
55     uart_rx_fifo_trg_gt_one_quarter = 1,
56     uart_rx_fifo_trg_gt_half = 2,
57     uart_rx_fifo_trg_gt_three_quarters = 3,
58 
59     uart_tx_fifo_trg_not_full = 0,
60     uart_tx_fifo_trg_lt_three_quarters = 1,
61     uart_tx_fifo_trg_lt_half = 2,
62     uart_tx_fifo_trg_lt_one_quarter = 3,
63 } uart_fifo_trg_lvl_t;
64 
65 /* @brief UART signals */
66 typedef enum uart_signal {
67     uart_signal_rts = UART_MCR_RTS_MASK,
68 } uart_signal_t;
69 
70 /* @brief UART signal levels */
71 typedef enum uart_signal_level {
72     uart_signal_level_high,
73     uart_signal_level_low,
74 } uart_signal_level_t;
75 
76 /* @brief UART modem status */
77 typedef enum uart_modem_stat {
78     uart_modem_stat_cts = UART_MSR_CTS_MASK,
79     uart_modem_stat_dcts_changed = UART_MSR_DCTS_MASK,
80 } uart_modem_stat_t;
81 
82 /* @brief UART interrupt enable masks */
83 typedef enum uart_intr_enable {
84     uart_intr_rx_data_avail_or_timeout = UART_IER_ERBI_MASK,
85     uart_intr_tx_slot_avail = UART_IER_ETHEI_MASK,
86     uart_intr_rx_line_stat = UART_IER_ELSI_MASK,
87     uart_intr_modem_stat = UART_IER_EMSI_MASK,
88 } uart_intr_enable_t;
89 
90 /* @brief UART interrupt IDs */
91 typedef enum uart_intr_id {
92     uart_intr_id_modem_stat = 0x0,
93     uart_intr_id_tx_slot_avail = 0x2,
94     uart_intr_id_rx_data_avail = 0x4,
95     uart_intr_id_rx_line_stat = 0x6,
96     uart_intr_id_rx_timeout = 0xc,
97 } uart_intr_id_t;
98 
99 /* @brief UART status */
100 typedef enum uart_stat {
101     uart_stat_data_ready = UART_LSR_DR_MASK,
102     uart_stat_overrun_error = UART_LSR_OE_MASK,
103     uart_stat_parity_error = UART_LSR_PE_MASK,
104     uart_stat_framing_error = UART_LSR_FE_MASK,
105     uart_stat_line_break = UART_LSR_LBREAK_MASK,
106     uart_stat_tx_slot_avail = UART_LSR_THRE_MASK,
107     uart_stat_transmitter_empty = UART_LSR_TEMT_MASK,
108     uart_stat_rx_fifo_error = UART_LSR_ERRF_MASK,
109 } uart_stat_t;
110 
111 /**
112  * @brief UART modem config
113  */
114 typedef struct uart_modem_config {
115     bool auto_flow_ctrl_en;     /**< Auto flow control enable flag */
116     bool loop_back_en;          /**< Loop back enable flag */
117     bool set_rts_high;          /**< Set signal RTS level high flag */
118 } uart_modem_config_t;
119 
120 /**
121  * @brief UART config
122  */
123 typedef struct hpm_uart_config {
124     uint32_t src_freq_in_hz;            /**< Source clock frequency in Hz */
125     uint32_t baudrate;                  /**< Baudrate */
126     uint8_t num_of_stop_bits;           /**< Number of stop bits */
127     uint8_t word_length;                /**< Word length */
128     uint8_t parity;                     /**< Parity */
129     uint8_t tx_fifo_level;              /**< TX Fifo level */
130     uint8_t rx_fifo_level;              /**< RX Fifo level */
131     bool dma_enable;                    /**< DMA Enable flag */
132     bool fifo_enable;                   /**< Fifo Enable flag */
133     uart_modem_config_t modem_config;   /**< Modem config */
134 } uart_config_t;
135 
136 #ifdef __cplusplus
137 extern "C" {
138 #endif
139 
140 /**
141  * @brief Get fifo size
142  *
143  * @param ptr UART base address
144  * @retval size of Fifo
145  */
uart_get_fifo_size(UART_Type * ptr)146 static inline uint8_t uart_get_fifo_size(UART_Type *ptr)
147 {
148     return 16 << ((ptr->CFG & UART_CFG_FIFOSIZE_MASK) >> UART_CFG_FIFOSIZE_SHIFT);
149 }
150 
151 /**
152  * @brief Reset TX Fifo
153  *
154  * @param ptr UART base address
155  */
uart_reset_tx_fifo(UART_Type * ptr)156 static inline void uart_reset_tx_fifo(UART_Type *ptr)
157 {
158     if (ptr->FCR & UART_FCR_FIFOE_MASK) {
159         ptr->FCR |= UART_FCR_TFIFORST_MASK;
160     }
161 }
162 
163 /**
164  * @brief Reset RX Fifo
165  *
166  * @param ptr UART base address
167  */
uart_reset_rx_fifo(UART_Type * ptr)168 static inline void uart_reset_rx_fifo(UART_Type *ptr)
169 {
170     if (ptr->FCR & UART_FCR_FIFOE_MASK) {
171         ptr->FCR |= UART_FCR_RFIFORST_MASK;
172     }
173 }
174 
175 /**
176  * @brief Reset both TX and RX Fifo
177  *
178  * @param ptr UART base address
179  */
uart_reset_all_fifo(UART_Type * ptr)180 static inline void uart_reset_all_fifo(UART_Type *ptr)
181 {
182     if (ptr->FCR & UART_FCR_FIFOE_MASK) {
183         ptr->FCR |= UART_FCR_RFIFORST_MASK | UART_FCR_TFIFORST_MASK;
184     }
185 }
186 
187 /**
188  * @brief Enable modem loopback
189  *
190  * @param ptr UART base address
191  */
uart_modem_enable_loopback(UART_Type * ptr)192 static inline void uart_modem_enable_loopback(UART_Type *ptr)
193 {
194     ptr->MCR |= UART_MCR_LOOP_MASK;
195 }
196 
197 /**
198  * @brief Disable modem loopback
199  *
200  * @param ptr UART base address
201  */
uart_modem_disable_loopback(UART_Type * ptr)202 static inline void uart_modem_disable_loopback(UART_Type *ptr)
203 {
204     ptr->MCR &= ~UART_MCR_LOOP_MASK;
205 }
206 
207 /**
208  * @brief Disable modem auto flow control
209  *
210  * @param ptr UART base address
211  */
212 
uart_modem_disable_auto_flow_control(UART_Type * ptr)213 static inline void uart_modem_disable_auto_flow_control(UART_Type *ptr)
214 {
215     ptr->MCR &= ~UART_MCR_AFE_MASK;
216 }
217 
218 /**
219  * @brief Enable modem auto flow control
220  *
221  * @param ptr UART base address
222  */
uart_modem_enable_auto_flow_control(UART_Type * ptr)223 static inline void uart_modem_enable_auto_flow_control(UART_Type *ptr)
224 {
225     ptr->MCR |= UART_MCR_AFE_MASK;
226 }
227 
228 /**
229  * @brief Configure modem
230  *
231  * @param ptr UART base address
232  * @param config Pointer to modem config struct
233  */
uart_modem_config(UART_Type * ptr,uart_modem_config_t * config)234 static inline void uart_modem_config(UART_Type *ptr, uart_modem_config_t *config)
235 {
236     ptr->MCR = UART_MCR_AFE_SET(config->auto_flow_ctrl_en)
237         | UART_MCR_LOOP_SET(config->loop_back_en)
238         | UART_MCR_RTS_SET(!config->set_rts_high);
239 }
240 
241 /**
242  * @brief Get modem status
243  *
244  * @param ptr UART base address
245  * @retval Current modem status
246  */
uart_get_modem_status(UART_Type * ptr)247 static inline uint8_t uart_get_modem_status(UART_Type *ptr)
248 {
249     return ptr->MSR;
250 }
251 
252 
253 /**
254  * @brief Check modem status with given mask
255  *
256  * @param ptr UART base address
257  * @param mask Status mask value to be checked against
258  * @retval true if any bit in given mask is set
259  * @retval false if none of any bit in given mask is set
260  */
uart_check_modem_status(UART_Type * ptr,uart_modem_stat_t mask)261 static inline bool uart_check_modem_status(UART_Type *ptr, uart_modem_stat_t mask)
262 {
263     return (ptr->MSR & mask);
264 }
265 
266 /**
267  * @brief Disable IRQ with mask
268  *
269  * @param ptr UART base address
270  * @param irq_mask IRQ mask value to be disabled
271  */
uart_disable_irq(UART_Type * ptr,uart_intr_enable_t irq_mask)272 static inline void uart_disable_irq(UART_Type *ptr, uart_intr_enable_t irq_mask)
273 {
274     ptr->IER &= ~irq_mask;
275 }
276 
277 /**
278  * @brief Enable IRQ with mask
279  *
280  * @param ptr UART base address
281  * @param irq_mask IRQ mask value to be enabled
282  */
uart_enable_irq(UART_Type * ptr,uart_intr_enable_t irq_mask)283 static inline void uart_enable_irq(UART_Type *ptr, uart_intr_enable_t irq_mask)
284 {
285     ptr->IER |= irq_mask;
286 }
287 
288 /**
289  * @brief Get Enabled IRQ
290  *
291  * @param ptr UART base address
292  * @return enabled irq
293  */
uart_get_enabled_irq(UART_Type * ptr)294 static inline uint32_t uart_get_enabled_irq(UART_Type *ptr)
295 {
296     return ptr->IER;
297 }
298 
299 /**
300  * @brief Get interrupt identification
301  *
302  * @param ptr UART base address
303  * @retval interrupt id
304  */
uart_get_irq_id(UART_Type * ptr)305 static inline uint8_t uart_get_irq_id(UART_Type *ptr)
306 {
307     return (ptr->IIR & UART_IIR_INTRID_MASK);
308 }
309 
310 /**
311  * @brief Get status
312  *
313  * @param ptr UART base address
314  * @retval current status
315  */
uart_get_status(UART_Type * ptr)316 static inline uint8_t uart_get_status(UART_Type *ptr)
317 {
318     return ptr->LSR;
319 }
320 
321 /**
322  * @brief Check uart status according to the given status mask
323  *
324  * @param ptr UART base address
325  * @param mask Status mask value to be checked against
326  * @retval true if any bit in given mask is set
327  * @retval false if none of any bit in given mask is set
328  */
uart_check_status(UART_Type * ptr,uart_stat_t mask)329 static inline bool uart_check_status(UART_Type *ptr, uart_stat_t mask)
330 {
331     return (ptr->LSR & mask);
332 }
333 
334 /**
335  * @brief Get default config
336  *
337  * @param ptr UART base address
338  * @param config Pointer to the buffer to save default values
339  */
340 void uart_default_config(UART_Type *ptr, uart_config_t *config);
341 
342 /**
343  * @brief Initialization
344  *
345  * @param ptr UART base address
346  * @param config Pointer to config struct
347  * @retval status_success only if it succeeds
348  */
349 hpm_stat_t uart_init(UART_Type *ptr, uart_config_t *config);
350 
351 /**
352  * @brief Send one byte
353  *
354  * @param ptr UART base address
355  * @param c Byte to be sent
356  * @retval status_success only if it succeeds
357  */
358 hpm_stat_t uart_send_byte(UART_Type *ptr, uint8_t c);
359 
360 /**
361  * @brief Receive one byte
362  *
363  * @param ptr UART base address
364  * @param c Pointer to buffer to save the byte received on UART
365  * @retval status_success only if it succeeds
366  */
367 hpm_stat_t uart_receive_byte(UART_Type *ptr, uint8_t *c);
368 
369 /**
370  * @brief Set uart signal output level
371  *
372  * @param ptr UART base address
373  * @param signal Target signal
374  * @param level Target signal level
375  */
376 void uart_set_signal_level(UART_Type *ptr,
377                            uart_signal_t signal,
378                            uart_signal_level_t level);
379 
380 /**
381  * @brief Flush sending buffer/fifo
382  *
383  * @param ptr UART base address
384  * @retval status_success only if it succeeds
385  */
386 hpm_stat_t uart_flush(UART_Type *ptr);
387 
388 /**
389  * @brief Receive bytes blocking
390  *
391  * @param ptr UART base address
392  * @param buf Pointer to the buffer to save received data
393  * @param size_in_byte Size in byte to be sent
394  * @retval status_success only if it succeeds
395  */
396 hpm_stat_t uart_receive_data(UART_Type *ptr, uint8_t *buf, uint32_t size_in_byte);
397 
398 /**
399  * @brief Send bytes blocking
400  *
401  * @param ptr UART base address
402  * @param buf Pointer to the buffer to be sent
403  * @param size_in_byte Size in byte to be sent
404  * @retval status_success only if it succeeds
405  */
406 hpm_stat_t uart_send_data(UART_Type *ptr, uint8_t *buf, uint32_t size_in_byte);
407 
408 
409 /**
410  * @brief Sets UART baudrate.
411  *
412  * This function configures the UART module baud rate. This function is used to update
413  * the UART module baud rate after the UART module is initialized by the uart_init.
414  *
415  * @param ptr UART base address
416  * @param baudrate UART baudrate to be set
417  * @param src_clock_hz UART clock source frequency in Hz.
418  * @retval status_uart_no_suitable_baudrate_parameter_found Baudrate is not supported in the current clock source
419  * @retval status_success Set baudrate succeeded.
420  */
421 hpm_stat_t uart_set_baudrate(UART_Type *ptr, uint32_t baudrate, uint32_t src_clock_hz);
422 
423 #ifdef __cplusplus
424 }
425 #endif
426 /**
427  * @}
428  */
429 
430 #endif    /* HPM_UART_DRV_H */
431