forked from gary/BCU
2
0
Fork 0
BCU/library/drv_stm32f4xx/drv_uart.c

484 lines
14 KiB
C
Raw Permalink 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] =
{
{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},
};
#define UART_FLAG_TXE KIT_BIT_MASK_32(7)
kit_ret_e 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 kKit_Ret_TimeOut;
}
}
reg->DR = buf[i++];
}
return kKit_Ret_Ok;
}
kit_ret_e drv_uart_dma_async_send(UartDev dev, uint8_t *buf, uint16_t len)
{
kit_ret_e 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 = kKit_Ret_Ok;
}
else
{
res = kKit_Ret_ParamErr;
}
return res;
}
kit_ret_e drv_uart_int_async_send(UartDev dev, uint8_t *buf, uint16_t len)
{
kit_ret_e 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 = kKit_Ret_Ok;
}
else
{
res = kKit_Ret_ParamErr;
}
return res;
}
#define GPIO_REMAP_UART0 KIT_BIT_MASK_32(2)
#define GPIO_REMAP_UART1 KIT_BIT_MASK_32(3)
#define GPIO_PARTIAL_REMAP_UART2 KIT_BIT_MASK_32(4)
#define GPIO_FULL_REMAP2_UART2 KIT_BIT_MASK_32S(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 kit_ret_e drv_uart_set_clock_gpio(UartDev dev, uint16_t tx_idx, uint16_t rx_idx)
{
kit_ret_e res = kKit_Ret_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);//设置复用功能7表示复用未usart1-3;
drv_gpio_set_af(kGpioPort_B, 7, 7);
}
else
{
res |= kKit_Ret_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 |= kKit_Ret_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_D, 8)) && (rx_io == GPIO_PORT_PIN(kGpioPort_D, 9)))
{
drv_gpio_set_af(kGpioPort_D, 8, 7);
drv_gpio_set_af(kGpioPort_D, 9, 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 |= kKit_Ret_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 |= kKit_Ret_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 |= kKit_Ret_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 |= kKit_Ret_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 |= kKit_Ret_ParamErr;
}
break;
#endif
default:
res = kKit_Ret_ParamErr;
break;
}
return res;
}
#define USER_CR1_UE KIT_BIT_MASK_32(13) //enable usart
#define USER_CR1_TXEIE KIT_BIT_MASK_32(7)
#define USER_CR1_TCIE KIT_BIT_MASK_32(6)
#define USER_CR1_RXNEIE KIT_BIT_MASK_32(5)
#define USER_CR1_TXEIE KIT_BIT_MASK_32(7)
#define USER_CR1_PCE_EN KIT_BIT_MASK_32(10) //enable parity
#define USER_SR1_TXEIE KIT_BIT_MASK_32(7)
#define USER_SR1_TCIE KIT_BIT_MASK_32(6)
#define USER_SR1_RXNEIE KIT_BIT_MASK_32(5)
#define USART_Mode_Rx KIT_BIT_MASK_32(2)
#define USART_Mode_Tx KIT_BIT_MASK_32(3)
#define USART_FLAG_ORE ((uint16_t)0x0008)
#define USART_FLAG_RXNE ((uint16_t)0x0020)
kit_ret_e 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;
kit_ret_e res = kKit_Ret_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 = kKit_Ret_ParamErr;
}
return res;
}
static const uint16_t uart_irq_flag[kUartInterrupt_End] = {USER_CR1_RXNEIE, USER_CR1_TXEIE};
kit_ret_e drv_uart_set_interrupt(UartDev dev, UartInterrupt it_type, uint16_t priority, KitIrqCall call)
{
kit_ret_e 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);
res = kKit_Ret_Ok;
}
else
{
res = kKit_Ret_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];
}
}
kit_ret_e drv_uart_set_dma(UartDev dev, bool is_rx_en, bool is_tx_en)
{
uint32_t tmp;
kit_ret_e res= kKit_Ret_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 = kKit_Ret_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](kKit_Ret_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](kKit_Ret_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