Skip to content

Commit

Permalink
Support pushpull or opendrain otype for alternate function pins
Browse files Browse the repository at this point in the history
  • Loading branch information
ReeceStevens committed Mar 15, 2019
1 parent 4fcf819 commit 453d572
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 57 deletions.
116 changes: 89 additions & 27 deletions f4/src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ pub struct Analog<MODE>(PhantomData<MODE>);
pub struct AnalogIn;
pub struct AnalogOut;

pub struct AF1;
pub struct AF2;
pub struct AF3;
pub struct AF4;
pub struct AF5;
pub struct AF6;
pub struct AF7;
pub struct AF8;
pub struct AF9;
pub struct AF1<OTYPE>(PhantomData<OTYPE>);
pub struct AF2<OTYPE>(PhantomData<OTYPE>);
pub struct AF3<OTYPE>(PhantomData<OTYPE>);
pub struct AF4<OTYPE>(PhantomData<OTYPE>);
pub struct AF5<OTYPE>(PhantomData<OTYPE>);
pub struct AF6<OTYPE>(PhantomData<OTYPE>);
pub struct AF7<OTYPE>(PhantomData<OTYPE>);
pub struct AF8<OTYPE>(PhantomData<OTYPE>);
pub struct AF9<OTYPE>(PhantomData<OTYPE>);

#[derive(Copy,Clone)]
pub enum Mode {
Expand Down Expand Up @@ -194,51 +194,113 @@ macro_rules! gpio {
}

impl<MODE> $PXi<MODE> {
pub fn into_af1(self, moder: &mut MODER, afr: &mut $AFR) -> $PXi<AF1> {
pub fn into_af1_pushpull(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF1<PushPull>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(1) });
$PXi::<AF1> { _mode: PhantomData }
otyper.otyper().modify(|_, w| w.$otyper().bit(false));
$PXi::<AF1<PushPull>> { _mode: PhantomData }
}
pub fn into_af1_opendrain(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF1<OpenDrain>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(1) });
otyper.otyper().modify(|_, w| w.$otyper().bit(true));
$PXi::<AF1<OpenDrain>> { _mode: PhantomData }
}
pub fn into_af2(self, moder: &mut MODER, afr: &mut $AFR) -> $PXi<AF2> {
pub fn into_af2_pushpull(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF2<PushPull>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(2) });
$PXi::<AF2> { _mode: PhantomData }
otyper.otyper().modify(|_, w| w.$otyper().bit(false));
$PXi::<AF2<PushPull>> { _mode: PhantomData }
}
pub fn into_af2_opendrain(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF2<OpenDrain>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(2) });
otyper.otyper().modify(|_, w| w.$otyper().bit(true));
$PXi::<AF2<OpenDrain>> { _mode: PhantomData }
}
pub fn into_af3_pushpull(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF3<PushPull>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(3) });
otyper.otyper().modify(|_, w| w.$otyper().bit(false));
$PXi::<AF3<PushPull>> { _mode: PhantomData }
}
pub fn into_af3(self, moder: &mut MODER, afr: &mut $AFR) -> $PXi<AF3> {
pub fn into_af3_opendrain(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF3<OpenDrain>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(3) });
$PXi::<AF3> { _mode: PhantomData }
otyper.otyper().modify(|_, w| w.$otyper().bit(true));
$PXi::<AF3<OpenDrain>> { _mode: PhantomData }
}
pub fn into_af4(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF4> {
pub fn into_af4_pushpull(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF4<PushPull>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(4) });
otyper.otyper().modify(|_, w| w.$otyper().bit(false));
$PXi::<AF4<PushPull>> { _mode: PhantomData }
}
pub fn into_af4_opendrain(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF4<OpenDrain>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(4) });
otyper.otyper().modify(|_, w| w.$otyper().bit(true));
$PXi::<AF4> { _mode: PhantomData }
$PXi::<AF4<OpenDrain>> { _mode: PhantomData }
}
pub fn into_af5_pushpull(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF5<PushPull>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(5) });
otyper.otyper().modify(|_, w| w.$otyper().bit(false));
$PXi::<AF5<PushPull>> { _mode: PhantomData }
}
pub fn into_af5(self, moder: &mut MODER, afr: &mut $AFR) -> $PXi<AF5> {
pub fn into_af5_opendrain(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF5<OpenDrain>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(5) });
$PXi::<AF5> { _mode: PhantomData }
otyper.otyper().modify(|_, w| w.$otyper().bit(true));
$PXi::<AF5<OpenDrain>> { _mode: PhantomData }
}
pub fn into_af6_pushpull(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF6<PushPull>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(6) });
otyper.otyper().modify(|_, w| w.$otyper().bit(false));
$PXi::<AF6<PushPull>> { _mode: PhantomData }
}
pub fn into_af6(self, moder: &mut MODER, afr: &mut $AFR) -> $PXi<AF6> {
pub fn into_af6_opendrain(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF6<OpenDrain>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(6) });
$PXi::<AF6> { _mode: PhantomData }
otyper.otyper().modify(|_, w| w.$otyper().bit(true));
$PXi::<AF6<OpenDrain>> { _mode: PhantomData }
}
pub fn into_af7_pushpull(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF7<PushPull>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(7) });
otyper.otyper().modify(|_, w| w.$otyper().bit(false));
$PXi::<AF7<PushPull>> { _mode: PhantomData }
}
pub fn into_af7(self, moder: &mut MODER, afr: &mut $AFR) -> $PXi<AF7> {
pub fn into_af7_opendrain(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF7<OpenDrain>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(7) });
$PXi::<AF7> { _mode: PhantomData }
otyper.otyper().modify(|_, w| w.$otyper().bit(true));
$PXi::<AF7<OpenDrain>> { _mode: PhantomData }
}
pub fn into_af8_pushpull(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF8<PushPull>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(8) });
otyper.otyper().modify(|_, w| w.$otyper().bit(false));
$PXi::<AF8<PushPull>> { _mode: PhantomData }
}
pub fn into_af8(self, moder: &mut MODER, afr: &mut $AFR) -> $PXi<AF8> {
pub fn into_af8_opendrain(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF8<OpenDrain>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(8) });
$PXi::<AF8> { _mode: PhantomData }
otyper.otyper().modify(|_, w| w.$otyper().bit(true));
$PXi::<AF8<OpenDrain>> { _mode: PhantomData }
}
pub fn into_af9(self, moder: &mut MODER, afr: &mut $AFR) -> $PXi<AF9> {
pub fn into_af9_pushpull(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF9<PushPull>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(9) });
$PXi::<AF9> { _mode: PhantomData }
otyper.otyper().modify(|_, w| w.$otyper().bit(false));
$PXi::<AF9<PushPull>> { _mode: PhantomData }
}
pub fn into_af9_opendrain(self, moder: &mut MODER, afr: &mut $AFR, otyper: &mut OTYPER) -> $PXi<AF9<OpenDrain>> {
moder.moder().modify(|_, w| unsafe { w.$moder().bits(Mode::AF as u8) });
afr.$afr().modify(|_, w| unsafe { w.$afr_num().bits(9) });
otyper.otyper().modify(|_, w| w.$otyper().bit(true));
$PXi::<AF9<OpenDrain>> { _mode: PhantomData }
}

