stm32l0xx-hal icon indicating copy to clipboard operation
stm32l0xx-hal copied to clipboard

ADC clock configuration

Open romixlab opened this issue 4 years ago • 4 comments

It seems the if you call 'rcc.freeze(rcc::Config::msi(MSIRange::Range5));' and then enable Adc it will just freeze, because there is no clock to it (default is HSI16) and no way to change clock source. For now I just modified CFGR2 manually through unsafe code. Am I missing something?

romixlab avatar Dec 03 '20 08:12 romixlab

I encountered the same issue. To repro, one just needs to modify this line in the adc example to use the MSI clock:

-    let mut rcc = dp.RCC.freeze(Config::hsi16());
+   let mut rcc = dp.RCC.freeze(Config::msi(MSIRange::Range5));

and observe it hang on adc.read.

@romixlab Would you mind sharing your workaround? I tried:

    // HSI clock is the default, but we are not using it.  Configure ADC to use
    // APB (aka PCLK) clock instead
    p.ADC.cfgr2.modify(|_, w| w.ckmode().pclk_div4());

before ADC::new() but did not work for me. Thanks!

EDIT: ~~Ah, using ADCLK instead of PCLK did work, i.e.:~~ The ADCLK did not work either.

p.ADC.cfgr2.modify(|_, w| w.ckmode().adclk());

2nd EDIT: The above works with hsi clock, but not MSI :cry:

jcard0na avatar Sep 13 '22 21:09 jcard0na

Well, finally made it work, but was not very ergonomic. Documenting here for my future self or for others in the same pickle...

    // Enable ADC clock.  This is only needed when using PCLK as ADC clock
    // The alternative is to use HSI16 clock, but system clock is MSI 
    p.RCC.apb2enr.modify(|_,w| w.adcen().set_bit());
    // Pick MSI clock for lower power.  Range 5 is 2MHz
    let mut rcc = p.RCC.freeze(Config::msi(MSIRange::Range5));

    // Enable ACD in low frequency mode, needed because we run out of the MSI clock at 2MHz and 
    // datasheet says this need to be enabled below 3.5 MHz
    p.ADC.ccr.modify(|_, w| w.lfmen().set_bit());

    // Pick PCKL clock for ADC
    p.ADC.cfgr2.modify(|_, w| w.ckmode().pclk());
    let mut adc = Adc::new(p.ADC, &mut rcc);
    ...

jcard0na avatar Sep 14 '22 16:09 jcard0na

Sorry, couldn't find it, it was a long time ago..

romixlab avatar Sep 20 '22 20:09 romixlab

had the same problem, your workaround worked perfectly. thanks @jcard0na

any update on when this gets fixed in hal?

sreyhani avatar Oct 21 '23 08:10 sreyhani