diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-01-14 23:31:10 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-01-19 17:59:55 +0100 |
| commit | 97ab859f0025ee6ffad19733dc24f17b6621fff8 (patch) | |
| tree | ddd6828cd1c65fa89fb0c07bcd138cbd7f20e048 | |
| parent | c949519714268afaf9b26d0ff4a7bc3c207b27d2 (diff) | |
stm32/i2c: expose all functionality as inherent methods.
| -rw-r--r-- | embassy-stm32/src/i2c/v1.rs | 50 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v2.rs | 103 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/i2c.rs | 3 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/i2c_dma.rs | 1 |
4 files changed, 96 insertions, 61 deletions
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 6fa269fc2..6b2c8a35c 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs | |||
| @@ -3,9 +3,6 @@ use crate::time::Hertz; | |||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | use embassy::util::Unborrow; | 4 | use embassy::util::Unborrow; |
| 5 | use embassy_hal_common::unborrow; | 5 | use embassy_hal_common::unborrow; |
| 6 | use embedded_hal::blocking::i2c::Read; | ||
| 7 | use embedded_hal::blocking::i2c::Write; | ||
| 8 | use embedded_hal::blocking::i2c::WriteRead; | ||
| 9 | 6 | ||
| 10 | use crate::pac::i2c; | 7 | use crate::pac::i2c; |
| 11 | 8 | ||
| @@ -179,12 +176,8 @@ impl<'d, T: Instance> I2c<'d, T> { | |||
| 179 | let value = T::regs().dr().read().dr(); | 176 | let value = T::regs().dr().read().dr(); |
| 180 | Ok(value) | 177 | Ok(value) |
| 181 | } | 178 | } |
| 182 | } | ||
| 183 | |||
| 184 | impl<'d, T: Instance> Read for I2c<'d, T> { | ||
| 185 | type Error = Error; | ||
| 186 | 179 | ||
| 187 | fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { | 180 | pub fn blocking_read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> { |
| 188 | if let Some((last, buffer)) = buffer.split_last_mut() { | 181 | if let Some((last, buffer)) = buffer.split_last_mut() { |
| 189 | // Send a START condition and set ACK bit | 182 | // Send a START condition and set ACK bit |
| 190 | unsafe { | 183 | unsafe { |
| @@ -248,12 +241,8 @@ impl<'d, T: Instance> Read for I2c<'d, T> { | |||
| 248 | Err(Error::Overrun) | 241 | Err(Error::Overrun) |
| 249 | } | 242 | } |
| 250 | } | 243 | } |
| 251 | } | ||
| 252 | |||
| 253 | impl<'d, T: Instance> Write for I2c<'d, T> { | ||
| 254 | type Error = Error; | ||
| 255 | 244 | ||
| 256 | fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { | 245 | pub fn blocking_write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { |
| 257 | unsafe { | 246 | unsafe { |
| 258 | self.write_bytes(addr, bytes)?; | 247 | self.write_bytes(addr, bytes)?; |
| 259 | // Send a STOP condition | 248 | // Send a STOP condition |
| @@ -267,16 +256,41 @@ impl<'d, T: Instance> Write for I2c<'d, T> { | |||
| 267 | // Fallthrough is success | 256 | // Fallthrough is success |
| 268 | Ok(()) | 257 | Ok(()) |
| 269 | } | 258 | } |
| 259 | |||
| 260 | pub fn blocking_write_read( | ||
| 261 | &mut self, | ||
| 262 | addr: u8, | ||
| 263 | bytes: &[u8], | ||
| 264 | buffer: &mut [u8], | ||
| 265 | ) -> Result<(), Error> { | ||
| 266 | unsafe { self.write_bytes(addr, bytes)? }; | ||
| 267 | self.blocking_read(addr, buffer)?; | ||
| 268 | |||
| 269 | Ok(()) | ||
| 270 | } | ||
| 270 | } | 271 | } |
| 271 | 272 | ||
| 272 | impl<'d, T: Instance> WriteRead for I2c<'d, T> { | 273 | impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> { |
| 273 | type Error = Error; | 274 | type Error = Error; |
| 274 | 275 | ||
| 275 | fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> { | 276 | fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { |
| 276 | unsafe { self.write_bytes(addr, bytes)? }; | 277 | self.blocking_read(addr, buffer) |
| 277 | self.read(addr, buffer)?; | 278 | } |
| 279 | } | ||
| 278 | 280 | ||
| 279 | Ok(()) | 281 | impl<'d, T: Instance> embedded_hal::blocking::i2c::Write for I2c<'d, T> { |
| 282 | type Error = Error; | ||
| 283 | |||
| 284 | fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { | ||
| 285 | self.blocking_write(addr, bytes) | ||
| 286 | } | ||
| 287 | } | ||
| 288 | |||
| 289 | impl<'d, T: Instance> embedded_hal::blocking::i2c::WriteRead for I2c<'d, T> { | ||
| 290 | type Error = Error; | ||
| 291 | |||
| 292 | fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> { | ||
| 293 | self.blocking_write_read(addr, bytes, buffer) | ||
| 280 | } | 294 | } |
| 281 | } | 295 | } |
| 282 | 296 | ||
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 73b6f5517..af04dc061 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs | |||
| @@ -10,9 +10,6 @@ use embassy::util::Unborrow; | |||
| 10 | use embassy::waitqueue::AtomicWaker; | 10 | use embassy::waitqueue::AtomicWaker; |
| 11 | use embassy_hal_common::drop::OnDrop; | 11 | use embassy_hal_common::drop::OnDrop; |
| 12 | use embassy_hal_common::unborrow; | 12 | use embassy_hal_common::unborrow; |
| 13 | use embedded_hal::blocking::i2c::Read; | ||
| 14 | use embedded_hal::blocking::i2c::Write; | ||
| 15 | use embedded_hal::blocking::i2c::WriteRead; | ||
| 16 | use futures::future::poll_fn; | 13 | use futures::future::poll_fn; |
| 17 | 14 | ||
| 18 | use crate::dma::NoDma; | 15 | use crate::dma::NoDma; |
| @@ -300,7 +297,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 300 | } | 297 | } |
| 301 | } | 298 | } |
| 302 | 299 | ||
| 303 | fn read(&mut self, address: u8, buffer: &mut [u8], restart: bool) -> Result<(), Error> { | 300 | fn read_internal( |
| 301 | &mut self, | ||
| 302 | address: u8, | ||
| 303 | buffer: &mut [u8], | ||
| 304 | restart: bool, | ||
| 305 | ) -> Result<(), Error> { | ||
| 304 | let completed_chunks = buffer.len() / 255; | 306 | let completed_chunks = buffer.len() / 255; |
| 305 | let total_chunks = if completed_chunks * 255 == buffer.len() { | 307 | let total_chunks = if completed_chunks * 255 == buffer.len() { |
| 306 | completed_chunks | 308 | completed_chunks |
| @@ -339,7 +341,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 339 | Ok(()) | 341 | Ok(()) |
| 340 | } | 342 | } |
| 341 | 343 | ||
| 342 | fn write(&mut self, address: u8, bytes: &[u8], send_stop: bool) -> Result<(), Error> { | 344 | fn write_internal(&mut self, address: u8, bytes: &[u8], send_stop: bool) -> Result<(), Error> { |
| 343 | let completed_chunks = bytes.len() / 255; | 345 | let completed_chunks = bytes.len() / 255; |
| 344 | let total_chunks = if completed_chunks * 255 == bytes.len() { | 346 | let total_chunks = if completed_chunks * 255 == bytes.len() { |
| 345 | completed_chunks | 347 | completed_chunks |
| @@ -568,14 +570,17 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 568 | Ok(()) | 570 | Ok(()) |
| 569 | } | 571 | } |
| 570 | 572 | ||
| 571 | pub async fn write_dma(&mut self, address: u8, bytes: &[u8]) -> Result<(), Error> | 573 | // ========================= |
| 574 | // Async public API | ||
| 575 | |||
| 576 | pub async fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Error> | ||
| 572 | where | 577 | where |
| 573 | TXDMA: crate::i2c::TxDma<T>, | 578 | TXDMA: crate::i2c::TxDma<T>, |
| 574 | { | 579 | { |
| 575 | self.write_dma_internal(address, bytes, true, true).await | 580 | self.write_dma_internal(address, bytes, true, true).await |
| 576 | } | 581 | } |
| 577 | 582 | ||
| 578 | pub async fn write_dma_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> | 583 | pub async fn write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> |
| 579 | where | 584 | where |
| 580 | TXDMA: crate::i2c::TxDma<T>, | 585 | TXDMA: crate::i2c::TxDma<T>, |
| 581 | { | 586 | { |
| @@ -597,19 +602,52 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 597 | Ok(()) | 602 | Ok(()) |
| 598 | } | 603 | } |
| 599 | 604 | ||
| 600 | pub async fn read_dma( | 605 | pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> |
| 606 | where | ||
| 607 | RXDMA: crate::i2c::RxDma<T>, | ||
| 608 | { | ||
| 609 | self.read_dma_internal(address, buffer, false).await | ||
| 610 | } | ||
| 611 | |||
| 612 | pub async fn write_read( | ||
| 601 | &mut self, | 613 | &mut self, |
| 602 | address: u8, | 614 | address: u8, |
| 615 | bytes: &[u8], | ||
| 603 | buffer: &mut [u8], | 616 | buffer: &mut [u8], |
| 604 | restart: bool, | ||
| 605 | ) -> Result<(), Error> | 617 | ) -> Result<(), Error> |
| 606 | where | 618 | where |
| 607 | RXDMA: crate::i2c::RxDma<T>, | 619 | TXDMA: super::TxDma<T>, |
| 620 | RXDMA: super::RxDma<T>, | ||
| 608 | { | 621 | { |
| 609 | self.read_dma_internal(address, buffer, restart).await | 622 | self.write_dma_internal(address, bytes, true, true).await?; |
| 623 | self.read_dma_internal(address, buffer, true).await?; | ||
| 624 | Ok(()) | ||
| 625 | } | ||
| 626 | |||
| 627 | // ========================= | ||
| 628 | // Blocking public API | ||
| 629 | |||
| 630 | pub fn blocking_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { | ||
| 631 | self.read_internal(address, buffer, false) | ||
| 632 | // Automatic Stop | ||
| 633 | } | ||
| 634 | |||
| 635 | pub fn blocking_write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Error> { | ||
| 636 | self.write_internal(address, bytes, true) | ||
| 610 | } | 637 | } |
| 611 | 638 | ||
| 612 | pub fn write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> { | 639 | pub fn blocking_write_read( |
| 640 | &mut self, | ||
| 641 | address: u8, | ||
| 642 | bytes: &[u8], | ||
| 643 | buffer: &mut [u8], | ||
| 644 | ) -> Result<(), Error> { | ||
| 645 | self.write_internal(address, bytes, false)?; | ||
| 646 | self.read_internal(address, buffer, true) | ||
| 647 | // Automatic Stop | ||
| 648 | } | ||
| 649 | |||
| 650 | pub fn blocking_write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> { | ||
| 613 | if bytes.is_empty() { | 651 | if bytes.is_empty() { |
| 614 | return Err(Error::ZeroLengthTransfer); | 652 | return Err(Error::ZeroLengthTransfer); |
| 615 | } | 653 | } |
| @@ -679,24 +717,23 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 679 | } | 717 | } |
| 680 | } | 718 | } |
| 681 | 719 | ||
| 682 | impl<'d, T: Instance> Read for I2c<'d, T> { | 720 | impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> { |
| 683 | type Error = Error; | 721 | type Error = Error; |
| 684 | 722 | ||
| 685 | fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { | 723 | fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { |
| 686 | self.read(address, buffer, false) | 724 | self.blocking_read(address, buffer) |
| 687 | // Automatic Stop | ||
| 688 | } | 725 | } |
| 689 | } | 726 | } |
| 690 | 727 | ||
| 691 | impl<'d, T: Instance> Write for I2c<'d, T> { | 728 | impl<'d, T: Instance> embedded_hal::blocking::i2c::Write for I2c<'d, T> { |
| 692 | type Error = Error; | 729 | type Error = Error; |
| 693 | 730 | ||
| 694 | fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { | 731 | fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { |
| 695 | self.write(address, bytes, true) | 732 | self.blocking_write(address, bytes) |
| 696 | } | 733 | } |
| 697 | } | 734 | } |
| 698 | 735 | ||
| 699 | impl<'d, T: Instance> WriteRead for I2c<'d, T> { | 736 | impl<'d, T: Instance> embedded_hal::blocking::i2c::WriteRead for I2c<'d, T> { |
| 700 | type Error = Error; | 737 | type Error = Error; |
| 701 | 738 | ||
| 702 | fn write_read( | 739 | fn write_read( |
| @@ -705,9 +742,7 @@ impl<'d, T: Instance> WriteRead for I2c<'d, T> { | |||
| 705 | bytes: &[u8], | 742 | bytes: &[u8], |
| 706 | buffer: &mut [u8], | 743 | buffer: &mut [u8], |
| 707 | ) -> Result<(), Self::Error> { | 744 | ) -> Result<(), Self::Error> { |
| 708 | self.write(address, bytes, false)?; | 745 | self.blocking_write_read(address, bytes, buffer) |
| 709 | self.read(address, buffer, true) | ||
| 710 | // Automatic Stop | ||
| 711 | } | 746 | } |
| 712 | } | 747 | } |
| 713 | 748 | ||
| @@ -715,7 +750,7 @@ impl<'d, T: Instance> WriteRead for I2c<'d, T> { | |||
| 715 | /// | 750 | /// |
| 716 | /// Peripheral options for generating the STOP condition | 751 | /// Peripheral options for generating the STOP condition |
| 717 | #[derive(Copy, Clone, PartialEq)] | 752 | #[derive(Copy, Clone, PartialEq)] |
| 718 | pub enum Stop { | 753 | enum Stop { |
| 719 | /// Software end mode: Must write register to generate STOP condition | 754 | /// Software end mode: Must write register to generate STOP condition |
| 720 | Software, | 755 | Software, |
| 721 | /// Automatic end mode: A STOP condition is automatically generated once the | 756 | /// Automatic end mode: A STOP condition is automatically generated once the |
| @@ -860,32 +895,23 @@ impl<'d, T: Instance, TXDMA: super::TxDma<T>, RXDMA: super::RxDma<T>> I2cTrait<u | |||
| 860 | 895 | ||
| 861 | type WriteFuture<'a> | 896 | type WriteFuture<'a> |
| 862 | where | 897 | where |
| 863 | 'd: 'a, | 898 | Self: 'a, |
| 864 | T: 'a, | ||
| 865 | TXDMA: 'a, | ||
| 866 | RXDMA: 'a, | ||
| 867 | = impl Future<Output = Result<(), Self::Error>> + 'a; | 899 | = impl Future<Output = Result<(), Self::Error>> + 'a; |
| 868 | type ReadFuture<'a> | 900 | type ReadFuture<'a> |
| 869 | where | 901 | where |
| 870 | 'd: 'a, | 902 | Self: 'a, |
| 871 | T: 'a, | ||
| 872 | TXDMA: 'a, | ||
| 873 | RXDMA: 'a, | ||
| 874 | = impl Future<Output = Result<(), Self::Error>> + 'a; | 903 | = impl Future<Output = Result<(), Self::Error>> + 'a; |
| 875 | type WriteReadFuture<'a> | 904 | type WriteReadFuture<'a> |
| 876 | where | 905 | where |
| 877 | 'd: 'a, | 906 | Self: 'a, |
| 878 | T: 'a, | ||
| 879 | TXDMA: 'a, | ||
| 880 | RXDMA: 'a, | ||
| 881 | = impl Future<Output = Result<(), Self::Error>> + 'a; | 907 | = impl Future<Output = Result<(), Self::Error>> + 'a; |
| 882 | 908 | ||
| 883 | fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { | 909 | fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { |
| 884 | self.read_dma(address, buffer, false) | 910 | self.read(address, buffer) |
| 885 | } | 911 | } |
| 886 | 912 | ||
| 887 | fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { | 913 | fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { |
| 888 | self.write_dma(address, bytes) | 914 | self.write(address, bytes) |
| 889 | } | 915 | } |
| 890 | 916 | ||
| 891 | fn write_read<'a>( | 917 | fn write_read<'a>( |
| @@ -894,9 +920,6 @@ impl<'d, T: Instance, TXDMA: super::TxDma<T>, RXDMA: super::RxDma<T>> I2cTrait<u | |||
| 894 | bytes: &'a [u8], | 920 | bytes: &'a [u8], |
| 895 | buffer: &'a mut [u8], | 921 | buffer: &'a mut [u8], |
| 896 | ) -> Self::WriteReadFuture<'a> { | 922 | ) -> Self::WriteReadFuture<'a> { |
| 897 | async move { | 923 | self.write_read(address, bytes, buffer) |
| 898 | self.write_dma(address, bytes).await?; | ||
| 899 | self.read_dma(address, buffer, true).await | ||
| 900 | } | ||
| 901 | } | 924 | } |
| 902 | } | 925 | } |
diff --git a/examples/stm32l4/src/bin/i2c.rs b/examples/stm32l4/src/bin/i2c.rs index 86215697b..615012a06 100644 --- a/examples/stm32l4/src/bin/i2c.rs +++ b/examples/stm32l4/src/bin/i2c.rs | |||
| @@ -11,7 +11,6 @@ use embassy_stm32::i2c::I2c; | |||
| 11 | use embassy_stm32::interrupt; | 11 | use embassy_stm32::interrupt; |
| 12 | use embassy_stm32::time::Hertz; | 12 | use embassy_stm32::time::Hertz; |
| 13 | use embassy_stm32::Peripherals; | 13 | use embassy_stm32::Peripherals; |
| 14 | use embedded_hal::blocking::i2c::WriteRead; | ||
| 15 | use example_common::{info, unwrap}; | 14 | use example_common::{info, unwrap}; |
| 16 | 15 | ||
| 17 | const ADDRESS: u8 = 0x5F; | 16 | const ADDRESS: u8 = 0x5F; |
| @@ -23,6 +22,6 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! { | |||
| 23 | let mut i2c = I2c::new(p.I2C2, p.PB10, p.PB11, irq, NoDma, NoDma, Hertz(100_000)); | 22 | let mut i2c = I2c::new(p.I2C2, p.PB10, p.PB11, irq, NoDma, NoDma, Hertz(100_000)); |
| 24 | 23 | ||
| 25 | let mut data = [0u8; 1]; | 24 | let mut data = [0u8; 1]; |
| 26 | unwrap!(i2c.write_read(ADDRESS, &[WHOAMI], &mut data)); | 25 | unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data)); |
| 27 | info!("Whoami: {}", data[0]); | 26 | info!("Whoami: {}", data[0]); |
| 28 | } | 27 | } |
diff --git a/examples/stm32l4/src/bin/i2c_dma.rs b/examples/stm32l4/src/bin/i2c_dma.rs index b0596aab8..d77bee8c1 100644 --- a/examples/stm32l4/src/bin/i2c_dma.rs +++ b/examples/stm32l4/src/bin/i2c_dma.rs | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | mod example_common; | 6 | mod example_common; |
| 7 | 7 | ||
| 8 | use embassy::executor::Spawner; | 8 | use embassy::executor::Spawner; |
| 9 | use embassy::traits::i2c::I2c as I2cTrait; | ||
| 10 | use embassy_stm32::i2c::I2c; | 9 | use embassy_stm32::i2c::I2c; |
| 11 | use embassy_stm32::interrupt; | 10 | use embassy_stm32::interrupt; |
| 12 | use embassy_stm32::time::Hertz; | 11 | use embassy_stm32::time::Hertz; |
