From d2f80426271f3b1f618c0e2238470c890bdecbf9 Mon Sep 17 00:00:00 2001
From: Dominic Fischer <git@dominicfischer.me>
Date: Sun, 17 Nov 2024 12:51:09 +0000
Subject: [PATCH] Refactor SPI MISO setup

---
 esp-hal/CHANGELOG.md              |  6 +++---
 esp-hal/src/spi/master.rs         | 24 ++++++++++++++++++++++--
 hil-test/tests/spi_full_duplex.rs |  6 ++++--
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md
index 77aab858e03..114bca1d4c6 100644
--- a/esp-hal/CHANGELOG.md
+++ b/esp-hal/CHANGELOG.md
@@ -84,10 +84,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - The `ledc::ChannelHW` trait is no longer generic. (#2387)
 - The `I2c::new_with_timeout` constructors have been removed (#2361)
 - `I2c::new()` no longer takes `frequency` and pins as parameters. (#2477)
-- The `spi::master::HalfDuplexReadWrite` trait has been removed. (#2373)
+- The `spi::master::HalfDuplexReadWrite` trait has been removed. (#2373, #2557)
 - The `Spi::with_pins` methods have been removed. (#2373)
-- The `Spi::new_half_duplex` constructor have been removed. (#2373)
-- The `HalfDuplexMode` and `FullDuplexMode` parameters have been removed from `Spi`. (#2373)
+- The `Spi::new_half_duplex` constructor have been removed. (#2373, #2557)
+- The `HalfDuplexMode` and `FullDuplexMode` parameters have been removed from `Spi`. (#2373, #2557)
 - Removed the output pin type parameter from `ledc::{Channel, ChannelIFace}` (#2388)
 - Removed the output pin type parameter from `mcpwm::operator::{PwmPin, LinkedPins}` (#2388)
 - Removed the output pin type parameter from `parl_io::{ClkOutPin, ClkInPin, RxClkInPin}` (#2388)
diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs
index 2bc93c5d61c..1cd8134418c 100644
--- a/esp-hal/src/spi/master.rs
+++ b/esp-hal/src/spi/master.rs
@@ -79,7 +79,12 @@ use super::{DmaError, Error, SpiBitOrder, SpiDataMode, SpiMode};
 use crate::{
     clock::Clocks,
     dma::{Channel, DmaChannelConvert, DmaEligible, DmaRxBuffer, DmaTxBuffer, Rx, Tx},
-    gpio::{interconnect::PeripheralOutput, InputSignal, NoPin, OutputSignal},
+    gpio::{
+        interconnect::{PeripheralInput, PeripheralOutput},
+        InputSignal,
+        NoPin,
+        OutputSignal,
+    },
     interrupt::InterruptHandler,
     peripheral::{Peripheral, PeripheralRef},
     peripherals::spi2::RegisterBlock,
@@ -618,9 +623,24 @@ where
 
     /// Assign the MISO (Master In Slave Out) pin for the SPI instance.
     ///
+    /// Enables input functionality for the pin, and connects it to the MISO
+    /// signal.
+    pub fn with_miso<MISO: PeripheralInput>(self, miso: impl Peripheral<P = MISO> + 'd) -> Self {
+        crate::into_mapped_ref!(miso);
+        miso.enable_input(true, private::Internal);
+
+        self.driver().miso.connect_to(&mut miso);
+
+        self
+    }
+
+    /// Assign the SIO1/MISO pin for the SPI instance.
+    ///
     /// Enables both input and output functionality for the pin, and connects it
     /// to the MISO signal and SIO1 input signal.
-    pub fn with_miso<MISO: PeripheralOutput>(self, miso: impl Peripheral<P = MISO> + 'd) -> Self {
+    ///
+    /// Note: You do not need to call [Self::with_miso] when this is used.
+    pub fn with_sio1<SIO1: PeripheralOutput>(self, miso: impl Peripheral<P = SIO1> + 'd) -> Self {
         crate::into_mapped_ref!(miso);
         miso.enable_input(true, private::Internal);
         miso.enable_output(true, private::Internal);
diff --git a/hil-test/tests/spi_full_duplex.rs b/hil-test/tests/spi_full_duplex.rs
index 1b893dcb132..502b0965511 100644
--- a/hil-test/tests/spi_full_duplex.rs
+++ b/hil-test/tests/spi_full_duplex.rs
@@ -71,8 +71,10 @@ mod tests {
             }
         }
 
+        let (miso, mosi) = mosi.split();
         #[cfg(pcnt)]
-        let (mosi_loopback_pcnt, mosi) = mosi.split();
+        let mosi_loopback_pcnt = miso.clone();
+
         // Need to set miso first so that mosi can overwrite the
         // output connection (because we are using the same pin to loop back)
         let spi = Spi::new_with_config(
@@ -83,7 +85,7 @@ mod tests {
             },
         )
         .with_sck(sclk)
-        .with_miso(unsafe { mosi.clone_unchecked() })
+        .with_miso(miso)
         .with_mosi(mosi);
 
         let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(32000);