Skip to main content
amomum
Associate III
September 27, 2017
Solved

Bug in LL library for stm32f1xx

  • September 27, 2017
  • 6 replies
  • 5073 views
Posted on September 27, 2017 at 19:03

I want to turn on the led attached to PC.9. I do this:

    LL_GPIO_InitTypeDef initStruct;

    LL_GPIO_StructInit( &initStruct );

    

    initStruct.Mode = LL_GPIO_MODE_OUTPUT_10MHz;

    initStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

    initStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;

    initStruct.Pin = LL_GPIO_PIN_9; // that equals 0x04020002

    

    LL_GPIO_Init( GPIOC, &initStruct )

This code will actually init PC.2 (not PC.9 as it's supposed to) to output push-pull.

Why? LL_GPIO_Init does this:

    pinpos = POSITION_VAL(GPIO_InitStruct->Pin);

where

    &sharpdefine POSITION_VAL(VAL)     (__CLZ(__RBIT(VAL)))

so pinpos will be equal to 

(__CLZ(__RBIT(

0x04020002

))) which is equal to 1.

Then current pin will be calculated like this:

    currentpin = (GPIO_InitStruct->Pin) & (0x00000101U << pinpos);

so currentpint will be equal to 2.

And then

    LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode);

will be called, despite the fact that LL_GPIO_SetPinMode should only accept parameters like LL_GPIO_PIN_x.

Reasons:

  •   all inline functions in header files do not check their arguments with assert_param, so this error was not caught early
  •   lack of proper (i.e. automatic) testing?
  •   lack of public bugtracker

I have already posted this bug here but it got mixed up with my own ignorance and stupidity so I haven't got a proper reaction. I believe it's time to post it again.

#hal-ll #ll-bug #software-error #bug #ll #stm32f1
This topic has been closed for replies.
Best answer by Bogdan Golab
Posted on March 19, 2018 at 17:08

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

6 replies

Simon Brouwer
Visitor II
January 31, 2018
Posted on January 31, 2018 at 22:43

Just starting with STM32, my first 'blinky' program didn't work because of this same issue.

LL_GPIO_Init() is a bit of a mess. I changed it to make it work better. The key is looking at (only) bits 8..23

in GPIO_InitStruct->Pin to determine which of the I/O pins are requested.

By the way, I was puzzled that the function called LL_GPIO_SetPinSpeed() and LL_GPIO_SetPinOutputType() when mode

is LL_GPIO_MODE_FLOATING. Is there any way that could make sense, or is it indeed better to call these functions only

when the mode is LL_GPIO_MODE_OUTPUT ?

Below is the modified code for LL_GPIO_Init()

ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct)

{

  uint32_t pinmask;

  uint32_t pinpos;

  uint32_t currentpin;

  /* Check the parameters */

  assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));

  assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin));

  assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode));

  assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull));

  /* make bitmask in which, for each requested I/O pin n, bit n is set */

  pinmask =    (GPIO_InitStruct->Pin & 0x00FFFF00U) >> 8 ;

  /* Initialize  pinpos on first bit that is set */

  pinpos = POSITION_VAL(pinmask);

  /* loop while any pins are left to configure */

  while (( pinmask >> pinpos) != 0U)

  {

    /* skip if bit is not set */

    if ((pinmask & (1U << pinpos)) == 0U)

    {

        pinpos++;

        continue;

    }

    /* with pinpos the number of an I/O pin to configure, */

    /* calculate the corresponding value of type GPIO_LL_EC_PIN (see stm32f1xx_ll_gpio.h) */

    if (pinpos < 8 )

      currentpin = (0x00000101U << pinpos);

    else

      currentpin = ((0x00010001U << (pinpos-8)) | 0x04000000U);

    /* Pin Mode configuration */

    LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode);

    /* Pull-up / Pull-down resistor configuration*/

    LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull);

    if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) /*|| (GPIO_InitStruct->Mode == LL_GPIO_MODE_FLOATING)*/)

    {

      assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType));

      /* Speed mode and output type configuration */

      LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed);

      LL_GPIO_SetPinOutputType(GPIOx, currentpin, GPIO_InitStruct->OutputType);

    }

    pinpos++;

  }

  return (SUCCESS);

}
Bogdan Golab
Lead
February 2, 2018
Posted on February 02, 2018 at 07:32

Looks the same as mine:

https://community.st.com/0D50X00009XkYowSAF

Simon Brouwer
Visitor II
February 2, 2018
Posted on February 02, 2018 at 16:00

I think so. The LL_GPIO_Init() generated by the current version of STM32CubeMX is broken for any pin numbers above 7.

ST Technical Moderator
February 6, 2018
Posted on February 06, 2018 at 10:31

Hello,

We will take in charge  to check and raise this issue internally to the appropriate team.

Thanks for your contribution to highlight this issue.

Best Regards,

Imen.

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
loeffel2
Associate III
February 19, 2018
Posted on February 19, 2018 at 08:43

Hi

We run into the same issue and found this forum entry, which confirmed our observed behavior of the LL for STM32F1xx devices. 

Has anybody a workaround to fix the issue?

Best regards Raphael

Bogdan Golab
Lead
February 19, 2018
Posted on February 19, 2018 at 08:58

Quick fix is mentioned by me here:

https://community.st.com/0D50X00009XkYowSAF

In my case (PC13, PC15) I set the bits manually:

GPIOC->CRH = 0x24244444

Have no time to fix LL lib as it's time consuming and boring.

loeffel2
Associate III
February 19, 2018
Posted on February 19, 2018 at 09:17

Dear Bogdan Golab

Thanks for the response and the hint to do it manually.

We generated the initial code with CubeMx for about 100pins and different peripheries. So to replace them manually is not fun. It looks like that we have to fix the LL or to switch back to the SPL.  

Best regards Raphael

Bogdan Golab
Lead
March 16, 2018
Posted on March 16, 2018 at 19:20

Just tested a STM32VLDIscovery board and the issue still exists in CubeMX 4.25.0 with the v1.6.0 HAL/LL drivers.

Bogdan Golab
Bogdan GolabBest answer
Lead
March 19, 2018
Posted on March 19, 2018 at 17:08

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

ST Technical Moderator
March 22, 2018
Posted on March 22, 2018 at 09:53

Hello,

We would inform you that the new patch of STM32CubeF1 Firmware package V1.6.1 is released to fix this issue.

Best Regards

Imen

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
amomum
amomumAuthor
Associate III
March 27, 2018
Posted on March 27, 2018 at 12:51

I'm glad that this issue is finally fixed but I'm startled that we still have to use community forum to submit issues about code. Moderators have to manually search for bugs and repost them in bug-tracker, users have to wait for several months just to be noticed!

Please, ST, please, make bug-tracker for code public! Or - better - make repository public (all of the code is open-source anyway, so why hide it?), a lot of the users will be glad to help with code.