spi.rs 6.7 KB

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