22
\$\begingroup\$

I started studying interrupts on stm32 specifically the stm32f4 discovery board. i found this example in which you have to press the button to start the interrupt and push it again to stop it.

In this line:EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt we have to choose either the interrupt mode or the event mode. I changed it to event mode but it doesn't seem to work .So i came out with the conclusion that the handler is executed with interrupts only.

Why do we then use Events on stm32 if you can't execute some code when they happens?

Here is the code:

#include "stm32f4xx.h"
#include "stm32f4xx_syscfg.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_exti.h"
#include "misc.h"

EXTI_InitTypeDef   EXTI_InitStructure;

void EXTILine0_Config(void);
void LEDInit(void);

void ExtInt(void)
{
    LEDInit();

    /* Configure EXTI Line0 (connected to PA0 pin) in interrupt mode */
    EXTILine0_Config();

    /* Generate software interrupt: simulate a rising edge applied on EXTI0 line */
    EXTI_GenerateSWInterrupt(EXTI_Line0);

    while (1)
    {
    }
}

/**
 * @brief  Configures LED GPIO.
 */
void LEDInit()
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    /* Enable the GPIO_LED Clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    /* Configure the GPIO_LED pin */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
}

/**
 * @brief  Configures EXTI Line0 (connected to PA0 pin) in interrupt mode
 */
void EXTILine0_Config(void)
{
    GPIO_InitTypeDef   GPIO_InitStructure;
    NVIC_InitTypeDef   NVIC_InitStructure;

    /* Enable GPIOA clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    /* Enable SYSCFG clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Configure PA0 pin as input floating */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Connect EXTI Line0 to PA0 pin */
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

    /* Configure EXTI Line0 */
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /* Enable and set EXTI Line0 Interrupt to the lowest priority */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/**
 * @brief  This function handles External line 0 interrupt request.
 */
void EXTI0_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        /* Toggle LED1 */
        GPIO_ToggleBits(GPIOD, GPIO_Pin_12);

        /* Clear the EXTI line 0 pending bit */
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

/**
 * @}
 */

/**
 * @}
 */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

int main(void)
{
    while(1)
    {
    }
}
```
\$\endgroup\$

2 Answers 2

19
\$\begingroup\$

Sometimes finding the answer to these questions for an ARM device can be more difficult than simpler microcontrollers because the information is often spread across family and programming guides rather than included in the datasheet. In this case the answer appears to be on page 381 of the RM0090 Reference manual:

The STM32F4xx are able to handle external or internal events in order to wake up the core (WFE). The wakeup event can be generated either by:

  • (I've removed normal external interrupt mode details)

  • or configuring an external or internal EXTI line in event mode. When the CPU resumes from WFE, it is not necessary to clear the peripheral interrupt pending bit or the NVIC IRQ channel pending bit as the pending bit corresponding to the event line is not set.

So it appears the main purpose is to enable wakeups without generating an interrupt or having to respond to interrupts during normal operation.

It's not mentioned in that guide and I'm not sure how applicable is to the STM32 architecture but on some other devices similar schemes can be useful to catch fast events without generating an interrupt. For example you may have an application where it's important to capture that a sub-microsecond event has occurred, but there's no need to respond to it quickly so you can just check a flag to see if it's occurred.

Edit: (5/2018) As of today, page number of referenced text is page 381 (formerly page 377)

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Yeah, on PICs it seems that much of what I do in an interrupt is set flags. In Cortex, most of those flags get set without having to interrupt, so I use less interrupts \$\endgroup\$ Jun 11, 2014 at 10:45
14
\$\begingroup\$

Why do we then use Events on stm32 if you can't execute some code when they happens?

Interrupts will typically be used to execute a few lines of code by the ARM core (NVIC, interrupt handlers, etc.).

Events don't necessary execute code but can signal another peripheral to do something without processor intervention. For example, a periodic timer can generate an event to tell an ADC to sample and then write the measured value to memory using DMA without ever waking up the ARM core processor (no code executed...in theory).

So interrupts involve code execution. Events don't necessarily require code execution.

\$\endgroup\$
2
  • \$\begingroup\$ You mean there exist dedicated buses to route events between peripherals? If so I have a question is there any event multiplexer in between? the routings are standalone? Is there any ARM or STM32 explanation about it? \$\endgroup\$ May 17, 2022 at 5:40
  • \$\begingroup\$ @mohammadsdtmnd I've yet to see configurable events on an stm32. Usually they are hardwired/hardconfigured to specific other peripherals (e.g. many are wired to the DMA, timers to ADCs etc.) and can be enabled in the peripheral registers when needed. \$\endgroup\$
    – CShark
    Dec 11, 2022 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.