bs_bcu_app/drv/drv_stm32f4xx/drv_uart.c

507 lines
16 KiB
C
Raw Normal View History

2024-11-07 17:24:19 +08:00
#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) 使
*24002400
*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