cancel
Showing results for 
Search instead for 
Did you mean: 

Bug in LL library for stm32f1xx

amomum
Associate III
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
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on March 19, 2018 at 17:08

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

View solution in original post

20 REPLIES 20
Simon Brouwer
Associate II
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);

}
Posted on February 02, 2018 at 07:32

Looks the same as mine:

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

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.

Posted on February 02, 2018 at 16:29

Yes, exactly. It's my conclusion as well. I only do not know how to make ST fix it;)

Imen.D
ST Employee
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.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
loeffel2
Associate III
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

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.

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

Posted on February 19, 2018 at 09:26

ST is going to take care of it but I have not got any confirmation if they reproduced the issue or not. Neither any info about the fix availability.

If you manage to fix the LL please share the fix with me.

I was initially excited when LL was available for STM32F1 but I think I need to wait a few releases for more mature lib. I do not like mixed LL and manual fixes.