spi.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. use core::ptr;
  2. use hal;
  3. pub use hal::spi::{Mode, Phase, Polarity};
  4. use nb;
  5. use stm32::{SPI1, SPI2};
  6. use afio::MAPR;
  7. use gpio::gpioa::{PA5, PA6, PA7};
  8. use gpio::gpiob::{PB13, PB14, PB15, PB3, PB4, PB5};
  9. use gpio::{Alternate, Floating, Input, PushPull};
  10. use rcc::{APB1, APB2, Clocks};
  11. use time::Hertz;
  12. /// SPI error
  13. #[derive(Debug)]
  14. pub enum Error {
  15. /// Overrun occurred
  16. Overrun,
  17. /// Mode fault occurred
  18. ModeFault,
  19. /// CRC error
  20. Crc,
  21. #[doc(hidden)]
  22. _Extensible,
  23. }
  24. pub trait Pins<SPI> {
  25. const REMAP: bool;
  26. }
  27. impl Pins<SPI1>
  28. for (
  29. PA5<Alternate<PushPull>>,
  30. PA6<Input<Floating>>,
  31. PA7<Alternate<PushPull>>,
  32. )
  33. {
  34. const REMAP: bool = false;
  35. }
  36. impl Pins<SPI1>
  37. for (
  38. PB3<Alternate<PushPull>>,
  39. PB4<Input<Floating>>,
  40. PB5<Alternate<PushPull>>,
  41. )
  42. {
  43. const REMAP: bool = true;
  44. }
  45. impl Pins<SPI2>
  46. for (
  47. PB13<Alternate<PushPull>>,
  48. PB14<Input<Floating>>,
  49. PB15<Alternate<PushPull>>,
  50. )
  51. {
  52. const REMAP: bool = false;
  53. }
  54. pub struct Spi<SPI, PINS> {
  55. spi: SPI,
  56. pins: PINS,
  57. }
  58. impl<PINS> Spi<SPI1, PINS> {
  59. pub fn spi1<F>(
  60. spi: SPI1,
  61. pins: PINS,
  62. mapr: &mut MAPR,
  63. mode: Mode,
  64. freq: F,
  65. clocks: Clocks,
  66. apb: &mut APB2,
  67. ) -> Self
  68. where
  69. F: Into<Hertz>,
  70. PINS: Pins<SPI1>,
  71. {
  72. mapr.mapr().modify(|_, w| w.spi1_remap().bit(PINS::REMAP));
  73. Spi::_spi1(spi, pins, mode, freq.into(), clocks, apb)
  74. }
  75. }
  76. impl<PINS> Spi<SPI2, PINS> {
  77. pub fn spi2<F>(
  78. spi: SPI2,
  79. pins: PINS,
  80. mode: Mode,
  81. freq: F,
  82. clocks: Clocks,
  83. apb: &mut APB1,
  84. ) -> Self
  85. where
  86. F: Into<Hertz>,
  87. PINS: Pins<SPI2>,
  88. {
  89. Spi::_spi2(spi, pins, mode, freq.into(), clocks, apb)
  90. }
  91. }
  92. macro_rules! hal {
  93. ($($SPIX:ident: ($spiX:ident, $spiXen:ident, $spiXrst:ident, $APB:ident),)+) => {
  94. $(
  95. impl<PINS> Spi<$SPIX, PINS> {
  96. fn $spiX(
  97. spi: $SPIX,
  98. pins: PINS,
  99. mode: Mode,
  100. freq: Hertz,
  101. clocks: Clocks,
  102. apb: &mut $APB,
  103. ) -> Self {
  104. // enable or reset $SPIX
  105. apb.enr().modify(|_, w| w.$spiXen().set_bit());
  106. apb.rstr().modify(|_, w| w.$spiXrst().set_bit());
  107. apb.rstr().modify(|_, w| w.$spiXrst().clear_bit());
  108. // disable SS output
  109. spi.cr2.write(|w| w.ssoe().clear_bit());
  110. let br = match clocks.pclk2().0 / freq.0 {
  111. 0 => unreachable!(),
  112. 1...2 => 0b000,
  113. 3...5 => 0b001,
  114. 6...11 => 0b010,
  115. 12...23 => 0b011,
  116. 24...47 => 0b100,
  117. 48...95 => 0b101,
  118. 96...191 => 0b110,
  119. _ => 0b111,
  120. };
  121. // mstr: master configuration
  122. // lsbfirst: MSB first
  123. // ssm: enable software slave management (NSS pin free for other uses)
  124. // ssi: set nss high = master mode
  125. // dff: 8 bit frames
  126. // bidimode: 2-line unidirectional
  127. // spe: enable the SPI bus
  128. spi.cr1.write(|w| {
  129. w.cpha()
  130. .bit(mode.phase == Phase::CaptureOnSecondTransition)
  131. .cpol()
  132. .bit(mode.polarity == Polarity::IdleHigh)
  133. .mstr()
  134. .set_bit()
  135. .br()
  136. .bits(br)
  137. .lsbfirst()
  138. .clear_bit()
  139. .ssm()
  140. .set_bit()
  141. .ssi()
  142. .set_bit()
  143. .rxonly()
  144. .clear_bit()
  145. .dff()
  146. .clear_bit()
  147. .bidimode()
  148. .clear_bit()
  149. .spe()
  150. .set_bit()
  151. });
  152. Spi { spi, pins }
  153. }
  154. pub fn free(self) -> ($SPIX, PINS) {
  155. (self.spi, self.pins)
  156. }
  157. }
  158. impl<PINS> hal::spi::FullDuplex<u8> for Spi<$SPIX, PINS> {
  159. type Error = Error;
  160. fn read(&mut self) -> nb::Result<u8, Error> {
  161. let sr = self.spi.sr.read();
  162. Err(if sr.ovr().bit_is_set() {
  163. nb::Error::Other(Error::Overrun)
  164. } else if sr.modf().bit_is_set() {
  165. nb::Error::Other(Error::ModeFault)
  166. } else if sr.crcerr().bit_is_set() {
  167. nb::Error::Other(Error::Crc)
  168. } else if sr.rxne().bit_is_set() {
  169. // NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
  170. // reading a half-word)
  171. return Ok(unsafe {
  172. ptr::read_volatile(&self.spi.dr as *const _ as *const u8)
  173. });
  174. } else {
  175. nb::Error::WouldBlock
  176. })
  177. }
  178. fn send(&mut self, byte: u8) -> nb::Result<(), Error> {
  179. let sr = self.spi.sr.read();
  180. Err(if sr.ovr().bit_is_set() {
  181. nb::Error::Other(Error::Overrun)
  182. } else if sr.modf().bit_is_set() {
  183. nb::Error::Other(Error::ModeFault)
  184. } else if sr.crcerr().bit_is_set() {
  185. nb::Error::Other(Error::Crc)
  186. } else if sr.txe().bit_is_set() {
  187. // NOTE(write_volatile) see note above
  188. unsafe { ptr::write_volatile(&self.spi.dr as *const _ as *mut u8, byte) }
  189. return Ok(());
  190. } else {
  191. nb::Error::WouldBlock
  192. })
  193. }
  194. }
  195. impl<PINS> ::hal::blocking::spi::transfer::Default<u8> for Spi<$SPIX, PINS> {}
  196. impl<PINS> ::hal::blocking::spi::write::Default<u8> for Spi<$SPIX, PINS> {}
  197. )+
  198. }
  199. }
  200. hal! {
  201. SPI1: (_spi1, spi1en, spi1rst, APB2),
  202. SPI2: (_spi2, spi2en, spi2rst, APB1),
  203. }