diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index 585e9861e..f9a5eff50 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs @@ -224,8 +224,6 @@ pub(crate) mod sealed { SIO.gpio_in(self.bank() as _) } } - - pub trait OptionalPin {} } pub trait Pin: Unborrow + sealed::Pin { @@ -250,54 +248,6 @@ impl sealed::Pin for AnyPin { // ========================== -pub trait OptionalPin: Unborrow + sealed::OptionalPin + Sized { - type Pin: Pin; - fn pin(&self) -> Option<&Self::Pin>; - fn pin_mut(&mut self) -> Option<&mut Self::Pin>; - - /// Convert from concrete pin type PIN_XX to type erased `Option`. - #[inline] - fn degrade_optional(mut self) -> Option { - self.pin_mut() - .map(|pin| unsafe { core::ptr::read(pin) }.degrade()) - } -} - -impl sealed::OptionalPin for T {} -impl OptionalPin for T { - type Pin = T; - - #[inline] - fn pin(&self) -> Option<&T> { - Some(self) - } - - #[inline] - fn pin_mut(&mut self) -> Option<&mut T> { - Some(self) - } -} - -#[derive(Clone, Copy, Debug)] -pub struct NoPin; -unsafe_impl_unborrow!(NoPin); -impl sealed::OptionalPin for NoPin {} -impl OptionalPin for NoPin { - type Pin = AnyPin; - - #[inline] - fn pin(&self) -> Option<&AnyPin> { - None - } - - #[inline] - fn pin_mut(&mut self) -> Option<&mut AnyPin> { - None - } -} - -// ========================== - macro_rules! impl_pin { ($name:ident, $bank:expr, $pin_num:expr) => { impl Pin for peripherals::$name {} diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index 491082188..3d498aff9 100644 --- a/embassy-rp/src/spi.rs +++ b/embassy-rp/src/spi.rs @@ -6,7 +6,7 @@ use embedded_hal::blocking::spi as eh; use embedded_hal::spi as ehnb; use crate::gpio::sealed::Pin as _; -use crate::gpio::{NoPin, OptionalPin}; +use crate::gpio::{AnyPin, Pin as GpioPin}; use crate::{pac, peripherals}; pub use ehnb::{Phase, Polarity}; @@ -66,10 +66,62 @@ impl<'d, T: Instance> Spi<'d, T> { clk: impl Unborrow> + 'd, mosi: impl Unborrow> + 'd, miso: impl Unborrow> + 'd, - cs: impl Unborrow> + 'd, config: Config, ) -> Self { - unborrow!(inner, clk, mosi, miso, cs); + unborrow!(clk, mosi, miso); + Self::new_inner( + inner, + Some(clk.degrade()), + Some(mosi.degrade()), + Some(miso.degrade()), + None, + config, + ) + } + + pub fn new_txonly( + inner: impl Unborrow + 'd, + clk: impl Unborrow> + 'd, + mosi: impl Unborrow> + 'd, + config: Config, + ) -> Self { + unborrow!(clk, mosi); + Self::new_inner( + inner, + Some(clk.degrade()), + Some(mosi.degrade()), + None, + None, + config, + ) + } + + pub fn new_rxonly( + inner: impl Unborrow + 'd, + clk: impl Unborrow> + 'd, + miso: impl Unborrow> + 'd, + config: Config, + ) -> Self { + unborrow!(clk, miso); + Self::new_inner( + inner, + Some(clk.degrade()), + None, + Some(miso.degrade()), + None, + config, + ) + } + + fn new_inner( + inner: impl Unborrow + 'd, + clk: Option, + mosi: Option, + miso: Option, + cs: Option, + config: Config, + ) -> Self { + unborrow!(inner); unsafe { let p = inner.regs(); @@ -86,16 +138,16 @@ impl<'d, T: Instance> Spi<'d, T> { w.set_sse(true); // enable }); - if let Some(pin) = clk.pin_mut() { + if let Some(pin) = &clk { pin.io().ctrl().write(|w| w.set_funcsel(1)); } - if let Some(pin) = mosi.pin_mut() { + if let Some(pin) = &mosi { pin.io().ctrl().write(|w| w.set_funcsel(1)); } - if let Some(pin) = miso.pin_mut() { + if let Some(pin) = &miso { pin.io().ctrl().write(|w| w.set_funcsel(1)); } - if let Some(pin) = cs.pin_mut() { + if let Some(pin) = &cs { pin.io().ctrl().write(|w| w.set_funcsel(1)); } } @@ -180,10 +232,6 @@ mod sealed { pub trait Instance { fn regs(&self) -> pac::spi::Spi; } - pub trait ClkPin {} - pub trait CsPin {} - pub trait MosiPin {} - pub trait MisoPin {} } pub trait Instance: sealed::Instance {} @@ -202,23 +250,13 @@ macro_rules! impl_instance { impl_instance!(SPI0, Spi0); impl_instance!(SPI1, Spi1); -pub trait ClkPin: sealed::ClkPin + OptionalPin {} -pub trait CsPin: sealed::CsPin + OptionalPin {} -pub trait MosiPin: sealed::MosiPin + OptionalPin {} -pub trait MisoPin: sealed::MisoPin + OptionalPin {} - -impl sealed::ClkPin for NoPin {} -impl ClkPin for NoPin {} -impl sealed::CsPin for NoPin {} -impl CsPin for NoPin {} -impl sealed::MosiPin for NoPin {} -impl MosiPin for NoPin {} -impl sealed::MisoPin for NoPin {} -impl MisoPin for NoPin {} +pub trait ClkPin: GpioPin {} +pub trait CsPin: GpioPin {} +pub trait MosiPin: GpioPin {} +pub trait MisoPin: GpioPin {} macro_rules! impl_pin { ($pin:ident, $instance:ident, $function:ident) => { - impl sealed::$function for peripherals::$pin {} impl $function for peripherals::$pin {} }; } diff --git a/examples/rp/src/bin/spi.rs b/examples/rp/src/bin/spi.rs index c4748f2ec..71dec94f3 100644 --- a/examples/rp/src/bin/spi.rs +++ b/examples/rp/src/bin/spi.rs @@ -7,7 +7,6 @@ mod example_common; use defmt::*; use embassy::executor::Spawner; -use embassy_rp::gpio::NoPin; use embassy_rp::spi; use embassy_rp::spi::Spi; use embassy_rp::{gpio, Peripherals}; @@ -27,7 +26,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { // create SPI let mut config = spi::Config::default(); config.frequency = 2_000_000; - let mut spi = Spi::new(p.SPI1, clk, mosi, miso, NoPin, config); + let mut spi = Spi::new(p.SPI1, clk, mosi, miso, config); // Configure CS let mut cs = Output::new(touch_cs, Level::Low); diff --git a/examples/rp/src/bin/spi_display.rs b/examples/rp/src/bin/spi_display.rs index 1ae3ae66e..96f0cf378 100644 --- a/examples/rp/src/bin/spi_display.rs +++ b/examples/rp/src/bin/spi_display.rs @@ -12,7 +12,6 @@ use defmt::*; use display_interface_spi::SPIInterfaceNoCS; use embassy::executor::Spawner; use embassy::time::Delay; -use embassy_rp::gpio::NoPin; use embassy_rp::peripherals; use embassy_rp::spi; use embassy_rp::spi::Spi; @@ -49,7 +48,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { let spi = RefCell::new(SpiState { last_mode: SpiMode::Display, - spi: Spi::new(p.SPI1, clk, mosi, miso, NoPin, config), + spi: Spi::new(p.SPI1, clk, mosi, miso, config), display_cs: Output::new(display_cs, Level::Low), });