Skip to content

Commit 5d1498e

Browse files
committed
spi nb
1 parent 8162c5e commit 5d1498e

File tree

4 files changed

+209
-49
lines changed

4 files changed

+209
-49
lines changed

examples/spi-slave.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use cortex_m_rt::entry;
1313
use panic_halt as _;
1414

1515
use cortex_m::{asm, singleton};
16-
use embedded_hal_02::spi::{Mode, Phase, Polarity};
16+
use stm32f1xx_hal::spi::{Mode, Phase, Polarity};
1717
pub const MODE: Mode = Mode {
1818
phase: Phase::CaptureOnSecondTransition,
1919
polarity: Polarity::IdleHigh,

src/spi.rs

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@
3434
*/
3535

3636
mod hal_02;
37+
mod hal_1;
3738

3839
use core::ops::Deref;
3940

4041
use crate::pac::{self, RCC};
41-
pub use embedded_hal_02::spi::{Mode, Phase, Polarity};
4242

4343
use crate::afio::MAPR;
4444
use crate::dma::dma1;
@@ -52,6 +52,33 @@ use crate::time::Hertz;
5252
use core::sync::atomic::{self, Ordering};
5353
use embedded_dma::{ReadBuffer, WriteBuffer};
5454

55+
/// Clock polarity
56+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
57+
pub enum Polarity {
58+
/// Clock signal low when idle
59+
IdleLow,
60+
/// Clock signal high when idle
61+
IdleHigh,
62+
}
63+
64+
/// Clock phase
65+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
66+
pub enum Phase {
67+
/// Data in "captured" on the first clock transition
68+
CaptureOnFirstTransition,
69+
/// Data in "captured" on the second clock transition
70+
CaptureOnSecondTransition,
71+
}
72+
73+
/// SPI mode
74+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
75+
pub struct Mode {
76+
/// Clock polarity
77+
pub polarity: Polarity,
78+
/// Clock phase
79+
pub phase: Phase,
80+
}
81+
5582
/// Interrupt event
5683
pub enum Event {
5784
/// New data has been received
@@ -192,7 +219,7 @@ impl<REMAP, PINS> Spi<pac::SPI1, REMAP, PINS, u8, Master> {
192219
spi: pac::SPI1,
193220
pins: PINS,
194221
mapr: &mut MAPR,
195-
mode: Mode,
222+
mode: impl Into<Mode>,
196223
freq: Hertz,
197224
clocks: Clocks,
198225
) -> Self
@@ -213,7 +240,7 @@ impl<REMAP, PINS> Spi<pac::SPI1, REMAP, PINS, u8, Slave> {
213240
214241
You can also use `NoMiso` or `NoMosi` if you don't want to use the pins
215242
*/
216-
pub fn spi1_slave(spi: pac::SPI1, pins: PINS, mapr: &mut MAPR, mode: Mode) -> Self
243+
pub fn spi1_slave(spi: pac::SPI1, pins: PINS, mapr: &mut MAPR, mode: impl Into<Mode>) -> Self
217244
where
218245
REMAP: Remap<Periph = pac::SPI1>,
219246
PINS: Pins<REMAP, Slave>,
@@ -461,7 +488,8 @@ impl<SPI, REMAP, PINS> Spi<SPI, REMAP, PINS, u8, Master>
461488
where
462489
SPI: Instance,
463490
{
464-
fn configure(spi: SPI, pins: PINS, mode: Mode, freq: Hertz, clocks: Clocks) -> Self {
491+
fn configure(spi: SPI, pins: PINS, mode: impl Into<Mode>, freq: Hertz, clocks: Clocks) -> Self {
492+
let mode = mode.into();
465493
// enable or reset SPI
466494
let rcc = unsafe { &(*RCC::ptr()) };
467495
SPI::enable(rcc);
@@ -521,7 +549,8 @@ impl<SPI, REMAP, PINS> Spi<SPI, REMAP, PINS, u8, Slave>
521549
where
522550
SPI: Instance,
523551
{
524-
fn configure(spi: SPI, pins: PINS, mode: Mode) -> Self {
552+
fn configure(spi: SPI, pins: PINS, mode: impl Into<Mode>) -> Self {
553+
let mode = mode.into();
525554
// enable or reset SPI
526555
let rcc = unsafe { &(*RCC::ptr()) };
527556
SPI::enable(rcc);
@@ -601,6 +630,49 @@ where
601630
}
602631
}
603632

633+
impl<SPI, REMAP, PINS, FrameSize, OP> Spi<SPI, REMAP, PINS, FrameSize, OP>
634+
where
635+
SPI: Instance,
636+
FrameSize: Copy,
637+
{
638+
pub fn read_nonblocking(&mut self) -> nb::Result<FrameSize, Error> {
639+
let sr = self.spi.sr.read();
640+
641+
Err(if sr.ovr().bit_is_set() {
642+
Error::Overrun.into()
643+
} else if sr.modf().bit_is_set() {
644+
Error::ModeFault.into()
645+
} else if sr.crcerr().bit_is_set() {
646+
Error::Crc.into()
647+
} else if sr.rxne().bit_is_set() {
648+
// NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
649+
// reading a half-word)
650+
return Ok(self.read_data_reg());
651+
} else {
652+
nb::Error::WouldBlock
653+
})
654+
}
655+
pub fn write_nonblocking(&mut self, data: FrameSize) -> nb::Result<(), Error> {
656+
let sr = self.spi.sr.read();
657+
658+
// NOTE: Error::Overrun was deleted in #408. Need check
659+
Err(if sr.modf().bit_is_set() {
660+
Error::ModeFault.into()
661+
} else if sr.crcerr().bit_is_set() {
662+
Error::Crc.into()
663+
} else if sr.txe().bit_is_set() {
664+
// NOTE(write_volatile) see note above
665+
self.write_data_reg(data);
666+
return Ok(());
667+
} else {
668+
nb::Error::WouldBlock
669+
})
670+
}
671+
pub fn write(&mut self, words: &[FrameSize]) -> Result<(), Error> {
672+
self.spi_write(words)
673+
}
674+
}
675+
604676
// DMA
605677

606678
pub type SpiTxDma<SPI, REMAP, PINS, OP, CHANNEL> = TxDma<Spi<SPI, REMAP, PINS, u8, OP>, CHANNEL>;

src/spi/hal_02.rs

Lines changed: 38 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,70 @@
11
use super::*;
22

3+
pub use embedded_hal_02::spi::{Mode, Phase, Polarity};
34
use embedded_hal_02::{blocking::spi as blocking, spi};
45

5-
impl<SPI, REMAP, PINS, FrameSize, OP> spi::FullDuplex<FrameSize>
6-
for Spi<SPI, REMAP, PINS, FrameSize, OP>
6+
impl From<Polarity> for super::Polarity {
7+
fn from(p: Polarity) -> Self {
8+
match p {
9+
Polarity::IdleLow => Self::IdleLow,
10+
Polarity::IdleHigh => Self::IdleHigh,
11+
}
12+
}
13+
}
14+
15+
impl From<Phase> for super::Phase {
16+
fn from(p: Phase) -> Self {
17+
match p {
18+
Phase::CaptureOnFirstTransition => Self::CaptureOnFirstTransition,
19+
Phase::CaptureOnSecondTransition => Self::CaptureOnSecondTransition,
20+
}
21+
}
22+
}
23+
24+
impl From<Mode> for super::Mode {
25+
fn from(m: Mode) -> Self {
26+
Self {
27+
polarity: m.polarity.into(),
28+
phase: m.phase.into(),
29+
}
30+
}
31+
}
32+
33+
impl<SPI, REMAP, PINS, W, OP> spi::FullDuplex<W> for Spi<SPI, REMAP, PINS, W, OP>
734
where
835
SPI: Instance,
9-
FrameSize: Copy,
36+
W: Copy,
1037
{
1138
type Error = Error;
1239

13-
fn read(&mut self) -> nb::Result<FrameSize, Error> {
14-
let sr = self.spi.sr.read();
15-
16-
Err(if sr.ovr().bit_is_set() {
17-
Error::Overrun.into()
18-
} else if sr.modf().bit_is_set() {
19-
Error::ModeFault.into()
20-
} else if sr.crcerr().bit_is_set() {
21-
Error::Crc.into()
22-
} else if sr.rxne().bit_is_set() {
23-
// NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
24-
// reading a half-word)
25-
return Ok(self.read_data_reg());
26-
} else {
27-
nb::Error::WouldBlock
28-
})
40+
fn read(&mut self) -> nb::Result<W, Error> {
41+
self.read_nonblocking()
2942
}
3043

31-
fn send(&mut self, data: FrameSize) -> nb::Result<(), Error> {
32-
let sr = self.spi.sr.read();
33-
34-
// NOTE: Error::Overrun was deleted in #408. Need check
35-
Err(if sr.modf().bit_is_set() {
36-
Error::ModeFault.into()
37-
} else if sr.crcerr().bit_is_set() {
38-
Error::Crc.into()
39-
} else if sr.txe().bit_is_set() {
40-
// NOTE(write_volatile) see note above
41-
self.write_data_reg(data);
42-
return Ok(());
43-
} else {
44-
nb::Error::WouldBlock
45-
})
44+
fn send(&mut self, data: W) -> nb::Result<(), Error> {
45+
self.write_nonblocking(data)
4646
}
4747
}
4848

49-
impl<SPI, REMAP, PINS, FrameSize, OP> blocking::transfer::Default<FrameSize>
50-
for Spi<SPI, REMAP, PINS, FrameSize, OP>
49+
impl<SPI, REMAP, PINS, W, OP> blocking::transfer::Default<W> for Spi<SPI, REMAP, PINS, W, OP>
5150
where
5251
SPI: Instance,
53-
FrameSize: Copy,
52+
W: Copy,
5453
{
5554
}
5655

5756
impl<SPI: Instance, REMAP, PINS, OP> blocking::Write<u8> for Spi<SPI, REMAP, PINS, u8, OP> {
5857
type Error = Error;
5958

60-
// Implement write as per the "Transmit only procedure" page 712
61-
// of RM0008 Rev 20. This is more than twice as fast as the
62-
// default Write<> implementation (which reads and drops each
63-
// received value)
6459
fn write(&mut self, words: &[u8]) -> Result<(), Error> {
65-
self.spi_write(words)
60+
self.write(words)
6661
}
6762
}
6863

6964
impl<SPI: Instance, REMAP, PINS, OP> blocking::Write<u16> for Spi<SPI, REMAP, PINS, u16, OP> {
7065
type Error = Error;
7166

7267
fn write(&mut self, words: &[u16]) -> Result<(), Error> {
73-
self.spi_write(words)
68+
self.write(words)
7469
}
7570
}

src/spi/hal_1.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
use super::*;
2+
pub use embedded_hal::spi::{ErrorKind, ErrorType, Mode, Phase, Polarity};
3+
4+
impl From<Polarity> for super::Polarity {
5+
fn from(p: Polarity) -> Self {
6+
match p {
7+
Polarity::IdleLow => Self::IdleLow,
8+
Polarity::IdleHigh => Self::IdleHigh,
9+
}
10+
}
11+
}
12+
13+
impl From<Phase> for super::Phase {
14+
fn from(p: Phase) -> Self {
15+
match p {
16+
Phase::CaptureOnFirstTransition => Self::CaptureOnFirstTransition,
17+
Phase::CaptureOnSecondTransition => Self::CaptureOnSecondTransition,
18+
}
19+
}
20+
}
21+
22+
impl From<Mode> for super::Mode {
23+
fn from(m: Mode) -> Self {
24+
Self {
25+
polarity: m.polarity.into(),
26+
phase: m.phase.into(),
27+
}
28+
}
29+
}
30+
31+
impl embedded_hal::spi::Error for Error {
32+
fn kind(&self) -> ErrorKind {
33+
match self {
34+
Self::Overrun => ErrorKind::Overrun,
35+
Self::ModeFault => ErrorKind::ModeFault,
36+
Self::Crc => ErrorKind::Other,
37+
}
38+
}
39+
}
40+
41+
impl<SPI: Instance, REMAP, PINS, W, OP> ErrorType for Spi<SPI, REMAP, PINS, W, OP> {
42+
type Error = Error;
43+
}
44+
45+
mod nb {
46+
use super::{Error, Instance, Spi};
47+
use embedded_hal_nb::spi::FullDuplex;
48+
49+
impl<SPI, REMAP, PINS, W, OP> FullDuplex<W> for Spi<SPI, REMAP, PINS, W, OP>
50+
where
51+
SPI: Instance,
52+
W: Copy,
53+
{
54+
fn read(&mut self) -> nb::Result<W, Error> {
55+
self.read_nonblocking()
56+
}
57+
58+
fn write(&mut self, data: W) -> nb::Result<(), Error> {
59+
self.write_nonblocking(data)
60+
}
61+
}
62+
}
63+
64+
mod blocking {
65+
use super::super::{Instance, Spi};
66+
use embedded_hal::spi::SpiBus;
67+
68+
impl<SPI: Instance, REMAP, PINS, W, OP> SpiBus<W> for Spi<SPI, REMAP, PINS, W, OP>
69+
where
70+
SPI: Instance,
71+
W: Copy + 'static,
72+
{
73+
fn transfer_in_place(&mut self, _words: &mut [W]) -> Result<(), Self::Error> {
74+
todo!()
75+
}
76+
77+
fn transfer(&mut self, _buff: &mut [W], _data: &[W]) -> Result<(), Self::Error> {
78+
todo!()
79+
}
80+
81+
fn read(&mut self, _words: &mut [W]) -> Result<(), Self::Error> {
82+
todo!()
83+
}
84+
85+
fn write(&mut self, words: &[W]) -> Result<(), Self::Error> {
86+
self.write(words)
87+
}
88+
89+
fn flush(&mut self) -> Result<(), Self::Error> {
90+
Ok(())
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)