diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index 81cb09b24..808a5bc82 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -681,6 +681,38 @@ 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).read().mode(n % 8) {
+                    vals::Mode::INPUT => match r.cr(crlh).read().cnf_in(n % 8) {
+                        vals::CnfIn::PULL => match r.odr().read().odr(n) {
+                            vals::Odr::LOW => Pull::Down,
+                            vals::Odr::HIGH => Pull::Up,
+                        },
+                        _ => Pull::None,
+                    },
+                    _ => Pull::None,
+                }
+            }
+            #[cfg(gpio_v2)]
+            {
+                match r.pupdr().read().pupdr(n) {
+                    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 0875cfe41..5fc8691ac 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_pull: Pull,
 }
 
 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_pull: Pull::None,
         }
     }
 }
@@ -273,6 +279,11 @@ impl<'d, M: PeriMode> Spi<'d, M> {
             BitOrder::MsbFirst
         };
 
+        let miso_pull = match &self.miso {
+            None => Pull::None,
+            Some(pin) => pin.pull(),
+        };
+
         #[cfg(any(spi_v1, spi_f1, spi_v2))]
         let br = cfg.br();
         #[cfg(any(spi_v3, spi_v4, spi_v5))]
@@ -284,6 +295,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
             mode: Mode { polarity, phase },
             bit_order,
             frequency,
+            miso_pull,
         }
     }
 
@@ -406,7 +418,7 @@ impl<'d> Spi<'d, 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::VeryHigh, config.miso_pull),
             None,
             None,
             config,
@@ -424,7 +436,7 @@ impl<'d> Spi<'d, 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::VeryHigh, config.miso_pull),
             None,
             None,
             config,