aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-01-14 23:31:10 +0100
committerDario Nieuwenhuis <[email protected]>2022-01-19 17:59:55 +0100
commit97ab859f0025ee6ffad19733dc24f17b6621fff8 (patch)
treeddd6828cd1c65fa89fb0c07bcd138cbd7f20e048
parentc949519714268afaf9b26d0ff4a7bc3c207b27d2 (diff)
stm32/i2c: expose all functionality as inherent methods.
-rw-r--r--embassy-stm32/src/i2c/v1.rs50
-rw-r--r--embassy-stm32/src/i2c/v2.rs103
-rw-r--r--examples/stm32l4/src/bin/i2c.rs3
-rw-r--r--examples/stm32l4/src/bin/i2c_dma.rs1
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;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use embassy::util::Unborrow; 4use embassy::util::Unborrow;
5use embassy_hal_common::unborrow; 5use embassy_hal_common::unborrow;
6use embedded_hal::blocking::i2c::Read;
7use embedded_hal::blocking::i2c::Write;
8use embedded_hal::blocking::i2c::WriteRead;
9 6
10use crate::pac::i2c; 7use 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
184impl<'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
253impl<'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
272impl<'d, T: Instance> WriteRead for I2c<'d, T> { 273impl<'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(()) 281impl<'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
289impl<'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;
10use embassy::waitqueue::AtomicWaker; 10use embassy::waitqueue::AtomicWaker;
11use embassy_hal_common::drop::OnDrop; 11use embassy_hal_common::drop::OnDrop;
12use embassy_hal_common::unborrow; 12use embassy_hal_common::unborrow;
13use embedded_hal::blocking::i2c::Read;
14use embedded_hal::blocking::i2c::Write;
15use embedded_hal::blocking::i2c::WriteRead;
16use futures::future::poll_fn; 13use futures::future::poll_fn;
17 14
18use crate::dma::NoDma; 15use 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
682impl<'d, T: Instance> Read for I2c<'d, T> { 720impl<'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
691impl<'d, T: Instance> Write for I2c<'d, T> { 728impl<'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
699impl<'d, T: Instance> WriteRead for I2c<'d, T> { 736impl<'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)]
718pub enum Stop { 753enum 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;
11use embassy_stm32::interrupt; 11use embassy_stm32::interrupt;
12use embassy_stm32::time::Hertz; 12use embassy_stm32::time::Hertz;
13use embassy_stm32::Peripherals; 13use embassy_stm32::Peripherals;
14use embedded_hal::blocking::i2c::WriteRead;
15use example_common::{info, unwrap}; 14use example_common::{info, unwrap};
16 15
17const ADDRESS: u8 = 0x5F; 16const 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 @@
6mod example_common; 6mod example_common;
7 7
8use embassy::executor::Spawner; 8use embassy::executor::Spawner;
9use embassy::traits::i2c::I2c as I2cTrait;
10use embassy_stm32::i2c::I2c; 9use embassy_stm32::i2c::I2c;
11use embassy_stm32::interrupt; 10use embassy_stm32::interrupt;
12use embassy_stm32::time::Hertz; 11use embassy_stm32::time::Hertz;