Skip to content

Commit 4448d34

Browse files
committed
fix spi to be compatible with embedded-hal v1.0.0-alpha.8
1 parent 17aebc6 commit 4448d34

File tree

5 files changed

+82
-293
lines changed

5 files changed

+82
-293
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ license = "ISC"
1010
edition = "2018"
1111

1212
[dependencies]
13-
embedded-hal = "=1.0.0-alpha.7"
13+
embedded-hal = "=1.0.0-alpha.8"
1414
nb = "1.0.0"
1515
riscv = "0.9.0-alpha.1"
1616
e310x = { version = "0.9.1", features = ["rt"] }

src/spi/bus.rs

Lines changed: 50 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
use embedded_hal::spi::blocking::Operation;
2-
pub use embedded_hal::spi::blocking::{Read, Transfer, TransferInplace, Write, WriteIter};
3-
pub use embedded_hal::spi::nb::FullDuplex;
1+
use embedded_hal::spi::blocking::{SpiBus as SpiBusTransfer, SpiBusFlush};
2+
use embedded_hal::spi::blocking::{SpiBusRead, SpiBusWrite};
3+
use embedded_hal::spi::ErrorType;
44
pub use embedded_hal::spi::{ErrorKind, Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
55

6-
use nb;
7-
86
use super::{Pins, PinsNoCS, SharedBus, SpiConfig, SpiExclusiveDevice, SpiX};
97

108
/// SPI bus abstraction
@@ -101,38 +99,18 @@ where
10199
}
102100
}
103101

