#include "board.h" #include "hard_hdma_int.h" #include "my_board.h" #include "hpm_clock_drv.h" #include "drv_usart.h" #include "rkfifo.h" #include "test.h" #include /* ========== 辅助函数:获取DMA完成标志指针 ========== */ static bool* _get_dma_done_flag(UART_Type *uart_base) { if (uart_base == HPM_UART1) { return &uart1_tx_dma_done; } else if (uart_base == HPM_UART2) { return &uart2_tx_dma_done; } else if (uart_base == HPM_UART3) { return &uart3_tx_dma_done; } else if (uart_base == HPM_UART4) { return &uart4_tx_dma_done; } else if (uart_base == HPM_UART5) { return &uart5_tx_dma_done; } else if (uart_base == HPM_UART6) { return &uart6_tx_dma_done; } return NULL; } /* ========== 时钟使能函数 ========== */ static void _uart_clock_enable(UART_Type *uart_base) { if (uart_base == HPM_UART0) { clock_set_source_divider(clock_uart0, clk_src_osc24m, 1); clock_add_to_group(clock_uart0, 0); } else if (uart_base == HPM_UART1) { clock_set_source_divider(clock_uart1, clk_src_osc24m, 1); clock_add_to_group(clock_uart1, 0); } else if (uart_base == HPM_UART2) { clock_set_source_divider(clock_uart2, clk_src_osc24m, 1); clock_add_to_group(clock_uart2, 0); } else if (uart_base == HPM_UART3) { clock_set_source_divider(clock_uart3, clk_src_osc24m, 1); clock_add_to_group(clock_uart3, 0); } else if (uart_base == HPM_UART4) { clock_set_source_divider(clock_uart4, clk_src_osc24m, 1); clock_add_to_group(clock_uart4, 0); } else if (uart_base == HPM_UART5) { clock_set_source_divider(clock_uart5, clk_src_osc24m, 1); clock_add_to_group(clock_uart5, 0); } else if (uart_base == HPM_UART6) { clock_set_source_divider(clock_uart6, clk_src_osc24m, 1); clock_add_to_group(clock_uart6, 0); } else if (uart_base == HPM_UART7) { clock_set_source_divider(clock_uart7, clk_src_osc24m, 1); clock_add_to_group(clock_uart7, 0); } } /* ========== DMA时钟使能 ========== */ static void _dma_clock_enable(DMA_Type *dma_base) { /* HDMA 时钟来源于系统总线时钟(AHB),已默认使能 */ // clock_add_to_group(clock_hdma, 0); } /* ========== GPIO配置 ========== */ static void _uart_gpio_config(UART_Type *uart_base) // 根据实际引脚配置 { if (uart_base == HPM_UART1) { HPM_IOC->PAD[IOC_PAD_PA02].FUNC_CTL = IOC_PA02_FUNC_CTL_UART1_TXD; HPM_IOC->PAD[IOC_PAD_PA01].FUNC_CTL = IOC_PA01_FUNC_CTL_UART1_RXD; } else if (uart_base == HPM_UART2) { HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_UART2_RXD; HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_UART2_TXD; } else if (uart_base == HPM_UART3) { HPM_IOC->PAD[IOC_PAD_PB24].FUNC_CTL = IOC_PB24_FUNC_CTL_UART3_RXD; HPM_IOC->PAD[IOC_PAD_PB25].FUNC_CTL = IOC_PB25_FUNC_CTL_UART3_TXD; } else if (uart_base == HPM_UART4) { HPM_IOC->PAD[IOC_PAD_PA09].FUNC_CTL = IOC_PA09_FUNC_CTL_UART4_RXD; HPM_IOC->PAD[IOC_PAD_PA04].FUNC_CTL = IOC_PA04_FUNC_CTL_UART4_TXD; } else if (uart_base == HPM_UART5) { HPM_IOC->PAD[IOC_PAD_PA08].FUNC_CTL = IOC_PA08_FUNC_CTL_UART5_TXD; HPM_IOC->PAD[IOC_PAD_PA07].FUNC_CTL = IOC_PA07_FUNC_CTL_UART5_RXD; } else if (uart_base == HPM_UART6) { HPM_IOC->PAD[IOC_PAD_PA05].FUNC_CTL = IOC_PA05_FUNC_CTL_UART6_RXD; HPM_IOC->PAD[IOC_PAD_PA06].FUNC_CTL = IOC_PA06_FUNC_CTL_UART6_TXD; } } /* ========== UART配置 ========== */ static int _uart_config(struct _uart_config *config, uint32_t baudrate) { uart_config_t uart_cfg; uint32_t uart_clock_freq = 0; /* 使能时钟 */ _uart_clock_enable(config->uart_base); /* 配置GPIO */ _uart_gpio_config(config->uart_base); /* 获取UART时钟频率 */ if (config->uart_base == HPM_UART1) { uart_clock_freq = clock_get_frequency(clock_uart1); } else if (config->uart_base == HPM_UART2) { uart_clock_freq = clock_get_frequency(clock_uart2); } else if (config->uart_base == HPM_UART3) { uart_clock_freq = clock_get_frequency(clock_uart3); } else if (config->uart_base == HPM_UART4) { uart_clock_freq = clock_get_frequency(clock_uart4); } else if (config->uart_base == HPM_UART5) { uart_clock_freq = clock_get_frequency(clock_uart5); } else if (config->uart_base == HPM_UART6) { uart_clock_freq = clock_get_frequency(clock_uart6); } /* 配置UART */ uart_default_config(config->uart_base, &uart_cfg); uart_cfg.baudrate = baudrate; uart_cfg.word_length = word_length_8_bits; uart_cfg.num_of_stop_bits = stop_bits_1; uart_cfg.parity = parity_none; uart_cfg.fifo_enable = true; uart_cfg.dma_enable = config->dma_enable ? true : false; uart_cfg.tx_fifo_level = uart_tx_fifo_trg_not_full; uart_cfg.rx_fifo_level = uart_rx_fifo_trg_gt_three_quarters; uart_cfg.src_freq_in_hz = uart_clock_freq; uart_init(config->uart_base, &uart_cfg); return 0; } /* ========== DMA配置 ========== */ static int _uart_dma_config(struct _uart_config *config) { dma_handshake_config_t handshake_config; if (config->dma_tx_buff == NULL) { return -1; } /* 使能DMA时钟 */ _dma_clock_enable(config->dma_base); /* 配置 DMAMUX */ dmamux_config(config->dma_mux_base, DMA_SOC_CHN_TO_DMAMUX_CHN(config->dma_base, config->dma_channel), config->dma_request, true); /* 配置 TX 握手参数 */ dma_default_handshake_config(config->dma_base, &handshake_config); handshake_config.ch_index = config->dma_channel; handshake_config.dst = (uint32_t)&config->uart_base->THR; handshake_config.dst_fixed = true; handshake_config.src = core_local_mem_to_sys_address(0, (uint32_t)config->dma_tx_buff); handshake_config.src_fixed = false; handshake_config.data_width = DMA_TRANSFER_WIDTH_BYTE; handshake_config.size_in_byte = config->dma_tx_buff_size; hpm_stat_t stat = dma_setup_handshake(config->dma_base, &handshake_config, false); if (stat != status_success) { printf("uart dma tx config error\r\n"); return -1; } return 0; } /* ========== NVIC中断配置 ========== */ static void _uart_nvic_config(struct _uart_config *config) { /* 使能UART中断 */ uart_enable_irq(config->uart_base, config->uart_irq_mask); intc_m_enable_irq_with_priority(config->uart_irq_num, 1); /* 使能DMA中断 */ if (config->dma_enable) { intc_m_enable_irq_with_priority(config->dma_irq_num, 1); printf("DMA interrupt enabled for channel %d\n", config->dma_channel); } } /* ========== UART初始化 ========== */ int _uart_init(struct _uart_config *config, uint32_t baudrate) { /* 初始化FIFO */ rkfifo_init(&config->tx_fifo, config->tx_fifo_buff, config->tx_fifo_buff_size, 1); rkfifo_init(&config->rx_fifo, config->rx_fifo_buff, config->rx_fifo_buff_size, 1); /* 配置UART硬件 */ _uart_config(config, baudrate); /* 配置DMA */ if (config->dma_enable) { _uart_dma_config(config); } /* 配置中断 */ _uart_nvic_config(config); return 0; } uint8_t TX_BUFF[256]={'0','1','3'}; void open_usart_dma_tx(struct _uart_config *config, uint32_t len) { dma_handshake_config_t handshake_config; /* 重新配置 TX 传输大小 */ dma_default_handshake_config(config->dma_base, &handshake_config); handshake_config.ch_index = config->dma_channel; handshake_config.dst = (uint32_t)&(config->uart_base->THR); handshake_config.dst_fixed = true; handshake_config.src = core_local_mem_to_sys_address(0,(uint32_t)config->dma_tx_buff); handshake_config.src_fixed = false; handshake_config.data_width = DMA_TRANSFER_WIDTH_BYTE; handshake_config.size_in_byte = len; hpm_stat_t stat = dma_setup_handshake(config->dma_base, &handshake_config, true); if(stat != status_success) { printf("uart dma tx config error\r\n"); } } /* ========== UART发送数据(DMA方式) ========== */ static uint32_t uart_tx_data(struct _uart_config *config, const void *data, uint32_t len) { uint32_t ret = 0; if (len == 0) return 0; /* 将数据压入TX FIFO */ ret = rkfifo_in(&config->tx_fifo, data, len); if (config->dma_tx_buff != NULL && config->dma_enable) { uint32_t count = rkfifo_out(&config->tx_fifo, config->dma_tx_buff, config->dma_tx_buff_size); if (count > 0) { open_usart_dma_tx(config, count); } } return ret; } /* ========== UART接收数据(从fifo往外读) ========== */ static uint32_t uart_rx_data(struct _uart_config *config, void *data, uint32_t len) { return rkfifo_out(&config->rx_fifo, data, len); } /* ========== UART中断处理函数 ========== */ void uart_isr_callback(struct _uart_config *config) { uint8_t count = 0; rkfifo_t *rxfifo = &config->rx_fifo; uint8_t irq_id = uart_get_irq_id(config->uart_base); if (irq_id == uart_intr_id_rx_data_avail) { while (uart_check_status(config->uart_base, uart_stat_data_ready)) { uint8_t byte = uart_read_byte(config->uart_base); rkfifo_in(rxfifo, &byte, 1); count++; /* 确保RX FIFO不会溢出 */ if (count > 12) { break; } } } if (irq_id == uart_intr_id_rx_timeout) { /* 接收超时,读取剩余数据 */ while (uart_check_status(config->uart_base, uart_stat_data_ready)) { uint8_t byte = uart_read_byte(config->uart_base); rkfifo_in(rxfifo, &byte, 1); } } } /* ========== DMA发送完成中断处理 ========== */ void uart_tx_dma_isr_callback(struct _uart_config *config) { rkfifo_t *tx_fifo = &config->tx_fifo; uint8_t *dma_buff = config->dma_tx_buff; uint32_t dma_buff_size = config->dma_tx_buff_size; uint32_t count = rkfifo_out(tx_fifo, dma_buff, dma_buff_size); if (count > 0) { open_usart_dma_tx(config, count); } } /* ========== UART1 配置 ========== */ #ifdef DRV_USING_UART1 // ATTR_PLACE_AT_NONCACHEABLE这个一定不要忘记加 static ATTR_PLACE_AT_NONCACHEABLE uint8_t u1_rx_fifo_buff[UART1_RX_FIFO_BUFFER_LEN]; static ATTR_PLACE_AT_NONCACHEABLE uint8_t u1_tx_fifo_buff[UART1_TX_FIFO_BUFFER_LEN]; static ATTR_PLACE_AT_NONCACHEABLE uint8_t u1_dma_tx_buff[UART1_TX_DMA_BUFFER_LEN]; struct _uart_config _u1_config = { .uart_base = HPM_UART1, .uart_irq_mask = uart_intr_rx_data_avail_or_timeout, /* 添加中断掩码 */ .uart_irq_num = IRQn_UART1, /* DMA配置 */ .dma_base = HPM_HDMA, .dma_mux_base = HPM_DMAMUX, .dma_enable = 1, .dma_channel = 0, .dma_irq_num = IRQn_HDMA, .dma_request = HPM_DMA_SRC_UART1_TX, /* FIFO缓冲区 */ .tx_fifo_buff = u1_tx_fifo_buff, .tx_fifo_buff_size = sizeof(u1_tx_fifo_buff), .rx_fifo_buff = u1_rx_fifo_buff, .rx_fifo_buff_size = sizeof(u1_rx_fifo_buff), /* DMA缓冲区 */ .dma_tx_buff = u1_dma_tx_buff, .dma_tx_buff_size = sizeof(u1_dma_tx_buff), }; static uint32_t u1_write_data(const void *data, uint32_t len) { return uart_tx_data(&_u1_config, data, len); } static uint32_t u1_read_data( void *data, uint32_t len) { return uart_rx_data(&_u1_config, data, len); } static int u1_init(uint32_t baudrate) { return _uart_init(&_u1_config, baudrate); } static struct _uart_ops _u1_ops = { .init = u1_init, .read = u1_read_data, .write = u1_write_data, }; static struct _uart_device uart1 = { .config = &_u1_config, .ops = &_u1_ops, }; /* UART1中断处理函数 */ SDK_DECLARE_EXT_ISR_M(IRQn_UART1, uart1_isr) void uart1_isr(void) { uart_isr_callback(&_u1_config); } #endif #ifdef DRV_USING_UART4 // ATTR_PLACE_AT_NONCACHEABLE这个一定不要忘记加 static ATTR_PLACE_AT_NONCACHEABLE uint8_t u4_rx_fifo_buff[UART4_RX_FIFO_BUFFER_LEN]; static ATTR_PLACE_AT_NONCACHEABLE uint8_t u4_tx_fifo_buff[UART4_TX_FIFO_BUFFER_LEN]; static ATTR_PLACE_AT_NONCACHEABLE uint8_t u4_dma_tx_buff[UART4_TX_DMA_BUFFER_LEN]; struct _uart_config _u4_config = { .uart_base = HPM_UART4, .uart_irq_mask = uart_intr_rx_data_avail_or_timeout, /* 添加中断掩码 */ .uart_irq_num = IRQn_UART4, /* DMA配置 */ .dma_base = HPM_HDMA, .dma_mux_base = HPM_DMAMUX, .dma_enable = 1, .dma_channel = 0, .dma_irq_num = IRQn_HDMA, .dma_request = HPM_DMA_SRC_UART4_TX, /* FIFO缓冲区 */ .tx_fifo_buff = u4_tx_fifo_buff, .tx_fifo_buff_size = sizeof(u4_tx_fifo_buff), .rx_fifo_buff = u4_rx_fifo_buff, .rx_fifo_buff_size = sizeof(u4_rx_fifo_buff), /* DMA缓冲区 */ .dma_tx_buff = u4_dma_tx_buff, .dma_tx_buff_size = sizeof(u4_dma_tx_buff), }; static uint32_t u4_write_data(const void *data, uint32_t len) { return uart_tx_data(&_u4_config, data, len); } static uint32_t u4_read_data( void *data, uint32_t len) { return uart_rx_data(&_u4_config, data, len); } static int u4_init(uint32_t baudrate) { return _uart_init(&_u4_config, baudrate); } static struct _uart_ops _u4_ops = { .init = u4_init, .read = u4_read_data, .write = u4_write_data, }; static struct _uart_device uart4 = { .config = &_u4_config, .ops = &_u4_ops, }; /* UART4中断处理函数 */ SDK_DECLARE_EXT_ISR_M(IRQn_UART4, uart4_isr) void uart4_isr(void) { uart_isr_callback(&_u4_config); } #endif /* DRV_USING_UART4 */ /* ========== UART查找函数 ========== */ struct _uart_device *uart_find(const char *name) { struct _uart_device *uart = NULL; if (strncmp(name, "uart1", 5) == 0) { #ifdef DRV_USING_UART1 uart = &uart1; #endif } else if (strncmp(name, "uart2", 5) == 0) { #ifdef DRV_USING_UART2 uart = &uart2; #endif } else if (strncmp(name, "uart3", 5) == 0) { #ifdef DRV_USING_UART3 uart = &uart3; #endif } else if (strncmp(name, "uart4", 5) == 0) { #ifdef DRV_USING_UART4 uart = &uart4; #endif } else if (strncmp(name, "uart5", 5) == 0) { #ifdef DRV_USING_UART5 uart = &uart5; #endif } else if (strncmp(name, "uart6", 5) == 0) { #ifdef DRV_USING_UART6 uart = &uart6; #endif } return uart; } // 通用串口驱动测试例程 20260323 pass #ifdef UART_DRV_TEST /* uart_test.c * UART驱动测试例程 * 测试功能:发送测试、接收测试、回环测试、DMA传输测试 */ #include "board.h" #include "my_board.h" #include "drv_usart.h" #include #include /* ========== 测试配置 ========== */ #define TEST_UART_NAME "uart3" /* 测试的UART名称 */ #define TEST_BAUDRATE 115200 /* 波特率 */ #define TEST_BUFFER_SIZE 256 /* 测试缓冲区大小 */ #define TEST_LOOP_COUNT 10 /* 回环测试次数 */ /* 测试标志 */ static uint32_t test_pass_count = 0; static uint32_t test_fail_count = 0; /* ========== 辅助函数 ========== */ /** * @brief 打印测试结果 */ static void print_test_result(const char *test_name, bool passed) { if (passed) { printf("[PASS] %s\n", test_name); test_pass_count++; } else { printf("[FAIL] %s\n", test_name); test_fail_count++; } } /** * @brief 打印测试汇总 */ static void print_test_summary(void) { printf("\n========== Test Summary ==========\n"); printf("Total Tests: %d\n", test_pass_count + test_fail_count); printf("Passed: %d\n", test_pass_count); printf("Failed: %d\n", test_fail_count); printf("==================================\n"); if (test_fail_count == 0) { printf("All tests PASSED!\n"); } else { printf("Some tests FAILED!\n"); } } /** * @brief 延迟函数(毫秒) */ static void delay_ms(uint32_t ms) { board_delay_ms(ms); } /** * @brief 生成测试数据 */ static void generate_test_data(uint8_t *buffer, uint32_t len, uint8_t pattern) { for (uint32_t i = 0; i < len; i++) { buffer[i] = pattern+i; } } /** * @brief 验证数据是否正确 */ static bool verify_test_data(uint8_t *buffer, uint32_t len, uint8_t pattern) { for (uint32_t i = 0; i < len; i++) { if (buffer[i] != (pattern + i)) { printf("Data mismatch at pos %d: expected 0x%02X, got 0x%02X\n", i, pattern + i, buffer[i]); return false; } } return true; } /* ========== 测试用例 ========== */ /** * @brief 测试1:UART初始化 */ static void test_uart_init(struct _uart_device *uart_dev) { printf("\n--- Test 1: UART Init ---\n"); if (uart_dev == NULL) { printf("UART device not found!\n"); print_test_result("UART Init", false); return; } int ret = uart_dev->ops->init( TEST_BAUDRATE); if (ret == 0) { printf("UART initialized successfully at %d baud\n", TEST_BAUDRATE); print_test_result("UART Init", true); } else { printf("UART init failed with code: %d\n", ret); print_test_result("UART Init", false); } } /** * @brief 测试2:单字节发送和接收(回环测试) * 需要将TX和RX引脚短接 */ static void test_single_byte_loopback(struct _uart_device *uart_dev) { printf("\n--- Test 2: Single Byte Loopback ---\n"); printf("NOTE: Please short TX and RX pins for this test!\n"); delay_ms(100); /* 等待用户准备 */ uint8_t test_byte = 0x5A; uint8_t recv_byte = 0; uint32_t timeout = 10000; /* 发送数据 */ uint32_t sent = uart_dev->ops->write( &test_byte, 1); if (sent != 1) { printf("Failed to send byte\n"); print_test_result("Single Byte Loopback", false); return; } printf("Sent: 0x%02X\n", test_byte); /* 等待接收 */ while (timeout--) { uint32_t received = uart_dev->ops->read( &recv_byte, 1); if (received == 1) { break; } delay_ms(1); } if (timeout == 0) { printf("Timeout waiting for data\n"); print_test_result("Single Byte Loopback", false); return; } printf("Received: 0x%02X\n", recv_byte); if (test_byte == recv_byte) { print_test_result("Single Byte Loopback", true); } else { printf("Data mismatch!\n"); print_test_result("Single Byte Loopback", false); } } /** * @brief 测试3:多字节发送和接收(回环测试) */ static void test_multi_byte_loopback(struct _uart_device *uart_dev) { printf("\n--- Test 3: Multi-Byte Loopback ---\n"); uint8_t tx_buffer[64]; uint8_t rx_buffer[64]; uint32_t test_len = 64; /* 生成测试数据 */ generate_test_data(tx_buffer, test_len, 0x40); memset(rx_buffer, 0, test_len); /* 发送数据 */ uint32_t sent = uart_dev->ops->write( tx_buffer, test_len); if (sent != test_len) { printf("Failed to send data: sent %d, expected %d\n", sent, test_len); print_test_result("Multi-Byte Loopback", false); return; } printf("Sent %d bytes\n", sent); /* 等待接收完成 */ uint32_t total_received = 0; uint32_t timeout = 100000; while (total_received < test_len && timeout--) { uint32_t received = uart_dev->ops->read( &rx_buffer[total_received], test_len - total_received); if (received > 0) { total_received += received; } delay_ms(1); } if (timeout == 0) { printf("Timeout: received %d/%d bytes\n", total_received, test_len); print_test_result("Multi-Byte Loopback", false); return; } printf("Received %d bytes\n", total_received); /* 验证数据 */ if (verify_test_data(rx_buffer, test_len, 0x40)) { print_test_result("Multi-Byte Loopback", true); } else { print_test_result("Multi-Byte Loopback", false); } } /** * @brief 测试4:DMA发送测试 */ static void test_dma_transmit(struct _uart_device *uart_dev) { printf("\n--- Test 4: DMA Transmit Test ---\n"); /* 检查是否支持DMA */ if (!uart_dev->config->dma_enable || uart_dev->config->dma_tx_buff == NULL) { printf("DMA not enabled for this UART\n"); print_test_result("DMA Transmit", false); return; } uint8_t tx_buffer[256]; uint32_t test_len = 256; generate_test_data(tx_buffer, test_len, 0x30); tx_buffer[255] = 0; //printf("%s\r\n", tx_buffer); /* 通过DMA发送 */ // uart_send_data(HPM_UART3, tx_buffer, 128); uint32_t sent = uart_dev->ops->write( tx_buffer, test_len); if (sent != test_len) { printf("DMA send failed: sent %d, expected %d\n", sent, test_len); print_test_result("DMA Transmit", false); return; } printf("DMA sent %d bytes\n", sent); printf("DMA transfer completed\n"); print_test_result("DMA Transmit", true); } /** * @brief 测试5:压力测试 - 连续发送接收 */ static void test_stress_loopback(struct _uart_device *uart_dev) { printf("\n--- Test 5: Stress Test (Continuous Loopback) ---\n"); uint8_t tx_buffer[32]; uint8_t rx_buffer[32]; uint32_t total_tests = TEST_LOOP_COUNT; uint32_t pass_tests = 0; for (uint32_t i = 0; i < total_tests; i++) { uint8_t pattern = (uint8_t)(0x10 + i); uint32_t test_len = 16 + (i % 16); /* 可变长度测试 */ generate_test_data(tx_buffer, test_len, pattern); memset(rx_buffer, 0, test_len); /* 发送 */ uint32_t sent = uart_dev->ops->write( tx_buffer, test_len); if (sent != test_len) { printf("Test %d: Send failed\n", i); continue; } /* 接收 */ uint32_t total_received = 0; uint32_t timeout = 10000; while (total_received < test_len && timeout--) { uint32_t received = uart_dev->ops->read( &rx_buffer[total_received], test_len - total_received); if (received > 0) { total_received += received; } delay_ms(1); } if (total_received != test_len) { printf("Test %d: Received %d/%d bytes\n", i, total_received, test_len); continue; } /* 验证 */ if (verify_test_data(rx_buffer, test_len, pattern)) { pass_tests++; } else { printf("Test %d: Data verification failed\n", i); } delay_ms(10); /* 测试间隔 */ } printf("Stress test: %d/%d passed\n", pass_tests, total_tests); print_test_result("Stress Test", (pass_tests == total_tests)); } /** * @brief 测试6:波特率准确性测试 */ static void test_baudrate_accuracy(struct _uart_device *uart_dev) { printf("\n--- Test 6: Baudrate Accuracy Test ---\n"); /* 发送一串特定字符,在接收端验证 */ const char *test_string = "Hello UART! 1234567890\r\n"; uint32_t test_len = strlen(test_string); char rx_buffer[128]; printf("Sending: %s", test_string); uint32_t sent = uart_dev->ops->write(test_string, test_len); if (sent != test_len) { print_test_result("Baudrate Accuracy", false); return; } /* 等待接收 */ uint32_t total_received = 0; uint32_t timeout = 50000; while (total_received < test_len && timeout--) { uint32_t received = uart_dev->ops->read( &rx_buffer[total_received], test_len - total_received); if (received > 0) { total_received += received; } delay_ms(1); } if (total_received != test_len) { printf("Received %d/%d bytes\n", total_received, test_len); print_test_result("Baudrate Accuracy", false); return; } rx_buffer[total_received] = '\0'; printf("Received: %s", rx_buffer); if (memcmp(test_string, rx_buffer, test_len) == 0) { print_test_result("Baudrate Accuracy", true); } else { printf("Data mismatch!\n"); print_test_result("Baudrate Accuracy", false); } } /* ========== 主测试函数 ========== */ /** * @brief UART测试主函数 * @param test_mode 测试模式: * 0 - 完整测试(需要TX/RX短接) * 1 - 仅发送测试(不需要短接) */ int uart_test_main(int test_mode) { struct _uart_device *uart_dev = NULL; printf("\n"); printf("========================================\n"); printf(" UART Driver Test Suite\n"); printf("========================================\n"); printf("Testing UART: %s\n", TEST_UART_NAME); printf("Baudrate: %d\n", TEST_BAUDRATE); printf("Test Mode: %s\n", test_mode == 0 ? "Full (Loopback)" : "Transmit Only"); printf("========================================\n"); /* 查找UART设备 */ uart_dev = uart_find(TEST_UART_NAME); if (uart_dev == NULL) { printf("Error: UART device '%s' not found!\n", TEST_UART_NAME); return -1; } printf("UART device found\n"); /* 重置测试计数器 */ test_pass_count = 0; test_fail_count = 0; /* 执行测试 */ test_uart_init(uart_dev); if (test_mode == 0) { /* 完整测试模式 - 需要TX/RX短接 */ test_single_byte_loopback(uart_dev); test_multi_byte_loopback(uart_dev); test_stress_loopback(uart_dev); test_baudrate_accuracy(uart_dev); } /* DMA测试(无论是否回环都可以测试) */ test_dma_transmit(uart_dev); /* 打印测试结果 */ print_test_summary(); return (test_fail_count == 0) ? 0 : -1; } /** * @brief 简单的打印测试(用于验证基本功能) */ int uart_simple_print_test(void) { struct _uart_device *uart_dev = NULL; const char *message = "Hello from UART test!\r\n"; uart_dev = uart_find(TEST_UART_NAME); if (uart_dev == NULL) { printf("UART device not found!\n"); return -1; } /* 初始化UART */ if (uart_dev->ops->init( TEST_BAUDRATE) != 0) { printf("UART init failed!\n"); return -1; } printf("UART initialized, sending test message...\n"); /* 发送测试消息 */ uint32_t sent = uart_dev->ops->write(message, strlen(message)); printf("Sent %d bytes: %s", sent, message); return 0; } #endif