diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_usart.c b/bsp/stm32/libraries/HAL_Drivers/drv_usart.c index a1379f8a01..68133457b4 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_usart.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_usart.c @@ -7,7 +7,7 @@ * Date Author Notes * 2018-10-30 SummerGift first version */ - + #include "board.h" #include "drv_usart.h" #include "drv_config.h" @@ -20,12 +20,12 @@ #if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3) \ && !defined(BSP_USING_UART4) && !defined(BSP_USING_UART5) && !defined(BSP_USING_UART6) && !defined(BSP_USING_LPUART1) -#error "Please define at least one BSP_USING_UARTx" -/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */ + #error "Please define at least one BSP_USING_UARTx" + /* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */ #endif #ifdef RT_SERIAL_USING_DMA -static void stm32_dma_config(struct rt_serial_device *serial); + static void stm32_dma_config(struct rt_serial_device *serial); #endif enum @@ -56,25 +56,25 @@ enum static struct stm32_uart_config uart_config[] = { #ifdef BSP_USING_UART1 - UART1_CONFIG, + UART1_CONFIG, #endif #ifdef BSP_USING_UART2 - UART2_CONFIG, + UART2_CONFIG, #endif #ifdef BSP_USING_UART3 - UART3_CONFIG, + UART3_CONFIG, #endif #ifdef BSP_USING_UART4 - UART4_CONFIG, + UART4_CONFIG, #endif #ifdef BSP_USING_UART5 - UART5_CONFIG, + UART5_CONFIG, #endif #ifdef BSP_USING_UART6 - UART6_CONFIG, + UART6_CONFIG, #endif #ifdef BSP_USING_LPUART1 - LPUART1_CONFIG, + LPUART1_CONFIG, #endif }; @@ -147,7 +147,7 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar #ifdef RT_SERIAL_USING_DMA rt_ubase_t ctrl_arg = (rt_ubase_t)arg; #endif - + RT_ASSERT(serial != RT_NULL); uart = (struct stm32_uart *)serial->parent.user_data; RT_ASSERT(uart != RT_NULL); @@ -239,7 +239,7 @@ static void uart_isr(struct rt_serial_device *serial) rt_size_t recv_total_index, recv_len; rt_base_t level; #endif - + RT_ASSERT(serial != RT_NULL); uart = (struct stm32_uart *) serial->parent.user_data; @@ -247,7 +247,7 @@ static void uart_isr(struct rt_serial_device *serial) /* UART in mode Receiver -------------------------------------------------*/ if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET) && - (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_RXNE) != RESET)) + (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_RXNE) != RESET)) { rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } @@ -312,6 +312,42 @@ static void uart_isr(struct rt_serial_device *serial) } } +#ifdef RT_SERIAL_USING_DMA +static void dma_isr(struct rt_serial_device *serial) +{ + struct stm32_uart *uart; + rt_size_t recv_total_index, recv_len; + rt_base_t level; + + RT_ASSERT(serial != RT_NULL); + + uart = (struct stm32_uart *) serial->parent.user_data; + RT_ASSERT(uart != RT_NULL); + + if ((__HAL_DMA_GET_IT_SOURCE(&(uart->dma.handle), DMA_IT_TC) != RESET) || + (__HAL_DMA_GET_IT_SOURCE(&(uart->dma.handle), DMA_IT_HT) != RESET)) + { + level = rt_hw_interrupt_disable(); + recv_total_index = serial->config.bufsz - __HAL_DMA_GET_COUNTER(&(uart->dma.handle)); + if (recv_total_index == 0) + { + recv_len = serial->config.bufsz - uart->dma.last_index; + } + else + { + recv_len = recv_total_index - uart->dma.last_index; + } + uart->dma.last_index = recv_total_index; + rt_hw_interrupt_enable(level); + + if (recv_len) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8)); + } + } +} +#endif + #if defined(BSP_USING_UART1) void USART1_IRQHandler(void) { @@ -319,7 +355,7 @@ void USART1_IRQHandler(void) rt_interrupt_enter(); uart_isr(&(uart_obj[UART1_INDEX].serial)); - + /* leave interrupt */ rt_interrupt_leave(); } @@ -369,7 +405,7 @@ void USART3_IRQHandler(void) rt_interrupt_enter(); uart_isr(&(uart_obj[UART3_INDEX].serial)); - + /* leave interrupt */ rt_interrupt_leave(); } @@ -394,7 +430,7 @@ void UART4_IRQHandler(void) rt_interrupt_enter(); uart_isr(&(uart_obj[UART4_INDEX].serial)); - + /* leave interrupt */ rt_interrupt_leave(); } @@ -419,7 +455,7 @@ void UART5_IRQHandler(void) rt_interrupt_enter(); uart_isr(&(uart_obj[UART5_INDEX].serial)); - + /* leave interrupt */ rt_interrupt_leave(); } @@ -444,7 +480,7 @@ void USART6_IRQHandler(void) rt_interrupt_enter(); uart_isr(&(uart_obj[UART6_INDEX].serial)); - + /* leave interrupt */ rt_interrupt_leave(); } @@ -469,7 +505,7 @@ void LPUART1_IRQHandler(void) rt_interrupt_enter(); uart_isr(&(uart_obj[LPUART1_INDEX].serial)); - + /* leave interrupt */ rt_interrupt_leave(); } @@ -494,13 +530,13 @@ static void stm32_dma_config(struct rt_serial_device *serial) struct stm32_uart *uart = (struct stm32_uart *)serial->parent.user_data; RT_ASSERT(uart != RT_NULL); struct rt_serial_rx_fifo *rx_fifo; - + LOG_D("%s dma config start", uart->config->name); { - rt_uint32_t tmpreg= 0x00U; + rt_uint32_t tmpreg = 0x00U; #if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) \ - || defined(SOC_SERIES_STM32L0) + || defined(SOC_SERIES_STM32L0) /* enable DMA clock && Delay after an RCC peripheral clock enabling*/ SET_BIT(RCC->AHBENR, uart->config->dma_rx->dma_rcc); tmpreg = READ_BIT(RCC->AHBENR, uart->config->dma_rx->dma_rcc); @@ -508,7 +544,7 @@ static void stm32_dma_config(struct rt_serial_device *serial) /* enable DMA clock && Delay after an RCC peripheral clock enabling*/ SET_BIT(RCC->AHB1ENR, uart->config->dma_rx->dma_rcc); tmpreg = READ_BIT(RCC->AHB1ENR, uart->config->dma_rx->dma_rcc); -#endif +#endif UNUSED(tmpreg); /* To avoid compiler warnings */ } @@ -544,7 +580,7 @@ static void stm32_dma_config(struct rt_serial_device *serial) } rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; - + /* Start DMA transfer */ if (HAL_UART_Receive_DMA(&(uart->handle), rx_fifo->buffer, serial->config.bufsz) != HAL_OK) { @@ -554,14 +590,14 @@ static void stm32_dma_config(struct rt_serial_device *serial) /* enable interrupt */ __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_IDLE); - + /* enable rx irq */ HAL_NVIC_SetPriority(uart->config->dma_rx->dma_irq, 0, 0); HAL_NVIC_EnableIRQ(uart->config->dma_rx->dma_irq); - + HAL_NVIC_SetPriority(uart->config->irq_type, 1, 0); HAL_NVIC_EnableIRQ(uart->config->irq_type); - + LOG_D("%s dma RX instance: %x", uart->config->name, uart->dma.handle.Instance); LOG_D("%s dma config done", uart->config->name); } @@ -590,25 +626,25 @@ void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { - struct rt_serial_device *serial; struct stm32_uart *uart; - rt_size_t recv_len; - rt_base_t level; - RT_ASSERT(huart != NULL); uart = (struct stm32_uart *)huart; - serial = &uart->serial; + dma_isr(&uart->serial); +} - level = rt_hw_interrupt_disable(); - - recv_len = serial->config.bufsz - uart->dma.last_index; - uart->dma.last_index = 0; - - rt_hw_interrupt_enable(level); - if (recv_len) - { - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8)); - } +/** + * @brief Rx Half transfer completed callback + * @param huart: UART handle + * @note This example shows a simple way to report end of DMA Rx Half transfer, + * and you can add your own implementation. + * @retval None + */ +void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) +{ + struct stm32_uart *uart; + RT_ASSERT(huart != NULL); + uart = (struct stm32_uart *)huart; + dma_isr(&uart->serial); } #endif /* RT_SERIAL_USING_DMA */ @@ -658,7 +694,7 @@ int rt_hw_usart_init(void) rt_err_t result = 0; stm32_uart_get_dma_config(); - + for (int i = 0; i < obj_num; i++) { uart_obj[i].config = &uart_config[i]; @@ -666,20 +702,20 @@ int rt_hw_usart_init(void) uart_obj[i].serial.config = config; #if defined(RT_SERIAL_USING_DMA) - if(uart_obj[i].uart_dma_flag) + if (uart_obj[i].uart_dma_flag) { /* register UART device */ - result = rt_hw_serial_register(&uart_obj[i].serial,uart_obj[i].config->name, - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX| RT_DEVICE_FLAG_DMA_RX - ,&uart_obj[i]); + result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX + , &uart_obj[i]); } else #endif { /* register UART device */ - result = rt_hw_serial_register(&uart_obj[i].serial,uart_obj[i].config->name, + result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX - ,&uart_obj[i]); + , &uart_obj[i]); } RT_ASSERT(result == RT_EOK); }