I am using interrupt based UART IO (no DMA).
HAL_UART_Transmit_IT
function sets EIE
bit in CR3
register. According to STM32F407 datasheet (and real behaviour), this generates interrupt only in multi buffer mode (when DMAR
bit is set). EIE
enables interrupt generation for frame error (FE
), overrun error (ORE
), noise error (NE
). This error, as I understand, only for receiving.
Part of HAL_UART_IRQHandler
function:
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
/* UART Over-Run interrupt occurred ----------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_OREFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
if(huart->ErrorCode != HAL_UART_ERROR_NONE)
{
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
HAL_UART_ErrorCallback(huart);
}
HAL_UART_IRQHandler
checks for each error. If error occurred and EIE
bit is set, it resets UART state, but doesn't reset interrupt enabling bits, so TXE
interrupt will be always generated, but UART_Transmit_IT
function treats state HAL_UART_STATE_READY
as invalid and doesn't do anything. Infinite loop.
Part of UART_Transmit_IT
function:
static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
{
uint16_t* tmp;
uint32_t tmp1 = 0;
tmp1 = huart->State;
if((tmp1 == HAL_UART_STATE_BUSY_TX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX))
{
}
else
{
return HAL_BUSY;
}
}
Is it a bug in Cube HAL?