cancel
Showing results forĀ 
Search instead forĀ 
Did you mean:Ā 

HAL GPIO pins definitions seems weird? Useless for portable code?

DavidAlfa
Senior II

For example:

#define IO_Pin		GPIO_PIN_5
#define IO_Port		GPIOA

In stm32fxxx_hal_gpio.h:

#define GPIO_PIN_5	((uint16_t)0x0020) /* Pin 5 selected  */

Why do that? Setting an absolute number instead defining the pin number itself (5), which could be later converted using bit shifting (1<<5 = 0x20).

This makes much harder to make automated code.

So, if I quickly wanted to change IO_Pin to input or output, I can't simply make a quick mask operation into MODER register. The only way is to hardcode the number.

// Change IO_pin to OUTPUT mode.
IO_Port->MODER = (IO_Port->MODER & ~(uint32_t)(MODE_ANALOG<<10)) | (uint32_t)(MODE_OUTPUT<<10);
 
// Change IO_pin to INPUT mode.
IO_Port->MODER = (IO_Port->MODER & ~(uint32_t)(MODE_ANALOG<<10)) | (uint32_t)(MODE_INPUT<<10);
 
// Change IO_pin to AF mode.
IO_Port->MODER = (IO_Port->MODER & ~(uint32_t)(MODE_ANALOG<<10)) | (uint32_t)(MODE_AF<<10);
 

This makes an issue for allowing portable code that could be reconfigured by only changing the GPIO label in Cube MX.

Or there's something I'm missing out?

The ideal would be this, allowing changing the pin label while not needing to modify the code:

#define GPIO_PIN_5	5 /* Pin 5 selected  */
// Change IO_pin to OUTPUT mode.
IO_Port->MODER = (IO_Port->MODER & ~(uint32_t)(MODE_ANALOG<<(IO_Pin*2))) | (uint32_t)(MODE_OUTPUT<<(IO_Pin*2));
 
// Change IO_pin to INPUT mode.
IO_Port->MODER = (IO_Port->MODER & ~(uint32_t)(MODE_ANALOG<<(IO_Pin*2))) | (uint32_t)(MODE_INPUT<<(IO_Pin*2));
 
// Change IO_pin to AF mode.
IO_Port->MODER = (IO_Port->MODER & ~(uint32_t)(MODE_ANALOG<<(IO_Pin*2))) | (uint32_t)(MODE_AF<<(IO_Pin*2));

2 REPLIES 2

I don't Cube but IMO the idea was to be able to OR these constants together if you want certain functions to manipulate several pins at once.

JW

I get the point of OR'ing them for their code, but it should be a method to get the GPIO index (0...15) out of the label you set in CubeMX.

Otherwise, the only alternative is hardcoding it.

Or making log2(IO_Pin) which is absolutely no sense:face_with_tears_of_joy: