aboutsummaryrefslogtreecommitdiff
path: root/embassy-traits/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-01-26 22:01:46 +0000
committerGitHub <[email protected]>2022-01-26 22:01:46 +0000
commitd76cd5ceaf5140c48ef97180beae156c0c0e07c8 (patch)
treea453271d10c017854184335584188bc8709ed517 /embassy-traits/src
parentcd36e3f7332d08865e670ca5b515d1c6efa1bf85 (diff)
parentc8347fafb0814078466d7ed220224b9f4c7d78cf (diff)
Merge #592
592: Initial work on unstable-trait feature for stm32 r=lulf a=lulf Implements async traits for exti for now. Co-authored-by: Ulf Lilleengen <[email protected]>
Diffstat (limited to 'embassy-traits/src')
-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
6 files changed, 145 insertions, 405 deletions
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}