drv_usart.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. #include "board.h"
  2. #include "hard_hdma_int.h"
  3. #include "my_board.h"
  4. #include "hpm_clock_drv.h"
  5. #include "drv_usart.h"
  6. #include "rkfifo.h"
  7. #include "test.h"
  8. #include <string.h>
  9. /* ========== 辅助函数:获取DMA完成标志指针 ========== */
  10. static bool* _get_dma_done_flag(UART_Type *uart_base)
  11. {
  12. if (uart_base == HPM_UART1) {
  13. return &uart1_tx_dma_done;
  14. } else if (uart_base == HPM_UART2) {
  15. return &uart2_tx_dma_done;
  16. } else if (uart_base == HPM_UART3) {
  17. return &uart3_tx_dma_done;
  18. } else if (uart_base == HPM_UART4) {
  19. return &uart4_tx_dma_done;
  20. } else if (uart_base == HPM_UART5) {
  21. return &uart5_tx_dma_done;
  22. } else if (uart_base == HPM_UART6) {
  23. return &uart6_tx_dma_done;
  24. }
  25. return NULL;
  26. }
  27. /* ========== 时钟使能函数 ========== */
  28. static void _uart_clock_enable(UART_Type *uart_base)
  29. {
  30. if (uart_base == HPM_UART0) {
  31. clock_set_source_divider(clock_uart0, clk_src_osc24m, 1);
  32. clock_add_to_group(clock_uart0, 0);
  33. } else if (uart_base == HPM_UART1) {
  34. clock_set_source_divider(clock_uart1, clk_src_osc24m, 1);
  35. clock_add_to_group(clock_uart1, 0);
  36. } else if (uart_base == HPM_UART2) {
  37. clock_set_source_divider(clock_uart2, clk_src_osc24m, 1);
  38. clock_add_to_group(clock_uart2, 0);
  39. } else if (uart_base == HPM_UART3) {
  40. clock_set_source_divider(clock_uart3, clk_src_osc24m, 1);
  41. clock_add_to_group(clock_uart3, 0);
  42. } else if (uart_base == HPM_UART4) {
  43. clock_set_source_divider(clock_uart4, clk_src_osc24m, 1);
  44. clock_add_to_group(clock_uart4, 0);
  45. } else if (uart_base == HPM_UART5) {
  46. clock_set_source_divider(clock_uart5, clk_src_osc24m, 1);
  47. clock_add_to_group(clock_uart5, 0);
  48. } else if (uart_base == HPM_UART6) {
  49. clock_set_source_divider(clock_uart6, clk_src_osc24m, 1);
  50. clock_add_to_group(clock_uart6, 0);
  51. } else if (uart_base == HPM_UART7) {
  52. clock_set_source_divider(clock_uart7, clk_src_osc24m, 1);
  53. clock_add_to_group(clock_uart7, 0);
  54. }
  55. }
  56. /* ========== DMA时钟使能 ========== */
  57. static void _dma_clock_enable(DMA_Type *dma_base)
  58. {
  59. /* HDMA 时钟来源于系统总线时钟(AHB),已默认使能 */
  60. // clock_add_to_group(clock_hdma, 0);
  61. }
  62. /* ========== GPIO配置 ========== */
  63. static void _uart_gpio_config(UART_Type *uart_base) // 根据实际引脚配置
  64. {
  65. if (uart_base == HPM_UART1) {
  66. HPM_IOC->PAD[IOC_PAD_PA02].FUNC_CTL = IOC_PA02_FUNC_CTL_UART1_TXD;
  67. HPM_IOC->PAD[IOC_PAD_PA01].FUNC_CTL = IOC_PA01_FUNC_CTL_UART1_RXD;
  68. } else if (uart_base == HPM_UART2) {
  69. HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_UART2_RXD;
  70. HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_UART2_TXD;
  71. } else if (uart_base == HPM_UART3) {
  72. HPM_IOC->PAD[IOC_PAD_PB24].FUNC_CTL = IOC_PB24_FUNC_CTL_UART3_RXD;
  73. HPM_IOC->PAD[IOC_PAD_PB25].FUNC_CTL = IOC_PB25_FUNC_CTL_UART3_TXD;
  74. } else if (uart_base == HPM_UART4) {
  75. HPM_IOC->PAD[IOC_PAD_PA09].FUNC_CTL = IOC_PA09_FUNC_CTL_UART4_RXD;
  76. HPM_IOC->PAD[IOC_PAD_PA04].FUNC_CTL = IOC_PA04_FUNC_CTL_UART4_TXD;
  77. } else if (uart_base == HPM_UART5) {
  78. HPM_IOC->PAD[IOC_PAD_PA08].FUNC_CTL = IOC_PA08_FUNC_CTL_UART5_TXD;
  79. HPM_IOC->PAD[IOC_PAD_PA07].FUNC_CTL = IOC_PA07_FUNC_CTL_UART5_RXD;
  80. } else if (uart_base == HPM_UART6) {
  81. HPM_IOC->PAD[IOC_PAD_PA05].FUNC_CTL = IOC_PA05_FUNC_CTL_UART6_RXD;
  82. HPM_IOC->PAD[IOC_PAD_PA06].FUNC_CTL = IOC_PA06_FUNC_CTL_UART6_TXD;
  83. }
  84. }
  85. /* ========== UART配置 ========== */
  86. static int _uart_config(struct _uart_config *config, uint32_t baudrate)
  87. {
  88. uart_config_t uart_cfg;
  89. uint32_t uart_clock_freq = 0;
  90. /* 使能时钟 */
  91. _uart_clock_enable(config->uart_base);
  92. /* 配置GPIO */
  93. _uart_gpio_config(config->uart_base);
  94. /* 获取UART时钟频率 */
  95. if (config->uart_base == HPM_UART1) {
  96. uart_clock_freq = clock_get_frequency(clock_uart1);
  97. } else if (config->uart_base == HPM_UART2) {
  98. uart_clock_freq = clock_get_frequency(clock_uart2);
  99. } else if (config->uart_base == HPM_UART3) {
  100. uart_clock_freq = clock_get_frequency(clock_uart3);
  101. } else if (config->uart_base == HPM_UART4) {
  102. uart_clock_freq = clock_get_frequency(clock_uart4);
  103. } else if (config->uart_base == HPM_UART5) {
  104. uart_clock_freq = clock_get_frequency(clock_uart5);
  105. } else if (config->uart_base == HPM_UART6) {
  106. uart_clock_freq = clock_get_frequency(clock_uart6);
  107. }
  108. /* 配置UART */
  109. uart_default_config(config->uart_base, &uart_cfg);
  110. uart_cfg.baudrate = baudrate;
  111. uart_cfg.word_length = word_length_8_bits;
  112. uart_cfg.num_of_stop_bits = stop_bits_1;
  113. uart_cfg.parity = parity_none;
  114. uart_cfg.fifo_enable = true;
  115. uart_cfg.dma_enable = config->dma_enable ? true : false;
  116. uart_cfg.tx_fifo_level = uart_tx_fifo_trg_not_full;
  117. uart_cfg.rx_fifo_level = uart_rx_fifo_trg_gt_three_quarters;
  118. uart_cfg.src_freq_in_hz = uart_clock_freq;
  119. uart_init(config->uart_base, &uart_cfg);
  120. return 0;
  121. }
  122. /* ========== DMA配置 ========== */
  123. static int _uart_dma_config(struct _uart_config *config)
  124. {
  125. dma_handshake_config_t handshake_config;
  126. if (config->dma_tx_buff == NULL) {
  127. return -1;
  128. }
  129. /* 使能DMA时钟 */
  130. _dma_clock_enable(config->dma_base);
  131. /* 配置 DMAMUX */
  132. dmamux_config(config->dma_mux_base,
  133. DMA_SOC_CHN_TO_DMAMUX_CHN(config->dma_base, config->dma_channel),
  134. config->dma_request,
  135. true);
  136. /* 配置 TX 握手参数 */
  137. dma_default_handshake_config(config->dma_base, &handshake_config);
  138. handshake_config.ch_index = config->dma_channel;
  139. handshake_config.dst = (uint32_t)&config->uart_base->THR;
  140. handshake_config.dst_fixed = true;
  141. handshake_config.src = core_local_mem_to_sys_address(0, (uint32_t)config->dma_tx_buff);
  142. handshake_config.src_fixed = false;
  143. handshake_config.data_width = DMA_TRANSFER_WIDTH_BYTE;
  144. handshake_config.size_in_byte = config->dma_tx_buff_size;
  145. hpm_stat_t stat = dma_setup_handshake(config->dma_base, &handshake_config, false);
  146. if (stat != status_success) {
  147. printf("uart dma tx config error\r\n");
  148. return -1;
  149. }
  150. return 0;
  151. }
  152. /* ========== NVIC中断配置 ========== */
  153. static void _uart_nvic_config(struct _uart_config *config)
  154. {
  155. /* 使能UART中断 */
  156. uart_enable_irq(config->uart_base, config->uart_irq_mask);
  157. intc_m_enable_irq_with_priority(config->uart_irq_num, 1);
  158. /* 使能DMA中断 */
  159. if (config->dma_enable) {
  160. intc_m_enable_irq_with_priority(config->dma_irq_num, 1);
  161. printf("DMA interrupt enabled for channel %d\n", config->dma_channel);
  162. }
  163. }
  164. /* ========== UART初始化 ========== */
  165. int _uart_init(struct _uart_config *config, uint32_t baudrate)
  166. {
  167. /* 初始化FIFO */
  168. rkfifo_init(&config->tx_fifo, config->tx_fifo_buff, config->tx_fifo_buff_size, 1);
  169. rkfifo_init(&config->rx_fifo, config->rx_fifo_buff, config->rx_fifo_buff_size, 1);
  170. /* 配置UART硬件 */
  171. _uart_config(config, baudrate);
  172. /* 配置DMA */
  173. if (config->dma_enable) {
  174. _uart_dma_config(config);
  175. }
  176. /* 配置中断 */
  177. _uart_nvic_config(config);
  178. return 0;
  179. }
  180. uint8_t TX_BUFF[256]={'0','1','3'};
  181. void open_usart_dma_tx(struct _uart_config *config, uint32_t len)
  182. {
  183. dma_handshake_config_t handshake_config;
  184. /* 重新配置 TX 传输大小 */
  185. dma_default_handshake_config(config->dma_base, &handshake_config);
  186. handshake_config.ch_index = config->dma_channel;
  187. handshake_config.dst = (uint32_t)&(config->uart_base->THR);
  188. handshake_config.dst_fixed = true;
  189. handshake_config.src = core_local_mem_to_sys_address(0,(uint32_t)config->dma_tx_buff);
  190. handshake_config.src_fixed = false;
  191. handshake_config.data_width = DMA_TRANSFER_WIDTH_BYTE;
  192. handshake_config.size_in_byte = len;
  193. hpm_stat_t stat = dma_setup_handshake(config->dma_base, &handshake_config, true);
  194. if(stat != status_success)
  195. {
  196. printf("uart dma tx config error\r\n");
  197. }
  198. }
  199. /* ========== UART发送数据(DMA方式) ========== */
  200. static uint32_t uart_tx_data(struct _uart_config *config, const void *data, uint32_t len)
  201. {
  202. uint32_t ret = 0;
  203. if (len == 0) return 0;
  204. /* 将数据压入TX FIFO */
  205. ret = rkfifo_in(&config->tx_fifo, data, len);
  206. if (config->dma_tx_buff != NULL && config->dma_enable) {
  207. uint32_t count = rkfifo_out(&config->tx_fifo, config->dma_tx_buff, config->dma_tx_buff_size);
  208. if (count > 0) {
  209. open_usart_dma_tx(config, count);
  210. }
  211. }
  212. return ret;
  213. }
  214. /* ========== UART接收数据(从fifo往外读) ========== */
  215. static uint32_t uart_rx_data(struct _uart_config *config, void *data, uint32_t len)
  216. {
  217. return rkfifo_out(&config->rx_fifo, data, len);
  218. }
  219. /* ========== UART中断处理函数 ========== */
  220. void uart_isr_callback(struct _uart_config *config)
  221. {
  222. uint8_t count = 0;
  223. rkfifo_t *rxfifo = &config->rx_fifo;
  224. uint8_t irq_id = uart_get_irq_id(config->uart_base);
  225. if (irq_id == uart_intr_id_rx_data_avail) {
  226. while (uart_check_status(config->uart_base, uart_stat_data_ready)) {
  227. uint8_t byte = uart_read_byte(config->uart_base);
  228. rkfifo_in(rxfifo, &byte, 1);
  229. count++;
  230. /* 确保RX FIFO不会溢出 */
  231. if (count > 12) {
  232. break;
  233. }
  234. }
  235. }
  236. if (irq_id == uart_intr_id_rx_timeout) {
  237. /* 接收超时,读取剩余数据 */
  238. while (uart_check_status(config->uart_base, uart_stat_data_ready)) {
  239. uint8_t byte = uart_read_byte(config->uart_base);
  240. rkfifo_in(rxfifo, &byte, 1);
  241. }
  242. }
  243. }
  244. /* ========== DMA发送完成中断处理 ========== */
  245. void uart_tx_dma_isr_callback(struct _uart_config *config)
  246. {
  247. rkfifo_t *tx_fifo = &config->tx_fifo;
  248. uint8_t *dma_buff = config->dma_tx_buff;
  249. uint32_t dma_buff_size = config->dma_tx_buff_size;
  250. uint32_t count = rkfifo_out(tx_fifo, dma_buff, dma_buff_size);
  251. if (count > 0) {
  252. open_usart_dma_tx(config, count);
  253. }
  254. }
  255. /* ========== UART1 配置 ========== */
  256. #ifdef DRV_USING_UART1
  257. // ATTR_PLACE_AT_NONCACHEABLE这个一定不要忘记加
  258. static ATTR_PLACE_AT_NONCACHEABLE uint8_t u1_rx_fifo_buff[UART1_RX_FIFO_BUFFER_LEN];
  259. static ATTR_PLACE_AT_NONCACHEABLE uint8_t u1_tx_fifo_buff[UART1_TX_FIFO_BUFFER_LEN];
  260. static ATTR_PLACE_AT_NONCACHEABLE uint8_t u1_dma_tx_buff[UART1_TX_DMA_BUFFER_LEN];
  261. struct _uart_config _u1_config = {
  262. .uart_base = HPM_UART1,
  263. .uart_irq_mask = uart_intr_rx_data_avail_or_timeout, /* 添加中断掩码 */
  264. .uart_irq_num = IRQn_UART1,
  265. /* DMA配置 */
  266. .dma_base = HPM_HDMA,
  267. .dma_mux_base = HPM_DMAMUX,
  268. .dma_enable = 1,
  269. .dma_channel = 0,
  270. .dma_irq_num = IRQn_HDMA,
  271. .dma_request = HPM_DMA_SRC_UART1_TX,
  272. /* FIFO缓冲区 */
  273. .tx_fifo_buff = u1_tx_fifo_buff,
  274. .tx_fifo_buff_size = sizeof(u1_tx_fifo_buff),
  275. .rx_fifo_buff = u1_rx_fifo_buff,
  276. .rx_fifo_buff_size = sizeof(u1_rx_fifo_buff),
  277. /* DMA缓冲区 */
  278. .dma_tx_buff = u1_dma_tx_buff,
  279. .dma_tx_buff_size = sizeof(u1_dma_tx_buff),
  280. };
  281. static uint32_t u1_write_data(const void *data, uint32_t len)
  282. {
  283. return uart_tx_data(&_u1_config, data, len);
  284. }
  285. static uint32_t u1_read_data( void *data, uint32_t len)
  286. {
  287. return uart_rx_data(&_u1_config, data, len);
  288. }
  289. static int u1_init(uint32_t baudrate)
  290. {
  291. return _uart_init(&_u1_config, baudrate);
  292. }
  293. static struct _uart_ops _u1_ops = {
  294. .init = u1_init,
  295. .read = u1_read_data,
  296. .write = u1_write_data,
  297. };
  298. static struct _uart_device uart1 = {
  299. .config = &_u1_config,
  300. .ops = &_u1_ops,
  301. };
  302. /* UART1中断处理函数 */
  303. SDK_DECLARE_EXT_ISR_M(IRQn_UART1, uart1_isr)
  304. void uart1_isr(void)
  305. {
  306. uart_isr_callback(&_u1_config);
  307. }
  308. #endif
  309. #ifdef DRV_USING_UART4
  310. // ATTR_PLACE_AT_NONCACHEABLE这个一定不要忘记加
  311. static ATTR_PLACE_AT_NONCACHEABLE uint8_t u4_rx_fifo_buff[UART4_RX_FIFO_BUFFER_LEN];
  312. static ATTR_PLACE_AT_NONCACHEABLE uint8_t u4_tx_fifo_buff[UART4_TX_FIFO_BUFFER_LEN];
  313. static ATTR_PLACE_AT_NONCACHEABLE uint8_t u4_dma_tx_buff[UART4_TX_DMA_BUFFER_LEN];
  314. struct _uart_config _u4_config = {
  315. .uart_base = HPM_UART4,
  316. .uart_irq_mask = uart_intr_rx_data_avail_or_timeout, /* 添加中断掩码 */
  317. .uart_irq_num = IRQn_UART4,
  318. /* DMA配置 */
  319. .dma_base = HPM_HDMA,
  320. .dma_mux_base = HPM_DMAMUX,
  321. .dma_enable = 1,
  322. .dma_channel = 0,
  323. .dma_irq_num = IRQn_HDMA,
  324. .dma_request = HPM_DMA_SRC_UART4_TX,
  325. /* FIFO缓冲区 */
  326. .tx_fifo_buff = u4_tx_fifo_buff,
  327. .tx_fifo_buff_size = sizeof(u4_tx_fifo_buff),
  328. .rx_fifo_buff = u4_rx_fifo_buff,
  329. .rx_fifo_buff_size = sizeof(u4_rx_fifo_buff),
  330. /* DMA缓冲区 */
  331. .dma_tx_buff = u4_dma_tx_buff,
  332. .dma_tx_buff_size = sizeof(u4_dma_tx_buff),
  333. };
  334. static uint32_t u4_write_data(const void *data, uint32_t len)
  335. {
  336. return uart_tx_data(&_u4_config, data, len);
  337. }
  338. static uint32_t u4_read_data( void *data, uint32_t len)
  339. {
  340. return uart_rx_data(&_u4_config, data, len);
  341. }
  342. static int u4_init(uint32_t baudrate)
  343. {
  344. return _uart_init(&_u4_config, baudrate);
  345. }
  346. static struct _uart_ops _u4_ops = {
  347. .init = u4_init,
  348. .read = u4_read_data,
  349. .write = u4_write_data,
  350. };
  351. static struct _uart_device uart4 = {
  352. .config = &_u4_config,
  353. .ops = &_u4_ops,
  354. };
  355. /* UART4中断处理函数 */
  356. SDK_DECLARE_EXT_ISR_M(IRQn_UART4, uart4_isr)
  357. void uart4_isr(void)
  358. {
  359. uart_isr_callback(&_u4_config);
  360. }
  361. #endif /* DRV_USING_UART4 */
  362. /* ========== UART查找函数 ========== */
  363. struct _uart_device *uart_find(const char *name)
  364. {
  365. struct _uart_device *uart = NULL;
  366. if (strncmp(name, "uart1", 5) == 0) {
  367. #ifdef DRV_USING_UART1
  368. uart = &uart1;
  369. #endif
  370. } else if (strncmp(name, "uart2", 5) == 0) {
  371. #ifdef DRV_USING_UART2
  372. uart = &uart2;
  373. #endif
  374. } else if (strncmp(name, "uart3", 5) == 0) {
  375. #ifdef DRV_USING_UART3
  376. uart = &uart3;
  377. #endif
  378. } else if (strncmp(name, "uart4", 5) == 0) {
  379. #ifdef DRV_USING_UART4
  380. uart = &uart4;
  381. #endif
  382. } else if (strncmp(name, "uart5", 5) == 0) {
  383. #ifdef DRV_USING_UART5
  384. uart = &uart5;
  385. #endif
  386. } else if (strncmp(name, "uart6", 5) == 0) {
  387. #ifdef DRV_USING_UART6
  388. uart = &uart6;
  389. #endif
  390. }
  391. return uart;
  392. }
  393. // 通用串口驱动测试例程 20260323 pass
  394. #ifdef UART_DRV_TEST
  395. /* uart_test.c
  396. * UART驱动测试例程
  397. * 测试功能:发送测试、接收测试、回环测试、DMA传输测试
  398. */
  399. #include "board.h"
  400. #include "my_board.h"
  401. #include "drv_usart.h"
  402. #include <stdio.h>
  403. #include <string.h>
  404. /* ========== 测试配置 ========== */
  405. #define TEST_UART_NAME "uart3" /* 测试的UART名称 */
  406. #define TEST_BAUDRATE 115200 /* 波特率 */
  407. #define TEST_BUFFER_SIZE 256 /* 测试缓冲区大小 */
  408. #define TEST_LOOP_COUNT 10 /* 回环测试次数 */
  409. /* 测试标志 */
  410. static uint32_t test_pass_count = 0;
  411. static uint32_t test_fail_count = 0;
  412. /* ========== 辅助函数 ========== */
  413. /**
  414. * @brief 打印测试结果
  415. */
  416. static void print_test_result(const char *test_name, bool passed)
  417. {
  418. if (passed) {
  419. printf("[PASS] %s\n", test_name);
  420. test_pass_count++;
  421. } else {
  422. printf("[FAIL] %s\n", test_name);
  423. test_fail_count++;
  424. }
  425. }
  426. /**
  427. * @brief 打印测试汇总
  428. */
  429. static void print_test_summary(void)
  430. {
  431. printf("\n========== Test Summary ==========\n");
  432. printf("Total Tests: %d\n", test_pass_count + test_fail_count);
  433. printf("Passed: %d\n", test_pass_count);
  434. printf("Failed: %d\n", test_fail_count);
  435. printf("==================================\n");
  436. if (test_fail_count == 0) {
  437. printf("All tests PASSED!\n");
  438. } else {
  439. printf("Some tests FAILED!\n");
  440. }
  441. }
  442. /**
  443. * @brief 延迟函数(毫秒)
  444. */
  445. static void delay_ms(uint32_t ms)
  446. {
  447. board_delay_ms(ms);
  448. }
  449. /**
  450. * @brief 生成测试数据
  451. */
  452. static void generate_test_data(uint8_t *buffer, uint32_t len, uint8_t pattern)
  453. {
  454. for (uint32_t i = 0; i < len; i++) {
  455. buffer[i] = pattern+i;
  456. }
  457. }
  458. /**
  459. * @brief 验证数据是否正确
  460. */
  461. static bool verify_test_data(uint8_t *buffer, uint32_t len, uint8_t pattern)
  462. {
  463. for (uint32_t i = 0; i < len; i++) {
  464. if (buffer[i] != (pattern + i)) {
  465. printf("Data mismatch at pos %d: expected 0x%02X, got 0x%02X\n",
  466. i, pattern + i, buffer[i]);
  467. return false;
  468. }
  469. }
  470. return true;
  471. }
  472. /* ========== 测试用例 ========== */
  473. /**
  474. * @brief 测试1:UART初始化
  475. */
  476. static void test_uart_init(struct _uart_device *uart_dev)
  477. {
  478. printf("\n--- Test 1: UART Init ---\n");
  479. if (uart_dev == NULL) {
  480. printf("UART device not found!\n");
  481. print_test_result("UART Init", false);
  482. return;
  483. }
  484. int ret = uart_dev->ops->init( TEST_BAUDRATE);
  485. if (ret == 0) {
  486. printf("UART initialized successfully at %d baud\n", TEST_BAUDRATE);
  487. print_test_result("UART Init", true);
  488. } else {
  489. printf("UART init failed with code: %d\n", ret);
  490. print_test_result("UART Init", false);
  491. }
  492. }
  493. /**
  494. * @brief 测试2:单字节发送和接收(回环测试)
  495. * 需要将TX和RX引脚短接
  496. */
  497. static void test_single_byte_loopback(struct _uart_device *uart_dev)
  498. {
  499. printf("\n--- Test 2: Single Byte Loopback ---\n");
  500. printf("NOTE: Please short TX and RX pins for this test!\n");
  501. delay_ms(100); /* 等待用户准备 */
  502. uint8_t test_byte = 0x5A;
  503. uint8_t recv_byte = 0;
  504. uint32_t timeout = 10000;
  505. /* 发送数据 */
  506. uint32_t sent = uart_dev->ops->write( &test_byte, 1);
  507. if (sent != 1) {
  508. printf("Failed to send byte\n");
  509. print_test_result("Single Byte Loopback", false);
  510. return;
  511. }
  512. printf("Sent: 0x%02X\n", test_byte);
  513. /* 等待接收 */
  514. while (timeout--) {
  515. uint32_t received = uart_dev->ops->read( &recv_byte, 1);
  516. if (received == 1) {
  517. break;
  518. }
  519. delay_ms(1);
  520. }
  521. if (timeout == 0) {
  522. printf("Timeout waiting for data\n");
  523. print_test_result("Single Byte Loopback", false);
  524. return;
  525. }
  526. printf("Received: 0x%02X\n", recv_byte);
  527. if (test_byte == recv_byte) {
  528. print_test_result("Single Byte Loopback", true);
  529. } else {
  530. printf("Data mismatch!\n");
  531. print_test_result("Single Byte Loopback", false);
  532. }
  533. }
  534. /**
  535. * @brief 测试3:多字节发送和接收(回环测试)
  536. */
  537. static void test_multi_byte_loopback(struct _uart_device *uart_dev)
  538. {
  539. printf("\n--- Test 3: Multi-Byte Loopback ---\n");
  540. uint8_t tx_buffer[64];
  541. uint8_t rx_buffer[64];
  542. uint32_t test_len = 64;
  543. /* 生成测试数据 */
  544. generate_test_data(tx_buffer, test_len, 0x40);
  545. memset(rx_buffer, 0, test_len);
  546. /* 发送数据 */
  547. uint32_t sent = uart_dev->ops->write( tx_buffer, test_len);
  548. if (sent != test_len) {
  549. printf("Failed to send data: sent %d, expected %d\n", sent, test_len);
  550. print_test_result("Multi-Byte Loopback", false);
  551. return;
  552. }
  553. printf("Sent %d bytes\n", sent);
  554. /* 等待接收完成 */
  555. uint32_t total_received = 0;
  556. uint32_t timeout = 100000;
  557. while (total_received < test_len && timeout--) {
  558. uint32_t received = uart_dev->ops->read(
  559. &rx_buffer[total_received],
  560. test_len - total_received);
  561. if (received > 0) {
  562. total_received += received;
  563. }
  564. delay_ms(1);
  565. }
  566. if (timeout == 0) {
  567. printf("Timeout: received %d/%d bytes\n", total_received, test_len);
  568. print_test_result("Multi-Byte Loopback", false);
  569. return;
  570. }
  571. printf("Received %d bytes\n", total_received);
  572. /* 验证数据 */
  573. if (verify_test_data(rx_buffer, test_len, 0x40)) {
  574. print_test_result("Multi-Byte Loopback", true);
  575. } else {
  576. print_test_result("Multi-Byte Loopback", false);
  577. }
  578. }
  579. /**
  580. * @brief 测试4:DMA发送测试
  581. */
  582. static void test_dma_transmit(struct _uart_device *uart_dev)
  583. {
  584. printf("\n--- Test 4: DMA Transmit Test ---\n");
  585. /* 检查是否支持DMA */
  586. if (!uart_dev->config->dma_enable || uart_dev->config->dma_tx_buff == NULL) {
  587. printf("DMA not enabled for this UART\n");
  588. print_test_result("DMA Transmit", false);
  589. return;
  590. }
  591. uint8_t tx_buffer[256];
  592. uint32_t test_len = 256;
  593. generate_test_data(tx_buffer, test_len, 0x30);
  594. tx_buffer[255] = 0;
  595. //printf("%s\r\n", tx_buffer);
  596. /* 通过DMA发送 */
  597. // uart_send_data(HPM_UART3, tx_buffer, 128);
  598. uint32_t sent = uart_dev->ops->write( tx_buffer, test_len);
  599. if (sent != test_len) {
  600. printf("DMA send failed: sent %d, expected %d\n", sent, test_len);
  601. print_test_result("DMA Transmit", false);
  602. return;
  603. }
  604. printf("DMA sent %d bytes\n", sent);
  605. printf("DMA transfer completed\n");
  606. print_test_result("DMA Transmit", true);
  607. }
  608. /**
  609. * @brief 测试5:压力测试 - 连续发送接收
  610. */
  611. static void test_stress_loopback(struct _uart_device *uart_dev)
  612. {
  613. printf("\n--- Test 5: Stress Test (Continuous Loopback) ---\n");
  614. uint8_t tx_buffer[32];
  615. uint8_t rx_buffer[32];
  616. uint32_t total_tests = TEST_LOOP_COUNT;
  617. uint32_t pass_tests = 0;
  618. for (uint32_t i = 0; i < total_tests; i++) {
  619. uint8_t pattern = (uint8_t)(0x10 + i);
  620. uint32_t test_len = 16 + (i % 16); /* 可变长度测试 */
  621. generate_test_data(tx_buffer, test_len, pattern);
  622. memset(rx_buffer, 0, test_len);
  623. /* 发送 */
  624. uint32_t sent = uart_dev->ops->write( tx_buffer, test_len);
  625. if (sent != test_len) {
  626. printf("Test %d: Send failed\n", i);
  627. continue;
  628. }
  629. /* 接收 */
  630. uint32_t total_received = 0;
  631. uint32_t timeout = 10000;
  632. while (total_received < test_len && timeout--) {
  633. uint32_t received = uart_dev->ops->read(
  634. &rx_buffer[total_received],
  635. test_len - total_received);
  636. if (received > 0) {
  637. total_received += received;
  638. }
  639. delay_ms(1);
  640. }
  641. if (total_received != test_len) {
  642. printf("Test %d: Received %d/%d bytes\n", i, total_received, test_len);
  643. continue;
  644. }
  645. /* 验证 */
  646. if (verify_test_data(rx_buffer, test_len, pattern)) {
  647. pass_tests++;
  648. } else {
  649. printf("Test %d: Data verification failed\n", i);
  650. }
  651. delay_ms(10); /* 测试间隔 */
  652. }
  653. printf("Stress test: %d/%d passed\n", pass_tests, total_tests);
  654. print_test_result("Stress Test", (pass_tests == total_tests));
  655. }
  656. /**
  657. * @brief 测试6:波特率准确性测试
  658. */
  659. static void test_baudrate_accuracy(struct _uart_device *uart_dev)
  660. {
  661. printf("\n--- Test 6: Baudrate Accuracy Test ---\n");
  662. /* 发送一串特定字符,在接收端验证 */
  663. const char *test_string = "Hello UART! 1234567890\r\n";
  664. uint32_t test_len = strlen(test_string);
  665. char rx_buffer[128];
  666. printf("Sending: %s", test_string);
  667. uint32_t sent = uart_dev->ops->write(test_string, test_len);
  668. if (sent != test_len) {
  669. print_test_result("Baudrate Accuracy", false);
  670. return;
  671. }
  672. /* 等待接收 */
  673. uint32_t total_received = 0;
  674. uint32_t timeout = 50000;
  675. while (total_received < test_len && timeout--) {
  676. uint32_t received = uart_dev->ops->read(
  677. &rx_buffer[total_received],
  678. test_len - total_received);
  679. if (received > 0) {
  680. total_received += received;
  681. }
  682. delay_ms(1);
  683. }
  684. if (total_received != test_len) {
  685. printf("Received %d/%d bytes\n", total_received, test_len);
  686. print_test_result("Baudrate Accuracy", false);
  687. return;
  688. }
  689. rx_buffer[total_received] = '\0';
  690. printf("Received: %s", rx_buffer);
  691. if (memcmp(test_string, rx_buffer, test_len) == 0) {
  692. print_test_result("Baudrate Accuracy", true);
  693. } else {
  694. printf("Data mismatch!\n");
  695. print_test_result("Baudrate Accuracy", false);
  696. }
  697. }
  698. /* ========== 主测试函数 ========== */
  699. /**
  700. * @brief UART测试主函数
  701. * @param test_mode 测试模式:
  702. * 0 - 完整测试(需要TX/RX短接)
  703. * 1 - 仅发送测试(不需要短接)
  704. */
  705. int uart_test_main(int test_mode)
  706. {
  707. struct _uart_device *uart_dev = NULL;
  708. printf("\n");
  709. printf("========================================\n");
  710. printf(" UART Driver Test Suite\n");
  711. printf("========================================\n");
  712. printf("Testing UART: %s\n", TEST_UART_NAME);
  713. printf("Baudrate: %d\n", TEST_BAUDRATE);
  714. printf("Test Mode: %s\n", test_mode == 0 ? "Full (Loopback)" : "Transmit Only");
  715. printf("========================================\n");
  716. /* 查找UART设备 */
  717. uart_dev = uart_find(TEST_UART_NAME);
  718. if (uart_dev == NULL) {
  719. printf("Error: UART device '%s' not found!\n", TEST_UART_NAME);
  720. return -1;
  721. }
  722. printf("UART device found\n");
  723. /* 重置测试计数器 */
  724. test_pass_count = 0;
  725. test_fail_count = 0;
  726. /* 执行测试 */
  727. test_uart_init(uart_dev);
  728. if (test_mode == 0) {
  729. /* 完整测试模式 - 需要TX/RX短接 */
  730. test_single_byte_loopback(uart_dev);
  731. test_multi_byte_loopback(uart_dev);
  732. test_stress_loopback(uart_dev);
  733. test_baudrate_accuracy(uart_dev);
  734. }
  735. /* DMA测试(无论是否回环都可以测试) */
  736. test_dma_transmit(uart_dev);
  737. /* 打印测试结果 */
  738. print_test_summary();
  739. return (test_fail_count == 0) ? 0 : -1;
  740. }
  741. /**
  742. * @brief 简单的打印测试(用于验证基本功能)
  743. */
  744. int uart_simple_print_test(void)
  745. {
  746. struct _uart_device *uart_dev = NULL;
  747. const char *message = "Hello from UART test!\r\n";
  748. uart_dev = uart_find(TEST_UART_NAME);
  749. if (uart_dev == NULL) {
  750. printf("UART device not found!\n");
  751. return -1;
  752. }
  753. /* 初始化UART */
  754. if (uart_dev->ops->init( TEST_BAUDRATE) != 0) {
  755. printf("UART init failed!\n");
  756. return -1;
  757. }
  758. printf("UART initialized, sending test message...\n");
  759. /* 发送测试消息 */
  760. uint32_t sent = uart_dev->ops->write(message, strlen(message));
  761. printf("Sent %d bytes: %s", sent, message);
  762. return 0;
  763. }
  764. #endif