Page 22 of 23

Re: The RTC driver topic

Posted: Mon Jul 06, 2015 8:56 pm
by gallegojm
As I explain in an other topic, I wrote a NTP client to set the clock of my Olimex STM32-E407 board and use RTC driver
The code is at Github.

But the clock was too fast
This screen show that it was leading 80 seconds every 10 minutes!
RTC drift
RTC drift
RTCdrift.jpg (56.71 KiB) Viewed 6874 times


To slow the clock, I have to modify the value of STM32_RTC_PRESS_VALUE in file chibios3\os\hal\ports\STM32\LLD\RTCv2\rtc_lld.h

For the modification to be effective, I have to unplug the board and reconnect it. This is because the RTC registers of the STM32F407 microcontroller are write-protected after the power up (see DM000310020.pdf , page 788). A system reset do not affect this protection.

I set STM32_RTC_PRESS_VALUE to 1024 x 1.133 = 1160
The clock is now accurate.

Re: The RTC driver topic

Posted: Tue Jul 07, 2015 5:31 am
by gallegojm
in order to adjust the value of the RTC PRESS divider without modifying the code I propose to make the following change in the file chibios3\os\hal\ports\STM32\LLD\RTCv2\rtc_lld.h :

Replace

Code: Select all

/**
 * @brief   RTC PRESS divider initialization.
 * @note    The default is calculated for a 32768Hz clock.
 */
#if !defined(STM32_RTC_PRESS_VALUE) || defined(__DOXYGEN__)
#define STM32_RTC_PRESS_VALUE               1024
#endif


by

Code: Select all

/**
 * @brief   RTC PRESS divider initialization.
 * @note    The default is calculated for a 32768Hz clock.
 */
#if !defined(STM32_RTC_PRESS_VALUE) || defined(__DOXYGEN__)
#if STM32_LSECLK
#define STM32_RTC_PRESS_VALUE              (( STM32_LSECLK + 16 ) / 32 )
#else
#define STM32_RTC_PRESS_VALUE               1024
#endif
#endif


In this way, simply correcting the value of the RTC oscillator in the corresponding board.h file would give the good value for the RTC PRESS divider

Re: The RTC driver topic

Posted: Tue Jul 07, 2015 7:51 am
by barthess
1)
gallegojm wrote:it was leading 80 seconds every 10 minutes!

Are you absolutely sure your RTC uses external crystal (not LSI)?
2) This configuration option looks kind of hardcode. RTC in STM32 has special calibration "knobs"
for that purpose.

Re: The RTC driver topic

Posted: Tue Jul 07, 2015 9:31 am
by Giovanni
gallegojm wrote:in order to adjust the value of the RTC PRESS divider without modifying the code I propose to make the following change in the file chibios3\os\hal\ports\STM32\LLD\RTCv2\rtc_lld.h :

Replace

Code: Select all

/**
 * @brief   RTC PRESS divider initialization.
 * @note    The default is calculated for a 32768Hz clock.
 */
#if !defined(STM32_RTC_PRESS_VALUE) || defined(__DOXYGEN__)
#define STM32_RTC_PRESS_VALUE               1024
#endif


by

Code: Select all

/**
 * @brief   RTC PRESS divider initialization.
 * @note    The default is calculated for a 32768Hz clock.
 */
#if !defined(STM32_RTC_PRESS_VALUE) || defined(__DOXYGEN__)
#if STM32_LSECLK
#define STM32_RTC_PRESS_VALUE              (( STM32_LSECLK + 16 ) / 32 )
#else
#define STM32_RTC_PRESS_VALUE               1024
#endif
#endif


In this way, simply correcting the value of the RTC oscillator in the corresponding board.h file would give the good value for the RTC PRESS divider


It is still overridden by mcuconf.h which always contains the definition. The macro should check the LSE enable switch anyway, it could be disabled and not started.

Giovanni

Re: The RTC driver topic

