cancel
Showing results for 
Search instead for 
Did you mean: 

LSE is disabled right after enabling it when using LowLayer code generated with CubeMX

WilkoL
Senior

I'm using the STM32L031 and Low Layer code, generated with STM32CubeMX (lateset version)

If the selected oscillator for the RTC is not LSE (e.g. after poweron) the code generated with STM32CubeMX will disable the LSE via a ForceBackupDomainReset right after enabling it.

This is the entire SystemClock_Config:

void SystemClock_Config(void)
{
  LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);
  while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_0);
  LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
  LL_RCC_MSI_Enable();
  while(LL_RCC_MSI_IsReady() != 1);
  LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_5);
  LL_RCC_MSI_SetCalibTrimming(0);
  
  
  LL_PWR_EnableBkUpAccess();
  LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_LOW);
  LL_RCC_LSE_Enable();
  while(LL_RCC_LSE_IsReady() != 1);
  if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE)
  {
    LL_RCC_ForceBackupDomainReset();
    LL_RCC_ReleaseBackupDomainReset();
    LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
  }
  
  
  LL_RCC_EnableRTC();
  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
  LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
  while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI);
  LL_Init1msTick(2097000);
  LL_SetSystemCoreClock(2097000);
  LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_LSE, LL_RCC_MCO1_DIV_16);
}

and this is the part that first enables the LSE and disables it when the RTC does not have the LSE as source clock:

  LL_PWR_EnableBkUpAccess();
  LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_LOW);
  LL_RCC_LSE_Enable();
  while(LL_RCC_LSE_IsReady() != 1);
  if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE)
  {
    LL_RCC_ForceBackupDomainReset();
    LL_RCC_ReleaseBackupDomainReset();
    LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
  }

It needs to (re-) enable the LSE inside the if statment again.

4 REPLIES 4
Piranha
Chief II

Useless disables, enables, resets, rewrites etc. introducing bugs, which wouldn't be there without that useless bloat - that's just the way HAL/Cube "professionals" write code. Drop the CubeMX code generation and leave those problems behind.

WilkoL
Senior

This isn't the HAL, it is the LL which is somewhat similar to the old SPL. It works quite well and I think that writing :

LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_3);

makes the intentions of the programmer more clear than:

GPIOA->BSRR = 0x0004;

It may be not as efficient but sometimes that is less important, in the code I showed there simply is a mistake where the LSE accidentally gets disabled. I sometimes make mistakes like that, it just needs to be fixed. Which is what I did in my code and hopefully ST will do in theirs.

Piranha
Chief II

Writing magic numbers is a misrepresentation of register level programming. A correct direct analogy to your example would be:

GPIOA->BSRR = GPIO_BSRR_BS3;

I know what LL is. Using it one still must read the reference manual, but, as it renames the registers and bits, it doubles the amount of work, because one has to translate from register names to LL names and back all the time. And you are still writing port A, pin 3, which doesn't make anything clear. If you want to make something really clear, then you have to write like this:

DRV_GPIO_PinSet1(BSP_LED_SYSTEM);

Now that's a clear intent of what exactly is being done there. Therefore make your own high-level sane driver libraries with typical often used functionality, but implement them with an effective register level code inside.

WilkoL
Senior
  1. Agreed, GPIO_BSRR_BS3 is better than 0x0004, although I 'm quite used to translating pin numbers to hex by head.
  2. I don't know why you mention that one "still" has to read the reference manual. Don't you read it? I have it open all the time. Or do you make your libraries so that everything is abstracted away? If so, why not use the HAL?
  3. I'm used to writing "bare metal" code, but I like the comfort of the thin layer that LL puts on top of that. Yes, it does add some extra code, I can live with that.