From 19fd0a55877fa7997d88d14dde09df6cc18fd084 Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Tue, 21 Jun 2022 10:10:09 -0300 Subject: [PATCH] stm32xx: Fix RTC drift when using HSE When using HSE to clock RTC NuttX internal time is gaining 5.5 second per minute. Problem was NuttX using 7182 for one of the RTC division factors, it should have been 7812. The incorrect factors used are 7182 and 0xff. These are used in 3-4 places within Nuttx and other places as 7812 and 0xff. However, the STMicro app note AN4759 suggests using 7999 and 124, which is what I've used. Explanation: These 2 factors are used to divide the HSE clock (which at this point is 1 MHz) to 1 Hz for the RTC hardware. To test the 2 factors, add 1 to both numbers and multiply them together. The result needs to be as close as possible to 1 MHz. The suggested values of 7999 and 124 => 8000*125 = 1,000,000, the prime factors. So, the best fix for Nuttx would be these values. Issue discovered and fixed by Peter Moody --- arch/arm/src/stm32/stm32_rtcc.c | 8 ++++---- arch/arm/src/stm32/stm32f40xxx_rtcc.c | 8 ++++---- arch/arm/src/stm32f7/stm32_rtc.c | 8 ++++---- arch/arm/src/stm32h7/stm32_rtc.c | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/arm/src/stm32/stm32_rtcc.c b/arch/arm/src/stm32/stm32_rtcc.c index 4e8be5a5ac4..24091b659d3 100644 --- a/arch/arm/src/stm32/stm32_rtcc.c +++ b/arch/arm/src/stm32/stm32_rtcc.c @@ -415,12 +415,12 @@ static int rtc_setup(void) /* Configure RTC pre-scaler with the required values */ #ifdef CONFIG_STM32_RTC_HSECLOCK - /* For a 1 MHz clock this yields 0.9999360041 Hz on the second - * timer - which is pretty close. + /* STMicro app note AN4759 suggests using 7999 and 124 to + * get exactly 1MHz when using the RTC at 8MHz. */ - putreg32(((uint32_t)7182 << RTC_PRER_PREDIV_S_SHIFT) | - ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + putreg32(((uint32_t)7999 << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)124 << RTC_PRER_PREDIV_A_SHIFT), STM32_RTC_PRER); #else /* Correct values for 32.768 KHz LSE clock and inaccurate LSI clock */ diff --git a/arch/arm/src/stm32/stm32f40xxx_rtcc.c b/arch/arm/src/stm32/stm32f40xxx_rtcc.c index 5ad9228abaf..4a04586e39e 100644 --- a/arch/arm/src/stm32/stm32f40xxx_rtcc.c +++ b/arch/arm/src/stm32/stm32f40xxx_rtcc.c @@ -483,12 +483,12 @@ static int rtc_setup(void) /* Configure RTC pre-scaler with the required values */ #ifdef CONFIG_STM32_RTC_HSECLOCK - /* For a 1 MHz clock this yields 0.9999360041 Hz on the second - * timer - which is pretty close. + /* STMicro app note AN4759 suggests using 7999 and 124 to + * get exactly 1MHz when using the RTC at 8MHz. */ - putreg32(((uint32_t)7182 << RTC_PRER_PREDIV_S_SHIFT) | - ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + putreg32(((uint32_t)7999 << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)124 << RTC_PRER_PREDIV_A_SHIFT), STM32_RTC_PRER); #else /* Correct values for 32.768 KHz LSE clock and inaccurate LSI clock */ diff --git a/arch/arm/src/stm32f7/stm32_rtc.c b/arch/arm/src/stm32f7/stm32_rtc.c index 30618d91bd2..3d30a3dce9d 100644 --- a/arch/arm/src/stm32f7/stm32_rtc.c +++ b/arch/arm/src/stm32f7/stm32_rtc.c @@ -490,12 +490,12 @@ static int rtc_setup(void) /* Configure RTC pre-scaler with the required values */ #ifdef CONFIG_STM32F7_RTC_HSECLOCK - /* For a 1 MHz clock this yields 0.9999360041 Hz on the second - * timer - which is pretty close. + /* STMicro app note AN4759 suggests using 7999 and 124 to + * get exactly 1MHz when using the RTC at 8MHz. */ - putreg32(((uint32_t)7182 << RTC_PRER_PREDIV_S_SHIFT) | - ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + putreg32(((uint32_t)7999 << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)124 << RTC_PRER_PREDIV_A_SHIFT), STM32_RTC_PRER); #else /* Correct values for 32.768 KHz LSE clock and inaccurate LSI clock */ diff --git a/arch/arm/src/stm32h7/stm32_rtc.c b/arch/arm/src/stm32h7/stm32_rtc.c index 3d77b1b3e88..a826e0c9bf8 100644 --- a/arch/arm/src/stm32h7/stm32_rtc.c +++ b/arch/arm/src/stm32h7/stm32_rtc.c @@ -490,12 +490,12 @@ static int rtc_setup(void) /* Configure RTC pre-scaler with the required values */ #ifdef CONFIG_STM32H7_RTC_HSECLOCK - /* For a 1 MHz clock this yields 0.9999360041 Hz on the second - * timer - which is pretty close. + /* STMicro app note AN4759 suggests using 7999 and 124 to + * get exactly 1MHz when using the RTC at 8MHz. */ - putreg32(((uint32_t)7182 << RTC_PRER_PREDIV_S_SHIFT) | - ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + putreg32(((uint32_t)7999 << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)124 << RTC_PRER_PREDIV_A_SHIFT), STM32_RTC_PRER); #else /* Correct values for 32.768 KHz LSE clock and inaccurate LSI clock */