aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-hal-common/src/peripheral.rs2
-rw-r--r--embassy-lora/Cargo.toml4
-rw-r--r--embassy-lora/src/stm32wl/mod.rs2
-rw-r--r--embassy-lora/src/sx127x/mod.rs18
-rw-r--r--embassy-lora/src/sx127x/sx127x_lora/mod.rs4
-rw-r--r--embassy-nrf/Cargo.toml4
-rw-r--r--embassy-nrf/src/gpiote.rs122
-rw-r--r--embassy-nrf/src/spim.rs169
-rw-r--r--embassy-nrf/src/twim.rs71
-rw-r--r--embassy-nrf/src/uarte.rs125
-rw-r--r--embassy-rp/Cargo.toml4
-rw-r--r--embassy-rp/src/spi.rs52
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/src/eth/v1c/mod.rs2
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs2
-rw-r--r--embassy-stm32/src/exti.rs63
-rw-r--r--embassy-stm32/src/i2c/v2.rs84
-rw-r--r--embassy-stm32/src/spi/mod.rs200
-rw-r--r--embassy-stm32/src/usart/mod.rs51
-rw-r--r--embassy-traits/Cargo.toml4
-rw-r--r--embassy-traits/src/adapter.rs121
-rw-r--r--embassy/Cargo.toml4
-rw-r--r--embassy/src/lib.rs7
-rw-r--r--embassy/src/time/delay.rs36
-rw-r--r--examples/nrf/Cargo.toml2
-rw-r--r--examples/rp/Cargo.toml7
-rw-r--r--examples/rp/src/bin/spi_display.rs375
-rw-r--r--examples/stm32f4/Cargo.toml2
-rw-r--r--examples/stm32h7/Cargo.toml2
-rw-r--r--examples/stm32l4/Cargo.toml2
-rw-r--r--examples/stm32l4/src/bin/spi_blocking_async.rs2
-rw-r--r--rust-toolchain.toml2
-rw-r--r--tests/stm32/Cargo.toml2
33 files changed, 714 insertions, 837 deletions
diff --git a/embassy-hal-common/src/peripheral.rs b/embassy-hal-common/src/peripheral.rs
index dcf9d3a27..89420a422 100644
--- a/embassy-hal-common/src/peripheral.rs
+++ b/embassy-hal-common/src/peripheral.rs
@@ -97,7 +97,7 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
97 // Interrupts' priorities can only be changed with raw embassy `Interrupts`, 97 // Interrupts' priorities can only be changed with raw embassy `Interrupts`,
98 // which can't safely store a `PeripheralMutex` across invocations. 98 // which can't safely store a `PeripheralMutex` across invocations.
99 // - We can't have preempted a with() call because the irq is disabled during it. 99 // - We can't have preempted a with() call because the irq is disabled during it.
100 let state = unsafe { &mut *(p as *mut S) }; 100 let state = &mut *(p as *mut S);
101 state.on_interrupt(); 101 state.on_interrupt();
102 }); 102 });
103 irq.set_handler_context(state_ptr as *mut ()); 103 irq.set_handler_context(state_ptr as *mut ());
diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml
index c27641521..dfd262548 100644
--- a/embassy-lora/Cargo.toml
+++ b/embassy-lora/Cargo.toml
@@ -18,8 +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} 21embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
22embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"} 22embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2"}
23embassy-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 }
24futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } 24futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
25embedded-hal = { version = "0.2", features = ["unproven"] } 25embedded-hal = { version = "0.2", features = ["unproven"] }
diff --git a/embassy-lora/src/stm32wl/mod.rs b/embassy-lora/src/stm32wl/mod.rs
index 783140cb3..7dc750cf9 100644
--- a/embassy-lora/src/stm32wl/mod.rs
+++ b/embassy-lora/src/stm32wl/mod.rs
@@ -78,7 +78,7 @@ impl<'a> SubGhzRadio<'a> {
78 // This is safe because we only get interrupts when configured for, so 78 // This is safe because we only get interrupts when configured for, so
79 // the radio will be awaiting on the signal at this point. If not, the ISR will 79 // the radio will be awaiting on the signal at this point. If not, the ISR will
80 // anyway only adjust the state in the IRQ signal state. 80 // anyway only adjust the state in the IRQ signal state.
81 let state = unsafe { &mut *(p as *mut StateInner<'a>) }; 81 let state = &mut *(p as *mut StateInner<'a>);
82 state.on_interrupt(); 82 state.on_interrupt();
83 }); 83 });
84 irq.set_handler_context(state_ptr as *mut ()); 84 irq.set_handler_context(state_ptr as *mut ());
diff --git a/embassy-lora/src/sx127x/mod.rs b/embassy-lora/src/sx127x/mod.rs
index 6a15dab82..c70f33582 100644
--- a/embassy-lora/src/sx127x/mod.rs
+++ b/embassy-lora/src/sx127x/mod.rs
@@ -20,7 +20,7 @@ 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: ReadWrite<u8, Error = E> + 'static, 23 SPI: SpiBus<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,
@@ -42,7 +42,7 @@ 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: ReadWrite<u8, Error = E> + 'static, 45 SPI: SpiBus<u8, Error = E> + 'static,
46 CS: OutputPin + 'static, 46 CS: OutputPin + 'static,
47 RESET: OutputPin + 'static, 47 RESET: OutputPin + 'static,
48 I: Wait + 'static, 48 I: Wait + 'static,
@@ -64,7 +64,7 @@ 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: ReadWrite<u8, Error = E> + 'static, 67 SPI: SpiBus<u8, Error = E> + 'static,
68 CS: OutputPin + 'static, 68 CS: OutputPin + 'static,
69 RESET: OutputPin + 'static, 69 RESET: OutputPin + 'static,
70 I: Wait + 'static, 70 I: Wait + 'static,
@@ -80,7 +80,7 @@ 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: ReadWrite<u8, Error = E> + 'static, 83 SPI: SpiBus<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,
@@ -89,15 +89,14 @@ where
89{ 89{
90 type PhyError = Sx127xError; 90 type PhyError = Sx127xError;
91 91
92 type TxFuture<'m> 92 type TxFuture<'m> = impl Future<Output = Result<u32, Self::PhyError>> + 'm
93 where 93 where
94 SPI: 'm, 94 SPI: 'm,
95 CS: 'm, 95 CS: 'm,
96 RESET: 'm, 96 RESET: 'm,
97 E: 'm, 97 E: 'm,
98 I: 'm, 98 I: 'm,
99 RFS: 'm, 99 RFS: 'm;
100 = impl Future<Output = Result<u32, Self::PhyError>> + 'm;
101 100
102 fn tx<'m>(&'m mut self, config: TxConfig, buf: &'m [u8]) -> Self::TxFuture<'m> { 101 fn tx<'m>(&'m mut self, config: TxConfig, buf: &'m [u8]) -> Self::TxFuture<'m> {
103 trace!("TX START"); 102 trace!("TX START");
@@ -137,15 +136,14 @@ where
137 } 136 }
138 } 137 }
139 138
140 type RxFuture<'m> 139 type RxFuture<'m> = impl Future<Output = Result<(usize, RxQuality), Self::PhyError>> + 'm
141 where 140 where
142 SPI: 'm, 141 SPI: 'm,
143 CS: 'm, 142 CS: 'm,
144 RESET: 'm, 143 RESET: 'm,
145 E: 'm, 144 E: 'm,
146 I: 'm, 145 I: 'm,
147 RFS: 'm, 146 RFS: 'm;
148 = impl Future<Output = Result<(usize, RxQuality), Self::PhyError>> + 'm;
149 147
150 fn rx<'m>(&'m mut self, config: RfConfig, buf: &'m mut [u8]) -> Self::RxFuture<'m> { 148 fn rx<'m>(&'m mut self, config: RfConfig, buf: &'m mut [u8]) -> Self::RxFuture<'m> {
151 trace!("RX START"); 149 trace!("RX START");
diff --git a/embassy-lora/src/sx127x/sx127x_lora/mod.rs b/embassy-lora/src/sx127x/sx127x_lora/mod.rs
index 6fbd3a4bd..62eaf0a95 100644
--- a/embassy-lora/src/sx127x/sx127x_lora/mod.rs
+++ b/embassy-lora/src/sx127x/sx127x_lora/mod.rs
@@ -8,7 +8,7 @@
8use bit_field::BitField; 8use bit_field::BitField;
9use embassy::time::{Duration, Timer}; 9use embassy::time::{Duration, Timer};
10use embedded_hal::digital::v2::OutputPin; 10use embedded_hal::digital::v2::OutputPin;
11use embedded_hal_async::spi::ReadWrite; 11use embedded_hal_async::spi::SpiBus;
12 12
13mod register; 13mod register;
14use self::register::PaConfig; 14use self::register::PaConfig;
@@ -48,7 +48,7 @@ const VERSION_CHECK: u8 = 0x09;
48 48
49impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET> 49impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET>
50where 50where
51 SPI: ReadWrite<u8, Error = E>, 51 SPI: SpiBus<u8, Error = E>,
52 CS: OutputPin, 52 CS: OutputPin,
53 RESET: OutputPin, 53 RESET: OutputPin,
54{ 54{
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index d8bac3227..5c0450ebf 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -63,8 +63,8 @@ embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["n
63embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" } 63embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
64 64
65embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } 65embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
66embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} 66embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
67embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} 67embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
68 68
69defmt = { version = "0.3", optional = true } 69defmt = { version = "0.3", optional = true }
70log = { version = "0.4.14", optional = true } 70log = { version = "0.4.14", optional = true }
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index b856c2dfe..32b5d908d 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -108,7 +108,7 @@ unsafe fn handle_gpiote_interrupt() {
108 108
109 for i in 0..CHANNEL_COUNT { 109 for i in 0..CHANNEL_COUNT {
110 if g.events_in[i].read().bits() != 0 { 110 if g.events_in[i].read().bits() != 0 {
111 g.intenclr.write(|w| unsafe { w.bits(1 << i) }); 111 g.intenclr.write(|w| w.bits(1 << i));
112 CHANNEL_WAKERS[i].wake(); 112 CHANNEL_WAKERS[i].wake();
113 } 113 }
114 } 114 }
@@ -481,102 +481,72 @@ mod eh1 {
481 } 481 }
482} 482}
483 483
484#[cfg(all(feature = "unstable-traits", feature = "nightly"))] 484cfg_if::cfg_if! {
485mod eh1a { 485 if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
486 use super::*; 486 use futures::FutureExt;
487 use futures::FutureExt;
488 487
489 impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> { 488 impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> {
490 type WaitForHighFuture<'a> 489 type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
491 where
492 Self: 'a,
493 = impl Future<Output = Result<(), Self::Error>> + 'a;
494 490
495 fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { 491 fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
496 self.wait_for_high().map(Ok) 492 self.wait_for_high().map(Ok)
497 } 493 }
498 494
499 type WaitForLowFuture<'a> 495 type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
500 where
501 Self: 'a,
502 = impl Future<Output = Result<(), Self::Error>> + 'a;
503 496
504 fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> { 497 fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
505 self.wait_for_low().map(Ok) 498 self.wait_for_low().map(Ok)
506 } 499 }
507 500
508 type WaitForRisingEdgeFuture<'a> 501 type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
509 where
510 Self: 'a,
511 = impl Future<Output = Result<(), Self::Error>> + 'a;
512 502
513 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> { 503 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
514 self.wait_for_rising_edge().map(Ok) 504 self.wait_for_rising_edge().map(Ok)
515 } 505 }
516 506
517 type WaitForFallingEdgeFuture<'a> 507 type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
518 where
519 Self: 'a,
520 = impl Future<Output = Result<(), Self::Error>> + 'a;
521 508
522 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> { 509 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
523 self.wait_for_falling_edge().map(Ok) 510 self.wait_for_falling_edge().map(Ok)
524 } 511 }
525 512
526 type WaitForAnyEdgeFuture<'a> 513 type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
527 where
528 Self: 'a,
529 = impl Future<Output = Result<(), Self::Error>> + 'a;
530 514
531 fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> { 515 fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
532 self.wait_for_any_edge().map(Ok) 516 self.wait_for_any_edge().map(Ok)
517 }
533 } 518 }
534 }
535 519
536 impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Flex<'d, T> { 520 impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Flex<'d, T> {
537 type WaitForHighFuture<'a> 521 type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
538 where
539 Self: 'a,
540 = impl Future<Output = Result<(), Self::Error>> + 'a;
541 522
542 fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { 523 fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
543 self.wait_for_high().map(Ok) 524 self.wait_for_high().map(Ok)
544 } 525 }
545 526
546 type WaitForLowFuture<'a> 527 type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
547 where
548 Self: 'a,
549 = impl Future<Output = Result<(), Self::Error>> + 'a;
550 528
551 fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> { 529 fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
552 self.wait_for_low().map(Ok) 530 self.wait_for_low().map(Ok)
553 } 531 }
554 532
555 type WaitForRisingEdgeFuture<'a> 533 type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
556 where
557 Self: 'a,
558 = impl Future<Output = Result<(), Self::Error>> + 'a;
559 534
560 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> { 535 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
561 self.wait_for_rising_edge().map(Ok) 536 self.wait_for_rising_edge().map(Ok)
562 } 537 }
563 538
564 type WaitForFallingEdgeFuture<'a> 539 type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
565 where
566 Self: 'a,
567 = impl Future<Output = Result<(), Self::Error>> + 'a;
568 540
569 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> { 541 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
570 self.wait_for_falling_edge().map(Ok) 542 self.wait_for_falling_edge().map(Ok)
571 } 543 }
572 544
573 type WaitForAnyEdgeFuture<'a> 545 type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
574 where
575 Self: 'a,
576 = impl Future<Output = Result<(), Self::Error>> + 'a;
577 546
578 fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> { 547 fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
579 self.wait_for_any_edge().map(Ok) 548 self.wait_for_any_edge().map(Ok)
549 }
580 } 550 }
581 } 551 }
582} 552}
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index 5d88b2326..f97a1c0fe 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -455,43 +455,25 @@ mod eh1 {
455 type Error = Error; 455 type Error = Error;
456 } 456 }
457 457
458 impl<'d, T: Instance> embedded_hal_1::spi::blocking::Read<u8> for Spim<'d, T> { 458 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusFlush for Spim<'d, T> {
459 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 459 fn flush(&mut self) -> Result<(), Self::Error> {
460 self.blocking_transfer(words, &[]) 460 Ok(())
461 } 461 }
462 }
462 463
463 fn read_transaction(&mut self, words: &mut [&mut [u8]]) -> Result<(), Self::Error> { 464 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusRead<u8> for Spim<'d, T> {
464 for buf in words { 465 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
465 self.blocking_read(buf)? 466 self.blocking_transfer(words, &[])
466 }
467 Ok(())
468 } 467 }
469 } 468 }
470 469
471 impl<'d, T: Instance> embedded_hal_1::spi::blocking::Write<u8> for Spim<'d, T> { 470 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusWrite<u8> for Spim<'d, T> {
472 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 471 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
473 self.blocking_write(words) 472 self.blocking_write(words)
474 } 473 }
475
476 fn write_transaction(&mut self, words: &[&[u8]]) -> Result<(), Self::Error> {
477 for buf in words {
478 self.blocking_write(buf)?
479 }
480 Ok(())
481 }
482
483 fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
484 where
485 WI: IntoIterator<Item = u8>,
486 {
487 for w in words {
488 self.blocking_write(&[w])?;
489 }
490 Ok(())
491 }
492 } 474 }
493 475
494 impl<'d, T: Instance> embedded_hal_1::spi::blocking::ReadWrite<u8> for Spim<'d, T> { 476 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBus<u8> for Spim<'d, T> {
495 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { 477 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
496 self.blocking_transfer(read, write) 478 self.blocking_transfer(read, write)
497 } 479 }
@@ -499,128 +481,51 @@ mod eh1 {
499 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 481 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
500 self.blocking_transfer_in_place(words) 482 self.blocking_transfer_in_place(words)
501 } 483 }
502
503 fn transaction<'a>(
504 &mut self,
505 operations: &mut [embedded_hal_1::spi::blocking::Operation<'a, u8>],
506 ) -> Result<(), Self::Error> {
507 use embedded_hal_1::spi::blocking::Operation;
508 for o in operations {
509 match o {
510 Operation::Read(b) => self.blocking_read(b)?,
511 Operation::Write(b) => self.blocking_write(b)?,
512 Operation::Transfer(r, w) => self.blocking_transfer(r, w)?,
513 Operation::TransferInPlace(b) => self.blocking_transfer_in_place(b)?,
514 }
515 }
516 Ok(())
517 }
518 } 484 }
519} 485}
520 486
521#[cfg(all(feature = "unstable-traits", feature = "nightly"))] 487cfg_if::cfg_if! {
522mod eh1a { 488 if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
523 use super::*; 489 use core::future::Future;
524 use core::future::Future;
525 490
526 impl<'d, T: Instance> embedded_hal_async::spi::Read<u8> for Spim<'d, T> { 491 impl<'d, T: Instance> embedded_hal_async::spi::SpiBusFlush for Spim<'d, T> {
527 type ReadFuture<'a> 492 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
528 where
529 Self: 'a,
530 = impl Future<Output = Result<(), Self::Error>> + 'a;
531 493
532 fn read<'a>(&'a mut self, words: &'a mut [u8]) -> Self::ReadFuture<'a> { 494 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
533 self.read(words) 495 async move { Ok(()) }
534 }
535
536 type ReadTransactionFuture<'a>
537 where
538 Self: 'a,
539 = impl Future<Output = Result<(), Self::Error>> + 'a;
540
541 fn read_transaction<'a>(
542 &'a mut self,
543 words: &'a mut [&'a mut [u8]],
544 ) -> Self::ReadTransactionFuture<'a> {
545 async move {
546 for buf in words {
547 self.read(buf).await?
548 }
549 Ok(())
550 } 496 }
551 } 497 }
552 }
553 498
554 impl<'d, T: Instance> embedded_hal_async::spi::Write<u8> for Spim<'d, T> { 499 impl<'d, T: Instance> embedded_hal_async::spi::SpiBusRead<u8> for Spim<'d, T> {
555 type WriteFuture<'a> 500 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
556 where
557 Self: 'a,
558 = impl Future<Output = Result<(), Self::Error>> + 'a;
559 501
560 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { 502 fn read<'a>(&'a mut self, words: &'a mut [u8]) -> Self::ReadFuture<'a> {
561 self.write(data) 503 self.read(words)
562 }
563
564 type WriteTransactionFuture<'a>
565 where
566 Self: 'a,
567 = impl Future<Output = Result<(), Self::Error>> + 'a;
568
569 fn write_transaction<'a>(
570 &'a mut self,
571 words: &'a [&'a [u8]],
572 ) -> Self::WriteTransactionFuture<'a> {
573 async move {
574 for buf in words {
575 self.write(buf).await?
576 }
577 Ok(())
578 } 504 }
579 } 505 }
580 }
581 506
582 impl<'d, T: Instance> embedded_hal_async::spi::ReadWrite<u8> for Spim<'d, T> { 507 impl<'d, T: Instance> embedded_hal_async::spi::SpiBusWrite<u8> for Spim<'d, T> {
583 type TransferFuture<'a> 508 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
584 where
585 Self: 'a,
586 = impl Future<Output = Result<(), Self::Error>> + 'a;
587 509
588 fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { 510 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
589 self.transfer(rx, tx) 511 self.write(data)
512 }
590 } 513 }
591 514
592 type TransferInPlaceFuture<'a> 515 impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spim<'d, T> {
593 where 516 type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
594 Self: 'a,
595 = impl Future<Output = Result<(), Self::Error>> + 'a;
596 517
597 fn transfer_in_place<'a>( 518 fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> {
598 &'a mut self, 519 self.transfer(rx, tx)
599 words: &'a mut [u8], 520 }
600 ) -> Self::TransferInPlaceFuture<'a> {
601 self.transfer_in_place(words)
602 }
603 521
604 type TransactionFuture<'a> 522 type TransferInPlaceFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
605 where 523
606 Self: 'a, 524 fn transfer_in_place<'a>(
607 = impl Future<Output = Result<(), Self::Error>> + 'a; 525 &'a mut self,
608 526 words: &'a mut [u8],
609 fn transaction<'a>( 527 ) -> Self::TransferInPlaceFuture<'a> {
610 &'a mut self, 528 self.transfer_in_place(words)
611 operations: &'a mut [embedded_hal_async::spi::Operation<'a, u8>],
612 ) -> Self::TransactionFuture<'a> {
613 use embedded_hal_1::spi::blocking::Operation;
614 async move {
615 for o in operations {
616 match o {
617 Operation::Read(b) => self.read(b).await?,
618 Operation::Write(b) => self.write(b).await?,
619 Operation::Transfer(r, w) => self.transfer(r, w).await?,
620 Operation::TransferInPlace(b) => self.transfer_in_place(b).await?,
621 }
622 }
623 Ok(())
624 } 529 }
625 } 530 }
626 } 531 }
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index 40705477f..9bee16f3d 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -743,52 +743,43 @@ mod eh1 {
743 } 743 }
744} 744}
745 745
746#[cfg(all(feature = "unstable-traits", feature = "nightly"))] 746cfg_if::cfg_if! {
747impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> { 747 if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
748 type ReadFuture<'a> 748 impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> {
749 where 749 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
750 Self: 'a,
751 = impl Future<Output = Result<(), Self::Error>> + 'a;
752 750
753 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 751 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
754 self.read(address, buffer) 752 self.read(address, buffer)
755 } 753 }
756 754
757 type WriteFuture<'a> 755 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
758 where
759 Self: 'a,
760 = impl Future<Output = Result<(), Self::Error>> + 'a;
761 756
762 fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> { 757 fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
763 self.write(address, bytes) 758 self.write(address, bytes)
764 } 759 }
765 760
766 type WriteReadFuture<'a> 761 type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
767 where
768 Self: 'a,
769 = impl Future<Output = Result<(), Self::Error>> + 'a;
770 762
771 fn write_read<'a>( 763 fn write_read<'a>(
772 &'a mut self, 764 &'a mut self,
773 address: u8, 765 address: u8,
774 wr_buffer: &'a [u8], 766 wr_buffer: &'a [u8],
775 rd_buffer: &'a mut [u8], 767 rd_buffer: &'a mut [u8],
776 ) -> Self::WriteReadFuture<'a> { 768 ) -> Self::WriteReadFuture<'a> {
777 self.write_read(address, wr_buffer, rd_buffer) 769 self.write_read(address, wr_buffer, rd_buffer)
778 } 770 }
779 771
780 type TransactionFuture<'a> 772 type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
781 where
782 Self: 'a,
783 = impl Future<Output = Result<(), Self::Error>> + 'a;
784 773
785 fn transaction<'a>( 774 fn transaction<'a, 'b>(
786 &'a mut self, 775 &'a mut self,
787 address: u8, 776 address: u8,
788 operations: &mut [embedded_hal_async::i2c::Operation<'a>], 777 operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
789 ) -> Self::TransactionFuture<'a> { 778 ) -> Self::TransactionFuture<'a, 'b> {
790 let _ = address; 779 let _ = address;
791 let _ = operations; 780 let _ = operations;
792 async move { todo!() } 781 async move { todo!() }
782 }
783 }
793 } 784 }
794} 785}
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 111c8341b..2b01dd075 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -934,105 +934,78 @@ mod eh1 {
934 } 934 }
935} 935}
936 936
937#[cfg(all(feature = "unstable-traits", feature = "nightly"))] 937cfg_if::cfg_if! {
938mod eh1a { 938 if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
939 use super::*; 939 use core::future::Future;
940 use core::future::Future;
941 940
942 impl<'d, T: Instance> embedded_hal_async::serial::Read for Uarte<'d, T> { 941 impl<'d, T: Instance> embedded_hal_async::serial::Read for Uarte<'d, T> {
943 type ReadFuture<'a> 942 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
944 where
945 Self: 'a,
946 = impl Future<Output = Result<(), Self::Error>> + 'a;
947 943
948 fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 944 fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
949 self.read(buffer) 945 self.read(buffer)
946 }
950 } 947 }
951 }
952 948
953 impl<'d, T: Instance> embedded_hal_async::serial::Write for Uarte<'d, T> { 949 impl<'d, T: Instance> embedded_hal_async::serial::Write for Uarte<'d, T> {
954 type WriteFuture<'a> 950 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
955 where
956 Self: 'a,
957 = impl Future<Output = Result<(), Self::Error>> + 'a;
958 951
959 fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { 952 fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> {
960 self.write(buffer) 953 self.write(buffer)
961 } 954 }
962 955
963 type FlushFuture<'a> 956 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
964 where
965 Self: 'a,
966 = impl Future<Output = Result<(), Self::Error>> + 'a;
967 957
968 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { 958 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
969 async move { Ok(()) } 959 async move { Ok(()) }
960 }
970 } 961 }
971 }
972 962
973 impl<'d, T: Instance> embedded_hal_async::serial::Write for UarteTx<'d, T> { 963 impl<'d, T: Instance> embedded_hal_async::serial::Write for UarteTx<'d, T> {
974 type WriteFuture<'a> 964 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
975 where
976 Self: 'a,
977 = impl Future<Output = Result<(), Self::Error>> + 'a;
978 965
979 fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { 966 fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> {
980 self.write(buffer) 967 self.write(buffer)
981 } 968 }
982 969
983 type FlushFuture<'a> 970 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
984 where
985 Self: 'a,
986 = impl Future<Output = Result<(), Self::Error>> + 'a;
987 971
988 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { 972 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
989 async move { Ok(()) } 973 async move { Ok(()) }
974 }
990 } 975 }
991 }
992 976
993 impl<'d, T: Instance> embedded_hal_async::serial::Read for UarteRx<'d, T> { 977 impl<'d, T: Instance> embedded_hal_async::serial::Read for UarteRx<'d, T> {
994 type ReadFuture<'a> 978 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
995 where
996 Self: 'a,
997 = impl Future<Output = Result<(), Self::Error>> + 'a;
998 979
999 fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 980 fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
1000 self.read(buffer) 981 self.read(buffer)
982 }
1001 } 983 }
1002 }
1003 984
1004 impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Read 985 impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Read
1005 for UarteWithIdle<'d, U, T> 986 for UarteWithIdle<'d, U, T>
1006 { 987 {
1007 type ReadFuture<'a> 988 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
1008 where
1009 Self: 'a,
1010 = impl Future<Output = Result<(), Self::Error>> + 'a;
1011 989
1012 fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 990 fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
1013 self.read(buffer) 991 self.read(buffer)
992 }
1014 } 993 }
1015 }
1016 994
1017 impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Write 995 impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Write
1018 for UarteWithIdle<'d, U, T> 996 for UarteWithIdle<'d, U, T>
1019 { 997 {
1020 type WriteFuture<'a> 998 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
1021 where
1022 Self: 'a,
1023 = impl Future<Output = Result<(), Self::Error>> + 'a;
1024 999
1025 fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { 1000 fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> {
1026 self.write(buffer) 1001 self.write(buffer)
1027 } 1002 }
1028 1003
1029 type FlushFuture<'a> 1004 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
1030 where
1031 Self: 'a,
1032 = impl Future<Output = Result<(), Self::Error>> + 'a;
1033 1005
1034 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { 1006 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
1035 async move { Ok(()) } 1007 async move { Ok(()) }
1008 }
1036 } 1009 }
1037 } 1010 }
1038} 1011}
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml
index a957af6b2..37cd77f8b 100644
--- a/embassy-rp/Cargo.toml
+++ b/embassy-rp/Cargo.toml
@@ -34,5 +34,5 @@ rp2040-pac2 = { git = "https://github.com/embassy-rs/rp2040-pac2", rev="9ad7223a
34#rp2040-pac2 = { path = "../../rp/rp2040-pac2", features = ["rt"] } 34#rp2040-pac2 = { path = "../../rp/rp2040-pac2", features = ["rt"] }
35 35
36embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } 36embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
37embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} 37embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
38embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} 38embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index 549e1bd06..8b90ba285 100644
--- a/embassy-rp/src/spi.rs
+++ b/embassy-rp/src/spi.rs
@@ -342,43 +342,25 @@ mod eh1 {
342 type Error = Error; 342 type Error = Error;
343 } 343 }
344 344
345 impl<'d, T: Instance> embedded_hal_1::spi::blocking::Read<u8> for Spi<'d, T> { 345 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusFlush for Spi<'d, T> {
346 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 346 fn flush(&mut self) -> Result<(), Self::Error> {
347 self.blocking_transfer(words, &[]) 347 Ok(())
348 } 348 }
349 }
349 350
350 fn read_transaction(&mut self, words: &mut [&mut [u8]]) -> Result<(), Self::Error> { 351 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusRead<u8> for Spi<'d, T> {
351 for buf in words { 352 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
352 self.blocking_read(buf)? 353 self.blocking_transfer(words, &[])
353 }
354 Ok(())
355 } 354 }
356 } 355 }
357 356
358 impl<'d, T: Instance> embedded_hal_1::spi::blocking::Write<u8> for Spi<'d, T> { 357 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusWrite<u8> for Spi<'d, T> {
359 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 358 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
360 self.blocking_write(words) 359 self.blocking_write(words)
361 } 360 }
362
363 fn write_transaction(&mut self, words: &[&[u8]]) -> Result<(), Self::Error> {
364 for buf in words {
365 self.blocking_write(buf)?
366 }
367 Ok(())
368 }
369
370 fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
371 where
372 WI: IntoIterator<Item = u8>,
373 {
374 for w in words {
375 self.blocking_write(&[w])?;
376 }
377 Ok(())
378 }
379 } 361 }
380 362
381 impl<'d, T: Instance> embedded_hal_1::spi::blocking::ReadWrite<u8> for Spi<'d, T> { 363 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBus<u8> for Spi<'d, T> {
382 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { 364 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
383 self.blocking_transfer(read, write) 365 self.blocking_transfer(read, write)
384 } 366 }
@@ -386,21 +368,5 @@ mod eh1 {
386 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 368 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
387 self.blocking_transfer_in_place(words) 369 self.blocking_transfer_in_place(words)
388 } 370 }
389
390 fn transaction<'a>(
391 &mut self,
392 operations: &mut [embedded_hal_1::spi::blocking::Operation<'a, u8>],
393 ) -> Result<(), Self::Error> {
394 use embedded_hal_1::spi::blocking::Operation;
395 for o in operations {
396 match o {
397 Operation::Read(b) => self.blocking_read(b)?,
398 Operation::Write(b) => self.blocking_write(b)?,
399 Operation::Transfer(r, w) => self.blocking_transfer(r, w)?,
400 Operation::TransferInPlace(b) => self.blocking_transfer_in_place(b)?,
401 }
402 }
403 Ok(())
404 }
405 } 371 }
406} 372}
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 116bba2ac..44c78dfef 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -35,8 +35,8 @@ embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
35embassy-net = { version = "0.1.0", path = "../embassy-net", default-features = false, optional = true } 35embassy-net = { version = "0.1.0", path = "../embassy-net", default-features = false, optional = true }
36 36
37embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } 37embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
38embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} 38embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
39embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} 39embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
40 40
41defmt = { version = "0.3", optional = true } 41defmt = { version = "0.3", optional = true }
42log = { version = "0.4.14", optional = true } 42log = { version = "0.4.14", optional = true }
diff --git a/embassy-stm32/src/eth/v1c/mod.rs b/embassy-stm32/src/eth/v1c/mod.rs
index 044e2cc9c..8abe2e172 100644
--- a/embassy-stm32/src/eth/v1c/mod.rs
+++ b/embassy-stm32/src/eth/v1c/mod.rs
@@ -45,7 +45,7 @@ pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
45macro_rules! config_pins { 45macro_rules! config_pins {
46 ($($pin:ident),*) => { 46 ($($pin:ident),*) => {
47 // NOTE(unsafe) Exclusive access to the registers 47 // NOTE(unsafe) Exclusive access to the registers
48 critical_section::with(|_| unsafe { 48 critical_section::with(|_| {
49 $( 49 $(
50 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); 50 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
51 $pin.set_speed(Speed::VeryHigh); 51 $pin.set_speed(Speed::VeryHigh);
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 34b0bc093..023ec7a0b 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -36,7 +36,7 @@ pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
36macro_rules! config_pins { 36macro_rules! config_pins {
37 ($($pin:ident),*) => { 37 ($($pin:ident),*) => {
38 // NOTE(unsafe) Exclusive access to the registers 38 // NOTE(unsafe) Exclusive access to the registers
39 critical_section::with(|_| unsafe { 39 critical_section::with(|_| {
40 $( 40 $(
41 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); 41 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
42 $pin.set_speed(Speed::VeryHigh); 42 $pin.set_speed(Speed::VeryHigh);
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index 47307530b..8858bb648 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -165,55 +165,40 @@ mod eh1 {
165 } 165 }
166 } 166 }
167} 167}
168#[cfg(all(feature = "unstable-traits", feature = "nightly"))] 168cfg_if::cfg_if! {
169mod eh1a { 169 if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
170 use super::*; 170 use futures::FutureExt;
171 use futures::FutureExt;
172 171
173 impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for ExtiInput<'d, T> { 172 impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for ExtiInput<'d, T> {
174 type WaitForHighFuture<'a> 173 type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
175 where
176 Self: 'a,
177 = impl Future<Output = Result<(), Self::Error>> + 'a;
178 174
179 fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> { 175 fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
180 self.wait_for_high().map(Ok) 176 self.wait_for_high().map(Ok)
181 } 177 }
182 178
183 type WaitForLowFuture<'a> 179 type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
184 where
185 Self: 'a,
186 = impl Future<Output = Result<(), Self::Error>> + 'a;
187 180
188 fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> { 181 fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
189 self.wait_for_low().map(Ok) 182 self.wait_for_low().map(Ok)
190 } 183 }
191 184
192 type WaitForRisingEdgeFuture<'a> 185 type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
193 where
194 Self: 'a,
195 = impl Future<Output = Result<(), Self::Error>> + 'a;
196 186
197 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> { 187 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
198 self.wait_for_rising_edge().map(Ok) 188 self.wait_for_rising_edge().map(Ok)
199 } 189 }
200 190
201 type WaitForFallingEdgeFuture<'a> 191 type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
202 where
203 Self: 'a,
204 = impl Future<Output = Result<(), Self::Error>> + 'a;
205 192
206 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> { 193 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
207 self.wait_for_falling_edge().map(Ok) 194 self.wait_for_falling_edge().map(Ok)
208 } 195 }
209 196
210 type WaitForAnyEdgeFuture<'a> 197 type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
211 where
212 Self: 'a,
213 = impl Future<Output = Result<(), Self::Error>> + 'a;
214 198
215 fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> { 199 fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
216 self.wait_for_any_edge().map(Ok) 200 self.wait_for_any_edge().map(Ok)
201 }
217 } 202 }
218 } 203 }
219} 204}
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 2c46237d6..5e9de8fd3 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -917,58 +917,46 @@ mod eh1 {
917 } 917 }
918} 918}
919 919
920#[cfg(all(feature = "unstable-traits", feature = "nightly"))] 920cfg_if::cfg_if! {
921mod eh1a { 921 if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
922 use super::super::{RxDma, TxDma}; 922 use super::{RxDma, TxDma};
923 use super::*; 923 use core::future::Future;
924 use core::future::Future; 924
925 925 impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_async::i2c::I2c
926 impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_async::i2c::I2c 926 for I2c<'d, T, TXDMA, RXDMA>
927 for I2c<'d, T, TXDMA, RXDMA> 927 {
928 { 928 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
929 type ReadFuture<'a> 929
930 where 930 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
931 Self: 'a, 931 self.read(address, buffer)
932 = impl Future<Output = Result<(), Self::Error>> + 'a; 932 }
933
934 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
935 self.read(address, buffer)
936 }
937 933
938 type WriteFuture<'a> 934 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
939 where 935 fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
940 Self: 'a, 936 self.write(address, bytes)
941 = impl Future<Output = Result<(), Self::Error>> + 'a; 937 }
942 fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
943 self.write(address, bytes)
944 }
945 938
946 type WriteReadFuture<'a> 939 type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
947 where 940 fn write_read<'a>(
948 Self: 'a, 941 &'a mut self,
949 = impl Future<Output = Result<(), Self::Error>> + 'a; 942 address: u8,
950 fn write_read<'a>( 943 bytes: &'a [u8],
951 &'a mut self, 944 buffer: &'a mut [u8],
952 address: u8, 945 ) -> Self::WriteReadFuture<'a> {
953 bytes: &'a [u8], 946 self.write_read(address, bytes, buffer)
954 buffer: &'a mut [u8], 947 }
955 ) -> Self::WriteReadFuture<'a> {
956 self.write_read(address, bytes, buffer)
957 }
958 948
959 type TransactionFuture<'a> 949 type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
960 where
961 Self: 'a,
962 = impl Future<Output = Result<(), Self::Error>> + 'a;
963 950
964 fn transaction<'a>( 951 fn transaction<'a, 'b>(
965 &'a mut self, 952 &'a mut self,
966 address: u8, 953 address: u8,
967 operations: &mut [embedded_hal_async::i2c::Operation<'a>], 954 operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
968 ) -> Self::TransactionFuture<'a> { 955 ) -> Self::TransactionFuture<'a, 'b> {
969 let _ = address; 956 let _ = address;
970 let _ = operations; 957 let _ = operations;
971 async move { todo!() } 958 async move { todo!() }
959 }
972 } 960 }
973 } 961 }
974} 962}
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index e3b647280..3352b24d2 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -445,6 +445,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
445 Ok(()) 445 Ok(())
446 } 446 }
447 447
448 pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
449 self.set_word_size(W::WORDSIZE);
450 let regs = T::regs();
451 for word in words.iter_mut() {
452 *word = transfer_word(regs, W::default())?;
453 }
454 Ok(())
455 }
456
448 pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { 457 pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
449 self.set_word_size(W::WORDSIZE); 458 self.set_word_size(W::WORDSIZE);
450 let regs = T::regs(); 459 let regs = T::regs();
@@ -453,6 +462,21 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
453 } 462 }
454 Ok(()) 463 Ok(())
455 } 464 }
465
466 pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> {
467 self.set_word_size(W::WORDSIZE);
468 let regs = T::regs();
469
470 let len = read.len().max(write.len());
471 for i in 0..len {
472 let wb = write.get(i).copied().unwrap_or_default();
473 let rb = transfer_word(regs, wb)?;
474 if let Some(r) = read.get_mut(i) {
475 *r = rb;
476 }
477 }
478 Ok(())
479 }
456} 480}
457 481
458impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { 482impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
@@ -669,6 +693,34 @@ mod eh1 {
669 type Error = Error; 693 type Error = Error;
670 } 694 }
671 695
696 impl<'d, T: Instance, Tx, Rx> embedded_hal_1::spi::blocking::SpiBusFlush for Spi<'d, T, Tx, Rx> {
697 fn flush(&mut self) -> Result<(), Self::Error> {
698 Ok(())
699 }
700 }
701
702 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusRead<u8> for Spi<'d, T, NoDma, NoDma> {
703 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
704 self.blocking_read(words)
705 }
706 }
707
708 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusWrite<u8> for Spi<'d, T, NoDma, NoDma> {
709 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
710 self.blocking_write(words)
711 }
712 }
713
714 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBus<u8> for Spi<'d, T, NoDma, NoDma> {
715 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
716 self.blocking_transfer(read, write)
717 }
718
719 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
720 self.blocking_transfer_in_place(words)
721 }
722 }
723
672 impl embedded_hal_1::spi::Error for Error { 724 impl embedded_hal_1::spi::Error for Error {
673 fn kind(&self) -> embedded_hal_1::spi::ErrorKind { 725 fn kind(&self) -> embedded_hal_1::spi::ErrorKind {
674 match *self { 726 match *self {
@@ -681,115 +733,55 @@ mod eh1 {
681 } 733 }
682} 734}
683 735
684#[cfg(all(feature = "unstable-traits", feature = "nightly"))] 736cfg_if::cfg_if! {
685mod eh1a { 737 if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
686 use super::*; 738 use core::future::Future;
687 use core::future::Future; 739 impl<'d, T: Instance, Tx, Rx> embedded_hal_async::spi::SpiBusFlush for Spi<'d, T, Tx, Rx> {
688 740 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
689 impl<'d, T: Instance, Tx: TxDma<T>, Rx> embedded_hal_async::spi::Write<u8> for Spi<'d, T, Tx, Rx> { 741
690 type WriteFuture<'a> 742 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
691 where 743 async { Ok(()) }
692 Self: 'a,
693 = impl Future<Output = Result<(), Self::Error>> + 'a;
694
695 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
696 self.write(data)
697 }
698
699 type WriteTransactionFuture<'a>
700 where
701 Self: 'a,
702 = impl Future<Output = Result<(), Self::Error>> + 'a;
703
704 fn write_transaction<'a>(
705 &'a mut self,
706 words: &'a [&'a [u8]],
707 ) -> Self::WriteTransactionFuture<'a> {
708 async move {
709 for buf in words {
710 self.write(buf).await?
711 }
712 Ok(())
713 } 744 }
714 } 745 }
715 }
716 746
717 impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::Read<u8> 747 impl<'d, T: Instance, Tx: TxDma<T>, Rx> embedded_hal_async::spi::SpiBusWrite<u8>
718 for Spi<'d, T, Tx, Rx> 748 for Spi<'d, T, Tx, Rx>
719 { 749 {
720 type ReadFuture<'a> 750 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
721 where 751
722 Self: 'a, 752 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
723 = impl Future<Output = Result<(), Self::Error>> + 'a; 753 self.write(data)
724
725 fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
726 self.read(data)
727 }
728
729 type ReadTransactionFuture<'a>
730 where
731 Self: 'a,
732 = impl Future<Output = Result<(), Self::Error>> + 'a;
733
734 fn read_transaction<'a>(
735 &'a mut self,
736 words: &'a mut [&'a mut [u8]],
737 ) -> Self::ReadTransactionFuture<'a> {
738 async move {
739 for buf in words {
740 self.read(buf).await?
741 }
742 Ok(())
743 } 754 }
744 } 755 }
745 }
746 756
747 impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::ReadWrite<u8> 757 impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::SpiBusRead<u8>
748 for Spi<'d, T, Tx, Rx> 758 for Spi<'d, T, Tx, Rx>
749 { 759 {
750 type TransferFuture<'a> 760 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
751 where 761
752 Self: 'a, 762 fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
753 = impl Future<Output = Result<(), Self::Error>> + 'a; 763 self.read(data)
754 764 }
755 fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { 765 }
756 self.transfer(rx, tx) 766
757 } 767 impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::SpiBus<u8>
758 768 for Spi<'d, T, Tx, Rx>
759 type TransferInPlaceFuture<'a> 769 {
760 where 770 type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
761 Self: 'a, 771
762 = impl Future<Output = Result<(), Self::Error>> + 'a; 772 fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> {
763 773 self.transfer(rx, tx)
764 fn transfer_in_place<'a>( 774 }
765 &'a mut self, 775
766 words: &'a mut [u8], 776 type TransferInPlaceFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
767 ) -> Self::TransferInPlaceFuture<'a> { 777
768 // TODO: Implement async version 778 fn transfer_in_place<'a>(
769 let result = self.blocking_transfer_in_place(words); 779 &'a mut self,
770 async move { result } 780 words: &'a mut [u8],
771 } 781 ) -> Self::TransferInPlaceFuture<'a> {
772 782 // TODO: Implement async version
773 type TransactionFuture<'a> 783 let result = self.blocking_transfer_in_place(words);
774 where 784 async move { result }
775 Self: 'a,
776 = impl Future<Output = Result<(), Self::Error>> + 'a;
777
778 fn transaction<'a>(
779 &'a mut self,
780 operations: &'a mut [embedded_hal_async::spi::Operation<'a, u8>],
781 ) -> Self::TransactionFuture<'a> {
782 use embedded_hal_1::spi::blocking::Operation;
783 async move {
784 for o in operations {
785 match o {
786 Operation::Read(b) => self.read(b).await?,
787 Operation::Write(b) => self.write(b).await?,
788 Operation::Transfer(r, w) => self.transfer(r, w).await?,
789 Operation::TransferInPlace(b) => self.transfer_in_place(b).await?,
790 }
791 }
792 Ok(())
793 } 785 }
794 } 786 }
795 } 787 }
@@ -862,7 +854,7 @@ pub(crate) mod sealed {
862 } 854 }
863} 855}
864 856
865pub trait Word: Copy + 'static + sealed::Word {} 857pub trait Word: Copy + 'static + sealed::Word + Default {}
866 858
867impl Word for u8 {} 859impl Word for u8 {}
868impl Word for u16 {} 860impl Word for u16 {}
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 60e607126..a62c49c7b 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -275,45 +275,36 @@ mod eh1 {
275 } 275 }
276} 276}
277 277
278#[cfg(all(feature = "unstable-traits", feature = "nightly"))] 278cfg_if::cfg_if! {
279mod eh1a { 279 if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
280 use super::*; 280 use core::future::Future;
281 use core::future::Future;
282 281
283 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma> 282 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma>
284 where
285 TxDma: crate::usart::TxDma<T>,
286 {
287 type WriteFuture<'a>
288 where 283 where
289 Self: 'a, 284 TxDma: crate::usart::TxDma<T>,
290 = impl Future<Output = Result<(), Self::Error>> + 'a; 285 {
286 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
291 287
292 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> {
293 self.write(buf) 289 self.write(buf)
294 } 290 }
295 291
296 type FlushFuture<'a> 292 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
297 where
298 Self: 'a,
299 = impl Future<Output = Result<(), Self::Error>> + 'a;
300 293
301 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { 294 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
302 async move { Ok(()) } 295 async move { Ok(()) }
296 }
303 } 297 }
304 }
305 298
306 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma> 299 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma>
307 where
308 RxDma: crate::usart::RxDma<T>,
309 {
310 type ReadFuture<'a>
311 where 300 where
312 Self: 'a, 301 RxDma: crate::usart::RxDma<T>,
313 = impl Future<Output = Result<(), Self::Error>> + 'a; 302 {
303 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
314 304
315 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { 305 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
316 self.read(buf) 306 self.read(buf)
307 }
317 } 308 }
318 } 309 }
319} 310}
diff --git a/embassy-traits/Cargo.toml b/embassy-traits/Cargo.toml
index fa2082ef3..e23259eb4 100644
--- a/embassy-traits/Cargo.toml
+++ b/embassy-traits/Cargo.toml
@@ -9,8 +9,8 @@ std = []
9 9
10[dependencies] 10[dependencies]
11embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } 11embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
12embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy" } 12embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2" }
13embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"} 13embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2"}
14embedded-storage = "0.3.0" 14embedded-storage = "0.3.0"
15embedded-storage-async = "0.3.0" 15embedded-storage-async = "0.3.0"
16nb = "1.0.0" 16nb = "1.0.0"
diff --git a/embassy-traits/src/adapter.rs b/embassy-traits/src/adapter.rs
index 735f9aacc..b709f389f 100644
--- a/embassy-traits/src/adapter.rs
+++ b/embassy-traits/src/adapter.rs
@@ -39,18 +39,9 @@ where
39 + blocking::i2c::Read<Error = E> 39 + blocking::i2c::Read<Error = E>
40 + blocking::i2c::Write<Error = E>, 40 + blocking::i2c::Write<Error = E>,
41{ 41{
42 type WriteFuture<'a> 42 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
43 where 43 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
44 Self: 'a, 44 type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where 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;
54 45
55 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 46 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
56 async move { self.wrapped.read(address, buffer) } 47 async move { self.wrapped.read(address, buffer) }
@@ -69,16 +60,13 @@ where
69 async move { self.wrapped.write_read(address, bytes, buffer) } 60 async move { self.wrapped.write_read(address, bytes, buffer) }
70 } 61 }
71 62
72 type TransactionFuture<'a> 63 type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
73 where
74 Self: 'a,
75 = impl Future<Output = Result<(), Self::Error>> + 'a;
76 64
77 fn transaction<'a>( 65 fn transaction<'a, 'b>(
78 &'a mut self, 66 &'a mut self,
79 address: u8, 67 address: u8,
80 operations: &mut [embedded_hal_async::i2c::Operation<'a>], 68 operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
81 ) -> Self::TransactionFuture<'a> { 69 ) -> Self::TransactionFuture<'a, 'b> {
82 let _ = address; 70 let _ = address;
83 let _ = operations; 71 let _ = operations;
84 async move { todo!() } 72 async move { todo!() }
@@ -97,15 +85,12 @@ where
97 type Error = E; 85 type Error = E;
98} 86}
99 87
100impl<T, E> embedded_hal_async::spi::ReadWrite<u8> for BlockingAsync<T> 88impl<T, E> embedded_hal_async::spi::SpiBus<u8> for BlockingAsync<T>
101where 89where
102 E: embedded_hal_1::spi::Error + 'static, 90 E: embedded_hal_1::spi::Error + 'static,
103 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, 91 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
104{ 92{
105 type TransferFuture<'a> 93 type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
106 where
107 Self: 'a,
108 = impl Future<Output = Result<(), Self::Error>> + 'a;
109 94
110 fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Self::TransferFuture<'a> { 95 fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Self::TransferFuture<'a> {
111 async move { 96 async move {
@@ -118,37 +103,31 @@ where
118 } 103 }
119 } 104 }
120 105
121 type TransferInPlaceFuture<'a> 106 type TransferInPlaceFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
122 where
123 Self: 'a,
124 = impl Future<Output = Result<(), Self::Error>> + 'a;
125 107
126 fn transfer_in_place<'a>(&'a mut self, _: &'a mut [u8]) -> Self::TransferInPlaceFuture<'a> { 108 fn transfer_in_place<'a>(&'a mut self, _: &'a mut [u8]) -> Self::TransferInPlaceFuture<'a> {
127 async move { todo!() } 109 async move { todo!() }
128 } 110 }
111}
129 112
130 type TransactionFuture<'a> 113impl<T, E> embedded_hal_async::spi::SpiBusFlush for BlockingAsync<T>
131 where 114where
132 Self: 'a, 115 E: embedded_hal_1::spi::Error + 'static,
133 = impl Future<Output = Result<(), Self::Error>> + 'a; 116 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
117{
118 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
134 119
135 fn transaction<'a>( 120 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
136 &'a mut self, 121 async move { Ok(()) }
137 _: &'a mut [embedded_hal_async::spi::Operation<'a, u8>],
138 ) -> Self::TransactionFuture<'a> {
139 async move { todo!() }
140 } 122 }
141} 123}
142 124
143impl<T, E> embedded_hal_async::spi::Write<u8> for BlockingAsync<T> 125impl<T, E> embedded_hal_async::spi::SpiBusWrite<u8> for BlockingAsync<T>
144where 126where
145 E: embedded_hal_1::spi::Error + 'static, 127 E: embedded_hal_1::spi::Error + 'static,
146 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, 128 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
147{ 129{
148 type WriteFuture<'a> 130 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
149 where
150 Self: 'a,
151 = impl Future<Output = Result<(), Self::Error>> + 'a;
152 131
153 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { 132 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
154 async move { 133 async move {
@@ -156,26 +135,14 @@ where
156 Ok(()) 135 Ok(())
157 } 136 }
158 } 137 }
159
160 type WriteTransactionFuture<'a>
161 where
162 Self: 'a,
163 = impl Future<Output = Result<(), Self::Error>> + 'a;
164
165 fn write_transaction<'a>(&'a mut self, _: &'a [&'a [u8]]) -> Self::WriteTransactionFuture<'a> {
166 async move { todo!() }
167 }
168} 138}
169 139
170impl<T, E> embedded_hal_async::spi::Read<u8> for BlockingAsync<T> 140impl<T, E> embedded_hal_async::spi::SpiBusRead<u8> for BlockingAsync<T>
171where 141where
172 E: embedded_hal_1::spi::Error + 'static, 142 E: embedded_hal_1::spi::Error + 'static,
173 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, 143 T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
174{ 144{
175 type ReadFuture<'a> 145 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
176 where
177 Self: 'a,
178 = impl Future<Output = Result<(), Self::Error>> + 'a;
179 146
180 fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { 147 fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
181 async move { 148 async move {
@@ -183,18 +150,6 @@ where
183 Ok(()) 150 Ok(())
184 } 151 }
185 } 152 }
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 }
198} 153}
199 154
200// Uart implementatinos 155// Uart implementatinos
@@ -211,10 +166,7 @@ where
211 T: serial::Read<u8, Error = E>, 166 T: serial::Read<u8, Error = E>,
212 E: embedded_hal_1::serial::Error + 'static, 167 E: embedded_hal_1::serial::Error + 'static,
213{ 168{
214 type ReadFuture<'a> 169 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where T: 'a;
215 where
216 T: 'a,
217 = impl Future<Output = Result<(), Self::Error>> + 'a;
218 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { 170 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
219 async move { 171 async move {
220 let mut pos = 0; 172 let mut pos = 0;
@@ -238,18 +190,12 @@ where
238 T: blocking::serial::Write<u8, Error = E> + serial::Read<u8, Error = E>, 190 T: blocking::serial::Write<u8, Error = E> + serial::Read<u8, Error = E>,
239 E: embedded_hal_1::serial::Error + 'static, 191 E: embedded_hal_1::serial::Error + 'static,
240{ 192{
241 type WriteFuture<'a> 193 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where T: 'a;
242 where
243 T: 'a,
244 = impl Future<Output = Result<(), Self::Error>> + 'a;
245 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { 194 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
246 async move { self.wrapped.bwrite_all(buf) } 195 async move { self.wrapped.bwrite_all(buf) }
247 } 196 }
248 197
249 type FlushFuture<'a> 198 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where T: 'a;
250 where
251 T: 'a,
252 = impl Future<Output = Result<(), Self::Error>> + 'a;
253 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { 199 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
254 async move { self.wrapped.bflush() } 200 async move { self.wrapped.bflush() }
255 } 201 }
@@ -273,18 +219,12 @@ where
273 const WRITE_SIZE: usize = <T as NorFlash>::WRITE_SIZE; 219 const WRITE_SIZE: usize = <T as NorFlash>::WRITE_SIZE;
274 const ERASE_SIZE: usize = <T as NorFlash>::ERASE_SIZE; 220 const ERASE_SIZE: usize = <T as NorFlash>::ERASE_SIZE;
275 221
276 type WriteFuture<'a> 222 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
277 where
278 Self: 'a,
279 = impl Future<Output = Result<(), Self::Error>> + 'a;
280 fn write<'a>(&'a mut self, offset: u32, data: &'a [u8]) -> Self::WriteFuture<'a> { 223 fn write<'a>(&'a mut self, offset: u32, data: &'a [u8]) -> Self::WriteFuture<'a> {
281 async move { self.wrapped.write(offset, data) } 224 async move { self.wrapped.write(offset, data) }
282 } 225 }
283 226
284 type EraseFuture<'a> 227 type EraseFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
285 where
286 Self: 'a,
287 = impl Future<Output = Result<(), Self::Error>> + 'a;
288 fn erase<'a>(&'a mut self, from: u32, to: u32) -> Self::EraseFuture<'a> { 228 fn erase<'a>(&'a mut self, from: u32, to: u32) -> Self::EraseFuture<'a> {
289 async move { self.wrapped.erase(from, to) } 229 async move { self.wrapped.erase(from, to) }
290 } 230 }
@@ -295,10 +235,7 @@ where
295 T: ReadNorFlash, 235 T: ReadNorFlash,
296{ 236{
297 const READ_SIZE: usize = <T as ReadNorFlash>::READ_SIZE; 237 const READ_SIZE: usize = <T as ReadNorFlash>::READ_SIZE;
298 type ReadFuture<'a> 238 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
299 where
300 Self: 'a,
301 = impl Future<Output = Result<(), Self::Error>> + 'a;
302 fn read<'a>(&'a mut self, address: u32, data: &'a mut [u8]) -> Self::ReadFuture<'a> { 239 fn read<'a>(&'a mut self, address: u32, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
303 async move { self.wrapped.read(address, data) } 240 async move { self.wrapped.read(address, data) }
304 } 241 }
diff --git a/embassy/Cargo.toml b/embassy/Cargo.toml
index 9b7e72078..902a3bcb7 100644
--- a/embassy/Cargo.toml
+++ b/embassy/Cargo.toml
@@ -55,8 +55,8 @@ defmt = { version = "0.3", optional = true }
55log = { version = "0.4.14", optional = true } 55log = { version = "0.4.14", optional = true }
56 56
57embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" } 57embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" }
58embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} 58embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
59embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} 59embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2", optional = true}
60 60
61futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] } 61futures = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] }
62pin-project = { version = "1.0.8", default-features = false } 62pin-project = { version = "1.0.8", default-features = false }
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs
index acc71e105..6b24b5989 100644
--- a/embassy/src/lib.rs
+++ b/embassy/src/lib.rs
@@ -1,12 +1,7 @@
1#![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)] 1#![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)]
2#![cfg_attr( 2#![cfg_attr(
3 feature = "nightly", 3 feature = "nightly",
4 feature( 4 feature(generic_associated_types, type_alias_impl_trait)
5 const_fn_trait_bound,
6 const_fn_fn_ptr_basics,
7 generic_associated_types,
8 type_alias_impl_trait
9 )
10)] 5)]
11#![allow(clippy::new_without_default)] 6#![allow(clippy::new_without_default)]
12 7
diff --git a/embassy/src/time/delay.rs b/embassy/src/time/delay.rs
index 27ec61fe6..06ed8ec4e 100644
--- a/embassy/src/time/delay.rs
+++ b/embassy/src/time/delay.rs
@@ -31,32 +31,26 @@ mod eh1 {
31 } 31 }
32} 32}
33 33
34#[cfg(all(feature = "unstable-traits", feature = "nightly"))] 34cfg_if::cfg_if! {
35mod eh1a { 35 if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
36 use super::*; 36 use crate::time::Timer;
37 use crate::time::Timer; 37 use core::future::Future;
38 use core::future::Future; 38 use futures::FutureExt;
39 use futures::FutureExt;
40 39
41 impl embedded_hal_async::delay::DelayUs for Delay { 40 impl embedded_hal_async::delay::DelayUs for Delay {
42 type Error = core::convert::Infallible; 41 type Error = core::convert::Infallible;
43 42
44 type DelayUsFuture<'a> 43 type DelayUsFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
45 where
46 Self: 'a,
47 = impl Future<Output = Result<(), Self::Error>> + 'a;
48 44
49 fn delay_us(&mut self, micros: u32) -> Self::DelayUsFuture<'_> { 45 fn delay_us(&mut self, micros: u32) -> Self::DelayUsFuture<'_> {
50 Timer::after(Duration::from_micros(micros as _)).map(Ok) 46 Timer::after(Duration::from_micros(micros as _)).map(Ok)
51 } 47 }
52 48
53 type DelayMsFuture<'a> 49 type DelayMsFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
54 where
55 Self: 'a,
56 = impl Future<Output = Result<(), Self::Error>> + 'a;
57 50
58 fn delay_ms(&mut self, millis: u32) -> Self::DelayMsFuture<'_> { 51 fn delay_ms(&mut self, millis: u32) -> Self::DelayMsFuture<'_> {
59 Timer::after(Duration::from_millis(millis as _)).map(Ok) 52 Timer::after(Duration::from_millis(millis as _)).map(Ok)
53 }
60 } 54 }
61 } 55 }
62} 56}
diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml
index 2d9c99530..7fdc27ffa 100644
--- a/examples/nrf/Cargo.toml
+++ b/examples/nrf/Cargo.toml
@@ -6,7 +6,7 @@ version = "0.1.0"
6 6
7[features] 7[features]
8default = ["nightly"] 8default = ["nightly"]
9nightly = ["embassy-nrf/nightly"] 9nightly = ["embassy-nrf/nightly", "embassy-nrf/unstable-traits"]
10 10
11[dependencies] 11[dependencies]
12embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } 12embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index c067fbbcf..830e54174 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -1,6 +1,6 @@
1[package] 1[package]
2authors = ["Dario Nieuwenhuis <[email protected]>"] 2authors = ["Dario Nieuwenhuis <[email protected]>"]
3edition = "2018" 3edition = "2021"
4name = "embassy-rp-examples" 4name = "embassy-rp-examples"
5version = "0.1.0" 5version = "0.1.0"
6 6
@@ -15,9 +15,12 @@ defmt-rtt = "0.3"
15 15
16cortex-m = "0.7.3" 16cortex-m = "0.7.3"
17cortex-m-rt = "0.7.0" 17cortex-m-rt = "0.7.0"
18embedded-hal = "0.2.6"
19panic-probe = { version = "0.3", features = ["print-defmt"] } 18panic-probe = { version = "0.3", features = ["print-defmt"] }
20futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] } 19futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] }
21display-interface-spi = "0.4.1" 20display-interface-spi = "0.4.1"
22embedded-graphics = "0.7.1" 21embedded-graphics = "0.7.1"
23st7789 = "0.6.1" 22st7789 = "0.6.1"
23
24embedded-hal = { version = "1.0.0-alpha.7", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2" }
25display-interface = "0.4.1"
26byte-slice-cast = { version = "1.2.0", default-features = false }
diff --git a/examples/rp/src/bin/spi_display.rs b/examples/rp/src/bin/spi_display.rs
index 01149c250..b2854afcb 100644
--- a/examples/rp/src/bin/spi_display.rs
+++ b/examples/rp/src/bin/spi_display.rs
@@ -6,16 +6,14 @@
6mod example_common; 6mod example_common;
7 7
8use core::cell::RefCell; 8use core::cell::RefCell;
9use core::fmt::Debug;
10 9
11use defmt::*; 10use defmt::*;
12use display_interface_spi::SPIInterfaceNoCS;
13use embassy::executor::Spawner; 11use embassy::executor::Spawner;
14use embassy::time::Delay; 12use embassy::time::Delay;
15use embassy_rp::peripherals; 13use embassy_rp::gpio::{Level, Output};
16use embassy_rp::spi; 14use embassy_rp::spi;
17use embassy_rp::spi::Spi; 15use embassy_rp::spi::Spi;
18use embassy_rp::{gpio, Peripherals}; 16use embassy_rp::Peripherals;
19use embedded_graphics::image::{Image, ImageRawLE}; 17use embedded_graphics::image::{Image, ImageRawLE};
20use embedded_graphics::mono_font::ascii::FONT_10X20; 18use embedded_graphics::mono_font::ascii::FONT_10X20;
21use embedded_graphics::mono_font::MonoTextStyle; 19use embedded_graphics::mono_font::MonoTextStyle;
@@ -23,9 +21,15 @@ use embedded_graphics::pixelcolor::Rgb565;
23use embedded_graphics::prelude::*; 21use embedded_graphics::prelude::*;
24use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle}; 22use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle};
25use embedded_graphics::text::Text; 23use embedded_graphics::text::Text;
26use gpio::{Level, Output};
27use st7789::{Orientation, ST7789}; 24use st7789::{Orientation, ST7789};
28 25
26use crate::my_display_interface::SPIDeviceInterface;
27use crate::shared_spi::SpiDeviceWithCs;
28use crate::touch::Touch;
29
30//const DISPLAY_FREQ: u32 = 64_000_000;
31const TOUCH_FREQ: u32 = 200_000;
32
29#[embassy::main] 33#[embassy::main]
30async fn main(_spawner: Spawner, p: Peripherals) { 34async fn main(_spawner: Spawner, p: Peripherals) {
31 info!("Hello World!"); 35 info!("Hello World!");
@@ -42,17 +46,16 @@ async fn main(_spawner: Spawner, p: Peripherals) {
42 46
43 // create SPI 47 // create SPI
44 let mut config = spi::Config::default(); 48 let mut config = spi::Config::default();
45 config.frequency = DISPLAY_FREQ; 49 config.frequency = TOUCH_FREQ; // use the lowest freq
46 config.phase = spi::Phase::CaptureOnSecondTransition; 50 config.phase = spi::Phase::CaptureOnSecondTransition;
47 config.polarity = spi::Polarity::IdleHigh; 51 config.polarity = spi::Polarity::IdleHigh;
48 52
49 let spi = RefCell::new(SpiState { 53 let spi_bus = RefCell::new(Spi::new(p.SPI1, clk, mosi, miso, config));
50 last_mode: SpiMode::Display,
51 spi: Spi::new(p.SPI1, clk, mosi, miso, config),
52 display_cs: Output::new(display_cs, Level::Low),
53 });
54 54
55 let mut touch = Touch::new(TouchSpi(&spi), Output::new(touch_cs, Level::High)); 55 let display_spi = SpiDeviceWithCs::new(&spi_bus, Output::new(display_cs, Level::High));
56 let touch_spi = SpiDeviceWithCs::new(&spi_bus, Output::new(touch_cs, Level::High));
57
58 let mut touch = Touch::new(touch_spi);
56 59
57 let dcx = Output::new(dcx, Level::Low); 60 let dcx = Output::new(dcx, Level::Low);
58 let rst = Output::new(rst, Level::Low); 61 let rst = Output::new(rst, Level::Low);
@@ -62,7 +65,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
62 let _bl = Output::new(bl, Level::High); 65 let _bl = Output::new(bl, Level::High);
63 66
64 // display interface abstraction from SPI and DC 67 // display interface abstraction from SPI and DC
65 let di = SPIInterfaceNoCS::new(DisplaySpi(&spi), dcx); 68 let di = SPIDeviceInterface::new(display_spi, dcx);
66 69
67 // create driver 70 // create driver
68 let mut display = ST7789::new(di, rst, 240, 320); 71 let mut display = ST7789::new(di, rst, 240, 320);
@@ -104,107 +107,293 @@ async fn main(_spawner: Spawner, p: Peripherals) {
104 } 107 }
105} 108}
106 109
107#[derive(Debug, Clone, Copy, PartialEq, Eq)] 110mod shared_spi {
108enum SpiMode { 111 use core::cell::RefCell;
109 Display, 112 use core::fmt::Debug;
110 Touch,
111}
112 113
113struct SpiState { 114 use embedded_hal::digital::blocking::OutputPin;
114 spi: Spi<'static, peripherals::SPI1>, 115 use embedded_hal::spi;
115 display_cs: Output<'static, peripherals::PIN_9>, 116 use embedded_hal::spi::blocking::SpiDevice;
116 117
117 last_mode: SpiMode, 118 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
118} 119 pub enum SpiDeviceWithCsError<BUS, CS> {
120 #[allow(unused)] // will probably use in the future when adding a flush() to SpiBus
121 Spi(BUS),
122 Cs(CS),
123 }
119 124
120const DISPLAY_FREQ: u32 = 64_000_000; 125 impl<BUS, CS> spi::Error for SpiDeviceWithCsError<BUS, CS>
121const TOUCH_FREQ: u32 = 200_000; 126 where
127 BUS: spi::Error + Debug,
128 CS: Debug,
129 {
130 fn kind(&self) -> spi::ErrorKind {
131 match self {
132 Self::Spi(e) => e.kind(),
133 Self::Cs(_) => spi::ErrorKind::Other,
134 }
135 }
136 }
122 137
123struct DisplaySpi<'a>(&'a RefCell<SpiState>); 138 pub struct SpiDeviceWithCs<'a, BUS, CS> {
124impl<'a> embedded_hal::blocking::spi::Write<u8> for DisplaySpi<'a> { 139 bus: &'a RefCell<BUS>,
125 type Error = core::convert::Infallible; 140 cs: CS,
141 }
126 142
127 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 143 impl<'a, BUS, CS> SpiDeviceWithCs<'a, BUS, CS> {
128 let this = &mut *self.0.borrow_mut(); 144 pub fn new(bus: &'a RefCell<BUS>, cs: CS) -> Self {
129 if this.last_mode != SpiMode::Display { 145 Self { bus, cs }
130 this.spi.set_frequency(DISPLAY_FREQ);
131 this.display_cs.set_low();
132 this.last_mode = SpiMode::Display;
133 } 146 }
134 this.spi.write(words).unwrap();
135 Ok(())
136 } 147 }
137}
138 148
139struct TouchSpi<'a>(&'a RefCell<SpiState>); 149 impl<'a, BUS, CS> spi::ErrorType for SpiDeviceWithCs<'a, BUS, CS>
140impl<'a> embedded_hal::blocking::spi::Transfer<u8> for TouchSpi<'a> { 150 where
141 type Error = core::convert::Infallible; 151 BUS: spi::ErrorType,
152 CS: OutputPin,
153 {
154 type Error = SpiDeviceWithCsError<BUS::Error, CS::Error>;
155 }
156
157 impl<'a, BUS, CS> SpiDevice for SpiDeviceWithCs<'a, BUS, CS>
158 where
159 BUS: spi::blocking::SpiBusFlush,
160 CS: OutputPin,
161 {
162 type Bus = BUS;
163
164 fn transaction<R>(
165 &mut self,
166 f: impl FnOnce(&mut Self::Bus) -> Result<R, BUS::Error>,
167 ) -> Result<R, Self::Error> {
168 let mut bus = self.bus.borrow_mut();
169 self.cs.set_low().map_err(SpiDeviceWithCsError::Cs)?;
142 170
143 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { 171 let f_res = f(&mut bus);
144 let this = &mut *self.0.borrow_mut(); 172
145 if this.last_mode != SpiMode::Touch { 173 // On failure, it's important to still flush and deassert CS.
146 this.spi.set_frequency(TOUCH_FREQ); 174 let flush_res = bus.flush();
147 this.display_cs.set_high(); 175 let cs_res = self.cs.set_high();
148 this.last_mode = SpiMode::Touch; 176
177 let f_res = f_res.map_err(SpiDeviceWithCsError::Spi)?;
178 flush_res.map_err(SpiDeviceWithCsError::Spi)?;
179 cs_res.map_err(SpiDeviceWithCsError::Cs)?;
180
181 Ok(f_res)
149 } 182 }
150 this.spi.transfer(words).unwrap();
151 Ok(words)
152 } 183 }
153} 184}
154 185
155struct Calibration { 186/// Driver for the XPT2046 resistive touchscreen sensor
156 x1: i32, 187mod touch {
157 x2: i32, 188 use embedded_hal::spi::blocking::{SpiBus, SpiBusRead, SpiBusWrite, SpiDevice};
158 y1: i32, 189
159 y2: i32, 190 struct Calibration {
160 sx: i32, 191 x1: i32,
161 sy: i32, 192 x2: i32,
162} 193 y1: i32,
194 y2: i32,
195 sx: i32,
196 sy: i32,
197 }
198
199 const CALIBRATION: Calibration = Calibration {
200 x1: 3880,
201 x2: 340,
202 y1: 262,
203 y2: 3850,
204 sx: 320,
205 sy: 240,
206 };
207
208 pub struct Touch<SPI: SpiDevice> {
209 spi: SPI,
210 }
211
212 impl<SPI> Touch<SPI>
213 where
214 SPI: SpiDevice,
215 SPI::Bus: SpiBus,
216 {
217 pub fn new(spi: SPI) -> Self {
218 Self { spi }
219 }
220
221 pub fn read(&mut self) -> Option<(i32, i32)> {
222 let mut x = [0; 2];
223 let mut y = [0; 2];
224 self.spi
225 .transaction(|bus| {
226 bus.write(&[0x90])?;
227 bus.read(&mut x)?;
228 bus.write(&[0xd0])?;
229 bus.read(&mut y)?;
230 Ok(())
231 })
232 .unwrap();
233
234 let x = (u16::from_be_bytes(x) >> 3) as i32;
235 let y = (u16::from_be_bytes(y) >> 3) as i32;
236
237 let cal = &CALIBRATION;
163 238
164const CALIBRATION: Calibration = Calibration { 239 let x = ((x - cal.x1) * cal.sx / (cal.x2 - cal.x1)).clamp(0, cal.sx);
165 x1: 3880, 240 let y = ((y - cal.y1) * cal.sy / (cal.y2 - cal.y1)).clamp(0, cal.sy);
166 x2: 340, 241 if x == 0 && y == 0 {
167 y1: 262, 242 None
168 y2: 3850, 243 } else {
169 sx: 320, 244 Some((x, y))
170 sy: 240, 245 }
171}; 246 }
172 247 }
173struct Touch<
174 SPI: embedded_hal::blocking::spi::Transfer<u8>,
175 CS: embedded_hal::digital::v2::OutputPin,
176> {
177 spi: SPI,
178 cs: CS,
179} 248}
180 249
181impl<SPI: embedded_hal::blocking::spi::Transfer<u8>, CS: embedded_hal::digital::v2::OutputPin> 250mod my_display_interface {
182 Touch<SPI, CS> 251 use display_interface::{DataFormat, DisplayError, WriteOnlyDataCommand};
183where 252 use embedded_hal::digital::blocking::OutputPin;
184 SPI::Error: Debug, 253 use embedded_hal::spi::blocking::{SpiBusWrite, SpiDevice};
185 CS::Error: Debug, 254
186{ 255 /// SPI display interface.
187 pub fn new(spi: SPI, cs: CS) -> Self { 256 ///
188 Self { spi, cs } 257 /// This combines the SPI peripheral and a data/command pin
258 pub struct SPIDeviceInterface<SPI, DC> {
259 spi: SPI,
260 dc: DC,
189 } 261 }
190 262
191 pub fn read(&mut self) -> Option<(i32, i32)> { 263 impl<SPI, DC> SPIDeviceInterface<SPI, DC>
192 self.cs.set_low().unwrap(); 264 where
193 let mut buf = [0x90, 0x00, 0x00, 0xd0, 0x00, 0x00]; 265 SPI: SpiDevice,
194 self.spi.transfer(&mut buf).unwrap(); 266 SPI::Bus: SpiBusWrite,
195 self.cs.set_high().unwrap(); 267 DC: OutputPin,
268 {
269 /// Create new SPI interface for communciation with a display driver
270 pub fn new(spi: SPI, dc: DC) -> Self {
271 Self { spi, dc }
272 }
273 }
196 274
197 let x = ((buf[1] as u32) << 5 | (buf[2] as u32) >> 3) as i32; 275 impl<SPI, DC> WriteOnlyDataCommand for SPIDeviceInterface<SPI, DC>
198 let y = ((buf[4] as u32) << 5 | (buf[5] as u32) >> 3) as i32; 276 where
277 SPI: SpiDevice,
278 SPI::Bus: SpiBusWrite,
279 DC: OutputPin,
280 {
281 fn send_commands(&mut self, cmds: DataFormat<'_>) -> Result<(), DisplayError> {
282 let r = self.spi.transaction(|bus| {
283 // 1 = data, 0 = command
284 if let Err(_) = self.dc.set_low() {
285 return Ok(Err(DisplayError::DCError));
286 }
287
288 // Send words over SPI
289 send_u8(bus, cmds)?;
290
291 Ok(Ok(()))
292 });
293 r.map_err(|_| DisplayError::BusWriteError)?
294 }
199 295
200 let cal = &CALIBRATION; 296 fn send_data(&mut self, buf: DataFormat<'_>) -> Result<(), DisplayError> {
297 let r = self.spi.transaction(|bus| {
298 // 1 = data, 0 = command
299 if let Err(_) = self.dc.set_high() {
300 return Ok(Err(DisplayError::DCError));
301 }
302
303 // Send words over SPI
304 send_u8(bus, buf)?;
305
306 Ok(Ok(()))
307 });
308 r.map_err(|_| DisplayError::BusWriteError)?
309 }
310 }
201 311
202 let x = ((x - cal.x1) * cal.sx / (cal.x2 - cal.x1)).clamp(0, cal.sx); 312 fn send_u8<T: SpiBusWrite>(spi: &mut T, words: DataFormat<'_>) -> Result<(), T::Error> {
203 let y = ((y - cal.y1) * cal.sy / (cal.y2 - cal.y1)).clamp(0, cal.sy); 313 match words {
204 if x == 0 && y == 0 { 314 DataFormat::U8(slice) => spi.write(slice),
205 None 315 DataFormat::U16(slice) => {
206 } else { 316 use byte_slice_cast::*;
207 Some((x, y)) 317 spi.write(slice.as_byte_slice())
318 }
319 DataFormat::U16LE(slice) => {
320 use byte_slice_cast::*;
321 for v in slice.as_mut() {
322 *v = v.to_le();
323 }
324 spi.write(slice.as_byte_slice())
325 }
326 DataFormat::U16BE(slice) => {
327 use byte_slice_cast::*;
328 for v in slice.as_mut() {
329 *v = v.to_be();
330 }
331 spi.write(slice.as_byte_slice())
332 }
333 DataFormat::U8Iter(iter) => {
334 let mut buf = [0; 32];
335 let mut i = 0;
336
337 for v in iter.into_iter() {
338 buf[i] = v;
339 i += 1;
340
341 if i == buf.len() {
342 spi.write(&buf)?;
343 i = 0;
344 }
345 }
346
347 if i > 0 {
348 spi.write(&buf[..i])?;
349 }
350
351 Ok(())
352 }
353 DataFormat::U16LEIter(iter) => {
354 use byte_slice_cast::*;
355 let mut buf = [0; 32];
356 let mut i = 0;
357
358 for v in iter.map(u16::to_le) {
359 buf[i] = v;
360 i += 1;
361
362 if i == buf.len() {
363 spi.write(&buf.as_byte_slice())?;
364 i = 0;
365 }
366 }
367
368 if i > 0 {
369 spi.write(&buf[..i].as_byte_slice())?;
370 }
371
372 Ok(())
373 }
374 DataFormat::U16BEIter(iter) => {
375 use byte_slice_cast::*;
376 let mut buf = [0; 64];
377 let mut i = 0;
378 let len = buf.len();
379
380 for v in iter.map(u16::to_be) {
381 buf[i] = v;
382 i += 1;
383
384 if i == len {
385 spi.write(&buf.as_byte_slice())?;
386 i = 0;
387 }
388 }
389
390 if i > 0 {
391 spi.write(&buf[..i].as_byte_slice())?;
392 }
393
394 Ok(())
395 }
396 _ => unimplemented!(),
208 } 397 }
209 } 398 }
210} 399}
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml
index 8b6441655..c53f04e1c 100644
--- a/examples/stm32f4/Cargo.toml
+++ b/examples/stm32f4/Cargo.toml
@@ -8,7 +8,7 @@ resolver = "2"
8 8
9[dependencies] 9[dependencies]
10embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "unstable-traits"] } 10embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "unstable-traits"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "usb-otg"] } 11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "usb-otg"] }
12 12
13defmt = "0.3" 13defmt = "0.3"
14defmt-rtt = "0.3" 14defmt-rtt = "0.3"
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 2929f539c..2e761df8f 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -19,7 +19,7 @@ defmt-rtt = "0.3"
19cortex-m = "0.7.3" 19cortex-m = "0.7.3"
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21embedded-hal = "0.2.6" 21embedded-hal = "0.2.6"
22embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"} 22embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2"}
23panic-probe = { version = "0.3", features = ["print-defmt"] } 23panic-probe = { version = "0.3", features = ["print-defmt"] }
24futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 24futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
25heapless = { version = "0.7.5", default-features = false } 25heapless = { version = "0.7.5", default-features = false }
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index 1d5a83fa1..4b1f9a912 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -18,7 +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"} 21embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2"}
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "0.3", features = ["print-defmt"] }
23futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 23futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
24heapless = { version = "0.7.5", default-features = false } 24heapless = { version = "0.7.5", default-features = false }
diff --git a/examples/stm32l4/src/bin/spi_blocking_async.rs b/examples/stm32l4/src/bin/spi_blocking_async.rs
index bcd2e32d5..89925d309 100644
--- a/examples/stm32l4/src/bin/spi_blocking_async.rs
+++ b/examples/stm32l4/src/bin/spi_blocking_async.rs
@@ -12,7 +12,7 @@ use 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; 14use embassy_traits::adapter::BlockingAsync;
15use embedded_hal_async::spi::ReadWrite; 15use embedded_hal_async::spi::SpiBus;
16use example_common::*; 16use example_common::*;
17 17
18#[embassy::main] 18#[embassy::main]
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index fe15a4c67..72a832460 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -1,6 +1,6 @@
1# Before upgrading check that everything is available on all tier1 targets here: 1# Before upgrading check that everything is available on all tier1 targets here:
2# https://rust-lang.github.io/rustup-components-history 2# https://rust-lang.github.io/rustup-components-history
3[toolchain] 3[toolchain]
4channel = "nightly-2022-02-20" 4channel = "nightly-2022-03-10"
5components = [ "rust-src", "rustfmt" ] 5components = [ "rust-src", "rustfmt" ]
6targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "thumbv8m.main-none-eabihf", "wasm32-unknown-unknown" ] 6targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "thumbv8m.main-none-eabihf", "wasm32-unknown-unknown" ]
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index 041ec76ad..9893b0289 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -23,7 +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"} 26embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy2"}
27panic-probe = { version = "0.3.0", features = ["print-defmt"] } 27panic-probe = { version = "0.3.0", features = ["print-defmt"] }
28 28
29[profile.dev] 29[profile.dev]