Typical HAL EXTI use cases for migration

This section presents the typical EXTI use cases for migration from HAL1 to HAL2.

Use case: Interrupt service routine

Sequence diagram

Interrupt service routine.

@startuml
participant "Application" as App
participant "GPIO" as GPIO
participant "EXTI" as EXTI
participant "NVIC" as NVIC

App -> GPIO: HAL_GPIO_Init()
App -> EXTI: HAL_EXTI_GetHandle()
App -> EXTI: HAL_EXTI_RegisterCallback()
App -> NVIC: HAL_NVIC_SetPriority()
App -> NVIC: HAL_NVIC_EnableIRQ()
EXTI -> App: GPIOx_Exti_FallingCb()
@enduml

Code snippet

HAL1

HAL2

GPIO_Init_TypeDef GPIO_InitStructure;
EXTI_HandleTypeDef EXTI_HandleStructure;


GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Pin = GPIO_PIN_13;

HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);

HAL_EXTI_GetHandle(&EXTI_HandleStructure, EXTI_LINE_13);






HAL_EXTI_RegisterCallback(&EXTI_HandleStructure,
                          HAL_EXTI_FALLING_CB_ID,
                          GPIOC_Exti_FallingCb);

HAL_NVIC_SetPriority(EXTI13_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI13_IRQn);
HAL_EXTI_Enable(&hexti, HAL_EXTI_MODE_INTERRUPT);


static void GPIOx_Exti_FallingCb(void)
{
  (...)
}
hal_gpio_config_t GPIO_ConfigStructure;
hal_exti_handle_t hexti;
hal_exti_config_t EXTI_ConfigStructure;

GPIO_ConfigStructure.mode = HAL_GPIO_MODE_INPUT;
GPIO_ConfigStructure.pull = HAL_GPIO_PULL_NO;


HAL_GPIO_Init(HAL_GPIOC, GPIO_PIN_13,
              &GPIO_ConfigStructure);

HAL_EXTI_Init(&hexti, HAL_EXTI_LINE_13);

EXTI_ConfigStructure.trigger = HAL_EXTI_TRIGGER_FALLING;
EXTI_ConfigStructure.gpio_port = HAL_EXTI_GPIOC;
HAL_EXTI_SetConfig(&hexti, &EXTI_ConfigStructure);

HAL_EXTI_RegisterTriggerCallback(&hexti,
                                 GPIOC_Exti_FallingCb);


HAL_NVIC_SetPriority(EXTI13_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI13_IRQn);

HAL_EXTI_Enable(&hexti, HAL_EXTI_MODE_INTERRUPT);

static void GPIOx_Exti_FallingCb(void)
{
  (...)
}

Key changes

  1. HAL2 separates configuration from initialization using HAL_EXTI_SetConfig() and requires explicit enabling using HAL_EXTI_Enable().

  2. HAL2 uses trigger-callback registration through HAL_EXTI_RegisterTriggerCallback().


Use case: Wake-up from stop mode with EXTI interrupt (WFI)

Sequence diagram

Wake-up from stop mode with EXTI interrupt (WFI).

@startuml

 !pragma teoz true

 == Prerequisites ==

 "Application" -> GPIO: HAL_GPIO_Init()
 "Application" -> EXTI: HAL_EXTI_GetHandle()
 "Application" -> EXTI: HAL_EXTI_RegisterCallback()
 "Application" -> NVIC: HAL_NVIC_SetPriority()
 "Application" -> NVIC: HAL_NVIC_EnableIRQ()

 == Enter STOP Mode ==

 "Application" -> "PWR":  **HAL_PWR_EnterSTOP0Mode( PWR_STOPENTRY_WFI);**
 "PWR" --> "Application": MCU enters Stop Mode
 {start} "Application" <- "Application"
 ...
 ...
 ...
 {end} "Application" -> "Application"
 {start} <-> {end}: <i>MCU in Stop Mode
 == System wake-up from stop mode ==

 "EXTI IRQHandler" <- :  Interrupt

 "EXTI IRQHandler" --> "EXTI": "**HAL_EXTI IRQHandler(&hexti)**"
 "EXTI" -> "PWR": Wake-up the CPU from Stop Mode
 "EXTI" -> "Application": "**FallingCallback()** / **RisingCallback()**"

 @enduml

