1use core::ptr;
2
3use nb;
4
5pub use hal::spi::{Mode, Phase, Polarity};
6use rcc::Clocks;
7
8use stm32::{RCC, SPI1};
9
10use gpio::gpioa::{PA5, PA6, PA7};
11use gpio::gpiob::{PB3, PB4, PB5};
12use gpio::{Alternate, AF0};
13use time::Hertz;
14
15#[derive(Debug)]
17pub enum Error {
18 Overrun,
20 ModeFault,
22 Crc,
24 #[doc(hidden)]
25 _Extensible,
26}
27
28pub struct Spi<SPI, PINS> {
30 spi: SPI,
31 pins: PINS,
32}
33
34pub trait Pins<Spi> {}
35
36impl Pins<SPI1>
37 for (
38 PA5<Alternate<AF0>>,
39 PA6<Alternate<AF0>>,
40 PA7<Alternate<AF0>>,
41 )
42{}
43impl Pins<SPI1>
44 for (
45 PB3<Alternate<AF0>>,
46 PB4<Alternate<AF0>>,
47 PB5<Alternate<AF0>>,
48 )
49{}
50
51impl<PINS> Spi<SPI1, PINS> {
52 pub fn spi1<F>(spi: SPI1, pins: PINS, mode: Mode, speed: F, clocks: Clocks) -> Self
53 where
54 PINS: Pins<SPI1>,
55 F: Into<Hertz>,
56 {
57 let rcc = unsafe { &(*RCC::ptr()) };
59
60 rcc.apb2enr.modify(|_, w| w.spi1en().set_bit());
62
63 rcc.apb2rstr.modify(|_, w| w.spi1rst().set_bit());
65 rcc.apb2rstr.modify(|_, w| w.spi1rst().clear_bit());
66
67 spi.cr1.modify(|_, w| w.spe().clear_bit());
69
70 spi.cr2
77 .write(|w| unsafe { w.frxth().set_bit().ds().bits(0b0111).ssoe().clear_bit() });
78
79 let br = match clocks.pclk().0 / speed.into().0 {
80 0 => unreachable!(),
81 1...2 => 0b000,
82 3...5 => 0b001,
83 6...11 => 0b010,
84 12...23 => 0b011,
85 24...47 => 0b100,
86 48...95 => 0b101,
87 96...191 => 0b110,
88 _ => 0b111,
89 };
90
91 spi.cr1.write(|w| unsafe {
99 w.cpha()
100 .bit(mode.phase == Phase::CaptureOnSecondTransition)
101 .cpol()
102 .bit(mode.polarity == Polarity::IdleHigh)
103 .mstr()
104 .set_bit()
105 .br()
106 .bits(br)
107 .lsbfirst()
108 .clear_bit()
109 .ssm()
110 .set_bit()
111 .ssi()
112 .set_bit()
113 .rxonly()
114 .clear_bit()
115 .bidimode()
116 .clear_bit()
117 .spe()
118 .set_bit()
119 });
120
121 Spi { spi, pins }
122 }
123
124 pub fn release(self) -> (SPI1, PINS) {
125 (self.spi, self.pins)
126 }
127}
128
129impl<PINS> ::hal::spi::FullDuplex<u8> for Spi<SPI1, PINS> {
130 type Error = Error;
131
132 fn read(&mut self) -> nb::Result<u8, Error> {
133 let sr = self.spi.sr.read();
134
135 Err(if sr.ovr().bit_is_set() {
136 nb::Error::Other(Error::Overrun)
137 } else if sr.modf().bit_is_set() {
138 nb::Error::Other(Error::ModeFault)
139 } else if sr.crcerr().bit_is_set() {
140 nb::Error::Other(Error::Crc)
141 } else if sr.rxne().bit_is_set() {
142 return Ok(unsafe { ptr::read_volatile(&self.spi.dr as *const _ as *const u8) });
145 } else {
146 nb::Error::WouldBlock
147 })
148 }
149
150 fn send(&mut self, byte: u8) -> nb::Result<(), Error> {
151 let sr = self.spi.sr.read();
152
153 Err(if sr.ovr().bit_is_set() {
154 nb::Error::Other(Error::Overrun)
155 } else if sr.modf().bit_is_set() {
156 nb::Error::Other(Error::ModeFault)
157 } else if sr.crcerr().bit_is_set() {
158 nb::Error::Other(Error::Crc)
159 } else if sr.txe().bit_is_set() {
160 unsafe { ptr::write_volatile(&self.spi.dr as *const _ as *mut u8, byte) }
162 return Ok(());
163 } else {
164 nb::Error::WouldBlock
165 })
166 }
167}
168
169impl<PINS> ::hal::blocking::spi::transfer::Default<u8> for Spi<SPI1, PINS> {}
170impl<PINS> ::hal::blocking::spi::write::Default<u8> for Spi<SPI1, PINS> {}