From 486fe9e59da7474c5162f56d89d5b6c279d02753 Mon Sep 17 00:00:00 2001 From: pennae Date: Wed, 3 May 2023 10:18:24 +0200 Subject: [PATCH] rp/pio: remove PioStateMachineInstance move all methods into PioStateMachine instead. the huge trait wasn't object-safe and thus didn't have any benefits whatsoever except for making it *slightly* easier to write bounds for passing around state machines. that would be much better solved with generics-less instances. --- embassy-rp/src/pio.rs | 271 +++++++++++++---------------- embassy-rp/src/pio_instr_util.rs | 20 +-- examples/rp/src/bin/pio_async.rs | 2 +- examples/rp/src/bin/pio_dma.rs | 2 +- examples/rp/src/bin/pio_hd44780.rs | 2 +- examples/rp/src/bin/ws2812-pio.rs | 4 +- 6 files changed, 138 insertions(+), 163 deletions(-) diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs index a2e3d3a9..52ef89a1 100644 --- a/embassy-rp/src/pio.rs +++ b/embassy-rp/src/pio.rs @@ -14,7 +14,6 @@ use crate::dma::{Channel, Transfer, Word}; use crate::gpio::sealed::Pin as SealedPin; use crate::gpio::{self, AnyPin, Drive, Pull, SlewRate}; use crate::pac::dma::vals::TreqSel; -use crate::pio::sealed::PioInstance as _; use crate::{interrupt, pac, peripherals, RegExt}; struct Wakers([AtomicWaker; 12]); @@ -97,23 +96,18 @@ pub(crate) unsafe fn init() { /// Future that waits for TX-FIFO to become writable #[must_use = "futures do nothing unless you `.await` or poll them"] -pub struct FifoOutFuture<'a, PIO: PioInstance, SM: PioStateMachineInstance + Unpin> { - sm: &'a mut SM, - pio: PhantomData, +pub struct FifoOutFuture<'a, 'd, PIO: PioInstance, const SM: usize> { + sm: &'a mut PioStateMachine<'d, PIO, SM>, value: u32, } -impl<'a, PIO: PioInstance, SM: PioStateMachineInstance + Unpin> FifoOutFuture<'a, PIO, SM> { - pub fn new(sm: &'a mut SM, value: u32) -> Self { - FifoOutFuture { - sm, - pio: PhantomData::default(), - value, - } +impl<'a, 'd, PIO: PioInstance, const SM: usize> FifoOutFuture<'a, 'd, PIO, SM> { + pub fn new(sm: &'a mut PioStateMachine<'d, PIO, SM>, value: u32) -> Self { + FifoOutFuture { sm, value } } } -impl<'d, PIO: PioInstance, SM: PioStateMachineInstance + Unpin> Future for FifoOutFuture<'d, PIO, SM> { +impl<'a, 'd, PIO: PioInstance, const SM: usize> Future for FifoOutFuture<'a, 'd, PIO, SM> { type Output = (); fn poll(self: FuturePin<&mut Self>, cx: &mut Context<'_>) -> Poll { //debug!("Poll {},{}", PIO::PIO_NO, SM); @@ -121,10 +115,10 @@ impl<'d, PIO: PioInstance, SM: PioStateMachineInstance + Unpin> Future for FifoO if self.get_mut().sm.try_push_tx(value) { Poll::Ready(()) } else { - WAKERS[PIO::PIO_NO as usize].fifo_out()[SM::SM as usize].register(cx.waker()); + WAKERS[PIO::PIO_NO as usize].fifo_out()[SM].register(cx.waker()); unsafe { PIO::PIO.irqs(0).inte().write_set(|m| { - m.0 = TXNFULL_MASK << SM::SM; + m.0 = TXNFULL_MASK << SM; }); } // debug!("Pending"); @@ -133,11 +127,11 @@ impl<'d, PIO: PioInstance, SM: PioStateMachineInstance + Unpin> Future for FifoO } } -impl<'d, PIO: PioInstance, SM: PioStateMachineInstance + Unpin> Drop for FifoOutFuture<'d, PIO, SM> { +impl<'a, 'd, PIO: PioInstance, const SM: usize> Drop for FifoOutFuture<'a, 'd, PIO, SM> { fn drop(&mut self) { unsafe { PIO::PIO.irqs(0).inte().write_clear(|m| { - m.0 = TXNFULL_MASK << SM::SM; + m.0 = TXNFULL_MASK << SM; }); } } @@ -145,31 +139,27 @@ impl<'d, PIO: PioInstance, SM: PioStateMachineInstance + Unpin> Drop for FifoOut /// Future that waits for RX-FIFO to become readable #[must_use = "futures do nothing unless you `.await` or poll them"] -pub struct FifoInFuture<'a, PIO: PioInstance, SM: PioStateMachineInstance> { - sm: &'a mut SM, - pio: PhantomData, +pub struct FifoInFuture<'a, 'd, PIO: PioInstance, const SM: usize> { + sm: &'a mut PioStateMachine<'d, PIO, SM>, } -impl<'a, PIO: PioInstance, SM: PioStateMachineInstance> FifoInFuture<'a, PIO, SM> { - pub fn new(sm: &'a mut SM) -> Self { - FifoInFuture { - sm, - pio: PhantomData::default(), - } +impl<'a, 'd, PIO: PioInstance, const SM: usize> FifoInFuture<'a, 'd, PIO, SM> { + pub fn new(sm: &'a mut PioStateMachine<'d, PIO, SM>) -> Self { + FifoInFuture { sm } } } -impl<'d, PIO: PioInstance, SM: PioStateMachineInstance> Future for FifoInFuture<'d, PIO, SM> { +impl<'a, 'd, PIO: PioInstance, const SM: usize> Future for FifoInFuture<'a, 'd, PIO, SM> { type Output = u32; fn poll(mut self: FuturePin<&mut Self>, cx: &mut Context<'_>) -> Poll { //debug!("Poll {},{}", PIO::PIO_NO, SM); if let Some(v) = self.sm.try_pull_rx() { Poll::Ready(v) } else { - WAKERS[PIO::PIO_NO as usize].fifo_in()[SM::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| { - m.0 = RXNEMPTY_MASK << SM::SM; + m.0 = RXNEMPTY_MASK << SM; }); } //debug!("Pending"); @@ -178,11 +168,11 @@ impl<'d, PIO: PioInstance, SM: PioStateMachineInstance> Future for FifoInFuture< } } -impl<'d, PIO: PioInstance, SM: PioStateMachineInstance> Drop for FifoInFuture<'d, PIO, SM> { +impl<'a, 'd, PIO: PioInstance, const SM: usize> Drop for FifoInFuture<'a, 'd, PIO, SM> { fn drop(&mut self) { unsafe { PIO::PIO.irqs(0).inte().write_clear(|m| { - m.0 = RXNEMPTY_MASK << SM::SM; + m.0 = RXNEMPTY_MASK << SM; }); } } @@ -325,69 +315,68 @@ impl<'d, PIO: PioInstance, const SM: usize> Drop for PioStateMachine<'d, PIO, SM } } -impl<'d, PIO: PioInstance, const SM: usize> sealed::PioStateMachineInstance for PioStateMachine<'d, PIO, SM> { - type Pio = PIO; - const SM: usize = SM; -} -impl<'d, PIO: PioInstance, const SM: usize> PioStateMachineInstance for PioStateMachine<'d, PIO, SM> {} +impl<'d, PIO: PioInstance + 'd, const SM: usize> PioStateMachine<'d, PIO, SM> { + #[inline(always)] + fn this_sm() -> crate::pac::pio::StateMachine { + PIO::PIO.sm(SM) + } -pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unpin { - fn restart(&mut self) { - let mask = 1u8 << Self::SM; + pub fn restart(&mut self) { + let mask = 1u8 << SM; unsafe { - Self::Pio::PIO.ctrl().write_set(|w| w.set_sm_restart(mask)); + PIO::PIO.ctrl().write_set(|w| w.set_sm_restart(mask)); } } - fn set_enable(&mut self, enable: bool) { - let mask = 1u8 << Self::SM; + pub fn set_enable(&mut self, enable: bool) { + let mask = 1u8 << SM; unsafe { if enable { - Self::Pio::PIO.ctrl().write_set(|w| w.set_sm_enable(mask)); + PIO::PIO.ctrl().write_set(|w| w.set_sm_enable(mask)); } else { - Self::Pio::PIO.ctrl().write_clear(|w| w.set_sm_enable(mask)); + PIO::PIO.ctrl().write_clear(|w| w.set_sm_enable(mask)); } } } - fn is_enabled(&self) -> bool { - unsafe { Self::Pio::PIO.ctrl().read().sm_enable() & (1u8 << Self::SM) != 0 } + pub fn is_enabled(&self) -> bool { + unsafe { PIO::PIO.ctrl().read().sm_enable() & (1u8 << SM) != 0 } } - fn is_tx_empty(&self) -> bool { - unsafe { Self::Pio::PIO.fstat().read().txempty() & (1u8 << Self::SM) != 0 } + pub fn is_tx_empty(&self) -> bool { + unsafe { PIO::PIO.fstat().read().txempty() & (1u8 << SM) != 0 } } - fn is_tx_full(&self) -> bool { - unsafe { Self::Pio::PIO.fstat().read().txfull() & (1u8 << Self::SM) != 0 } + pub fn is_tx_full(&self) -> bool { + unsafe { PIO::PIO.fstat().read().txfull() & (1u8 << SM) != 0 } } - fn is_rx_empty(&self) -> bool { - unsafe { Self::Pio::PIO.fstat().read().rxempty() & (1u8 << Self::SM) != 0 } + pub fn is_rx_empty(&self) -> bool { + unsafe { PIO::PIO.fstat().read().rxempty() & (1u8 << SM) != 0 } } - fn is_rx_full(&self) -> bool { - unsafe { Self::Pio::PIO.fstat().read().rxfull() & (1u8 << Self::SM) != 0 } + pub fn is_rx_full(&self) -> bool { + unsafe { PIO::PIO.fstat().read().rxfull() & (1u8 << SM) != 0 } } - fn tx_level(&self) -> u8 { + pub fn tx_level(&self) -> u8 { unsafe { - let flevel = Self::Pio::PIO.flevel().read().0; - (flevel >> (Self::SM * 8)) as u8 & 0x0f + let flevel = PIO::PIO.flevel().read().0; + (flevel >> (SM * 8)) as u8 & 0x0f } } - fn rx_level(&self) -> u8 { + pub fn rx_level(&self) -> u8 { unsafe { - let flevel = Self::Pio::PIO.flevel().read().0; - (flevel >> (Self::SM * 8 + 4)) as u8 & 0x0f + let flevel = PIO::PIO.flevel().read().0; + (flevel >> (SM * 8 + 4)) as u8 & 0x0f } } - fn push_tx(&mut self, v: u32) { + pub fn push_tx(&mut self, v: u32) { unsafe { - Self::Pio::PIO.txf(Self::SM).write_value(v); + PIO::PIO.txf(SM).write_value(v); } } - fn try_push_tx(&mut self, v: u32) -> bool { + pub fn try_push_tx(&mut self, v: u32) -> bool { if self.is_tx_full() { return false; } @@ -395,65 +384,65 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp true } - fn pull_rx(&mut self) -> u32 { - unsafe { Self::Pio::PIO.rxf(Self::SM).read() } + pub fn pull_rx(&mut self) -> u32 { + unsafe { PIO::PIO.rxf(SM).read() } } - fn try_pull_rx(&mut self) -> Option { + pub fn try_pull_rx(&mut self) -> Option { if self.is_rx_empty() { return None; } Some(self.pull_rx()) } - fn set_clkdiv(&mut self, div_x_256: u32) { + pub fn set_clkdiv(&mut self, div_x_256: u32) { unsafe { Self::this_sm().clkdiv().write(|w| w.0 = div_x_256 << 8); } } - fn get_clkdiv(&self) -> u32 { + pub fn get_clkdiv(&self) -> u32 { unsafe { Self::this_sm().clkdiv().read().0 >> 8 } } - fn clkdiv_restart(&mut self) { - let mask = 1u8 << Self::SM; + pub fn clkdiv_restart(&mut self) { + let mask = 1u8 << SM; unsafe { - Self::Pio::PIO.ctrl().write_set(|w| w.set_clkdiv_restart(mask)); + PIO::PIO.ctrl().write_set(|w| w.set_clkdiv_restart(mask)); } } - fn set_side_enable(&self, enable: bool) { + pub fn set_side_enable(&self, enable: bool) { unsafe { Self::this_sm().execctrl().modify(|w| w.set_side_en(enable)); } } - fn is_side_enabled(&self) -> bool { + pub fn is_side_enabled(&self) -> bool { unsafe { Self::this_sm().execctrl().read().side_en() } } - fn set_side_pindir(&mut self, pindir: bool) { + pub fn set_side_pindir(&mut self, pindir: bool) { unsafe { Self::this_sm().execctrl().modify(|w| w.set_side_pindir(pindir)); } } - fn is_side_pindir(&self) -> bool { + pub fn is_side_pindir(&self) -> bool { unsafe { Self::this_sm().execctrl().read().side_pindir() } } - fn set_jmp_pin(&mut self, pin: u8) { + pub fn set_jmp_pin(&mut self, pin: u8) { unsafe { Self::this_sm().execctrl().modify(|w| w.set_jmp_pin(pin)); } } - fn get_jmp_pin(&mut self) -> u8 { + pub fn get_jmp_pin(&mut self) -> u8 { unsafe { Self::this_sm().execctrl().read().jmp_pin() } } - fn set_wrap(&self, source: u8, target: u8) { + pub fn set_wrap(&self, source: u8, target: u8) { unsafe { Self::this_sm().execctrl().modify(|w| { w.set_wrap_top(source); @@ -463,14 +452,14 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp } /// Get wrapping addresses. Returns (source, target). - fn get_wrap(&self) -> (u8, u8) { + pub fn get_wrap(&self) -> (u8, u8) { unsafe { let r = Self::this_sm().execctrl().read(); (r.wrap_top(), r.wrap_bottom()) } } - fn set_fifo_join(&mut self, join: FifoJoin) { + pub fn set_fifo_join(&mut self, join: FifoJoin) { let (rx, tx) = match join { FifoJoin::Duplex => (false, false), FifoJoin::RxOnly => (true, false), @@ -483,7 +472,7 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp }); } } - fn get_fifo_join(&self) -> FifoJoin { + pub fn get_fifo_join(&self) -> FifoJoin { unsafe { let r = Self::this_sm().shiftctrl().read(); // Ignores the invalid state when both bits are set @@ -497,7 +486,7 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp } } - fn clear_fifos(&mut self) { + pub fn clear_fifos(&mut self) { // Toggle FJOIN_RX to flush FIFOs unsafe { let shiftctrl = Self::this_sm().shiftctrl(); @@ -510,33 +499,33 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp } } - fn set_pull_threshold(&mut self, threshold: u8) { + pub fn set_pull_threshold(&mut self, threshold: u8) { unsafe { Self::this_sm().shiftctrl().modify(|w| w.set_pull_thresh(threshold)); } } - fn get_pull_threshold(&self) -> u8 { + pub fn get_pull_threshold(&self) -> u8 { unsafe { Self::this_sm().shiftctrl().read().pull_thresh() } } - fn set_push_threshold(&mut self, threshold: u8) { + pub fn set_push_threshold(&mut self, threshold: u8) { unsafe { Self::this_sm().shiftctrl().modify(|w| w.set_push_thresh(threshold)); } } - fn get_push_threshold(&self) -> u8 { + pub fn get_push_threshold(&self) -> u8 { unsafe { Self::this_sm().shiftctrl().read().push_thresh() } } - fn set_out_shift_dir(&mut self, dir: ShiftDirection) { + pub fn set_out_shift_dir(&mut self, dir: ShiftDirection) { unsafe { Self::this_sm() .shiftctrl() .modify(|w| w.set_out_shiftdir(dir == ShiftDirection::Right)); } } - fn get_out_shiftdir(&self) -> ShiftDirection { + pub fn get_out_shiftdir(&self) -> ShiftDirection { unsafe { if Self::this_sm().shiftctrl().read().out_shiftdir() { ShiftDirection::Right @@ -546,14 +535,14 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp } } - fn set_in_shift_dir(&mut self, dir: ShiftDirection) { + pub fn set_in_shift_dir(&mut self, dir: ShiftDirection) { unsafe { Self::this_sm() .shiftctrl() .modify(|w| w.set_in_shiftdir(dir == ShiftDirection::Right)); } } - fn get_in_shiftdir(&self) -> ShiftDirection { + pub fn get_in_shiftdir(&self) -> ShiftDirection { unsafe { if Self::this_sm().shiftctrl().read().in_shiftdir() { ShiftDirection::Right @@ -563,46 +552,46 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp } } - fn set_autopull(&mut self, auto: bool) { + pub fn set_autopull(&mut self, auto: bool) { unsafe { Self::this_sm().shiftctrl().modify(|w| w.set_autopull(auto)); } } - fn is_autopull(&self) -> bool { + pub fn is_autopull(&self) -> bool { unsafe { Self::this_sm().shiftctrl().read().autopull() } } - fn set_autopush(&mut self, auto: bool) { + pub fn set_autopush(&mut self, auto: bool) { unsafe { Self::this_sm().shiftctrl().modify(|w| w.set_autopush(auto)); } } - fn is_autopush(&self) -> bool { + pub fn is_autopush(&self) -> bool { unsafe { Self::this_sm().shiftctrl().read().autopush() } } - fn get_addr(&self) -> u8 { + pub fn get_addr(&self) -> u8 { unsafe { Self::this_sm().addr().read().addr() } } - fn set_sideset_count(&mut self, count: u8) { + pub fn set_sideset_count(&mut self, count: u8) { unsafe { Self::this_sm().pinctrl().modify(|w| w.set_sideset_count(count)); } } - fn get_sideset_count(&self) -> u8 { + pub fn get_sideset_count(&self) -> u8 { unsafe { Self::this_sm().pinctrl().read().sideset_count() } } - fn set_sideset_base_pin(&mut self, base_pin: &Pin) { + pub fn set_sideset_base_pin(&mut self, base_pin: &Pin) { unsafe { Self::this_sm().pinctrl().modify(|w| w.set_sideset_base(base_pin.pin())); } } - fn get_sideset_base(&self) -> u8 { + pub fn get_sideset_base(&self) -> u8 { unsafe { let r = Self::this_sm().pinctrl().read(); r.sideset_base() @@ -610,7 +599,7 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp } /// Set the range of out pins affected by a set instruction. - fn set_set_range(&mut self, base: u8, count: u8) { + pub fn set_set_range(&mut self, base: u8, count: u8) { assert!(base + count < 32); unsafe { Self::this_sm().pinctrl().modify(|w| { @@ -621,27 +610,27 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp } /// Get the range of out pins affected by a set instruction. Returns (base, count). - fn get_set_range(&self) -> (u8, u8) { + pub fn get_set_range(&self) -> (u8, u8) { unsafe { let r = Self::this_sm().pinctrl().read(); (r.set_base(), r.set_count()) } } - fn set_in_base_pin(&mut self, base: &Pin) { + pub fn set_in_base_pin(&mut self, base: &Pin) { unsafe { Self::this_sm().pinctrl().modify(|w| w.set_in_base(base.pin())); } } - fn get_in_base(&self) -> u8 { + pub fn get_in_base(&self) -> u8 { unsafe { let r = Self::this_sm().pinctrl().read(); r.in_base() } } - fn set_out_range(&mut self, base: u8, count: u8) { + pub fn set_out_range(&mut self, base: u8, count: u8) { assert!(base + count < 32); unsafe { Self::this_sm().pinctrl().modify(|w| { @@ -652,14 +641,14 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp } /// Get the range of out pins affected by a set instruction. Returns (base, count). - fn get_out_range(&self) -> (u8, u8) { + pub fn get_out_range(&self) -> (u8, u8) { unsafe { let r = Self::this_sm().pinctrl().read(); (r.out_base(), r.out_count()) } } - fn set_out_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&Pin]) { + pub fn set_out_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&Pin]) { let count = pins.len(); assert!(count >= 1); let start = pins[0].pin() as usize; @@ -670,7 +659,7 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp self.set_out_range(start as u8, count as u8); } - fn set_set_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&Pin]) { + pub fn set_set_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&Pin]) { let count = pins.len(); assert!(count >= 1); let start = pins[0].pin() as usize; @@ -681,76 +670,75 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp self.set_set_range(start as u8, count as u8); } - fn get_current_instr() -> u32 { + pub fn get_current_instr() -> u32 { unsafe { Self::this_sm().instr().read().0 } } - fn exec_instr(&mut self, instr: u16) { + pub fn exec_instr(&mut self, instr: u16) { unsafe { Self::this_sm().instr().write(|w| w.set_instr(instr)); } } - fn wait_push<'a>(&'a mut self, value: u32) -> FifoOutFuture<'a, Self::Pio, Self> { + pub fn wait_push<'a>(&'a mut self, value: u32) -> FifoOutFuture<'a, 'd, PIO, SM> { FifoOutFuture::new(self, value) } - fn wait_pull<'a>(&'a mut self) -> FifoInFuture<'a, Self::Pio, Self> { + pub fn wait_pull<'a>(&'a mut self) -> FifoInFuture<'a, 'd, PIO, SM> { FifoInFuture::new(self) } - fn wait_irq(&self, irq_no: u8) -> IrqFuture { + pub fn wait_irq(&self, irq_no: u8) -> IrqFuture { IrqFuture::new(irq_no) } - fn has_tx_stalled(&self) -> bool { + pub fn has_tx_stalled(&self) -> bool { unsafe { - let fdebug = Self::Pio::PIO.fdebug(); - let ret = fdebug.read().txstall() & (1 << Self::SM) != 0; - fdebug.write(|w| w.set_txstall(1 << Self::SM)); + let fdebug = PIO::PIO.fdebug(); + let ret = fdebug.read().txstall() & (1 << SM) != 0; + fdebug.write(|w| w.set_txstall(1 << SM)); ret } } - fn has_tx_overflowed(&self) -> bool { + pub fn has_tx_overflowed(&self) -> bool { unsafe { - let fdebug = Self::Pio::PIO.fdebug(); - let ret = fdebug.read().txover() & (1 << Self::SM) != 0; - fdebug.write(|w| w.set_txover(1 << Self::SM)); + let fdebug = PIO::PIO.fdebug(); + let ret = fdebug.read().txover() & (1 << SM) != 0; + fdebug.write(|w| w.set_txover(1 << SM)); ret } } - fn has_rx_stalled(&self) -> bool { + pub fn has_rx_stalled(&self) -> bool { unsafe { - let fdebug = Self::Pio::PIO.fdebug(); - let ret = fdebug.read().rxstall() & (1 << Self::SM) != 0; - fdebug.write(|w| w.set_rxstall(1 << Self::SM)); + let fdebug = PIO::PIO.fdebug(); + let ret = fdebug.read().rxstall() & (1 << SM) != 0; + fdebug.write(|w| w.set_rxstall(1 << SM)); ret } } - fn has_rx_underflowed(&self) -> bool { + pub fn has_rx_underflowed(&self) -> bool { unsafe { - let fdebug = Self::Pio::PIO.fdebug(); - let ret = fdebug.read().rxunder() & (1 << Self::SM) != 0; - fdebug.write(|w| w.set_rxunder(1 << Self::SM)); + let fdebug = PIO::PIO.fdebug(); + let ret = fdebug.read().rxunder() & (1 << SM) != 0; + fdebug.write(|w| w.set_rxunder(1 << SM)); ret } } - fn dma_push<'a, C: Channel, W: Word>(&'a self, ch: PeripheralRef<'a, C>, data: &'a [W]) -> Transfer<'a, C> { + pub fn dma_push<'a, C: Channel, W: Word>(&'a self, ch: PeripheralRef<'a, C>, data: &'a [W]) -> Transfer<'a, C> { unsafe { - let pio_no = Self::Pio::PIO_NO; - let sm_no = Self::SM; + let pio_no = PIO::PIO_NO; let p = ch.regs(); p.read_addr().write_value(data.as_ptr() as u32); - p.write_addr().write_value(Self::Pio::PIO.txf(sm_no).ptr() as u32); + p.write_addr().write_value(PIO::PIO.txf(SM).ptr() as u32); p.trans_count().write_value(data.len() as u32); compiler_fence(Ordering::SeqCst); p.ctrl_trig().write(|w| { // Set TX DREQ for this statemachine - w.set_treq_sel(TreqSel(pio_no * 8 + sm_no as u8)); + w.set_treq_sel(TreqSel(pio_no * 8 + SM as u8)); w.set_data_size(W::size()); w.set_chain_to(ch.number()); w.set_incr_read(true); @@ -762,18 +750,17 @@ pub trait PioStateMachineInstance: sealed::PioStateMachineInstance + Sized + Unp Transfer::new(ch) } - fn dma_pull<'a, C: Channel, W: Word>(&'a self, ch: PeripheralRef<'a, C>, data: &'a mut [W]) -> Transfer<'a, C> { + pub fn dma_pull<'a, C: Channel, W: Word>(&'a self, ch: PeripheralRef<'a, C>, data: &'a mut [W]) -> Transfer<'a, C> { unsafe { - let pio_no = Self::Pio::PIO_NO; - let sm_no = Self::SM; + let pio_no = PIO::PIO_NO; let p = ch.regs(); p.write_addr().write_value(data.as_ptr() as u32); - p.read_addr().write_value(Self::Pio::PIO.rxf(sm_no).ptr() as u32); + p.read_addr().write_value(PIO::PIO.rxf(SM).ptr() as u32); p.trans_count().write_value(data.len() as u32); compiler_fence(Ordering::SeqCst); p.ctrl_trig().write(|w| { // Set RX DREQ for this statemachine - w.set_treq_sel(TreqSel(pio_no * 8 + sm_no as u8 + 4)); + w.set_treq_sel(TreqSel(pio_no * 8 + SM as u8 + 4)); w.set_data_size(W::size()); w.set_chain_to(ch.number()); w.set_incr_read(false); @@ -944,16 +931,6 @@ fn on_pio_drop() { mod sealed { use super::*; - pub trait PioStateMachineInstance { - type Pio: super::PioInstance; - const SM: usize; - - #[inline(always)] - fn this_sm() -> crate::pac::pio::StateMachine { - Self::Pio::PIO.sm(Self::SM as usize) - } - } - pub trait PioPin {} pub trait PioInstance { diff --git a/embassy-rp/src/pio_instr_util.rs b/embassy-rp/src/pio_instr_util.rs index f5e7d7ab..ffe16024 100644 --- a/embassy-rp/src/pio_instr_util.rs +++ b/embassy-rp/src/pio_instr_util.rs @@ -1,8 +1,8 @@ use pio::{InSource, InstructionOperands, JmpCondition, OutDestination, SetDestination}; -use crate::pio::PioStateMachineInstance; +use crate::pio::{PioInstance, PioStateMachine}; -pub fn set_x(sm: &mut SM, value: u32) { +pub fn set_x(sm: &mut PioStateMachine, value: u32) { const OUT: u16 = InstructionOperands::OUT { destination: OutDestination::X, bit_count: 32, @@ -12,7 +12,7 @@ pub fn set_x(sm: &mut SM, value: u32) { sm.exec_instr(OUT); } -pub fn get_x(sm: &mut SM) -> u32 { +pub fn get_x(sm: &mut PioStateMachine) -> u32 { const IN: u16 = InstructionOperands::IN { source: InSource::X, bit_count: 32, @@ -22,7 +22,7 @@ pub fn get_x(sm: &mut SM) -> u32 { sm.pull_rx() } -pub fn set_y(sm: &mut SM, value: u32) { +pub fn set_y(sm: &mut PioStateMachine, value: u32) { const OUT: u16 = InstructionOperands::OUT { destination: OutDestination::Y, bit_count: 32, @@ -32,7 +32,7 @@ pub fn set_y(sm: &mut SM, value: u32) { sm.exec_instr(OUT); } -pub fn get_y(sm: &mut SM) -> u32 { +pub fn get_y(sm: &mut PioStateMachine) -> u32 { const IN: u16 = InstructionOperands::IN { source: InSource::Y, bit_count: 32, @@ -43,7 +43,7 @@ pub fn get_y(sm: &mut SM) -> u32 { sm.pull_rx() } -pub fn set_pindir(sm: &mut SM, data: u8) { +pub fn set_pindir(sm: &mut PioStateMachine, data: u8) { let set: u16 = InstructionOperands::SET { destination: SetDestination::PINDIRS, data, @@ -52,7 +52,7 @@ pub fn set_pindir(sm: &mut SM, data: u8) { sm.exec_instr(set); } -pub fn set_pin(sm: &mut SM, data: u8) { +pub fn set_pin(sm: &mut PioStateMachine, data: u8) { let set: u16 = InstructionOperands::SET { destination: SetDestination::PINS, data, @@ -61,7 +61,7 @@ pub fn set_pin(sm: &mut SM, data: u8) { sm.exec_instr(set); } -pub fn set_out_pin(sm: &mut SM, data: u32) { +pub fn set_out_pin(sm: &mut PioStateMachine, data: u32) { const OUT: u16 = InstructionOperands::OUT { destination: OutDestination::PINS, bit_count: 32, @@ -70,7 +70,7 @@ pub fn set_out_pin(sm: &mut SM, data: u32) { sm.push_tx(data); sm.exec_instr(OUT); } -pub fn set_out_pindir(sm: &mut SM, data: u32) { +pub fn set_out_pindir(sm: &mut PioStateMachine, data: u32) { const OUT: u16 = InstructionOperands::OUT { destination: OutDestination::PINDIRS, bit_count: 32, @@ -80,7 +80,7 @@ pub fn set_out_pindir(sm: &mut SM, data: u32) { sm.exec_instr(OUT); } -pub fn exec_jmp(sm: &mut SM, to_addr: u8) { +pub fn exec_jmp(sm: &mut PioStateMachine, to_addr: u8) { let jmp: u16 = InstructionOperands::JMP { address: to_addr, condition: JmpCondition::Always, diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index 8c02f9f1..11b29086 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs @@ -4,7 +4,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_rp::peripherals::PIO0; -use embassy_rp::pio::{Pio, PioCommon, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection}; +use embassy_rp::pio::{Pio, PioCommon, PioPin, PioStateMachine, ShiftDirection}; use embassy_rp::pio_instr_util; use embassy_rp::relocate::RelocatedProgram; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs index a351e2c7..a2a2ee39 100644 --- a/examples/rp/src/bin/pio_dma.rs +++ b/examples/rp/src/bin/pio_dma.rs @@ -4,7 +4,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_futures::join::join; -use embassy_rp::pio::{Pio, PioStateMachineInstance, ShiftDirection}; +use embassy_rp::pio::{Pio, ShiftDirection}; use embassy_rp::relocate::RelocatedProgram; use embassy_rp::{pio_instr_util, Peripheral}; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index 249711a3..bc51d43c 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs @@ -7,7 +7,7 @@ use core::fmt::Write; use embassy_executor::Spawner; use embassy_rp::dma::{AnyChannel, Channel}; use embassy_rp::peripherals::PIO0; -use embassy_rp::pio::{FifoJoin, Pio, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection}; +use embassy_rp::pio::{FifoJoin, Pio, PioPin, PioStateMachine, ShiftDirection}; use embassy_rp::pwm::{Config, Pwm}; use embassy_rp::relocate::RelocatedProgram; use embassy_rp::{into_ref, Peripheral, PeripheralRef}; diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs index c141560e..713e01b4 100644 --- a/examples/rp/src/bin/ws2812-pio.rs +++ b/examples/rp/src/bin/ws2812-pio.rs @@ -4,9 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_rp::pio::{ - FifoJoin, Pio, PioCommon, PioInstance, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection, -}; +use embassy_rp::pio::{FifoJoin, Pio, PioCommon, PioInstance, PioPin, PioStateMachine, ShiftDirection}; use embassy_rp::pio_instr_util; use embassy_rp::relocate::RelocatedProgram; use embassy_time::{Duration, Timer};