pub fn into_pushpull_output(self, moder: &mut MODER, otyper: &mut OTYPER) -> $PXi<Output<PushPull>> {
Expand Down
18 changes: 9 additions & 9 deletions f4/src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ use hal::blocking::i2c::{Read, Write};
use rcc::Clocks;
use logger::*;

use gpio::{AF4};
use gpio::{AF4, OpenDrain};
use gpio::gpioa::{PA8};
use gpio::gpiob::{PB6, PB7, PB8, PB9, PB10, PB11};
use gpio::gpioc::PC9;

pub trait Sda<I2C> {}
pub trait Scl<I2C> {}

impl Scl<I2C1> for PB6<AF4> {}
impl Sda<I2C1> for PB7<AF4> {}
impl Scl<I2C1> for PB8<AF4> {}
impl Sda<I2C1> for PB9<AF4> {}
impl Scl<I2C1> for PB6<AF4<OpenDrain>> {}
impl Sda<I2C1> for PB7<AF4<OpenDrain>> {}
impl Scl<I2C1> for PB8<AF4<OpenDrain>> {}
impl Sda<I2C1> for PB9<AF4<OpenDrain>> {}

impl Scl<I2C2> for PB10<AF4> {}
impl Sda<I2C2> for PB11<AF4> {}
impl Scl<I2C2> for PB10<AF4<OpenDrain>> {}
impl Sda<I2C2> for PB11<AF4<OpenDrain>> {}

impl Scl<I2C3> for PA8<AF4> {}
impl Sda<I2C3> for PC9<AF4> {}
impl Scl<I2C3> for PA8<AF4<OpenDrain>> {}
impl Sda<I2C3> for PC9<AF4<OpenDrain>> {}

#[derive(Debug)]
pub enum Error {
Expand Down
20 changes: 10 additions & 10 deletions f4/src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use hal::spi::FullDuplex;
use nb;

use stm32f40x::{SPI1, SPI2, SPI4, RCC};
use gpio::AF5;
use gpio::{AF5, PushPull};
use gpio::gpioa::{PA5, PA6, PA7, PA11, PA1};
use gpio::gpiob::{PB14, PB15, PB13};
use gpio::gpioc::{PC7};
Expand All @@ -13,17 +13,17 @@ pub trait Sclk<SPI> {}
pub trait Miso<SPI> {}
pub trait Mosi<SPI> {}

impl Sclk<SPI1> for PA5<AF5> {}
impl Miso<SPI1> for PA6<AF5> {}
impl Mosi<SPI1> for PA7<AF5> {}
impl Sclk<SPI1> for PA5<AF5<PushPull>> {}
impl Miso<SPI1> for PA6<AF5<PushPull>> {}
impl Mosi<SPI1> for PA7<AF5<PushPull>> {}

impl Sclk<SPI2> for PC7<AF5> {}
impl Miso<SPI2> for PB14<AF5> {}
impl Mosi<SPI2> for PB15<AF5> {}
impl Sclk<SPI2> for PC7<AF5<PushPull>> {}
impl Miso<SPI2> for PB14<AF5<PushPull>> {}
impl Mosi<SPI2> for PB15<AF5<PushPull>> {}

impl Sclk<SPI2> for PB13<AF5> {}
impl Miso<SPI2> for PA11<AF5> {}
impl Mosi<SPI2> for PA1<AF5> {}
impl Sclk<SPI2> for PB13<AF5<PushPull>> {}
impl Miso<SPI2> for PA11<AF5<PushPull>> {}
impl Mosi<SPI2> for PA1<AF5<PushPull>> {}

pub struct Spi<SPIX, PINS> {
spi: SPIX,
Expand Down
22 changes: 11 additions & 11 deletions f4/src/usart.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use stm32f40x::{RCC, USART1, USART2, USART6};
use gpio::{AF7, AF8};
use gpio::{AF7, AF8, PushPull};
use gpio::gpioa::{PA9, PA15, PA10, PA2, PA3, PA11, PA12};
use gpio::gpiob::{PB3, PB7, PB6};
use rcc::get_pclk2;
Expand All @@ -10,18 +10,18 @@ use core::fmt;
pub trait TxPin<USART> {}
pub trait RxPin<USART> {}

impl TxPin<USART1> for PA9<AF7> {}
impl TxPin<USART1> for PA15<AF7> {}
impl TxPin<USART1> for PB6<AF7> {}
impl RxPin<USART1> for PA10<AF7> {}
impl RxPin<USART1> for PB3<AF7> {}
impl RxPin<USART1> for PB7<AF7> {}
impl TxPin<USART1> for PA9<AF7<PushPull>> {}
impl TxPin<USART1> for PA15<AF7<PushPull>> {}
impl TxPin<USART1> for PB6<AF7<PushPull>> {}
impl RxPin<USART1> for PA10<AF7<PushPull>> {}
impl RxPin<USART1> for PB3<AF7<PushPull>> {}
impl RxPin<USART1> for PB7<AF7<PushPull>> {}

impl TxPin<USART2> for PA2<AF7> {}
impl RxPin<USART2> for PA3<AF7> {}
impl TxPin<USART2> for PA2<AF7<PushPull>> {}
impl RxPin<USART2> for PA3<AF7<PushPull>> {}

impl TxPin<USART6> for PA11<AF8> {}
impl RxPin<USART6> for PA12<AF8> {}
impl TxPin<USART6> for PA11<AF8<PushPull>> {}
impl RxPin<USART6> for PA12<AF8<PushPull>> {}

pub struct Usart<USART, PINS> {
usart: USART,
Expand Down

0 comments on commit 453d572

Please sign in to comment.