Skip to content

Commit 42f27d1

Browse files
committed
spi nb
1 parent 8162c5e commit 42f27d1

File tree

3 files changed

+160
-30
lines changed

3 files changed

+160
-30
lines changed

src/spi.rs

Lines changed: 68 additions & 1 deletion
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
@@ -601,6 +628,46 @@ where
601628
}
602629
}
603630

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

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

src/spi/hal_02.rs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,35 @@
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

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+
533
impl<SPI, REMAP, PINS, FrameSize, OP> spi::FullDuplex<FrameSize>
634
for Spi<SPI, REMAP, PINS, FrameSize, OP>
735
where
@@ -11,38 +39,11 @@ where
1139
type Error = Error;
1240

1341
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-
})
42+
self.read_nonblocking()
2943
}
3044

3145
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-
})
46+
self.write_nonblocking(data)
4647
}
4748
}
4849

src/spi/hal_1.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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, FrameSize, OP> ErrorType for Spi<SPI, REMAP, PINS, FrameSize, 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, FrameSize, OP> FullDuplex<FrameSize> for Spi<SPI, REMAP, PINS, FrameSize, OP>
50+
where
51+
SPI: Instance,
52+
FrameSize: Copy,
53+
{
54+
fn read(&mut self) -> nb::Result<FrameSize, Error> {
55+
self.read_nonblocking()
56+
}
57+
58+
fn write(&mut self, data: FrameSize) -> nb::Result<(), Error> {
59+
self.write_nonblocking(data)
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)