cancel
Showing results for 
Search instead for 
Did you mean: 

Bug Report: LL USART->BRR register configured incorrectly in LL_USART_Init in stm32l4xx_ll_usart.c

Reuben Hill
Associate II
Posted on October 25, 2017 at 16:10

I have an STM32L4 project configured to use LL drivers in CubeMX. I am using

  • An stm32L4 series MCU
  • USART1
  • Desired baud rate 115200

The LL library function

LL_USART_Init(USART1, &USART_InitStruct);

does not correctly set the LL_USART_InitTypeDef USART_InitStruct

USART_InitStruct.BaudRate  parameter for USART1.

In the source stm32l4xx_ll_usart.c this appears to be due to line 288

ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_InitStruct)

{

  ...

  periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE);

  ...

}

returning 40 MHz instead of 80 MHz (as set in CubeMX), causing the `USART->BRR` register to be set to half the value it should be as described in reference manual RM0394. The effective baud rate is then twice that requested by the USART_InitStruct.

The line causing the problem appears to be 352 in stm32l4xx_ll_rcc.c

uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource)

{

  ...

  usart_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));

  ...

  return usart_frequency;

}

Given that this occurs in the LL drivers I must assume this is an LL driver bug and not a CubeMX one. Note that the LL driver is reporting the peripheral clock to be half the value needed for communication to work correctly. When configured with HAL, the baud rate is set correctly.

Since this appears to be the only place to report such bugs, I am posting this here. Please reply if more information is required.

EDIT: Incorrect line number quoted in 

stm32l4xx_ll_rcc.c updated.

#stm32l4 #bug #ll-bug #ll-drivers #bug-report
5 REPLIES 5
Posted on October 25, 2017 at 17:26

Isn't USART1 on APB2? Would be code below that at issue.

I'd expect APB2 to be 80 MHz in normal DIV1 cases, perhaps you want manually decode the RCC settings, and confirm HSE_VALUE, or clock speeds provided as inputs.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 25, 2017 at 18:10

My apologies, I quoted the wrong line number in stm32l4xx_ll_rcc.c: I meant to refer to line 352, which is the one that my STLINK debugger says is being run. It's the default case in the switch statement

uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource)

{

  ... 

  if (USARTxSource == LL_RCC_USART1_CLKSOURCE)

  {

  /* USART1CLK clock frequency */

  switch (LL_RCC_GetUSARTClockSource(USARTxSource))

  {

    ...

    default:

      usart_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));

      break;

  }

}

I'll update my original post to reflect the line number.

Posted on October 25, 2017 at 19:10

I think you miss my point, which is why 

RCC_GetPCLK2ClockFreq() would return 40 MHz

You'd want to review the math that gets you that answer. Or if that line is entirely obtuse.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 25, 2017 at 19:13

What clock source are you using?

What clock is attached as HSE?

What value does HSE_VALUE report? see stm32l4xx_hal_conf.h

Value of 

RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())

Value of 

RCC_GetSystemClockFreq()

Value of 

RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()))

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 26, 2017 at 12:21

Hi Clive, thanks for your thorough response. My apologies for not fully engaging with your response yesterday.

  • Clock source is configured in cubeMX to be PLCLK2. Below are the relevant clock configurations in cubeMX:
    • APB2 Prescaler = /1
    • AHB Prescaler = /1
    • SYSCLK = 80 MHz
    • SYSCLK Source is PLLCLK
    • PLL: divider R = 2, multiplier N = 10
    • PLLM = /1
    • PLL Source is HSE
    • HSE is the External crystal/ceramic resonator (HSE crystal) @ 16 MHz for my board.
  • I am using LL drivers only so I don't have 

    stm32l4xx_hal_conf.h in my project but a quick test post-initialisation reveals HSE_VALUE = 8000000U in my code. I guess that's the culprit?

    • The only &sharpdefines of HSE_VALUE in my project that I can find are line 136 of stm32l4xx_ll_rcc.h and line 111 of system_stm32l4xx.c. In both cases they define HSE_VALUE as 

      8000000U.

I note that in the notes for the function SystemCoreClockUpdate in ststem_stm32l4xx.c, it is specifically noted that HSE_VALUE should be adjusted for the real input clock value. Changing the defined 

HSE_VALUE to 

16000000U  in both stm32l4xx_ll_rcc.h and 

system_stm32l4xx.c resolves the problem.

Perhaps this is a cube issue after all then: I notice that changing the HSE crystal input value in the clock diagram doesn't actually modify or add any &sharpdefines when a project is created. Presumably it ought to, or did I miss a required configuration step post-project creation?

In case I haven't made it clear, I've configured CubeMX to use LL drivers for all peripherals.

EDIT: For anyone following this that runs into a similar problem, my current fix is to add HSE_VALUE=16000000U to the list of defined preprocessor symbols in the C/C++ tab of the Target Options for the project.