Skip to content

Commit 009cfc3

Browse files
committed
Implement SpiDevice for SPI
1 parent 5c38934 commit 009cfc3

File tree

1 file changed

+110
-27
lines changed

1 file changed

+110
-27
lines changed

src/spi.rs

Lines changed: 110 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ use crate::gpio::*;
22
use crate::rcc::*;
33
use crate::stm32::{SPI1, SPI2};
44
use crate::time::Hertz;
5+
use core::convert::Infallible;
56
use core::ptr;
7+
use embedded_hal::delay::DelayNs;
8+
use hal::digital;
9+
use hal::digital::OutputPin;
610
pub use hal::spi::{
7-
ErrorKind, ErrorType, Mode, Phase, Polarity, SpiBus, MODE_0, MODE_1, MODE_2, MODE_3,
11+
self, ErrorKind, ErrorType, Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3,
812
};
913
use nb::block;
1014

@@ -17,18 +21,45 @@ pub enum Error {
1721
ModeFault,
1822
/// CRC error
1923
Crc,
24+
/// Chip Select Fault
25+
ChipSelectFault,
2026
}
2127

2228
impl hal::spi::Error for Error {
2329
fn kind(&self) -> ErrorKind {
2430
match self {
2531
Error::Overrun => ErrorKind::Overrun,
2632
Error::ModeFault => ErrorKind::ModeFault,
33+
Error::ChipSelectFault => ErrorKind::ChipSelectFault,
2734
Error::Crc => ErrorKind::Other,
2835
}
2936
}
3037
}
3138

39+
/// A filler type for when the delay is unnecessary
40+
pub struct NoDelay;
41+
42+
impl DelayNs for NoDelay {
43+
fn delay_ns(&mut self, _: u32) {}
44+
}
45+
46+
/// A filler type for when the CS pin is unnecessary
47+
pub struct NoCS;
48+
49+
impl digital::ErrorType for NoCS {
50+
type Error = Infallible;
51+
}
52+
53+
impl digital::OutputPin for NoCS {
54+
fn set_low(&mut self) -> Result<(), Self::Error> {
55+
Ok(())
56+
}
57+
58+
fn set_high(&mut self) -> Result<(), Self::Error> {
59+
Ok(())
60+
}
61+
}
62+
3263
/// A filler type for when the SCK pin is unnecessary
3364
pub struct NoSck;
3465
/// A filler type for when the Miso pin is unnecessary
@@ -74,13 +105,20 @@ where
74105
}
75106

76107
#[derive(Debug)]
77-
pub struct Spi<SPI, PINS> {
108+
pub struct SpiBus<SPI, PINS> {
78109
spi: SPI,
79110
pins: PINS,
80111
}
81112

113+
#[derive(Debug)]
114+
pub struct SpiDevice<BUS, CS, DELAY> {
115+
bus: BUS,
116+
cs: CS,
117+
delay: DELAY,
118+
}
119+
82120
pub trait SpiExt: Sized {
83-
fn spi<PINS>(self, pins: PINS, mode: Mode, freq: Hertz, rcc: &mut Rcc) -> Spi<Self, PINS>
121+
fn spi<PINS>(self, pins: PINS, mode: Mode, freq: Hertz, rcc: &mut Rcc) -> SpiBus<Self, PINS>
84122
where
85123
PINS: Pins<Self>;
86124
}
@@ -149,7 +187,7 @@ macro_rules! spi {
149187
}
150188
)*
151189

