aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/twim.rs557
1 files changed, 312 insertions, 245 deletions
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index c64743ecc..187fce021 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -4,6 +4,7 @@
4 4
5use core::future::{poll_fn, Future}; 5use core::future::{poll_fn, Future};
6use core::marker::PhantomData; 6use core::marker::PhantomData;
7use core::mem::MaybeUninit;
7use core::sync::atomic::compiler_fence; 8use core::sync::atomic::compiler_fence;
8use core::sync::atomic::Ordering::SeqCst; 9use core::sync::atomic::Ordering::SeqCst;
9use core::task::Poll; 10use core::task::Poll;
@@ -13,11 +14,12 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
13use embassy_sync::waitqueue::AtomicWaker; 14use embassy_sync::waitqueue::AtomicWaker;
14#[cfg(feature = "time")] 15#[cfg(feature = "time")]
15use embassy_time::{Duration, Instant}; 16use embassy_time::{Duration, Instant};
17use embedded_hal_1::i2c::Operation;
16 18
17use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; 19use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
18use crate::gpio::Pin as GpioPin; 20use crate::gpio::Pin as GpioPin;
19use crate::interrupt::typelevel::Interrupt; 21use crate::interrupt::typelevel::Interrupt;
20use crate::util::{slice_in_ram, slice_in_ram_or}; 22use crate::util::slice_in_ram;
21use crate::{gpio, interrupt, pac, Peripheral}; 23use crate::{gpio, interrupt, pac, Peripheral};
22 24
23/// TWI frequency 25/// TWI frequency
@@ -103,6 +105,10 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
103 let r = T::regs(); 105 let r = T::regs();
104 let s = T::state(); 106 let s = T::state();
105 107
108 if r.events_suspended.read().bits() != 0 {
109 s.end_waker.wake();
110 r.intenclr.write(|w| w.suspended().clear());
111 }
106 if r.events_stopped.read().bits() != 0 { 112 if r.events_stopped.read().bits() != 0 {
107 s.end_waker.wake(); 113 s.end_waker.wake();
108 r.intenclr.write(|w| w.stopped().clear()); 114 r.intenclr.write(|w| w.stopped().clear());
@@ -182,8 +188,22 @@ impl<'d, T: Instance> Twim<'d, T> {
182 } 188 }
183 189
184 /// Set TX buffer, checking that it is in RAM and has suitable length. 190 /// Set TX buffer, checking that it is in RAM and has suitable length.
185 unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> { 191 unsafe fn set_tx_buffer(
186 slice_in_ram_or(buffer, Error::BufferNotInRAM)?; 192 &mut self,
193 buffer: &[u8],
194 ram_buffer: Option<&mut [MaybeUninit<u8>; FORCE_COPY_BUFFER_SIZE]>,
195 ) -> Result<(), Error> {
196 let buffer = if slice_in_ram(buffer) {
197 buffer
198 } else {
199 let ram_buffer = ram_buffer.ok_or(Error::BufferNotInRAM)?;
200 trace!("Copying TWIM tx buffer into RAM for DMA");
201 let ram_buffer = &mut ram_buffer[..buffer.len()];
202 // Inline implementation of the nightly API MaybeUninit::copy_from_slice(ram_buffer, buffer)
203 let uninit_src: &[MaybeUninit<u8>] = unsafe { core::mem::transmute(buffer) };
204 ram_buffer.copy_from_slice(uninit_src);
205 unsafe { &*(ram_buffer as *const [MaybeUninit<u8>] as *const [u8]) }
206 };
187 207
188 if buffer.len() > EASY_DMA_SIZE { 208 if buffer.len() > EASY_DMA_SIZE {
189 return Err(Error::TxBufferTooLong); 209 return Err(Error::TxBufferTooLong);
@@ -290,7 +310,8 @@ impl<'d, T: Instance> Twim<'d, T> {
290 fn blocking_wait(&mut self) { 310 fn blocking_wait(&mut self) {
291 let r = T::regs(); 311 let r = T::regs();
292 loop { 312 loop {
293 if r.events_stopped.read().bits() != 0 { 313 if r.events_suspended.read().bits() != 0 || r.events_stopped.read().bits() != 0 {
314 r.events_suspended.reset();
294 r.events_stopped.reset(); 315 r.events_stopped.reset();
295 break; 316 break;
296 } 317 }
@@ -307,7 +328,7 @@ impl<'d, T: Instance> Twim<'d, T> {
307 let r = T::regs(); 328 let r = T::regs();
308 let deadline = Instant::now() + timeout; 329 let deadline = Instant::now() + timeout;
309 loop { 330 loop {
310 if r.events_stopped.read().bits() != 0 { 331 if r.events_suspended.read().bits() != 0 || r.events_stopped.read().bits() != 0 {
311 r.events_stopped.reset(); 332 r.events_stopped.reset();
312 break; 333 break;
313 } 334 }
@@ -331,7 +352,7 @@ impl<'d, T: Instance> Twim<'d, T> {
331 let s = T::state(); 352 let s = T::state();
332 353
333 s.end_waker.register(cx.waker()); 354 s.end_waker.register(cx.waker());
334 if r.events_stopped.read().bits() != 0 { 355 if r.events_suspended.read().bits() != 0 || r.events_stopped.read().bits() != 0 {
335 r.events_stopped.reset(); 356 r.events_stopped.reset();
336 357
337 return Poll::Ready(()); 358 return Poll::Ready(());
@@ -347,168 +368,316 @@ impl<'d, T: Instance> Twim<'d, T> {
347 }) 368 })
348 } 369 }
349 370
350 fn setup_write_from_ram(&mut self, address: u8, buffer: &[u8], inten: bool) -> Result<(), Error> { 371 fn setup_operations(
372 &mut self,
373 address: u8,
374 operations: &mut [Operation<'_>],
375 tx_ram_buffer: Option<&mut [MaybeUninit<u8>; FORCE_COPY_BUFFER_SIZE]>,
376 last_op: Option<&Operation<'_>>,
377 inten: bool,
378 ) -> Result<usize, Error> {
351 let r = T::regs(); 379 let r = T::regs();
352 380
353 compiler_fence(SeqCst); 381 compiler_fence(SeqCst);
354 382
355 r.address.write(|w| unsafe { w.address().bits(address) }); 383 r.address.write(|w| unsafe { w.address().bits(address) });
356 384
357 // Set up the DMA write. 385 r.events_suspended.reset();
358 unsafe { self.set_tx_buffer(buffer)? };
359
360 // Clear events
361 r.events_stopped.reset(); 386 r.events_stopped.reset();
362 r.events_error.reset(); 387 r.events_error.reset();
363 r.events_lasttx.reset();
364 self.clear_errorsrc(); 388 self.clear_errorsrc();
365 389
366 if inten { 390 if inten {
367 r.intenset.write(|w| w.stopped().set().error().set()); 391 r.intenset.write(|w| w.suspended().set().stopped().set().error().set());
368 } else { 392 } else {
369 r.intenclr.write(|w| w.stopped().clear().error().clear()); 393 r.intenclr
394 .write(|w| w.suspended().clear().stopped().clear().error().clear());
370 } 395 }
371 396
372 // Start write operation. 397 assert!(!operations.is_empty());
373 r.shorts.write(|w| w.lasttx_stop().enabled()); 398 match operations {
374 r.tasks_starttx.write(|w| unsafe { w.bits(1) }); 399 [Operation::Read(_), Operation::Read(_), ..] => {
375 if buffer.is_empty() { 400 panic!("Consecutive read operations are not supported!")
376 // With a zero-length buffer, LASTTX doesn't fire (because there's no last byte!), so do the STOP ourselves. 401 }
377 r.tasks_stop.write(|w| unsafe { w.bits(1) }); 402 [Operation::Read(rd_buffer), Operation::Write(wr_buffer), rest @ ..] => {
378 } 403 let stop = rest.is_empty();
379 Ok(())
380 }
381 404
382 fn setup_read(&mut self, address: u8, buffer: &mut [u8], inten: bool) -> Result<(), Error> { 405 // Set up DMA buffers.
383 let r = T::regs(); 406 unsafe {
407 self.set_tx_buffer(wr_buffer, tx_ram_buffer)?;
408 self.set_rx_buffer(rd_buffer)?;
409 }
384 410
385 compiler_fence(SeqCst); 411 r.shorts.write(|w| {
412 w.lastrx_starttx().enabled();
413 if stop {
414 w.lasttx_stop().enabled();
415 } else {
416 w.lasttx_suspend().enabled();
417 }
418 w
419 });
420
421 // Start read+write operation.
422 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
423 if last_op.is_some() {
424 r.tasks_resume.write(|w| unsafe { w.bits(1) });
425 }
386 426
387 r.address.write(|w| unsafe { w.address().bits(address) }); 427 // TODO: Handle empty write buffer
428 if rd_buffer.is_empty() {
429 // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STARTTX ourselves.
430 r.tasks_starttx.write(|w| unsafe { w.bits(1) });
431 }
432
433 Ok(2)
434 }
435 [Operation::Read(buffer)] => {
436 // Set up DMA buffers.
437 unsafe {
438 self.set_rx_buffer(buffer)?;
439 }
388 440
389 // Set up the DMA read. 441 r.shorts.write(|w| w.lastrx_stop().enabled());
390 unsafe { self.set_rx_buffer(buffer)? };
391 442
392 // Clear events 443 // Start read operation.
393 r.events_stopped.reset(); 444 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
394 r.events_error.reset(); 445 if last_op.is_some() {
395 self.clear_errorsrc(); 446 r.tasks_resume.write(|w| unsafe { w.bits(1) });
447 }
396 448
397 if inten { 449 if buffer.is_empty() {
398 r.intenset.write(|w| w.stopped().set().error().set()); 450 // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STOP ourselves.
399 } else { 451 r.tasks_stop.write(|w| unsafe { w.bits(1) });
400 r.intenclr.write(|w| w.stopped().clear().error().clear()); 452 }
401 } 453
454 Ok(1)
455 }
456 [Operation::Write(wr_buffer), Operation::Read(rd_buffer)]
457 if !wr_buffer.is_empty() && !rd_buffer.is_empty() =>
458 {
459 // Set up DMA buffers.
460 unsafe {
461 self.set_tx_buffer(wr_buffer, tx_ram_buffer)?;
462 self.set_rx_buffer(rd_buffer)?;
463 }
464
465 // Start write+read operation.
466 r.shorts.write(|w| {
467 w.lasttx_startrx().enabled();
468 w.lastrx_stop().enabled();
469 w
470 });
471
472 r.tasks_starttx.write(|w| unsafe { w.bits(1) });
473 if last_op.is_some() {
474 r.tasks_resume.write(|w| unsafe { w.bits(1) });
475 }
476
477 Ok(2)
478 }
479 [Operation::Write(buffer), rest @ ..] => {
480 let stop = rest.is_empty();
402 481
403 // Start read operation. 482 // Set up DMA buffers.
404 r.shorts.write(|w| w.lastrx_stop().enabled()); 483 unsafe {
405 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 484 self.set_tx_buffer(buffer, tx_ram_buffer)?;
406 if buffer.is_empty() { 485 }
407 // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STOP ourselves. 486
408 r.tasks_stop.write(|w| unsafe { w.bits(1) }); 487 // Start write operation.
488 r.shorts.write(|w| {
489 if stop {
490 w.lasttx_stop().enabled();
491 } else {
492 w.lasttx_suspend().enabled();
493 }
494 w
495 });
496
497 r.tasks_starttx.write(|w| unsafe { w.bits(1) });
498 if last_op.is_some() {
499 r.tasks_resume.write(|w| unsafe { w.bits(1) });
500 }
501
502 if buffer.is_empty() {
503 // With a zero-length buffer, LASTTX doesn't fire (because there's no last byte!), so do the STOP/SUSPEND ourselves.
504 if stop {
505 r.tasks_stop.write(|w| unsafe { w.bits(1) });
506 } else {
507 r.tasks_suspend.write(|w| unsafe { w.bits(1) });
508 }
509 }
510
511 Ok(1)
512 }
513 [] => unreachable!(),
409 } 514 }
410 Ok(())
411 } 515 }
412 516
413 fn setup_write_read_from_ram( 517 fn check_operations(&mut self, operations: &[Operation<'_>]) -> Result<(), Error> {
414 &mut self,
415 address: u8,
416 wr_buffer: &[u8],
417 rd_buffer: &mut [u8],
418 inten: bool,
419 ) -> Result<(), Error> {
420 let r = T::regs();
421
422 compiler_fence(SeqCst); 518 compiler_fence(SeqCst);
519 self.check_errorsrc()?;
423 520
424 r.address.write(|w| unsafe { w.address().bits(address) }); 521 assert!(operations.len() == 1 || operations.len() == 2);
425 522 match operations {
426 // Set up DMA buffers. 523 [Operation::Read(rd_buffer), Operation::Write(wr_buffer)]
427 unsafe { 524 | [Operation::Write(wr_buffer), Operation::Read(rd_buffer)] => {
428 self.set_tx_buffer(wr_buffer)?; 525 self.check_rx(rd_buffer.len())?;
429 self.set_rx_buffer(rd_buffer)?; 526 self.check_tx(wr_buffer.len())?;
527 }
528 [Operation::Read(buffer)] => {
529 self.check_rx(buffer.len())?;
530 }
531 [Operation::Write(buffer), ..] => {
532 self.check_tx(buffer.len())?;
533 }
534 _ => unreachable!(),
430 } 535 }
536 Ok(())
537 }
431 538
432 // Clear events 539 // ===========================================
433 r.events_stopped.reset();
434 r.events_error.reset();
435 self.clear_errorsrc();
436 540
437 if inten { 541 /// Execute the provided operations on the I2C bus.
438 r.intenset.write(|w| w.stopped().set().error().set()); 542 ///
439 } else { 543 /// Each buffer must have a length of at most 255 bytes on the nRF52832
440 r.intenclr.write(|w| w.stopped().clear().error().clear()); 544 /// and at most 65535 bytes on the nRF52840.
545 ///
546 /// Consecutive `Operation::Read`s are not supported due to hardware
547 /// limitations.
548 ///
549 /// An `Operation::Write` following an `Operation::Read` must have a
550 /// non-empty buffer.
551 pub fn blocking_transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> {
552 let mut tx_ram_buffer = [MaybeUninit::uninit(); FORCE_COPY_BUFFER_SIZE];
553 let mut last_op = None;
554 while !operations.is_empty() {
555 let ops = self.setup_operations(address, operations, Some(&mut tx_ram_buffer), last_op, false)?;
556 let (in_progress, rest) = operations.split_at_mut(ops);
557 self.blocking_wait();
558 self.check_operations(in_progress)?;
559 last_op = in_progress.last();
560 operations = rest;
441 } 561 }
562 Ok(())
563 }
442 564
443 // Start write+read operation. 565 /// Same as [`blocking_transaction`](Twim::blocking_transaction) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
444 r.shorts.write(|w| { 566 pub fn blocking_transaction_from_ram(
445 w.lasttx_startrx().enabled(); 567 &mut self,
446 w.lastrx_stop().enabled(); 568 address: u8,
447 w 569 mut operations: &mut [Operation<'_>],
448 }); 570 ) -> Result<(), Error> {
449 r.tasks_starttx.write(|w| unsafe { w.bits(1) }); 571 let mut last_op = None;
450 if wr_buffer.is_empty() && rd_buffer.is_empty() { 572 while !operations.is_empty() {
451 // With a zero-length buffer, LASTRX/LASTTX doesn't fire (because there's no last byte!), so do the STOP ourselves. 573 let ops = self.setup_operations(address, operations, None, last_op, false)?;
452 // TODO handle when only one of the buffers is zero length 574 let (in_progress, rest) = operations.split_at_mut(ops);
453 r.tasks_stop.write(|w| unsafe { w.bits(1) }); 575 self.blocking_wait();
576 self.check_operations(in_progress)?;
577 last_op = in_progress.last();
578 operations = rest;
454 } 579 }
580 Ok(())
581 }
455 582
583 /// Execute the provided operations on the I2C bus with timeout.
584 ///
585 /// See [`blocking_transaction`].
586 #[cfg(feature = "time")]
587 pub fn blocking_transaction_timeout(
588 &mut self,
589 address: u8,
590 mut operations: &mut [Operation<'_>],
591 timeout: Duration,
592 ) -> Result<(), Error> {
593 let mut tx_ram_buffer = [MaybeUninit::uninit(); FORCE_COPY_BUFFER_SIZE];
594 let mut last_op = None;
595 while !operations.is_empty() {
596 let ops = self.setup_operations(address, operations, Some(&mut tx_ram_buffer), last_op, false)?;
597 let (in_progress, rest) = operations.split_at_mut(ops);
598 self.blocking_wait_timeout(timeout)?;
599 self.check_operations(in_progress)?;
600 last_op = in_progress.last();
601 operations = rest;
602 }
456 Ok(()) 603 Ok(())
457 } 604 }
458 605
459 fn setup_write_read( 606 /// Same as [`blocking_transaction_timeout`](Twim::blocking_transaction_timeout) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
607 #[cfg(feature = "time")]
608 pub fn blocking_transaction_from_ram_timeout(
460 &mut self, 609 &mut self,
461 address: u8, 610 address: u8,
462 wr_buffer: &[u8], 611 mut operations: &mut [Operation<'_>],
463 rd_buffer: &mut [u8], 612 timeout: Duration,
464 inten: bool,
465 ) -> Result<(), Error> { 613 ) -> Result<(), Error> {
466 match self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, inten) { 614 let mut last_op = None;
467 Ok(_) => Ok(()), 615 while !operations.is_empty() {
468 Err(Error::BufferNotInRAM) => { 616 let ops = self.setup_operations(address, operations, None, last_op, false)?;
469 trace!("Copying TWIM tx buffer into RAM for DMA"); 617 let (in_progress, rest) = operations.split_at_mut(ops);
470 let tx_ram_buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()]; 618 self.blocking_wait_timeout(timeout)?;
471 tx_ram_buf.copy_from_slice(wr_buffer); 619 self.check_operations(in_progress)?;
472 self.setup_write_read_from_ram(address, tx_ram_buf, rd_buffer, inten) 620 last_op = in_progress.last();
473 } 621 operations = rest;
474 Err(error) => Err(error),
475 } 622 }
623 Ok(())
476 } 624 }
477 625
478 fn setup_write(&mut self, address: u8, wr_buffer: &[u8], inten: bool) -> Result<(), Error> { 626 /// Execute the provided operations on the I2C bus.
479 match self.setup_write_from_ram(address, wr_buffer, inten) { 627 ///
480 Ok(_) => Ok(()), 628 /// Each buffer must have a length of at most 255 bytes on the nRF52832
481 Err(Error::BufferNotInRAM) => { 629 /// and at most 65535 bytes on the nRF52840.
482 trace!("Copying TWIM tx buffer into RAM for DMA"); 630 ///
483 let tx_ram_buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()]; 631 /// Consecutive `Operation::Read`s are not supported due to hardware
484 tx_ram_buf.copy_from_slice(wr_buffer); 632 /// limitations.
485 self.setup_write_from_ram(address, tx_ram_buf, inten) 633 ///
486 } 634 /// An `Operation::Write` following an `Operation::Read` must have a
487 Err(error) => Err(error), 635 /// non-empty buffer.
636 pub async fn transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> {
637 let mut tx_ram_buffer = [MaybeUninit::uninit(); FORCE_COPY_BUFFER_SIZE];
638 let mut last_op = None;
639 while !operations.is_empty() {
640 let ops = self.setup_operations(address, operations, Some(&mut tx_ram_buffer), last_op, true)?;
641 let (in_progress, rest) = operations.split_at_mut(ops);
642 self.async_wait().await;
643 self.check_operations(in_progress)?;
644 last_op = in_progress.last();
645 operations = rest;
488 } 646 }
647 Ok(())
648 }
649
650 /// Same as [`transaction`](Twim::transaction) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
651 pub async fn transaction_from_ram(
652 &mut self,
653 address: u8,
654 mut operations: &mut [Operation<'_>],
655 ) -> Result<(), Error> {
656 let mut last_op = None;
657 while !operations.is_empty() {
658 let ops = self.setup_operations(address, operations, None, last_op, true)?;
659 let (in_progress, rest) = operations.split_at_mut(ops);
660 self.async_wait().await;
661 self.check_operations(in_progress)?;
662 last_op = in_progress.last();
663 operations = rest;
664 }
665 Ok(())
489 } 666 }
490 667
668 // ===========================================
669
491 /// Write to an I2C slave. 670 /// Write to an I2C slave.
492 /// 671 ///
493 /// The buffer must have a length of at most 255 bytes on the nRF52832 672 /// The buffer must have a length of at most 255 bytes on the nRF52832
494 /// and at most 65535 bytes on the nRF52840. 673 /// and at most 65535 bytes on the nRF52840.
495 pub fn blocking_write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { 674 pub fn blocking_write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
496 self.setup_write(address, buffer, false)?; 675 self.blocking_transaction(address, &mut [Operation::Write(buffer)])
497 self.blocking_wait();
498 compiler_fence(SeqCst);
499 self.check_errorsrc()?;
500 self.check_tx(buffer.len())?;
501 Ok(())
502 } 676 }
503 677
504 /// Same as [`blocking_write`](Twim::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. 678 /// Same as [`blocking_write`](Twim::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
505 pub fn blocking_write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { 679 pub fn blocking_write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
506 self.setup_write_from_ram(address, buffer, false)?; 680 self.blocking_transaction_from_ram(address, &mut [Operation::Write(buffer)])
507 self.blocking_wait();
508 compiler_fence(SeqCst);
509 self.check_errorsrc()?;
510 self.check_tx(buffer.len())?;
511 Ok(())
512 } 681 }
513 682
514 /// Read from an I2C slave. 683 /// Read from an I2C slave.
@@ -516,12 +685,7 @@ impl<'d, T: Instance> Twim<'d, T> {
516 /// The buffer must have a length of at most 255 bytes on the nRF52832 685 /// The buffer must have a length of at most 255 bytes on the nRF52832
517 /// and at most 65535 bytes on the nRF52840. 686 /// and at most 65535 bytes on the nRF52840.
518 pub fn blocking_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { 687 pub fn blocking_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
519 self.setup_read(address, buffer, false)?; 688 self.blocking_transaction(address, &mut [Operation::Read(buffer)])
520 self.blocking_wait();
521 compiler_fence(SeqCst);
522 self.check_errorsrc()?;
523 self.check_rx(buffer.len())?;
524 Ok(())
525 } 689 }
526 690
527 /// Write data to an I2C slave, then read data from the slave without 691 /// Write data to an I2C slave, then read data from the slave without
@@ -530,13 +694,7 @@ impl<'d, T: Instance> Twim<'d, T> {
530 /// The buffers must have a length of at most 255 bytes on the nRF52832 694 /// The buffers must have a length of at most 255 bytes on the nRF52832
531 /// and at most 65535 bytes on the nRF52840. 695 /// and at most 65535 bytes on the nRF52840.
532 pub fn blocking_write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Error> { 696 pub fn blocking_write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Error> {
533 self.setup_write_read(address, wr_buffer, rd_buffer, false)?; 697 self.blocking_transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)])
534 self.blocking_wait();
535 compiler_fence(SeqCst);
536 self.check_errorsrc()?;
537 self.check_tx(wr_buffer.len())?;
538 self.check_rx(rd_buffer.len())?;
539 Ok(())
540 } 698 }
541 699
542 /// Same as [`blocking_write_read`](Twim::blocking_write_read) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. 700 /// Same as [`blocking_write_read`](Twim::blocking_write_read) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
@@ -546,13 +704,7 @@ impl<'d, T: Instance> Twim<'d, T> {
546 wr_buffer: &[u8], 704 wr_buffer: &[u8],
547 rd_buffer: &mut [u8], 705 rd_buffer: &mut [u8],
548 ) -> Result<(), Error> { 706 ) -> Result<(), Error> {
549 self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, false)?; 707 self.blocking_transaction_from_ram(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)])
550 self.blocking_wait();
551 compiler_fence(SeqCst);
552 self.check_errorsrc()?;
553 self.check_tx(wr_buffer.len())?;
554 self.check_rx(rd_buffer.len())?;
555 Ok(())
556 } 708 }
557 709
558 // =========================================== 710 // ===========================================
@@ -562,12 +714,7 @@ impl<'d, T: Instance> Twim<'d, T> {
562 /// See [`blocking_write`]. 714 /// See [`blocking_write`].
563 #[cfg(feature = "time")] 715 #[cfg(feature = "time")]
564 pub fn blocking_write_timeout(&mut self, address: u8, buffer: &[u8], timeout: Duration) -> Result<(), Error> { 716 pub fn blocking_write_timeout(&mut self, address: u8, buffer: &[u8], timeout: Duration) -> Result<(), Error> {
565 self.setup_write(address, buffer, false)?; 717 self.blocking_transaction_timeout(address, &mut [Operation::Write(buffer)], timeout)
566 self.blocking_wait_timeout(timeout)?;
567 compiler_fence(SeqCst);
568 self.check_errorsrc()?;
569 self.check_tx(buffer.len())?;
570 Ok(())
571 } 718 }
572 719
573 /// Same as [`blocking_write`](Twim::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. 720 /// Same as [`blocking_write`](Twim::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
@@ -578,12 +725,7 @@ impl<'d, T: Instance> Twim<'d, T> {
578 buffer: &[u8], 725 buffer: &[u8],
579 timeout: Duration, 726 timeout: Duration,
580 ) -> Result<(), Error> { 727 ) -> Result<(), Error> {
581 self.setup_write_from_ram(address, buffer, false)?; 728 self.blocking_transaction_from_ram_timeout(address, &mut [Operation::Write(buffer)], timeout)
582 self.blocking_wait_timeout(timeout)?;
583 compiler_fence(SeqCst);
584 self.check_errorsrc()?;
585 self.check_tx(buffer.len())?;
586 Ok(())
587 } 729 }
588 730
589 /// Read from an I2C slave. 731 /// Read from an I2C slave.
@@ -592,12 +734,7 @@ impl<'d, T: Instance> Twim<'d, T> {
592 /// and at most 65535 bytes on the nRF52840. 734 /// and at most 65535 bytes on the nRF52840.
593 #[cfg(feature = "time")] 735 #[cfg(feature = "time")]
594 pub fn blocking_read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error> { 736 pub fn blocking_read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error> {
595 self.setup_read(address, buffer, false)?; 737 self.blocking_transaction_timeout(address, &mut [Operation::Read(buffer)], timeout)
596 self.blocking_wait_timeout(timeout)?;
597 compiler_fence(SeqCst);
598 self.check_errorsrc()?;
599 self.check_rx(buffer.len())?;
600 Ok(())
601 } 738 }
602 739
603 /// Write data to an I2C slave, then read data from the slave without 740 /// Write data to an I2C slave, then read data from the slave without
@@ -613,13 +750,11 @@ impl<'d, T: Instance> Twim<'d, T> {
613 rd_buffer: &mut [u8], 750 rd_buffer: &mut [u8],
614 timeout: Duration, 751 timeout: Duration,
615 ) -> Result<(), Error> { 752 ) -> Result<(), Error> {
616 self.setup_write_read(address, wr_buffer, rd_buffer, false)?; 753 self.blocking_transaction_timeout(
617 self.blocking_wait_timeout(timeout)?; 754 address,
618 compiler_fence(SeqCst); 755 &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)],
619 self.check_errorsrc()?; 756 timeout,
620 self.check_tx(wr_buffer.len())?; 757 )
621 self.check_rx(rd_buffer.len())?;
622 Ok(())
623 } 758 }
624 759
625 /// Same as [`blocking_write_read`](Twim::blocking_write_read) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. 760 /// Same as [`blocking_write_read`](Twim::blocking_write_read) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
@@ -631,13 +766,11 @@ impl<'d, T: Instance> Twim<'d, T> {
631 rd_buffer: &mut [u8], 766 rd_buffer: &mut [u8],
632 timeout: Duration, 767 timeout: Duration,
633 ) -> Result<(), Error> { 768 ) -> Result<(), Error> {
634 self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, false)?; 769 self.blocking_transaction_from_ram_timeout(
635 self.blocking_wait_timeout(timeout)?; 770 address,
636 compiler_fence(SeqCst); 771 &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)],
637 self.check_errorsrc()?; 772 timeout,
638 self.check_tx(wr_buffer.len())?; 773 )
639 self.check_rx(rd_buffer.len())?;
640 Ok(())
641 } 774 }
642 775
643 // =========================================== 776 // ===========================================
@@ -647,12 +780,7 @@ impl<'d, T: Instance> Twim<'d, T> {
647 /// The buffer must have a length of at most 255 bytes on the nRF52832 780 /// The buffer must have a length of at most 255 bytes on the nRF52832
648 /// and at most 65535 bytes on the nRF52840. 781 /// and at most 65535 bytes on the nRF52840.
649 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { 782 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
650 self.setup_read(address, buffer, true)?; 783 self.transaction(address, &mut [Operation::Read(buffer)]).await
651 self.async_wait().await;
652 compiler_fence(SeqCst);
653 self.check_errorsrc()?;
654 self.check_rx(buffer.len())?;
655 Ok(())
656 } 784 }
657 785
658 /// Write to an I2C slave. 786 /// Write to an I2C slave.
@@ -660,22 +788,13 @@ impl<'d, T: Instance> Twim<'d, T> {
660 /// The buffer must have a length of at most 255 bytes on the nRF52832 788 /// The buffer must have a length of at most 255 bytes on the nRF52832
661 /// and at most 65535 bytes on the nRF52840. 789 /// and at most 65535 bytes on the nRF52840.
662 pub async fn write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { 790 pub async fn write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
663 self.setup_write(address, buffer, true)?; 791 self.transaction(address, &mut [Operation::Write(buffer)]).await
664 self.async_wait().await;
665 compiler_fence(SeqCst);
666 self.check_errorsrc()?;
667 self.check_tx(buffer.len())?;
668 Ok(())
669 } 792 }
670 793
671 /// Same as [`write`](Twim::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. 794 /// Same as [`write`](Twim::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
672 pub async fn write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { 795 pub async fn write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
673 self.setup_write_from_ram(address, buffer, true)?; 796 self.transaction_from_ram(address, &mut [Operation::Write(buffer)])
674 self.async_wait().await; 797 .await
675 compiler_fence(SeqCst);
676 self.check_errorsrc()?;
677 self.check_tx(buffer.len())?;
678 Ok(())
679 } 798 }
680 799
681 /// Write data to an I2C slave, then read data from the slave without 800 /// Write data to an I2C slave, then read data from the slave without
@@ -684,13 +803,8 @@ impl<'d, T: Instance> Twim<'d, T> {
684 /// The buffers must have a length of at most 255 bytes on the nRF52832 803 /// The buffers must have a length of at most 255 bytes on the nRF52832
685 /// and at most 65535 bytes on the nRF52840. 804 /// and at most 65535 bytes on the nRF52840.
686 pub async fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Error> { 805 pub async fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Error> {
687 self.setup_write_read(address, wr_buffer, rd_buffer, true)?; 806 self.transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)])
688 self.async_wait().await; 807 .await
689 compiler_fence(SeqCst);
690 self.check_errorsrc()?;
691 self.check_tx(wr_buffer.len())?;
692 self.check_rx(rd_buffer.len())?;
693 Ok(())
694 } 808 }
695 809
696 /// Same as [`write_read`](Twim::write_read) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. 810 /// Same as [`write_read`](Twim::write_read) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
@@ -700,13 +814,8 @@ impl<'d, T: Instance> Twim<'d, T> {
700 wr_buffer: &[u8], 814 wr_buffer: &[u8],
701 rd_buffer: &mut [u8], 815 rd_buffer: &mut [u8],
702 ) -> Result<(), Error> { 816 ) -> Result<(), Error> {
703 self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, true)?; 817 self.transaction_from_ram(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)])
704 self.async_wait().await; 818 .await
705 compiler_fence(SeqCst);
706 self.check_errorsrc()?;
707 self.check_tx(wr_buffer.len())?;
708 self.check_rx(rd_buffer.len())?;
709 Ok(())
710 } 819 }
711} 820}
712 821
@@ -777,16 +886,7 @@ mod eh02 {
777 type Error = Error; 886 type Error = Error;
778 887
779 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { 888 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
780 if slice_in_ram(bytes) { 889 self.blocking_write(addr, bytes)
781 self.blocking_write(addr, bytes)
782 } else {
783 let buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..];
784 for chunk in bytes.chunks(FORCE_COPY_BUFFER_SIZE) {
785 buf[..chunk.len()].copy_from_slice(chunk);
786 self.blocking_write(addr, &buf[..chunk.len()])?;
787 }
788 Ok(())
789 }
790 } 890 }
791 } 891 }
792 892
@@ -832,47 +932,14 @@ impl<'d, T: Instance> embedded_hal_1::i2c::ErrorType for Twim<'d, T> {
832} 932}
833 933
834impl<'d, T: Instance> embedded_hal_1::i2c::I2c for Twim<'d, T> { 934impl<'d, T: Instance> embedded_hal_1::i2c::I2c for Twim<'d, T> {
835 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { 935 fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
836 self.blocking_read(address, buffer) 936 self.blocking_transaction(address, operations)
837 }
838
839 fn write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Self::Error> {
840 self.blocking_write(address, buffer)
841 }
842
843 fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Self::Error> {
844 self.blocking_write_read(address, wr_buffer, rd_buffer)
845 }
846
847 fn transaction(
848 &mut self,
849 _address: u8,
850 _operations: &mut [embedded_hal_1::i2c::Operation<'_>],
851 ) -> Result<(), Self::Error> {
852 todo!();
853 } 937 }
854} 938}
855 939
856impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> { 940impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> {
857 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { 941 async fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
858 self.read(address, read).await 942 self.transaction(address, operations).await
859 }
860
861 async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
862 self.write(address, write).await
863 }
864 async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
865 self.write_read(address, write, read).await
866 }
867
868 async fn transaction(
869 &mut self,
870 address: u8,
871 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
872 ) -> Result<(), Self::Error> {
873 let _ = address;
874 let _ = operations;
875 todo!()
876 } 943 }
877} 944}
878 945