cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeMX generates incorrect code for GPIO initialisation with LL-libraries (STM32F1xx)

SergK
Associate II

I beleive that I have discovered a bug where CubeMX v4.27.0 generates incorrect code for GPIO initialisation.

Here is the story:

Pins have been preconfigured via Pin Configuration menu in the CubeMX app the following way:

  • PC14 as Input with Pull-Up
  • PC15 as Output (push-pull) with Low Initial State

0690X000006CDVvQAO.png

Here is the code generated for MX_GPIO_Init() function with my comments added:

  /**/
  LL_GPIO_ResetOutputPin(GPIOC, DO_5V_ENABLE_Pin);  // DO_5V_ENABLE_Pin is set to be LOW here
 
  /* ... skipped ... */
 
  /**/
  GPIO_InitStruct.Pin = DI_5V_FUSE_STAT_Pin;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  LL_GPIO_Init(DI_5V_FUSE_STAT_GPIO_Port, &GPIO_InitStruct);
 
  /**/
  GPIO_InitStruct.Pin = DO_5V_ENABLE_Pin;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  LL_GPIO_Init(DO_5V_ENABLE_GPIO_Port, &GPIO_InitStruct);  // DO_5V_ENABLE_Pin goes HIGH after initialisation

As you see, the DO_5V_ENABLE_Pin ends up HIGH after initialisation although STM-code tried setting it LOW in the beginning.

Why?

Because the GPIO_InitStruct structure is re-used for each pin being configured but not all fields are initialised all the time.

It is obvious that line 9​ sets the 'Pull' field to HIGH and later, when another pin is configured as Output, the 'Pull' field is never updated but still gets written to the corresponding ODR-register by the LL_GPIO_SetPinPull() function called by the LL_GPIO_Init() function (file 'stm32f1xx_ll_gpio.c'):

      /* Pull-up Pull-down resistor configuration*/
      LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull);

That's how the pin set to have its initial value to be LOW ends up being HIGH as a result.

The solution is either to initialise all fields of the structure explicitly OR update the LL_GPIO_Initi() function so it only calls LL_GPIO_SetPinPull() function when we the pin Mode is set to Input, i.e. change this code in the 'stm32f1xx_ll_gpio.c' file:

      /* Pull-up Pull-down resistor configuration*/
      LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull);

to this code:

      /* Pull-up Pull-down resistor configuration - ONLY FOR INPUTS (STM bug fix) */
      if (GPIO_InitStruct->Mode == LL_GPIO_MODE_INPUT)
      {
    	  LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull);
      }

Hope it saves time someone ;)

Cheers.

#[STM32 MCUs]​ #STM32CubeMX​ #Ll-gpio​ 

6 REPLIES 6
Amel NASRI
ST Employee

Hi @SergK​ ,

Even in output mode, you should be able to set the pull value (No pull-up and no pull-down, pull-up, pull-down). So there is no need to update stm32f1xx_ll_gpio.c.

However, STM32CubeMX code should take care of initializing pull parameter in GPIO_InitStruct even if its value is the default one (No pull-up and no pull-down).

This is reported internally. Thanks.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

SergK
Associate II

Hi Amel,

Thanks for confirming my finding that STM32CubeMX code uses under-initialised structures to initialise hardware. I agree that full initialisation should solve the issue.

However, I think that your suggestion that "Even in output mode, you should be able to set the pull value" is sort of contradicting the hardware description of the output configuration. The 'STM32F10xxx Reference Manual (RM0008 Rev 19)' clearly says that "When the I/O Port is programmed as Output: The weak pull-up and pull-down resistors are disabled." (p.163). In addition, Figure 16 (Output Configuration) does not show any pull-ups or pull-downs in comparison to the Figure 15 (Input configuration):

0690X000006CDvPQAW.png

So, from programmer's point of view, configuring pull-up/pull-down for output looks a bit strange and unnecessary. However, it should be made clear that GPIO_InitStruct->Pull is actually defining the active output state of the pin (High or Low) if that pin has been defined as an Output earlier.

Thanks!

Houda GHABRI
ST Employee

Hello @SergK​ ,

Could you please send me your ioc ?

Best regards,

Houda

Sure, see attached.

Cheers

​Hi @SergK​ ,

Sorry for the delay to reply.

I have just payed attention that you are using STM32F1. The GPIO structure for this family is different of all others. So you are right: no pull-up/down in output mode for STM32F1 GPIOs.

I was confused, what I said is valid for other products than STM32F1.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

WBOUG
Senior

Hello @SergK​ 

Thank you very much for your feedback and sorry for late responce.

It will be corrected in next CubeMX version .

Best regards,

Wael