cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F410 RTC fails on year

JSirk
Associate II

When writing to RTC and then reading back, my year is always off - writing 18 gives me back 21. Tried adding delays up to a second between instructions, no joy. Using Cube and MDK, RTC is running LSE 32768 and works fine otherwise. Both read and write depend on HAL libraries that I haven't touched.

typedef struct __TIME_INFO

{

   RTC_TimeTypeDef sTime;

   RTC_DateTypeDef sDate;

} TIME_INFO;

void rtc_updateRTCclock(TIME_INFO *t)

{

HAL_RTC_SetTime(&MAIN_RTC, &(t->sTime), RTC_FORMAT_BIN);

HAL_RTC_SetDate(&MAIN_RTC, &(t->sDate), RTC_FORMAT_BIN);

}

TIME_INFO rtc_getCurrentTime() {

   TIME_INFO t;

   HAL_RTC_GetTime(&MAIN_RTC, &(t.sTime), RTC_FORMAT_BIN);

   HAL_RTC_GetDate(&MAIN_RTC, &(t.sDate), RTC_FORMAT_BIN);

   return t;

}

12 REPLIES 12
Eliahu Aaron
Associate

I had the same problem. I found that the problem was not setting the WeekDay (when creating a struct RTC_DateTypeDef, the field WeekDay gets a random value). The value WeekDay must be set to a value between 0 to 7.

Explanation: The code for setting the date in function HAL_RTC_SetDate:

if (Format == RTC_FORMAT_BIN)
 
{
 
    assert_param(IS_RTC_YEAR(sDate->Year));
 
    assert_param(IS_RTC_MONTH(sDate->Month));
 
    assert_param(IS_RTC_DATE(sDate->Date));
 
 
 
    datetmpreg = (((uint32_t)RTC_ByteToBcd2(sDate->Year) << 16U) | \
 
                  ((uint32_t)RTC_ByteToBcd2(sDate->Month) << 8U) | \
 
                  ((uint32_t)RTC_ByteToBcd2(sDate->Date)) | \
 
                  ((uint32_t)sDate->WeekDay << 13U));
 
}
 
else
 
{
 
    assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
 
    assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
 
    assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
 
 
 
    datetmpreg = ((((uint32_t)sDate->Year) << 16U) | \
 
                  (((uint32_t)sDate->Month) << 8U) | \
 
                  ((uint32_t)sDate->Date) | \
 
                  (((uint32_t)sDate->WeekDay) << 13U));
 
}

  • Date occupies bits 0-7: two BCD digits.
  • Month occupies bits 8-12: two BCD digits but the left digit can only be 0 or 1 - 5 bits is enough.
  • WeekDay occupies bits 13-15. one BCD digit from 1 to 7 - 3 bits is enough.
  • Year occupies bits 16-24.

When WeekDay is greater than 7, it overlaps with the bits of Year and can change it.

Pavel A.
Evangelist III

> When WeekDay is greater than 7, it overlaps with the bits of Year and can change it

So you've found a bug in the HAL library where the function does not validate sDate->WeekDay input value.

-- pa

> So you've found a bug in the HAL library where the function does not validate sDate->WeekDay input value.

There's no bug. There is an assertion just above those lines - see my previous post.

JW