diff options
| author | Christian Perez Llamas <[email protected]> | 2022-11-10 00:24:49 +0100 |
|---|---|---|
| committer | Christian Perez Llamas <[email protected]> | 2022-11-10 00:24:49 +0100 |
| commit | f22f36f51ba4466dd15df78df0ad86ac96f9051c (patch) | |
| tree | 6a393deebe7120e7fe9c72030827fffa65069159 | |
| parent | 5a64bf651c66f2da16cd3ae20ed9ba2489f40d7a (diff) | |
Add input rx
| -rw-r--r-- | embassy-nrf/src/i2s.rs | 59 |
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. |
| 167 | pub struct I2S<'d, T: Instance> { | 167 | pub 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 | ||
| 333 | impl<'d, T: Instance> I2sOutput<'d, T> { | 340 | impl<'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 | ||
| 376 | impl<'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 | |||
| 369 | pub trait Buffer: Sized { | 412 | pub 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; |
