#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)®->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)®->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