2021-04-26 04:38 AM
Hi,
I want to partially configure GPIO's using HAL and CubeMX. In my simple case, I just want to enable/disable the pull-up resistors while running a program.
At first I looked up, how the pins get initialized by CubeMX:
There's this structure, which you have to fill using all parameters.
typedef struct
{
uint32_t Pin; // Specifies the GPIO pins to be configured.
uint32_t Mode; // Specifies the operating mode for the selected pins.
uint32_t Pull; // Specifies the Pull-up or Pull-Down activation for the selected pins.
uint32_t Speed; // Specifies the speed for the selected pins.
uint32_t Alternate; // Peripheral to be connected to the selected pins
}GPIO_InitTypeDef;
=> I could use that, if I would be able to get the parameters I selected in CubeMX, but there's no such function as "void HAL_GPIO_Get_Config(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_InitTypeDef *GPIO_Init)"...
The next thing I heard of is the LL (low level) driver (https://community.st.com/s/question/0D50X00009Xkf0P/partially-configure-gpio-using-hal). It has a seperate function for setting the pull-up/pull-down seperatly:
void LL_GPIO_SetPinPull (GPIO_TypeDef * GPIOx, uint32_t Pin, uint32_t Pull);�?
That would be perfect, but you can use either HAL or LL ( Got that information here at 6.2: https://www.st.com/content/ccc/resource/technical/document/user_manual/10/c5/1a/43/3a/70/43/7d/DM00104712.pdf/files/DM00104712.pdf/jcr:content/translations/en.DM00104712.pdf). And I don't want to switch to LL just for a single function.
There's also no way to add custom "USER CODE BEGIN/END" sections to the gpio configuration to save the config from CubeMX... (https://community.st.com/s/question/0D50X0000ALxNlmSQF/is-it-possible-to-add-custom-user-code-sections)
Is there any other option than creating constant arrays with the GPIO settings from CubeMX and change them in code whenever I change them in CubeMX? I feel stupid doing this...
Thanks in advance!
Solved! Go to Solution.
2021-04-26 09:12 AM
For things like GPIO configuration and reading or setting pin states you can mix HAL and LL calls. A possible exception might be if the GPIO is also configured as EXTI (don't know, haven't tried that). After the HAL init code (MX_UARTx_init(), etc.), I use the LL funcions to change pullups/downs, and outputs to inputs and to read the value of the pins. Timers, UARTs, etc. are a different story and mixing HAL/LL for these will cause trouble.
2021-04-26 09:12 AM
For things like GPIO configuration and reading or setting pin states you can mix HAL and LL calls. A possible exception might be if the GPIO is also configured as EXTI (don't know, haven't tried that). After the HAL init code (MX_UARTx_init(), etc.), I use the LL funcions to change pullups/downs, and outputs to inputs and to read the value of the pins. Timers, UARTs, etc. are a different story and mixing HAL/LL for these will cause trouble.
2021-04-26 11:42 AM
Which STM32?
> just want to enable/disable the pull-up resistors while running a program.
CubeMX is a clicky program to configure the chip, mainly as startup, so you shouldn't really expect it to generate runtime code.
Also, by using a "library" such as Cube/HAL, you accept that it inevitably caters only for a very limited subset of the virtually infinite number of ways how a hardware can be used; mainly "typical cases", as judged by the library's authors. Sure, you can slap on your code - Cube is open source after all, you can read it and even modify it at your will - but then don't be surprised if the same code you used for convenience will later bite you.
But pullups/pulldowns should be pretty straighforward. You can use the LL functions as BobS suggested above, or you can directly access registers. Some of similar operations have macros defined in Cube/HAL, these don't appear to have those. And, from the functionality point of view, there's also nothing wrong with calling HAL_GPIO_Init with the same init struct you've used for initializing the given pin (simply make it global), with modified Pull field - this would probably be the true Cube/HAL-ish approach, bloated and inefficient. Don't forget about atomicity (i.e. if you modify them both in interrupt and "main", or interrupts of different priority, or in any multitasking environment a.k.a. RTOS, you have to consider what happens if a RMW operation is interrupted by another RMW operation).
JW
2021-04-27 12:13 AM
Thanks for your advice, that solved my problem!
I manually added the LL gpio drivers from the Cube Repository (Drivers\STM32L4xx_HAL_Driver) to my project.
Using the following function, I can set the pull-up/pull-down correctly:
void LL_GPIO_SetPinPull (GPIO_TypeDef * GPIOx, uint32_t Pin, uint32_t Pull);�?
FYI: It's no EXTI, so I also don't know yet, if that would be possible.
2021-04-27 12:29 AM
> Which STM32?
STM32L433VCT
> CubeMX is a clicky program to configure the chip, mainly as startup, so you shouldn't really expect it to generate runtime code.
That's a bit sad, because it saves me a lot of time in most of the cases. In this case it would be nice to have a checkbox for every peripherial in CubeMX like "Generate parameter settings globaly". I think it is possible to do productive programming and save a lot of time with CubeMX if you can deal with the few bugs.
> Cube is open source after all, you can read it and even modify it at your will
Oh nice, I didn't know that. I will keep it in mind!
> this would probably be the true Cube/HAL-ish approach, bloated and inefficient.
This is why I chose what Bob S suggested. Probably the best/easiest approach here.
2021-04-27 12:43 AM
> no EXTI, so I also don't know yet, if that would be possible.
Yes, although again not something you'd just click in CubeMX.
JW
2021-04-27 12:46 AM
> I think it is possible to do productive programming and save a lot of time with CubeMX if you can deal with the few bugs.
It's not exactly bugs which you should be worried about, but the "clash of concepts". If you do something the Cube/HAL (or for that matter, any "library") authors did not anticipate, you can run into problems; and then you do double work: not only you have to understand the "library", but also the chip itself, which easily defeats the "saves me a lot of time in most of cases". YMMV.
Principially, the more Abstraction, the more constraints.
> it would be nice to have a checkbox for every peripherial in CubeMX like "Generate parameter settings globaly"
Consider submitting it as an "Idea".
JW
2021-04-27 01:00 AM
> Yes
Nice, thanks!
> although again not something you'd just click in CubeMX.
I have no problem at all with that.
2021-04-27 02:01 AM
> authors did not anticipate
Yeah, you're right. I ran into a few "problems" as I have to do a lot of energy-saving things. f.E. I did not find a HAL function to deactivate the SD clock, if the interface is unused.
Edit: I did find a macro to deactivate the SD clock in stm32l4xx_hal_rcc.h named __HAL_RCC_SDMMC1_CLK_DISABLE()
> not only you have to understand the "library", but also the chip itself
My goal is to understand the interface itself to be able to do anything, but I'll use Cube/HAL whenever I can.
> Consider submitting it as an "Idea".
I'll definitely do that, thanks for the link!