Skip to main content
alexey_public
Associate II
November 9, 2018
Question

After STMCube update to version 4.27.0 HAL RTC driver clear RTC date and time and set it's to default value on MCU power up, STM32F373 series and STM32Cube FW_F3 V1.10.0.

  • November 9, 2018
  • 3 replies
  • 814 views

On last version normal rtc init code was so:

/* RTC init function */
static void MX_RTC_Init(void)
{
 
 /* USER CODE BEGIN RTC_Init 0 */
 
 /* USER CODE END RTC_Init 0 */
 
 RTC_TimeTypeDef sTime;
 RTC_DateTypeDef sDate;
 RTC_AlarmTypeDef sAlarm;
 
 /* USER CODE BEGIN RTC_Init 1 */
 
 /* USER CODE END RTC_Init 1 */
 
 /**Initialize RTC Only 
 */
 hrtc.Instance = RTC;
 hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
 hrtc.Init.AsynchPrediv = 0;
 hrtc.Init.SynchPrediv = 0x7FFF;
 hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
 hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
 hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
 if (HAL_RTC_Init(&hrtc) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 /* USER CODE BEGIN RTC_Init 2 */
 
 /* USER CODE END RTC_Init 2 */
 
 /**Initialize RTC and set the Time and Date 
 */
 sTime.Hours = 0;
 sTime.Minutes = 0;
 sTime.Seconds = 0;
 sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
 sTime.StoreOperation = RTC_STOREOPERATION_RESET;
 if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 /* USER CODE BEGIN RTC_Init 3 */
 
 /* USER CODE END RTC_Init 3 */
 
 sDate.WeekDay = RTC_WEEKDAY_SUNDAY;
 sDate.Month = RTC_MONTH_JANUARY;
 sDate.Date = 1;
 sDate.Year = 17;
 
 if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 /* USER CODE BEGIN RTC_Init 4 */
 
 /* USER CODE END RTC_Init 4 */
 
 /**Enable the Alarm A 
 */
 sAlarm.AlarmTime.Hours = 0;
 sAlarm.AlarmTime.Minutes = 0;
 sAlarm.AlarmTime.Seconds = 0;
 sAlarm.AlarmTime.SubSeconds = 0;
 sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
 sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
 sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
 sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
 sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
 sAlarm.AlarmDateWeekDay = 1;
 sAlarm.Alarm = RTC_ALARM_A;
 if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 /* USER CODE BEGIN RTC_Init 5 */
 
 /* USER CODE END RTC_Init 5 */
 
 /**Enable the WakeUp 
 */
 if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 /* USER CODE BEGIN RTC_Init 6 */
 
 /* USER CODE END RTC_Init 6 */
 
}

And I can insert code with simple control for RTC state:

/* USER CODE BEGIN RTC_Init 2 */
if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){ 
/* USER CODE END RTC_Init 2 */

And so one.

But in new version of libraries no any user code for this purpose:

/* RTC init function */
static void MX_RTC_Init(void)
{
 
 /* USER CODE BEGIN RTC_Init 0 */
 
 /* USER CODE END RTC_Init 0 */
 
 RTC_TimeTypeDef sTime;
 RTC_DateTypeDef sDate;
 
 /* USER CODE BEGIN RTC_Init 1 */
 
 /* USER CODE END RTC_Init 1 */
 
 /**Initialize RTC Only 
 */
 hrtc.Instance = RTC;
 hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
 hrtc.Init.AsynchPrediv = 0;
 hrtc.Init.SynchPrediv = 0x7FFF;
 hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
 hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
 hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
 if (HAL_RTC_Init(&hrtc) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 
 /**Initialize RTC and set the Time and Date 
 */
 sTime.Hours = 0;
 sTime.Minutes = 0;
 sTime.Seconds = 0;
 sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
 sTime.StoreOperation = RTC_STOREOPERATION_RESET;
 if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 
 sDate.WeekDay = RTC_WEEKDAY_SUNDAY;
 sDate.Month = RTC_MONTH_JANUARY;
 sDate.Date = 1;
 sDate.Year = 17;
 
 if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 
}

Only Use Code 0 and User code 1. But I can't stopped writing date and time. It's needed User code 2 and 4.

Of course I can write this code by myself, but after next code updating by STMCube I will lost all my changes.

    This topic has been closed for replies.

    3 replies

    AVI-crak
    Senior
    November 9, 2018

    So it was intended.

    I advise the second time: use CMSIS.

    #define swRCC_BDCR_LSEDRV(write) (((write) & 0x00000003U) << 3)
    #define srRCC_BDCR_LSEDRV (((RCC->BDCR) >> 3) & 0x00000003U)
    #define srRCC_BDCR_LSERDY (((RCC->BDCR) >> 1) & 0x00000001U)
     
    static const struct
    {
    const uint32_t No_clock;
    const uint32_t LSE;
    const uint32_t LSI;
    const uint32_t HSE;
    const uint32_t FFFF;
    }sRCC_BDCR_RTCSEL = {0x00000000U,0x00000100U,0x00000200U,0x00000300U,0x00000300U};
    /*
     RCC->BDCR = swRCC_BDCR_LSEDRV(write) /// Power LSE oscillator's drive capability. 0-3
     |sRCC_BDCR_RTCSEL.x /// RTC clock source selection
     |RCC_BDCR_LSEON /// 1: External low-speed oscillator LSE enable
     |RCC_BDCR_LSEBYP /// 1: Bypassing the LSE generator
     |RCC_BDCR_RTCEN /// RTC clock enable
     |RCC_BDCR_BDRST /// Backup domain software reset
     
    srRCC_BDCR_LSEDRV /// Reading power LSE oscillator's drive capability.
    /// only reading
    srRCC_BDCR_LSERDY /// 1: Stable operation of the LSE
    */
     
     
    if((RCC->BDCR & ( RCC_BDCR_LSERDY | sRCC_BDCR_RTCSEL.LSE | RCC_BDCR_RTCEN ))
     ^ ( RCC_BDCR_LSERDY | sRCC_BDCR_RTCSEL.LSE | RCC_BDCR_RTCEN ))
    { /// Сбой ча�?ового кварца, коммутатора кварца, ча�?ового модул�?
     RCC->BDCR = RCC_BDCR_BDRST; /// ре�?ет модул�?
     RCC->BDCR &= ~RCC_BDCR_BDRST;
     RCC->AHB1LPENR |= RCC_AHB1LPENR_BKPSRAMLPEN;
     PWR->CSR1 |= PWR_CSR1_BRE; /// вкл LP �?таб на BKPSRAM
     while(!(PWR->CSR1 & PWR_CSR1_BRR));
     RCC->BDCR |= RCC_BDCR_RTCEN /// вкл ча�?ового модул�?
     |RCC_BDCR_LSEON /// включаем внешний кварц
     |swRCC_BDCR_LSEDRV(3); /// Power LSE oscillator's drive capability. 0-3
     RCC->CSR |= RCC_CSR_LSION; /// включаем внутренний генератор 32Кгц
     for(tmp = 0x40024000; tmp < 0x40024FFC ; tmp +=4) // обнуление BKPSRAM
     { *(__IO uint32_t*) tmp = 0x0; delay(10);}
     tmp = 33554432;
     do { tmp--; }
     while ( (srRCC_BDCR_LSERDY == 0) && ( tmp != 0) );
     if ( tmp != 0) RCC->BDCR |= sRCC_BDCR_RTCSEL.LSE;
     else RCC->BDCR |= sRCC_BDCR_RTCSEL.LSI;
     
    /// обновление даты и времени: год , ме�?�?ц , день , день_недели , ча�? , минуты , �?екунды
    /// year, month, day, day_of_the_week, hour, minutes, seconds);
     PWR->CR1 |= PWR_CR1_DBP;
     RTC->WPR = 0xCA;
     delay(1000);
     RTC->WPR = 0x53;
     delay(1000);
     RTC->ISR |= RTC_ISR_INIT;
     while(!(RTC->ISR & RTC_ISR_INITF));
     RTC->CR |= RTC_CR_BYPSHAD; /// чтение/запи�?ь без кеша
     RTC->PRER = 0x007F00FF; //0x007f00ff;
     delay(100);
     
     RTC->TR = ((__TIME__[0]-'0') << 20) // hour 10
     | ((__TIME__[1]-'0') << 16) // hour 1
     | ((__TIME__[3]-'0') << 12) // minutes 10
     | ((__TIME__[4]-'0') << 8) // minutes 1
     | ((__TIME__[6]-'0') << 4) // seconds 10
     | (__TIME__[7]-'0'); // seconds 1
     
     RTC->DR = ((__DATE__[9]-'0') << 20) // year 10
     | ((__DATE__[10]-'0') << 16) // year 1
     | ((__TIMESTAMP__[2]=='e'?2:__TIMESTAMP__[2]=='d'?3 \
     :__TIMESTAMP__[2]=='u'?4:__TIMESTAMP__[2]=='i'?5 \
     :__TIMESTAMP__[2]=='t'?6:__TIMESTAMP__[0]=='M'?1:7) << 13) // Week day
     | ((((__DATE__[2]=='n'?(__DATE__[1]=='a'?0:5):__DATE__[2]=='b'?1 \
     :__DATE__[2]=='r'?(__DATE__[0]=='M'?2:3):__DATE__[2]=='y'?4 \
     :__DATE__[2]=='l'?6:__DATE__[2]=='g'?7:__DATE__[2]=='p'?8 \
     :__DATE__[2] =='t'?9:__DATE__[2]=='v'?10:11)+1)/10) << 12) // Month 10
     | ((((__DATE__[2]=='n'?(__DATE__[1]=='a'?0:5):__DATE__[2]=='b'?1 \
     :__DATE__[2]=='r'?(__DATE__[0]=='M'?2:3):__DATE__[2]=='y'?4 \
     :__DATE__[2]=='l'?6:__DATE__[2]=='g'?7:__DATE__[2]=='p'?8 \
     :__DATE__[2] =='t'?9:__DATE__[2]=='v'?10:11)+1)%10) << 8) // Month 1
     | ((__DATE__[4]==' ' ? 0 : __DATE__[4]-'0') << 4) // day 10
     | (__DATE__[5]-'0'); // day 1
     
     delay(100);
     RTC->ISR &= (~RTC_ISR_INIT); // закрываем до�?туп на запи�?ь реги�?трам ча�?ов реального времени
     RTC->WPR =0xEE;
     delay(1000);
     
    }else; 

    alexey_public
    Associate II
    November 9, 2018

    Good variant.

    But I must using Hall Libraries for fully compatible with all code.

    alexey_public
    Associate II
    January 21, 2019

    In new version all is OK.

    Thank :)