aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-08-01 08:20:48 +0000
committerGitHub <[email protected]>2023-08-01 08:20:48 +0000
commit0d8a9b1e7a963fe1a1a3cf0e10c33314bba65e2d (patch)
treecc2eaa14fa266f03e930c3397dd7ccaeff657af9
parentef3b1f46a99bd44f4702459adcc42a176a36b2f8 (diff)
parent036bc669cd46012e37e09af070ddb8353454719a (diff)
Merge pull request #1729 from mattico/i2c-async-timeout
stm32: add async timeout functions to I2c and TimeoutI2c
-rw-r--r--embassy-stm32/src/i2c/timeout.rs98
-rw-r--r--embassy-stm32/src/i2c/v2.rs70
2 files changed, 153 insertions, 15 deletions
diff --git a/embassy-stm32/src/i2c/timeout.rs b/embassy-stm32/src/i2c/timeout.rs
index 8dc228b34..103017cd1 100644
--- a/embassy-stm32/src/i2c/timeout.rs
+++ b/embassy-stm32/src/i2c/timeout.rs
@@ -22,11 +22,93 @@ fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> {
22 } 22 }
23} 23}
24 24
25impl<'a, 'd, T: Instance, TXDMA, RXDMA> TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { 25impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
26 pub fn new(i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>, timeout: Duration) -> Self { 26 pub fn new(i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>, timeout: Duration) -> Self {
27 Self { i2c, timeout } 27 Self { i2c, timeout }
28 } 28 }
29 29
30 // =========================
31 // Async public API
32
33 #[cfg(i2c_v2)]
34 pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error>
35 where
36 TXDMA: crate::i2c::TxDma<T>,
37 {
38 self.write_timeout(address, write, self.timeout).await
39 }
40
41 #[cfg(i2c_v2)]
42 pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error>
43 where
44 TXDMA: crate::i2c::TxDma<T>,
45 {
46 self.i2c.write_timeout(address, write, timeout_fn(timeout)).await
47 }
48
49 #[cfg(i2c_v2)]
50 pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error>
51 where
52 TXDMA: crate::i2c::TxDma<T>,
53 {
54 self.write_vectored_timeout(address, write, self.timeout).await
55 }
56
57 #[cfg(i2c_v2)]
58 pub async fn write_vectored_timeout(&mut self, address: u8, write: &[&[u8]], timeout: Duration) -> Result<(), Error>
59 where
60 TXDMA: crate::i2c::TxDma<T>,
61 {
62 self.i2c
63 .write_vectored_timeout(address, write, timeout_fn(timeout))
64 .await
65 }
66
67 #[cfg(i2c_v2)]
68 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error>
69 where
70 RXDMA: crate::i2c::RxDma<T>,
71 {
72 self.read_timeout(address, buffer, self.timeout).await
73 }
74
75 #[cfg(i2c_v2)]
76 pub async fn read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error>
77 where
78 RXDMA: crate::i2c::RxDma<T>,
79 {
80 self.i2c.read_timeout(address, buffer, timeout_fn(timeout)).await
81 }
82
83 #[cfg(i2c_v2)]
84 pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error>
85 where
86 TXDMA: super::TxDma<T>,
87 RXDMA: super::RxDma<T>,
88 {
89 self.write_read_timeout(address, write, read, self.timeout).await
90 }
91
92 #[cfg(i2c_v2)]
93 pub async fn write_read_timeout(
94 &mut self,
95 address: u8,
96 write: &[u8],
97 read: &mut [u8],
98 timeout: Duration,
99 ) -> Result<(), Error>
100 where
101 TXDMA: super::TxDma<T>,
102 RXDMA: super::RxDma<T>,
103 {
104 self.i2c
105 .write_read_timeout(address, write, read, timeout_fn(timeout))
106 .await
107 }
108
109 // =========================
110 // Blocking public API
111
30 /// Blocking read with a custom timeout 112 /// Blocking read with a custom timeout
31 pub fn blocking_read_timeout(&mut self, addr: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> { 113 pub fn blocking_read_timeout(&mut self, addr: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> {
32 self.i2c.blocking_read_timeout(addr, read, timeout_fn(timeout)) 114 self.i2c.blocking_read_timeout(addr, read, timeout_fn(timeout))
@@ -65,7 +147,9 @@ impl<'a, 'd, T: Instance, TXDMA, RXDMA> TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
65 } 147 }
66} 148}
67 149
68impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { 150impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read
151 for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
152{
69 type Error = Error; 153 type Error = Error;
70 154
71 fn read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Self::Error> { 155 fn read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Self::Error> {
@@ -73,7 +157,9 @@ impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read for
73 } 157 }
74} 158}
75 159
76impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { 160impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write
161 for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
162{
77 type Error = Error; 163 type Error = Error;
78 164
79 fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> { 165 fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> {
@@ -81,7 +167,7 @@ impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write fo
81 } 167 }
82} 168}
83 169
84impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRead 170impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRead
85 for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> 171 for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
86{ 172{
87 type Error = Error; 173 type Error = Error;
@@ -95,11 +181,11 @@ impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRea
95mod eh1 { 181mod eh1 {
96 use super::*; 182 use super::*;
97 183
98 impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { 184 impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
99 type Error = Error; 185 type Error = Error;
100 } 186 }
101 187
102 impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::I2c for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { 188 impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::I2c for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
103 fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { 189 fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
104 self.blocking_read(address, read) 190 self.blocking_read(address, read)
105 } 191 }
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index eaf980a4d..4327899bb 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -598,10 +598,22 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
598 where 598 where
599 TXDMA: crate::i2c::TxDma<T>, 599 TXDMA: crate::i2c::TxDma<T>,
600 { 600 {
601 self.write_timeout(address, write, || Ok(())).await
602 }
603
604 pub async fn write_timeout(
605 &mut self,
606 address: u8,
607 write: &[u8],
608 check_timeout: impl Fn() -> Result<(), Error>,
609 ) -> Result<(), Error>
610 where
611 TXDMA: crate::i2c::TxDma<T>,
612 {
601 if write.is_empty() { 613 if write.is_empty() {
602 self.write_internal(address, write, true, || Ok(())) 614 self.write_internal(address, write, true, check_timeout)
603 } else { 615 } else {
604 self.write_dma_internal(address, write, true, true, || Ok(())).await 616 self.write_dma_internal(address, write, true, true, check_timeout).await
605 } 617 }
606 } 618 }
607 619
@@ -609,6 +621,18 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
609 where 621 where
610 TXDMA: crate::i2c::TxDma<T>, 622 TXDMA: crate::i2c::TxDma<T>,
611 { 623 {
624 self.write_vectored_timeout(address, write, || Ok(())).await
625 }
626
627 pub async fn write_vectored_timeout(
628 &mut self,
629 address: u8,
630 write: &[&[u8]],
631 check_timeout: impl Fn() -> Result<(), Error>,
632 ) -> Result<(), Error>
633 where
634 TXDMA: crate::i2c::TxDma<T>,
635 {
612 if write.is_empty() { 636 if write.is_empty() {
613 return Err(Error::ZeroLengthTransfer); 637 return Err(Error::ZeroLengthTransfer);
614 } 638 }
@@ -620,7 +644,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
620 let next = iter.next(); 644 let next = iter.next();
621 let is_last = next.is_none(); 645 let is_last = next.is_none();
622 646
623 self.write_dma_internal(address, c, first, is_last, || Ok(())).await?; 647 self.write_dma_internal(address, c, first, is_last, || check_timeout())
648 .await?;
624 first = false; 649 first = false;
625 current = next; 650 current = next;
626 } 651 }
@@ -631,10 +656,22 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
631 where 656 where
632 RXDMA: crate::i2c::RxDma<T>, 657 RXDMA: crate::i2c::RxDma<T>,
633 { 658 {
659 self.read_timeout(address, buffer, || Ok(())).await
660 }
661
662 pub async fn read_timeout(
663 &mut self,
664 address: u8,
665 buffer: &mut [u8],
666 check_timeout: impl Fn() -> Result<(), Error>,
667 ) -> Result<(), Error>
668 where
669 RXDMA: crate::i2c::RxDma<T>,
670 {
634 if buffer.is_empty() { 671 if buffer.is_empty() {
635 self.read_internal(address, buffer, false, || Ok(())) 672 self.read_internal(address, buffer, false, check_timeout)
636 } else { 673 } else {
637 self.read_dma_internal(address, buffer, false, || Ok(())).await 674 self.read_dma_internal(address, buffer, false, check_timeout).await
638 } 675 }
639 } 676 }
640 677
@@ -643,16 +680,31 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
643 TXDMA: super::TxDma<T>, 680 TXDMA: super::TxDma<T>,
644 RXDMA: super::RxDma<T>, 681 RXDMA: super::RxDma<T>,
645 { 682 {
683 self.write_read_timeout(address, write, read, || Ok(())).await
684 }
685
686 pub async fn write_read_timeout(
687 &mut self,
688 address: u8,
689 write: &[u8],
690 read: &mut [u8],
691 check_timeout: impl Fn() -> Result<(), Error>,
692 ) -> Result<(), Error>
693 where
694 TXDMA: super::TxDma<T>,
695 RXDMA: super::RxDma<T>,
696 {
646 if write.is_empty() { 697 if write.is_empty() {
647 self.write_internal(address, write, false, || Ok(()))?; 698 self.write_internal(address, write, false, || check_timeout())?;
648 } else { 699 } else {
649 self.write_dma_internal(address, write, true, true, || Ok(())).await?; 700 self.write_dma_internal(address, write, true, true, || check_timeout())
701 .await?;
650 } 702 }
651 703
652 if read.is_empty() { 704 if read.is_empty() {
653 self.read_internal(address, read, true, || Ok(()))?; 705 self.read_internal(address, read, true, check_timeout)?;
654 } else { 706 } else {
655 self.read_dma_internal(address, read, true, || Ok(())).await?; 707 self.read_dma_internal(address, read, true, check_timeout).await?;
656 } 708 }
657 709
658 Ok(()) 710 Ok(())