USART 简介
通用同步异步收发器(USART)是一种全双工或半双工,同步或异步的一个串行数据交换接口。USART 提
供了可编程的波特率发生器,能对系统时钟进行分频产生 USART 发送和接收所需的特定频率。
USART 支持标准的异步收发模式、红外编码规范、SIR、智能卡协议、LIN、同步单双工模式、多处理器通
信和 Modem 流控操作(CTS/RTS),为了实现高速数据通信还使用多缓冲器配置的 DMA 方式。
USART 主要特性
全双工异步通信
单线半双工通信
NRZ 标准格式(Mark/Space)
可编程的波特率发生器
发送和接收共用的可编程波特率,最高达 4.5MBits/s
可编程数据字长度(8 位或 9 位)
可配置的停止位-支持 1 或 2 个停止位
LIN 主机有发送断开符的能力以及 LIN 从机有检测断开符的能力
当 USART 硬件配置成 LIN 时,生成 13 位断开符;检测 10/11 位断开符
发送方为同步传输提供时钟
IrDA SIR 编码器解码器
在普通模式下支持 3/16 位的持续时间
ISO7816-3 标准里定义的异步智能卡协议
智能卡模式支持 0.5 或 1.5 个停止位
可配置的 DMA 多缓冲器通信
利用 DMA 缓冲接收/发送数据
单独的发送器和接收器使能位
检测标志
接收缓冲器满
发送缓冲器空
传输结束标志
校验控制
发送校验位
对接收数据进行校验
四个错误检测标志
溢出错误
噪音错误
帧错误
校验错误
10 个带标志的中断源。 CTS 改变
LIN 断开符检测
发送数据寄存器空
发送完成
接收数据寄存器满
检测到总线为空闲
溢出错误
帧错误
噪音错误
校验错误
多处理器通信 --如果地址不匹配,则进入静默模式
从静默模式中唤醒(通过空闲总线检测或地址检测)
两种唤醒接收器的方式:地址位(MSB,第 9 位),总线空闲
#include <stdio.h>
#include <string.h>
#include "n32g4fr.h"
#include "stdarg.h"
#include "bsp_uart.h"
#if BOOT
#define ENTER_CRITICAL()
#define EXIT_CRITICAL(VAL)
#else
#include "sys_cmsis.h"
#define ENTER_CRITICAL() sys_enter_critical();
#define EXIT_CRITICAL(VAL) sys_exit_critical(VAL);
#endif
/****************************BSP_UART0 for comm*******************************/
#define N32_USART0 USART1
#define N32_USART0_GPIO GPIOA
#define N32_USART0_CLK RCC_APB2_PERIPH_USART1
#define N32_USART0_GPIO_CLK RCC_APB2_PERIPH_GPIOA
#define N32_USART0_RxPin GPIO_PIN_10
#define N32_USART0_TxPin GPIO_PIN_9
#define N32_USART0_APBxClkCmd RCC_EnableAPB2PeriphClk
#define N32_USART0_DMAx DMA1
#define N32_USART0_DMAx_CLK RCC_AHB_PERIPH_DMA1
#define N32_USART0_DR_Base (USART1_BASE + 0x04)
#define N32_USART0_Tx_DMA_Channel DMA1_CH4
#define N32_USART0_Tx_DMA_FLAG DMA1_FLAG_TC4
#define N32_USART0_DMA_TX_IRQn DMA1_Channel4_IRQn
#define N32_USART0_IRQn USART1_IRQn
#define N32_USART0_Rx_DMA_Channel DMA1_CH5
#define N32_USART0_Rx_DMA_FLAG DMA1_INT_TXC5
#define N32_USART0_DMA_RX_IRQn DMA1_Channel5_IRQn
#define N32_UART0_BUF_SIZE 550
static uint8_t bsp_uart0_tx_buf[N32_UART0_BUF_SIZE];
static uint8_t bsp_uart0_rx_buf[N32_UART0_BUF_SIZE];
static bsp_uart_recv_cb_t bsp_uart_recv_cb = NULL;
/*************************BSP_UART1 for debug printf**************************/
#define N32_USART1 UART6
#define N32_USART1_GPIO GPIOB
#define N32_USART1_CLK RCC_APB2_PERIPH_UART6
#define N32_USART1_GPIO_CLK RCC_APB2_PERIPH_GPIOB
#define N32_USART1_RxPin GPIO_PIN_1
#define N32_USART1_TxPin GPIO_PIN_0
#define N32_USART1_APBxClkCmd RCC_EnableAPB2PeriphClk
#define N32_USART1_DMAx DMA2
#define N32_USART1_DMAx_CLK RCC_AHB_PERIPH_DMA2
#define N32_USART1_DR_Base (UART6_BASE + 0x04)
#define N32_USART1_Tx_DMA_Channel DMA2_CH2
#define N32_USART1_Tx_DMA_FLAG DMA2_FLAG_TC2
#define N32_USART1_DMA_TX_IRQn DMA2_Channel2_IRQn
#define N32_USART1_IRQn UART6_IRQn
#define N32_USART1_Rx_DMA_Channel DMA2_CH1
#define N32_USART1_Rx_DMA_FLAG DMA2_INT_TXC1
#define N32_USART1_DMA_RX_IRQn DMA2_Channel1_IRQn
#define N32_UART1_BUF_SIZE 550
static uint8_t bsp_uart1_tx_buf[N32_UART1_BUF_SIZE];
static uint8_t bsp_uart1_rx_buf[N32_UART1_BUF_SIZE];
static bsp_uart_recv_cb_t bsp_uart1_recv_cb = NULL;
/*************************BSP_UART2 for debug printf**************************/
#define N32_USART2 USART2
#define N32_USART2_GPIO GPIOB
#define N32_USART2_CLK RCC_APB1_PERIPH_USART2
#define N32_USART2_GPIO_CLK RCC_APB2_PERIPH_GPIOB
#define N32_USART2_RxPin GPIO_PIN_5
#define N32_USART2_TxPin GPIO_PIN_4
#define N32_USART2_APBxClkCmd RCC_EnableAPB1PeriphClk
#define N32_USART2_DMAx DMA1
#define N32_USART2_DMAx_CLK RCC_AHB_PERIPH_DMA1
#define N32_USART2_DR_Base (USART2_BASE + 0x04)
#define N32_USART2_Tx_DMA_Channel DMA1_CH7
#define N32_USART2_Tx_DMA_FLAG DMA1_FLAG_TC7
#define N32_USART2_DMA_TX_IRQn DMA1_Channel7_IRQn
#define N32_USART2_IRQn USART2_IRQn
#define N32_USART2_Rx_DMA_Channel DMA1_CH6
#define N32_USART2_Rx_DMA_FLAG DMA1_INT_TXC6
#define N32_USART2_DMA_RX_IRQn DMA1_Channel6_IRQn
#define N32_UART2_BUF_SIZE 550
static uint8_t bsp_uart2_tx_buf[N32_UART2_BUF_SIZE];
static uint8_t bsp_uart2_rx_buf[N32_UART2_BUF_SIZE];
static bsp_uart_recv_cb_t bsp_uart2_recv_cb = NULL;
/**
* @brief usart init
* @param null
* @retval null
*/
void bsp_uart_init(bsp_uart_t uart)
{
if (uart == BSP_UART0)
{
memset(bsp_uart0_tx_buf, 0, N32_UART0_BUF_SIZE);
memset(bsp_uart0_rx_buf, 0, N32_UART0_BUF_SIZE);
RCC_EnableAHBPeriphClk(N32_USART0_DMAx_CLK, ENABLE);
RCC_EnableAPB2PeriphClk(N32_USART0_GPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE);
N32_USART0_APBxClkCmd(N32_USART0_CLK, ENABLE);
GPIO_InitType GPIO_InitStructure;
#if !COMM_MODE_HALF_DUPLEX_USART0
GPIO_InitStructure.Pin = N32_USART0_RxPin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitPeripheral(N32_USART0_GPIO, &GPIO_InitStructure);
#endif
GPIO_InitStructure.Pin = N32_USART0_TxPin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitPeripheral(N32_USART0_GPIO, &GPIO_InitStructure);
USART_InitType USART_InitStructure;
USART_InitStructure.BaudRate = 115200;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
USART_Init(N32_USART0, &USART_InitStructure);
#if COMM_MODE_HALF_DUPLEX_USART0
USART_EnableHalfDuplex(N32_USART0, ENABLE);
#endif
NVIC_InitType NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = N32_USART0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#if COMM_MODE_HALF_DUPLEX_USART0
NVIC_InitStructure.NVIC_IRQChannel = N32_USART0_DMA_TX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
DMA_InitType DMA_InitStructure;
DMA_DeInit(N32_USART0_Tx_DMA_Channel);
DMA_InitStructure.PeriphAddr = N32_USART0_DR_Base;
DMA_InitStructure.MemAddr = (uint32_t)bsp_uart0_tx_buf;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;
DMA_InitStructure.BufSize = 0;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(N32_USART0_Tx_DMA_Channel, &DMA_InitStructure);
DMA_DeInit(N32_USART0_Rx_DMA_Channel);
DMA_InitStructure.PeriphAddr = N32_USART0_DR_Base;
DMA_InitStructure.MemAddr = (uint32_t)bsp_uart0_rx_buf;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = N32_UART0_BUF_SIZE;
DMA_Init(N32_USART0_Rx_DMA_Channel, &DMA_InitStructure);
USART_EnableDMA(N32_USART0, USART_DMAREQ_TX | USART_DMAREQ_RX, ENABLE);
USART_ClrFlag(N32_USART0, USART_INT_IDLEF);
USART_ConfigInt(N32_USART0, USART_INT_IDLEF, ENABLE);
#if COMM_MODE_HALF_DUPLEX_USART0
DMA_ClearFlag(N32_USART0_Tx_DMA_FLAG, N32_USART0_DMAx);
DMA_ConfigInt(N32_USART0_Tx_DMA_Channel, DMA_INT_TXC, ENABLE);
#endif
DMA_EnableChannel(N32_USART0_Tx_DMA_Channel, ENABLE);
DMA_EnableChannel(N32_USART0_Rx_DMA_Channel, ENABLE);
USART_Enable(N32_USART0, ENABLE);
}
else if (uart == BSP_UART1)
{
memset(bsp_uart1_tx_buf, 0, N32_UART1_BUF_SIZE);
memset(bsp_uart1_rx_buf, 0, N32_UART1_BUF_SIZE);
RCC_EnableAHBPeriphClk(N32_USART1_DMAx_CLK, ENABLE);
RCC_EnableAPB2PeriphClk(N32_USART1_GPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE);
N32_USART1_APBxClkCmd(N32_USART1_CLK, ENABLE);
GPIO_ConfigPinRemap(GPIO_RMP3_UART6, ENABLE);
GPIO_InitType GPIO_InitStructure;
#if !COMM_MODE_HALF_DUPLEX_USART1
GPIO_InitStructure.Pin = N32_USART1_RxPin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitPeripheral(N32_USART1_GPIO, &GPIO_InitStructure);
#endif
GPIO_InitStructure.Pin = N32_USART1_TxPin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitPeripheral(N32_USART1_GPIO, &GPIO_InitStructure);
USART_InitType USART_InitStructure;
USART_InitStructure.BaudRate = 230400;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
USART_Init(N32_USART1, &USART_InitStructure);
#if COMM_MODE_HALF_DUPLEX_USART1
USART_EnableHalfDuplex(N32_USART1, ENABLE);
#endif
NVIC_InitType NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = N32_USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#if COMM_MODE_HALF_DUPLEX_USART1
NVIC_InitStructure.NVIC_IRQChannel = N32_USART1_DMA_TX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
DMA_InitType DMA_InitStructure;
DMA_DeInit(N32_USART1_Tx_DMA_Channel);
DMA_InitStructure.PeriphAddr = N32_USART1_DR_Base;
DMA_InitStructure.MemAddr = (uint32_t)bsp_uart1_tx_buf;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;
DMA_InitStructure.BufSize = 0;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(N32_USART1_Tx_DMA_Channel, &DMA_InitStructure);
DMA_DeInit(N32_USART1_Rx_DMA_Channel);
DMA_InitStructure.PeriphAddr = N32_USART1_DR_Base;
DMA_InitStructure.MemAddr = (uint32_t)bsp_uart1_rx_buf;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = N32_UART1_BUF_SIZE;
DMA_Init(N32_USART1_Rx_DMA_Channel, &DMA_InitStructure);
USART_EnableDMA(N32_USART1, USART_DMAREQ_TX | USART_DMAREQ_RX, ENABLE);
USART_ClrFlag(N32_USART1, USART_INT_IDLEF);
USART_ConfigInt(N32_USART1, USART_INT_IDLEF, ENABLE);
#if COMM_MODE_HALF_DUPLEX_USART1
DMA_ClearFlag(N32_USART1_Tx_DMA_FLAG, N32_USART1_DMAx);
DMA_ConfigInt(N32_USART1_Tx_DMA_Channel, DMA_INT_TXC, ENABLE);
#endif
DMA_EnableChannel(N32_USART1_Tx_DMA_Channel, ENABLE);
DMA_EnableChannel(N32_USART1_Rx_DMA_Channel, ENABLE);
USART_Enable(N32_USART1, ENABLE);
}
else if (uart == BSP_UART2)
{
memset(bsp_uart2_tx_buf, 0, N32_UART2_BUF_SIZE);
memset(bsp_uart2_rx_buf, 0, N32_UART2_BUF_SIZE);
RCC_EnableAHBPeriphClk(N32_USART2_DMAx_CLK, ENABLE);
RCC_EnableAPB2PeriphClk(N32_USART2_GPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE);
N32_USART2_APBxClkCmd(N32_USART2_CLK, ENABLE);
GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_DISABLE, ENABLE);
GPIO_ConfigPinRemap(GPIO_RMP3_USART2, ENABLE);
GPIO_InitType GPIO_InitStructure;
#if !COMM_MODE_HALF_DUPLEX_USART2
GPIO_InitStructure.Pin = N32_USART2_RxPin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitPeripheral(N32_USART2_GPIO, &GPIO_InitStructure);
#endif
GPIO_InitStructure.Pin = N32_USART2_TxPin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitPeripheral(N32_USART2_GPIO, &GPIO_InitStructure);
USART_InitType USART_InitStructure;
USART_InitStructure.BaudRate = 230400;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
USART_Init(N32_USART2, &USART_InitStructure);
#if COMM_MODE_HALF_DUPLEX_USART2
USART_EnableHalfDuplex(N32_USART2, ENABLE);
#endif
NVIC_InitType NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = N32_USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#if COMM_MODE_HALF_DUPLEX_USART2
NVIC_InitStructure.NVIC_IRQChannel = N32_USART2_DMA_TX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
DMA_InitType DMA_InitStructure;
DMA_DeInit(N32_USART2_Tx_DMA_Channel);
DMA_InitStructure.PeriphAddr = N32_USART2_DR_Base;
DMA_InitStructure.MemAddr = (uint32_t)bsp_uart2_tx_buf;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;
DMA_InitStructure.BufSize = 0;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(N32_USART2_Tx_DMA_Channel, &DMA_InitStructure);
DMA_DeInit(N32_USART2_Rx_DMA_Channel);
DMA_InitStructure.PeriphAddr = N32_USART2_DR_Base;
DMA_InitStructure.MemAddr = (uint32_t)bsp_uart2_rx_buf;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = N32_UART2_BUF_SIZE;
DMA_Init(N32_USART2_Rx_DMA_Channel, &DMA_InitStructure);
USART_EnableDMA(N32_USART2, USART_DMAREQ_TX | USART_DMAREQ_RX, ENABLE);
USART_ClrFlag(N32_USART2, USART_INT_IDLEF);
USART_ConfigInt(N32_USART2, USART_INT_IDLEF, ENABLE);
#if COMM_MODE_HALF_DUPLEX_USART2
DMA_ClearFlag(N32_USART2_Tx_DMA_FLAG, N32_USART2_DMAx);
DMA_ConfigInt(N32_USART2_Tx_DMA_Channel, DMA_INT_TXC, ENABLE);
#endif
DMA_EnableChannel(N32_USART2_Tx_DMA_Channel, ENABLE);
DMA_EnableChannel(N32_USART2_Rx_DMA_Channel, ENABLE);
USART_Enable(N32_USART2, ENABLE);
}
}
/**
* @brief communication usart send data
* @param data
* @param len
* @retval 1:too more data
* 2:dma channel is busy
*/
uint32_t bsp_uart_transmit(bsp_uart_t uart, uint8_t* data, uint16_t len, uint32_t timeout)
{
uint32_t ret = 0;
if (uart == BSP_UART0)
{
//Wait for the last transfer to complete
while (USART_GetFlagStatus(N32_USART0, USART_FLAG_TXC) != SET)
{
if (timeout == 0)
{
break;
}
timeout--;
};
DMA_EnableChannel(N32_USART0_Tx_DMA_Channel, DISABLE);
if (0 == DMA_GetCurrDataCounter(N32_USART0_Tx_DMA_Channel))
{
if (len >= N32_UART0_BUF_SIZE)
{
ret = 1;
}
else
{
memcpy(bsp_uart0_tx_buf, data, len);
// trigger send
DMA_SetCurrDataCounter(N32_USART0_Tx_DMA_Channel, len);
}
}
else
{
ret = 2;
}
#if COMM_MODE_HALF_DUPLEX_USART0
USART_ClrFlag(N32_USART0, USART_INT_IDLEF);
USART_GetIntStatus(N32_USART0, USART_INT_IDLEF);
USART_ReceiveData(N32_USART0);
USART_ConfigInt(N32_USART0, USART_INT_IDLEF, DISABLE);
DMA_ClearFlag(N32_USART0_Tx_DMA_FLAG, N32_USART0_DMAx);
DMA_ClearFlag(N32_USART0_Rx_DMA_FLAG, N32_USART0_DMAx);
DMA_ConfigInt(N32_USART0_Tx_DMA_Channel, DMA_INT_TXC, ENABLE);
#endif
DMA_EnableChannel(N32_USART0_Tx_DMA_Channel, ENABLE);
}
else if (uart == BSP_UART1)
{
while (USART_GetFlagStatus(N32_USART1, USART_FLAG_TXC) != SET)
{
if (timeout == 0)
{
break;
}
timeout--;
}
DMA_EnableChannel(N32_USART1_Tx_DMA_Channel, DISABLE);
if (0 == DMA_GetCurrDataCounter(N32_USART1_Tx_DMA_Channel))
{
if (len >= N32_UART1_BUF_SIZE)
{
ret = 1;
}
else
{
memcpy(bsp_uart1_tx_buf, data, len);
// trigger send
DMA_SetCurrDataCounter(N32_USART1_Tx_DMA_Channel, len);
}
}
else
{
ret = 2;
}
#if COMM_MODE_HALF_DUPLEX_USART1
USART_ClrFlag(N32_USART1, USART_INT_IDLEF);
USART_GetIntStatus(N32_USART1, USART_INT_IDLEF);
USART_ReceiveData(N32_USART1);
USART_ConfigInt(N32_USART1, USART_INT_IDLEF, DISABLE);
DMA_ClearFlag(N32_USART1_Tx_DMA_FLAG, N32_USART1_DMAx);
DMA_ClearFlag(N32_USART1_Rx_DMA_FLAG, N32_USART1_DMAx);
DMA_ConfigInt(N32_USART1_Tx_DMA_Channel, DMA_INT_TXC, ENABLE);
#endif
DMA_EnableChannel(N32_USART1_Tx_DMA_Channel, ENABLE);
}
else if (uart == BSP_UART2)
{
while (USART_GetFlagStatus(N32_USART2, USART_FLAG_TXC) != SET)
{
if (timeout == 0)
{
break;
}
timeout--;
}
DMA_EnableChannel(N32_USART2_Tx_DMA_Channel, DISABLE);
if (0 == DMA_GetCurrDataCounter(N32_USART2_Tx_DMA_Channel))
{
if (len >= N32_UART2_BUF_SIZE)
{
ret = 1;
}
else
{
memcpy(bsp_uart2_tx_buf, data, len);
// trigger send
DMA_SetCurrDataCounter(N32_USART2_Tx_DMA_Channel, len);
}
}
else
{
ret = 2;
}
#if COMM_MODE_HALF_DUPLEX_USART2
USART_ClrFlag(N32_USART2, USART_INT_IDLEF);
USART_GetIntStatus(N32_USART2, USART_INT_IDLEF);
USART_ReceiveData(N32_USART2);
USART_ConfigInt(N32_USART2, USART_INT_IDLEF, DISABLE);
DMA_ClearFlag(N32_USART2_Tx_DMA_FLAG, N32_USART2_DMAx);
DMA_ClearFlag(N32_USART2_Rx_DMA_FLAG, N32_USART2_DMAx);
DMA_ConfigInt(N32_USART2_Tx_DMA_Channel, DMA_INT_TXC, ENABLE);
#endif
DMA_EnableChannel(N32_USART2_Tx_DMA_Channel, ENABLE);
}
return ret;
}
/**
* @brief
* @param
* @retval
*/
uint32_t bsp_uart_register_recv_callback(bsp_uart_t uart, bsp_uart_recv_cb_t cb)
{
if (uart == BSP_UART0)
{
if (bsp_uart_recv_cb != NULL)
{
return 1;
}
bsp_uart_recv_cb = cb;
}
else if (uart == BSP_UART1)
{
if (bsp_uart1_recv_cb != NULL)
{
return 1;
}
bsp_uart1_recv_cb = cb;
}
else if (uart == BSP_UART2)
{
if (bsp_uart2_recv_cb != NULL)
{
return 1;
}
bsp_uart2_recv_cb = cb;
}
return 0;
}
/**
* @brief
* @param
* @retval
*/
void bsp_uart_irq_handler(bsp_uart_t uart)
{
#if !BOOT
uint32_t temp;
temp = ENTER_CRITICAL();
#endif
if (uart == BSP_UART0)
{
if (USART_GetIntStatus(N32_USART0, USART_INT_IDLEF) != RESET)
{
//idle flag bit is read only in status register,read status register and read data register to clear
USART_ReceiveData(N32_USART0);
DMA_EnableChannel(N32_USART0_Rx_DMA_Channel, DISABLE);
uint16_t bsp_uart0_dma_rev_len = DMA_GetCurrDataCounter(N32_USART0_Rx_DMA_Channel);
(*bsp_uart_recv_cb)(uart, (uint8_t *)bsp_uart0_rx_buf, N32_UART0_BUF_SIZE - bsp_uart0_dma_rev_len);
DMA_SetCurrDataCounter(N32_USART0_Rx_DMA_Channel, N32_UART0_BUF_SIZE);
if (DMA_GetFlagStatus(N32_USART0_Rx_DMA_FLAG, N32_USART0_DMAx) != RESET)
{
DMA_ClearFlag(N32_USART0_Rx_DMA_FLAG, N32_USART0_DMAx);
}
DMA_EnableChannel(N32_USART0_Rx_DMA_Channel, ENABLE);
}
else if(USART_GetIntStatus(N32_USART0, USART_INT_OREF) != RESET)
{
USART_ReceiveData(N32_USART0);
}
else if(USART_GetIntStatus(N32_USART0, USART_INT_ERRF) != RESET)
{
USART_ReceiveData(N32_USART0);
}
else if(USART_GetIntStatus(N32_USART0, USART_INT_NEF) != RESET)
{
USART_ReceiveData(N32_USART0);
}
else if(USART_GetIntStatus(N32_USART0, USART_INT_FEF) != RESET)
{
USART_ReceiveData(N32_USART0);
}
else if(USART_GetIntStatus(N32_USART0, USART_INT_PEF) != RESET)
{
USART_ReceiveData(N32_USART0);
}
}
else if (uart == BSP_UART1)
{
if (USART_GetIntStatus(N32_USART1, USART_INT_IDLEF) != RESET)
{
USART_ReceiveData(N32_USART1);
DMA_EnableChannel(N32_USART1_Rx_DMA_Channel, DISABLE);
uint16_t bsp_uart1_dma_rev_len = DMA_GetCurrDataCounter(N32_USART1_Rx_DMA_Channel);
(*bsp_uart1_recv_cb)(uart, (uint8_t *)bsp_uart1_rx_buf, N32_UART1_BUF_SIZE - bsp_uart1_dma_rev_len);
DMA_SetCurrDataCounter(N32_USART1_Rx_DMA_Channel, N32_UART1_BUF_SIZE);
if (DMA_GetFlagStatus(N32_USART1_Rx_DMA_FLAG, N32_USART1_DMAx) != RESET)
{
DMA_ClearFlag(N32_USART1_Rx_DMA_FLAG, N32_USART1_DMAx);
}
DMA_EnableChannel(N32_USART1_Rx_DMA_Channel, ENABLE);
}
else if(USART_GetIntStatus(N32_USART1, USART_INT_OREF) != RESET)
{
USART_ReceiveData(N32_USART1);
}
else if(USART_GetIntStatus(N32_USART1, USART_INT_ERRF) != RESET)
{
USART_ReceiveData(N32_USART1);
}
else if(USART_GetIntStatus(N32_USART1, USART_INT_NEF) != RESET)
{
USART_ReceiveData(N32_USART1);
}
else if(USART_GetIntStatus(N32_USART1, USART_INT_FEF) != RESET)
{
USART_ReceiveData(N32_USART1);
}
else if(USART_GetIntStatus(N32_USART1, USART_INT_PEF) != RESET)
{
USART_ReceiveData(N32_USART1);
}
}
else if (uart == BSP_UART2)
{
if (USART_GetIntStatus(N32_USART2, USART_INT_IDLEF) != RESET)
{
USART_ReceiveData(N32_USART2);
DMA_EnableChannel(N32_USART2_Rx_DMA_Channel, DISABLE);
uint16_t bsp_uart2_dma_rev_len = DMA_GetCurrDataCounter(N32_USART2_Rx_DMA_Channel);
(*bsp_uart2_recv_cb)(uart, (uint8_t *)bsp_uart2_rx_buf, N32_UART2_BUF_SIZE - bsp_uart2_dma_rev_len);
DMA_SetCurrDataCounter(N32_USART2_Rx_DMA_Channel, N32_UART2_BUF_SIZE);
if (DMA_GetFlagStatus(N32_USART2_Rx_DMA_FLAG, N32_USART2_DMAx) != RESET)
{
DMA_ClearFlag(N32_USART2_Rx_DMA_FLAG, N32_USART2_DMAx);
}
DMA_EnableChannel(N32_USART2_Rx_DMA_Channel, ENABLE);
}
else if(USART_GetIntStatus(N32_USART2, USART_INT_OREF) != RESET)
{
USART_ReceiveData(N32_USART2);
}
else if(USART_GetIntStatus(N32_USART2, USART_INT_ERRF) != RESET)
{
USART_ReceiveData(N32_USART2);
}
else if(USART_GetIntStatus(N32_USART2, USART_INT_NEF) != RESET)
{
USART_ReceiveData(N32_USART2);
}
else if(USART_GetIntStatus(N32_USART2, USART_INT_FEF) != RESET)
{
USART_ReceiveData(N32_USART2);
}
else if(USART_GetIntStatus(N32_USART2, USART_INT_PEF) != RESET)
{
USART_ReceiveData(N32_USART2);
}
}
#if !BOOT
EXIT_CRITICAL(temp);
#endif
}
void bsp_uart_dma_tx_irq_handler(bsp_uart_t uart)
{
if (uart == BSP_UART0)
{
#if COMM_MODE_HALF_DUPLEX_USART0
if (DMA_GetIntStatus(N32_USART0_Tx_DMA_FLAG, N32_USART0_DMAx) != RESET)
{
DMA_ClearFlag(N32_USART0_Tx_DMA_FLAG, N32_USART0_DMAx);
DMA_ConfigInt(N32_USART0_Tx_DMA_Channel, DMA_INT_TXC, DISABLE);
DMA_SetCurrDataCounter(N32_USART0_Rx_DMA_Channel, N32_UART0_BUF_SIZE);
if (DMA_GetFlagStatus(N32_USART0_Rx_DMA_FLAG, N32_USART0_DMAx) != RESET)
{
DMA_ClearFlag(N32_USART0_Rx_DMA_FLAG, N32_USART0_DMAx);
}
memset(bsp_uart0_rx_buf, 0, N32_UART0_BUF_SIZE);
USART_ClrFlag(N32_USART0, USART_INT_IDLEF);
USART_GetIntStatus(N32_USART0, USART_INT_IDLEF);
USART_ReceiveData(N32_USART0);
USART_ConfigInt(N32_USART0, USART_INT_IDLEF, ENABLE);
}
#endif
}
else if (uart == BSP_UART1)
{
#if COMM_MODE_HALF_DUPLEX_USART1
if (DMA_GetIntStatus(N32_USART1_Tx_DMA_FLAG, N32_USART1_DMAx) != RESET)
{
DMA_ClearFlag(N32_USART1_Tx_DMA_FLAG, N32_USART1_DMAx);
DMA_ConfigInt(N32_USART1_Tx_DMA_Channel, DMA_INT_TXC, DISABLE);
DMA_SetCurrDataCounter(N32_USART1_Rx_DMA_Channel, N32_UART1_BUF_SIZE);
if (DMA_GetFlagStatus(N32_USART1_Rx_DMA_FLAG, N32_USART1_DMAx) != RESET)
{
DMA_ClearFlag(N32_USART1_Rx_DMA_FLAG, N32_USART1_DMAx);
}
memset(bsp_uart1_rx_buf, 0, N32_UART1_BUF_SIZE);
USART_ClrFlag(N32_USART1, USART_INT_IDLEF);
USART_GetIntStatus(N32_USART1, USART_INT_IDLEF);
USART_ReceiveData(N32_USART1);
USART_ConfigInt(N32_USART1, USART_INT_IDLEF, ENABLE);
}
#endif
}
else if (uart == BSP_UART2)
{
#if COMM_MODE_HALF_DUPLEX_USART2
if (DMA_GetIntStatus(N32_USART2_Tx_DMA_FLAG, N32_USART2_DMAx) != RESET)
{
DMA_ClearFlag(N32_USART2_Tx_DMA_FLAG, N32_USART2_DMAx);
DMA_ConfigInt(N32_USART2_Tx_DMA_Channel, DMA_INT_TXC, DISABLE);
DMA_SetCurrDataCounter(N32_USART2_Rx_DMA_Channel, N32_UART2_BUF_SIZE);
if (DMA_GetFlagStatus(N32_USART2_Rx_DMA_FLAG, N32_USART2_DMAx) != RESET)
{
DMA_ClearFlag(N32_USART2_Rx_DMA_FLAG, N32_USART2_DMAx);
}
memset(bsp_uart2_rx_buf, 0, N32_UART2_BUF_SIZE);
USART_ClrFlag(N32_USART2, USART_INT_IDLEF);
USART_GetIntStatus(N32_USART2, USART_INT_IDLEF);
USART_ReceiveData(N32_USART2);
USART_ConfigInt(N32_USART2, USART_INT_IDLEF, ENABLE);
}
#endif
}
}
#ifndef __BSP_UART_H__
#define __BSP_UART_H__
#include "typedefs.h"
typedef enum {
BSP_UART0,
BSP_UART1,
BSP_UART2,
} bsp_uart_t;
typedef void (*bsp_uart_recv_cb_t)(bsp_uart_t uart, uint8_t* data, uint16_t len);
void bsp_uart_init(bsp_uart_t uart);
uint32_t bsp_uart_transmit(bsp_uart_t uart, uint8_t* data, uint16_t len, uint32_t timeout);
uint32_t bsp_uart_register_recv_callback(bsp_uart_t uart, bsp_uart_recv_cb_t cb);
void bsp_uart_irq_handler(bsp_uart_t uart);
void bsp_uart_dma_tx_irq_handler(bsp_uart_t uart);
#endif // __BSP_USART_H__