bs_bcu_app/drv/drv_stm32f4xx/drv_uart.c

507 lines
16 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "drv_clk.h"
#include "drv_dma.h"
#include "drv_gpio.h"
#include "drv_uart.h"
#include "drv_misc.h"
#include "kit_debug.h"
#define USART_BRR_2400_AT_72M ((uint16_t)0x7530)
#define USART_BRR_2400_AT_36M ((uint16_t)0x3A98)
#define USART_BRR_2400_AT_84M ((uint16_t)0x88B8)
#define USART_BRR_2400_AT_42M ((uint16_t)0x445C)
#define USART_BRR_2400_AT_96M ((uint16_t)0x9C40)
#define USART_BRR_2400_AT_48M ((uint16_t)0x4E20)
#define USART_BRR_2400_AT_120M ((uint16_t)0xC350)
#define USART_BRR_2400_AT_60M ((uint16_t)0x61A8)
typedef struct
{
KitIrqCall call[kUartInterrupt_End];
uint16_t buf_len;
uint16_t send_pos;
uint8_t *send_buf;
}UartIntItem;
UartIntItem uart_int_item[kUartDev_End];
typedef struct
{
uint8_t irq;
DmaStream rx_dma_stream;
DmaStream tx_dma_stream;
DmaChannel dma_channel;
USART_TypeDef* reg;
uint32_t base_baudrate;
}STM32UsartProp;
static const STM32UsartProp stm32_uart[kUartDev_End] =
{
#ifdef GD32F450
{USART1_IRQn, kDma2Stream_2, kDma2Stream_7, kDmaChannel_4, USART1, USART_BRR_2400_AT_96M},
{USART2_IRQn, kDma1Stream_5, kDma1Stream_6, kDmaChannel_4, USART2, USART_BRR_2400_AT_48M},
{USART3_IRQn, kDma1Stream_1, kDma1Stream_3, kDmaChannel_4, USART3, USART_BRR_2400_AT_48M},
{UART4_IRQn, kDma1Stream_2, kDma1Stream_4, kDmaChannel_4, UART4, USART_BRR_2400_AT_48M},
{UART5_IRQn, kDma1Stream_0, kDma1Stream_7, kDmaChannel_5, UART5, USART_BRR_2400_AT_48M},
{USART6_IRQn, kDma2Stream_1, kDma2Stream_6, kDmaChannel_5, USART6, USART_BRR_2400_AT_96M},
{UART7_IRQn, kDma1Stream_3, kDma1Stream_1, kDmaChannel_5, UART7, USART_BRR_2400_AT_48M},
#elif GD32F470
{USART1_IRQn, kDma2Stream_2, kDma2Stream_7, kDmaChannel_4, USART1, USART_BRR_2400_AT_120M},
{USART2_IRQn, kDma1Stream_5, kDma1Stream_6, kDmaChannel_4, USART2, USART_BRR_2400_AT_60M},
{USART3_IRQn, kDma1Stream_1, kDma1Stream_3, kDmaChannel_4, USART3, USART_BRR_2400_AT_60M},
{UART4_IRQn, kDma1Stream_2, kDma1Stream_4, kDmaChannel_4, UART4, USART_BRR_2400_AT_60M},
{UART5_IRQn, kDma1Stream_0, kDma1Stream_7, kDmaChannel_5, UART5, USART_BRR_2400_AT_60M},
{USART6_IRQn, kDma2Stream_1, kDma2Stream_6, kDmaChannel_5, USART6, USART_BRR_2400_AT_120M},
{UART7_IRQn, kDma1Stream_3, kDma1Stream_1, kDmaChannel_5, UART7, USART_BRR_2400_AT_60M},
#else
{USART1_IRQn, kDma2Stream_2, kDma2Stream_7, kDmaChannel_4, USART1, USART_BRR_2400_AT_84M},
{USART2_IRQn, kDma1Stream_5, kDma1Stream_6, kDmaChannel_4, USART2, USART_BRR_2400_AT_42M},
{USART3_IRQn, kDma1Stream_1, kDma1Stream_3, kDmaChannel_4, USART3, USART_BRR_2400_AT_42M},
{UART4_IRQn, kDma1Stream_2, kDma1Stream_4, kDmaChannel_4, UART4, USART_BRR_2400_AT_42M},
{UART5_IRQn, kDma1Stream_0, kDma1Stream_7, kDmaChannel_5, UART5, USART_BRR_2400_AT_42M},
{USART6_IRQn, kDma2Stream_1, kDma2Stream_6, kDmaChannel_5, USART6, USART_BRR_2400_AT_84M},
#endif
};
#define UART_FLAG_TXE KIT_CREAT_BIT(7)
//在2400bps波特率下发送一个字节数据大约dly16000次
KitResult drv_uart_series_sync_send(UartDev dev, uint8_t *buf, uint16_t len)
{
uint32_t i = 0, dly;
USART_TypeDef *reg = stm32_uart[dev].reg;
while(i < len)
{
dly = 0;
while((reg->SR & UART_FLAG_TXE) != UART_FLAG_TXE)
{
if(dly++ > 20000)
{
return kKitResult_TimeOut;
}
}
reg->DR = buf[i++];
}
return kKitResult_Ok;
}
KitResult drv_uart_dma_async_send(UartDev dev, uint8_t *buf, uint16_t len)
{
KitResult res;
KIT_ASSERT_PARAM((dev < kUartDev_End) && (buf != NULL) && (len > 0));
if((dev < kUartDev_End) && (buf != NULL) && (len > 0))
{
stm32_uart[dev].reg->SR &= ~USART_SR_TC;
drv_dma_set_buf(stm32_uart[dev].tx_dma_stream, buf, len);
res = kKitResult_Ok;
}
else
{
res = kKitResult_ParamErr;
}
return res;
}
KitResult drv_uart_int_async_send(UartDev dev, uint8_t *buf, uint16_t len)
{
KitResult res;
KIT_ASSERT_PARAM((dev < kUartDev_End) && (buf != NULL) && (len > 0));
if((dev < kUartDev_End) && (buf != NULL) && (len > 0))
{
stm32_uart[dev].reg->SR &= ~USART_SR_TC;
uart_int_item[dev].buf_len = len;
uart_int_item[dev].send_pos = 1;
uart_int_item[dev].send_buf = buf;
stm32_uart[dev].reg->DR = buf[0];
stm32_uart[dev].reg->CR1 |= USART_CR1_TXEIE;
res = kKitResult_Ok;
}
else
{
res = kKitResult_ParamErr;
}
return res;
}
#define GPIO_REMAP_UART0 KIT_CREAT_BIT(2)
#define GPIO_REMAP_UART1 KIT_CREAT_BIT(3)
#define GPIO_PARTIAL_REMAP_UART2 KIT_CREAT_BIT(4)
#define GPIO_FULL_REMAP2_UART2 KIT_CREAT_BITS(4,5)
/********************************************************************************
Func UART0_REMAP = 0 UART0_REMAP = 1 | UART1_REMAP = 0 UART1_REMAP = 1 | UART2_REMAP = 0 UART2_REMAP = 1 UART1_REMAP = 2
UART_TX PA9 PB6 | PA2 PD5 | PB10 PC10 PD8
UART_RX PA10 PB7 | PA3 PD6 | PB11 PC11 PD9
********************************************************************************/
static KitResult drv_uart_set_clock_gpio(UartDev dev, uint16_t tx_idx, uint16_t rx_idx)
{
KitResult res = kKitResult_Ok;
uint32_t tx_io = drv_gpio_get_actual_io(tx_idx);
uint32_t rx_io = drv_gpio_get_actual_io(rx_idx);
switch (dev)
{
case kUartDev_1:
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
if((tx_io == GPIO_PORT_PIN(kGpioPort_A, 9)) && (rx_io == GPIO_PORT_PIN(kGpioPort_A, 10)))
{
drv_gpio_set_af(kGpioPort_A, 9, 7);
drv_gpio_set_af(kGpioPort_A, 10, 7);
}
else if((tx_io == GPIO_PORT_PIN(kGpioPort_B, 6)) && (rx_io == GPIO_PORT_PIN(kGpioPort_B, 7)))
{
drv_gpio_set_af(kGpioPort_B, 6, 7);
drv_gpio_set_af(kGpioPort_B, 7, 7);
}
else
{
res |= kKitResult_ParamErr;
}
break;
case kUartDev_2:
RCC->APB1ENR |= RCC_APB1Periph_USART2;
if((tx_io == GPIO_PORT_PIN(kGpioPort_A, 2)) && (rx_io == GPIO_PORT_PIN(kGpioPort_A, 3)))
{
drv_gpio_set_af(kGpioPort_A, 2, 7);
drv_gpio_set_af(kGpioPort_A, 3, 7);
}
else if((tx_io == GPIO_PORT_PIN(kGpioPort_D, 5)) && (rx_io == GPIO_PORT_PIN(kGpioPort_D, 6)))
{
drv_gpio_set_af(kGpioPort_D, 5, 7);
drv_gpio_set_af(kGpioPort_D, 6, 7);
}
else if((tx_io == GPIO_PORT_PIN(kGpioPort_D, 5)) && (rx_io == GPIO_PORT_PIN(kGpioPort_A, 3)))
{
drv_gpio_set_af(kGpioPort_D, 5, 7);
drv_gpio_set_af(kGpioPort_A, 3, 7);
}
else
{
res |= kKitResult_ParamErr;
}
break;
case kUartDev_3:
RCC->APB1ENR |= RCC_APB1Periph_USART3;
if((tx_io == GPIO_PORT_PIN(kGpioPort_B, 10)) && (rx_io == GPIO_PORT_PIN(kGpioPort_B, 11)))
{
drv_gpio_set_af(kGpioPort_B, 10, 7);
drv_gpio_set_af(kGpioPort_B, 11, 7);
}
else if((tx_io == GPIO_PORT_PIN(kGpioPort_C, 10)) && (rx_io == GPIO_PORT_PIN(kGpioPort_C, 11)))
{
drv_gpio_set_af(kGpioPort_C, 10, 7);
drv_gpio_set_af(kGpioPort_C, 11, 7);
}
else if((tx_io == GPIO_PORT_PIN(kGpioPort_D, 8)) && (rx_io == GPIO_PORT_PIN(kGpioPort_B, 11)))
{
drv_gpio_set_af(kGpioPort_D, 8, 7);
drv_gpio_set_af(kGpioPort_B, 11, 7);
}
else if((tx_io == GPIO_PORT_PIN(kGpioPort_B, 10)) && (rx_io == GPIO_PORT_PIN(kGpioPort_D, 9)))
{
drv_gpio_set_af(kGpioPort_B, 10, 7);
drv_gpio_set_af(kGpioPort_D, 9, 7);
}
else
{
res |= kKitResult_ParamErr;
}
break;
case kUartDev_4:
RCC->APB1ENR |= RCC_APB1Periph_UART4;
if((tx_io == GPIO_PORT_PIN(kGpioPort_A, 0)) && (rx_io == GPIO_PORT_PIN(kGpioPort_A, 1)))
{
drv_gpio_set_af(kGpioPort_A, 0, 8);
drv_gpio_set_af(kGpioPort_A, 1, 8);
}
else if((tx_io == GPIO_PORT_PIN(kGpioPort_C, 10)) && (rx_io == GPIO_PORT_PIN(kGpioPort_C, 11)))
{
drv_gpio_set_af(kGpioPort_C, 10, 8);
drv_gpio_set_af(kGpioPort_C, 11, 8);
}
else
{
res |= kKitResult_ParamErr;
}
break;
case kUartDev_5:
RCC->APB1ENR |= RCC_APB1Periph_UART5;
if((tx_io == GPIO_PORT_PIN(kGpioPort_C, 12)) && (rx_io == GPIO_PORT_PIN(kGpioPort_D, 2)))
{
drv_gpio_set_af(kGpioPort_C, 12, 8);
drv_gpio_set_af(kGpioPort_D, 2, 8);
}
else
{
res |= kKitResult_ParamErr;
}
break;
case kUartDev_6:
RCC->APB2ENR |= RCC_APB2ENR_USART6EN;
if((tx_io == GPIO_PORT_PIN(kGpioPort_C, 6)) && (rx_io == GPIO_PORT_PIN(kGpioPort_C, 7)))
{
drv_gpio_set_af(kGpioPort_C, 6, 8);
drv_gpio_set_af(kGpioPort_C, 7, 8);
}
else
{
res |= kKitResult_ParamErr;
}
break;
#if defined(STM32F429_439xx)
case kUartDev_7:
RCC->APB1ENR |= RCC_APB1ENR_UART7EN;
if((tx_io == GPIO_PORT_PIN(kGpioPort_F, 7)) && (rx_io == GPIO_PORT_PIN(kGpioPort_F, 6)))
{
drv_gpio_set_af(kGpioPort_F, 6, 8);
drv_gpio_set_af(kGpioPort_F, 7, 8);
}
else
{
res |= kKitResult_ParamErr;
}
break;
#endif
default:
res = kKitResult_ParamErr;
break;
}
return res;
}
#define USER_CR1_UE KIT_CREAT_BIT(13) //enable usart
#define USER_CR1_TXEIE KIT_CREAT_BIT(7)
#define USER_CR1_TCIE KIT_CREAT_BIT(6)
#define USER_CR1_RXNEIE KIT_CREAT_BIT(5)
#define USER_CR1_TXEIE KIT_CREAT_BIT(7)
#define USER_CR1_PCE_EN KIT_CREAT_BIT(10) //enable parity
#define USER_SR1_TXEIE KIT_CREAT_BIT(7)
#define USER_SR1_TCIE KIT_CREAT_BIT(6)
#define USER_SR1_RXNEIE KIT_CREAT_BIT(5)
#define USART_Mode_Rx KIT_CREAT_BIT(2)
#define USART_Mode_Tx KIT_CREAT_BIT(3)
#define USART_FLAG_ORE ((uint16_t)0x0008)
#define USART_FLAG_RXNE ((uint16_t)0x0020)
/*******************重要寄存器默认值*******************
*USART_CR1-M(12) 默认8个数据位
*USART_CR1-TXEIE(7) 默认关闭发送缓冲区空中断使能
*USART_CR1-TCIE(6) 默认关闭发送完成中断使能
*USART_CR1-RXNEIE(5) 默认关闭接收缓冲区非空中断使能
*波特率以2400为基数必须为2400整数倍
*开启奇偶校验长度必须为9Bit
********************************************************/
KitResult drv_uart_init(UartDev dev, uint32_t baudrate, uint32_t uart_config, uint8_t tx_io, uint8_t rx_io)
{
uint32_t tmp;
USART_TypeDef *reg;
KitResult res = kKitResult_Ok;
KIT_ASSERT_PARAM((dev < kUartDev_End) && ((baudrate % 2400) == 0));
if (((baudrate % 2400) == 0) && (dev < kUartDev_End))
{
reg = stm32_uart[dev].reg;
drv_uart_set_clock_gpio(dev, tx_io, rx_io);
//计算波特率基于2400
reg->BRR = stm32_uart[dev].base_baudrate / (baudrate / 2400);
//使能收、发和uart
tmp = USER_CR1_UE | USART_Mode_Rx | USART_Mode_Tx;
//设置数据长度
tmp |= (uart_config & 0x0001) << 12;
//设置校验
tmp |= ((uart_config & 0x0006) >> 1) << 9;
//停止位长度
reg->CR2 |= ((uart_config & 0x0018) >> 3) << 12;
reg->CR1 |= tmp;
}
else
{
res = kKitResult_ParamErr;
}
return res;
}
//static KitIrqCall uart_irq_call[kUartDev_End][kUartInterrupt_End];
static const uint16_t uart_irq_flag[kUartInterrupt_End] = {USER_CR1_RXNEIE, USER_CR1_TXEIE};
KitResult drv_uart_set_interrupt(UartDev dev, UartInterrupt it_type, uint16_t priority, KitIrqCall call)
{
KitResult res;
KIT_ASSERT_PARAM((dev < kUartDev_End) && (it_type < kUartInterrupt_End));
if((dev < kUartDev_End) && (it_type < kUartInterrupt_End))
{
uart_int_item[dev].call[it_type] = call;
drv_misc_set_nvic(stm32_uart[dev].irq, priority);
// stm32_uart[dev].reg->CR1 |= uart_irq_flag[it_type];
res = kKitResult_Ok;
}
else
{
res = kKitResult_ParamErr;
}
return res;
}
void drv_uart_ctrl_interrupt(UartDev dev, UartInterrupt it_type, bool is_enable)
{
KIT_ASSERT_PARAM((dev < kUartDev_End) && (it_type < kUartInterrupt_End));
if(is_enable == true)
{
stm32_uart[dev].reg->CR1 |= uart_irq_flag[it_type];
}
else
{
stm32_uart[dev].reg->CR1 &= ~uart_irq_flag[it_type];
}
}
KitResult drv_uart_set_dma(UartDev dev, bool is_rx_en, bool is_tx_en)
{
uint32_t tmp;
KitResult res= kKitResult_Ok;
USART_TypeDef *reg;
KIT_ASSERT_PARAM(dev < kUartDev_End);
if(dev < kUartDev_End)
{
reg = stm32_uart[dev].reg;
tmp = reg->CR3;
if(is_rx_en == true)
{
drv_dma_init(stm32_uart[dev].rx_dma_stream, stm32_uart[dev].dma_channel, DMA_CFG_DATA_DIR_P2M|DMA_CFG_CYCLE_NONE|DMA_CFG_DATA_M_I|DMA_CFG_DATA_P_N|DMA_CFG_DATA_LEN_1B, (uint32_t)&reg->DR);
tmp |= USART_CR3_DMAR;
}
else
{
tmp &= ~USART_CR3_DMAR;
}
if(is_tx_en == true)
{
drv_dma_init(stm32_uart[dev].tx_dma_stream, stm32_uart[dev].dma_channel, DMA_CFG_DATA_DIR_M2P|DMA_CFG_CYCLE_NONE|DMA_CFG_DATA_M_I|DMA_CFG_DATA_P_N|DMA_CFG_DATA_LEN_1B, (uint32_t)&reg->DR);
tmp |= USART_CR3_DMAT;
}
else
{
tmp &= ~USART_CR3_DMAT;
}
reg->CR3 = tmp;
}
else
{
res = kKitResult_OutRange;
}
return res;
}
static void uart_irq_handler(UartDev dev)
{
uint8_t data;
UartIntItem *item = &uart_int_item[dev];
USART_TypeDef* reg = stm32_uart[dev].reg;
/* USART接收溢出中断ORE清标志位,只要使能RXNE,ORE中断默认使能*/
if(((reg->CR1 & USER_CR1_RXNEIE) == USER_CR1_RXNEIE)
&& (((reg->SR & USART_FLAG_RXNE) != 0) || ((reg->SR & USART_FLAG_ORE) != 0)))
{
data = reg->DR;
if(item->call[kUartInterrupt_Rx] != NULL)
{
item->call[kUartInterrupt_Rx](kKitResult_Ok, &data);
}
}
else if((reg->SR & USER_SR1_TCIE) != 0)
{
//清除标志位
stm32_uart[dev].reg->SR &= ~USART_SR_TC;
//关闭发送完成中断
stm32_uart[dev].reg->CR1 &= ~USER_CR1_TCIE;
if(item->call[kUartInterrupt_Tx] != NULL)
{
item->call[kUartInterrupt_Tx](kKitResult_Ok, &dev);
}
}
else if((reg->SR & USER_SR1_TXEIE) != 0)
{
if(item->send_pos < item->buf_len)
{
reg->DR = item->send_buf[item->send_pos++];
if(item->send_pos >= item->buf_len)
{
//关闭发送缓冲区空中断
stm32_uart[dev].reg->CR1 &= ~USER_CR1_TXEIE;
//打开发送完成中断
stm32_uart[dev].reg->CR1 |= USER_CR1_TCIE;
}
}
else
{
//关闭发送缓冲区空中断
stm32_uart[dev].reg->CR1 &= ~USER_CR1_TXEIE;
//打开发送完成中断
stm32_uart[dev].reg->CR1 |= USER_CR1_TCIE;
}
}
}
void USART1_IRQHandler(void)
{
uart_irq_handler(kUartDev_1);
}
void USART2_IRQHandler(void)
{
uart_irq_handler(kUartDev_2);
}
void USART3_IRQHandler(void)
{
uart_irq_handler(kUartDev_3);
}
void UART4_IRQHandler(void)
{
uart_irq_handler(kUartDev_4);
}
void UART5_IRQHandler(void)
{
uart_irq_handler(kUartDev_5);
}
void USART6_IRQHandler(void)
{
uart_irq_handler(kUartDev_6);
}
#if defined(STM32F429_439xx)
void UART7_IRQHandler(void)
{
uart_irq_handler(kUartDev_7);
}
#endif