cancel
Showing results for 
Search instead for 
Did you mean: 

GPIO HAL Sanity Check

Carl_G
Senior

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??

2 REPLIES 2
TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".
Carl_G
Senior
Spoiler
 

I guess i was confused because the reference manual says "these bits are written" implying its bitwise. But with PD being 3 it can't be bitwise.  This implies only one of any given numbered port can trigger an interrupt or be a wakeup. So either PA6 or PB6 or PC6 but only one of them. No one has ever mentioned this in their lessons or videos...

 

This is a bit strange though isn't it? If its not bitwise why the &=~ and the |=  Why even care about the previous value if its not bitwise?