diff --git a/rp2040-hal/src/pll.rs b/rp2040-hal/src/pll.rs index 598c554..02e8537 100644 --- a/rp2040-hal/src/pll.rs +++ b/rp2040-hal/src/pll.rs @@ -18,7 +18,12 @@ use nb::Error::WouldBlock; pub trait State {} /// PLL is disabled. -pub struct Disabled; +pub struct Disabled { + refdiv: u8, + fbdiv: u16, + post_div1: u8, + post_div2: u8, +} /// PLL is configured, started and locking into its designated frequency. pub struct Locking { @@ -118,19 +123,11 @@ pub mod common_configs { impl PhaseLockedLoop { /// Instantiates a new Phase-Locked-Loop device. - pub fn new(dev: D) -> PhaseLockedLoop { - PhaseLockedLoop { - state: Disabled, - device: dev, - } - } - - /// Configures and starts the PLL : it switches to Locking state. - pub fn initialize( - self, + pub fn new( + dev: D, xosc_frequency: Generic, config: PLLConfig, - ) -> Result, Error> + ) -> Result, Error> where R: Into>, { @@ -155,10 +152,6 @@ impl PhaseLockedLoop { let ref_freq_range: Range> = Hertz(5_000_000)..vco_freq.div(16); - // Turn off PLL in case it is already running - self.device.pwr.reset(); - self.device.fbdiv_int.reset(); - let ref_freq_hz = Hertz::::try_from(xosc_frequency) .map_err(|_| Error::BadArgument)? .checked_div(&(config.refdiv as u32)) @@ -168,11 +161,6 @@ impl PhaseLockedLoop { return Err(Error::RefFreqOutOfRange); } - self.device.cs.write(|w| unsafe { - w.refdiv().bits(config.refdiv); - w - }); - let fbdiv = vco_freq .checked_div(ref_freq_hz.integer()) .ok_or(Error::BadArgument)?; @@ -185,8 +173,34 @@ impl PhaseLockedLoop { return Err(Error::FBDIVOutOfRange); } + let refdiv = config.refdiv; + let post_div1 = config.post_div1; + let post_div2 = config.post_div2; + + Ok(PhaseLockedLoop { + state: Disabled { + refdiv, + fbdiv, + post_div1, + post_div2, + }, + device: dev, + }) + } + + /// Configures and starts the PLL : it switches to Locking state. + pub fn initialize(self) -> PhaseLockedLoop { + // Turn off PLL in case it is already running + self.device.pwr.reset(); + self.device.fbdiv_int.reset(); + + self.device.cs.write(|w| unsafe { + w.refdiv().bits(self.state.refdiv); + w + }); + self.device.fbdiv_int.write(|w| unsafe { - w.fbdiv_int().bits(fbdiv); + w.fbdiv_int().bits(self.state.fbdiv); w }); @@ -197,13 +211,13 @@ impl PhaseLockedLoop { w }); - let post_div1 = config.post_div1; - let post_div2 = config.post_div2; + let post_div1 = self.state.post_div1; + let post_div2 = self.state.post_div2; - Ok(self.transition(Locking { + self.transition(Locking { post_div1, post_div2, - })) + }) } }