Skip to content

STM32L0 UART IRQ infinitely retriggered #3452

Closed
@bisqwit

Description

@bisqwit

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);
            }
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions