Add input rx
This commit is contained in:
parent
5a64bf651c
commit
f22f36f51b
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user