Skip to content

Commit

Permalink
Add startup_delay_multiplier parameter to xosc initialization
Browse files Browse the repository at this point in the history
This works the same way as PICO_XOSC_STARTUP_DELAY_MULTIPLIER in the Pico SDK
  • Loading branch information
jannic committed Dec 31, 2023
1 parent 9c4eea7 commit 38f5963
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions rp2040-hal/src/xosc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn setup_xosc_blocking(
xosc_dev: XOSC,
frequency: HertzU32,
) -> Result<CrystalOscillator<Stable>, Error> {
let initialized_xosc = CrystalOscillator::new(xosc_dev).initialize(frequency)?;
let initialized_xosc = CrystalOscillator::new(xosc_dev).initialize(frequency, 1)?;

let stable_xosc_token = nb::block!(initialized_xosc.await_stabilization()).unwrap();

Expand Down Expand Up @@ -91,7 +91,12 @@ impl CrystalOscillator<Disabled> {
}

/// Initializes the XOSC : frequency range is set, startup delay is calculated and set.
pub fn initialize(self, frequency: HertzU32) -> Result<CrystalOscillator<Initialized>, Error> {
/// Set startup_delay_multiplier to a value > 1 when using a slow-starting oscillator.
pub fn initialize(
self,
frequency: HertzU32,
startup_delay_multiplier: u32,
) -> Result<CrystalOscillator<Initialized>, Error> {
const ALLOWED_FREQUENCY_RANGE: RangeInclusive<HertzU32> =
HertzU32::MHz(1)..=HertzU32::MHz(15);
//1 ms = 10e-3 sec and Freq = 1/T where T is in seconds so 1ms converts to 1000Hz
Expand All @@ -102,6 +107,10 @@ impl CrystalOscillator<Disabled> {
return Err(Error::FrequencyOutOfRange);
}

if startup_delay_multiplier == 0 {
return Err(Error::BadArgument);
}

self.device.ctrl.write(|w| {
w.freq_range()._1_15mhz();
w
Expand All @@ -112,6 +121,7 @@ impl CrystalOscillator<Disabled> {
//See Chapter 2, Section 16, §3)
//We do the calculation first.
let startup_delay = frequency.to_Hz() / (STABLE_DELAY_AS_HZ.to_Hz() * DIVIDER);
let startup_delay = startup_delay.saturating_mul(startup_delay_multiplier);

//Then we check if it fits into an u16.
let startup_delay: u16 = startup_delay.try_into().map_err(|_| Error::BadArgument)?;
Expand Down

0 comments on commit 38f5963

Please sign in to comment.