1use core::ptr;
2
3use nb;
4
5pub use hal::spi::{Mode, Phase, Polarity};
6use rcc::Clocks;
7
8use stm32::{RCC, SPI1, SPI2};
9
10use gpio::gpioa::{PA5, PA6, PA7};
11use gpio::gpiob::{PB3, PB4, PB5, PB10, PB13, PB14, PB15};
12use gpio::gpioc::{PC2, PC3};
13use gpio::{Alternate, AF0, AF1, AF5};
14use time::Hertz;
15
16#[derive(Debug)]
18pub enum Error {
19 Overrun,
21 ModeFault,
23 Crc,
25 #[doc(hidden)]
26 _Extensible,
27}
28
29pub struct Spi<SPI, PINS> {
31 spi: SPI,
32 pins: PINS,
33}
34
35pub trait Pins<Spi> {}
36
37impl Pins<SPI1>
38 for (
39 PA5<Alternate<AF0>>,
40 PA6<Alternate<AF0>>,
41 PA7<Alternate<AF0>>,
42 )
43{}
44impl Pins<SPI1>
45 for (
46 PB3<Alternate<AF0>>,
47 PB4<Alternate<AF0>>,
48 PB5<Alternate<AF0>>,
49 )
50{}
51
52impl Pins<SPI2>
53 for (
54 PB13<Alternate<AF0>>,
55 PB14<Alternate<AF0>>,
56 PB15<Alternate<AF0>>,
57 )
58{}
59
60impl Pins<SPI2>
61 for (
62 PB10<Alternate<AF5>>,
63 PC2<Alternate<AF1>>,
64 PC3<Alternate<AF1>>,
65 )
66{}
67
68impl<PINS> Spi<SPI1, PINS> {
69 pub fn spi1<F>(spi: SPI1, pins: PINS, mode: Mode, speed: F, clocks: Clocks) -> Self
70 where
71 PINS: Pins<SPI1>,
72 F: Into<Hertz>,
73 {
74 let rcc = unsafe { &(*RCC::ptr()) };
76
77 rcc.apb2enr.modify(|_, w| w.spi1en().set_bit());
79
80 rcc.apb2rstr.modify(|_, w| w.spi1rst().set_bit());
82 rcc.apb2rstr.modify(|_, w| w.spi1rst().clear_bit());
83
84 spi.cr1.modify(|_, w| w.spe().clear_bit());
86
87 spi.cr2
94 .write(|w| unsafe { w.frxth().set_bit().ds().bits(0b0111).ssoe().clear_bit() });
95
96 let br = match clocks.pclk().0 / speed.into().0 {
97 0 => unreachable!(),
98 1...2 => 0b000,
99 3...5 => 0b001,
100 6...11 => 0b010,
101 12...23 => 0b011,
102 24...47 => 0b100,
103 48...95 => 0b101,
104 96...191 => 0b110,
105 _ => 0b111,
106 };
107
108 spi.cr1.write(|w| unsafe {
116 w.cpha()
117 .bit(mode.phase == Phase::CaptureOnSecondTransition)
118 .cpol()
119 .bit(mode.polarity == Polarity::IdleHigh)
120 .mstr()
121 .set_bit()
122 .br()
123 .bits(br)
124 .lsbfirst()
125 .clear_bit()
126 .ssm()
127 .set_bit()
128 .ssi()
129 .set_bit()
130 .rxonly()
131 .clear_bit()
132 .bidimode()
133 .clear_bit()
134 .spe()
135 .set_bit()
136 });
137
138 Spi { spi, pins }
139 }
140
141 pub fn release(self) -> (SPI1, PINS) {
142 (self.spi, self.pins)
143 }
144}
145
146impl<PINS> ::hal::spi::FullDuplex<u8> for Spi<SPI1, PINS> {
147 type Error = Error;
148
149 fn read(&mut self) -> nb::Result<u8, Error> {
150 let sr = self.spi.sr.read();
151
152 Err(if sr.ovr().bit_is_set() {
153 nb::Error::Other(Error::Overrun)
154 } else if sr.modf().bit_is_set() {
155 nb::Error::Other(Error::ModeFault)
156 } else if sr.crcerr().bit_is_set() {
157 nb::Error::Other(Error::Crc)
158 } else if sr.rxne().bit_is_set() {
159 return Ok(unsafe { ptr::read_volatile(&self.spi.dr as *const _ as *const u8) });
162 } else {
163 nb::Error::WouldBlock
164 })
165 }
166
167 fn send(&mut self, byte: u8) -> nb::Result<(), Error> {
168 let sr = self.spi.sr.read();
169
170 Err(if sr.ovr().bit_is_set() {
171 nb::Error::Other(Error::Overrun)
172 } else if sr.modf().bit_is_set() {
173 nb::Error::Other(Error::ModeFault)
174 } else if sr.crcerr().bit_is_set() {
175 nb::Error::Other(Error::Crc)
176 } else if sr.txe().bit_is_set() {
177 unsafe { ptr::write_volatile(&self.spi.dr as *const _ as *mut u8, byte) }
179 return Ok(());
180 } else {
181 nb::Error::WouldBlock
182 })
183 }
184}
185
186impl<PINS> ::hal::blocking::spi::transfer::Default<u8> for Spi<SPI1, PINS> {}
187impl<PINS> ::hal::blocking::spi::write::Default<u8> for Spi<SPI1, PINS> {}
188
189impl<PINS> Spi<SPI2, PINS> {
190 pub fn spi2<F>(spi: SPI2, pins: PINS, mode: Mode, speed: F, clocks: Clocks) -> Self
191 where
192 PINS: Pins<SPI2>,
193 F: Into<Hertz>,
194 {
195 let rcc = unsafe { &(*RCC::ptr()) };
197
198 rcc.apb1enr.modify(|_, w| w.spi2en().set_bit());
200
201 rcc.apb1rstr.modify(|_, w| w.spi2rst().set_bit());
203 rcc.apb1rstr.modify(|_, w| w.spi2rst().clear_bit());
204
205 spi.cr1.modify(|_, w| w.spe().clear_bit());
207
208 spi.cr2
215 .write(|w| unsafe { w.frxth().set_bit().ds().bits(0b0111).ssoe().clear_bit() });
216
217 let br = match clocks.pclk().0 / speed.into().0 {
218 0 => unreachable!(),
219 1...2 => 0b000,
220 3...5 => 0b001,
221 6...11 => 0b010,
222 12...23 => 0b011,
223 24...47 => 0b100,
224 48...95 => 0b101,
225 96...191 => 0b110,
226 _ => 0b111,
227 };
228
229 spi.cr1.write(|w| unsafe {
237 w.cpha()
238 .bit(mode.phase == Phase::CaptureOnSecondTransition)
239 .cpol()
240 .bit(mode.polarity == Polarity::IdleHigh)
241 .mstr()
242 .set_bit()
243 .br()
244 .bits(br)
245 .lsbfirst()
246 .clear_bit()
247 .ssm()
248 .set_bit()
249 .ssi()
250 .set_bit()
251 .rxonly()
252 .clear_bit()
253 .bidimode()
254 .clear_bit()
255 .spe()
256 .set_bit()
257 });
258
259 Spi { spi, pins }
260 }
261
262 pub fn release(self) -> (SPI2, PINS) {
263 (self.spi, self.pins)
264 }
265}
266
267impl<PINS> ::hal::spi::FullDuplex<u8> for Spi<SPI2, PINS> {
268 type Error = Error;
269
270 fn read(&mut self) -> nb::Result<u8, Error> {
271 let sr = self.spi.sr.read();
272
273 Err(if sr.ovr().bit_is_set() {
274 nb::Error::Other(Error::Overrun)
275 } else if sr.modf().bit_is_set() {
276 nb::Error::Other(Error::ModeFault)
277 } else if sr.crcerr().bit_is_set() {
278 nb::Error::Other(Error::Crc)
279 } else if sr.rxne().bit_is_set() {
280 return Ok(unsafe { ptr::read_volatile(&self.spi.dr as *const _ as *const u8) });
283 } else {
284 nb::Error::WouldBlock
285 })
286 }
287
288 fn send(&mut self, byte: u8) -> nb::Result<(), Error> {
289 let sr = self.spi.sr.read();
290
291 Err(if sr.ovr().bit_is_set() {
292 nb::Error::Other(Error::Overrun)
293 } else if sr.modf().bit_is_set() {
294 nb::Error::Other(Error::ModeFault)
295 } else if sr.crcerr().bit_is_set() {
296 nb::Error::Other(Error::Crc)
297 } else if sr.txe().bit_is_set() {
298 unsafe { ptr::write_volatile(&self.spi.dr as *const _ as *mut u8, byte) }
300 return Ok(());
301 } else {
302 nb::Error::WouldBlock
303 })
304 }
305}
306
307impl<PINS> ::hal::blocking::spi::transfer::Default<u8> for Spi<SPI2, PINS> {}
308impl<PINS> ::hal::blocking::spi::write::Default<u8> for Spi<SPI2, PINS> {}