From 258ba533bdf8dc353513bbd5d409e8b12d307d5f Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 9 Apr 2021 23:37:22 +0200 Subject: [PATCH] Implement GPIO input --- embassy-stm32-examples/src/bin/blinky.rs | 4 +- embassy-stm32-examples/src/bin/button.rs | 57 ++++++++++++++++++++++ embassy-stm32/src/chip/f429.rs | 8 +++- embassy-stm32/src/gpio.rs | 61 ++++++++++++++---------- 4 files changed, 101 insertions(+), 29 deletions(-) create mode 100644 embassy-stm32-examples/src/bin/button.rs diff --git a/embassy-stm32-examples/src/bin/blinky.rs b/embassy-stm32-examples/src/bin/blinky.rs index a90992be4..ec6c00fe1 100644 --- a/embassy-stm32-examples/src/bin/blinky.rs +++ b/embassy-stm32-examples/src/bin/blinky.rs @@ -43,10 +43,10 @@ fn main() -> ! { loop { info!("high"); led.set_high().unwrap(); - cortex_m::asm::delay(1_000_000); + cortex_m::asm::delay(10_000_000); info!("low"); led.set_low().unwrap(); - cortex_m::asm::delay(1_000_000); + cortex_m::asm::delay(10_000_000); } } diff --git a/embassy-stm32-examples/src/bin/button.rs b/embassy-stm32-examples/src/bin/button.rs new file mode 100644 index 000000000..c02e34c09 --- /dev/null +++ b/embassy-stm32-examples/src/bin/button.rs @@ -0,0 +1,57 @@ +#![no_std] +#![no_main] +#![feature(trait_alias)] +#![feature(min_type_alias_impl_trait)] +#![feature(impl_trait_in_bindings)] +#![feature(type_alias_impl_trait)] + +#[path = "../example_common.rs"] +mod example_common; +use embassy_stm32::gpio::{Input, Level, Output, Pull}; +use embedded_hal::digital::v2::{InputPin, OutputPin}; +use example_common::*; + +use cortex_m_rt::entry; +use stm32f4::stm32f429 as pac; + +#[entry] +fn main() -> ! { + info!("Hello World!"); + + let pp = pac::Peripherals::take().unwrap(); + + pp.DBGMCU.cr.modify(|_, w| { + w.dbg_sleep().set_bit(); + w.dbg_standby().set_bit(); + w.dbg_stop().set_bit() + }); + pp.RCC.ahb1enr.modify(|_, w| w.dma1en().enabled()); + + pp.RCC.ahb1enr.modify(|_, w| { + w.gpioaen().enabled(); + w.gpioben().enabled(); + w.gpiocen().enabled(); + w.gpioden().enabled(); + w.gpioeen().enabled(); + w.gpiofen().enabled(); + w + }); + + let p = embassy_stm32::Peripherals::take().unwrap(); + let button = Input::new(p.PC13, Pull::Down); + let mut led1 = Output::new(p.PB0, Level::High); + let _led2 = Output::new(p.PB7, Level::High); + let mut led3 = Output::new(p.PB14, Level::High); + + loop { + if button.is_high().unwrap() { + info!("high"); + led1.set_high().unwrap(); + led3.set_low().unwrap(); + } else { + info!("low"); + led1.set_low().unwrap(); + led3.set_high().unwrap(); + } + } +} diff --git a/embassy-stm32/src/chip/f429.rs b/embassy-stm32/src/chip/f429.rs index 1c2fdc0c6..26956e01f 100644 --- a/embassy-stm32/src/chip/f429.rs +++ b/embassy-stm32/src/chip/f429.rs @@ -1,6 +1,10 @@ use embassy_extras::peripherals; peripherals!( - PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, PB0, PB1, - PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15, + // GPIO Port A + PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, + // GPIO Port B + PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15, + // GPIO Port C + PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10, PC11, PC12, PC13, PC14, PC15, ); diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 80fcbba24..f963400a7 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -5,9 +5,8 @@ use core::marker::PhantomData; use embassy::util::PeripheralBorrow; use embassy_extras::{impl_unborrow, unborrow}; use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; -use gpio::vals::{self, Pupdr}; +use gpio::vals; -use crate::pac; use crate::pac::gpio_v2 as gpio; use crate::peripherals; @@ -27,7 +26,6 @@ pub enum Pull { Down, } -/* /// GPIO input driver. pub struct Input<'d, T: Pin> { pub(crate) pin: T, @@ -38,23 +36,17 @@ impl<'d, T: Pin> Input<'d, T> { pub fn new(pin: impl PeripheralBorrow + 'd, pull: Pull) -> Self { unborrow!(pin); - pin.conf().write(|w| { - w.dir().input(); - w.input().connect(); - match pull { - Pull::None => { - w.pull().disabled(); - } - Pull::Up => { - w.pull().pullup(); - } - Pull::Down => { - w.pull().pulldown(); - } - } - w.drive().s0s1(); - w.sense().disabled(); - w + cortex_m::interrupt::free(|_| unsafe { + let r = pin.block(); + let n = pin.pin() as usize; + let val = match pull { + Pull::None => vals::Pupdr::FLOATING, + Pull::Up => vals::Pupdr::PULLUP, + Pull::Down => vals::Pupdr::PULLDOWN, + }; + r.pupdr().modify(|w| w.set_pupdr(n, val)); + r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL)); + r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT)); }); Self { @@ -66,7 +58,11 @@ impl<'d, T: Pin> Input<'d, T> { impl<'d, T: Pin> Drop for Input<'d, T> { fn drop(&mut self) { - self.pin.conf().reset(); + cortex_m::interrupt::free(|_| unsafe { + let r = self.pin.block(); + let n = self.pin.pin() as usize; + r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); + }); } } @@ -78,12 +74,11 @@ impl<'d, T: Pin> InputPin for Input<'d, T> { } fn is_low(&self) -> Result { - Ok(self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0) + let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) }; + Ok(state == vals::Idr::LOW) } } -*/ - /// Digital input or output level. #[derive(Debug, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -111,7 +106,6 @@ impl<'d, T: Pin> Output<'d, T> { let r = pin.block(); let n = pin.pin() as usize; r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); - r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL)); r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT)); }); @@ -127,6 +121,7 @@ impl<'d, T: Pin> Drop for Output<'d, T> { cortex_m::interrupt::free(|_| unsafe { let r = self.pin.block(); let n = self.pin.pin() as usize; + r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT)); }); } @@ -368,3 +363,19 @@ impl_pin!(PB12, 1, 12); impl_pin!(PB13, 1, 13); impl_pin!(PB14, 1, 14); impl_pin!(PB15, 1, 15); +impl_pin!(PC0, 2, 0); +impl_pin!(PC1, 2, 1); +impl_pin!(PC2, 2, 2); +impl_pin!(PC3, 2, 3); +impl_pin!(PC4, 2, 4); +impl_pin!(PC5, 2, 5); +impl_pin!(PC6, 2, 6); +impl_pin!(PC7, 2, 7); +impl_pin!(PC8, 2, 8); +impl_pin!(PC9, 2, 9); +impl_pin!(PC10, 2, 10); +impl_pin!(PC11, 2, 11); +impl_pin!(PC12, 2, 12); +impl_pin!(PC13, 2, 13); +impl_pin!(PC14, 2, 14); +impl_pin!(PC15, 2, 15);