cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F1 - LL_GPIO_Init() problem

Posted on March 17, 2018 at 20:45

Hi,

A piece of code from STM32CubeMX v4.0 and latest F1 drivers generated for STM32VLDiscovery (the button is pulled-down by external resistor):

static void MX_GPIO_Init(void)

{

LL_GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */

LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC);

LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOD);

LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);

GPIO_InitStruct.Pin = LL_GPIO_PIN_0;

GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;

LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

and the results from the Keil debugger:

0690X0000060A77QAE.png

So commented the line below to prove that there is only one line of code used for GPIOA initialization:

// LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

and got as expected (the default settings for GPIOA)

0690X0000060A9WQAU.png

It seems that the LL_GPIO_Init gives messy config on more than one pin. Am I wrong?

Have no luck with F1 line and LL drivers - this issue seems to be continuation of my previous finding:

https://community.st.com/message/190160-re-stm32cubemx-v4240-stm32f1-gpio-ll-led-blinking-fails?commentID=190160#comment-190160

--------------------------------

So switching back to register programming when working with boards with low SRAM size. It takes less time than investigating issues in LL drivers.

I wonder if you use LL drivers for F1 line. I know that more people prefer SPL drivers for this line.

Note: this post was migrated and contained many threaded conversations, some content may be missing.
18 REPLIES 18
Posted on March 18, 2018 at 10:25

Getting more confused, I found this in the LL documentation

void LL_GPIO_StructInit    (LL_GPIO_InitTypeDef *     GPIO_InitStruct)

Set each LL_GPIO_InitTypeDef field to default value.

So I changed my code to this:

LL_GPIO_StructInit(GPIOA);

GPIO_InitStruct.Pin = LL_GPIO_PIN_4|LL_GPIO_PIN_5;

GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;

LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

GPIO_InitStruct.Pin = LL_GPIO_PIN_3|LL_GPIO_PIN_6|LL_GPIO_PIN_7;

GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;

GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;

GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

As expected, before the LL_GPIO_StructInit(GPIOA) the settings of GPIOA looked like this

0690X00000604UJQAY.jpg

To my surprise the LL_GPIO_StructInit(GPIOA)  did this to the actual settings of GPIOA

0690X00000604UOQAY.jpg

I didn't expect any change at all, I thought it would only fill the structure with the defaults, not actually changing  anything in the uC. No doubt I (a hobbyist too) am doing things wrong but for me the docs are quite confusing.

And in the end it didn't help, GPIO_PIN_5 still got changed from input to output. The only thing that seems to help is configuring every GPIO_PIN separately.

EDIT: I'm starting to understand why it changes the actual GPIOA, but not with the values of it.

Posted on March 18, 2018 at 11:07

Not

LL_GPIO_StructInit(GPIOA);

but

LL_GPIO_StructInit(&GPIO_InitStruct);

JW

Posted on March 18, 2018 at 11:10

Ah, that makes sense!

Still learning 🙂

Unfortunately it doesn't help preventing

GPIO_InitStruct.Pin = LL_GPIO_PIN_3|LL_GPIO_PIN_6|LL_GPIO_PIN_7;

GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;

GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;

GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

from changing the settings for LL_GPIO_PIN_5

I'm also considering going back to register-programming. And I think that is a shame as reading the above lines is more explanatory than lines like this:

GPIOA->CRL &= ~GPIO_CRL_MODE0;

GPIOA->CRL |= GPIO_CRL_CNF0_0;

GPIOA->CRL |= GPIO_CRL_MODE1;

GPIOA->CRL &= ~GPIO_CRL_CNF1;

GPIOA->CRL |= GPIO_CRL_MODE2;

GPIOA->CRL &= ~GPIO_CRL_CNF2_0;

GPIOA->CRL |= GPIO_CRL_CNF2_1;
Posted on March 19, 2018 at 07:39

I mostly generate HAL skeleton for a project but in this case due to limited SRAM memory I wanted to use LL.

I used to use LL drivers for L0 boards ( I guess) and do not remember such basic problems with GPIO.

Going back to registers is good to re-fresh what is going on under the hood;)

Posted on March 19, 2018 at 11:16

'

Going back to registers is good to re-fresh what is going on under the hood;)'

in the end, going to registers may take you less time than necessary to understand and debug LL.

Posted on March 19, 2018 at 12:57

True, but for me there is the advantage of learning.

I'm a hobbyist who long ago programmed in assembler on the 6502, later also in asm on the atmel tiny and mega chips. Years later I switched to programming in C and only recently took the jump to STM

I started using the SPL but then I was told that that was a dead end (like now starting with python2) and that the Cube/HAL was the way forward.

But I do not like what it produces, eg the way interrupts are handled with callbacks. So LL it was, as it 'looks' better than register programming.

I am a hobbyist, I don't care how long something takes to get working, I don't get payed for it anyway. When something doesn't work as expected I love the search for why. Usually I'm the cause. Sometimes Im not. And I learn in both cases. So thanks for all the help from the pro's here.

STOne-32
ST Employee
Posted on March 19, 2018 at 15:58

Dear all,

Thank you for the comments and opening the discussion on this GPIO LL driver limitation.  Indeed, we confirm the issue , and we confirm it  is fixed  in STM32CubeF1 Firmware patch Package V1.6.1 which will be in a couple of days on public  web site and available in CubeMx to download as well.  

Cheers,

STOne-32

Posted on March 19, 2018 at 16:21

Thank you for letting us know!

Posted on March 19, 2018 at 17:07

Just tested STM32CubeF1 Firmware patch Package V1.6.1 - GPIO works fine.

Thanks,