mcu_ab568x/app/platform/bsp/bsp_uart.c
2025-05-30 18:03:10 +08:00

439 lines
13 KiB
C

#include "include.h"
#define HSUART_DMA_BUF_LEN 64
static const int uart_gpio_map[] = {
0,
IO_PB3, IO_PA1, IO_PA3, IO_PE3, IO_PE5, IO_PE7, IO_PF5, IO_MAX_NUM,
IO_PB4, IO_PA0, IO_PA2, IO_PE2, IO_PE4, IO_PE6, IO_MAX_NUM, IO_MAX_NUM,
IO_PA1, IO_PA7, IO_PB1, IO_PB3, IO_PE0, IO_PE3, IO_PF5, IO_MAX_NUM,
IO_PA1, IO_PA7, IO_PB1, IO_PB3, IO_PE0, IO_PE3, IO_PF5, IO_MAX_NUM,
IO_MAX_NUM, IO_PA5, IO_PA7, IO_PB1, IO_PB7, IO_PE0, IO_PF0, IO_PF2,
IO_MAX_NUM, IO_PA4, IO_PA6, IO_PB0, IO_PB6, IO_PE1, IO_PF1, IO_PF3,
};
static uart_isr_rece_callback_t uart_isr_rece_callback[UART_MAX - 1] = {NULL};
#if HSUART_MODULE_EN
static uint32_t hsuart_dma_rx_buf[HSUART_DMA_BUF_LEN];
static uint32_t hsuart_dma_tx_buf[HSUART_DMA_BUF_LEN];
#endif
//UART中断处理
#if (UART0_MODULE_EN | UART1_MODULE_EN | HSUART_MODULE_EN)
AT(.com_text.uart)
void uart_isr(void)
{
uint32_t uart_read_data;
uint8_t uart_buf;
#if UART0_MODULE_EN //uart0_rx
if(UART0CON & BIT(9)) {
UART0CPND |= BIT(9);
uart_read_data = UART0DATA;
uart_buf = uart_read_data & 0xff;
if (uart_isr_rece_callback[UART0 - 1]) {
uart_isr_rece_callback[UART0 - 1]((uint8_t *)&uart_buf, sizeof(uart_buf));
}
}
#endif //UART0_MODULE_EN
#if UART1_MODULE_EN //uart1_rx
if(UART1CON & BIT(9)){
UART1CPND |= BIT(9);
uart_read_data = UART1DATA;
uart_buf = uart_read_data & 0xff;
if (uart_isr_rece_callback[UART1 - 1]) {
uart_isr_rece_callback[UART1 - 1]((uint8_t *)&uart_buf, sizeof(uart_buf));
}
}
#endif //HSUART_MODULE_EN
#if HSUART_MODULE_EN
if(HSUT0CON & BIT(12)) { //hsuart rx
HSUT0CPND = BIT(0);
HSUT0CPND = BIT(12);
if (uart_isr_rece_callback[HS_UART - 1]) {
uart_isr_rece_callback[HS_UART - 1]((uint8_t *)hsuart_dma_rx_buf, HSUT0FIFOCNT);
}
HSUT0FIFOCNT = 0;
HSUT0CPND = BIT(15);
HSUT0RXADR = DMA_ADR(&hsuart_dma_rx_buf);
HSUT0RXCNT = 4 * HSUART_DMA_BUF_LEN;
}
#endif //HSUART_MODULE_EN
}
#endif //(UART0_MODULE_EN | UART1_MODULE_EN | HSUART_MODULE_EN)
//获取uart_type
static uart_type bsp_uart_type_get(uart_pin pin)
{
if (UART_RTX_NONE == pin) {
return UART_NONE;
}
uint8_t uart_type_tmp = (pin - 1) / 16 + 1;
if (uart_type_tmp >= UART_MAX) {
return UART_NONE;
}
return uart_type_tmp;
}
//获取uart map
static uint8_t bsp_uart_map_value(uart_pin pin)
{
if (UART_RTX_NONE == pin) {
return 0;
}
uint8_t map_value = (pin - 1) % 8;
map_value += 1;
map_value &= 0x0f;
return map_value;
}
//串口初始化
bool bsp_uart_init(const uart_cfg_t *cfg, uint32_t baudrate, uart_isr_rece_callback_t rece_handle)
{
if(NULL == cfg) {
return false;
}
uint32_t baud_cfg;
gpio_t gpio_reg;
uart_type rx_uart_type = bsp_uart_type_get(cfg->rx);
uart_type tx_uart_type = bsp_uart_type_get(cfg->tx);
uart_type comm_uart_type = rx_uart_type | tx_uart_type;
uint8_t map_value = 0;
uint8_t reg_pos;
static bool use_oneline_mode = false;
if (UART_NONE == comm_uart_type) {
return false;
}
if (UART_NONE != rx_uart_type && tx_uart_type != rx_uart_type) {
return false;
}
if (UART_NONE == rx_uart_type) {
use_oneline_mode = true;
}
//RX
if (!use_oneline_mode) {
if(uart_gpio_map[cfg->rx] < IO_MAX_NUM) {
//IO init
bsp_gpio_cfg_init(&gpio_reg, uart_gpio_map[cfg->rx]);
gpio_reg.sfr[GPIOxFEN] |= BIT(gpio_reg.num);
gpio_reg.sfr[GPIOxDIR] |= BIT(gpio_reg.num);
gpio_reg.sfr[GPIOxDE] |= BIT(gpio_reg.num);
gpio_reg.sfr[GPIOxPU] |= BIT(gpio_reg.num);
map_value = bsp_uart_map_value(cfg->rx);
reg_pos = 8 + (rx_uart_type * 2 - 1) * 4;
FUNCMCON0 |= (0xf << reg_pos);
FUNCMCON0 |= (map_value << reg_pos);
} else {
//VUSB做串口
PWRCON0 |= BIT(30);
RTCCON &= ~BIT(20);
}
} else {
if (UART0 == comm_uart_type) {
map_value = bsp_uart_map_value(UART0_RX_NONE0);
} else if (UART1 == comm_uart_type) {
map_value = bsp_uart_map_value(UART1_RX_NONE);
} else if(HS_UART == comm_uart_type) {
map_value = bsp_uart_map_value(cfg->tx);
}
}
reg_pos = 8 + (comm_uart_type * 2 - 1) * 4;
FUNCMCON0 |= (0xf << reg_pos);
FUNCMCON0 |= (map_value << reg_pos);
//TX
if (UART_NONE != tx_uart_type) {
if(uart_gpio_map[cfg->tx] < IO_MAX_NUM) {
//IO init
bsp_gpio_cfg_init(&gpio_reg, uart_gpio_map[cfg->tx]);
gpio_reg.sfr[GPIOxFEN] |= BIT(gpio_reg.num);
gpio_reg.sfr[GPIOxDE] |= BIT(gpio_reg.num);
gpio_reg.sfr[GPIOxPU] |= BIT(gpio_reg.num);
if(!use_oneline_mode) {
gpio_reg.sfr[GPIOxDIR] &= ~BIT(gpio_reg.num);
} else {
gpio_reg.sfr[GPIOxDIR] |= BIT(gpio_reg.num);
}
//mapping uart
map_value = bsp_uart_map_value(cfg->tx);
u8 reg_pos = 8 + (tx_uart_type - 1) * 2 * 4;
FUNCMCON0 |= (0xf << reg_pos);
FUNCMCON0 |= (map_value << reg_pos);
} else {
//VUSB做串口
PWRCON0 |= BIT(30);
RTCCON &= ~BIT(20);
}
}
if (UART0 == comm_uart_type) {
CLKCON0 &= ~BIT(20); //uart_inc select xosc26m_clk
CLKCON0 |= BIT(21);
CLKGAT0 |= BIT(9); //enable uart0 clk
UART0CON = 0;
UART0CON |= BIT(5); //set baud
baud_cfg = (XOSC_CLK_HZ / baudrate) - 1; //baud_cfg=(串口时钟/波特率)-1; 四舍五入
UART0BAUD = (baud_cfg << 16) | baud_cfg;
UART0CON |= (BIT(0) | BIT(2) | BIT(7)); //使能uart,接收中断
if(use_oneline_mode) { //use oneline
UART0CON |= BIT(6);
}
} else if (UART1 == comm_uart_type) {
CLKCON0 &= ~BIT(22); //uart_inc select xosc26m_clk
CLKCON0 |= BIT(23);
CLKGAT0 |= BIT(20); //enable uart1 clk
UART1CON = 0;
UART1CON |= BIT(5); //set baud
baud_cfg = (XOSC_CLK_HZ / baudrate) - 1; //baud_cfg=(串口时钟/波特率)-1; 四舍五入
UART1BAUD = (baud_cfg << 16) | baud_cfg;
UART1CON |= (BIT(0) | BIT(2) | BIT(7)); //使能uart,接收中断
if(use_oneline_mode) { //use oneline
UART1CON |= BIT(6);
}
} else if (HS_UART == comm_uart_type) {
CLKGAT0 |= BIT(11); //enable hsuart clk
delay_us(10);
CLKCON0 &= ~(7 << 17); //uart_inc select xosc26m_clk
baud_cfg = ((XOSC_CLK_HZ + (baudrate / 2)) / baudrate) - 1; //set baudrate
HSUT0BAUD = (baud_cfg << 16) | baud_cfg;
HSUT0TMRCNT = 32;
HSUT0CON = (BIT(0) | BIT(1) | BIT(2) | BIT(4) | BIT(7) | BIT(10)); //enable hsuart dma
if(use_oneline_mode) {
HSUT0CON |= BIT(18);
}
HSUT0CPND = (BIT(0) | BIT(1) | BIT(12) | BIT(15));
#if HSUART_MODULE_EN
HSUT0RXADR = DMA_ADR(hsuart_dma_rx_buf);
HSUT0RXCNT = 4 * HSUART_DMA_BUF_LEN;
#endif
}
uart_isr_rece_callback[comm_uart_type - 1] = rece_handle; //数据接收回调
if(HS_UART == comm_uart_type) {
#if HSUART_MODULE_EN
register_isr(IRQ_HSUART_VECTOR, uart_isr); // 注册串口中断
#endif
PICPR &= ~BIT(IRQ_HSUART_VECTOR); //配置中断优先级
PICEN |= BIT(IRQ_HSUART_VECTOR);
} else {
#if (UART0_MODULE_EN | UART1_MODULE_EN)
register_isr(IRQ_UART_VECTOR, uart_isr); // 注册串口中断
#endif
PICPR &= ~BIT(IRQ_UART_VECTOR); //配置中断优先级
PICEN |= BIT(IRQ_UART_VECTOR);
}
return true;
}
//设置波特率
void bsp_uart_baudrate_set(const uart_cfg_t *cfg, uint32_t rate)
{
uint32_t baud_cfg;
uart_type rx_uart_type = bsp_uart_type_get(cfg->rx);
uart_type tx_uart_type = bsp_uart_type_get(cfg->tx);
uart_type comm_uart_type = rx_uart_type | tx_uart_type;
PICEN &= ~BIT(IRQ_UART_VECTOR);
if (UART0 == comm_uart_type) {
baud_cfg = (XOSC_CLK_HZ / rate) - 1; //baud_cfg=(串口时钟/波特率)-1; 四舍五入
UART0BAUD = (baud_cfg << 16) | baud_cfg;
} else if (UART1 == comm_uart_type) {
baud_cfg = (XOSC_CLK_HZ / rate) - 1;
UART1BAUD = (baud_cfg << 16) | baud_cfg;
} else if (HS_UART == comm_uart_type) {
baud_cfg = ((XOSC_CLK_HZ + (rate / 2)) / rate) - 1;
HSUT0BAUD = (baud_cfg << 16) | baud_cfg;
}
PICEN |= BIT(IRQ_UART_VECTOR);
}
//发送单字节
void bsp_uart_send_byte(const uart_cfg_t *cfg, char ch)
{
uart_type rx_uart_type = bsp_uart_type_get(cfg->rx);
uart_type tx_uart_type = bsp_uart_type_get(cfg->tx);
uart_type comm_uart_type = rx_uart_type | tx_uart_type;
if (UART0 == comm_uart_type) {
while(!(UART0CON & BIT(8)));
UART0DATA = ch;
} else if (UART1 == comm_uart_type) {
while(!(UART1CON & BIT(8)));
UART1DATA = ch;
}
}
//发送字符串
void bsp_uart_send_str(const uart_cfg_t *cfg, char *str)
{
uart_type rx_uart_type = bsp_uart_type_get(cfg->rx);
uart_type tx_uart_type = bsp_uart_type_get(cfg->tx);
uart_type comm_uart_type = rx_uart_type | tx_uart_type;
if (UART0 == comm_uart_type) {
while(*str) {
while(!(UART0CON & BIT(8)));
UART0DATA = *str;
str ++;
}
} else if(UART1 == comm_uart_type) {
while(*str) {
while(!(UART1CON & BIT(8)));
UART1DATA = *str;
str ++;
}
}
}
//hsuart 发送
#if HSUART_MODULE_EN
AT(.com_text.uart)
void hsuart_send(uint8_t *buf, uint16_t len)
{
if(len > (4 * HSUART_DMA_BUF_LEN)) {
len = 4 * HSUART_DMA_BUF_LEN;
}
HSUT0CPND = BIT(1);
HSUT0CPND = BIT(13);
memcpy(hsuart_dma_tx_buf, buf, len);
HSUT0TXADR = DMA_ADR(hsuart_dma_tx_buf);
HSUT0TXCNT = len;
}
#else
void hsuart_send(uint8_t *buf, uint16_t len)
{
}
#endif //HSUART_MODULE_EN
//example
#if UART_EXAMPLE_EN
//UART0_PRINTF_SEL == PRINTF_NONE
#define EXAMPLE_UART_NONE 0
#define EXAMPLE_UART_INIT 1
#define EXAMPLE_UART_RUN 2
static uint8_t example_uart_status = EXAMPLE_UART_NONE;
static uint8_t example_uart0_rec_buf = 0xff;
static uint16_t example_hsuart_rec_len;
static uint8_t example_hsuart_buf[256];
const uart_cfg_t uart0_cfg = { //UART0_PB单线模式
.rx = UART_NONE,
.tx = UART0_TX_PB3,
};
const uart_cfg_t hsuart_cfg = { //HSUART_PB单线模式
.rx = UART_NONE,
.tx = HSUART_TX_PB3,
};
AT(.com_text.uart)
void uart0_isr_rece_handle(uint8_t *buf, uint16_t len)
{
example_uart0_rec_buf = *buf;
}
static void bsp_uart_example_uart0_process(void)
{
static uint8_t seq_cnt = 0;
char send_data[10];
if(0xff != example_uart0_rec_buf) {
bsp_uart_send_byte(&uart0_cfg, seq_cnt + 48);
snprintf(send_data, sizeof(send_data), "rx:%c", example_uart0_rec_buf);
bsp_uart_send_str(&uart0_cfg, send_data);
example_uart0_rec_buf = 0xff;
seq_cnt ++;
if(seq_cnt >= 10) {
seq_cnt = 0;
}
}
}
AT(.com_text.uart)
void hsuart_isr_rece_handle(uint8_t *buf, uint16_t len)
{
memcpy(example_hsuart_buf,buf,len);
example_hsuart_rec_len = len;
}
static void bsp_uart_example_hsuart_process(void)
{
if(example_hsuart_rec_len) {
hsuart_send(example_hsuart_buf, example_hsuart_rec_len);
example_hsuart_rec_len = 0;
}
}
void bsp_uart_example_process(void)
{
if(EXAMPLE_UART_NONE == example_uart_status) {
//bsp_uart_init(&uart0_cfg, 115200, uart0_isr_rece_handle);
bsp_uart_init(&hsuart_cfg, 115200, hsuart_isr_rece_handle);
example_uart_status = EXAMPLE_UART_INIT;
} else if(EXAMPLE_UART_INIT == example_uart_status) {
example_uart_status = EXAMPLE_UART_RUN;
} else if(EXAMPLE_UART_RUN == example_uart_status) {
//bsp_uart_example_uart0_process();
bsp_uart_example_hsuart_process();
}
}
#endif //UART_EXAMPLE_EN