104-
// ex-traits now only accessible via devices
105-
106-
pub(crate) fn read(&mut self) -> nb::Result<u8, ErrorKind> {
107-
let rxdata = self.spi.rxdata.read();
108-
109-
if rxdata.empty().bit_is_set() {
110-
Err(nb::Error::WouldBlock)
111-
} else {
112-
Ok(rxdata.data().bits())
113-
}
114-
}
115-
116-
pub(crate) fn send(&mut self, byte: u8) -> nb::Result<(), ErrorKind> {
117-
let txdata = self.spi.txdata.read();
118-
119-
if txdata.full().bit_is_set() {
120-
Err(nb::Error::WouldBlock)
121-
} else {
122-
self.spi.txdata.write(|w| unsafe { w.data().bits(byte) });
123-
Ok(())
124-
}
125-
}
126-
127-
pub(crate) fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), ErrorKind> {
102+
/// Transfer implementation out of trait for reuse in Read and Write
103+
fn perform_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), ErrorKind> {
128104
let mut iwrite = 0;
129105
let mut iread = 0;
106+
let bytes = core::cmp::max(read.len(), write.len());
130107

131108
// Ensure that RX FIFO is empty
132109
self.wait_for_rxfifo();
133110

134111
// go through entire write buffer and read back (even if read buffer is empty)
135-
while iwrite < write.len() || iread < write.len() {
112+
// while iwrite < write.len() || iread < write.len() {
113+
while iwrite < bytes || iread < bytes {
136114
if iwrite < write.len() && self.spi.txdata.read().full().bit_is_clear() {
137115
let byte = write.get(iwrite).unwrap_or(&0);
138116
iwrite += 1;
@@ -152,8 +130,49 @@ where
152130

153131
Ok(())
154132
}
133+
}
134+
135+
impl<SPI, PINS> ErrorType for SpiBus<SPI, PINS> {
136+
type Error = ErrorKind;
137+
}
138+
139+
impl<SPI, PINS> SpiBusFlush for SpiBus<SPI, PINS>
140+
where
141+
SPI: SpiX,
142+
{
143+
fn flush(&mut self) -> Result<(), Self::Error> {
144+
// unnecessary
145+
146+
Ok(())
147+
}
148+
}
149+
impl<SPI, PINS> SpiBusRead for SpiBus<SPI, PINS>
150+
where
151+
SPI: SpiX,
152+
{
153+
fn read(&mut self, words: &mut [u8]) -> Result<(), ErrorKind> {
154+
self.perform_transfer(words, &[])
155+
}
156+
}
157+
158+
impl<SPI, PINS> SpiBusWrite for SpiBus<SPI, PINS>
159+
where
160+
SPI: SpiX,
161+
{
162+
fn write(&mut self, words: &[u8]) -> Result<(), ErrorKind> {
163+
self.perform_transfer(&mut [], words)
164+
}
165+
}
166+
167+
impl<SPI, PINS> SpiBusTransfer for SpiBus<SPI, PINS>
168+
where
169+
SPI: SpiX,
170+
{
171+
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), ErrorKind> {
172+
self.perform_transfer(read, write)
173+
}
155174

156-
pub(crate) fn transfer_inplace(&mut self, words: &mut [u8]) -> Result<(), ErrorKind> {
175+
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), ErrorKind> {
157176
let mut iwrite = 0;
158177
let mut iread = 0;
159178

@@ -178,63 +197,6 @@ where
178197

179198
Ok(())
180199
}
181-
182-
pub(crate) fn write_iter<WI>(&mut self, words: WI) -> Result<(), ErrorKind>
183-
where
184-
WI: IntoIterator<Item = u8>,
185-
{
186-
let mut iter = words.into_iter();
187-
188-
let mut read_count = 0;
189-
let mut has_data = true;
190-
191-
// Ensure that RX FIFO is empty
192-
self.wait_for_rxfifo();
193-
194-
while has_data || read_count > 0 {
195-
if has_data && self.spi.txdata.read().full().bit_is_clear() {
196-
if let Some(byte) = iter.next() {
197-
self.spi.txdata.write(|w| unsafe { w.data().bits(byte) });
198-
read_count += 1;
199-
} else {
200-
has_data = false;
201-
}
202-
}
203-
204-
if read_count > 0 {
205-
// Read and discard byte, if any
206-
if self.spi.rxdata.read().empty().bit_is_clear() {
207-
read_count -= 1;
208-
}
209-
}
210-
}
211-
212-
Ok(())
213-
}
214-
215-
pub(crate) fn exec<'op>(
216-
&mut self,
217-
operations: &mut [Operation<'op, u8>],
218-
) -> Result<(), ErrorKind> {
219-
for op in operations {
220-
match op {
221-
Operation::Read(words) => {
222-
self.transfer(words, &[])?;
223-
}
224-
Operation::Write(words) => {
225-
self.transfer(&mut [], words)?;
226-
}
227-
Operation::Transfer(read_words, write_words) => {
228-
self.transfer(read_words, write_words)?;
229-
}
230-
Operation::TransferInplace(words) => {
231-
self.transfer_inplace(words)?;
232-
}
233-
}
234-
}
235-
236-
Ok(())
237-
}
238200
}
239201

240202
impl<SPI, PINS> SpiBus<SPI, PINS>

src/spi/exclusive_device.rs

Lines changed: 9 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
use embedded_hal::spi::{
2-
blocking::{Operation, Transactional, Transfer, TransferInplace, Write, WriteIter},
3-
nb::FullDuplex,
4-
ErrorKind, ErrorType,
5-
};
1+
use embedded_hal::spi::{blocking::SpiDevice, ErrorKind, ErrorType};
62

73
use crate::spi::SpiConfig;
84

@@ -39,89 +35,21 @@ impl<SPI, PINS> ErrorType for SpiExclusiveDevice<SPI, PINS> {
3935
type Error = ErrorKind;
4036
}
4137

42-
impl<SPI, PINS> FullDuplex for SpiExclusiveDevice<SPI, PINS>
38+
impl<SPI, PINS> SpiDevice for SpiExclusiveDevice<SPI, PINS>
4339
where
4440
SPI: SpiX,
4541
PINS: Pins<SPI>,
4642
{
47-
fn read(&mut self) -> nb::Result<u8, Self::Error> {
48-
self.bus.read()
49-
}
50-
51-
fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
52-
self.bus.send(byte)
53-
}
54-
}
55-
56-
impl<SPI, PINS> Transfer for SpiExclusiveDevice<SPI, PINS>
57-
where
58-
SPI: SpiX,
59-
PINS: Pins<SPI>,
60-
{
61-
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
62-
self.bus.start_frame();
63-
let result = self.bus.transfer(read, write);
64-
self.bus.end_frame();
65-
66-
result
67-
}
68-
}
69-
70-
impl<SPI, PINS> TransferInplace for SpiExclusiveDevice<SPI, PINS>
71-
where
72-
SPI: SpiX,
73-
PINS: Pins<SPI>,
74-
{
75-
fn transfer_inplace<'w>(&mut self, words: &'w mut [u8]) -> Result<(), Self::Error> {
76-
self.bus.start_frame();
77-
let result = self.bus.transfer_inplace(words);
78-
self.bus.end_frame();
79-
80-
result
81-
}
82-
}
83-
84-
impl<SPI, PINS> Write for SpiExclusiveDevice<SPI, PINS>
85-
where
86-
SPI: SpiX,
87-
PINS: Pins<SPI>,
88-
{
89-
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
90-
self.bus.start_frame();
91-
let result = self.bus.transfer(&mut [], words);
92-
self.bus.end_frame();
43+
type Bus = SpiBus<SPI, PINS>;
9344

94-
result
95-
}
96-
}
97-
98-
impl<SPI, PINS> WriteIter for SpiExclusiveDevice<SPI, PINS>
99-
where
100-
SPI: SpiX,
101-
PINS: Pins<SPI>,
102-
{
103-
fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
104-
where
105-
WI: IntoIterator<Item = u8>,
106-
{
107-
self.bus.start_frame();
108-
let result = self.bus.write_iter(words);
109-
self.bus.end_frame();
110-
111-
result
112-
}
113-
}
114-
115-
impl<SPI, PINS> Transactional for SpiExclusiveDevice<SPI, PINS>
116-
where
117-
SPI: SpiX,
118-
PINS: Pins<SPI>,
119-
{
120-
fn exec<'op>(&mut self, operations: &mut [Operation<'op, u8>]) -> Result<(), Self::Error> {
45+
fn transaction<R>(
46+
&mut self,
47+
f: impl FnOnce(&mut Self::Bus) -> Result<R, <Self::Bus as ErrorType>::Error>,
48+
) -> Result<R, Self::Error> {
12149
self.bus.start_frame();
122-
let result = self.bus.exec(operations);
50+
let result = f(&mut self.bus)?;
12351
self.bus.end_frame();
12452

125-
result
53+
Ok(result)
12654
}
12755
}

src/spi/shared_bus.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use core::cell::RefCell;
22
use core::ops::Deref;
3+
use embedded_hal::spi::{ErrorKind, ErrorType};
34
pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
45
use riscv::interrupt;
56
use riscv::interrupt::Mutex;
@@ -10,6 +11,10 @@ use super::{PinCS, PinsNoCS, SpiBus, SpiConfig, SpiSharedDevice, SpiX};
1011
/// Used to hold the [SpiBus] instance so it can be used for multiple [SpiSharedDevice] instances.
1112
pub struct SharedBus<SPI, PINS>(Mutex<RefCell<SpiBus<SPI, PINS>>>);
1213

14+
impl<SPI, PINS> ErrorType for SharedBus<SPI, PINS> {
15+
type Error = ErrorKind;
16+
}
17+
1318
impl<SPI, PINS> SharedBus<SPI, PINS>
1419
where
1520
SPI: SpiX,

0 commit comments

Comments
 (0)