for now, RxEventCallback does not allow to distinguish interrupt reason, in DMA mode this could be RX half transfer, RX transfer complete or RX line idle. Adding information about interrupt reason would allow end user to react only on certain situations, eg. RX line idle interrupt is really helpful in communication with GSM modems.
/** @defgroup UART_RX_DMA_INTERRUPT_TYPE_Values UART RX DMA interrupt type values
* @{
*/
#define HAL_UART_RX_DMA_INTERRUPT_HALF_TRANSFER (0xFFFFFFFEU) /*!< RX DMA half transfer interrupt */
#define HAL_UART_RX_DMA_INTERRUPT_TRANSFER_COMPLETE (0xFFFFFFFFU) /*!< RX DMA transfer complete interrupt */
/**
* @}
*/
typedef void (*pUART_RxEventCallbackTypeDef)(struct __UART_HandleTypeDef *huart, uint16_t Pos, uint32_t Interrupt); /*!< pointer to a UART Rx Event specific callback function */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size, uint32_t Interrupt);
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
...
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount), isrflags);
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount), isrflags);
#endif
...
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx complete callback*/
huart->RxEventCallback(huart, nb_rx_data, isrflags);
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, nb_rx_data, isrflags);
#endif
}
__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size, uint32_t Interrupt)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
UNUSED(Size);
UNUSED(Interrupt);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_UARTEx_RxEventCallback can be implemented in the user file.
*/
}
static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
{
...
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
huart->RxEventCallback(huart, huart->RxXferSize, HAL_UART_RX_DMA_INTERRUPT_TRANSFER_COMPLETE);
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize, HAL_UART_RX_DMA_INTERRUPT_TRANSFER_COMPLETE);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
{
...
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
huart->RxEventCallback(huart, huart->RxXferSize/2U, HAL_UART_RX_DMA_INTERRUPT_HALF_TRANSFER);
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize/2U, HAL_UART_RX_DMA_INTERRUPT_HALF_TRANSFER);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
...
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
huart->RxEventCallback(huart, huart->RxXferSize, isrflags);
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize, isrflags);
#endif
}
Adding above changes will allow end user to distinguish various interrupt reasons, either by checking SR flags or checking predefined values for DMA interrupts.