cancel
Showing results for 
Search instead for 
Did you mean: 

my RTC don't run after power off and RTC_BKP_DR0 was cleared

Tinnagit
Senior II

I have Nucleo G0B1RE.

I had add 3V battery to VBAT.

I had change to use LSE for RTC.

I had add RTC_BKP_DR to keep time before reset so RTC time reg was not cleared after reset but It was re-initial while booting.

But RTC don't count while power off and RTC_BKP_DR was cleared after reset.

So I don't know what my mistake?

This is my system clock config

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  /** Configure LSE Drive Capability
  */
  HAL_PWR_EnableBkUpAccess();
  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
 
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 8;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Enables the Clock Security System
  */
  HAL_RCC_EnableLSECSS();
}

and This is my RTC Initial

static void MX_RTC_Init(void)
{
 
  /* USER CODE BEGIN RTC_Init 0 */
 
  /* USER CODE END RTC_Init 0 */
 
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
 
  /* USER CODE BEGIN RTC_Init 1 */
  rtc_state = 0x01;
  /* USER CODE END RTC_Init 1 */
 
  /** Initialize RTC Only
  */
  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;
  hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
 
  /* USER CODE BEGIN Check_RTC_BKUP */
  rtc_state |= 0x02;
  if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){
	  rtc_state |= 0x04;
  /* USER CODE END Check_RTC_BKUP */
 
  /** Initialize RTC and set the Time and Date
  */
  sTime.Hours = 0x0;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.SubSeconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_SET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 0x1;
  sDate.Year = 0x0;
 
  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */
   rtc_state |= 0x08;
   HAL_PWR_EnableBkUpAccess();
   HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2);
   HAL_PWR_DisableBkUpAccess();
   rtc_state |= 0x10;
   }
  /* USER CODE BEGIN RTC_Init 2 */
 
  /* USER CODE END RTC_Init 2 */
 
}

1 ACCEPTED SOLUTION

Accepted Solutions

Did you disconnect SB26?

JW

View solution in original post

6 REPLIES 6

Did you disconnect SB26?

JW

No I don't.

Do I need to disconnect it?

Oh, What!!!!

That's work.

Your suggestion is great, That's wonderful.

Thank You so Much.

OK, Thank you again.

And for another one who read this question later.

I had disconnect SB26

and add those line to RTC Initial.

  HAL_RTCEx_EnableBypassShadow(&hrtc);
  if(HAL_RTC_WaitForSynchro(&hrtc) != HAL_OK)
  {
	  Error_Handler();
  }

it's going to switched to allow you can get date and time from register that update with VBAT.

So you will got an update time.

And this my update RTC initial code.

static void MX_RTC_Init(void)
{
 
  /* USER CODE BEGIN RTC_Init 0 */
 
  /* USER CODE END RTC_Init 0 */
 
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
 
  /* USER CODE BEGIN RTC_Init 1 */
  rtc_state = 0x01;
  /* USER CODE END RTC_Init 1 */
 
  /** Initialize RTC Only
  */
  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;
  hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN Check_RTC_BKUP */
  HAL_RTCEx_EnableBypassShadow(&hrtc);
  if(HAL_RTC_WaitForSynchro(&hrtc) != HAL_OK)
  {
	  Error_Handler();
  }
  rtc_state |= 0x02;
  if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) != 0x32F2){
	  rtc_state |= 0x04;
  /* USER CODE END Check_RTC_BKUP */
 
  /** Initialize RTC and set the Time and Date
  */
  sTime.Hours = 0x0;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.SubSeconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_SET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 0x1;
  sDate.Year = 0x0;
 
  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */
   rtc_state |= 0x08;
   HAL_PWR_EnableBkUpAccess();
   HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1,0x32F2);
   HAL_PWR_DisableBkUpAccess();
   rtc_state |= 0x10;
   }
  /* USER CODE BEGIN RTC_Init 2 */
 
  /* USER CODE END RTC_Init 2 */
 
}

Note, that by setting BYPHSAD=1 you have to follow the "read twice, compare, repeat if no match" procedure, read the relevant chapter in RM and perhaps the second part of this.

Also, RSF after setting BYPSHAD=1 won't get set, the Cube/HAL function you're using for waiting for RSF (HAL_RTC_WaitForSynchro()) has a timeout though so that's why it won't loop forever for you. OTOH, HAL_RTC_WaitForSynchro() starts with clearing RSF without disabling the RTC registers protection, so it won't clear RSF if it was set previously, and that's another mechanism how HAL_RTC_WaitForSynchro() will appear to working just OK for you.

JW

Oh Thank You so much.

I had rewrite RTC initial already.

As you comment that BYPHSAD for access a shadow register is not necessary.

I just let is sync data between shadow register and actual register by HAL_RTC_WaitForSynchro

and waiting for it complete the process. that's all.

So I don't use HAL_RTCEx_EnableBypassShadow now.

Thank You so much.