This commit is contained in:
刘可亮
2024-12-10 16:40:04 +08:00
parent 791ea5b94b
commit 3b8c04c942
2 changed files with 63 additions and 32 deletions

View File

@@ -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);

View File

@@ -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)
{