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,
PullDown,
PullUp,
BusKeep,
}
/// Value-level `enum` for input configurations
@ -100,6 +101,7 @@ pub enum DynInput {
Floating,
PullDown,
PullUp,
BusKeep,
}
/// 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
//! represent [type classes] and types as instances of those type classes. For
//! example, the trait [`InputConfig`] acts as a [type-level enum] of the
//! available input configurations, and the types [`Floating`], [`PullDown`] and
//! [`PullUp`] are its type-level variants.
//! available input configurations, and the types [`Floating`], [`PullDown`],
//! [`PullUp`] and [`BusKeep`] are its type-level variants.
//!
//! 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,
@ -126,10 +126,13 @@ pub enum Floating {}
pub enum PullDown {}
/// Type-level variant of both [`DisabledConfig`] and [`InputConfig`]
pub enum PullUp {}
/// Type-level variant of both [`DisabledConfig`] and [`InputConfig`]
pub enum BusKeep {}
impl Sealed for Floating {}
impl Sealed for PullDown {}
impl Sealed for PullUp {}
impl Sealed for BusKeep {}
impl DisabledConfig for Floating {
const DYN: DynDisabled = DynDisabled::Floating;
@ -140,11 +143,14 @@ impl DisabledConfig for PullDown {
impl DisabledConfig for PullUp {
const DYN: DynDisabled = DynDisabled::PullUp;
}
impl DisabledConfig for BusKeep {
const DYN: DynDisabled = DynDisabled::BusKeep;
}
/// Type-level variant of [`PinMode`] for disabled modes
///
/// Type `C` is one of three configurations: [`Floating`], [`PullDown`] or
/// [`PullUp`]
/// Type `C` is one of four configurations: [`Floating`], [`PullDown`],
/// [`PullUp`] or [`BusKeep`]
pub struct Disabled<C: DisabledConfig> {
cfg: PhantomData<C>,
}
@ -160,6 +166,9 @@ pub type PullDownDisabled = Disabled<PullDown>;
/// Type-level variant of [`PinMode`] for pull-up disabled mode
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> {}
//==============================================================================
@ -181,11 +190,14 @@ impl InputConfig for PullDown {
impl InputConfig for PullUp {
const DYN: DynInput = DynInput::PullUp;
}
impl InputConfig for BusKeep {
const DYN: DynInput = DynInput::BusKeep;
}
/// Type-level variant of [`PinMode`] for input modes
///
/// Type `C` is one of three input configurations: [`Floating`], [`PullDown`] or
/// [`PullUp`]
/// Type `C` is one of four input configurations: [`Floating`], [`PullDown`],
/// [`PullUp`] or [`BusKeep`]
pub struct Input<C: InputConfig> {
cfg: PhantomData<C>,
}
@ -201,6 +213,9 @@ pub type PullDownInput = Input<PullDown>;
/// Type-level variant of [`PinMode`] for pull-up input mode
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> {}
//==============================================================================
@ -490,6 +505,12 @@ where
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
#[inline]
pub fn into_push_pull_output(self) -> Pin<I, PushPullOutput> {
@ -792,7 +813,7 @@ macro_rules! gpio {
// FIXME: Somehow just import what we need
#[allow(unused_imports)]
use super::{PullDownDisabled,PullUpDisabled,FloatingDisabled};
use super::{PullDownDisabled,PullUpDisabled,FloatingDisabled,BusKeepDisabled};
use super::{Pin,PinId};
use crate::resets::SubsystemReset;

View file

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