2017-10-25 07:10 AM
I have an STM32L4 project configured to use LL drivers in CubeMX. I am using
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-report2017-10-25 08:26 AM
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.
2017-10-25 11:10 AM
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.
2017-10-25 12:10 PM
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.
2017-10-25 12:13 PM
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()))
2017-10-26 05:21 AM
Hi Clive, thanks for your thorough response. My apologies for not fully engaging with your response yesterday.
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 andsystem_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.