From 531801d56691eaeaac37fe5251f0970ad17827a1 Mon Sep 17 00:00:00 2001 From: Javier Alvarez Date: Mon, 22 Mar 2021 21:10:11 +0100 Subject: [PATCH] Implement initial state for output pins --- avr-hal-generic/src/port.rs | 28 ++++++++++++++++++++++++++++ chips/atmega1280-hal/src/port.rs | 1 + chips/atmega168-hal/src/port.rs | 2 +- chips/atmega2560-hal/src/port.rs | 1 + chips/atmega328p-hal/src/port.rs | 2 +- chips/atmega32u4-hal/src/port.rs | 1 + chips/atmega48p-hal/src/port.rs | 1 + chips/attiny85-hal/src/port.rs | 1 + chips/attiny88-hal/src/port.rs | 1 + 9 files changed, 36 insertions(+), 2 deletions(-) diff --git a/avr-hal-generic/src/port.rs b/avr-hal-generic/src/port.rs index 81003aa22a..69696deb03 100644 --- a/avr-hal-generic/src/port.rs +++ b/avr-hal-generic/src/port.rs @@ -49,6 +49,9 @@ //! // Convert into output //! let pd2: PD2 = pd2.into_output(&mut portd.ddr); //! +//! // Convert into output with an initial state +//! let pd2: PD2 = pd2.into_output_with_state(&mut portd.ddr, State::High); +//! //! // Convert into tri-state input and output. //! let pd2: PD2 = pd2.into_tri_state(&mut portd.ddr); //! ``` @@ -172,6 +175,12 @@ pub mod mode { } } +/// State of an output pin. +pub enum State { + High, + Low, +} + /// Create a generic pin to be used for downgrading #[macro_export] macro_rules! impl_generic_pin { @@ -434,6 +443,7 @@ macro_rules! impl_port { use $crate::void::Void; use $crate::hal::digital::v2 as digital; use $crate::port::mode; + use $crate::port::State; // We have to "use" the port-ext trait so we can implement it inside // the macro. @@ -477,6 +487,7 @@ macro_rules! impl_port { /// /// - Mode is changed with /// - `.into_output()` + /// - `.into_output_with_state()` /// - `.into_floating_input()` /// - `.into_pull_up_input()` /// - Input pins are sampled with @@ -516,6 +527,23 @@ macro_rules! impl_port { $PXi { _mode: marker::PhantomData } } + /// Make this pin a digital output with the provided initial state + pub fn into_output_with_state(self, ddr: &D, initial_state: State) -> $PXi { + unsafe { + (*<$PORTX>::ptr()).$reg_port.modify(|r, w| { + match initial_state { + State::High => w.bits(r.bits() | (1 << $i)), + State::Low => w.bits(r.bits() & !(1 << $i)) + } + }); + (*<$PORTX>::ptr()).$reg_ddr.modify(|r, w| { + w.bits(r.bits() | (1 << $i)) + }); + } + $PXi { _mode: marker::PhantomData } + } + + /// Make this pin a digital input **without** enabling the internal pull-up. pub fn into_floating_input(self, ddr: &D) -> $PXi> { unsafe { diff --git a/chips/atmega1280-hal/src/port.rs b/chips/atmega1280-hal/src/port.rs index 2160046ebe..a758595e7b 100644 --- a/chips/atmega1280-hal/src/port.rs +++ b/chips/atmega1280-hal/src/port.rs @@ -5,6 +5,7 @@ //! [1]: ../../avr_hal_generic/port/index.html pub use avr_hal_generic::port::mode; +pub use avr_hal_generic::port::State; pub trait PortExt { type Parts; diff --git a/chips/atmega168-hal/src/port.rs b/chips/atmega168-hal/src/port.rs index 9fa65ca35c..c50cadae3c 100644 --- a/chips/atmega168-hal/src/port.rs +++ b/chips/atmega168-hal/src/port.rs @@ -1,5 +1,6 @@ //! `PORTB` - `PORTD` digital IO pub use avr_hal_generic::port::mode; +pub use avr_hal_generic::port::State; pub trait PortExt { type Parts; @@ -79,4 +80,3 @@ avr_hal_generic::impl_port! { } } } - diff --git a/chips/atmega2560-hal/src/port.rs b/chips/atmega2560-hal/src/port.rs index 2160046ebe..a758595e7b 100644 --- a/chips/atmega2560-hal/src/port.rs +++ b/chips/atmega2560-hal/src/port.rs @@ -5,6 +5,7 @@ //! [1]: ../../avr_hal_generic/port/index.html pub use avr_hal_generic::port::mode; +pub use avr_hal_generic::port::State; pub trait PortExt { type Parts; diff --git a/chips/atmega328p-hal/src/port.rs b/chips/atmega328p-hal/src/port.rs index 8b3117ffed..9a5e93528b 100644 --- a/chips/atmega328p-hal/src/port.rs +++ b/chips/atmega328p-hal/src/port.rs @@ -5,6 +5,7 @@ //! [1]: ../../avr_hal_generic/port/index.html pub use avr_hal_generic::port::mode; +pub use avr_hal_generic::port::State; pub trait PortExt { type Parts; @@ -31,7 +32,6 @@ avr_hal_generic::impl_generic_pin! { } } - avr_hal_generic::impl_port! { pub mod portb { #[port_ext] diff --git a/chips/atmega32u4-hal/src/port.rs b/chips/atmega32u4-hal/src/port.rs index acc6d1557c..b4a1536f03 100644 --- a/chips/atmega32u4-hal/src/port.rs +++ b/chips/atmega32u4-hal/src/port.rs @@ -5,6 +5,7 @@ //! [1]: ../../avr_hal_generic/port/index.html pub use avr_hal_generic::port::mode; +pub use avr_hal_generic::port::State; pub trait PortExt { type Parts; diff --git a/chips/atmega48p-hal/src/port.rs b/chips/atmega48p-hal/src/port.rs index 18a7b3b06f..f3ab43bfc3 100644 --- a/chips/atmega48p-hal/src/port.rs +++ b/chips/atmega48p-hal/src/port.rs @@ -5,6 +5,7 @@ //! [1]: ../../avr_hal_generic/port/index.html pub use avr_hal_generic::port::mode; +pub use avr_hal_generic::port::State; pub trait PortExt { type Parts; diff --git a/chips/attiny85-hal/src/port.rs b/chips/attiny85-hal/src/port.rs index f33fb995f0..a58d225844 100644 --- a/chips/attiny85-hal/src/port.rs +++ b/chips/attiny85-hal/src/port.rs @@ -5,6 +5,7 @@ //! [1]: ../../avr_hal_generic/port/index.html pub use avr_hal_generic::port::mode; +pub use avr_hal_generic::port::State; pub trait PortExt { type Parts; diff --git a/chips/attiny88-hal/src/port.rs b/chips/attiny88-hal/src/port.rs index 66133c81e0..e3e099352a 100644 --- a/chips/attiny88-hal/src/port.rs +++ b/chips/attiny88-hal/src/port.rs @@ -5,6 +5,7 @@ //! [1]: ../../avr_hal_generic/port/index.html pub use avr_hal_generic::port::mode; +pub use avr_hal_generic::port::State; pub trait PortExt { type Parts;