[bsp/stm32] 简化drv_usart中的DMA接收逻辑 (#6357)

This commit is contained in:
BreederBai 2022-09-22 14:13:57 +08:00 committed by GitHub
parent 50cb4be8ce
commit 61e1e31ca9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 48 deletions

View File

@ -170,7 +170,7 @@ static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_c
#ifdef RT_SERIAL_USING_DMA #ifdef RT_SERIAL_USING_DMA
if (!(serial->parent.open_flag & RT_DEVICE_OFLAG_OPEN)) { if (!(serial->parent.open_flag & RT_DEVICE_OFLAG_OPEN)) {
uart->dma_rx.last_index = 0; uart->dma_rx.remaining_cnt = 0;
} }
#endif #endif
@ -367,6 +367,53 @@ static rt_size_t stm32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t
return 0; 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. * 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) 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)) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE) != RESET))
{ {
level = rt_hw_interrupt_disable(); dma_recv_isr(serial, UART_RX_DMA_IT_IDLE_FLAG);
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));
}
__HAL_UART_CLEAR_IDLEFLAG(&uart->handle); __HAL_UART_CLEAR_IDLEFLAG(&uart->handle);
} }
else if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) && 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) #if defined(BSP_USING_UART1)
void USART1_IRQHandler(void) void USART1_IRQHandler(void)
{ {
@ -1088,7 +1092,7 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
struct stm32_uart *uart; struct stm32_uart *uart;
RT_ASSERT(huart != NULL); RT_ASSERT(huart != NULL);
uart = (struct stm32_uart *)huart; 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; struct stm32_uart *uart;
RT_ASSERT(huart != NULL); RT_ASSERT(huart != NULL);
uart = (struct stm32_uart *)huart; 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) static void _dma_tx_complete(struct rt_serial_device *serial)

View File

@ -38,6 +38,10 @@ int rt_hw_usart_init(void);
#define UART_INSTANCE_CLEAR_FUNCTION __HAL_UART_CLEAR_IT #define UART_INSTANCE_CLEAR_FUNCTION __HAL_UART_CLEAR_IT
#endif #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 */ /* stm32 config class */
struct stm32_uart_config struct stm32_uart_config
{ {
@ -58,7 +62,7 @@ struct stm32_uart
struct struct
{ {
DMA_HandleTypeDef handle; DMA_HandleTypeDef handle;
rt_size_t last_index; rt_size_t remaining_cnt;
} dma_rx; } dma_rx;
struct struct
{ {