Skip to content

Commit 68cd1be

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

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-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

+175
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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<W: '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 [W]) -> 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 [W]],
35+
) -> Self::ReadTransactionFuture<'a>;
36+
}
37+
38+
impl<T: Read<W>, W: 'static + Copy> Read<W> 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 [W]) -> 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 [W]],
56+
) -> Self::ReadTransactionFuture<'a> {
57+
T::read_transaction(self, words)
58+
}
59+
}
60+
61+
/// Write-only SPI
62+
pub trait Write<W: '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 [W]) -> 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 [W]],
80+
) -> Self::WriteTransactionFuture<'a>;
81+
}
82+
83+
impl<T: Write<W>, W: 'static + Copy> Write<W> 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 [W]) -> 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 [W]],
101+
) -> Self::WriteTransactionFuture<'a> {
102+
T::write_transaction(self, words)
103+
}
104+
}
105+
106+
/// Read-write SPI
107+
pub trait ReadWrite<W: 'static + Copy = u8>: Read<W> + Write<W> {
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>(&'a mut self, read: &'a mut [W], write: &'a [W]) -> Self::TransferFuture<'a>;
122+
123+
/// Future returned by the `transfer_in_place` method.
124+
type TransferInPlaceFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
125+
where
126+
Self: 'a;
127+
128+
/// Write and read simultaneously. The contents of `words` are
129+
/// written to the slave, and the received words are stored into the same
130+
/// `words` buffer, overwriting it.
131+
fn transfer_in_place<'a>(&'a mut self, words: &'a mut [W]) -> Self::TransferInPlaceFuture<'a>;
132+
133+
/// Future returned by the `transaction` method.
134+
type TransactionFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
135+
where
136+
Self: 'a;
137+
138+
/// Execute multiple operations as part of a single SPI transaction
139+
fn transaction<'a>(
140+
&'a mut self,
141+
operations: &'a mut [Operation<'a, W>],
142+
) -> Self::TransactionFuture<'a>;
143+
}
144+
145+
impl<T: ReadWrite<W>, W: 'static + Copy> ReadWrite<W> for &mut T {
146+
type TransferFuture<'a>
147+
where
148+
Self: 'a,
149+
= T::TransferFuture<'a>;
150+
151+
fn transfer<'a>(&'a mut self, read: &'a mut [W], write: &'a [W]) -> Self::TransferFuture<'a> {
152+
T::transfer(self, read, write)
153+
}
154+
155+
type TransferInPlaceFuture<'a>
156+
where
157+
Self: 'a,
158+
= T::TransferInPlaceFuture<'a>;
159+
160+
fn transfer_in_place<'a>(&'a mut self, words: &'a mut [W]) -> Self::TransferInPlaceFuture<'a> {
161+
T::transfer_in_place(self, words)
162+
}
163+
164+
type TransactionFuture<'a>
165+
where
166+
Self: 'a,
167+
= T::TransactionFuture<'a>;
168+
169+
fn transaction<'a>(
170+
&'a mut self,
171+
operations: &'a mut [Operation<'a, W>],
172+
) -> Self::TransactionFuture<'a> {
173+
T::transaction(self, operations)
174+
}
175+
}

0 commit comments

Comments
 (0)