rp/pio: wrap sm rx, tx in structs and allow splitting
this *finally* allows sound implementions of bidirectional transfers without blocking. the futures previously allowed only a single direction to be active at any given time, and the dma transfers didn't take a mutable reference and were thus unsound.
This commit is contained in:
		
							parent
							
								
									77f7830da3
								
							
						
					
					
						commit
						c44c108db5
					
				| @ -97,13 +97,13 @@ pub(crate) unsafe fn init() { | |||||||
| /// Future that waits for TX-FIFO to become writable
 | /// Future that waits for TX-FIFO to become writable
 | ||||||
| #[must_use = "futures do nothing unless you `.await` or poll them"] | #[must_use = "futures do nothing unless you `.await` or poll them"] | ||||||
| pub struct FifoOutFuture<'a, 'd, PIO: PioInstance, const SM: usize> { | pub struct FifoOutFuture<'a, 'd, PIO: PioInstance, const SM: usize> { | ||||||
|     sm: &'a mut PioStateMachine<'d, PIO, SM>, |     sm_tx: &'a mut PioStateMachineTx<'d, PIO, SM>, | ||||||
|     value: u32, |     value: u32, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'a, 'd, PIO: PioInstance, const SM: usize> FifoOutFuture<'a, 'd, PIO, SM> { | 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 { |     pub fn new(sm: &'a mut PioStateMachineTx<'d, PIO, SM>, value: u32) -> Self { | ||||||
|         FifoOutFuture { sm, value } |         FifoOutFuture { sm_tx: sm, value } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -112,7 +112,7 @@ impl<'a, 'd, PIO: PioInstance, const SM: usize> Future for FifoOutFuture<'a, 'd, | |||||||
|     fn poll(self: FuturePin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |     fn poll(self: FuturePin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | ||||||
|         //debug!("Poll {},{}", PIO::PIO_NO, SM);
 |         //debug!("Poll {},{}", PIO::PIO_NO, SM);
 | ||||||
|         let value = self.value; |         let value = self.value; | ||||||
|         if self.get_mut().sm.try_push_tx(value) { |         if self.get_mut().sm_tx.try_push(value) { | ||||||
|             Poll::Ready(()) |             Poll::Ready(()) | ||||||
|         } else { |         } else { | ||||||
|             WAKERS[PIO::PIO_NO as usize].fifo_out()[SM].register(cx.waker()); |             WAKERS[PIO::PIO_NO as usize].fifo_out()[SM].register(cx.waker()); | ||||||
| @ -140,12 +140,12 @@ impl<'a, 'd, PIO: PioInstance, const SM: usize> Drop for FifoOutFuture<'a, 'd, P | |||||||
| /// Future that waits for RX-FIFO to become readable
 | /// Future that waits for RX-FIFO to become readable
 | ||||||
| #[must_use = "futures do nothing unless you `.await` or poll them"] | #[must_use = "futures do nothing unless you `.await` or poll them"] | ||||||
| pub struct FifoInFuture<'a, 'd, PIO: PioInstance, const SM: usize> { | pub struct FifoInFuture<'a, 'd, PIO: PioInstance, const SM: usize> { | ||||||
|     sm: &'a mut PioStateMachine<'d, PIO, SM>, |     sm_rx: &'a mut PioStateMachineRx<'d, PIO, SM>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'a, 'd, PIO: PioInstance, const SM: usize> FifoInFuture<'a, 'd, PIO, SM> { | impl<'a, 'd, PIO: PioInstance, const SM: usize> FifoInFuture<'a, 'd, PIO, SM> { | ||||||
|     pub fn new(sm: &'a mut PioStateMachine<'d, PIO, SM>) -> Self { |     pub fn new(sm: &'a mut PioStateMachineRx<'d, PIO, SM>) -> Self { | ||||||
|         FifoInFuture { sm } |         FifoInFuture { sm_rx: sm } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -153,7 +153,7 @@ impl<'a, 'd, PIO: PioInstance, const SM: usize> Future for FifoInFuture<'a, 'd, | |||||||
|     type Output = u32; |     type Output = u32; | ||||||
|     fn poll(mut self: FuturePin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |     fn poll(mut self: FuturePin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | ||||||
|         //debug!("Poll {},{}", PIO::PIO_NO, SM);
 |         //debug!("Poll {},{}", PIO::PIO_NO, SM);
 | ||||||
|         if let Some(v) = self.sm.try_pull_rx() { |         if let Some(v) = self.sm_rx.try_pull() { | ||||||
|             Poll::Ready(v) |             Poll::Ready(v) | ||||||
|         } else { |         } else { | ||||||
|             WAKERS[PIO::PIO_NO as usize].fifo_in()[SM].register(cx.waker()); |             WAKERS[PIO::PIO_NO as usize].fifo_in()[SM].register(cx.waker()); | ||||||
| @ -293,10 +293,163 @@ impl<'l, PIO: PioInstance> Pin<'l, PIO> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct PioStateMachine<'d, PIO: PioInstance, const SM: usize> { | pub struct PioStateMachineRx<'d, PIO: PioInstance, const SM: usize> { | ||||||
|     pio: PhantomData<&'d PIO>, |     pio: PhantomData<&'d PIO>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl<'d, PIO: PioInstance, const SM: usize> PioStateMachineRx<'d, PIO, SM> { | ||||||
|  |     pub fn empty(&self) -> bool { | ||||||
|  |         unsafe { PIO::PIO.fstat().read().rxempty() & (1u8 << SM) != 0 } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn full(&self) -> bool { | ||||||
|  |         unsafe { PIO::PIO.fstat().read().rxfull() & (1u8 << SM) != 0 } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn level(&self) -> u8 { | ||||||
|  |         unsafe { (PIO::PIO.flevel().read().0 >> (SM * 8 + 4)) as u8 & 0x0f } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn stalled(&self) -> bool { | ||||||
|  |         unsafe { | ||||||
|  |             let fdebug = PIO::PIO.fdebug(); | ||||||
|  |             let ret = fdebug.read().rxstall() & (1 << SM) != 0; | ||||||
|  |             fdebug.write(|w| w.set_rxstall(1 << SM)); | ||||||
|  |             ret | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn underflowed(&self) -> bool { | ||||||
|  |         unsafe { | ||||||
|  |             let fdebug = PIO::PIO.fdebug(); | ||||||
|  |             let ret = fdebug.read().rxunder() & (1 << SM) != 0; | ||||||
|  |             fdebug.write(|w| w.set_rxunder(1 << SM)); | ||||||
|  |             ret | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn pull(&mut self) -> u32 { | ||||||
|  |         unsafe { PIO::PIO.rxf(SM).read() } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn try_pull(&mut self) -> Option<u32> { | ||||||
|  |         if self.empty() { | ||||||
|  |             return None; | ||||||
|  |         } | ||||||
|  |         Some(self.pull()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn wait_pull<'a>(&'a mut self) -> FifoInFuture<'a, 'd, PIO, SM> { | ||||||
|  |         FifoInFuture::new(self) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn dma_pull<'a, C: Channel, W: Word>( | ||||||
|  |         &'a mut self, | ||||||
|  |         ch: PeripheralRef<'a, C>, | ||||||
|  |         data: &'a mut [W], | ||||||
|  |     ) -> Transfer<'a, C> { | ||||||
|  |         unsafe { | ||||||
|  |             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(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 as u8 + 4)); | ||||||
|  |                 w.set_data_size(W::size()); | ||||||
|  |                 w.set_chain_to(ch.number()); | ||||||
|  |                 w.set_incr_read(false); | ||||||
|  |                 w.set_incr_write(true); | ||||||
|  |                 w.set_en(true); | ||||||
|  |             }); | ||||||
|  |             compiler_fence(Ordering::SeqCst); | ||||||
|  |         } | ||||||
|  |         Transfer::new(ch) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub struct PioStateMachineTx<'d, PIO: PioInstance, const SM: usize> { | ||||||
|  |     pio: PhantomData<&'d PIO>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'d, PIO: PioInstance, const SM: usize> PioStateMachineTx<'d, PIO, SM> { | ||||||
|  |     pub fn empty(&self) -> bool { | ||||||
|  |         unsafe { PIO::PIO.fstat().read().txempty() & (1u8 << SM) != 0 } | ||||||
|  |     } | ||||||
|  |     pub fn full(&self) -> bool { | ||||||
|  |         unsafe { PIO::PIO.fstat().read().txfull() & (1u8 << SM) != 0 } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn level(&self) -> u8 { | ||||||
|  |         unsafe { (PIO::PIO.flevel().read().0 >> (SM * 8)) as u8 & 0x0f } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn stalled(&self) -> bool { | ||||||
|  |         unsafe { | ||||||
|  |             let fdebug = PIO::PIO.fdebug(); | ||||||
|  |             let ret = fdebug.read().txstall() & (1 << SM) != 0; | ||||||
|  |             fdebug.write(|w| w.set_txstall(1 << SM)); | ||||||
|  |             ret | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn overflowed(&self) -> bool { | ||||||
|  |         unsafe { | ||||||
|  |             let fdebug = PIO::PIO.fdebug(); | ||||||
|  |             let ret = fdebug.read().txover() & (1 << SM) != 0; | ||||||
|  |             fdebug.write(|w| w.set_txover(1 << SM)); | ||||||
|  |             ret | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn push(&mut self, v: u32) { | ||||||
|  |         unsafe { | ||||||
|  |             PIO::PIO.txf(SM).write_value(v); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn try_push(&mut self, v: u32) -> bool { | ||||||
|  |         if self.full() { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         self.push(v); | ||||||
|  |         true | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn wait_push<'a>(&'a mut self, value: u32) -> FifoOutFuture<'a, 'd, PIO, SM> { | ||||||
|  |         FifoOutFuture::new(self, value) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn dma_push<'a, C: Channel, W: Word>(&'a mut self, ch: PeripheralRef<'a, C>, data: &'a [W]) -> Transfer<'a, C> { | ||||||
|  |         unsafe { | ||||||
|  |             let pio_no = PIO::PIO_NO; | ||||||
|  |             let p = ch.regs(); | ||||||
|  |             p.read_addr().write_value(data.as_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 as u8)); | ||||||
|  |                 w.set_data_size(W::size()); | ||||||
|  |                 w.set_chain_to(ch.number()); | ||||||
|  |                 w.set_incr_read(true); | ||||||
|  |                 w.set_incr_write(false); | ||||||
|  |                 w.set_en(true); | ||||||
|  |             }); | ||||||
|  |             compiler_fence(Ordering::SeqCst); | ||||||
|  |         } | ||||||
|  |         Transfer::new(ch) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub struct PioStateMachine<'d, PIO: PioInstance, const SM: usize> { | ||||||
|  |     rx: PioStateMachineRx<'d, PIO, SM>, | ||||||
|  |     tx: PioStateMachineTx<'d, PIO, SM>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| impl<'d, PIO: PioInstance, const SM: usize> Drop for PioStateMachine<'d, PIO, SM> { | impl<'d, PIO: PioInstance, const SM: usize> Drop for PioStateMachine<'d, PIO, SM> { | ||||||
|     fn drop(&mut self) { |     fn drop(&mut self) { | ||||||
|         unsafe { |         unsafe { | ||||||
| @ -333,59 +486,6 @@ impl<'d, PIO: PioInstance + 'd, const SM: usize> PioStateMachine<'d, PIO, SM> { | |||||||
|         unsafe { PIO::PIO.ctrl().read().sm_enable() & (1u8 << SM) != 0 } |         unsafe { PIO::PIO.ctrl().read().sm_enable() & (1u8 << SM) != 0 } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn is_tx_empty(&self) -> bool { |  | ||||||
|         unsafe { PIO::PIO.fstat().read().txempty() & (1u8 << SM) != 0 } |  | ||||||
|     } |  | ||||||
|     pub fn is_tx_full(&self) -> bool { |  | ||||||
|         unsafe { PIO::PIO.fstat().read().txfull() & (1u8 << SM) != 0 } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn is_rx_empty(&self) -> bool { |  | ||||||
|         unsafe { PIO::PIO.fstat().read().rxempty() & (1u8 << SM) != 0 } |  | ||||||
|     } |  | ||||||
|     pub fn is_rx_full(&self) -> bool { |  | ||||||
|         unsafe { PIO::PIO.fstat().read().rxfull() & (1u8 << SM) != 0 } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn tx_level(&self) -> u8 { |  | ||||||
|         unsafe { |  | ||||||
|             let flevel = PIO::PIO.flevel().read().0; |  | ||||||
|             (flevel >> (SM * 8)) as u8 & 0x0f |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn rx_level(&self) -> u8 { |  | ||||||
|         unsafe { |  | ||||||
|             let flevel = PIO::PIO.flevel().read().0; |  | ||||||
|             (flevel >> (SM * 8 + 4)) as u8 & 0x0f |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn push_tx(&mut self, v: u32) { |  | ||||||
|         unsafe { |  | ||||||
|             PIO::PIO.txf(SM).write_value(v); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn try_push_tx(&mut self, v: u32) -> bool { |  | ||||||
|         if self.is_tx_full() { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|         self.push_tx(v); |  | ||||||
|         true |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn pull_rx(&mut self) -> u32 { |  | ||||||
|         unsafe { PIO::PIO.rxf(SM).read() } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn try_pull_rx(&mut self) -> Option<u32> { |  | ||||||
|         if self.is_rx_empty() { |  | ||||||
|             return None; |  | ||||||
|         } |  | ||||||
|         Some(self.pull_rx()) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn set_clkdiv(&mut self, div_x_256: u32) { |     pub fn set_clkdiv(&mut self, div_x_256: u32) { | ||||||
|         unsafe { |         unsafe { | ||||||
|             Self::this_sm().clkdiv().write(|w| w.0 = div_x_256 << 8); |             Self::this_sm().clkdiv().write(|w| w.0 = div_x_256 << 8); | ||||||
| @ -671,92 +771,14 @@ impl<'d, PIO: PioInstance + 'd, const SM: usize> PioStateMachine<'d, PIO, SM> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn wait_push<'a>(&'a mut self, value: u32) -> FifoOutFuture<'a, 'd, PIO, SM> { |     pub fn rx(&mut self) -> &mut PioStateMachineRx<'d, PIO, SM> { | ||||||
|         FifoOutFuture::new(self, value) |         &mut self.rx | ||||||
|     } |     } | ||||||
| 
 |     pub fn tx(&mut self) -> &mut PioStateMachineTx<'d, PIO, SM> { | ||||||
|     pub fn wait_pull<'a>(&'a mut self) -> FifoInFuture<'a, 'd, PIO, SM> { |         &mut self.tx | ||||||
|         FifoInFuture::new(self) |  | ||||||
|     } |     } | ||||||
| 
 |     pub fn rx_tx(&mut self) -> (&mut PioStateMachineRx<'d, PIO, SM>, &mut PioStateMachineTx<'d, PIO, SM>) { | ||||||
|     pub fn has_tx_stalled(&self) -> bool { |         (&mut self.rx, &mut self.tx) | ||||||
|         unsafe { |  | ||||||
|             let fdebug = PIO::PIO.fdebug(); |  | ||||||
|             let ret = fdebug.read().txstall() & (1 << SM) != 0; |  | ||||||
|             fdebug.write(|w| w.set_txstall(1 << SM)); |  | ||||||
|             ret |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn has_tx_overflowed(&self) -> bool { |  | ||||||
|         unsafe { |  | ||||||
|             let fdebug = PIO::PIO.fdebug(); |  | ||||||
|             let ret = fdebug.read().txover() & (1 << SM) != 0; |  | ||||||
|             fdebug.write(|w| w.set_txover(1 << SM)); |  | ||||||
|             ret |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn has_rx_stalled(&self) -> bool { |  | ||||||
|         unsafe { |  | ||||||
|             let fdebug = PIO::PIO.fdebug(); |  | ||||||
|             let ret = fdebug.read().rxstall() & (1 << SM) != 0; |  | ||||||
|             fdebug.write(|w| w.set_rxstall(1 << SM)); |  | ||||||
|             ret |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn has_rx_underflowed(&self) -> bool { |  | ||||||
|         unsafe { |  | ||||||
|             let fdebug = PIO::PIO.fdebug(); |  | ||||||
|             let ret = fdebug.read().rxunder() & (1 << SM) != 0; |  | ||||||
|             fdebug.write(|w| w.set_rxunder(1 << SM)); |  | ||||||
|             ret |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     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 = PIO::PIO_NO; |  | ||||||
|             let p = ch.regs(); |  | ||||||
|             p.read_addr().write_value(data.as_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 as u8)); |  | ||||||
|                 w.set_data_size(W::size()); |  | ||||||
|                 w.set_chain_to(ch.number()); |  | ||||||
|                 w.set_incr_read(true); |  | ||||||
|                 w.set_incr_write(false); |  | ||||||
|                 w.set_en(true); |  | ||||||
|             }); |  | ||||||
|             compiler_fence(Ordering::SeqCst); |  | ||||||
|         } |  | ||||||
|         Transfer::new(ch) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     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 = PIO::PIO_NO; |  | ||||||
|             let p = ch.regs(); |  | ||||||
|             p.write_addr().write_value(data.as_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 as u8 + 4)); |  | ||||||
|                 w.set_data_size(W::size()); |  | ||||||
|                 w.set_chain_to(ch.number()); |  | ||||||
|                 w.set_incr_read(false); |  | ||||||
|                 w.set_incr_write(true); |  | ||||||
|                 w.set_en(true); |  | ||||||
|             }); |  | ||||||
|             compiler_fence(Ordering::SeqCst); |  | ||||||
|         } |  | ||||||
|         Transfer::new(ch) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -921,10 +943,22 @@ impl<'d, PIO: PioInstance> Pio<'d, PIO> { | |||||||
|             irq1: PioIrq { pio: PhantomData }, |             irq1: PioIrq { pio: PhantomData }, | ||||||
|             irq2: PioIrq { pio: PhantomData }, |             irq2: PioIrq { pio: PhantomData }, | ||||||
|             irq3: PioIrq { pio: PhantomData }, |             irq3: PioIrq { pio: PhantomData }, | ||||||
|             sm0: PioStateMachine { pio: PhantomData }, |             sm0: PioStateMachine { | ||||||
|             sm1: PioStateMachine { pio: PhantomData }, |                 rx: PioStateMachineRx { pio: PhantomData }, | ||||||
|             sm2: PioStateMachine { pio: PhantomData }, |                 tx: PioStateMachineTx { pio: PhantomData }, | ||||||
|             sm3: PioStateMachine { pio: PhantomData }, |             }, | ||||||
|  |             sm1: PioStateMachine { | ||||||
|  |                 rx: PioStateMachineRx { pio: PhantomData }, | ||||||
|  |                 tx: PioStateMachineTx { pio: PhantomData }, | ||||||
|  |             }, | ||||||
|  |             sm2: PioStateMachine { | ||||||
|  |                 rx: PioStateMachineRx { pio: PhantomData }, | ||||||
|  |                 tx: PioStateMachineTx { pio: PhantomData }, | ||||||
|  |             }, | ||||||
|  |             sm3: PioStateMachine { | ||||||
|  |                 rx: PioStateMachineRx { pio: PhantomData }, | ||||||
|  |                 tx: PioStateMachineTx { pio: PhantomData }, | ||||||
|  |             }, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ pub fn set_x<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<PIO, SM | |||||||
|         bit_count: 32, |         bit_count: 32, | ||||||
|     } |     } | ||||||
|     .encode(); |     .encode(); | ||||||
|     sm.push_tx(value); |     sm.tx().push(value); | ||||||
|     sm.exec_instr(OUT); |     sm.exec_instr(OUT); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -19,7 +19,7 @@ pub fn get_x<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<PIO, SM | |||||||
|     } |     } | ||||||
|     .encode(); |     .encode(); | ||||||
|     sm.exec_instr(IN); |     sm.exec_instr(IN); | ||||||
|     sm.pull_rx() |     sm.rx().pull() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn set_y<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<PIO, SM>, value: u32) { | pub fn set_y<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<PIO, SM>, value: u32) { | ||||||
| @ -28,7 +28,7 @@ pub fn set_y<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<PIO, SM | |||||||
|         bit_count: 32, |         bit_count: 32, | ||||||
|     } |     } | ||||||
|     .encode(); |     .encode(); | ||||||
|     sm.push_tx(value); |     sm.tx().push(value); | ||||||
|     sm.exec_instr(OUT); |     sm.exec_instr(OUT); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -40,7 +40,7 @@ pub fn get_y<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<PIO, SM | |||||||
|     .encode(); |     .encode(); | ||||||
|     sm.exec_instr(IN); |     sm.exec_instr(IN); | ||||||
| 
 | 
 | ||||||
|     sm.pull_rx() |     sm.rx().pull() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn set_pindir<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<PIO, SM>, data: u8) { | pub fn set_pindir<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<PIO, SM>, data: u8) { | ||||||
| @ -67,7 +67,7 @@ pub fn set_out_pin<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<P | |||||||
|         bit_count: 32, |         bit_count: 32, | ||||||
|     } |     } | ||||||
|     .encode(); |     .encode(); | ||||||
|     sm.push_tx(data); |     sm.tx().push(data); | ||||||
|     sm.exec_instr(OUT); |     sm.exec_instr(OUT); | ||||||
| } | } | ||||||
| pub fn set_out_pindir<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<PIO, SM>, data: u32) { | pub fn set_out_pindir<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachine<PIO, SM>, data: u32) { | ||||||
| @ -76,7 +76,7 @@ pub fn set_out_pindir<PIO: PioInstance, const SM: usize>(sm: &mut PioStateMachin | |||||||
|         bit_count: 32, |         bit_count: 32, | ||||||
|     } |     } | ||||||
|     .encode(); |     .encode(); | ||||||
|     sm.push_tx(data); |     sm.tx().push(data); | ||||||
|     sm.exec_instr(OUT); |     sm.exec_instr(OUT); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -42,7 +42,7 @@ async fn pio_task_sm0(mut sm: PioStateMachine<'static, PIO0, 0>) { | |||||||
| 
 | 
 | ||||||
|     let mut v = 0x0f0caffa; |     let mut v = 0x0f0caffa; | ||||||
|     loop { |     loop { | ||||||
|         sm.wait_push(v).await; |         sm.tx().wait_push(v).await; | ||||||
|         v ^= 0xffff; |         v ^= 0xffff; | ||||||
|         info!("Pushed {:032b} to FIFO", v); |         info!("Pushed {:032b} to FIFO", v); | ||||||
|     } |     } | ||||||
| @ -70,7 +70,7 @@ fn setup_pio_task_sm1(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachine<PIO0, | |||||||
| async fn pio_task_sm1(mut sm: PioStateMachine<'static, PIO0, 1>) { | async fn pio_task_sm1(mut sm: PioStateMachine<'static, PIO0, 1>) { | ||||||
|     sm.set_enable(true); |     sm.set_enable(true); | ||||||
|     loop { |     loop { | ||||||
|         let rx = sm.wait_pull().await; |         let rx = sm.rx().wait_pull().await; | ||||||
|         info!("Pulled {:032b} from FIFO", rx); |         info!("Pulled {:032b} from FIFO", rx); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -60,9 +60,10 @@ async fn main(_spawner: Spawner) { | |||||||
|     } |     } | ||||||
|     let mut din = [0u32; 29]; |     let mut din = [0u32; 29]; | ||||||
|     loop { |     loop { | ||||||
|  |         let (rx, tx) = sm.rx_tx(); | ||||||
|         join( |         join( | ||||||
|             sm.dma_push(dma_out_ref.reborrow(), &dout), |             tx.dma_push(dma_out_ref.reborrow(), &dout), | ||||||
|             sm.dma_pull(dma_in_ref.reborrow(), &mut din), |             rx.dma_pull(dma_in_ref.reborrow(), &mut din), | ||||||
|         ) |         ) | ||||||
|         .await; |         .await; | ||||||
|         for i in 0..din.len() { |         for i in 0..din.len() { | ||||||
|  | |||||||
| @ -139,14 +139,14 @@ impl<'l> HD44780<'l> { | |||||||
| 
 | 
 | ||||||
|         sm0.set_enable(true); |         sm0.set_enable(true); | ||||||
|         // init to 8 bit thrice
 |         // init to 8 bit thrice
 | ||||||
|         sm0.push_tx((50000 << 8) | 0x30); |         sm0.tx().push((50000 << 8) | 0x30); | ||||||
|         sm0.push_tx((5000 << 8) | 0x30); |         sm0.tx().push((5000 << 8) | 0x30); | ||||||
|         sm0.push_tx((200 << 8) | 0x30); |         sm0.tx().push((200 << 8) | 0x30); | ||||||
|         // init 4 bit
 |         // init 4 bit
 | ||||||
|         sm0.push_tx((200 << 8) | 0x20); |         sm0.tx().push((200 << 8) | 0x20); | ||||||
|         // set font and lines
 |         // set font and lines
 | ||||||
|         sm0.push_tx((50 << 8) | 0x20); |         sm0.tx().push((50 << 8) | 0x20); | ||||||
|         sm0.push_tx(0b1100_0000); |         sm0.tx().push(0b1100_0000); | ||||||
| 
 | 
 | ||||||
|         irq0.wait().await; |         irq0.wait().await; | ||||||
|         sm0.set_enable(false); |         sm0.set_enable(false); | ||||||
| @ -216,7 +216,7 @@ impl<'l> HD44780<'l> { | |||||||
|         sm0.set_enable(true); |         sm0.set_enable(true); | ||||||
| 
 | 
 | ||||||
|         // display on and cursor on and blinking, reset display
 |         // display on and cursor on and blinking, reset display
 | ||||||
|         sm0.dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1]).await; |         sm0.tx().dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1]).await; | ||||||
| 
 | 
 | ||||||
|         Self { |         Self { | ||||||
|             dma: dma.map_into(), |             dma: dma.map_into(), | ||||||
| @ -240,6 +240,6 @@ impl<'l> HD44780<'l> { | |||||||
|         // set cursor to 1:15
 |         // set cursor to 1:15
 | ||||||
|         self.buf[38..].copy_from_slice(&[0x80, 0xcf]); |         self.buf[38..].copy_from_slice(&[0x80, 0xcf]); | ||||||
| 
 | 
 | ||||||
|         self.sm.dma_push(self.dma.reborrow(), &self.buf).await; |         self.sm.tx().dma_push(self.dma.reborrow(), &self.buf).await; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -87,7 +87,7 @@ impl<'d, P: PioInstance, const S: usize> Ws2812<'d, P, S> { | |||||||
|     pub async fn write(&mut self, colors: &[RGB8]) { |     pub async fn write(&mut self, colors: &[RGB8]) { | ||||||
|         for color in colors { |         for color in colors { | ||||||
|             let word = (u32::from(color.g) << 24) | (u32::from(color.r) << 16) | (u32::from(color.b) << 8); |             let word = (u32::from(color.g) << 24) | (u32::from(color.r) << 16) | (u32::from(color.b) << 8); | ||||||
|             self.sm.wait_push(word).await; |             self.sm.tx().wait_push(word).await; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user