Description
I am having trouble where uart2_irq gets triggered, but never acknowledged, causing the IRQ being immediately triggered again when it exits, with user code never getting chance to progress.
I single-step the IRQ handler, and I see it tests and sees that UART_FLAG_ORE
is set. Then it tests whether UART_IT_ORE
is set, and it’s not, so it never clears the ORE condition. And the IRQ gets never acknowledged, and it therefore gets triggered again, infinitely.
I made a comparison on how uart_irq()
is written in all the different STM32 targets, and I see they are quite different on each CPU. Should they be? Should it perchance be testing USART_IT_ERR
instead of UART_IT_ORE
, on L0, like it is doing on F4, and like it is actually doing in serial_irq_handler_asynch()
on L0?
--- TARGET_STM32L0 ---
static void uart_irq(int id)
{
UART_HandleTypeDef * huart = &uart_handlers[id];
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
volatile uint32_t tmpval = huart->Instance->RDR; // Clear RXNE flag
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ORE) != RESET) {
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
}
}
}
}
--- TARGET_STM32L1 ---
static void uart_irq(int id)
{
UART_HandleTypeDef * huart = &uart_handlers[id];
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_RXNE);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET) {
volatile uint32_t tmpval = huart->Instance->DR; // Clear ORE flag
}
}
}
}
--- TARGET_STM32L4 ---
static void uart_irq(int id)
{
UART_HandleTypeDef * huart = &uart_handlers[id];
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_RXNE);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET) {
volatile uint32_t tmpval = huart->Instance->RDR; // Clear ORE flag
}
}
}
}
--- TARGET_STM32F0 ---
static void uart_irq(int id)
{
UART_HandleTypeDef * huart = &uart_handlers[id];
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
volatile uint32_t tmpval = huart->Instance->RDR; // Clear RXNE flag
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ORE) != RESET) {
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
}
}
}
}
--- TARGET_STM32F1 ---
static void uart_irq(int id)
{
UART_HandleTypeDef * huart = &uart_handlers[id];
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_RXNE);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET) {
volatile uint32_t tmpval = huart->Instance->DR; // Clear ORE flag
}
}
}
}
--- TARGET_STM32F2 ---
static void uart_irq(int id)
{
UART_HandleTypeDef * huart = &uart_handlers[id];
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_RXNE);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, USART_IT_ERR) != RESET) {
volatile uint32_t tmpval = huart->Instance->DR; // Clear ORE flag
}
}
}
}
--- TARGET_STM32F3 ---
static void uart_irq(int id)
{
UART_HandleTypeDef * huart = &uart_handlers[id];
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
volatile uint32_t tmpval = huart->Instance->RDR; // Clear RXNE flag
UNUSED(tmpval);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ORE) != RESET) {
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
}
}
}
}
--- TARGET_STM32F4 ---
static void uart_irq(int id)
{
UART_HandleTypeDef * huart = &uart_handlers[id];
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_RXNE);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, USART_IT_ERR) != RESET) {
volatile uint32_t tmpval = huart->Instance->DR; // Clear ORE flag
}
}
}
}
--- TARGET_STM32F7 ---
static void uart_irq(int id)
{
UART_HandleTypeDef * huart = &uart_handlers[id];
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_TCF);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
volatile uint32_t tmpval = huart->Instance->RDR; // Clear RXNE
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ORE) != RESET) {
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
}
}
}
}