2021-09-08 10:26 PM
This is on a STM32F412RGTx.
I just inherited a long over-due project based on this MCU. I've done lots of PIC and 8051 programming, but very little on an STM, or with the HAL.
We are sending short commands to the MCU from the PC (ie, SET VAR1 1.234), parsing them, then sending responses or data back via printf().
This seems to be the same problem from here: https://community.st.com/s/question/0D50X00009XkflR/haluartirqhandler-bug
The problem I seem to be having is that the HAL_UART_ErrorCallback() function is never getting called when the overrun occurs, so it can never be cleared, and the uart locks up.
The uart interrupt priority is 1, with both the SPI and TIM2 interrupts at 0 (and they are firing frequently).
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 19200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
in main:
{
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); // Receive Data register not empty interrupt
// __HAL_UART_ENABLE_IT(&huart1, UART_IT_PE); // Parity Error interrupt
__HAL_UART_ENABLE_IT(&huart1, UART_IT_ERR); // Error interrupt(Frame error, noise error, overrun error)
// Setup UART Receive Interrupt Low Level Driver
HAL_UART_Receive_IT(&huart1, &rx_char, 1);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
// IRQ must be re-enabled after each interrupt
HAL_UART_Receive_IT(&huart1, &rx_char, 1);
rxBuffer_AddChar(rx_char); // adds the char to a ring buffer
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
uint32_t isrflags = READ_REG(huart->Instance->SR);
uint32_t cr1its = READ_REG(huart->Instance->CR1);
// a breakpoint here is never reached, so the error can never be cleared, and the uart resumed
}
After it locks up, if I pause execution, I can look at USART1 in the watch window.
SR is always 0xF8, which seems to indicate an overrun.
CR1 is always 0x200C, which shows the RXNEIE bit OFF, so the RX interrupt is disabled. I can verify this by putting a breaking in the RxCplt callback, sending a character, and it never hits the breakpoint.
CubeIDE is v1.7, and the configurator version is the latest.
Any ideas? Thanks.
2021-09-21 02:58 PM
Ended up going with LL DMA.
2021-09-22 07:21 PM
Can you confirm which version of the STM32F4 [HAL] library is in use actually?
IIRC the 'F4 overrun bug has been fixed by ST.
You wrote this is a project created some time ago, by someone else, and people have a habit to copy the HAL library files into the project.
So despite that you've updated everything, outdated UART files still can sit in the project sources.
2021-09-22 10:28 PM
When I got it, their computer had IDE v1.6.something. I updated that to 1.7.0. When I opened the IOC file, it asked about migrating from something, to FW_F4 1.26.2 (found on the Project Manager tab, "Use latest version" is checked)
I've saved and regenerated the code quite a few times, so I assume it would have used the latest code to avoid the older bug? I'm not seeing a version number in the generated files.
Are those the correct numbers, or do I need to look somewhere else?
2021-09-23 02:29 PM
To be sure, one can only compare the files under project /Drivers against the original in the Cube "repository".