aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Perez Llamas <[email protected]>2022-11-10 00:24:49 +0100
committerChristian Perez Llamas <[email protected]>2022-11-10 00:24:49 +0100
commitf22f36f51ba4466dd15df78df0ad86ac96f9051c (patch)
tree6a393deebe7120e7fe9c72030827fffa65069159
parent5a64bf651c66f2da16cd3ae20ed9ba2489f40d7a (diff)
Add input rx
-rw-r--r--embassy-nrf/src/i2s.rs59
1 files changed, 51 insertions, 8 deletions
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs
index 3f5491ee3..fb6fa4bdf 100644
--- a/embassy-nrf/src/i2s.rs
+++ b/embassy-nrf/src/i2s.rs
@@ -166,7 +166,7 @@ pub enum Mode {
166/// For more details about EasyDMA, consult the module documentation. 166/// For more details about EasyDMA, consult the module documentation.
167pub struct I2S<'d, T: Instance> { 167pub struct I2S<'d, T: Instance> {
168 output: I2sOutput<'d, T>, 168 output: I2sOutput<'d, T>,
169 _input: I2sInput<'d, T>, 169 input: I2sInput<'d, T>,
170} 170}
171 171
172/// Transmitter interface to the UARTE peripheral obtained 172/// Transmitter interface to the UARTE peripheral obtained
@@ -253,7 +253,7 @@ impl<'d, T: Instance> I2S<'d, T> {
253 output: I2sOutput { 253 output: I2sOutput {
254 _p: unsafe { i2s.clone_unchecked() }, 254 _p: unsafe { i2s.clone_unchecked() },
255 }, 255 },
256 _input: I2sInput { _p: i2s }, 256 input: I2sInput { _p: i2s },
257 } 257 }
258 } 258 }
259 259
@@ -284,7 +284,7 @@ impl<'d, T: Instance> I2S<'d, T> {
284 284
285 /// Stops the I2S transfer and waits until it has stopped. 285 /// Stops the I2S transfer and waits until it has stopped.
286 #[inline(always)] 286 #[inline(always)]
287 pub async fn stop(&self) -> &Self { 287 pub async fn stop(&self) {
288 todo!() 288 todo!()
289 } 289 }
290 290
@@ -304,10 +304,8 @@ impl<'d, T: Instance> I2S<'d, T> {
304 self 304 self
305 } 305 }
306 306
307 /// Transmits the given `tx_buffer`. 307 /// Transmits the given `buffer`.
308 /// Buffer address must be 4 byte aligned and located in RAM. 308 /// Buffer address must be 4 byte aligned and located in RAM.
309 /// Returns a value that represents the in-progress DMA transfer.
310 #[allow(unused_mut)]
311 pub async fn tx<B>(&mut self, buffer: B) -> Result<(), Error> 309 pub async fn tx<B>(&mut self, buffer: B) -> Result<(), Error>
312 where 310 where
313 B: Buffer, 311 B: Buffer,
@@ -315,6 +313,15 @@ impl<'d, T: Instance> I2S<'d, T> {
315 self.output.tx(buffer).await 313 self.output.tx(buffer).await
316 } 314 }
317 315
316 /// Receives data into the given `buffer` until it's filled.
317 /// Buffer address must be 4 byte aligned and located in RAM.
318 pub async fn rx<B>(&mut self, buffer: B) -> Result<(), Error>
319 where
320 B: Buffer,
321 {
322 self.input.rx(buffer).await
323 }
324
318 fn apply_config(c: &CONFIG, config: &Config) { 325 fn apply_config(c: &CONFIG, config: &Config) {
319 // TODO support slave too 326 // TODO support slave too
320 c.mcken.write(|w| w.mcken().enabled()); 327 c.mcken.write(|w| w.mcken().enabled());
@@ -331,9 +338,9 @@ impl<'d, T: Instance> I2S<'d, T> {
331} 338}
332 339
333impl<'d, T: Instance> I2sOutput<'d, T> { 340impl<'d, T: Instance> I2sOutput<'d, T> {
334 /// Transmits the given `tx_buffer`. 341 /// Transmits the given `buffer`.
335 /// Buffer address must be 4 byte aligned and located in RAM. 342 /// Buffer address must be 4 byte aligned and located in RAM.
336 /// Returns a value that represents the in-progress DMA transfer. 343 #[allow(unused_mut)]
337 pub async fn tx<B>(&mut self, buffer: B) -> Result<(), Error> 344 pub async fn tx<B>(&mut self, buffer: B) -> Result<(), Error>
338 where 345 where
339 B: Buffer, 346 B: Buffer,
@@ -366,6 +373,42 @@ impl<'d, T: Instance> I2sOutput<'d, T> {
366 } 373 }
367} 374}
368 375
376impl<'d, T: Instance> I2sInput<'d, T> {
377 /// Receives into the given `buffer`.
378 /// Buffer address must be 4 byte aligned and located in RAM.
379 #[allow(unused_mut)]
380 pub async fn rx<B>(&mut self, buffer: B) -> Result<(), Error>
381 where
382 B: Buffer,
383 {
384 let ptr = buffer.bytes_ptr();
385 let len = buffer.bytes_len();
386
387 if ptr as u32 % 4 != 0 {
388 return Err(Error::BufferMisaligned);
389 }
390 if (ptr as usize) < SRAM_LOWER || (ptr as usize) > SRAM_UPPER {
391 return Err(Error::DMABufferNotInDataMemory);
392 }
393 let maxcnt = ((len + core::mem::size_of::<u32>() - 1) / core::mem::size_of::<u32>()) as u32;
394 if maxcnt > MAX_DMA_MAXCNT {
395 return Err(Error::BufferTooLong);
396 }
397
398 let r = T::regs();
399 let _s = T::state();
400
401 // TODO we can not progress until the last buffer written in RXD.PTR
402 // has started the transmission.
403 // We can use some sync primitive from `embassy-sync`.
404
405 r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
406 r.rxtxd.maxcnt.write(|w| unsafe { w.bits(maxcnt) });
407
408 Ok(())
409 }
410}
411
369pub trait Buffer: Sized { 412pub trait Buffer: Sized {
370 fn bytes_ptr(&self) -> *const u8; 413 fn bytes_ptr(&self) -> *const u8;
371 fn bytes_len(&self) -> usize; 414 fn bytes_len(&self) -> usize;