diff --git a/rp2040-hal/src/xosc.rs b/rp2040-hal/src/xosc.rs index cf5d9ed..a499488 100644 --- a/rp2040-hal/src/xosc.rs +++ b/rp2040-hal/src/xosc.rs @@ -2,23 +2,13 @@ // See [Chapter 2 Section 16](https://datasheets.raspberrypi.org/rp2040/rp2040_datasheet.pdf) for more details use core::convert::TryInto; -use core::{ - convert::Infallible, - ops::RangeInclusive -}; +use core::{convert::Infallible, ops::RangeInclusive}; use embedded_time::{ - fraction::Fraction, + duration::{Duration, Milliseconds}, fixed_point::FixedPoint, - rate::{ - Hertz, - Megahertz, - Rate - }, - duration::{ - Milliseconds, - Duration - } + fraction::Fraction, + rate::{Hertz, Megahertz, Rate}, }; use nb::Error::WouldBlock; @@ -31,12 +21,12 @@ pub struct Disabled; /// XOSC is initialized, ie we've given parameters (typestate) pub struct Initialized { - freq_hz: Hertz + freq_hz: Hertz, } /// Stable state (typestate) -pub struct Stable{ - freq_hz: Hertz +pub struct Stable { + freq_hz: Hertz, } /// XOSC is in dormant mode (see Chapter 2, Section 16, §5) @@ -53,13 +43,14 @@ pub enum Error { FrequencyOutOfRange, /// Argument is bad : overflows, ... - BadArgument + BadArgument, } - /// Blocking helper method to setup the XOSC without going through all the steps. -pub fn setup_xosc_blocking(xosc_dev: rp2040_pac::XOSC, frequency: Hertz) -> Result, Error> { - +pub fn setup_xosc_blocking( + xosc_dev: rp2040_pac::XOSC, + frequency: Hertz, +) -> Result, Error> { let initialized_xosc = CrystalOscillator::new(xosc_dev).initialize(frequency)?; let stable_xosc_token = nb::block!(initialized_xosc.await_stabilization()).unwrap(); @@ -67,11 +58,10 @@ pub fn setup_xosc_blocking(xosc_dev: rp2040_pac::XOSC, frequency: Hertz) -> Resu Ok(initialized_xosc.get_stable(stable_xosc_token)) } - /// A Crystal Oscillator. pub struct CrystalOscillator { device: rp2040_pac::XOSC, - state: S + state: S, } impl CrystalOscillator { @@ -79,7 +69,7 @@ impl CrystalOscillator { fn transition(self, state: To) -> CrystalOscillator { CrystalOscillator { device: self.device, - state: state + state, } } @@ -90,26 +80,25 @@ impl CrystalOscillator { } impl CrystalOscillator { - /// Creates a new CrystalOscillator from the underlying device. pub fn new(dev: rp2040_pac::XOSC) -> Self { CrystalOscillator { device: dev, - state: Disabled + state: Disabled, } } /// Initializes the XOSC : frequency range is set, startup delay is calculated and set. pub fn initialize(self, frequency: Hertz) -> Result, Error> { - - const ALLOWED_FREQUENCY_RANGE: RangeInclusive> = Megahertz(1)..=Megahertz(15); + const ALLOWED_FREQUENCY_RANGE: RangeInclusive> = + Megahertz(1)..=Megahertz(15); const STABLE_DELAY: Milliseconds = Milliseconds(1_u32); const DIVIDER: Fraction = Fraction::new(256, 1); let freq_mhz: Megahertz = frequency.into(); if !ALLOWED_FREQUENCY_RANGE.contains(&freq_mhz) { - return Err(Error::FrequencyOutOfRange) + return Err(Error::FrequencyOutOfRange); } self.device.ctrl.write(|w| { @@ -118,20 +107,20 @@ impl CrystalOscillator { }); //1 ms = 10e-3 sec and Freq = 1/T where T is in seconds so 1ms converts to 1000Hz - let delay_to_hz: Hertz = STABLE_DELAY.to_rate().map_err(|_|Error::BadArgument)?; + let delay_to_hz: Hertz = STABLE_DELAY.to_rate().map_err(|_| Error::BadArgument)?; //startup_delay = ((freq_hz * 10e-3) / 256) = ((freq_hz / 1000) / 256) //See Chapter 2, Section 16, §3) //We do the calculation first. - let startup_delay = frequency. - checked_div(delay_to_hz.integer()).and_then(|r| - r.to_generic::(DIVIDER).ok() - ). - ok_or(Error::BadArgument)?; + let startup_delay = frequency + .checked_div(delay_to_hz.integer()) + .and_then(|r| r.to_generic::(DIVIDER).ok()) + .ok_or(Error::BadArgument)?; //Then we check if it fits into an u16. - let startup_delay: u16 = (*startup_delay.integer()).try_into(). - map_err(|_|Error::BadArgument)?; + let startup_delay: u16 = (*startup_delay.integer()) + .try_into() + .map_err(|_| Error::BadArgument)?; self.device.startup.write(|w| unsafe { w.delay().bits(startup_delay); @@ -143,42 +132,33 @@ impl CrystalOscillator { w }); - Ok(self.transition(Initialized { - freq_hz: frequency - })) + Ok(self.transition(Initialized { freq_hz: frequency })) } } /// A token that's given when the oscillator is stablilzed, and can be exchanged to proceed to the next stage. pub struct StableOscillatorToken { - _private : () + _private: (), } impl CrystalOscillator { - /// One has to wait for the startup delay before using the oscillator, ie awaiting stablilzation of the XOSC pub fn await_stabilization(&self) -> nb::Result { - if self.device.status.read().stable().bit_is_clear() { - return Err(WouldBlock) + return Err(WouldBlock); } - Ok(StableOscillatorToken { - _private: () - }) + Ok(StableOscillatorToken { _private: () }) } /// Returns the stablilzed oscillator pub fn get_stable(self, _token: StableOscillatorToken) -> CrystalOscillator { let freq_hz = self.state.freq_hz; - self.transition(Stable { - freq_hz - }) + self.transition(Stable { freq_hz }) } } impl CrystalOscillator { - /// Operating frequency of the XOSC in hertz pub fn operating_frequency(&self) -> Hertz { self.state.freq_hz @@ -186,7 +166,7 @@ impl CrystalOscillator { /// Disables the XOSC pub fn disable(self) -> CrystalOscillator { - self.device.ctrl.modify(|_r,w| { + self.device.ctrl.modify(|_r, w| { w.enable().disable(); w }); @@ -203,7 +183,7 @@ impl CrystalOscillator { //taken from the C SDK const XOSC_DORMANT_VALUE: u32 = 0x636f6d61; - self.device.dormant.write(|w| unsafe { + self.device.dormant.write(|w| { w.bits(XOSC_DORMANT_VALUE); w });