cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 RTC timer randomly reset prescaler to default value

Matteo Cardani
Associate II

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

2 REPLIES 2

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

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