cancel
Showing results for 
Search instead for 
Did you mean: 

Wakeup from standby with RTC is causing losing time accuracy

CYesi.1
Associate II

Hello,

I am using STM32L073V8T MCU, STM32CubeIDE.

My application needs low power consumotion. When some events occurs, MCU move to standby. Than it waits new event for waking up. In other words, my application periodically check new event. After going standby, MCU wakes up with about 23 seconds period and check new events. If there isnt event, MCU contuniue stay standby mode.

There is not any problem about going to standby or waking from standby. But, periodically sleeping and waking is causing losing time accuracy.

In my test condition, I setted device time according my PC. Than, I let device in standby mode during 1 day period. And, there was a 10 minutes difference from my PC time. In addition, in same conditions without standby there is about 2 second accuracy lose. (2 sec is not problem for my case)

void wakeupWithRTC(void)

{

  HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);

 HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x63BA50, RTC_WAKEUPCLOCK_RTCCLK_DIV16);

  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);

}

void pwr_lowPowermode(void)

{

  dbg_printf("standby\n\r");

  wakeupWithRTC();

  GPIO_low_power();

  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); */

   HAL_PWR_EnterSTANDBYMode();

}

11 REPLIES 11
Peter BENSCH
ST Employee

How do you clock the RTC?

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
CYesi.1
Associate II

Thnks for answer,

RTC clock source is LSE

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

 /** Configure the main internal regulator output voltage 

 */

 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

 /** Configure LSE Drive Capability 

 */

 HAL_PWR_EnableBkUpAccess();

 __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);

 /** Initializes the CPU, AHB and APB busses clocks 

 */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSE;

 RCC_OscInitStruct.LSEState = RCC_LSE_ON;

 RCC_OscInitStruct.HSIState = RCC_HSI_ON;

 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

  Error_Handler();

 }

 /** Initializes the CPU, AHB and APB busses clocks 

 */

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

 {

  Error_Handler();

 }

 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_RTC;

 PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;

 PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;

 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

 {

  Error_Handler();

 }

}

static void MX_RTC_Init(void)

{

 hrtc.Instance = RTC;

 hrtc.Init.HourFormat = RTC_HOURFORMAT_24;

 hrtc.Init.AsynchPrediv = 127;

 hrtc.Init.SynchPrediv = 255;

 hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;

 hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;

 hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;

 hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

 if (HAL_RTC_Init(&hrtc) != HAL_OK)

 {

  Error_Handler();

 }

}

Do you call MX_RTC_Init() regularly? If yes, that probably resets the subsecond counter.

I don't use and don't understand Cube/HAL.

JW

M.Hajji
Associate III

Try to output the RTC_OUT on the PC13, visualize it with a oscilloscope and look for deviation from the 1MHz, also RTC_out on the PC13 should still be functional with standby mode so that can give an idea on what's happening when entering, during and when exiting the low power mode.

Does your application check the SBF status flag in the PWR_CSR register to know that the microcontroller was in Standby mode ? if the RTC in already running then no need to re-initiate it.

Regards,

Hajji.

Hello,

Thank you for reply.

It sounds likely. In standby mode, after wake-up, program starts as reset thats why all peripheral are reinitialized.

Now, i did some changes. If program come from standby, application doesnt reinit RTC. In this case, RTC alarm not work properly after first alarm. It needs reinitializition.

  if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)

  {

dbg_printf("wake from standby\n\r");

HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);

    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);

   __RTC_get_time(&hour, &minute, &second);

   dbg_printf("hour %d, min %d, sec %d,\n\r", hour,minute,second);

    if(isVextExist())

     set_powerState(power_WakeUp);

     else

     pwr_lowPowermode();

  }else{

  dbg_printf("wake normal\n\r");

  MX_RTC_Init();

  }

Hello,

Thank you for reply,

I will check PC13. But, i think the re-init RTC seems more suspicious. Normally, after wakeup, application re-init RTC. Now i change it like below. But, in this case, RTC wake CPU only one times. It seems alarm needs re-initialization.

 if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)

  {

dbg_printf("wake from standby\n\r");

HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);

   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);

   __RTC_get_time(&hour, &minute, &second);

   dbg_printf("hour %d, min %d, sec %d,\n\r", hour,minute,second);

    if(isVextExist())

     set_powerState(power_WakeUp);

    else

     pwr_lowPowermode();

  }else{

  dbg_printf("wake normal\n\r");

  MX_RTC_Init();

  }

> In this case, RTC alarm not work properly after first alarm.

What does it mean, exactly?

JW

Hi,

In order to verify that the RTC has already been initialized, it is sufficient to check

void Config_RTC(void)
{
  // If the RTC has already been configured previously -> exit immediately
  if((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) return;
 
  // Here initialize the RTC, i.e. clock source, date and time, etc...
}

INITS bit is set when the calendar has been set already, and it should stay on during standby.

If it is set, then all you have to do is reconfigure the alarms (as I am not sure that their content is kept after standby).

I use direct register access, so I don't know what the HAL/LL is accessing when setting alarms, hopefully it does not alter the RTC itself.

Best regards,

Kraal

I mean after I changed re-init, RTC wake up MCU only first time.

According to my new configuration, RTC only initialize when PWR_FLAG_SB is clear. If software is resetted by the standby, RTC will not initialize. And in this situation, RTC is not waking up MCU.