Skip to main content
sak hos
Associate II
August 21, 2017
Solved

STM32F103c8t6 external interrupt issue

  • August 21, 2017
  • 7 replies
  • 2570 views
Posted on August 21, 2017 at 17:03

hello,

i'm facing a strange issue, i'm using STM32F103c8t6 and i'm trying to use external interrupt (please take a look the configuration below), the issue is when i trigger the interruption only one time, the callback(HAL_GPIO_EXTI_Callback) is called twice in a row

does anyone have an idea about this

thank you

/*******************************************************************/

void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOD_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

/*Configure GPIO pin : PA1 */

GPIO_InitStruct.Pin = GPIO_PIN_1;

GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;//GPIO_MODE_IT_RISING_FALLING;//GPIO_MODE_IT_RISING;

GPIO_InitStruct.Pull = GPIO_PULLDOWN;//GPIO_NOPULL;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/*Configure GPIO pins : PB0 PB12 PB15 PB5

PB6 PB7 PB8 PB9 */

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_12|GPIO_PIN_15|GPIO_PIN_5

|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;

GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;

GPIO_InitStruct.Pull =GPIO_PULLDOWN; //GPIO_NOPULL;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* EXTI interrupt init*/

HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI0_IRQn);

HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI1_IRQn);

HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

}

/********************************************************************************/

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

switch (GPIO_Pin)

{

case GPIO_PIN_0:/*BEGIN_END_OF_COMPETITION*/

MessageToBSent.Command=BEGIN_END_OF_COMPETITION;

MessageToBSent.DestinationAddress=BROADCAST_ADDRESS;

Send_Command_To_Modules (&MessageToBSent);

break;

case GPIO_PIN_1:/*START_COMPETITION or STOP_COMPETITION*/

if (StartStopCompetitionButtonLastValue==STOP_COMPETITION)

{

MessageToBSent.Command=START_COMPETITION;

MessageToBSent.DestinationAddress=TIMER_MODULE_ADDRESS;

Send_Command_To_Modules (&MessageToBSent);

StartStopCompetitionButtonLastValue=START_COMPETITION;

break;

}

}

}

    This topic has been closed for replies.
    Best answer by Tesla DeLorean
    Posted on August 21, 2017 at 17:18

    Review the IRQHandler code an how it qualifies, and clears the source.

    IRQs can reenter if the last thing you do is clear the interrupt source. Do that after you've qualified the source, and before you call back into the HAL

    7 replies

    Tesla DeLorean
    Tesla DeLoreanBest answer
    Guru
    August 21, 2017
    Posted on August 21, 2017 at 17:18

    Review the IRQHandler code an how it qualifies, and clears the source.

    IRQs can reenter if the last thing you do is clear the interrupt source. Do that after you've qualified the source, and before you call back into the HAL

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    sak hos
    sak hosAuthor
    Associate II
    August 21, 2017
    Posted on August 21, 2017 at 18:02

    Hi Clive One ,

    thanks it's done

    i added __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); as mentioned bloow and now i have only one call of HAL_GPIO_EXTI_Callback(GPIO_Pin);

    /******************************************/

    void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)

    {

    /* EXTI line interrupt detected */

    if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)

    {

    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);

    HAL_GPIO_EXTI_Callback(GPIO_Pin);

    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); /*added*/

    }

    }

    /******************************************/

    but can you explain to me how can this happen

    thanks a lot
    Bob Boys
    Visitor II
    August 21, 2017
    Posted on August 21, 2017 at 17:34

    Hello

    Please give this a try:

    http://www.keil.com/support/docs/3928.htm

     

    Thanks

    Bob Boys

    on holidays in Ontario, Canada

    waclawek.jan
    Super User
    August 21, 2017
    Posted on August 21, 2017 at 18:11

    If I understand Cube correctly, this is not the case.

    /**

      * @brief  This function handles EXTI interrupt request.

      * @param  GPIO_Pin: Specifies the pins connected EXTI line

      * @retval None

      */

    void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)

    {

      /* EXTI line interrupt detected */

      if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)

      {

        __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);

        HAL_GPIO_EXTI_Callback(GPIO_Pin);

      }

    }

    I'd suspect the interrupt source to be bouncy.

    JW

    Bob Boys
    Visitor II
    August 21, 2017
    Posted on August 21, 2017 at 19:36

    Hello

    This often looks just like a bouncy switch but it is not necessarily so.

    The article I pointed to explains what is going on.

    I came across this in one of the first STM32 processors about 10 years ago and someone encountered it a few weeks again.  In my case, I had a switch on a GPIO pin that generated an EXTI interrupt for a demo.

    So, we made a new appnote explaining several solutions.

    In the other case someone had, they were using GCC, the problem did not show up until some optimization was applied and the code got a lot smaller and the double interrupt appeared.  Using Keil and IAR, the problem showed immediatley with no optimization because these compilers happened to produce smaller code at the end of the interrupt handler.

    It seems a lot of instructions near the end of the handler can make this problem disappear.

    The best solution is apparently a dummy write is the solution across a wide variety of Cortex-M processors.

    A DSB instruction can be effective too.

    Bob

    waclawek.jan
    Super User
    August 21, 2017
    Posted on August 21, 2017 at 23:17

    The best solution is apparently a dummy write is the solution across a wide variety of Cortex-M processors.

    No; see attachment. Comments welcome.

    The ARM guys tend to see their processor as the pinnacle of complexity, despising the surrounding circuitry.

    JW

    ________________

    Attachments :

    m1.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HyUB&d=%2Fa%2F0X0000000b8U%2FA9FxkgJZVZJRojPNCikGuo2uI0r_JvVL1kBHA0yFUNU&asPdf=false
    waclawek.jan
    Super User
    August 21, 2017
    Posted on August 21, 2017 at 19:41

    The fact that an added flag clear *after* the bulk of ISR helped, confirms that it's not the case of late flag clear, but another interrupt arriving during that bulk.

    JW