Cargo fmt pass.

This commit is contained in:
Nic0w 2021-04-29 20:35:47 +02:00
parent e91e124484
commit eb4ebc782a

View file

@ -2,26 +2,14 @@
// See [Chapter 2 Section 18](https://datasheets.raspberrypi.org/rp2040/rp2040_datasheet.pdf) for more details // See [Chapter 2 Section 18](https://datasheets.raspberrypi.org/rp2040/rp2040_datasheet.pdf) for more details
use core::{ use core::{
convert::{ convert::{Infallible, TryFrom, TryInto},
Infallible,
TryFrom,
TryInto
},
marker::PhantomData, marker::PhantomData,
ops::{ ops::{Deref, Range, RangeInclusive},
RangeInclusive,
Range,
Deref
}
}; };
use embedded_time::{ use embedded_time::{
fixed_point::FixedPoint, fixed_point::FixedPoint,
rate::{ rate::{Generic, Hertz, Rate},
Hertz,
Generic,
Rate
}
}; };
use nb::Error::WouldBlock; use nb::Error::WouldBlock;
@ -29,14 +17,13 @@ use nb::Error::WouldBlock;
/// State of the PLL /// State of the PLL
pub trait State {} pub trait State {}
/// PLL is disabled. /// PLL is disabled.
pub struct Disabled; pub struct Disabled;
/// PLL is configured, started and locking into its designated frequency. /// PLL is configured, started and locking into its designated frequency.
pub struct Locking { pub struct Locking {
post_div1: u8, post_div1: u8,
post_div2: u8 post_div2: u8,
} }
/// PLL is locked : it delivers a steady frequency. /// PLL is locked : it delivers a steady frequency.
@ -55,28 +42,26 @@ impl PhaseLockedLoopDevice for rp2040_pac::PLL_USB {}
/// A PLL. /// A PLL.
pub struct PhaseLockedLoop<S: State, D: PhaseLockedLoopDevice> { pub struct PhaseLockedLoop<S: State, D: PhaseLockedLoopDevice> {
device: D, device: D,
state: S state: S,
} }
impl<S: State, D: PhaseLockedLoopDevice> PhaseLockedLoop<S, D> { impl<S: State, D: PhaseLockedLoopDevice> PhaseLockedLoop<S, D> {
fn transition<To: State>(self, state: To) -> PhaseLockedLoop<To, D> { fn transition<To: State>(self, state: To) -> PhaseLockedLoop<To, D> {
PhaseLockedLoop { PhaseLockedLoop {
device: self.device, device: self.device,
state: state state: state,
} }
} }
/// Releases the underlying device. /// Releases the underlying device.
pub fn free(self) -> D{ pub fn free(self) -> D {
self.device self.device
} }
} }
/// Error type for the PLL module. /// Error type for the PLL module.
/// See Chapter 2, Section 18 §2 for details on constraints triggering these errors. /// See Chapter 2, Section 18 §2 for details on constraints triggering these errors.
pub enum Error { pub enum Error {
/// Proposed VCO frequency is out of range. /// Proposed VCO frequency is out of range.
VCOFreqOutOfRange, VCOFreqOutOfRange,
@ -90,13 +75,11 @@ pub enum Error {
RefFreqOutOfRange, RefFreqOutOfRange,
/// Bad argument : overflows, bad conversion, ... /// Bad argument : overflows, bad conversion, ...
BadArgument BadArgument,
} }
/// Parameters for a PLL. /// Parameters for a PLL.
pub struct PLLConfig<R: Rate> { pub struct PLLConfig<R: Rate> {
/// Voltage Controlled Oscillator frequency. /// Voltage Controlled Oscillator frequency.
pub vco_freq: R, pub vco_freq: R,
@ -107,7 +90,7 @@ pub struct PLLConfig<R: Rate> {
pub post_div1: u8, pub post_div1: u8,
/// Post Divider 2 /// Post Divider 2
pub post_div2: u8 pub post_div2: u8,
} }
/// Common configs for the two PLLs. Both assume the XOSC is cadenced at 12MHz ! /// Common configs for the two PLLs. Both assume the XOSC is cadenced at 12MHz !
@ -121,7 +104,7 @@ pub mod common_configs {
vco_freq: Megahertz(1500), vco_freq: Megahertz(1500),
refdiv: 1, refdiv: 1,
post_div1: 6, post_div1: 6,
post_div2: 2 post_div2: 2,
}; };
/// Default, nominal configuration for PLL_USB. /// Default, nominal configuration for PLL_USB.
@ -129,12 +112,11 @@ pub mod common_configs {
vco_freq: Megahertz(480), vco_freq: Megahertz(480),
refdiv: 1, refdiv: 1,
post_div1: 5, post_div1: 5,
post_div2: 2 post_div2: 2,
}; };
} }
impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Disabled, D> { impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Disabled, D> {
/// Instantiates a new Phase-Locked-Loop device. /// Instantiates a new Phase-Locked-Loop device.
pub fn new(dev: D) -> PhaseLockedLoop<Disabled, D> { pub fn new(dev: D) -> PhaseLockedLoop<Disabled, D> {
PhaseLockedLoop { PhaseLockedLoop {
@ -144,8 +126,14 @@ impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Disabled, D> {
} }
/// Configures and starts the PLL : it switches to Locking state. /// Configures and starts the PLL : it switches to Locking state.
pub fn initialize<R: Rate>(self, xosc_frequency: Generic<u32>, config: PLLConfig<R>) -> Result<PhaseLockedLoop<Locking, D>, Error> where R: Into<Hertz<u64>>{ pub fn initialize<R: Rate>(
self,
xosc_frequency: Generic<u32>,
config: PLLConfig<R>,
) -> Result<PhaseLockedLoop<Locking, D>, Error>
where
R: Into<Hertz<u64>>,
{
const VCO_FREQ_RANGE: RangeInclusive<Hertz<u32>> = Hertz(400_000_000)..=Hertz(1600_000_000); const VCO_FREQ_RANGE: RangeInclusive<Hertz<u32>> = Hertz(400_000_000)..=Hertz(1600_000_000);
const POSTDIV_RANGE: Range<u8> = 1..7; const POSTDIV_RANGE: Range<u8> = 1..7;
const FBDIV_RANGE: Range<u16> = 16..320; const FBDIV_RANGE: Range<u16> = 16..320;
@ -157,11 +145,12 @@ impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Disabled, D> {
let vco_freq: Hertz<u32> = vco_freq.try_into().map_err(|_| Error::BadArgument)?; let vco_freq: Hertz<u32> = vco_freq.try_into().map_err(|_| Error::BadArgument)?;
if !VCO_FREQ_RANGE.contains(&vco_freq) { if !VCO_FREQ_RANGE.contains(&vco_freq) {
return Err(Error::VCOFreqOutOfRange) return Err(Error::VCOFreqOutOfRange);
} }
if !POSTDIV_RANGE.contains(&config.post_div1) || !POSTDIV_RANGE.contains(&config.post_div2) { if !POSTDIV_RANGE.contains(&config.post_div1) || !POSTDIV_RANGE.contains(&config.post_div2)
return Err(Error::PostDivOutOfRage) {
return Err(Error::PostDivOutOfRage);
} }
let ref_freq_range: Range<Hertz<u32>> = Hertz(5_000_000)..vco_freq.div(16); let ref_freq_range: Range<Hertz<u32>> = Hertz(5_000_000)..vco_freq.div(16);
@ -170,13 +159,13 @@ impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Disabled, D> {
self.device.pwr.reset(); self.device.pwr.reset();
self.device.fbdiv_int.reset(); self.device.fbdiv_int.reset();
let ref_freq_hz = Hertz::<u32>::try_from(xosc_frequency). let ref_freq_hz = Hertz::<u32>::try_from(xosc_frequency)
map_err(|_| Error::BadArgument)?. .map_err(|_| Error::BadArgument)?
checked_div(&(config.refdiv as u32)). .checked_div(&(config.refdiv as u32))
ok_or(Error::BadArgument)?; .ok_or(Error::BadArgument)?;
if !ref_freq_range.contains(&ref_freq_hz) { if !ref_freq_range.contains(&ref_freq_hz) {
return Err(Error::RefFreqOutOfRange) return Err(Error::RefFreqOutOfRange);
} }
self.device.cs.write(|w| unsafe { self.device.cs.write(|w| unsafe {
@ -184,13 +173,16 @@ impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Disabled, D> {
w w
}); });
let fbdiv = vco_freq.checked_div(ref_freq_hz.integer()). let fbdiv = vco_freq
ok_or(Error::BadArgument)?; .checked_div(ref_freq_hz.integer())
.ok_or(Error::BadArgument)?;
let fbdiv: u16 = (*fbdiv.integer()).try_into().map_err(|_| Error::BadArgument)?; let fbdiv: u16 = (*fbdiv.integer())
.try_into()
.map_err(|_| Error::BadArgument)?;
if !FBDIV_RANGE.contains(&fbdiv) { if !FBDIV_RANGE.contains(&fbdiv) {
return Err(Error::FBDIVOutOfRange) return Err(Error::FBDIVOutOfRange);
} }
self.device.fbdiv_int.write(|w| unsafe { self.device.fbdiv_int.write(|w| unsafe {
@ -199,7 +191,7 @@ impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Disabled, D> {
}); });
// Turn on PLL // Turn on PLL
self.device.pwr.modify(|_,w| { self.device.pwr.modify(|_, w| {
w.pd().clear_bit(); w.pd().clear_bit();
w.vcopd().clear_bit(); w.vcopd().clear_bit();
w w
@ -209,33 +201,31 @@ impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Disabled, D> {
let post_div2 = config.post_div2; let post_div2 = config.post_div2;
Ok(self.transition(Locking { Ok(self.transition(Locking {
post_div1, post_div2 post_div1,
post_div2,
})) }))
} }
} }
/// A token that's given when the PLL is properly locked, so we can safely transition to the next state. /// A token that's given when the PLL is properly locked, so we can safely transition to the next state.
pub struct LockedPLLToken<D> { pub struct LockedPLLToken<D> {
_private: PhantomData<D> _private: PhantomData<D>,
} }
impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Locking, D> { impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Locking, D> {
/// Awaits locking of the PLL. /// Awaits locking of the PLL.
pub fn await_lock(&self) -> nb::Result<LockedPLLToken<D>, Infallible> { pub fn await_lock(&self) -> nb::Result<LockedPLLToken<D>, Infallible> {
if self.device.cs.read().lock().bit_is_clear() { if self.device.cs.read().lock().bit_is_clear() {
return Err(WouldBlock); return Err(WouldBlock);
} }
Ok(LockedPLLToken { Ok(LockedPLLToken {
_private: PhantomData _private: PhantomData,
}) })
} }
/// Exchanges a token for a Locked PLL. /// Exchanges a token for a Locked PLL.
pub fn get_locked(self, _token: LockedPLLToken<D>) -> PhaseLockedLoop<Locked, D> { pub fn get_locked(self, _token: LockedPLLToken<D>) -> PhaseLockedLoop<Locked, D> {
// Set up post dividers // Set up post dividers
self.device.prim.write(|w| unsafe { self.device.prim.write(|w| unsafe {
w.postdiv1().bits(self.state.post_div1); w.postdiv1().bits(self.state.post_div1);
@ -244,12 +234,11 @@ impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Locking, D> {
}); });
// Turn on post divider // Turn on post divider
self.device.pwr.modify(|_,w| { self.device.pwr.modify(|_, w| {
w.postdivpd().clear_bit(); w.postdivpd().clear_bit();
w w
}); });
self.transition(Locked) self.transition(Locked)
} }
} }