cancel
Showing results for 
Search instead for 
Did you mean: 

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.

alexey_public
Associate II

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.

3 REPLIES 3
AVI-crak
Senior

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

Good variant.

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

alexey_public
Associate II

In new version all is OK.

Thank :)