Posted: Tue Jul 07, 2015 7:10 pm
by gallegojm
Hi Barthess and Giovanny
Thanks to your comments, I realized:
- that I was trying to solve the problem from the wrong end. :?
- that I forgot that a crystal oscillator can not be so far from his nominal frequency (very bad for an old electronic engineer :cry: )
- that I had to study a little more the data sheet of the mcu :roll:

After these three steps, I add the following code in the main routine:

Code: Select all

  uint32_t reg;
  chprintf( (BaseSequentialStream *) & SDU2, "RTC info:\r\n" );
  chprintf( (BaseSequentialStream *) & SDU2, "RTC clock %s\r\n",
            ( RCC_BDCR_RTCEN ? "enable" : "disable" ));
  reg = ( RCC->BDCR & STM32_RTCSEL_MASK ) >> 8;
  if( reg == 0 )
    chprintf( (BaseSequentialStream *) & SDU2, "No" );
  else if( reg == 1 )
    chprintf( (BaseSequentialStream *) & SDU2, "LSE" );
  else if( reg == 2 )
    chprintf( (BaseSequentialStream *) & SDU2, "LSI" );
  else
    chprintf( (BaseSequentialStream *) & SDU2, "HSE" );
  chprintf( (BaseSequentialStream *) & SDU2, " clock used as the RTC clock\r\n" );

And got this result:
RTC info:
RTC clock enable
LSI clock used as the RTC clock

So, how can I oblige the mcu to use the external crystal oscillator?

Re: The RTC driver topic

Posted: Tue Jul 07, 2015 7:23 pm
by Giovanni
You need:

Code: Select all

#define STM32_LSE_ENABLED                   TRUE

#define STM32_RTCSEL                        STM32_RTCSEL_LSE


Giovanni

Re: The RTC driver topic

Posted: Tue Jul 07, 2015 8:09 pm
by barthess
Add grain of salt to Giovanni's message:
And do not forget to remove RTC battery and poweroff board to apply changes.

Re: The RTC driver topic

Posted: Fri Jul 10, 2015 10:24 pm
by gallegojm
Hi Barthess and Giovanny
Thank you to both of you.
So I modify those define in file mcuconf.h

Code: Select all

#define STM32_LSI_ENABLED                   FALSE
#define STM32_LSE_ENABLED                   TRUE
#define STM32_RTCSEL                        STM32_RTCSEL_LSE

and it works fine.
The next step would be to test accuracy on larger periods of time and play with the RTC digital calibration capability.

Note there was a mistake in the code I write to test the values of the RCC_BDCR register:
The test of RTCEN bit always return true.
Correct code is:

Code: Select all

  chprintf((BaseSequentialStream *) & SDU2, "RTC clock %s\r\n",
           (( reg & RCC_BDCR_RTCEN ) ? "enable" : "disable" ));

Jean-Michel
(I have difficulties with the radio connection to internet those days that explain the late response)

Re: The RTC driver topic

Posted: Mon Jul 13, 2015 2:13 am
by gallegojm
Hi
I had two problems running rtcConvertDateTimeToFAT()

First, I think the code that performs the calculation of seconds, minutes and hours is not correct.
I replace

Code: Select all

  tmp = timespec->millisecond / 1000U;
  sec = tmp % 60U;
  min = (tmp - sec) % 3600U;
  hour = ((tmp - sec) - (min * 60U)) / 3600U;

with

Code: Select all

  sec = timespec->millisecond / 1000U;
  hour = sec / 3600U;
  sec %= 3600U;
  min = sec / 60U;
  sec %= 60U;

to get the correct result.

Second, is there a way to disable DST? (in case of a country that do not use daylight saving)

Jean-Michel

Re: The RTC driver topic

Posted: Mon Jul 13, 2015 7:47 am
by barthess
1) That's my fault. Giovanni, can I commit fix now or you still perform release related work on trunk?
2) Just set DST to 0 and forget.