Add input rx
This commit is contained in:
		@@ -166,7 +166,7 @@ pub enum Mode {
 | 
				
			|||||||
/// For more details about EasyDMA, consult the module documentation.
 | 
					/// For more details about EasyDMA, consult the module documentation.
 | 
				
			||||||
pub struct I2S<'d, T: Instance> {
 | 
					pub struct I2S<'d, T: Instance> {
 | 
				
			||||||
    output: I2sOutput<'d, T>,
 | 
					    output: I2sOutput<'d, T>,
 | 
				
			||||||
    _input: I2sInput<'d, T>,
 | 
					    input: I2sInput<'d, T>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Transmitter interface to the UARTE peripheral obtained
 | 
					/// Transmitter interface to the UARTE peripheral obtained
 | 
				
			||||||
@@ -253,7 +253,7 @@ impl<'d, T: Instance> I2S<'d, T> {
 | 
				
			|||||||
            output: I2sOutput {
 | 
					            output: I2sOutput {
 | 
				
			||||||
                _p: unsafe { i2s.clone_unchecked() },
 | 
					                _p: unsafe { i2s.clone_unchecked() },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            _input: I2sInput { _p: i2s },
 | 
					            input: I2sInput { _p: i2s },
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -284,7 +284,7 @@ impl<'d, T: Instance> I2S<'d, T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Stops the I2S transfer and waits until it has stopped.
 | 
					    /// Stops the I2S transfer and waits until it has stopped.
 | 
				
			||||||
    #[inline(always)]
 | 
					    #[inline(always)]
 | 
				
			||||||
    pub async fn stop(&self) -> &Self {
 | 
					    pub async fn stop(&self) {
 | 
				
			||||||
        todo!()
 | 
					        todo!()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -304,10 +304,8 @@ impl<'d, T: Instance> I2S<'d, T> {
 | 
				
			|||||||
        self
 | 
					        self
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Transmits the given `tx_buffer`.
 | 
					    /// Transmits the given `buffer`.
 | 
				
			||||||
    /// Buffer address must be 4 byte aligned and located in RAM.
 | 
					    /// Buffer address must be 4 byte aligned and located in RAM.
 | 
				
			||||||
    /// Returns a value that represents the in-progress DMA transfer.
 | 
					 | 
				
			||||||
    #[allow(unused_mut)]
 | 
					 | 
				
			||||||
    pub async fn tx<B>(&mut self, buffer: B) -> Result<(), Error>
 | 
					    pub async fn tx<B>(&mut self, buffer: B) -> Result<(), Error>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        B: Buffer,
 | 
					        B: Buffer,
 | 
				
			||||||
@@ -315,6 +313,15 @@ impl<'d, T: Instance> I2S<'d, T> {
 | 
				
			|||||||
        self.output.tx(buffer).await
 | 
					        self.output.tx(buffer).await
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Receives data into the given `buffer` until it's filled.
 | 
				
			||||||
 | 
					    /// Buffer address must be 4 byte aligned and located in RAM.
 | 
				
			||||||
 | 
					    pub async fn rx<B>(&mut self, buffer: B) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        B: Buffer,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.input.rx(buffer).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn apply_config(c: &CONFIG, config: &Config) {
 | 
					    fn apply_config(c: &CONFIG, config: &Config) {
 | 
				
			||||||
        // TODO support slave too
 | 
					        // TODO support slave too
 | 
				
			||||||
        c.mcken.write(|w| w.mcken().enabled());
 | 
					        c.mcken.write(|w| w.mcken().enabled());
 | 
				
			||||||
@@ -331,9 +338,9 @@ impl<'d, T: Instance> I2S<'d, T> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> I2sOutput<'d, T> {
 | 
					impl<'d, T: Instance> I2sOutput<'d, T> {
 | 
				
			||||||
    /// Transmits the given `tx_buffer`.
 | 
					    /// Transmits the given `buffer`.
 | 
				
			||||||
    /// Buffer address must be 4 byte aligned and located in RAM.
 | 
					    /// Buffer address must be 4 byte aligned and located in RAM.
 | 
				
			||||||
    /// Returns a value that represents the in-progress DMA transfer.
 | 
					    #[allow(unused_mut)]
 | 
				
			||||||
    pub async fn tx<B>(&mut self, buffer: B) -> Result<(), Error>
 | 
					    pub async fn tx<B>(&mut self, buffer: B) -> Result<(), Error>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        B: Buffer,
 | 
					        B: Buffer,
 | 
				
			||||||
@@ -366,6 +373,42 @@ impl<'d, T: Instance> I2sOutput<'d, T> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'d, T: Instance> I2sInput<'d, T> {
 | 
				
			||||||
 | 
					    /// Receives into the given `buffer`.
 | 
				
			||||||
 | 
					    /// Buffer address must be 4 byte aligned and located in RAM.
 | 
				
			||||||
 | 
					    #[allow(unused_mut)]
 | 
				
			||||||
 | 
					    pub async fn rx<B>(&mut self, buffer: B) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        B: Buffer,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        let ptr = buffer.bytes_ptr();
 | 
				
			||||||
 | 
					        let len = buffer.bytes_len();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ptr as u32 % 4 != 0 {
 | 
				
			||||||
 | 
					            return Err(Error::BufferMisaligned);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (ptr as usize) < SRAM_LOWER || (ptr as usize) > SRAM_UPPER {
 | 
				
			||||||
 | 
					            return Err(Error::DMABufferNotInDataMemory);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        let maxcnt = ((len + core::mem::size_of::<u32>() - 1) / core::mem::size_of::<u32>()) as u32;
 | 
				
			||||||
 | 
					        if maxcnt > MAX_DMA_MAXCNT {
 | 
				
			||||||
 | 
					            return Err(Error::BufferTooLong);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let r = T::regs();
 | 
				
			||||||
 | 
					        let _s = T::state();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO we can not progress until the last buffer written in RXD.PTR
 | 
				
			||||||
 | 
					        // has started the transmission.
 | 
				
			||||||
 | 
					        // We can use some sync primitive from `embassy-sync`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
 | 
				
			||||||
 | 
					        r.rxtxd.maxcnt.write(|w| unsafe { w.bits(maxcnt) });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait Buffer: Sized {
 | 
					pub trait Buffer: Sized {
 | 
				
			||||||
    fn bytes_ptr(&self) -> *const u8;
 | 
					    fn bytes_ptr(&self) -> *const u8;
 | 
				
			||||||
    fn bytes_len(&self) -> usize;
 | 
					    fn bytes_len(&self) -> usize;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user