docs: document all embassy-rp public apis
Enable missing doc warnings.
This commit is contained in:
		@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! ADC driver.
 | 
				
			||||||
use core::future::poll_fn;
 | 
					use core::future::poll_fn;
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
use core::mem;
 | 
					use core::mem;
 | 
				
			||||||
@@ -16,6 +17,7 @@ use crate::{dma, interrupt, pac, peripherals, Peripheral, RegExt};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static WAKER: AtomicWaker = AtomicWaker::new();
 | 
					static WAKER: AtomicWaker = AtomicWaker::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC config.
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
pub struct Config {}
 | 
					pub struct Config {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,9 +32,11 @@ enum Source<'p> {
 | 
				
			|||||||
    TempSensor(PeripheralRef<'p, ADC_TEMP_SENSOR>),
 | 
					    TempSensor(PeripheralRef<'p, ADC_TEMP_SENSOR>),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC channel.
 | 
				
			||||||
pub struct Channel<'p>(Source<'p>);
 | 
					pub struct Channel<'p>(Source<'p>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'p> Channel<'p> {
 | 
					impl<'p> Channel<'p> {
 | 
				
			||||||
 | 
					    /// Create a new ADC channel from pin with the provided [Pull] configuration.
 | 
				
			||||||
    pub fn new_pin(pin: impl Peripheral<P = impl AdcPin + 'p> + 'p, pull: Pull) -> Self {
 | 
					    pub fn new_pin(pin: impl Peripheral<P = impl AdcPin + 'p> + 'p, pull: Pull) -> Self {
 | 
				
			||||||
        into_ref!(pin);
 | 
					        into_ref!(pin);
 | 
				
			||||||
        pin.pad_ctrl().modify(|w| {
 | 
					        pin.pad_ctrl().modify(|w| {
 | 
				
			||||||
@@ -49,6 +53,7 @@ impl<'p> Channel<'p> {
 | 
				
			|||||||
        Self(Source::Pin(pin.map_into()))
 | 
					        Self(Source::Pin(pin.map_into()))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Create a new ADC channel for the internal temperature sensor.
 | 
				
			||||||
    pub fn new_temp_sensor(s: impl Peripheral<P = ADC_TEMP_SENSOR> + 'p) -> Self {
 | 
					    pub fn new_temp_sensor(s: impl Peripheral<P = ADC_TEMP_SENSOR> + 'p) -> Self {
 | 
				
			||||||
        let r = pac::ADC;
 | 
					        let r = pac::ADC;
 | 
				
			||||||
        r.cs().write_set(|w| w.set_ts_en(true));
 | 
					        r.cs().write_set(|w| w.set_ts_en(true));
 | 
				
			||||||
@@ -83,35 +88,44 @@ impl<'p> Drop for Source<'p> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC sample.
 | 
				
			||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]
 | 
					#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]
 | 
				
			||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
					#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
				
			||||||
#[repr(transparent)]
 | 
					#[repr(transparent)]
 | 
				
			||||||
pub struct Sample(u16);
 | 
					pub struct Sample(u16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Sample {
 | 
					impl Sample {
 | 
				
			||||||
 | 
					    /// Sample is valid.
 | 
				
			||||||
    pub fn good(&self) -> bool {
 | 
					    pub fn good(&self) -> bool {
 | 
				
			||||||
        self.0 < 0x8000
 | 
					        self.0 < 0x8000
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Sample value.
 | 
				
			||||||
    pub fn value(&self) -> u16 {
 | 
					    pub fn value(&self) -> u16 {
 | 
				
			||||||
        self.0 & !0x8000
 | 
					        self.0 & !0x8000
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC error.
 | 
				
			||||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
 | 
					#[derive(Debug, Eq, PartialEq, Copy, Clone)]
 | 
				
			||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
					#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
				
			||||||
pub enum Error {
 | 
					pub enum Error {
 | 
				
			||||||
 | 
					    /// Error converting value.
 | 
				
			||||||
    ConversionFailed,
 | 
					    ConversionFailed,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC mode.
 | 
				
			||||||
pub trait Mode {}
 | 
					pub trait Mode {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC async mode.
 | 
				
			||||||
pub struct Async;
 | 
					pub struct Async;
 | 
				
			||||||
impl Mode for Async {}
 | 
					impl Mode for Async {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC blocking mode.
 | 
				
			||||||
pub struct Blocking;
 | 
					pub struct Blocking;
 | 
				
			||||||
impl Mode for Blocking {}
 | 
					impl Mode for Blocking {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC driver.
 | 
				
			||||||
pub struct Adc<'d, M: Mode> {
 | 
					pub struct Adc<'d, M: Mode> {
 | 
				
			||||||
    phantom: PhantomData<(&'d ADC, M)>,
 | 
					    phantom: PhantomData<(&'d ADC, M)>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -150,6 +164,7 @@ impl<'d, M: Mode> Adc<'d, M> {
 | 
				
			|||||||
        while !r.cs().read().ready() {}
 | 
					        while !r.cs().read().ready() {}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Sample a value from a channel in blocking mode.
 | 
				
			||||||
    pub fn blocking_read(&mut self, ch: &mut Channel) -> Result<u16, Error> {
 | 
					    pub fn blocking_read(&mut self, ch: &mut Channel) -> Result<u16, Error> {
 | 
				
			||||||
        let r = Self::regs();
 | 
					        let r = Self::regs();
 | 
				
			||||||
        r.cs().modify(|w| {
 | 
					        r.cs().modify(|w| {
 | 
				
			||||||
@@ -166,6 +181,7 @@ impl<'d, M: Mode> Adc<'d, M> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d> Adc<'d, Async> {
 | 
					impl<'d> Adc<'d, Async> {
 | 
				
			||||||
 | 
					    /// Create ADC driver in async mode.
 | 
				
			||||||
    pub fn new(
 | 
					    pub fn new(
 | 
				
			||||||
        _inner: impl Peripheral<P = ADC> + 'd,
 | 
					        _inner: impl Peripheral<P = ADC> + 'd,
 | 
				
			||||||
        _irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>,
 | 
					        _irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>,
 | 
				
			||||||
@@ -194,6 +210,7 @@ impl<'d> Adc<'d, Async> {
 | 
				
			|||||||
        .await;
 | 
					        .await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Sample a value from a channel until completed.
 | 
				
			||||||
    pub async fn read(&mut self, ch: &mut Channel<'_>) -> Result<u16, Error> {
 | 
					    pub async fn read(&mut self, ch: &mut Channel<'_>) -> Result<u16, Error> {
 | 
				
			||||||
        let r = Self::regs();
 | 
					        let r = Self::regs();
 | 
				
			||||||
        r.cs().modify(|w| {
 | 
					        r.cs().modify(|w| {
 | 
				
			||||||
@@ -272,6 +289,7 @@ impl<'d> Adc<'d, Async> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Sample multiple values from a channel using DMA.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn read_many<S: AdcSample>(
 | 
					    pub async fn read_many<S: AdcSample>(
 | 
				
			||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
@@ -283,6 +301,7 @@ impl<'d> Adc<'d, Async> {
 | 
				
			|||||||
        self.read_many_inner(ch, buf, false, div, dma).await
 | 
					        self.read_many_inner(ch, buf, false, div, dma).await
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Sample multiple values from a channel using DMA with errors inlined in samples.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn read_many_raw(
 | 
					    pub async fn read_many_raw(
 | 
				
			||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
@@ -299,6 +318,7 @@ impl<'d> Adc<'d, Async> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d> Adc<'d, Blocking> {
 | 
					impl<'d> Adc<'d, Blocking> {
 | 
				
			||||||
 | 
					    /// Create ADC driver in blocking mode.
 | 
				
			||||||
    pub fn new_blocking(_inner: impl Peripheral<P = ADC> + 'd, _config: Config) -> Self {
 | 
					    pub fn new_blocking(_inner: impl Peripheral<P = ADC> + 'd, _config: Config) -> Self {
 | 
				
			||||||
        Self::setup();
 | 
					        Self::setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -306,6 +326,7 @@ impl<'d> Adc<'d, Blocking> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Interrupt handler.
 | 
				
			||||||
pub struct InterruptHandler {
 | 
					pub struct InterruptHandler {
 | 
				
			||||||
    _empty: (),
 | 
					    _empty: (),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -324,6 +345,7 @@ mod sealed {
 | 
				
			|||||||
    pub trait AdcChannel {}
 | 
					    pub trait AdcChannel {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC sample.
 | 
				
			||||||
pub trait AdcSample: sealed::AdcSample {}
 | 
					pub trait AdcSample: sealed::AdcSample {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl sealed::AdcSample for u16 {}
 | 
					impl sealed::AdcSample for u16 {}
 | 
				
			||||||
@@ -332,7 +354,9 @@ impl AdcSample for u16 {}
 | 
				
			|||||||
impl sealed::AdcSample for u8 {}
 | 
					impl sealed::AdcSample for u8 {}
 | 
				
			||||||
impl AdcSample for u8 {}
 | 
					impl AdcSample for u8 {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC channel.
 | 
				
			||||||
pub trait AdcChannel: sealed::AdcChannel {}
 | 
					pub trait AdcChannel: sealed::AdcChannel {}
 | 
				
			||||||
 | 
					/// ADC pin.
 | 
				
			||||||
pub trait AdcPin: AdcChannel + gpio::Pin {}
 | 
					pub trait AdcPin: AdcChannel + gpio::Pin {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! impl_pin {
 | 
					macro_rules! impl_pin {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,15 +45,20 @@ static CLOCKS: Clocks = Clocks {
 | 
				
			|||||||
    rtc: AtomicU16::new(0),
 | 
					    rtc: AtomicU16::new(0),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Enumeration of supported clock sources.
 | 
					/// Peripheral clock sources.
 | 
				
			||||||
#[repr(u8)]
 | 
					#[repr(u8)]
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
					#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
				
			||||||
pub enum PeriClkSrc {
 | 
					pub enum PeriClkSrc {
 | 
				
			||||||
 | 
					    /// SYS.
 | 
				
			||||||
    Sys = ClkPeriCtrlAuxsrc::CLK_SYS as _,
 | 
					    Sys = ClkPeriCtrlAuxsrc::CLK_SYS as _,
 | 
				
			||||||
 | 
					    /// PLL SYS.
 | 
				
			||||||
    PllSys = ClkPeriCtrlAuxsrc::CLKSRC_PLL_SYS as _,
 | 
					    PllSys = ClkPeriCtrlAuxsrc::CLKSRC_PLL_SYS as _,
 | 
				
			||||||
 | 
					    /// PLL USB.
 | 
				
			||||||
    PllUsb = ClkPeriCtrlAuxsrc::CLKSRC_PLL_USB as _,
 | 
					    PllUsb = ClkPeriCtrlAuxsrc::CLKSRC_PLL_USB as _,
 | 
				
			||||||
 | 
					    /// ROSC.
 | 
				
			||||||
    Rosc = ClkPeriCtrlAuxsrc::ROSC_CLKSRC_PH as _,
 | 
					    Rosc = ClkPeriCtrlAuxsrc::ROSC_CLKSRC_PH as _,
 | 
				
			||||||
 | 
					    /// XOSC.
 | 
				
			||||||
    Xosc = ClkPeriCtrlAuxsrc::XOSC_CLKSRC as _,
 | 
					    Xosc = ClkPeriCtrlAuxsrc::XOSC_CLKSRC as _,
 | 
				
			||||||
    // Gpin0 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN0 as _ ,
 | 
					    // Gpin0 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN0 as _ ,
 | 
				
			||||||
    // Gpin1 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
 | 
					    // Gpin1 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
 | 
				
			||||||
@@ -83,6 +88,7 @@ pub struct ClockConfig {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl ClockConfig {
 | 
					impl ClockConfig {
 | 
				
			||||||
 | 
					    /// Clock configuration derived from external crystal.
 | 
				
			||||||
    pub fn crystal(crystal_hz: u32) -> Self {
 | 
					    pub fn crystal(crystal_hz: u32) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            rosc: Some(RoscConfig {
 | 
					            rosc: Some(RoscConfig {
 | 
				
			||||||
@@ -141,6 +147,7 @@ impl ClockConfig {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Clock configuration from internal oscillator.
 | 
				
			||||||
    pub fn rosc() -> Self {
 | 
					    pub fn rosc() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            rosc: Some(RoscConfig {
 | 
					            rosc: Some(RoscConfig {
 | 
				
			||||||
@@ -190,13 +197,18 @@ impl ClockConfig {
 | 
				
			|||||||
    // }
 | 
					    // }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ROSC freq range.
 | 
				
			||||||
#[repr(u16)]
 | 
					#[repr(u16)]
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
					#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
				
			||||||
pub enum RoscRange {
 | 
					pub enum RoscRange {
 | 
				
			||||||
 | 
					    /// Low range.
 | 
				
			||||||
    Low = pac::rosc::vals::FreqRange::LOW.0,
 | 
					    Low = pac::rosc::vals::FreqRange::LOW.0,
 | 
				
			||||||
 | 
					    /// Medium range (1.33x low)
 | 
				
			||||||
    Medium = pac::rosc::vals::FreqRange::MEDIUM.0,
 | 
					    Medium = pac::rosc::vals::FreqRange::MEDIUM.0,
 | 
				
			||||||
 | 
					    /// High range (2x low)
 | 
				
			||||||
    High = pac::rosc::vals::FreqRange::HIGH.0,
 | 
					    High = pac::rosc::vals::FreqRange::HIGH.0,
 | 
				
			||||||
 | 
					    /// Too high. Should not be used.
 | 
				
			||||||
    TooHigh = pac::rosc::vals::FreqRange::TOOHIGH.0,
 | 
					    TooHigh = pac::rosc::vals::FreqRange::TOOHIGH.0,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -239,96 +251,136 @@ pub struct PllConfig {
 | 
				
			|||||||
    pub post_div2: u8,
 | 
					    pub post_div2: u8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Reference
 | 
					/// Reference clock config.
 | 
				
			||||||
pub struct RefClkConfig {
 | 
					pub struct RefClkConfig {
 | 
				
			||||||
 | 
					    /// Reference clock source.
 | 
				
			||||||
    pub src: RefClkSrc,
 | 
					    pub src: RefClkSrc,
 | 
				
			||||||
 | 
					    /// Reference clock divider.
 | 
				
			||||||
    pub div: u8,
 | 
					    pub div: u8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Reference clock source.
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
					#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
				
			||||||
pub enum RefClkSrc {
 | 
					pub enum RefClkSrc {
 | 
				
			||||||
    // main sources
 | 
					    /// XOSC.
 | 
				
			||||||
    Xosc,
 | 
					    Xosc,
 | 
				
			||||||
 | 
					    /// ROSC.
 | 
				
			||||||
    Rosc,
 | 
					    Rosc,
 | 
				
			||||||
    // aux sources
 | 
					    /// PLL USB.
 | 
				
			||||||
    PllUsb,
 | 
					    PllUsb,
 | 
				
			||||||
    // Gpin0,
 | 
					    // Gpin0,
 | 
				
			||||||
    // Gpin1,
 | 
					    // Gpin1,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// SYS clock source.
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
					#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
				
			||||||
pub enum SysClkSrc {
 | 
					pub enum SysClkSrc {
 | 
				
			||||||
    // main sources
 | 
					    /// REF.
 | 
				
			||||||
    Ref,
 | 
					    Ref,
 | 
				
			||||||
    // aux sources
 | 
					    /// PLL SYS.
 | 
				
			||||||
    PllSys,
 | 
					    PllSys,
 | 
				
			||||||
 | 
					    /// PLL USB.
 | 
				
			||||||
    PllUsb,
 | 
					    PllUsb,
 | 
				
			||||||
 | 
					    /// ROSC.
 | 
				
			||||||
    Rosc,
 | 
					    Rosc,
 | 
				
			||||||
 | 
					    /// XOSC.
 | 
				
			||||||
    Xosc,
 | 
					    Xosc,
 | 
				
			||||||
    // Gpin0,
 | 
					    // Gpin0,
 | 
				
			||||||
    // Gpin1,
 | 
					    // Gpin1,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// SYS clock config.
 | 
				
			||||||
pub struct SysClkConfig {
 | 
					pub struct SysClkConfig {
 | 
				
			||||||
 | 
					    /// SYS clock source.
 | 
				
			||||||
    pub src: SysClkSrc,
 | 
					    pub src: SysClkSrc,
 | 
				
			||||||
 | 
					    /// SYS clock divider.
 | 
				
			||||||
    pub div_int: u32,
 | 
					    pub div_int: u32,
 | 
				
			||||||
 | 
					    /// SYS clock fraction.
 | 
				
			||||||
    pub div_frac: u8,
 | 
					    pub div_frac: u8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// USB clock source.
 | 
				
			||||||
#[repr(u8)]
 | 
					#[repr(u8)]
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
					#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
				
			||||||
pub enum UsbClkSrc {
 | 
					pub enum UsbClkSrc {
 | 
				
			||||||
 | 
					    /// PLL USB.
 | 
				
			||||||
    PllUsb = ClkUsbCtrlAuxsrc::CLKSRC_PLL_USB as _,
 | 
					    PllUsb = ClkUsbCtrlAuxsrc::CLKSRC_PLL_USB as _,
 | 
				
			||||||
 | 
					    /// PLL SYS.
 | 
				
			||||||
    PllSys = ClkUsbCtrlAuxsrc::CLKSRC_PLL_SYS as _,
 | 
					    PllSys = ClkUsbCtrlAuxsrc::CLKSRC_PLL_SYS as _,
 | 
				
			||||||
 | 
					    /// ROSC.
 | 
				
			||||||
    Rosc = ClkUsbCtrlAuxsrc::ROSC_CLKSRC_PH as _,
 | 
					    Rosc = ClkUsbCtrlAuxsrc::ROSC_CLKSRC_PH as _,
 | 
				
			||||||
 | 
					    /// XOSC.
 | 
				
			||||||
    Xosc = ClkUsbCtrlAuxsrc::XOSC_CLKSRC as _,
 | 
					    Xosc = ClkUsbCtrlAuxsrc::XOSC_CLKSRC as _,
 | 
				
			||||||
    // Gpin0 = ClkUsbCtrlAuxsrc::CLKSRC_GPIN0 as _ ,
 | 
					    // Gpin0 = ClkUsbCtrlAuxsrc::CLKSRC_GPIN0 as _ ,
 | 
				
			||||||
    // Gpin1 = ClkUsbCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
 | 
					    // Gpin1 = ClkUsbCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// USB clock config.
 | 
				
			||||||
pub struct UsbClkConfig {
 | 
					pub struct UsbClkConfig {
 | 
				
			||||||
 | 
					    /// USB clock source.
 | 
				
			||||||
    pub src: UsbClkSrc,
 | 
					    pub src: UsbClkSrc,
 | 
				
			||||||
 | 
					    /// USB clock divider.
 | 
				
			||||||
    pub div: u8,
 | 
					    pub div: u8,
 | 
				
			||||||
 | 
					    /// USB clock phase.
 | 
				
			||||||
    pub phase: u8,
 | 
					    pub phase: u8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC clock source.
 | 
				
			||||||
#[repr(u8)]
 | 
					#[repr(u8)]
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
					#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
				
			||||||
pub enum AdcClkSrc {
 | 
					pub enum AdcClkSrc {
 | 
				
			||||||
 | 
					    /// PLL USB.
 | 
				
			||||||
    PllUsb = ClkAdcCtrlAuxsrc::CLKSRC_PLL_USB as _,
 | 
					    PllUsb = ClkAdcCtrlAuxsrc::CLKSRC_PLL_USB as _,
 | 
				
			||||||
 | 
					    /// PLL SYS.
 | 
				
			||||||
    PllSys = ClkAdcCtrlAuxsrc::CLKSRC_PLL_SYS as _,
 | 
					    PllSys = ClkAdcCtrlAuxsrc::CLKSRC_PLL_SYS as _,
 | 
				
			||||||
 | 
					    /// ROSC.
 | 
				
			||||||
    Rosc = ClkAdcCtrlAuxsrc::ROSC_CLKSRC_PH as _,
 | 
					    Rosc = ClkAdcCtrlAuxsrc::ROSC_CLKSRC_PH as _,
 | 
				
			||||||
 | 
					    /// XOSC.
 | 
				
			||||||
    Xosc = ClkAdcCtrlAuxsrc::XOSC_CLKSRC as _,
 | 
					    Xosc = ClkAdcCtrlAuxsrc::XOSC_CLKSRC as _,
 | 
				
			||||||
    // Gpin0 = ClkAdcCtrlAuxsrc::CLKSRC_GPIN0 as _ ,
 | 
					    // Gpin0 = ClkAdcCtrlAuxsrc::CLKSRC_GPIN0 as _ ,
 | 
				
			||||||
    // Gpin1 = ClkAdcCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
 | 
					    // Gpin1 = ClkAdcCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC clock config.
 | 
				
			||||||
pub struct AdcClkConfig {
 | 
					pub struct AdcClkConfig {
 | 
				
			||||||
 | 
					    /// ADC clock source.
 | 
				
			||||||
    pub src: AdcClkSrc,
 | 
					    pub src: AdcClkSrc,
 | 
				
			||||||
 | 
					    /// ADC clock divider.
 | 
				
			||||||
    pub div: u8,
 | 
					    pub div: u8,
 | 
				
			||||||
 | 
					    /// ADC clock phase.
 | 
				
			||||||
    pub phase: u8,
 | 
					    pub phase: u8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// RTC clock source.
 | 
				
			||||||
#[repr(u8)]
 | 
					#[repr(u8)]
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
					#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
				
			||||||
pub enum RtcClkSrc {
 | 
					pub enum RtcClkSrc {
 | 
				
			||||||
 | 
					    /// PLL USB.
 | 
				
			||||||
    PllUsb = ClkRtcCtrlAuxsrc::CLKSRC_PLL_USB as _,
 | 
					    PllUsb = ClkRtcCtrlAuxsrc::CLKSRC_PLL_USB as _,
 | 
				
			||||||
 | 
					    /// PLL SYS.
 | 
				
			||||||
    PllSys = ClkRtcCtrlAuxsrc::CLKSRC_PLL_SYS as _,
 | 
					    PllSys = ClkRtcCtrlAuxsrc::CLKSRC_PLL_SYS as _,
 | 
				
			||||||
 | 
					    /// ROSC.
 | 
				
			||||||
    Rosc = ClkRtcCtrlAuxsrc::ROSC_CLKSRC_PH as _,
 | 
					    Rosc = ClkRtcCtrlAuxsrc::ROSC_CLKSRC_PH as _,
 | 
				
			||||||
 | 
					    /// XOSC.
 | 
				
			||||||
    Xosc = ClkRtcCtrlAuxsrc::XOSC_CLKSRC as _,
 | 
					    Xosc = ClkRtcCtrlAuxsrc::XOSC_CLKSRC as _,
 | 
				
			||||||
    // Gpin0 = ClkRtcCtrlAuxsrc::CLKSRC_GPIN0 as _ ,
 | 
					    // Gpin0 = ClkRtcCtrlAuxsrc::CLKSRC_GPIN0 as _ ,
 | 
				
			||||||
    // Gpin1 = ClkRtcCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
 | 
					    // Gpin1 = ClkRtcCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// RTC clock config.
 | 
				
			||||||
pub struct RtcClkConfig {
 | 
					pub struct RtcClkConfig {
 | 
				
			||||||
 | 
					    /// RTC clock source.
 | 
				
			||||||
    pub src: RtcClkSrc,
 | 
					    pub src: RtcClkSrc,
 | 
				
			||||||
 | 
					    /// RTC clock divider.
 | 
				
			||||||
    pub div_int: u32,
 | 
					    pub div_int: u32,
 | 
				
			||||||
 | 
					    /// RTC clock divider fraction.
 | 
				
			||||||
    pub div_frac: u8,
 | 
					    pub div_frac: u8,
 | 
				
			||||||
 | 
					    /// RTC clock phase.
 | 
				
			||||||
    pub phase: u8,
 | 
					    pub phase: u8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -605,10 +657,12 @@ fn configure_rosc(config: RoscConfig) -> u32 {
 | 
				
			|||||||
    config.hz
 | 
					    config.hz
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ROSC clock frequency.
 | 
				
			||||||
pub fn rosc_freq() -> u32 {
 | 
					pub fn rosc_freq() -> u32 {
 | 
				
			||||||
    CLOCKS.rosc.load(Ordering::Relaxed)
 | 
					    CLOCKS.rosc.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// XOSC clock frequency.
 | 
				
			||||||
pub fn xosc_freq() -> u32 {
 | 
					pub fn xosc_freq() -> u32 {
 | 
				
			||||||
    CLOCKS.xosc.load(Ordering::Relaxed)
 | 
					    CLOCKS.xosc.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -620,34 +674,42 @@ pub fn xosc_freq() -> u32 {
 | 
				
			|||||||
//     CLOCKS.gpin1.load(Ordering::Relaxed)
 | 
					//     CLOCKS.gpin1.load(Ordering::Relaxed)
 | 
				
			||||||
// }
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// PLL SYS clock frequency.
 | 
				
			||||||
pub fn pll_sys_freq() -> u32 {
 | 
					pub fn pll_sys_freq() -> u32 {
 | 
				
			||||||
    CLOCKS.pll_sys.load(Ordering::Relaxed)
 | 
					    CLOCKS.pll_sys.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// PLL USB clock frequency.
 | 
				
			||||||
pub fn pll_usb_freq() -> u32 {
 | 
					pub fn pll_usb_freq() -> u32 {
 | 
				
			||||||
    CLOCKS.pll_usb.load(Ordering::Relaxed)
 | 
					    CLOCKS.pll_usb.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// SYS clock frequency.
 | 
				
			||||||
pub fn clk_sys_freq() -> u32 {
 | 
					pub fn clk_sys_freq() -> u32 {
 | 
				
			||||||
    CLOCKS.sys.load(Ordering::Relaxed)
 | 
					    CLOCKS.sys.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// REF clock frequency.
 | 
				
			||||||
pub fn clk_ref_freq() -> u32 {
 | 
					pub fn clk_ref_freq() -> u32 {
 | 
				
			||||||
    CLOCKS.reference.load(Ordering::Relaxed)
 | 
					    CLOCKS.reference.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Peripheral clock frequency.
 | 
				
			||||||
pub fn clk_peri_freq() -> u32 {
 | 
					pub fn clk_peri_freq() -> u32 {
 | 
				
			||||||
    CLOCKS.peri.load(Ordering::Relaxed)
 | 
					    CLOCKS.peri.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// USB clock frequency.
 | 
				
			||||||
pub fn clk_usb_freq() -> u32 {
 | 
					pub fn clk_usb_freq() -> u32 {
 | 
				
			||||||
    CLOCKS.usb.load(Ordering::Relaxed)
 | 
					    CLOCKS.usb.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// ADC clock frequency.
 | 
				
			||||||
pub fn clk_adc_freq() -> u32 {
 | 
					pub fn clk_adc_freq() -> u32 {
 | 
				
			||||||
    CLOCKS.adc.load(Ordering::Relaxed)
 | 
					    CLOCKS.adc.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// RTC clock frequency.
 | 
				
			||||||
pub fn clk_rtc_freq() -> u16 {
 | 
					pub fn clk_rtc_freq() -> u16 {
 | 
				
			||||||
    CLOCKS.rtc.load(Ordering::Relaxed)
 | 
					    CLOCKS.rtc.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -708,7 +770,9 @@ fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> u32 {
 | 
				
			|||||||
    vco_freq / ((config.post_div1 * config.post_div2) as u32)
 | 
					    vco_freq / ((config.post_div1 * config.post_div2) as u32)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// General purpose input clock pin.
 | 
				
			||||||
pub trait GpinPin: crate::gpio::Pin {
 | 
					pub trait GpinPin: crate::gpio::Pin {
 | 
				
			||||||
 | 
					    /// Pin number.
 | 
				
			||||||
    const NR: usize;
 | 
					    const NR: usize;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -723,12 +787,14 @@ macro_rules! impl_gpinpin {
 | 
				
			|||||||
impl_gpinpin!(PIN_20, 20, 0);
 | 
					impl_gpinpin!(PIN_20, 20, 0);
 | 
				
			||||||
impl_gpinpin!(PIN_22, 22, 1);
 | 
					impl_gpinpin!(PIN_22, 22, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// General purpose clock input driver.
 | 
				
			||||||
pub struct Gpin<'d, T: Pin> {
 | 
					pub struct Gpin<'d, T: Pin> {
 | 
				
			||||||
    gpin: PeripheralRef<'d, AnyPin>,
 | 
					    gpin: PeripheralRef<'d, AnyPin>,
 | 
				
			||||||
    _phantom: PhantomData<T>,
 | 
					    _phantom: PhantomData<T>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Pin> Gpin<'d, T> {
 | 
					impl<'d, T: Pin> Gpin<'d, T> {
 | 
				
			||||||
 | 
					    /// Create new gpin driver.
 | 
				
			||||||
    pub fn new<P: GpinPin>(gpin: impl Peripheral<P = P> + 'd) -> Gpin<'d, P> {
 | 
					    pub fn new<P: GpinPin>(gpin: impl Peripheral<P = P> + 'd) -> Gpin<'d, P> {
 | 
				
			||||||
        into_ref!(gpin);
 | 
					        into_ref!(gpin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -754,7 +820,9 @@ impl<'d, T: Pin> Drop for Gpin<'d, T> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// General purpose clock output pin.
 | 
				
			||||||
pub trait GpoutPin: crate::gpio::Pin {
 | 
					pub trait GpoutPin: crate::gpio::Pin {
 | 
				
			||||||
 | 
					    /// Pin number.
 | 
				
			||||||
    fn number(&self) -> usize;
 | 
					    fn number(&self) -> usize;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -773,26 +841,38 @@ impl_gpoutpin!(PIN_23, 1);
 | 
				
			|||||||
impl_gpoutpin!(PIN_24, 2);
 | 
					impl_gpoutpin!(PIN_24, 2);
 | 
				
			||||||
impl_gpoutpin!(PIN_25, 3);
 | 
					impl_gpoutpin!(PIN_25, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Gpout clock source.
 | 
				
			||||||
#[repr(u8)]
 | 
					#[repr(u8)]
 | 
				
			||||||
pub enum GpoutSrc {
 | 
					pub enum GpoutSrc {
 | 
				
			||||||
 | 
					    /// Sys PLL.
 | 
				
			||||||
    PllSys = ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS as _,
 | 
					    PllSys = ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS as _,
 | 
				
			||||||
    // Gpin0 = ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0 as _ ,
 | 
					    // Gpin0 = ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0 as _ ,
 | 
				
			||||||
    // Gpin1 = ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
 | 
					    // Gpin1 = ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
 | 
				
			||||||
 | 
					    /// USB PLL.
 | 
				
			||||||
    PllUsb = ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB as _,
 | 
					    PllUsb = ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB as _,
 | 
				
			||||||
 | 
					    /// ROSC.
 | 
				
			||||||
    Rosc = ClkGpoutCtrlAuxsrc::ROSC_CLKSRC as _,
 | 
					    Rosc = ClkGpoutCtrlAuxsrc::ROSC_CLKSRC as _,
 | 
				
			||||||
 | 
					    /// XOSC.
 | 
				
			||||||
    Xosc = ClkGpoutCtrlAuxsrc::XOSC_CLKSRC as _,
 | 
					    Xosc = ClkGpoutCtrlAuxsrc::XOSC_CLKSRC as _,
 | 
				
			||||||
 | 
					    /// SYS.
 | 
				
			||||||
    Sys = ClkGpoutCtrlAuxsrc::CLK_SYS as _,
 | 
					    Sys = ClkGpoutCtrlAuxsrc::CLK_SYS as _,
 | 
				
			||||||
 | 
					    /// USB.
 | 
				
			||||||
    Usb = ClkGpoutCtrlAuxsrc::CLK_USB as _,
 | 
					    Usb = ClkGpoutCtrlAuxsrc::CLK_USB as _,
 | 
				
			||||||
 | 
					    /// ADC.
 | 
				
			||||||
    Adc = ClkGpoutCtrlAuxsrc::CLK_ADC as _,
 | 
					    Adc = ClkGpoutCtrlAuxsrc::CLK_ADC as _,
 | 
				
			||||||
 | 
					    /// RTC.
 | 
				
			||||||
    Rtc = ClkGpoutCtrlAuxsrc::CLK_RTC as _,
 | 
					    Rtc = ClkGpoutCtrlAuxsrc::CLK_RTC as _,
 | 
				
			||||||
 | 
					    /// REF.
 | 
				
			||||||
    Ref = ClkGpoutCtrlAuxsrc::CLK_REF as _,
 | 
					    Ref = ClkGpoutCtrlAuxsrc::CLK_REF as _,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// General purpose clock output driver.
 | 
				
			||||||
pub struct Gpout<'d, T: GpoutPin> {
 | 
					pub struct Gpout<'d, T: GpoutPin> {
 | 
				
			||||||
    gpout: PeripheralRef<'d, T>,
 | 
					    gpout: PeripheralRef<'d, T>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: GpoutPin> Gpout<'d, T> {
 | 
					impl<'d, T: GpoutPin> Gpout<'d, T> {
 | 
				
			||||||
 | 
					    /// Create new general purpose cloud output.
 | 
				
			||||||
    pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self {
 | 
					    pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self {
 | 
				
			||||||
        into_ref!(gpout);
 | 
					        into_ref!(gpout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -801,6 +881,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
 | 
				
			|||||||
        Self { gpout }
 | 
					        Self { gpout }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Set clock divider.
 | 
				
			||||||
    pub fn set_div(&self, int: u32, frac: u8) {
 | 
					    pub fn set_div(&self, int: u32, frac: u8) {
 | 
				
			||||||
        let c = pac::CLOCKS;
 | 
					        let c = pac::CLOCKS;
 | 
				
			||||||
        c.clk_gpout_div(self.gpout.number()).write(|w| {
 | 
					        c.clk_gpout_div(self.gpout.number()).write(|w| {
 | 
				
			||||||
@@ -809,6 +890,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Set clock source.
 | 
				
			||||||
    pub fn set_src(&self, src: GpoutSrc) {
 | 
					    pub fn set_src(&self, src: GpoutSrc) {
 | 
				
			||||||
        let c = pac::CLOCKS;
 | 
					        let c = pac::CLOCKS;
 | 
				
			||||||
        c.clk_gpout_ctrl(self.gpout.number()).modify(|w| {
 | 
					        c.clk_gpout_ctrl(self.gpout.number()).modify(|w| {
 | 
				
			||||||
@@ -816,6 +898,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Enable clock.
 | 
				
			||||||
    pub fn enable(&self) {
 | 
					    pub fn enable(&self) {
 | 
				
			||||||
        let c = pac::CLOCKS;
 | 
					        let c = pac::CLOCKS;
 | 
				
			||||||
        c.clk_gpout_ctrl(self.gpout.number()).modify(|w| {
 | 
					        c.clk_gpout_ctrl(self.gpout.number()).modify(|w| {
 | 
				
			||||||
@@ -823,6 +906,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Disable clock.
 | 
				
			||||||
    pub fn disable(&self) {
 | 
					    pub fn disable(&self) {
 | 
				
			||||||
        let c = pac::CLOCKS;
 | 
					        let c = pac::CLOCKS;
 | 
				
			||||||
        c.clk_gpout_ctrl(self.gpout.number()).modify(|w| {
 | 
					        c.clk_gpout_ctrl(self.gpout.number()).modify(|w| {
 | 
				
			||||||
@@ -830,6 +914,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Clock frequency.
 | 
				
			||||||
    pub fn get_freq(&self) -> u32 {
 | 
					    pub fn get_freq(&self) -> u32 {
 | 
				
			||||||
        let c = pac::CLOCKS;
 | 
					        let c = pac::CLOCKS;
 | 
				
			||||||
        let src = c.clk_gpout_ctrl(self.gpout.number()).read().auxsrc();
 | 
					        let src = c.clk_gpout_ctrl(self.gpout.number()).read().auxsrc();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,6 +38,9 @@ pub(crate) unsafe fn init() {
 | 
				
			|||||||
    interrupt::DMA_IRQ_0.enable();
 | 
					    interrupt::DMA_IRQ_0.enable();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// DMA read.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// SAFETY: Slice must point to a valid location reachable by DMA.
 | 
				
			||||||
pub unsafe fn read<'a, C: Channel, W: Word>(
 | 
					pub unsafe fn read<'a, C: Channel, W: Word>(
 | 
				
			||||||
    ch: impl Peripheral<P = C> + 'a,
 | 
					    ch: impl Peripheral<P = C> + 'a,
 | 
				
			||||||
    from: *const W,
 | 
					    from: *const W,
 | 
				
			||||||
@@ -57,6 +60,9 @@ pub unsafe fn read<'a, C: Channel, W: Word>(
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// DMA write.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// SAFETY: Slice must point to a valid location reachable by DMA.
 | 
				
			||||||
pub unsafe fn write<'a, C: Channel, W: Word>(
 | 
					pub unsafe fn write<'a, C: Channel, W: Word>(
 | 
				
			||||||
    ch: impl Peripheral<P = C> + 'a,
 | 
					    ch: impl Peripheral<P = C> + 'a,
 | 
				
			||||||
    from: *const [W],
 | 
					    from: *const [W],
 | 
				
			||||||
@@ -79,6 +85,9 @@ pub unsafe fn write<'a, C: Channel, W: Word>(
 | 
				
			|||||||
// static mut so that this is allocated in RAM.
 | 
					// static mut so that this is allocated in RAM.
 | 
				
			||||||
static mut DUMMY: u32 = 0;
 | 
					static mut DUMMY: u32 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// DMA repeated write.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// SAFETY: Slice must point to a valid location reachable by DMA.
 | 
				
			||||||
pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
 | 
					pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
 | 
				
			||||||
    ch: impl Peripheral<P = C> + 'a,
 | 
					    ch: impl Peripheral<P = C> + 'a,
 | 
				
			||||||
    to: *mut W,
 | 
					    to: *mut W,
 | 
				
			||||||
@@ -97,6 +106,9 @@ pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// DMA copy between slices.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// SAFETY: Slices must point to locations reachable by DMA.
 | 
				
			||||||
pub unsafe fn copy<'a, C: Channel, W: Word>(
 | 
					pub unsafe fn copy<'a, C: Channel, W: Word>(
 | 
				
			||||||
    ch: impl Peripheral<P = C> + 'a,
 | 
					    ch: impl Peripheral<P = C> + 'a,
 | 
				
			||||||
    from: &[W],
 | 
					    from: &[W],
 | 
				
			||||||
@@ -152,6 +164,7 @@ fn copy_inner<'a, C: Channel>(
 | 
				
			|||||||
    Transfer::new(ch)
 | 
					    Transfer::new(ch)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// DMA transfer driver.
 | 
				
			||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
 | 
					#[must_use = "futures do nothing unless you `.await` or poll them"]
 | 
				
			||||||
pub struct Transfer<'a, C: Channel> {
 | 
					pub struct Transfer<'a, C: Channel> {
 | 
				
			||||||
    channel: PeripheralRef<'a, C>,
 | 
					    channel: PeripheralRef<'a, C>,
 | 
				
			||||||
@@ -201,19 +214,25 @@ mod sealed {
 | 
				
			|||||||
    pub trait Word {}
 | 
					    pub trait Word {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// DMA channel interface.
 | 
				
			||||||
pub trait Channel: Peripheral<P = Self> + sealed::Channel + Into<AnyChannel> + Sized + 'static {
 | 
					pub trait Channel: Peripheral<P = Self> + sealed::Channel + Into<AnyChannel> + Sized + 'static {
 | 
				
			||||||
 | 
					    /// Channel number.
 | 
				
			||||||
    fn number(&self) -> u8;
 | 
					    fn number(&self) -> u8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Channel registry block.
 | 
				
			||||||
    fn regs(&self) -> pac::dma::Channel {
 | 
					    fn regs(&self) -> pac::dma::Channel {
 | 
				
			||||||
        pac::DMA.ch(self.number() as _)
 | 
					        pac::DMA.ch(self.number() as _)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Convert into type-erased [AnyChannel].
 | 
				
			||||||
    fn degrade(self) -> AnyChannel {
 | 
					    fn degrade(self) -> AnyChannel {
 | 
				
			||||||
        AnyChannel { number: self.number() }
 | 
					        AnyChannel { number: self.number() }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// DMA word.
 | 
				
			||||||
pub trait Word: sealed::Word {
 | 
					pub trait Word: sealed::Word {
 | 
				
			||||||
 | 
					    /// Word size.
 | 
				
			||||||
    fn size() -> vals::DataSize;
 | 
					    fn size() -> vals::DataSize;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -238,6 +257,7 @@ impl Word for u32 {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Type erased DMA channel.
 | 
				
			||||||
pub struct AnyChannel {
 | 
					pub struct AnyChannel {
 | 
				
			||||||
    number: u8,
 | 
					    number: u8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Flash driver.
 | 
				
			||||||
use core::future::Future;
 | 
					use core::future::Future;
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
use core::pin::Pin;
 | 
					use core::pin::Pin;
 | 
				
			||||||
@@ -13,9 +14,10 @@ use crate::dma::{AnyChannel, Channel, Transfer};
 | 
				
			|||||||
use crate::pac;
 | 
					use crate::pac;
 | 
				
			||||||
use crate::peripherals::FLASH;
 | 
					use crate::peripherals::FLASH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Flash base address.
 | 
				
			||||||
pub const FLASH_BASE: *const u32 = 0x10000000 as _;
 | 
					pub const FLASH_BASE: *const u32 = 0x10000000 as _;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// If running from RAM, we might have no boot2. Use bootrom `flash_enter_cmd_xip` instead.
 | 
					/// If running from RAM, we might have no boot2. Use bootrom `flash_enter_cmd_xip` instead.
 | 
				
			||||||
// TODO: when run-from-ram is set, completely skip the "pause cores and jumpp to RAM" dance.
 | 
					// TODO: when run-from-ram is set, completely skip the "pause cores and jumpp to RAM" dance.
 | 
				
			||||||
pub const USE_BOOT2: bool = !cfg!(feature = "run-from-ram");
 | 
					pub const USE_BOOT2: bool = !cfg!(feature = "run-from-ram");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,10 +26,15 @@ pub const USE_BOOT2: bool = !cfg!(feature = "run-from-ram");
 | 
				
			|||||||
// These limitations are currently enforced because of using the
 | 
					// These limitations are currently enforced because of using the
 | 
				
			||||||
// RP2040 boot-rom flash functions, that are optimized for flash compatibility
 | 
					// RP2040 boot-rom flash functions, that are optimized for flash compatibility
 | 
				
			||||||
// rather than performance.
 | 
					// rather than performance.
 | 
				
			||||||
 | 
					/// Flash page size.
 | 
				
			||||||
pub const PAGE_SIZE: usize = 256;
 | 
					pub const PAGE_SIZE: usize = 256;
 | 
				
			||||||
 | 
					/// Flash write size.
 | 
				
			||||||
pub const WRITE_SIZE: usize = 1;
 | 
					pub const WRITE_SIZE: usize = 1;
 | 
				
			||||||
 | 
					/// Flash read size.
 | 
				
			||||||
pub const READ_SIZE: usize = 1;
 | 
					pub const READ_SIZE: usize = 1;
 | 
				
			||||||
 | 
					/// Flash erase size.
 | 
				
			||||||
pub const ERASE_SIZE: usize = 4096;
 | 
					pub const ERASE_SIZE: usize = 4096;
 | 
				
			||||||
 | 
					/// Flash DMA read size.
 | 
				
			||||||
pub const ASYNC_READ_SIZE: usize = 4;
 | 
					pub const ASYNC_READ_SIZE: usize = 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Error type for NVMC operations.
 | 
					/// Error type for NVMC operations.
 | 
				
			||||||
@@ -38,7 +45,9 @@ pub enum Error {
 | 
				
			|||||||
    OutOfBounds,
 | 
					    OutOfBounds,
 | 
				
			||||||
    /// Unaligned operation or using unaligned buffers.
 | 
					    /// Unaligned operation or using unaligned buffers.
 | 
				
			||||||
    Unaligned,
 | 
					    Unaligned,
 | 
				
			||||||
 | 
					    /// Accessed from the wrong core.
 | 
				
			||||||
    InvalidCore,
 | 
					    InvalidCore,
 | 
				
			||||||
 | 
					    /// Other error
 | 
				
			||||||
    Other,
 | 
					    Other,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -96,12 +105,18 @@ impl<'a, 'd, T: Instance, const FLASH_SIZE: usize> Drop for BackgroundRead<'a, '
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Flash driver.
 | 
				
			||||||
pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> {
 | 
					pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> {
 | 
				
			||||||
    dma: Option<PeripheralRef<'d, AnyChannel>>,
 | 
					    dma: Option<PeripheralRef<'d, AnyChannel>>,
 | 
				
			||||||
    phantom: PhantomData<(&'d mut T, M)>,
 | 
					    phantom: PhantomData<(&'d mut T, M)>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SIZE> {
 | 
					impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SIZE> {
 | 
				
			||||||
 | 
					    /// Blocking read.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// The offset and buffer must be aligned.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
 | 
				
			||||||
    pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
 | 
				
			||||||
        trace!(
 | 
					        trace!(
 | 
				
			||||||
            "Reading from 0x{:x} to 0x{:x}",
 | 
					            "Reading from 0x{:x} to 0x{:x}",
 | 
				
			||||||
@@ -116,10 +131,14 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
 | 
				
			|||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Flash capacity.
 | 
				
			||||||
    pub fn capacity(&self) -> usize {
 | 
					    pub fn capacity(&self) -> usize {
 | 
				
			||||||
        FLASH_SIZE
 | 
					        FLASH_SIZE
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Blocking erase.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
 | 
				
			||||||
    pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
 | 
					    pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
 | 
				
			||||||
        check_erase(self, from, to)?;
 | 
					        check_erase(self, from, to)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -136,6 +155,11 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
 | 
				
			|||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Blocking write.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// The offset and buffer must be aligned.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
 | 
				
			||||||
    pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
 | 
				
			||||||
        check_write(self, offset, bytes.len())?;
 | 
					        check_write(self, offset, bytes.len())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -219,6 +243,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> {
 | 
					impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> {
 | 
				
			||||||
 | 
					    /// Create a new flash driver in blocking mode.
 | 
				
			||||||
    pub fn new_blocking(_flash: impl Peripheral<P = T> + 'd) -> Self {
 | 
					    pub fn new_blocking(_flash: impl Peripheral<P = T> + 'd) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            dma: None,
 | 
					            dma: None,
 | 
				
			||||||
@@ -228,6 +253,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
 | 
					impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
 | 
				
			||||||
 | 
					    /// Create a new flash driver in async mode.
 | 
				
			||||||
    pub fn new(_flash: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = impl Channel> + 'd) -> Self {
 | 
					    pub fn new(_flash: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = impl Channel> + 'd) -> Self {
 | 
				
			||||||
        into_ref!(dma);
 | 
					        into_ref!(dma);
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
@@ -236,6 +262,11 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Start a background read operation.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// The offset and buffer must be aligned.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
 | 
				
			||||||
    pub fn background_read<'a>(
 | 
					    pub fn background_read<'a>(
 | 
				
			||||||
        &'a mut self,
 | 
					        &'a mut self,
 | 
				
			||||||
        offset: u32,
 | 
					        offset: u32,
 | 
				
			||||||
@@ -279,6 +310,11 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Async read.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// The offset and buffer must be aligned.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
 | 
				
			||||||
    pub async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
 | 
					    pub async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
 | 
				
			||||||
        use core::mem::MaybeUninit;
 | 
					        use core::mem::MaybeUninit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -874,7 +910,9 @@ mod sealed {
 | 
				
			|||||||
    pub trait Mode {}
 | 
					    pub trait Mode {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Flash instance.
 | 
				
			||||||
pub trait Instance: sealed::Instance {}
 | 
					pub trait Instance: sealed::Instance {}
 | 
				
			||||||
 | 
					/// Flash mode.
 | 
				
			||||||
pub trait Mode: sealed::Mode {}
 | 
					pub trait Mode: sealed::Mode {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl sealed::Instance for FLASH {}
 | 
					impl sealed::Instance for FLASH {}
 | 
				
			||||||
@@ -887,7 +925,9 @@ macro_rules! impl_mode {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Flash blocking mode.
 | 
				
			||||||
pub struct Blocking;
 | 
					pub struct Blocking;
 | 
				
			||||||
 | 
					/// Flash async mode.
 | 
				
			||||||
pub struct Async;
 | 
					pub struct Async;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_mode!(Blocking);
 | 
					impl_mode!(Blocking);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! GPIO driver.
 | 
				
			||||||
#![macro_use]
 | 
					#![macro_use]
 | 
				
			||||||
use core::convert::Infallible;
 | 
					use core::convert::Infallible;
 | 
				
			||||||
use core::future::Future;
 | 
					use core::future::Future;
 | 
				
			||||||
@@ -23,7 +24,9 @@ static QSPI_WAKERS: [AtomicWaker; QSPI_PIN_COUNT] = [NEW_AW; QSPI_PIN_COUNT];
 | 
				
			|||||||
/// Represents a digital input or output level.
 | 
					/// Represents a digital input or output level.
 | 
				
			||||||
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
 | 
					#[derive(Debug, Eq, PartialEq, Clone, Copy)]
 | 
				
			||||||
pub enum Level {
 | 
					pub enum Level {
 | 
				
			||||||
 | 
					    /// Logical low.
 | 
				
			||||||
    Low,
 | 
					    Low,
 | 
				
			||||||
 | 
					    /// Logical high.
 | 
				
			||||||
    High,
 | 
					    High,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -48,48 +51,66 @@ impl From<Level> for bool {
 | 
				
			|||||||
/// Represents a pull setting for an input.
 | 
					/// Represents a pull setting for an input.
 | 
				
			||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
 | 
					#[derive(Debug, Clone, Copy, Eq, PartialEq)]
 | 
				
			||||||
pub enum Pull {
 | 
					pub enum Pull {
 | 
				
			||||||
 | 
					    /// No pull.
 | 
				
			||||||
    None,
 | 
					    None,
 | 
				
			||||||
 | 
					    /// Internal pull-up resistor.
 | 
				
			||||||
    Up,
 | 
					    Up,
 | 
				
			||||||
 | 
					    /// Internal pull-down resistor.
 | 
				
			||||||
    Down,
 | 
					    Down,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Drive strength of an output
 | 
					/// Drive strength of an output
 | 
				
			||||||
#[derive(Debug, Eq, PartialEq)]
 | 
					#[derive(Debug, Eq, PartialEq)]
 | 
				
			||||||
pub enum Drive {
 | 
					pub enum Drive {
 | 
				
			||||||
 | 
					    /// 2 mA drive.
 | 
				
			||||||
    _2mA,
 | 
					    _2mA,
 | 
				
			||||||
 | 
					    /// 4 mA drive.
 | 
				
			||||||
    _4mA,
 | 
					    _4mA,
 | 
				
			||||||
 | 
					    /// 8 mA drive.
 | 
				
			||||||
    _8mA,
 | 
					    _8mA,
 | 
				
			||||||
 | 
					    /// 1 2mA drive.
 | 
				
			||||||
    _12mA,
 | 
					    _12mA,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/// Slew rate of an output
 | 
					/// Slew rate of an output
 | 
				
			||||||
#[derive(Debug, Eq, PartialEq)]
 | 
					#[derive(Debug, Eq, PartialEq)]
 | 
				
			||||||
pub enum SlewRate {
 | 
					pub enum SlewRate {
 | 
				
			||||||
 | 
					    /// Fast slew rate.
 | 
				
			||||||
    Fast,
 | 
					    Fast,
 | 
				
			||||||
 | 
					    /// Slow slew rate.
 | 
				
			||||||
    Slow,
 | 
					    Slow,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// A GPIO bank with up to 32 pins.
 | 
					/// A GPIO bank with up to 32 pins.
 | 
				
			||||||
#[derive(Debug, Eq, PartialEq)]
 | 
					#[derive(Debug, Eq, PartialEq)]
 | 
				
			||||||
pub enum Bank {
 | 
					pub enum Bank {
 | 
				
			||||||
 | 
					    /// Bank 0.
 | 
				
			||||||
    Bank0 = 0,
 | 
					    Bank0 = 0,
 | 
				
			||||||
 | 
					    /// QSPI.
 | 
				
			||||||
    #[cfg(feature = "qspi-as-gpio")]
 | 
					    #[cfg(feature = "qspi-as-gpio")]
 | 
				
			||||||
    Qspi = 1,
 | 
					    Qspi = 1,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Dormant mode config.
 | 
				
			||||||
#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)]
 | 
					#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)]
 | 
				
			||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
					#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
				
			||||||
pub struct DormantWakeConfig {
 | 
					pub struct DormantWakeConfig {
 | 
				
			||||||
 | 
					    /// Wake on edge high.
 | 
				
			||||||
    pub edge_high: bool,
 | 
					    pub edge_high: bool,
 | 
				
			||||||
 | 
					    /// Wake on edge low.
 | 
				
			||||||
    pub edge_low: bool,
 | 
					    pub edge_low: bool,
 | 
				
			||||||
 | 
					    /// Wake on level high.
 | 
				
			||||||
    pub level_high: bool,
 | 
					    pub level_high: bool,
 | 
				
			||||||
 | 
					    /// Wake on level low.
 | 
				
			||||||
    pub level_low: bool,
 | 
					    pub level_low: bool,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// GPIO input driver.
 | 
				
			||||||
pub struct Input<'d, T: Pin> {
 | 
					pub struct Input<'d, T: Pin> {
 | 
				
			||||||
    pin: Flex<'d, T>,
 | 
					    pin: Flex<'d, T>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Pin> Input<'d, T> {
 | 
					impl<'d, T: Pin> Input<'d, T> {
 | 
				
			||||||
 | 
					    /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
 | 
					    pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
 | 
				
			||||||
        let mut pin = Flex::new(pin);
 | 
					        let mut pin = Flex::new(pin);
 | 
				
			||||||
@@ -104,11 +125,13 @@ impl<'d, T: Pin> Input<'d, T> {
 | 
				
			|||||||
        self.pin.set_schmitt(enable)
 | 
					        self.pin.set_schmitt(enable)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Get whether the pin input level is high.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn is_high(&mut self) -> bool {
 | 
					    pub fn is_high(&mut self) -> bool {
 | 
				
			||||||
        self.pin.is_high()
 | 
					        self.pin.is_high()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Get whether the pin input level is low.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn is_low(&mut self) -> bool {
 | 
					    pub fn is_low(&mut self) -> bool {
 | 
				
			||||||
        self.pin.is_low()
 | 
					        self.pin.is_low()
 | 
				
			||||||
@@ -120,31 +143,37 @@ impl<'d, T: Pin> Input<'d, T> {
 | 
				
			|||||||
        self.pin.get_level()
 | 
					        self.pin.get_level()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait until the pin is high. If it is already high, return immediately.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_high(&mut self) {
 | 
					    pub async fn wait_for_high(&mut self) {
 | 
				
			||||||
        self.pin.wait_for_high().await;
 | 
					        self.pin.wait_for_high().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait until the pin is low. If it is already low, return immediately.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_low(&mut self) {
 | 
					    pub async fn wait_for_low(&mut self) {
 | 
				
			||||||
        self.pin.wait_for_low().await;
 | 
					        self.pin.wait_for_low().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait for the pin to undergo a transition from low to high.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_rising_edge(&mut self) {
 | 
					    pub async fn wait_for_rising_edge(&mut self) {
 | 
				
			||||||
        self.pin.wait_for_rising_edge().await;
 | 
					        self.pin.wait_for_rising_edge().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait for the pin to undergo a transition from high to low.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_falling_edge(&mut self) {
 | 
					    pub async fn wait_for_falling_edge(&mut self) {
 | 
				
			||||||
        self.pin.wait_for_falling_edge().await;
 | 
					        self.pin.wait_for_falling_edge().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_any_edge(&mut self) {
 | 
					    pub async fn wait_for_any_edge(&mut self) {
 | 
				
			||||||
        self.pin.wait_for_any_edge().await;
 | 
					        self.pin.wait_for_any_edge().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Configure dormant wake.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn dormant_wake(&mut self, cfg: DormantWakeConfig) -> DormantWake<T> {
 | 
					    pub fn dormant_wake(&mut self, cfg: DormantWakeConfig) -> DormantWake<T> {
 | 
				
			||||||
        self.pin.dormant_wake(cfg)
 | 
					        self.pin.dormant_wake(cfg)
 | 
				
			||||||
@@ -155,10 +184,15 @@ impl<'d, T: Pin> Input<'d, T> {
 | 
				
			|||||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
 | 
					#[derive(Debug, Eq, PartialEq, Copy, Clone)]
 | 
				
			||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
					#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
				
			||||||
pub enum InterruptTrigger {
 | 
					pub enum InterruptTrigger {
 | 
				
			||||||
 | 
					    /// Trigger on pin low.
 | 
				
			||||||
    LevelLow,
 | 
					    LevelLow,
 | 
				
			||||||
 | 
					    /// Trigger on pin high.
 | 
				
			||||||
    LevelHigh,
 | 
					    LevelHigh,
 | 
				
			||||||
 | 
					    /// Trigger on high to low transition.
 | 
				
			||||||
    EdgeLow,
 | 
					    EdgeLow,
 | 
				
			||||||
 | 
					    /// Trigger on low to high transition.
 | 
				
			||||||
    EdgeHigh,
 | 
					    EdgeHigh,
 | 
				
			||||||
 | 
					    /// Trigger on any transition.
 | 
				
			||||||
    AnyEdge,
 | 
					    AnyEdge,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -226,6 +260,7 @@ struct InputFuture<'a, T: Pin> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Pin> InputFuture<'d, T> {
 | 
					impl<'d, T: Pin> InputFuture<'d, T> {
 | 
				
			||||||
 | 
					    /// Create a new future wiating for input trigger.
 | 
				
			||||||
    pub fn new(pin: impl Peripheral<P = T> + 'd, level: InterruptTrigger) -> Self {
 | 
					    pub fn new(pin: impl Peripheral<P = T> + 'd, level: InterruptTrigger) -> Self {
 | 
				
			||||||
        into_ref!(pin);
 | 
					        into_ref!(pin);
 | 
				
			||||||
        let pin_group = (pin.pin() % 8) as usize;
 | 
					        let pin_group = (pin.pin() % 8) as usize;
 | 
				
			||||||
@@ -308,11 +343,13 @@ impl<'d, T: Pin> Future for InputFuture<'d, T> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// GPIO output driver.
 | 
				
			||||||
pub struct Output<'d, T: Pin> {
 | 
					pub struct Output<'d, T: Pin> {
 | 
				
			||||||
    pin: Flex<'d, T>,
 | 
					    pin: Flex<'d, T>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Pin> Output<'d, T> {
 | 
					impl<'d, T: Pin> Output<'d, T> {
 | 
				
			||||||
 | 
					    /// Create GPIO output driver for a [Pin] with the provided [Level].
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level) -> Self {
 | 
					    pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level) -> Self {
 | 
				
			||||||
        let mut pin = Flex::new(pin);
 | 
					        let mut pin = Flex::new(pin);
 | 
				
			||||||
@@ -331,7 +368,7 @@ impl<'d, T: Pin> Output<'d, T> {
 | 
				
			|||||||
        self.pin.set_drive_strength(strength)
 | 
					        self.pin.set_drive_strength(strength)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Set the pin's slew rate.
 | 
					    /// Set the pin's slew rate.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_slew_rate(&mut self, slew_rate: SlewRate) {
 | 
					    pub fn set_slew_rate(&mut self, slew_rate: SlewRate) {
 | 
				
			||||||
        self.pin.set_slew_rate(slew_rate)
 | 
					        self.pin.set_slew_rate(slew_rate)
 | 
				
			||||||
@@ -386,6 +423,7 @@ pub struct OutputOpenDrain<'d, T: Pin> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Pin> OutputOpenDrain<'d, T> {
 | 
					impl<'d, T: Pin> OutputOpenDrain<'d, T> {
 | 
				
			||||||
 | 
					    /// Create GPIO output driver for a [Pin] in open drain mode with the provided [Level].
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level) -> Self {
 | 
					    pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level) -> Self {
 | 
				
			||||||
        let mut pin = Flex::new(pin);
 | 
					        let mut pin = Flex::new(pin);
 | 
				
			||||||
@@ -403,7 +441,7 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
 | 
				
			|||||||
        self.pin.set_drive_strength(strength)
 | 
					        self.pin.set_drive_strength(strength)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Set the pin's slew rate.
 | 
					    /// Set the pin's slew rate.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_slew_rate(&mut self, slew_rate: SlewRate) {
 | 
					    pub fn set_slew_rate(&mut self, slew_rate: SlewRate) {
 | 
				
			||||||
        self.pin.set_slew_rate(slew_rate)
 | 
					        self.pin.set_slew_rate(slew_rate)
 | 
				
			||||||
@@ -456,11 +494,13 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
 | 
				
			|||||||
        self.pin.toggle_set_as_output()
 | 
					        self.pin.toggle_set_as_output()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Get whether the pin input level is high.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn is_high(&mut self) -> bool {
 | 
					    pub fn is_high(&mut self) -> bool {
 | 
				
			||||||
        self.pin.is_high()
 | 
					        self.pin.is_high()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Get whether the pin input level is low.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn is_low(&mut self) -> bool {
 | 
					    pub fn is_low(&mut self) -> bool {
 | 
				
			||||||
        self.pin.is_low()
 | 
					        self.pin.is_low()
 | 
				
			||||||
@@ -472,26 +512,31 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
 | 
				
			|||||||
        self.is_high().into()
 | 
					        self.is_high().into()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait until the pin is high. If it is already high, return immediately.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_high(&mut self) {
 | 
					    pub async fn wait_for_high(&mut self) {
 | 
				
			||||||
        self.pin.wait_for_high().await;
 | 
					        self.pin.wait_for_high().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait until the pin is low. If it is already low, return immediately.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_low(&mut self) {
 | 
					    pub async fn wait_for_low(&mut self) {
 | 
				
			||||||
        self.pin.wait_for_low().await;
 | 
					        self.pin.wait_for_low().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait for the pin to undergo a transition from low to high.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_rising_edge(&mut self) {
 | 
					    pub async fn wait_for_rising_edge(&mut self) {
 | 
				
			||||||
        self.pin.wait_for_rising_edge().await;
 | 
					        self.pin.wait_for_rising_edge().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait for the pin to undergo a transition from high to low.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_falling_edge(&mut self) {
 | 
					    pub async fn wait_for_falling_edge(&mut self) {
 | 
				
			||||||
        self.pin.wait_for_falling_edge().await;
 | 
					        self.pin.wait_for_falling_edge().await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_any_edge(&mut self) {
 | 
					    pub async fn wait_for_any_edge(&mut self) {
 | 
				
			||||||
        self.pin.wait_for_any_edge().await;
 | 
					        self.pin.wait_for_any_edge().await;
 | 
				
			||||||
@@ -508,6 +553,10 @@ pub struct Flex<'d, T: Pin> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Pin> Flex<'d, T> {
 | 
					impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			||||||
 | 
					    /// Wrap the pin in a `Flex`.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// The pin remains disconnected. The initial output level is unspecified, but can be changed
 | 
				
			||||||
 | 
					    /// before the pin is put into output mode.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn new(pin: impl Peripheral<P = T> + 'd) -> Self {
 | 
					    pub fn new(pin: impl Peripheral<P = T> + 'd) -> Self {
 | 
				
			||||||
        into_ref!(pin);
 | 
					        into_ref!(pin);
 | 
				
			||||||
@@ -556,7 +605,7 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Set the pin's slew rate.
 | 
					    /// Set the pin's slew rate.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_slew_rate(&mut self, slew_rate: SlewRate) {
 | 
					    pub fn set_slew_rate(&mut self, slew_rate: SlewRate) {
 | 
				
			||||||
        self.pin.pad_ctrl().modify(|w| {
 | 
					        self.pin.pad_ctrl().modify(|w| {
 | 
				
			||||||
@@ -589,6 +638,7 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
        self.pin.sio_oe().value_set().write_value(self.bit())
 | 
					        self.pin.sio_oe().value_set().write_value(self.bit())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Set as output pin.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn is_set_as_output(&mut self) -> bool {
 | 
					    pub fn is_set_as_output(&mut self) -> bool {
 | 
				
			||||||
        self.ref_is_set_as_output()
 | 
					        self.ref_is_set_as_output()
 | 
				
			||||||
@@ -599,15 +649,18 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
        (self.pin.sio_oe().value().read() & self.bit()) != 0
 | 
					        (self.pin.sio_oe().value().read() & self.bit()) != 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Toggle output pin.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn toggle_set_as_output(&mut self) {
 | 
					    pub fn toggle_set_as_output(&mut self) {
 | 
				
			||||||
        self.pin.sio_oe().value_xor().write_value(self.bit())
 | 
					        self.pin.sio_oe().value_xor().write_value(self.bit())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Get whether the pin input level is high.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn is_high(&mut self) -> bool {
 | 
					    pub fn is_high(&mut self) -> bool {
 | 
				
			||||||
        !self.is_low()
 | 
					        !self.is_low()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    /// Get whether the pin input level is low.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn is_low(&mut self) -> bool {
 | 
					    pub fn is_low(&mut self) -> bool {
 | 
				
			||||||
@@ -675,31 +728,37 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
        self.pin.sio_out().value_xor().write_value(self.bit())
 | 
					        self.pin.sio_out().value_xor().write_value(self.bit())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait until the pin is high. If it is already high, return immediately.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_high(&mut self) {
 | 
					    pub async fn wait_for_high(&mut self) {
 | 
				
			||||||
        InputFuture::new(&mut self.pin, InterruptTrigger::LevelHigh).await;
 | 
					        InputFuture::new(&mut self.pin, InterruptTrigger::LevelHigh).await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait until the pin is low. If it is already low, return immediately.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_low(&mut self) {
 | 
					    pub async fn wait_for_low(&mut self) {
 | 
				
			||||||
        InputFuture::new(&mut self.pin, InterruptTrigger::LevelLow).await;
 | 
					        InputFuture::new(&mut self.pin, InterruptTrigger::LevelLow).await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait for the pin to undergo a transition from low to high.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_rising_edge(&mut self) {
 | 
					    pub async fn wait_for_rising_edge(&mut self) {
 | 
				
			||||||
        InputFuture::new(&mut self.pin, InterruptTrigger::EdgeHigh).await;
 | 
					        InputFuture::new(&mut self.pin, InterruptTrigger::EdgeHigh).await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait for the pin to undergo a transition from high to low.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_falling_edge(&mut self) {
 | 
					    pub async fn wait_for_falling_edge(&mut self) {
 | 
				
			||||||
        InputFuture::new(&mut self.pin, InterruptTrigger::EdgeLow).await;
 | 
					        InputFuture::new(&mut self.pin, InterruptTrigger::EdgeLow).await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub async fn wait_for_any_edge(&mut self) {
 | 
					    pub async fn wait_for_any_edge(&mut self) {
 | 
				
			||||||
        InputFuture::new(&mut self.pin, InterruptTrigger::AnyEdge).await;
 | 
					        InputFuture::new(&mut self.pin, InterruptTrigger::AnyEdge).await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Configure dormant wake.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn dormant_wake(&mut self, cfg: DormantWakeConfig) -> DormantWake<T> {
 | 
					    pub fn dormant_wake(&mut self, cfg: DormantWakeConfig) -> DormantWake<T> {
 | 
				
			||||||
        let idx = self.pin._pin() as usize;
 | 
					        let idx = self.pin._pin() as usize;
 | 
				
			||||||
@@ -737,6 +796,7 @@ impl<'d, T: Pin> Drop for Flex<'d, T> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Dormant wake driver.
 | 
				
			||||||
pub struct DormantWake<'w, T: Pin> {
 | 
					pub struct DormantWake<'w, T: Pin> {
 | 
				
			||||||
    pin: PeripheralRef<'w, T>,
 | 
					    pin: PeripheralRef<'w, T>,
 | 
				
			||||||
    cfg: DormantWakeConfig,
 | 
					    cfg: DormantWakeConfig,
 | 
				
			||||||
@@ -818,6 +878,7 @@ pub(crate) mod sealed {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
 | 
				
			||||||
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
 | 
					pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
 | 
				
			||||||
    /// Degrade to a generic pin struct
 | 
					    /// Degrade to a generic pin struct
 | 
				
			||||||
    fn degrade(self) -> AnyPin {
 | 
					    fn degrade(self) -> AnyPin {
 | 
				
			||||||
@@ -839,6 +900,7 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'stat
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Type-erased GPIO pin
 | 
				
			||||||
pub struct AnyPin {
 | 
					pub struct AnyPin {
 | 
				
			||||||
    pin_bank: u8,
 | 
					    pin_bank: u8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! I2C driver.
 | 
				
			||||||
use core::future;
 | 
					use core::future;
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
use core::task::Poll;
 | 
					use core::task::Poll;
 | 
				
			||||||
@@ -22,6 +23,7 @@ pub enum AbortReason {
 | 
				
			|||||||
    ArbitrationLoss,
 | 
					    ArbitrationLoss,
 | 
				
			||||||
    /// Transmit ended with data still in fifo
 | 
					    /// Transmit ended with data still in fifo
 | 
				
			||||||
    TxNotEmpty(u16),
 | 
					    TxNotEmpty(u16),
 | 
				
			||||||
 | 
					    /// Other reason.
 | 
				
			||||||
    Other(u32),
 | 
					    Other(u32),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -41,9 +43,11 @@ pub enum Error {
 | 
				
			|||||||
    AddressReserved(u16),
 | 
					    AddressReserved(u16),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// I2C config.
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
pub struct Config {
 | 
					pub struct Config {
 | 
				
			||||||
 | 
					    /// Frequency.
 | 
				
			||||||
    pub frequency: u32,
 | 
					    pub frequency: u32,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,13 +57,16 @@ impl Default for Config {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Size of I2C FIFO.
 | 
				
			||||||
pub const FIFO_SIZE: u8 = 16;
 | 
					pub const FIFO_SIZE: u8 = 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// I2C driver.
 | 
				
			||||||
pub struct I2c<'d, T: Instance, M: Mode> {
 | 
					pub struct I2c<'d, T: Instance, M: Mode> {
 | 
				
			||||||
    phantom: PhantomData<(&'d mut T, M)>,
 | 
					    phantom: PhantomData<(&'d mut T, M)>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> I2c<'d, T, Blocking> {
 | 
					impl<'d, T: Instance> I2c<'d, T, Blocking> {
 | 
				
			||||||
 | 
					    /// Create a new driver instance in blocking mode.
 | 
				
			||||||
    pub fn new_blocking(
 | 
					    pub fn new_blocking(
 | 
				
			||||||
        peri: impl Peripheral<P = T> + 'd,
 | 
					        peri: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
        scl: impl Peripheral<P = impl SclPin<T>> + 'd,
 | 
					        scl: impl Peripheral<P = impl SclPin<T>> + 'd,
 | 
				
			||||||
@@ -72,6 +79,7 @@ impl<'d, T: Instance> I2c<'d, T, Blocking> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
					impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			||||||
 | 
					    /// Create a new driver instance in async mode.
 | 
				
			||||||
    pub fn new_async(
 | 
					    pub fn new_async(
 | 
				
			||||||
        peri: impl Peripheral<P = T> + 'd,
 | 
					        peri: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
        scl: impl Peripheral<P = impl SclPin<T>> + 'd,
 | 
					        scl: impl Peripheral<P = impl SclPin<T>> + 'd,
 | 
				
			||||||
@@ -292,16 +300,19 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Read from address into buffer using DMA.
 | 
				
			||||||
    pub async fn read_async(&mut self, addr: u16, buffer: &mut [u8]) -> Result<(), Error> {
 | 
					    pub async fn read_async(&mut self, addr: u16, buffer: &mut [u8]) -> Result<(), Error> {
 | 
				
			||||||
        Self::setup(addr)?;
 | 
					        Self::setup(addr)?;
 | 
				
			||||||
        self.read_async_internal(buffer, true, true).await
 | 
					        self.read_async_internal(buffer, true, true).await
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Write to address from buffer using DMA.
 | 
				
			||||||
    pub async fn write_async(&mut self, addr: u16, bytes: impl IntoIterator<Item = u8>) -> Result<(), Error> {
 | 
					    pub async fn write_async(&mut self, addr: u16, bytes: impl IntoIterator<Item = u8>) -> Result<(), Error> {
 | 
				
			||||||
        Self::setup(addr)?;
 | 
					        Self::setup(addr)?;
 | 
				
			||||||
        self.write_async_internal(bytes, true).await
 | 
					        self.write_async_internal(bytes, true).await
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Write to address from bytes and read from address into buffer using DMA.
 | 
				
			||||||
    pub async fn write_read_async(
 | 
					    pub async fn write_read_async(
 | 
				
			||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
        addr: u16,
 | 
					        addr: u16,
 | 
				
			||||||
@@ -314,6 +325,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Interrupt handler.
 | 
				
			||||||
pub struct InterruptHandler<T: Instance> {
 | 
					pub struct InterruptHandler<T: Instance> {
 | 
				
			||||||
    _uart: PhantomData<T>,
 | 
					    _uart: PhantomData<T>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -569,17 +581,20 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
 | 
				
			|||||||
    // Blocking public API
 | 
					    // Blocking public API
 | 
				
			||||||
    // =========================
 | 
					    // =========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Read from address into buffer blocking caller until done.
 | 
				
			||||||
    pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
 | 
				
			||||||
        Self::setup(address.into())?;
 | 
					        Self::setup(address.into())?;
 | 
				
			||||||
        self.read_blocking_internal(read, true, true)
 | 
					        self.read_blocking_internal(read, true, true)
 | 
				
			||||||
        // Automatic Stop
 | 
					        // Automatic Stop
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Write to address from buffer blocking caller until done.
 | 
				
			||||||
    pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
 | 
				
			||||||
        Self::setup(address.into())?;
 | 
					        Self::setup(address.into())?;
 | 
				
			||||||
        self.write_blocking_internal(write, true)
 | 
					        self.write_blocking_internal(write, true)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Write to address from bytes and read from address into buffer blocking caller until done.
 | 
				
			||||||
    pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
 | 
				
			||||||
        Self::setup(address.into())?;
 | 
					        Self::setup(address.into())?;
 | 
				
			||||||
        self.write_blocking_internal(write, false)?;
 | 
					        self.write_blocking_internal(write, false)?;
 | 
				
			||||||
@@ -742,6 +757,7 @@ where
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Check if address is reserved.
 | 
				
			||||||
pub fn i2c_reserved_addr(addr: u16) -> bool {
 | 
					pub fn i2c_reserved_addr(addr: u16) -> bool {
 | 
				
			||||||
    ((addr & 0x78) == 0 || (addr & 0x78) == 0x78) && addr != 0
 | 
					    ((addr & 0x78) == 0 || (addr & 0x78) == 0x78) && addr != 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -768,6 +784,7 @@ mod sealed {
 | 
				
			|||||||
    pub trait SclPin<T: Instance> {}
 | 
					    pub trait SclPin<T: Instance> {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Driver mode.
 | 
				
			||||||
pub trait Mode: sealed::Mode {}
 | 
					pub trait Mode: sealed::Mode {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! impl_mode {
 | 
					macro_rules! impl_mode {
 | 
				
			||||||
@@ -777,12 +794,15 @@ macro_rules! impl_mode {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Blocking mode.
 | 
				
			||||||
pub struct Blocking;
 | 
					pub struct Blocking;
 | 
				
			||||||
 | 
					/// Async mode.
 | 
				
			||||||
pub struct Async;
 | 
					pub struct Async;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_mode!(Blocking);
 | 
					impl_mode!(Blocking);
 | 
				
			||||||
impl_mode!(Async);
 | 
					impl_mode!(Async);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// I2C instance.
 | 
				
			||||||
pub trait Instance: sealed::Instance {}
 | 
					pub trait Instance: sealed::Instance {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! impl_instance {
 | 
					macro_rules! impl_instance {
 | 
				
			||||||
@@ -819,7 +839,9 @@ macro_rules! impl_instance {
 | 
				
			|||||||
impl_instance!(I2C0, I2C0_IRQ, set_i2c0, 32, 33);
 | 
					impl_instance!(I2C0, I2C0_IRQ, set_i2c0, 32, 33);
 | 
				
			||||||
impl_instance!(I2C1, I2C1_IRQ, set_i2c1, 34, 35);
 | 
					impl_instance!(I2C1, I2C1_IRQ, set_i2c1, 34, 35);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// SDA pin.
 | 
				
			||||||
pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + crate::gpio::Pin {}
 | 
					pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + crate::gpio::Pin {}
 | 
				
			||||||
 | 
					/// SCL pin.
 | 
				
			||||||
pub trait SclPin<T: Instance>: sealed::SclPin<T> + crate::gpio::Pin {}
 | 
					pub trait SclPin<T: Instance>: sealed::SclPin<T> + crate::gpio::Pin {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! impl_pin {
 | 
					macro_rules! impl_pin {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! I2C slave driver.
 | 
				
			||||||
use core::future;
 | 
					use core::future;
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
use core::task::Poll;
 | 
					use core::task::Poll;
 | 
				
			||||||
@@ -63,11 +64,13 @@ impl Default for Config {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// I2CSlave driver.
 | 
				
			||||||
pub struct I2cSlave<'d, T: Instance> {
 | 
					pub struct I2cSlave<'d, T: Instance> {
 | 
				
			||||||
    phantom: PhantomData<&'d mut T>,
 | 
					    phantom: PhantomData<&'d mut T>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> I2cSlave<'d, T> {
 | 
					impl<'d, T: Instance> I2cSlave<'d, T> {
 | 
				
			||||||
 | 
					    /// Create a new instance.
 | 
				
			||||||
    pub fn new(
 | 
					    pub fn new(
 | 
				
			||||||
        _peri: impl Peripheral<P = T> + 'd,
 | 
					        _peri: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
        scl: impl Peripheral<P = impl SclPin<T>> + 'd,
 | 
					        scl: impl Peripheral<P = impl SclPin<T>> + 'd,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
#![no_std]
 | 
					#![no_std]
 | 
				
			||||||
#![allow(async_fn_in_trait)]
 | 
					#![allow(async_fn_in_trait)]
 | 
				
			||||||
#![doc = include_str!("../README.md")]
 | 
					#![doc = include_str!("../README.md")]
 | 
				
			||||||
 | 
					#![warn(missing_docs)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This mod MUST go first, so that the others see its macros.
 | 
					// This mod MUST go first, so that the others see its macros.
 | 
				
			||||||
pub(crate) mod fmt;
 | 
					pub(crate) mod fmt;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! PIO driver.
 | 
				
			||||||
use core::future::Future;
 | 
					use core::future::Future;
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
use core::pin::Pin as FuturePin;
 | 
					use core::pin::Pin as FuturePin;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,11 +119,13 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Create PWM driver without any configured pins.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn new_free(inner: impl Peripheral<P = T> + 'd, config: Config) -> Self {
 | 
					    pub fn new_free(inner: impl Peripheral<P = T> + 'd, config: Config) -> Self {
 | 
				
			||||||
        Self::new_inner(inner, None, None, config, Divmode::DIV)
 | 
					        Self::new_inner(inner, None, None, config, Divmode::DIV)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Create PWM driver with a single 'a' as output.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn new_output_a(
 | 
					    pub fn new_output_a(
 | 
				
			||||||
        inner: impl Peripheral<P = T> + 'd,
 | 
					        inner: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
@@ -134,6 +136,7 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
        Self::new_inner(inner, Some(a.map_into()), None, config, Divmode::DIV)
 | 
					        Self::new_inner(inner, Some(a.map_into()), None, config, Divmode::DIV)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Create PWM driver with a single 'b' pin as output.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn new_output_b(
 | 
					    pub fn new_output_b(
 | 
				
			||||||
        inner: impl Peripheral<P = T> + 'd,
 | 
					        inner: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
@@ -144,6 +147,7 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
        Self::new_inner(inner, None, Some(b.map_into()), config, Divmode::DIV)
 | 
					        Self::new_inner(inner, None, Some(b.map_into()), config, Divmode::DIV)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Create PWM driver with a 'a' and 'b' pins as output.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn new_output_ab(
 | 
					    pub fn new_output_ab(
 | 
				
			||||||
        inner: impl Peripheral<P = T> + 'd,
 | 
					        inner: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
@@ -155,6 +159,7 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
        Self::new_inner(inner, Some(a.map_into()), Some(b.map_into()), config, Divmode::DIV)
 | 
					        Self::new_inner(inner, Some(a.map_into()), Some(b.map_into()), config, Divmode::DIV)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Create PWM driver with a single 'b' as input pin.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn new_input(
 | 
					    pub fn new_input(
 | 
				
			||||||
        inner: impl Peripheral<P = T> + 'd,
 | 
					        inner: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
@@ -166,6 +171,7 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
        Self::new_inner(inner, None, Some(b.map_into()), config, mode.into())
 | 
					        Self::new_inner(inner, None, Some(b.map_into()), config, mode.into())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Create PWM driver with a 'a' and 'b' pins in the desired input mode.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn new_output_input(
 | 
					    pub fn new_output_input(
 | 
				
			||||||
        inner: impl Peripheral<P = T> + 'd,
 | 
					        inner: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
@@ -178,6 +184,7 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
        Self::new_inner(inner, Some(a.map_into()), Some(b.map_into()), config, mode.into())
 | 
					        Self::new_inner(inner, Some(a.map_into()), Some(b.map_into()), config, mode.into())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Set the PWM config.
 | 
				
			||||||
    pub fn set_config(&mut self, config: &Config) {
 | 
					    pub fn set_config(&mut self, config: &Config) {
 | 
				
			||||||
        Self::configure(self.inner.regs(), config);
 | 
					        Self::configure(self.inner.regs(), config);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -221,28 +228,33 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
        while p.csr().read().ph_ret() {}
 | 
					        while p.csr().read().ph_ret() {}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Read PWM counter.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn counter(&self) -> u16 {
 | 
					    pub fn counter(&self) -> u16 {
 | 
				
			||||||
        self.inner.regs().ctr().read().ctr()
 | 
					        self.inner.regs().ctr().read().ctr()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Write PWM counter.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_counter(&self, ctr: u16) {
 | 
					    pub fn set_counter(&self, ctr: u16) {
 | 
				
			||||||
        self.inner.regs().ctr().write(|w| w.set_ctr(ctr))
 | 
					        self.inner.regs().ctr().write(|w| w.set_ctr(ctr))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Wait for channel interrupt.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn wait_for_wrap(&mut self) {
 | 
					    pub fn wait_for_wrap(&mut self) {
 | 
				
			||||||
        while !self.wrapped() {}
 | 
					        while !self.wrapped() {}
 | 
				
			||||||
        self.clear_wrapped();
 | 
					        self.clear_wrapped();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Check if interrupt for channel is set.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn wrapped(&mut self) -> bool {
 | 
					    pub fn wrapped(&mut self) -> bool {
 | 
				
			||||||
        pac::PWM.intr().read().0 & self.bit() != 0
 | 
					        pac::PWM.intr().read().0 & self.bit() != 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
 | 
					    /// Clear interrupt flag.
 | 
				
			||||||
    pub fn clear_wrapped(&mut self) {
 | 
					    pub fn clear_wrapped(&mut self) {
 | 
				
			||||||
        pac::PWM.intr().write_value(Intr(self.bit() as _));
 | 
					        pac::PWM.intr().write_value(Intr(self.bit() as _));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -253,15 +265,18 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Batch representation of PWM channels.
 | 
				
			||||||
pub struct PwmBatch(u32);
 | 
					pub struct PwmBatch(u32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl PwmBatch {
 | 
					impl PwmBatch {
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
 | 
					    /// Enable a PWM channel in this batch.
 | 
				
			||||||
    pub fn enable(&mut self, pwm: &Pwm<'_, impl Channel>) {
 | 
					    pub fn enable(&mut self, pwm: &Pwm<'_, impl Channel>) {
 | 
				
			||||||
        self.0 |= pwm.bit();
 | 
					        self.0 |= pwm.bit();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
 | 
					    /// Enable channels in this batch in a PWM.
 | 
				
			||||||
    pub fn set_enabled(enabled: bool, batch: impl FnOnce(&mut PwmBatch)) {
 | 
					    pub fn set_enabled(enabled: bool, batch: impl FnOnce(&mut PwmBatch)) {
 | 
				
			||||||
        let mut en = PwmBatch(0);
 | 
					        let mut en = PwmBatch(0);
 | 
				
			||||||
        batch(&mut en);
 | 
					        batch(&mut en);
 | 
				
			||||||
@@ -289,9 +304,12 @@ mod sealed {
 | 
				
			|||||||
    pub trait Channel {}
 | 
					    pub trait Channel {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// PWM Channel.
 | 
				
			||||||
pub trait Channel: Peripheral<P = Self> + sealed::Channel + Sized + 'static {
 | 
					pub trait Channel: Peripheral<P = Self> + sealed::Channel + Sized + 'static {
 | 
				
			||||||
 | 
					    /// Channel number.
 | 
				
			||||||
    fn number(&self) -> u8;
 | 
					    fn number(&self) -> u8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Channel register block.
 | 
				
			||||||
    fn regs(&self) -> pac::pwm::Channel {
 | 
					    fn regs(&self) -> pac::pwm::Channel {
 | 
				
			||||||
        pac::PWM.ch(self.number() as _)
 | 
					        pac::PWM.ch(self.number() as _)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -317,7 +335,9 @@ channel!(PWM_CH5, 5);
 | 
				
			|||||||
channel!(PWM_CH6, 6);
 | 
					channel!(PWM_CH6, 6);
 | 
				
			||||||
channel!(PWM_CH7, 7);
 | 
					channel!(PWM_CH7, 7);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// PWM Pin A.
 | 
				
			||||||
pub trait PwmPinA<T: Channel>: GpioPin {}
 | 
					pub trait PwmPinA<T: Channel>: GpioPin {}
 | 
				
			||||||
 | 
					/// PWM Pin B.
 | 
				
			||||||
pub trait PwmPinB<T: Channel>: GpioPin {}
 | 
					pub trait PwmPinB<T: Channel>: GpioPin {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! impl_pin {
 | 
					macro_rules! impl_pin {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! RTC driver.
 | 
				
			||||||
mod filter;
 | 
					mod filter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
 | 
					use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Timer driver.
 | 
				
			||||||
use core::cell::Cell;
 | 
					use core::cell::Cell;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use atomic_polyfill::{AtomicU8, Ordering};
 | 
					use atomic_polyfill::{AtomicU8, Ordering};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! Buffered UART driver.
 | 
				
			||||||
use core::future::{poll_fn, Future};
 | 
					use core::future::{poll_fn, Future};
 | 
				
			||||||
use core::slice;
 | 
					use core::slice;
 | 
				
			||||||
use core::task::Poll;
 | 
					use core::task::Poll;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! UART driver.
 | 
				
			||||||
use core::future::poll_fn;
 | 
					use core::future::poll_fn;
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
use core::task::Poll;
 | 
					use core::task::Poll;
 | 
				
			||||||
@@ -947,7 +948,7 @@ pub struct Async;
 | 
				
			|||||||
impl_mode!(Blocking);
 | 
					impl_mode!(Blocking);
 | 
				
			||||||
impl_mode!(Async);
 | 
					impl_mode!(Async);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// UART instance trait.
 | 
					/// UART instance.
 | 
				
			||||||
pub trait Instance: sealed::Instance {}
 | 
					pub trait Instance: sealed::Instance {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! impl_instance {
 | 
					macro_rules! impl_instance {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					//! USB driver.
 | 
				
			||||||
use core::future::poll_fn;
 | 
					use core::future::poll_fn;
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
use core::slice;
 | 
					use core::slice;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user