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

And what is in the RTC registers?

I don't Cube/HAL - do those functions properly unlock the backup domain and RTC before writing to registers, as outlined in RTC register write protection subchapter of RTC chapter of RM?

JW

JSirk
Associate II

Is there a handy instruction for reading them? #hwguy

JSirk
Associate II

I'd be tempted to say that the HAL library as supplied by ST should do data write and retrieval properly - I wouldn't have the competence to judge that. Also, given that everything else in both time and date is properly written and read back, I can't see how the write protection could be at fault.

I've banged my head to the wall for days with this now, after having banged my head last week on the Stop mode issue where one needs to call

HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);

twice for it to take effect.

> hwguy

That's no excuse. SW is the same as HW, you read the manuals thoroughly and then act accordingly.

Use the debugger to read out the registers. Or, in program, read RTC->TR and RTC->DR (in this order; read Reading the calendar subsection in RTC section of RM).

> one needs to call

> HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);

> twice for it to take effect.

Probably needs not, and there's some underlying reason why writing it twice appears to work.

JW

[deleted doubled post courtesy of updated force]

JSirk
Associate II

SW should be the same as HW in the sense that I wouldn't do a CPU with single transistors if I can get one all ready made. So using registers isn't my strong suite as I thought I'd get by with using ready made libraries that keep the required low level stuff out of view.

Managed to pull the DR value out, 0x1B7017. 1B is year in BCD format so that's 1 of tens and B=11 ones? Doesn't seem right. I'm guessing there's no internal checks on the RTC for proper values? Now to find out how that B gets there in the first place.

> I wouldn't do a CPU with single transistors if I can get one all ready made

SW has several orders of magnitude more degrees of freedom than HW so you can get ready-made "libraries", except that they inevitably cover only a fraction of possible usage modes. Also, with the processor you'd start with reading thoroughly its manual - did you do that with the "library" you've used? Please do so, you might perhaps start to see reasons to go for transistors.

> 1B is year in BCD format

Yes, incorrect as you've noted.

> Now to find out how that B gets there in the first place.

Most probably through

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

and t->sDate not being in the format this function expects with RTC_FORMAT_BIN. My guess is that the struct was not entirely initialized. But by now you've figured, I guess.

JW

JSirk
Associate II

Don't get me started on the HAL User Manual... I've found out more about the usage and proper syntax of the libraries from Google than from that manual.

I finally found the problem and solution - while setting the year, month and date manually in main loop worked without a hitch, setting them after parsing them from an incoming string always failed. Turns out that the weekday parameter (that I don't even use but the RTC sure does) of my time structure defaults to something (likely 0) in main but when it's a temporary structure in a function, it can be anything and while the HAL_RTC_SetDate asserts all else, it doesn't assert the weekday so it can overlap into year. This should be fixed in stm32f4xx_hal_rtc.c in my opinion, but I'm not holding my breath.

Thanks Jan for the support!

> Don't get me started on the HAL User Manual...

As I've said, it's one of the reasons to go for the transistors.

> when it's a temporary structure in a function, it can be anything

Oh yes. The Cube manual ought to say that all used structs have to be initialized entirely. For some parts of the "library" there are initialization functions which do this (I don't see such for RTC_DateTypeDef though, but I'm not surprised - systematic approach is not Cube's forte). This is something which ought to be written as the first thing in Cube's manual - maybe it's there, I am not going to spoil my evening by looking at it.

> while the HAL_RTC_SetDate asserts all else, it doesn't assert the weekday

In [STM32Cube_FW_F4_V1.15.0]\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_rtc.c (I know it's old but as I don't use it I don't care to update, and I don't believe this fell out in newer versions) in HAL_RTC_SetDate() at around its 16th line I see:

 assert_param(IS_RTC_WEEKDAY(sDate->WeekDay));

So I'd say you have the asserts switched off. Don't ask me how to check/turn on.

JW