Browse Source

Implement multiple spi instances (BROKEN)

features/pwm
David Sawatzke 4 years ago
parent
commit
14aab2a12c
  1. 105
      src/spi.rs

105
src/spi.rs

@ -1,3 +1,4 @@
use core::ops::Deref;
use core::ptr;
use nb;
@ -72,33 +73,62 @@ spi_pins! {
}
}
macro_rules! spi {
($($SPI:ident: ($spi:ident, $spiXen:ident, $spiXrst:ident, $apbrstr:ident, $apbenr:ident),)+) => {
$(
use crate::stm32::$SPI;
impl<SCKPIN, MISOPIN, MOSIPIN> Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN> {
pub fn $spi<F>(
spi: $SPI,
pins: (SCKPIN, MISOPIN, MOSIPIN),
mode: Mode,
speed: F,
clocks: Clocks,
) -> Self
where
SCKPIN: SckPin<$SPI>,
MISOPIN: MisoPin<$SPI>,
MOSIPIN: MosiPin<$SPI>,
F: Into<Hertz>,
{
// NOTE(unsafe) This executes only during initialisation
let rcc = unsafe { &(*RCC::ptr()) };
/* Enable clock for SPI1 */
rcc.$apbenr.modify(|_, w| w.$spiXen().set_bit());
/* Reset SPI1 */
rcc.$apbrstr.modify(|_, w| w.$spiXrst().set_bit());
rcc.$apbrstr.modify(|_, w| w.$spiXrst().clear_bit());
Spi { spi, pins }.spi_init(mode, speed, clocks)
}
}
)+
}
}
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
impl<SCKPIN, MISOPIN, MOSIPIN> Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN> {
pub fn spi1<F>(
spi: SPI1,
pins: (SCKPIN, MISOPIN, MOSIPIN),
mode: Mode,
speed: F,
clocks: Clocks,
) -> Self
spi! {
SPI1: (spi1, spi1en, spi1rst, apb2enr, apb2rstr),
}
#[cfg(any(feature = "stm32f030x8", feature = "stm32f030xc"))]
spi! {
SPI2: (spi2, spi2en, spi2rst, apb1enr, apb1rstr),
}
// It's s needed for the impls, but rustc doesn't recognize that
#[allow(dead_code)]
type SpiRegisterBlock = stm32::spi1::RegisterBlock;
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> Spi<SPI, SCKPIN, MISOPIN, MOSIPIN>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
fn spi_init<F>(self: Self, mode: Mode, speed: F, clocks: Clocks) -> Self
where
SCKPIN: SckPin<SPI1>,
MISOPIN: MisoPin<SPI1>,
MOSIPIN: MosiPin<SPI1>,
F: Into<Hertz>,
{
// NOTE(unsafe) This executes only during initialisation
let rcc = unsafe { &(*RCC::ptr()) };
/* Enable clock for SPI1 */
rcc.apb2enr.modify(|_, w| w.spi1en().set_bit());
/* Reset SPI1 */
rcc.apb2rstr.modify(|_, w| w.spi1rst().set_bit());
rcc.apb2rstr.modify(|_, w| w.spi1rst().clear_bit());
/* Make sure the SPI unit is disabled so we can configure it */
spi.cr1.modify(|_, w| w.spe().clear_bit());
self.spi.cr1.modify(|_, w| w.spe().clear_bit());
// FRXTH: 8-bit threshold on RX FIFO
// DS: 8-bit data size
@ -106,7 +136,8 @@ impl<SCKPIN, MISOPIN, MOSIPIN> Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN> {
//
// NOTE(unsafe): DS reserved bit patterns are 0b0000, 0b0001, and 0b0010. 0b0111 is valid
// (reference manual, pp 804)
spi.cr2
self.spi
.cr2
.write(|w| unsafe { w.frxth().set_bit().ds().bits(0b0111).ssoe().clear_bit() });
let br = match clocks.pclk().0 / speed.into().0 {
@ -128,7 +159,7 @@ impl<SCKPIN, MISOPIN, MOSIPIN> Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN> {
// dff: 8 bit frames
// bidimode: 2-line unidirectional
// spe: enable the SPI bus
spi.cr1.write(|w| unsafe {
self.spi.cr1.write(|w| unsafe {
w.cpha()
.bit(mode.phase == Phase::CaptureOnSecondTransition)
.cpol()
@ -151,17 +182,17 @@ impl<SCKPIN, MISOPIN, MOSIPIN> Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN> {
.set_bit()
});
Spi { spi, pins }
self
}
pub fn release(self) -> (SPI1, (SCKPIN, MISOPIN, MOSIPIN)) {
pub fn release(self) -> (SPI, (SCKPIN, MISOPIN, MOSIPIN)) {
(self.spi, self.pins)
}
}
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
impl<SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u8>
for Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN>
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
type Error = Error;
@ -202,13 +233,15 @@ impl<SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u8>
}
}
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
impl<SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::transfer::Default<u8>
for Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN>
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::transfer::Default<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
}
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
impl<SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::write::Default<u8>
for Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN>
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::write::Default<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
}

Loading…
Cancel
Save