Implement single pin trait based AF for SPI

This commit is contained in:
David Sawatzke 2018-12-19 08:58:53 +01:00
parent f1f2b32a5e
commit 527f182154
1 changed files with 62 additions and 33 deletions

View File

@ -4,6 +4,7 @@ use nb;
pub use embedded_hal::spi::{Mode, Phase, Polarity};
use crate::stm32;
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
use crate::stm32::{RCC, SPI1};
@ -25,45 +26,65 @@ pub enum Error {
}
/// SPI abstraction
pub struct Spi<SPI, PINS> {
pub struct Spi<SPI, SCKPIN, MISOPIN, MOSIPIN> {
spi: SPI,
pins: PINS,
pins: (SCKPIN, MISOPIN, MOSIPIN),
}
pub trait Pins<Spi> {}
pub trait SckPin<SPI> {}
pub trait MisoPin<SPI> {}
pub trait MosiPin<SPI> {}
macro_rules! spi_pins {
($($SPI:ident => {
sck => [$($sck:ty),+ $(,)*],
miso => [$($miso:ty),+ $(,)*],
mosi => [$($mosi:ty),+ $(,)*],
})+) => {
$(
$(
impl SckPin<stm32::$SPI> for $sck {}
)+
$(
impl MisoPin<stm32::$SPI> for $miso {}
)+
$(
impl MosiPin<stm32::$SPI> for $mosi {}
)+
)+
}
}
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
impl Pins<SPI1>
for (
gpioa::PA5<Alternate<AF0>>,
gpioa::PA6<Alternate<AF0>>,
gpioa::PA7<Alternate<AF0>>,
)
{}
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
impl Pins<SPI1>
for (
gpiob::PB3<Alternate<AF0>>,
gpiob::PB4<Alternate<AF0>>,
gpiob::PB5<Alternate<AF0>>,
)
{}
spi_pins! {
SPI1 => {
sck => [gpioa::PA5<Alternate<AF0>>, gpiob::PB3<Alternate<AF0>>],
miso => [gpioa::PA6<Alternate<AF0>>, gpiob::PB4<Alternate<AF0>>],
mosi => [gpioa::PA7<Alternate<AF0>>, gpiob::PB5<Alternate<AF0>>],
}
}
#[cfg(feature = "stm32f030x6")]
impl Pins<SPI1>
for (
gpiob::PB13<Alternate<AF0>>,
gpiob::PB14<Alternate<AF0>>,
gpiob::PB15<Alternate<AF0>>,
)
{
spi_pins! {
SPI1 => {
sck => [gpiob::PB13<Alternate<AF0>>],
miso => [gpiob::PB14<Alternate<AF0>>],
mosi => [gpiob::PB15<Alternate<AF0>>],
}
}
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
impl<PINS> Spi<SPI1, PINS> {
pub fn spi1<F>(spi: SPI1, pins: PINS, mode: Mode, speed: F, clocks: Clocks) -> Self
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
where
PINS: Pins<SPI1>,
SCKPIN: SckPin<SPI1>,
MISOPIN: MisoPin<SPI1>,
MOSIPIN: MosiPin<SPI1>,
F: Into<Hertz>,
{
// NOTE(unsafe) This executes only during initialisation
@ -133,13 +154,15 @@ impl<PINS> Spi<SPI1, PINS> {
Spi { spi, pins }
}
pub fn release(self) -> (SPI1, PINS) {
pub fn release(self) -> (SPI1, (SCKPIN, MISOPIN, MOSIPIN)) {
(self.spi, self.pins)
}
}
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
impl<PINS> ::embedded_hal::spi::FullDuplex<u8> for Spi<SPI1, PINS> {
impl<SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u8>
for Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN>
{
type Error = Error;
fn read(&mut self) -> nb::Result<u8, Error> {
@ -180,6 +203,12 @@ impl<PINS> ::embedded_hal::spi::FullDuplex<u8> for Spi<SPI1, PINS> {
}
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
impl<PINS> ::embedded_hal::blocking::spi::transfer::Default<u8> for Spi<SPI1, PINS> {}
impl<SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::transfer::Default<u8>
for Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN>
{
}
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
impl<PINS> ::embedded_hal::blocking::spi::write::Default<u8> for Spi<SPI1, PINS> {}
impl<SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::write::Default<u8>
for Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN>
{
}