diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2023-05-01 11:00:48 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-05-01 11:00:48 +0000 |
| commit | ac0ea406f91a5b630811accd0c97a622a020c700 (patch) | |
| tree | 08ae76de328feabf6406e6ad7f79b7d23bbe035e | |
| parent | ce04b732d131f488967846f6f593e10d7721ca86 (diff) | |
| parent | f4ade6af8bb2571ce2de0531d9c9715a7b8b941c (diff) | |
Merge #1395
1395: rp/pio: bit of a rework r=Dirbaio a=pennae
the pio module is currently in a Bit of a State. this is far from all that's needed to make it more useful, but it's a start.
Co-authored-by: pennae <[email protected]>
| -rw-r--r-- | embassy-rp/src/lib.rs | 1 | ||||
| -rw-r--r-- | embassy-rp/src/pio.rs | 661 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_async.rs | 46 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_dma.rs | 6 | ||||
| -rw-r--r-- | examples/rp/src/bin/ws2812-pio.rs | 13 |
5 files changed, 284 insertions, 443 deletions
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index 697f4308b..d69d12a30 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs | |||
| @@ -156,6 +156,7 @@ pub fn init(_config: config::Config) -> Peripherals { | |||
| 156 | #[cfg(feature = "time-driver")] | 156 | #[cfg(feature = "time-driver")] |
| 157 | timer::init(); | 157 | timer::init(); |
| 158 | dma::init(); | 158 | dma::init(); |
| 159 | pio::init(); | ||
| 159 | } | 160 | } |
| 160 | 161 | ||
| 161 | peripherals | 162 | peripherals |
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs index 3c7abea25..7faec10b5 100644 --- a/embassy-rp/src/pio.rs +++ b/embassy-rp/src/pio.rs | |||
| @@ -8,18 +8,33 @@ use embassy_cortex_m::interrupt::{Interrupt, InterruptExt}; | |||
| 8 | use embassy_hal_common::PeripheralRef; | 8 | use embassy_hal_common::PeripheralRef; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | 10 | ||
| 11 | use crate::dma::{self, Channel, Transfer}; | 11 | use crate::dma::{Channel, Transfer}; |
| 12 | use crate::gpio::sealed::Pin as SealedPin; | 12 | use crate::gpio::sealed::Pin as SealedPin; |
| 13 | use crate::gpio::{Drive, Pin, Pull, SlewRate}; | 13 | use crate::gpio::{Drive, Pin, Pull, SlewRate}; |
| 14 | use crate::pac::dma::vals::{DataSize, TreqSel}; | 14 | use crate::pac::dma::vals::{DataSize, TreqSel}; |
| 15 | use crate::{interrupt, pac, peripherals}; | 15 | use crate::pio::sealed::{PioInstance as _, SmInstance as _}; |
| 16 | use crate::{interrupt, pac, peripherals, RegExt}; | ||
| 17 | |||
| 18 | struct Wakers([AtomicWaker; 12]); | ||
| 19 | |||
| 20 | impl Wakers { | ||
| 21 | #[inline(always)] | ||
| 22 | fn fifo_in(&self) -> &[AtomicWaker] { | ||
| 23 | &self.0[0..4] | ||
| 24 | } | ||
| 25 | #[inline(always)] | ||
| 26 | fn fifo_out(&self) -> &[AtomicWaker] { | ||
| 27 | &self.0[4..8] | ||
| 28 | } | ||
| 29 | #[inline(always)] | ||
| 30 | fn irq(&self) -> &[AtomicWaker] { | ||
| 31 | &self.0[8..12] | ||
| 32 | } | ||
| 33 | } | ||
| 16 | 34 | ||
| 17 | const PIOS: [&pac::pio::Pio; 2] = [&pac::PIO0, &pac::PIO1]; | ||
| 18 | const NEW_AW: AtomicWaker = AtomicWaker::new(); | 35 | const NEW_AW: AtomicWaker = AtomicWaker::new(); |
| 19 | const PIO_WAKERS_INIT: [AtomicWaker; 4] = [NEW_AW; 4]; | 36 | const PIO_WAKERS_INIT: Wakers = Wakers([NEW_AW; 12]); |
| 20 | static FIFO_OUT_WAKERS: [[AtomicWaker; 4]; 2] = [PIO_WAKERS_INIT; 2]; | 37 | static WAKERS: [Wakers; 2] = [PIO_WAKERS_INIT; 2]; |
| 21 | static FIFO_IN_WAKERS: [[AtomicWaker; 4]; 2] = [PIO_WAKERS_INIT; 2]; | ||
| 22 | static IRQ_WAKERS: [[AtomicWaker; 4]; 2] = [PIO_WAKERS_INIT; 2]; | ||
| 23 | 38 | ||
| 24 | pub enum FifoJoin { | 39 | pub enum FifoJoin { |
| 25 | /// Both TX and RX fifo is enabled | 40 | /// Both TX and RX fifo is enabled |
| @@ -41,82 +56,41 @@ const TXNFULL_MASK: u32 = 1 << 4; | |||
| 41 | const SMIRQ_MASK: u32 = 1 << 8; | 56 | const SMIRQ_MASK: u32 = 1 << 8; |
| 42 | 57 | ||
| 43 | #[interrupt] | 58 | #[interrupt] |
| 44 | unsafe fn PIO0_IRQ_1() { | ||
| 45 | use crate::pac; | ||
| 46 | let ints = pac::PIO0.irqs(1).ints().read().0; | ||
| 47 | let inte = pac::PIO0.irqs(1).inte(); | ||
| 48 | for i in 0..4 { | ||
| 49 | // Check RXNEMPTY | ||
| 50 | if ints & (RXNEMPTY_MASK << i) != 0 { | ||
| 51 | inte.modify(|m| { | ||
| 52 | m.0 &= !(RXNEMPTY_MASK << i); | ||
| 53 | }); | ||
| 54 | FIFO_IN_WAKERS[0][i].wake(); | ||
| 55 | } | ||
| 56 | // Check IRQ flgs | ||
| 57 | if ints & (SMIRQ_MASK << i) != 0 { | ||
| 58 | inte.modify(|m| { | ||
| 59 | m.0 &= !(SMIRQ_MASK << i); | ||
| 60 | }); | ||
| 61 | IRQ_WAKERS[0][i].wake(); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | #[interrupt] | ||
| 67 | unsafe fn PIO1_IRQ_1() { | ||
| 68 | use crate::pac; | ||
| 69 | let ints = pac::PIO1.irqs(1).ints().read().0; | ||
| 70 | let inte = pac::PIO1.irqs(1).inte(); | ||
| 71 | for i in 0..4 { | ||
| 72 | // Check all RXNEMPTY | ||
| 73 | if ints & (RXNEMPTY_MASK << i) != 0 { | ||
| 74 | inte.modify(|m| { | ||
| 75 | m.0 &= !(RXNEMPTY_MASK << i); | ||
| 76 | }); | ||
| 77 | FIFO_IN_WAKERS[1][i].wake(); | ||
| 78 | } | ||
| 79 | // Check IRQ flgs | ||
| 80 | if ints & (SMIRQ_MASK << i) != 0 { | ||
| 81 | inte.modify(|m| { | ||
| 82 | m.0 &= !(SMIRQ_MASK << i); | ||
| 83 | }); | ||
| 84 | IRQ_WAKERS[1][i].wake(); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | #[interrupt] | ||
| 90 | unsafe fn PIO0_IRQ_0() { | 59 | unsafe fn PIO0_IRQ_0() { |
| 91 | use crate::pac; | 60 | use crate::pac; |
| 92 | let ints = pac::PIO0.irqs(0).ints().read().0; | 61 | let ints = pac::PIO0.irqs(0).ints().read().0; |
| 93 | let inte = pac::PIO0.irqs(0).inte(); | 62 | for bit in 0..12 { |
| 94 | //debug!("!{:04x}",ints); | 63 | if ints & (1 << bit) != 0 { |
| 95 | // Check all TXNFULL | 64 | WAKERS[0].0[bit].wake(); |
| 96 | for i in 0..4 { | ||
| 97 | if ints & (TXNFULL_MASK << i) != 0 { | ||
| 98 | inte.modify(|m| { | ||
| 99 | m.0 &= !(TXNFULL_MASK << i); | ||
| 100 | }); | ||
| 101 | FIFO_OUT_WAKERS[0][i].wake(); | ||
| 102 | } | 65 | } |
| 103 | } | 66 | } |
| 67 | pac::PIO0.irqs(0).inte().write_clear(|m| m.0 = ints); | ||
| 104 | } | 68 | } |
| 105 | 69 | ||
| 106 | #[interrupt] | 70 | #[interrupt] |
| 107 | unsafe fn PIO1_IRQ_0() { | 71 | unsafe fn PIO1_IRQ_0() { |
| 108 | use crate::pac; | 72 | use crate::pac; |
| 109 | let ints = pac::PIO1.irqs(0).ints().read().0; | 73 | let ints = pac::PIO1.irqs(0).ints().read().0; |
| 110 | let inte = pac::PIO1.irqs(0).inte(); | 74 | for bit in 0..12 { |
| 111 | // Check all TXNFULL | 75 | if ints & (1 << bit) != 0 { |
| 112 | for i in 0..4 { | 76 | WAKERS[1].0[bit].wake(); |
| 113 | if ints & (TXNFULL_MASK << i) != 0 { | ||
| 114 | inte.modify(|m| { | ||
| 115 | m.0 &= !(TXNFULL_MASK << i); | ||
| 116 | }); | ||
| 117 | FIFO_OUT_WAKERS[1][i].wake(); | ||
| 118 | } | 77 | } |
| 119 | } | 78 | } |
| 79 | pac::PIO1.irqs(0).inte().write_clear(|m| m.0 = ints); | ||
| 80 | } | ||
| 81 | |||
| 82 | pub(crate) unsafe fn init() { | ||
| 83 | let irq = interrupt::PIO0_IRQ_0::steal(); | ||
| 84 | irq.disable(); | ||
| 85 | irq.set_priority(interrupt::Priority::P3); | ||
| 86 | pac::PIO0.irqs(0).inte().write(|m| m.0 = 0); | ||
| 87 | irq.enable(); | ||
| 88 | |||
| 89 | let irq = interrupt::PIO1_IRQ_0::steal(); | ||
| 90 | irq.disable(); | ||
| 91 | irq.set_priority(interrupt::Priority::P3); | ||
| 92 | pac::PIO1.irqs(0).inte().write(|m| m.0 = 0); | ||
| 93 | irq.enable(); | ||
| 120 | } | 94 | } |
| 121 | 95 | ||
| 122 | /// Future that waits for TX-FIFO to become writable | 96 | /// Future that waits for TX-FIFO to become writable |
| @@ -129,14 +103,6 @@ pub struct FifoOutFuture<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> { | |||
| 129 | 103 | ||
| 130 | impl<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> FifoOutFuture<'a, PIO, SM> { | 104 | impl<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> FifoOutFuture<'a, PIO, SM> { |
| 131 | pub fn new(sm: &'a mut SM, value: u32) -> Self { | 105 | pub fn new(sm: &'a mut SM, value: u32) -> Self { |
| 132 | unsafe { | ||
| 133 | critical_section::with(|_| { | ||
| 134 | let irq = PIO::IrqOut::steal(); | ||
| 135 | irq.set_priority(interrupt::Priority::P3); | ||
| 136 | |||
| 137 | irq.enable(); | ||
| 138 | }); | ||
| 139 | } | ||
| 140 | FifoOutFuture { | 106 | FifoOutFuture { |
| 141 | sm, | 107 | sm, |
| 142 | pio: PhantomData::default(), | 108 | pio: PhantomData::default(), |
| @@ -153,16 +119,11 @@ impl<'d, PIO: PioInstance, SM: PioStateMachine + Unpin> Future for FifoOutFuture | |||
| 153 | if self.get_mut().sm.try_push_tx(value) { | 119 | if self.get_mut().sm.try_push_tx(value) { |
| 154 | Poll::Ready(()) | 120 | Poll::Ready(()) |
| 155 | } else { | 121 | } else { |
| 156 | FIFO_OUT_WAKERS[PIO::PIO_NO as usize][SM::Sm::SM_NO as usize].register(cx.waker()); | 122 | WAKERS[PIO::PIO_NO as usize].fifo_out()[SM::Sm::SM_NO as usize].register(cx.waker()); |
| 157 | unsafe { | 123 | unsafe { |
| 158 | let irq = PIO::IrqOut::steal(); | 124 | PIO::PIO.irqs(0).inte().write_set(|m| { |
| 159 | irq.disable(); | 125 | m.0 = TXNFULL_MASK << SM::Sm::SM_NO; |
| 160 | critical_section::with(|_| { | ||
| 161 | PIOS[PIO::PIO_NO as usize].irqs(0).inte().modify(|m| { | ||
| 162 | m.0 |= TXNFULL_MASK << SM::Sm::SM_NO; | ||
| 163 | }); | ||
| 164 | }); | 126 | }); |
| 165 | irq.enable(); | ||
| 166 | } | 127 | } |
| 167 | // debug!("Pending"); | 128 | // debug!("Pending"); |
| 168 | Poll::Pending | 129 | Poll::Pending |
| @@ -173,10 +134,8 @@ impl<'d, PIO: PioInstance, SM: PioStateMachine + Unpin> Future for FifoOutFuture | |||
| 173 | impl<'d, PIO: PioInstance, SM: PioStateMachine + Unpin> Drop for FifoOutFuture<'d, PIO, SM> { | 134 | impl<'d, PIO: PioInstance, SM: PioStateMachine + Unpin> Drop for FifoOutFuture<'d, PIO, SM> { |
| 174 | fn drop(&mut self) { | 135 | fn drop(&mut self) { |
| 175 | unsafe { | 136 | unsafe { |
| 176 | critical_section::with(|_| { | 137 | PIO::PIO.irqs(0).inte().write_clear(|m| { |
| 177 | PIOS[PIO::PIO_NO as usize].irqs(0).inte().modify(|m| { | 138 | m.0 = TXNFULL_MASK << SM::Sm::SM_NO; |
| 178 | m.0 &= !(TXNFULL_MASK << SM::Sm::SM_NO); | ||
| 179 | }); | ||
| 180 | }); | 139 | }); |
| 181 | } | 140 | } |
| 182 | } | 141 | } |
| @@ -191,14 +150,6 @@ pub struct FifoInFuture<'a, PIO: PioInstance, SM: PioStateMachine> { | |||
| 191 | 150 | ||
| 192 | impl<'a, PIO: PioInstance, SM: PioStateMachine> FifoInFuture<'a, PIO, SM> { | 151 | impl<'a, PIO: PioInstance, SM: PioStateMachine> FifoInFuture<'a, PIO, SM> { |
| 193 | pub fn new(sm: &'a mut SM) -> Self { | 152 | pub fn new(sm: &'a mut SM) -> Self { |
| 194 | unsafe { | ||
| 195 | critical_section::with(|_| { | ||
| 196 | let irq = PIO::IrqIn::steal(); | ||
| 197 | irq.set_priority(interrupt::Priority::P3); | ||
| 198 | |||
| 199 | irq.enable(); | ||
| 200 | }); | ||
| 201 | } | ||
| 202 | FifoInFuture { | 153 | FifoInFuture { |
| 203 | sm, | 154 | sm, |
| 204 | pio: PhantomData::default(), | 155 | pio: PhantomData::default(), |
| @@ -213,16 +164,11 @@ impl<'d, PIO: PioInstance, SM: PioStateMachine> Future for FifoInFuture<'d, PIO, | |||
| 213 | if let Some(v) = self.sm.try_pull_rx() { | 164 | if let Some(v) = self.sm.try_pull_rx() { |
| 214 | Poll::Ready(v) | 165 | Poll::Ready(v) |
| 215 | } else { | 166 | } else { |
| 216 | FIFO_IN_WAKERS[PIO::PIO_NO as usize][SM::Sm::SM_NO as usize].register(cx.waker()); | 167 | WAKERS[PIO::PIO_NO as usize].fifo_in()[SM::Sm::SM_NO as usize].register(cx.waker()); |
| 217 | unsafe { | 168 | unsafe { |
| 218 | let irq = PIO::IrqIn::steal(); | 169 | PIO::PIO.irqs(0).inte().write_set(|m| { |
| 219 | irq.disable(); | 170 | m.0 = RXNEMPTY_MASK << SM::Sm::SM_NO; |
| 220 | critical_section::with(|_| { | ||
| 221 | PIOS[PIO::PIO_NO as usize].irqs(1).inte().modify(|m| { | ||
| 222 | m.0 |= RXNEMPTY_MASK << SM::Sm::SM_NO; | ||
| 223 | }); | ||
| 224 | }); | 171 | }); |
| 225 | irq.enable(); | ||
| 226 | } | 172 | } |
| 227 | //debug!("Pending"); | 173 | //debug!("Pending"); |
| 228 | Poll::Pending | 174 | Poll::Pending |
| @@ -233,10 +179,8 @@ impl<'d, PIO: PioInstance, SM: PioStateMachine> Future for FifoInFuture<'d, PIO, | |||
| 233 | impl<'d, PIO: PioInstance, SM: PioStateMachine> Drop for FifoInFuture<'d, PIO, SM> { | 179 | impl<'d, PIO: PioInstance, SM: PioStateMachine> Drop for FifoInFuture<'d, PIO, SM> { |
| 234 | fn drop(&mut self) { | 180 | fn drop(&mut self) { |
| 235 | unsafe { | 181 | unsafe { |
| 236 | critical_section::with(|_| { | 182 | PIO::PIO.irqs(0).inte().write_clear(|m| { |
| 237 | PIOS[PIO::PIO_NO as usize].irqs(1).inte().modify(|m| { | 183 | m.0 = RXNEMPTY_MASK << SM::Sm::SM_NO; |
| 238 | m.0 &= !(RXNEMPTY_MASK << SM::Sm::SM_NO); | ||
| 239 | }); | ||
| 240 | }); | 184 | }); |
| 241 | } | 185 | } |
| 242 | } | 186 | } |
| @@ -251,14 +195,6 @@ pub struct IrqFuture<PIO: PioInstance> { | |||
| 251 | 195 | ||
| 252 | impl<'a, PIO: PioInstance> IrqFuture<PIO> { | 196 | impl<'a, PIO: PioInstance> IrqFuture<PIO> { |
| 253 | pub fn new(irq_no: u8) -> Self { | 197 | pub fn new(irq_no: u8) -> Self { |
| 254 | unsafe { | ||
| 255 | critical_section::with(|_| { | ||
| 256 | let irq = PIO::IrqSm::steal(); | ||
| 257 | irq.set_priority(interrupt::Priority::P3); | ||
| 258 | |||
| 259 | irq.enable(); | ||
| 260 | }); | ||
| 261 | } | ||
| 262 | IrqFuture { | 198 | IrqFuture { |
| 263 | pio: PhantomData::default(), | 199 | pio: PhantomData::default(), |
| 264 | irq_no, | 200 | irq_no, |
| @@ -273,7 +209,7 @@ impl<'d, PIO: PioInstance> Future for IrqFuture<PIO> { | |||
| 273 | 209 | ||
| 274 | // Check if IRQ flag is already set | 210 | // Check if IRQ flag is already set |
| 275 | if critical_section::with(|_| unsafe { | 211 | if critical_section::with(|_| unsafe { |
| 276 | let irq_flags = PIOS[PIO::PIO_NO as usize].irq(); | 212 | let irq_flags = PIO::PIO.irq(); |
| 277 | if irq_flags.read().0 & (1 << self.irq_no) != 0 { | 213 | if irq_flags.read().0 & (1 << self.irq_no) != 0 { |
| 278 | irq_flags.write(|m| { | 214 | irq_flags.write(|m| { |
| 279 | m.0 = 1 << self.irq_no; | 215 | m.0 = 1 << self.irq_no; |
| @@ -286,16 +222,11 @@ impl<'d, PIO: PioInstance> Future for IrqFuture<PIO> { | |||
| 286 | return Poll::Ready(()); | 222 | return Poll::Ready(()); |
| 287 | } | 223 | } |
| 288 | 224 | ||
| 289 | IRQ_WAKERS[PIO::PIO_NO as usize][self.irq_no as usize].register(cx.waker()); | 225 | WAKERS[PIO::PIO_NO as usize].irq()[self.irq_no as usize].register(cx.waker()); |
| 290 | unsafe { | 226 | unsafe { |
| 291 | let irq = PIO::IrqSm::steal(); | 227 | PIO::PIO.irqs(0).inte().write_set(|m| { |
| 292 | irq.disable(); | 228 | m.0 = SMIRQ_MASK << self.irq_no; |
| 293 | critical_section::with(|_| { | ||
| 294 | PIOS[PIO::PIO_NO as usize].irqs(1).inte().modify(|m| { | ||
| 295 | m.0 |= SMIRQ_MASK << self.irq_no; | ||
| 296 | }); | ||
| 297 | }); | 229 | }); |
| 298 | irq.enable(); | ||
| 299 | } | 230 | } |
| 300 | Poll::Pending | 231 | Poll::Pending |
| 301 | } | 232 | } |
| @@ -304,10 +235,8 @@ impl<'d, PIO: PioInstance> Future for IrqFuture<PIO> { | |||
| 304 | impl<'d, PIO: PioInstance> Drop for IrqFuture<PIO> { | 235 | impl<'d, PIO: PioInstance> Drop for IrqFuture<PIO> { |
| 305 | fn drop(&mut self) { | 236 | fn drop(&mut self) { |
| 306 | unsafe { | 237 | unsafe { |
| 307 | critical_section::with(|_| { | 238 | PIO::PIO.irqs(0).inte().write_clear(|m| { |
| 308 | PIOS[PIO::PIO_NO as usize].irqs(1).inte().modify(|m| { | 239 | m.0 = SMIRQ_MASK << self.irq_no; |
| 309 | m.0 &= !(SMIRQ_MASK << self.irq_no); | ||
| 310 | }); | ||
| 311 | }); | 240 | }); |
| 312 | } | 241 | } |
| 313 | } | 242 | } |
| @@ -369,7 +298,7 @@ impl<PIO: PioInstance> PioPin<PIO> { | |||
| 369 | pub fn set_input_sync_bypass<'a>(&mut self, bypass: bool) { | 298 | pub fn set_input_sync_bypass<'a>(&mut self, bypass: bool) { |
| 370 | let mask = 1 << self.pin(); | 299 | let mask = 1 << self.pin(); |
| 371 | unsafe { | 300 | unsafe { |
| 372 | PIOS[PIO::PIO_NO as usize] | 301 | PIO::PIO |
| 373 | .input_sync_bypass() | 302 | .input_sync_bypass() |
| 374 | .modify(|w| *w = if bypass { *w & !mask } else { *w | mask }); | 303 | .modify(|w| *w = if bypass { *w & !mask } else { *w | mask }); |
| 375 | } | 304 | } |
| @@ -391,16 +320,14 @@ pub struct PioStateMachineInstance<PIO: PioInstance, SM: SmInstance> { | |||
| 391 | sm: PhantomData<SM>, | 320 | sm: PhantomData<SM>, |
| 392 | } | 321 | } |
| 393 | 322 | ||
| 394 | impl<PIO: PioInstance, SM: SmInstance> PioStateMachine for PioStateMachineInstance<PIO, SM> { | 323 | impl<PIO: PioInstance, SM: SmInstance> sealed::PioStateMachine for PioStateMachineInstance<PIO, SM> { |
| 395 | type Pio = PIO; | 324 | type Pio = PIO; |
| 396 | type Sm = SM; | 325 | type Sm = SM; |
| 397 | } | 326 | } |
| 327 | impl<PIO: PioInstance, SM: SmInstance> PioStateMachine for PioStateMachineInstance<PIO, SM> {} | ||
| 398 | 328 | ||
| 399 | pub trait PioStateMachine: Sized + Unpin { | 329 | pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin { |
| 400 | type Pio: PioInstance; | ||
| 401 | type Sm: SmInstance; | ||
| 402 | fn pio_no(&self) -> u8 { | 330 | fn pio_no(&self) -> u8 { |
| 403 | let _ = self; | ||
| 404 | Self::Pio::PIO_NO | 331 | Self::Pio::PIO_NO |
| 405 | } | 332 | } |
| 406 | 333 | ||
| @@ -409,65 +336,56 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 409 | } | 336 | } |
| 410 | 337 | ||
| 411 | fn restart(&mut self) { | 338 | fn restart(&mut self) { |
| 412 | let _ = self; | ||
| 413 | unsafe { | 339 | unsafe { |
| 414 | PIOS[Self::Pio::PIO_NO as usize] | 340 | Self::Pio::PIO |
| 415 | .ctrl() | 341 | .ctrl() |
| 416 | .modify(|w| w.set_sm_restart(1u8 << Self::Sm::SM_NO)); | 342 | .modify(|w| w.set_sm_restart(1u8 << Self::Sm::SM_NO)); |
| 417 | } | 343 | } |
| 418 | } | 344 | } |
| 419 | fn set_enable(&mut self, enable: bool) { | 345 | fn set_enable(&mut self, enable: bool) { |
| 420 | let _ = self; | ||
| 421 | let mask = 1u8 << Self::Sm::SM_NO; | 346 | let mask = 1u8 << Self::Sm::SM_NO; |
| 422 | unsafe { | 347 | unsafe { |
| 423 | PIOS[Self::Pio::PIO_NO as usize] | 348 | Self::Pio::PIO |
| 424 | .ctrl() | 349 | .ctrl() |
| 425 | .modify(|w| w.set_sm_enable((w.sm_enable() & !mask) | (if enable { mask } else { 0 }))); | 350 | .modify(|w| w.set_sm_enable((w.sm_enable() & !mask) | (if enable { mask } else { 0 }))); |
| 426 | } | 351 | } |
| 427 | } | 352 | } |
| 428 | 353 | ||
| 429 | fn is_enabled(&self) -> bool { | 354 | fn is_enabled(&self) -> bool { |
| 430 | let _ = self; | 355 | unsafe { Self::Pio::PIO.ctrl().read().sm_enable() & (1u8 << Self::Sm::SM_NO) != 0 } |
| 431 | unsafe { PIOS[Self::Pio::PIO_NO as usize].ctrl().read().sm_enable() & (1u8 << Self::Sm::SM_NO) != 0 } | ||
| 432 | } | 356 | } |
| 433 | 357 | ||
| 434 | fn is_tx_empty(&self) -> bool { | 358 | fn is_tx_empty(&self) -> bool { |
| 435 | let _ = self; | 359 | unsafe { Self::Pio::PIO.fstat().read().txempty() & (1u8 << Self::Sm::SM_NO) != 0 } |
| 436 | unsafe { PIOS[Self::Pio::PIO_NO as usize].fstat().read().txempty() & (1u8 << Self::Sm::SM_NO) != 0 } | ||
| 437 | } | 360 | } |
| 438 | fn is_tx_full(&self) -> bool { | 361 | fn is_tx_full(&self) -> bool { |
| 439 | let _ = self; | 362 | unsafe { Self::Pio::PIO.fstat().read().txfull() & (1u8 << Self::Sm::SM_NO) != 0 } |
| 440 | unsafe { PIOS[Self::Pio::PIO_NO as usize].fstat().read().txfull() & (1u8 << Self::Sm::SM_NO) != 0 } | ||
| 441 | } | 363 | } |
| 442 | 364 | ||
| 443 | fn is_rx_empty(&self) -> bool { | 365 | fn is_rx_empty(&self) -> bool { |
| 444 | let _ = self; | 366 | unsafe { Self::Pio::PIO.fstat().read().rxempty() & (1u8 << Self::Sm::SM_NO) != 0 } |
| 445 | unsafe { PIOS[Self::Pio::PIO_NO as usize].fstat().read().rxempty() & (1u8 << Self::Sm::SM_NO) != 0 } | ||
| 446 | } | 367 | } |
| 447 | fn is_rx_full(&self) -> bool { | 368 | fn is_rx_full(&self) -> bool { |
| 448 | let _ = self; | 369 | unsafe { Self::Pio::PIO.fstat().read().rxfull() & (1u8 << Self::Sm::SM_NO) != 0 } |
| 449 | unsafe { PIOS[Self::Pio::PIO_NO as usize].fstat().read().rxfull() & (1u8 << Self::Sm::SM_NO) != 0 } | ||
| 450 | } | 370 | } |
| 451 | 371 | ||
| 452 | fn tx_level(&self) -> u8 { | 372 | fn tx_level(&self) -> u8 { |
| 453 | unsafe { | 373 | unsafe { |
| 454 | let flevel = PIOS[Self::Pio::PIO_NO as usize].flevel().read().0; | 374 | let flevel = Self::Pio::PIO.flevel().read().0; |
| 455 | (flevel >> (Self::Sm::SM_NO * 8)) as u8 & 0x0f | 375 | (flevel >> (Self::Sm::SM_NO * 8)) as u8 & 0x0f |
| 456 | } | 376 | } |
| 457 | } | 377 | } |
| 458 | 378 | ||
| 459 | fn rx_level(&self) -> u8 { | 379 | fn rx_level(&self) -> u8 { |
| 460 | unsafe { | 380 | unsafe { |
| 461 | let flevel = PIOS[Self::Pio::PIO_NO as usize].flevel().read().0; | 381 | let flevel = Self::Pio::PIO.flevel().read().0; |
| 462 | (flevel >> (Self::Sm::SM_NO * 8 + 4)) as u8 & 0x0f | 382 | (flevel >> (Self::Sm::SM_NO * 8 + 4)) as u8 & 0x0f |
| 463 | } | 383 | } |
| 464 | } | 384 | } |
| 465 | 385 | ||
| 466 | fn push_tx(&mut self, v: u32) { | 386 | fn push_tx(&mut self, v: u32) { |
| 467 | unsafe { | 387 | unsafe { |
| 468 | PIOS[Self::Pio::PIO_NO as usize] | 388 | Self::Pio::PIO.txf(Self::Sm::SM_NO as usize).write_value(v); |
| 469 | .txf(Self::Sm::SM_NO as usize) | ||
| 470 | .write_value(v); | ||
| 471 | } | 389 | } |
| 472 | } | 390 | } |
| 473 | 391 | ||
| @@ -480,7 +398,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 480 | } | 398 | } |
| 481 | 399 | ||
| 482 | fn pull_rx(&mut self) -> u32 { | 400 | fn pull_rx(&mut self) -> u32 { |
| 483 | unsafe { PIOS[Self::Pio::PIO_NO as usize].rxf(Self::Sm::SM_NO as usize).read() } | 401 | unsafe { Self::Pio::PIO.rxf(Self::Sm::SM_NO as usize).read() } |
| 484 | } | 402 | } |
| 485 | 403 | ||
| 486 | fn try_pull_rx(&mut self) -> Option<u32> { | 404 | fn try_pull_rx(&mut self) -> Option<u32> { |
| @@ -492,7 +410,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 492 | 410 | ||
| 493 | fn set_clkdiv(&mut self, div_x_256: u32) { | 411 | fn set_clkdiv(&mut self, div_x_256: u32) { |
| 494 | unsafe { | 412 | unsafe { |
| 495 | PIOS[Self::Pio::PIO_NO as usize] | 413 | Self::Pio::PIO |
| 496 | .sm(Self::Sm::SM_NO as usize) | 414 | .sm(Self::Sm::SM_NO as usize) |
| 497 | .clkdiv() | 415 | .clkdiv() |
| 498 | .write(|w| w.0 = div_x_256 << 8); | 416 | .write(|w| w.0 = div_x_256 << 8); |
| @@ -500,20 +418,12 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 500 | } | 418 | } |
| 501 | 419 | ||
| 502 | fn get_clkdiv(&self) -> u32 { | 420 | fn get_clkdiv(&self) -> u32 { |
| 503 | unsafe { | 421 | unsafe { Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).clkdiv().read().0 >> 8 } |
| 504 | PIOS[Self::Pio::PIO_NO as usize] | ||
| 505 | .sm(Self::Sm::SM_NO as usize) | ||
| 506 | .clkdiv() | ||
| 507 | .read() | ||
| 508 | .0 | ||
| 509 | >> 8 | ||
| 510 | } | ||
| 511 | } | 422 | } |
| 512 | 423 | ||
| 513 | fn clkdiv_restart(&mut self) { | 424 | fn clkdiv_restart(&mut self) { |
| 514 | let _ = self; | ||
| 515 | unsafe { | 425 | unsafe { |
| 516 | PIOS[Self::Pio::PIO_NO as usize] | 426 | Self::Pio::PIO |
| 517 | .ctrl() | 427 | .ctrl() |
| 518 | .modify(|w| w.set_clkdiv_restart(1u8 << Self::Sm::SM_NO)); | 428 | .modify(|w| w.set_clkdiv_restart(1u8 << Self::Sm::SM_NO)); |
| 519 | } | 429 | } |
| @@ -521,7 +431,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 521 | 431 | ||
| 522 | fn set_side_enable(&self, enable: bool) { | 432 | fn set_side_enable(&self, enable: bool) { |
| 523 | unsafe { | 433 | unsafe { |
| 524 | PIOS[Self::Pio::PIO_NO as usize] | 434 | Self::Pio::PIO |
| 525 | .sm(Self::Sm::SM_NO as usize) | 435 | .sm(Self::Sm::SM_NO as usize) |
| 526 | .execctrl() | 436 | .execctrl() |
| 527 | .modify(|w| w.set_side_en(enable)); | 437 | .modify(|w| w.set_side_en(enable)); |
| @@ -529,18 +439,12 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 529 | } | 439 | } |
| 530 | 440 | ||
| 531 | fn is_side_enabled(&self) -> bool { | 441 | fn is_side_enabled(&self) -> bool { |
| 532 | unsafe { | 442 | unsafe { Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).execctrl().read().side_en() } |
| 533 | PIOS[Self::Pio::PIO_NO as usize] | ||
| 534 | .sm(Self::Sm::SM_NO as usize) | ||
| 535 | .execctrl() | ||
| 536 | .read() | ||
| 537 | .side_en() | ||
| 538 | } | ||
| 539 | } | 443 | } |
| 540 | 444 | ||
| 541 | fn set_side_pindir(&mut self, pindir: bool) { | 445 | fn set_side_pindir(&mut self, pindir: bool) { |
| 542 | unsafe { | 446 | unsafe { |
| 543 | PIOS[Self::Pio::PIO_NO as usize] | 447 | Self::Pio::PIO |
| 544 | .sm(Self::Sm::SM_NO as usize) | 448 | .sm(Self::Sm::SM_NO as usize) |
| 545 | .execctrl() | 449 | .execctrl() |
| 546 | .modify(|w| w.set_side_pindir(pindir)); | 450 | .modify(|w| w.set_side_pindir(pindir)); |
| @@ -549,7 +453,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 549 | 453 | ||
| 550 | fn is_side_pindir(&self) -> bool { | 454 | fn is_side_pindir(&self) -> bool { |
| 551 | unsafe { | 455 | unsafe { |
| 552 | PIOS[Self::Pio::PIO_NO as usize] | 456 | Self::Pio::PIO |
| 553 | .sm(Self::Sm::SM_NO as usize) | 457 | .sm(Self::Sm::SM_NO as usize) |
| 554 | .execctrl() | 458 | .execctrl() |
| 555 | .read() | 459 | .read() |
| @@ -559,7 +463,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 559 | 463 | ||
| 560 | fn set_jmp_pin(&mut self, pin: u8) { | 464 | fn set_jmp_pin(&mut self, pin: u8) { |
| 561 | unsafe { | 465 | unsafe { |
| 562 | PIOS[Self::Pio::PIO_NO as usize] | 466 | Self::Pio::PIO |
| 563 | .sm(Self::Sm::SM_NO as usize) | 467 | .sm(Self::Sm::SM_NO as usize) |
| 564 | .execctrl() | 468 | .execctrl() |
| 565 | .modify(|w| w.set_jmp_pin(pin)); | 469 | .modify(|w| w.set_jmp_pin(pin)); |
| @@ -567,34 +471,22 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 567 | } | 471 | } |
| 568 | 472 | ||
| 569 | fn get_jmp_pin(&mut self) -> u8 { | 473 | fn get_jmp_pin(&mut self) -> u8 { |
| 570 | unsafe { | 474 | unsafe { Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).execctrl().read().jmp_pin() } |
| 571 | PIOS[Self::Pio::PIO_NO as usize] | ||
| 572 | .sm(Self::Sm::SM_NO as usize) | ||
| 573 | .execctrl() | ||
| 574 | .read() | ||
| 575 | .jmp_pin() | ||
| 576 | } | ||
| 577 | } | 475 | } |
| 578 | 476 | ||
| 579 | fn set_wrap(&self, source: u8, target: u8) { | 477 | fn set_wrap(&self, source: u8, target: u8) { |
| 580 | unsafe { | 478 | unsafe { |
| 581 | PIOS[Self::Pio::PIO_NO as usize] | 479 | Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).execctrl().modify(|w| { |
| 582 | .sm(Self::Sm::SM_NO as usize) | 480 | w.set_wrap_top(source); |
| 583 | .execctrl() | 481 | w.set_wrap_bottom(target) |
| 584 | .modify(|w| { | 482 | }); |
| 585 | w.set_wrap_top(source); | ||
| 586 | w.set_wrap_bottom(target) | ||
| 587 | }); | ||
| 588 | } | 483 | } |
| 589 | } | 484 | } |
| 590 | 485 | ||
| 591 | /// Get wrapping addresses. Returns (source, target). | 486 | /// Get wrapping addresses. Returns (source, target). |
| 592 | fn get_wrap(&self) -> (u8, u8) { | 487 | fn get_wrap(&self) -> (u8, u8) { |
| 593 | unsafe { | 488 | unsafe { |
| 594 | let r = PIOS[Self::Pio::PIO_NO as usize] | 489 | let r = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).execctrl().read(); |
| 595 | .sm(Self::Sm::SM_NO as usize) | ||
| 596 | .execctrl() | ||
| 597 | .read(); | ||
| 598 | (r.wrap_top(), r.wrap_bottom()) | 490 | (r.wrap_top(), r.wrap_bottom()) |
| 599 | } | 491 | } |
| 600 | } | 492 | } |
| @@ -606,21 +498,15 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 606 | FifoJoin::TxOnly => (false, true), | 498 | FifoJoin::TxOnly => (false, true), |
| 607 | }; | 499 | }; |
| 608 | unsafe { | 500 | unsafe { |
| 609 | PIOS[Self::Pio::PIO_NO as usize] | 501 | Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).shiftctrl().modify(|w| { |
| 610 | .sm(Self::Sm::SM_NO as usize) | 502 | w.set_fjoin_rx(rx); |
| 611 | .shiftctrl() | 503 | w.set_fjoin_tx(tx) |
| 612 | .modify(|w| { | 504 | }); |
| 613 | w.set_fjoin_rx(rx); | ||
| 614 | w.set_fjoin_tx(tx) | ||
| 615 | }); | ||
| 616 | } | 505 | } |
| 617 | } | 506 | } |
| 618 | fn get_fifo_join(&self) -> FifoJoin { | 507 | fn get_fifo_join(&self) -> FifoJoin { |
| 619 | unsafe { | 508 | unsafe { |
| 620 | let r = PIOS[Self::Pio::PIO_NO as usize] | 509 | let r = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).shiftctrl().read(); |
| 621 | .sm(Self::Sm::SM_NO as usize) | ||
| 622 | .shiftctrl() | ||
| 623 | .read(); | ||
| 624 | // Ignores the invalid state when both bits are set | 510 | // Ignores the invalid state when both bits are set |
| 625 | if r.fjoin_rx() { | 511 | if r.fjoin_rx() { |
| 626 | FifoJoin::RxOnly | 512 | FifoJoin::RxOnly |
| @@ -635,9 +521,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 635 | fn clear_fifos(&mut self) { | 521 | fn clear_fifos(&mut self) { |
| 636 | // Toggle FJOIN_RX to flush FIFOs | 522 | // Toggle FJOIN_RX to flush FIFOs |
| 637 | unsafe { | 523 | unsafe { |
| 638 | let shiftctrl = PIOS[Self::Pio::PIO_NO as usize] | 524 | let shiftctrl = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).shiftctrl(); |
| 639 | .sm(Self::Sm::SM_NO as usize) | ||
| 640 | .shiftctrl(); | ||
| 641 | shiftctrl.modify(|w| { | 525 | shiftctrl.modify(|w| { |
| 642 | w.set_fjoin_rx(!w.fjoin_rx()); | 526 | w.set_fjoin_rx(!w.fjoin_rx()); |
| 643 | }); | 527 | }); |
| @@ -649,7 +533,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 649 | 533 | ||
| 650 | fn set_pull_threshold(&mut self, threshold: u8) { | 534 | fn set_pull_threshold(&mut self, threshold: u8) { |
| 651 | unsafe { | 535 | unsafe { |
| 652 | PIOS[Self::Pio::PIO_NO as usize] | 536 | Self::Pio::PIO |
| 653 | .sm(Self::Sm::SM_NO as usize) | 537 | .sm(Self::Sm::SM_NO as usize) |
| 654 | .shiftctrl() | 538 | .shiftctrl() |
| 655 | .modify(|w| w.set_pull_thresh(threshold)); | 539 | .modify(|w| w.set_pull_thresh(threshold)); |
| @@ -658,16 +542,13 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 658 | 542 | ||
| 659 | fn get_pull_threshold(&self) -> u8 { | 543 | fn get_pull_threshold(&self) -> u8 { |
| 660 | unsafe { | 544 | unsafe { |
| 661 | let r = PIOS[Self::Pio::PIO_NO as usize] | 545 | let r = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).shiftctrl().read(); |
| 662 | .sm(Self::Sm::SM_NO as usize) | ||
| 663 | .shiftctrl() | ||
| 664 | .read(); | ||
| 665 | r.pull_thresh() | 546 | r.pull_thresh() |
| 666 | } | 547 | } |
| 667 | } | 548 | } |
| 668 | fn set_push_threshold(&mut self, threshold: u8) { | 549 | fn set_push_threshold(&mut self, threshold: u8) { |
| 669 | unsafe { | 550 | unsafe { |
| 670 | PIOS[Self::Pio::PIO_NO as usize] | 551 | Self::Pio::PIO |
| 671 | .sm(Self::Sm::SM_NO as usize) | 552 | .sm(Self::Sm::SM_NO as usize) |
| 672 | .shiftctrl() | 553 | .shiftctrl() |
| 673 | .modify(|w| w.set_push_thresh(threshold)); | 554 | .modify(|w| w.set_push_thresh(threshold)); |
| @@ -676,17 +557,14 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 676 | 557 | ||
| 677 | fn get_push_threshold(&self) -> u8 { | 558 | fn get_push_threshold(&self) -> u8 { |
| 678 | unsafe { | 559 | unsafe { |
| 679 | let r = PIOS[Self::Pio::PIO_NO as usize] | 560 | let r = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).shiftctrl().read(); |
| 680 | .sm(Self::Sm::SM_NO as usize) | ||
| 681 | .shiftctrl() | ||
| 682 | .read(); | ||
| 683 | r.push_thresh() | 561 | r.push_thresh() |
| 684 | } | 562 | } |
| 685 | } | 563 | } |
| 686 | 564 | ||
| 687 | fn set_out_shift_dir(&mut self, dir: ShiftDirection) { | 565 | fn set_out_shift_dir(&mut self, dir: ShiftDirection) { |
| 688 | unsafe { | 566 | unsafe { |
| 689 | PIOS[Self::Pio::PIO_NO as usize] | 567 | Self::Pio::PIO |
| 690 | .sm(Self::Sm::SM_NO as usize) | 568 | .sm(Self::Sm::SM_NO as usize) |
| 691 | .shiftctrl() | 569 | .shiftctrl() |
| 692 | .modify(|w| w.set_out_shiftdir(dir == ShiftDirection::Right)); | 570 | .modify(|w| w.set_out_shiftdir(dir == ShiftDirection::Right)); |
| @@ -694,7 +572,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 694 | } | 572 | } |
| 695 | fn get_out_shiftdir(&self) -> ShiftDirection { | 573 | fn get_out_shiftdir(&self) -> ShiftDirection { |
| 696 | unsafe { | 574 | unsafe { |
| 697 | if PIOS[Self::Pio::PIO_NO as usize] | 575 | if Self::Pio::PIO |
| 698 | .sm(Self::Sm::SM_NO as usize) | 576 | .sm(Self::Sm::SM_NO as usize) |
| 699 | .shiftctrl() | 577 | .shiftctrl() |
| 700 | .read() | 578 | .read() |
| @@ -709,7 +587,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 709 | 587 | ||
| 710 | fn set_in_shift_dir(&mut self, dir: ShiftDirection) { | 588 | fn set_in_shift_dir(&mut self, dir: ShiftDirection) { |
| 711 | unsafe { | 589 | unsafe { |
| 712 | PIOS[Self::Pio::PIO_NO as usize] | 590 | Self::Pio::PIO |
| 713 | .sm(Self::Sm::SM_NO as usize) | 591 | .sm(Self::Sm::SM_NO as usize) |
| 714 | .shiftctrl() | 592 | .shiftctrl() |
| 715 | .modify(|w| w.set_in_shiftdir(dir == ShiftDirection::Right)); | 593 | .modify(|w| w.set_in_shiftdir(dir == ShiftDirection::Right)); |
| @@ -717,7 +595,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 717 | } | 595 | } |
| 718 | fn get_in_shiftdir(&self) -> ShiftDirection { | 596 | fn get_in_shiftdir(&self) -> ShiftDirection { |
| 719 | unsafe { | 597 | unsafe { |
| 720 | if PIOS[Self::Pio::PIO_NO as usize] | 598 | if Self::Pio::PIO |
| 721 | .sm(Self::Sm::SM_NO as usize) | 599 | .sm(Self::Sm::SM_NO as usize) |
| 722 | .shiftctrl() | 600 | .shiftctrl() |
| 723 | .read() | 601 | .read() |
| @@ -732,7 +610,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 732 | 610 | ||
| 733 | fn set_autopull(&mut self, auto: bool) { | 611 | fn set_autopull(&mut self, auto: bool) { |
| 734 | unsafe { | 612 | unsafe { |
| 735 | PIOS[Self::Pio::PIO_NO as usize] | 613 | Self::Pio::PIO |
| 736 | .sm(Self::Sm::SM_NO as usize) | 614 | .sm(Self::Sm::SM_NO as usize) |
| 737 | .shiftctrl() | 615 | .shiftctrl() |
| 738 | .modify(|w| w.set_autopull(auto)); | 616 | .modify(|w| w.set_autopull(auto)); |
| @@ -741,7 +619,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 741 | 619 | ||
| 742 | fn is_autopull(&self) -> bool { | 620 | fn is_autopull(&self) -> bool { |
| 743 | unsafe { | 621 | unsafe { |
| 744 | PIOS[Self::Pio::PIO_NO as usize] | 622 | Self::Pio::PIO |
| 745 | .sm(Self::Sm::SM_NO as usize) | 623 | .sm(Self::Sm::SM_NO as usize) |
| 746 | .shiftctrl() | 624 | .shiftctrl() |
| 747 | .read() | 625 | .read() |
| @@ -751,7 +629,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 751 | 629 | ||
| 752 | fn set_autopush(&mut self, auto: bool) { | 630 | fn set_autopush(&mut self, auto: bool) { |
| 753 | unsafe { | 631 | unsafe { |
| 754 | PIOS[Self::Pio::PIO_NO as usize] | 632 | Self::Pio::PIO |
| 755 | .sm(Self::Sm::SM_NO as usize) | 633 | .sm(Self::Sm::SM_NO as usize) |
| 756 | .shiftctrl() | 634 | .shiftctrl() |
| 757 | .modify(|w| w.set_autopush(auto)); | 635 | .modify(|w| w.set_autopush(auto)); |
| @@ -760,7 +638,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 760 | 638 | ||
| 761 | fn is_autopush(&self) -> bool { | 639 | fn is_autopush(&self) -> bool { |
| 762 | unsafe { | 640 | unsafe { |
| 763 | PIOS[Self::Pio::PIO_NO as usize] | 641 | Self::Pio::PIO |
| 764 | .sm(Self::Sm::SM_NO as usize) | 642 | .sm(Self::Sm::SM_NO as usize) |
| 765 | .shiftctrl() | 643 | .shiftctrl() |
| 766 | .read() | 644 | .read() |
| @@ -770,16 +648,13 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 770 | 648 | ||
| 771 | fn get_addr(&self) -> u8 { | 649 | fn get_addr(&self) -> u8 { |
| 772 | unsafe { | 650 | unsafe { |
| 773 | let r = PIOS[Self::Pio::PIO_NO as usize] | 651 | let r = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).addr().read(); |
| 774 | .sm(Self::Sm::SM_NO as usize) | ||
| 775 | .addr() | ||
| 776 | .read(); | ||
| 777 | r.addr() | 652 | r.addr() |
| 778 | } | 653 | } |
| 779 | } | 654 | } |
| 780 | fn set_sideset_count(&mut self, count: u8) { | 655 | fn set_sideset_count(&mut self, count: u8) { |
| 781 | unsafe { | 656 | unsafe { |
| 782 | PIOS[Self::Pio::PIO_NO as usize] | 657 | Self::Pio::PIO |
| 783 | .sm(Self::Sm::SM_NO as usize) | 658 | .sm(Self::Sm::SM_NO as usize) |
| 784 | .pinctrl() | 659 | .pinctrl() |
| 785 | .modify(|w| w.set_sideset_count(count)); | 660 | .modify(|w| w.set_sideset_count(count)); |
| @@ -788,37 +663,14 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 788 | 663 | ||
| 789 | fn get_sideset_count(&self) -> u8 { | 664 | fn get_sideset_count(&self) -> u8 { |
| 790 | unsafe { | 665 | unsafe { |
| 791 | let r = PIOS[Self::Pio::PIO_NO as usize] | 666 | let r = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).pinctrl().read(); |
| 792 | .sm(Self::Sm::SM_NO as usize) | ||
| 793 | .pinctrl() | ||
| 794 | .read(); | ||
| 795 | r.sideset_count() | 667 | r.sideset_count() |
| 796 | } | 668 | } |
| 797 | } | 669 | } |
| 798 | 670 | ||
| 799 | fn make_pio_pin(&self, pin: impl Pin) -> PioPin<Self::Pio> { | ||
| 800 | unsafe { | ||
| 801 | pin.io().ctrl().write(|w| { | ||
| 802 | w.set_funcsel( | ||
| 803 | if Self::Pio::PIO_NO == 1 { | ||
| 804 | pac::io::vals::Gpio0ctrlFuncsel::PIO1_0 | ||
| 805 | } else { | ||
| 806 | // PIO == 0 | ||
| 807 | pac::io::vals::Gpio0ctrlFuncsel::PIO0_0 | ||
| 808 | } | ||
| 809 | .0, | ||
| 810 | ); | ||
| 811 | }); | ||
| 812 | } | ||
| 813 | PioPin { | ||
| 814 | pin_bank: pin.pin_bank(), | ||
| 815 | pio: PhantomData::default(), | ||
| 816 | } | ||
| 817 | } | ||
| 818 | |||
| 819 | fn set_sideset_base_pin(&mut self, base_pin: &PioPin<Self::Pio>) { | 671 | fn set_sideset_base_pin(&mut self, base_pin: &PioPin<Self::Pio>) { |
| 820 | unsafe { | 672 | unsafe { |
| 821 | PIOS[Self::Pio::PIO_NO as usize] | 673 | Self::Pio::PIO |
| 822 | .sm(Self::Sm::SM_NO as usize) | 674 | .sm(Self::Sm::SM_NO as usize) |
| 823 | .pinctrl() | 675 | .pinctrl() |
| 824 | .modify(|w| w.set_sideset_base(base_pin.pin())); | 676 | .modify(|w| w.set_sideset_base(base_pin.pin())); |
| @@ -827,10 +679,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 827 | 679 | ||
| 828 | fn get_sideset_base(&self) -> u8 { | 680 | fn get_sideset_base(&self) -> u8 { |
| 829 | unsafe { | 681 | unsafe { |
| 830 | let r = PIOS[Self::Pio::PIO_NO as usize] | 682 | let r = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).pinctrl().read(); |
| 831 | .sm(Self::Sm::SM_NO as usize) | ||
| 832 | .pinctrl() | ||
| 833 | .read(); | ||
| 834 | r.sideset_base() | 683 | r.sideset_base() |
| 835 | } | 684 | } |
| 836 | } | 685 | } |
| @@ -839,30 +688,24 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 839 | fn set_set_range(&mut self, base: u8, count: u8) { | 688 | fn set_set_range(&mut self, base: u8, count: u8) { |
| 840 | assert!(base + count < 32); | 689 | assert!(base + count < 32); |
| 841 | unsafe { | 690 | unsafe { |
| 842 | PIOS[Self::Pio::PIO_NO as usize] | 691 | Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).pinctrl().modify(|w| { |
| 843 | .sm(Self::Sm::SM_NO as usize) | 692 | w.set_set_base(base); |
| 844 | .pinctrl() | 693 | w.set_set_count(count) |
| 845 | .modify(|w| { | 694 | }); |
| 846 | w.set_set_base(base); | ||
| 847 | w.set_set_count(count) | ||
| 848 | }); | ||
| 849 | } | 695 | } |
| 850 | } | 696 | } |
| 851 | 697 | ||
| 852 | /// Get the range of out pins affected by a set instruction. Returns (base, count). | 698 | /// Get the range of out pins affected by a set instruction. Returns (base, count). |
| 853 | fn get_set_range(&self) -> (u8, u8) { | 699 | fn get_set_range(&self) -> (u8, u8) { |
| 854 | unsafe { | 700 | unsafe { |
| 855 | let r = PIOS[Self::Pio::PIO_NO as usize] | 701 | let r = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).pinctrl().read(); |
| 856 | .sm(Self::Sm::SM_NO as usize) | ||
| 857 | .pinctrl() | ||
| 858 | .read(); | ||
| 859 | (r.set_base(), r.set_count()) | 702 | (r.set_base(), r.set_count()) |
| 860 | } | 703 | } |
| 861 | } | 704 | } |
| 862 | 705 | ||
| 863 | fn set_in_base_pin(&mut self, base: &PioPin<Self::Pio>) { | 706 | fn set_in_base_pin(&mut self, base: &PioPin<Self::Pio>) { |
| 864 | unsafe { | 707 | unsafe { |
| 865 | PIOS[Self::Pio::PIO_NO as usize] | 708 | Self::Pio::PIO |
| 866 | .sm(Self::Sm::SM_NO as usize) | 709 | .sm(Self::Sm::SM_NO as usize) |
| 867 | .pinctrl() | 710 | .pinctrl() |
| 868 | .modify(|w| w.set_in_base(base.pin())); | 711 | .modify(|w| w.set_in_base(base.pin())); |
| @@ -871,10 +714,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 871 | 714 | ||
| 872 | fn get_in_base(&self) -> u8 { | 715 | fn get_in_base(&self) -> u8 { |
| 873 | unsafe { | 716 | unsafe { |
| 874 | let r = PIOS[Self::Pio::PIO_NO as usize] | 717 | let r = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).pinctrl().read(); |
| 875 | .sm(Self::Sm::SM_NO as usize) | ||
| 876 | .pinctrl() | ||
| 877 | .read(); | ||
| 878 | r.in_base() | 718 | r.in_base() |
| 879 | } | 719 | } |
| 880 | } | 720 | } |
| @@ -882,23 +722,17 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 882 | fn set_out_range(&mut self, base: u8, count: u8) { | 722 | fn set_out_range(&mut self, base: u8, count: u8) { |
| 883 | assert!(base + count < 32); | 723 | assert!(base + count < 32); |
| 884 | unsafe { | 724 | unsafe { |
| 885 | PIOS[Self::Pio::PIO_NO as usize] | 725 | Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).pinctrl().modify(|w| { |
| 886 | .sm(Self::Sm::SM_NO as usize) | 726 | w.set_out_base(base); |
| 887 | .pinctrl() | 727 | w.set_out_count(count) |
| 888 | .modify(|w| { | 728 | }); |
| 889 | w.set_out_base(base); | ||
| 890 | w.set_out_count(count) | ||
| 891 | }); | ||
| 892 | } | 729 | } |
| 893 | } | 730 | } |
| 894 | 731 | ||
| 895 | /// Get the range of out pins affected by a set instruction. Returns (base, count). | 732 | /// Get the range of out pins affected by a set instruction. Returns (base, count). |
| 896 | fn get_out_range(&self) -> (u8, u8) { | 733 | fn get_out_range(&self) -> (u8, u8) { |
| 897 | unsafe { | 734 | unsafe { |
| 898 | let r = PIOS[Self::Pio::PIO_NO as usize] | 735 | let r = Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).pinctrl().read(); |
| 899 | .sm(Self::Sm::SM_NO as usize) | ||
| 900 | .pinctrl() | ||
| 901 | .read(); | ||
| 902 | (r.out_base(), r.out_count()) | 736 | (r.out_base(), r.out_count()) |
| 903 | } | 737 | } |
| 904 | } | 738 | } |
| @@ -926,50 +760,18 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 926 | } | 760 | } |
| 927 | 761 | ||
| 928 | fn get_current_instr() -> u32 { | 762 | fn get_current_instr() -> u32 { |
| 929 | unsafe { | 763 | unsafe { Self::Pio::PIO.sm(Self::Sm::SM_NO as usize).instr().read().0 } |
| 930 | PIOS[Self::Pio::PIO_NO as usize] | ||
| 931 | .sm(Self::Sm::SM_NO as usize) | ||
| 932 | .instr() | ||
| 933 | .read() | ||
| 934 | .0 | ||
| 935 | } | ||
| 936 | } | 764 | } |
| 937 | 765 | ||
| 938 | fn exec_instr(&mut self, instr: u16) { | 766 | fn exec_instr(&mut self, instr: u16) { |
| 939 | unsafe { | 767 | unsafe { |
| 940 | PIOS[Self::Pio::PIO_NO as usize] | 768 | Self::Pio::PIO |
| 941 | .sm(Self::Sm::SM_NO as usize) | 769 | .sm(Self::Sm::SM_NO as usize) |
| 942 | .instr() | 770 | .instr() |
| 943 | .write(|w| w.set_instr(instr)); | 771 | .write(|w| w.set_instr(instr)); |
| 944 | } | 772 | } |
| 945 | } | 773 | } |
| 946 | 774 | ||
| 947 | fn write_instr<I>(&mut self, start: usize, instrs: I) | ||
| 948 | where | ||
| 949 | I: Iterator<Item = u16>, | ||
| 950 | { | ||
| 951 | let _ = self; | ||
| 952 | write_instr( | ||
| 953 | Self::Pio::PIO_NO, | ||
| 954 | start, | ||
| 955 | instrs, | ||
| 956 | MEM_USED_BY_STATEMACHINE | Self::Sm::SM_NO as u32, | ||
| 957 | ); | ||
| 958 | } | ||
| 959 | |||
| 960 | fn is_irq_set(&self, irq_no: u8) -> bool { | ||
| 961 | assert!(irq_no < 8); | ||
| 962 | unsafe { | ||
| 963 | let irq_flags = PIOS[Self::Pio::PIO_NO as usize].irq(); | ||
| 964 | irq_flags.read().0 & (1 << irq_no) != 0 | ||
| 965 | } | ||
| 966 | } | ||
| 967 | |||
| 968 | fn clear_irq(&mut self, irq_no: usize) { | ||
| 969 | assert!(irq_no < 8); | ||
| 970 | unsafe { PIOS[Self::Pio::PIO_NO as usize].irq().write(|w| w.set_irq(1 << irq_no)) } | ||
| 971 | } | ||
| 972 | |||
| 973 | fn wait_push<'a>(&'a mut self, value: u32) -> FifoOutFuture<'a, Self::Pio, Self> { | 775 | fn wait_push<'a>(&'a mut self, value: u32) -> FifoOutFuture<'a, Self::Pio, Self> { |
| 974 | FifoOutFuture::new(self, value) | 776 | FifoOutFuture::new(self, value) |
| 975 | } | 777 | } |
| @@ -984,7 +786,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 984 | 786 | ||
| 985 | fn has_tx_stalled(&self) -> bool { | 787 | fn has_tx_stalled(&self) -> bool { |
| 986 | unsafe { | 788 | unsafe { |
| 987 | let fdebug = PIOS[Self::Pio::PIO_NO as usize].fdebug(); | 789 | let fdebug = Self::Pio::PIO.fdebug(); |
| 988 | let ret = fdebug.read().txstall() & (1 << Self::Sm::SM_NO) != 0; | 790 | let ret = fdebug.read().txstall() & (1 << Self::Sm::SM_NO) != 0; |
| 989 | fdebug.write(|w| w.set_txstall(1 << Self::Sm::SM_NO)); | 791 | fdebug.write(|w| w.set_txstall(1 << Self::Sm::SM_NO)); |
| 990 | ret | 792 | ret |
| @@ -993,7 +795,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 993 | 795 | ||
| 994 | fn has_tx_overflowed(&self) -> bool { | 796 | fn has_tx_overflowed(&self) -> bool { |
| 995 | unsafe { | 797 | unsafe { |
| 996 | let fdebug = PIOS[Self::Pio::PIO_NO as usize].fdebug(); | 798 | let fdebug = Self::Pio::PIO.fdebug(); |
| 997 | let ret = fdebug.read().txover() & (1 << Self::Sm::SM_NO) != 0; | 799 | let ret = fdebug.read().txover() & (1 << Self::Sm::SM_NO) != 0; |
| 998 | fdebug.write(|w| w.set_txover(1 << Self::Sm::SM_NO)); | 800 | fdebug.write(|w| w.set_txover(1 << Self::Sm::SM_NO)); |
| 999 | ret | 801 | ret |
| @@ -1002,7 +804,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 1002 | 804 | ||
| 1003 | fn has_rx_stalled(&self) -> bool { | 805 | fn has_rx_stalled(&self) -> bool { |
| 1004 | unsafe { | 806 | unsafe { |
| 1005 | let fdebug = PIOS[Self::Pio::PIO_NO as usize].fdebug(); | 807 | let fdebug = Self::Pio::PIO.fdebug(); |
| 1006 | let ret = fdebug.read().rxstall() & (1 << Self::Sm::SM_NO) != 0; | 808 | let ret = fdebug.read().rxstall() & (1 << Self::Sm::SM_NO) != 0; |
| 1007 | fdebug.write(|w| w.set_rxstall(1 << Self::Sm::SM_NO)); | 809 | fdebug.write(|w| w.set_rxstall(1 << Self::Sm::SM_NO)); |
| 1008 | ret | 810 | ret |
| @@ -1011,7 +813,7 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 1011 | 813 | ||
| 1012 | fn has_rx_underflowed(&self) -> bool { | 814 | fn has_rx_underflowed(&self) -> bool { |
| 1013 | unsafe { | 815 | unsafe { |
| 1014 | let fdebug = PIOS[Self::Pio::PIO_NO as usize].fdebug(); | 816 | let fdebug = Self::Pio::PIO.fdebug(); |
| 1015 | let ret = fdebug.read().rxunder() & (1 << Self::Sm::SM_NO) != 0; | 817 | let ret = fdebug.read().rxunder() & (1 << Self::Sm::SM_NO) != 0; |
| 1016 | fdebug.write(|w| w.set_rxunder(1 << Self::Sm::SM_NO)); | 818 | fdebug.write(|w| w.set_rxunder(1 << Self::Sm::SM_NO)); |
| 1017 | ret | 819 | ret |
| @@ -1020,13 +822,12 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 1020 | 822 | ||
| 1021 | fn dma_push<'a, C: Channel>(&'a self, ch: PeripheralRef<'a, C>, data: &'a [u32]) -> Transfer<'a, C> { | 823 | fn dma_push<'a, C: Channel>(&'a self, ch: PeripheralRef<'a, C>, data: &'a [u32]) -> Transfer<'a, C> { |
| 1022 | unsafe { | 824 | unsafe { |
| 1023 | dma::init(); | ||
| 1024 | let pio_no = Self::Pio::PIO_NO; | 825 | let pio_no = Self::Pio::PIO_NO; |
| 1025 | let sm_no = Self::Sm::SM_NO; | 826 | let sm_no = Self::Sm::SM_NO; |
| 1026 | let p = ch.regs(); | 827 | let p = ch.regs(); |
| 1027 | p.read_addr().write_value(data.as_ptr() as u32); | 828 | p.read_addr().write_value(data.as_ptr() as u32); |
| 1028 | p.write_addr() | 829 | p.write_addr() |
| 1029 | .write_value(PIOS[pio_no as usize].txf(sm_no as usize).ptr() as u32); | 830 | .write_value(Self::Pio::PIO.txf(sm_no as usize).ptr() as u32); |
| 1030 | p.trans_count().write_value(data.len() as u32); | 831 | p.trans_count().write_value(data.len() as u32); |
| 1031 | p.ctrl_trig().write(|w| { | 832 | p.ctrl_trig().write(|w| { |
| 1032 | // Set TX DREQ for this statemachine | 833 | // Set TX DREQ for this statemachine |
| @@ -1044,13 +845,12 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 1044 | 845 | ||
| 1045 | fn dma_pull<'a, C: Channel>(&'a self, ch: PeripheralRef<'a, C>, data: &'a mut [u32]) -> Transfer<'a, C> { | 846 | fn dma_pull<'a, C: Channel>(&'a self, ch: PeripheralRef<'a, C>, data: &'a mut [u32]) -> Transfer<'a, C> { |
| 1046 | unsafe { | 847 | unsafe { |
| 1047 | dma::init(); | ||
| 1048 | let pio_no = Self::Pio::PIO_NO; | 848 | let pio_no = Self::Pio::PIO_NO; |
| 1049 | let sm_no = Self::Sm::SM_NO; | 849 | let sm_no = Self::Sm::SM_NO; |
| 1050 | let p = ch.regs(); | 850 | let p = ch.regs(); |
| 1051 | p.write_addr().write_value(data.as_ptr() as u32); | 851 | p.write_addr().write_value(data.as_ptr() as u32); |
| 1052 | p.read_addr() | 852 | p.read_addr() |
| 1053 | .write_value(PIOS[pio_no as usize].rxf(sm_no as usize).ptr() as u32); | 853 | .write_value(Self::Pio::PIO.rxf(sm_no as usize).ptr() as u32); |
| 1054 | p.trans_count().write_value(data.len() as u32); | 854 | p.trans_count().write_value(data.len() as u32); |
| 1055 | p.ctrl_trig().write(|w| { | 855 | p.ctrl_trig().write(|w| { |
| 1056 | // Set TX DREQ for this statemachine | 856 | // Set TX DREQ for this statemachine |
| @@ -1067,120 +867,127 @@ pub trait PioStateMachine: Sized + Unpin { | |||
| 1067 | } | 867 | } |
| 1068 | } | 868 | } |
| 1069 | 869 | ||
| 1070 | /* | 870 | pub struct PioCommonInstance<PIO: PioInstance> { |
| 1071 | This is a bit array containing 4 bits for every word in the PIO instruction memory. | 871 | instructions_used: u32, |
| 1072 | */ | 872 | pio: PhantomData<PIO>, |
| 1073 | // Bit 3-2 | ||
| 1074 | //const MEM_USE_MASK: u32 = 0b1100; | ||
| 1075 | const MEM_NOT_USED: u32 = 0b0000; | ||
| 1076 | const MEM_USED_BY_STATEMACHINE: u32 = 0b0100; | ||
| 1077 | const MEM_USED_BY_COMMON: u32 = 0b1000; | ||
| 1078 | |||
| 1079 | // Bit 1-0 is the number of the state machine | ||
| 1080 | //const MEM_STATE_MASK: u32 = 0b0011; | ||
| 1081 | |||
| 1082 | // Should use mutex if running on multiple cores | ||
| 1083 | static mut INSTR_MEM_STATUS: &'static mut [[u32; 4]; 2] = &mut [[0; 4]; 2]; | ||
| 1084 | |||
| 1085 | fn instr_mem_get_status(pio_no: u8, addr: u8) -> u32 { | ||
| 1086 | ((unsafe { INSTR_MEM_STATUS[pio_no as usize][(addr >> 3) as usize] }) >> ((addr & 0x07) * 4)) & 0xf | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | fn instr_mem_set_status(pio_no: u8, addr: u8, status: u32) { | ||
| 1090 | let w = unsafe { &mut INSTR_MEM_STATUS[pio_no as usize][(addr >> 3) as usize] }; | ||
| 1091 | let shift = (addr & 0x07) * 4; | ||
| 1092 | *w = (*w & !(0xf << shift)) | (status << shift); | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | fn instr_mem_is_free(pio_no: u8, addr: u8) -> bool { | ||
| 1096 | instr_mem_get_status(pio_no, addr) == MEM_NOT_USED | ||
| 1097 | } | 873 | } |
| 1098 | 874 | ||
| 1099 | pub struct PioCommonInstance<PIO: PioInstance> { | 875 | pub struct PioInstanceMemory<PIO: PioInstance> { |
| 876 | used_mask: u32, | ||
| 1100 | pio: PhantomData<PIO>, | 877 | pio: PhantomData<PIO>, |
| 1101 | } | 878 | } |
| 1102 | 879 | ||
| 1103 | impl<PIO: PioInstance> PioCommon for PioCommonInstance<PIO> { | 880 | impl<PIO: PioInstance> sealed::PioCommon for PioCommonInstance<PIO> { |
| 1104 | type Pio = PIO; | 881 | type Pio = PIO; |
| 1105 | } | 882 | } |
| 1106 | 883 | impl<PIO: PioInstance> PioCommon for PioCommonInstance<PIO> { | |
| 1107 | fn write_instr<I>(pio_no: u8, start: usize, instrs: I, mem_user: u32) | 884 | fn write_instr<I>(&mut self, start: usize, instrs: I) -> PioInstanceMemory<Self::Pio> |
| 1108 | where | 885 | where |
| 1109 | I: Iterator<Item = u16>, | 886 | I: Iterator<Item = u16>, |
| 1110 | { | 887 | { |
| 1111 | for (i, instr) in instrs.enumerate() { | 888 | let mut used_mask = 0; |
| 1112 | let addr = (i + start) as u8; | 889 | for (i, instr) in instrs.enumerate() { |
| 1113 | assert!( | 890 | let addr = (i + start) as u8; |
| 1114 | instr_mem_is_free(pio_no, addr), | 891 | let mask = 1 << (addr as usize); |
| 1115 | "Trying to write already used PIO instruction memory at {}", | 892 | assert!( |
| 1116 | addr | 893 | self.instructions_used & mask == 0, |
| 1117 | ); | 894 | "Trying to write already used PIO instruction memory at {}", |
| 1118 | unsafe { | 895 | addr |
| 1119 | PIOS[pio_no as usize].instr_mem(addr as usize).write(|w| { | 896 | ); |
| 1120 | w.set_instr_mem(instr); | 897 | unsafe { |
| 1121 | }); | 898 | PIO::PIO.instr_mem(addr as usize).write(|w| { |
| 1122 | instr_mem_set_status(pio_no, addr, mem_user); | 899 | w.set_instr_mem(instr); |
| 900 | }); | ||
| 901 | } | ||
| 902 | used_mask |= mask; | ||
| 903 | } | ||
| 904 | self.instructions_used |= used_mask; | ||
| 905 | PioInstanceMemory { | ||
| 906 | used_mask, | ||
| 907 | pio: PhantomData, | ||
| 1123 | } | 908 | } |
| 1124 | } | 909 | } |
| 1125 | } | ||
| 1126 | 910 | ||
| 1127 | pub trait PioCommon: Sized { | 911 | fn free_instr(&mut self, instrs: PioInstanceMemory<Self::Pio>) { |
| 1128 | type Pio: PioInstance; | 912 | self.instructions_used &= !instrs.used_mask; |
| 913 | } | ||
| 914 | } | ||
| 1129 | 915 | ||
| 1130 | fn write_instr<I>(&mut self, start: usize, instrs: I) | 916 | pub trait PioCommon: sealed::PioCommon + Sized { |
| 917 | fn write_instr<I>(&mut self, start: usize, instrs: I) -> PioInstanceMemory<Self::Pio> | ||
| 1131 | where | 918 | where |
| 1132 | I: Iterator<Item = u16>, | 919 | I: Iterator<Item = u16>; |
| 1133 | { | 920 | |
| 1134 | let _ = self; | 921 | // TODO make instruction memory that is currently in use unfreeable |
| 1135 | write_instr(Self::Pio::PIO_NO, start, instrs, MEM_USED_BY_COMMON); | 922 | fn free_instr(&mut self, instrs: PioInstanceMemory<Self::Pio>); |
| 923 | |||
| 924 | fn is_irq_set(&self, irq_no: u8) -> bool { | ||
| 925 | assert!(irq_no < 8); | ||
| 926 | unsafe { | ||
| 927 | let irq_flags = Self::Pio::PIO.irq(); | ||
| 928 | irq_flags.read().0 & (1 << irq_no) != 0 | ||
| 929 | } | ||
| 1136 | } | 930 | } |
| 1137 | 931 | ||
| 1138 | fn clear_irq(&mut self, irq_no: usize) { | 932 | fn clear_irq(&mut self, irq_no: usize) { |
| 1139 | assert!(irq_no < 8); | 933 | assert!(irq_no < 8); |
| 1140 | unsafe { PIOS[Self::Pio::PIO_NO as usize].irq().write(|w| w.set_irq(1 << irq_no)) } | 934 | unsafe { Self::Pio::PIO.irq().write(|w| w.set_irq(1 << irq_no)) } |
| 1141 | } | 935 | } |
| 1142 | 936 | ||
| 1143 | fn clear_irqs(&mut self, mask: u8) { | 937 | fn clear_irqs(&mut self, mask: u8) { |
| 1144 | unsafe { PIOS[Self::Pio::PIO_NO as usize].irq().write(|w| w.set_irq(mask)) } | 938 | unsafe { Self::Pio::PIO.irq().write(|w| w.set_irq(mask)) } |
| 1145 | } | 939 | } |
| 1146 | 940 | ||
| 1147 | fn force_irq(&mut self, irq_no: usize) { | 941 | fn force_irq(&mut self, irq_no: usize) { |
| 1148 | assert!(irq_no < 8); | 942 | assert!(irq_no < 8); |
| 1149 | unsafe { | 943 | unsafe { Self::Pio::PIO.irq_force().write(|w| w.set_irq_force(1 << irq_no)) } |
| 1150 | PIOS[Self::Pio::PIO_NO as usize] | ||
| 1151 | .irq_force() | ||
| 1152 | .write(|w| w.set_irq_force(1 << irq_no)) | ||
| 1153 | } | ||
| 1154 | } | 944 | } |
| 1155 | 945 | ||
| 1156 | fn set_input_sync_bypass<'a>(&'a mut self, bypass: u32, mask: u32) { | 946 | fn set_input_sync_bypass<'a>(&'a mut self, bypass: u32, mask: u32) { |
| 1157 | unsafe { | 947 | unsafe { |
| 1158 | PIOS[Self::Pio::PIO_NO as usize] | 948 | Self::Pio::PIO |
| 1159 | .input_sync_bypass() | 949 | .input_sync_bypass() |
| 1160 | .modify(|w| *w = (*w & !mask) | (bypass & mask)); | 950 | .modify(|w| *w = (*w & !mask) | (bypass & mask)); |
| 1161 | } | 951 | } |
| 1162 | } | 952 | } |
| 1163 | 953 | ||
| 1164 | fn get_input_sync_bypass(&self) -> u32 { | 954 | fn get_input_sync_bypass(&self) -> u32 { |
| 1165 | unsafe { PIOS[Self::Pio::PIO_NO as usize].input_sync_bypass().read() } | 955 | unsafe { Self::Pio::PIO.input_sync_bypass().read() } |
| 956 | } | ||
| 957 | |||
| 958 | fn make_pio_pin(&self, pin: impl Pin) -> PioPin<Self::Pio> { | ||
| 959 | unsafe { | ||
| 960 | pin.io().ctrl().write(|w| { | ||
| 961 | w.set_funcsel( | ||
| 962 | if Self::Pio::PIO_NO == 1 { | ||
| 963 | pac::io::vals::Gpio0ctrlFuncsel::PIO1_0 | ||
| 964 | } else { | ||
| 965 | // PIO == 0 | ||
| 966 | pac::io::vals::Gpio0ctrlFuncsel::PIO0_0 | ||
| 967 | } | ||
| 968 | .0, | ||
| 969 | ); | ||
| 970 | }); | ||
| 971 | } | ||
| 972 | PioPin { | ||
| 973 | pin_bank: pin.pin_bank(), | ||
| 974 | pio: PhantomData::default(), | ||
| 975 | } | ||
| 1166 | } | 976 | } |
| 1167 | } | 977 | } |
| 1168 | 978 | ||
| 1169 | // Identifies a specific state machine inside a PIO device | 979 | // Identifies a specific state machine inside a PIO device |
| 1170 | pub struct SmInstanceBase<const SM_NO: u8> {} | 980 | pub struct SmInstanceBase<const SM_NO: u8> {} |
| 1171 | 981 | ||
| 1172 | pub trait SmInstance: Unpin { | 982 | pub trait SmInstance: sealed::SmInstance + Unpin {} |
| 1173 | const SM_NO: u8; | ||
| 1174 | } | ||
| 1175 | 983 | ||
| 1176 | impl<const SM_NO: u8> SmInstance for SmInstanceBase<SM_NO> { | 984 | impl<const SM_NO: u8> sealed::SmInstance for SmInstanceBase<SM_NO> { |
| 1177 | const SM_NO: u8 = SM_NO; | 985 | const SM_NO: u8 = SM_NO; |
| 1178 | } | 986 | } |
| 987 | impl<const SM_NO: u8> SmInstance for SmInstanceBase<SM_NO> {} | ||
| 1179 | 988 | ||
| 1180 | pub trait PioPeripheral: Sized { | 989 | pub trait PioPeripheral: sealed::PioPeripheral + Sized { |
| 1181 | type Pio: PioInstance; | ||
| 1182 | fn pio(&self) -> u8 { | 990 | fn pio(&self) -> u8 { |
| 1183 | let _ = self; | ||
| 1184 | Self::Pio::PIO_NO | 991 | Self::Pio::PIO_NO |
| 1185 | } | 992 | } |
| 1186 | 993 | ||
| @@ -1193,9 +1000,9 @@ pub trait PioPeripheral: Sized { | |||
| 1193 | PioStateMachineInstance<Self::Pio, SmInstanceBase<2>>, | 1000 | PioStateMachineInstance<Self::Pio, SmInstanceBase<2>>, |
| 1194 | PioStateMachineInstance<Self::Pio, SmInstanceBase<3>>, | 1001 | PioStateMachineInstance<Self::Pio, SmInstanceBase<3>>, |
| 1195 | ) { | 1002 | ) { |
| 1196 | let _ = self; | ||
| 1197 | ( | 1003 | ( |
| 1198 | PioCommonInstance { | 1004 | PioCommonInstance { |
| 1005 | instructions_used: 0, | ||
| 1199 | pio: PhantomData::default(), | 1006 | pio: PhantomData::default(), |
| 1200 | }, | 1007 | }, |
| 1201 | PioStateMachineInstance { | 1008 | PioStateMachineInstance { |
| @@ -1218,29 +1025,46 @@ pub trait PioPeripheral: Sized { | |||
| 1218 | } | 1025 | } |
| 1219 | } | 1026 | } |
| 1220 | 1027 | ||
| 1028 | mod sealed { | ||
| 1029 | pub trait PioInstance { | ||
| 1030 | const PIO_NO: u8; | ||
| 1031 | const PIO: &'static crate::pac::pio::Pio; | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | pub trait PioCommon { | ||
| 1035 | type Pio: super::PioInstance; | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | pub trait PioStateMachine { | ||
| 1039 | type Pio: super::PioInstance; | ||
| 1040 | type Sm: super::SmInstance; | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | pub trait SmInstance { | ||
| 1044 | const SM_NO: u8; | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | pub trait PioPeripheral { | ||
| 1048 | type Pio: super::PioInstance; | ||
| 1049 | } | ||
| 1050 | } | ||
| 1051 | |||
| 1221 | // Identifies a specific PIO device | 1052 | // Identifies a specific PIO device |
| 1222 | pub struct PioInstanceBase<const PIO_NO: u8> {} | 1053 | pub struct PioInstanceBase<const PIO_NO: u8> {} |
| 1223 | 1054 | ||
| 1224 | pub trait PioInstance: Unpin { | 1055 | pub trait PioInstance: sealed::PioInstance + Unpin {} |
| 1225 | const PIO_NO: u8; | ||
| 1226 | type IrqOut: Interrupt; | ||
| 1227 | type IrqIn: Interrupt; | ||
| 1228 | type IrqSm: Interrupt; | ||
| 1229 | } | ||
| 1230 | 1056 | ||
| 1231 | impl PioInstance for PioInstanceBase<0> { | 1057 | impl sealed::PioInstance for PioInstanceBase<0> { |
| 1232 | const PIO_NO: u8 = 0; | 1058 | const PIO_NO: u8 = 0; |
| 1233 | type IrqOut = interrupt::PIO0_IRQ_0; | 1059 | const PIO: &'static pac::pio::Pio = &pac::PIO0; |
| 1234 | type IrqIn = interrupt::PIO0_IRQ_1; | ||
| 1235 | type IrqSm = interrupt::PIO0_IRQ_1; | ||
| 1236 | } | 1060 | } |
| 1061 | impl PioInstance for PioInstanceBase<0> {} | ||
| 1237 | 1062 | ||
| 1238 | impl PioInstance for PioInstanceBase<1> { | 1063 | impl sealed::PioInstance for PioInstanceBase<1> { |
| 1239 | const PIO_NO: u8 = 1; | 1064 | const PIO_NO: u8 = 1; |
| 1240 | type IrqOut = interrupt::PIO1_IRQ_0; | 1065 | const PIO: &'static pac::pio::Pio = &pac::PIO1; |
| 1241 | type IrqIn = interrupt::PIO1_IRQ_1; | ||
| 1242 | type IrqSm = interrupt::PIO1_IRQ_1; | ||
| 1243 | } | 1066 | } |
| 1067 | impl PioInstance for PioInstanceBase<1> {} | ||
| 1244 | 1068 | ||
| 1245 | pub type Pio0 = PioInstanceBase<0>; | 1069 | pub type Pio0 = PioInstanceBase<0>; |
| 1246 | pub type Pio1 = PioInstanceBase<1>; | 1070 | pub type Pio1 = PioInstanceBase<1>; |
| @@ -1252,9 +1076,10 @@ pub type Sm3 = SmInstanceBase<3>; | |||
| 1252 | 1076 | ||
| 1253 | macro_rules! impl_pio_sm { | 1077 | macro_rules! impl_pio_sm { |
| 1254 | ($name:ident, $pio:expr) => { | 1078 | ($name:ident, $pio:expr) => { |
| 1255 | impl PioPeripheral for peripherals::$name { | 1079 | impl sealed::PioPeripheral for peripherals::$name { |
| 1256 | type Pio = PioInstanceBase<$pio>; | 1080 | type Pio = PioInstanceBase<$pio>; |
| 1257 | } | 1081 | } |
| 1082 | impl PioPeripheral for peripherals::$name {} | ||
| 1258 | }; | 1083 | }; |
| 1259 | } | 1084 | } |
| 1260 | 1085 | ||
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index e616d8c5a..1b075b8fd 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs | |||
| @@ -4,13 +4,15 @@ | |||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_rp::gpio::{AnyPin, Pin}; | 6 | use embassy_rp::gpio::{AnyPin, Pin}; |
| 7 | use embassy_rp::pio::{Pio0, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2}; | 7 | use embassy_rp::pio::{ |
| 8 | Pio0, PioCommon, PioCommonInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, | ||
| 9 | Sm1, Sm2, | ||
| 10 | }; | ||
| 8 | use embassy_rp::pio_instr_util; | 11 | use embassy_rp::pio_instr_util; |
| 9 | use embassy_rp::relocate::RelocatedProgram; | 12 | use embassy_rp::relocate::RelocatedProgram; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 14 | ||
| 12 | #[embassy_executor::task] | 15 | fn setup_pio_task_sm0(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) { |
| 13 | async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) { | ||
| 14 | // Setup sm0 | 16 | // Setup sm0 |
| 15 | 17 | ||
| 16 | // Send data serially to pin | 18 | // Send data serially to pin |
| @@ -23,11 +25,11 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) { | |||
| 23 | ); | 25 | ); |
| 24 | 26 | ||
| 25 | let relocated = RelocatedProgram::new(&prg.program); | 27 | let relocated = RelocatedProgram::new(&prg.program); |
| 26 | let out_pin = sm.make_pio_pin(pin); | 28 | let out_pin = pio.make_pio_pin(pin); |
| 27 | let pio_pins = [&out_pin]; | 29 | let pio_pins = [&out_pin]; |
| 28 | sm.set_out_pins(&pio_pins); | 30 | sm.set_out_pins(&pio_pins); |
| 29 | sm.write_instr(relocated.origin() as usize, relocated.code()); | 31 | pio.write_instr(relocated.origin() as usize, relocated.code()); |
| 30 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); | 32 | pio_instr_util::exec_jmp(sm, relocated.origin()); |
| 31 | sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32); | 33 | sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32); |
| 32 | sm.set_set_range(0, 1); | 34 | sm.set_set_range(0, 1); |
| 33 | let pio::Wrap { source, target } = relocated.wrap(); | 35 | let pio::Wrap { source, target } = relocated.wrap(); |
| @@ -35,7 +37,10 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) { | |||
| 35 | 37 | ||
| 36 | sm.set_autopull(true); | 38 | sm.set_autopull(true); |
| 37 | sm.set_out_shift_dir(ShiftDirection::Left); | 39 | sm.set_out_shift_dir(ShiftDirection::Left); |
| 40 | } | ||
| 38 | 41 | ||
| 42 | #[embassy_executor::task] | ||
| 43 | async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>) { | ||
| 39 | sm.set_enable(true); | 44 | sm.set_enable(true); |
| 40 | 45 | ||
| 41 | let mut v = 0x0f0caffa; | 46 | let mut v = 0x0f0caffa; |
| @@ -46,16 +51,15 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) { | |||
| 46 | } | 51 | } |
| 47 | } | 52 | } |
| 48 | 53 | ||
| 49 | #[embassy_executor::task] | 54 | fn setup_pio_task_sm1(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm1>) { |
| 50 | async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) { | ||
| 51 | // Setupm sm1 | 55 | // Setupm sm1 |
| 52 | 56 | ||
| 53 | // Read 0b10101 repeatedly until ISR is full | 57 | // Read 0b10101 repeatedly until ISR is full |
| 54 | let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",); | 58 | let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",); |
| 55 | 59 | ||
| 56 | let relocated = RelocatedProgram::new(&prg.program); | 60 | let relocated = RelocatedProgram::new(&prg.program); |
| 57 | sm.write_instr(relocated.origin() as usize, relocated.code()); | 61 | pio.write_instr(relocated.origin() as usize, relocated.code()); |
| 58 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); | 62 | pio_instr_util::exec_jmp(sm, relocated.origin()); |
| 59 | sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); | 63 | sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); |
| 60 | sm.set_set_range(0, 0); | 64 | sm.set_set_range(0, 0); |
| 61 | let pio::Wrap { source, target } = relocated.wrap(); | 65 | let pio::Wrap { source, target } = relocated.wrap(); |
| @@ -63,6 +67,10 @@ async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) { | |||
| 63 | 67 | ||
| 64 | sm.set_autopush(true); | 68 | sm.set_autopush(true); |
| 65 | sm.set_in_shift_dir(ShiftDirection::Right); | 69 | sm.set_in_shift_dir(ShiftDirection::Right); |
| 70 | } | ||
| 71 | |||
| 72 | #[embassy_executor::task] | ||
| 73 | async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) { | ||
| 66 | sm.set_enable(true); | 74 | sm.set_enable(true); |
| 67 | loop { | 75 | loop { |
| 68 | let rx = sm.wait_pull().await; | 76 | let rx = sm.wait_pull().await; |
| @@ -70,8 +78,7 @@ async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) { | |||
| 70 | } | 78 | } |
| 71 | } | 79 | } |
| 72 | 80 | ||
| 73 | #[embassy_executor::task] | 81 | fn setup_pio_task_sm2(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm2>) { |
| 74 | async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) { | ||
| 75 | // Setup sm2 | 82 | // Setup sm2 |
| 76 | 83 | ||
| 77 | // Repeatedly trigger IRQ 3 | 84 | // Repeatedly trigger IRQ 3 |
| @@ -85,13 +92,17 @@ async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) { | |||
| 85 | ".wrap", | 92 | ".wrap", |
| 86 | ); | 93 | ); |
| 87 | let relocated = RelocatedProgram::new(&prg.program); | 94 | let relocated = RelocatedProgram::new(&prg.program); |
| 88 | sm.write_instr(relocated.origin() as usize, relocated.code()); | 95 | pio.write_instr(relocated.origin() as usize, relocated.code()); |
| 89 | 96 | ||
| 90 | let pio::Wrap { source, target } = relocated.wrap(); | 97 | let pio::Wrap { source, target } = relocated.wrap(); |
| 91 | sm.set_wrap(source, target); | 98 | sm.set_wrap(source, target); |
| 92 | 99 | ||
| 93 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); | 100 | pio_instr_util::exec_jmp(sm, relocated.origin()); |
| 94 | sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); | 101 | sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); |
| 102 | } | ||
| 103 | |||
| 104 | #[embassy_executor::task] | ||
| 105 | async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) { | ||
| 95 | sm.set_enable(true); | 106 | sm.set_enable(true); |
| 96 | loop { | 107 | loop { |
| 97 | sm.wait_irq(3).await; | 108 | sm.wait_irq(3).await; |
| @@ -104,9 +115,12 @@ async fn main(spawner: Spawner) { | |||
| 104 | let p = embassy_rp::init(Default::default()); | 115 | let p = embassy_rp::init(Default::default()); |
| 105 | let pio = p.PIO0; | 116 | let pio = p.PIO0; |
| 106 | 117 | ||
| 107 | let (_, sm0, sm1, sm2, ..) = pio.split(); | 118 | let (mut pio0, mut sm0, mut sm1, mut sm2, ..) = pio.split(); |
| 108 | 119 | ||
| 109 | spawner.spawn(pio_task_sm0(sm0, p.PIN_0.degrade())).unwrap(); | 120 | setup_pio_task_sm0(&mut pio0, &mut sm0, p.PIN_0.degrade()); |
| 121 | setup_pio_task_sm1(&mut pio0, &mut sm1); | ||
| 122 | setup_pio_task_sm2(&mut pio0, &mut sm2); | ||
| 123 | spawner.spawn(pio_task_sm0(sm0)).unwrap(); | ||
| 110 | spawner.spawn(pio_task_sm1(sm1)).unwrap(); | 124 | spawner.spawn(pio_task_sm1(sm1)).unwrap(); |
| 111 | spawner.spawn(pio_task_sm2(sm2)).unwrap(); | 125 | spawner.spawn(pio_task_sm2(sm2)).unwrap(); |
| 112 | } | 126 | } |
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs index 145e4a656..7d4919f75 100644 --- a/examples/rp/src/bin/pio_dma.rs +++ b/examples/rp/src/bin/pio_dma.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| 7 | use embassy_rp::pio::{PioPeripheral, PioStateMachine, ShiftDirection}; | 7 | use embassy_rp::pio::{PioCommon, PioPeripheral, PioStateMachine, ShiftDirection}; |
| 8 | use embassy_rp::relocate::RelocatedProgram; | 8 | use embassy_rp::relocate::RelocatedProgram; |
| 9 | use embassy_rp::{pio_instr_util, Peripheral}; | 9 | use embassy_rp::{pio_instr_util, Peripheral}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -19,7 +19,7 @@ fn swap_nibbles(v: u32) -> u32 { | |||
| 19 | async fn main(_spawner: Spawner) { | 19 | async fn main(_spawner: Spawner) { |
| 20 | let p = embassy_rp::init(Default::default()); | 20 | let p = embassy_rp::init(Default::default()); |
| 21 | let pio = p.PIO0; | 21 | let pio = p.PIO0; |
| 22 | let (_, mut sm, ..) = pio.split(); | 22 | let (mut pio0, mut sm, ..) = pio.split(); |
| 23 | 23 | ||
| 24 | let prg = pio_proc::pio_asm!( | 24 | let prg = pio_proc::pio_asm!( |
| 25 | ".origin 0", | 25 | ".origin 0", |
| @@ -34,7 +34,7 @@ async fn main(_spawner: Spawner) { | |||
| 34 | ); | 34 | ); |
| 35 | 35 | ||
| 36 | let relocated = RelocatedProgram::new(&prg.program); | 36 | let relocated = RelocatedProgram::new(&prg.program); |
| 37 | sm.write_instr(relocated.origin() as usize, relocated.code()); | 37 | pio0.write_instr(relocated.origin() as usize, relocated.code()); |
| 38 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); | 38 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); |
| 39 | sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); | 39 | sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); |
| 40 | let pio::Wrap { source, target } = relocated.wrap(); | 40 | let pio::Wrap { source, target } = relocated.wrap(); |
diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs index 5f8a3baee..041e8ae11 100644 --- a/examples/rp/src/bin/ws2812-pio.rs +++ b/examples/rp/src/bin/ws2812-pio.rs | |||
| @@ -6,7 +6,8 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::gpio::{self, Pin}; | 7 | use embassy_rp::gpio::{self, Pin}; |
| 8 | use embassy_rp::pio::{ | 8 | use embassy_rp::pio::{ |
| 9 | FifoJoin, PioInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, SmInstance, | 9 | FifoJoin, PioCommon, PioCommonInstance, PioInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, |
| 10 | ShiftDirection, SmInstance, | ||
| 10 | }; | 11 | }; |
| 11 | use embassy_rp::pio_instr_util; | 12 | use embassy_rp::pio_instr_util; |
| 12 | use embassy_rp::relocate::RelocatedProgram; | 13 | use embassy_rp::relocate::RelocatedProgram; |
| @@ -18,7 +19,7 @@ pub struct Ws2812<P: PioInstance, S: SmInstance> { | |||
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | impl<P: PioInstance, S: SmInstance> Ws2812<P, S> { | 21 | impl<P: PioInstance, S: SmInstance> Ws2812<P, S> { |
| 21 | pub fn new(mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self { | 22 | pub fn new(mut pio: PioCommonInstance<P>, mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self { |
| 22 | // Setup sm0 | 23 | // Setup sm0 |
| 23 | 24 | ||
| 24 | // prepare the PIO program | 25 | // prepare the PIO program |
| @@ -49,11 +50,11 @@ impl<P: PioInstance, S: SmInstance> Ws2812<P, S> { | |||
| 49 | let prg = a.assemble_with_wrap(wrap_source, wrap_target); | 50 | let prg = a.assemble_with_wrap(wrap_source, wrap_target); |
| 50 | 51 | ||
| 51 | let relocated = RelocatedProgram::new(&prg); | 52 | let relocated = RelocatedProgram::new(&prg); |
| 52 | sm.write_instr(relocated.origin() as usize, relocated.code()); | 53 | pio.write_instr(relocated.origin() as usize, relocated.code()); |
| 53 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); | 54 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); |
| 54 | 55 | ||
| 55 | // Pin config | 56 | // Pin config |
| 56 | let out_pin = sm.make_pio_pin(pin); | 57 | let out_pin = pio.make_pio_pin(pin); |
| 57 | sm.set_set_pins(&[&out_pin]); | 58 | sm.set_set_pins(&[&out_pin]); |
| 58 | sm.set_sideset_base_pin(&out_pin); | 59 | sm.set_sideset_base_pin(&out_pin); |
| 59 | sm.set_sideset_count(1); | 60 | sm.set_sideset_count(1); |
| @@ -115,7 +116,7 @@ async fn main(_spawner: Spawner) { | |||
| 115 | info!("Start"); | 116 | info!("Start"); |
| 116 | let p = embassy_rp::init(Default::default()); | 117 | let p = embassy_rp::init(Default::default()); |
| 117 | 118 | ||
| 118 | let (_pio0, sm0, _sm1, _sm2, _sm3) = p.PIO0.split(); | 119 | let (pio0, sm0, _sm1, _sm2, _sm3) = p.PIO0.split(); |
| 119 | 120 | ||
| 120 | // This is the number of leds in the string. Helpfully, the sparkfun thing plus and adafruit | 121 | // This is the number of leds in the string. Helpfully, the sparkfun thing plus and adafruit |
| 121 | // feather boards for the 2040 both have one built in. | 122 | // feather boards for the 2040 both have one built in. |
| @@ -124,7 +125,7 @@ async fn main(_spawner: Spawner) { | |||
| 124 | 125 | ||
| 125 | // For the thing plus, use pin 8 | 126 | // For the thing plus, use pin 8 |
| 126 | // For the feather, use pin 16 | 127 | // For the feather, use pin 16 |
| 127 | let mut ws2812 = Ws2812::new(sm0, p.PIN_8.degrade()); | 128 | let mut ws2812 = Ws2812::new(pio0, sm0, p.PIN_8.degrade()); |
| 128 | 129 | ||
| 129 | // Loop forever making RGB values and pushing them out to the WS2812. | 130 | // Loop forever making RGB values and pushing them out to the WS2812. |
| 130 | loop { | 131 | loop { |