Code snippet

HAL1

HAL2

/* */

static void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOC_CLK_ENABLE();


    /*Configure GPIO pin : GPIO_PIN_13 */
    GPIO_InitStruct.Pin = GPIO_PIN_13;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);


    HAL_EXTI_GetHandle(&EXTI_HandleStructure, EXTI_LINE_13);









    HAL_EXTI_RegisterCallback(&EXTI_HandleStructure,
                              HAL_EXTI_FALLING_CB_ID,
                              GPIOC_Exti_FallingCb);
  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);


  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}






void EXTI13_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
}

















/* Enter STOP 0 mode */
HAL_PWREx_EnterSTOPMode(PWR_STOPENTRY_WFI);


static void GPIOx_Exti_FallingCb(void)
{
  (...)
}
static hal_exti_handle_t exti_line13_handle;

void *exti_init(void)
{
    /* GPIOC GPIO_PIN_13 Clock activation */
    hal_gpio_config_t config_gpio;
    hal_exti_config_t exti_config;

    MX_EXAMPLE_GPIO_TRIGGER_CLK_ENABLE();

    config_gpio.mode         = HAL_GPIO_MODE_INPUT;
    config_gpio.pull         = HAL_GPIO_PULL_NO;
    config_gpio.output_type  = HAL_GPIO_OUTPUT_OPENDRAIN;
    config_gpio.speed        = HAL_GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(HAL_GPIOC, HAL_GPIO_PIN_13, &config_gpio);

    if (HAL_EXTI_Init(&exti_line13_handle, HAL_EXTI_LINE_13) != HAL_OK)
    {
        return NULL;
    }

    exti_config.trigger = HAL_EXTI_TRIGGER_FALLING;
    exti_config.gpio_port = HAL_EXTI_GPIOC;

    HAL_EXTI_SetConfig(&exti_line13_handle, &exti_config);


    HAL_EXTI_RegisterTriggerCallback(&hexti,
                                     GPIOC_Exti_FallingCb);


    HAL_CORTEX_NVIC_SetPriority(MX_EXAMPLE_EXTI_TRIGGER_EXTI_IRQ_N,
                                HAL_CORTEX_NVIC_PREEMP_PRIORITY_0,
                                HAL_CORTEX_NVIC_SUB_PRIORITY_0);
    HAL_CORTEX_NVIC_EnableIRQ(MX_EXAMPLE_EXTI_TRIGGER_EXTI_IRQ_N);

    HAL_EXTI_Enable(&hexti, HAL_EXTI_MODE_INTERRUPT);

    return (void *)&exti_line13_handle;
}

void EXTI13_IRQHandler(void)
{
  HAL_EXTI_IRQHandler(&exti_line13_handle);
}

uint32_t mx_power_config(void)
{
    uint32_t config_status = 0;

    config_status = HAL_PWR_SetMainRegulatorSupply(HAL_PWR_MAIN_REGULATOR_SMPS_SUPPLY);

    HAL_PWR_SetMainRegulatorStartupMode(HAL_PWR_MAIN_REGULATOR_FAST_STARTUP);

    HAL_PWR_SetCoreSleepMode(HAL_PWR_CORE_DEEP_SLEEP);

    return config_status;
}


    /* Enter STOP0 Mode */
    HAL_PWR_EnterStopMode(HAL_PWR_LOW_PWR_MODE_WFI,
                          HAL_PWR_STOP0_MODE);

static void GPIOx_Exti_FallingCb(void)
{
  (...)
}

Key changes

  1. HAL2 uses explicit EXTI initialization and configuration (HAL_EXTI_Init() + HAL_EXTI_SetConfig()) instead of handle retrieval.

  2. HAL2 requires explicit line enabling using HAL_EXTI_Enable() before entering stop mode.


Use case: Generate a software interrupt

Sequence diagram

Generate a software interrupt.

@startuml

== Initialization ==

