AnsweredAssumed Answered

Enabling LSE

Question asked by waclawek.jan on Jul 8, 2013
Latest reply on May 26, 2014 by waclawek.jan
When trying to run the LSE oscillator (at 32.768kHz), I stumbled upon the following problem:

 PWR->CR |= PWR_CR_DBP;  // disable backup-domain lock
 RCC->BDCR = RCC_BDCR_LSEON;  // enable 32.768kHz oscillator

did not result in the LSEON bit being set, unless single-stepped in debugger. Turns out, there must be some delay between the two writes in order the second is accomplished.

The reason is, that while the PWR register is at the APB1 bus (and on this 'F4xx design its clock is set to system clock divided by 4), RCC is directly on AHB1. Thus, the write to PWR->CR, after being buffered, has to pass the AHB/APB synchronizer, but meantime the processor may continue by writing into RCC->BDCR, but that gets ignored as the lock has not been removed, yet.

A bullet-proof solution might perhaps be similar to:
PWR->CR |= PWR_CR_DBP;
while ((RCC->BDCR AND RCC_BDCR_LSERDY) == 0) {  // wait until LSE starts up
  RCC->BDCR = RCC_BDCR_LSEON;  // enable 32.768kHz oscillator
}

(plus optional timeout for case of hardware LSE fault).
 
Browsing through forum I saw several messages reporting a similar problem; however, it's hard to tell what was the root problem in individual cases as they all differ in details (and of course many of the vital information might have remained untold), and in several cases where a solution was found I suspect the "solution" just coincidentally masked the root cause.

JW

Outcomes