Implement bus keep inputs, as documented in C SDK (#134)

When both pull-up and pull-down are enabled, the RP2040 enters a
so-called "bus keep" function, which uses a weak pull to tue current
high/low state of the GPIO.

See for example
https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__gpio.html#gab6bf9552da32b3dd0a5d0db45d8374fc
This commit is contained in:
Jan Niehusmann 2021-09-26 15:38:07 +02:00 committed by GitHub
parent d93c4fc4c8
commit 105dcfddd7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 7 deletions

View file

@ -91,6 +91,7 @@ pub enum DynDisabled {
Floating, Floating,
PullDown, PullDown,
PullUp, PullUp,
BusKeep,
} }
/// Value-level `enum` for input configurations /// Value-level `enum` for input configurations
@ -100,6 +101,7 @@ pub enum DynInput {
Floating, Floating,
PullDown, PullDown,
PullUp, PullUp,
BusKeep,
} }
/// Value-level `enum` for output configurations /// Value-level `enum` for output configurations

View file

@ -6,8 +6,8 @@
//! to track the state of pins at compile-time. To do so, it uses traits to //! to track the state of pins at compile-time. To do so, it uses traits to
//! represent [type classes] and types as instances of those type classes. For //! represent [type classes] and types as instances of those type classes. For
//! example, the trait [`InputConfig`] acts as a [type-level enum] of the //! example, the trait [`InputConfig`] acts as a [type-level enum] of the
//! available input configurations, and the types [`Floating`], [`PullDown`] and //! available input configurations, and the types [`Floating`], [`PullDown`],
//! [`PullUp`] are its type-level variants. //! [`PullUp`] and [`BusKeep`] are its type-level variants.
//! //!
//! When applied as a trait bound, a type-level enum restricts type parameters //! When applied as a trait bound, a type-level enum restricts type parameters
//! to the corresponding variants. All of the traits in this module are closed, //! to the corresponding variants. All of the traits in this module are closed,
@ -126,10 +126,13 @@ pub enum Floating {}
pub enum PullDown {} pub enum PullDown {}
/// Type-level variant of both [`DisabledConfig`] and [`InputConfig`] /// Type-level variant of both [`DisabledConfig`] and [`InputConfig`]
pub enum PullUp {} pub enum PullUp {}
/// Type-level variant of both [`DisabledConfig`] and [`InputConfig`]
pub enum BusKeep {}
impl Sealed for Floating {} impl Sealed for Floating {}
impl Sealed for PullDown {} impl Sealed for PullDown {}
impl Sealed for PullUp {} impl Sealed for PullUp {}
impl Sealed for BusKeep {}
impl DisabledConfig for Floating { impl DisabledConfig for Floating {
const DYN: DynDisabled = DynDisabled::Floating; const DYN: DynDisabled = DynDisabled::Floating;
@ -140,11 +143,14 @@ impl DisabledConfig for PullDown {
impl DisabledConfig for PullUp { impl DisabledConfig for PullUp {
const DYN: DynDisabled = DynDisabled::PullUp; const DYN: DynDisabled = DynDisabled::PullUp;
} }
impl DisabledConfig for BusKeep {
const DYN: DynDisabled = DynDisabled::BusKeep;
}
/// Type-level variant of [`PinMode`] for disabled modes /// Type-level variant of [`PinMode`] for disabled modes
/// ///
/// Type `C` is one of three configurations: [`Floating`], [`PullDown`] or /// Type `C` is one of four configurations: [`Floating`], [`PullDown`],
/// [`PullUp`] /// [`PullUp`] or [`BusKeep`]
pub struct Disabled<C: DisabledConfig> { pub struct Disabled<C: DisabledConfig> {
cfg: PhantomData<C>, cfg: PhantomData<C>,
} }
@ -160,6 +166,9 @@ pub type PullDownDisabled = Disabled<PullDown>;
/// Type-level variant of [`PinMode`] for pull-up disabled mode /// Type-level variant of [`PinMode`] for pull-up disabled mode
pub type PullUpDisabled = Disabled<PullUp>; pub type PullUpDisabled = Disabled<PullUp>;
/// Type-level variant of [`PinMode`] for bus keep disabled mode
pub type BusKeepDisabled = Disabled<BusKeep>;
impl<I: PinId, C: DisabledConfig> ValidPinMode<I> for Disabled<C> {} impl<I: PinId, C: DisabledConfig> ValidPinMode<I> for Disabled<C> {}
//============================================================================== //==============================================================================
@ -181,11 +190,14 @@ impl InputConfig for PullDown {
impl InputConfig for PullUp { impl InputConfig for PullUp {
const DYN: DynInput = DynInput::PullUp; const DYN: DynInput = DynInput::PullUp;
} }
impl InputConfig for BusKeep {
const DYN: DynInput = DynInput::BusKeep;
}
/// Type-level variant of [`PinMode`] for input modes /// Type-level variant of [`PinMode`] for input modes
/// ///
/// Type `C` is one of three input configurations: [`Floating`], [`PullDown`] or /// Type `C` is one of four input configurations: [`Floating`], [`PullDown`],
/// [`PullUp`] /// [`PullUp`] or [`BusKeep`]
pub struct Input<C: InputConfig> { pub struct Input<C: InputConfig> {
cfg: PhantomData<C>, cfg: PhantomData<C>,
} }
@ -201,6 +213,9 @@ pub type PullDownInput = Input<PullDown>;
/// Type-level variant of [`PinMode`] for pull-up input mode /// Type-level variant of [`PinMode`] for pull-up input mode
pub type PullUpInput = Input<PullUp>; pub type PullUpInput = Input<PullUp>;
/// Type-level variant of [`PinMode`] for bus keep input mode
pub type BusKeepInput = Input<BusKeep>;
impl<I: PinId, C: InputConfig> ValidPinMode<I> for Input<C> {} impl<I: PinId, C: InputConfig> ValidPinMode<I> for Input<C> {}
//============================================================================== //==============================================================================
@ -490,6 +505,12 @@ where
self.into_mode() self.into_mode()
} }
/// Configure the pin to operate as a bus keep input
#[inline]
pub fn into_bus_keep_input(self) -> Pin<I, BusKeepInput> {
self.into_mode()
}
/// Configure the pin to operate as a push-pull output /// Configure the pin to operate as a push-pull output
#[inline] #[inline]
pub fn into_push_pull_output(self) -> Pin<I, PushPullOutput> { pub fn into_push_pull_output(self) -> Pin<I, PushPullOutput> {
@ -792,7 +813,7 @@ macro_rules! gpio {
// FIXME: Somehow just import what we need // FIXME: Somehow just import what we need
#[allow(unused_imports)] #[allow(unused_imports)]
use super::{PullDownDisabled,PullUpDisabled,FloatingDisabled}; use super::{PullDownDisabled,PullUpDisabled,FloatingDisabled,BusKeepDisabled};
use super::{Pin,PinId}; use super::{Pin,PinId};
use crate::resets::SubsystemReset; use crate::resets::SubsystemReset;

View file

@ -45,6 +45,10 @@ impl From<DynPinMode> for ModeFields {
PullUp => { PullUp => {
fields.pue = true; fields.pue = true;
} }
BusKeep => {
fields.pde = true;
fields.pue = true;
}
} }
} }
Input(config) => { Input(config) => {
@ -61,6 +65,10 @@ impl From<DynPinMode> for ModeFields {
PullUp => { PullUp => {
fields.pue = true; fields.pue = true;
} }
BusKeep => {
fields.pde = true;
fields.pue = true;
}
} }
} }
Output(config) => { Output(config) => {