zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.74k stars 6.56k forks source link

STM32G0 Incorrect UART baudrate when reducing system clock from 64 MHz to 16 MHz #70572

Closed rijesha closed 7 months ago

rijesha commented 7 months ago

Hello,

Describe the bug I am using an STM32G070KBT with uart4 at a baudrate of 9600. I am able to have good communication when the SYSCLK set to 64 MHz. But when I set it to 16 MHz I am no longer able to have communication.

I changed the baudrate to 38400 and I am able to have communication with the other board that is still set to 9600baud, but with more packet loss(may be related, but could just be due effects of the reduced clock rate on processing speed).

Original that works SYSCLK 64 MHz: ''' &pll { div-m = <1>; mul-n = <8>; div-p = <2>; div-r = <2>; clocks = <&clk_hsi>; status = "okay"; };

&rcc { clocks = <&pll>; clock-frequency = <DT_FREQ_M(64)>; ahb-prescaler = <1>; apb1-prescaler = <1>; // };

&usart4 { pinctrl-0 = <&usart4_tx_pa0 &usart4_rx_pa1>; current-speed = <9600>; pinctrl-names = "default"; status = "okay"; }; '''

Revised that does not work SYSCLK 16 MHz: ''' &pll { div-m = <1>; mul-n = <8>; div-p = <2>; div-r = <8>; clocks = <&clk_hsi>; status = "okay"; };

&rcc { clocks = <&pll>; clock-frequency = <DT_FREQ_M(16)>; ahb-prescaler = <1>; apb1-prescaler = <1>; // };

&usart4 { pinctrl-0 = <&usart4_tx_pa0 &usart4_rx_pa1>; current-speed = <9600>; pinctrl-names = "default"; status = "okay"; }; '''

Revised that does work (with more packet loss that may be unrelated) SYSCLK 16 MHz: ''' &pll { div-m = <1>; mul-n = <8>; div-p = <2>; div-r = <8>; clocks = <&clk_hsi>; status = "okay"; };

&rcc { clocks = <&pll>; clock-frequency = <DT_FREQ_M(16)>; ahb-prescaler = <1>; apb1-prescaler = <1>; // };

&usart4 { pinctrl-0 = <&usart4_tx_pa0 &usart4_rx_pa1>; current-speed = <38400>; pinctrl-names = "default"; status = "okay"; }; '''

The return from HAL_RCC_GetHCLKFreq() is always 64000000 regardless of the configuration I use, as a result SystemCoreClock is always the same as well. This is used in the function stm32_clock_control_get_subsys_rate which is called by clock_control_get_rate function in zephyr/drivers/serial/uart_stm32.c

Environment:

rijesha commented 7 months ago

I think I found the problem. I was testing a simple timer and it was off by a factor of 4. I defined the following variable in my kconfig and it is now working correctly. CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=16000000

erwango commented 7 months ago

Thanks for the update. I'm closing the issue