Electronic – STM32F0 Interrupt Debugging

interruptsstm32

Issue:

I'm having an impossible time debugging why one of my interrupts isn't working. I'm trying to setup a hardware interrupt on PA3, but as soon as I initialize it, the interrupt triggers and then it never triggers again.

Hardware:

The pin is pulled up (10k) externally and can be shorted to GND via a push button. If I probe the pin, I can see it toggle as I press the button. Further, if I poll the pin using a GPIO_ReadInputDataBit it is toggling correctly as I press the button. All my other interrupts that are configured by the same routine work fine.

Software:

I'm including the code below, but I'm mostly hoping someone can help explain how to debug the interrupt handler. I don't know much about it beyond configuring it which had been working fine until this hiccup. (SWA_Button is the one that's not working, while all the others are fine). Am I missing something really obvious?

*** UPDATE:

I just noticed that it seems PB3 is what is triggering that interrupt. How is the interrupt handler supposed to differentiate between an interrupt on PB3 and PA3?

    #define SWA_BUTTON_PIN                  GPIO_Pin_3
    #define SWA_BUTTON_GPIO_PORT            GPIOA
    #define SWA_BUTTON_GPIO_CLK             RCC_AHBPeriph_GPIOA
    #define SWA_BUTTON_EXTI_LINE            EXTI_Line3
    #define SWA_BUTTON_EXTI_PORT_SOURCE     EXTI_PortSourceGPIOA
    #define SWA_BUTTON_EXTI_PIN_SOURCE      EXTI_PinSource3
    #define SWA_BUTTON_EXTI_IRQn            EXTI2_3_IRQn 


    #define ROTARY_BUTTON_PIN               GPIO_Pin_1
    #define ROTARY_BUTTON_GPIO_PORT         GPIOA
    #define ROTARY_BUTTON_GPIO_CLK          RCC_AHBPeriph_GPIOA
    #define ROTARY_BUTTON_EXTI_LINE         EXTI_Line1
    #define ROTARY_BUTTON_EXTI_PORT_SOURCE  EXTI_PortSourceGPIOA
    #define ROTARY_BUTTON_EXTI_PIN_SOURCE   EXTI_PinSource1
    #define ROTARY_BUTTON_EXTI_IRQn         EXTI0_1_IRQn 

    typedef enum 
    {
      SWA_BUTTON = 0,
      BUTTON_ROTARY = 1,
      ROTARY_A = 2,
      ROTARY_B = 3,
      TX_LOOPBACK = 4,
      SWB_BUTTON = 5
    } Input_TypeDef;

    GPIO_TypeDef* INPUT_PORT[SYS_Num_Inputs] = {
      SWA_BUTTON_GPIO_PORT,         \
      ROTARY_BUTTON_GPIO_PORT,      \
      ROTARY_A_GPIO_PORT,           \
      ROTARY_B_GPIO_PORT,           \
      TX_LOOPBACK_GPIO_PORT,        \
      SWB_BUTTON_GPIO_PORT};

    const uint16_t INPUT_PIN[SYS_Num_Inputs] = {
      SWA_BUTTON_PIN,               \
      ROTARY_BUTTON_PIN,            \
      ROTARY_A_PIN,                 \
      ROTARY_B_PIN,                 \
      TX_LOOPBACK_PIN,              \
      SWB_BUTTON_PIN}; 

    const uint32_t INPUT_CLK[SYS_Num_Inputs] = {
      SWA_BUTTON_GPIO_CLK,          \
      ROTARY_BUTTON_GPIO_CLK,       \
      ROTARY_A_GPIO_CLK,            \
      ROTARY_B_GPIO_CLK,            \
      TX_LOOPBACK_GPIO_CLK,         \
      SWB_BUTTON_GPIO_CLK};

    const uint16_t INPUT_EXTI_LINE[SYS_Num_Inputs] = {
      SWA_BUTTON_EXTI_LINE,         \
      ROTARY_BUTTON_EXTI_LINE,      \
      ROTARY_A_EXTI_LINE,           \
      ROTARY_B_EXTI_LINE,           \
      TX_LOOPBACK_EXTI_LINE,        \
      SWB_BUTTON_EXTI_LINE};

    const uint16_t INPUT_PORT_SOURCE[SYS_Num_Inputs] = {
      SWA_BUTTON_EXTI_PORT_SOURCE,          \
      ROTARY_BUTTON_EXTI_PORT_SOURCE,       \
      ROTARY_A_EXTI_PORT_SOURCE,            \
      ROTARY_B_EXTI_PORT_SOURCE,            \
      TX_LOOPBACK_EXTI_PORT_SOURCE,         \
      SWB_BUTTON_EXTI_PORT_SOURCE};                  

    const uint16_t INPUT_PIN_SOURCE[SYS_Num_Inputs] = {
       SWA_BUTTON_EXTI_PIN_SOURCE,          \
       ROTARY_BUTTON_EXTI_PIN_SOURCE,       \
       ROTARY_A_EXTI_PIN_SOURCE,            \
       ROTARY_B_EXTI_PIN_SOURCE,            \
       TX_LOOPBACK_EXTI_PIN_SOURCE,         \
       SWB_BUTTON_EXTI_PIN_SOURCE}; 

    const uint16_t INPUT_IRQn[SYS_Num_Inputs] = {
      SWA_BUTTON_EXTI_IRQn,         \
      ROTARY_BUTTON_EXTI_IRQn,      \
      ROTARY_A_EXTI_IRQn,           \
      ROTARY_B_EXTI_IRQn,           \
      TX_LOOPBACK_EXTI_IRQn,        \
      SWB_BUTTON_EXTI_IRQn};

    SYS_Input_Init(SWA_BUTTON, INPUT_MODE_EXTI);
    SYS_Input_Init(SWB_BUTTON, INPUT_MODE_EXTI);
    SYS_Input_Init(BUTTON_ROTARY, INPUT_MODE_EXTI);
    SYS_Input_Init(ROTARY_A, INPUT_MODE_EXTI);
    SYS_Input_Init(ROTARY_B, INPUT_MODE_EXTI);
    SYS_Input_Init(TX_LOOPBACK, INPUT_MODE_EXTI);

    void SYS_Input_Init(Input_TypeDef SYS_Input, InputMode_TypeDef Input_Mode)
    {
      GPIO_InitTypeDef GPIO_InitStructure;
      EXTI_InitTypeDef EXTI_InitStructure;
      NVIC_InitTypeDef NVIC_InitStructure;

      /* Enable the SYS_Input Clock */
      RCC_AHBPeriphClockCmd(INPUT_CLK[SYS_Input], ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

      /* Configure SYS_Input pin as input */
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
      GPIO_InitStructure.GPIO_Pin = INPUT_PIN[SYS_Input];
      GPIO_Init(INPUT_PORT[SYS_Input], &GPIO_InitStructure);

      if (Input_Mode == INPUT_MODE_EXTI)
      {
        /* Connect SYS_Input EXTI Line to SYS_Input GPIO Pin */
        SYSCFG_EXTILineConfig(INPUT_PORT_SOURCE[SYS_Input], INPUT_PIN_SOURCE[SYS_Input]);

        /* Configure SYS_Input EXTI line */
        EXTI_InitStructure.EXTI_Line = INPUT_EXTI_LINE[SYS_Input];
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        if (SYS_Input == ROTARY_A || SYS_Input == ROTARY_B || SYS_Input == TX_LOOPBACK) 
        {
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
        }
        else
        {
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;    
        }
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);

        /* Enable and set SYS_Input EXTI Interrupt to the lowest priority */
        NVIC_InitStructure.NVIC_IRQChannel = INPUT_IRQn[SYS_Input];
        NVIC_InitStructure.NVIC_IRQChannelPriority = 0x03;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

        NVIC_Init(&NVIC_InitStructure); 
      }
    }


    void EXTI2_3_IRQHandler(void)
    {
      if(EXTI_GetITStatus(SWA_BUTTON_EXTI_LINE) != RESET)
      {
          swaFlag = 1;
          EXTI_ClearITPendingBit(SWA_BUTTON_EXTI_LINE);
      }
    }

    void EXTI0_1_IRQHandler(void)
    {
      if(EXTI_GetITStatus(ROTARY_BUTTON_EXTI_LINE) != RESET)
      {
        ButtonFlag = 1;
        EXTI_ClearITPendingBit(ROTARY_BUTTON_EXTI_LINE);
      }
    }

Best Answer

I've found the issue. It turns out it is not possible to trigger off the same pin on multiple GPIO ports. I was overwriting my PA3 interrupt with a PB3 one.

enter image description here