Electronic – STM32 NVIC interrupts after a reset / power-on

interruptsresetstm32

I have a few active-low signals that I want to interrupt on. During normal operation, the interrupts work just fine. However, on reset / power-on only rising edge is detected.

In other words, on start-up my routine is called when the interrupt line is inactive (pulled-up to VDD). If the line is active (LOW), the function is not called on start-up.

I tried disabling the rising edge trigger, but that didn't help.

Is this expected or am I doing something wrong? What would be the best way to work around this issue?

TLDR: How do I get my interrupt routines called when the interrupt signal is in a stable LOW state at the time of power-on?

Here is my code:

#include <stm32f2xx.h>
#include "DBG.h"

void EXTI3_IRQHandler(void)
{
    DBG("EXTI3\r\n");
    EXTI->PR |= EXTI_PR_PR3;
}

void EXTI4_IRQHandler(void)
{
    DBG("EXTI4\r\n");
    EXTI->PR |= EXTI_PR_PR4;
}

void DI_interrupt_setup(void)
{
    /* enable syscfg controller clock */
    RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;

    /* unmask relevant interrupt lines */
    EXTI->IMR |= EXTI_IMR_MR3 | EXTI_IMR_MR4;

    /* enable falling edge triggers */
    EXTI->FTSR |= EXTI_FTSR_TR3 | EXTI_FTSR_TR4;

    /* enable rising edge triggers */
    EXTI->RTSR |= EXTI_RTSR_TR3 | EXTI_RTSR_TR4;

    SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI3_PD;
    SYSCFG->EXTICR[1] |= SYSCFG_EXTICR2_EXTI4_PD;

    NVIC_EnableIRQ(EXTI3_IRQn);
    NVIC_EnableIRQ(EXTI4_IRQn);
}

Best Answer

It would appear that the STM32 interrupt system can only trigger on external signal edges. To see whether an external signal is already active at start-up, you're going to have to explictly poll it as GPIO and then call the corresponding handler as a subroutine if it's in the active state.