2023-08-30 16:21:18 +08:00
|
|
|
/*
|
2024-09-03 11:16:08 +08:00
|
|
|
* Copyright (c) 2022-2024, Artinchip Technology Co., Ltd
|
2023-08-30 16:21:18 +08:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <rtthread.h>
|
|
|
|
|
#include <rtdevice.h>
|
|
|
|
|
#include <aic_core.h>
|
|
|
|
|
#include <aic_drv.h>
|
|
|
|
|
#include "aic_hal_uart.h"
|
|
|
|
|
#include "aic_drv_uart.h"
|
|
|
|
|
|
|
|
|
|
#ifndef AIC_CLK_UART0_FREQ
|
|
|
|
|
#define AIC_CLK_UART0_FREQ 48000000 /* default 48M*/
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_CLK_UART1_FREQ
|
|
|
|
|
#define AIC_CLK_UART1_FREQ 48000000 /* default 48M*/
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_CLK_UART2_FREQ
|
|
|
|
|
#define AIC_CLK_UART2_FREQ 48000000 /* default 48M*/
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_CLK_UART3_FREQ
|
|
|
|
|
#define AIC_CLK_UART3_FREQ 48000000 /* default 48M*/
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_CLK_UART4_FREQ
|
|
|
|
|
#define AIC_CLK_UART4_FREQ 48000000 /* default 48M*/
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_CLK_UART5_FREQ
|
|
|
|
|
#define AIC_CLK_UART5_FREQ 48000000 /* default 48M*/
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_CLK_UART6_FREQ
|
|
|
|
|
#define AIC_CLK_UART6_FREQ 48000000 /* default 48M*/
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_CLK_UART7_FREQ
|
|
|
|
|
#define AIC_CLK_UART7_FREQ 48000000 /* default 48M*/
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-04-03 16:40:57 +08:00
|
|
|
#ifndef AIC_UART0_CTS_NAME
|
|
|
|
|
#define AIC_UART0_CTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART1_CTS_NAME
|
|
|
|
|
#define AIC_UART1_CTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART2_CTS_NAME
|
|
|
|
|
#define AIC_UART2_CTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART3_CTS_NAME
|
|
|
|
|
#define AIC_UART3_CTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART4_CTS_NAME
|
|
|
|
|
#define AIC_UART4_CTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART5_CTS_NAME
|
|
|
|
|
#define AIC_UART5_CTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART6_CTS_NAME
|
|
|
|
|
#define AIC_UART6_CTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART7_CTS_NAME
|
|
|
|
|
#define AIC_UART7_CTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef AIC_UART0_RTS_NAME
|
|
|
|
|
#define AIC_UART0_RTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART1_RTS_NAME
|
|
|
|
|
#define AIC_UART1_RTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART2_RTS_NAME
|
|
|
|
|
#define AIC_UART2_RTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART3_RTS_NAME
|
|
|
|
|
#define AIC_UART3_RTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART4_RTS_NAME
|
|
|
|
|
#define AIC_UART4_RTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART5_RTS_NAME
|
|
|
|
|
#define AIC_UART5_RTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART6_RTS_NAME
|
|
|
|
|
#define AIC_UART6_RTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef AIC_UART7_RTS_NAME
|
|
|
|
|
#define AIC_UART7_RTS_NAME "no_pin"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
struct aic_uart_rts_cts_dev
|
|
|
|
|
{
|
|
|
|
|
unsigned int uart_rts_pin;
|
|
|
|
|
unsigned int uart_cts_pin;
|
|
|
|
|
usart_handle_t handle;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct aic_uart_rts_cts_dev uart_rts_dev[AIC_UART_DEV_NUM];
|
|
|
|
|
struct aic_uart_rts_cts_dev uart_cts_dev[AIC_UART_DEV_NUM];
|
|
|
|
|
|
2023-08-30 16:21:18 +08:00
|
|
|
void drv_usart_irqhandler(int irq, void * data);
|
2024-09-03 11:16:08 +08:00
|
|
|
void drv_usart_set_freq(uint32_t baudrate, int u);
|
2024-04-03 16:40:57 +08:00
|
|
|
static rt_err_t drv_uart_control(struct rt_serial_device *serial, int cmd, void *arg);
|
2023-08-30 16:21:18 +08:00
|
|
|
|
|
|
|
|
struct
|
|
|
|
|
{
|
|
|
|
|
uint32_t base;
|
|
|
|
|
uint32_t irq;
|
|
|
|
|
void *handler;
|
|
|
|
|
}
|
|
|
|
|
const drv_usart_config[AIC_UART_DEV_NUM] =
|
|
|
|
|
{
|
|
|
|
|
#if (AIC_UART_DEV_NUM >= 4)
|
|
|
|
|
{UART0_BASE, UART0_IRQn, drv_usart_irqhandler},
|
|
|
|
|
{UART1_BASE, UART1_IRQn, drv_usart_irqhandler},
|
|
|
|
|
{UART2_BASE, UART2_IRQn, drv_usart_irqhandler},
|
|
|
|
|
{UART3_BASE, UART3_IRQn, drv_usart_irqhandler},
|
|
|
|
|
#endif
|
|
|
|
|
#if (AIC_UART_DEV_NUM >= 8)
|
|
|
|
|
{UART4_BASE, UART4_IRQn, drv_usart_irqhandler},
|
|
|
|
|
{UART5_BASE, UART5_IRQn, drv_usart_irqhandler},
|
|
|
|
|
{UART6_BASE, UART6_IRQn, drv_usart_irqhandler},
|
|
|
|
|
{UART7_BASE, UART7_IRQn, drv_usart_irqhandler},
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static usart_handle_t uart_handle[AIC_UART_DEV_NUM];
|
2024-04-03 16:40:57 +08:00
|
|
|
static struct rt_serial_device g_serial[AIC_UART_DEV_NUM];
|
2024-06-04 19:00:30 +08:00
|
|
|
|
|
|
|
|
#if defined (AIC_SERIAL_USING_DMA)
|
2024-04-03 16:40:57 +08:00
|
|
|
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;
|
2024-06-04 19:00:30 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
struct uart_freq_baud
|
|
|
|
|
{
|
|
|
|
|
uint32_t baud;
|
|
|
|
|
uint32_t freq;
|
|
|
|
|
}uart_freq_baud;
|
|
|
|
|
|
|
|
|
|
struct uart_freq_baud uart_freq_baud_list[] =
|
|
|
|
|
{
|
|
|
|
|
#if defined(AIC_CHIP_D13X) || defined(AIC_CHIP_D21X)
|
|
|
|
|
{300, 48000000},
|
|
|
|
|
{1200, 48000000},
|
|
|
|
|
{2400, 48000000},
|
|
|
|
|
{4800, 48000000},
|
|
|
|
|
{9600, 48000000},
|
|
|
|
|
{19200, 48000000},
|
|
|
|
|
{38400, 48000000},
|
|
|
|
|
{57600, 48000000},
|
|
|
|
|
{115200, 48000000},
|
|
|
|
|
{230400, 48000000},
|
|
|
|
|
{460800, 44444444},
|
|
|
|
|
{921600, 44444444},
|
|
|
|
|
{1000000, 48000000},
|
|
|
|
|
{1152000, 54545454},
|
|
|
|
|
{1500000, 48000000},
|
|
|
|
|
#elif defined(AIC_CHIP_D12X)
|
|
|
|
|
{300, 53454545},
|
|
|
|
|
{1200, 53454545},
|
|
|
|
|
{2400, 53454545},
|
|
|
|
|
{4800, 53454545},
|
|
|
|
|
{9600, 53454545},
|
|
|
|
|
{19200, 53454545},
|
|
|
|
|
{38400, 53454545},
|
|
|
|
|
{57600, 53454545},
|
|
|
|
|
{115200, 53454545},
|
|
|
|
|
{230400, 58800000},
|
|
|
|
|
{460800, 58800000},
|
|
|
|
|
{921600, 58800000},
|
|
|
|
|
{1000000, 49000000},
|
|
|
|
|
{1152000, 36750000},
|
|
|
|
|
{1500000, 49000000},
|
|
|
|
|
{2000000, 65333333},
|
|
|
|
|
#else
|
|
|
|
|
{0, 0},
|
|
|
|
|
#endif
|
|
|
|
|
};
|
2023-08-30 16:21:18 +08:00
|
|
|
|
|
|
|
|
int32_t drv_usart_target_init(int32_t idx, uint32_t *base, uint32_t *irq, void **handler)
|
|
|
|
|
{
|
|
|
|
|
if (idx >= AIC_UART_DEV_NUM)
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (base != NULL)
|
|
|
|
|
{
|
|
|
|
|
*base = drv_usart_config[idx].base;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (irq != NULL)
|
|
|
|
|
{
|
|
|
|
|
*irq = drv_usart_config[idx].irq;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (handler != NULL)
|
|
|
|
|
{
|
|
|
|
|
*handler = drv_usart_config[idx].handler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return idx;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-03 11:16:08 +08:00
|
|
|
void drv_usart_cb_event(int32_t index, usart_event_e event)
|
|
|
|
|
{
|
|
|
|
|
usart_handle_t uart;
|
|
|
|
|
RT_ASSERT(g_serial != RT_NULL);
|
|
|
|
|
uart = (usart_handle_t)g_serial[index].parent.user_data;
|
|
|
|
|
|
|
|
|
|
switch (event)
|
|
|
|
|
{
|
|
|
|
|
case USART_EVENT_RX_BREAK:
|
|
|
|
|
case USART_EVENT_RX_FRAMING_ERROR:
|
|
|
|
|
case USART_EVENT_RX_PARITY_ERROR:
|
|
|
|
|
hal_usart_clear_rxfifo(uart);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-03 16:40:57 +08:00
|
|
|
void drv_usart_irqhandler(int irq, void * data)
|
|
|
|
|
{
|
|
|
|
|
int index = irq - UART0_IRQn;
|
|
|
|
|
uint8_t status= 0;
|
2024-09-03 11:16:08 +08:00
|
|
|
usart_handle_t uart;
|
|
|
|
|
|
|
|
|
|
RT_ASSERT(g_serial != RT_NULL);
|
|
|
|
|
uart = (usart_handle_t)g_serial[index].parent.user_data;
|
2024-04-03 16:40:57 +08:00
|
|
|
|
|
|
|
|
if (index >= AIC_UART_DEV_NUM)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
status = hal_usart_get_irqstatus(index);
|
|
|
|
|
|
|
|
|
|
if (g_serial[index].config.flag == AIC_UART_DMA_FLAG) {
|
2024-06-04 19:00:30 +08:00
|
|
|
#if defined (AIC_SERIAL_USING_DMA)
|
2024-04-03 16:40:57 +08:00
|
|
|
|
|
|
|
|
RT_ASSERT(uart != RT_NULL);
|
2024-09-03 11:16:08 +08:00
|
|
|
hal_usart_set_interrupt(uart, USART_INTR_READ, 0);
|
|
|
|
|
|
2024-04-03 16:40:57 +08:00
|
|
|
switch (status)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-06-04 19:00:30 +08:00
|
|
|
#endif
|
2024-04-03 16:40:57 +08:00
|
|
|
} else {
|
|
|
|
|
switch (status)
|
|
|
|
|
{
|
|
|
|
|
case AIC_IIR_RECV_DATA:
|
|
|
|
|
case AIC_IIR_CHAR_TIMEOUT:
|
|
|
|
|
rt_hw_serial_isr(&g_serial[index], RT_SERIAL_EVENT_RX_IND);
|
|
|
|
|
break;
|
2024-09-03 11:16:08 +08:00
|
|
|
case AIC_IIR_RECV_LINE:
|
|
|
|
|
hal_usart_set_interrupt(uart, USART_INTR_READ, 0);
|
|
|
|
|
hal_usart_intr_recv_line(index, (aic_usart_priv_t *)g_serial[index].parent.user_data);
|
|
|
|
|
hal_usart_set_interrupt(uart, USART_INTR_READ, 1);
|
|
|
|
|
break;
|
2024-04-03 16:40:57 +08:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-30 16:21:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* UART interface
|
|
|
|
|
*/
|
|
|
|
|
static rt_err_t drv_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
usart_handle_t uart;
|
|
|
|
|
|
|
|
|
|
uint32_t bauds;
|
|
|
|
|
usart_mode_e mode;
|
|
|
|
|
usart_parity_e parity;
|
|
|
|
|
usart_stop_bits_e stopbits;
|
|
|
|
|
usart_data_bits_e databits;
|
|
|
|
|
|
|
|
|
|
RT_ASSERT(serial != RT_NULL);
|
|
|
|
|
uart = (usart_handle_t)serial->parent.user_data;
|
|
|
|
|
RT_ASSERT(uart != RT_NULL);
|
|
|
|
|
|
|
|
|
|
/* set baudrate parity...*/
|
|
|
|
|
bauds = cfg->baud_rate;
|
|
|
|
|
mode = USART_MODE_ASYNCHRONOUS;
|
|
|
|
|
|
|
|
|
|
if (cfg->parity == PARITY_EVEN)
|
|
|
|
|
parity = USART_PARITY_EVEN;
|
|
|
|
|
else if (cfg->parity == PARITY_ODD)
|
|
|
|
|
parity = USART_PARITY_ODD;
|
|
|
|
|
else
|
|
|
|
|
parity = USART_PARITY_NONE;
|
|
|
|
|
|
2024-04-03 16:40:57 +08:00
|
|
|
if (cfg->stop_bits == STOP_BITS_1)
|
2023-11-30 19:48:02 +08:00
|
|
|
stopbits = USART_STOP_BITS_1;
|
2024-04-03 16:40:57 +08:00
|
|
|
else if (cfg->stop_bits == STOP_BITS_2)
|
2023-11-30 19:48:02 +08:00
|
|
|
stopbits = USART_STOP_BITS_2;
|
2024-04-03 16:40:57 +08:00
|
|
|
else if (cfg->stop_bits == STOP_BITS_3)
|
2023-11-30 19:48:02 +08:00
|
|
|
stopbits = USART_STOP_BITS_1_5;
|
2023-08-30 16:21:18 +08:00
|
|
|
else
|
2023-11-30 19:48:02 +08:00
|
|
|
stopbits = USART_STOP_BITS_0_5;
|
2023-08-30 16:21:18 +08:00
|
|
|
|
|
|
|
|
if (cfg->data_bits == 5)
|
|
|
|
|
databits = USART_DATA_BITS_5;
|
|
|
|
|
else if (cfg->data_bits == 6)
|
|
|
|
|
databits = USART_DATA_BITS_6;
|
|
|
|
|
else if (cfg->data_bits == 7)
|
|
|
|
|
databits = USART_DATA_BITS_7;
|
|
|
|
|
else if (cfg->data_bits == 8)
|
|
|
|
|
databits = USART_DATA_BITS_8;
|
|
|
|
|
else if (cfg->data_bits == 9)
|
|
|
|
|
databits = USART_DATA_BITS_9;
|
|
|
|
|
else
|
|
|
|
|
databits = USART_DATA_BITS_8;
|
|
|
|
|
|
|
|
|
|
ret = hal_usart_config(uart, bauds, mode, parity, stopbits, databits, cfg->function);
|
|
|
|
|
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
{
|
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-03 16:40:57 +08:00
|
|
|
rt_err_t aic_uart_configure(u32 index, struct serial_configure *cfg)
|
|
|
|
|
{
|
|
|
|
|
if (index >= AIC_UART_DEV_NUM) {
|
|
|
|
|
pr_err("Invalid UART port NO. %d\n", index);
|
|
|
|
|
return RT_EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!cfg) {
|
|
|
|
|
pr_err("Invalid serial_configure\n");
|
|
|
|
|
return RT_EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return drv_uart_configure(&g_serial[index], cfg);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-30 16:21:18 +08:00
|
|
|
static rt_err_t drv_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
|
|
|
|
|
{
|
|
|
|
|
usart_handle_t uart;
|
2024-04-03 16:40:57 +08:00
|
|
|
aic_usart_priv_t *uart_data;
|
|
|
|
|
unsigned int group, pin;
|
2023-08-30 16:21:18 +08:00
|
|
|
|
2024-09-03 11:16:08 +08:00
|
|
|
|
2023-08-30 16:21:18 +08:00
|
|
|
RT_ASSERT(serial != RT_NULL);
|
|
|
|
|
uart = (usart_handle_t)serial->parent.user_data;
|
2024-04-03 16:40:57 +08:00
|
|
|
uart_data = serial->parent.user_data;
|
2023-08-30 16:21:18 +08:00
|
|
|
RT_ASSERT(uart != RT_NULL);
|
2024-04-03 16:40:57 +08:00
|
|
|
char off = AIC_UART_XOFF;
|
|
|
|
|
char on = AIC_UART_XON;
|
2023-08-30 16:21:18 +08:00
|
|
|
|
|
|
|
|
switch (cmd)
|
|
|
|
|
{
|
|
|
|
|
case RT_DEVICE_CTRL_CLR_INT:
|
|
|
|
|
/* Disable the UART Interrupt */
|
2024-01-27 08:47:24 +08:00
|
|
|
if ((uintptr_t)arg == RT_DEVICE_FLAG_INT_RX)
|
|
|
|
|
hal_usart_set_interrupt(uart, USART_INTR_READ, 0);
|
2023-08-30 16:21:18 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RT_DEVICE_CTRL_SET_INT:
|
|
|
|
|
/* Enable the UART Interrupt */
|
2024-01-27 08:47:24 +08:00
|
|
|
if ((uintptr_t)arg == RT_DEVICE_FLAG_INT_RX)
|
|
|
|
|
hal_usart_set_interrupt(uart, USART_INTR_READ, 1);
|
2023-08-30 16:21:18 +08:00
|
|
|
break;
|
2024-04-03 16:40:57 +08:00
|
|
|
|
|
|
|
|
case AIC_UART_485_CTL_SOFT_MODE0:
|
|
|
|
|
hal_usart_rts_ctl_soft_mode_clr(uart);
|
|
|
|
|
group = GPIO_GROUP(uart_rts_dev[uart_data->idx].uart_rts_pin);
|
|
|
|
|
pin = GPIO_GROUP_PIN(uart_rts_dev[uart_data->idx].uart_rts_pin);
|
|
|
|
|
hal_gpio_clr_output(group, pin);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AIC_UART_485_CTL_SOFT_MODE1:
|
|
|
|
|
hal_usart_rts_ctl_soft_mode_set(uart);
|
|
|
|
|
group = GPIO_GROUP(uart_rts_dev[uart_data->idx].uart_rts_pin);
|
|
|
|
|
pin = GPIO_GROUP_PIN(uart_rts_dev[uart_data->idx].uart_rts_pin);
|
|
|
|
|
hal_gpio_set_output(group, pin);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AIC_UART_232_RESUME_DATA:
|
|
|
|
|
if (serial->config.function == USART_MODE_RS232_UNAUTO_FLOW_CTRL ||
|
|
|
|
|
serial->config.function == USART_MODE_RS232_SW_HW_FLOW_CTRL) {
|
2024-06-04 19:00:30 +08:00
|
|
|
rt_pin_write(uart_rts_dev[uart_data->idx].uart_rts_pin, PIN_LOW);
|
2024-04-03 16:40:57 +08:00
|
|
|
}
|
|
|
|
|
if (serial->config.function == USART_MODE_RS232_SW_FLOW_CTRL ||
|
|
|
|
|
serial->config.function == USART_MODE_RS232_SW_HW_FLOW_CTRL) {
|
|
|
|
|
#ifdef RT_USING_DEVICE_OPS
|
|
|
|
|
serial->parent.ops->write(&serial->parent, 0, &on, 1);
|
|
|
|
|
#else
|
|
|
|
|
serial->parent.write(&serial->parent, 0, &on, 1);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AIC_UART_232_SUSPEND_DATA:
|
|
|
|
|
if (serial->config.function == USART_MODE_RS232_UNAUTO_FLOW_CTRL ||
|
|
|
|
|
serial->config.function == USART_MODE_RS232_SW_HW_FLOW_CTRL) {
|
2024-06-04 19:00:30 +08:00
|
|
|
rt_pin_write(uart_rts_dev[uart_data->idx].uart_rts_pin, PIN_HIGH);
|
2024-04-03 16:40:57 +08:00
|
|
|
}
|
|
|
|
|
if (serial->config.function == USART_MODE_RS232_SW_FLOW_CTRL ||
|
|
|
|
|
serial->config.function == USART_MODE_RS232_SW_HW_FLOW_CTRL) {
|
|
|
|
|
#ifdef RT_USING_DEVICE_OPS
|
|
|
|
|
serial->parent.ops->write(&serial->parent, 0, &off, 1);
|
|
|
|
|
#else
|
|
|
|
|
serial->parent.write(&serial->parent, 0, &off, 1);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
break;
|
2024-06-04 19:00:30 +08:00
|
|
|
|
|
|
|
|
case AIC_UART_SW_RECEIVE_ON_OFF:
|
|
|
|
|
if (*(char *)arg == AIC_UART_XOFF) {
|
|
|
|
|
hal_usart_halt_tx_enable(uart, HALT_TX_ENABLE);
|
|
|
|
|
} else if (*(char *)arg == AIC_UART_XON) {
|
|
|
|
|
hal_usart_halt_tx_enable(uart, HALT_TX_DISABLE);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2024-09-03 11:16:08 +08:00
|
|
|
|
|
|
|
|
case AIC_UART_SET_BAUDRATE:
|
|
|
|
|
hal_clk_disable(CLK_UART0 + serial->config.uart_index);
|
|
|
|
|
drv_usart_set_freq(*(uint32_t *)arg, serial->config.uart_index);
|
|
|
|
|
hal_clk_enable(CLK_UART0 + serial->config.uart_index);
|
|
|
|
|
aic_udelay(1000);
|
|
|
|
|
hal_usart_config_baudrate(uart, *(uint32_t *)arg);
|
|
|
|
|
break;
|
2023-08-30 16:21:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (RT_EOK);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int drv_uart_putc(struct rt_serial_device *serial, char c)
|
|
|
|
|
{
|
|
|
|
|
usart_handle_t uart;
|
|
|
|
|
|
|
|
|
|
RT_ASSERT(serial != RT_NULL);
|
|
|
|
|
uart = (usart_handle_t)serial->parent.user_data;
|
|
|
|
|
RT_ASSERT(uart != RT_NULL);
|
2024-09-03 11:16:08 +08:00
|
|
|
hal_usart_putchar(uart, c);
|
2023-08-30 16:21:18 +08:00
|
|
|
|
|
|
|
|
return (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int drv_uart_getc(struct rt_serial_device *serial)
|
|
|
|
|
{
|
|
|
|
|
int ch;
|
|
|
|
|
usart_handle_t uart;
|
|
|
|
|
|
|
|
|
|
RT_ASSERT(serial != RT_NULL);
|
|
|
|
|
uart = (usart_handle_t)serial->parent.user_data;
|
|
|
|
|
RT_ASSERT(uart != RT_NULL);
|
|
|
|
|
|
|
|
|
|
ch = hal_uart_getchar(uart);
|
|
|
|
|
|
|
|
|
|
return ch;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-04 19:00:30 +08:00
|
|
|
#if defined (AIC_SERIAL_USING_DMA)
|
2024-04-03 16:40:57 +08:00
|
|
|
#include <string.h>
|
|
|
|
|
static void drv_uart_callback(aic_usart_priv_t *uart, void *arg)
|
|
|
|
|
{
|
|
|
|
|
unsigned long event = (unsigned long)arg;
|
|
|
|
|
struct rt_serial_rx_fifo *rx_fifo;
|
|
|
|
|
|
|
|
|
|
switch(event)
|
|
|
|
|
{
|
|
|
|
|
case AIC_UART_TX_INT:
|
|
|
|
|
rt_hw_serial_isr(&g_serial[uart->idx], RT_SERIAL_EVENT_TX_DMADONE);
|
|
|
|
|
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);
|
|
|
|
|
} else {
|
|
|
|
|
memcpy((rx_fifo->buffer + rx_fifo->put_index), (rt_uint8_t *)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);
|
|
|
|
|
}
|
2024-09-03 11:16:08 +08:00
|
|
|
hal_usart_set_interrupt(uart, USART_INTR_READ, 1);
|
|
|
|
|
|
2024-04-03 16:40:57 +08:00
|
|
|
rt_hw_serial_isr(&g_serial[uart->idx], RT_SERIAL_EVENT_RX_DMADONE | (rx_size << 8));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
hal_log_err("not support event\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static rt_size_t drv_uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf,
|
|
|
|
|
rt_size_t size, int direction)
|
|
|
|
|
{
|
|
|
|
|
usart_handle_t uart;
|
|
|
|
|
|
|
|
|
|
RT_ASSERT(serial != RT_NULL);
|
|
|
|
|
uart = (usart_handle_t)serial->parent.user_data;
|
|
|
|
|
|
|
|
|
|
if (direction == RT_SERIAL_DMA_TX) {
|
|
|
|
|
memcpy((rt_uint8_t *)uart_tx_fifo, buf, size);
|
|
|
|
|
|
2024-09-03 11:16:08 +08:00
|
|
|
if (hal_uart_send_by_dma(uart, (rt_uint8_t *)uart_tx_fifo, size) == 0) {
|
2024-04-03 16:40:57 +08:00
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-08-30 16:21:18 +08:00
|
|
|
const struct rt_uart_ops drv_uart_ops =
|
|
|
|
|
{
|
|
|
|
|
drv_uart_configure,
|
|
|
|
|
drv_uart_control,
|
|
|
|
|
drv_uart_putc,
|
|
|
|
|
drv_uart_getc,
|
2024-06-04 19:00:30 +08:00
|
|
|
#if defined (AIC_SERIAL_USING_DMA)
|
2024-04-03 16:40:57 +08:00
|
|
|
drv_uart_dma_transmit,
|
|
|
|
|
#endif
|
2023-08-30 16:21:18 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct drv_uart_dev_para
|
|
|
|
|
{
|
|
|
|
|
uint32_t index :4;
|
|
|
|
|
uint32_t data_bits :4;
|
|
|
|
|
uint32_t stop_bits :2;
|
|
|
|
|
uint32_t parity :2;
|
2024-04-03 16:40:57 +08:00
|
|
|
uint32_t flag;
|
2023-08-30 16:21:18 +08:00
|
|
|
uint32_t baud_rate;
|
|
|
|
|
uint32_t clk_freq;
|
|
|
|
|
uint32_t function;
|
|
|
|
|
char * name;
|
2024-04-03 16:40:57 +08:00
|
|
|
char * uart_rts_name;
|
|
|
|
|
char * uart_cts_name;
|
2023-08-30 16:21:18 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const struct drv_uart_dev_para uart_dev_paras[] =
|
|
|
|
|
{
|
|
|
|
|
#ifdef AIC_USING_UART0
|
2024-04-03 16:40:57 +08:00
|
|
|
{0, AIC_DEV_UART0_DATABITS, AIC_DEV_UART0_STOPBITS, AIC_DEV_UART0_PARITY, AIC_UART0_FLAG,
|
|
|
|
|
AIC_DEV_UART0_BAUDRATE, AIC_CLK_UART0_FREQ, AIC_DEV_UART0_MODE, "uart0", AIC_UART0_RTS_NAME, AIC_UART0_CTS_NAME},
|
2023-08-30 16:21:18 +08:00
|
|
|
#endif
|
|
|
|
|
#ifdef AIC_USING_UART1
|
2024-04-03 16:40:57 +08:00
|
|
|
{1, AIC_DEV_UART1_DATABITS, AIC_DEV_UART1_STOPBITS, AIC_DEV_UART1_PARITY, AIC_UART1_FLAG,
|
|
|
|
|
AIC_DEV_UART1_BAUDRATE, AIC_CLK_UART1_FREQ, AIC_DEV_UART1_MODE, "uart1", AIC_UART1_RTS_NAME, AIC_UART1_CTS_NAME},
|
2023-08-30 16:21:18 +08:00
|
|
|
#endif
|
|
|
|
|
#ifdef AIC_USING_UART2
|
2024-04-03 16:40:57 +08:00
|
|
|
{2, AIC_DEV_UART2_DATABITS, AIC_DEV_UART2_STOPBITS, AIC_DEV_UART2_PARITY, AIC_UART2_FLAG,
|
|
|
|
|
AIC_DEV_UART2_BAUDRATE, AIC_CLK_UART2_FREQ, AIC_DEV_UART2_MODE, "uart2", AIC_UART2_RTS_NAME, AIC_UART2_CTS_NAME},
|
2023-08-30 16:21:18 +08:00
|
|
|
#endif
|
|
|
|
|
#ifdef AIC_USING_UART3
|
2024-04-03 16:40:57 +08:00
|
|
|
{3, AIC_DEV_UART3_DATABITS, AIC_DEV_UART3_STOPBITS, AIC_DEV_UART3_PARITY, AIC_UART3_FLAG,
|
|
|
|
|
AIC_DEV_UART3_BAUDRATE, AIC_CLK_UART3_FREQ, AIC_DEV_UART3_MODE, "uart3", AIC_UART3_RTS_NAME, AIC_UART3_CTS_NAME},
|
2023-08-30 16:21:18 +08:00
|
|
|
#endif
|
|
|
|
|
#ifdef AIC_USING_UART4
|
2024-04-03 16:40:57 +08:00
|
|
|
{4, AIC_DEV_UART4_DATABITS, AIC_DEV_UART4_STOPBITS, AIC_DEV_UART4_PARITY, AIC_UART4_FLAG,
|
|
|
|
|
AIC_DEV_UART4_BAUDRATE, AIC_CLK_UART4_FREQ, AIC_DEV_UART4_MODE, "uart4", AIC_UART4_RTS_NAME, AIC_UART4_CTS_NAME},
|
2023-08-30 16:21:18 +08:00
|
|
|
#endif
|
|
|
|
|
#ifdef AIC_USING_UART5
|
2024-04-03 16:40:57 +08:00
|
|
|
{5, AIC_DEV_UART5_DATABITS, AIC_DEV_UART5_STOPBITS, AIC_DEV_UART5_PARITY, AIC_UART5_FLAG,
|
|
|
|
|
AIC_DEV_UART5_BAUDRATE, AIC_CLK_UART5_FREQ, AIC_DEV_UART5_MODE, "uart5", AIC_UART5_RTS_NAME, AIC_UART5_CTS_NAME},
|
2023-08-30 16:21:18 +08:00
|
|
|
#endif
|
|
|
|
|
#ifdef AIC_USING_UART6
|
2024-04-03 16:40:57 +08:00
|
|
|
{6, AIC_DEV_UART6_DATABITS, AIC_DEV_UART6_STOPBITS, AIC_DEV_UART6_PARITY, AIC_UART6_FLAG,
|
|
|
|
|
AIC_DEV_UART6_BAUDRATE, AIC_CLK_UART6_FREQ, AIC_DEV_UART6_MODE, "uart6", AIC_UART6_RTS_NAME, AIC_UART6_CTS_NAME},
|
2023-08-30 16:21:18 +08:00
|
|
|
#endif
|
|
|
|
|
#ifdef AIC_USING_UART7
|
2024-04-03 16:40:57 +08:00
|
|
|
{7, AIC_DEV_UART7_DATABITS, AIC_DEV_UART7_STOPBITS, AIC_DEV_UART7_PARITY, AIC_UART7_FLAG,
|
|
|
|
|
AIC_DEV_UART7_BAUDRATE, AIC_CLK_UART7_FREQ, AIC_DEV_UART7_MODE, "uart7", AIC_UART7_RTS_NAME, AIC_UART7_CTS_NAME},
|
2023-08-30 16:21:18 +08:00
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
2024-06-04 19:00:30 +08:00
|
|
|
static void uart_halt_tx_irq_handler(void *args)
|
2024-04-03 16:40:57 +08:00
|
|
|
{
|
|
|
|
|
usart_handle_t uart;
|
2024-06-04 19:00:30 +08:00
|
|
|
unsigned int pin, value = PIN_LOW;
|
2024-04-03 16:40:57 +08:00
|
|
|
struct rt_serial_device *serial = args;
|
|
|
|
|
|
|
|
|
|
uart = (usart_handle_t)serial->parent.user_data;
|
2024-06-04 19:00:30 +08:00
|
|
|
|
2024-09-03 11:16:08 +08:00
|
|
|
pin = rt_pin_get(uart_dev_paras[serial->config.uart_index].uart_cts_name);
|
2024-06-04 19:00:30 +08:00
|
|
|
value = rt_pin_read(pin);
|
2024-04-03 16:40:57 +08:00
|
|
|
|
|
|
|
|
if (value == PIN_HIGH) {
|
2024-06-04 19:00:30 +08:00
|
|
|
hal_usart_halt_tx_enable(uart, HALT_TX_ENABLE);
|
2024-04-03 16:40:57 +08:00
|
|
|
} else {
|
2024-06-04 19:00:30 +08:00
|
|
|
hal_usart_halt_tx_enable(uart, HALT_TX_DISABLE);
|
2024-04-03 16:40:57 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drv_usart_function_init(int i, int u)
|
|
|
|
|
{
|
2024-06-04 19:00:30 +08:00
|
|
|
if ((rt_strcmp(uart_dev_paras[i].uart_rts_name, "no_pin") != 0) &&
|
|
|
|
|
(uart_dev_paras[i].function == USART_FUNC_RS485_SIMULATION ||
|
2024-04-03 16:40:57 +08:00
|
|
|
uart_dev_paras[i].function == USART_MODE_RS232_UNAUTO_FLOW_CTRL ||
|
|
|
|
|
uart_dev_paras[i].function == USART_MODE_RS232_SW_HW_FLOW_CTRL)) {
|
|
|
|
|
|
2024-09-03 11:16:08 +08:00
|
|
|
uart_rts_dev[u].uart_rts_pin = rt_pin_get(uart_dev_paras[i].uart_rts_name);
|
2024-06-04 19:00:30 +08:00
|
|
|
rt_pin_mode(uart_rts_dev[u].uart_rts_pin, PIN_MODE_OUTPUT);
|
|
|
|
|
rt_pin_write(uart_rts_dev[u].uart_rts_pin, PIN_LOW);
|
|
|
|
|
g_serial[u].config.flowctrl_rts_enable = 1;
|
2024-04-03 16:40:57 +08:00
|
|
|
}
|
|
|
|
|
|
2024-06-04 19:00:30 +08:00
|
|
|
if ((rt_strcmp(uart_dev_paras[i].uart_cts_name, "no_pin") != 0) &&
|
2024-04-03 16:40:57 +08:00
|
|
|
(uart_dev_paras[i].function == USART_MODE_RS232_UNAUTO_FLOW_CTRL ||
|
|
|
|
|
uart_dev_paras[i].function == USART_MODE_RS232_SW_HW_FLOW_CTRL)) {
|
|
|
|
|
|
2024-09-03 11:16:08 +08:00
|
|
|
uart_cts_dev[u].uart_cts_pin = rt_pin_get(uart_dev_paras[i].uart_cts_name);
|
2024-06-04 19:00:30 +08:00
|
|
|
rt_pin_mode(uart_cts_dev[u].uart_cts_pin, PIN_MODE_INPUT);
|
|
|
|
|
rt_pin_attach_irq(uart_cts_dev[u].uart_cts_pin, PIN_IRQ_MODE_RISING_FALLING,
|
|
|
|
|
uart_halt_tx_irq_handler, &(g_serial[u]));
|
|
|
|
|
rt_pin_irq_enable(uart_cts_dev[u].uart_cts_pin, PIN_IRQ_ENABLE);
|
|
|
|
|
g_serial[u].config.flowctrl_cts_enable = 1;
|
|
|
|
|
}
|
2024-04-03 16:40:57 +08:00
|
|
|
|
2024-06-04 19:00:30 +08:00
|
|
|
if (uart_dev_paras[i].function == USART_MODE_RS232_SW_FLOW_CTRL) {
|
|
|
|
|
g_serial[u].config.flowctrl_cts_enable = 1;
|
|
|
|
|
g_serial[u].config.flowctrl_rts_enable = 1;
|
2024-04-03 16:40:57 +08:00
|
|
|
}
|
2024-06-04 19:00:30 +08:00
|
|
|
}
|
2024-04-03 16:40:57 +08:00
|
|
|
|
2024-09-03 11:16:08 +08:00
|
|
|
void drv_usart_set_freq(uint32_t baudrate, int u)
|
2024-06-04 19:00:30 +08:00
|
|
|
{
|
|
|
|
|
int uart_freq;
|
|
|
|
|
int config_num = sizeof(uart_freq_baud_list)/sizeof(uart_freq_baud);
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < config_num; x++) {
|
|
|
|
|
if (baudrate == uart_freq_baud_list[x].baud) {
|
|
|
|
|
uart_freq = uart_freq_baud_list[x].freq;
|
|
|
|
|
hal_clk_set_freq(CLK_UART0 + u, uart_freq);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-04-03 16:40:57 +08:00
|
|
|
}
|
2024-06-04 19:00:30 +08:00
|
|
|
/* Use the menuconfig freq when the baud dose not match in the list */
|
2024-09-03 11:16:08 +08:00
|
|
|
hal_clk_set_freq(CLK_UART0 + u, g_serial[u].config.uart_freq);
|
2024-04-03 16:40:57 +08:00
|
|
|
}
|
|
|
|
|
|
2023-08-30 16:21:18 +08:00
|
|
|
int drv_usart_init(void)
|
|
|
|
|
{
|
|
|
|
|
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
|
|
|
|
int u = 0;
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
2023-11-30 19:48:02 +08:00
|
|
|
for (i=0; i<sizeof(uart_dev_paras)/sizeof(struct drv_uart_dev_para); i++) {
|
2023-08-30 16:21:18 +08:00
|
|
|
u = uart_dev_paras[i].index;
|
2024-04-03 16:40:57 +08:00
|
|
|
g_serial[u].ops = & drv_uart_ops;
|
|
|
|
|
g_serial[u].config = config;
|
|
|
|
|
g_serial[u].config.bufsz = 2048;
|
|
|
|
|
g_serial[u].config.baud_rate = uart_dev_paras[i].baud_rate;
|
|
|
|
|
g_serial[u].config.data_bits = uart_dev_paras[i].data_bits;
|
|
|
|
|
g_serial[u].config.stop_bits = uart_dev_paras[i].stop_bits - 1;
|
|
|
|
|
g_serial[u].config.parity = uart_dev_paras[i].parity;
|
|
|
|
|
g_serial[u].config.function = uart_dev_paras[i].function;
|
|
|
|
|
g_serial[u].config.flag = uart_dev_paras[i].flag;
|
|
|
|
|
g_serial[u].config.uart_index = uart_dev_paras[i].index;
|
2024-09-03 11:16:08 +08:00
|
|
|
g_serial[u].config.uart_freq = uart_dev_paras[i].clk_freq;
|
2023-08-30 16:21:18 +08:00
|
|
|
|
2024-09-03 11:16:08 +08:00
|
|
|
drv_usart_set_freq(uart_dev_paras[i].baud_rate, u);
|
2023-08-30 16:21:18 +08:00
|
|
|
hal_clk_enable(CLK_UART0 + u);
|
|
|
|
|
hal_reset_assert(RESET_UART0 + u);
|
|
|
|
|
aic_udelay(10000);
|
|
|
|
|
hal_reset_deassert(RESET_UART0 + u);
|
2024-04-03 16:40:57 +08:00
|
|
|
|
2023-11-30 19:48:02 +08:00
|
|
|
#ifdef FINSH_POLL_MODE
|
|
|
|
|
uart_handle[u] = hal_usart_initialize(u, NULL, NULL);
|
|
|
|
|
#else
|
2024-09-03 11:16:08 +08:00
|
|
|
uart_handle[u] = hal_usart_initialize(u, drv_usart_cb_event, drv_usart_irqhandler);
|
2023-11-30 19:48:02 +08:00
|
|
|
#endif
|
2024-04-03 16:40:57 +08:00
|
|
|
rt_hw_serial_register(&g_serial[u],
|
2023-08-30 16:21:18 +08:00
|
|
|
uart_dev_paras[i].name,
|
2023-11-30 19:48:02 +08:00
|
|
|
#ifdef FINSH_POLL_MODE
|
|
|
|
|
RT_DEVICE_FLAG_RDWR,
|
|
|
|
|
#else
|
2024-04-03 16:40:57 +08:00
|
|
|
uart_dev_paras[i].flag,
|
2023-11-30 19:48:02 +08:00
|
|
|
#endif
|
2023-08-30 16:21:18 +08:00
|
|
|
uart_handle[u]);
|
2024-06-04 19:00:30 +08:00
|
|
|
#if defined (AIC_SERIAL_USING_DMA)
|
2024-04-03 16:40:57 +08:00
|
|
|
if (uart_dev_paras[i].flag == AIC_UART_DMA_FLAG) {
|
|
|
|
|
hal_uart_set_fifo((aic_usart_priv_t *)g_serial[u].parent.user_data);
|
|
|
|
|
hal_uart_attach_callback((aic_usart_priv_t *)g_serial[u].parent.user_data,
|
|
|
|
|
drv_uart_callback, NULL);
|
2024-09-03 11:16:08 +08:00
|
|
|
hal_usart_set_interrupt((aic_usart_priv_t *)g_serial[u].parent.user_data,
|
|
|
|
|
USART_INTR_READ, 1);
|
2024-04-03 16:40:57 +08:00
|
|
|
}
|
2024-06-04 19:00:30 +08:00
|
|
|
#endif
|
2024-04-03 16:40:57 +08:00
|
|
|
drv_usart_function_init(i, u);
|
2023-08-30 16:21:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
INIT_BOARD_EXPORT(drv_usart_init);
|