Add input rx

This commit is contained in:
Christian Perez Llamas 2022-11-10 00:24:49 +01:00
parent 5a64bf651c
commit f22f36f51b

View File

@ -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;