From 3b8c04c94280800a0010ae268948efb7bccbe34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=8F=AF=E4=BA=AE?= Date: Tue, 10 Dec 2024 16:40:04 +0800 Subject: [PATCH] v1.1.1 --- bsp/artinchip/drv/uart/aic_drv_uart.c | 61 ++++++++++++++++++++------- bsp/artinchip/hal/uart/aic_hal_uart.c | 34 ++++++++------- 2 files changed, 63 insertions(+), 32 deletions(-) diff --git a/bsp/artinchip/drv/uart/aic_drv_uart.c b/bsp/artinchip/drv/uart/aic_drv_uart.c index 7eb958d7..f55542ac 100644 --- a/bsp/artinchip/drv/uart/aic_drv_uart.c +++ b/bsp/artinchip/drv/uart/aic_drv_uart.c @@ -126,9 +126,26 @@ static usart_handle_t uart_handle[AIC_UART_DEV_NUM]; static struct rt_serial_device g_serial[AIC_UART_DEV_NUM]; #if defined (AIC_SERIAL_USING_DMA) -static uint32_t uart_rx_fifo[AIC_UART_RX_FIFO_SIZE] __attribute__((aligned(64))); -static uint32_t uart_tx_fifo[AIC_UART_TX_FIFO_SIZE] __attribute__((aligned(64))); -static uint32_t rx_size = 0; +#define UART_ALIGN_SIZE CACHE_LINE_SIZE +struct aic_uart_info { + uint32_t *uart_tx_fifo; + uint32_t *uart_rx_fifo; + uint8_t rx_size; + rt_sem_t tx_semaphore; +}; +static struct aic_uart_info g_info[AIC_UART_DEV_NUM] = {0}; + +char uart_sem_name[][9] = { + "uart_tx0", + "uart_tx1", + "uart_tx2", + "uart_tx3", + "uart_tx4", + "uart_tx5", + "uart_tx6", + "uart_tx7", +}; + #endif struct uart_freq_baud @@ -245,9 +262,8 @@ void drv_usart_irqhandler(int irq, void * data) { case AIC_IIR_RECV_DATA: case AIC_IIR_CHAR_TIMEOUT: - rx_size = hal_usart_get_rx_fifo_num(uart); - // rt_kprintf("%d,%d\n",rx_size,status); - hal_uart_rx_dma_config(uart, (uint8_t *)uart_rx_fifo, rx_size); + g_info[index].rx_size = hal_usart_get_rx_fifo_num(uart); + hal_uart_rx_dma_config(uart, (uint8_t *)g_info[index].uart_rx_fifo, g_info[index].rx_size); break; default: @@ -478,21 +494,23 @@ static void drv_uart_callback(aic_usart_priv_t *uart, void *arg) { case AIC_UART_TX_INT: rt_hw_serial_isr(&g_serial[uart->idx], RT_SERIAL_EVENT_TX_DMADONE); + rt_sem_release(g_info[uart->idx].tx_semaphore); break; case AIC_UART_RX_INT: rx_fifo = (struct rt_serial_rx_fifo *)g_serial[uart->idx].serial_rx; - if (rx_fifo->put_index + rx_size < g_serial[uart->idx].config.bufsz) { - memcpy((rx_fifo->buffer + rx_fifo->put_index), (rt_uint8_t *)uart_rx_fifo, rx_size); + aicos_dcache_invalid_range((void *)g_info[uart->idx].uart_rx_fifo, AIC_UART_RX_FIFO_SIZE); + if (rx_fifo->put_index + g_info[uart->idx].rx_size < g_serial[uart->idx].config.bufsz) { + memcpy((rx_fifo->buffer + rx_fifo->put_index), (rt_uint8_t *)g_info[uart->idx].uart_rx_fifo, g_info[uart->idx].rx_size); } else { - memcpy((rx_fifo->buffer + rx_fifo->put_index), (rt_uint8_t *)uart_rx_fifo, + memcpy((rx_fifo->buffer + rx_fifo->put_index), (rt_uint8_t *)g_info[uart->idx].uart_rx_fifo, g_serial->config.bufsz - rx_fifo->put_index); - memcpy((rx_fifo->buffer), ((rt_uint8_t *)uart_rx_fifo + g_serial->config.bufsz - - rx_fifo->put_index), rx_size + rx_fifo->put_index - g_serial->config.bufsz); + memcpy((rx_fifo->buffer), ((rt_uint8_t *)g_info[uart->idx].uart_rx_fifo + g_serial->config.bufsz - + rx_fifo->put_index), g_info[uart->idx].rx_size + rx_fifo->put_index - g_serial->config.bufsz); } hal_usart_set_interrupt(uart, USART_INTR_READ, 1); - rt_hw_serial_isr(&g_serial[uart->idx], RT_SERIAL_EVENT_RX_DMADONE | (rx_size << 8)); + rt_hw_serial_isr(&g_serial[uart->idx], RT_SERIAL_EVENT_RX_DMADONE | (g_info[uart->idx].rx_size << 8)); break; default: @@ -505,14 +523,16 @@ static rt_size_t drv_uart_dma_transmit(struct rt_serial_device *serial, rt_uint8 rt_size_t size, int direction) { usart_handle_t uart; - + rt_uint8_t index; RT_ASSERT(serial != RT_NULL); uart = (usart_handle_t)serial->parent.user_data; + index = serial->config.uart_index; if (direction == RT_SERIAL_DMA_TX) { - memcpy((rt_uint8_t *)uart_tx_fifo, buf, size); - - if (hal_uart_send_by_dma(uart, (rt_uint8_t *)uart_tx_fifo, size) == 0) { + memcpy((rt_uint8_t *)g_info[index].uart_tx_fifo, buf, size); + aicos_dcache_clean_range((void *)g_info[index].uart_tx_fifo, AIC_UART_TX_FIFO_SIZE); + if (hal_uart_send_by_dma(uart, (rt_uint8_t *)g_info[index].uart_tx_fifo, size) == 0) { + rt_sem_take(g_info[index].tx_semaphore, RT_WAITING_FOREVER); return size; } } @@ -693,6 +713,15 @@ int drv_usart_init(void) drv_uart_callback, NULL); hal_usart_set_interrupt((aic_usart_priv_t *)g_serial[u].parent.user_data, USART_INTR_READ, 1); + + g_info[u].uart_rx_fifo = (uint32_t *)aicos_malloc_align(0, AIC_UART_RX_FIFO_SIZE, UART_ALIGN_SIZE); + g_info[u].uart_tx_fifo = (uint32_t *)aicos_malloc_align(0, AIC_UART_TX_FIFO_SIZE, UART_ALIGN_SIZE); + RT_ASSERT(g_info[u].uart_rx_fifo != RT_NULL); + RT_ASSERT(g_info[u].uart_tx_fifo != RT_NULL); + + g_info[u].tx_semaphore = rt_sem_create(uart_sem_name[u], 0, RT_IPC_FLAG_FIFO); + if (!g_info[u].tx_semaphore) + return -RT_ERROR; } #endif drv_usart_function_init(i, u); diff --git a/bsp/artinchip/hal/uart/aic_hal_uart.c b/bsp/artinchip/hal/uart/aic_hal_uart.c index 977a55ac..fe43e343 100644 --- a/bsp/artinchip/hal/uart/aic_hal_uart.c +++ b/bsp/artinchip/hal/uart/aic_hal_uart.c @@ -125,6 +125,7 @@ int32_t hal_usart_config_baudrate(usart_handle_t handle, uint32_t baud) USART_NULL_PARAM_CHK(handle); aic_usart_priv_t *usart_priv = handle; aic_usart_reg_t *addr = (aic_usart_reg_t *)(usart_priv->base); + uint32_t timecount = 0; /* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/ uint32_t divisor = ((hal_clk_get_freq(CLK_UART0 + usart_priv->idx) * 10) / baud) >> 4; @@ -135,6 +136,16 @@ int32_t hal_usart_config_baudrate(usart_handle_t handle, uint32_t baud) divisor = divisor / 10; } + addr->FCR = FCR_FIFO_EN | FCR_RX_FIFO_RST | FCR_TX_FIFO_RST; + while (addr->USR & USR_UART_BUSY) { + timecount++; + if (timecount >= UART_BUSY_TIMEOUT) + { + hal_log_info("Uart controller busy, waiting for timeout\n"); + return ERR_USART(DRV_ERROR_TIMEOUT); + } + }; + addr->HALT |= (HALT_CHCFG_AT_BUSY); addr->LCR |= LCR_SET_DLAB; @@ -325,30 +336,21 @@ static void hal_usart_get_dma_flag(void) #endif } -int32_t hal_usart_config_fifo(usart_handle_t handle, usart_func_e func) +int32_t hal_usart_config_fifo(usart_handle_t handle) { USART_NULL_PARAM_CHK(handle); aic_usart_priv_t *usart_priv = handle; aic_usart_reg_t *addr = (aic_usart_reg_t *)(usart_priv->base); - if (func == USART_MODE_RS232_AUTO_FLOW_CTRL || - func == USART_MODE_RS232_UNAUTO_FLOW_CTRL || - func == USART_MODE_RS232_SW_FLOW_CTRL || - func == USART_MODE_RS232_SW_HW_FLOW_CTRL) - { - addr->FCR = (FCR_FIFO_EN | FCR_RX_FIFO_RST | FCR_TX_FIFO_RST | FRC_RX_FIFO_SET(3)); - } - else - { - addr->FCR = (FCR_FIFO_EN | FCR_RX_FIFO_RST | FCR_TX_FIFO_RST); - } - hal_usart_get_dma_flag(); /* if use dma reconfigure the fcr reg */ if (dma_flag[usart_priv->idx].dma_enable == 1) { - addr->FCR = (FCR_TX_FIFO_RST | FCR_RX_FIFO_RST); - addr->FCR = (AIC_UART_DMA_MODE(1) | FRC_TX_FIFO_SET(3)| FRC_RX_FIFO_SET(2) | FCR_FIFO_EN); + addr->FCR = FCR_TX_FIFO_RST | FCR_RX_FIFO_RST; + addr->FCR = AIC_UART_DMA_MODE(1) | FRC_TX_FIFO_SET(3) | FRC_RX_FIFO_SET(2) | FCR_FIFO_EN; + } else { + addr->FCR = FCR_FIFO_EN | FCR_RX_FIFO_RST | FCR_TX_FIFO_RST | FRC_RX_FIFO_SET(3); } + return 0; } @@ -909,7 +911,7 @@ int32_t hal_usart_config(usart_handle_t handle, } /* control fifo */ - ret = hal_usart_config_fifo(handle, func); + ret = hal_usart_config_fifo(handle); if (ret < 0) {