aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xci.sh13
-rw-r--r--embassy-lora/Cargo.toml2
-rw-r--r--embassy-lora/src/sx127x/mod.rs24
-rw-r--r--embassy-lora/src/sx127x/sx127x_lora/mod.rs9
-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
-rw-r--r--embassy-traits/Cargo.toml4
-rw-r--r--embassy-traits/src/adapter.rs200
-rw-r--r--embassy-traits/src/gpio.rs57
-rw-r--r--embassy-traits/src/i2c.rs192
-rw-r--r--embassy-traits/src/lib.rs4
-rw-r--r--embassy-traits/src/spi.rs61
-rw-r--r--embassy-traits/src/uart.rs36
-rw-r--r--examples/stm32f3/src/bin/spi_dma.rs3
-rw-r--r--examples/stm32h7/Cargo.toml3
-rw-r--r--examples/stm32h7/src/bin/camera.rs2
-rw-r--r--examples/stm32h7/src/bin/spi_dma.rs5
-rw-r--r--examples/stm32l0/Cargo.toml2
-rw-r--r--examples/stm32l4/Cargo.toml3
-rw-r--r--examples/stm32l4/src/bin/i2c_blocking_async.rs3
-rw-r--r--examples/stm32l4/src/bin/spi_blocking_async.rs9
-rw-r--r--examples/stm32l4/src/bin/spi_dma.rs3
-rw-r--r--examples/stm32l4/src/bin/usart_blocking_async.rs6
-rw-r--r--tests/stm32/Cargo.toml1
-rw-r--r--tests/stm32/src/bin/spi_dma.rs3
33 files changed, 611 insertions, 667 deletions
diff --git a/ci.sh b/ci.sh
index 4b8e77379..452130be2 100755
--- a/ci.sh
+++ b/ci.sh
@@ -43,18 +43,31 @@ cargo batch \
43 --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,log,gpiote,time-driver-rtc1 \ 43 --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,log,gpiote,time-driver-rtc1 \
44 --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,defmt,gpiote,time-driver-rtc1,unstable-traits \ 44 --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,defmt,gpiote,time-driver-rtc1,unstable-traits \
45 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any \ 45 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any \
46 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,unstable-traits \
46 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any \ 47 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any \
48 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,unstable-traits \
47 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any \ 49 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any \
50 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,unstable-traits \
48 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any \ 51 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any \
52 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,unstable-traits \
49 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any \ 53 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any \
54 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,unstable-traits \
50 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any \ 55 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any \
56 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,unstable-traits \
51 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any \ 57 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any \
58 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,unstable-traits \
52 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,exti,time-driver-any \ 59 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,exti,time-driver-any \
60 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,exti,time-driver-any,unstable-traits \
53 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any \ 61 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any \
62 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,unstable-traits \
54 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any \ 63 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any \
64 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \
55 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any \ 65 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any \
66 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,unstable-traits \
56 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any \ 67 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any \
68 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,unstable-traits \
57 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any \ 69 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any \
70 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits \
58 --- build --release --manifest-path docs/modules/ROOT/examples/basic/Cargo.toml --target thumbv7em-none-eabi \ 71 --- build --release --manifest-path docs/modules/ROOT/examples/basic/Cargo.toml --target thumbv7em-none-eabi \
59 --- build --release --manifest-path examples/std/Cargo.toml --target x86_64-unknown-linux-gnu --out-dir out/examples/std \ 72 --- build --release --manifest-path examples/std/Cargo.toml --target x86_64-unknown-linux-gnu --out-dir out/examples/std \
60 --- build --release --manifest-path examples/nrf/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf \ 73 --- build --release --manifest-path examples/nrf/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf \
diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml
index 9f04adabb..c27641521 100644
--- a/embassy-lora/Cargo.toml
+++ b/embassy-lora/Cargo.toml
@@ -18,6 +18,8 @@ log = { version = "0.4.14", optional = true }
18 18
19embassy = { version = "0.1.0", path = "../embassy", default-features = false } 19embassy = { version = "0.1.0", path = "../embassy", default-features = false }
20embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } 20embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
21embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true}
22embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"}
21embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false } 23embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false }
22futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } 24futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
23embedded-hal = { version = "0.2", features = ["unproven"] } 25embedded-hal = { version = "0.2", features = ["unproven"] }
diff --git a/embassy-lora/src/sx127x/mod.rs b/embassy-lora/src/sx127x/mod.rs
index c26628b0f..6a15dab82 100644
--- a/embassy-lora/src/sx127x/mod.rs
+++ b/embassy-lora/src/sx127x/mod.rs
@@ -1,7 +1,7 @@
1use core::future::Future; 1use core::future::Future;
2use embassy::traits::gpio::WaitForRisingEdge;
3use embassy::traits::spi::*;
4use embedded_hal::digital::v2::OutputPin; 2use embedded_hal::digital::v2::OutputPin;
3use embedded_hal_async::digital::Wait;
4use embedded_hal_async::spi::*;
5use lorawan_device::async_device::{ 5use lorawan_device::async_device::{
6 radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig}, 6 radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig},
7 Timings, 7 Timings,
@@ -20,11 +20,11 @@ pub trait RadioSwitch {
20/// Semtech Sx127x radio peripheral 20/// Semtech Sx127x radio peripheral
21pub struct Sx127xRadio<SPI, CS, RESET, E, I, RFS> 21pub struct Sx127xRadio<SPI, CS, RESET, E, I, RFS>
22where 22where
23 SPI: FullDuplex<u8, Error = E> + 'static, 23 SPI: ReadWrite<u8, Error = E> + 'static,
24 E: 'static, 24 E: 'static,
25 CS: OutputPin + 'static, 25 CS: OutputPin + 'static,
26 RESET: OutputPin + 'static, 26 RESET: OutputPin + 'static,
27 I: WaitForRisingEdge + 'static, 27 I: Wait + 'static,
28 RFS: RadioSwitch + 'static, 28 RFS: RadioSwitch + 'static,
29{ 29{
30 radio: LoRa<SPI, CS, RESET>, 30 radio: LoRa<SPI, CS, RESET>,
@@ -42,10 +42,10 @@ pub enum State {
42 42
43impl<SPI, CS, RESET, E, I, RFS> Sx127xRadio<SPI, CS, RESET, E, I, RFS> 43impl<SPI, CS, RESET, E, I, RFS> Sx127xRadio<SPI, CS, RESET, E, I, RFS>
44where 44where
45 SPI: FullDuplex<u8, Error = E> + 'static, 45 SPI: ReadWrite<u8, Error = E> + 'static,
46 CS: OutputPin + 'static, 46 CS: OutputPin + 'static,
47 RESET: OutputPin + 'static, 47 RESET: OutputPin + 'static,
48 I: WaitForRisingEdge + 'static, 48 I: Wait + 'static,
49 RFS: RadioSwitch + 'static, 49 RFS: RadioSwitch + 'static,
50 E: 'static, 50 E: 'static,
51{ 51{
@@ -64,10 +64,10 @@ where
64 64
65impl<SPI, CS, RESET, E, I, RFS> Timings for Sx127xRadio<SPI, CS, RESET, E, I, RFS> 65impl<SPI, CS, RESET, E, I, RFS> Timings for Sx127xRadio<SPI, CS, RESET, E, I, RFS>
66where 66where
67 SPI: FullDuplex<u8, Error = E> + 'static, 67 SPI: ReadWrite<u8, Error = E> + 'static,
68 CS: OutputPin + 'static, 68 CS: OutputPin + 'static,
69 RESET: OutputPin + 'static, 69 RESET: OutputPin + 'static,
70 I: WaitForRisingEdge + 'static, 70 I: Wait + 'static,
71 RFS: RadioSwitch + 'static, 71 RFS: RadioSwitch + 'static,
72{ 72{
73 fn get_rx_window_offset_ms(&self) -> i32 { 73 fn get_rx_window_offset_ms(&self) -> i32 {
@@ -80,11 +80,11 @@ where
80 80
81impl<SPI, CS, RESET, E, I, RFS> PhyRxTx for Sx127xRadio<SPI, CS, RESET, E, I, RFS> 81impl<SPI, CS, RESET, E, I, RFS> PhyRxTx for Sx127xRadio<SPI, CS, RESET, E, I, RFS>
82where 82where
83 SPI: FullDuplex<u8, Error = E> + 'static, 83 SPI: ReadWrite<u8, Error = E> + 'static,
84 CS: OutputPin + 'static, 84 CS: OutputPin + 'static,
85 E: 'static, 85 E: 'static,
86 RESET: OutputPin + 'static, 86 RESET: OutputPin + 'static,
87 I: WaitForRisingEdge + 'static, 87 I: Wait + 'static,
88 RFS: RadioSwitch + 'static, 88 RFS: RadioSwitch + 'static,
89{ 89{
90 type PhyError = Sx127xError; 90 type PhyError = Sx127xError;
@@ -126,7 +126,7 @@ where
126 self.radio.transmit_start(buf).await?; 126 self.radio.transmit_start(buf).await?;
127 127
128 loop { 128 loop {
129 self.irq.wait_for_rising_edge().await; 129 self.irq.wait_for_rising_edge().await.unwrap();
130 self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap(); 130 self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
131 let irq = self.radio.clear_irq().await.ok().unwrap(); 131 let irq = self.radio.clear_irq().await.ok().unwrap();
132 if (irq & IRQ::IrqTxDoneMask.addr()) != 0 { 132 if (irq & IRQ::IrqTxDoneMask.addr()) != 0 {
@@ -171,7 +171,7 @@ where
171 self.radio.set_mode(RadioMode::RxContinuous).await?; 171 self.radio.set_mode(RadioMode::RxContinuous).await?;
172 172
173 loop { 173 loop {
174 self.irq.wait_for_rising_edge().await; 174 self.irq.wait_for_rising_edge().await.unwrap();
175 self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap(); 175 self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
176 let irq = self.radio.clear_irq().await.ok().unwrap(); 176 let irq = self.radio.clear_irq().await.ok().unwrap();
177 if (irq & IRQ::IrqRxDoneMask.addr()) != 0 { 177 if (irq & IRQ::IrqRxDoneMask.addr()) != 0 {
diff --git a/embassy-lora/src/sx127x/sx127x_lora/mod.rs b/embassy-lora/src/sx127x/sx127x_lora/mod.rs
index a903779ca..6fbd3a4bd 100644
--- a/embassy-lora/src/sx127x/sx127x_lora/mod.rs
+++ b/embassy-lora/src/sx127x/sx127x_lora/mod.rs
@@ -7,8 +7,8 @@
7 7
8use bit_field::BitField; 8use bit_field::BitField;
9use embassy::time::{Duration, Timer}; 9use embassy::time::{Duration, Timer};
10use embassy::traits::spi::*;
11use embedded_hal::digital::v2::OutputPin; 10use embedded_hal::digital::v2::OutputPin;
11use embedded_hal_async::spi::ReadWrite;
12 12
13mod register; 13mod register;
14use self::register::PaConfig; 14use self::register::PaConfig;
@@ -36,9 +36,10 @@ pub enum Error<SPI, CS, RESET> {
36 Transmitting, 36 Transmitting,
37} 37}
38 38
39use super::sx127x_lora::register::{FskDataModulationShaping, FskRampUpRamDown};
40use Error::*; 39use Error::*;
41 40
41use super::sx127x_lora::register::{FskDataModulationShaping, FskRampUpRamDown};
42
42#[cfg(not(feature = "version_0x09"))] 43#[cfg(not(feature = "version_0x09"))]
43const VERSION_CHECK: u8 = 0x12; 44const VERSION_CHECK: u8 = 0x12;
44 45
@@ -47,7 +48,7 @@ const VERSION_CHECK: u8 = 0x09;
47 48
48impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET> 49impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET>
49where 50where
50 SPI: FullDuplex<u8, Error = E>, 51 SPI: ReadWrite<u8, Error = E>,
51 CS: OutputPin, 52 CS: OutputPin,
52 RESET: OutputPin, 53 RESET: OutputPin,
53{ 54{
@@ -546,7 +547,7 @@ where
546 547
547 let _ = self 548 let _ = self
548 .spi 549 .spi
549 .read_write(&mut buffer, &[reg & 0x7f, 0]) 550 .transfer(&mut buffer, &[reg & 0x7f, 0])
550 .await 551 .await
551 .map_err(SPI)?; 552 .map_err(SPI)?;
552 553
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
diff --git a/embassy-traits/Cargo.toml b/embassy-traits/Cargo.toml
index a93cb3c54..4d0d21916 100644
--- a/embassy-traits/Cargo.toml
+++ b/embassy-traits/Cargo.toml
@@ -9,5 +9,7 @@ std = []
9 9
10[dependencies] 10[dependencies]
11defmt = { version = "0.3", optional = true } 11defmt = { version = "0.3", optional = true }
12embedded-hal = { version = "0.2.6", features = ["unproven"] } 12embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
13embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy" }
14embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"}
13nb = "1.0.0" 15nb = "1.0.0"
diff --git a/embassy-traits/src/adapter.rs b/embassy-traits/src/adapter.rs
index ce7dd411f..415b5e814 100644
--- a/embassy-traits/src/adapter.rs
+++ b/embassy-traits/src/adapter.rs
@@ -1,6 +1,6 @@
1use core::future::Future; 1use core::future::Future;
2use embedded_hal::blocking; 2use embedded_hal_02::blocking;
3use embedded_hal::serial; 3use embedded_hal_02::serial;
4 4
5/// BlockingAsync is a wrapper that implements async traits using blocking peripherals. This allows 5/// BlockingAsync is a wrapper that implements async traits using blocking peripherals. This allows
6/// driver writers to depend on the async traits while still supporting embedded-hal peripheral implementations. 6/// driver writers to depend on the async traits while still supporting embedded-hal peripheral implementations.
@@ -20,24 +20,37 @@ impl<T> BlockingAsync<T> {
20} 20}
21 21
22// 22//
23// I2C implementatinos 23// I2C implementations
24// 24//
25 25impl<T, E> embedded_hal_1::i2c::ErrorType for BlockingAsync<T>
26impl<T, E> crate::i2c::I2c for BlockingAsync<T>
27where 26where
28 E: 'static, 27 E: embedded_hal_1::i2c::Error + 'static,
29 T: blocking::i2c::WriteRead<Error = E> 28 T: blocking::i2c::WriteRead<Error = E>
30 + blocking::i2c::Read<Error = E> 29 + blocking::i2c::Read<Error = E>
31 + blocking::i2c::Write<Error = E>, 30 + blocking::i2c::Write<Error = E>,
32{ 31{
33 type Error = E; 32 type Error = E;
33}
34 34
35 #[rustfmt::skip] 35impl<T, E> embedded_hal_async::i2c::I2c for BlockingAsync<T>
36 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; 36where
37 #[rustfmt::skip] 37 E: embedded_hal_1::i2c::Error + 'static,
38 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; 38 T: blocking::i2c::WriteRead<Error = E>
39 #[rustfmt::skip] 39 + blocking::i2c::Read<Error = E>
40 type WriteReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; 40 + blocking::i2c::Write<Error = E>,
41{
42 type WriteFuture<'a>
43 where
44 Self: 'a,
45 = impl Future<Output = Result<(), Self::Error>> + 'a;
46 type ReadFuture<'a>
47 where
48 Self: 'a,
49 = impl Future<Output = Result<(), Self::Error>> + 'a;
50 type WriteReadFuture<'a>
51 where
52 Self: 'a,
53 = impl Future<Output = Result<(), Self::Error>> + 'a;
41 54
42 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 55 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
43 async move { self.wrapped.read(address, buffer) } 56 async move { self.wrapped.read(address, buffer) }
@@ -55,33 +68,46 @@ where
55 ) -> Self::WriteReadFuture<'a> { 68 ) -> Self::WriteReadFuture<'a> {
56 async move { self.wrapped.write_read(address, bytes, buffer) } 69 async move { self.wrapped.write_read(address, bytes, buffer) }
57 } 70 }
71
72 type TransactionFuture<'a>
73 where
74 Self: 'a,
75 = impl Future<Output = Result<(), Self::Error>> + 'a;
76
77 fn transaction<'a>(
78 &'a mut self,
79 address: u8,
80 operations: &mut [embedded_hal_async::i2c::Operation<'a>],
81 ) -> Self::TransactionFuture<'a> {
82 let _ = address;
83 let _ = operations;
84 async move { todo!() }
85 }
58} 86}
59 87
60// 88//
61// SPI implementatinos 89// SPI implementatinos
62// 90//
63 91
64impl<T, E, Word> crate::spi::Spi<Word> for BlockingAsync<T> 92impl<T, E> embedded_hal_async::spi::ErrorType for BlockingAsync<T>
65where 93where
66 T: blocking::spi::Write<Word, Error = E>, 94 E: embedded_hal_1::spi::Error,
95 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
67{ 96{
68 type Error = E; 97 type Error = E;
69} 98}
70 99
71impl<T, E, Word> crate::spi::FullDuplex<Word> for BlockingAsync<T> 100impl<T, E> embedded_hal_async::spi::ReadWrite<u8> for BlockingAsync<T>
72where 101where
73 E: 'static, 102 E: embedded_hal_1::spi::Error + 'static,
74 Word: Clone, 103 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
75 T: blocking::spi::Transfer<Word, Error = E> + blocking::spi::Write<Word, Error = E>,
76{ 104{
77 #[rustfmt::skip] 105 type TransferFuture<'a>
78 type WriteReadFuture<'a> where Word: 'a, Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; 106 where
107 Self: 'a,
108 = impl Future<Output = Result<(), Self::Error>> + 'a;
79 109
80 fn read_write<'a>( 110 fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Self::TransferFuture<'a> {
81 &'a mut self,
82 read: &'a mut [Word],
83 write: &'a [Word],
84 ) -> Self::WriteReadFuture<'a> {
85 async move { 111 async move {
86 // Ensure we write the expected bytes 112 // Ensure we write the expected bytes
87 for i in 0..core::cmp::min(read.len(), write.len()) { 113 for i in 0..core::cmp::min(read.len(), write.len()) {
@@ -91,53 +117,111 @@ where
91 Ok(()) 117 Ok(())
92 } 118 }
93 } 119 }
120
121 type TransferInPlaceFuture<'a>
122 where
123 Self: 'a,
124 = impl Future<Output = Result<(), Self::Error>> + 'a;
125
126 fn transfer_in_place<'a>(&'a mut self, _: &'a mut [u8]) -> Self::TransferInPlaceFuture<'a> {
127 async move { todo!() }
128 }
129
130 type TransactionFuture<'a>
131 where
132 Self: 'a,
133 = impl Future<Output = Result<(), Self::Error>> + 'a;
134
135 fn transaction<'a>(
136 &'a mut self,
137 _: &'a mut [embedded_hal_async::spi::Operation<'a, u8>],
138 ) -> Self::TransactionFuture<'a> {
139 async move { todo!() }
140 }
94} 141}
95 142
96impl<T, E, Word> crate::spi::Write<Word> for BlockingAsync<T> 143impl<T, E> embedded_hal_async::spi::Write<u8> for BlockingAsync<T>
97where 144where
98 E: 'static, 145 E: embedded_hal_1::spi::Error + 'static,
99 Word: Clone, 146 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
100 T: blocking::spi::Write<Word, Error = E>,
101{ 147{
102 #[rustfmt::skip] 148 type WriteFuture<'a>
103 type WriteFuture<'a> where Word: 'a, Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; 149 where
150 Self: 'a,
151 = impl Future<Output = Result<(), Self::Error>> + 'a;
152
153 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
154 async move {
155 self.wrapped.write(data)?;
156 Ok(())
157 }
158 }
159
160 type WriteTransactionFuture<'a>
161 where
162 Self: 'a,
163 = impl Future<Output = Result<(), Self::Error>> + 'a;
104 164
105 fn write<'a>(&'a mut self, data: &'a [Word]) -> Self::WriteFuture<'a> { 165 fn write_transaction<'a>(&'a mut self, _: &'a [&'a [u8]]) -> Self::WriteTransactionFuture<'a> {
106 async move { self.wrapped.write(data) } 166 async move { todo!() }
107 } 167 }
108} 168}
109 169
110impl<T, E, Word> crate::spi::Read<Word> for BlockingAsync<T> 170impl<T, E> embedded_hal_async::spi::Read<u8> for BlockingAsync<T>
111where 171where
112 E: 'static, 172 E: embedded_hal_1::spi::Error + 'static,
113 Word: Clone, 173 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
114 T: blocking::spi::Transfer<Word, Error = E> + blocking::spi::Write<Word, Error = E>,
115{ 174{
116 #[rustfmt::skip] 175 type ReadFuture<'a>
117 type ReadFuture<'a> where Word: 'a, Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a; 176 where
177 Self: 'a,
178 = impl Future<Output = Result<(), Self::Error>> + 'a;
118 179
119 fn read<'a>(&'a mut self, data: &'a mut [Word]) -> Self::ReadFuture<'a> { 180 fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
120 async move { 181 async move {
121 self.wrapped.transfer(data)?; 182 self.wrapped.transfer(data)?;
122 Ok(()) 183 Ok(())
123 } 184 }
124 } 185 }
186
187 type ReadTransactionFuture<'a>
188 where
189 Self: 'a,
190 = impl Future<Output = Result<(), Self::Error>> + 'a;
191
192 fn read_transaction<'a>(
193 &'a mut self,
194 _: &'a mut [&'a mut [u8]],
195 ) -> Self::ReadTransactionFuture<'a> {
196 async move { todo!() }
197 }
125} 198}
126 199
127// Uart implementatinos 200// Uart implementatinos
128impl<T> crate::uart::Read for BlockingAsync<T> 201impl<T, E> embedded_hal_1::serial::ErrorType for BlockingAsync<T>
202where
203 T: serial::Read<u8, Error = E>,
204 E: embedded_hal_1::serial::Error + 'static,
205{
206 type Error = E;
207}
208
209impl<T, E> embedded_hal_async::serial::Read for BlockingAsync<T>
129where 210where
130 T: serial::Read<u8>, 211 T: serial::Read<u8, Error = E>,
212 E: embedded_hal_1::serial::Error + 'static,
131{ 213{
132 #[rustfmt::skip] 214 type ReadFuture<'a>
133 type ReadFuture<'a> where T: 'a = impl Future<Output = Result<(), crate::uart::Error>> + 'a; 215 where
216 T: 'a,
217 = impl Future<Output = Result<(), Self::Error>> + 'a;
134 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { 218 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
135 async move { 219 async move {
136 let mut pos = 0; 220 let mut pos = 0;
137 while pos < buf.len() { 221 while pos < buf.len() {
138 match self.wrapped.read() { 222 match self.wrapped.read() {
139 Err(nb::Error::WouldBlock) => {} 223 Err(nb::Error::WouldBlock) => {}
140 Err(_) => return Err(crate::uart::Error::Other), 224 Err(nb::Error::Other(e)) => return Err(e),
141 Ok(b) => { 225 Ok(b) => {
142 buf[pos] = b; 226 buf[pos] = b;
143 pos += 1; 227 pos += 1;
@@ -149,18 +233,24 @@ where
149 } 233 }
150} 234}
151 235
152impl<T> crate::uart::Write for BlockingAsync<T> 236impl<T, E> embedded_hal_async::serial::Write for BlockingAsync<T>
153where 237where
154 T: blocking::serial::Write<u8>, 238 T: blocking::serial::Write<u8, Error = E> + serial::Read<u8, Error = E>,
239 E: embedded_hal_1::serial::Error + 'static,
155{ 240{
156 #[rustfmt::skip] 241 type WriteFuture<'a>
157 type WriteFuture<'a> where T: 'a = impl Future<Output = Result<(), crate::uart::Error>> + 'a; 242 where
243 T: 'a,
244 = impl Future<Output = Result<(), Self::Error>> + 'a;
158 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { 245 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
159 async move { 246 async move { self.wrapped.bwrite_all(buf) }
160 self.wrapped 247 }
161 .bwrite_all(buf) 248
162 .map_err(|_| crate::uart::Error::Other)?; 249 type FlushFuture<'a>
163 self.wrapped.bflush().map_err(|_| crate::uart::Error::Other) 250 where
164 } 251 T: 'a,
252 = impl Future<Output = Result<(), Self::Error>> + 'a;
253 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
254 async move { self.wrapped.bflush() }
165 } 255 }
166} 256}
diff --git a/embassy-traits/src/gpio.rs b/embassy-traits/src/gpio.rs
deleted file mode 100644
index 3752c8d60..000000000
--- a/embassy-traits/src/gpio.rs
+++ /dev/null
@@ -1,57 +0,0 @@
1use core::future::Future;
2
3/// Wait for a pin to become high.
4pub trait WaitForHigh {
5 type Future<'a>: Future<Output = ()> + 'a
6 where
7 Self: 'a;
8
9 /// Wait for a pin to become high.
10 ///
11 /// If the pin is already high, the future completes immediately.
12 /// Otherwise, it completes when it becomes high.
13 fn wait_for_high(&mut self) -> Self::Future<'_>;
14}
15
16/// Wait for a pin to become low.
17pub trait WaitForLow {
18 type Future<'a>: Future<Output = ()> + 'a
19 where
20 Self: 'a;
21
22 /// Wait for a pin to become low.
23 ///
24 /// If the pin is already low, the future completes immediately.
25 /// Otherwise, it completes when it becomes low.
26 fn wait_for_low(&mut self) -> Self::Future<'_>;
27}
28
29/// Wait for a rising edge (transition from low to high)
30pub trait WaitForRisingEdge {
31 type Future<'a>: Future<Output = ()> + 'a
32 where
33 Self: 'a;
34
35 /// Wait for a rising edge (transition from low to high)
36 fn wait_for_rising_edge(&mut self) -> Self::Future<'_>;
37}
38
39/// Wait for a falling edge (transition from high to low)
40pub trait WaitForFallingEdge {
41 type Future<'a>: Future<Output = ()> + 'a
42 where
43 Self: 'a;
44
45 /// Wait for a falling edge (transition from high to low)
46 fn wait_for_falling_edge(&'_ mut self) -> Self::Future<'_>;
47}
48
49/// Wait for any edge (any transition, high to low or low to high)
50pub trait WaitForAnyEdge {
51 type Future<'a>: Future<Output = ()> + 'a
52 where
53 Self: 'a;
54
55 /// Wait for any edge (any transition, high to low or low to high)
56 fn wait_for_any_edge(&mut self) -> Self::Future<'_>;
57}
diff --git a/embassy-traits/src/i2c.rs b/embassy-traits/src/i2c.rs
deleted file mode 100644
index 4e2e8e2f0..000000000
--- a/embassy-traits/src/i2c.rs
+++ /dev/null
@@ -1,192 +0,0 @@
1//! Async I2C API
2//!
3//! This API supports 7-bit and 10-bit addresses. Traits feature an `AddressMode`
4//! marker type parameter. Two implementation of the `AddressMode` exist:
5//! `SevenBitAddress` and `TenBitAddress`.
6//!
7//! Through this marker types it is possible to implement each address mode for
8//! the traits independently in `embedded-hal` implementations and device drivers
9//! can depend only on the mode that they support.
10//!
11//! Additionally, the I2C 10-bit address mode has been developed to be fully
12//! backwards compatible with the 7-bit address mode. This allows for a
13//! software-emulated 10-bit addressing implementation if the address mode
14//! is not supported by the hardware.
15//!
16//! Since 7-bit addressing is the mode of the majority of I2C devices,
17//! `SevenBitAddress` has been set as default mode and thus can be omitted if desired.
18//!
19//! ### Device driver compatible only with 7-bit addresses
20//!
21//! For demonstration purposes the address mode parameter has been omitted in this example.
22//!
23//! ```
24//! # use embassy_traits::i2c::I2c;
25//! const ADDR: u8 = 0x15;
26//! # const TEMP_REGISTER: u8 = 0x1;
27//! pub struct TemperatureSensorDriver<I2C> {
28//! i2c: I2C,
29//! }
30//!
31//! impl<I2C, E> TemperatureSensorDriver<I2C>
32//! where
33//! I2C: I2c<Error = E>,
34//! {
35//! pub fn read_temperature(&mut self) -> Result<u8, E> {
36//! let mut temp = [0];
37//! self.i2c
38//! .write_read(ADDR, &[TEMP_REGISTER], &mut temp)
39//! .await
40//! .and(Ok(temp[0]))
41//! }
42//! }
43//! ```
44//!
45//! ### Device driver compatible only with 10-bit addresses
46//!
47//! ```
48//! # use embassy_traits::i2c::{TenBitAddress, I2c};
49//! const ADDR: u16 = 0x158;
50//! # const TEMP_REGISTER: u8 = 0x1;
51//! pub struct TemperatureSensorDriver<I2C> {
52//! i2c: I2C,
53//! }
54//!
55//! impl<I2C, E> TemperatureSensorDriver<I2C>
56//! where
57//! I2C: I2c<TenBitAddress, Error = E>,
58//! {
59//! pub fn read_temperature(&mut self) -> Result<u8, E> {
60//! let mut temp = [0];
61//! self.i2c
62//! .write_read(ADDR, &[TEMP_REGISTER], &mut temp)
63//! .await
64//! .and(Ok(temp[0]))
65//! }
66//! }
67//! ```
68
69use core::future::Future;
70
71mod private {
72 pub trait Sealed {}
73}
74
75/// Address mode (7-bit / 10-bit)
76///
77/// Note: This trait is sealed and should not be implemented outside of this crate.
78pub trait AddressMode: private::Sealed {}
79
80/// 7-bit address mode type
81pub type SevenBitAddress = u8;
82
83/// 10-bit address mode type
84pub type TenBitAddress = u16;
85
86impl private::Sealed for SevenBitAddress {}
87impl private::Sealed for TenBitAddress {}
88
89impl AddressMode for SevenBitAddress {}
90
91impl AddressMode for TenBitAddress {}
92
93pub trait I2c<A: AddressMode = SevenBitAddress> {
94 /// Error type
95 type Error;
96
97 type WriteFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
98 where
99 Self: 'a;
100 type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
101 where
102 Self: 'a;
103 type WriteReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
104 where
105 Self: 'a;
106
107 /// Reads enough bytes from slave with `address` to fill `buffer`
108 ///
109 /// # I2C Events (contract)
110 ///
111 /// ``` text
112 /// Master: ST SAD+R MAK MAK ... NMAK SP
113 /// Slave: SAK B0 B1 ... BN
114 /// ```
115 ///
116 /// Where
117 ///
118 /// - `ST` = start condition
119 /// - `SAD+R` = slave address followed by bit 1 to indicate reading
120 /// - `SAK` = slave acknowledge
121 /// - `Bi` = ith byte of data
122 /// - `MAK` = master acknowledge
123 /// - `NMAK` = master no acknowledge
124 /// - `SP` = stop condition
125 fn read<'a>(&'a mut self, address: A, buffer: &'a mut [u8]) -> Self::ReadFuture<'a>;
126
127 /// Sends bytes to slave with address `address`
128 ///
129 /// # I2C Events (contract)
130 ///
131 /// ``` text
132 /// Master: ST SAD+W B0 B1 ... BN SP
133 /// Slave: SAK SAK SAK ... SAK
134 /// ```
135 ///
136 /// Where
137 ///
138 /// - `ST` = start condition
139 /// - `SAD+W` = slave address followed by bit 0 to indicate writing
140 /// - `SAK` = slave acknowledge
141 /// - `Bi` = ith byte of data
142 /// - `SP` = stop condition
143 fn write<'a>(&'a mut self, address: A, bytes: &'a [u8]) -> Self::WriteFuture<'a>;
144
145 /// Sends bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
146 /// single transaction*
147 ///
148 /// # I2C Events (contract)
149 ///
150 /// ``` text
151 /// Master: ST SAD+W O0 O1 ... OM SR SAD+R MAK MAK ... NMAK SP
152 /// Slave: SAK SAK SAK ... SAK SAK I0 I1 ... IN
153 /// ```
154 ///
155 /// Where
156 ///
157 /// - `ST` = start condition
158 /// - `SAD+W` = slave address followed by bit 0 to indicate writing
159 /// - `SAK` = slave acknowledge
160 /// - `Oi` = ith outgoing byte of data
161 /// - `SR` = repeated start condition
162 /// - `SAD+R` = slave address followed by bit 1 to indicate reading
163 /// - `Ii` = ith incoming byte of data
164 /// - `MAK` = master acknowledge
165 /// - `NMAK` = master no acknowledge
166 /// - `SP` = stop condition
167 fn write_read<'a>(
168 &'a mut self,
169 address: A,
170 bytes: &'a [u8],
171 buffer: &'a mut [u8],
172 ) -> Self::WriteReadFuture<'a>;
173}
174
175pub trait WriteIter<A: AddressMode = SevenBitAddress> {
176 /// Error type
177 type Error;
178
179 type WriteIterFuture<'a, V>: Future<Output = Result<(), Self::Error>> + 'a
180 where
181 V: 'a + IntoIterator<Item = u8>,
182 Self: 'a;
183
184 /// Sends bytes to slave with address `address`
185 ///
186 /// # I2C Events (contract)
187 ///
188 /// Same as `I2c::write`
189 fn write_iter<'a, U>(&'a mut self, address: A, bytes: U) -> Self::WriteIterFuture<'a, U>
190 where
191 U: IntoIterator<Item = u8> + 'a;
192}
diff --git a/embassy-traits/src/lib.rs b/embassy-traits/src/lib.rs
index a5342b77e..a41d0106f 100644
--- a/embassy-traits/src/lib.rs
+++ b/embassy-traits/src/lib.rs
@@ -5,8 +5,4 @@
5pub mod adapter; 5pub mod adapter;
6pub mod delay; 6pub mod delay;
7pub mod flash; 7pub mod flash;
8pub mod gpio;
9pub mod i2c;
10pub mod rng; 8pub mod rng;
11pub mod spi;
12pub mod uart;
diff --git a/embassy-traits/src/spi.rs b/embassy-traits/src/spi.rs
deleted file mode 100644
index 6beb442ba..000000000
--- a/embassy-traits/src/spi.rs
+++ /dev/null
@@ -1,61 +0,0 @@
1//! Async SPI API
2
3use core::future::Future;
4
5/// Full duplex (master mode)
6///
7/// # Notes
8///
9/// - It's the task of the user of this interface to manage the slave select lines
10///
11/// - Due to how full duplex SPI works each `read` call must be preceded by a `write` call.
12///
13/// - `read` calls only return the data received with the last `write` call.
14/// Previously received data is discarded
15///
16/// - Data is only guaranteed to be clocked out when the `read` call succeeds.
17/// The slave select line shouldn't be released before that.
18///
19/// - Some SPIs can work with 8-bit *and* 16-bit words. You can overload this trait with different
20/// `Word` types to allow operation in both modes.
21
22pub trait Spi<Word> {
23 /// An enumeration of SPI errors
24 type Error;
25}
26
27pub trait FullDuplex<Word>: Spi<Word> + Write<Word> + Read<Word> {
28 type WriteReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
29 where
30 Self: 'a,
31 Word: 'a;
32
33 /// The `read` array must be at least as long as the `write` array,
34 /// but is guaranteed to only be filled with bytes equal to the
35 /// length of the `write` array.
36 fn read_write<'a>(
37 &'a mut self,
38 read: &'a mut [Word],
39 write: &'a [Word],
40 ) -> Self::WriteReadFuture<'a>;
41}
42
43pub trait Write<Word>: Spi<Word> {
44 type WriteFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
45 where
46 Self: 'a,
47 Word: 'a;
48
49 /// Writes `data` to the peripheral, ignoring all the incoming words.
50 fn write<'a>(&'a mut self, data: &'a [Word]) -> Self::WriteFuture<'a>;
51}
52
53pub trait Read<Word>: Write<Word> {
54 type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
55 where
56 Self: 'a,
57 Word: 'a;
58
59 /// Reads words into `data` from the peripheral.
60 fn read<'a>(&'a mut self, data: &'a mut [Word]) -> Self::ReadFuture<'a>;
61}
diff --git a/embassy-traits/src/uart.rs b/embassy-traits/src/uart.rs
deleted file mode 100644
index 4984bc89c..000000000
--- a/embassy-traits/src/uart.rs
+++ /dev/null
@@ -1,36 +0,0 @@
1use core::future::Future;
2
3#[derive(Copy, Clone, Debug, Eq, PartialEq)]
4#[cfg_attr(feature = "defmt", derive(defmt::Format))]
5#[non_exhaustive]
6pub enum Error {
7 Other,
8}
9
10pub trait Read {
11 type ReadFuture<'a>: Future<Output = Result<(), Error>>
12 where
13 Self: 'a;
14
15 /// Receive into the buffer until the buffer is full.
16 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a>;
17}
18
19pub trait ReadUntilIdle {
20 type ReadUntilIdleFuture<'a>: Future<Output = Result<usize, Error>>
21 where
22 Self: 'a;
23
24 /// Receive into the buffer until the buffer is full or the line is idle after some bytes are received
25 /// Return the number of bytes received
26 fn read_until_idle<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadUntilIdleFuture<'a>;
27}
28
29pub trait Write {
30 type WriteFuture<'a>: Future<Output = Result<(), Error>>
31 where
32 Self: 'a;
33
34 /// Write all bytes in `buf`.
35 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a>;
36}
diff --git a/examples/stm32f3/src/bin/spi_dma.rs b/examples/stm32f3/src/bin/spi_dma.rs
index a87a36f73..bd66b1202 100644
--- a/examples/stm32f3/src/bin/spi_dma.rs
+++ b/examples/stm32f3/src/bin/spi_dma.rs
@@ -10,7 +10,6 @@ use embassy::executor::Spawner;
10use embassy_stm32::spi::{Config, Spi}; 10use embassy_stm32::spi::{Config, Spi};
11use embassy_stm32::time::Hertz; 11use embassy_stm32::time::Hertz;
12use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
13use embassy_traits::spi::FullDuplex;
14use example_common::*; 13use example_common::*;
15use heapless::String; 14use heapless::String;
16 15
@@ -33,7 +32,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
33 let mut write: String<128> = String::new(); 32 let mut write: String<128> = String::new();
34 let mut read = [0; 128]; 33 let mut read = [0; 128];
35 core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); 34 core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap();
36 spi.read_write(&mut read[0..write.len()], write.as_bytes()) 35 spi.transfer(&mut read[0..write.len()], write.as_bytes())
37 .await 36 .await
38 .ok(); 37 .ok();
39 info!("read via spi+dma: {}", from_utf8(&read).unwrap()); 38 info!("read via spi+dma: {}", from_utf8(&read).unwrap());
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 67f1cfc94..16adcdb91 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -10,7 +10,7 @@ resolver = "2"
10[dependencies] 10[dependencies]
11embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } 11embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
12embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } 12embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
13embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743zi", "net", "time-driver-any", "exti", "unstable-pac"] } 13embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743zi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
14embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] } 14embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] }
15embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] } 15embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] }
16 16
@@ -20,6 +20,7 @@ defmt-rtt = "0.3"
20cortex-m = "0.7.3" 20cortex-m = "0.7.3"
21cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
22embedded-hal = "0.2.6" 22embedded-hal = "0.2.6"
23embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"}
23panic-probe = { version = "0.3", features = ["print-defmt"] } 24panic-probe = { version = "0.3", features = ["print-defmt"] }
24futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 25futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
25heapless = { version = "0.7.5", default-features = false } 26heapless = { version = "0.7.5", default-features = false }
diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs
index 9e8071bb3..9760d0f74 100644
--- a/examples/stm32h7/src/bin/camera.rs
+++ b/examples/stm32h7/src/bin/camera.rs
@@ -128,7 +128,7 @@ mod ov7725 {
128 use defmt::Format; 128 use defmt::Format;
129 use embassy::time::{Duration, Timer}; 129 use embassy::time::{Duration, Timer};
130 use embassy_stm32::rcc::{Mco, McoInstance}; 130 use embassy_stm32::rcc::{Mco, McoInstance};
131 use embassy_traits::i2c::I2c; 131 use embedded_hal_async::i2c::I2c;
132 132
133 #[repr(u8)] 133 #[repr(u8)]
134 pub enum RgbFormat { 134 pub enum RgbFormat {
diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs
index 192e2e864..15ae09973 100644
--- a/examples/stm32h7/src/bin/spi_dma.rs
+++ b/examples/stm32h7/src/bin/spi_dma.rs
@@ -9,7 +9,6 @@ use core::fmt::Write;
9use embassy::executor::Executor; 9use embassy::executor::Executor;
10use embassy::util::Forever; 10use embassy::util::Forever;
11use embassy_stm32::time::U32Ext; 11use embassy_stm32::time::U32Ext;
12use embassy_traits::spi::FullDuplex;
13use example_common::*; 12use example_common::*;
14 13
15use core::str::from_utf8; 14use core::str::from_utf8;
@@ -24,8 +23,8 @@ async fn main_task(mut spi: spi::Spi<'static, SPI3, DMA1_CH3, DMA1_CH4>) {
24 let mut write: String<128> = String::new(); 23 let mut write: String<128> = String::new();
25 let mut read = [0; 128]; 24 let mut read = [0; 128];
26 core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); 25 core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap();
27 // read_write will slice the &mut read down to &write's actual length. 26 // transfer will slice the &mut read down to &write's actual length.
28 spi.read_write(&mut read, write.as_bytes()).await.ok(); 27 spi.transfer(&mut read, write.as_bytes()).await.ok();
29 info!("read via spi+dma: {}", from_utf8(&read).unwrap()); 28 info!("read via spi+dma: {}", from_utf8(&read).unwrap());
30 } 29 }
31} 30}
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
index f101c15f5..2c27e276c 100644
--- a/examples/stm32l0/Cargo.toml
+++ b/examples/stm32l0/Cargo.toml
@@ -8,7 +8,7 @@ resolver = "2"
8[dependencies] 8[dependencies]
9embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } 9embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
10embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } 10embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } 11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] }
12 12
13embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time", "defmt"] } 13embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time", "defmt"] }
14 14
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index d01c76f6e..ca76a1299 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -10,7 +10,7 @@ resolver = "2"
10[dependencies] 10[dependencies]
11embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt" ] } 11embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt" ] }
12embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } 12embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
13embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti"] } 13embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits"] }
14 14
15defmt = "0.3" 15defmt = "0.3"
16defmt-rtt = "0.3" 16defmt-rtt = "0.3"
@@ -18,6 +18,7 @@ defmt-rtt = "0.3"
18cortex-m = "0.7.3" 18cortex-m = "0.7.3"
19cortex-m-rt = "0.7.0" 19cortex-m-rt = "0.7.0"
20embedded-hal = "0.2.6" 20embedded-hal = "0.2.6"
21embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"}
21panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "0.3", features = ["print-defmt"] }
22futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 23futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
23heapless = { version = "0.7.5", default-features = false } 24heapless = { version = "0.7.5", default-features = false }
diff --git a/examples/stm32l4/src/bin/i2c_blocking_async.rs b/examples/stm32l4/src/bin/i2c_blocking_async.rs
index 0339ed4d3..07077f9fb 100644
--- a/examples/stm32l4/src/bin/i2c_blocking_async.rs
+++ b/examples/stm32l4/src/bin/i2c_blocking_async.rs
@@ -11,7 +11,8 @@ 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 embassy_traits::{adapter::BlockingAsync, i2c::I2c as _}; 14use embassy_traits::adapter::BlockingAsync;
15use embedded_hal_async::i2c::I2c as I2cTrait;
15use example_common::{info, unwrap}; 16use example_common::{info, unwrap};
16 17
17const ADDRESS: u8 = 0x5F; 18const ADDRESS: u8 = 0x5F;
diff --git a/examples/stm32l4/src/bin/spi_blocking_async.rs b/examples/stm32l4/src/bin/spi_blocking_async.rs
index 3be3f21c9..bcd2e32d5 100644
--- a/examples/stm32l4/src/bin/spi_blocking_async.rs
+++ b/examples/stm32l4/src/bin/spi_blocking_async.rs
@@ -11,7 +11,8 @@ use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
11use embassy_stm32::spi::{Config, Spi}; 11use embassy_stm32::spi::{Config, Spi};
12use embassy_stm32::time::Hertz; 12use embassy_stm32::time::Hertz;
13use embassy_stm32::Peripherals; 13use embassy_stm32::Peripherals;
14use embassy_traits::{adapter::BlockingAsync, spi::FullDuplex}; 14use embassy_traits::adapter::BlockingAsync;
15use embedded_hal_async::spi::ReadWrite;
15use example_common::*; 16use example_common::*;
16 17
17#[embassy::main] 18#[embassy::main]
@@ -47,10 +48,10 @@ async fn main(_spawner: Spawner, p: Peripherals) {
47 info!("waiting for ready"); 48 info!("waiting for ready");
48 } 49 }
49 50
50 let write = [0x0A; 10]; 51 let write: [u8; 10] = [0x0A; 10];
51 let mut read = [0; 10]; 52 let mut read: [u8; 10] = [0; 10];
52 cs.set_low(); 53 cs.set_low();
53 spi.read_write(&mut read, &write).await.ok(); 54 spi.transfer(&mut read, &write).await.ok();
54 cs.set_high(); 55 cs.set_high();
55 info!("xfer {=[u8]:x}", read); 56 info!("xfer {=[u8]:x}", read);
56} 57}
diff --git a/examples/stm32l4/src/bin/spi_dma.rs b/examples/stm32l4/src/bin/spi_dma.rs
index d6464bbfa..b4d5091b2 100644
--- a/examples/stm32l4/src/bin/spi_dma.rs
+++ b/examples/stm32l4/src/bin/spi_dma.rs
@@ -10,7 +10,6 @@ use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
10use embassy_stm32::spi::{Config, Spi}; 10use embassy_stm32::spi::{Config, Spi};
11use embassy_stm32::time::Hertz; 11use embassy_stm32::time::Hertz;
12use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
13use embassy_traits::spi::FullDuplex;
14use example_common::*; 13use example_common::*;
15 14
16#[embassy::main] 15#[embassy::main]
@@ -47,7 +46,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
47 let write = [0x0A; 10]; 46 let write = [0x0A; 10];
48 let mut read = [0; 10]; 47 let mut read = [0; 10];
49 cs.set_low(); 48 cs.set_low();
50 spi.read_write(&mut read, &write).await.ok(); 49 spi.transfer(&mut read, &write).await.ok();
51 cs.set_high(); 50 cs.set_high();
52 info!("xfer {=[u8]:x}", read); 51 info!("xfer {=[u8]:x}", read);
53} 52}
diff --git a/examples/stm32l4/src/bin/usart_blocking_async.rs b/examples/stm32l4/src/bin/usart_blocking_async.rs
index 679d4e0da..10b7127da 100644
--- a/examples/stm32l4/src/bin/usart_blocking_async.rs
+++ b/examples/stm32l4/src/bin/usart_blocking_async.rs
@@ -6,13 +6,11 @@
6mod example_common; 6mod example_common;
7 7
8use embassy::executor::Spawner; 8use embassy::executor::Spawner;
9use embassy::traits::{ 9use embassy::traits::adapter::BlockingAsync;
10 adapter::BlockingAsync,
11 uart::{Read, Write},
12};
13use embassy_stm32::dma::NoDma; 10use embassy_stm32::dma::NoDma;
14use embassy_stm32::usart::{Config, Uart}; 11use embassy_stm32::usart::{Config, Uart};
15use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
13use embedded_hal_async::serial::{Read, Write};
16use example_common::*; 14use example_common::*;
17 15
18#[embassy::main] 16#[embassy::main]
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index dc66d08c0..63bfb9d22 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -23,6 +23,7 @@ defmt-rtt = "0.3.0"
23cortex-m = "0.7.3" 23cortex-m = "0.7.3"
24cortex-m-rt = "0.7.0" 24cortex-m-rt = "0.7.0"
25embedded-hal = "0.2.6" 25embedded-hal = "0.2.6"
26embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"}
26panic-probe = { version = "0.3.0", features = ["print-defmt"] } 27panic-probe = { version = "0.3.0", features = ["print-defmt"] }
27 28
28[profile.dev] 29[profile.dev]
diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs
index 1a827b434..bf682e097 100644
--- a/tests/stm32/src/bin/spi_dma.rs
+++ b/tests/stm32/src/bin/spi_dma.rs
@@ -9,7 +9,6 @@ use embassy::executor::Spawner;
9use embassy_stm32::spi::{self, Spi}; 9use embassy_stm32::spi::{self, Spi};
10use embassy_stm32::time::Hertz; 10use embassy_stm32::time::Hertz;
11use embassy_stm32::Peripherals; 11use embassy_stm32::Peripherals;
12use embassy_traits::spi::FullDuplex;
13use example_common::*; 12use example_common::*;
14 13
15#[embassy::main(config = "config()")] 14#[embassy::main(config = "config()")]
@@ -43,7 +42,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
43 // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. 42 // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor.
44 // so we should get the data we sent back. 43 // so we should get the data we sent back.
45 let mut buf = [0; 9]; 44 let mut buf = [0; 9];
46 spi.read_write(&mut buf, &data).await.unwrap(); 45 spi.transfer(&mut buf, &data).await.unwrap();
47 assert_eq!(buf, data); 46 assert_eq!(buf, data);
48 47
49 info!("Test OK"); 48 info!("Test OK");