1use core::ptr;
3use core::ops::Deref;
4
5use embedded_hal::spi;
6pub use embedded_hal::spi::{Mode, Phase, Polarity};
7use nb;
8
9use crate::stm32::{spi1, SPI1, SPI2, SPI3, SPI4, SPI5, SPI6, RCC};
10
11use crate::gpio::{
12 gpioa::{PA1, PA5, PA6, PA7, PA9, PA10, PA11, PA12},
13 gpiob::{PB0, PB2, PB3, PB4, PB5, PB8, PB10, PB12, PB13, PB14, PB15},
14 gpioc::{PC1, PC2, PC3, PC7, PC10, PC11, PC12},
15 gpiod::{PD0, PD3, PD6},
16 gpioe::{PE2, PE5, PE6, PE12, PE13, PE14},
17 gpiof::{PF7, PF8, PF9, PF11},
18 gpiog::{PG11, PG12, PG13, PG14},
19 gpioh::{PH6, PH7},
20 gpioi::{PI1, PI2, PI3},
21};
22
23use crate::gpio::{Alternate, AF5, AF6, AF7};
24
25use crate::rcc::Clocks;
26use crate::time::Hertz;
27
28#[derive(Debug)]
30pub enum Error {
31 Overrun,
33 ModeFault,
35 Crc,
37 #[doc(hidden)]
38 _Extensible,
39}
40
41pub trait Pins<SPI> {}
42pub trait PinSck<SPI> {}
43pub trait PinMiso<SPI> {}
44pub trait PinMosi<SPI> {}
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
53pub struct NoSck;
55pub struct NoMiso;
57pub struct NoMosi;
59
60macro_rules! pins {
61 ($($SPIX:ty: SCK: [$($SCK:ty),*] MISO: [$($MISO:ty),*] MOSI: [$($MOSI:ty),*])+) => {
62 $(
63 $(
64 impl PinSck<$SPIX> for $SCK {}
65 )*
66 $(
67 impl PinMiso<$SPIX> for $MISO {}
68 )*
69 $(
70 impl PinMosi<$SPIX> for $MOSI {}
71 )*
72 )+
73 }
74}
75
76pins! {
77 SPI1:
78 SCK: [
79 NoSck,
80 PA5<Alternate<AF5>>,
81 PB3<Alternate<AF5>>
82 ]
83 MISO: [
84 NoMiso,
85 PA6<Alternate<AF5>>,
86 PB4<Alternate<AF5>>
87 ]
88 MOSI: [
89 NoMosi,
90 PA7<Alternate<AF5>>,
91 PB5<Alternate<AF5>>
92 ]
93
94 SPI2:
95 SCK: [
96 NoSck,
97 PB10<Alternate<AF5>>,
98 PB13<Alternate<AF5>>
99 ]
100 MISO: [
101 NoMiso,
102 PB14<Alternate<AF5>>,
103 PC2<Alternate<AF5>>
104 ]
105 MOSI: [
106 NoMosi,
107 PB15<Alternate<AF5>>,
108 PC3<Alternate<AF5>>
109 ]
110}
111
112pins! {
113 SPI3:
114 SCK: [
115 NoSck,
116 PB3<Alternate<AF6>>,
117 PC10<Alternate<AF6>>
118 ]
119 MISO: [
120 NoMiso,
121 PB4<Alternate<AF6>>,
122 PC11<Alternate<AF6>>
123 ]
124 MOSI: [
125 NoMosi,
126 PB5<Alternate<AF6>>,
127 PC12<Alternate<AF6>>
128 ]
129}
130
131pins! {
132 SPI2:
133 SCK: [PD3<Alternate<AF5>>]
134 MISO: []
135 MOSI: []
136 SPI3:
137 SCK: []
138 MISO: []
139 MOSI: [PD6<Alternate<AF5>>]
140 SPI4:
141 SCK: [
142 NoSck,
143 PE2<Alternate<AF5>>,
144 PE12<Alternate<AF5>>
145 ]
146 MISO: [
147 NoMiso,
148 PE5<Alternate<AF5>>,
149 PE13<Alternate<AF5>>
150 ]
151 MOSI: [
152 NoMosi,
153 PE6<Alternate<AF5>>,
154 PE14<Alternate<AF5>>
155 ]
156}
157
158pins! {
159 SPI2:
160 SCK: [PI1<Alternate<AF5>>]
161 MISO: [PI2<Alternate<AF5>>]
162 MOSI: [PI3<Alternate<AF5>>]
163}
164
165pins! {
166 SPI2:
167 SCK: [PC7<Alternate<AF5>>]
168 MISO: []
169 MOSI: []
170}
171
172pins! {
173 SPI5:
174 SCK: [
175 NoSck,
176 PB0<Alternate<AF6>>
177 ]
178 MISO: [
179 NoMiso,
180 PA12<Alternate<AF6>>
181 ]
182 MOSI: [
183 NoMosi,
184 PA10<Alternate<AF6>>,
185 PB8<Alternate<AF6>>
186 ]
187}
188
189pins! {
190 SPI3:
191 SCK: [PB12<Alternate<AF7>>]
192 MISO: []
193 MOSI: []
194 SPI4:
195 SCK: [PB13<Alternate<AF6>>]
196 MISO: [PA11<Alternate<AF6>>]
197 MOSI: [PA1<Alternate<AF5>>]
198 SPI5:
199 SCK: [
200 PE2<Alternate<AF6>>,
201 PE12<Alternate<AF6>>
202 ]
203 MISO: [
204 PE5<Alternate<AF6>>,
205 PE13<Alternate<AF6>>
206 ]
207 MOSI: [
208 PE6<Alternate<AF6>>,
209 PE14<Alternate<AF6>>
210 ]
211}
212
213pins! {
214 SPI2:
215 SCK: [PA9<Alternate<AF5>>]
216 MISO: [PA12<Alternate<AF5>>]
217 MOSI: [PA10<Alternate<AF5>>]
218}
219
220pins! {
221 SPI5:
222 SCK: [
223 PF7<Alternate<AF5>>,
224 PH6<Alternate<AF5>>
225 ]
226 MISO: [
227 PF8<Alternate<AF5>>,
228 PH7<Alternate<AF5>>
229 ]
230 MOSI: [
231 PF9<Alternate<AF5>>,
232 PF11<Alternate<AF5>>
233 ]
234
235 SPI6:
236 SCK: [
237 NoSck,
238 PG13<Alternate<AF5>>
239 ]
240 MISO: [
241 NoMiso,
242 PG12<Alternate<AF5>>
243 ]
244 MOSI: [
245 NoMosi,
246 PG14<Alternate<AF5>>
247 ]
248}
249
250pins! {
251 SPI2:
252 SCK: []
253 MISO: []
254 MOSI: [PC1<Alternate<AF7>>]
255
256 SPI3:
257 SCK: []
258 MISO: []
259 MOSI: [
260 PB0<Alternate<AF7>>,
261 PB2<Alternate<AF7>>,
262 PD0<Alternate<AF6>>
263 ]
264
265 SPI4:
266 SCK: [PG11<Alternate<AF6>>]
267 MISO: [
268 PG12<Alternate<AF6>>,
269 PD0<Alternate<AF5>>
270 ]
271 MOSI: [PG13<Alternate<AF6>>]
272}
273
274pins! {
275 SPI2:
276 SCK: []
277 MISO: []
278 MOSI: [PC1<Alternate<AF5>>]
279}
280
281pub enum Event {
283 Rxne,
285 Txe,
287 Error,
289}
290
291#[derive(Debug)]
292pub struct Spi<SPI, PINS> {
293 spi: SPI,
294 pins: PINS,
295}
296
297impl<PINS> Spi<SPI1, PINS> {
298 pub fn spi1(spi: SPI1, pins: PINS, mode: Mode, freq: Hertz, clocks: Clocks) -> Self
299 where
300 PINS: Pins<SPI1>
301 {
302 let rcc = unsafe { &(*RCC::ptr()) };
304
305 rcc.apb2enr.modify(|_, w| w.spi1en().set_bit());
307
308 Spi { spi, pins }.init(mode, freq, clocks.pclk2())
309 }
310}
311
312impl<PINS> Spi<SPI2, PINS> {
313 pub fn spi2(spi: SPI2, pins: PINS, mode: Mode, freq: Hertz, clocks: Clocks) -> Self
314 where
315 PINS: Pins<SPI2>
316 {
317 let rcc = unsafe { &(*RCC::ptr()) };
319
320 rcc.apb1enr.modify(|_, w| w.spi2en().set_bit());
322
323 Spi { spi, pins }.init(mode, freq, clocks.pclk1())
324 }
325}
326
327impl<PINS> Spi<SPI3, PINS> {
328 pub fn spi3(spi: SPI3, pins: PINS, mode: Mode, freq: Hertz, clocks: Clocks) -> Self
329 where
330 PINS: Pins<SPI3>
331 {
332 let rcc = unsafe { &(*RCC::ptr()) };
334
335 rcc.apb1enr.modify(|_, w| w.spi3en().set_bit());
337
338 Spi { spi, pins }.init(mode, freq, clocks.pclk1())
339 }
340}
341
342impl<PINS> Spi<SPI4, PINS> {
343 pub fn spi4(spi: SPI4, pins: PINS, mode: Mode, freq: Hertz, clocks: Clocks) -> Self
344 where
345 PINS: Pins<SPI4>
346 {
347 let rcc = unsafe { &(*RCC::ptr()) };
349
350 rcc.apb2enr.modify(|_, w| w.spi4en().set_bit());
352
353 Spi { spi, pins }.init(mode, freq, clocks.pclk2())
354 }
355}
356
357impl<PINS> Spi<SPI5, PINS> {
358 pub fn spi5(spi: SPI5, pins: PINS, mode: Mode, freq: Hertz, clocks: Clocks) -> Self
359 where
360 PINS: Pins<SPI5>
361 {
362 let rcc = unsafe { &(*RCC::ptr()) };
364
365 rcc.apb2enr.modify(|_, w| w.spi5en().set_bit());
367
368 Spi { spi, pins }.init(mode, freq, clocks.pclk2())
369 }
370}
371
372impl<PINS> Spi<SPI6, PINS> {
373 pub fn spi6(spi: SPI6, pins: PINS, mode: Mode, freq: Hertz, clocks: Clocks) -> Self
374 where
375 PINS: Pins<SPI6>
376 {
377 let rcc = unsafe { &(*RCC::ptr()) };
379
380 rcc.apb2enr.modify(|_, w| w.spi6en().set_bit());
382
383 Spi { spi, pins }.init(mode, freq, clocks.pclk2())
384 }
385}
386
387impl<SPI, PINS> Spi<SPI, PINS>
388where
389 SPI: Deref<Target = spi1::RegisterBlock>,
390{
391 pub fn init(self, mode: Mode, freq: Hertz, clock: Hertz) -> Self
392 {
393 self.spi.cr1.write(|w| w.spe().clear_bit());
395
396 self.spi.cr2.write(|w| w.ssoe().clear_bit());
398
399 let br = match clock.0 / freq.0 {
400 0 => unreachable!(),
401 1...2 => 0b000,
402 3...5 => 0b001,
403 6...11 => 0b010,
404 12...23 => 0b011,
405 24...47 => 0b100,
406 48...95 => 0b101,
407 96...191 => 0b110,
408 _ => 0b111,
409 };
410
411 self.spi.cr2.write(|w| { unsafe { w
414 .ds()
415 .bits(0b111)
416 .frxth()
417 .set_bit()
418 }});
419
420 self.spi.cr1.write(|w| { w
427 .cpha()
428 .bit(mode.phase == Phase::CaptureOnSecondTransition)
429 .cpol()
430 .bit(mode.polarity == Polarity::IdleHigh)
431 .mstr()
432 .set_bit()
433 .br()
434 .bits(br)
435 .lsbfirst()
436 .clear_bit()
437 .ssm()
438 .set_bit()
439 .ssi()
440 .set_bit()
441 .rxonly()
442 .clear_bit()
443 .bidimode()
444 .clear_bit()
445 .bidioe()
446 .clear_bit()
447 .spe()
448 .set_bit()
449 });
450
451 self
452 }
453
454 pub fn listen(&mut self, event: Event) {
459 match event {
460 Event::Rxne => self.spi.cr2.modify(|_, w| { w.rxneie().set_bit() }),
461 Event::Txe => self.spi.cr2.modify(|_, w| { w.txeie().set_bit() }),
462 Event::Error => self.spi.cr2.modify(|_, w| { w.errie().set_bit() }),
463 }
464 }
465
466 pub fn unlisten(&mut self, event: Event) {
471 match event {
472 Event::Rxne => self.spi.cr2.modify(|_, w| { w.rxneie().clear_bit() }),
473 Event::Txe => self.spi.cr2.modify(|_, w| { w.txeie().clear_bit() }),
474 Event::Error => self.spi.cr2.modify(|_, w| { w.errie().clear_bit() }),
475 }
476 }
477
478 pub fn is_txe(&self) -> bool {
481 self.spi.sr.read().txe().bit_is_set()
482 }
483
484 pub fn is_rxne(&self) -> bool {
487 self.spi.sr.read().rxne().bit_is_set()
488 }
489
490 pub fn is_modf(&self) -> bool {
493 self.spi.sr.read().modf().bit_is_set()
494 }
495
496 pub fn is_ovr(&self) -> bool {
499 self.spi.sr.read().ovr().bit_is_set()
500 }
501
502 pub fn free(self) -> (SPI, PINS) {
503 (self.spi, self.pins)
504 }
505}
506
507impl<SPI, PINS> spi::FullDuplex<u8> for Spi<SPI, PINS>
508where
509 SPI: Deref<Target = spi1::RegisterBlock>,
510{
511 type Error = Error;
512
513 fn read(&mut self) -> nb::Result<u8, Error> {
514 let sr = self.spi.sr.read();
515
516 Err(if sr.ovr().bit_is_set() {
517 nb::Error::Other(Error::Overrun)
518 } else if sr.modf().bit_is_set() {
519 nb::Error::Other(Error::ModeFault)
520 } else if sr.crcerr().bit_is_set() {
521 nb::Error::Other(Error::Crc)
522 } else if sr.rxne().bit_is_set() {
523 return Ok(unsafe {
526 ptr::read_volatile(&self.spi.dr as *const _ as *const u8)
527 });
528 } else {
529 nb::Error::WouldBlock
530 })
531 }
532
533 fn send(&mut self, byte: u8) -> nb::Result<(), Error> {
534 let sr = self.spi.sr.read();
535
536 Err(if sr.ovr().bit_is_set() {
537 nb::Error::Other(Error::Overrun)
538 } else if sr.modf().bit_is_set() {
539 nb::Error::Other(Error::ModeFault)
540 } else if sr.crcerr().bit_is_set() {
541 nb::Error::Other(Error::Crc)
542 } else if sr.txe().bit_is_set() {
543 unsafe { ptr::write_volatile(&self.spi.dr as *const _ as *mut u8, byte) }
545 return Ok(());
546 } else {
547 nb::Error::WouldBlock
548 })
549 }
550}
551
552impl<SPI, PINS> embedded_hal::blocking::spi::transfer::Default<u8> for Spi<SPI, PINS>
553where
554 SPI: Deref<Target = spi1::RegisterBlock>,
555{}
556
557impl<SPI, PINS> embedded_hal::blocking::spi::write::Default<u8> for Spi<SPI, PINS>
558where
559 SPI: Deref<Target = spi1::RegisterBlock>,
560{}
561
562
563
564