diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs index 6f91c7c034f..2a62193b7b0 100644 --- a/esp-hal/src/gpio/interconnect.rs +++ b/esp-hal/src/gpio/interconnect.rs @@ -393,13 +393,6 @@ impl Signal<'_> { } } - fn connect_with_guard(self, signal: crate::gpio::OutputSignal) -> PinGuard { - match self { - Signal::Pin(pin) => PinGuard::new(pin, signal), - Signal::Level(_) => PinGuard::new_unconnected(signal), - } - } - fn connect_to_peripheral_input( &self, signal: gpio::InputSignal, @@ -864,7 +857,10 @@ impl<'d> OutputSignal<'d> { #[instability::unstable] pub(crate) fn connect_with_guard(self, signal: crate::gpio::OutputSignal) -> PinGuard { signal.connect_to(&self); - self.pin.connect_with_guard(signal) + match self.pin { + Signal::Pin(pin) => PinGuard::new(pin), + Signal::Level(_) => PinGuard::new_unconnected(), + } } delegate::delegate! { diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 38970870104..e73fbb192b4 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -64,6 +64,7 @@ crate::unstable_module! { #[cfg(all(soc_has_rtc_io, not(esp32)))] pub mod rtc_io; } +use interconnect::PeripheralOutput; mod asynch; mod embedded_hal_impls; @@ -99,24 +100,19 @@ pub(crate) static GPIO_LOCK: RawMutex = RawMutex::new(); #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub(crate) struct PinGuard { pin: u8, - signal: OutputSignal, } impl crate::private::Sealed for PinGuard {} impl PinGuard { - pub(crate) fn new(pin: AnyPin<'_>, signal: OutputSignal) -> Self { - Self { - pin: pin.number(), - signal, - } + // This must only be used with a pin currently configured for output, and the PinGuard must be + // dropped before the pin can be reconfigured (e.g. for input). + fn new(pin: AnyPin<'_>) -> Self { + Self { pin: pin.number() } } - pub(crate) fn new_unconnected(signal: OutputSignal) -> Self { - Self { - pin: u8::MAX, - signal, - } + pub(crate) fn new_unconnected() -> Self { + Self { pin: u8::MAX } } #[allow(unused)] @@ -133,7 +129,7 @@ impl Drop for PinGuard { fn drop(&mut self) { if self.pin != u8::MAX { let pin = unsafe { AnyPin::steal(self.pin) }; - self.signal.disconnect_from(&pin); + pin.disconnect_from_peripheral_output(); } } } diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs index 0e8f517f655..93b6fd28776 100644 --- a/esp-hal/src/i2c/master/mod.rs +++ b/esp-hal/src/i2c/master/mod.rs @@ -715,8 +715,8 @@ impl<'d> I2c<'d, Blocking> { pub fn new(i2c: impl Instance + 'd, config: Config) -> Result { let guard = PeripheralGuard::new(i2c.info().peripheral); - let sda_pin = PinGuard::new_unconnected(i2c.info().sda_output); - let scl_pin = PinGuard::new_unconnected(i2c.info().scl_output); + let sda_pin = PinGuard::new_unconnected(); + let scl_pin = PinGuard::new_unconnected(); let mut i2c = I2c { i2c: i2c.degrade(), diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 5aa28670cd6..35819135dc5 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -616,16 +616,16 @@ struct SpiPinGuard { cs_pin: PinGuard, sio0_pin: PinGuard, sio1_pin: PinGuard, - sio2_pin: Option, - sio3_pin: Option, + sio2_pin: PinGuard, + sio3_pin: PinGuard, #[cfg(spi_master_has_octal)] - sio4_pin: Option, + sio4_pin: PinGuard, #[cfg(spi_master_has_octal)] - sio5_pin: Option, + sio5_pin: PinGuard, #[cfg(spi_master_has_octal)] - sio6_pin: Option, + sio6_pin: PinGuard, #[cfg(spi_master_has_octal)] - sio7_pin: Option, + sio7_pin: PinGuard, } /// Configuration errors. @@ -710,20 +710,20 @@ impl<'d> Spi<'d, Blocking> { _mode: PhantomData, guard, pins: SpiPinGuard { - sclk_pin: PinGuard::new_unconnected(spi.info().sclk), - cs_pin: PinGuard::new_unconnected(spi.info().cs(0)), - sio0_pin: PinGuard::new_unconnected(spi.info().sio_output(0)), - sio1_pin: PinGuard::new_unconnected(spi.info().sio_output(1)), - sio2_pin: spi.info().opt_sio_output(2).map(PinGuard::new_unconnected), - sio3_pin: spi.info().opt_sio_output(3).map(PinGuard::new_unconnected), + sclk_pin: PinGuard::new_unconnected(), + cs_pin: PinGuard::new_unconnected(), + sio0_pin: PinGuard::new_unconnected(), + sio1_pin: PinGuard::new_unconnected(), + sio2_pin: PinGuard::new_unconnected(), + sio3_pin: PinGuard::new_unconnected(), #[cfg(spi_master_has_octal)] - sio4_pin: spi.info().opt_sio_output(4).map(PinGuard::new_unconnected), + sio4_pin: PinGuard::new_unconnected(), #[cfg(spi_master_has_octal)] - sio5_pin: spi.info().opt_sio_output(5).map(PinGuard::new_unconnected), + sio5_pin: PinGuard::new_unconnected(), #[cfg(spi_master_has_octal)] - sio6_pin: spi.info().opt_sio_output(6).map(PinGuard::new_unconnected), + sio6_pin: PinGuard::new_unconnected(), #[cfg(spi_master_has_octal)] - sio7_pin: spi.info().opt_sio_output(7).map(PinGuard::new_unconnected), + sio7_pin: PinGuard::new_unconnected(), }, spi: spi.degrade(), }; @@ -922,7 +922,7 @@ macro_rules! def_with_sio_pin { #[doc = concat!(" to the SIO", stringify!($n), " output and input signals.")] #[instability::unstable] pub fn $fn(mut self, sio: impl PeripheralOutput<'d>) -> Self { - self.pins.$field = Some(self.connect_sio_pin(sio.into(), $n)); + self.pins.$field = self.connect_sio_pin(sio.into(), $n); self } diff --git a/esp-hal/src/uart/mod.rs b/esp-hal/src/uart/mod.rs index b16ee571f78..4aedae1e5e5 100644 --- a/esp-hal/src/uart/mod.rs +++ b/esp-hal/src/uart/mod.rs @@ -469,8 +469,8 @@ where let mem_guard = create_mem_guard(unsafe { self.uart.clone_unchecked() }); - let rts_pin = PinGuard::new_unconnected(self.uart.info().rts_signal); - let tx_pin = PinGuard::new_unconnected(self.uart.info().tx_signal); + let rts_pin = PinGuard::new_unconnected(); + let tx_pin = PinGuard::new_unconnected(); let mut serial = Uart { rx: UartRx {