3

I'm using STM32F030RCT6 with CubeMX. Device is a datalogger and RTC is the main thing that cannot fail. On Errata Sheet there is something about RTC Shadow Register.

I configured CubeMX to not generate MX_RTC_Init() function and it has been working normally so far. (I'm using LSE)

I need to update the time/date from GSM time but when I set the year to 18 with HAL_SetDate() and after a small delay I read with HAL_GetDate(), sDate.Year gave me 20. Apart from Year, the other values are correct.

What I tried:

  • Used LSI
  • while (HAL_SetDate != HAL_GetDate) HAL_SetDate(ActualDate)
  • First HAL_GetDate then HAL_SetDate

I got no progress and thing even got worse like Month = 56, Day = 45 etc.

Thanks in advance. Best regards.

sbtek
  • 33
  • 1
  • 8

3 Answers3

6

The value WeekDay must be set to a value between 0 to 7

I had the same problem. I found that the problem was: Not setting a value to WeekDay. When creating a struct RTC_DateTypeDef in a functions scope, the field WeekDay gets a random value. I discovered that: The value WeekDay must be set to a value between 0 to 7, if it is out of this range, it can change the year.

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 (8 bits): two BCD digits.
  • Month occupies bits 8-12 (5 bits): two BCD digits but the left digit can only be 0 or 1 -> 5 bits is enough.
  • WeekDay occupies bits 13-15 (3 bits): one BCD digit with value range 1-7 -> 3 bits is enough.
  • Year occupies bits 16-24 (9 bits).

When WeekDay is greater than 7, the MSB is 1 and it overlaps with the LSB of Year and can change it (if the LSB is 0).

Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
0

I had exactly the same issue with setting the year value after using HAL_SetDate(). Wrong values was read with the Hal_GetDate() function.

MX_RTC_Init() checks first a particular value in a RTC BKP register to know if a Reset occurred on the RTC domain. It prevents from setting again the time and date if it has been already done.

I finally did the same and tadaaaam for the first time I'm reading a good year value of 18 !!

if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR10) != 0x32F2){ // Mandatory: workaround found ?
    if(HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) == HAL_OK){
        if(HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK){
             HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR10, 0x32F2);
        }
    }
}

I do not understand precisely why it works, I'll ask on ST forum and edit this answer as soon as I know.

In the meantime could you check if it works for you too ?

aMJay
  • 2,215
  • 6
  • 22
  • 34
  • Thank for reply. I already changed HW with external RTC but I will try. What MCU are you using? Because my MX_RTC_Init() also not working properly it resets the RTC everytime. – sbtek Apr 20 '18 at 06:48
  • I'm using an STM32L476 with the driver revision v1.9.0. – Mathieu G. Apr 20 '18 at 07:04
0

Set your WeekDay parameter to a valid value.

Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
Vince
  • 11