aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src
diff options
context:
space:
mode:
authorTil Blechschmidt <[email protected]>2022-03-02 22:45:38 +0100
committerTil Blechschmidt <[email protected]>2022-03-02 22:45:38 +0100
commit3f2d9cfe0a643b1f1afcaef0fcb2cbbf305fd83d (patch)
tree4af9d59399a6674eca331fcc9450e84f5a9fa1d0 /embassy-nrf/src
parent2c402ecf1695974ae5474f828f062d06b2392295 (diff)
Change TWIM methods to copy slice if required and add non-copying variants
Diffstat (limited to 'embassy-nrf/src')
-rw-r--r--embassy-nrf/src/twim.rs127
1 files changed, 86 insertions, 41 deletions
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index ed2844f79..675029a88 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -287,7 +287,12 @@ impl<'d, T: Instance> Twim<'d, T> {
287 }) 287 })
288 } 288 }
289 289
290 fn setup_write(&mut self, address: u8, buffer: &[u8], inten: bool) -> Result<(), Error> { 290 fn setup_write_from_ram(
291 &mut self,
292 address: u8,
293 buffer: &[u8],
294 inten: bool,
295 ) -> Result<(), Error> {
291 let r = T::regs(); 296 let r = T::regs();
292 297
293 compiler_fence(SeqCst); 298 compiler_fence(SeqCst);
@@ -342,7 +347,7 @@ impl<'d, T: Instance> Twim<'d, T> {
342 Ok(()) 347 Ok(())
343 } 348 }
344 349
345 fn setup_write_read( 350 fn setup_write_read_from_ram(
346 &mut self, 351 &mut self,
347 address: u8, 352 address: u8,
348 wr_buffer: &[u8], 353 wr_buffer: &[u8],
@@ -382,6 +387,43 @@ impl<'d, T: Instance> Twim<'d, T> {
382 Ok(()) 387 Ok(())
383 } 388 }
384 389
390 fn setup_write_read(
391 &mut self,
392 address: u8,
393 wr_buffer: &[u8],
394 rd_buffer: &mut [u8],
395 inten: bool,
396 ) -> Result<(), Error> {
397 match self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, inten) {
398 Ok(_) => Ok(()),
399 Err(Error::DMABufferNotInDataMemory) => {
400 trace!("Copying TWIM tx buffer into RAM for DMA");
401 let mut tx_buf = [0u8; FORCE_COPY_BUFFER_SIZE];
402 tx_buf[..wr_buffer.len()].copy_from_slice(wr_buffer);
403 self.setup_write_read_from_ram(
404 address,
405 &tx_buf[..wr_buffer.len()],
406 rd_buffer,
407 inten,
408 )
409 }
410 Err(error) => Err(error),
411 }
412 }
413
414 fn setup_write(&mut self, address: u8, wr_buffer: &[u8], inten: bool) -> Result<(), Error> {
415 match self.setup_write_from_ram(address, wr_buffer, inten) {
416 Ok(_) => Ok(()),
417 Err(Error::DMABufferNotInDataMemory) => {
418 trace!("Copying TWIM tx buffer into RAM for DMA");
419 let mut tx_buf = [0u8; FORCE_COPY_BUFFER_SIZE];
420 tx_buf[..wr_buffer.len()].copy_from_slice(wr_buffer);
421 self.setup_write_from_ram(address, &tx_buf[..wr_buffer.len()], inten)
422 }
423 Err(error) => Err(error),
424 }
425 }
426
385 /// Write to an I2C slave. 427 /// Write to an I2C slave.
386 /// 428 ///
387 /// The buffer must have a length of at most 255 bytes on the nRF52832 429 /// The buffer must have a length of at most 255 bytes on the nRF52832
@@ -395,6 +437,15 @@ impl<'d, T: Instance> Twim<'d, T> {
395 Ok(()) 437 Ok(())
396 } 438 }
397 439
440 pub fn blocking_write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
441 self.setup_write_from_ram(address, buffer, false)?;
442 self.blocking_wait();
443 compiler_fence(SeqCst);
444 self.check_errorsrc()?;
445 self.check_tx(buffer.len())?;
446 Ok(())
447 }
448
398 /// Read from an I2C slave. 449 /// Read from an I2C slave.
399 /// 450 ///
400 /// The buffer must have a length of at most 255 bytes on the nRF52832 451 /// The buffer must have a length of at most 255 bytes on the nRF52832
@@ -428,45 +479,19 @@ impl<'d, T: Instance> Twim<'d, T> {
428 Ok(()) 479 Ok(())
429 } 480 }
430 481
431 /// Copy data into RAM and write to an I2C slave. 482 pub fn blocking_write_read_from_ram(
432 ///
433 /// The write buffer must have a length of at most 255 bytes on the nRF52832
434 /// and at most 1024 bytes on the nRF52840.
435 pub fn blocking_copy_write(&mut self, address: u8, wr_buffer: &[u8]) -> Result<(), Error> {
436 if wr_buffer.len() > FORCE_COPY_BUFFER_SIZE {
437 return Err(Error::TxBufferTooLong);
438 }
439
440 // Copy to RAM
441 let wr_ram_buffer = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()];
442 wr_ram_buffer.copy_from_slice(wr_buffer);
443
444 self.blocking_write(address, wr_ram_buffer)
445 }
446
447 /// Copy data into RAM and write to an I2C slave, then read data from the slave without
448 /// triggering a stop condition between the two.
449 ///
450 /// The write buffer must have a length of at most 255 bytes on the nRF52832
451 /// and at most 1024 bytes on the nRF52840.
452 ///
453 /// The read buffer must have a length of at most 255 bytes on the nRF52832
454 /// and at most 65535 bytes on the nRF52840.
455 pub fn blocking_copy_write_read(
456 &mut self, 483 &mut self,
457 address: u8, 484 address: u8,
458 wr_buffer: &[u8], 485 wr_buffer: &[u8],
459 rd_buffer: &mut [u8], 486 rd_buffer: &mut [u8],
460 ) -> Result<(), Error> { 487 ) -> Result<(), Error> {
461 if wr_buffer.len() > FORCE_COPY_BUFFER_SIZE { 488 self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, false)?;
462 return Err(Error::TxBufferTooLong); 489 self.blocking_wait();
463 } 490 compiler_fence(SeqCst);
464 491 self.check_errorsrc()?;
465 // Copy to RAM 492 self.check_tx(wr_buffer.len())?;
466 let wr_ram_buffer = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()]; 493 self.check_rx(rd_buffer.len())?;
467 wr_ram_buffer.copy_from_slice(wr_buffer); 494 Ok(())
468
469 self.blocking_write_read(address, wr_ram_buffer, rd_buffer)
470 } 495 }
471 496
472 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { 497 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
@@ -487,6 +512,15 @@ impl<'d, T: Instance> Twim<'d, T> {
487 Ok(()) 512 Ok(())
488 } 513 }
489 514
515 pub async fn write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
516 self.setup_write_from_ram(address, buffer, true)?;
517 self.async_wait().await;
518 compiler_fence(SeqCst);
519 self.check_errorsrc()?;
520 self.check_tx(buffer.len())?;
521 Ok(())
522 }
523
490 pub async fn write_read( 524 pub async fn write_read(
491 &mut self, 525 &mut self,
492 address: u8, 526 address: u8,
@@ -501,6 +535,21 @@ impl<'d, T: Instance> Twim<'d, T> {
501 self.check_rx(rd_buffer.len())?; 535 self.check_rx(rd_buffer.len())?;
502 Ok(()) 536 Ok(())
503 } 537 }
538
539 pub async fn write_read_from_ram(
540 &mut self,
541 address: u8,
542 wr_buffer: &[u8],
543 rd_buffer: &mut [u8],
544 ) -> Result<(), Error> {
545 self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, true)?;
546 self.async_wait().await;
547 compiler_fence(SeqCst);
548 self.check_errorsrc()?;
549 self.check_tx(wr_buffer.len())?;
550 self.check_rx(rd_buffer.len())?;
551 Ok(())
552 }
504} 553}
505 554
506impl<'a, T: Instance> Drop for Twim<'a, T> { 555impl<'a, T: Instance> Drop for Twim<'a, T> {
@@ -601,11 +650,7 @@ mod eh02 {
601 bytes: &'w [u8], 650 bytes: &'w [u8],
602 buffer: &'w mut [u8], 651 buffer: &'w mut [u8],
603 ) -> Result<(), Error> { 652 ) -> Result<(), Error> {
604 if slice_in_ram(bytes) { 653 self.blocking_write_read(addr, bytes, buffer)
605 self.blocking_write_read(addr, bytes, buffer)
606 } else {
607 self.blocking_copy_write_read(addr, bytes, buffer)
608 }
609 } 654 }
610 } 655 }
611} 656}