| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520 |
- #include "board.h"
- #include "hard_hdma_int.h"
- #include "hpm_uart_drv.h"
- #include "hpm_dmamux_drv.h"
- #include "hpm_dma_drv.h"
- #include "hpm_gpio_drv.h"
- #include "hpm_clock_drv.h"
- #include "rkfifo.h"
- #include <string.h>
- /* ========== 配置宏定义 ========== */
- #ifndef UART_RX_FIFO_BUFFER_LEN
- #define UART_RX_FIFO_BUFFER_LEN 256
- #endif
- #ifndef UART_TX_FIFO_BUFFER_LEN
- #define UART_TX_FIFO_BUFFER_LEN 256
- #endif
- #ifndef UART_TX_DMA_BUFFER_LEN
- #define UART_TX_DMA_BUFFER_LEN 1024
- #endif
- /* ========== 外部DMA完成标志声明 ========== */
- extern bool uart1_tx_dma_done;
- extern bool uart2_tx_dma_done;
- extern bool uart3_tx_dma_done;
- extern bool uart4_tx_dma_done;
- extern bool uart5_tx_dma_done;
- extern bool uart6_tx_dma_done;
- /* ========== 结构体定义 ========== */
- struct _uart_config {
- UART_Type *uart_base; /* UART基地址 */
- uart_intr_enable_t uart_irq_mask; /* UART中断掩码 */
- uint8_t uart_irq_num; /* 中断号 */
-
- /* GPIO配置 */
- uint8_t tx_port; /* TX端口: 0-9 (GPIOA-GPIOJ) */
- uint8_t tx_pin; /* TX引脚 */
- uint8_t rx_port; /* RX端口 */
- uint8_t rx_pin; /* RX引脚 */
- uint8_t tx_af; /* TX复用功能 */
- uint8_t rx_af; /* RX复用功能 */
-
- /* DMA配置 */
- DMA_Type *dma_base; /* DMA控制器基地址 */
- DMAMUX_Type *dma_mux_base; /* DMA MUX */
- uint8_t dma_enable; /* DMA 使能 (修正拼写) */
- uint8_t dma_channel; /* DMA通道 */
- uint8_t dma_irq_num; /* DMA中断号 */
- uint8_t dma_request; /* DMA请求源 */
-
- /* 缓冲区 */
- uint8_t *tx_fifo_buff; /* TX FIFO缓冲区 */
- uint32_t tx_fifo_buff_size; /* TX FIFO大小 */
- uint8_t *rx_fifo_buff; /* RX FIFO缓冲区 */
- uint32_t rx_fifo_buff_size; /* RX FIFO大小 */
-
- /* DMA缓冲区 */
- uint8_t *dma_tx_buff; /* DMA发送缓冲区 */
- uint32_t dma_tx_buff_size; /* DMA发送缓冲区大小 */
-
- /* 内部使用 */
- rkfifo_t tx_fifo; /* TX FIFO */
- rkfifo_t rx_fifo; /* RX FIFO */
- volatile uint8_t dma_busy; /* DMA发送忙标志 */
- };
- struct _uart_ops {
- int (*init)(struct _uart_config *config, uint32_t baudrate);
- uint32_t (*read)(struct _uart_config *config, void *data, uint32_t len);
- uint32_t (*write)(struct _uart_config *config, const void *data, uint32_t len);
- };
- struct _uart_device {
- struct _uart_config *config;
- struct _uart_ops *ops;
- };
- /* ========== 辅助函数:获取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),已默认使能 */
- (void)dma_base;
- }
- /* ========== 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_UART0) {
- uart_clock_freq = clock_get_frequency(clock_uart0);
- } else 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);
- } else if (config->uart_base == HPM_UART7) {
- uart_clock_freq = clock_get_frequency(clock_uart7);
- }
-
- /* 配置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);
- }
- }
- /* ========== 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);
-
- config->dma_busy = 0;
-
- return 0;
- }
- /**
- * @brief 获取串口发送是否忙碌
- */
- bool usart_tx_isbusy(struct _uart_config *config)
- {
- bool *dma_done_flag = _get_dma_done_flag(config->uart_base);
-
- if (dma_done_flag) {
- return !(*dma_done_flag);
- }
-
- return false;
- }
- void open_usart_dma_tx(struct _uart_config *config, uint32_t len)
- {
- dma_handshake_config_t handshake_config;
- bool *dma_done_flag = _get_dma_done_flag(config->uart_base);
-
- /* 等待上次发送完成 */
- uint32_t timeout = 1000000;
- while (usart_tx_isbusy(config) && timeout--) {
- __asm("nop");
- }
-
- if (timeout == 0) {
- /* 超时处理,复位DMA */
- dma_abort_channel(config->dma_base, config->dma_channel);
- if (dma_done_flag) {
- *dma_done_flag = true;
- }
- }
-
- /* 清除DMA完成标志 */
- if (dma_done_flag) {
- *dma_done_flag = false;
- }
-
- /* 重新配置 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;
-
- dma_setup_handshake(config->dma_base, &handshake_config, true);
- }
- /* ========== 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) {
- /* DMA方式发送 */
- if (!config->dma_busy) {
- /* DMA空闲,立即发送 */
- 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);
- config->dma_busy = 1;
- }
- }
- }
-
- 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)
- {
- bool *dma_done_flag = _get_dma_done_flag(config->uart_base);
-
- /* 设置DMA完成标志 */
- if (dma_done_flag) {
- *dma_done_flag = true;
- }
-
- config->dma_busy = 0;
-
- 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);
- config->dma_busy = 1;
- }
- }
- /* ========== UART1 配置 ========== */
- #ifdef DRV_USING_UART1
- static uint8_t u1_rx_fifo_buff[UART_RX_FIFO_BUFFER_LEN];
- static uint8_t u1_tx_fifo_buff[UART_TX_FIFO_BUFFER_LEN];
- static uint8_t u1_dma_tx_buff[UART_TX_DMA_BUFFER_LEN];
- struct _uart_config _u1_config = {
- .uart_base = HPM_UART1, /* 修正:应该是UART1 */
- .uart_irq_mask = uart_intr_rx_rdy | uart_intr_rx_timeout, /* 添加中断掩码 */
- .uart_irq_num = IRQn_UART1, /* 修正:IRQn_UART1 */
-
- /* DMA配置 */
- .dma_base = HPM_DMA0,
- .dma_mux_base = HPM_DMAMUX0,
- .dma_enable = 1, /* 修正拼写 */
- .dma_channel = 0,
- .dma_irq_num = IRQn_DMA0_CH0,
- .dma_request = DMA_REQUEST_UART1_TX, /* 修正: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中断处理函数 */
- void uart1_irq_handler(void)
- {
- uart_isr_callback(&_u1_config);
- }
- /* DMA0通道0中断处理函数 */
- void dma0_ch0_irq_handler(void)
- {
- uart_tx_dma_isr_callback(&_u1_config);
- }
- #endif /* DRV_USING_UART1 */
- /* ========== 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;
- }
|