打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

LiSun

打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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__

posted on 2022-09-09 09:30  xuejianqiang  阅读(56)  评论(0编辑  收藏  举报  来源
打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033