Implement GPIO input

This commit is contained in:
Dario Nieuwenhuis 2021-04-09 23:37:22 +02:00
parent aa65d5ccaf
commit 258ba533bd
4 changed files with 101 additions and 29 deletions

View File

@ -43,10 +43,10 @@ fn main() -> ! {
loop { loop {
info!("high"); info!("high");
led.set_high().unwrap(); led.set_high().unwrap();
cortex_m::asm::delay(1_000_000); cortex_m::asm::delay(10_000_000);
info!("low"); info!("low");
led.set_low().unwrap(); led.set_low().unwrap();
cortex_m::asm::delay(1_000_000); cortex_m::asm::delay(10_000_000);
} }
} }

View File

@ -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();
}
}
}

View File

@ -1,6 +1,10 @@
use embassy_extras::peripherals; use embassy_extras::peripherals;
peripherals!( peripherals!(
PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, PB0, PB1, // GPIO Port A
PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15, 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,
); );

View File

@ -5,9 +5,8 @@ use core::marker::PhantomData;
use embassy::util::PeripheralBorrow; use embassy::util::PeripheralBorrow;
use embassy_extras::{impl_unborrow, unborrow}; use embassy_extras::{impl_unborrow, unborrow};
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; 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::pac::gpio_v2 as gpio;
use crate::peripherals; use crate::peripherals;
@ -27,7 +26,6 @@ pub enum Pull {
Down, Down,
} }
/*
/// GPIO input driver. /// GPIO input driver.
pub struct Input<'d, T: Pin> { pub struct Input<'d, T: Pin> {
pub(crate) pin: T, pub(crate) pin: T,
@ -38,23 +36,17 @@ impl<'d, T: Pin> Input<'d, T> {
pub fn new(pin: impl PeripheralBorrow<Target = T> + 'd, pull: Pull) -> Self { pub fn new(pin: impl PeripheralBorrow<Target = T> + 'd, pull: Pull) -> Self {
unborrow!(pin); unborrow!(pin);
pin.conf().write(|w| { cortex_m::interrupt::free(|_| unsafe {
w.dir().input(); let r = pin.block();
w.input().connect(); let n = pin.pin() as usize;
match pull { let val = match pull {
Pull::None => { Pull::None => vals::Pupdr::FLOATING,
w.pull().disabled(); Pull::Up => vals::Pupdr::PULLUP,
} Pull::Down => vals::Pupdr::PULLDOWN,
Pull::Up => { };
w.pull().pullup(); r.pupdr().modify(|w| w.set_pupdr(n, val));
} r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL));
Pull::Down => { r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
w.pull().pulldown();
}
}
w.drive().s0s1();
w.sense().disabled();
w
}); });
Self { Self {
@ -66,7 +58,11 @@ impl<'d, T: Pin> Input<'d, T> {
impl<'d, T: Pin> Drop for Input<'d, T> { impl<'d, T: Pin> Drop for Input<'d, T> {
fn drop(&mut self) { 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<bool, Self::Error> { fn is_low(&self) -> Result<bool, Self::Error> {
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. /// Digital input or output level.
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
@ -111,7 +106,6 @@ impl<'d, T: Pin> Output<'d, T> {
let r = pin.block(); let r = pin.block();
let n = pin.pin() as usize; let n = pin.pin() as usize;
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); 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)); 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 { cortex_m::interrupt::free(|_| unsafe {
let r = self.pin.block(); let r = self.pin.block();
let n = self.pin.pin() as usize; 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)); 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!(PB13, 1, 13);
impl_pin!(PB14, 1, 14); impl_pin!(PB14, 1, 14);
impl_pin!(PB15, 1, 15); 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);