Merge pull request #1562 from embassy-rs/rp-pac-update
rp: update rp-pac.
This commit is contained in:
		
						commit
						0ac43d3e7c
					
				@ -76,7 +76,7 @@ embedded-storage = { version = "0.3" }
 | 
				
			|||||||
rand_core = "0.6.4"
 | 
					rand_core = "0.6.4"
 | 
				
			||||||
fixed = "1.23.1"
 | 
					fixed = "1.23.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rp-pac = { version = "4" }
 | 
					rp-pac = { version = "5" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
 | 
					embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
 | 
				
			||||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.10", optional = true}
 | 
					embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.10", optional = true}
 | 
				
			||||||
 | 
				
			|||||||
@ -50,7 +50,6 @@ impl<'d> Adc<'d> {
 | 
				
			|||||||
        _irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>,
 | 
					        _irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>,
 | 
				
			||||||
        _config: Config,
 | 
					        _config: Config,
 | 
				
			||||||
    ) -> Self {
 | 
					    ) -> Self {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let reset = Self::reset();
 | 
					        let reset = Self::reset();
 | 
				
			||||||
        crate::reset::reset(reset);
 | 
					        crate::reset::reset(reset);
 | 
				
			||||||
        crate::reset::unreset_wait(reset);
 | 
					        crate::reset::unreset_wait(reset);
 | 
				
			||||||
@ -59,7 +58,6 @@ impl<'d> Adc<'d> {
 | 
				
			|||||||
        r.cs().write(|w| w.set_en(true));
 | 
					        r.cs().write(|w| w.set_en(true));
 | 
				
			||||||
        // Wait for ADC ready
 | 
					        // Wait for ADC ready
 | 
				
			||||||
        while !r.cs().read().ready() {}
 | 
					        while !r.cs().read().ready() {}
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Setup IRQ
 | 
					        // Setup IRQ
 | 
				
			||||||
        interrupt::ADC_IRQ_FIFO.unpend();
 | 
					        interrupt::ADC_IRQ_FIFO.unpend();
 | 
				
			||||||
@ -70,7 +68,6 @@ impl<'d> Adc<'d> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async fn wait_for_ready() {
 | 
					    async fn wait_for_ready() {
 | 
				
			||||||
        let r = Self::regs();
 | 
					        let r = Self::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        r.inte().write(|w| w.set_fifo(true));
 | 
					        r.inte().write(|w| w.set_fifo(true));
 | 
				
			||||||
        compiler_fence(Ordering::SeqCst);
 | 
					        compiler_fence(Ordering::SeqCst);
 | 
				
			||||||
        poll_fn(|cx| {
 | 
					        poll_fn(|cx| {
 | 
				
			||||||
@ -82,11 +79,9 @@ impl<'d> Adc<'d> {
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
        .await;
 | 
					        .await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn read<PIN: Channel<Adc<'d>, ID = u8> + Pin>(&mut self, pin: &mut PIN) -> u16 {
 | 
					    pub async fn read<PIN: Channel<Adc<'d>, ID = u8> + Pin>(&mut self, pin: &mut PIN) -> u16 {
 | 
				
			||||||
        let r = Self::regs();
 | 
					        let r = Self::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        // disable pull-down and pull-up resistors
 | 
					        // disable pull-down and pull-up resistors
 | 
				
			||||||
        // pull-down resistors are enabled by default
 | 
					        // pull-down resistors are enabled by default
 | 
				
			||||||
        pin.pad_ctrl().modify(|w| {
 | 
					        pin.pad_ctrl().modify(|w| {
 | 
				
			||||||
@ -102,11 +97,9 @@ impl<'d> Adc<'d> {
 | 
				
			|||||||
        Self::wait_for_ready().await;
 | 
					        Self::wait_for_ready().await;
 | 
				
			||||||
        r.result().read().result().into()
 | 
					        r.result().read().result().into()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn read_temperature(&mut self) -> u16 {
 | 
					    pub async fn read_temperature(&mut self) -> u16 {
 | 
				
			||||||
        let r = Self::regs();
 | 
					        let r = Self::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        r.cs().modify(|w| w.set_ts_en(true));
 | 
					        r.cs().modify(|w| w.set_ts_en(true));
 | 
				
			||||||
        if !r.cs().read().ready() {
 | 
					        if !r.cs().read().ready() {
 | 
				
			||||||
            Self::wait_for_ready().await;
 | 
					            Self::wait_for_ready().await;
 | 
				
			||||||
@ -118,11 +111,9 @@ impl<'d> Adc<'d> {
 | 
				
			|||||||
        Self::wait_for_ready().await;
 | 
					        Self::wait_for_ready().await;
 | 
				
			||||||
        r.result().read().result().into()
 | 
					        r.result().read().result().into()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn blocking_read<PIN: Channel<Adc<'d>, ID = u8>>(&mut self, _pin: &mut PIN) -> u16 {
 | 
					    pub fn blocking_read<PIN: Channel<Adc<'d>, ID = u8>>(&mut self, _pin: &mut PIN) -> u16 {
 | 
				
			||||||
        let r = Self::regs();
 | 
					        let r = Self::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        r.cs().modify(|w| {
 | 
					        r.cs().modify(|w| {
 | 
				
			||||||
            w.set_ainsel(PIN::channel());
 | 
					            w.set_ainsel(PIN::channel());
 | 
				
			||||||
            w.set_start_once(true)
 | 
					            w.set_start_once(true)
 | 
				
			||||||
@ -130,11 +121,9 @@ impl<'d> Adc<'d> {
 | 
				
			|||||||
        while !r.cs().read().ready() {}
 | 
					        while !r.cs().read().ready() {}
 | 
				
			||||||
        r.result().read().result().into()
 | 
					        r.result().read().result().into()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn blocking_read_temperature(&mut self) -> u16 {
 | 
					    pub fn blocking_read_temperature(&mut self) -> u16 {
 | 
				
			||||||
        let r = Self::regs();
 | 
					        let r = Self::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        r.cs().modify(|w| w.set_ts_en(true));
 | 
					        r.cs().modify(|w| w.set_ts_en(true));
 | 
				
			||||||
        while !r.cs().read().ready() {}
 | 
					        while !r.cs().read().ready() {}
 | 
				
			||||||
        r.cs().modify(|w| {
 | 
					        r.cs().modify(|w| {
 | 
				
			||||||
@ -145,7 +134,6 @@ impl<'d> Adc<'d> {
 | 
				
			|||||||
        r.result().read().result().into()
 | 
					        r.result().read().result().into()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! impl_pin {
 | 
					macro_rules! impl_pin {
 | 
				
			||||||
    ($pin:ident, $channel:expr) => {
 | 
					    ($pin:ident, $channel:expr) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -542,7 +542,7 @@ pub(crate) unsafe fn init(config: ClockConfig) {
 | 
				
			|||||||
    reset::unreset_wait(peris);
 | 
					    reset::unreset_wait(peris);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsafe fn configure_rosc(config: RoscConfig) -> u32 {
 | 
					fn configure_rosc(config: RoscConfig) -> u32 {
 | 
				
			||||||
    let p = pac::ROSC;
 | 
					    let p = pac::ROSC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    p.freqa().write(|w| {
 | 
					    p.freqa().write(|w| {
 | 
				
			||||||
@ -620,7 +620,7 @@ pub fn clk_rtc_freq() -> u16 {
 | 
				
			|||||||
    CLOCKS.rtc.load(Ordering::Relaxed)
 | 
					    CLOCKS.rtc.load(Ordering::Relaxed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsafe fn start_xosc(crystal_hz: u32) {
 | 
					fn start_xosc(crystal_hz: u32) {
 | 
				
			||||||
    pac::XOSC
 | 
					    pac::XOSC
 | 
				
			||||||
        .ctrl()
 | 
					        .ctrl()
 | 
				
			||||||
        .write(|w| w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ));
 | 
					        .write(|w| w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ));
 | 
				
			||||||
@ -635,7 +635,7 @@ unsafe fn start_xosc(crystal_hz: u32) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[inline(always)]
 | 
					#[inline(always)]
 | 
				
			||||||
unsafe fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> u32 {
 | 
					fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> u32 {
 | 
				
			||||||
    let ref_freq = input_freq / config.refdiv as u32;
 | 
					    let ref_freq = input_freq / config.refdiv as u32;
 | 
				
			||||||
    assert!(config.fbdiv >= 16 && config.fbdiv <= 320);
 | 
					    assert!(config.fbdiv >= 16 && config.fbdiv <= 320);
 | 
				
			||||||
    assert!(config.post_div1 >= 1 && config.post_div1 <= 7);
 | 
					    assert!(config.post_div1 >= 1 && config.post_div1 <= 7);
 | 
				
			||||||
@ -700,9 +700,7 @@ impl<'d, T: Pin> Gpin<'d, T> {
 | 
				
			|||||||
    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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        gpin.io().ctrl().write(|w| w.set_funcsel(0x08));
 | 
					        gpin.io().ctrl().write(|w| w.set_funcsel(0x08));
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Gpin {
 | 
					        Gpin {
 | 
				
			||||||
            gpin: gpin.map_into(),
 | 
					            gpin: gpin.map_into(),
 | 
				
			||||||
@ -717,14 +715,12 @@ impl<'d, T: Pin> Gpin<'d, T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Pin> Drop for Gpin<'d, T> {
 | 
					impl<'d, T: Pin> Drop for Gpin<'d, T> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.gpin
 | 
					        self.gpin
 | 
				
			||||||
            .io()
 | 
					            .io()
 | 
				
			||||||
            .ctrl()
 | 
					            .ctrl()
 | 
				
			||||||
            .write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0));
 | 
					            .write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait GpoutPin: crate::gpio::Pin {
 | 
					pub trait GpoutPin: crate::gpio::Pin {
 | 
				
			||||||
    fn number(&self) -> usize;
 | 
					    fn number(&self) -> usize;
 | 
				
			||||||
@ -768,53 +764,43 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
 | 
				
			|||||||
    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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        gpout.io().ctrl().write(|w| w.set_funcsel(0x08));
 | 
					        gpout.io().ctrl().write(|w| w.set_funcsel(0x08));
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Self { gpout }
 | 
					        Self { gpout }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn set_div(&self, int: u32, frac: u8) {
 | 
					    pub fn set_div(&self, int: u32, frac: u8) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        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| {
 | 
				
			||||||
            w.set_int(int);
 | 
					            w.set_int(int);
 | 
				
			||||||
            w.set_frac(frac);
 | 
					            w.set_frac(frac);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn set_src(&self, src: GpoutSrc) {
 | 
					    pub fn set_src(&self, src: GpoutSrc) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        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| {
 | 
				
			||||||
            w.set_auxsrc(ClkGpoutCtrlAuxsrc(src as _));
 | 
					            w.set_auxsrc(ClkGpoutCtrlAuxsrc(src as _));
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn enable(&self) {
 | 
					    pub fn enable(&self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        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| {
 | 
				
			||||||
            w.set_enable(true);
 | 
					            w.set_enable(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn disable(&self) {
 | 
					    pub fn disable(&self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        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| {
 | 
				
			||||||
            w.set_enable(false);
 | 
					            w.set_enable(false);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn get_freq(&self) -> u32 {
 | 
					    pub fn get_freq(&self) -> u32 {
 | 
				
			||||||
        let c = pac::CLOCKS;
 | 
					        let c = pac::CLOCKS;
 | 
				
			||||||
        let src = unsafe { c.clk_gpout_ctrl(self.gpout.number()).read().auxsrc() };
 | 
					        let src = c.clk_gpout_ctrl(self.gpout.number()).read().auxsrc();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let base = match src {
 | 
					        let base = match src {
 | 
				
			||||||
            ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(),
 | 
					            ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(),
 | 
				
			||||||
@ -831,7 +817,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
 | 
				
			|||||||
            _ => unreachable!(),
 | 
					            _ => unreachable!(),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let div = unsafe { c.clk_gpout_div(self.gpout.number()).read() };
 | 
					        let div = c.clk_gpout_div(self.gpout.number()).read();
 | 
				
			||||||
        let int = if div.int() == 0 { 65536 } else { div.int() } as u64;
 | 
					        let int = if div.int() == 0 { 65536 } else { div.int() } as u64;
 | 
				
			||||||
        let frac = div.frac() as u64;
 | 
					        let frac = div.frac() as u64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -842,14 +828,12 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
 | 
				
			|||||||
impl<'d, T: GpoutPin> Drop for Gpout<'d, T> {
 | 
					impl<'d, T: GpoutPin> Drop for Gpout<'d, T> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        self.disable();
 | 
					        self.disable();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.gpout
 | 
					        self.gpout
 | 
				
			||||||
            .io()
 | 
					            .io()
 | 
				
			||||||
            .ctrl()
 | 
					            .ctrl()
 | 
				
			||||||
            .write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0));
 | 
					            .write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Random number generator based on the ROSC RANDOMBIT register.
 | 
					/// Random number generator based on the ROSC RANDOMBIT register.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
@ -864,7 +848,7 @@ impl RoscRng {
 | 
				
			|||||||
        let mut acc = 0;
 | 
					        let mut acc = 0;
 | 
				
			||||||
        for _ in 0..u8::BITS {
 | 
					        for _ in 0..u8::BITS {
 | 
				
			||||||
            acc <<= 1;
 | 
					            acc <<= 1;
 | 
				
			||||||
            acc |= unsafe { random_reg.read().randombit() as u8 };
 | 
					            acc |= random_reg.read().randombit() as u8;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        acc
 | 
					        acc
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -103,8 +103,6 @@ where
 | 
				
			|||||||
    /// Try to claim the spinlock. Will return `Some(Self)` if the lock is obtained, and `None` if the lock is
 | 
					    /// Try to claim the spinlock. Will return `Some(Self)` if the lock is obtained, and `None` if the lock is
 | 
				
			||||||
    /// already in use somewhere else.
 | 
					    /// already in use somewhere else.
 | 
				
			||||||
    pub fn try_claim() -> Option<Self> {
 | 
					    pub fn try_claim() -> Option<Self> {
 | 
				
			||||||
        // Safety: We're only reading from this register
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let lock = pac::SIO.spinlock(N).read();
 | 
					        let lock = pac::SIO.spinlock(N).read();
 | 
				
			||||||
        if lock > 0 {
 | 
					        if lock > 0 {
 | 
				
			||||||
            Some(Self(core::marker::PhantomData))
 | 
					            Some(Self(core::marker::PhantomData))
 | 
				
			||||||
@ -112,7 +110,6 @@ where
 | 
				
			|||||||
            None
 | 
					            None
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Clear a locked spin-lock.
 | 
					    /// Clear a locked spin-lock.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
@ -120,12 +117,10 @@ where
 | 
				
			|||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// Only call this function if you hold the spin-lock.
 | 
					    /// Only call this function if you hold the spin-lock.
 | 
				
			||||||
    pub unsafe fn release() {
 | 
					    pub unsafe fn release() {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        // Write (any value): release the lock
 | 
					        // Write (any value): release the lock
 | 
				
			||||||
        pac::SIO.spinlock(N).write_value(1);
 | 
					        pac::SIO.spinlock(N).write_value(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<const N: usize> Drop for Spinlock<N>
 | 
					impl<const N: usize> Drop for Spinlock<N>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,7 @@ use crate::{interrupt, pac, peripherals};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "rt")]
 | 
					#[cfg(feature = "rt")]
 | 
				
			||||||
#[interrupt]
 | 
					#[interrupt]
 | 
				
			||||||
unsafe fn DMA_IRQ_0() {
 | 
					fn DMA_IRQ_0() {
 | 
				
			||||||
    let ints0 = pac::DMA.ints0().read().ints0();
 | 
					    let ints0 = pac::DMA.ints0().read().ints0();
 | 
				
			||||||
    for channel in 0..CHANNEL_COUNT {
 | 
					    for channel in 0..CHANNEL_COUNT {
 | 
				
			||||||
        let ctrl_trig = pac::DMA.ch(channel).ctrl_trig().read();
 | 
					        let ctrl_trig = pac::DMA.ch(channel).ctrl_trig().read();
 | 
				
			||||||
@ -128,7 +128,6 @@ fn copy_inner<'a, C: Channel>(
 | 
				
			|||||||
) -> Transfer<'a, C> {
 | 
					) -> Transfer<'a, C> {
 | 
				
			||||||
    into_ref!(ch);
 | 
					    into_ref!(ch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
    let p = ch.regs();
 | 
					    let p = ch.regs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    p.read_addr().write_value(from as u32);
 | 
					    p.read_addr().write_value(from as u32);
 | 
				
			||||||
@ -149,7 +148,6 @@ fn copy_inner<'a, C: Channel>(
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    compiler_fence(Ordering::SeqCst);
 | 
					    compiler_fence(Ordering::SeqCst);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Transfer::new(ch)
 | 
					    Transfer::new(ch)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -169,14 +167,12 @@ impl<'a, C: Channel> Transfer<'a, C> {
 | 
				
			|||||||
impl<'a, C: Channel> Drop for Transfer<'a, C> {
 | 
					impl<'a, C: Channel> Drop for Transfer<'a, C> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        let p = self.channel.regs();
 | 
					        let p = self.channel.regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        pac::DMA
 | 
					        pac::DMA
 | 
				
			||||||
            .chan_abort()
 | 
					            .chan_abort()
 | 
				
			||||||
            .modify(|m| m.set_chan_abort(1 << self.channel.number()));
 | 
					            .modify(|m| m.set_chan_abort(1 << self.channel.number()));
 | 
				
			||||||
        while p.ctrl_trig().read().busy() {}
 | 
					        while p.ctrl_trig().read().busy() {}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a, C: Channel> Unpin for Transfer<'a, C> {}
 | 
					impl<'a, C: Channel> Unpin for Transfer<'a, C> {}
 | 
				
			||||||
impl<'a, C: Channel> Future for Transfer<'a, C> {
 | 
					impl<'a, C: Channel> Future for Transfer<'a, C> {
 | 
				
			||||||
@ -186,7 +182,7 @@ impl<'a, C: Channel> Future for Transfer<'a, C> {
 | 
				
			|||||||
        // calls to wake will deregister the waker.
 | 
					        // calls to wake will deregister the waker.
 | 
				
			||||||
        CHANNEL_WAKERS[self.channel.number() as usize].register(cx.waker());
 | 
					        CHANNEL_WAKERS[self.channel.number() as usize].register(cx.waker());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if unsafe { self.channel.regs().ctrl_trig().read().busy() } {
 | 
					        if self.channel.regs().ctrl_trig().read().busy() {
 | 
				
			||||||
            Poll::Pending
 | 
					            Poll::Pending
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            Poll::Ready(())
 | 
					            Poll::Ready(())
 | 
				
			||||||
 | 
				
			|||||||
@ -167,7 +167,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
 | 
				
			|||||||
    /// - DMA must not access flash memory
 | 
					    /// - DMA must not access flash memory
 | 
				
			||||||
    unsafe fn in_ram(&mut self, operation: impl FnOnce()) -> Result<(), Error> {
 | 
					    unsafe fn in_ram(&mut self, operation: impl FnOnce()) -> Result<(), Error> {
 | 
				
			||||||
        // Make sure we're running on CORE0
 | 
					        // Make sure we're running on CORE0
 | 
				
			||||||
        let core_id: u32 = unsafe { pac::SIO.cpuid().read() };
 | 
					        let core_id: u32 = pac::SIO.cpuid().read();
 | 
				
			||||||
        if core_id != 0 {
 | 
					        if core_id != 0 {
 | 
				
			||||||
            return Err(Error::InvalidCore);
 | 
					            return Err(Error::InvalidCore);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -17,7 +17,6 @@ where
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    let sio = rp_pac::SIO;
 | 
					    let sio = rp_pac::SIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
    // Since we can't save the signed-ness of the calculation, we have to make
 | 
					    // Since we can't save the signed-ness of the calculation, we have to make
 | 
				
			||||||
    // sure that there's at least an 8 cycle delay before we read the result.
 | 
					    // sure that there's at least an 8 cycle delay before we read the result.
 | 
				
			||||||
    // The Pico SDK ensures this by using a 6 cycle push and two 1 cycle reads.
 | 
					    // The Pico SDK ensures this by using a 6 cycle push and two 1 cycle reads.
 | 
				
			||||||
@ -56,14 +55,13 @@ where
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    result
 | 
					    result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn save_divider<F, R>(f: F) -> R
 | 
					fn save_divider<F, R>(f: F) -> R
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    F: FnOnce() -> R,
 | 
					    F: FnOnce() -> R,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    let sio = rp_pac::SIO;
 | 
					    let sio = rp_pac::SIO;
 | 
				
			||||||
    if unsafe { !sio.div().csr().read().dirty() } {
 | 
					    if !sio.div().csr().read().dirty() {
 | 
				
			||||||
        // Not dirty, so nothing is waiting for the calculation.  So we can just
 | 
					        // Not dirty, so nothing is waiting for the calculation.  So we can just
 | 
				
			||||||
        // issue it directly without a save/restore.
 | 
					        // issue it directly without a save/restore.
 | 
				
			||||||
        f()
 | 
					        f()
 | 
				
			||||||
 | 
				
			|||||||
@ -144,7 +144,7 @@ pub(crate) unsafe fn init() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "rt")]
 | 
					#[cfg(feature = "rt")]
 | 
				
			||||||
#[interrupt]
 | 
					#[interrupt]
 | 
				
			||||||
unsafe fn IO_IRQ_BANK0() {
 | 
					fn IO_IRQ_BANK0() {
 | 
				
			||||||
    let cpu = SIO.cpuid().read() as usize;
 | 
					    let cpu = SIO.cpuid().read() as usize;
 | 
				
			||||||
    // There are two sets of interrupt registers, one for cpu0 and one for cpu1
 | 
					    // There are two sets of interrupt registers, one for cpu0 and one for cpu1
 | 
				
			||||||
    // and here we are selecting the set that belongs to the currently executing
 | 
					    // and here we are selecting the set that belongs to the currently executing
 | 
				
			||||||
@ -185,7 +185,6 @@ struct InputFuture<'a, T: Pin> {
 | 
				
			|||||||
impl<'d, T: Pin> InputFuture<'d, T> {
 | 
					impl<'d, T: Pin> InputFuture<'d, T> {
 | 
				
			||||||
    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);
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let pin_group = (pin.pin() % 8) as usize;
 | 
					        let pin_group = (pin.pin() % 8) as usize;
 | 
				
			||||||
        // first, clear the INTR register bits. without this INTR will still
 | 
					        // first, clear the INTR register bits. without this INTR will still
 | 
				
			||||||
        // contain reports of previous edges, causing the IRQ to fire early
 | 
					        // contain reports of previous edges, causing the IRQ to fire early
 | 
				
			||||||
@ -224,7 +223,6 @@ impl<'d, T: Pin> InputFuture<'d, T> {
 | 
				
			|||||||
                    w.set_edge_low(pin_group, true);
 | 
					                    w.set_edge_low(pin_group, true);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Self { pin, level }
 | 
					        Self { pin, level }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -242,7 +240,7 @@ impl<'d, T: Pin> Future for InputFuture<'d, T> {
 | 
				
			|||||||
        // then we want to access the interrupt enable register for our
 | 
					        // then we want to access the interrupt enable register for our
 | 
				
			||||||
        // pin (there are 4 of these PROC0_INTE0, PROC0_INTE1, PROC0_INTE2, and
 | 
					        // pin (there are 4 of these PROC0_INTE0, PROC0_INTE1, PROC0_INTE2, and
 | 
				
			||||||
        // PROC0_INTE3 per cpu).
 | 
					        // PROC0_INTE3 per cpu).
 | 
				
			||||||
        let inte: pac::io::regs::Int = unsafe { self.pin.int_proc().inte((self.pin.pin() / 8) as usize).read() };
 | 
					        let inte: pac::io::regs::Int = self.pin.int_proc().inte((self.pin.pin() / 8) as usize).read();
 | 
				
			||||||
        // The register is divided into groups of four, one group for
 | 
					        // The register is divided into groups of four, one group for
 | 
				
			||||||
        // each pin. Each group consists of four trigger levels LEVEL_LOW,
 | 
					        // each pin. Each group consists of four trigger levels LEVEL_LOW,
 | 
				
			||||||
        // LEVEL_HIGH, EDGE_LOW, and EDGE_HIGH for each pin.
 | 
					        // LEVEL_HIGH, EDGE_LOW, and EDGE_HIGH for each pin.
 | 
				
			||||||
@ -449,7 +447,6 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
    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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        pin.pad_ctrl().write(|w| {
 | 
					        pin.pad_ctrl().write(|w| {
 | 
				
			||||||
            w.set_ie(true);
 | 
					            w.set_ie(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
@ -457,7 +454,6 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
        pin.io().ctrl().write(|w| {
 | 
					        pin.io().ctrl().write(|w| {
 | 
				
			||||||
            w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::SIO_0.0);
 | 
					            w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::SIO_0.0);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Self { pin }
 | 
					        Self { pin }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -470,7 +466,6 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
    /// Set the pin's pull.
 | 
					    /// Set the pin's pull.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_pull(&mut self, pull: Pull) {
 | 
					    pub fn set_pull(&mut self, pull: Pull) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.pin.pad_ctrl().modify(|w| {
 | 
					        self.pin.pad_ctrl().modify(|w| {
 | 
				
			||||||
            w.set_ie(true);
 | 
					            w.set_ie(true);
 | 
				
			||||||
            let (pu, pd) = match pull {
 | 
					            let (pu, pd) = match pull {
 | 
				
			||||||
@ -482,12 +477,10 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
            w.set_pde(pd);
 | 
					            w.set_pde(pd);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Set the pin's drive strength.
 | 
					    /// Set the pin's drive strength.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_drive_strength(&mut self, strength: Drive) {
 | 
					    pub fn set_drive_strength(&mut self, strength: Drive) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.pin.pad_ctrl().modify(|w| {
 | 
					        self.pin.pad_ctrl().modify(|w| {
 | 
				
			||||||
            w.set_drive(match strength {
 | 
					            w.set_drive(match strength {
 | 
				
			||||||
                Drive::_2mA => pac::pads::vals::Drive::_2MA,
 | 
					                Drive::_2mA => pac::pads::vals::Drive::_2MA,
 | 
				
			||||||
@ -497,24 +490,21 @@ 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) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.pin.pad_ctrl().modify(|w| {
 | 
					        self.pin.pad_ctrl().modify(|w| {
 | 
				
			||||||
            w.set_slewfast(slew_rate == SlewRate::Fast);
 | 
					            w.set_slewfast(slew_rate == SlewRate::Fast);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Put the pin into input mode.
 | 
					    /// Put the pin into input mode.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// The pull setting is left unchanged.
 | 
					    /// The pull setting is left unchanged.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_as_input(&mut self) {
 | 
					    pub fn set_as_input(&mut self) {
 | 
				
			||||||
        unsafe { self.pin.sio_oe().value_clr().write_value(self.bit()) }
 | 
					        self.pin.sio_oe().value_clr().write_value(self.bit())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Put the pin into output mode.
 | 
					    /// Put the pin into output mode.
 | 
				
			||||||
@ -523,17 +513,17 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
    /// at a specific level, call `set_high`/`set_low` on the pin first.
 | 
					    /// at a specific level, call `set_high`/`set_low` on the pin first.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_as_output(&mut self) {
 | 
					    pub fn set_as_output(&mut self) {
 | 
				
			||||||
        unsafe { self.pin.sio_oe().value_set().write_value(self.bit()) }
 | 
					        self.pin.sio_oe().value_set().write_value(self.bit())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    fn is_set_as_output(&self) -> bool {
 | 
					    fn is_set_as_output(&self) -> bool {
 | 
				
			||||||
        unsafe { (self.pin.sio_oe().value().read() & self.bit()) != 0 }
 | 
					        (self.pin.sio_oe().value().read() & self.bit()) != 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn toggle_set_as_output(&mut self) {
 | 
					    pub fn toggle_set_as_output(&mut self) {
 | 
				
			||||||
        unsafe { self.pin.sio_oe().value_xor().write_value(self.bit()) }
 | 
					        self.pin.sio_oe().value_xor().write_value(self.bit())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
@ -543,7 +533,7 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn is_low(&self) -> bool {
 | 
					    pub fn is_low(&self) -> bool {
 | 
				
			||||||
        unsafe { self.pin.sio_in().read() & self.bit() == 0 }
 | 
					        self.pin.sio_in().read() & self.bit() == 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Returns current pin level
 | 
					    /// Returns current pin level
 | 
				
			||||||
@ -555,13 +545,13 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
    /// Set the output as high.
 | 
					    /// Set the output as high.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_high(&mut self) {
 | 
					    pub fn set_high(&mut self) {
 | 
				
			||||||
        unsafe { self.pin.sio_out().value_set().write_value(self.bit()) }
 | 
					        self.pin.sio_out().value_set().write_value(self.bit())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Set the output as low.
 | 
					    /// Set the output as low.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_low(&mut self) {
 | 
					    pub fn set_low(&mut self) {
 | 
				
			||||||
        unsafe { self.pin.sio_out().value_clr().write_value(self.bit()) }
 | 
					        self.pin.sio_out().value_clr().write_value(self.bit())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Set the output level.
 | 
					    /// Set the output level.
 | 
				
			||||||
@ -576,7 +566,7 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
    /// Is the output level high?
 | 
					    /// Is the output level high?
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn is_set_high(&self) -> bool {
 | 
					    pub fn is_set_high(&self) -> bool {
 | 
				
			||||||
        unsafe { (self.pin.sio_out().value().read() & self.bit()) == 0 }
 | 
					        (self.pin.sio_out().value().read() & self.bit()) == 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Is the output level low?
 | 
					    /// Is the output level low?
 | 
				
			||||||
@ -594,7 +584,7 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
    /// Toggle pin output
 | 
					    /// Toggle pin output
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn toggle(&mut self) {
 | 
					    pub fn toggle(&mut self) {
 | 
				
			||||||
        unsafe { self.pin.sio_out().value_xor().write_value(self.bit()) }
 | 
					        self.pin.sio_out().value_xor().write_value(self.bit())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
@ -626,14 +616,12 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
impl<'d, T: Pin> Drop for Flex<'d, T> {
 | 
					impl<'d, T: Pin> Drop for Flex<'d, T> {
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.pin.pad_ctrl().write(|_| {});
 | 
					        self.pin.pad_ctrl().write(|_| {});
 | 
				
			||||||
        self.pin.io().ctrl().write(|w| {
 | 
					        self.pin.io().ctrl().write(|w| {
 | 
				
			||||||
            w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0);
 | 
					            w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) mod sealed {
 | 
					pub(crate) mod sealed {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
@ -688,7 +676,7 @@ pub(crate) mod sealed {
 | 
				
			|||||||
                Bank::Bank0 => crate::pac::IO_BANK0,
 | 
					                Bank::Bank0 => crate::pac::IO_BANK0,
 | 
				
			||||||
                Bank::Qspi => crate::pac::IO_QSPI,
 | 
					                Bank::Qspi => crate::pac::IO_QSPI,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            let proc = unsafe { SIO.cpuid().read() };
 | 
					            let proc = SIO.cpuid().read();
 | 
				
			||||||
            io_block.int_proc(proc as _)
 | 
					            io_block.int_proc(proc as _)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -85,7 +85,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
        let r = T::regs();
 | 
					        let r = T::regs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // mask everything initially
 | 
					        // mask everything initially
 | 
				
			||||||
        unsafe { r.ic_intr_mask().write_value(i2c::regs::IcIntrMask(0)) }
 | 
					        r.ic_intr_mask().write_value(i2c::regs::IcIntrMask(0));
 | 
				
			||||||
        T::Interrupt::unpend();
 | 
					        T::Interrupt::unpend();
 | 
				
			||||||
        unsafe { T::Interrupt::enable() };
 | 
					        unsafe { T::Interrupt::enable() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -135,14 +135,12 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
                let last = remaining_queue == 0;
 | 
					                let last = remaining_queue == 0;
 | 
				
			||||||
                batch += 1;
 | 
					                batch += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                unsafe {
 | 
					 | 
				
			||||||
                p.ic_data_cmd().write(|w| {
 | 
					                p.ic_data_cmd().write(|w| {
 | 
				
			||||||
                    w.set_restart(restart && remaining_queue == buffer.len() - 1);
 | 
					                    w.set_restart(restart && remaining_queue == buffer.len() - 1);
 | 
				
			||||||
                    w.set_stop(last && send_stop);
 | 
					                    w.set_stop(last && send_stop);
 | 
				
			||||||
                    w.set_cmd(true);
 | 
					                    w.set_cmd(true);
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // We've either run out of txfifo or just plain finished setting up
 | 
					            // We've either run out of txfifo or just plain finished setting up
 | 
				
			||||||
            // the clocks for the message - either way we need to wait for rx
 | 
					            // the clocks for the message - either way we need to wait for rx
 | 
				
			||||||
@ -161,7 +159,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
                            Poll::Pending
 | 
					                            Poll::Pending
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    |_me| unsafe {
 | 
					                    |_me| {
 | 
				
			||||||
                        // Set the read threshold to the number of bytes we're
 | 
					                        // Set the read threshold to the number of bytes we're
 | 
				
			||||||
                        // expecting so we don't get spurious interrupts.
 | 
					                        // expecting so we don't get spurious interrupts.
 | 
				
			||||||
                        p.ic_rx_tl().write(|w| w.set_rx_tl(batch - 1));
 | 
					                        p.ic_rx_tl().write(|w| w.set_rx_tl(batch - 1));
 | 
				
			||||||
@ -185,7 +183,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
                    let rxbytes = (rxfifo as usize).min(remaining);
 | 
					                    let rxbytes = (rxfifo as usize).min(remaining);
 | 
				
			||||||
                    let received = buffer.len() - remaining;
 | 
					                    let received = buffer.len() - remaining;
 | 
				
			||||||
                    for b in &mut buffer[received..received + rxbytes] {
 | 
					                    for b in &mut buffer[received..received + rxbytes] {
 | 
				
			||||||
                        *b = unsafe { p.ic_data_cmd().read().dat() };
 | 
					                        *b = p.ic_data_cmd().read().dat();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    remaining -= rxbytes;
 | 
					                    remaining -= rxbytes;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -211,13 +209,11 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
                if let Some(byte) = bytes.next() {
 | 
					                if let Some(byte) = bytes.next() {
 | 
				
			||||||
                    let last = bytes.peek().is_none();
 | 
					                    let last = bytes.peek().is_none();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    unsafe {
 | 
					 | 
				
			||||||
                    p.ic_data_cmd().write(|w| {
 | 
					                    p.ic_data_cmd().write(|w| {
 | 
				
			||||||
                        w.set_stop(last && send_stop);
 | 
					                        w.set_stop(last && send_stop);
 | 
				
			||||||
                        w.set_cmd(false);
 | 
					                        w.set_cmd(false);
 | 
				
			||||||
                        w.set_dat(byte);
 | 
					                        w.set_dat(byte);
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    break 'xmit Ok(());
 | 
					                    break 'xmit Ok(());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -235,7 +231,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
                            Poll::Pending
 | 
					                            Poll::Pending
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    |_me| unsafe {
 | 
					                    |_me| {
 | 
				
			||||||
                        // Set tx "free" threshold a little high so that we get
 | 
					                        // Set tx "free" threshold a little high so that we get
 | 
				
			||||||
                        // woken before the fifo completely drains to minimize
 | 
					                        // woken before the fifo completely drains to minimize
 | 
				
			||||||
                        // transfer stalls.
 | 
					                        // transfer stalls.
 | 
				
			||||||
@ -267,7 +263,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            let had_abort2 = self
 | 
					            let had_abort2 = self
 | 
				
			||||||
                .wait_on(
 | 
					                .wait_on(
 | 
				
			||||||
                    |me| unsafe {
 | 
					                    |me| {
 | 
				
			||||||
                        // We could see an abort while processing fifo backlog,
 | 
					                        // We could see an abort while processing fifo backlog,
 | 
				
			||||||
                        // so handle it here.
 | 
					                        // so handle it here.
 | 
				
			||||||
                        let abort = me.read_and_clear_abort_reason();
 | 
					                        let abort = me.read_and_clear_abort_reason();
 | 
				
			||||||
@ -279,7 +275,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
                            Poll::Pending
 | 
					                            Poll::Pending
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    |_me| unsafe {
 | 
					                    |_me| {
 | 
				
			||||||
                        p.ic_intr_mask().modify(|w| {
 | 
					                        p.ic_intr_mask().modify(|w| {
 | 
				
			||||||
                            w.set_m_stop_det(true);
 | 
					                            w.set_m_stop_det(true);
 | 
				
			||||||
                            w.set_m_tx_abrt(true);
 | 
					                            w.set_m_tx_abrt(true);
 | 
				
			||||||
@ -287,9 +283,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
 | 
				
			|||||||
                    },
 | 
					                    },
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                .await;
 | 
					                .await;
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            p.ic_clr_stop_det().read();
 | 
					            p.ic_clr_stop_det().read();
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            had_abort.and(had_abort2)
 | 
					            had_abort.and(had_abort2)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@ -336,7 +330,6 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let p = T::regs();
 | 
					        let p = T::regs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let reset = T::reset();
 | 
					        let reset = T::reset();
 | 
				
			||||||
        crate::reset::reset(reset);
 | 
					        crate::reset::reset(reset);
 | 
				
			||||||
        crate::reset::unreset_wait(reset);
 | 
					        crate::reset::unreset_wait(reset);
 | 
				
			||||||
@ -424,7 +417,6 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Enable I2C block
 | 
					        // Enable I2C block
 | 
				
			||||||
        p.ic_enable().write(|w| w.set_enable(true));
 | 
					        p.ic_enable().write(|w| w.set_enable(true));
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Self { phantom: PhantomData }
 | 
					        Self { phantom: PhantomData }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -439,11 +431,9 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let p = T::regs();
 | 
					        let p = T::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        p.ic_enable().write(|w| w.set_enable(false));
 | 
					        p.ic_enable().write(|w| w.set_enable(false));
 | 
				
			||||||
        p.ic_tar().write(|w| w.set_ic_tar(addr));
 | 
					        p.ic_tar().write(|w| w.set_ic_tar(addr));
 | 
				
			||||||
        p.ic_enable().write(|w| w.set_enable(true));
 | 
					        p.ic_enable().write(|w| w.set_enable(true));
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -455,18 +445,17 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
 | 
				
			|||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    fn tx_fifo_capacity() -> u8 {
 | 
					    fn tx_fifo_capacity() -> u8 {
 | 
				
			||||||
        let p = T::regs();
 | 
					        let p = T::regs();
 | 
				
			||||||
        unsafe { FIFO_SIZE - p.ic_txflr().read().txflr() }
 | 
					        FIFO_SIZE - p.ic_txflr().read().txflr()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    fn rx_fifo_len() -> u8 {
 | 
					    fn rx_fifo_len() -> u8 {
 | 
				
			||||||
        let p = T::regs();
 | 
					        let p = T::regs();
 | 
				
			||||||
        unsafe { p.ic_rxflr().read().rxflr() }
 | 
					        p.ic_rxflr().read().rxflr()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn read_and_clear_abort_reason(&mut self) -> Result<(), Error> {
 | 
					    fn read_and_clear_abort_reason(&mut self) -> Result<(), Error> {
 | 
				
			||||||
        let p = T::regs();
 | 
					        let p = T::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let abort_reason = p.ic_tx_abrt_source().read();
 | 
					        let abort_reason = p.ic_tx_abrt_source().read();
 | 
				
			||||||
        if abort_reason.0 != 0 {
 | 
					        if abort_reason.0 != 0 {
 | 
				
			||||||
            // Note clearing the abort flag also clears the reason, and this
 | 
					            // Note clearing the abort flag also clears the reason, and this
 | 
				
			||||||
@ -490,7 +479,6 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
 | 
				
			|||||||
            Ok(())
 | 
					            Ok(())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn read_blocking_internal(&mut self, read: &mut [u8], restart: bool, send_stop: bool) -> Result<(), Error> {
 | 
					    fn read_blocking_internal(&mut self, read: &mut [u8], restart: bool, send_stop: bool) -> Result<(), Error> {
 | 
				
			||||||
        if read.is_empty() {
 | 
					        if read.is_empty() {
 | 
				
			||||||
@ -503,8 +491,6 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
 | 
				
			|||||||
            let first = i == 0;
 | 
					            let first = i == 0;
 | 
				
			||||||
            let last = i == lastindex;
 | 
					            let last = i == lastindex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // NOTE(unsafe) We have &mut self
 | 
					 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            // wait until there is space in the FIFO to write the next byte
 | 
					            // wait until there is space in the FIFO to write the next byte
 | 
				
			||||||
            while Self::tx_fifo_full() {}
 | 
					            while Self::tx_fifo_full() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -521,7 +507,6 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            *byte = p.ic_data_cmd().read().dat();
 | 
					            *byte = p.ic_data_cmd().read().dat();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -536,8 +521,6 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
 | 
				
			|||||||
        for (i, byte) in write.iter().enumerate() {
 | 
					        for (i, byte) in write.iter().enumerate() {
 | 
				
			||||||
            let last = i == write.len() - 1;
 | 
					            let last = i == write.len() - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // NOTE(unsafe) We have &mut self
 | 
					 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            p.ic_data_cmd().write(|w| {
 | 
					            p.ic_data_cmd().write(|w| {
 | 
				
			||||||
                w.set_stop(send_stop && last);
 | 
					                w.set_stop(send_stop && last);
 | 
				
			||||||
                w.set_dat(*byte);
 | 
					                w.set_dat(*byte);
 | 
				
			||||||
@ -566,7 +549,6 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
 | 
				
			|||||||
            // IC_AVOID_RX_FIFO_FLUSH_ON_TX_ABRT to 0.
 | 
					            // IC_AVOID_RX_FIFO_FLUSH_ON_TX_ABRT to 0.
 | 
				
			||||||
            abort_reason?;
 | 
					            abort_reason?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -261,33 +261,39 @@ pub fn init(config: config::Config) -> Peripherals {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes.
 | 
					/// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes.
 | 
				
			||||||
trait RegExt<T: Copy> {
 | 
					trait RegExt<T: Copy> {
 | 
				
			||||||
    unsafe fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
 | 
					    fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
 | 
				
			||||||
    unsafe fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
 | 
					    fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
 | 
				
			||||||
    unsafe fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
 | 
					    fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T: Default + Copy, A: pac::common::Write> RegExt<T> for pac::common::Reg<T, A> {
 | 
					impl<T: Default + Copy, A: pac::common::Write> RegExt<T> for pac::common::Reg<T, A> {
 | 
				
			||||||
    unsafe fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
 | 
					    fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
 | 
				
			||||||
        let mut val = Default::default();
 | 
					        let mut val = Default::default();
 | 
				
			||||||
        let res = f(&mut val);
 | 
					        let res = f(&mut val);
 | 
				
			||||||
        let ptr = (self.ptr() as *mut u8).add(0x1000) as *mut T;
 | 
					        unsafe {
 | 
				
			||||||
 | 
					            let ptr = (self.as_ptr() as *mut u8).add(0x1000) as *mut T;
 | 
				
			||||||
            ptr.write_volatile(val);
 | 
					            ptr.write_volatile(val);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        res
 | 
					        res
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
 | 
					    fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
 | 
				
			||||||
        let mut val = Default::default();
 | 
					        let mut val = Default::default();
 | 
				
			||||||
        let res = f(&mut val);
 | 
					        let res = f(&mut val);
 | 
				
			||||||
        let ptr = (self.ptr() as *mut u8).add(0x2000) as *mut T;
 | 
					        unsafe {
 | 
				
			||||||
 | 
					            let ptr = (self.as_ptr() as *mut u8).add(0x2000) as *mut T;
 | 
				
			||||||
            ptr.write_volatile(val);
 | 
					            ptr.write_volatile(val);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        res
 | 
					        res
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
 | 
					    fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
 | 
				
			||||||
        let mut val = Default::default();
 | 
					        let mut val = Default::default();
 | 
				
			||||||
        let res = f(&mut val);
 | 
					        let res = f(&mut val);
 | 
				
			||||||
        let ptr = (self.ptr() as *mut u8).add(0x3000) as *mut T;
 | 
					        unsafe {
 | 
				
			||||||
 | 
					            let ptr = (self.as_ptr() as *mut u8).add(0x3000) as *mut T;
 | 
				
			||||||
            ptr.write_volatile(val);
 | 
					            ptr.write_volatile(val);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        res
 | 
					        res
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -163,14 +163,12 @@ where
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Reset the core
 | 
					    // Reset the core
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
    let psm = pac::PSM;
 | 
					    let psm = pac::PSM;
 | 
				
			||||||
    psm.frce_off().modify(|w| w.set_proc1(true));
 | 
					    psm.frce_off().modify(|w| w.set_proc1(true));
 | 
				
			||||||
    while !psm.frce_off().read().proc1() {
 | 
					    while !psm.frce_off().read().proc1() {
 | 
				
			||||||
        cortex_m::asm::nop();
 | 
					        cortex_m::asm::nop();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    psm.frce_off().modify(|w| w.set_proc1(false));
 | 
					    psm.frce_off().modify(|w| w.set_proc1(false));
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The ARM AAPCS ABI requires 8-byte stack alignment.
 | 
					    // The ARM AAPCS ABI requires 8-byte stack alignment.
 | 
				
			||||||
    // #[align] on `struct Stack` ensures the bottom is aligned, but the top could still be
 | 
					    // #[align] on `struct Stack` ensures the bottom is aligned, but the top could still be
 | 
				
			||||||
@ -270,14 +268,12 @@ pub fn resume_core1() {
 | 
				
			|||||||
// Push a value to the inter-core FIFO, block until space is available
 | 
					// Push a value to the inter-core FIFO, block until space is available
 | 
				
			||||||
#[inline(always)]
 | 
					#[inline(always)]
 | 
				
			||||||
fn fifo_write(value: u32) {
 | 
					fn fifo_write(value: u32) {
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
    let sio = pac::SIO;
 | 
					    let sio = pac::SIO;
 | 
				
			||||||
    // Wait for the FIFO to have enough space
 | 
					    // Wait for the FIFO to have enough space
 | 
				
			||||||
    while !sio.fifo().st().read().rdy() {
 | 
					    while !sio.fifo().st().read().rdy() {
 | 
				
			||||||
        cortex_m::asm::nop();
 | 
					        cortex_m::asm::nop();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    sio.fifo().wr().write_value(value);
 | 
					    sio.fifo().wr().write_value(value);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // Fire off an event to the other core.
 | 
					    // Fire off an event to the other core.
 | 
				
			||||||
    // This is required as the other core may be `wfe` (waiting for event)
 | 
					    // This is required as the other core may be `wfe` (waiting for event)
 | 
				
			||||||
    cortex_m::asm::sev();
 | 
					    cortex_m::asm::sev();
 | 
				
			||||||
@ -286,7 +282,6 @@ fn fifo_write(value: u32) {
 | 
				
			|||||||
// Pop a value from inter-core FIFO, block until available
 | 
					// Pop a value from inter-core FIFO, block until available
 | 
				
			||||||
#[inline(always)]
 | 
					#[inline(always)]
 | 
				
			||||||
fn fifo_read() -> u32 {
 | 
					fn fifo_read() -> u32 {
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
    let sio = pac::SIO;
 | 
					    let sio = pac::SIO;
 | 
				
			||||||
    // Wait until FIFO has data
 | 
					    // Wait until FIFO has data
 | 
				
			||||||
    while !sio.fifo().st().read().vld() {
 | 
					    while !sio.fifo().st().read().vld() {
 | 
				
			||||||
@ -294,13 +289,11 @@ fn fifo_read() -> u32 {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    sio.fifo().rd().read()
 | 
					    sio.fifo().rd().read()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Pop a value from inter-core FIFO, `wfe` until available
 | 
					// Pop a value from inter-core FIFO, `wfe` until available
 | 
				
			||||||
#[inline(always)]
 | 
					#[inline(always)]
 | 
				
			||||||
#[allow(unused)]
 | 
					#[allow(unused)]
 | 
				
			||||||
fn fifo_read_wfe() -> u32 {
 | 
					fn fifo_read_wfe() -> u32 {
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
    let sio = pac::SIO;
 | 
					    let sio = pac::SIO;
 | 
				
			||||||
    // Wait until FIFO has data
 | 
					    // Wait until FIFO has data
 | 
				
			||||||
    while !sio.fifo().st().read().vld() {
 | 
					    while !sio.fifo().st().read().vld() {
 | 
				
			||||||
@ -308,18 +301,15 @@ fn fifo_read_wfe() -> u32 {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    sio.fifo().rd().read()
 | 
					    sio.fifo().rd().read()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Drain inter-core FIFO
 | 
					// Drain inter-core FIFO
 | 
				
			||||||
#[inline(always)]
 | 
					#[inline(always)]
 | 
				
			||||||
fn fifo_drain() {
 | 
					fn fifo_drain() {
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
    let sio = pac::SIO;
 | 
					    let sio = pac::SIO;
 | 
				
			||||||
    while sio.fifo().st().read().vld() {
 | 
					    while sio.fifo().st().read().vld() {
 | 
				
			||||||
        let _ = sio.fifo().rd().read();
 | 
					        let _ = sio.fifo().rd().read();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// https://github.com/nvzqz/bad-rs/blob/master/src/never.rs
 | 
					// https://github.com/nvzqz/bad-rs/blob/master/src/never.rs
 | 
				
			||||||
mod bad {
 | 
					mod bad {
 | 
				
			||||||
 | 
				
			|||||||
@ -87,7 +87,7 @@ const SMIRQ_MASK: u32 = 1 << 8;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "rt")]
 | 
					#[cfg(feature = "rt")]
 | 
				
			||||||
#[interrupt]
 | 
					#[interrupt]
 | 
				
			||||||
unsafe fn PIO0_IRQ_0() {
 | 
					fn PIO0_IRQ_0() {
 | 
				
			||||||
    use crate::pac;
 | 
					    use crate::pac;
 | 
				
			||||||
    let ints = pac::PIO0.irqs(0).ints().read().0;
 | 
					    let ints = pac::PIO0.irqs(0).ints().read().0;
 | 
				
			||||||
    for bit in 0..12 {
 | 
					    for bit in 0..12 {
 | 
				
			||||||
@ -100,7 +100,7 @@ unsafe fn PIO0_IRQ_0() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "rt")]
 | 
					#[cfg(feature = "rt")]
 | 
				
			||||||
#[interrupt]
 | 
					#[interrupt]
 | 
				
			||||||
unsafe fn PIO1_IRQ_0() {
 | 
					fn PIO1_IRQ_0() {
 | 
				
			||||||
    use crate::pac;
 | 
					    use crate::pac;
 | 
				
			||||||
    let ints = pac::PIO1.irqs(0).ints().read().0;
 | 
					    let ints = pac::PIO1.irqs(0).ints().read().0;
 | 
				
			||||||
    for bit in 0..12 {
 | 
					    for bit in 0..12 {
 | 
				
			||||||
@ -145,11 +145,9 @@ impl<'a, 'd, PIO: Instance, const SM: usize> Future for FifoOutFuture<'a, 'd, PI
 | 
				
			|||||||
            Poll::Ready(())
 | 
					            Poll::Ready(())
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            WAKERS[PIO::PIO_NO as usize].fifo_out()[SM].register(cx.waker());
 | 
					            WAKERS[PIO::PIO_NO as usize].fifo_out()[SM].register(cx.waker());
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            PIO::PIO.irqs(0).inte().write_set(|m| {
 | 
					            PIO::PIO.irqs(0).inte().write_set(|m| {
 | 
				
			||||||
                m.0 = TXNFULL_MASK << SM;
 | 
					                m.0 = TXNFULL_MASK << SM;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            // debug!("Pending");
 | 
					            // debug!("Pending");
 | 
				
			||||||
            Poll::Pending
 | 
					            Poll::Pending
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -158,13 +156,11 @@ impl<'a, 'd, PIO: Instance, const SM: usize> Future for FifoOutFuture<'a, 'd, PI
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'a, 'd, PIO: Instance, const SM: usize> Drop for FifoOutFuture<'a, 'd, PIO, SM> {
 | 
					impl<'a, 'd, PIO: Instance, const SM: usize> Drop for FifoOutFuture<'a, 'd, PIO, SM> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        PIO::PIO.irqs(0).inte().write_clear(|m| {
 | 
					        PIO::PIO.irqs(0).inte().write_clear(|m| {
 | 
				
			||||||
            m.0 = TXNFULL_MASK << SM;
 | 
					            m.0 = TXNFULL_MASK << SM;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Future that waits for RX-FIFO to become readable
 | 
					/// Future that waits for RX-FIFO to become readable
 | 
				
			||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
 | 
					#[must_use = "futures do nothing unless you `.await` or poll them"]
 | 
				
			||||||
@ -186,11 +182,9 @@ impl<'a, 'd, PIO: Instance, const SM: usize> Future for FifoInFuture<'a, 'd, PIO
 | 
				
			|||||||
            Poll::Ready(v)
 | 
					            Poll::Ready(v)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            WAKERS[PIO::PIO_NO as usize].fifo_in()[SM].register(cx.waker());
 | 
					            WAKERS[PIO::PIO_NO as usize].fifo_in()[SM].register(cx.waker());
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            PIO::PIO.irqs(0).inte().write_set(|m| {
 | 
					            PIO::PIO.irqs(0).inte().write_set(|m| {
 | 
				
			||||||
                m.0 = RXNEMPTY_MASK << SM;
 | 
					                m.0 = RXNEMPTY_MASK << SM;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            //debug!("Pending");
 | 
					            //debug!("Pending");
 | 
				
			||||||
            Poll::Pending
 | 
					            Poll::Pending
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -199,13 +193,11 @@ impl<'a, 'd, PIO: Instance, const SM: usize> Future for FifoInFuture<'a, 'd, PIO
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'a, 'd, PIO: Instance, const SM: usize> Drop for FifoInFuture<'a, 'd, PIO, SM> {
 | 
					impl<'a, 'd, PIO: Instance, const SM: usize> Drop for FifoInFuture<'a, 'd, PIO, SM> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        PIO::PIO.irqs(0).inte().write_clear(|m| {
 | 
					        PIO::PIO.irqs(0).inte().write_clear(|m| {
 | 
				
			||||||
            m.0 = RXNEMPTY_MASK << SM;
 | 
					            m.0 = RXNEMPTY_MASK << SM;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Future that waits for IRQ
 | 
					/// Future that waits for IRQ
 | 
				
			||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
 | 
					#[must_use = "futures do nothing unless you `.await` or poll them"]
 | 
				
			||||||
@ -220,32 +212,26 @@ impl<'a, 'd, PIO: Instance> Future for IrqFuture<'a, 'd, PIO> {
 | 
				
			|||||||
        //debug!("Poll {},{}", PIO::PIO_NO, SM);
 | 
					        //debug!("Poll {},{}", PIO::PIO_NO, SM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Check if IRQ flag is already set
 | 
					        // Check if IRQ flag is already set
 | 
				
			||||||
        if unsafe { PIO::PIO.irq().read().0 & (1 << self.irq_no) != 0 } {
 | 
					        if PIO::PIO.irq().read().0 & (1 << self.irq_no) != 0 {
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            PIO::PIO.irq().write(|m| m.0 = 1 << self.irq_no);
 | 
					            PIO::PIO.irq().write(|m| m.0 = 1 << self.irq_no);
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return Poll::Ready(());
 | 
					            return Poll::Ready(());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        WAKERS[PIO::PIO_NO as usize].irq()[self.irq_no as usize].register(cx.waker());
 | 
					        WAKERS[PIO::PIO_NO as usize].irq()[self.irq_no as usize].register(cx.waker());
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        PIO::PIO.irqs(0).inte().write_set(|m| {
 | 
					        PIO::PIO.irqs(0).inte().write_set(|m| {
 | 
				
			||||||
            m.0 = SMIRQ_MASK << self.irq_no;
 | 
					            m.0 = SMIRQ_MASK << self.irq_no;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Poll::Pending
 | 
					        Poll::Pending
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a, 'd, PIO: Instance> Drop for IrqFuture<'a, 'd, PIO> {
 | 
					impl<'a, 'd, PIO: Instance> Drop for IrqFuture<'a, 'd, PIO> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        PIO::PIO.irqs(0).inte().write_clear(|m| {
 | 
					        PIO::PIO.irqs(0).inte().write_clear(|m| {
 | 
				
			||||||
            m.0 = SMIRQ_MASK << self.irq_no;
 | 
					            m.0 = SMIRQ_MASK << self.irq_no;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Pin<'l, PIO: Instance> {
 | 
					pub struct Pin<'l, PIO: Instance> {
 | 
				
			||||||
    pin: PeripheralRef<'l, AnyPin>,
 | 
					    pin: PeripheralRef<'l, AnyPin>,
 | 
				
			||||||
@ -256,7 +242,6 @@ impl<'l, PIO: Instance> Pin<'l, PIO> {
 | 
				
			|||||||
    /// Set the pin's drive strength.
 | 
					    /// Set the pin's drive strength.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_drive_strength(&mut self, strength: Drive) {
 | 
					    pub fn set_drive_strength(&mut self, strength: Drive) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.pin.pad_ctrl().modify(|w| {
 | 
					        self.pin.pad_ctrl().modify(|w| {
 | 
				
			||||||
            w.set_drive(match strength {
 | 
					            w.set_drive(match strength {
 | 
				
			||||||
                Drive::_2mA => pac::pads::vals::Drive::_2MA,
 | 
					                Drive::_2mA => pac::pads::vals::Drive::_2MA,
 | 
				
			||||||
@ -266,49 +251,40 @@ impl<'l, PIO: Instance> Pin<'l, PIO> {
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 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) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.pin.pad_ctrl().modify(|w| {
 | 
					        self.pin.pad_ctrl().modify(|w| {
 | 
				
			||||||
            w.set_slewfast(slew_rate == SlewRate::Fast);
 | 
					            w.set_slewfast(slew_rate == SlewRate::Fast);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Set the pin's pull.
 | 
					    /// Set the pin's pull.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_pull(&mut self, pull: Pull) {
 | 
					    pub fn set_pull(&mut self, pull: Pull) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.pin.pad_ctrl().modify(|w| {
 | 
					        self.pin.pad_ctrl().modify(|w| {
 | 
				
			||||||
            w.set_pue(pull == Pull::Up);
 | 
					            w.set_pue(pull == Pull::Up);
 | 
				
			||||||
            w.set_pde(pull == Pull::Down);
 | 
					            w.set_pde(pull == Pull::Down);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Set the pin's schmitt trigger.
 | 
					    /// Set the pin's schmitt trigger.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_schmitt(&mut self, enable: bool) {
 | 
					    pub fn set_schmitt(&mut self, enable: bool) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.pin.pad_ctrl().modify(|w| {
 | 
					        self.pin.pad_ctrl().modify(|w| {
 | 
				
			||||||
            w.set_schmitt(enable);
 | 
					            w.set_schmitt(enable);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn set_input_sync_bypass<'a>(&mut self, bypass: bool) {
 | 
					    pub fn set_input_sync_bypass<'a>(&mut self, bypass: bool) {
 | 
				
			||||||
        let mask = 1 << self.pin();
 | 
					        let mask = 1 << self.pin();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        if bypass {
 | 
					        if bypass {
 | 
				
			||||||
            PIO::PIO.input_sync_bypass().write_set(|w| *w = mask);
 | 
					            PIO::PIO.input_sync_bypass().write_set(|w| *w = mask);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            PIO::PIO.input_sync_bypass().write_clear(|w| *w = mask);
 | 
					            PIO::PIO.input_sync_bypass().write_clear(|w| *w = mask);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn pin(&self) -> u8 {
 | 
					    pub fn pin(&self) -> u8 {
 | 
				
			||||||
        self.pin._pin()
 | 
					        self.pin._pin()
 | 
				
			||||||
@ -321,19 +297,18 @@ pub struct StateMachineRx<'d, PIO: Instance, const SM: usize> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
 | 
					impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
 | 
				
			||||||
    pub fn empty(&self) -> bool {
 | 
					    pub fn empty(&self) -> bool {
 | 
				
			||||||
        unsafe { PIO::PIO.fstat().read().rxempty() & (1u8 << SM) != 0 }
 | 
					        PIO::PIO.fstat().read().rxempty() & (1u8 << SM) != 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn full(&self) -> bool {
 | 
					    pub fn full(&self) -> bool {
 | 
				
			||||||
        unsafe { PIO::PIO.fstat().read().rxfull() & (1u8 << SM) != 0 }
 | 
					        PIO::PIO.fstat().read().rxfull() & (1u8 << SM) != 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn level(&self) -> u8 {
 | 
					    pub fn level(&self) -> u8 {
 | 
				
			||||||
        unsafe { (PIO::PIO.flevel().read().0 >> (SM * 8 + 4)) as u8 & 0x0f }
 | 
					        (PIO::PIO.flevel().read().0 >> (SM * 8 + 4)) as u8 & 0x0f
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn stalled(&self) -> bool {
 | 
					    pub fn stalled(&self) -> bool {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let fdebug = PIO::PIO.fdebug();
 | 
					        let fdebug = PIO::PIO.fdebug();
 | 
				
			||||||
        let ret = fdebug.read().rxstall() & (1 << SM) != 0;
 | 
					        let ret = fdebug.read().rxstall() & (1 << SM) != 0;
 | 
				
			||||||
        if ret {
 | 
					        if ret {
 | 
				
			||||||
@ -341,10 +316,8 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        ret
 | 
					        ret
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn underflowed(&self) -> bool {
 | 
					    pub fn underflowed(&self) -> bool {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let fdebug = PIO::PIO.fdebug();
 | 
					        let fdebug = PIO::PIO.fdebug();
 | 
				
			||||||
        let ret = fdebug.read().rxunder() & (1 << SM) != 0;
 | 
					        let ret = fdebug.read().rxunder() & (1 << SM) != 0;
 | 
				
			||||||
        if ret {
 | 
					        if ret {
 | 
				
			||||||
@ -352,10 +325,9 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        ret
 | 
					        ret
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn pull(&mut self) -> u32 {
 | 
					    pub fn pull(&mut self) -> u32 {
 | 
				
			||||||
        unsafe { PIO::PIO.rxf(SM).read() }
 | 
					        PIO::PIO.rxf(SM).read()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn try_pull(&mut self) -> Option<u32> {
 | 
					    pub fn try_pull(&mut self) -> Option<u32> {
 | 
				
			||||||
@ -374,11 +346,10 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
 | 
				
			|||||||
        ch: PeripheralRef<'a, C>,
 | 
					        ch: PeripheralRef<'a, C>,
 | 
				
			||||||
        data: &'a mut [W],
 | 
					        data: &'a mut [W],
 | 
				
			||||||
    ) -> Transfer<'a, C> {
 | 
					    ) -> Transfer<'a, C> {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let pio_no = PIO::PIO_NO;
 | 
					        let pio_no = PIO::PIO_NO;
 | 
				
			||||||
        let p = ch.regs();
 | 
					        let p = ch.regs();
 | 
				
			||||||
        p.write_addr().write_value(data.as_ptr() as u32);
 | 
					        p.write_addr().write_value(data.as_ptr() as u32);
 | 
				
			||||||
            p.read_addr().write_value(PIO::PIO.rxf(SM).ptr() as u32);
 | 
					        p.read_addr().write_value(PIO::PIO.rxf(SM).as_ptr() as u32);
 | 
				
			||||||
        p.trans_count().write_value(data.len() as u32);
 | 
					        p.trans_count().write_value(data.len() as u32);
 | 
				
			||||||
        compiler_fence(Ordering::SeqCst);
 | 
					        compiler_fence(Ordering::SeqCst);
 | 
				
			||||||
        p.ctrl_trig().write(|w| {
 | 
					        p.ctrl_trig().write(|w| {
 | 
				
			||||||
@ -391,7 +362,6 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
 | 
				
			|||||||
            w.set_en(true);
 | 
					            w.set_en(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        compiler_fence(Ordering::SeqCst);
 | 
					        compiler_fence(Ordering::SeqCst);
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Transfer::new(ch)
 | 
					        Transfer::new(ch)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -402,18 +372,17 @@ pub struct StateMachineTx<'d, PIO: Instance, const SM: usize> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
 | 
					impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
 | 
				
			||||||
    pub fn empty(&self) -> bool {
 | 
					    pub fn empty(&self) -> bool {
 | 
				
			||||||
        unsafe { PIO::PIO.fstat().read().txempty() & (1u8 << SM) != 0 }
 | 
					        PIO::PIO.fstat().read().txempty() & (1u8 << SM) != 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    pub fn full(&self) -> bool {
 | 
					    pub fn full(&self) -> bool {
 | 
				
			||||||
        unsafe { PIO::PIO.fstat().read().txfull() & (1u8 << SM) != 0 }
 | 
					        PIO::PIO.fstat().read().txfull() & (1u8 << SM) != 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn level(&self) -> u8 {
 | 
					    pub fn level(&self) -> u8 {
 | 
				
			||||||
        unsafe { (PIO::PIO.flevel().read().0 >> (SM * 8)) as u8 & 0x0f }
 | 
					        (PIO::PIO.flevel().read().0 >> (SM * 8)) as u8 & 0x0f
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn stalled(&self) -> bool {
 | 
					    pub fn stalled(&self) -> bool {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let fdebug = PIO::PIO.fdebug();
 | 
					        let fdebug = PIO::PIO.fdebug();
 | 
				
			||||||
        let ret = fdebug.read().txstall() & (1 << SM) != 0;
 | 
					        let ret = fdebug.read().txstall() & (1 << SM) != 0;
 | 
				
			||||||
        if ret {
 | 
					        if ret {
 | 
				
			||||||
@ -421,10 +390,8 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        ret
 | 
					        ret
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn overflowed(&self) -> bool {
 | 
					    pub fn overflowed(&self) -> bool {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let fdebug = PIO::PIO.fdebug();
 | 
					        let fdebug = PIO::PIO.fdebug();
 | 
				
			||||||
        let ret = fdebug.read().txover() & (1 << SM) != 0;
 | 
					        let ret = fdebug.read().txover() & (1 << SM) != 0;
 | 
				
			||||||
        if ret {
 | 
					        if ret {
 | 
				
			||||||
@ -432,13 +399,10 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        ret
 | 
					        ret
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn push(&mut self, v: u32) {
 | 
					    pub fn push(&mut self, v: u32) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        PIO::PIO.txf(SM).write_value(v);
 | 
					        PIO::PIO.txf(SM).write_value(v);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn try_push(&mut self, v: u32) -> bool {
 | 
					    pub fn try_push(&mut self, v: u32) -> bool {
 | 
				
			||||||
        if self.full() {
 | 
					        if self.full() {
 | 
				
			||||||
@ -453,11 +417,10 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn dma_push<'a, C: Channel, W: Word>(&'a mut self, ch: PeripheralRef<'a, C>, data: &'a [W]) -> Transfer<'a, C> {
 | 
					    pub fn dma_push<'a, C: Channel, W: Word>(&'a mut self, ch: PeripheralRef<'a, C>, data: &'a [W]) -> Transfer<'a, C> {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let pio_no = PIO::PIO_NO;
 | 
					        let pio_no = PIO::PIO_NO;
 | 
				
			||||||
        let p = ch.regs();
 | 
					        let p = ch.regs();
 | 
				
			||||||
        p.read_addr().write_value(data.as_ptr() as u32);
 | 
					        p.read_addr().write_value(data.as_ptr() as u32);
 | 
				
			||||||
            p.write_addr().write_value(PIO::PIO.txf(SM).ptr() as u32);
 | 
					        p.write_addr().write_value(PIO::PIO.txf(SM).as_ptr() as u32);
 | 
				
			||||||
        p.trans_count().write_value(data.len() as u32);
 | 
					        p.trans_count().write_value(data.len() as u32);
 | 
				
			||||||
        compiler_fence(Ordering::SeqCst);
 | 
					        compiler_fence(Ordering::SeqCst);
 | 
				
			||||||
        p.ctrl_trig().write(|w| {
 | 
					        p.ctrl_trig().write(|w| {
 | 
				
			||||||
@ -470,7 +433,6 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
 | 
				
			|||||||
            w.set_en(true);
 | 
					            w.set_en(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        compiler_fence(Ordering::SeqCst);
 | 
					        compiler_fence(Ordering::SeqCst);
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Transfer::new(ch)
 | 
					        Transfer::new(ch)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -482,9 +444,7 @@ pub struct StateMachine<'d, PIO: Instance, const SM: usize> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'d, PIO: Instance, const SM: usize> Drop for StateMachine<'d, PIO, SM> {
 | 
					impl<'d, PIO: Instance, const SM: usize> Drop for StateMachine<'d, PIO, SM> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        PIO::PIO.ctrl().write_clear(|w| w.set_sm_enable(1 << SM));
 | 
					        PIO::PIO.ctrl().write_clear(|w| w.set_sm_enable(1 << SM));
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        on_pio_drop::<PIO>();
 | 
					        on_pio_drop::<PIO>();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -647,7 +607,6 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
 | 
				
			|||||||
        assert!(config.shift_in.threshold <= 32, "shift_in.threshold must be <= 32");
 | 
					        assert!(config.shift_in.threshold <= 32, "shift_in.threshold must be <= 32");
 | 
				
			||||||
        assert!(config.shift_out.threshold <= 32, "shift_out.threshold must be <= 32");
 | 
					        assert!(config.shift_out.threshold <= 32, "shift_out.threshold must be <= 32");
 | 
				
			||||||
        let sm = Self::this_sm();
 | 
					        let sm = Self::this_sm();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        sm.clkdiv().write(|w| w.0 = config.clock_divider.to_bits() << 8);
 | 
					        sm.clkdiv().write(|w| w.0 = config.clock_divider.to_bits() << 8);
 | 
				
			||||||
        sm.execctrl().write(|w| {
 | 
					        sm.execctrl().write(|w| {
 | 
				
			||||||
            w.set_side_en(config.exec.side_en);
 | 
					            w.set_side_en(config.exec.side_en);
 | 
				
			||||||
@ -684,8 +643,7 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
 | 
				
			|||||||
            w.set_out_base(config.pins.out_base);
 | 
					            w.set_out_base(config.pins.out_base);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        if let Some(origin) = config.origin {
 | 
					        if let Some(origin) = config.origin {
 | 
				
			||||||
                pio_instr_util::exec_jmp(self, origin);
 | 
					            unsafe { pio_instr_util::exec_jmp(self, origin) }
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -696,45 +654,35 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    pub fn restart(&mut self) {
 | 
					    pub fn restart(&mut self) {
 | 
				
			||||||
        let mask = 1u8 << SM;
 | 
					        let mask = 1u8 << SM;
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        PIO::PIO.ctrl().write_set(|w| w.set_sm_restart(mask));
 | 
					        PIO::PIO.ctrl().write_set(|w| w.set_sm_restart(mask));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    pub fn set_enable(&mut self, enable: bool) {
 | 
					    pub fn set_enable(&mut self, enable: bool) {
 | 
				
			||||||
        let mask = 1u8 << SM;
 | 
					        let mask = 1u8 << SM;
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        if enable {
 | 
					        if enable {
 | 
				
			||||||
            PIO::PIO.ctrl().write_set(|w| w.set_sm_enable(mask));
 | 
					            PIO::PIO.ctrl().write_set(|w| w.set_sm_enable(mask));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            PIO::PIO.ctrl().write_clear(|w| w.set_sm_enable(mask));
 | 
					            PIO::PIO.ctrl().write_clear(|w| w.set_sm_enable(mask));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn is_enabled(&self) -> bool {
 | 
					    pub fn is_enabled(&self) -> bool {
 | 
				
			||||||
        unsafe { PIO::PIO.ctrl().read().sm_enable() & (1u8 << SM) != 0 }
 | 
					        PIO::PIO.ctrl().read().sm_enable() & (1u8 << SM) != 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn clkdiv_restart(&mut self) {
 | 
					    pub fn clkdiv_restart(&mut self) {
 | 
				
			||||||
        let mask = 1u8 << SM;
 | 
					        let mask = 1u8 << SM;
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        PIO::PIO.ctrl().write_set(|w| w.set_clkdiv_restart(mask));
 | 
					        PIO::PIO.ctrl().write_set(|w| w.set_clkdiv_restart(mask));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn with_paused(&mut self, f: impl FnOnce(&mut Self)) {
 | 
					    fn with_paused(&mut self, f: impl FnOnce(&mut Self)) {
 | 
				
			||||||
        let enabled = self.is_enabled();
 | 
					        let enabled = self.is_enabled();
 | 
				
			||||||
        self.set_enable(false);
 | 
					        self.set_enable(false);
 | 
				
			||||||
        let pincfg = unsafe { Self::this_sm().pinctrl().read() };
 | 
					        let pincfg = Self::this_sm().pinctrl().read();
 | 
				
			||||||
        let execcfg = unsafe { Self::this_sm().execctrl().read() };
 | 
					        let execcfg = Self::this_sm().execctrl().read();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        Self::this_sm().execctrl().write_clear(|w| w.set_out_sticky(true));
 | 
					        Self::this_sm().execctrl().write_clear(|w| w.set_out_sticky(true));
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        f(self);
 | 
					        f(self);
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        Self::this_sm().pinctrl().write_value(pincfg);
 | 
					        Self::this_sm().pinctrl().write_value(pincfg);
 | 
				
			||||||
        Self::this_sm().execctrl().write_value(execcfg);
 | 
					        Self::this_sm().execctrl().write_value(execcfg);
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        self.set_enable(enabled);
 | 
					        self.set_enable(enabled);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -743,14 +691,12 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
 | 
				
			|||||||
    pub fn set_pin_dirs(&mut self, dir: Direction, pins: &[&Pin<'d, PIO>]) {
 | 
					    pub fn set_pin_dirs(&mut self, dir: Direction, pins: &[&Pin<'d, PIO>]) {
 | 
				
			||||||
        self.with_paused(|sm| {
 | 
					        self.with_paused(|sm| {
 | 
				
			||||||
            for pin in pins {
 | 
					            for pin in pins {
 | 
				
			||||||
                unsafe {
 | 
					 | 
				
			||||||
                Self::this_sm().pinctrl().write(|w| {
 | 
					                Self::this_sm().pinctrl().write(|w| {
 | 
				
			||||||
                    w.set_set_base(pin.pin());
 | 
					                    w.set_set_base(pin.pin());
 | 
				
			||||||
                    w.set_set_count(1);
 | 
					                    w.set_set_count(1);
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                // SET PINDIRS, (dir)
 | 
					                // SET PINDIRS, (dir)
 | 
				
			||||||
                    sm.exec_instr(0b111_00000_100_00000 | dir as u16);
 | 
					                unsafe { sm.exec_instr(0b111_00000_100_00000 | dir as u16) };
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -760,21 +706,18 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
 | 
				
			|||||||
    pub fn set_pins(&mut self, level: Level, pins: &[&Pin<'d, PIO>]) {
 | 
					    pub fn set_pins(&mut self, level: Level, pins: &[&Pin<'d, PIO>]) {
 | 
				
			||||||
        self.with_paused(|sm| {
 | 
					        self.with_paused(|sm| {
 | 
				
			||||||
            for pin in pins {
 | 
					            for pin in pins {
 | 
				
			||||||
                unsafe {
 | 
					 | 
				
			||||||
                Self::this_sm().pinctrl().write(|w| {
 | 
					                Self::this_sm().pinctrl().write(|w| {
 | 
				
			||||||
                    w.set_set_base(pin.pin());
 | 
					                    w.set_set_base(pin.pin());
 | 
				
			||||||
                    w.set_set_count(1);
 | 
					                    w.set_set_count(1);
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                // SET PINS, (dir)
 | 
					                // SET PINS, (dir)
 | 
				
			||||||
                    sm.exec_instr(0b111_00000_000_00000 | level as u16);
 | 
					                unsafe { sm.exec_instr(0b111_00000_000_00000 | level as u16) };
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn clear_fifos(&mut self) {
 | 
					    pub fn clear_fifos(&mut self) {
 | 
				
			||||||
        // Toggle FJOIN_RX to flush FIFOs
 | 
					        // Toggle FJOIN_RX to flush FIFOs
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let shiftctrl = Self::this_sm().shiftctrl();
 | 
					        let shiftctrl = Self::this_sm().shiftctrl();
 | 
				
			||||||
        shiftctrl.modify(|w| {
 | 
					        shiftctrl.modify(|w| {
 | 
				
			||||||
            w.set_fjoin_rx(!w.fjoin_rx());
 | 
					            w.set_fjoin_rx(!w.fjoin_rx());
 | 
				
			||||||
@ -783,7 +726,6 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
 | 
				
			|||||||
            w.set_fjoin_rx(!w.fjoin_rx());
 | 
					            w.set_fjoin_rx(!w.fjoin_rx());
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub unsafe fn exec_instr(&mut self, instr: u16) {
 | 
					    pub unsafe fn exec_instr(&mut self, instr: u16) {
 | 
				
			||||||
        Self::this_sm().instr().write(|w| w.set_instr(instr));
 | 
					        Self::this_sm().instr().write(|w| w.set_instr(instr));
 | 
				
			||||||
@ -856,11 +798,9 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
 | 
				
			|||||||
            if (self.instructions_used | used_mask) & mask != 0 {
 | 
					            if (self.instructions_used | used_mask) & mask != 0 {
 | 
				
			||||||
                return Err(addr);
 | 
					                return Err(addr);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            PIO::PIO.instr_mem(addr).write(|w| {
 | 
					            PIO::PIO.instr_mem(addr).write(|w| {
 | 
				
			||||||
                w.set_instr_mem(instr);
 | 
					                w.set_instr_mem(instr);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            used_mask |= mask;
 | 
					            used_mask |= mask;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        self.instructions_used |= used_mask;
 | 
					        self.instructions_used |= used_mask;
 | 
				
			||||||
@ -877,17 +817,15 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn set_input_sync_bypass<'a>(&'a mut self, bypass: u32, mask: u32) {
 | 
					    pub fn set_input_sync_bypass<'a>(&'a mut self, bypass: u32, mask: u32) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        // this can interfere with per-pin bypass functions. splitting the
 | 
					        // this can interfere with per-pin bypass functions. splitting the
 | 
				
			||||||
        // modification is going to be fine since nothing that relies on
 | 
					        // modification is going to be fine since nothing that relies on
 | 
				
			||||||
        // it can reasonably run before we finish.
 | 
					        // it can reasonably run before we finish.
 | 
				
			||||||
        PIO::PIO.input_sync_bypass().write_set(|w| *w = mask & bypass);
 | 
					        PIO::PIO.input_sync_bypass().write_set(|w| *w = mask & bypass);
 | 
				
			||||||
        PIO::PIO.input_sync_bypass().write_clear(|w| *w = mask & !bypass);
 | 
					        PIO::PIO.input_sync_bypass().write_clear(|w| *w = mask & !bypass);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn get_input_sync_bypass(&self) -> u32 {
 | 
					    pub fn get_input_sync_bypass(&self) -> u32 {
 | 
				
			||||||
        unsafe { PIO::PIO.input_sync_bypass().read() }
 | 
					        PIO::PIO.input_sync_bypass().read()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Register a pin for PIO usage. Pins will be released from the PIO block
 | 
					    /// Register a pin for PIO usage. Pins will be released from the PIO block
 | 
				
			||||||
@ -896,9 +834,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
 | 
				
			|||||||
    /// of [`Pio`] do not keep pin registrations alive.**
 | 
					    /// of [`Pio`] do not keep pin registrations alive.**
 | 
				
			||||||
    pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> {
 | 
					    pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> {
 | 
				
			||||||
        into_ref!(pin);
 | 
					        into_ref!(pin);
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        pin.io().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL.0));
 | 
					        pin.io().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL.0));
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // we can be relaxed about this because we're &mut here and nothing is cached
 | 
					        // we can be relaxed about this because we're &mut here and nothing is cached
 | 
				
			||||||
        PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed);
 | 
					        PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed);
 | 
				
			||||||
        Pin {
 | 
					        Pin {
 | 
				
			||||||
@ -916,7 +852,6 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
 | 
				
			|||||||
            _pio: PhantomData,
 | 
					            _pio: PhantomData,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        f(&mut batch);
 | 
					        f(&mut batch);
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        PIO::PIO.ctrl().modify(|w| {
 | 
					        PIO::PIO.ctrl().modify(|w| {
 | 
				
			||||||
            w.set_clkdiv_restart(batch.clkdiv_restart);
 | 
					            w.set_clkdiv_restart(batch.clkdiv_restart);
 | 
				
			||||||
            w.set_sm_restart(batch.sm_restart);
 | 
					            w.set_sm_restart(batch.sm_restart);
 | 
				
			||||||
@ -924,7 +859,6 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct PioBatch<'a, PIO: Instance> {
 | 
					pub struct PioBatch<'a, PIO: Instance> {
 | 
				
			||||||
    clkdiv_restart: u8,
 | 
					    clkdiv_restart: u8,
 | 
				
			||||||
@ -974,11 +908,11 @@ impl<'d, PIO: Instance> IrqFlags<'d, PIO> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn check_any(&self, irqs: u8) -> bool {
 | 
					    pub fn check_any(&self, irqs: u8) -> bool {
 | 
				
			||||||
        unsafe { PIO::PIO.irq().read().irq() & irqs != 0 }
 | 
					        PIO::PIO.irq().read().irq() & irqs != 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn check_all(&self, irqs: u8) -> bool {
 | 
					    pub fn check_all(&self, irqs: u8) -> bool {
 | 
				
			||||||
        unsafe { PIO::PIO.irq().read().irq() & irqs == irqs }
 | 
					        PIO::PIO.irq().read().irq() & irqs == irqs
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn clear(&self, irq_no: usize) {
 | 
					    pub fn clear(&self, irq_no: usize) {
 | 
				
			||||||
@ -987,7 +921,7 @@ impl<'d, PIO: Instance> IrqFlags<'d, PIO> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn clear_all(&self, irqs: u8) {
 | 
					    pub fn clear_all(&self, irqs: u8) {
 | 
				
			||||||
        unsafe { PIO::PIO.irq().write(|w| w.set_irq(irqs)) }
 | 
					        PIO::PIO.irq().write(|w| w.set_irq(irqs))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn set(&self, irq_no: usize) {
 | 
					    pub fn set(&self, irq_no: usize) {
 | 
				
			||||||
@ -996,7 +930,7 @@ impl<'d, PIO: Instance> IrqFlags<'d, PIO> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn set_all(&self, irqs: u8) {
 | 
					    pub fn set_all(&self, irqs: u8) {
 | 
				
			||||||
        unsafe { PIO::PIO.irq_force().write(|w| w.set_irq_force(irqs)) }
 | 
					        PIO::PIO.irq_force().write(|w| w.set_irq_force(irqs))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1068,13 +1002,11 @@ fn on_pio_drop<PIO: Instance>() {
 | 
				
			|||||||
        // we only have 30 pins. don't test the other two since gpio() asserts.
 | 
					        // we only have 30 pins. don't test the other two since gpio() asserts.
 | 
				
			||||||
        for i in 0..30 {
 | 
					        for i in 0..30 {
 | 
				
			||||||
            if used_pins & (1 << i) != 0 {
 | 
					            if used_pins & (1 << i) != 0 {
 | 
				
			||||||
                unsafe {
 | 
					 | 
				
			||||||
                pac::IO_BANK0.gpio(i).ctrl().write(|w| w.set_funcsel(null));
 | 
					                pac::IO_BANK0.gpio(i).ctrl().write(|w| w.set_funcsel(null));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod sealed {
 | 
					mod sealed {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
				
			|||||||
@ -71,7 +71,6 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
        into_ref!(inner);
 | 
					        into_ref!(inner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let p = inner.regs();
 | 
					        let p = inner.regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        p.csr().modify(|w| {
 | 
					        p.csr().modify(|w| {
 | 
				
			||||||
            w.set_divmode(divmode);
 | 
					            w.set_divmode(divmode);
 | 
				
			||||||
            w.set_en(false);
 | 
					            w.set_en(false);
 | 
				
			||||||
@ -85,7 +84,6 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
        if let Some(pin) = &b {
 | 
					        if let Some(pin) = &b {
 | 
				
			||||||
            pin.io().ctrl().write(|w| w.set_funcsel(4));
 | 
					            pin.io().ctrl().write(|w| w.set_funcsel(4));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            inner,
 | 
					            inner,
 | 
				
			||||||
            pin_a: a.into(),
 | 
					            pin_a: a.into(),
 | 
				
			||||||
@ -161,7 +159,6 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
            panic!("Requested divider is too large");
 | 
					            panic!("Requested divider is too large");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        p.div().write_value(ChDiv(config.divider.to_bits() as u32));
 | 
					        p.div().write_value(ChDiv(config.divider.to_bits() as u32));
 | 
				
			||||||
        p.cc().write(|w| {
 | 
					        p.cc().write(|w| {
 | 
				
			||||||
            w.set_a(config.compare_a);
 | 
					            w.set_a(config.compare_a);
 | 
				
			||||||
@ -175,17 +172,16 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
            w.set_en(config.enable);
 | 
					            w.set_en(config.enable);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub unsafe fn phase_advance(&mut self) {
 | 
					    pub fn phase_advance(&mut self) {
 | 
				
			||||||
        let p = self.inner.regs();
 | 
					        let p = self.inner.regs();
 | 
				
			||||||
        p.csr().write_set(|w| w.set_ph_adv(true));
 | 
					        p.csr().write_set(|w| w.set_ph_adv(true));
 | 
				
			||||||
        while p.csr().read().ph_adv() {}
 | 
					        while p.csr().read().ph_adv() {}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub unsafe fn phase_retard(&mut self) {
 | 
					    pub fn phase_retard(&mut self) {
 | 
				
			||||||
        let p = self.inner.regs();
 | 
					        let p = self.inner.regs();
 | 
				
			||||||
        p.csr().write_set(|w| w.set_ph_ret(true));
 | 
					        p.csr().write_set(|w| w.set_ph_ret(true));
 | 
				
			||||||
        while p.csr().read().ph_ret() {}
 | 
					        while p.csr().read().ph_ret() {}
 | 
				
			||||||
@ -193,12 +189,12 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn counter(&self) -> u16 {
 | 
					    pub fn counter(&self) -> u16 {
 | 
				
			||||||
        unsafe { self.inner.regs().ctr().read().ctr() }
 | 
					        self.inner.regs().ctr().read().ctr()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_counter(&self, ctr: u16) {
 | 
					    pub fn set_counter(&self, ctr: u16) {
 | 
				
			||||||
        unsafe { self.inner.regs().ctr().write(|w| w.set_ctr(ctr)) }
 | 
					        self.inner.regs().ctr().write(|w| w.set_ctr(ctr))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
@ -209,15 +205,13 @@ impl<'d, T: Channel> Pwm<'d, T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn wrapped(&mut self) -> bool {
 | 
					    pub fn wrapped(&mut self) -> bool {
 | 
				
			||||||
        unsafe { pac::PWM.intr().read().0 & self.bit() != 0 }
 | 
					        pac::PWM.intr().read().0 & self.bit() != 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn clear_wrapped(&mut self) {
 | 
					    pub fn clear_wrapped(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        pac::PWM.intr().write_value(Intr(self.bit() as _));
 | 
					        pac::PWM.intr().write_value(Intr(self.bit() as _));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    fn bit(&self) -> u32 {
 | 
					    fn bit(&self) -> u32 {
 | 
				
			||||||
@ -237,7 +231,6 @@ impl PwmBatch {
 | 
				
			|||||||
    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);
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        if enabled {
 | 
					        if enabled {
 | 
				
			||||||
            pac::PWM.en().write_set(|w| w.0 = en.0);
 | 
					            pac::PWM.en().write_set(|w| w.0 = en.0);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@ -245,11 +238,9 @@ impl PwmBatch {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Channel> Drop for Pwm<'d, T> {
 | 
					impl<'d, T: Channel> Drop for Pwm<'d, T> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.inner.regs().csr().write_clear(|w| w.set_en(false));
 | 
					        self.inner.regs().csr().write_clear(|w| w.set_en(false));
 | 
				
			||||||
        if let Some(pin) = &self.pin_a {
 | 
					        if let Some(pin) = &self.pin_a {
 | 
				
			||||||
            pin.io().ctrl().write(|w| w.set_funcsel(31));
 | 
					            pin.io().ctrl().write(|w| w.set_funcsel(31));
 | 
				
			||||||
@ -259,7 +250,6 @@ impl<'d, T: Channel> Drop for Pwm<'d, T> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod sealed {
 | 
					mod sealed {
 | 
				
			||||||
    pub trait Channel {}
 | 
					    pub trait Channel {}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,11 +4,11 @@ use crate::pac;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub const ALL_PERIPHERALS: Peripherals = Peripherals(0x01ffffff);
 | 
					pub const ALL_PERIPHERALS: Peripherals = Peripherals(0x01ffffff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub unsafe fn reset(peris: Peripherals) {
 | 
					pub(crate) fn reset(peris: Peripherals) {
 | 
				
			||||||
    pac::RESETS.reset().write_value(peris);
 | 
					    pac::RESETS.reset().write_value(peris);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub unsafe fn unreset_wait(peris: Peripherals) {
 | 
					pub(crate) fn unreset_wait(peris: Peripherals) {
 | 
				
			||||||
    // TODO use the "atomic clear" register version
 | 
					    // TODO use the "atomic clear" register version
 | 
				
			||||||
    pac::RESETS.reset().modify(|v| *v = Peripherals(v.0 & !peris.0));
 | 
					    pac::RESETS.reset().modify(|v| *v = Peripherals(v.0 & !peris.0));
 | 
				
			||||||
    while ((!pac::RESETS.reset_done().read().0) & peris.0) != 0 {}
 | 
					    while ((!pac::RESETS.reset_done().read().0) & peris.0) != 0 {}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,7 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
 | 
				
			|||||||
        into_ref!(inner);
 | 
					        into_ref!(inner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Set the RTC divider
 | 
					        // Set the RTC divider
 | 
				
			||||||
        unsafe { inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1)) };
 | 
					        inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut result = Self { inner };
 | 
					        let mut result = Self { inner };
 | 
				
			||||||
        result.set_leap_year_check(true); // should be on by default, make sure this is the case.
 | 
					        result.set_leap_year_check(true); // should be on by default, make sure this is the case.
 | 
				
			||||||
@ -38,17 +38,14 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
 | 
				
			|||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// Leap year checking is enabled by default.
 | 
					    /// Leap year checking is enabled by default.
 | 
				
			||||||
    pub fn set_leap_year_check(&mut self, leap_year_check_enabled: bool) {
 | 
					    pub fn set_leap_year_check(&mut self, leap_year_check_enabled: bool) {
 | 
				
			||||||
        unsafe {
 | 
					        self.inner.regs().ctrl().modify(|w| {
 | 
				
			||||||
            self.inner
 | 
					            w.set_force_notleapyear(!leap_year_check_enabled);
 | 
				
			||||||
                .regs()
 | 
					        });
 | 
				
			||||||
                .ctrl()
 | 
					 | 
				
			||||||
                .modify(|w| w.set_force_notleapyear(!leap_year_check_enabled))
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Checks to see if this RealTimeClock is running
 | 
					    /// Checks to see if this RealTimeClock is running
 | 
				
			||||||
    pub fn is_running(&self) -> bool {
 | 
					    pub fn is_running(&self) -> bool {
 | 
				
			||||||
        unsafe { self.inner.regs().ctrl().read().rtc_active() }
 | 
					        self.inner.regs().ctrl().read().rtc_active()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Set the datetime to a new value.
 | 
					    /// Set the datetime to a new value.
 | 
				
			||||||
@ -60,7 +57,6 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
 | 
				
			|||||||
        self::datetime::validate_datetime(&t).map_err(RtcError::InvalidDateTime)?;
 | 
					        self::datetime::validate_datetime(&t).map_err(RtcError::InvalidDateTime)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // disable RTC while we configure it
 | 
					        // disable RTC while we configure it
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.inner.regs().ctrl().modify(|w| w.set_rtc_enable(false));
 | 
					        self.inner.regs().ctrl().modify(|w| w.set_rtc_enable(false));
 | 
				
			||||||
        while self.inner.regs().ctrl().read().rtc_active() {
 | 
					        while self.inner.regs().ctrl().read().rtc_active() {
 | 
				
			||||||
            core::hint::spin_loop();
 | 
					            core::hint::spin_loop();
 | 
				
			||||||
@ -79,7 +75,6 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
 | 
				
			|||||||
        while !self.inner.regs().ctrl().read().rtc_active() {
 | 
					        while !self.inner.regs().ctrl().read().rtc_active() {
 | 
				
			||||||
            core::hint::spin_loop();
 | 
					            core::hint::spin_loop();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -93,8 +88,8 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
 | 
				
			|||||||
            return Err(RtcError::NotRunning);
 | 
					            return Err(RtcError::NotRunning);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let rtc_0 = unsafe { self.inner.regs().rtc_0().read() };
 | 
					        let rtc_0 = self.inner.regs().rtc_0().read();
 | 
				
			||||||
        let rtc_1 = unsafe { self.inner.regs().rtc_1().read() };
 | 
					        let rtc_1 = self.inner.regs().rtc_1().read();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self::datetime::datetime_from_registers(rtc_0, rtc_1).map_err(RtcError::InvalidDateTime)
 | 
					        self::datetime::datetime_from_registers(rtc_0, rtc_1).map_err(RtcError::InvalidDateTime)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -103,14 +98,12 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
 | 
				
			|||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// [`schedule_alarm`]: #method.schedule_alarm
 | 
					    /// [`schedule_alarm`]: #method.schedule_alarm
 | 
				
			||||||
    pub fn disable_alarm(&mut self) {
 | 
					    pub fn disable_alarm(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.inner.regs().irq_setup_0().modify(|s| s.set_match_ena(false));
 | 
					        self.inner.regs().irq_setup_0().modify(|s| s.set_match_ena(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while self.inner.regs().irq_setup_0().read().match_active() {
 | 
					        while self.inner.regs().irq_setup_0().read().match_active() {
 | 
				
			||||||
            core::hint::spin_loop();
 | 
					            core::hint::spin_loop();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Schedule an alarm. The `filter` determines at which point in time this alarm is set.
 | 
					    /// Schedule an alarm. The `filter` determines at which point in time this alarm is set.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
@ -132,7 +125,6 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
 | 
				
			|||||||
    pub fn schedule_alarm(&mut self, filter: DateTimeFilter) {
 | 
					    pub fn schedule_alarm(&mut self, filter: DateTimeFilter) {
 | 
				
			||||||
        self.disable_alarm();
 | 
					        self.disable_alarm();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.inner.regs().irq_setup_0().write(|w| {
 | 
					        self.inner.regs().irq_setup_0().write(|w| {
 | 
				
			||||||
            filter.write_setup_0(w);
 | 
					            filter.write_setup_0(w);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
@ -148,7 +140,6 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
 | 
				
			|||||||
            core::hint::spin_loop();
 | 
					            core::hint::spin_loop();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Clear the interrupt. This should be called every time the `RTC_IRQ` interrupt is triggered,
 | 
					    /// Clear the interrupt. This should be called every time the `RTC_IRQ` interrupt is triggered,
 | 
				
			||||||
    /// or the next [`schedule_alarm`] will never fire.
 | 
					    /// or the next [`schedule_alarm`] will never fire.
 | 
				
			||||||
 | 
				
			|||||||
@ -79,7 +79,6 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
 | 
				
			|||||||
    ) -> Self {
 | 
					    ) -> Self {
 | 
				
			||||||
        into_ref!(inner);
 | 
					        into_ref!(inner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let p = inner.regs();
 | 
					        let p = inner.regs();
 | 
				
			||||||
        let (presc, postdiv) = calc_prescs(config.frequency);
 | 
					        let (presc, postdiv) = calc_prescs(config.frequency);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -112,7 +111,6 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
 | 
				
			|||||||
        if let Some(pin) = &cs {
 | 
					        if let Some(pin) = &cs {
 | 
				
			||||||
            pin.io().ctrl().write(|w| w.set_funcsel(1));
 | 
					            pin.io().ctrl().write(|w| w.set_funcsel(1));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            inner,
 | 
					            inner,
 | 
				
			||||||
            tx_dma,
 | 
					            tx_dma,
 | 
				
			||||||
@ -122,7 +120,6 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let p = self.inner.regs();
 | 
					        let p = self.inner.regs();
 | 
				
			||||||
        for &b in data {
 | 
					        for &b in data {
 | 
				
			||||||
            while !p.sr().read().tnf() {}
 | 
					            while !p.sr().read().tnf() {}
 | 
				
			||||||
@ -130,13 +127,11 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
 | 
				
			|||||||
            while !p.sr().read().rne() {}
 | 
					            while !p.sr().read().rne() {}
 | 
				
			||||||
            let _ = p.dr().read();
 | 
					            let _ = p.dr().read();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        self.flush()?;
 | 
					        self.flush()?;
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn blocking_transfer_in_place(&mut self, data: &mut [u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_transfer_in_place(&mut self, data: &mut [u8]) -> Result<(), Error> {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let p = self.inner.regs();
 | 
					        let p = self.inner.regs();
 | 
				
			||||||
        for b in data {
 | 
					        for b in data {
 | 
				
			||||||
            while !p.sr().read().tnf() {}
 | 
					            while !p.sr().read().tnf() {}
 | 
				
			||||||
@ -144,13 +139,11 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
 | 
				
			|||||||
            while !p.sr().read().rne() {}
 | 
					            while !p.sr().read().rne() {}
 | 
				
			||||||
            *b = p.dr().read().data() as u8;
 | 
					            *b = p.dr().read().data() as u8;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        self.flush()?;
 | 
					        self.flush()?;
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn blocking_read(&mut self, data: &mut [u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_read(&mut self, data: &mut [u8]) -> Result<(), Error> {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let p = self.inner.regs();
 | 
					        let p = self.inner.regs();
 | 
				
			||||||
        for b in data {
 | 
					        for b in data {
 | 
				
			||||||
            while !p.sr().read().tnf() {}
 | 
					            while !p.sr().read().tnf() {}
 | 
				
			||||||
@ -158,13 +151,11 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
 | 
				
			|||||||
            while !p.sr().read().rne() {}
 | 
					            while !p.sr().read().rne() {}
 | 
				
			||||||
            *b = p.dr().read().data() as u8;
 | 
					            *b = p.dr().read().data() as u8;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        self.flush()?;
 | 
					        self.flush()?;
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn blocking_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let p = self.inner.regs();
 | 
					        let p = self.inner.regs();
 | 
				
			||||||
        let len = read.len().max(write.len());
 | 
					        let len = read.len().max(write.len());
 | 
				
			||||||
        for i in 0..len {
 | 
					        for i in 0..len {
 | 
				
			||||||
@ -177,23 +168,19 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
 | 
				
			|||||||
                *r = rb;
 | 
					                *r = rb;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        self.flush()?;
 | 
					        self.flush()?;
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn flush(&mut self) -> Result<(), Error> {
 | 
					    pub fn flush(&mut self) -> Result<(), Error> {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let p = self.inner.regs();
 | 
					        let p = self.inner.regs();
 | 
				
			||||||
        while p.sr().read().bsy() {}
 | 
					        while p.sr().read().bsy() {}
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn set_frequency(&mut self, freq: u32) {
 | 
					    pub fn set_frequency(&mut self, freq: u32) {
 | 
				
			||||||
        let (presc, postdiv) = calc_prescs(freq);
 | 
					        let (presc, postdiv) = calc_prescs(freq);
 | 
				
			||||||
        let p = self.inner.regs();
 | 
					        let p = self.inner.regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        // disable
 | 
					        // disable
 | 
				
			||||||
        p.cr1().write(|w| w.set_sse(false));
 | 
					        p.cr1().write(|w| w.set_sse(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -207,7 +194,6 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
 | 
				
			|||||||
        p.cr1().write(|w| w.set_sse(true));
 | 
					        p.cr1().write(|w| w.set_sse(true));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> Spi<'d, T, Blocking> {
 | 
					impl<'d, T: Instance> Spi<'d, T, Blocking> {
 | 
				
			||||||
    pub fn new_blocking(
 | 
					    pub fn new_blocking(
 | 
				
			||||||
@ -337,12 +323,11 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
 | 
				
			|||||||
        let tx_transfer = unsafe {
 | 
					        let tx_transfer = unsafe {
 | 
				
			||||||
            // If we don't assign future to a variable, the data register pointer
 | 
					            // If we don't assign future to a variable, the data register pointer
 | 
				
			||||||
            // is held across an await and makes the future non-Send.
 | 
					            // is held across an await and makes the future non-Send.
 | 
				
			||||||
            crate::dma::write(tx_ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ)
 | 
					            crate::dma::write(tx_ch, buffer, self.inner.regs().dr().as_ptr() as *mut _, T::TX_DREQ)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        tx_transfer.await;
 | 
					        tx_transfer.await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let p = self.inner.regs();
 | 
					        let p = self.inner.regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        while p.sr().read().bsy() {}
 | 
					        while p.sr().read().bsy() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // clear RX FIFO contents to prevent stale reads
 | 
					        // clear RX FIFO contents to prevent stale reads
 | 
				
			||||||
@ -351,7 +336,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        // clear RX overrun interrupt
 | 
					        // clear RX overrun interrupt
 | 
				
			||||||
        p.icr().write(|w| w.set_roric(true));
 | 
					        p.icr().write(|w| w.set_roric(true));
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -363,14 +347,19 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
 | 
				
			|||||||
        let rx_transfer = unsafe {
 | 
					        let rx_transfer = unsafe {
 | 
				
			||||||
            // If we don't assign future to a variable, the data register pointer
 | 
					            // If we don't assign future to a variable, the data register pointer
 | 
				
			||||||
            // is held across an await and makes the future non-Send.
 | 
					            // is held across an await and makes the future non-Send.
 | 
				
			||||||
            crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, buffer, T::RX_DREQ)
 | 
					            crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, buffer, T::RX_DREQ)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let tx_ch = self.tx_dma.as_mut().unwrap();
 | 
					        let tx_ch = self.tx_dma.as_mut().unwrap();
 | 
				
			||||||
        let tx_transfer = unsafe {
 | 
					        let tx_transfer = unsafe {
 | 
				
			||||||
            // If we don't assign future to a variable, the data register pointer
 | 
					            // If we don't assign future to a variable, the data register pointer
 | 
				
			||||||
            // is held across an await and makes the future non-Send.
 | 
					            // is held across an await and makes the future non-Send.
 | 
				
			||||||
            crate::dma::write_repeated(tx_ch, self.inner.regs().dr().ptr() as *mut u8, buffer.len(), T::TX_DREQ)
 | 
					            crate::dma::write_repeated(
 | 
				
			||||||
 | 
					                tx_ch,
 | 
				
			||||||
 | 
					                self.inner.regs().dr().as_ptr() as *mut u8,
 | 
				
			||||||
 | 
					                buffer.len(),
 | 
				
			||||||
 | 
					                T::TX_DREQ,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        join(tx_transfer, rx_transfer).await;
 | 
					        join(tx_transfer, rx_transfer).await;
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
@ -394,7 +383,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
 | 
				
			|||||||
        let rx_transfer = unsafe {
 | 
					        let rx_transfer = unsafe {
 | 
				
			||||||
            // If we don't assign future to a variable, the data register pointer
 | 
					            // If we don't assign future to a variable, the data register pointer
 | 
				
			||||||
            // is held across an await and makes the future non-Send.
 | 
					            // is held across an await and makes the future non-Send.
 | 
				
			||||||
            crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, rx_ptr, T::RX_DREQ)
 | 
					            crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, rx_ptr, T::RX_DREQ)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut tx_ch = self.tx_dma.as_mut().unwrap();
 | 
					        let mut tx_ch = self.tx_dma.as_mut().unwrap();
 | 
				
			||||||
@ -403,13 +392,13 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
 | 
				
			|||||||
        let tx_transfer = async {
 | 
					        let tx_transfer = async {
 | 
				
			||||||
            let p = self.inner.regs();
 | 
					            let p = self.inner.regs();
 | 
				
			||||||
            unsafe {
 | 
					            unsafe {
 | 
				
			||||||
                crate::dma::write(&mut tx_ch, tx_ptr, p.dr().ptr() as *mut _, T::TX_DREQ).await;
 | 
					                crate::dma::write(&mut tx_ch, tx_ptr, p.dr().as_ptr() as *mut _, T::TX_DREQ).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if rx_len > tx_len {
 | 
					                if rx_len > tx_len {
 | 
				
			||||||
                    let write_bytes_len = rx_len - tx_len;
 | 
					                    let write_bytes_len = rx_len - tx_len;
 | 
				
			||||||
                    // write dummy data
 | 
					                    // write dummy data
 | 
				
			||||||
                    // this will disable incrementation of the buffers
 | 
					                    // this will disable incrementation of the buffers
 | 
				
			||||||
                    crate::dma::write_repeated(tx_ch, p.dr().ptr() as *mut u8, write_bytes_len, T::TX_DREQ).await
 | 
					                    crate::dma::write_repeated(tx_ch, p.dr().as_ptr() as *mut u8, write_bytes_len, T::TX_DREQ).await
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
@ -418,7 +407,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
 | 
				
			|||||||
        // if tx > rx we should clear any overflow of the FIFO SPI buffer
 | 
					        // if tx > rx we should clear any overflow of the FIFO SPI buffer
 | 
				
			||||||
        if tx_len > rx_len {
 | 
					        if tx_len > rx_len {
 | 
				
			||||||
            let p = self.inner.regs();
 | 
					            let p = self.inner.regs();
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            while p.sr().read().bsy() {}
 | 
					            while p.sr().read().bsy() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // clear RX FIFO contents to prevent stale reads
 | 
					            // clear RX FIFO contents to prevent stale reads
 | 
				
			||||||
@ -428,7 +416,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
 | 
				
			|||||||
            // clear RX overrun interrupt
 | 
					            // clear RX overrun interrupt
 | 
				
			||||||
            p.icr().write(|w| w.set_roric(true));
 | 
					            p.icr().write(|w| w.set_roric(true));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -625,7 +612,6 @@ impl<'d, T: Instance, M: Mode> SetConfig for Spi<'d, T, M> {
 | 
				
			|||||||
    fn set_config(&mut self, config: &Self::Config) {
 | 
					    fn set_config(&mut self, config: &Self::Config) {
 | 
				
			||||||
        let p = self.inner.regs();
 | 
					        let p = self.inner.regs();
 | 
				
			||||||
        let (presc, postdiv) = calc_prescs(config.frequency);
 | 
					        let (presc, postdiv) = calc_prescs(config.frequency);
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        p.cpsr().write(|w| w.set_cpsdvsr(presc));
 | 
					        p.cpsr().write(|w| w.set_cpsdvsr(presc));
 | 
				
			||||||
        p.cr0().write(|w| {
 | 
					        p.cr0().write(|w| {
 | 
				
			||||||
            w.set_dss(0b0111); // 8bit
 | 
					            w.set_dss(0b0111); // 8bit
 | 
				
			||||||
@ -635,4 +621,3 @@ impl<'d, T: Instance, M: Mode> SetConfig for Spi<'d, T, M> {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,6 @@ embassy_time::time_driver_impl!(static DRIVER: TimerDriver = TimerDriver{
 | 
				
			|||||||
impl Driver for TimerDriver {
 | 
					impl Driver for TimerDriver {
 | 
				
			||||||
    fn now(&self) -> u64 {
 | 
					    fn now(&self) -> u64 {
 | 
				
			||||||
        loop {
 | 
					        loop {
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            let hi = pac::TIMER.timerawh().read();
 | 
					            let hi = pac::TIMER.timerawh().read();
 | 
				
			||||||
            let lo = pac::TIMER.timerawl().read();
 | 
					            let lo = pac::TIMER.timerawl().read();
 | 
				
			||||||
            let hi2 = pac::TIMER.timerawh().read();
 | 
					            let hi2 = pac::TIMER.timerawh().read();
 | 
				
			||||||
@ -43,7 +42,6 @@ impl Driver for TimerDriver {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
 | 
					    unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
 | 
				
			||||||
        let id = self.next_alarm.fetch_update(Ordering::AcqRel, Ordering::Acquire, |x| {
 | 
					        let id = self.next_alarm.fetch_update(Ordering::AcqRel, Ordering::Acquire, |x| {
 | 
				
			||||||
@ -78,13 +76,13 @@ impl Driver for TimerDriver {
 | 
				
			|||||||
            // Note that we're not checking the high bits at all. This means the irq may fire early
 | 
					            // Note that we're not checking the high bits at all. This means the irq may fire early
 | 
				
			||||||
            // if the alarm is more than 72 minutes (2^32 us) in the future. This is OK, since on irq fire
 | 
					            // if the alarm is more than 72 minutes (2^32 us) in the future. This is OK, since on irq fire
 | 
				
			||||||
            // it is checked if the alarm time has passed.
 | 
					            // it is checked if the alarm time has passed.
 | 
				
			||||||
            unsafe { pac::TIMER.alarm(n).write_value(timestamp as u32) };
 | 
					            pac::TIMER.alarm(n).write_value(timestamp as u32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let now = self.now();
 | 
					            let now = self.now();
 | 
				
			||||||
            if timestamp <= now {
 | 
					            if timestamp <= now {
 | 
				
			||||||
                // If alarm timestamp has passed the alarm will not fire.
 | 
					                // If alarm timestamp has passed the alarm will not fire.
 | 
				
			||||||
                // Disarm the alarm and return `false` to indicate that.
 | 
					                // Disarm the alarm and return `false` to indicate that.
 | 
				
			||||||
                unsafe { pac::TIMER.armed().write(|w| w.set_armed(1 << n)) }
 | 
					                pac::TIMER.armed().write(|w| w.set_armed(1 << n));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                alarm.timestamp.set(u64::MAX);
 | 
					                alarm.timestamp.set(u64::MAX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -106,17 +104,17 @@ impl TimerDriver {
 | 
				
			|||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                // Not elapsed, arm it again.
 | 
					                // Not elapsed, arm it again.
 | 
				
			||||||
                // This can happen if it was set more than 2^32 us in the future.
 | 
					                // This can happen if it was set more than 2^32 us in the future.
 | 
				
			||||||
                unsafe { pac::TIMER.alarm(n).write_value(timestamp as u32) };
 | 
					                pac::TIMER.alarm(n).write_value(timestamp as u32);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // clear the irq
 | 
					        // clear the irq
 | 
				
			||||||
        unsafe { pac::TIMER.intr().write(|w| w.set_alarm(n, true)) }
 | 
					        pac::TIMER.intr().write(|w| w.set_alarm(n, true));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn trigger_alarm(&self, n: usize, cs: CriticalSection) {
 | 
					    fn trigger_alarm(&self, n: usize, cs: CriticalSection) {
 | 
				
			||||||
        // disarm
 | 
					        // disarm
 | 
				
			||||||
        unsafe { pac::TIMER.armed().write(|w| w.set_armed(1 << n)) }
 | 
					        pac::TIMER.armed().write(|w| w.set_armed(1 << n));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let alarm = &self.alarms.borrow(cs)[n];
 | 
					        let alarm = &self.alarms.borrow(cs)[n];
 | 
				
			||||||
        alarm.timestamp.set(u64::MAX);
 | 
					        alarm.timestamp.set(u64::MAX);
 | 
				
			||||||
@ -153,24 +151,24 @@ pub unsafe fn init() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "rt")]
 | 
					#[cfg(feature = "rt")]
 | 
				
			||||||
#[interrupt]
 | 
					#[interrupt]
 | 
				
			||||||
unsafe fn TIMER_IRQ_0() {
 | 
					fn TIMER_IRQ_0() {
 | 
				
			||||||
    DRIVER.check_alarm(0)
 | 
					    DRIVER.check_alarm(0)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "rt")]
 | 
					#[cfg(feature = "rt")]
 | 
				
			||||||
#[interrupt]
 | 
					#[interrupt]
 | 
				
			||||||
unsafe fn TIMER_IRQ_1() {
 | 
					fn TIMER_IRQ_1() {
 | 
				
			||||||
    DRIVER.check_alarm(1)
 | 
					    DRIVER.check_alarm(1)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "rt")]
 | 
					#[cfg(feature = "rt")]
 | 
				
			||||||
#[interrupt]
 | 
					#[interrupt]
 | 
				
			||||||
unsafe fn TIMER_IRQ_2() {
 | 
					fn TIMER_IRQ_2() {
 | 
				
			||||||
    DRIVER.check_alarm(2)
 | 
					    DRIVER.check_alarm(2)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "rt")]
 | 
					#[cfg(feature = "rt")]
 | 
				
			||||||
#[interrupt]
 | 
					#[interrupt]
 | 
				
			||||||
unsafe fn TIMER_IRQ_3() {
 | 
					fn TIMER_IRQ_3() {
 | 
				
			||||||
    DRIVER.check_alarm(3)
 | 
					    DRIVER.check_alarm(3)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -73,7 +73,6 @@ pub(crate) fn init_buffers<'d, T: Instance + 'd>(
 | 
				
			|||||||
    // we clear it after it happens. The downside is that the we manually have
 | 
					    // we clear it after it happens. The downside is that the we manually have
 | 
				
			||||||
    // to pend the ISR when we want data transmission to start.
 | 
					    // to pend the ISR when we want data transmission to start.
 | 
				
			||||||
    let regs = T::regs();
 | 
					    let regs = T::regs();
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
    regs.uartimsc().write(|w| {
 | 
					    regs.uartimsc().write(|w| {
 | 
				
			||||||
        w.set_rxim(true);
 | 
					        w.set_rxim(true);
 | 
				
			||||||
        w.set_rtim(true);
 | 
					        w.set_rtim(true);
 | 
				
			||||||
@ -81,8 +80,7 @@ pub(crate) fn init_buffers<'d, T: Instance + 'd>(
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    T::Interrupt::unpend();
 | 
					    T::Interrupt::unpend();
 | 
				
			||||||
        T::Interrupt::enable();
 | 
					    unsafe { T::Interrupt::enable() };
 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> BufferedUart<'d, T> {
 | 
					impl<'d, T: Instance> BufferedUart<'d, T> {
 | 
				
			||||||
@ -247,12 +245,10 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
 | 
				
			|||||||
        // (Re-)Enable the interrupt to receive more data in case it was
 | 
					        // (Re-)Enable the interrupt to receive more data in case it was
 | 
				
			||||||
        // disabled because the buffer was full or errors were detected.
 | 
					        // disabled because the buffer was full or errors were detected.
 | 
				
			||||||
        let regs = T::regs();
 | 
					        let regs = T::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        regs.uartimsc().write_set(|w| {
 | 
					        regs.uartimsc().write_set(|w| {
 | 
				
			||||||
            w.set_rxim(true);
 | 
					            w.set_rxim(true);
 | 
				
			||||||
            w.set_rtim(true);
 | 
					            w.set_rtim(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poll::Ready(result)
 | 
					        Poll::Ready(result)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -299,14 +295,12 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
 | 
				
			|||||||
        // (Re-)Enable the interrupt to receive more data in case it was
 | 
					        // (Re-)Enable the interrupt to receive more data in case it was
 | 
				
			||||||
        // disabled because the buffer was full or errors were detected.
 | 
					        // disabled because the buffer was full or errors were detected.
 | 
				
			||||||
        let regs = T::regs();
 | 
					        let regs = T::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        regs.uartimsc().write_set(|w| {
 | 
					        regs.uartimsc().write_set(|w| {
 | 
				
			||||||
            w.set_rxim(true);
 | 
					            w.set_rxim(true);
 | 
				
			||||||
            w.set_rtim(true);
 | 
					            w.set_rtim(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> BufferedUartTx<'d, T> {
 | 
					impl<'d, T: Instance> BufferedUartTx<'d, T> {
 | 
				
			||||||
    pub fn new(
 | 
					    pub fn new(
 | 
				
			||||||
@ -414,7 +408,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn busy(&self) -> bool {
 | 
					    pub fn busy(&self) -> bool {
 | 
				
			||||||
        unsafe { T::regs().uartfr().read().busy() }
 | 
					        T::regs().uartfr().read().busy()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Assert a break condition after waiting for the transmit buffers to empty,
 | 
					    /// Assert a break condition after waiting for the transmit buffers to empty,
 | 
				
			||||||
@ -426,36 +420,30 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
 | 
				
			|||||||
    /// for the transmit fifo to empty, which may take a while on slow links.
 | 
					    /// for the transmit fifo to empty, which may take a while on slow links.
 | 
				
			||||||
    pub async fn send_break(&mut self, bits: u32) {
 | 
					    pub async fn send_break(&mut self, bits: u32) {
 | 
				
			||||||
        let regs = T::regs();
 | 
					        let regs = T::regs();
 | 
				
			||||||
        let bits = bits.max(unsafe {
 | 
					        let bits = bits.max({
 | 
				
			||||||
            let lcr = regs.uartlcr_h().read();
 | 
					            let lcr = regs.uartlcr_h().read();
 | 
				
			||||||
            let width = lcr.wlen() as u32 + 5;
 | 
					            let width = lcr.wlen() as u32 + 5;
 | 
				
			||||||
            let parity = lcr.pen() as u32;
 | 
					            let parity = lcr.pen() as u32;
 | 
				
			||||||
            let stops = 1 + lcr.stp2() as u32;
 | 
					            let stops = 1 + lcr.stp2() as u32;
 | 
				
			||||||
            2 * (1 + width + parity + stops)
 | 
					            2 * (1 + width + parity + stops)
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        let divx64 = unsafe {
 | 
					        let divx64 = (((regs.uartibrd().read().baud_divint() as u32) << 6)
 | 
				
			||||||
            ((regs.uartibrd().read().baud_divint() as u32) << 6) + regs.uartfbrd().read().baud_divfrac() as u32
 | 
					            + regs.uartfbrd().read().baud_divfrac() as u32) as u64;
 | 
				
			||||||
        } as u64;
 | 
					 | 
				
			||||||
        let div_clk = clk_peri_freq() as u64 * 64;
 | 
					        let div_clk = clk_peri_freq() as u64 * 64;
 | 
				
			||||||
        let wait_usecs = (1_000_000 * bits as u64 * divx64 * 16 + div_clk - 1) / div_clk;
 | 
					        let wait_usecs = (1_000_000 * bits as u64 * divx64 * 16 + div_clk - 1) / div_clk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Self::flush().await.unwrap();
 | 
					        Self::flush().await.unwrap();
 | 
				
			||||||
        while self.busy() {}
 | 
					        while self.busy() {}
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        regs.uartlcr_h().write_set(|w| w.set_brk(true));
 | 
					        regs.uartlcr_h().write_set(|w| w.set_brk(true));
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Timer::after(Duration::from_micros(wait_usecs)).await;
 | 
					        Timer::after(Duration::from_micros(wait_usecs)).await;
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        regs.uartlcr_h().write_clear(|w| w.set_brk(true));
 | 
					        regs.uartlcr_h().write_clear(|w| w.set_brk(true));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> Drop for BufferedUartRx<'d, T> {
 | 
					impl<'d, T: Instance> Drop for BufferedUartRx<'d, T> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        let state = T::buffered_state();
 | 
					        let state = T::buffered_state();
 | 
				
			||||||
        unsafe {
 | 
					        unsafe { state.rx_buf.deinit() }
 | 
				
			||||||
            state.rx_buf.deinit();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TX is inactive if the the buffer is not available.
 | 
					        // TX is inactive if the the buffer is not available.
 | 
				
			||||||
        // We can now unregister the interrupt handler
 | 
					        // We can now unregister the interrupt handler
 | 
				
			||||||
@ -464,13 +452,11 @@ impl<'d, T: Instance> Drop for BufferedUartRx<'d, T> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> Drop for BufferedUartTx<'d, T> {
 | 
					impl<'d, T: Instance> Drop for BufferedUartTx<'d, T> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        let state = T::buffered_state();
 | 
					        let state = T::buffered_state();
 | 
				
			||||||
        unsafe {
 | 
					        unsafe { state.tx_buf.deinit() }
 | 
				
			||||||
            state.tx_buf.deinit();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // RX is inactive if the the buffer is not available.
 | 
					        // RX is inactive if the the buffer is not available.
 | 
				
			||||||
        // We can now unregister the interrupt handler
 | 
					        // We can now unregister the interrupt handler
 | 
				
			||||||
@ -479,7 +465,6 @@ impl<'d, T: Instance> Drop for BufferedUartTx<'d, T> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct BufferedInterruptHandler<T: Instance> {
 | 
					pub struct BufferedInterruptHandler<T: Instance> {
 | 
				
			||||||
    _uart: PhantomData<T>,
 | 
					    _uart: PhantomData<T>,
 | 
				
			||||||
@ -494,7 +479,6 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let s = T::buffered_state();
 | 
					        let s = T::buffered_state();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        // Clear TX and error interrupt flags
 | 
					        // Clear TX and error interrupt flags
 | 
				
			||||||
        // RX interrupt flags are cleared by reading from the FIFO.
 | 
					        // RX interrupt flags are cleared by reading from the FIFO.
 | 
				
			||||||
        let ris = r.uartris().read();
 | 
					        let ris = r.uartris().read();
 | 
				
			||||||
@ -523,7 +507,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterr
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // RX
 | 
					        // RX
 | 
				
			||||||
            let mut rx_writer = s.rx_buf.writer();
 | 
					        let mut rx_writer = unsafe { s.rx_buf.writer() };
 | 
				
			||||||
        let rx_buf = rx_writer.push_slice();
 | 
					        let rx_buf = rx_writer.push_slice();
 | 
				
			||||||
        let mut n_read = 0;
 | 
					        let mut n_read = 0;
 | 
				
			||||||
        let mut error = false;
 | 
					        let mut error = false;
 | 
				
			||||||
@ -564,7 +548,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterr
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TX
 | 
					        // TX
 | 
				
			||||||
            let mut tx_reader = s.tx_buf.reader();
 | 
					        let mut tx_reader = unsafe { s.tx_buf.reader() };
 | 
				
			||||||
        let tx_buf = tx_reader.pop_slice();
 | 
					        let tx_buf = tx_reader.pop_slice();
 | 
				
			||||||
        let mut n_written = 0;
 | 
					        let mut n_written = 0;
 | 
				
			||||||
        for tx_byte in tx_buf.iter_mut() {
 | 
					        for tx_byte in tx_buf.iter_mut() {
 | 
				
			||||||
@ -583,7 +567,6 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterr
 | 
				
			|||||||
        // as it does re-trigger anymore once we have cleared it.
 | 
					        // as it does re-trigger anymore once we have cleared it.
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl embedded_io::Error for Error {
 | 
					impl embedded_io::Error for Error {
 | 
				
			||||||
    fn kind(&self) -> embedded_io::ErrorKind {
 | 
					    fn kind(&self) -> embedded_io::ErrorKind {
 | 
				
			||||||
@ -695,7 +678,6 @@ mod eh02 {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
 | 
					        fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
 | 
				
			||||||
            let r = T::regs();
 | 
					            let r = T::regs();
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            if r.uartfr().read().rxfe() {
 | 
					            if r.uartfr().read().rxfe() {
 | 
				
			||||||
                return Err(nb::Error::WouldBlock);
 | 
					                return Err(nb::Error::WouldBlock);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -715,7 +697,6 @@ mod eh02 {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d, T> {
 | 
					    impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d, T> {
 | 
				
			||||||
        type Error = Error;
 | 
					        type Error = Error;
 | 
				
			||||||
 | 
				
			|||||||
@ -146,23 +146,21 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
 | 
				
			||||||
        let r = T::regs();
 | 
					        let r = T::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        for &b in buffer {
 | 
					        for &b in buffer {
 | 
				
			||||||
            while r.uartfr().read().txff() {}
 | 
					            while r.uartfr().read().txff() {}
 | 
				
			||||||
            r.uartdr().write(|w| w.set_data(b));
 | 
					            r.uartdr().write(|w| w.set_data(b));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn blocking_flush(&mut self) -> Result<(), Error> {
 | 
					    pub fn blocking_flush(&mut self) -> Result<(), Error> {
 | 
				
			||||||
        let r = T::regs();
 | 
					        let r = T::regs();
 | 
				
			||||||
        unsafe { while !r.uartfr().read().txfe() {} }
 | 
					        while !r.uartfr().read().txfe() {}
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn busy(&self) -> bool {
 | 
					    pub fn busy(&self) -> bool {
 | 
				
			||||||
        unsafe { T::regs().uartfr().read().busy() }
 | 
					        T::regs().uartfr().read().busy()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Assert a break condition after waiting for the transmit buffers to empty,
 | 
					    /// Assert a break condition after waiting for the transmit buffers to empty,
 | 
				
			||||||
@ -174,30 +172,25 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
 | 
				
			|||||||
    /// for the transmit fifo to empty, which may take a while on slow links.
 | 
					    /// for the transmit fifo to empty, which may take a while on slow links.
 | 
				
			||||||
    pub async fn send_break(&mut self, bits: u32) {
 | 
					    pub async fn send_break(&mut self, bits: u32) {
 | 
				
			||||||
        let regs = T::regs();
 | 
					        let regs = T::regs();
 | 
				
			||||||
        let bits = bits.max(unsafe {
 | 
					        let bits = bits.max({
 | 
				
			||||||
            let lcr = regs.uartlcr_h().read();
 | 
					            let lcr = regs.uartlcr_h().read();
 | 
				
			||||||
            let width = lcr.wlen() as u32 + 5;
 | 
					            let width = lcr.wlen() as u32 + 5;
 | 
				
			||||||
            let parity = lcr.pen() as u32;
 | 
					            let parity = lcr.pen() as u32;
 | 
				
			||||||
            let stops = 1 + lcr.stp2() as u32;
 | 
					            let stops = 1 + lcr.stp2() as u32;
 | 
				
			||||||
            2 * (1 + width + parity + stops)
 | 
					            2 * (1 + width + parity + stops)
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        let divx64 = unsafe {
 | 
					        let divx64 = (((regs.uartibrd().read().baud_divint() as u32) << 6)
 | 
				
			||||||
            ((regs.uartibrd().read().baud_divint() as u32) << 6) + regs.uartfbrd().read().baud_divfrac() as u32
 | 
					            + regs.uartfbrd().read().baud_divfrac() as u32) as u64;
 | 
				
			||||||
        } as u64;
 | 
					 | 
				
			||||||
        let div_clk = clk_peri_freq() as u64 * 64;
 | 
					        let div_clk = clk_peri_freq() as u64 * 64;
 | 
				
			||||||
        let wait_usecs = (1_000_000 * bits as u64 * divx64 * 16 + div_clk - 1) / div_clk;
 | 
					        let wait_usecs = (1_000_000 * bits as u64 * divx64 * 16 + div_clk - 1) / div_clk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.blocking_flush().unwrap();
 | 
					        self.blocking_flush().unwrap();
 | 
				
			||||||
        while self.busy() {}
 | 
					        while self.busy() {}
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        regs.uartlcr_h().write_set(|w| w.set_brk(true));
 | 
					        regs.uartlcr_h().write_set(|w| w.set_brk(true));
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Timer::after(Duration::from_micros(wait_usecs)).await;
 | 
					        Timer::after(Duration::from_micros(wait_usecs)).await;
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        regs.uartlcr_h().write_clear(|w| w.set_brk(true));
 | 
					        regs.uartlcr_h().write_clear(|w| w.set_brk(true));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> UartTx<'d, T, Blocking> {
 | 
					impl<'d, T: Instance> UartTx<'d, T, Blocking> {
 | 
				
			||||||
    #[cfg(feature = "nightly")]
 | 
					    #[cfg(feature = "nightly")]
 | 
				
			||||||
@ -221,7 +214,7 @@ impl<'d, T: Instance> UartTx<'d, T, Async> {
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
            // If we don't assign future to a variable, the data register pointer
 | 
					            // If we don't assign future to a variable, the data register pointer
 | 
				
			||||||
            // is held across an await and makes the future non-Send.
 | 
					            // is held across an await and makes the future non-Send.
 | 
				
			||||||
            crate::dma::write(ch, buffer, T::regs().uartdr().ptr() as *mut _, T::TX_DREQ)
 | 
					            crate::dma::write(ch, buffer, T::regs().uartdr().as_ptr() as *mut _, T::TX_DREQ)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        transfer.await;
 | 
					        transfer.await;
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
@ -246,7 +239,7 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> {
 | 
				
			|||||||
        debug_assert_eq!(has_irq, rx_dma.is_some());
 | 
					        debug_assert_eq!(has_irq, rx_dma.is_some());
 | 
				
			||||||
        if has_irq {
 | 
					        if has_irq {
 | 
				
			||||||
            // disable all error interrupts initially
 | 
					            // disable all error interrupts initially
 | 
				
			||||||
            unsafe { T::regs().uartimsc().write(|w| w.0 = 0) }
 | 
					            T::regs().uartimsc().write(|w| w.0 = 0);
 | 
				
			||||||
            T::Interrupt::unpend();
 | 
					            T::Interrupt::unpend();
 | 
				
			||||||
            unsafe { T::Interrupt::enable() };
 | 
					            unsafe { T::Interrupt::enable() };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -267,11 +260,11 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> {
 | 
				
			|||||||
    fn drain_fifo(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
 | 
					    fn drain_fifo(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
 | 
				
			||||||
        let r = T::regs();
 | 
					        let r = T::regs();
 | 
				
			||||||
        for (i, b) in buffer.iter_mut().enumerate() {
 | 
					        for (i, b) in buffer.iter_mut().enumerate() {
 | 
				
			||||||
            if unsafe { r.uartfr().read().rxfe() } {
 | 
					            if r.uartfr().read().rxfe() {
 | 
				
			||||||
                return Ok(i);
 | 
					                return Ok(i);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let dr = unsafe { r.uartdr().read() };
 | 
					            let dr = r.uartdr().read();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if dr.oe() {
 | 
					            if dr.oe() {
 | 
				
			||||||
                return Err(Error::Overrun);
 | 
					                return Err(Error::Overrun);
 | 
				
			||||||
@ -292,7 +285,6 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> {
 | 
				
			|||||||
impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> {
 | 
					impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        if let Some(_) = self.rx_dma {
 | 
					        if let Some(_) = self.rx_dma {
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            T::Interrupt::disable();
 | 
					            T::Interrupt::disable();
 | 
				
			||||||
            // clear dma flags. irq handlers use these to disambiguate among themselves.
 | 
					            // clear dma flags. irq handlers use these to disambiguate among themselves.
 | 
				
			||||||
            T::regs().uartdmacr().write_clear(|reg| {
 | 
					            T::regs().uartdmacr().write_clear(|reg| {
 | 
				
			||||||
@ -303,7 +295,6 @@ impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> UartRx<'d, T, Blocking> {
 | 
					impl<'d, T: Instance> UartRx<'d, T, Blocking> {
 | 
				
			||||||
    pub fn new_blocking(
 | 
					    pub fn new_blocking(
 | 
				
			||||||
@ -355,14 +346,12 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
 | 
				
			|||||||
        // clear error flags before we drain the fifo. errors that have accumulated
 | 
					        // clear error flags before we drain the fifo. errors that have accumulated
 | 
				
			||||||
        // in the flags will also be present in the fifo.
 | 
					        // in the flags will also be present in the fifo.
 | 
				
			||||||
        T::dma_state().rx_errs.store(0, Ordering::Relaxed);
 | 
					        T::dma_state().rx_errs.store(0, Ordering::Relaxed);
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        T::regs().uarticr().write(|w| {
 | 
					        T::regs().uarticr().write(|w| {
 | 
				
			||||||
            w.set_oeic(true);
 | 
					            w.set_oeic(true);
 | 
				
			||||||
            w.set_beic(true);
 | 
					            w.set_beic(true);
 | 
				
			||||||
            w.set_peic(true);
 | 
					            w.set_peic(true);
 | 
				
			||||||
            w.set_feic(true);
 | 
					            w.set_feic(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // then drain the fifo. we need to read at most 32 bytes. errors that apply
 | 
					        // then drain the fifo. we need to read at most 32 bytes. errors that apply
 | 
				
			||||||
        // to fifo bytes will be reported directly.
 | 
					        // to fifo bytes will be reported directly.
 | 
				
			||||||
@ -379,7 +368,6 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
 | 
				
			|||||||
        // interrupt flags will have been raised, and those will be picked up immediately
 | 
					        // interrupt flags will have been raised, and those will be picked up immediately
 | 
				
			||||||
        // by the interrupt handler.
 | 
					        // by the interrupt handler.
 | 
				
			||||||
        let ch = self.rx_dma.as_mut().unwrap();
 | 
					        let ch = self.rx_dma.as_mut().unwrap();
 | 
				
			||||||
        let transfer = unsafe {
 | 
					 | 
				
			||||||
        T::regs().uartimsc().write_set(|w| {
 | 
					        T::regs().uartimsc().write_set(|w| {
 | 
				
			||||||
            w.set_oeim(true);
 | 
					            w.set_oeim(true);
 | 
				
			||||||
            w.set_beim(true);
 | 
					            w.set_beim(true);
 | 
				
			||||||
@ -390,9 +378,10 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
 | 
				
			|||||||
            reg.set_rxdmae(true);
 | 
					            reg.set_rxdmae(true);
 | 
				
			||||||
            reg.set_dmaonerr(true);
 | 
					            reg.set_dmaonerr(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					        let transfer = unsafe {
 | 
				
			||||||
            // If we don't assign future to a variable, the data register pointer
 | 
					            // If we don't assign future to a variable, the data register pointer
 | 
				
			||||||
            // is held across an await and makes the future non-Send.
 | 
					            // is held across an await and makes the future non-Send.
 | 
				
			||||||
            crate::dma::read(ch, T::regs().uartdr().ptr() as *const _, buffer, T::RX_DREQ)
 | 
					            crate::dma::read(ch, T::regs().uartdr().as_ptr() as *const _, buffer, T::RX_DREQ)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // wait for either the transfer to complete or an error to happen.
 | 
					        // wait for either the transfer to complete or an error to happen.
 | 
				
			||||||
@ -575,7 +564,6 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
 | 
				
			|||||||
        config: Config,
 | 
					        config: Config,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        let r = T::regs();
 | 
					        let r = T::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        if let Some(pin) = &tx {
 | 
					        if let Some(pin) = &tx {
 | 
				
			||||||
            pin.io().ctrl().write(|w| {
 | 
					            pin.io().ctrl().write(|w| {
 | 
				
			||||||
                w.set_funcsel(2);
 | 
					                w.set_funcsel(2);
 | 
				
			||||||
@ -650,7 +638,6 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
 | 
				
			|||||||
            w.set_rtsen(rts.is_some());
 | 
					            w.set_rtsen(rts.is_some());
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// sets baudrate on runtime    
 | 
					    /// sets baudrate on runtime    
 | 
				
			||||||
    pub fn set_baudrate(&mut self, baudrate: u32) {
 | 
					    pub fn set_baudrate(&mut self, baudrate: u32) {
 | 
				
			||||||
@ -674,7 +661,6 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
 | 
				
			|||||||
            baud_fbrd = 0;
 | 
					            baud_fbrd = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        // Load PL011's baud divisor registers
 | 
					        // Load PL011's baud divisor registers
 | 
				
			||||||
        r.uartibrd().write_value(pac::uart::regs::Uartibrd(baud_ibrd));
 | 
					        r.uartibrd().write_value(pac::uart::regs::Uartibrd(baud_ibrd));
 | 
				
			||||||
        r.uartfbrd().write_value(pac::uart::regs::Uartfbrd(baud_fbrd));
 | 
					        r.uartfbrd().write_value(pac::uart::regs::Uartfbrd(baud_fbrd));
 | 
				
			||||||
@ -684,7 +670,6 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
 | 
				
			|||||||
        r.uartlcr_h().modify(|_| {});
 | 
					        r.uartlcr_h().modify(|_| {});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance, M: Mode> Uart<'d, T, M> {
 | 
					impl<'d, T: Instance, M: Mode> Uart<'d, T, M> {
 | 
				
			||||||
    pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
 | 
					    pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
 | 
				
			||||||
@ -731,7 +716,6 @@ mod eh02 {
 | 
				
			|||||||
        type Error = Error;
 | 
					        type Error = Error;
 | 
				
			||||||
        fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
 | 
					        fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
 | 
				
			||||||
            let r = T::regs();
 | 
					            let r = T::regs();
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            if r.uartfr().read().rxfe() {
 | 
					            if r.uartfr().read().rxfe() {
 | 
				
			||||||
                return Err(nb::Error::WouldBlock);
 | 
					                return Err(nb::Error::WouldBlock);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -751,30 +735,25 @@ mod eh02 {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for UartTx<'d, T, M> {
 | 
					    impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for UartTx<'d, T, M> {
 | 
				
			||||||
        type Error = Error;
 | 
					        type Error = Error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fn write(&mut self, word: u8) -> Result<(), nb::Error<Self::Error>> {
 | 
					        fn write(&mut self, word: u8) -> Result<(), nb::Error<Self::Error>> {
 | 
				
			||||||
            let r = T::regs();
 | 
					            let r = T::regs();
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            if r.uartfr().read().txff() {
 | 
					            if r.uartfr().read().txff() {
 | 
				
			||||||
                return Err(nb::Error::WouldBlock);
 | 
					                return Err(nb::Error::WouldBlock);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            r.uartdr().write(|w| w.set_data(word));
 | 
					            r.uartdr().write(|w| w.set_data(word));
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Ok(())
 | 
					            Ok(())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fn flush(&mut self) -> Result<(), nb::Error<Self::Error>> {
 | 
					        fn flush(&mut self) -> Result<(), nb::Error<Self::Error>> {
 | 
				
			||||||
            let r = T::regs();
 | 
					            let r = T::regs();
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            if !r.uartfr().read().txfe() {
 | 
					            if !r.uartfr().read().txfe() {
 | 
				
			||||||
                return Err(nb::Error::WouldBlock);
 | 
					                return Err(nb::Error::WouldBlock);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Ok(())
 | 
					            Ok(())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -854,7 +833,6 @@ mod eh1 {
 | 
				
			|||||||
    impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, T, M> {
 | 
					    impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, T, M> {
 | 
				
			||||||
        fn read(&mut self) -> nb::Result<u8, Self::Error> {
 | 
					        fn read(&mut self) -> nb::Result<u8, Self::Error> {
 | 
				
			||||||
            let r = T::regs();
 | 
					            let r = T::regs();
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            let dr = r.uartdr().read();
 | 
					            let dr = r.uartdr().read();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if dr.oe() {
 | 
					            if dr.oe() {
 | 
				
			||||||
@ -872,7 +850,6 @@ mod eh1 {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    impl<'d, T: Instance, M: Mode> embedded_hal_1::serial::Write for UartTx<'d, T, M> {
 | 
					    impl<'d, T: Instance, M: Mode> embedded_hal_1::serial::Write for UartTx<'d, T, M> {
 | 
				
			||||||
        fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
 | 
					        fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@ impl crate::usb::Instance for peripherals::USB {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const EP_COUNT: usize = 16;
 | 
					const EP_COUNT: usize = 16;
 | 
				
			||||||
const EP_MEMORY_SIZE: usize = 4096;
 | 
					const EP_MEMORY_SIZE: usize = 4096;
 | 
				
			||||||
const EP_MEMORY: *mut u8 = pac::USBCTRL_DPRAM.0;
 | 
					const EP_MEMORY: *mut u8 = pac::USBCTRL_DPRAM.as_ptr() as *mut u8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
 | 
					const NEW_AW: AtomicWaker = AtomicWaker::new();
 | 
				
			||||||
static BUS_WAKER: AtomicWaker = NEW_AW;
 | 
					static BUS_WAKER: AtomicWaker = NEW_AW;
 | 
				
			||||||
@ -111,7 +111,7 @@ impl<'d, T: Instance> Driver<'d, T> {
 | 
				
			|||||||
        let regs = T::regs();
 | 
					        let regs = T::regs();
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            // zero fill regs
 | 
					            // zero fill regs
 | 
				
			||||||
            let p = regs.0 as *mut u32;
 | 
					            let p = regs.as_ptr() as *mut u32;
 | 
				
			||||||
            for i in 0..0x9c / 4 {
 | 
					            for i in 0..0x9c / 4 {
 | 
				
			||||||
                p.add(i).write_volatile(0)
 | 
					                p.add(i).write_volatile(0)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -121,6 +121,7 @@ impl<'d, T: Instance> Driver<'d, T> {
 | 
				
			|||||||
            for i in 0..0x100 / 4 {
 | 
					            for i in 0..0x100 / 4 {
 | 
				
			||||||
                p.add(i).write_volatile(0)
 | 
					                p.add(i).write_volatile(0)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        regs.usb_muxing().write(|w| {
 | 
					        regs.usb_muxing().write(|w| {
 | 
				
			||||||
            w.set_to_phy(true);
 | 
					            w.set_to_phy(true);
 | 
				
			||||||
@ -133,7 +134,6 @@ impl<'d, T: Instance> Driver<'d, T> {
 | 
				
			|||||||
        regs.main_ctrl().write(|w| {
 | 
					        regs.main_ctrl().write(|w| {
 | 
				
			||||||
            w.set_controller_en(true);
 | 
					            w.set_controller_en(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Initialize the bus so that it signals that power is available
 | 
					        // Initialize the bus so that it signals that power is available
 | 
				
			||||||
        BUS_WAKER.wake();
 | 
					        BUS_WAKER.wake();
 | 
				
			||||||
@ -213,22 +213,18 @@ impl<'d, T: Instance> Driver<'d, T> {
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        match D::dir() {
 | 
					        match D::dir() {
 | 
				
			||||||
            Direction::Out => unsafe {
 | 
					            Direction::Out => T::dpram().ep_out_control(index - 1).write(|w| {
 | 
				
			||||||
                T::dpram().ep_out_control(index - 1).write(|w| {
 | 
					 | 
				
			||||||
                w.set_enable(false);
 | 
					                w.set_enable(false);
 | 
				
			||||||
                w.set_buffer_address(addr);
 | 
					                w.set_buffer_address(addr);
 | 
				
			||||||
                w.set_interrupt_per_buff(true);
 | 
					                w.set_interrupt_per_buff(true);
 | 
				
			||||||
                w.set_endpoint_type(ep_type_reg);
 | 
					                w.set_endpoint_type(ep_type_reg);
 | 
				
			||||||
                })
 | 
					            }),
 | 
				
			||||||
            },
 | 
					            Direction::In => T::dpram().ep_in_control(index - 1).write(|w| {
 | 
				
			||||||
            Direction::In => unsafe {
 | 
					 | 
				
			||||||
                T::dpram().ep_in_control(index - 1).write(|w| {
 | 
					 | 
				
			||||||
                w.set_enable(false);
 | 
					                w.set_enable(false);
 | 
				
			||||||
                w.set_buffer_address(addr);
 | 
					                w.set_buffer_address(addr);
 | 
				
			||||||
                w.set_interrupt_per_buff(true);
 | 
					                w.set_interrupt_per_buff(true);
 | 
				
			||||||
                w.set_endpoint_type(ep_type_reg);
 | 
					                w.set_endpoint_type(ep_type_reg);
 | 
				
			||||||
                })
 | 
					            }),
 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(Endpoint {
 | 
					        Ok(Endpoint {
 | 
				
			||||||
@ -315,7 +311,6 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
 | 
					    fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
 | 
				
			||||||
        let regs = T::regs();
 | 
					        let regs = T::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        regs.inte().write(|w| {
 | 
					        regs.inte().write(|w| {
 | 
				
			||||||
            w.set_bus_reset(true);
 | 
					            w.set_bus_reset(true);
 | 
				
			||||||
            w.set_buff_status(true);
 | 
					            w.set_buff_status(true);
 | 
				
			||||||
@ -329,8 +324,8 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
 | 
				
			|||||||
        regs.sie_ctrl().write(|w| {
 | 
					        regs.sie_ctrl().write(|w| {
 | 
				
			||||||
            w.set_ep0_int_1buf(true);
 | 
					            w.set_ep0_int_1buf(true);
 | 
				
			||||||
            w.set_pullup_en(true);
 | 
					            w.set_pullup_en(true);
 | 
				
			||||||
            })
 | 
					        });
 | 
				
			||||||
        }
 | 
					
 | 
				
			||||||
        trace!("enabled");
 | 
					        trace!("enabled");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        (
 | 
					        (
 | 
				
			||||||
@ -355,7 +350,7 @@ pub struct Bus<'d, T: Instance> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
 | 
					impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
 | 
				
			||||||
    async fn poll(&mut self) -> Event {
 | 
					    async fn poll(&mut self) -> Event {
 | 
				
			||||||
        poll_fn(move |cx| unsafe {
 | 
					        poll_fn(move |cx| {
 | 
				
			||||||
            BUS_WAKER.register(cx.waker());
 | 
					            BUS_WAKER.register(cx.waker());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if !self.inited {
 | 
					            if !self.inited {
 | 
				
			||||||
@ -425,14 +420,14 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let n = ep_addr.index();
 | 
					        let n = ep_addr.index();
 | 
				
			||||||
        match ep_addr.direction() {
 | 
					        match ep_addr.direction() {
 | 
				
			||||||
            Direction::In => unsafe {
 | 
					            Direction::In => {
 | 
				
			||||||
                T::dpram().ep_in_control(n - 1).modify(|w| w.set_enable(enabled));
 | 
					                T::dpram().ep_in_control(n - 1).modify(|w| w.set_enable(enabled));
 | 
				
			||||||
                T::dpram().ep_in_buffer_control(ep_addr.index()).write(|w| {
 | 
					                T::dpram().ep_in_buffer_control(ep_addr.index()).write(|w| {
 | 
				
			||||||
                    w.set_pid(0, true); // first packet is DATA0, but PID is flipped before
 | 
					                    w.set_pid(0, true); // first packet is DATA0, but PID is flipped before
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                EP_IN_WAKERS[n].wake();
 | 
					                EP_IN_WAKERS[n].wake();
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
            Direction::Out => unsafe {
 | 
					            Direction::Out => {
 | 
				
			||||||
                T::dpram().ep_out_control(n - 1).modify(|w| w.set_enable(enabled));
 | 
					                T::dpram().ep_out_control(n - 1).modify(|w| w.set_enable(enabled));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                T::dpram().ep_out_buffer_control(ep_addr.index()).write(|w| {
 | 
					                T::dpram().ep_out_buffer_control(ep_addr.index()).write(|w| {
 | 
				
			||||||
@ -446,7 +441,7 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
 | 
				
			|||||||
                    w.set_available(0, true);
 | 
					                    w.set_available(0, true);
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                EP_OUT_WAKERS[n].wake();
 | 
					                EP_OUT_WAKERS[n].wake();
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -504,7 +499,7 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, In> {
 | 
				
			|||||||
        let index = self.info.addr.index();
 | 
					        let index = self.info.addr.index();
 | 
				
			||||||
        poll_fn(|cx| {
 | 
					        poll_fn(|cx| {
 | 
				
			||||||
            EP_IN_WAKERS[index].register(cx.waker());
 | 
					            EP_IN_WAKERS[index].register(cx.waker());
 | 
				
			||||||
            let val = unsafe { T::dpram().ep_in_control(self.info.addr.index() - 1).read() };
 | 
					            let val = T::dpram().ep_in_control(self.info.addr.index() - 1).read();
 | 
				
			||||||
            if val.enable() {
 | 
					            if val.enable() {
 | 
				
			||||||
                Poll::Ready(())
 | 
					                Poll::Ready(())
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
@ -526,7 +521,7 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, Out> {
 | 
				
			|||||||
        let index = self.info.addr.index();
 | 
					        let index = self.info.addr.index();
 | 
				
			||||||
        poll_fn(|cx| {
 | 
					        poll_fn(|cx| {
 | 
				
			||||||
            EP_OUT_WAKERS[index].register(cx.waker());
 | 
					            EP_OUT_WAKERS[index].register(cx.waker());
 | 
				
			||||||
            let val = unsafe { T::dpram().ep_out_control(self.info.addr.index() - 1).read() };
 | 
					            let val = T::dpram().ep_out_control(self.info.addr.index() - 1).read();
 | 
				
			||||||
            if val.enable() {
 | 
					            if val.enable() {
 | 
				
			||||||
                Poll::Ready(())
 | 
					                Poll::Ready(())
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
@ -542,7 +537,7 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
 | 
				
			|||||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> {
 | 
					    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> {
 | 
				
			||||||
        trace!("READ WAITING, buf.len() = {}", buf.len());
 | 
					        trace!("READ WAITING, buf.len() = {}", buf.len());
 | 
				
			||||||
        let index = self.info.addr.index();
 | 
					        let index = self.info.addr.index();
 | 
				
			||||||
        let val = poll_fn(|cx| unsafe {
 | 
					        let val = poll_fn(|cx| {
 | 
				
			||||||
            EP_OUT_WAKERS[index].register(cx.waker());
 | 
					            EP_OUT_WAKERS[index].register(cx.waker());
 | 
				
			||||||
            let val = T::dpram().ep_out_buffer_control(index).read();
 | 
					            let val = T::dpram().ep_out_buffer_control(index).read();
 | 
				
			||||||
            if val.available(0) {
 | 
					            if val.available(0) {
 | 
				
			||||||
@ -561,7 +556,6 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        trace!("READ OK, rx_len = {}", rx_len);
 | 
					        trace!("READ OK, rx_len = {}", rx_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let pid = !val.pid(0);
 | 
					        let pid = !val.pid(0);
 | 
				
			||||||
        T::dpram().ep_out_buffer_control(index).write(|w| {
 | 
					        T::dpram().ep_out_buffer_control(index).write(|w| {
 | 
				
			||||||
            w.set_pid(0, pid);
 | 
					            w.set_pid(0, pid);
 | 
				
			||||||
@ -573,7 +567,6 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
 | 
				
			|||||||
            w.set_length(0, self.info.max_packet_size);
 | 
					            w.set_length(0, self.info.max_packet_size);
 | 
				
			||||||
            w.set_available(0, true);
 | 
					            w.set_available(0, true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(rx_len)
 | 
					        Ok(rx_len)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -588,7 +581,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
 | 
				
			|||||||
        trace!("WRITE WAITING");
 | 
					        trace!("WRITE WAITING");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let index = self.info.addr.index();
 | 
					        let index = self.info.addr.index();
 | 
				
			||||||
        let val = poll_fn(|cx| unsafe {
 | 
					        let val = poll_fn(|cx| {
 | 
				
			||||||
            EP_IN_WAKERS[index].register(cx.waker());
 | 
					            EP_IN_WAKERS[index].register(cx.waker());
 | 
				
			||||||
            let val = T::dpram().ep_in_buffer_control(index).read();
 | 
					            let val = T::dpram().ep_in_buffer_control(index).read();
 | 
				
			||||||
            if val.available(0) {
 | 
					            if val.available(0) {
 | 
				
			||||||
@ -601,7 +594,6 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        self.buf.write(buf);
 | 
					        self.buf.write(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let pid = !val.pid(0);
 | 
					        let pid = !val.pid(0);
 | 
				
			||||||
        T::dpram().ep_in_buffer_control(index).write(|w| {
 | 
					        T::dpram().ep_in_buffer_control(index).write(|w| {
 | 
				
			||||||
            w.set_pid(0, pid);
 | 
					            w.set_pid(0, pid);
 | 
				
			||||||
@ -615,7 +607,6 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
 | 
				
			|||||||
            w.set_full(0, true);
 | 
					            w.set_full(0, true);
 | 
				
			||||||
            w.set_available(0, true);
 | 
					            w.set_available(0, true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        trace!("WRITE OK");
 | 
					        trace!("WRITE OK");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -637,9 +628,9 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
        loop {
 | 
					        loop {
 | 
				
			||||||
            trace!("SETUP read waiting");
 | 
					            trace!("SETUP read waiting");
 | 
				
			||||||
            let regs = T::regs();
 | 
					            let regs = T::regs();
 | 
				
			||||||
            unsafe { regs.inte().write_set(|w| w.set_setup_req(true)) };
 | 
					            regs.inte().write_set(|w| w.set_setup_req(true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            poll_fn(|cx| unsafe {
 | 
					            poll_fn(|cx| {
 | 
				
			||||||
                EP_OUT_WAKERS[0].register(cx.waker());
 | 
					                EP_OUT_WAKERS[0].register(cx.waker());
 | 
				
			||||||
                let regs = T::regs();
 | 
					                let regs = T::regs();
 | 
				
			||||||
                if regs.sie_status().read().setup_rec() {
 | 
					                if regs.sie_status().read().setup_rec() {
 | 
				
			||||||
@ -654,13 +645,11 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
            EndpointBuffer::<T>::new(0, 8).read(&mut buf);
 | 
					            EndpointBuffer::<T>::new(0, 8).read(&mut buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let regs = T::regs();
 | 
					            let regs = T::regs();
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            regs.sie_status().write(|w| w.set_setup_rec(true));
 | 
					            regs.sie_status().write(|w| w.set_setup_rec(true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // set PID to 0, so (after toggling) first DATA is PID 1
 | 
					            // set PID to 0, so (after toggling) first DATA is PID 1
 | 
				
			||||||
            T::dpram().ep_in_buffer_control(0).write(|w| w.set_pid(0, false));
 | 
					            T::dpram().ep_in_buffer_control(0).write(|w| w.set_pid(0, false));
 | 
				
			||||||
            T::dpram().ep_out_buffer_control(0).write(|w| w.set_pid(0, false));
 | 
					            T::dpram().ep_out_buffer_control(0).write(|w| w.set_pid(0, false));
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            trace!("SETUP read ok");
 | 
					            trace!("SETUP read ok");
 | 
				
			||||||
            return buf;
 | 
					            return buf;
 | 
				
			||||||
@ -668,7 +657,6 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async fn data_out(&mut self, buf: &mut [u8], first: bool, last: bool) -> Result<usize, EndpointError> {
 | 
					    async fn data_out(&mut self, buf: &mut [u8], first: bool, last: bool) -> Result<usize, EndpointError> {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let bufcontrol = T::dpram().ep_out_buffer_control(0);
 | 
					        let bufcontrol = T::dpram().ep_out_buffer_control(0);
 | 
				
			||||||
        let pid = !bufcontrol.read().pid(0);
 | 
					        let pid = !bufcontrol.read().pid(0);
 | 
				
			||||||
        bufcontrol.write(|w| {
 | 
					        bufcontrol.write(|w| {
 | 
				
			||||||
@ -681,10 +669,9 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
            w.set_pid(0, pid);
 | 
					            w.set_pid(0, pid);
 | 
				
			||||||
            w.set_available(0, true);
 | 
					            w.set_available(0, true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        trace!("control: data_out len={} first={} last={}", buf.len(), first, last);
 | 
					        trace!("control: data_out len={} first={} last={}", buf.len(), first, last);
 | 
				
			||||||
        let val = poll_fn(|cx| unsafe {
 | 
					        let val = poll_fn(|cx| {
 | 
				
			||||||
            EP_OUT_WAKERS[0].register(cx.waker());
 | 
					            EP_OUT_WAKERS[0].register(cx.waker());
 | 
				
			||||||
            let val = T::dpram().ep_out_buffer_control(0).read();
 | 
					            let val = T::dpram().ep_out_buffer_control(0).read();
 | 
				
			||||||
            if val.available(0) {
 | 
					            if val.available(0) {
 | 
				
			||||||
@ -714,7 +701,6 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        EndpointBuffer::<T>::new(0x100, 64).write(data);
 | 
					        EndpointBuffer::<T>::new(0x100, 64).write(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
					        let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
				
			||||||
        let pid = !bufcontrol.read().pid(0);
 | 
					        let pid = !bufcontrol.read().pid(0);
 | 
				
			||||||
        bufcontrol.write(|w| {
 | 
					        bufcontrol.write(|w| {
 | 
				
			||||||
@ -729,9 +715,8 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
            w.set_full(0, true);
 | 
					            w.set_full(0, true);
 | 
				
			||||||
            w.set_available(0, true);
 | 
					            w.set_available(0, true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        poll_fn(|cx| unsafe {
 | 
					        poll_fn(|cx| {
 | 
				
			||||||
            EP_IN_WAKERS[0].register(cx.waker());
 | 
					            EP_IN_WAKERS[0].register(cx.waker());
 | 
				
			||||||
            let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
					            let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
				
			||||||
            if bufcontrol.read().available(0) {
 | 
					            if bufcontrol.read().available(0) {
 | 
				
			||||||
@ -745,7 +730,6 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if last {
 | 
					        if last {
 | 
				
			||||||
            // prepare status phase right away.
 | 
					            // prepare status phase right away.
 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
            let bufcontrol = T::dpram().ep_out_buffer_control(0);
 | 
					            let bufcontrol = T::dpram().ep_out_buffer_control(0);
 | 
				
			||||||
            bufcontrol.write(|w| {
 | 
					            bufcontrol.write(|w| {
 | 
				
			||||||
                w.set_length(0, 0);
 | 
					                w.set_length(0, 0);
 | 
				
			||||||
@ -758,7 +742,6 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
                w.set_available(0, true);
 | 
					                w.set_available(0, true);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -767,7 +750,6 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
        trace!("control: accept");
 | 
					        trace!("control: accept");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
					        let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        bufcontrol.write(|w| {
 | 
					        bufcontrol.write(|w| {
 | 
				
			||||||
            w.set_length(0, 0);
 | 
					            w.set_length(0, 0);
 | 
				
			||||||
            w.set_pid(0, true);
 | 
					            w.set_pid(0, true);
 | 
				
			||||||
@ -780,13 +762,12 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
            w.set_full(0, true);
 | 
					            w.set_full(0, true);
 | 
				
			||||||
            w.set_available(0, true);
 | 
					            w.set_available(0, true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // wait for completion before returning, needed so
 | 
					        // wait for completion before returning, needed so
 | 
				
			||||||
        // set_address() doesn't happen early.
 | 
					        // set_address() doesn't happen early.
 | 
				
			||||||
        poll_fn(|cx| {
 | 
					        poll_fn(|cx| {
 | 
				
			||||||
            EP_IN_WAKERS[0].register(cx.waker());
 | 
					            EP_IN_WAKERS[0].register(cx.waker());
 | 
				
			||||||
            if unsafe { bufcontrol.read().available(0) } {
 | 
					            if bufcontrol.read().available(0) {
 | 
				
			||||||
                Poll::Pending
 | 
					                Poll::Pending
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                Poll::Ready(())
 | 
					                Poll::Ready(())
 | 
				
			||||||
@ -799,7 +780,6 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
        trace!("control: reject");
 | 
					        trace!("control: reject");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let regs = T::regs();
 | 
					        let regs = T::regs();
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        regs.ep_stall_arm().write_set(|w| {
 | 
					        regs.ep_stall_arm().write_set(|w| {
 | 
				
			||||||
            w.set_ep0_in(true);
 | 
					            w.set_ep0_in(true);
 | 
				
			||||||
            w.set_ep0_out(true);
 | 
					            w.set_ep0_out(true);
 | 
				
			||||||
@ -807,13 +787,12 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
				
			|||||||
        T::dpram().ep_out_buffer_control(0).write(|w| w.set_stall(true));
 | 
					        T::dpram().ep_out_buffer_control(0).write(|w| w.set_stall(true));
 | 
				
			||||||
        T::dpram().ep_in_buffer_control(0).write(|w| w.set_stall(true));
 | 
					        T::dpram().ep_in_buffer_control(0).write(|w| w.set_stall(true));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async fn accept_set_address(&mut self, addr: u8) {
 | 
					    async fn accept_set_address(&mut self, addr: u8) {
 | 
				
			||||||
        self.accept().await;
 | 
					        self.accept().await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let regs = T::regs();
 | 
					        let regs = T::regs();
 | 
				
			||||||
        trace!("setting addr: {}", addr);
 | 
					        trace!("setting addr: {}", addr);
 | 
				
			||||||
        unsafe { regs.addr_endp().write(|w| w.set_address(addr)) }
 | 
					        regs.addr_endp().write(|w| w.set_address(addr))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -35,19 +35,16 @@ impl Watchdog {
 | 
				
			|||||||
    /// * `cycles` - Total number of tick cycles before the next tick is generated.
 | 
					    /// * `cycles` - Total number of tick cycles before the next tick is generated.
 | 
				
			||||||
    ///   It is expected to be the frequency in MHz of clk_ref.
 | 
					    ///   It is expected to be the frequency in MHz of clk_ref.
 | 
				
			||||||
    pub fn enable_tick_generation(&mut self, cycles: u8) {
 | 
					    pub fn enable_tick_generation(&mut self, cycles: u8) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let watchdog = pac::WATCHDOG;
 | 
					        let watchdog = pac::WATCHDOG;
 | 
				
			||||||
        watchdog.tick().write(|w| {
 | 
					        watchdog.tick().write(|w| {
 | 
				
			||||||
            w.set_enable(true);
 | 
					            w.set_enable(true);
 | 
				
			||||||
            w.set_cycles(cycles.into())
 | 
					            w.set_cycles(cycles.into())
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Defines whether or not the watchdog timer should be paused when processor(s) are in debug mode
 | 
					    /// Defines whether or not the watchdog timer should be paused when processor(s) are in debug mode
 | 
				
			||||||
    /// or when JTAG is accessing bus fabric
 | 
					    /// or when JTAG is accessing bus fabric
 | 
				
			||||||
    pub fn pause_on_debug(&mut self, pause: bool) {
 | 
					    pub fn pause_on_debug(&mut self, pause: bool) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let watchdog = pac::WATCHDOG;
 | 
					        let watchdog = pac::WATCHDOG;
 | 
				
			||||||
        watchdog.ctrl().write(|w| {
 | 
					        watchdog.ctrl().write(|w| {
 | 
				
			||||||
            w.set_pause_dbg0(pause);
 | 
					            w.set_pause_dbg0(pause);
 | 
				
			||||||
@ -55,25 +52,20 @@ impl Watchdog {
 | 
				
			|||||||
            w.set_pause_jtag(pause);
 | 
					            w.set_pause_jtag(pause);
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn load_counter(&self, counter: u32) {
 | 
					    fn load_counter(&self, counter: u32) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let watchdog = pac::WATCHDOG;
 | 
					        let watchdog = pac::WATCHDOG;
 | 
				
			||||||
        watchdog.load().write_value(pac::watchdog::regs::Load(counter));
 | 
					        watchdog.load().write_value(pac::watchdog::regs::Load(counter));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn enable(&self, bit: bool) {
 | 
					    fn enable(&self, bit: bool) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        let watchdog = pac::WATCHDOG;
 | 
					        let watchdog = pac::WATCHDOG;
 | 
				
			||||||
        watchdog.ctrl().write(|w| w.set_enable(bit))
 | 
					        watchdog.ctrl().write(|w| w.set_enable(bit))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Configure which hardware will be reset by the watchdog
 | 
					    // Configure which hardware will be reset by the watchdog
 | 
				
			||||||
    // (everything except ROSC, XOSC)
 | 
					    // (everything except ROSC, XOSC)
 | 
				
			||||||
    unsafe fn configure_wdog_reset_triggers(&self) {
 | 
					    fn configure_wdog_reset_triggers(&self) {
 | 
				
			||||||
        let psm = pac::PSM;
 | 
					        let psm = pac::PSM;
 | 
				
			||||||
        psm.wdsel().write_value(pac::psm::regs::Wdsel(
 | 
					        psm.wdsel().write_value(pac::psm::regs::Wdsel(
 | 
				
			||||||
            0x0001ffff & !(0x01 << 0usize) & !(0x01 << 1usize),
 | 
					            0x0001ffff & !(0x01 << 0usize) & !(0x01 << 1usize),
 | 
				
			||||||
@ -100,16 +92,13 @@ impl Watchdog {
 | 
				
			|||||||
        self.load_value = delay_us * 2;
 | 
					        self.load_value = delay_us * 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.enable(false);
 | 
					        self.enable(false);
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.configure_wdog_reset_triggers();
 | 
					        self.configure_wdog_reset_triggers();
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        self.load_counter(self.load_value);
 | 
					        self.load_counter(self.load_value);
 | 
				
			||||||
        self.enable(true);
 | 
					        self.enable(true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Trigger a system reset
 | 
					    /// Trigger a system reset
 | 
				
			||||||
    pub fn trigger_reset(&mut self) {
 | 
					    pub fn trigger_reset(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
        self.configure_wdog_reset_triggers();
 | 
					        self.configure_wdog_reset_triggers();
 | 
				
			||||||
        self.pause_on_debug(false);
 | 
					        self.pause_on_debug(false);
 | 
				
			||||||
        self.enable(true);
 | 
					        self.enable(true);
 | 
				
			||||||
@ -119,4 +108,3 @@ impl Watchdog {
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -18,11 +18,9 @@ async fn main(_spawner: Spawner) {
 | 
				
			|||||||
    const PI_F: f32 = 3.1415926535f32;
 | 
					    const PI_F: f32 = 3.1415926535f32;
 | 
				
			||||||
    const PI_D: f64 = 3.14159265358979323846f64;
 | 
					    const PI_D: f64 = 3.14159265358979323846f64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
    pac::BUSCTRL
 | 
					    pac::BUSCTRL
 | 
				
			||||||
        .perfsel(0)
 | 
					        .perfsel(0)
 | 
				
			||||||
        .write(|r| r.set_perfsel(pac::busctrl::vals::Perfsel::ROM));
 | 
					        .write(|r| r.set_perfsel(pac::busctrl::vals::Perfsel::ROM));
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for i in 0..=360 {
 | 
					    for i in 0..=360 {
 | 
				
			||||||
        let rad_f = (i as f32) * PI_F / 180.0;
 | 
					        let rad_f = (i as f32) * PI_F / 180.0;
 | 
				
			||||||
@ -46,7 +44,7 @@ async fn main(_spawner: Spawner) {
 | 
				
			|||||||
        Timer::after(Duration::from_millis(10)).await;
 | 
					        Timer::after(Duration::from_millis(10)).await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let rom_accesses = unsafe { pac::BUSCTRL.perfctr(0).read().perfctr() };
 | 
					    let rom_accesses = pac::BUSCTRL.perfctr(0).read().perfctr();
 | 
				
			||||||
    // every float operation used here uses at least 10 cycles
 | 
					    // every float operation used here uses at least 10 cycles
 | 
				
			||||||
    defmt::assert!(rom_accesses >= 360 * 12 * 10);
 | 
					    defmt::assert!(rom_accesses >= 360 * 12 * 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user