"Application" -> GPIO: HAL_GPIO_Init()
"Application" -> EXTI: HAL_EXTI_GetHandle()
"Application" -> EXTI: HAL_EXTI_RegisterCallback()
"Application" -> NVIC: HAL_NVIC_SetPriority()
"Application" -> NVIC: HAL_NVIC_EnableIRQ()
"Application" -> EXTI: HAL_EXTI_SetConfigLine()


== Register Callback ==

"Application" -> "EXTI": **HAL_EXTI_RegisterCallback(&hexti, &user_cb)**
"EXTI" --> "Application": hal status: HAL_OK

== Generate a software interrupt ==

"Application" -> "EXTI": **HAL_EXTI_GenerateSW(&hexti)**
"EXTI" --> "Application": hal status: HAL_OK

@enduml

Code snippet

HAL1

HAL2

GPIO_InitTypeDef GPIO_InitStruct = {0};
/* EXTI handle instantiation */
EXTI_HandleTypeDef    *hexti;
/* EXTI Global Configuration structure */
EXTI_ConfigTypeDef *pExtiConfig;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();


/*Configure GPIO pin : GPIO_PIN_13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

HAL_EXTI_GetHandle(&EXTI_HandleStructure, EXTI_LINE_13);

/* Setting the EXTI configuration structure */
pExtiConfig->Line       = EXTI_LINE_13;
pExtiConfig->Mode       = EXTI_MODE_INTERRUPT;

/* Setting new values to the EXTI configuration structure */
HAL_EXTI_SetConfigLine(&hexti, &pExtiConfig);

HAL_EXTI_RegisterCallback(&EXTI_HandleStructure,
                          HAL_EXTI_FALLING_CB_ID,
                          GPIOC_Exti_FallingCb);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);


HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);





/* Generate the software interrupt signal */
HAL_EXTI_GenerateSWI(&hexti);

static void GPIOx_Exti_FallingCb(void)
{
  (...)
}
void *exti_init(void)
{
    /* GPIOC GPIO_PIN_13 Clock activation */
    hal_gpio_config_t config_gpio;
    hal_exti_config_t exti_config;

    MX_EXAMPLE_GPIO_TRIGGER_CLK_ENABLE();

    config_gpio.mode         = HAL_GPIO_MODE_INPUT;
    config_gpio.pull         = HAL_GPIO_PULL_NO;
    config_gpio.output_type  = HAL_GPIO_OUTPUT_OPENDRAIN;
    config_gpio.speed        = HAL_GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(HAL_GPIOC, HAL_GPIO_PIN_13, &config_gpio);

    if (HAL_EXTI_Init(&exti_line13_handle, HAL_EXTI_LINE_13) != HAL_OK)
    {
        return NULL;
    }

    exti_config.trigger = HAL_EXTI_TRIGGER_FALLING;
    exti_config.gpio_port = HAL_EXTI_GPIOC;

    HAL_EXTI_SetConfig(&exti_line13_handle, &exti_config);

    HAL_EXTI_RegisterTriggerCallback(&hexti,
                                    GPIOC_Exti_FallingCb);


    HAL_CORTEX_NVIC_SetPriority(MX_EXAMPLE_EXTI_TRIGGER_EXTI_IRQ_N,
                                HAL_CORTEX_NVIC_PREEMP_PRIORITY_0,
                                HAL_CORTEX_NVIC_SUB_PRIORITY_0);
    HAL_CORTEX_NVIC_EnableIRQ(MX_EXAMPLE_EXTI_TRIGGER_EXTI_IRQ_N);

    HAL_EXTI_Enable(&hexti, HAL_EXTI_MODE_INTERRUPT);

    return (void *)&exti_line13_handle;
}

/* Generate the software interrupt signal on the selected EXTI line */
HAL_EXTI_GenerateSWI(&hexti);

static void GPIOx_Exti_FallingCb(void)
{
  (...)
}

Key changes

  1. HAL2 configures the EXTI line through HAL_EXTI_Init() and HAL_EXTI_SetConfig() and requires explicit enabling via HAL_EXTI_Enable().

  2. HAL2 uses HAL_EXTI_RegisterTriggerCallback() for trigger callbacks instead of the generic callback registration in HAL1.