Question
Enabling LSE
Posted on July 08, 2013 at 14:05
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 #good-catch #lse #stm32-hazard