From 61e1e31ca9ee3e99a7d6b5ce0ad83164a7afe115 Mon Sep 17 00:00:00 2001 From: BreederBai Date: Thu, 22 Sep 2022 14:13:57 +0800 Subject: [PATCH] =?UTF-8?q?[bsp/stm32]=20=E7=AE=80=E5=8C=96drv=5Fusart?= =?UTF-8?q?=E4=B8=AD=E7=9A=84DMA=E6=8E=A5=E6=94=B6=E9=80=BB=E8=BE=91=20(#6?= =?UTF-8?q?357)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/stm32/libraries/HAL_Drivers/drv_usart.c | 98 +++++++++++---------- bsp/stm32/libraries/HAL_Drivers/drv_usart.h | 6 +- 2 files changed, 56 insertions(+), 48 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_usart.c b/bsp/stm32/libraries/HAL_Drivers/drv_usart.c index 2f60d7edfc..addd5da9c4 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_usart.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_usart.c @@ -170,7 +170,7 @@ static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_c #ifdef RT_SERIAL_USING_DMA if (!(serial->parent.open_flag & RT_DEVICE_OFLAG_OPEN)) { - uart->dma_rx.last_index = 0; + uart->dma_rx.remaining_cnt = 0; } #endif @@ -367,6 +367,53 @@ static rt_size_t stm32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t return 0; } +#ifdef RT_SERIAL_USING_DMA +static void dma_recv_isr(struct rt_serial_device *serial, rt_uint8_t isr_flag) +{ + struct stm32_uart *uart; + rt_base_t level; + rt_size_t recv_len, counter; + + RT_ASSERT(serial != RT_NULL); + uart = rt_container_of(serial, struct stm32_uart, serial); + + level = rt_hw_interrupt_disable(); + recv_len = 0; + counter = __HAL_DMA_GET_COUNTER(&(uart->dma_rx.handle)); + + switch (isr_flag) + { + case UART_RX_DMA_IT_IDLE_FLAG: + if (counter <= uart->dma_rx.remaining_cnt) + recv_len = uart->dma_rx.remaining_cnt - counter; + else + recv_len = serial->config.bufsz + uart->dma_rx.remaining_cnt - counter; + break; + + case UART_RX_DMA_IT_HT_FLAG: + if (counter < uart->dma_rx.remaining_cnt) + recv_len = uart->dma_rx.remaining_cnt - counter; + break; + + case UART_RX_DMA_IT_TC_FLAG: + if(counter >= uart->dma_rx.remaining_cnt) + recv_len = serial->config.bufsz + uart->dma_rx.remaining_cnt - counter; + + default: + break; + } + + if (recv_len) + { + uart->dma_rx.remaining_cnt = counter; + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8)); + } + rt_hw_interrupt_enable(level); + +} + +#endif + /** * Uart common interrupt process. This need add to uart ISR. * @@ -393,16 +440,7 @@ static void uart_isr(struct rt_serial_device *serial) else if ((uart->uart_dma_flag) && (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_IDLE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE) != RESET)) { - level = rt_hw_interrupt_disable(); - recv_total_index = serial->config.bufsz - __HAL_DMA_GET_COUNTER(&(uart->dma_rx.handle)); - recv_len = recv_total_index - uart->dma_rx.last_index; - uart->dma_rx.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)); - } + dma_recv_isr(serial, UART_RX_DMA_IT_IDLE_FLAG); __HAL_UART_CLEAR_IDLEFLAG(&uart->handle); } else if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) && @@ -464,40 +502,6 @@ 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 = rt_container_of(serial, struct stm32_uart, serial); - - if ((__HAL_DMA_GET_IT_SOURCE(&(uart->dma_rx.handle), DMA_IT_TC) != RESET) || - (__HAL_DMA_GET_IT_SOURCE(&(uart->dma_rx.handle), DMA_IT_HT) != RESET)) - { - level = rt_hw_interrupt_disable(); - recv_total_index = serial->config.bufsz - __HAL_DMA_GET_COUNTER(&(uart->dma_rx.handle)); - if (recv_total_index == 0) - { - recv_len = serial->config.bufsz - uart->dma_rx.last_index; - } - else - { - recv_len = serial->config.bufsz - uart->dma_rx.last_index + recv_total_index; - } - uart->dma_rx.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) { @@ -1088,7 +1092,7 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) struct stm32_uart *uart; RT_ASSERT(huart != NULL); uart = (struct stm32_uart *)huart; - dma_isr(&uart->serial); + dma_recv_isr(&uart->serial, UART_RX_DMA_IT_TC_FLAG); } /** @@ -1103,7 +1107,7 @@ void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) struct stm32_uart *uart; RT_ASSERT(huart != NULL); uart = (struct stm32_uart *)huart; - dma_isr(&uart->serial); + dma_recv_isr(&uart->serial, UART_RX_DMA_IT_HT_FLAG); } static void _dma_tx_complete(struct rt_serial_device *serial) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_usart.h b/bsp/stm32/libraries/HAL_Drivers/drv_usart.h index 1a886f3050..7763a70683 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_usart.h +++ b/bsp/stm32/libraries/HAL_Drivers/drv_usart.h @@ -38,6 +38,10 @@ int rt_hw_usart_init(void); #define UART_INSTANCE_CLEAR_FUNCTION __HAL_UART_CLEAR_IT #endif +#define UART_RX_DMA_IT_IDLE_FLAG 0x00 +#define UART_RX_DMA_IT_HT_FLAG 0x01 +#define UART_RX_DMA_IT_TC_FLAG 0x02 + /* stm32 config class */ struct stm32_uart_config { @@ -58,7 +62,7 @@ struct stm32_uart struct { DMA_HandleTypeDef handle; - rt_size_t last_index; + rt_size_t remaining_cnt; } dma_rx; struct { -- GitLab