hpm_uart_drv.h 10 KB

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