1use crate::gpio::*;
2use crate::rcc::*;
3use crate::stm32::{SPI1, SPI2};
4use crate::time::Hertz;
5use core::ptr;
6pub use hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
7
8#[derive(Debug)]
10pub enum Error {
11 Overrun,
13 ModeFault,
15 Crc,
17}
18
19pub struct NoSck;
21pub struct NoMiso;
23pub struct NoMosi;
25
26pub trait Pins<SPI> {
27 fn setup(&self);
28 fn release(self) -> Self;
29}
30
31pub trait PinSck<SPI> {
32 fn setup(&self);
33 fn release(self) -> Self;
34}
35
36pub trait PinMiso<SPI> {
37 fn setup(&self);
38 fn release(self) -> Self;
39}
40
41pub trait PinMosi<SPI> {
42 fn setup(&self);
43 fn release(self) -> Self;
44}
45
46impl<SPI, SCK, MISO, MOSI> Pins<SPI> for (SCK, MISO, MOSI)
47where
48 SCK: PinSck<SPI>,
49 MISO: PinMiso<SPI>,
50 MOSI: PinMosi<SPI>,
51{
52 fn setup(&self) {
53 self.0.setup();
54 self.1.setup();
55 self.2.setup();
56 }
57
58 fn release(self) -> Self {
59 (self.0.release(), self.1.release(), self.2.release())
60 }
61}
62
63#[derive(Debug)]
64pub struct Spi<SPI, PINS> {
65 spi: SPI,
66 pins: PINS,
67}
68
69pub trait SpiExt: Sized {
70 fn spi<PINS>(self, pins: PINS, mode: Mode, freq: Hertz, rcc: &mut Rcc) -> Spi<Self, PINS>
71 where
72 PINS: Pins<Self>;
73}
74
75macro_rules! spi {
76 ($SPIX:ident, $spiX:ident,
77 sck: [ $(($SCK:ty, $SCK_AF:expr),)+ ],
78 miso: [ $(($MISO:ty, $MISO_AF:expr),)+ ],
79 mosi: [ $(($MOSI:ty, $MOSI_AF:expr),)+ ],
80 ) => {
81 impl PinSck<$SPIX> for NoSck {
82 fn setup(&self) {}
83
84 fn release(self) -> Self {
85 self
86 }
87 }
88
89 impl PinMiso<$SPIX> for NoMiso {
90 fn setup(&self) {}
91
92 fn release(self) -> Self {
93 self
94 }
95 }
96
97 impl PinMosi<$SPIX> for NoMosi {
98 fn setup(&self) {}
99
100 fn release(self) -> Self {
101 self
102 }
103 }
104
105 $(
106 impl PinSck<$SPIX> for $SCK {
107 fn setup(&self) {
108 self.set_alt_mode($SCK_AF);
109 }
110
111 fn release(self) -> Self {
112 self.into_analog()
113 }
114 }
115 )*
116 $(
117 impl PinMiso<$SPIX> for $MISO {
118 fn setup(&self) {
119 self.set_alt_mode($MISO_AF);
120 }
121
122 fn release(self) -> Self {
123 self.into_analog()
124 }
125 }
126 )*
127 $(
128 impl PinMosi<$SPIX> for $MOSI {
129 fn setup(&self) {
130 self.set_alt_mode($MOSI_AF);
131 }
132
133 fn release(self) -> Self {
134 self.into_analog()
135 }
136 }
137 )*
138
139 impl<PINS: Pins<$SPIX>> Spi<$SPIX, PINS> {
140 pub fn $spiX(
141 spi: $SPIX,
142 pins: PINS,
143 mode: Mode,
144 speed: Hertz,
145 rcc: &mut Rcc
146 ) -> Self {
147 $SPIX::enable(rcc);
148 $SPIX::reset(rcc);
149
150 spi.cr2.write(|w| w.ssoe().clear_bit());
152
153 let br = match rcc.clocks.apb_clk / speed {
154 0 => unreachable!(),
155 1..=2 => 0b000,
156 3..=5 => 0b001,
157 6..=11 => 0b010,
158 12..=23 => 0b011,
159 24..=47 => 0b100,
160 48..=95 => 0b101,
161 96..=191 => 0b110,
162 _ => 0b111,
163 };
164
165 spi.cr2.write(|w| unsafe {
166 w.frxth().set_bit().ds().bits(0b111).ssoe().clear_bit()
167 });
168
169 pins.setup();
171
172 spi.cr1.write(|w| unsafe {
173 w.cpha()
174 .bit(mode.phase == Phase::CaptureOnSecondTransition)
175 .cpol()
176 .bit(mode.polarity == Polarity::IdleHigh)
177 .mstr()
178 .set_bit()
179 .br()
180 .bits(br)
181 .lsbfirst()
182 .clear_bit()
183 .ssm()
184 .set_bit()
185 .ssi()
186 .set_bit()
187 .rxonly()
188 .clear_bit()
189 .dff()
190 .clear_bit()
191 .bidimode()
192 .clear_bit()
193 .ssi()
194 .set_bit()
195 .spe()
196 .set_bit()
197 });
198
199 Spi { spi, pins }
200 }
201
202 pub fn data_size(&mut self, nr_bits: u8) {
203 self.spi.cr2.modify(|_, w| unsafe {
204 w.ds().bits(nr_bits-1)
205 });
206 }
207
208 pub fn half_duplex_enable(&mut self, enable: bool) {
209 self.spi.cr1.modify(|_, w|
210 w.bidimode().bit(enable)
211 );
212 }
213
214 pub fn half_duplex_output_enable(&mut self, enable: bool) {
215 self.spi.cr1.modify(|_, w|
216 w.bidioe().bit(enable)
217 );
218 }
219
220 pub fn release(self) -> ($SPIX, PINS) {
221 (self.spi, self.pins.release())
222 }
223 }
224
225 impl SpiExt for $SPIX {
226 fn spi<PINS>(self, pins: PINS, mode: Mode, freq: Hertz, rcc: &mut Rcc) -> Spi<$SPIX, PINS>
227 where
228 PINS: Pins<$SPIX>,
229 {
230 Spi::$spiX(self, pins, mode, freq, rcc)
231 }
232 }
233
234 impl<PINS> hal::spi::FullDuplex<u8> for Spi<$SPIX, PINS> {
235 type Error = Error;
236
237 fn read(&mut self) -> nb::Result<u8, Error> {
238 let sr = self.spi.sr.read();
239
240 Err(if sr.ovr().bit_is_set() {
241 nb::Error::Other(Error::Overrun)
242 } else if sr.modf().bit_is_set() {
243 nb::Error::Other(Error::ModeFault)
244 } else if sr.crcerr().bit_is_set() {
245 nb::Error::Other(Error::Crc)
246 } else if sr.rxne().bit_is_set() {
247 return Ok(unsafe {
250 ptr::read_volatile(&self.spi.dr as *const _ as *const u8)
251 });
252 } else {
253 nb::Error::WouldBlock
254 })
255 }
256
257 fn send(&mut self, byte: u8) -> nb::Result<(), Error> {
258 let sr = self.spi.sr.read();
259
260 Err(if sr.ovr().bit_is_set() {
261 nb::Error::Other(Error::Overrun)
262 } else if sr.modf().bit_is_set() {
263 nb::Error::Other(Error::ModeFault)
264 } else if sr.crcerr().bit_is_set() {
265 nb::Error::Other(Error::Crc)
266 } else if sr.txe().bit_is_set() {
267 unsafe { ptr::write_volatile(&self.spi.dr as *const _ as *mut u8, byte) }
269 return Ok(());
270 } else {
271 nb::Error::WouldBlock
272 })
273 }
274 }
275
276 impl<PINS> ::hal::blocking::spi::transfer::Default<u8> for Spi<$SPIX, PINS> {}
277
278 impl<PINS> ::hal::blocking::spi::write::Default<u8> for Spi<$SPIX, PINS> {}
279 }
280}
281
282spi!(
283 SPI1,
284 spi1,
285 sck: [
286 (PA1<DefaultMode>, AltFunction::AF0),
287 (PA5<DefaultMode>, AltFunction::AF0),
288 (PB3<DefaultMode>, AltFunction::AF0),
289 (PD8<DefaultMode>, AltFunction::AF1),
290 ],
291 miso: [
292 (PA6<DefaultMode>, AltFunction::AF0),
293 (PA11<DefaultMode>, AltFunction::AF0),
294 (PB4<DefaultMode>, AltFunction::AF0),
295 (PD5<DefaultMode>, AltFunction::AF1),
296 ],
297 mosi: [
298 (PA2<DefaultMode>, AltFunction::AF0),
299 (PA7<DefaultMode>, AltFunction::AF0),
300 (PA12<DefaultMode>, AltFunction::AF0),
301 (PB5<DefaultMode>, AltFunction::AF0),
302 (PD6<DefaultMode>, AltFunction::AF1),
303 ],
304);
305
306spi!(
307 SPI2,
308 spi2,
309 sck: [
310 (PA0<DefaultMode>, AltFunction::AF0),
311 (PB8<DefaultMode>, AltFunction::AF1),
312 (PB10<DefaultMode>, AltFunction::AF5),
313 (PB13<DefaultMode>, AltFunction::AF0),
314 (PD1<DefaultMode>, AltFunction::AF1),
315 ],
316 miso: [
317 (PA3<DefaultMode>, AltFunction::AF0),
318 (PA9<DefaultMode>, AltFunction::AF4),
319 (PB2<DefaultMode>, AltFunction::AF1),
320 (PB6<DefaultMode>, AltFunction::AF4),
321 (PB14<DefaultMode>, AltFunction::AF0),
322 (PC2<DefaultMode>, AltFunction::AF1),
323 (PD3<DefaultMode>, AltFunction::AF1),
324 ],
325 mosi: [
326 (PA4<DefaultMode>, AltFunction::AF1),
327 (PA10<DefaultMode>, AltFunction::AF0),
328 (PB7<DefaultMode>, AltFunction::AF1),
329 (PB11<DefaultMode>, AltFunction::AF0),
330 (PB15<DefaultMode>, AltFunction::AF0),
331 (PC3<DefaultMode>, AltFunction::AF1),
332 (PD4<DefaultMode>, AltFunction::AF1),
333 ],
334);