Skip to content

Commit 3ca97af

Browse files
committed
spi nb
1 parent 7630578 commit 3ca97af

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,12 +34,12 @@
3434
*/
3535

3636
mod hal_02;
37+
mod hal_1;
3738

3839
use core::ops::Deref;
3940
use core::ptr;
4041

4142
use crate::pac::{self, RCC};
42-
pub use embedded_hal_02::spi::{Mode, Phase, Polarity};
4343

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

56+
/// Clock polarity
57+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
58+
pub enum Polarity {
59+
/// Clock signal low when idle
60+
IdleLow,
61+
/// Clock signal high when idle
62+
IdleHigh,
63+
}
64+
65+
/// Clock phase
66+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
67+
pub enum Phase {
68+
/// Data in "captured" on the first clock transition
69+
CaptureOnFirstTransition,
70+
/// Data in "captured" on the second clock transition
71+
CaptureOnSecondTransition,
72+
}
73+
74+
/// SPI mode
75+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
76+
pub struct Mode {
77+
/// Clock polarity
78+
pub polarity: Polarity,
79+
/// Clock phase
80+
pub phase: Phase,
81+
}
82+
5683
/// Interrupt event
5784
pub enum Event {
5885
/// New data has been received
@@ -193,7 +220,7 @@ impl<REMAP, PINS> Spi<pac::SPI1, REMAP, PINS, u8, Master> {
193220
spi: pac::SPI1,
194221
pins: PINS,
195222
mapr: &mut MAPR,
196-
mode: Mode,
223+
mode: impl Into<Mode>,
197224
freq: Hertz,
198225
clocks: Clocks,
199226
) -> Self
@@ -214,7 +241,7 @@ impl<REMAP, PINS> Spi<pac::SPI1, REMAP, PINS, u8, Slave> {
214241
215242
You can also use `NoMiso` or `NoMosi` if you don't want to use the pins
216243
*/
217-
pub fn spi1_slave(spi: pac::SPI1, pins: PINS, mapr: &mut MAPR, mode: Mode) -> Self
244+
pub fn spi1_slave(spi: pac::SPI1, pins: PINS, mapr: &mut MAPR, mode: impl Into<Mode>) -> Self
218245
where
219246
REMAP: Remap<Periph = pac::SPI1>,
220247
PINS: Pins<REMAP, Slave>,
@@ -457,7 +484,8 @@ impl<SPI, REMAP, PINS> Spi<SPI, REMAP, PINS, u8, Master>
457484
where
458485
SPI: Instance,
459486
{
460-
fn configure(spi: SPI, pins: PINS, mode: Mode, freq: Hertz, clocks: Clocks) -> Self {
487+
fn configure(spi: SPI, pins: PINS, mode: impl Into<Mode>, freq: Hertz, clocks: Clocks) -> Self {
488+
let mode = mode.into();
461489
// enable or reset SPI
462490
let rcc = unsafe { &(*RCC::ptr()) };
463491
SPI::enable(rcc);
@@ -517,7 +545,8 @@ impl<SPI, REMAP, PINS> Spi<SPI, REMAP, PINS, u8, Slave>
517545
where
518546
SPI: Instance,
519547
{
520-
fn configure(spi: SPI, pins: PINS, mode: Mode) -> Self {
548+
fn configure(spi: SPI, pins: PINS, mode: impl Into<Mode>) -> Self {
549+
let mode = mode.into();
521550
// enable or reset SPI
522551
let rcc = unsafe { &(*RCC::ptr()) };
523552
SPI::enable(rcc);
@@ -597,6 +626,49 @@ where
597626
}
598627
}
599628

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

602674
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)