stm32l0xx-hal
stm32l0xx-hal copied to clipboard
ADC clock configuration
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?
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:
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);
...
Sorry, couldn't find it, it was a long time ago..
had the same problem, your workaround worked perfectly. thanks @jcard0na
any update on when this gets fixed in hal?