diff options
| -rw-r--r-- | embassy-nrf/src/twim.rs | 171 | ||||
| -rw-r--r-- | examples/nrf52840/src/bin/twim.rs | 4 | ||||
| -rw-r--r-- | examples/nrf52840/src/bin/twim_lowpower.rs | 2 |
3 files changed, 34 insertions, 143 deletions
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 083b54b99..3d5e841d1 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | use core::future::{poll_fn, Future}; | 5 | use core::future::{poll_fn, Future}; |
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::mem::MaybeUninit; | ||
| 8 | use core::sync::atomic::compiler_fence; | 7 | use core::sync::atomic::compiler_fence; |
| 9 | use core::sync::atomic::Ordering::SeqCst; | 8 | use core::sync::atomic::Ordering::SeqCst; |
| 10 | use core::task::Poll; | 9 | use core::task::Poll; |
| @@ -17,7 +16,7 @@ use embassy_time::{Duration, Instant}; | |||
| 17 | use embedded_hal_1::i2c::Operation; | 16 | use embedded_hal_1::i2c::Operation; |
| 18 | pub use pac::twim::vals::Frequency; | 17 | pub use pac::twim::vals::Frequency; |
| 19 | 18 | ||
| 20 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 19 | use crate::chip::EASY_DMA_SIZE; |
| 21 | use crate::gpio::Pin as GpioPin; | 20 | use crate::gpio::Pin as GpioPin; |
| 22 | use crate::interrupt::typelevel::Interrupt; | 21 | use crate::interrupt::typelevel::Interrupt; |
| 23 | use crate::pac::gpio::vals as gpiovals; | 22 | use crate::pac::gpio::vals as gpiovals; |
| @@ -75,8 +74,8 @@ pub enum Error { | |||
| 75 | Transmit, | 74 | Transmit, |
| 76 | /// Data reception failed. | 75 | /// Data reception failed. |
| 77 | Receive, | 76 | Receive, |
| 78 | /// The buffer is not in data RAM. It's most likely in flash, and nRF's DMA cannot access flash. | 77 | /// The buffer is not in data RAM and is larger than the RAM buffer. It's most likely in flash, and nRF's DMA cannot access flash. |
| 79 | BufferNotInRAM, | 78 | RAMBufferTooSmall, |
| 80 | /// Didn't receive an ACK bit after the address byte. Address might be wrong, or the i2c device chip might not be connected properly. | 79 | /// Didn't receive an ACK bit after the address byte. Address might be wrong, or the i2c device chip might not be connected properly. |
| 81 | AddressNack, | 80 | AddressNack, |
| 82 | /// Didn't receive an ACK bit after a data byte. | 81 | /// Didn't receive an ACK bit after a data byte. |
| @@ -115,16 +114,24 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 115 | /// TWI driver. | 114 | /// TWI driver. |
| 116 | pub struct Twim<'d, T: Instance> { | 115 | pub struct Twim<'d, T: Instance> { |
| 117 | _p: Peri<'d, T>, | 116 | _p: Peri<'d, T>, |
| 117 | tx_ram_buffer: &'d mut [u8], | ||
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | impl<'d, T: Instance> Twim<'d, T> { | 120 | impl<'d, T: Instance> Twim<'d, T> { |
| 121 | /// Create a new TWI driver. | 121 | /// Create a new TWI driver. |
| 122 | /// | ||
| 123 | /// `tx_ram_buffer` is required if any write operations will be performed with data that is not in RAM. | ||
| 124 | /// Usually this is static data that the compiler locates in flash instead of RAM. The `tx_ram_buffer` | ||
| 125 | /// needs to be at least as large as the largest write operation that will be executed with a buffer | ||
| 126 | /// that is not in RAM. If all write operations will be performed from RAM, an empty buffer (`&[]`) may | ||
| 127 | /// be used. | ||
| 122 | pub fn new( | 128 | pub fn new( |
| 123 | twim: Peri<'d, T>, | 129 | twim: Peri<'d, T>, |
| 124 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 130 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 125 | sda: Peri<'d, impl GpioPin>, | 131 | sda: Peri<'d, impl GpioPin>, |
| 126 | scl: Peri<'d, impl GpioPin>, | 132 | scl: Peri<'d, impl GpioPin>, |
| 127 | config: Config, | 133 | config: Config, |
| 134 | tx_ram_buffer: &'d mut [u8], | ||
| 128 | ) -> Self { | 135 | ) -> Self { |
| 129 | let r = T::regs(); | 136 | let r = T::regs(); |
| 130 | 137 | ||
| @@ -159,7 +166,10 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 159 | // Enable TWIM instance. | 166 | // Enable TWIM instance. |
| 160 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | 167 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 161 | 168 | ||
| 162 | let mut twim = Self { _p: twim }; | 169 | let mut twim = Self { |
| 170 | _p: twim, | ||
| 171 | tx_ram_buffer, | ||
| 172 | }; | ||
| 163 | 173 | ||
| 164 | // Apply runtime peripheral configuration | 174 | // Apply runtime peripheral configuration |
| 165 | Self::set_config(&mut twim, &config).unwrap(); | 175 | Self::set_config(&mut twim, &config).unwrap(); |
| @@ -174,21 +184,17 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 174 | } | 184 | } |
| 175 | 185 | ||
| 176 | /// Set TX buffer, checking that it is in RAM and has suitable length. | 186 | /// Set TX buffer, checking that it is in RAM and has suitable length. |
| 177 | unsafe fn set_tx_buffer( | 187 | unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 178 | &mut self, | ||
| 179 | buffer: &[u8], | ||
| 180 | ram_buffer: Option<&mut [MaybeUninit<u8>; FORCE_COPY_BUFFER_SIZE]>, | ||
| 181 | ) -> Result<(), Error> { | ||
| 182 | let buffer = if slice_in_ram(buffer) { | 188 | let buffer = if slice_in_ram(buffer) { |
| 183 | buffer | 189 | buffer |
| 184 | } else { | 190 | } else { |
| 185 | let ram_buffer = ram_buffer.ok_or(Error::BufferNotInRAM)?; | 191 | if buffer.len() > self.tx_ram_buffer.len() { |
| 192 | return Err(Error::RAMBufferTooSmall); | ||
| 193 | } | ||
| 186 | trace!("Copying TWIM tx buffer into RAM for DMA"); | 194 | trace!("Copying TWIM tx buffer into RAM for DMA"); |
| 187 | let ram_buffer = &mut ram_buffer[..buffer.len()]; | 195 | let ram_buffer = &mut self.tx_ram_buffer[..buffer.len()]; |
| 188 | // Inline implementation of the nightly API MaybeUninit::copy_from_slice(ram_buffer, buffer) | 196 | ram_buffer.copy_from_slice(buffer); |
| 189 | let uninit_src: &[MaybeUninit<u8>] = unsafe { core::mem::transmute(buffer) }; | 197 | &*ram_buffer |
| 190 | ram_buffer.copy_from_slice(uninit_src); | ||
| 191 | unsafe { &*(ram_buffer as *const [MaybeUninit<u8>] as *const [u8]) } | ||
| 192 | }; | 198 | }; |
| 193 | 199 | ||
| 194 | if buffer.len() > EASY_DMA_SIZE { | 200 | if buffer.len() > EASY_DMA_SIZE { |
| @@ -358,7 +364,6 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 358 | &mut self, | 364 | &mut self, |
| 359 | address: u8, | 365 | address: u8, |
| 360 | operations: &mut [Operation<'_>], | 366 | operations: &mut [Operation<'_>], |
| 361 | tx_ram_buffer: Option<&mut [MaybeUninit<u8>; FORCE_COPY_BUFFER_SIZE]>, | ||
| 362 | last_op: Option<&Operation<'_>>, | 367 | last_op: Option<&Operation<'_>>, |
| 363 | inten: bool, | 368 | inten: bool, |
| 364 | ) -> Result<usize, Error> { | 369 | ) -> Result<usize, Error> { |
| @@ -397,7 +402,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 397 | 402 | ||
| 398 | // Set up DMA buffers. | 403 | // Set up DMA buffers. |
| 399 | unsafe { | 404 | unsafe { |
| 400 | self.set_tx_buffer(wr_buffer, tx_ram_buffer)?; | 405 | self.set_tx_buffer(wr_buffer)?; |
| 401 | self.set_rx_buffer(rd_buffer)?; | 406 | self.set_rx_buffer(rd_buffer)?; |
| 402 | } | 407 | } |
| 403 | 408 | ||
| @@ -450,7 +455,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 450 | { | 455 | { |
| 451 | // Set up DMA buffers. | 456 | // Set up DMA buffers. |
| 452 | unsafe { | 457 | unsafe { |
| 453 | self.set_tx_buffer(wr_buffer, tx_ram_buffer)?; | 458 | self.set_tx_buffer(wr_buffer)?; |
| 454 | self.set_rx_buffer(rd_buffer)?; | 459 | self.set_rx_buffer(rd_buffer)?; |
| 455 | } | 460 | } |
| 456 | 461 | ||
| @@ -472,7 +477,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 472 | 477 | ||
| 473 | // Set up DMA buffers. | 478 | // Set up DMA buffers. |
| 474 | unsafe { | 479 | unsafe { |
| 475 | self.set_tx_buffer(buffer, tx_ram_buffer)?; | 480 | self.set_tx_buffer(buffer)?; |
| 476 | } | 481 | } |
| 477 | 482 | ||
| 478 | // Start write operation. | 483 | // Start write operation. |
| @@ -539,28 +544,9 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 539 | /// An `Operation::Write` following an `Operation::Read` must have a | 544 | /// An `Operation::Write` following an `Operation::Read` must have a |
| 540 | /// non-empty buffer. | 545 | /// non-empty buffer. |
| 541 | pub fn blocking_transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> { | 546 | pub fn blocking_transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> { |
| 542 | let mut tx_ram_buffer = [MaybeUninit::uninit(); FORCE_COPY_BUFFER_SIZE]; | ||
| 543 | let mut last_op = None; | 547 | let mut last_op = None; |
| 544 | while !operations.is_empty() { | 548 | while !operations.is_empty() { |
| 545 | let ops = self.setup_operations(address, operations, Some(&mut tx_ram_buffer), last_op, false)?; | 549 | let ops = self.setup_operations(address, operations, last_op, false)?; |
| 546 | let (in_progress, rest) = operations.split_at_mut(ops); | ||
| 547 | self.blocking_wait(); | ||
| 548 | self.check_operations(in_progress)?; | ||
| 549 | last_op = in_progress.last(); | ||
| 550 | operations = rest; | ||
| 551 | } | ||
| 552 | Ok(()) | ||
| 553 | } | ||
| 554 | |||
| 555 | /// Same as [`blocking_transaction`](Twim::blocking_transaction) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. | ||
| 556 | pub fn blocking_transaction_from_ram( | ||
| 557 | &mut self, | ||
| 558 | address: u8, | ||
| 559 | mut operations: &mut [Operation<'_>], | ||
| 560 | ) -> Result<(), Error> { | ||
| 561 | let mut last_op = None; | ||
| 562 | while !operations.is_empty() { | ||
| 563 | let ops = self.setup_operations(address, operations, None, last_op, false)?; | ||
| 564 | let (in_progress, rest) = operations.split_at_mut(ops); | 550 | let (in_progress, rest) = operations.split_at_mut(ops); |
| 565 | self.blocking_wait(); | 551 | self.blocking_wait(); |
| 566 | self.check_operations(in_progress)?; | 552 | self.check_operations(in_progress)?; |
| @@ -580,30 +566,9 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 580 | mut operations: &mut [Operation<'_>], | 566 | mut operations: &mut [Operation<'_>], |
| 581 | timeout: Duration, | 567 | timeout: Duration, |
| 582 | ) -> Result<(), Error> { | 568 | ) -> Result<(), Error> { |
| 583 | let mut tx_ram_buffer = [MaybeUninit::uninit(); FORCE_COPY_BUFFER_SIZE]; | ||
| 584 | let mut last_op = None; | ||
| 585 | while !operations.is_empty() { | ||
| 586 | let ops = self.setup_operations(address, operations, Some(&mut tx_ram_buffer), last_op, false)?; | ||
| 587 | let (in_progress, rest) = operations.split_at_mut(ops); | ||
| 588 | self.blocking_wait_timeout(timeout)?; | ||
| 589 | self.check_operations(in_progress)?; | ||
| 590 | last_op = in_progress.last(); | ||
| 591 | operations = rest; | ||
| 592 | } | ||
| 593 | Ok(()) | ||
| 594 | } | ||
| 595 | |||
| 596 | /// 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. | ||
| 597 | #[cfg(feature = "time")] | ||
| 598 | pub fn blocking_transaction_from_ram_timeout( | ||
| 599 | &mut self, | ||
| 600 | address: u8, | ||
| 601 | mut operations: &mut [Operation<'_>], | ||
| 602 | timeout: Duration, | ||
| 603 | ) -> Result<(), Error> { | ||
| 604 | let mut last_op = None; | 569 | let mut last_op = None; |
| 605 | while !operations.is_empty() { | 570 | while !operations.is_empty() { |
| 606 | let ops = self.setup_operations(address, operations, None, last_op, false)?; | 571 | let ops = self.setup_operations(address, operations, last_op, false)?; |
| 607 | let (in_progress, rest) = operations.split_at_mut(ops); | 572 | let (in_progress, rest) = operations.split_at_mut(ops); |
| 608 | self.blocking_wait_timeout(timeout)?; | 573 | self.blocking_wait_timeout(timeout)?; |
| 609 | self.check_operations(in_progress)?; | 574 | self.check_operations(in_progress)?; |
| @@ -624,28 +589,9 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 624 | /// An `Operation::Write` following an `Operation::Read` must have a | 589 | /// An `Operation::Write` following an `Operation::Read` must have a |
| 625 | /// non-empty buffer. | 590 | /// non-empty buffer. |
| 626 | pub async fn transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> { | 591 | pub async fn transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> { |
| 627 | let mut tx_ram_buffer = [MaybeUninit::uninit(); FORCE_COPY_BUFFER_SIZE]; | ||
| 628 | let mut last_op = None; | ||
| 629 | while !operations.is_empty() { | ||
| 630 | let ops = self.setup_operations(address, operations, Some(&mut tx_ram_buffer), last_op, true)?; | ||
| 631 | let (in_progress, rest) = operations.split_at_mut(ops); | ||
| 632 | self.async_wait().await?; | ||
| 633 | self.check_operations(in_progress)?; | ||
| 634 | last_op = in_progress.last(); | ||
| 635 | operations = rest; | ||
| 636 | } | ||
| 637 | Ok(()) | ||
| 638 | } | ||
| 639 | |||
| 640 | /// Same as [`transaction`](Twim::transaction) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. | ||
| 641 | pub async fn transaction_from_ram( | ||
| 642 | &mut self, | ||
| 643 | address: u8, | ||
| 644 | mut operations: &mut [Operation<'_>], | ||
| 645 | ) -> Result<(), Error> { | ||
| 646 | let mut last_op = None; | 592 | let mut last_op = None; |
| 647 | while !operations.is_empty() { | 593 | while !operations.is_empty() { |
| 648 | let ops = self.setup_operations(address, operations, None, last_op, true)?; | 594 | let ops = self.setup_operations(address, operations, last_op, true)?; |
| 649 | let (in_progress, rest) = operations.split_at_mut(ops); | 595 | let (in_progress, rest) = operations.split_at_mut(ops); |
| 650 | self.async_wait().await?; | 596 | self.async_wait().await?; |
| 651 | self.check_operations(in_progress)?; | 597 | self.check_operations(in_progress)?; |
| @@ -665,11 +611,6 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 665 | self.blocking_transaction(address, &mut [Operation::Write(buffer)]) | 611 | self.blocking_transaction(address, &mut [Operation::Write(buffer)]) |
| 666 | } | 612 | } |
| 667 | 613 | ||
| 668 | /// Same as [`blocking_write`](Twim::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. | ||
| 669 | pub fn blocking_write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { | ||
| 670 | self.blocking_transaction_from_ram(address, &mut [Operation::Write(buffer)]) | ||
| 671 | } | ||
| 672 | |||
| 673 | /// Read from an I2C slave. | 614 | /// Read from an I2C slave. |
| 674 | /// | 615 | /// |
| 675 | /// The buffer must have a length of at most 255 bytes on the nRF52832 | 616 | /// The buffer must have a length of at most 255 bytes on the nRF52832 |
| @@ -687,16 +628,6 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 687 | self.blocking_transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)]) | 628 | self.blocking_transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)]) |
| 688 | } | 629 | } |
| 689 | 630 | ||
| 690 | /// 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. | ||
| 691 | pub fn blocking_write_read_from_ram( | ||
| 692 | &mut self, | ||
| 693 | address: u8, | ||
| 694 | wr_buffer: &[u8], | ||
| 695 | rd_buffer: &mut [u8], | ||
| 696 | ) -> Result<(), Error> { | ||
| 697 | self.blocking_transaction_from_ram(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)]) | ||
| 698 | } | ||
| 699 | |||
| 700 | // =========================================== | 631 | // =========================================== |
| 701 | 632 | ||
| 702 | /// Write to an I2C slave with timeout. | 633 | /// Write to an I2C slave with timeout. |
| @@ -707,17 +638,6 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 707 | self.blocking_transaction_timeout(address, &mut [Operation::Write(buffer)], timeout) | 638 | self.blocking_transaction_timeout(address, &mut [Operation::Write(buffer)], timeout) |
| 708 | } | 639 | } |
| 709 | 640 | ||
| 710 | /// Same as [`blocking_write`](Twim::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. | ||
| 711 | #[cfg(feature = "time")] | ||
| 712 | pub fn blocking_write_from_ram_timeout( | ||
| 713 | &mut self, | ||
| 714 | address: u8, | ||
| 715 | buffer: &[u8], | ||
| 716 | timeout: Duration, | ||
| 717 | ) -> Result<(), Error> { | ||
| 718 | self.blocking_transaction_from_ram_timeout(address, &mut [Operation::Write(buffer)], timeout) | ||
| 719 | } | ||
| 720 | |||
| 721 | /// Read from an I2C slave. | 641 | /// Read from an I2C slave. |
| 722 | /// | 642 | /// |
| 723 | /// The buffer must have a length of at most 255 bytes on the nRF52832 | 643 | /// The buffer must have a length of at most 255 bytes on the nRF52832 |
| @@ -747,22 +667,6 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 747 | ) | 667 | ) |
| 748 | } | 668 | } |
| 749 | 669 | ||
| 750 | /// 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. | ||
| 751 | #[cfg(feature = "time")] | ||
| 752 | pub fn blocking_write_read_from_ram_timeout( | ||
| 753 | &mut self, | ||
| 754 | address: u8, | ||
| 755 | wr_buffer: &[u8], | ||
| 756 | rd_buffer: &mut [u8], | ||
| 757 | timeout: Duration, | ||
| 758 | ) -> Result<(), Error> { | ||
| 759 | self.blocking_transaction_from_ram_timeout( | ||
| 760 | address, | ||
| 761 | &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)], | ||
| 762 | timeout, | ||
| 763 | ) | ||
| 764 | } | ||
| 765 | |||
| 766 | // =========================================== | 670 | // =========================================== |
| 767 | 671 | ||
| 768 | /// Read from an I2C slave. | 672 | /// Read from an I2C slave. |
| @@ -781,12 +685,6 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 781 | self.transaction(address, &mut [Operation::Write(buffer)]).await | 685 | self.transaction(address, &mut [Operation::Write(buffer)]).await |
| 782 | } | 686 | } |
| 783 | 687 | ||
| 784 | /// Same as [`write`](Twim::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. | ||
| 785 | pub async fn write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { | ||
| 786 | self.transaction_from_ram(address, &mut [Operation::Write(buffer)]) | ||
| 787 | .await | ||
| 788 | } | ||
| 789 | |||
| 790 | /// Write data to an I2C slave, then read data from the slave without | 688 | /// Write data to an I2C slave, then read data from the slave without |
| 791 | /// triggering a stop condition between the two. | 689 | /// triggering a stop condition between the two. |
| 792 | /// | 690 | /// |
| @@ -796,17 +694,6 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 796 | self.transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)]) | 694 | self.transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)]) |
| 797 | .await | 695 | .await |
| 798 | } | 696 | } |
| 799 | |||
| 800 | /// Same as [`write_read`](Twim::write_read) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. | ||
| 801 | pub async fn write_read_from_ram( | ||
| 802 | &mut self, | ||
| 803 | address: u8, | ||
| 804 | wr_buffer: &[u8], | ||
| 805 | rd_buffer: &mut [u8], | ||
| 806 | ) -> Result<(), Error> { | ||
| 807 | self.transaction_from_ram(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)]) | ||
| 808 | .await | ||
| 809 | } | ||
| 810 | } | 697 | } |
| 811 | 698 | ||
| 812 | impl<'a, T: Instance> Drop for Twim<'a, T> { | 699 | impl<'a, T: Instance> Drop for Twim<'a, T> { |
| @@ -904,7 +791,7 @@ impl embedded_hal_1::i2c::Error for Error { | |||
| 904 | Self::RxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other, | 791 | Self::RxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other, |
| 905 | Self::Transmit => embedded_hal_1::i2c::ErrorKind::Other, | 792 | Self::Transmit => embedded_hal_1::i2c::ErrorKind::Other, |
| 906 | Self::Receive => embedded_hal_1::i2c::ErrorKind::Other, | 793 | Self::Receive => embedded_hal_1::i2c::ErrorKind::Other, |
| 907 | Self::BufferNotInRAM => embedded_hal_1::i2c::ErrorKind::Other, | 794 | Self::RAMBufferTooSmall => embedded_hal_1::i2c::ErrorKind::Other, |
| 908 | Self::AddressNack => { | 795 | Self::AddressNack => { |
| 909 | embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address) | 796 | embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address) |
| 910 | } | 797 | } |
diff --git a/examples/nrf52840/src/bin/twim.rs b/examples/nrf52840/src/bin/twim.rs index ceaafd784..e30a3855d 100644 --- a/examples/nrf52840/src/bin/twim.rs +++ b/examples/nrf52840/src/bin/twim.rs | |||
| @@ -9,6 +9,7 @@ use defmt::*; | |||
| 9 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 10 | use embassy_nrf::twim::{self, Twim}; | 10 | use embassy_nrf::twim::{self, Twim}; |
| 11 | use embassy_nrf::{bind_interrupts, peripherals}; | 11 | use embassy_nrf::{bind_interrupts, peripherals}; |
| 12 | use static_cell::ConstStaticCell; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | 14 | ||
| 14 | const ADDRESS: u8 = 0x50; | 15 | const ADDRESS: u8 = 0x50; |
| @@ -22,7 +23,8 @@ async fn main(_spawner: Spawner) { | |||
| 22 | let p = embassy_nrf::init(Default::default()); | 23 | let p = embassy_nrf::init(Default::default()); |
| 23 | info!("Initializing TWI..."); | 24 | info!("Initializing TWI..."); |
| 24 | let config = twim::Config::default(); | 25 | let config = twim::Config::default(); |
| 25 | let mut twi = Twim::new(p.TWISPI0, Irqs, p.P0_03, p.P0_04, config); | 26 | static RAM_BUFFER: ConstStaticCell<[u8; 16]> = ConstStaticCell::new([0; 16]); |
| 27 | let mut twi = Twim::new(p.TWISPI0, Irqs, p.P0_03, p.P0_04, config, RAM_BUFFER.take()); | ||
| 26 | 28 | ||
| 27 | info!("Reading..."); | 29 | info!("Reading..."); |
| 28 | 30 | ||
diff --git a/examples/nrf52840/src/bin/twim_lowpower.rs b/examples/nrf52840/src/bin/twim_lowpower.rs index 8a6f958eb..f7380e20d 100644 --- a/examples/nrf52840/src/bin/twim_lowpower.rs +++ b/examples/nrf52840/src/bin/twim_lowpower.rs | |||
| @@ -30,6 +30,7 @@ async fn main(_p: Spawner) { | |||
| 30 | loop { | 30 | loop { |
| 31 | info!("Initializing TWI..."); | 31 | info!("Initializing TWI..."); |
| 32 | let config = twim::Config::default(); | 32 | let config = twim::Config::default(); |
| 33 | let mut ram_buffer = [0u8; 16]; | ||
| 33 | 34 | ||
| 34 | // Create the TWIM instance with borrowed singletons, so they're not consumed. | 35 | // Create the TWIM instance with borrowed singletons, so they're not consumed. |
| 35 | let mut twi = Twim::new( | 36 | let mut twi = Twim::new( |
| @@ -38,6 +39,7 @@ async fn main(_p: Spawner) { | |||
| 38 | p.P0_03.reborrow(), | 39 | p.P0_03.reborrow(), |
| 39 | p.P0_04.reborrow(), | 40 | p.P0_04.reborrow(), |
| 40 | config, | 41 | config, |
| 42 | &mut ram_buffer, | ||
| 41 | ); | 43 | ); |
| 42 | 44 | ||
| 43 | info!("Reading..."); | 45 | info!("Reading..."); |
