rp: fix async SPI read and write
This commit is contained in:
		
							parent
							
								
									336ebe54c0
								
							
						
					
					
						commit
						ab1a6889a6
					
				| @ -56,6 +56,25 @@ pub unsafe fn read<'a, C: Channel, W: Word>( | |||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub unsafe fn read_repeated<'a, C: Channel, W: Word>( | ||||||
|  |     ch: impl Peripheral<P = C> + 'a, | ||||||
|  |     from: *const W, | ||||||
|  |     len: usize, | ||||||
|  |     dreq: u8, | ||||||
|  | ) -> Transfer<'a, C> { | ||||||
|  |     let mut dummy: u32 = 0; | ||||||
|  |     copy_inner( | ||||||
|  |         ch, | ||||||
|  |         from as *const u32, | ||||||
|  |         &mut dummy as *mut u32, | ||||||
|  |         len, | ||||||
|  |         W::size(), | ||||||
|  |         false, | ||||||
|  |         false, | ||||||
|  |         dreq, | ||||||
|  |     ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub unsafe fn write<'a, C: Channel, W: Word>( | pub unsafe fn write<'a, C: Channel, W: Word>( | ||||||
|     ch: impl Peripheral<P = C> + 'a, |     ch: impl Peripheral<P = C> + 'a, | ||||||
|     from: *const [W], |     from: *const [W], | ||||||
| @ -75,6 +94,25 @@ pub unsafe fn write<'a, C: Channel, W: Word>( | |||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub unsafe fn write_repeated<'a, C: Channel, W: Word>( | ||||||
|  |     ch: impl Peripheral<P = C> + 'a, | ||||||
|  |     to: *mut W, | ||||||
|  |     len: usize, | ||||||
|  |     dreq: u8, | ||||||
|  | ) -> Transfer<'a, C> { | ||||||
|  |     let dummy: u32 = 0; | ||||||
|  |     copy_inner( | ||||||
|  |         ch, | ||||||
|  |         &dummy as *const u32, | ||||||
|  |         to as *mut u32, | ||||||
|  |         len, | ||||||
|  |         W::size(), | ||||||
|  |         false, | ||||||
|  |         false, | ||||||
|  |         dreq, | ||||||
|  |     ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub unsafe fn copy<'a, C: Channel, W: Word>( | pub unsafe fn copy<'a, C: Channel, W: Word>( | ||||||
|     ch: impl Peripheral<P = C> + 'a, |     ch: impl Peripheral<P = C> + 'a, | ||||||
|     from: &[W], |     from: &[W], | ||||||
|  | |||||||
| @ -325,30 +325,53 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { |     pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { | ||||||
|         let ch = self.tx_dma.as_mut().unwrap(); |         unsafe { | ||||||
|         let transfer = unsafe { |             self.inner.regs().dmacr().write(|reg| { | ||||||
|             self.inner.regs().dmacr().modify(|reg| { |                 reg.set_rxdmae(true); | ||||||
|                 reg.set_txdmae(true); |                 reg.set_txdmae(true); | ||||||
|             }); |             }) | ||||||
|  |         }; | ||||||
|  |         let tx_ch = self.tx_dma.as_mut().unwrap(); | ||||||
|  |         let tx_transfer = unsafe { | ||||||
|             // If we don't assign future to a variable, the data register pointer
 |             // If we don't assign future to a variable, the data register pointer
 | ||||||
|             // is held across an await and makes the future non-Send.
 |             // is held across an await and makes the future non-Send.
 | ||||||
|             crate::dma::write(ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) |             crate::dma::write(tx_ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) | ||||||
|         }; |         }; | ||||||
|         transfer.await; |         let rx_ch = self.rx_dma.as_mut().unwrap(); | ||||||
|  |         let rx_transfer = unsafe { | ||||||
|  |             // If we don't assign future to a variable, the data register pointer
 | ||||||
|  |             // is held across an await and makes the future non-Send.
 | ||||||
|  |             crate::dma::read_repeated( | ||||||
|  |                 rx_ch, | ||||||
|  |                 self.inner.regs().dr().ptr() as *const u8, | ||||||
|  |                 buffer.len(), | ||||||
|  |                 T::RX_DREQ, | ||||||
|  |             ) | ||||||
|  |         }; | ||||||
|  |         join(tx_transfer, rx_transfer).await; | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { |     pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | ||||||
|         let ch = self.rx_dma.as_mut().unwrap(); |         unsafe { | ||||||
|         let transfer = unsafe { |             self.inner.regs().dmacr().write(|reg| { | ||||||
|             self.inner.regs().dmacr().modify(|reg| { |  | ||||||
|                 reg.set_rxdmae(true); |                 reg.set_rxdmae(true); | ||||||
|             }); |                 reg.set_txdmae(true); | ||||||
|  |             }) | ||||||
|  |         }; | ||||||
|  |         let tx_ch = self.tx_dma.as_mut().unwrap(); | ||||||
|  |         let tx_transfer = unsafe { | ||||||
|             // If we don't assign future to a variable, the data register pointer
 |             // If we don't assign future to a variable, the data register pointer
 | ||||||
|             // is held across an await and makes the future non-Send.
 |             // is held across an await and makes the future non-Send.
 | ||||||
|             crate::dma::read(ch, self.inner.regs().dr().ptr() as *const _, buffer, T::RX_DREQ) |             crate::dma::write_repeated(tx_ch, self.inner.regs().dr().ptr() as *mut u8, buffer.len(), T::TX_DREQ) | ||||||
|         }; |         }; | ||||||
|         transfer.await; |         let rx_ch = self.rx_dma.as_mut().unwrap(); | ||||||
|  |         let rx_transfer = unsafe { | ||||||
|  |             // If we don't assign future to a variable, the data register pointer
 | ||||||
|  |             // is held across an await and makes the future non-Send.
 | ||||||
|  |             crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, buffer, T::RX_DREQ) | ||||||
|  |         }; | ||||||
|  |         join(tx_transfer, rx_transfer).await; | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -364,20 +387,20 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||||||
|         let (_, from_len) = crate::dma::slice_ptr_parts(tx_ptr); |         let (_, from_len) = crate::dma::slice_ptr_parts(tx_ptr); | ||||||
|         let (_, to_len) = crate::dma::slice_ptr_parts_mut(rx_ptr); |         let (_, to_len) = crate::dma::slice_ptr_parts_mut(rx_ptr); | ||||||
|         assert_eq!(from_len, to_len); |         assert_eq!(from_len, to_len); | ||||||
|  |         unsafe { | ||||||
|  |             self.inner.regs().dmacr().write(|reg| { | ||||||
|  |                 reg.set_rxdmae(true); | ||||||
|  |                 reg.set_txdmae(true); | ||||||
|  |             }) | ||||||
|  |         }; | ||||||
|         let tx_ch = self.tx_dma.as_mut().unwrap(); |         let tx_ch = self.tx_dma.as_mut().unwrap(); | ||||||
|         let tx_transfer = unsafe { |         let tx_transfer = unsafe { | ||||||
|             self.inner.regs().dmacr().modify(|reg| { |  | ||||||
|                 reg.set_txdmae(true); |  | ||||||
|             }); |  | ||||||
|             // If we don't assign future to a variable, the data register pointer
 |             // If we don't assign future to a variable, the data register pointer
 | ||||||
|             // is held across an await and makes the future non-Send.
 |             // is held across an await and makes the future non-Send.
 | ||||||
|             crate::dma::write(tx_ch, tx_ptr, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) |             crate::dma::write(tx_ch, tx_ptr, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) | ||||||
|         }; |         }; | ||||||
|         let rx_ch = self.rx_dma.as_mut().unwrap(); |         let rx_ch = self.rx_dma.as_mut().unwrap(); | ||||||
|         let rx_transfer = unsafe { |         let rx_transfer = unsafe { | ||||||
|             self.inner.regs().dmacr().modify(|reg| { |  | ||||||
|                 reg.set_rxdmae(true); |  | ||||||
|             }); |  | ||||||
|             // If we don't assign future to a variable, the data register pointer
 |             // If we don't assign future to a variable, the data register pointer
 | ||||||
|             // is held across an await and makes the future non-Send.
 |             // is held across an await and makes the future non-Send.
 | ||||||
|             crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, rx_ptr, T::RX_DREQ) |             crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, rx_ptr, T::RX_DREQ) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user