Skip to main content
Matteo Cardani
Associate II
May 22, 2023
Question

STM32F103 RTC timer randomly reset prescaler to default value

  • May 22, 2023
  • 2 replies
  • 2105 views

Hello,

I'm facing some issue regarding the RTC peripheral of the STM32F103.

In particular, apperently, the RTC seems to randomly loose the configuration given:

  • The RTC device is always powered, and configuration is done ideally only once (except in case of reset)
  • Both the RTC Vbat and VDD comes from the same power supply rail (when in standby it comes from a tadiran lithium battery backed up with a 100mF supercap)
  • I'm setting the RTC with a prescaler value of 32 to have a tick of almost 1 ms
  • Sometimes on some samples it happens that the RTC is not counting at 1 ms anymore but it in fact counts every seconds

By attaching with the debugger to a running target device with this problem I found out that the prescaler value seems to be set at the default value 0f 0x8000:


_legacyfs_online_stmicro_images_0693W00000bkYqlQAE.png 

The initialization code is as follow:

/**
 * @brief Configures RTC clock source and prescaler.
 * @param None
 * @retval None
 */
void RTC_Configuration(void)
{
	uint8_t retVal;
	RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
	RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 /* Initialize RTC Only */
	//MyRtc = 0; //20200909 controlla
 RtcHandle.Instance = RTC;
 RtcHandle.Init.AsynchPrediv = 32; /* Set the RTC time base to ~1ms */
 RtcHandle.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
 
 if(READ_BIT(PWR->CSR, PWR_CSR_SBF) != RESET) /* Check if the StandBy flag is set */
 {
 	/* System resumed from STANDBY mode */
 	//putstring("test2\r\n");
 Flag_stby = TRUE;
 /* Clear StandBy flag */
 //PWR_ClearFlag(PWR_FLAG_SB);
 SET_BIT(PWR->CR, PWR_CR_CSBF);
 /* Wait for RTC APB registers synchronisation */
 //RTC_WaitForSynchro();
 retVal = HAL_RTC_WaitForSynchro(&RtcHandle);
 if(HAL_TIMEOUT == retVal) /*reinit*/
 {
 	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
			RCC_OscInitStruct.LSEState = RCC_LSE_ON;
 
			if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
			{
			 Error_Handler();
			}
			PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
			PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; /* 32768 Hz */
 
			if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
			{
			 Error_Handler();
			}
 
			if (HAL_RTC_Init(&RtcHandle) != HAL_OK)
			{
			 Error_Handler();
			}
 
 }
 /* No need to configure the RTC as the RTC configuration(clock source, enable,
 prescaler,...) is kept after wake-up from STANDBY */
 }
 else /* StandBy flag is not set */
 {
 /* RTC clock source configuration */
 /* Reset Backup Domain */
 //BKP_DeInit();
 	//putstring("reinit\r\n");
 	__HAL_RCC_BACKUPRESET_FORCE();
 	__HAL_RCC_BACKUPRESET_RELEASE();
 	//putstring("tout\r\n");
 
 	MyRtc = MY_RTC_RESET_CODE; //reset error
 	/* Clear StandBy flag */
 	SET_BIT(PWR->CR, PWR_CR_CSBF);
 /* Enable LSE OSC */
 //RCC_LSEConfig(RCC_LSE_ON);
 /* Wait till LSE is ready */
 //while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
 //{
 //}
 	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
 	RCC_OscInitStruct.LSEState = RCC_LSE_ON;
 	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 	{
 	 Error_Handler();
 	}
 
 	/* Select the RTC Clock Source */
 	 //RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
 	 /* Enable the RTC Clock */
 	 //RCC_RTCCLKCmd(ENABLE);
 	 /* RTC configuration */
 	 /* Wait for RTC APB registers synchronisation */
 	 //RTC_WaitForSynchro();
 	 /* Set the RTC time base to ~1ms (1.007)*/
 	 //RTC_SetPrescaler(32);
 	 /* Wait until last write operation on RTC registers has finished */
 	 //RTC_WaitForLastTask();
 	PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
 PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; /* 32768 Hz */
 
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
 {
 Error_Handler();
 }
 
 if (HAL_RTC_Init(&RtcHandle) != HAL_OK)
 {
 Error_Handler();
 }
 }
 HAL_PWR_EnableBkUpAccess();
}

May you provide some insight of this problem?

Best regards,

Matteo Cardani

This topic has been closed for replies.

2 replies

waclawek.jan
Super User
May 22, 2023

In the above code, at each point where RTC is initialized, toggle a pin, or output diagnostics to any interface, or write a diagnostic variable observed later by the debugger. Also, add a check for the proper value of the prescaler, after this routine. Do this, in order to find out the source/reason for the problem.

JW

Matteo Cardani
Associate II
May 24, 2023

Hello Jan,

as you suggested, I set a trap detecting the condition of prescaler different from 32.

I also set a trap inside the HAL_RTC_Init function.

However after two days of testing I had no luck and no GPIO were asserted.

Are there some other condition that may cause a reset of the peripheral to the default value? I don't think this is the case, but is it possible that the RTC counter timer register (CNTL and CNTH) overflowing might cause some issue?

Thank you,

Matteo