aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/twim.rs133
1 files changed, 131 insertions, 2 deletions
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index ecad58f3a..5eb1932e5 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -456,11 +456,138 @@ where
456 type WriteReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; 456 type WriteReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a;
457 457
458 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 458 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
459 self.write_read(address, &[], buffer) 459 async move {
460 // NOTE: RAM slice check for buffer is not necessary, as a mutable
461 // slice can only be built from data located in RAM.
462
463 let r = T::regs();
464 let s = T::state();
465
466 // Conservative compiler fence to prevent optimizations that do not
467 // take in to account actions by DMA. The fence has been placed here,
468 // before any DMA action has started.
469 compiler_fence(SeqCst);
470
471 r.address.write(|w| unsafe { w.address().bits(address) });
472
473 // Set up the DMA read.
474 unsafe { self.set_rx_buffer(buffer)? };
475
476 // Reset events
477 r.events_stopped.reset();
478 r.events_error.reset();
479 self.clear_errorsrc();
480
481 // Enable events
482 r.intenset.write(|w| w.stopped().set().error().set());
483
484 // Start read operation.
485 r.shorts.write(|w| w.lastrx_stop().enabled());
486 r.tasks_startrx.write(|w|
487 // `1` is a valid value to write to task registers.
488 unsafe { w.bits(1) });
489
490 // Conservative compiler fence to prevent optimizations that do not
491 // take in to account actions by DMA. The fence has been placed here,
492 // after all possible DMA actions have completed.
493 compiler_fence(SeqCst);
494
495 // Wait for 'stopped' event.
496 poll_fn(|cx| {
497 s.end_waker.register(cx.waker());
498 if r.events_stopped.read().bits() != 0 {
499 r.events_stopped.reset();
500
501 return Poll::Ready(());
502 }
503
504 // stop if an error occured
505 if r.events_error.read().bits() != 0 {
506 r.events_error.reset();
507 r.tasks_stop.write(|w| unsafe { w.bits(1) });
508 }
509
510 Poll::Pending
511 })
512 .await;
513
514 self.read_errorsrc()?;
515
516 if r.rxd.amount.read().bits() != buffer.len() as u32 {
517 return Err(Error::Receive);
518 }
519
520 Ok(())
521 }
460 } 522 }
461 523
462 fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { 524 fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
463 self.write_read(address, bytes, &mut []) 525 async move {
526 slice_in_ram_or(bytes, Error::DMABufferNotInDataMemory)?;
527
528 // Conservative compiler fence to prevent optimizations that do not
529 // take in to account actions by DMA. The fence has been placed here,
530 // before any DMA action has started.
531 compiler_fence(SeqCst);
532
533 let r = T::regs();
534 let s = T::state();
535
536 // Set up current address we're trying to talk to
537 r.address.write(|w| unsafe { w.address().bits(address) });
538
539 // Set up DMA buffers.
540 unsafe {
541 self.set_tx_buffer(bytes)?;
542 }
543
544 // Reset events
545 r.events_stopped.reset();
546 r.events_error.reset();
547 r.events_lasttx.reset();
548 self.clear_errorsrc();
549
550 // Enable events
551 r.intenset.write(|w| w.stopped().set().error().set());
552
553 // Start write operation.
554 r.shorts.write(|w| w.lasttx_stop().enabled());
555 r.tasks_starttx.write(|w|
556 // `1` is a valid value to write to task registers.
557 unsafe { w.bits(1) });
558
559 // Conservative compiler fence to prevent optimizations that do not
560 // take in to account actions by DMA. The fence has been placed here,
561 // after all possible DMA actions have completed.
562 compiler_fence(SeqCst);
563
564 // Wait for 'stopped' event.
565 poll_fn(|cx| {
566 s.end_waker.register(cx.waker());
567 if r.events_stopped.read().bits() != 0 {
568 r.events_stopped.reset();
569
570 return Poll::Ready(());
571 }
572
573 // stop if an error occured
574 if r.events_error.read().bits() != 0 {
575 r.events_error.reset();
576 r.tasks_stop.write(|w| unsafe { w.bits(1) });
577 }
578
579 Poll::Pending
580 })
581 .await;
582
583 self.read_errorsrc()?;
584
585 if r.txd.amount.read().bits() != bytes.len() as u32 {
586 return Err(Error::Transmit);
587 }
588
589 Ok(())
590 }
464 } 591 }
465 592
466 fn write_read<'a>( 593 fn write_read<'a>(
@@ -533,6 +660,8 @@ where
533 }) 660 })
534 .await; 661 .await;
535 662
663 self.read_errorsrc()?;
664
536 let bad_write = r.txd.amount.read().bits() != bytes.len() as u32; 665 let bad_write = r.txd.amount.read().bits() != bytes.len() as u32;
537 let bad_read = r.rxd.amount.read().bits() != buffer.len() as u32; 666 let bad_read = r.rxd.amount.read().bits() != buffer.len() as u32;
538 667