From db56c4fe6fb919e89edda37fc5acb2fb05f45745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Schulz-Ansres?= Date: Wed, 15 May 2024 12:54:30 +0200 Subject: [PATCH] Add miso pullup to spi configuration, add input as field for speed --- embassy-stm32/src/gpio.rs | 36 ++++++++++++++++++++++++++++++++++++ embassy-stm32/src/spi/mod.rs | 29 +++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 214813a42..d2db0a257 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -265,6 +265,7 @@ impl From for vals::Pupdr { #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Speed { + Input, Low, Medium, #[cfg(not(any(syscfg_f0, gpio_v1)))] @@ -278,6 +279,7 @@ impl From for vals::Mode { use Speed::*; match speed { + Input => vals::Mode::INPUT, Low => vals::Mode::OUTPUT2MHZ, Medium => vals::Mode::OUTPUT10MHZ, VeryHigh => vals::Mode::OUTPUT50MHZ, @@ -291,6 +293,7 @@ impl From for vals::Ospeedr { use Speed::*; match speed { + Input => vals::Ospeedr::LOWSPEED, Low => vals::Ospeedr::LOWSPEED, Medium => vals::Ospeedr::MEDIUMSPEED, #[cfg(not(syscfg_f0))] @@ -676,6 +679,39 @@ pub(crate) trait SealedPin { #[cfg(gpio_v2)] self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into())); } + + + /// Get the pull-up configuration. + #[inline] + fn pull(&self) -> Pull { + critical_section::with(|_| { + let r = self.block(); + let n = self._pin() as usize; + #[cfg(gpio_v1)] + { + let crlh = if n < 8 { 0 } else { 1 }; + match r.cr(crlh).cnf(n % 8) { + vals::CnfIn::FLOATING => Pull::None, + _ => if r.bsrr().read().bs(n % 8) { + Pull::Up + } else if r.bsrr().read().br(n % 8) { + Pull::Down + } else { + Pull::None + } + } + } + #[cfg(gpio_v2)] + { + match r.pupdr().read().pupdr(n % 8) { + vals::Pupdr::FLOATING => Pull::None, + vals::Pupdr::PULLDOWN => Pull::Down, + vals::Pupdr::PULLUP => Pull::Up, + vals::Pupdr::_RESERVED_3 => Pull::None, + } + } + }) + } } /// GPIO pin trait. diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index c39ef1913..bcd6b0bf4 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -50,6 +50,11 @@ pub struct Config { pub bit_order: BitOrder, /// Clock frequency. pub frequency: Hertz, + /// Enable internal pullup on MISO. + /// + /// There are some ICs that require a pull-up on the MISO pin for some applications. + /// If you are unsure, you probably don't need this. + pub miso_pullup: bool, } impl Default for Config { @@ -58,6 +63,7 @@ impl Default for Config { mode: MODE_0, bit_order: BitOrder::MsbFirst, frequency: Hertz(1_000_000), + miso_pullup: false, } } } @@ -275,6 +281,16 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { BitOrder::MsbFirst }; + let miso_pullup = match &self.miso { + None => false, + Some(pin) => + if pin.pull() == Pull::Up { + true + } else { + false + } + }; + #[cfg(any(spi_v1, spi_f1, spi_v2))] let br = cfg.br(); #[cfg(any(spi_v3, spi_v4, spi_v5))] @@ -287,6 +303,7 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { mode: Mode { polarity, phase }, bit_order, frequency, + miso_pullup, } } @@ -409,7 +426,11 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { peri, new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(miso, AFType::Input, Speed::VeryHigh), + new_pin!(miso, AFType::Input, Speed::Input, + match config.miso_pullup { + true => Pull::Up, + false => Pull::None, + }), None, None, config, @@ -427,7 +448,11 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { peri, new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), None, - new_pin!(miso, AFType::Input, Speed::VeryHigh), + new_pin!(miso, AFType::Input, Speed::Input, + match config.miso_pullup { + true => Pull::Up, + false => Pull::None, + }), None, None, config,