cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L073RZ GPIO EXTI Interrupt not triggering callback

Adam Mitchell
Associate II

I'm working with an STM32L073RZ on a custom board. The board is in STOP mode and I have a pin (PB_5) configured as a rising edge interrupt. I'm using ARM Mbed OS 5.12.0 but primarily working with the HAL API.

The code I have so far is below. It simply places the CPU into STOP mode and waits for a rising edge on PB_5. Main.h is just a bunch of pin definitions. I'm expecting pin PB_4 to toggle every time there is a rising edge on PB_5 and then go back to sleep.

#include "main.h"
 
void SystemClock_Config() {
    __HAL_RCC_PLL_DISABLE();
 
    __HAL_RCC_MSI_ENABLE();
 
    __HAL_RCC_MSI_RANGE_CONFIG(RCC_MSIRANGE_5);
    __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(0x00);
 
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
 
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
}
 
void Pwr_Config() {
    __HAL_RCC_PWR_CLK_ENABLE();
 
    __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
}
 
void GPIO_Config() {
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.Pin = GPIO_PIN_All;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
 
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();
    __HAL_RCC_GPIOE_CLK_ENABLE();  
 
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
 
    __HAL_RCC_GPIOA_CLK_DISABLE();
    __HAL_RCC_GPIOC_CLK_DISABLE();
    __HAL_RCC_GPIOD_CLK_DISABLE();
    __HAL_RCC_GPIOH_CLK_DISABLE();
    __HAL_RCC_GPIOE_CLK_DISABLE();
 
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
 
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 1);
    HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
 
    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
 
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);  
}
 
void StopMode_Enter() {
    HAL_PWREx_EnableUltraLowPower();
 
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
 
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
 
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4);
}
 
int main()
{
    SystemClock_Config();
    Pwr_Config();
    GPIO_Config();
    
    while(true) {
        StopMode_Enter();
    }  
}

As far as I'm aware, simply overriding the HAL_GPIO_EXTI_Callback function is the way to handle an interrupt, but the pin never toggles. What am I missing here? Ideally I'd like to simply set a flag for a state machine within the callback dependent on which pin I'm being interrupted from.

I believe the CPU is waking up as current consumption increases substantially when I apply a voltage to the interrupt pin and the CPU sleeps as soon as this voltage is removed but the callback function never appears to be serviced.

Thanks.

4 REPLIES 4
S.Ma
Principal

Hmm if you are in clock stop mode, I think you need to dig the WAKEUP pins specifically.

Check the reference manual for the functionality, then the datasheet for which pin has WAKEUP function.

Typically the user button on the nucleo is one of the wakeup pin.

Do you have the properly-named interrupt service routine? You could check this in the vector table in disassembly. If you complie this as C++, think about name mangling.

If so, does this ISR call the appropriate HAL function?

JW

As far as I'm aware, an interrupt on any EXTI line can wake the CPU when in STOP mode - it's only STANDBY mode that is limited to the WAKEUP pins? The CPU appears to be waking, just never entering the ISR.

I'm not sure where to start looking to be honest. Any pointers on how to obtain the disassembly from the output of the ARMC6 toolchain?