AnsweredAssumed Answered

STM32CubeMX MCU package for STM32F1, LSE & RTC problems

Question asked by Wilko Lunenburg on Apr 14, 2018
Latest reply on Apr 30, 2018 by Wilko Lunenburg

Using:

Truestudio for STM32 v9.0.0.0

STM32CubeMX v4.25.0 with STM32CubeF1 Firmware Package V1.6.1

uC STM32F103RB

LL_drivers only

 

 

LL_Code generated for the STM32F1 family by STM32CubeMx  seems to fail to configure the LSE oscillator as it omits to enable power_interface clock.

And why does it erase the BackupDomain at every reset? That seems to defeat the purpose of it.

See below:

 

void SystemClock_Config(void)
{
  LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
  if (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_2)
    {
      Error_Handler();
    }
  LL_RCC_HSE_Enable();

  /* Wait till HSE is ready */
  while (LL_RCC_HSE_IsReady() != 1)
    {
    }
  LL_PWR_EnableBkUpAccess();            //fails as there is no power_interface clock
  LL_RCC_ForceBackupDomainReset();        //why??!?!!
  LL_RCC_ReleaseBackupDomainReset();
  LL_RCC_LSE_Enable();                    //fails as there is no power_interface clock

 

  /* Wait till LSE is ready */
  while (LL_RCC_LSE_IsReady() != 1)        //it all ends here ;-)
    {
    }
  LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
  LL_RCC_EnableRTC();
  LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE_DIV_1, LL_RCC_PLL_MUL_9);
  LL_RCC_PLL_Enable();

  /* Wait till PLL is ready */
  while (LL_RCC_PLL_IsReady() != 1)
    {
    }
  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
  LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);

  /* Wait till System clock is ready */
  while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
    {
    }
  LL_Init1msTick(72000000);                    //why no use of SystemCoreClockUpdate();
  LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
  LL_SetSystemCoreClock(72000000);

  /* SysTick_IRQn interrupt configuration */
  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));

}

 

 

 

Then there are some things in the initialisation of the RTC itself.

It tries to enable access to the BackupDomain and enable the RTC, both were (should have been) already done in the SystemClock config.

 

I selected to have the RTC output on the TAMPER pin, but there is no RTC_InitStruct.OutPutSource = LL_RTC_CALIB_OUTPUT_RTCCLOCK;

 

As the STM32F103RB does not have a synchronous prescaler I understand that only the AsynchPrescaler will be set, but the STM32Cube does not let me put anything above 127 as its value.  See below:

 

static void MX_RTC_Init(void)
{
  LL_RTC_InitTypeDef RTC_InitStruct;
  LL_RTC_TimeTypeDef RTC_TimeStruct;

  LL_PWR_EnableBkUpAccess();                            //should already have been enabled in SystemClock_Config
  /* Enable BKP CLK enable for backup registers */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_BKP);
  /* Peripheral clock enable */
  LL_RCC_EnableRTC();                                    //should already have been enabled in SystemClock_Config

  /**Initialize RTC and set the Time and Date
  */
  RTC_InitStruct.AsynchPrescaler = 127;                    //cannot enter 32767 in STM32CubeMX
  LL_RTC_Init(RTC, &RTC_InitStruct);                    //missing: RTC_InitStruct.OutPutSource = LL_RTC_CALIB_OUTPUT_RTCCLOCK;

  LL_RTC_SetAsynchPrescaler(RTC, 127);                    //again?

  /**Initialize RTC and set the Time and Date
  */

  RTC_TimeStruct.Hours = 11;
  RTC_TimeStruct.Minutes = 30;
  RTC_TimeStruct.Seconds = 0;
  LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BIN, &RTC_TimeStruct);
}

 

The actual setting of the RTC->PRLH and PRLL does this:

 

__STATIC_INLINE void LL_RTC_SetAsynchPrescaler(RTC_TypeDef *RTCx, uint32_t AsynchPrescaler)
{
  MODIFY_REG(RTCx->PRLH, RTC_PRLH_PRL, (AsynchPrescaler >> 16));
  MODIFY_REG(RTCx->PRLL, RTC_PRLL_PRL, (AsynchPrescaler & RTC_PRLL_PRL));                //reading a write-only register?! should be 0x00FF ?
}

 

And once the RTC has been set, it shouldn't be initialised again every time the uC is reset. At initialisation it resets the prescaler so you might lose up to a second at every reset.

 

Regards,

Wilko

 

Attachments

Outcomes