drv_usart.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. #include "board.h"
  2. #include "hard_hdma_int.h"
  3. #include "hpm_uart_drv.h"
  4. #include "hpm_dmamux_drv.h"
  5. #include "hpm_dma_drv.h"
  6. #include "hpm_gpio_drv.h"
  7. #include "hpm_clock_drv.h"
  8. #include "rkfifo.h"
  9. #include <string.h>
  10. /* ========== 配置宏定义 ========== */
  11. #ifndef UART_RX_FIFO_BUFFER_LEN
  12. #define UART_RX_FIFO_BUFFER_LEN 256
  13. #endif
  14. #ifndef UART_TX_FIFO_BUFFER_LEN
  15. #define UART_TX_FIFO_BUFFER_LEN 256
  16. #endif
  17. #ifndef UART_TX_DMA_BUFFER_LEN
  18. #define UART_TX_DMA_BUFFER_LEN 1024
  19. #endif
  20. /* ========== 外部DMA完成标志声明 ========== */
  21. extern bool uart1_tx_dma_done;
  22. extern bool uart2_tx_dma_done;
  23. extern bool uart3_tx_dma_done;
  24. extern bool uart4_tx_dma_done;
  25. extern bool uart5_tx_dma_done;
  26. extern bool uart6_tx_dma_done;
  27. /* ========== 结构体定义 ========== */
  28. struct _uart_config {
  29. UART_Type *uart_base; /* UART基地址 */
  30. uart_intr_enable_t uart_irq_mask; /* UART中断掩码 */
  31. uint8_t uart_irq_num; /* 中断号 */
  32. /* GPIO配置 */
  33. uint8_t tx_port; /* TX端口: 0-9 (GPIOA-GPIOJ) */
  34. uint8_t tx_pin; /* TX引脚 */
  35. uint8_t rx_port; /* RX端口 */
  36. uint8_t rx_pin; /* RX引脚 */
  37. uint8_t tx_af; /* TX复用功能 */
  38. uint8_t rx_af; /* RX复用功能 */
  39. /* DMA配置 */
  40. DMA_Type *dma_base; /* DMA控制器基地址 */
  41. DMAMUX_Type *dma_mux_base; /* DMA MUX */
  42. uint8_t dma_enable; /* DMA 使能 (修正拼写) */
  43. uint8_t dma_channel; /* DMA通道 */
  44. uint8_t dma_irq_num; /* DMA中断号 */
  45. uint8_t dma_request; /* DMA请求源 */
  46. /* 缓冲区 */
  47. uint8_t *tx_fifo_buff; /* TX FIFO缓冲区 */
  48. uint32_t tx_fifo_buff_size; /* TX FIFO大小 */
  49. uint8_t *rx_fifo_buff; /* RX FIFO缓冲区 */
  50. uint32_t rx_fifo_buff_size; /* RX FIFO大小 */
  51. /* DMA缓冲区 */
  52. uint8_t *dma_tx_buff; /* DMA发送缓冲区 */
  53. uint32_t dma_tx_buff_size; /* DMA发送缓冲区大小 */
  54. /* 内部使用 */
  55. rkfifo_t tx_fifo; /* TX FIFO */
  56. rkfifo_t rx_fifo; /* RX FIFO */
  57. volatile uint8_t dma_busy; /* DMA发送忙标志 */
  58. };
  59. struct _uart_ops {
  60. int (*init)(struct _uart_config *config, uint32_t baudrate);
  61. uint32_t (*read)(struct _uart_config *config, void *data, uint32_t len);
  62. uint32_t (*write)(struct _uart_config *config, const void *data, uint32_t len);
  63. };
  64. struct _uart_device {
  65. struct _uart_config *config;
  66. struct _uart_ops *ops;
  67. };
  68. /* ========== 辅助函数:获取DMA完成标志指针 ========== */
  69. static bool* _get_dma_done_flag(UART_Type *uart_base)
  70. {
  71. if (uart_base == HPM_UART1) {
  72. return &uart1_tx_dma_done;
  73. } else if (uart_base == HPM_UART2) {
  74. return &uart2_tx_dma_done;
  75. } else if (uart_base == HPM_UART3) {
  76. return &uart3_tx_dma_done;
  77. } else if (uart_base == HPM_UART4) {
  78. return &uart4_tx_dma_done;
  79. } else if (uart_base == HPM_UART5) {
  80. return &uart5_tx_dma_done;
  81. } else if (uart_base == HPM_UART6) {
  82. return &uart6_tx_dma_done;
  83. }
  84. return NULL;
  85. }
  86. /* ========== 时钟使能函数 ========== */
  87. static void _uart_clock_enable(UART_Type *uart_base)
  88. {
  89. if (uart_base == HPM_UART0) {
  90. clock_set_source_divider(clock_uart0, clk_src_osc24m, 1);
  91. clock_add_to_group(clock_uart0, 0);
  92. } else if (uart_base == HPM_UART1) {
  93. clock_set_source_divider(clock_uart1, clk_src_osc24m, 1);
  94. clock_add_to_group(clock_uart1, 0);
  95. } else if (uart_base == HPM_UART2) {
  96. clock_set_source_divider(clock_uart2, clk_src_osc24m, 1);
  97. clock_add_to_group(clock_uart2, 0);
  98. } else if (uart_base == HPM_UART3) {
  99. clock_set_source_divider(clock_uart3, clk_src_osc24m, 1);
  100. clock_add_to_group(clock_uart3, 0);
  101. } else if (uart_base == HPM_UART4) {
  102. clock_set_source_divider(clock_uart4, clk_src_osc24m, 1);
  103. clock_add_to_group(clock_uart4, 0);
  104. } else if (uart_base == HPM_UART5) {
  105. clock_set_source_divider(clock_uart5, clk_src_osc24m, 1);
  106. clock_add_to_group(clock_uart5, 0);
  107. } else if (uart_base == HPM_UART6) {
  108. clock_set_source_divider(clock_uart6, clk_src_osc24m, 1);
  109. clock_add_to_group(clock_uart6, 0);
  110. } else if (uart_base == HPM_UART7) {
  111. clock_set_source_divider(clock_uart7, clk_src_osc24m, 1);
  112. clock_add_to_group(clock_uart7, 0);
  113. }
  114. }
  115. /* ========== DMA时钟使能 ========== */
  116. static void _dma_clock_enable(DMA_Type *dma_base)
  117. {
  118. /* HDMA 时钟来源于系统总线时钟(AHB),已默认使能 */
  119. (void)dma_base;
  120. }
  121. /* ========== GPIO配置 ========== */
  122. static void _uart_gpio_config(UART_Type *uart_base)
  123. {
  124. if (uart_base == HPM_UART1) {
  125. HPM_IOC->PAD[IOC_PAD_PA02].FUNC_CTL = IOC_PA02_FUNC_CTL_UART1_TXD;
  126. HPM_IOC->PAD[IOC_PAD_PA01].FUNC_CTL = IOC_PA01_FUNC_CTL_UART1_RXD;
  127. } else if (uart_base == HPM_UART2) {
  128. HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_UART2_RXD;
  129. HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_UART2_TXD;
  130. } else if (uart_base == HPM_UART3) {
  131. HPM_IOC->PAD[IOC_PAD_PB24].FUNC_CTL = IOC_PB24_FUNC_CTL_UART3_RXD;
  132. HPM_IOC->PAD[IOC_PAD_PB25].FUNC_CTL = IOC_PB25_FUNC_CTL_UART3_TXD;
  133. } else if (uart_base == HPM_UART4) {
  134. HPM_IOC->PAD[IOC_PAD_PA09].FUNC_CTL = IOC_PA09_FUNC_CTL_UART4_RXD;
  135. HPM_IOC->PAD[IOC_PAD_PA04].FUNC_CTL = IOC_PA04_FUNC_CTL_UART4_TXD;
  136. } else if (uart_base == HPM_UART5) {
  137. HPM_IOC->PAD[IOC_PAD_PA08].FUNC_CTL = IOC_PA08_FUNC_CTL_UART5_TXD;
  138. HPM_IOC->PAD[IOC_PAD_PA07].FUNC_CTL = IOC_PA07_FUNC_CTL_UART5_RXD;
  139. } else if (uart_base == HPM_UART6) {
  140. HPM_IOC->PAD[IOC_PAD_PA05].FUNC_CTL = IOC_PA05_FUNC_CTL_UART6_RXD;
  141. HPM_IOC->PAD[IOC_PAD_PA06].FUNC_CTL = IOC_PA06_FUNC_CTL_UART6_TXD;
  142. }
  143. }
  144. /* ========== UART配置 ========== */
  145. static int _uart_config(struct _uart_config *config, uint32_t baudrate)
  146. {
  147. uart_config_t uart_cfg;
  148. uint32_t uart_clock_freq = 0;
  149. /* 使能时钟 */
  150. _uart_clock_enable(config->uart_base);
  151. /* 配置GPIO */
  152. _uart_gpio_config(config->uart_base);
  153. /* 获取UART时钟频率 */
  154. if (config->uart_base == HPM_UART0) {
  155. uart_clock_freq = clock_get_frequency(clock_uart0);
  156. } else if (config->uart_base == HPM_UART1) {
  157. uart_clock_freq = clock_get_frequency(clock_uart1);
  158. } else if (config->uart_base == HPM_UART2) {
  159. uart_clock_freq = clock_get_frequency(clock_uart2);
  160. } else if (config->uart_base == HPM_UART3) {
  161. uart_clock_freq = clock_get_frequency(clock_uart3);
  162. } else if (config->uart_base == HPM_UART4) {
  163. uart_clock_freq = clock_get_frequency(clock_uart4);
  164. } else if (config->uart_base == HPM_UART5) {
  165. uart_clock_freq = clock_get_frequency(clock_uart5);
  166. } else if (config->uart_base == HPM_UART6) {
  167. uart_clock_freq = clock_get_frequency(clock_uart6);
  168. } else if (config->uart_base == HPM_UART7) {
  169. uart_clock_freq = clock_get_frequency(clock_uart7);
  170. }
  171. /* 配置UART */
  172. uart_default_config(config->uart_base, &uart_cfg);
  173. uart_cfg.baudrate = baudrate;
  174. uart_cfg.word_length = word_length_8_bits;
  175. uart_cfg.num_of_stop_bits = stop_bits_1;
  176. uart_cfg.parity = parity_none;
  177. uart_cfg.fifo_enable = true;
  178. uart_cfg.dma_enable = config->dma_enable ? true : false;
  179. uart_cfg.tx_fifo_level = uart_tx_fifo_trg_not_full;
  180. uart_cfg.rx_fifo_level = uart_rx_fifo_trg_gt_three_quarters;
  181. uart_cfg.src_freq_in_hz = uart_clock_freq;
  182. uart_init(config->uart_base, &uart_cfg);
  183. return 0;
  184. }
  185. /* ========== DMA配置 ========== */
  186. static int _uart_dma_config(struct _uart_config *config)
  187. {
  188. dma_handshake_config_t handshake_config;
  189. if (config->dma_tx_buff == NULL) {
  190. return -1;
  191. }
  192. /* 使能DMA时钟 */
  193. _dma_clock_enable(config->dma_base);
  194. /* 配置 DMAMUX */
  195. dmamux_config(config->dma_mux_base,
  196. DMA_SOC_CHN_TO_DMAMUX_CHN(config->dma_base, config->dma_channel),
  197. config->dma_request,
  198. true);
  199. /* 配置 TX 握手参数 */
  200. dma_default_handshake_config(config->dma_base, &handshake_config);
  201. handshake_config.ch_index = config->dma_channel;
  202. handshake_config.dst = (uint32_t)&config->uart_base->THR;
  203. handshake_config.dst_fixed = true;
  204. handshake_config.src = core_local_mem_to_sys_address(0, (uint32_t)config->dma_tx_buff);
  205. handshake_config.src_fixed = false;
  206. handshake_config.data_width = DMA_TRANSFER_WIDTH_BYTE;
  207. handshake_config.size_in_byte = config->dma_tx_buff_size;
  208. hpm_stat_t stat = dma_setup_handshake(config->dma_base, &handshake_config, false);
  209. if (stat != status_success) {
  210. printf("uart dma tx config error\r\n");
  211. return -1;
  212. }
  213. return 0;
  214. }
  215. /* ========== NVIC中断配置 ========== */
  216. static void _uart_nvic_config(struct _uart_config *config)
  217. {
  218. /* 使能UART中断 */
  219. uart_enable_irq(config->uart_base, config->uart_irq_mask);
  220. intc_m_enable_irq_with_priority(config->uart_irq_num, 1);
  221. /* 使能DMA中断 */
  222. if (config->dma_enable) {
  223. intc_m_enable_irq_with_priority(config->dma_irq_num, 1);
  224. }
  225. }
  226. /* ========== UART初始化 ========== */
  227. int _uart_init(struct _uart_config *config, uint32_t baudrate)
  228. {
  229. /* 初始化FIFO */
  230. rkfifo_init(&config->tx_fifo, config->tx_fifo_buff, config->tx_fifo_buff_size, 1);
  231. rkfifo_init(&config->rx_fifo, config->rx_fifo_buff, config->rx_fifo_buff_size, 1);
  232. /* 配置UART硬件 */
  233. _uart_config(config, baudrate);
  234. /* 配置DMA */
  235. if (config->dma_enable) {
  236. _uart_dma_config(config);
  237. }
  238. /* 配置中断 */
  239. _uart_nvic_config(config);
  240. config->dma_busy = 0;
  241. return 0;
  242. }
  243. /**
  244. * @brief 获取串口发送是否忙碌
  245. */
  246. bool usart_tx_isbusy(struct _uart_config *config)
  247. {
  248. bool *dma_done_flag = _get_dma_done_flag(config->uart_base);
  249. if (dma_done_flag) {
  250. return !(*dma_done_flag);
  251. }
  252. return false;
  253. }
  254. void open_usart_dma_tx(struct _uart_config *config, uint32_t len)
  255. {
  256. dma_handshake_config_t handshake_config;
  257. bool *dma_done_flag = _get_dma_done_flag(config->uart_base);
  258. /* 等待上次发送完成 */
  259. uint32_t timeout = 1000000;
  260. while (usart_tx_isbusy(config) && timeout--) {
  261. __asm("nop");
  262. }
  263. if (timeout == 0) {
  264. /* 超时处理,复位DMA */
  265. dma_abort_channel(config->dma_base, config->dma_channel);
  266. if (dma_done_flag) {
  267. *dma_done_flag = true;
  268. }
  269. }
  270. /* 清除DMA完成标志 */
  271. if (dma_done_flag) {
  272. *dma_done_flag = false;
  273. }
  274. /* 重新配置 TX 传输大小 */
  275. dma_default_handshake_config(config->dma_base, &handshake_config);
  276. handshake_config.ch_index = config->dma_channel;
  277. handshake_config.dst = (uint32_t)&config->uart_base->THR;
  278. handshake_config.dst_fixed = true;
  279. handshake_config.src = core_local_mem_to_sys_address(0, (uint32_t)config->dma_tx_buff);
  280. handshake_config.src_fixed = false;
  281. handshake_config.data_width = DMA_TRANSFER_WIDTH_BYTE;
  282. handshake_config.size_in_byte = len;
  283. dma_setup_handshake(config->dma_base, &handshake_config, true);
  284. }
  285. /* ========== UART发送数据(DMA方式) ========== */
  286. static uint32_t uart_tx_data(struct _uart_config *config, const void *data, uint32_t len)
  287. {
  288. uint32_t ret = 0;
  289. if (len == 0) return 0;
  290. /* 将数据压入TX FIFO */
  291. ret = rkfifo_in(&config->tx_fifo, data, len);
  292. if (config->dma_tx_buff != NULL && config->dma_enable) {
  293. /* DMA方式发送 */
  294. if (!config->dma_busy) {
  295. /* DMA空闲,立即发送 */
  296. uint32_t count = rkfifo_out(&config->tx_fifo,
  297. config->dma_tx_buff,
  298. config->dma_tx_buff_size);
  299. if (count > 0) {
  300. open_usart_dma_tx(config, count);
  301. config->dma_busy = 1;
  302. }
  303. }
  304. }
  305. return ret;
  306. }
  307. /* ========== UART接收数据(从fifo往外读) ========== */
  308. static uint32_t uart_rx_data(struct _uart_config *config, void *data, uint32_t len)
  309. {
  310. return rkfifo_out(&config->rx_fifo, data, len);
  311. }
  312. /* ========== UART中断处理函数 ========== */
  313. void uart_isr_callback(struct _uart_config *config)
  314. {
  315. uint8_t count = 0;
  316. rkfifo_t *rxfifo = &config->rx_fifo;
  317. uint8_t irq_id = uart_get_irq_id(config->uart_base);
  318. if (irq_id == uart_intr_id_rx_data_avail) {
  319. while (uart_check_status(config->uart_base, uart_stat_data_ready)) {
  320. uint8_t byte = uart_read_byte(config->uart_base);
  321. rkfifo_in(rxfifo, &byte, 1);
  322. count++;
  323. /* 确保RX FIFO不会溢出 */
  324. if (count > 12) {
  325. break;
  326. }
  327. }
  328. }
  329. if (irq_id == uart_intr_id_rx_timeout) {
  330. /* 接收超时,读取剩余数据 */
  331. while (uart_check_status(config->uart_base, uart_stat_data_ready)) {
  332. uint8_t byte = uart_read_byte(config->uart_base);
  333. rkfifo_in(rxfifo, &byte, 1);
  334. }
  335. }
  336. }
  337. /* ========== DMA发送完成中断处理 ========== */
  338. void uart_tx_dma_isr_callback(struct _uart_config *config)
  339. {
  340. bool *dma_done_flag = _get_dma_done_flag(config->uart_base);
  341. /* 设置DMA完成标志 */
  342. if (dma_done_flag) {
  343. *dma_done_flag = true;
  344. }
  345. config->dma_busy = 0;
  346. rkfifo_t *tx_fifo = &config->tx_fifo;
  347. uint8_t *dma_buff = config->dma_tx_buff;
  348. uint32_t dma_buff_size = config->dma_tx_buff_size;
  349. uint32_t count = rkfifo_out(tx_fifo, dma_buff, dma_buff_size);
  350. if (count > 0) {
  351. open_usart_dma_tx(config, count);
  352. config->dma_busy = 1;
  353. }
  354. }
  355. /* ========== UART1 配置 ========== */
  356. #ifdef DRV_USING_UART1
  357. static uint8_t u1_rx_fifo_buff[UART_RX_FIFO_BUFFER_LEN];
  358. static uint8_t u1_tx_fifo_buff[UART_TX_FIFO_BUFFER_LEN];
  359. static uint8_t u1_dma_tx_buff[UART_TX_DMA_BUFFER_LEN];
  360. struct _uart_config _u1_config = {
  361. .uart_base = HPM_UART1, /* 修正:应该是UART1 */
  362. .uart_irq_mask = uart_intr_rx_rdy | uart_intr_rx_timeout, /* 添加中断掩码 */
  363. .uart_irq_num = IRQn_UART1, /* 修正:IRQn_UART1 */
  364. /* DMA配置 */
  365. .dma_base = HPM_DMA0,
  366. .dma_mux_base = HPM_DMAMUX0,
  367. .dma_enable = 1, /* 修正拼写 */
  368. .dma_channel = 0,
  369. .dma_irq_num = IRQn_DMA0_CH0,
  370. .dma_request = DMA_REQUEST_UART1_TX, /* 修正:UART1_TX */
  371. /* FIFO缓冲区 */
  372. .tx_fifo_buff = u1_tx_fifo_buff,
  373. .tx_fifo_buff_size = sizeof(u1_tx_fifo_buff),
  374. .rx_fifo_buff = u1_rx_fifo_buff,
  375. .rx_fifo_buff_size = sizeof(u1_rx_fifo_buff),
  376. /* DMA缓冲区 */
  377. .dma_tx_buff = u1_dma_tx_buff,
  378. .dma_tx_buff_size = sizeof(u1_dma_tx_buff),
  379. };
  380. static uint32_t u1_write_data(const void *data, uint32_t len)
  381. {
  382. return uart_tx_data(&_u1_config, data, len);
  383. }
  384. static uint32_t u1_read_data(void *data, uint32_t len)
  385. {
  386. return uart_rx_data(&_u1_config, data, len);
  387. }
  388. static int u1_init(uint32_t baudrate)
  389. {
  390. return _uart_init(&_u1_config, baudrate);
  391. }
  392. static struct _uart_ops _u1_ops = {
  393. .init = u1_init,
  394. .read = u1_read_data,
  395. .write = u1_write_data,
  396. };
  397. static struct _uart_device uart1 = {
  398. .config = &_u1_config,
  399. .ops = &_u1_ops,
  400. };
  401. /* UART1中断处理函数 */
  402. void uart1_irq_handler(void)
  403. {
  404. uart_isr_callback(&_u1_config);
  405. }
  406. /* DMA0通道0中断处理函数 */
  407. void dma0_ch0_irq_handler(void)
  408. {
  409. uart_tx_dma_isr_callback(&_u1_config);
  410. }
  411. #endif /* DRV_USING_UART1 */
  412. /* ========== UART查找函数 ========== */
  413. struct _uart_device *uart_find(const char *name)
  414. {
  415. struct _uart_device *uart = NULL;
  416. if (strncmp(name, "uart1", 5) == 0) {
  417. #ifdef DRV_USING_UART1
  418. uart = &uart1;
  419. #endif
  420. } else if (strncmp(name, "uart2", 5) == 0) {
  421. #ifdef DRV_USING_UART2
  422. uart = &uart2;
  423. #endif
  424. } else if (strncmp(name, "uart3", 5) == 0) {
  425. #ifdef DRV_USING_UART3
  426. uart = &uart3;
  427. #endif
  428. } else if (strncmp(name, "uart4", 5) == 0) {
  429. #ifdef DRV_USING_UART4
  430. uart = &uart4;
  431. #endif
  432. } else if (strncmp(name, "uart5", 5) == 0) {
  433. #ifdef DRV_USING_UART5
  434. uart = &uart5;
  435. #endif
  436. } else if (strncmp(name, "uart6", 5) == 0) {
  437. #ifdef DRV_USING_UART6
  438. uart = &uart6;
  439. #endif
  440. }
  441. return uart;
  442. }