AnsweredAssumed Answered

RTC has wrong value after _WFI()

Question asked by nunes.ricardo on Aug 24, 2016
Latest reply on Aug 24, 2016 by FTITI.Walid
I noticed some problems with the RTC value after waking up from an interrupt (_WFI() instruction) so I made this code to test it out. It prints RTC value in seconds since the epoch and sleeps after 5s:
01.sysclock_reset();
02. 
03.    while(1)
04.    {
05.        int passed = 0;
06. 
07.        printf("\r\n");
08.        while(passed < 5)
09.        {
10.            uint32_t secs = sysclock_get_secs();
11. 
12.            if(secs != last_secs)
13.            {
14.                ++passed;
15.                last_secs = secs;
16.                printf("[%d]\r\n", (int)secs);
17.            }
18.        }
19. 
20.        printf("\r\n");
21. 
22.        HAL_SuspendTick();
23.        __WFI();
24.        HAL_ResumeTick();
25. 
26.        sysclock_reset();
27.        sysclock_reset();
28.    }

In this case the interrupt is me pausing the debug session and resuming it. This is the output:

01.sysclock reset at 1472047415 seconds     2500 ms
02. 
03.[1472047415]
04.[1472047416]
05.[1472047417]
06.[1472047418]
07.[1472047419]
08. 
09.sysclock reset at 1472047415 seconds     6501 ms
10.sysclock reset at 1472047423 seconds     6506 ms


So basically, I reset my sysclock at 2.5s since the MCU woke up, print the seconds for 5s and go to sleep. Right after that I wake up and reset the clock again, but the function HAL_RTC_GetTime returns the same value as before (function returns HAL_OK).

I realised that this only happens once and right after the first time the MCU wakes up from _WFI(), the next iterations are ok.

Debugging in the  HAL_RTC_GetTime function I realised that the TR register is not being updated, if I have a breakpoint in 

1./* Get the TR register */
2. tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK);

and put the cursor on top of TR it gives me the wrong value for the first time, and the right one at the next. According to the definition the register is volatile, so what can be doing this?

Thanks for the help, here is my RTC initialization code:
01.void cfg_rtc(RTC_HandleTypeDef* rtc)
02.{
03.    __HAL_RCC_RTC_ENABLE();
04.    __HAL_RTC_RESET_HANDLE_STATE(rtc);
05. 
06.    rtc->Instance = RTC;
07.    rtc->Init.HourFormat = RTC_HOURFORMAT_24;
08.    rtc->Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
09.    rtc->Init.SynchPrediv = RTC_SYNCH_PREDIV;
10.    rtc->Init.OutPut = RTC_OUTPUT_DISABLE;
11.    rtc->Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
12.    rtc->Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
13. 
14.    HAL_StatusTypeDef status = HAL_RTC_Init(rtc);
15. 
16.    assert(status == HAL_OK);
17.}



Outcomes