Skip to content

Commit 6013187

Browse files
committed
async: add SPI
1 parent 9c17bca commit 6013187

File tree

2 files changed

+190
-0
lines changed

2 files changed

+190
-0
lines changed

embedded-hal-async/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
#![feature(generic_associated_types)]
1313

1414
pub mod delay;
15+
pub mod spi;

embedded-hal-async/src/spi.rs

+189
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
//! Serial Peripheral Interface
2+
3+
use core::future::Future;
4+
5+
pub use embedded_hal::spi::blocking::Operation;
6+
pub use embedded_hal::spi::{
7+
Error, ErrorKind, ErrorType, Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3,
8+
};
9+
10+
/// Read-only SPI
11+
pub trait Read<Word: 'static + Copy = u8>: ErrorType {
12+
/// Future returned by the `read` method.
13+
type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
14+
where
15+
Self: 'a;
16+
17+
/// Read `words` from the slave.
18+
///
19+
/// The word value sent on MOSI during reading is implementation-defined,
20+
/// typically `0x00`, `0xFF`, or configurable.
21+
fn read<'a>(&'a mut self, words: &'a mut [Word]) -> Self::ReadFuture<'a>;
22+
23+
/// Future returned by the `read_transaction` method.
24+
type ReadTransactionFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
25+
where
26+
Self: 'a;
27+
28+
/// Read all slices in `words` from the slave as part of a single SPI transaction.
29+
///
30+
/// The word value sent on MOSI during reading is implementation-defined,
31+
/// typically `0x00`, `0xFF`, or configurable.
32+
fn read_transaction<'a>(
33+
&'a mut self,
34+
words: &'a mut [&'a mut [Word]],
35+
) -> Self::ReadTransactionFuture<'a>;
36+
}
37+
38+
impl<T: Read<Word>, Word: 'static + Copy> Read<Word> for &mut T {
39+
type ReadFuture<'a>
40+
where
41+
Self: 'a,
42+
= T::ReadFuture<'a>;
43+
44+
fn read<'a>(&'a mut self, words: &'a mut [Word]) -> Self::ReadFuture<'a> {
45+
T::read(self, words)
46+
}
47+
48+
type ReadTransactionFuture<'a>
49+
where
50+
Self: 'a,
51+
= T::ReadTransactionFuture<'a>;
52+
53+
fn read_transaction<'a>(
54+
&'a mut self,
55+
words: &'a mut [&'a mut [Word]],
56+
) -> Self::ReadTransactionFuture<'a> {
57+
T::read_transaction(self, words)
58+
}
59+
}
60+
61+
/// Write-only SPI
62+
pub trait Write<Word: 'static + Copy = u8>: ErrorType {
63+
/// Future returned by the `write` method.
64+
type WriteFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
65+
where
66+
Self: 'a;
67+
68+
/// Write `words` to the slave, ignoring all the incoming words
69+
fn write<'a>(&'a mut self, words: &'a [Word]) -> Self::WriteFuture<'a>;
70+
71+
/// Future returned by the `write_transaction` method.
72+
type WriteTransactionFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
73+
where
74+
Self: 'a;
75+
76+
/// Write all slices in `words` to the slave as part of a single SPI transaction, ignoring all the incoming words
77+
fn write_transaction<'a>(
78+
&'a mut self,
79+
words: &'a [&'a [Word]],
80+
) -> Self::WriteTransactionFuture<'a>;
81+
}
82+
83+
impl<T: Write<Word>, Word: 'static + Copy> Write<Word> for &mut T {
84+
type WriteFuture<'a>
85+
where
86+
Self: 'a,
87+
= T::WriteFuture<'a>;
88+
89+
fn write<'a>(&'a mut self, words: &'a [Word]) -> Self::WriteFuture<'a> {
90+
T::write(self, words)
91+
}
92+
93+
type WriteTransactionFuture<'a>
94+
where
95+
Self: 'a,
96+
= T::WriteTransactionFuture<'a>;
97+
98+
fn write_transaction<'a>(
99+
&'a mut self,
100+
words: &'a [&'a [Word]],
101+
) -> Self::WriteTransactionFuture<'a> {
102+
T::write_transaction(self, words)
103+
}
104+
}
105+
106+
/// Read-write SPI
107+
pub trait ReadWrite<Word: 'static + Copy = u8>: Read<Word> + Write<Word> {
108+
/// Future returned by the `transfer` method.
109+
type TransferFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
110+
where
111+
Self: 'a;
112+
113+
/// Write and read simultaneously. `write` is written to the slave on MOSI and
114+
/// words received on MISO are stored in `read`.
115+
///
116+
/// It is allowed for `read` and `write` to have different lengths, even zero length.
117+
/// The transfer runs for `max(read.len(), write.len())` words. If `read` is shorter,
118+
/// incoming words after `read` has been filled will be discarded. If `write` is shorter,
119+
/// the value of words sent in MOSI after all `write` has been sent is implementation-defined,
120+
/// typically `0x00`, `0xFF`, or configurable.
121+
fn transfer<'a>(
122+
&'a mut self,
123+
read: &'a mut [Word],
124+
write: &'a [Word],
125+
) -> Self::TransferFuture<'a>;
126+
127+
/// Future returned by the `transfer_in_place` method.
128+
type TransferInPlaceFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
129+
where
130+
Self: 'a;
131+
132+
/// Write and read simultaneously. The contents of `words` are
133+
/// written to the slave, and the received words are stored into the same
134+
/// `words` buffer, overwriting it.
135+
fn transfer_in_place<'a>(
136+
&'a mut self,
137+
words: &'a mut [Word],
138+
) -> Self::TransferInPlaceFuture<'a>;
139+
140+
/// Future returned by the `transaction` method.
141+
type TransactionFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
142+
where
143+
Self: 'a;
144+
145+
/// Execute multiple operations as part of a single SPI transaction
146+
fn transaction<'a>(
147+
&'a mut self,
148+
operations: &'a mut [Operation<'a, Word>],
149+
) -> Self::TransactionFuture<'a>;
150+
}
151+
152+
impl<T: ReadWrite<Word>, Word: 'static + Copy> ReadWrite<Word> for &mut T {
153+
type TransferFuture<'a>
154+
where
155+
Self: 'a,
156+
= T::TransferFuture<'a>;
157+
158+
fn transfer<'a>(
159+
&'a mut self,
160+
read: &'a mut [Word],
161+
write: &'a [Word],
162+
) -> Self::TransferFuture<'a> {
163+
T::transfer(self, read, write)
164+
}
165+
166+
type TransferInPlaceFuture<'a>
167+
where
168+
Self: 'a,
169+
= T::TransferInPlaceFuture<'a>;
170+
171+
fn transfer_in_place<'a>(
172+
&'a mut self,
173+
words: &'a mut [Word],
174+
) -> Self::TransferInPlaceFuture<'a> {
175+
T::transfer_in_place(self, words)
176+
}
177+
178+
type TransactionFuture<'a>
179+
where
180+
Self: 'a,
181+
= T::TransactionFuture<'a>;
182+
183+
fn transaction<'a>(
184+
&'a mut self,
185+
operations: &'a mut [Operation<'a, Word>],
186+
) -> Self::TransactionFuture<'a> {
187+
T::transaction(self, operations)
188+
}
189+
}

0 commit comments

Comments
 (0)