Question
STM32Cube_FW_L0_V1.1.2 - HSI/4 (clock&UART) problem - solution
Posted on September 24, 2015 at 14:35
Hi,
there are some problems with code generated by STM32CubeMX when using HSI/4 as a system clock. STM32CubeMX generates (stm32l0xx_hal_conf.h): #define HSI_VALUE ((uint32_t)4000000) which is wrong IMO.It should be 16MHz. By generating wrong value it forces Systick to be four times faster i.e. runnning every 250us. ''SystemCoreClock'' has also wrong value of 1MHz instead of 4MHz. Changing HSI_VALUE to 16MHz fixes the clock problem, but introduces problem with UART when running UART from HSI clock. It creates wrong baudrate. it calculates value from HSI not HSI/4. Possible fix:diff -uprN
/Project/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_uart.c
---
/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_uart.c 2015-07-14 17:02:397781359 +0100
+++ /Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_uart.c 2015-09-23 20:47:415687046 +0100
@@ -1723,8 +1723,15 @@
void
UART_SetConfig(UART_HandleTypeDef *
case
UART_CLOCKSOURCE_PCLK1:
huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate));
break
;
-
case
UART_CLOCKSOURCE_HSI:
- huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HSI_VALUE, huart->Init.BaudRate));
+
case
UART_CLOCKSOURCE_HSI:
+
if
((RCC->CR & RCC_CR_HSIDIVF) != 0)
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_LPUART((HSI_VALUE >> 2), huart->Init.BaudRate));
+ }
+
else
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HSI_VALUE, huart->Init.BaudRate));
+ }
break
;
case
UART_CLOCKSOURCE_SYSCLK:
huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
@@ -1748,7 +1755,14 @@
void
UART_SetConfig(UART_HandleTypeDef *
usartdiv = (uint32_t)(__DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate));
break
;
case
UART_CLOCKSOURCE_HSI:
- usartdiv = (uint32_t)(__DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate));
+
if
((RCC->CR & RCC_CR_HSIDIVF) != 0)
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING8((HSI_VALUE >> 2), huart->Init.BaudRate));
+ }
+
else
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate));
+ }
break
;
case
UART_CLOCKSOURCE_SYSCLK:
huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
@@ -1775,7 +1789,14 @@
void
UART_SetConfig(UART_HandleTypeDef *
huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate));
break
;
case
UART_CLOCKSOURCE_HSI:
- huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate));
+
if
((RCC->CR & RCC_CR_HSIDIVF) != 0)
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING16((HSI_VALUE >> 2), huart->Init.BaudRate));
+ }
+
else
+ {
+ huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate));
+ }
break
;
case
UART_CLOCKSOURCE_SYSCLK:
huart->Instance->BRR = (uint32_t)(__DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
diff -uprN
/Project/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_usart.c
---
/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_usart.c 2015-07-14 17:02:397781359 +0100
+++ /Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_usart.c 2015-09-23 20:57:00.170503984 +0100
@@ -1653,7 +1653,14 @@
static
void
USART_SetConfig(USART_Handle
husart->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK2Freq() / husart->Init.BaudRate);
break
;
case
USART_CLOCKSOURCE_HSI:
- husart->Instance->BRR = (uint16_t)(HSI_VALUE / husart->Init.BaudRate);
+
if
((RCC->CR & RCC_CR_HSIDIVF) != 0)
+ {
+ husart->Instance->BRR = (uint16_t)((HSI_VALUE >> 2) / husart->Init.BaudRate);
+ }
+
else
+ {
+ husart->Instance->BRR = (uint16_t)(HSI_VALUE / husart->Init.BaudRate);
+ }
break
;
case
USART_CLOCKSOURCE_SYSCLK:
husart->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / husart->Init.BaudRate);
Cheers,
Jan
#stm32-stm32l0