cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F207 EXTI interrupts

gary239955_stm1
Associate II
Posted on September 28, 2011 at 18:21

I have recently migrated to the STM32F207 MCU. Everything is going very well except that I am having a big problem with EXTI interrupts. My hardware originally had PC13 and PC15 as interrupt sources and everything worked OK into EXTI13 and EXTI15 (falling edge interrupts - EXTI 10->15 vector). A hardware revision meant that PC15 had to be moved to PG14. Therefore PC13 is still configued for falling edge interrupts on EXTI13 but PG14 is now configured for falling edge interrupts on EXTI14 instead of PC15 on EXTI15. When I run my code it code gets stuck in the EXTI10_15 ISR with an IRQ pending on EXTI14 (PG14) and the interrupt does not clear after writing 0x4000 to the EXTI interrupt pending register. Is there a bug in the silicon? It seems to work OK if EXTI group 10_15 is sourced by the same GPIO (i.e. GPIOC) but when sourcing it from different GPIOs (i.e. GPIOC and GPIOG) then I get the problem. A scope shows that PG14 is constant high so no interrupt should occur, yet I have a pending interrupt on EXTI14 that will not clear. Any ideas?

3 REPLIES 3
gary239955_stm1
Associate II
Posted on September 29, 2011 at 12:02

Further investigation has shown that the cause of this is as follows:

The initialisation code below may be called more than once so the ST library function SYSCFG_EXTILineConfig() can be called a second time to reconfig the EXT line even though it's already configured. Therefore the functions clears and then sets the relevant bits in the SYSCFG->EXTICR register. If the EXTI interrupts are already enabled then the act of clearing the bit causes an interrupt but this behaviour doesn't seem to occur on all EXT lines only some. The ISR is unable to clear the IRQ pending because of the state of SYSCFG->EXTICR. In some cases the App then becomes interrupt-bound but on some EXT lines it doesn't. This seems like a bug in the micro. Obviously the workaround is to ensure that the EXTI line is only initialised once.

        // Enable SYSCFG clock

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

#if defined (PCB_ISSUE_1)

        // Connect EXTI Line to PC13 and PC15

        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource13);

        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource15);

#else

        // Connect EXTI Line to PC13 and PG14

        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource13);

        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOG, EXTI_PinSource14);

#endif

        // Configure EXTI Line

#if defined (PCB_ISSUE_1)

        EXTI_InitStructure.EXTI_Line = EXTI_Line13 | EXTI_Line15;   // connected to Px13 and Px15

#else

        EXTI_InitStructure.EXTI_Line = EXTI_Line13 | EXTI_Line14;   // connected to Px13 and Px14

#endif

        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; 

        EXTI_InitStructure.EXTI_LineCmd = ENABLE;

#if defined (PCB_ISSUE_1)

        EXTI_ClearITPendingBit( EXTI_Line13 | EXTI_Line15 );

#else

        EXTI_ClearITPendingBit( EXTI_Line13 | EXTI_Line14 );

#endif

        EXTI_Init(&EXTI_InitStructure);

        // Configure EXTI Interrupt (lines 15 to 10)

        NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;

        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

        NVIC_InitStructure.NVIC_IRQChannelSubPriority = IRQ_PRIORITY_EXTI15_10;

        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

        NVIC_Init(&NVIC_InitStructure);

celdran
Associate II
Posted on October 13, 2011 at 16:27

Hi,

I have quite the same problem with the same processor.

I'm using a STM3220G eval board, and run RTX OS from Keil. USB and FS are working fine, and I'm trying to add an external interrupt via the Key button (on Pin PG15).

The interrupt handler only send a semaphore to a task. But in the interrupt handler, it seems that the IT pending bit is never reset.

Here is the code of the handler :

/*-----------------------------------------------------------------------------

  Interruption Line 15

 *----------------------------------------------------------------------------*/

void EXTI15_10_IRQHandler (void) __irq

{

  if(EXTI_GetITStatus(EXTI_Line15) != RESET)

  {

    /* Clear the EXTI line 15 pending bit */

    EXTI_ClearITPendingBit(EXTI_Line15);

    

        /* Toggle LED1 */

    STM_EVAL_LEDToggle(LED1);

    

        /*Send Semaphore */

        isr_sem_send (semaphore1);

        cpt++;    

    }

}

and the initialization of the EXTI is here :

void EXTI_User_Button_Config(void)

{

  EXTI_InitTypeDef   EXTI_InitStructure;

  GPIO_InitTypeDef   GPIO_InitStructure;

  NVIC_InitTypeDef   NVIC_InitStructure;

  /* Enable GPIOG clock */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);

  /* Enable SYSCFG clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

 

  /* Configure PG15 pin as input floating */

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;

  GPIO_Init(GPIOG, &GPIO_InitStructure);

    

  /* Connect EXTI Line0 to PG15 pin */

  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOG, EXTI_PinSource15);

  /* Configure EXTI Line0 */

  EXTI_InitStructure.EXTI_Line = EXTI_Line15;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_ClearITPendingBit(EXTI_Line15);

    EXTI_Init(&EXTI_InitStructure);

  /* Enable and set EXTI Line15 Interrupt to the lowest priority */

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

The interrupt is triggerred, but as the bit is never reset, the semaphore is set lots of time before the task can use it : the OS generate then an overflow error.

When I disable USB and FS, the interrupt is working better, but not perfectly. It seems that it's triggerred twice sometimes (I light up a led in the interrupt and another in the task, and sometimes one is on and the other is off).

slrile05
Associate
Posted on November 12, 2011 at 05:49

If you go look at the actual code for that clear the pending bit function, it is not right. it just loads a value into the pending register, which does not reset the desired pending bit....

oops, nevermind, I looked at the ARM information center site, and that is how you clear the pending bit, you write a '1' to that bit.   The ARM site, says that if you write a '0' to the bit, it doesn't do anything.   so, there you have it!