From d0d9291cdee12bcdf9c294cacba94dc6e6da9eb6 Mon Sep 17 00:00:00 2001 From: Nic0w Date: Sat, 24 Apr 2021 13:38:17 +0200 Subject: [PATCH 01/11] Working HAL for the XOSC --- rp2040-hal/Cargo.toml | 1 + rp2040-hal/src/lib.rs | 3 + rp2040-hal/src/xosc.rs | 192 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 rp2040-hal/src/xosc.rs diff --git a/rp2040-hal/Cargo.toml b/rp2040-hal/Cargo.toml index 782adb1..b0c0238 100644 --- a/rp2040-hal/Cargo.toml +++ b/rp2040-hal/Cargo.toml @@ -14,3 +14,4 @@ cortex-m = "0.7.1" embedded-hal = "0.2.4" nb = "1.0.0" rp2040-pac = "0.1.1" +embedded-time = "0.10.1" diff --git a/rp2040-hal/src/lib.rs b/rp2040-hal/src/lib.rs index e8d96e2..8fb2aba 100644 --- a/rp2040-hal/src/lib.rs +++ b/rp2040-hal/src/lib.rs @@ -10,6 +10,8 @@ extern crate cortex_m; extern crate embedded_hal as hal; extern crate nb; +extern crate embedded_time; + pub extern crate rp2040_pac as pac; pub mod adc; @@ -24,3 +26,4 @@ pub mod timer; pub mod uart; pub mod usb; pub mod watchdog; +pub mod xosc; diff --git a/rp2040-hal/src/xosc.rs b/rp2040-hal/src/xosc.rs new file mode 100644 index 0000000..2f07acf --- /dev/null +++ b/rp2040-hal/src/xosc.rs @@ -0,0 +1,192 @@ +//! Crystal Oscillator (XOSC) +// See [Chapter 2 Section 16](https://datasheets.raspberrypi.org/rp2040/rp2040_datasheet.pdf) for more details + +use core::{ + convert::Infallible, + ops::RangeInclusive +}; + +use embedded_time::{ + fraction::Fraction, + fixed_point::FixedPoint, + rate::{ + Hertz, + Megahertz, + }, + duration::{ + Seconds, + Milliseconds, + Duration + } +}; + +use nb::Error::WouldBlock; + +/// State of the Crystal Oscillator (typestate trait) +pub trait State {} + +/// XOSC is disabled (typestate) +pub struct Disabled; + +/// XOSC is initialized, ie we've given parameters (typestate) +pub struct Initialized { + freq_hz: Hertz +} + +/// Stable state (typestate) +pub struct Stable{ + freq_hz: Hertz +} + +/// XOSC is disabling (typestate) +pub struct Disabling; + +/// XOSC is in dormant mode (see Chapter 2, Section 16, §5) +pub struct Dormant; + +impl State for Disabled {} +impl State for Initialized {} +impl State for Stable {} +impl State for Disabling {} +impl State for Dormant {} + +/// Possible errors when initializing the CrystalOscillator +pub enum Error { + /// Frequency is out of the 1-15MHz range (see datasheet) + FrequencyOutOfRange, + + /// Argument is bad : overflows, ... + BadArgument +} + +/// A Crystal Oscillator. +pub struct CrystalOscillator { + device: rp2040_pac::XOSC, + state: S +} + +impl CrystalOscillator { + /// Transitions the oscillator to another state. + fn transition(self, state: To) -> CrystalOscillator { + CrystalOscillator { + device: self.device, + state: state + } + } + + /// Releases the underlying device. + pub fn free(self) -> rp2040_pac::XOSC { + self.device + } +} + +impl CrystalOscillator { + + /// Creates a new CrystalOscillator from the underlying device. + pub fn new(dev: rp2040_pac::XOSC) -> Self { + CrystalOscillator { + device: dev, + state: Disabled + } + } + + /// Initializes the XOSC : frequency range is set, startup delay is calculated and set. + pub fn initialize(self, frequency: Megahertz) -> Result, Error> { + + const ALLOWED_FREQUENCY_RANGE: RangeInclusive> = Megahertz(1)..=Megahertz(15); + const STABLE_DELAY: Milliseconds = Milliseconds(1_u64); + const DIVIDER: Fraction = Fraction::new(1, 256); + + if !ALLOWED_FREQUENCY_RANGE.contains(&frequency) { + return Err(Error::FrequencyOutOfRange) + } + + self.device.ctrl.write(|w| { + w.freq_range()._1_15mhz(); + w + }); + + let freq_hz: Hertz = frequency.into(); + let delay_sec: Seconds = STABLE_DELAY.into(); + + //let startup_delay = ((freq_hz / 1000) + 128) / 256; + let startup_delay = delay_sec. + checked_mul(freq_hz.integer()).and_then(|r| + r.to_generic::(DIVIDER).ok() + ). + ok_or(Error::BadArgument)?; + + self.device.startup.write(|w| unsafe { + w.delay().bits(*startup_delay.integer() as u16); + w + }); + + self.device.ctrl.write(|w| { + w.enable().enable(); + w + }); + + Ok(self.transition(Initialized { + freq_hz: freq_hz + })) + } +} + +/// A token that's given when the oscillator is stablilzed, and can be exchanged to proceed to the next stage. +pub struct StableOscillatorToken { + _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) + } + + 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:freq_hz + }) + } +} + +impl CrystalOscillator { + + /// Operating frequency of the XOSC in hertz + pub fn operating_frequency(&self) -> Hertz { + self.state.freq_hz + } + + /// Disables the XOSC + pub fn disable(self) -> CrystalOscillator { + self.device.ctrl.modify(|_r,w| { + w.enable().disable(); + w + }); + + self.transition(Disabling) + } + + /// Put the XOSC in dormant state + pub fn dormant(self) -> CrystalOscillator { + //taken from the C SDK + const XOSC_DORMANT_VALUE: u32 = 0x636f6d61; + + self.device.dormant.write(|w| unsafe { + w.bits(XOSC_DORMANT_VALUE); + w + }); + + self.transition(Dormant) + } +} From ed1e847618cccc54780963e664ffb1ef043319e3 Mon Sep 17 00:00:00 2001 From: Nic0w Date: Sat, 24 Apr 2021 22:26:26 +0200 Subject: [PATCH 02/11] Remove line as it builds fine without it. --- rp2040-hal/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/rp2040-hal/src/lib.rs b/rp2040-hal/src/lib.rs index 8fb2aba..477db61 100644 --- a/rp2040-hal/src/lib.rs +++ b/rp2040-hal/src/lib.rs @@ -10,7 +10,6 @@ extern crate cortex_m; extern crate embedded_hal as hal; extern crate nb; -extern crate embedded_time; pub extern crate rp2040_pac as pac; From 568cafe2d109ac3263c530b5adad708cf6efc063 Mon Sep 17 00:00:00 2001 From: Nic0w Date: Sat, 24 Apr 2021 23:38:49 +0200 Subject: [PATCH 03/11] Multiple changes related to @tdittr 's comments --- rp2040-hal/src/xosc.rs | 47 +++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/rp2040-hal/src/xosc.rs b/rp2040-hal/src/xosc.rs index 2f07acf..54a5147 100644 --- a/rp2040-hal/src/xosc.rs +++ b/rp2040-hal/src/xosc.rs @@ -1,6 +1,7 @@ //! Crystal Oscillator (XOSC) // 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 @@ -30,24 +31,20 @@ 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 + freq_hz: Hertz } -/// XOSC is disabling (typestate) -pub struct Disabling; - /// XOSC is in dormant mode (see Chapter 2, Section 16, §5) pub struct Dormant; impl State for Disabled {} impl State for Initialized {} impl State for Stable {} -impl State for Disabling {} impl State for Dormant {} /// Possible errors when initializing the CrystalOscillator @@ -91,10 +88,10 @@ impl CrystalOscillator { } /// Initializes the XOSC : frequency range is set, startup delay is calculated and set. - pub fn initialize(self, frequency: Megahertz) -> Result, Error> { + pub fn initialize(self, frequency: Hertz) -> Result, Error> { const ALLOWED_FREQUENCY_RANGE: RangeInclusive> = Megahertz(1)..=Megahertz(15); - const STABLE_DELAY: Milliseconds = Milliseconds(1_u64); + const STABLE_DELAY: Milliseconds = Milliseconds(1_u32); const DIVIDER: Fraction = Fraction::new(1, 256); if !ALLOWED_FREQUENCY_RANGE.contains(&frequency) { @@ -106,18 +103,22 @@ impl CrystalOscillator { w }); - let freq_hz: Hertz = frequency.into(); - let delay_sec: Seconds = STABLE_DELAY.into(); + let delay_sec: Seconds = STABLE_DELAY.into(); - //let startup_delay = ((freq_hz / 1000) + 128) / 256; + //startup_delay = ((freq_hz * 10e-3) / 256; See Chapter 2, Section 16, §3) + //We do the calculation first. let startup_delay = delay_sec. - checked_mul(freq_hz.integer()).and_then(|r| - r.to_generic::(DIVIDER).ok() + checked_mul(frequency.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)?; + self.device.startup.write(|w| unsafe { - w.delay().bits(*startup_delay.integer() as u16); + w.delay().bits(startup_delay); w }); @@ -127,7 +128,7 @@ impl CrystalOscillator { }); Ok(self.transition(Initialized { - freq_hz: freq_hz + freq_hz: frequency })) } } @@ -155,7 +156,7 @@ impl CrystalOscillator { pub fn get_stable(self, _token: StableOscillatorToken) -> CrystalOscillator { let freq_hz = self.state.freq_hz; self.transition(Stable { - freq_hz:freq_hz + freq_hz }) } } @@ -163,22 +164,26 @@ impl CrystalOscillator { impl CrystalOscillator { /// Operating frequency of the XOSC in hertz - pub fn operating_frequency(&self) -> Hertz { + pub fn operating_frequency(&self) -> Hertz { self.state.freq_hz } /// Disables the XOSC - pub fn disable(self) -> CrystalOscillator { + pub fn disable(self) -> CrystalOscillator { self.device.ctrl.modify(|_r,w| { w.enable().disable(); w }); - self.transition(Disabling) + self.transition(Disabled) } - /// Put the XOSC in dormant state - pub fn dormant(self) -> CrystalOscillator { + /// Put the XOSC in DORMANT state. + /// This method is marked unsafe because prior to switch the XOSC into DORMANT state, + /// PLLs must be stopped and IRQs have to be properly configured. + /// This method does not do any of that, it merely switches the XOSC to DORMANT state. + /// See Chapter 2, Section 16, §5) for details. + pub unsafe fn dormant(self) -> CrystalOscillator { //taken from the C SDK const XOSC_DORMANT_VALUE: u32 = 0x636f6d61; From d5cbd44adeb9137df7394b7daf887aafe5f2703c Mon Sep 17 00:00:00 2001 From: Nic0w Date: Sun, 25 Apr 2021 00:36:46 +0200 Subject: [PATCH 04/11] Fixing calculation bug pointed out by @tdittr --- rp2040-hal/src/xosc.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/rp2040-hal/src/xosc.rs b/rp2040-hal/src/xosc.rs index 54a5147..124cde6 100644 --- a/rp2040-hal/src/xosc.rs +++ b/rp2040-hal/src/xosc.rs @@ -92,7 +92,7 @@ impl CrystalOscillator { const ALLOWED_FREQUENCY_RANGE: RangeInclusive> = Megahertz(1)..=Megahertz(15); const STABLE_DELAY: Milliseconds = Milliseconds(1_u32); - const DIVIDER: Fraction = Fraction::new(1, 256); + const DIVIDER: Fraction = Fraction::new(256, 1); if !ALLOWED_FREQUENCY_RANGE.contains(&frequency) { return Err(Error::FrequencyOutOfRange) @@ -103,12 +103,14 @@ impl CrystalOscillator { w }); - let delay_sec: Seconds = STABLE_DELAY.into(); + //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(); - //startup_delay = ((freq_hz * 10e-3) / 256; See Chapter 2, Section 16, §3) + //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 = delay_sec. - checked_mul(frequency.integer()).and_then(|r| + let startup_delay = frequency. + checked_div(delay_to_hz.integer()).and_then(|r| r.to_generic::(DIVIDER).ok() ). ok_or(Error::BadArgument)?; @@ -118,7 +120,7 @@ impl CrystalOscillator { map_err(|_|Error::BadArgument)?; self.device.startup.write(|w| unsafe { - w.delay().bits(startup_delay); + w.delay().bits(startup_delay+1); w }); From 72694a07b5bff9dd0531e4042c08c5fb04e6824c Mon Sep 17 00:00:00 2001 From: Nic0w Date: Sun, 25 Apr 2021 08:58:43 +0200 Subject: [PATCH 05/11] Fix frequency range check. --- rp2040-hal/src/xosc.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rp2040-hal/src/xosc.rs b/rp2040-hal/src/xosc.rs index 124cde6..b97724d 100644 --- a/rp2040-hal/src/xosc.rs +++ b/rp2040-hal/src/xosc.rs @@ -94,7 +94,9 @@ impl CrystalOscillator { const STABLE_DELAY: Milliseconds = Milliseconds(1_u32); const DIVIDER: Fraction = Fraction::new(256, 1); - if !ALLOWED_FREQUENCY_RANGE.contains(&frequency) { + let freq_mhz: Megahertz = frequency.into(); + + if !ALLOWED_FREQUENCY_RANGE.contains(&freq_mhz) { return Err(Error::FrequencyOutOfRange) } @@ -120,7 +122,7 @@ impl CrystalOscillator { map_err(|_|Error::BadArgument)?; self.device.startup.write(|w| unsafe { - w.delay().bits(startup_delay+1); + w.delay().bits(startup_delay); w }); From 8f6aea6a31b04b43851b4755cd463b3e11d84b97 Mon Sep 17 00:00:00 2001 From: Nic0w Date: Sun, 25 Apr 2021 09:03:20 +0200 Subject: [PATCH 06/11] Fix compilation issues. --- rp2040-hal/src/xosc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rp2040-hal/src/xosc.rs b/rp2040-hal/src/xosc.rs index b97724d..0d3a1f5 100644 --- a/rp2040-hal/src/xosc.rs +++ b/rp2040-hal/src/xosc.rs @@ -13,9 +13,9 @@ use embedded_time::{ rate::{ Hertz, Megahertz, + Rate }, duration::{ - Seconds, Milliseconds, Duration } @@ -106,7 +106,7 @@ 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(); + 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) From 2a704a73f0fa0178e0775c2aec64183061deee4c Mon Sep 17 00:00:00 2001 From: Nic0w Date: Sun, 25 Apr 2021 16:34:48 +0200 Subject: [PATCH 07/11] Adding blocking helper method to setup the XOSC easily. --- rp2040-hal/src/xosc.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rp2040-hal/src/xosc.rs b/rp2040-hal/src/xosc.rs index 0d3a1f5..cf5d9ed 100644 --- a/rp2040-hal/src/xosc.rs +++ b/rp2040-hal/src/xosc.rs @@ -56,6 +56,18 @@ pub enum Error { 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> { + + let initialized_xosc = CrystalOscillator::new(xosc_dev).initialize(frequency)?; + + let stable_xosc_token = nb::block!(initialized_xosc.await_stabilization()).unwrap(); + + Ok(initialized_xosc.get_stable(stable_xosc_token)) +} + + /// A Crystal Oscillator. pub struct CrystalOscillator { device: rp2040_pac::XOSC, From 39f02c4a441dad79f6e8bbb3199130a3f1d61c1a Mon Sep 17 00:00:00 2001 From: tdittr Date: Tue, 27 Apr 2021 11:59:44 +0200 Subject: [PATCH 08/11] Add `cargo test` to CI run and fix an error found by it Besides the normal usage of unit-tests this also ensures that example in doc-comments do at least compile. --- .github/workflows/check.yml | 4 ++++ rp2040-hal/src/rom_data.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 3319f39..3441ac5 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -25,3 +25,7 @@ jobs: with: command: clippy args: -- -Dwarnings + - uses: actions-rs/cargo@v1 + with: + command: test + args: --target x86_64-unknown-linux-gnu diff --git a/rp2040-hal/src/rom_data.rs b/rp2040-hal/src/rom_data.rs index e55ccb3..8b80148 100644 --- a/rp2040-hal/src/rom_data.rs +++ b/rp2040-hal/src/rom_data.rs @@ -266,7 +266,7 @@ float_funcs! { /// Convert a float to a signed 64-bit integer, rounding towards -Infinity, and clamping /// the result to lie within the range -0x8000000000000000 to 0x7FFFFFFFFFFFFFFF 0x6c float_to_int64(v: f32) -> i64; - /// Convert a float to a signed fixed point 64-bit integer representation where n + /// Convert a float to a signed fixed point 64-bit integer representation where n /// specifies the position of the binary point in the resulting fixed point representation - /// e.g. _float2fix(0.5f, 16) == 0x8000. This method rounds towards -Infinity, and /// clamps the resulting integer to lie within the range -0x8000000000000000 to From 1b4291307758b71dbdfb4ba28ec300154d169aa1 Mon Sep 17 00:00:00 2001 From: 9names <60134748+9names@users.noreply.github.com> Date: Thu, 29 Apr 2021 11:11:11 +1000 Subject: [PATCH 09/11] Remove unneeded unsafe --- rp2040-hal/src/xosc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rp2040-hal/src/xosc.rs b/rp2040-hal/src/xosc.rs index cf5d9ed..dcf324d 100644 --- a/rp2040-hal/src/xosc.rs +++ b/rp2040-hal/src/xosc.rs @@ -203,7 +203,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 }); From f21648de933e24a330cdb05759590e5db442ba74 Mon Sep 17 00:00:00 2001 From: 9names <60134748+9names@users.noreply.github.com> Date: Thu, 29 Apr 2021 11:15:41 +1000 Subject: [PATCH 10/11] Autoformatted using cargo fmt --- rp2040-hal/src/xosc.rs | 84 ++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 52 deletions(-) diff --git a/rp2040-hal/src/xosc.rs b/rp2040-hal/src/xosc.rs index dcf324d..f2f266e 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: 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 }); From 010a5cabf3b6967489bda8a24759dbd425e4d6f4 Mon Sep 17 00:00:00 2001 From: 9names <60134748+9names@users.noreply.github.com> Date: Thu, 29 Apr 2021 11:19:47 +1000 Subject: [PATCH 11/11] Remove redundant field name --- rp2040-hal/src/xosc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rp2040-hal/src/xosc.rs b/rp2040-hal/src/xosc.rs index f2f266e..a499488 100644 --- a/rp2040-hal/src/xosc.rs +++ b/rp2040-hal/src/xosc.rs @@ -69,7 +69,7 @@ impl CrystalOscillator { fn transition(self, state: To) -> CrystalOscillator { CrystalOscillator { device: self.device, - state: state, + state, } }