diff --git a/src/main/drivers/serial.h b/src/main/drivers/serial.h index 9c4faba18f..247dbed0d7 100644 --- a/src/main/drivers/serial.h +++ b/src/main/drivers/serial.h @@ -59,6 +59,7 @@ typedef enum { #define CTRL_LINE_STATE_RTS (1 << 1) typedef void (*serialReceiveCallbackPtr)(uint16_t data, void *rxCallbackData); // used by serial drivers to return frames to app +typedef void (*serialIdleCallbackPtr)(); typedef struct serialPort_s { @@ -81,6 +82,8 @@ typedef struct serialPort_s { serialReceiveCallbackPtr rxCallback; void *rxCallbackData; + serialIdleCallbackPtr idleCallback; + uint8_t identifier; } serialPort_t; diff --git a/src/main/drivers/serial_uart_hal.c b/src/main/drivers/serial_uart_hal.c index 4c498f1a72..f9ce93100f 100644 --- a/src/main/drivers/serial_uart_hal.c +++ b/src/main/drivers/serial_uart_hal.c @@ -147,7 +147,6 @@ void uartReconfigure(uartPort_t *uartPort) HAL_UART_Receive_DMA(&uartPort->Handle, (uint8_t*)uartPort->port.rxBuffer, uartPort->port.rxBufferSize); uartPort->rxDMAPos = __HAL_DMA_GET_COUNTER(&uartPort->rxDMAHandle); - } else #endif { @@ -159,6 +158,9 @@ void uartReconfigure(uartPort_t *uartPort) /* Enable the UART Data Register not empty Interrupt */ SET_BIT(uartPort->USARTx->CR1, USART_CR1_RXNEIE); + + /* Enable Idle Line detection */ + SET_BIT(uartPort->USARTx->CR1, USART_CR1_IDLEIE); } } diff --git a/src/main/drivers/serial_uart_init.c b/src/main/drivers/serial_uart_init.c index 5b8d23140f..7e557eea8a 100644 --- a/src/main/drivers/serial_uart_init.c +++ b/src/main/drivers/serial_uart_init.c @@ -189,6 +189,7 @@ serialPort_t *uartOpen(UARTDevice_e device, serialReceiveCallbackPtr rxCallback, } else { USART_ClearITPendingBit(s->USARTx, USART_IT_RXNE); USART_ITConfig(s->USARTx, USART_IT_RXNE, ENABLE); + USART_ITConfig(s->USARTx, USART_IT_IDLE, ENABLE); } } diff --git a/src/main/drivers/serial_uart_stm32f10x.c b/src/main/drivers/serial_uart_stm32f10x.c index 64f4dbd0ba..fad9c7ecba 100644 --- a/src/main/drivers/serial_uart_stm32f10x.c +++ b/src/main/drivers/serial_uart_stm32f10x.c @@ -214,5 +214,13 @@ void uartIrqHandler(uartPort_t *s) USART_ITConfig(s->USARTx, USART_IT_TXE, DISABLE); } } + if (SR & USART_FLAG_IDLE) { + if (s->port.idleCallback) { + s->port.idleCallback(); + } + + const uint32_t read_to_clear = s->USARTx->DR; + (void) read_to_clear; + } } #endif // USE_UART diff --git a/src/main/drivers/serial_uart_stm32f30x.c b/src/main/drivers/serial_uart_stm32f30x.c index 65aedd3c44..80d5576f1f 100644 --- a/src/main/drivers/serial_uart_stm32f30x.c +++ b/src/main/drivers/serial_uart_stm32f30x.c @@ -285,7 +285,15 @@ void uartIrqHandler(uartPort_t *s) if (ISR & USART_FLAG_ORE) { - USART_ClearITPendingBit (s->USARTx, USART_IT_ORE); + USART_ClearITPendingBit(s->USARTx, USART_IT_ORE); + } + + if (ISR & USART_FLAG_IDLE) { + if (s->port.idleCallback) { + s->port.idleCallback(); + } + + USART_ClearITPendingBit(s->USARTx, USART_IT_IDLE); } } #endif // USE_UART diff --git a/src/main/drivers/serial_uart_stm32f4xx.c b/src/main/drivers/serial_uart_stm32f4xx.c index 7f3bd45c86..cca8b2249f 100644 --- a/src/main/drivers/serial_uart_stm32f4xx.c +++ b/src/main/drivers/serial_uart_stm32f4xx.c @@ -289,9 +289,18 @@ void uartIrqHandler(uartPort_t *s) } } - if (USART_GetITStatus(s->USARTx, USART_IT_ORE) == SET) - { - USART_ClearITPendingBit (s->USARTx, USART_IT_ORE); + if (USART_GetITStatus(s->USARTx, USART_IT_ORE) == SET) { + USART_ClearITPendingBit(s->USARTx, USART_IT_ORE); + } + + if (USART_GetITStatus(s->USARTx, USART_IT_IDLE) == SET) { + if (s->port.idleCallback) { + s->port.idleCallback(); + } + + // clear + (void) s->USARTx->SR; + (void) s->USARTx->DR; } } #endif diff --git a/src/main/drivers/serial_uart_stm32f7xx.c b/src/main/drivers/serial_uart_stm32f7xx.c index 0154d255be..26d6adf09a 100644 --- a/src/main/drivers/serial_uart_stm32f7xx.c +++ b/src/main/drivers/serial_uart_stm32f7xx.c @@ -39,6 +39,8 @@ #include "drivers/serial_uart.h" #include "drivers/serial_uart_impl.h" +#include "stm32f7xx_ll_usart.h" + static void handleUsartTxDma(uartPort_t *s); const uartHardware_t uartHardware[UARTDEV_COUNT] = { @@ -150,15 +152,15 @@ const uartHardware_t uartHardware[UARTDEV_COUNT] = { #endif .rxPins = { { DEFIO_TAG_E(PA1), GPIO_AF8_UART4 }, - { DEFIO_TAG_E(PC11), GPIO_AF8_UART4 }, + { DEFIO_TAG_E(PC11), GPIO_AF8_UART4 }, #ifdef STM32F765xx { DEFIO_TAG_E(PA11), GPIO_AF6_UART4 }, - { DEFIO_TAG_E(PD0), GPIO_AF8_UART4 } + { DEFIO_TAG_E(PD0), GPIO_AF8_UART4 } #endif }, .txPins = { { DEFIO_TAG_E(PA0), GPIO_AF8_UART4 }, - { DEFIO_TAG_E(PC10), GPIO_AF8_UART4 }, + { DEFIO_TAG_E(PC10), GPIO_AF8_UART4 }, #ifdef STM32F765xx { DEFIO_TAG_E(PA12), GPIO_AF6_UART4 }, { DEFIO_TAG_E(PD1), GPIO_AF8_UART4 } @@ -372,6 +374,14 @@ void uartIrqHandler(uartPort_t *s) handleUsartTxDma(s); } } + + if (__HAL_UART_GET_IT(huart, UART_IT_IDLE)) { + if (s->port.idleCallback) { + s->port.idleCallback(); + } + + __HAL_UART_CLEAR_IDLEFLAG(huart); + } } static void handleUsartTxDma(uartPort_t *s)