152-
impl<PINS: Pins<$SPIX>> Spi<$SPIX, PINS> {
190+
impl<PINS: Pins<$SPIX>> SpiBus<$SPIX, PINS> {
153191
pub fn $spiX(
154192
spi: $SPIX,
155193
pins: PINS,
@@ -197,7 +235,15 @@ macro_rules! spi {
197235
w.spe().set_bit()
198236
});
199237

200-
Spi { spi, pins }
238+
SpiBus { spi, pins }
239+
}
240+
241+
pub fn exclusive<CS: OutputPin, DELAY: DelayNs>(self, cs: CS, delay: DELAY) -> SpiDevice<SpiBus<$SPIX, PINS>, CS, DELAY,> {
242+
SpiDevice {
243+
bus: self,
244+
cs,
245+
delay
246+
}
201247
}
202248

203249
pub fn data_size(&mut self, nr_bits: u8) {
@@ -223,17 +269,39 @@ macro_rules! spi {
223269
}
224270
}
225271

272+
impl<PINS, CS: OutputPin, DELAY> ErrorType for SpiDevice<SpiBus<$SPIX, PINS>, CS, DELAY> {
273+
type Error = Error;
274+
}
275+
276+
impl<PINS, CS: OutputPin, DELAY: DelayNs> spi::SpiDevice for SpiDevice<SpiBus<$SPIX, PINS>, CS, DELAY> {
277+
fn transaction(&mut self, operations: &mut [hal::spi::Operation<'_, u8>]) -> Result<(), Error> {
278+
use crate::hal::spi::SpiBus;
279+
self.cs.set_low().map_err(|_| Error::ChipSelectFault)?;
280+
for op in operations {
281+
match op {
282+
spi::Operation::Read(read) => { self.bus.read(read)?; },
283+
spi::Operation::Write(write) => { self.bus.write(write)?; },
284+
spi::Operation::Transfer(write, read) => { self.bus.transfer(write, read)?; },
285+
spi::Operation::TransferInPlace(data) => { self.bus.transfer_in_place(data)?; },
286+
spi::Operation::DelayNs(ns) => { self.delay.delay_ns(*ns) },
287+
}
288+
}
289+
self.cs.set_high().map_err(|_| Error::ChipSelectFault)?;
290+
Ok(())
291+
}
292+
}
293+
226294
impl SpiExt for $SPIX {
227-
fn spi<PINS>(self, pins: PINS, mode: Mode, freq: Hertz, rcc: &mut Rcc) -> Spi<$SPIX, PINS>
295+
fn spi<PINS>(self, pins: PINS, mode: Mode, freq: Hertz, rcc: &mut Rcc) -> SpiBus<$SPIX, PINS>
228296
where
229297
PINS: Pins<$SPIX>,
230298
{
231-
Spi::$spiX(self, pins, mode, freq, rcc)
299+
SpiBus::$spiX(self, pins, mode, freq, rcc)
232300
}
233301
}
234302

235-
impl<PINS> Spi<$SPIX, PINS> {
236-
pub fn read(&mut self) -> nb::Result<u8, Error> {
303+
impl<PINS> SpiBus<$SPIX, PINS> {
304+
fn receive_byte(&mut self) -> nb::Result<u8, Error> {
237305
let sr = self.spi.sr().read();
238306
Err(if sr.ovr().bit_is_set() {
239307
nb::Error::Other(Error::Overrun)
@@ -248,7 +316,7 @@ macro_rules! spi {
248316
})
249317
}
250318

251-
pub fn send(&mut self, byte: u8) -> nb::Result<(), Error> {
319+
fn send_byte(&mut self, byte: u8) -> nb::Result<(), Error> {
252320
let sr = self.spi.sr().read();
253321
Err(if sr.ovr().bit_is_set() {
254322
nb::Error::Other(Error::Overrun)
@@ -267,38 +335,53 @@ macro_rules! spi {
267335
}
268336
}
269337

270-
impl<PINS> ErrorType for Spi<$SPIX, PINS> {
338+
impl<PINS> ErrorType for SpiBus<$SPIX, PINS> {
271339
type Error = Error;
272340
}
273341

274-
impl<PINS> SpiBus for Spi<$SPIX, PINS> {
275-
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
276-
for word in words.iter_mut() {
277-
*word = block!(self.read())?;
342+
impl<PINS> spi::SpiBus for SpiBus<$SPIX, PINS> {
343+
fn read(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error> {
344+
for byte in bytes.iter_mut() {
345+
block!(self.send_byte(0))?;
346+
*byte = block!(self.receive_byte())?;
278347
}
279348
Ok(())
280349
}
281350

282-
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
283-
for word in words.iter() {
284-
block!(self.send(*word))?;
285-
block!(self.read())?;
351+
fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
352+
for byte in bytes.iter() {
353+
block!(self.send_byte(*byte))?;
354+
block!(self.receive_byte())?;
286355
}
287356
Ok(())
288357
}
289358

290359
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
291-
for (r, w) in read.iter_mut().zip(write.iter()) {
292-
block!(self.send(*w))?;
293-
*r = block!(self.read())?;
360+
let mut iter_r = read.iter_mut();
361+
let mut iter_w = write.iter().cloned();
362+
loop {
363+
match (iter_r.next(), iter_w.next()) {
364+
(Some(r), Some(w)) => {
365+
block!(self.send_byte(w))?;
366+
*r = block!(self.receive_byte())?;
367+
}
368+
(Some(r), None) => {
369+
block!(self.send_byte(0))?;
370+
*r = block!(self.receive_byte())?;
371+
}
372+
(None, Some(w)) => {
373+
block!(self.send_byte(w))?;
374+
let _ = block!(self.receive_byte())?;
375+
}
376+
(None, None) => return Ok(()),
377+
}
294378
}
295-
Ok(())
296379
}
297380

298-
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
299-
for word in words.iter_mut() {
300-
block!(self.send(*word))?;
301-
*word = block!(self.read())?;
381+
fn transfer_in_place(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error> {
382+
for byte in bytes.iter_mut() {
383+
block!(self.send_byte(*byte))?;
384+
*byte = block!(self.receive_byte())?;
302385
}
303386
Ok(())
304387
}

0 commit comments

Comments
 (0)