2025-02-28 6:11 PM - edited 2025-02-28 6:14 PM
I need a second pair of eyes. I am trying to setup EXTI using the GPIO HAL. But it looks like its doing it wrong. It must be me but I need you to double check to be sure.
This is STM32G0 HAL so stm32g0xx_hal_gpio.c
/*--------------------- EXTI Mode Configuration ------------------------*/
/* Configure the External Interrupt or event for the current IO */
if ((GPIO_Init->Mode & EXTI_MODE) != 0x00u)
{
temp = EXTI->EXTICR[position >> 2u];
temp &= ~(0x0FuL << (8u * (position & 0x03u)));
temp |= (GPIO_GET_INDEX(GPIOx) << (8u * (position & 0x03u)));
EXTI->EXTICR[position >> 2u] = temp;
In this code sample the macro GPIO_GET_INDEX is used. It takes the value "GPIO_TypeDef *GPIOx" and this value will enter the function as GPIOB, GPIOA etc. The macro is
#if defined(GPIOE)
#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0uL :\
((__GPIOx__) == (GPIOB))? 1uL :\
((__GPIOx__) == (GPIOC))? 2uL :\
((__GPIOx__) == (GPIOD))? 3uL :\
((__GPIOx__) == (GPIOE))? 4uL : 5uL)
#else
#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0uL :\
((__GPIOx__) == (GPIOB))? 1uL :\
((__GPIOx__) == (GPIOC))? 2uL :\
((__GPIOx__) == (GPIOD))? 3uL : 5uL)
#endif /* GPIOE */
There is no GPIOE so the second macro. The problem is if you pass in GPIOA you get a 0. 0s don't shift. So the statement
temp |= (GPIO_GET_INDEX(GPIOx) << (8u * (position & 0x03u)));
Will always result in a 0 for GPIOA. Which means EXTI is never setup for GPIOA. But even worse, GPIOB is also 1 position off. It seems this statement requires something indexed to 1 and not to 0. It is the result I am getting in my software. EXTI is not being setup correctly when I do this.
Am I misreading it??
2025-02-28 8:36 PM
GPIOA is selected when the field is zero, GPIOB is 1, etc. The statement before clears the field. Seems correct. Look at the description of exticr in the reference manual.