AnsweredAssumed Answered

Problem with STM32F427 and spurious EXTI interrupts

Question asked by rhodes.keith on Apr 11, 2017
Latest reply on May 3, 2018 by waclawek.jan

I use the following code to initialize the GPIO for EXTI interrupt handling.
I want GPIO F14 to trigger on the falling edge and most of the time it works properly.
However, every 1000 or so interrupts, the EXTI Interrupt routine is triggered and the
EXTI->PR register shows 0x4000, which inidicates Pin 14 was triggered.

However, the GPIO pin value is high, and a Scope shows the pin is also high (not
triggered).

When I hit the ASSERT in the interrupt routine, I examine the EXTI registers, the IMR and
FTSR registers are both 0xc000, which indicates only PIN 15 & 14 are configured.

The SYSCFG->EXTICR4 register is set to 0x5500, and all other CR registers are 0, which
indicates the interrupt didn't come from a different GPIO.

 

Anyone have any ideas? Do I have to mask the PR register value with the contents of the specific
GPIO to know that I am *really* triggered?
Is it possible the EXTI interrupt isn't being cleared on the previous request (even though
I don't see how)?

 

Thanks..Keith Rhodes

 


#define POWERDOWN_PORT       GPIOF // Powerdown signal
#define POWERDOWN_PIN          GPIO_PIN_15
#define POWER_DOWN_MASK    0b1000000000000000 // 0x8000
#define SPIREADY_PORT             GPIOF // SPI data ready
#define SPIREADY_PIN                GPIO_PIN_14
#define SPI_READY_MASK          0b0100000000000000 // 0x4000
#define POWERDOWN_               INT_PRIORITY 5

 

 

// Initialization code for EXTI interrupts
static void EXTILine13_15_Config(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;

   /* Configure PC15 pin as input floating */
   GPIO_InitStructure.Pin = POWERDOWN_PIN;
   GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
   GPIO_InitStructure.Pull = GPIO_PULLUP;
   GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
   GPIO_InitStructure.Alternate = 0;
   HAL_GPIO_Init(POWERDOWN_PORT, &GPIO_InitStructure);

 

   GPIO_InitStructure.Pin = SPIREADY_PIN;
   GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
   GPIO_InitStructure.Pull = GPIO_PULLUP;
   GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
   GPIO_InitStructure.Alternate = 0;

   HAL_GPIO_Init(SPIREADY_PORT, &GPIO_InitStructure);

   /* Enable and set EXTI15_10 Interrupt to the lowest priority */
   HAL_NVIC_SetPriority(EXTI15_10_IRQn, POWERDOWN_INT_PRIORITY, 0);
   HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

 

   // Reset all interrupts
   EXTI->PR = GPIO_PIN_All;
}

 

volatile unsigned int tempPR;
volatile unsigned int tempEXTIGPIO = 0;

// EXTI15-10 Interrupt handler
void EXTI15_10_IRQHandler(void)
{
   tempPR = EXTI->PR;
   tempEXTIGPIO = GPIOF->IDR;

   // BUG: This ASSERT triggers when I sometimes get an interrupt
   // without the GPIO value being low
   // tempPR has 0x4000 and tempEXTIGPIO has bit 14 set
   ASSERT((tempEXTIGPIO & SPI_READY_MASK) == 0);

   if(0 != (tempPR & POWER_DOWN_MASK))
   {
      PowerDownInterruptHandler();
      __HAL_GPIO_EXTI_CLEAR_IT(POWERDOWN_PIN);
   }

   if(0 != (tempPR & SPI_READY_MASK))
   {
      SpiNotifyInterruptHandler();
      __HAL_GPIO_EXTI_CLEAR_IT(SPIREADY_PIN);

   }
}

Outcomes