From 105dcfddd70d71729cc6b809e9206243ae5cc0ab Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Sun, 26 Sep 2021 15:38:07 +0200 Subject: [PATCH] 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 --- rp2040-hal/src/gpio/dynpin.rs | 2 ++ rp2040-hal/src/gpio/pin.rs | 35 ++++++++++++++++++++++++++++------- rp2040-hal/src/gpio/reg.rs | 8 ++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/rp2040-hal/src/gpio/dynpin.rs b/rp2040-hal/src/gpio/dynpin.rs index 67b12f3..4cb275f 100644 --- a/rp2040-hal/src/gpio/dynpin.rs +++ b/rp2040-hal/src/gpio/dynpin.rs @@ -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 diff --git a/rp2040-hal/src/gpio/pin.rs b/rp2040-hal/src/gpio/pin.rs index 6bf4eee..edf6054 100644 --- a/rp2040-hal/src/gpio/pin.rs +++ b/rp2040-hal/src/gpio/pin.rs @@ -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 { cfg: PhantomData, } @@ -160,6 +166,9 @@ pub type PullDownDisabled = Disabled; /// Type-level variant of [`PinMode`] for pull-up disabled mode pub type PullUpDisabled = Disabled; +/// Type-level variant of [`PinMode`] for bus keep disabled mode +pub type BusKeepDisabled = Disabled; + impl ValidPinMode for Disabled {} //============================================================================== @@ -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 { cfg: PhantomData, } @@ -201,6 +213,9 @@ pub type PullDownInput = Input; /// Type-level variant of [`PinMode`] for pull-up input mode pub type PullUpInput = Input; +/// Type-level variant of [`PinMode`] for bus keep input mode +pub type BusKeepInput = Input; + impl ValidPinMode for Input {} //============================================================================== @@ -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 { + self.into_mode() + } + /// Configure the pin to operate as a push-pull output #[inline] pub fn into_push_pull_output(self) -> Pin { @@ -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; diff --git a/rp2040-hal/src/gpio/reg.rs b/rp2040-hal/src/gpio/reg.rs index 5d8bbd3..451959d 100644 --- a/rp2040-hal/src/gpio/reg.rs +++ b/rp2040-hal/src/gpio/reg.rs @@ -45,6 +45,10 @@ impl From for ModeFields { PullUp => { fields.pue = true; } + BusKeep => { + fields.pde = true; + fields.pue = true; + } } } Input(config) => { @@ -61,6 +65,10 @@ impl From for ModeFields { PullUp => { fields.pue = true; } + BusKeep => { + fields.pde = true; + fields.pue = true; + } } } Output(config) => {