aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorUlf Lilleengen <[email protected]>2022-01-26 22:39:06 +0100
committerUlf Lilleengen <[email protected]>2022-01-26 22:39:06 +0100
commit4032fc06556312eab27488f05efe1803ade47b45 (patch)
tree0b38343758741e5c4074e86da30867595501f9b6 /embassy-stm32
parentcd36e3f7332d08865e670ca5b515d1c6efa1bf85 (diff)
Support unstable-trait feature for stm32
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/Cargo.toml9
-rw-r--r--embassy-stm32/src/adc/f1.rs2
-rw-r--r--embassy-stm32/src/adc/v3.rs2
-rw-r--r--embassy-stm32/src/exti.rs119
-rw-r--r--embassy-stm32/src/gpio.rs2
-rw-r--r--embassy-stm32/src/i2c/mod.rs1
-rw-r--r--embassy-stm32/src/i2c/v1.rs6
-rw-r--r--embassy-stm32/src/i2c/v2.rs144
-rw-r--r--embassy-stm32/src/spi/mod.rs206
-rw-r--r--embassy-stm32/src/usart/mod.rs142
10 files changed, 410 insertions, 223 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 6f9b2043f..e0fd1d963 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -9,14 +9,16 @@ resolver = "2"
9embassy = { version = "0.1.0", path = "../embassy" } 9embassy = { version = "0.1.0", path = "../embassy" }
10embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] } 10embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] }
11embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" } 11embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
12embassy-traits = {version = "0.1.0", path = "../embassy-traits" }
13embassy-net = { version = "0.1.0", path = "../embassy-net", default-features = false, optional = true } 12embassy-net = { version = "0.1.0", path = "../embassy-net", default-features = false, optional = true }
14 13
14embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" }
15embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true}
16embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true}
17
15defmt = { version = "0.3", optional = true } 18defmt = { version = "0.3", optional = true }
16log = { version = "0.4.14", optional = true } 19log = { version = "0.4.14", optional = true }
17cortex-m-rt = ">=0.6.15,<0.8" 20cortex-m-rt = ">=0.6.15,<0.8"
18cortex-m = "0.7.3" 21cortex-m = "0.7.3"
19embedded-hal = { version = "0.2.6", features = ["unproven"] }
20futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 22futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
21rand_core = "0.6.3" 23rand_core = "0.6.3"
22sdio-host = "0.5.0" 24sdio-host = "0.5.0"
@@ -56,6 +58,9 @@ time-driver-tim5 = ["_time-driver"]
56# There are no plans to make this stable. 58# There are no plans to make this stable.
57unstable-pac = [] 59unstable-pac = []
58 60
61# Implement embedded-hal 1.0 alpha and embedded-hal-async traits.
62unstable-traits = ["embedded-hal-1", "embedded-hal-async"]
63
59# BEGIN GENERATED FEATURES 64# BEGIN GENERATED FEATURES
60# Generated by stm32-gen-features. DO NOT EDIT. 65# Generated by stm32-gen-features. DO NOT EDIT.
61stm32f030c6 = [ "stm32-metapac/stm32f030c6" ] 66stm32f030c6 = [ "stm32-metapac/stm32f030c6" ]
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index 3ed1701fa..6031883ec 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -4,7 +4,7 @@ use crate::time::Hertz;
4use core::marker::PhantomData; 4use core::marker::PhantomData;
5use embassy::util::Unborrow; 5use embassy::util::Unborrow;
6use embassy_hal_common::unborrow; 6use embassy_hal_common::unborrow;
7use embedded_hal::blocking::delay::DelayUs; 7use embedded_hal_02::blocking::delay::DelayUs;
8 8
9pub const VDDA_CALIB_MV: u32 = 3300; 9pub const VDDA_CALIB_MV: u32 = 3300;
10pub const ADC_MAX: u32 = (1 << 12) - 1; 10pub const ADC_MAX: u32 = (1 << 12) - 1;
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index ddf06deae..6f36daa23 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -2,7 +2,7 @@ use crate::adc::{AdcPin, Instance};
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3use embassy::util::Unborrow; 3use embassy::util::Unborrow;
4use embassy_hal_common::unborrow; 4use embassy_hal_common::unborrow;
5use embedded_hal::blocking::delay::DelayUs; 5use embedded_hal_02::blocking::delay::DelayUs;
6 6
7pub const VDDA_CALIB_MV: u32 = 3000; 7pub const VDDA_CALIB_MV: u32 = 3000;
8 8
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index af401796c..7d974c2dc 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -1,15 +1,10 @@
1use core::convert::Infallible;
2use core::future::Future; 1use core::future::Future;
3use core::marker::PhantomData; 2use core::marker::PhantomData;
4use core::pin::Pin; 3use core::pin::Pin;
5use core::task::{Context, Poll}; 4use core::task::{Context, Poll};
6use embassy::traits::gpio::{
7 WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge,
8};
9use embassy::util::Unborrow; 5use embassy::util::Unborrow;
10use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
11use embassy_hal_common::unsafe_impl_unborrow; 7use embassy_hal_common::unsafe_impl_unborrow;
12use embedded_hal::digital::v2::InputPin;
13 8
14use crate::gpio::{AnyPin, Input, Pin as GpioPin}; 9use crate::gpio::{AnyPin, Input, Pin as GpioPin};
15use crate::interrupt; 10use crate::interrupt;
@@ -134,70 +129,88 @@ impl<'d, T: GpioPin> ExtiInput<'d, T> {
134 } 129 }
135} 130}
136 131
137impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> { 132mod eh02 {
138 type Error = Infallible; 133 use super::*;
134 use core::convert::Infallible;
139 135
140 fn is_high(&self) -> Result<bool, Self::Error> { 136 impl<'d, T: GpioPin> embedded_hal_02::digital::v2::InputPin for ExtiInput<'d, T> {
141 Ok(self.is_high()) 137 type Error = Infallible;
142 } 138
139 fn is_high(&self) -> Result<bool, Self::Error> {
140 Ok(self.is_high())
141 }
143 142
144 fn is_low(&self) -> Result<bool, Self::Error> { 143 fn is_low(&self) -> Result<bool, Self::Error> {
145 Ok(self.is_low()) 144 Ok(self.is_low())
145 }
146 } 146 }
147} 147}
148 148
149impl<'d, T: GpioPin> WaitForHigh for ExtiInput<'d, T> { 149#[cfg(feature = "unstable-traits")]
150 type Future<'a> 150mod eh1 {
151 where 151 use super::*;
152 Self: 'a, 152 use core::convert::Infallible;
153 = impl Future<Output = ()> + 'a; 153 use futures::FutureExt;
154 154
155 fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> { 155 impl<'d, T: GpioPin> embedded_hal_1::digital::ErrorType for ExtiInput<'d, T> {
156 self.wait_for_high() 156 type Error = Infallible;
157 } 157 }
158}
159 158
160impl<'d, T: GpioPin> WaitForLow for ExtiInput<'d, T> { 159 impl<'d, T: GpioPin> embedded_hal_1::digital::blocking::InputPin for ExtiInput<'d, T> {
161 type Future<'a> 160 fn is_high(&self) -> Result<bool, Self::Error> {
162 where 161 Ok(self.is_high())
163 Self: 'a, 162 }
164 = impl Future<Output = ()> + 'a;
165 163
166 fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> { 164 fn is_low(&self) -> Result<bool, Self::Error> {
167 self.wait_for_low() 165 Ok(self.is_low())
166 }
168 } 167 }
169}
170 168
171impl<'d, T: GpioPin> WaitForRisingEdge for ExtiInput<'d, T> { 169 impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for ExtiInput<'d, T> {
172 type Future<'a> 170 type WaitForHighFuture<'a>
173 where 171 where
174 Self: 'a, 172 Self: 'a,
175 = impl Future<Output = ()> + 'a; 173 = impl Future<Output = Result<(), Self::Error>> + 'a;
176 174
177 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> { 175 fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
178 self.wait_for_rising_edge() 176 self.wait_for_high().map(Ok)
179 } 177 }
180}
181 178
182impl<'d, T: GpioPin> WaitForFallingEdge for ExtiInput<'d, T> { 179 type WaitForLowFuture<'a>
183 type Future<'a> 180 where
184 where 181 Self: 'a,
185 Self: 'a, 182 = impl Future<Output = Result<(), Self::Error>> + 'a;
186 = impl Future<Output = ()> + 'a;
187 183
188 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> { 184 fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
189 self.wait_for_falling_edge() 185 self.wait_for_low().map(Ok)
190 } 186 }
191} 187
188 type WaitForRisingEdgeFuture<'a>
189 where
190 Self: 'a,
191 = impl Future<Output = Result<(), Self::Error>> + 'a;
192
193 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
194 self.wait_for_rising_edge().map(Ok)
195 }
196
197 type WaitForFallingEdgeFuture<'a>
198 where
199 Self: 'a,
200 = impl Future<Output = Result<(), Self::Error>> + 'a;
192 201
193impl<'d, T: GpioPin> WaitForAnyEdge for ExtiInput<'d, T> { 202 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
194 type Future<'a> 203 self.wait_for_falling_edge().map(Ok)
195 where 204 }
196 Self: 'a,
197 = impl Future<Output = ()> + 'a;
198 205
199 fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> { 206 type WaitForAnyEdgeFuture<'a>
200 self.wait_for_any_edge() 207 where
208 Self: 'a,
209 = impl Future<Output = Result<(), Self::Error>> + 'a;
210
211 fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
212 self.wait_for_any_edge().map(Ok)
213 }
201 } 214 }
202} 215}
203 216
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index 57b9ba6b7..d4606716c 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -3,7 +3,7 @@ use core::convert::Infallible;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use embassy::util::Unborrow; 4use embassy::util::Unborrow;
5use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; 5use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
6use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin}; 6use embedded_hal_02::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
7 7
8use crate::pac; 8use crate::pac;
9use crate::pac::gpio::{self, vals}; 9use crate::pac::gpio::{self, vals};
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 8eee13825..2dcb9b720 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -8,6 +8,7 @@ mod _version;
8use crate::{dma, peripherals}; 8use crate::{dma, peripherals};
9pub use _version::*; 9pub use _version::*;
10 10
11#[derive(Debug)]
11#[cfg_attr(feature = "defmt", derive(defmt::Format))] 12#[cfg_attr(feature = "defmt", derive(defmt::Format))]
12pub enum Error { 13pub enum Error {
13 Bus, 14 Bus,
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 6b2c8a35c..aa5268987 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -270,7 +270,7 @@ impl<'d, T: Instance> I2c<'d, T> {
270 } 270 }
271} 271}
272 272
273impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> { 273impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> {
274 type Error = Error; 274 type Error = Error;
275 275
276 fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { 276 fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
@@ -278,7 +278,7 @@ impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> {
278 } 278 }
279} 279}
280 280
281impl<'d, T: Instance> embedded_hal::blocking::i2c::Write for I2c<'d, T> { 281impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> {
282 type Error = Error; 282 type Error = Error;
283 283
284 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { 284 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
@@ -286,7 +286,7 @@ impl<'d, T: Instance> embedded_hal::blocking::i2c::Write for I2c<'d, T> {
286 } 286 }
287} 287}
288 288
289impl<'d, T: Instance> embedded_hal::blocking::i2c::WriteRead for I2c<'d, T> { 289impl<'d, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T> {
290 type Error = Error; 290 type Error = Error;
291 291
292 fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> { 292 fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 5b0e5fce2..9c05187a5 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -1,11 +1,9 @@
1use core::cmp; 1use core::cmp;
2use core::future::Future;
3use core::marker::PhantomData; 2use core::marker::PhantomData;
4use core::task::Poll; 3use core::task::Poll;
5 4
6use atomic_polyfill::{AtomicUsize, Ordering}; 5use atomic_polyfill::{AtomicUsize, Ordering};
7use embassy::interrupt::InterruptExt; 6use embassy::interrupt::InterruptExt;
8use embassy::traits::i2c::I2c as I2cTrait;
9use embassy::util::Unborrow; 7use embassy::util::Unborrow;
10use embassy::waitqueue::AtomicWaker; 8use embassy::waitqueue::AtomicWaker;
11use embassy_hal_common::drop::OnDrop; 9use embassy_hal_common::drop::OnDrop;
@@ -735,32 +733,36 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
735 } 733 }
736} 734}
737 735
738impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> { 736mod eh02 {
739 type Error = Error; 737 use super::*;
740 738
741 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { 739 impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> {
742 self.blocking_read(address, buffer) 740 type Error = Error;
741
742 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
743 self.blocking_read(address, buffer)
744 }
743 } 745 }
744}
745 746
746impl<'d, T: Instance> embedded_hal::blocking::i2c::Write for I2c<'d, T> { 747 impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> {
747 type Error = Error; 748 type Error = Error;
748 749
749 fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { 750 fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
750 self.blocking_write(address, bytes) 751 self.blocking_write(address, bytes)
752 }
751 } 753 }
752}
753 754
754impl<'d, T: Instance> embedded_hal::blocking::i2c::WriteRead for I2c<'d, T> { 755 impl<'d, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T> {
755 type Error = Error; 756 type Error = Error;
756 757
757 fn write_read( 758 fn write_read(
758 &mut self, 759 &mut self,
759 address: u8, 760 address: u8,
760 bytes: &[u8], 761 bytes: &[u8],
761 buffer: &mut [u8], 762 buffer: &mut [u8],
762 ) -> Result<(), Self::Error> { 763 ) -> Result<(), Self::Error> {
763 self.blocking_write_read(address, bytes, buffer) 764 self.blocking_write_read(address, bytes, buffer)
765 }
764 } 766 }
765} 767}
766 768
@@ -906,38 +908,80 @@ impl Timings {
906 } 908 }
907} 909}
908 910
909impl<'d, T: Instance, TXDMA: super::TxDma<T>, RXDMA: super::RxDma<T>> I2cTrait<u8> 911#[cfg(feature = "unstable-traits")]
910 for I2c<'d, T, TXDMA, RXDMA> 912mod eh1 {
911{ 913 use super::super::{RxDma, TxDma};
912 type Error = super::Error; 914 use super::*;
913 915 use core::future::Future;
914 type WriteFuture<'a> 916
915 where 917 impl embedded_hal_1::i2c::Error for Error {
916 Self: 'a, 918 fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
917 = impl Future<Output = Result<(), Self::Error>> + 'a; 919 match *self {
918 type ReadFuture<'a> 920 Self::Bus => embedded_hal_1::i2c::ErrorKind::Bus,
919 where 921 Self::Arbitration => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss,
920 Self: 'a, 922 Self::Nack => embedded_hal_1::i2c::ErrorKind::NoAcknowledge(
921 = impl Future<Output = Result<(), Self::Error>> + 'a; 923 embedded_hal_1::i2c::NoAcknowledgeSource::Unknown,
922 type WriteReadFuture<'a> 924 ),
923 where 925 Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other,
924 Self: 'a, 926 Self::Crc => embedded_hal_1::i2c::ErrorKind::Other,
925 = impl Future<Output = Result<(), Self::Error>> + 'a; 927 Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun,
926 928 Self::ZeroLengthTransfer => embedded_hal_1::i2c::ErrorKind::Other,
927 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 929 }
928 self.read(address, buffer) 930 }
929 } 931 }
930 932
931 fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { 933 impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_1::i2c::ErrorType
932 self.write(address, bytes) 934 for I2c<'d, T, TXDMA, RXDMA>
935 {
936 type Error = Error;
933 } 937 }
934 938
935 fn write_read<'a>( 939 impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_async::i2c::I2c
936 &'a mut self, 940 for I2c<'d, T, TXDMA, RXDMA>
937 address: u8, 941 {
938 bytes: &'a [u8], 942 type ReadFuture<'a>
939 buffer: &'a mut [u8], 943 where
940 ) -> Self::WriteReadFuture<'a> { 944 Self: 'a,
941 self.write_read(address, bytes, buffer) 945 = impl Future<Output = Result<(), Self::Error>> + 'a;
946
947 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
948 self.read(address, buffer)
949 }
950
951 type WriteFuture<'a>
952 where
953 Self: 'a,
954 = impl Future<Output = Result<(), Self::Error>> + 'a;
955 fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
956 self.write(address, bytes)
957 }
958
959 type WriteReadFuture<'a>
960 where
961 Self: 'a,
962 = impl Future<Output = Result<(), Self::Error>> + 'a;
963 fn write_read<'a>(
964 &'a mut self,
965 address: u8,
966 bytes: &'a [u8],
967 buffer: &'a mut [u8],
968 ) -> Self::WriteReadFuture<'a> {
969 self.write_read(address, bytes, buffer)
970 }
971
972 type TransactionFuture<'a>
973 where
974 Self: 'a,
975 = impl Future<Output = Result<(), Self::Error>> + 'a;
976
977 fn transaction<'a>(
978 &'a mut self,
979 address: u8,
980 operations: &mut [embedded_hal_async::i2c::Operation<'a>],
981 ) -> Self::TransactionFuture<'a> {
982 let _ = address;
983 let _ = operations;
984 async move { todo!() }
985 }
942 } 986 }
943} 987}
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index f1ea8592d..4cf45f6f9 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -1,11 +1,9 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::future::Future;
4use core::marker::PhantomData; 3use core::marker::PhantomData;
5use core::ptr; 4use core::ptr;
6use embassy::util::Unborrow; 5use embassy::util::Unborrow;
7use embassy_hal_common::unborrow; 6use embassy_hal_common::unborrow;
8use embassy_traits::spi as traits;
9 7
10use self::sealed::WordSize; 8use self::sealed::WordSize;
11use crate::dma; 9use crate::dma;
@@ -17,7 +15,7 @@ use crate::peripherals;
17use crate::rcc::RccPeripheral; 15use crate::rcc::RccPeripheral;
18use crate::time::Hertz; 16use crate::time::Hertz;
19 17
20pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 18pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
21 19
22#[cfg_attr(spi_v1, path = "v1.rs")] 20#[cfg_attr(spi_v1, path = "v1.rs")]
23#[cfg_attr(spi_f1, path = "v1.rs")] 21#[cfg_attr(spi_f1, path = "v1.rs")]
@@ -549,76 +547,168 @@ fn transfer_word<W: Word>(regs: Regs, tx_word: W) -> Result<W, Error> {
549 return Ok(rx_word); 547 return Ok(rx_word);
550} 548}
551 549
552// Note: It is not possible to impl these traits generically in embedded-hal 0.2 due to a conflict with 550mod eh02 {
553// some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289 551 use super::*;
554macro_rules! impl_blocking {
555 ($w:ident) => {
556 impl<'d, T: Instance> embedded_hal::blocking::spi::Write<$w> for Spi<'d, T, NoDma, NoDma> {
557 type Error = Error;
558 552
559 fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> { 553 // Note: It is not possible to impl these traits generically in embedded-hal 0.2 due to a conflict with
560 self.blocking_write(words) 554 // some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289
555 macro_rules! impl_blocking {
556 ($w:ident) => {
557 impl<'d, T: Instance> embedded_hal_02::blocking::spi::Write<$w>
558 for Spi<'d, T, NoDma, NoDma>
559 {
560 type Error = Error;
561
562 fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> {
563 self.blocking_write(words)
564 }
561 } 565 }
562 }
563 566
564 impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<$w> 567 impl<'d, T: Instance> embedded_hal_02::blocking::spi::Transfer<$w>
565 for Spi<'d, T, NoDma, NoDma> 568 for Spi<'d, T, NoDma, NoDma>
566 { 569 {
567 type Error = Error; 570 type Error = Error;
568 571
569 fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> { 572 fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> {
570 self.blocking_transfer_in_place(words)?; 573 self.blocking_transfer_in_place(words)?;
571 Ok(words) 574 Ok(words)
575 }
572 } 576 }
573 } 577 };
574 }; 578 }
579
580 impl_blocking!(u8);
581 impl_blocking!(u16);
575} 582}
576 583
577impl_blocking!(u8); 584#[cfg(feature = "unstable-traits")]
578impl_blocking!(u16); 585mod eh1 {
586 use super::*;
587 use core::future::Future;
579 588
580impl<'d, T: Instance, Tx, Rx> traits::Spi<u8> for Spi<'d, T, Tx, Rx> { 589 impl<'d, T: Instance, Tx, Rx> embedded_hal_1::spi::ErrorType for Spi<'d, T, Tx, Rx> {
581 type Error = Error; 590 type Error = Error;
582} 591 }
583 592
584impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> traits::Write<u8> for Spi<'d, T, Tx, Rx> { 593 impl embedded_hal_1::spi::Error for Error {
585 type WriteFuture<'a> 594 fn kind(&self) -> embedded_hal_1::spi::ErrorKind {
586 where 595 match *self {
587 Self: 'a, 596 Self::Framing => embedded_hal_1::spi::ErrorKind::FrameFormat,
588 = impl Future<Output = Result<(), Self::Error>> + 'a; 597 Self::Crc => embedded_hal_1::spi::ErrorKind::Other,
598 Self::ModeFault => embedded_hal_1::spi::ErrorKind::ModeFault,
599 Self::Overrun => embedded_hal_1::spi::ErrorKind::Overrun,
600 }
601 }
602 }
603
604 impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> embedded_hal_async::spi::Write<u8>
605 for Spi<'d, T, Tx, Rx>
606 {
607 type WriteFuture<'a>
608 where
609 Self: 'a,
610 = impl Future<Output = Result<(), Self::Error>> + 'a;
589 611
590 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { 612 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
591 self.write(data) 613 self.write(data)
614 }
615
616 type WriteTransactionFuture<'a>
617 where
618 Self: 'a,
619 = impl Future<Output = Result<(), Self::Error>> + 'a;
620
621 fn write_transaction<'a>(
622 &'a mut self,
623 words: &'a [&'a [u8]],
624 ) -> Self::WriteTransactionFuture<'a> {
625 async move {
626 for buf in words {
627 self.write(buf).await?
628 }
629 Ok(())
630 }
631 }
592 } 632 }
593}
594 633
595impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::Read<u8> 634 impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>>
596 for Spi<'d, T, Tx, Rx> 635 embedded_hal_async::spi::Read<u8> for Spi<'d, T, Tx, Rx>
597{ 636 {
598 type ReadFuture<'a> 637 type ReadFuture<'a>
599 where 638 where
600 Self: 'a, 639 Self: 'a,
601 = impl Future<Output = Result<(), Self::Error>> + 'a; 640 = impl Future<Output = Result<(), Self::Error>> + 'a;
602 641
603 fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { 642 fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
604 self.read(data) 643 self.read(data)
644 }
645
646 type ReadTransactionFuture<'a>
647 where
648 Self: 'a,
649 = impl Future<Output = Result<(), Self::Error>> + 'a;
650
651 fn read_transaction<'a>(
652 &'a mut self,
653 words: &'a mut [&'a mut [u8]],
654 ) -> Self::ReadTransactionFuture<'a> {
655 async move {
656 for buf in words {
657 self.read(buf).await?
658 }
659 Ok(())
660 }
661 }
605 } 662 }
606}
607 663
608impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::FullDuplex<u8> 664 impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>>
609 for Spi<'d, T, Tx, Rx> 665 embedded_hal_async::spi::ReadWrite<u8> for Spi<'d, T, Tx, Rx>
610{ 666 {
611 type WriteReadFuture<'a> 667 type TransferFuture<'a>
612 where 668 where
613 Self: 'a, 669 Self: 'a,
614 = impl Future<Output = Result<(), Self::Error>> + 'a; 670 = impl Future<Output = Result<(), Self::Error>> + 'a;
615 671
616 fn read_write<'a>( 672 fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> {
617 &'a mut self, 673 self.transfer(rx, tx)
618 read: &'a mut [u8], 674 }
619 write: &'a [u8], 675
620 ) -> Self::WriteReadFuture<'a> { 676 type TransferInPlaceFuture<'a>
621 self.transfer(read, write) 677 where
678 Self: 'a,
679 = impl Future<Output = Result<(), Self::Error>> + 'a;
680
681 fn transfer_in_place<'a>(
682 &'a mut self,
683 words: &'a mut [u8],
684 ) -> Self::TransferInPlaceFuture<'a> {
685 // TODO: Implement async version
686 let result = self.blocking_transfer_in_place(words);
687 async move { result }
688 }
689
690 type TransactionFuture<'a>
691 where
692 Self: 'a,
693 = impl Future<Output = Result<(), Self::Error>> + 'a;
694
695 fn transaction<'a>(
696 &'a mut self,
697 operations: &'a mut [embedded_hal_async::spi::Operation<'a, u8>],
698 ) -> Self::TransactionFuture<'a> {
699 use embedded_hal_1::spi::blocking::Operation;
700 async move {
701 for o in operations {
702 match o {
703 Operation::Read(b) => self.read(b).await?,
704 Operation::Write(b) => self.write(b).await?,
705 Operation::Transfer(r, w) => self.transfer(r, w).await?,
706 Operation::TransferInPlace(b) => self.transfer_in_place(b).await?,
707 }
708 }
709 Ok(())
710 }
711 }
622 } 712 }
623} 713}
624 714
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 5309c6296..a391379c8 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -1,11 +1,9 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::future::Future;
4use core::marker::PhantomData; 3use core::marker::PhantomData;
5use embassy::interrupt::Interrupt; 4use embassy::interrupt::Interrupt;
6use embassy::util::Unborrow; 5use embassy::util::Unborrow;
7use embassy_hal_common::unborrow; 6use embassy_hal_common::unborrow;
8use futures::TryFutureExt;
9 7
10use crate::dma::NoDma; 8use crate::dma::NoDma;
11use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull}; 9use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull};
@@ -211,72 +209,108 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
211 } 209 }
212} 210}
213 211
214impl<'d, T: Instance, TxDma, RxDma> embedded_hal::serial::Read<u8> for Uart<'d, T, TxDma, RxDma> { 212mod eh02 {
215 type Error = Error; 213 use super::*;
216 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { 214
217 let r = self.inner.regs(); 215 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_02::serial::Read<u8>
218 unsafe { 216 for Uart<'d, T, TxDma, RxDma>
219 let sr = sr(r).read(); 217 {
220 if sr.pe() { 218 type Error = Error;
221 rdr(r).read_volatile(); 219 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
222 Err(nb::Error::Other(Error::Parity)) 220 let r = self.inner.regs();
223 } else if sr.fe() { 221 unsafe {
224 rdr(r).read_volatile(); 222 let sr = sr(r).read();
225 Err(nb::Error::Other(Error::Framing)) 223 if sr.pe() {
226 } else if sr.ne() { 224 rdr(r).read_volatile();
227 rdr(r).read_volatile(); 225 Err(nb::Error::Other(Error::Parity))
228 Err(nb::Error::Other(Error::Noise)) 226 } else if sr.fe() {
229 } else if sr.ore() { 227 rdr(r).read_volatile();
230 rdr(r).read_volatile(); 228 Err(nb::Error::Other(Error::Framing))
231 Err(nb::Error::Other(Error::Overrun)) 229 } else if sr.ne() {
232 } else if sr.rxne() { 230 rdr(r).read_volatile();
233 Ok(rdr(r).read_volatile()) 231 Err(nb::Error::Other(Error::Noise))
234 } else { 232 } else if sr.ore() {
235 Err(nb::Error::WouldBlock) 233 rdr(r).read_volatile();
234 Err(nb::Error::Other(Error::Overrun))
235 } else if sr.rxne() {
236 Ok(rdr(r).read_volatile())
237 } else {
238 Err(nb::Error::WouldBlock)
239 }
236 } 240 }
237 } 241 }
238 } 242 }
243
244 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_02::blocking::serial::Write<u8>
245 for Uart<'d, T, TxDma, RxDma>
246 {
247 type Error = Error;
248 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
249 self.blocking_write(buffer)
250 }
251 fn bflush(&mut self) -> Result<(), Self::Error> {
252 self.blocking_flush()
253 }
254 }
239} 255}
240 256
241impl<'d, T: Instance, TxDma, RxDma> embedded_hal::blocking::serial::Write<u8> 257#[cfg(feature = "unstable-traits")]
242 for Uart<'d, T, TxDma, RxDma> 258mod eh1 {
243{ 259 use super::*;
244 type Error = Error; 260 use core::future::Future;
245 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { 261
246 self.blocking_write(buffer) 262 impl embedded_hal_1::serial::Error for Error {
263 fn kind(&self) -> embedded_hal_1::serial::ErrorKind {
264 match *self {
265 Self::Framing => embedded_hal_1::serial::ErrorKind::FrameFormat,
266 Self::Noise => embedded_hal_1::serial::ErrorKind::Noise,
267 Self::Overrun => embedded_hal_1::serial::ErrorKind::Overrun,
268 Self::Parity => embedded_hal_1::serial::ErrorKind::Parity,
269 }
270 }
247 } 271 }
248 fn bflush(&mut self) -> Result<(), Self::Error> { 272
249 self.blocking_flush() 273 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_1::serial::ErrorType
274 for Uart<'d, T, TxDma, RxDma>
275 {
276 type Error = Error;
250 } 277 }
251}
252 278
253impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Write for Uart<'d, T, TxDma, RxDma> 279 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma>
254where
255 TxDma: crate::usart::TxDma<T>,
256{
257 type WriteFuture<'a>
258 where 280 where
259 Self: 'a, 281 TxDma: crate::usart::TxDma<T>,
260 = impl Future<Output = Result<(), embassy_traits::uart::Error>> + 'a; 282 {
283 type WriteFuture<'a>
284 where
285 Self: 'a,
286 = impl Future<Output = Result<(), Self::Error>> + 'a;
261 287
262 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { 288 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
263 self.write(buf) 289 self.write(buf)
264 .map_err(|_| embassy_traits::uart::Error::Other) 290 }
291
292 type FlushFuture<'a>
293 where
294 Self: 'a,
295 = impl Future<Output = Result<(), Self::Error>> + 'a;
296
297 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
298 async move { Ok(()) }
299 }
265 } 300 }
266}
267 301
268impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Read for Uart<'d, T, TxDma, RxDma> 302 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma>
269where
270 RxDma: crate::usart::RxDma<T>,
271{
272 type ReadFuture<'a>
273 where 303 where
274 Self: 'a, 304 RxDma: crate::usart::RxDma<T>,
275 = impl Future<Output = Result<(), embassy_traits::uart::Error>> + 'a; 305 {
306 type ReadFuture<'a>
307 where
308 Self: 'a,
309 = impl Future<Output = Result<(), Self::Error>> + 'a;
276 310
277 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { 311 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
278 self.read(buf) 312 self.read(buf)
279 .map_err(|_| embassy_traits::uart::Error::Other) 313 }
280 } 314 }
281} 315}
282 316