diff --git a/CHANGELOG.md b/CHANGELOG.md index 55f72b6d4..95e0819ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - MSRV raised to 1.79 - The PCNT and the Timer drivers are not available under ESP-IDF 6+. These need to be rewritten against their newer "gptimer" and "pulse_cnt" ESP-IDF C equivalents. +- (#529) `Peripheral` and `PeripheralRef` removed and replaced with a simple pattern similar to the `esp-hal` one. + - Check https://github.com/esp-rs/esp-idf-hal/pull/529 for details on that change +- The `prelude` module is removed. It was anyway only having a handful of types listed in it. And furthermore, there was no `prelude` module for `esp-idf-svc`. ### Deprecated - `DB_11` ADC attenuation in favor of `DB_12` for ESP-IDF V5.0+ diff --git a/examples/button.rs b/examples/button.rs index cc74d800b..ed025bb9a 100644 --- a/examples/button.rs +++ b/examples/button.rs @@ -16,9 +16,7 @@ fn main() -> anyhow::Result<()> { let peripherals = Peripherals::take()?; let mut led = PinDriver::output(peripherals.pins.gpio4)?; - let mut button = PinDriver::input(peripherals.pins.gpio9)?; - - button.set_pull(Pull::Down)?; + let button = PinDriver::input(peripherals.pins.gpio9, Pull::Down)?; loop { // we are using thread::sleep here to make sure the watchdog isn't triggered diff --git a/examples/button_async.rs b/examples/button_async.rs index b3f0caab0..32e02f866 100644 --- a/examples/button_async.rs +++ b/examples/button_async.rs @@ -17,9 +17,7 @@ fn main() -> anyhow::Result<()> { let peripherals = Peripherals::take()?; let mut led = PinDriver::output(peripherals.pins.gpio4)?; - let mut button = PinDriver::input(peripherals.pins.gpio9)?; - - button.set_pull(Pull::Down)?; + let mut button = PinDriver::input(peripherals.pins.gpio9, Pull::Down)?; block_on(async { loop { diff --git a/examples/button_interrupt.rs b/examples/button_interrupt.rs index 97c7bf0ed..3f895f514 100644 --- a/examples/button_interrupt.rs +++ b/examples/button_interrupt.rs @@ -18,9 +18,8 @@ fn main() -> anyhow::Result<()> { let peripherals = Peripherals::take()?; let mut led = PinDriver::output(peripherals.pins.gpio4)?; - let mut button = PinDriver::input(peripherals.pins.gpio9)?; + let mut button = PinDriver::input(peripherals.pins.gpio9, Pull::Down)?; - button.set_pull(Pull::Down)?; button.set_interrupt_type(InterruptType::PosEdge)?; let mut led_state = false; diff --git a/examples/i2c_master_slave.rs b/examples/i2c_master_slave.rs index 21d28a4fb..f07f38753 100644 --- a/examples/i2c_master_slave.rs +++ b/examples/i2c_master_slave.rs @@ -19,18 +19,16 @@ use esp_idf_hal::delay::BLOCK; use esp_idf_hal::gpio::{AnyIOPin, InputPin, OutputPin}; use esp_idf_hal::i2c::{I2c, I2cConfig, I2cDriver, I2cSlaveConfig, I2cSlaveDriver}; -use esp_idf_hal::peripheral::Peripheral; use esp_idf_hal::peripherals::Peripherals; -use esp_idf_hal::prelude::*; -use esp_idf_hal::units::Hertz; +use esp_idf_hal::units::*; const SLAVE_ADDR: u8 = 0x22; const SLAVE_BUFFER_SIZE: usize = 128; fn i2c_master_init<'d>( - i2c: impl Peripheral

+ 'd, - sda: AnyIOPin, - scl: AnyIOPin, + i2c: impl I2c + 'd, + sda: AnyIOPin<'d>, + scl: AnyIOPin<'d>, baudrate: Hertz, ) -> anyhow::Result> { let config = I2cConfig::new().baudrate(baudrate); @@ -39,9 +37,9 @@ fn i2c_master_init<'d>( } fn i2c_slave_init<'d>( - i2c: impl Peripheral

+ 'd, - sda: AnyIOPin, - scl: AnyIOPin, + i2c: impl I2c + 'd, + sda: AnyIOPin<'d>, + scl: AnyIOPin<'d>, buflen: usize, slave_addr: u8, ) -> anyhow::Result> { diff --git a/examples/i2c_ssd1306.rs b/examples/i2c_ssd1306.rs index 87df5b498..c3a27644e 100644 --- a/examples/i2c_ssd1306.rs +++ b/examples/i2c_ssd1306.rs @@ -12,7 +12,7 @@ use esp_idf_hal::delay::{FreeRtos, BLOCK}; use esp_idf_hal::i2c::*; use esp_idf_hal::peripherals::Peripherals; -use esp_idf_hal::prelude::*; +use esp_idf_hal::units::*; const SSD1306_ADDRESS: u8 = 0x3c; diff --git a/examples/ledc_fade.rs b/examples/ledc_fade.rs index 66eb01f0c..be2515151 100644 --- a/examples/ledc_fade.rs +++ b/examples/ledc_fade.rs @@ -1,10 +1,11 @@ #![allow(unexpected_cfgs)] +use std::time::Duration; + use esp_idf_hal::delay::FreeRtos; use esp_idf_hal::ledc::{config::TimerConfig, LedcDriver, LedcTimerDriver}; use esp_idf_hal::peripherals::Peripherals; -use esp_idf_hal::prelude::*; -use std::time::Duration; +use esp_idf_hal::units::*; fn main() -> anyhow::Result<()> { esp_idf_hal::sys::link_patches(); diff --git a/examples/ledc_simple.rs b/examples/ledc_simple.rs index fb7da2b42..6abe81df6 100644 --- a/examples/ledc_simple.rs +++ b/examples/ledc_simple.rs @@ -1,7 +1,7 @@ use esp_idf_hal::delay::FreeRtos; use esp_idf_hal::ledc::*; use esp_idf_hal::peripherals::Peripherals; -use esp_idf_hal::prelude::*; +use esp_idf_hal::units::*; fn main() -> anyhow::Result<()> { esp_idf_hal::sys::link_patches(); diff --git a/examples/ledc_threads.rs b/examples/ledc_threads.rs index d0946a030..fece9d10a 100644 --- a/examples/ledc_threads.rs +++ b/examples/ledc_threads.rs @@ -5,7 +5,7 @@ use embedded_hal_0_2::PwmPin; use esp_idf_hal::ledc::*; use esp_idf_hal::peripherals::Peripherals; -use esp_idf_hal::prelude::*; +use esp_idf_hal::units::*; const CYCLES: usize = 3; diff --git a/examples/pcnt_rotary_encoder.rs b/examples/pcnt_rotary_encoder.rs index cc62896f9..a740cabee 100644 --- a/examples/pcnt_rotary_encoder.rs +++ b/examples/pcnt_rotary_encoder.rs @@ -15,7 +15,7 @@ fn main() -> anyhow::Result<()> { use anyhow::Context; use encoder::Encoder; use esp_idf_hal::delay::FreeRtos; - use esp_idf_hal::prelude::*; + use esp_idf_hal::peripherals::Peripherals; // Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once, // or else some patches to the runtime implemented by esp-idf-sys might not link properly. @@ -23,10 +23,10 @@ fn main() -> anyhow::Result<()> { println!("setup pins"); let peripherals = Peripherals::take().context("failed to take Peripherals")?; - let mut pin_a = peripherals.pins.gpio4; - let mut pin_b = peripherals.pins.gpio5; + let pin_a = peripherals.pins.gpio4; + let pin_b = peripherals.pins.gpio5; println!("setup encoder"); - let encoder = Encoder::new(peripherals.pcnt0, &mut pin_a, &mut pin_b)?; + let encoder = Encoder::new(peripherals.pcnt0, pin_a, pin_b)?; let mut last_value = 0i32; loop { @@ -66,7 +66,6 @@ mod encoder { use esp_idf_hal::gpio::AnyInputPin; use esp_idf_hal::gpio::InputPin; use esp_idf_hal::pcnt::*; - use esp_idf_hal::peripheral::Peripheral; use esp_idf_sys::EspError; const LOW_LIMIT: i16 = -100; @@ -78,10 +77,10 @@ mod encoder { } impl<'d> Encoder<'d> { - pub fn new( - pcnt: impl Peripheral

+ 'd, - pin_a: impl Peripheral

+ 'd, - pin_b: impl Peripheral

+ 'd, + pub fn new( + pcnt: impl Pcnt + 'd, + pin_a: impl InputPin + 'd, + pin_b: impl InputPin + 'd, ) -> Result { let mut unit = PcntDriver::new( pcnt, diff --git a/examples/rmt_morse_code.rs b/examples/rmt_morse_code.rs index 3837fa6f7..10d3d9e71 100644 --- a/examples/rmt_morse_code.rs +++ b/examples/rmt_morse_code.rs @@ -34,12 +34,12 @@ fn main() -> anyhow::Result<()> { #[cfg(any(feature = "rmt-legacy", esp_idf_version_major = "4"))] mod example { + use esp_idf_hal::gpio::Pull; use esp_idf_hal::units::FromValueType; use esp_idf_hal::{ delay::Ets, gpio::{OutputPin, PinDriver}, - peripheral::Peripheral, - prelude::Peripherals, + peripherals::Peripherals, rmt::{ config::{CarrierConfig, DutyPercent, Loop, TransmitConfig}, PinState, Pulse, PulseTicks, RmtChannel, TxRmtDriver, VariableLengthSignal, @@ -62,9 +62,14 @@ mod example { .looping(Loop::Endless) .clock_divider(255); - let tx = send_morse_code(&mut channel, &mut led, &config, "HELLO ")?; + let tx = send_morse_code( + unsafe { channel.reborrow() }, + unsafe { led.reborrow() }, + &config, + "HELLO ", + )?; - let stop = PinDriver::input(stop)?; + let stop = PinDriver::input(stop, Pull::Down)?; println!("Keep sending until pin {} is set low.", stop.pin()); @@ -89,8 +94,8 @@ mod example { } fn send_morse_code<'d>( - channel: impl Peripheral

+ 'd, - led: impl Peripheral

+ 'd, + channel: impl RmtChannel + 'd, + led: impl OutputPin + 'd, config: &TransmitConfig, message: &str, ) -> anyhow::Result> { diff --git a/examples/rmt_musical_buzzer.rs b/examples/rmt_musical_buzzer.rs index 75ae4f43d..d9e9bed0e 100644 --- a/examples/rmt_musical_buzzer.rs +++ b/examples/rmt_musical_buzzer.rs @@ -28,7 +28,7 @@ mod example { use esp_idf_hal::delay::Ets; use esp_idf_hal::{ - prelude::Peripherals, + peripherals::Peripherals, rmt::{self, config::TransmitConfig, TxRmtDriver}, units::Hertz, }; diff --git a/examples/rmt_neopixel.rs b/examples/rmt_neopixel.rs index 70e817171..b10431309 100644 --- a/examples/rmt_neopixel.rs +++ b/examples/rmt_neopixel.rs @@ -33,7 +33,7 @@ mod example { use anyhow::{bail, Result}; use esp_idf_hal::{ delay::FreeRtos, - prelude::Peripherals, + peripherals::Peripherals, rmt::{config::TransmitConfig, FixedLengthSignal, PinState, Pulse, TxRmtDriver}, }; diff --git a/examples/rmt_transceiver.rs b/examples/rmt_transceiver.rs index b9b6fa87a..033c69b5c 100644 --- a/examples/rmt_transceiver.rs +++ b/examples/rmt_transceiver.rs @@ -39,7 +39,7 @@ fn main() -> anyhow::Result<()> { mod example { use esp_idf_hal::{ delay::FreeRtos, - prelude::Peripherals, + peripherals::Peripherals, rmt::{ FixedLengthSignal, PinState, Pulse, PulseTicks, Receive, RmtReceiveConfig, RmtTransmitConfig, RxRmtDriver, TxRmtDriver, diff --git a/examples/spi_loopback.rs b/examples/spi_loopback.rs index c58c85716..b26ba1d1e 100644 --- a/examples/spi_loopback.rs +++ b/examples/spi_loopback.rs @@ -14,8 +14,8 @@ use esp_idf_hal::delay::FreeRtos; use esp_idf_hal::peripherals::Peripherals; -use esp_idf_hal::prelude::*; use esp_idf_hal::spi::*; +use esp_idf_hal::units::*; fn main() -> anyhow::Result<()> { esp_idf_hal::sys::link_patches(); diff --git a/examples/spi_loopback_async.rs b/examples/spi_loopback_async.rs index f19d94846..a55134437 100644 --- a/examples/spi_loopback_async.rs +++ b/examples/spi_loopback_async.rs @@ -13,9 +13,9 @@ //! Connect SDI and SDO pins to see the outgoing data is read as incoming data. use esp_idf_hal::peripherals::Peripherals; -use esp_idf_hal::prelude::*; use esp_idf_hal::spi::*; use esp_idf_hal::task::*; +use esp_idf_hal::units::*; fn main() -> anyhow::Result<()> { esp_idf_hal::sys::link_patches(); diff --git a/examples/uart_loopback.rs b/examples/uart_loopback.rs index d90f1b694..886d8aaeb 100644 --- a/examples/uart_loopback.rs +++ b/examples/uart_loopback.rs @@ -12,8 +12,8 @@ use esp_idf_hal::delay::BLOCK; use esp_idf_hal::gpio; use esp_idf_hal::peripherals::Peripherals; -use esp_idf_hal::prelude::*; use esp_idf_hal::uart::*; +use esp_idf_hal::units::*; fn main() -> anyhow::Result<()> { esp_idf_hal::sys::link_patches(); diff --git a/examples/uart_loopback_async.rs b/examples/uart_loopback_async.rs index a012370da..4cc975b46 100644 --- a/examples/uart_loopback_async.rs +++ b/examples/uart_loopback_async.rs @@ -11,9 +11,9 @@ use esp_idf_hal::gpio; use esp_idf_hal::peripherals::Peripherals; -use esp_idf_hal::prelude::*; use esp_idf_hal::task::*; use esp_idf_hal::uart::*; +use esp_idf_hal::units::*; fn main() -> anyhow::Result<()> { esp_idf_hal::sys::link_patches(); diff --git a/src/adc.rs b/src/adc.rs index 915aff3b7..652f821ea 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -1,5 +1,7 @@ //! Analog to Digital Converter peripheral control. +use core::marker::PhantomData; + use esp_idf_sys::*; #[cfg(all( @@ -20,10 +22,82 @@ pub use continuous::{ ))] pub use oneshot_legacy::*; -pub trait Adc: Send { +/// A trait designating the ADC Unit +/// +/// An associated type provided by ADC peripherals +pub trait AdcUnit: 'static { + /// Return the ESP-IDF ADC unit identifier. fn unit() -> adc_unit_t; } +macro_rules! impl_adcu { + ($adcu:ident: $unit:expr) => { + pub struct $adcu; + + impl AdcUnit for $adcu { + fn unit() -> adc_unit_t { + $unit + } + } + }; +} + +impl_adcu!(ADCU1: adc_unit_t_ADC_UNIT_1); +#[cfg(any(esp32, esp32s2, esp32s3, esp32c3))] +impl_adcu!(ADCU2: adc_unit_t_ADC_UNIT_2); + +/// A trait designating the ADC channel +/// +/// An associated type provided by ADC pins +pub trait AdcChannel: 'static { + /// The ADC unit this channel is associated with. + type AdcUnit: AdcUnit; + + /// Return the ESP-IDF ADC unit identifier. + fn unit() -> adc_unit_t { + Self::AdcUnit::unit() + } + + /// Return the ESP-IDF ADC channel identifier. + fn channel() -> adc_channel_t; +} + +macro_rules! impl_adcch { + ($adcch:ident: $unit:expr) => { + pub struct $adcch(PhantomData); + + impl AdcChannel for $adcch { + type AdcUnit = U; + + fn channel() -> adc_channel_t { + $unit + } + } + }; +} + +impl_adcch!(ADCCH0: adc_channel_t_ADC_CHANNEL_0); +impl_adcch!(ADCCH1: adc_channel_t_ADC_CHANNEL_1); +impl_adcch!(ADCCH2: adc_channel_t_ADC_CHANNEL_2); +impl_adcch!(ADCCH3: adc_channel_t_ADC_CHANNEL_3); +impl_adcch!(ADCCH4: adc_channel_t_ADC_CHANNEL_4); +impl_adcch!(ADCCH5: adc_channel_t_ADC_CHANNEL_5); +impl_adcch!(ADCCH6: adc_channel_t_ADC_CHANNEL_6); +impl_adcch!(ADCCH7: adc_channel_t_ADC_CHANNEL_7); +impl_adcch!(ADCCH8: adc_channel_t_ADC_CHANNEL_8); +impl_adcch!(ADCCH9: adc_channel_t_ADC_CHANNEL_9); + +/// A trait for ADC peripherals +pub trait Adc: Send { + /// The ADC unit this peripheral is associated with. + type AdcUnit: AdcUnit; + + /// Return the ESP-IDF ADC unit identifier. + fn unit() -> adc_unit_t { + Self::AdcUnit::unit() + } +} + // NOTE: Will be changed to an enum once C-style enums are usable as const generics pub mod attenuation { pub use esp_idf_sys::{ @@ -125,11 +199,14 @@ impl From for adc_bits_width_t { esp_idf_version_major = "4" ))] mod oneshot_legacy { + use core::marker::PhantomData; + use esp_idf_sys::*; - use crate::gpio::ADCPin; - - use crate::peripheral::{Peripheral, PeripheralRef}; + use crate::{ + adc::{AdcChannel, AdcUnit}, + gpio::ADCPin, + }; use super::{to_nb_err, Adc, DirectConverter}; @@ -166,48 +243,48 @@ mod oneshot_legacy { } } - pub struct AdcChannelDriver<'d, const A: adc_atten_t, T: ADCPin> { - pin: PeripheralRef<'d, T>, + pub struct AdcChannelDriver<'d, const A: adc_atten_t, C: AdcChannel> { + _channel: PhantomData, + _t: PhantomData<&'d mut ()>, } - impl<'d, const A: adc_atten_t, T: ADCPin> AdcChannelDriver<'d, A, T> { - pub fn new(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); - + impl<'d, const A: adc_atten_t, C: AdcChannel> AdcChannelDriver<'d, A, C> + where + C: AdcChannel, + { + pub fn new(pin: impl ADCPin + 'd) -> Result { unsafe { - crate::gpio::rtc_reset_pin(pin.pin())?; + crate::gpio::rtc_reset_pin(pin.pin() as _)?; } - if T::Adc::unit() == adc_unit_t_ADC_UNIT_1 { - esp!(unsafe { adc1_config_channel_atten(pin.adc_channel(), A) })?; + if C::unit() == adc_unit_t_ADC_UNIT_1 { + esp!(unsafe { adc1_config_channel_atten(C::channel(), A) })?; } else { #[cfg(not(any(esp32c2, esp32h2, esp32c5, esp32c6, esp32p4)))] - esp!(unsafe { adc2_config_channel_atten(pin.adc_channel(), A) })?; + esp!(unsafe { adc2_config_channel_atten(C::channel(), A) })?; #[cfg(any(esp32c2, esp32h2, esp32c5, esp32c6, esp32p4))] unreachable!(); } - Ok(Self { pin }) - } - - fn pin(&mut self) -> &mut PeripheralRef<'d, T> { - &mut self.pin + Ok(Self { + _channel: PhantomData, + _t: PhantomData, + }) } } - impl embedded_hal_0_2::adc::Channel - for AdcChannelDriver<'_, A, T> + impl embedded_hal_0_2::adc::Channel + for AdcChannelDriver<'_, A, C> { type ID = (adc_channel_t, adc_atten_t); fn channel() -> Self::ID { - (T::CHANNEL, A) + (C::channel(), A) } } - pub struct AdcDriver<'d, ADC: Adc> { - _adc: PeripheralRef<'d, ADC>, + pub struct AdcDriver<'d, ADCU: AdcUnit> { #[allow(dead_code)] resolution: config::Resolution, #[cfg(all( @@ -217,11 +294,13 @@ mod oneshot_legacy { cal_characteristics: Option< [Option; adc_atten_t_ADC_ATTEN_DB_11 as usize + 1], >, + _unit: PhantomData, + _t: PhantomData<&'d mut ()>, } - unsafe impl Send for AdcDriver<'_, ADC> {} + unsafe impl Send for AdcDriver<'_, ADCU> {} - impl<'d, ADC: Adc> AdcDriver<'d, ADC> { + impl<'d, ADCU: AdcUnit> AdcDriver<'d, ADCU> { #[cfg(all( esp32, any(esp_idf_comp_esp_adc_cal_enabled, esp_idf_comp_esp_adc_enabled) @@ -243,12 +322,10 @@ mod oneshot_legacy { const CALIBRATION_SCHEME: esp_adc_cal_value_t = esp_adc_cal_value_t_ESP_ADC_CAL_VAL_EFUSE_TP_FIT; - pub fn new( - adc: impl Peripheral

+ 'd, + pub fn new + 'd>( + _adc: ADC, config: &config::Config, ) -> Result { - crate::into_ref!(adc); - #[cfg(all( any(esp32, esp32s2, esp32s3, esp32c3), any(esp_idf_comp_esp_adc_cal_enabled, esp_idf_comp_esp_adc_enabled) @@ -262,7 +339,6 @@ mod oneshot_legacy { } Ok(Self { - _adc: adc, resolution: config.resolution, #[cfg(all( any(esp32, esp32s2, esp32s3, esp32c3), @@ -273,46 +349,25 @@ mod oneshot_legacy { } else { None }, + _unit: PhantomData, + _t: PhantomData, }) } #[inline(always)] - pub fn read( + pub fn read>( &mut self, - pin: &mut AdcChannelDriver<'_, A, T>, - ) -> Result - where - T: ADCPin, - { - self.read_internal(ADC::unit(), pin.pin().adc_channel(), A) - } - - #[inline(always)] - pub fn read_raw( - &mut self, - pin: &mut AdcChannelDriver<'_, A, T>, - ) -> Result - where - T: ADCPin, - { - self.read_internal_raw(ADC::unit(), pin.pin().adc_channel()) - } - - #[inline(always)] - #[cfg(all(esp32, esp_idf_version_major = "4"))] - pub fn read_hall( - &mut self, - hall_sensor: &mut crate::hall::HallSensor, + _pin: &mut AdcChannelDriver<'_, A, C>, ) -> Result { - let measurement = self.read_hall_raw(hall_sensor); - - self.raw_to_voltage(measurement, adc_atten_t_ADC_ATTEN_DB_0) + self.read_internal(C::unit(), C::channel(), A) } #[inline(always)] - #[cfg(all(esp32, esp_idf_version_major = "4"))] - pub fn read_hall_raw(&mut self, _hall_sensor: &mut crate::hall::HallSensor) -> u16 { - unsafe { hall_sensor_read() as u16 } + pub fn read_raw>( + &mut self, + _pin: &mut AdcChannelDriver<'_, A, C>, + ) -> Result { + self.read_internal_raw(C::unit(), C::channel()) } #[inline(always)] @@ -392,7 +447,7 @@ mod oneshot_legacy { let mut cal: esp_adc_cal_characteristics_t = Default::default(); unsafe { esp_adc_cal_characterize( - ADC::unit(), + ADCU::unit(), attenuation, self.resolution.into(), 0, @@ -410,33 +465,19 @@ mod oneshot_legacy { } } - impl<'c, const A: adc_atten_t, T> - embedded_hal_0_2::adc::OneShot> - for AdcDriver<'_, T::Adc> + impl<'c, const A: adc_atten_t, C> + embedded_hal_0_2::adc::OneShot> + for AdcDriver<'_, C::AdcUnit> where - T: ADCPin, + C: AdcChannel, { type Error = EspError; - fn read(&mut self, pin: &mut AdcChannelDriver<'c, A, T>) -> nb::Result { - self.read_internal(T::Adc::unit(), pin.pin.adc_channel(), A) + fn read(&mut self, _pin: &mut AdcChannelDriver<'c, A, C>) -> nb::Result { + self.read_internal(C::unit(), C::channel(), A) .map_err(to_nb_err) } } - - #[cfg(all(esp32, esp_idf_version_major = "4"))] - impl embedded_hal_0_2::adc::OneShot - for AdcDriver<'_, super::ADC1> - { - type Error = EspError; - - fn read( - &mut self, - hall_sensor: &mut crate::hall::HallSensor, - ) -> nb::Result { - AdcDriver::read_hall(self, hall_sensor).map_err(to_nb_err) - } - } } fn to_nb_err(err: EspError) -> nb::Error { @@ -448,21 +489,18 @@ fn to_nb_err(err: EspError) -> nb::Error { } macro_rules! impl_adc { - ($adc:ident: $unit:expr) => { + ($adc:ident: $unit:ident) => { crate::impl_peripheral!($adc); - impl Adc for $adc { - #[inline(always)] - fn unit() -> adc_unit_t { - $unit - } + impl Adc for $adc<'_> { + type AdcUnit = $unit; } }; } -impl_adc!(ADC1: adc_unit_t_ADC_UNIT_1); +impl_adc!(ADC1: ADCU1); #[cfg(not(any(esp32c2, esp32h2, esp32c5, esp32c6, esp32p4)))] // TODO: Check for esp32c5 and esp32p4 -impl_adc!(ADC2: adc_unit_t_ADC_UNIT_2); +impl_adc!(ADC2: ADCU2); /// Converts a raw reading to mV without using calibration struct DirectConverter(adc_atten_t); @@ -551,16 +589,17 @@ impl DirectConverter { ))] pub mod oneshot { use core::borrow::Borrow; + use core::marker::PhantomData; use esp_idf_sys::*; + use crate::adc::to_nb_err; + use crate::adc::AdcChannel; use crate::gpio::ADCPin; - use crate::peripheral::Peripheral; - use crate::peripheral::PeripheralRef; use super::attenuation::adc_atten_t; - use super::to_nb_err; use super::Adc; + use super::AdcUnit; use super::DirectConverter; pub mod config { @@ -636,7 +675,7 @@ pub mod oneshot { impl Converter { #[allow(unused_variables)] fn create( - unit_id: u8, + unit: adc_unit_t, chan: adc_channel_t, atten: adc_atten_t, #[cfg(esp_idf_version_at_least_6_0_0)] bitwidth: adc_bitwidth_t, @@ -664,7 +703,7 @@ pub mod oneshot { // ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED // then we wouuld not need the ugliness for the esp32c6 let cal_config = adc_cali_curve_fitting_config_t { - unit_id: unit_id as u32, + unit_id: unit, #[cfg(esp_idf_version_at_least_5_1_1)] chan, atten, @@ -690,7 +729,7 @@ pub mod oneshot { // this as a config option? #[allow(clippy::needless_update)] let cal_config = adc_cali_line_fitting_config_t { - unit_id: unit_id as u32, + unit_id: unit, atten, bitwidth, ..Default::default() @@ -775,30 +814,29 @@ pub mod oneshot { } } - pub struct AdcChannelDriver<'d, T, M> + pub struct AdcChannelDriver<'d, C, M> where - T: ADCPin, - M: Borrow>, + C: AdcChannel, + M: Borrow>, { adc: M, - _pin: PeripheralRef<'d, T>, + _channel: PhantomData, converter: Converter, + _t: PhantomData<&'d mut ()>, } - impl<'d, T, M> AdcChannelDriver<'d, T, M> + impl<'d, C, M> AdcChannelDriver<'d, C, M> where - T: ADCPin, - M: Borrow>, + C: AdcChannel, + M: Borrow>, { pub fn new( adc: M, - pin: impl Peripheral

+ 'd, + pin: impl ADCPin + 'd, config: &config::AdcChannelConfig, ) -> Result { - crate::into_ref!(pin); - unsafe { - crate::gpio::rtc_reset_pin(pin.pin())?; + crate::gpio::rtc_reset_pin(pin.pin() as _)?; } let chan_config = adc_oneshot_chan_cfg_t { @@ -807,8 +845,8 @@ pub mod oneshot { }; let converter = Converter::create( - T::Adc::unit() as u8, - pin.adc_channel(), + C::unit(), + C::channel(), config.attenuation, config.resolution.into(), config.calibration, @@ -817,15 +855,16 @@ pub mod oneshot { unsafe { esp!(adc_oneshot_config_channel( adc.borrow().handle, - pin.adc_channel(), + C::channel(), &chan_config ))? }; Ok(Self { adc, - _pin: pin, + _channel: PhantomData, converter, + _t: PhantomData, }) } @@ -837,7 +876,7 @@ pub mod oneshot { #[inline(always)] pub fn read_raw(&mut self) -> Result { - let channel = T::CHANNEL; + let channel = C::channel(); self.adc.borrow().read_raw_internal(channel) } @@ -847,62 +886,69 @@ pub mod oneshot { } } - impl<'d, T, M> embedded_hal_0_2::adc::Channel for AdcChannelDriver<'d, T, M> + impl<'d, C, M> embedded_hal_0_2::adc::Channel for AdcChannelDriver<'d, C, M> where - T: ADCPin, - M: Borrow>, + C: AdcChannel, + M: Borrow>, { type ID = adc_channel_t; fn channel() -> Self::ID { - T::CHANNEL + C::channel() } } - unsafe impl<'d, T, M> Send for AdcChannelDriver<'d, T, M> + unsafe impl<'d, C, M> Send for AdcChannelDriver<'d, C, M> where - T: ADCPin, - M: Borrow>, + C: AdcChannel, + M: Borrow>, { } - pub struct AdcDriver<'d, ADC: Adc> { + pub struct AdcDriver<'d, U> { handle: adc_oneshot_unit_handle_t, - _adc: PeripheralRef<'d, ADC>, + _unit: PhantomData, + _t: PhantomData<&'d mut ()>, } - impl<'d, ADC: Adc> AdcDriver<'d, ADC> { - pub fn new(adc: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(adc); + impl<'d, U> AdcDriver<'d, U> + where + U: AdcUnit + 'd, + { + pub fn new + 'd>(_adc: ADC) -> Result { let config = adc_oneshot_unit_init_cfg_t { unit_id: ADC::unit(), ..Default::default() }; let mut handle: adc_oneshot_unit_handle_t = core::ptr::null_mut(); unsafe { esp!(adc_oneshot_new_unit(&config, &mut handle))? }; - Ok(Self { handle, _adc: adc }) + Ok(Self { + handle, + _unit: PhantomData, + _t: PhantomData, + }) } #[inline(always)] - pub fn read(&self, channel: &mut AdcChannelDriver<'d, T, M>) -> Result + pub fn read(&self, channel: &mut AdcChannelDriver<'d, C, M>) -> Result where - T: ADCPin, - M: Borrow>, + C: AdcChannel, + M: Borrow>, { let raw = self.read_raw(channel)?; self.raw_to_mv(channel, raw) } #[inline(always)] - pub fn read_raw( + pub fn read_raw( &self, - _channel: &mut AdcChannelDriver<'d, T, M>, + _channel: &mut AdcChannelDriver<'d, C, M>, ) -> Result where - T: ADCPin, - M: Borrow>, + C: AdcChannel, + M: Borrow>, { - self.read_raw_internal(T::CHANNEL) + self.read_raw_internal(C::channel()) } #[inline(always)] @@ -913,40 +959,40 @@ pub mod oneshot { } #[inline(always)] - pub fn raw_to_mv( + pub fn raw_to_mv( &self, - channel: &AdcChannelDriver<'d, T, M>, + channel: &AdcChannelDriver<'d, C, M>, raw: u16, ) -> Result where - T: ADCPin, - M: Borrow>, + C: AdcChannel, + M: Borrow>, { channel.converter.raw_to_mv(raw) } } - impl Drop for AdcDriver<'_, ADC> { + impl Drop for AdcDriver<'_, U> { fn drop(&mut self) { unsafe { esp!(adc_oneshot_del_unit(self.handle)) }.unwrap(); } } - impl<'d, T, M> embedded_hal_0_2::adc::OneShot> - for AdcDriver<'d, T::Adc> + impl<'d, C, M> embedded_hal_0_2::adc::OneShot> + for AdcDriver<'d, C::AdcUnit> where - T: ADCPin, - M: Borrow>, + C: AdcChannel, + M: Borrow>, { type Error = EspError; - fn read(&mut self, pin: &mut AdcChannelDriver<'d, T, M>) -> nb::Result { + fn read(&mut self, pin: &mut AdcChannelDriver<'d, C, M>) -> nb::Result { AdcDriver::read(self, pin).map_err(to_nb_err) } } - unsafe impl Send for AdcDriver<'_, ADC> {} - unsafe impl Sync for AdcDriver<'_, ADC> {} + unsafe impl Send for AdcDriver<'_, U> {} + unsafe impl Sync for AdcDriver<'_, U> {} } /// Continuous ADC module @@ -996,13 +1042,13 @@ pub mod continuous { use esp_idf_sys::*; + use crate::adc::AdcChannel; use crate::delay::{self, TickType}; - use crate::gpio::{sealed::ADCPin as _, ADCPin}; + use crate::gpio::ADCPin; use crate::interrupt::asynch::HalIsrNotification; use crate::io::EspIOError; - use crate::peripheral::Peripheral; - use super::{attenuation, Adc}; + use super::{attenuation, Adc, AdcUnit}; /// Set ADC attenuation level /// Example: let pin = Attenuated::db12(peripherals.pins.gpio0); @@ -1059,7 +1105,8 @@ pub mod continuous { pub type Atten12dB = Attenuated<{ attenuation::DB_12 }, T>; pub trait AdcChannels { - type Adc: Adc; + type AdcUnit: AdcUnit; + type Iterator<'a>: Iterator where Self: 'a; @@ -1069,10 +1116,9 @@ pub mod continuous { impl

AdcChannels for P where - P: Peripheral, - P::P: ADCPin, + P: ADCPin, { - type Adc = <

::P as ADCPin>::Adc; + type AdcUnit = ::AdcUnit; type Iterator<'a> = core::iter::Once<(adc_channel_t, adc_atten_t)> @@ -1080,7 +1126,7 @@ pub mod continuous { Self: 'a; fn iter(&self) -> Self::Iterator<'_> { - core::iter::once((P::P::CHANNEL, attenuation::NONE)) + core::iter::once((P::AdcChannel::channel(), attenuation::NONE)) } } @@ -1088,7 +1134,7 @@ pub mod continuous { where C: AdcChannels, { - type Adc = C::Adc; + type AdcUnit = C::AdcUnit; type Iterator<'a> = core::iter::Map< @@ -1109,7 +1155,7 @@ pub mod continuous { where C: AdcChannels, { - type Adc = C::Adc; + type AdcUnit = C::AdcUnit; type Iterator<'a> = core::iter::FlatMap< @@ -1131,7 +1177,7 @@ pub mod continuous { pub fn chain(other: O) -> ChainedAdcChannels where A: Adc, - O: AdcChannels, + O: AdcChannels, { ChainedAdcChannels { first: Self(PhantomData), @@ -1142,9 +1188,9 @@ pub mod continuous { impl AdcChannels for EmptyAdcChannels where - A: Adc, + A: AdcUnit, { - type Adc = A; + type AdcUnit = A; type Iterator<'a> = core::iter::Empty<(adc_channel_t, adc_atten_t)> @@ -1165,8 +1211,8 @@ pub mod continuous { pub fn chain(self, other: O) -> ChainedAdcChannels where F: AdcChannels, - S: AdcChannels, - O: AdcChannels, + S: AdcChannels, + O: AdcChannels, { ChainedAdcChannels { first: self, @@ -1178,9 +1224,9 @@ pub mod continuous { impl AdcChannels for ChainedAdcChannels where F: AdcChannels, - S: AdcChannels, + S: AdcChannels, { - type Adc = F::Adc; + type AdcUnit = F::AdcUnit; type Iterator<'a> = core::iter::Chain, S::Iterator<'a>> @@ -1350,10 +1396,10 @@ pub mod continuous { /// Initialize ADC continuous driver with configuration and channels. #[cfg(esp32)] pub fn new( - adc: impl Peripheral

+ 'd, - _i2s: impl Peripheral

+ 'd, + adc: super::ADC1<'d>, + _i2s: crate::i2s::I2S0<'d>, config: &config::Config, - channels: impl AdcChannels + 'd, + channels: impl AdcChannels + 'd, ) -> Result { Self::internal_new(adc, config, channels) } @@ -1361,28 +1407,28 @@ pub mod continuous { /// Initialize ADC continuous driver with configuration and channels #[cfg(esp32s2)] pub fn new( - adc: impl Peripheral

+ 'd, - _spi: impl Peripheral

+ 'd, + adc: super::ADC1<'d>, + _spi: crate::spi::SPI3<'d>, config: &config::Config, - channels: impl AdcChannels + 'd, + channels: impl AdcChannels + 'd, ) -> Result { Self::internal_new(adc, config, channels) } /// Initialize ADC continuous driver with configuration and channels. #[cfg(not(any(esp32, esp32s2)))] - pub fn new( - adc: impl Peripheral

+ 'd, + pub fn new( + adc: A, config: &config::Config, - channels: impl AdcChannels + 'd, + channels: impl AdcChannels + 'd, ) -> Result { Self::internal_new(adc, config, channels) } - fn internal_new( - _adc: impl Peripheral

+ 'd, + fn internal_new( + _adc: A, config: &config::Config, - channels: impl AdcChannels + 'd, + channels: impl AdcChannels + 'd, ) -> Result { let mut patterns = [adc_digi_pattern_config_t::default(); 32]; diff --git a/src/can.rs b/src/can.rs index 61e2bf9d1..5c105c297 100644 --- a/src/can.rs +++ b/src/can.rs @@ -44,7 +44,6 @@ use esp_idf_sys::*; use crate::cpu::Core; use crate::delay::{self, BLOCK, NON_BLOCK}; use crate::interrupt::InterruptType; -use crate::peripheral::{Peripheral, PeripheralRef}; use crate::task::asynch::Notification; use crate::{gpio::*, task}; @@ -384,22 +383,20 @@ pub enum Alert { } /// CAN abstraction -pub struct CanDriver<'d>(PeripheralRef<'d, CAN>, EnumSet, bool); +pub struct CanDriver<'d>(PhantomData<&'d mut ()>, EnumSet, bool); impl<'d> CanDriver<'d> { pub fn new( - can: impl Peripheral

+ 'd, - tx: impl Peripheral

+ 'd, - rx: impl Peripheral

+ 'd, + _can: CAN<'d>, + tx: impl OutputPin + 'd, + rx: impl InputPin + 'd, config: &config::Config, ) -> Result { - crate::into_ref!(can, tx, rx); - #[allow(clippy::needless_update)] let general_config = twai_general_config_t { mode: config.mode.into(), - tx_io: tx.pin(), - rx_io: rx.pin(), + tx_io: tx.pin() as _, + rx_io: rx.pin() as _, clkout_io: -1, bus_off_io: -1, tx_queue_len: config.tx_queue_len, @@ -438,7 +435,7 @@ impl<'d> CanDriver<'d> { esp!(unsafe { twai_driver_install(&general_config, &timing_config, &filter_config) })?; - Ok(Self(can, config.alerts, config.tx_queue_len > 0)) + Ok(Self(PhantomData, config.alerts, config.tx_queue_len > 0)) } pub fn start(&mut self) -> Result<(), EspError> { @@ -571,9 +568,9 @@ where impl<'d> AsyncCanDriver<'d, CanDriver<'d>> { pub fn new( - can: impl Peripheral

+ 'd, - tx: impl Peripheral

+ 'd, - rx: impl Peripheral

+ 'd, + can: CAN<'d>, + tx: impl OutputPin + 'd, + rx: impl InputPin + 'd, config: &config::Config, ) -> Result { Self::wrap(CanDriver::new(can, tx, rx, config)?) diff --git a/src/gpio.rs b/src/gpio.rs index 9830206a5..aa0a9f379 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -7,61 +7,55 @@ extern crate alloc; use esp_idf_sys::*; -use crate::adc::Adc; -use crate::peripheral::{Peripheral, PeripheralRef}; +use crate::adc::AdcChannel; pub use chip::*; +pub type PinId = u8; + /// A trait implemented by every pin instance -pub trait Pin: Peripheral

+ Sized + Send + 'static { - fn pin(&self) -> i32; +pub trait Pin: Sized + Send { + /// Return the pin ID + fn pin(&self) -> PinId; } /// A marker trait designating a pin which is capable of /// operating as an input pin -pub trait InputPin: Pin + Into { - fn downgrade_input(self) -> AnyInputPin { - self.into() - } -} +pub trait InputPin: Pin {} /// A marker trait designating a pin which is capable of /// operating as an output pin -pub trait OutputPin: Pin + Into { - fn downgrade_output(self) -> AnyOutputPin { - self.into() - } -} - -/// A marker trait designating a pin which is capable of -/// operating as an input and output pin -pub trait IOPin: InputPin + OutputPin + Into { - fn downgrade(self) -> AnyIOPin { - self.into() - } -} +pub trait OutputPin: Pin {} /// A marker trait designating a pin which is capable of /// operating as an RTC pin pub trait RTCPin: Pin { - fn rtc_pin(&self) -> i32; -} - -pub(crate) mod sealed { - pub trait ADCPin { - // NOTE: Will likely disappear in subsequent versions, - // once ADC support pops up in e-hal1. Hence sealed - const CHANNEL: super::adc_channel_t; - } + /// Return the RTC pin ID + fn rtc_pin(&self) -> PinId; } /// A marker trait designating a pin which is capable of /// operating as an ADC pin -pub trait ADCPin: sealed::ADCPin + Pin { - type Adc: Adc; +pub trait ADCPin: Pin { + /// Return the ADC channel for this pin + type AdcChannel: AdcChannel; +} - fn adc_channel(&self) -> adc_channel_t { - Self::CHANNEL +/// A marker trait designating a pin which is capable of +/// operating as a DAC pin +#[cfg(any(esp32, esp32s2))] +pub trait DacChannel: 'static { + /// Return the DAC channel for this pin + fn dac_channel(&self) -> dac_channel_t; +} + +#[cfg(any(esp32, esp32s2))] +pub struct DACCH; + +#[cfg(any(esp32, esp32s2))] +impl DacChannel for DACCH { + fn dac_channel(&self) -> dac_channel_t { + N } } @@ -69,135 +63,114 @@ pub trait ADCPin: sealed::ADCPin + Pin { /// operating as a DAC pin #[cfg(any(esp32, esp32s2))] pub trait DACPin: Pin { - fn dac_channel(&self) -> dac_channel_t; + /// Return the DAC channel for this pin + type DacChannel: DacChannel; +} + +/// A marker trait designating a pin which is capable of +/// operating as a touch pin +#[cfg(any(esp32, esp32s2, esp32s3))] +pub trait TouchChannel: 'static { + /// Return the touch channel for this pin + fn touch_channel(&self) -> touch_pad_t; +} + +#[cfg(any(esp32, esp32s2, esp32s3))] +pub struct TOUCHCH; + +#[cfg(any(esp32, esp32s2, esp32s3))] +impl TouchChannel for TOUCHCH { + fn touch_channel(&self) -> touch_pad_t { + N + } } /// A marker trait designating a pin which is capable of /// operating as a touch pin #[cfg(any(esp32, esp32s2, esp32s3))] pub trait TouchPin: Pin { - fn touch_channel(&self) -> touch_pad_t; + /// Return the touch channel for this pin + type TouchChannel: TouchChannel; } -/// Generic Gpio input-output pin -pub struct AnyIOPin { - pin: i32, - _p: PhantomData<*const ()>, -} - -impl AnyIOPin { - /// # Safety - /// - /// Care should be taken not to instantiate this Pin, if it is - /// already instantiated and used elsewhere, or if it is not set - /// already in the mode of operation which is being instantiated - pub unsafe fn new(pin: i32) -> Self { - Self { - pin, - _p: PhantomData, +#[allow(unused_macros)] +macro_rules! impl_any { + ($name:ident) => { + pub struct $name<'a> { + pin: PinId, + _t: ::core::marker::PhantomData<&'a mut ()>, } - } - /// Creates an `Option::None` for pins that are - /// optional in APIs. - pub const fn none() -> Option { - None - } -} + impl $name<'_> { + /// Unsafely create an instance of this peripheral out of thin air. + /// + /// # Safety + /// + /// You must ensure that you're only using one instance of this type at a time. + #[inline(always)] + pub unsafe fn steal(pin: PinId) -> Self { + Self { + pin, + _t: ::core::marker::PhantomData, + } + } -crate::impl_peripheral_trait!(AnyIOPin); + /// Creates a new peripheral reference with a shorter lifetime. + /// + /// Use this method if you would like to keep working with the peripheral after + /// you dropped the driver that consumes this. + /// + /// # Safety + /// + /// You must ensure that you are not using reborrowed peripherals in drivers which are + /// forgotten via `core::mem::forget`. + #[inline] + #[allow(dead_code)] + pub unsafe fn reborrow(&mut self) -> $name<'_> { + $name { + pin: self.pin, + _t: ::core::marker::PhantomData, + } + } -impl Pin for AnyIOPin { - fn pin(&self) -> i32 { - self.pin - } -} - -impl InputPin for AnyIOPin {} -impl OutputPin for AnyIOPin {} -impl IOPin for AnyIOPin {} - -/// Generic Gpio input pin -pub struct AnyInputPin { - pin: i32, - _p: PhantomData<*const ()>, -} - -impl AnyInputPin { - /// # Safety - /// - /// Care should be taken not to instantiate this Pin, if it is - /// already instantiated and used elsewhere, or if it is not set - /// already in the mode of operation which is being instantiated - pub unsafe fn new(pin: i32) -> Self { - Self { - pin, - _p: PhantomData, + /// Return `Option::None` for an unconfigured instance of that pin + pub const fn none() -> Option { + None + } } - } - /// Creates an `Option::None` for pins that are - /// optional in APIs. - pub const fn none() -> Option { - None - } -} + unsafe impl Send for $name<'_> {} -crate::impl_peripheral_trait!(AnyInputPin); - -impl Pin for AnyInputPin { - fn pin(&self) -> i32 { - self.pin - } -} - -impl InputPin for AnyInputPin {} - -impl From for AnyInputPin { - fn from(pin: AnyIOPin) -> Self { - unsafe { Self::new(pin.pin()) } - } -} - -/// Generic Gpio output pin -pub struct AnyOutputPin { - pin: i32, - _p: PhantomData<*const ()>, -} - -impl AnyOutputPin { - /// # Safety - /// - /// Care should be taken not to instantiate this Pin, if it is - /// already instantiated and used elsewhere, or if it is not set - /// already in the mode of operation which is being instantiated - pub unsafe fn new(pin: i32) -> Self { - Self { - pin, - _p: PhantomData, + impl Pin for $name<'_> { + fn pin(&self) -> PinId { + self.pin as _ + } } - } + }; +} - /// Creates an `Option::None` for pins that are - /// optional in APIs. - pub const fn none() -> Option { - None +impl_any!(AnyIOPin); + +impl InputPin for AnyIOPin<'_> {} +impl OutputPin for AnyIOPin<'_> {} + +impl_any!(AnyInputPin); + +impl InputPin for AnyInputPin<'_> {} + +impl<'a> From> for AnyInputPin<'a> { + fn from(pin: AnyIOPin<'a>) -> Self { + unsafe { Self::steal(pin.pin()) } } } -crate::impl_peripheral_trait!(AnyOutputPin); +impl_any!(AnyOutputPin); -impl Pin for AnyOutputPin { - fn pin(&self) -> i32 { - self.pin - } -} +impl OutputPin for AnyOutputPin<'_> {} -impl OutputPin for AnyOutputPin {} - -impl From for AnyOutputPin { - fn from(pin: AnyIOPin) -> Self { - unsafe { Self::new(pin.pin()) } +impl<'a> From> for AnyOutputPin<'a> { + fn from(pin: AnyIOPin<'a>) -> Self { + unsafe { Self::steal(pin.pin()) } } } @@ -382,15 +355,17 @@ pub struct RtcOutput; #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] pub struct RtcInputOutput; +impl GPIOMode for Disabled {} + +impl GPIOMode for Input {} + impl InputMode for Input { const RTC: bool = false; } -impl InputMode for InputOutput { - const RTC: bool = false; -} +impl GPIOMode for InputOutput {} -impl OutputMode for Output { +impl InputMode for InputOutput { const RTC: bool = false; } @@ -398,29 +373,10 @@ impl OutputMode for InputOutput { const RTC: bool = false; } -impl GPIOMode for Disabled {} -impl GPIOMode for Input {} -impl GPIOMode for InputOutput {} impl GPIOMode for Output {} -#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] -impl InputMode for RtcInput { - const RTC: bool = true; -} - -#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] -impl InputMode for RtcInputOutput { - const RTC: bool = true; -} - -#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] -impl OutputMode for RtcOutput { - const RTC: bool = true; -} - -#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] -impl OutputMode for RtcInputOutput { - const RTC: bool = true; +impl OutputMode for Output { + const RTC: bool = false; } #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] @@ -429,12 +385,32 @@ impl RTCMode for RtcDisabled {} #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] impl RTCMode for RtcInput {} +#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] +impl InputMode for RtcInput { + const RTC: bool = true; +} + #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] impl RTCMode for RtcInputOutput {} +#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] +impl InputMode for RtcInputOutput { + const RTC: bool = true; +} + +#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] +impl OutputMode for RtcInputOutput { + const RTC: bool = true; +} + #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] impl RTCMode for RtcOutput {} +#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] +impl OutputMode for RtcOutput { + const RTC: bool = true; +} + /// A driver for a GPIO pin. /// /// The driver can set the pin as a disconnected/disabled one, input, or output pin, or both or analog. @@ -443,354 +419,283 @@ impl RTCMode for RtcOutput {} /// /// The mode-setting depends on the capabilities of the pin as well, i.e. input-only pins cannot be set /// into output or input-output mode. -pub struct PinDriver<'d, T: Pin, MODE> { - pin: PeripheralRef<'d, T>, +pub struct PinDriver<'d, MODE> { + pin: PinId, _mode: PhantomData, + _t: PhantomData<&'d mut ()>, } -impl<'d, T: Pin> PinDriver<'d, T, Disabled> { - /// Creates the driver for a pin in disabled state. +impl<'d, MODE> PinDriver<'d, MODE> { + /// Try to convert the pin driver into a disabled pin driver. + /// + /// Return an error if the pin cannot be disabled. #[inline] - pub fn disabled(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); + pub fn try_into_disabled(self) -> Result, EspError> { + PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_DISABLE) + } - Self { - pin, - _mode: PhantomData, - } - .into_disabled() + /// Try to convert the pin driver into an input pin driver. + /// + /// Return an error if the pin cannot be set as input. + #[inline] + pub fn try_into_input(self, pull: Pull) -> Result, EspError> { + let mut pin = PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_INPUT)?; + + pin.set_pull(pull)?; + + Ok(pin) + } + + /// Try to convert the pin driver into an output pin driver. + /// + /// Return an error if the pin cannot be set as output. + #[inline] + pub fn try_into_output(self) -> Result, EspError> { + PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_OUTPUT) + } + + /// Try to convert the pin driver into an input-output pin driver. + /// + /// Return an error if the pin cannot be set as input-output. + #[inline] + pub fn try_into_input_output(self, pull: Pull) -> Result, EspError> { + let mut pin = PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_INPUT_OUTPUT)?; + + pin.set_pull(pull)?; + + Ok(pin) + } + + /// Try to convert the pin driver into an output open-drain pin driver. + /// + /// Return an error if the pin cannot be set as output open-drain. + #[inline] + pub fn try_into_output_od(self) -> Result, EspError> { + PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_OUTPUT_OD) + } + + /// Try to convert the pin driver into an input-output open-drain pin driver. + /// + /// Return an error if the pin cannot be set as input-output open-drain. + #[inline] + pub fn try_into_input_output_od( + self, + pull: Pull, + ) -> Result, EspError> { + let mut pin = PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD)?; + + pin.set_pull(pull)?; + + Ok(pin) + } + + /// Try to convert the pin driver into an RTC disabled pin driver. + /// + /// Return an error if the pin cannot be disabled. + #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] + #[inline] + pub fn try_into_rtc_disabled(self) -> Result, EspError> { + PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_DISABLED) + } + + /// Try to convert the pin driver into an RTC input pin driver. + /// + /// Return an error if the pin cannot be set as RTC input. + #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] + #[inline] + pub fn try_into_rtc_input(self, pull: Pull) -> Result, EspError> { + let mut pin = PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_ONLY)?; + + pin.set_pull(pull)?; + + Ok(pin) + } + + /// Try to convert the pin driver into an RTC output pin driver. + /// + /// Return an error if the pin cannot be set as RTC output. + #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] + #[inline] + pub fn try_into_rtc_output(self) -> Result, EspError> { + PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_OUTPUT_ONLY) + } + + /// Try to convert the pin driver into an RTC output open-drain pin driver. + /// + /// Return an error if the pin cannot be set as RTC output open-drain. + #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] + #[inline] + pub fn try_into_rtc_output_od(self) -> Result, EspError> { + PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_OUTPUT_OD) + } + + /// Try to convert the pin driver into an RTC input-output pin driver. + /// + /// Return an error if the pin cannot be set as RTC input-output. + #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] + #[inline] + pub fn try_into_rtc_input_output( + self, + pull: Pull, + ) -> Result, EspError> { + let mut pin = + PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_OUTPUT)?; + + pin.set_pull(pull)?; + + Ok(pin) + } + + /// Try to convert the pin driver into an RTC input-output open-drain pin driver. + /// + /// Return an error if the pin cannot be set as RTC input-output open-drain. + #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] + #[inline] + pub fn try_into_rtc_input_output_od( + self, + pull: Pull, + ) -> Result, EspError> { + let mut pin = + PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_OUTPUT_OD)?; + + pin.set_pull(pull)?; + + Ok(pin) } } -impl<'d, T: InputPin> PinDriver<'d, T, Input> { +impl<'d> PinDriver<'d, Disabled> { + /// Creates the driver for a pin in disabled state. + #[inline] + pub fn disabled(pin: T) -> Result { + Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_DISABLE) + } +} + +impl<'d> PinDriver<'d, Input> { /// Creates the driver for a pin in input state. #[inline] - pub fn input(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); + pub fn input(pin: T, pull: Pull) -> Result { + let mut pin = Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_INPUT)?; - Self { - pin, - _mode: PhantomData, - } - .into_input() + pin.set_pull(pull)?; + + Ok(pin) } } -impl<'d, T: InputPin + OutputPin> PinDriver<'d, T, InputOutput> { +impl<'d> PinDriver<'d, InputOutput> { /// Creates the driver for a pin in input-output state. #[inline] - pub fn input_output(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); + pub fn input_output( + pin: T, + pull: Pull, + ) -> Result { + let mut pin = Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_INPUT_OUTPUT)?; - Self { - pin, - _mode: PhantomData, - } - .into_input_output() + pin.set_pull(pull)?; + + Ok(pin) } -} -impl<'d, T: InputPin + OutputPin> PinDriver<'d, T, InputOutput> { /// Creates the driver for a pin in input-output open-drain state. #[inline] - pub fn input_output_od(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); + pub fn input_output_od( + pin: T, + pull: Pull, + ) -> Result { + let mut pin = Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD)?; - Self { - pin, - _mode: PhantomData, - } - .into_input_output_od() + pin.set_pull(pull)?; + + Ok(pin) } } -impl<'d, T: OutputPin> PinDriver<'d, T, Output> { +impl<'d> PinDriver<'d, Output> { /// Creates the driver for a pin in output state. #[inline] - pub fn output(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); - - Self { - pin, - _mode: PhantomData, - } - .into_output() + pub fn output(pin: T) -> Result { + Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_OUTPUT) } -} -impl<'d, T: OutputPin> PinDriver<'d, T, Output> { /// Creates the driver for a pin in output open-drain state. #[inline] - pub fn output_od(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); - - Self { - pin, - _mode: PhantomData, - } - .into_output_od() + pub fn output_od(pin: T) -> Result { + Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_OUTPUT_OD) } } #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] -impl<'d, T: Pin + RTCPin> PinDriver<'d, T, RtcDisabled> { +impl<'d> PinDriver<'d, RtcDisabled> { /// Creates the driver for a pin in disabled state. #[inline] - pub fn rtc_disabled(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); - - Self { - pin, - _mode: PhantomData, - } - .into_rtc_disabled() + pub fn rtc_disabled(pin: T) -> Result { + Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_DISABLED) } } #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] -impl<'d, T: InputPin + RTCPin> PinDriver<'d, T, RtcInput> { +impl<'d> PinDriver<'d, RtcInput> { /// Creates the driver for a pin in RTC input state. #[inline] - pub fn rtc_input(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); + pub fn rtc_input(pin: T, pull: Pull) -> Result { + let mut pin = Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_ONLY)?; - Self { - pin, - _mode: PhantomData, - } - .into_rtc_input() + pin.set_pull(pull)?; + + Ok(pin) } } #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] -impl<'d, T: InputPin + OutputPin + RTCPin> PinDriver<'d, T, RtcInputOutput> { +impl<'d> PinDriver<'d, RtcInputOutput> { /// Creates the driver for a pin in RTC input-output state. #[inline] - pub fn rtc_input_output(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); + pub fn rtc_input_output( + pin: T, + pull: Pull, + ) -> Result { + let mut pin = Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_OUTPUT)?; - Self { - pin, - _mode: PhantomData, - } - .into_rtc_input_output() + pin.set_pull(pull)?; + + Ok(pin) } -} -#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] -impl<'d, T: InputPin + OutputPin + RTCPin> PinDriver<'d, T, RtcInputOutput> { /// Creates the driver for a pin in RTC input-output open-drain state. #[inline] - pub fn rtc_input_output_od(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); + pub fn rtc_input_output_od( + pin: T, + pull: Pull, + ) -> Result { + let mut pin = Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_OUTPUT_OD)?; - Self { - pin, - _mode: PhantomData, - } - .into_rtc_input_output_od() + pin.set_pull(pull)?; + + Ok(pin) } } #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] -impl<'d, T: OutputPin + RTCPin> PinDriver<'d, T, RtcOutput> { +impl<'d> PinDriver<'d, RtcOutput> { /// Creates the driver for a pin in RTC output state. #[inline] - pub fn rtc_output(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); - - Self { - pin, - _mode: PhantomData, - } - .into_rtc_output() + pub fn rtc_output(pin: T) -> Result { + Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_OUTPUT_ONLY) } -} -#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] -impl<'d, T: OutputPin + RTCPin> PinDriver<'d, T, RtcOutput> { /// Creates the driver for a pin in RTC output open-drain state. #[inline] - pub fn rtc_output_od(pin: impl Peripheral

+ 'd) -> Result { - crate::into_ref!(pin); - - Self { - pin, - _mode: PhantomData, - } - .into_rtc_output_od() + pub fn rtc_output_od(pin: T) -> Result { + Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_OUTPUT_OD) } } -impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { +impl<'d, MODE> PinDriver<'d, MODE> { /// Returns the pin number. - pub fn pin(&self) -> i32 { - self.pin.pin() - } - - /// Put the pin into disabled mode. - pub fn into_disabled(self) -> Result, EspError> { - self.into_mode(gpio_mode_t_GPIO_MODE_DISABLE) - } - - /// Put the pin into input mode. - #[inline] - pub fn into_input(self) -> Result, EspError> - where - T: InputPin, - { - self.into_mode(gpio_mode_t_GPIO_MODE_INPUT) - } - - /// Put the pin into input + output mode. - #[inline] - pub fn into_input_output(self) -> Result, EspError> - where - T: InputPin + OutputPin, - { - self.into_mode(gpio_mode_t_GPIO_MODE_INPUT_OUTPUT) - } - - /// Put the pin into input + output Open Drain mode. - /// - /// This is commonly used for "open drain" mode. - /// the hardware will drive the line low if you set it to low, and will leave it floating if you set - /// it to high, in which case you can read the input to figure out whether another device - /// is driving the line low. - #[inline] - pub fn into_input_output_od(self) -> Result, EspError> - where - T: InputPin + OutputPin, - { - self.into_mode(gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD) - } - - /// Put the pin into output mode. - #[inline] - pub fn into_output(self) -> Result, EspError> - where - T: OutputPin, - { - self.into_mode(gpio_mode_t_GPIO_MODE_OUTPUT) - } - - /// Put the pin into output Open Drain mode. - #[inline] - pub fn into_output_od(self) -> Result, EspError> - where - T: OutputPin, - { - self.into_mode(gpio_mode_t_GPIO_MODE_OUTPUT_OD) - } - - /// Put the pin into RTC disabled mode. - #[inline] - #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - pub fn into_rtc_disabled(self) -> Result, EspError> - where - T: RTCPin, - { - self.into_rtc_mode(rtc_gpio_mode_t_RTC_GPIO_MODE_DISABLED) - } - - /// Put the pin into RTC input mode. - #[inline] - #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - pub fn into_rtc_input(self) -> Result, EspError> - where - T: InputPin + RTCPin, - { - self.into_rtc_mode(rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_ONLY) - } - - /// Put the pin into RTC input + output mode. - /// - /// This is commonly used for "open drain" mode. - /// the hardware will drive the line low if you set it to low, and will leave it floating if you set - /// it to high, in which case you can read the input to figure out whether another device - /// is driving the line low. - #[inline] - #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - pub fn into_rtc_input_output(self) -> Result, EspError> - where - T: InputPin + OutputPin + RTCPin, - { - self.into_rtc_mode(rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_OUTPUT) - } - - /// Put the pin into RTC input + output Open Drain mode. - /// - /// This is commonly used for "open drain" mode. - /// the hardware will drive the line low if you set it to low, and will leave it floating if you set - /// it to high, in which case you can read the input to figure out whether another device - /// is driving the line low. - #[inline] - #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - pub fn into_rtc_input_output_od(self) -> Result, EspError> - where - T: InputPin + OutputPin + RTCPin, - { - self.into_rtc_mode(rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_OUTPUT_OD) - } - - /// Put the pin into RTC output mode. - #[inline] - #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - pub fn into_rtc_output(self) -> Result, EspError> - where - T: OutputPin + RTCPin, - { - self.into_rtc_mode(rtc_gpio_mode_t_RTC_GPIO_MODE_OUTPUT_ONLY) - } - - /// Put the pin into RTC output Open Drain mode. - #[inline] - #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - pub fn into_rtc_output_od(self) -> Result, EspError> - where - T: OutputPin + RTCPin, - { - self.into_rtc_mode(rtc_gpio_mode_t_RTC_GPIO_MODE_OUTPUT_OD) - } - - #[inline] - fn into_mode(mut self, mode: gpio_mode_t) -> Result, EspError> - where - T: Pin, - { - let pin = unsafe { self.pin.clone_unchecked() }; - drop(self); - - if mode != gpio_mode_t_GPIO_MODE_DISABLE { - esp!(unsafe { gpio_set_direction(pin.pin(), mode) })?; - } - - Ok(PinDriver { - pin, - _mode: PhantomData, - }) - } - - #[inline] - #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - fn into_rtc_mode(mut self, mode: rtc_gpio_mode_t) -> Result, EspError> - where - T: RTCPin, - { - let pin = unsafe { self.pin.clone_unchecked() }; - - drop(self); - - #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - { - esp!(unsafe { rtc_gpio_init(pin.pin()) })?; - esp!(unsafe { rtc_gpio_set_direction(pin.pin(), mode) })?; - } - - Ok(PinDriver { - pin, - _mode: PhantomData, - }) + pub fn pin(&self) -> PinId { + self.pin } #[inline] @@ -802,12 +707,12 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { if MODE::RTC { #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - esp!(unsafe { rtc_gpio_get_drive_capability(self.pin.pin(), &mut cap) })?; + esp!(unsafe { rtc_gpio_get_drive_capability(self.pin as _, &mut cap) })?; #[cfg(any(esp32c3, esp32c2, esp32h2, esp32c5))] unreachable!(); } else { - esp!(unsafe { gpio_get_drive_capability(self.pin.pin(), &mut cap) })?; + esp!(unsafe { gpio_get_drive_capability(self.pin as _, &mut cap) })?; } Ok(cap.into()) @@ -820,12 +725,12 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { { if MODE::RTC { #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - esp!(unsafe { rtc_gpio_set_drive_capability(self.pin.pin(), strength.into()) })?; + esp!(unsafe { rtc_gpio_set_drive_capability(self.pin as _, strength.into()) })?; #[cfg(any(esp32c3, esp32c2, esp32h2, esp32c5))] unreachable!(); } else { - esp!(unsafe { gpio_set_drive_capability(self.pin.pin(), strength.into()) })?; + esp!(unsafe { gpio_set_drive_capability(self.pin as _, strength.into()) })?; } Ok(()) @@ -857,7 +762,7 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { if MODE::RTC { #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] { - res = if unsafe { rtc_gpio_get_level(self.pin.pin()) } != 0 { + res = if unsafe { rtc_gpio_get_level(self.pin as _) } != 0 { Level::High } else { Level::Low @@ -866,7 +771,7 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { #[cfg(any(esp32c3, esp32c2, esp32h2, esp32c5))] unreachable!(); - } else if unsafe { gpio_get_level(self.pin.pin()) } != 0 { + } else if unsafe { gpio_get_level(self.pin as _) } != 0 { res = Level::High; } else { res = Level::Low; @@ -900,7 +805,7 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { { // TODO: Implement for RTC mode - let pin = self.pin.pin() as u32; + let pin = self.pin as u32; #[cfg(any(esp32c3, esp32c2, esp32h2, esp32c5))] let is_set_high = unsafe { (*(GPIO_OUT_REG as *const u32) >> pin) & 0x01 != 0 }; @@ -949,12 +854,12 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { if MODE::RTC { #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] - esp!(unsafe { rtc_gpio_set_level(self.pin.pin(), on) })?; + esp!(unsafe { rtc_gpio_set_level(self.pin as _, on) })?; #[cfg(any(esp32c3, esp32c2, esp32h2, esp32c5))] unreachable!(); } else { - esp!(unsafe { gpio_set_level(self.pin.pin(), on) })?; + esp!(unsafe { gpio_set_level(self.pin as _, on) })?; } Ok(()) @@ -973,9 +878,8 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { } } - pub fn set_pull(&mut self, pull: Pull) -> Result<(), EspError> + fn set_pull(&mut self, pull: Pull) -> Result<(), EspError> where - T: InputPin + OutputPin, MODE: InputMode, { if MODE::RTC { @@ -983,20 +887,20 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { unsafe { match pull { Pull::Down => { - esp!(rtc_gpio_pulldown_en(self.pin.pin()))?; - esp!(rtc_gpio_pullup_dis(self.pin.pin()))?; + esp!(rtc_gpio_pulldown_en(self.pin as _))?; + esp!(rtc_gpio_pullup_dis(self.pin as _))?; } Pull::Up => { - esp!(rtc_gpio_pulldown_dis(self.pin.pin()))?; - esp!(rtc_gpio_pullup_en(self.pin.pin()))?; + esp!(rtc_gpio_pulldown_dis(self.pin as _))?; + esp!(rtc_gpio_pullup_en(self.pin as _))?; } Pull::UpDown => { - esp!(rtc_gpio_pulldown_en(self.pin.pin()))?; - esp!(rtc_gpio_pullup_en(self.pin.pin()))?; + esp!(rtc_gpio_pulldown_en(self.pin as _))?; + esp!(rtc_gpio_pullup_en(self.pin as _))?; } Pull::Floating => { - esp!(rtc_gpio_pulldown_dis(self.pin.pin()))?; - esp!(rtc_gpio_pullup_dis(self.pin.pin()))?; + esp!(rtc_gpio_pulldown_dis(self.pin as _))?; + esp!(rtc_gpio_pullup_dis(self.pin as _))?; } } } @@ -1004,7 +908,7 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { #[cfg(any(esp32c3, esp32c2, esp32h2, esp32c5))] unreachable!(); } else { - esp!(unsafe { gpio_set_pull_mode(self.pin.pin(), pull.into()) })?; + esp!(unsafe { gpio_set_pull_mode(self.pin as _, pull.into()) })?; } Ok(()) @@ -1089,7 +993,7 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { let callback: alloc::boxed::Box = alloc::boxed::Box::new(callback); unsafe { - chip::PIN_ISR_HANDLER[self.pin.pin() as usize] = Some(core::mem::transmute::< + chip::PIN_ISR_HANDLER[self.pin as usize] = Some(core::mem::transmute::< alloc::boxed::Box, alloc::boxed::Box, >(callback)); @@ -1103,7 +1007,7 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { MODE: InputMode, { unsafe { - unsubscribe_pin(self.pin.pin())?; + unsubscribe_pin(self.pin as _)?; } Ok(()) @@ -1125,9 +1029,9 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { unsafe { esp!(gpio_isr_handler_add( - self.pin.pin(), + self.pin as _, Some(Self::handle_isr), - self.pin.pin() as u32 as *mut core::ffi::c_void, + self.pin as u32 as *mut core::ffi::c_void, )) } } @@ -1139,7 +1043,7 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { use core::sync::atomic::Ordering; if ISR_SERVICE_ENABLED.load(Ordering::SeqCst) { - esp!(unsafe { gpio_isr_handler_remove(self.pin.pin()) })?; + esp!(unsafe { gpio_isr_handler_remove(self.pin as _) })?; } Ok(()) @@ -1149,11 +1053,43 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { where MODE: InputMode, { - esp!(unsafe { gpio_set_intr_type(self.pin.pin(), interrupt_type.into()) })?; + esp!(unsafe { gpio_set_intr_type(self.pin as _, interrupt_type.into()) })?; Ok(()) } + #[inline] + fn new_gpio(pin: PinId, mode: gpio_mode_t) -> Result + where + MODE: GPIOMode, + { + if mode != gpio_mode_t_GPIO_MODE_DISABLE { + esp!(unsafe { gpio_set_direction(pin as _, mode) })?; + } + + Ok(Self { + pin, + _mode: PhantomData, + _t: PhantomData, + }) + } + + #[inline] + #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32c5)))] + fn new_rtc(pin: PinId, mode: rtc_gpio_mode_t) -> Result + where + MODE: RTCMode, + { + esp!(unsafe { rtc_gpio_init(pin as _) })?; + esp!(unsafe { rtc_gpio_set_direction(pin as _, mode) })?; + + Ok(PinDriver { + pin, + _mode: PhantomData, + _t: PhantomData, + }) + } + unsafe extern "C" fn handle_isr(user_ctx: *mut core::ffi::c_void) { let pin = user_ctx as u32; @@ -1173,11 +1109,11 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> { } } -impl PinDriver<'_, T, MODE> { +impl PinDriver<'_, MODE> { pub async fn wait_for(&mut self, interrupt_type: InterruptType) -> Result<(), EspError> { self.disable_interrupt()?; - let notif = &chip::PIN_NOTIF[self.pin.pin() as usize]; + let notif = &chip::PIN_NOTIF[self.pin as usize]; notif.reset(); @@ -1224,15 +1160,15 @@ impl PinDriver<'_, T, MODE> { } } -impl Drop for PinDriver<'_, T, MODE> { +impl Drop for PinDriver<'_, MODE> { fn drop(&mut self) { - gpio_reset_without_pull(self.pin.pin()).unwrap(); + gpio_reset_without_pull(self.pin as _).unwrap(); } } -unsafe impl Send for PinDriver<'_, T, MODE> {} +unsafe impl Send for PinDriver<'_, MODE> {} -impl embedded_hal_0_2::digital::v2::InputPin for PinDriver<'_, T, MODE> +impl embedded_hal_0_2::digital::v2::InputPin for PinDriver<'_, MODE> where MODE: InputMode, { @@ -1258,11 +1194,11 @@ fn to_gpio_err(err: EspError) -> GpioError { GpioError::other(err) } -impl embedded_hal::digital::ErrorType for PinDriver<'_, T, MODE> { +impl embedded_hal::digital::ErrorType for PinDriver<'_, MODE> { type Error = GpioError; } -impl embedded_hal::digital::InputPin for PinDriver<'_, T, MODE> +impl embedded_hal::digital::InputPin for PinDriver<'_, MODE> where MODE: InputMode, { @@ -1275,7 +1211,7 @@ where } } -impl embedded_hal::digital::InputPin for &PinDriver<'_, T, MODE> +impl embedded_hal::digital::InputPin for &PinDriver<'_, MODE> where MODE: InputMode, { @@ -1288,7 +1224,7 @@ where } } -impl embedded_hal_0_2::digital::v2::OutputPin for PinDriver<'_, T, MODE> +impl embedded_hal_0_2::digital::v2::OutputPin for PinDriver<'_, MODE> where MODE: OutputMode, { @@ -1303,7 +1239,7 @@ where } } -impl embedded_hal::digital::OutputPin for PinDriver<'_, T, MODE> +impl embedded_hal::digital::OutputPin for PinDriver<'_, MODE> where MODE: OutputMode, { @@ -1316,7 +1252,7 @@ where } } -impl embedded_hal::digital::StatefulOutputPin for PinDriver<'_, T, MODE> +impl embedded_hal::digital::StatefulOutputPin for PinDriver<'_, MODE> where MODE: OutputMode, { @@ -1343,7 +1279,7 @@ where // } // } -impl embedded_hal_0_2::digital::v2::StatefulOutputPin for PinDriver<'_, T, MODE> +impl embedded_hal_0_2::digital::v2::StatefulOutputPin for PinDriver<'_, MODE> where MODE: OutputMode, { @@ -1356,7 +1292,7 @@ where } } -impl embedded_hal_0_2::digital::v2::ToggleableOutputPin for PinDriver<'_, T, MODE> +impl embedded_hal_0_2::digital::v2::ToggleableOutputPin for PinDriver<'_, MODE> where MODE: OutputMode, { @@ -1367,7 +1303,7 @@ where } } -impl embedded_hal_async::digital::Wait for PinDriver<'_, T, MODE> { +impl embedded_hal_async::digital::Wait for PinDriver<'_, MODE> { async fn wait_for_high(&mut self) -> Result<(), GpioError> { self.wait_for_high().await?; @@ -1471,11 +1407,11 @@ fn gpio_reset_without_pull(pin: gpio_num_t) -> Result<(), EspError> { Ok(()) } -unsafe fn unsubscribe_pin(pin: i32) -> Result<(), EspError> { +unsafe fn unsubscribe_pin(pin: gpio_num_t) -> Result<(), EspError> { use core::sync::atomic::Ordering; if ISR_SERVICE_ENABLED.load(Ordering::SeqCst) { - esp!(gpio_isr_handler_remove(pin))?; + esp!(gpio_isr_handler_remove(pin as _))?; chip::PIN_NOTIF[pin as usize].reset(); @@ -1498,19 +1434,32 @@ const PIN_NOTIF_INIT: crate::interrupt::asynch::HalIsrNotification = macro_rules! impl_input { ($pxi:ident: $pin:expr) => { - crate::impl_peripheral!($pxi); + $crate::impl_peripheral!($pxi); - impl Pin for $pxi { - fn pin(&self) -> i32 { - $pin + impl $pxi<'static> { + /// Return `Option::None` for an unconfigured instance of that pin + pub const fn none() -> Option { + None } } - impl InputPin for $pxi {} + impl Pin for $pxi<'_> { + fn pin(&self) -> PinId { + $pin as _ + } + } - impl From<$pxi> for AnyInputPin { + impl InputPin for $pxi<'_> {} + + impl<'a> From<$pxi<'a>> for AnyInputPin<'a> { fn from(pin: $pxi) -> Self { - unsafe { Self::new(pin.pin()) } + unsafe { Self::steal(pin.pin()) } + } + } + + impl<'a> $pxi<'a> { + pub fn degrade_input(self) -> AnyInputPin<'a> { + self.into() } } }; @@ -1520,19 +1469,27 @@ macro_rules! impl_input_output { ($pxi:ident: $pin:expr) => { impl_input!($pxi: $pin); - impl OutputPin for $pxi {} + impl<'a> $pxi<'a> { + pub fn degrade_output(self) -> AnyOutputPin<'a> { + self.into() + } - impl IOPin for $pxi {} - - impl From<$pxi> for AnyOutputPin { - fn from(pin: $pxi) -> Self { - unsafe { Self::new(pin.pin()) } + pub fn degrade_input_output(self) -> AnyIOPin<'a> { + self.into() } } - impl From<$pxi> for AnyIOPin { + impl OutputPin for $pxi<'_> {} + + impl<'a> From<$pxi<'a>> for AnyOutputPin<'a> { fn from(pin: $pxi) -> Self { - unsafe { Self::new(pin.pin()) } + unsafe { Self::steal(pin.pin()) } + } + } + + impl<'a> From<$pxi<'a>> for AnyIOPin<'a> { + fn from(pin: $pxi) -> Self { + unsafe { Self::steal(pin.pin()) } } } }; @@ -1540,8 +1497,8 @@ macro_rules! impl_input_output { macro_rules! impl_rtc { ($pxi:ident: $pin:expr, RTC: $rtc:expr) => { - impl RTCPin for $pxi { - fn rtc_pin(&self) -> i32 { + impl RTCPin for $pxi<'_> { + fn rtc_pin(&self) -> PinId { $rtc } } @@ -1551,45 +1508,26 @@ macro_rules! impl_rtc { } macro_rules! impl_adc { - ($pxi:ident: $pin:expr, ADC1: $adc:expr) => { - impl sealed::ADCPin for $pxi { - const CHANNEL: adc_channel_t = $adc; - } - - impl ADCPin for $pxi { - type Adc = ADC1; - - fn adc_channel(&self) -> adc_channel_t { - $adc - } + ($pxi:ident: $pin:expr, ADC1: $channel:ident) => { + impl ADCPin for $pxi<'_> { + type AdcChannel = $crate::adc::$channel<$crate::adc::ADCU1>; } }; - ($pxi:ident: $pin:expr, ADC2: $adc:expr) => { - impl sealed::ADCPin for $pxi { - const CHANNEL: adc_channel_t = $adc; - } - - #[cfg(any(esp32, esp32s2, esp32s3, esp32c3))] - impl ADCPin for $pxi { - type Adc = ADC2; - - fn adc_channel(&self) -> adc_channel_t { - $adc - } + ($pxi:ident: $pin:expr, ADC2: $channel:ident) => { + impl ADCPin for $pxi<'_> { + type AdcChannel = $crate::adc::$channel<$crate::adc::ADCU2>; } }; - ($pxi:ident: $pin:expr, NOADC: $adc:expr) => {}; + ($pxi:ident: $pin:expr, NOADC: $channel:ident) => {}; } macro_rules! impl_dac { ($pxi:ident: $pin:expr, DAC: $dac:expr) => { #[cfg(any(esp32, esp32s2))] - impl DACPin for $pxi { - fn dac_channel(&self) -> dac_channel_t { - $dac - } + impl DACPin for $pxi<'_> { + type DacChannel = DACCH<$dac>; } }; @@ -1599,10 +1537,8 @@ macro_rules! impl_dac { macro_rules! impl_touch { ($pxi:ident: $pin:expr, TOUCH: $touch:expr) => { #[cfg(any(esp32, esp32s2, esp32s3))] - impl TouchPin for $pxi { - fn touch_channel(&self) -> touch_pad_t { - $touch - } + impl TouchPin for $pxi<'_> { + type TouchChannel = TOUCHCH<$touch>; } }; @@ -1610,7 +1546,7 @@ macro_rules! impl_touch { } macro_rules! pin { - ($pxi:ident: $pin:expr, Input, $rtc:ident: $rtcno:expr, $adc:ident: $adcno:expr, $dac:ident: $dacno:expr, $touch:ident: $touchno:expr) => { + ($pxi:ident: $pin:expr, Input, $rtc:ident: $rtcno:expr, $adc:ident: $adcno:ident, $dac:ident: $dacno:expr, $touch:ident: $touchno:expr) => { impl_input!($pxi: $pin); impl_rtc!($pxi: $pin, $rtc: $rtcno); impl_adc!($pxi: $pin, $adc: $adcno); @@ -1618,7 +1554,7 @@ macro_rules! pin { impl_touch!($pxi: $pin, $touch: $touchno); }; - ($pxi:ident: $pin:expr, IO, $rtc:ident: $rtcno:expr, $adc:ident: $adcno:expr, $dac:ident: $dacno:expr, $touch:ident: $touchno:expr) => { + ($pxi:ident: $pin:expr, IO, $rtc:ident: $rtcno:expr, $adc:ident: $adcno:ident, $dac:ident: $dacno:expr, $touch:ident: $touchno:expr) => { impl_input_output!($pxi: $pin); impl_rtc!($pxi: $pin, $rtc: $rtcno); impl_adc!($pxi: $pin, $adc: $adcno); @@ -1635,12 +1571,8 @@ mod chip { #[cfg(feature = "alloc")] use alloc::boxed::Box; - use esp_idf_sys::*; - use crate::interrupt::asynch::HalIsrNotification; - use crate::adc::{ADC1, ADC2}; - use super::*; #[allow(clippy::type_complexity)] @@ -1653,78 +1585,78 @@ mod chip { // NOTE: Gpio26 - Gpio32 are used by SPI0/SPI1 for external PSRAM/SPI Flash and // are not recommended for other uses - pin!(Gpio0:0, IO, RTC:11, ADC2:1, NODAC:0, TOUCH:1); - pin!(Gpio1:1, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio2:2, IO, RTC:12, ADC2:2, NODAC:0, TOUCH:2); - pin!(Gpio3:3, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio4:4, IO, RTC:10, ADC2:0, NODAC:0, TOUCH:0); - pin!(Gpio5:5, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio6:6, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio7:7, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio8:8, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio9:9, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio10:10, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio11:11, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio12:12, IO, RTC:15, ADC2:5, NODAC:0, TOUCH:5); - pin!(Gpio13:13, IO, RTC:14, ADC2:4, NODAC:0, TOUCH:4); - pin!(Gpio14:14, IO, RTC:16, ADC2:6, NODAC:0, TOUCH:6); - pin!(Gpio15:15, IO, RTC:13, ADC2:3, NODAC:0, TOUCH:3); - pin!(Gpio16:16, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio17:17, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio18:18, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio19:19, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio20:20, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio21:21, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio22:22, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio23:23, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio25:25, IO, RTC:6, ADC2:8, DAC:1, NOTOUCH:0); - pin!(Gpio26:26, IO, RTC:7, ADC2:9, DAC:2, NOTOUCH:0); - pin!(Gpio27:27, IO, RTC:17, ADC2:7, NODAC:0, TOUCH:7); - pin!(Gpio32:32, IO, RTC:9, ADC1:4, NODAC:0, TOUCH:9); - pin!(Gpio33:33, IO, RTC:8, ADC1:5, NODAC:0, TOUCH:8); - pin!(Gpio34:34, Input, RTC:4, ADC1:6, NODAC:0, NOTOUCH:0); - pin!(Gpio35:35, Input, RTC:5, ADC1:7, NODAC:0, NOTOUCH:0); - pin!(Gpio36:36, Input, RTC:0, ADC1:0, NODAC:0, NOTOUCH:0); - pin!(Gpio37:37, Input, RTC:1, ADC1:1, NODAC:0, NOTOUCH:0); - pin!(Gpio38:38, Input, RTC:2, ADC1:2, NODAC:0, NOTOUCH:0); - pin!(Gpio39:39, Input, RTC:3, ADC1:3, NODAC:0, NOTOUCH:0); + pin!(Gpio0:0, IO, RTC:11, ADC2:ADCCH1, NODAC:0, TOUCH:1); + pin!(Gpio1:1, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio2:2, IO, RTC:12, ADC2:ADCCH2, NODAC:0, TOUCH:2); + pin!(Gpio3:3, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio4:4, IO, RTC:10, ADC2:ADCCH0, NODAC:0, TOUCH:0); + pin!(Gpio5:5, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio6:6, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio7:7, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio8:8, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio9:9, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio10:10, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio11:11, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio12:12, IO, RTC:15, ADC2:ADCCH5, NODAC:0, TOUCH:5); + pin!(Gpio13:13, IO, RTC:14, ADC2:ADCCH4, NODAC:0, TOUCH:4); + pin!(Gpio14:14, IO, RTC:16, ADC2:ADCCH6, NODAC:0, TOUCH:6); + pin!(Gpio15:15, IO, RTC:13, ADC2:ADCCH3, NODAC:0, TOUCH:3); + pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio21:21, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio22:22, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio23:23, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio25:25, IO, RTC:6, ADC2:ADCCH8, DAC:1, NOTOUCH:0); + pin!(Gpio26:26, IO, RTC:7, ADC2:ADCCH9, DAC:2, NOTOUCH:0); + pin!(Gpio27:27, IO, RTC:17, ADC2:ADCCH7, NODAC:0, TOUCH:7); + pin!(Gpio32:32, IO, RTC:9, ADC1:ADCCH4, NODAC:0, TOUCH:9); + pin!(Gpio33:33, IO, RTC:8, ADC1:ADCCH5, NODAC:0, TOUCH:8); + pin!(Gpio34:34, Input, RTC:4, ADC1:ADCCH6, NODAC:0, NOTOUCH:0); + pin!(Gpio35:35, Input, RTC:5, ADC1:ADCCH7, NODAC:0, NOTOUCH:0); + pin!(Gpio36:36, Input, RTC:0, ADC1:ADCCH0, NODAC:0, NOTOUCH:0); + pin!(Gpio37:37, Input, RTC:1, ADC1:ADCCH1, NODAC:0, NOTOUCH:0); + pin!(Gpio38:38, Input, RTC:2, ADC1:ADCCH2, NODAC:0, NOTOUCH:0); + pin!(Gpio39:39, Input, RTC:3, ADC1:ADCCH3, NODAC:0, NOTOUCH:0); pub struct Pins { - pub gpio0: Gpio0, - pub gpio1: Gpio1, - pub gpio2: Gpio2, - pub gpio3: Gpio3, - pub gpio4: Gpio4, - pub gpio5: Gpio5, - pub gpio6: Gpio6, - pub gpio7: Gpio7, - pub gpio8: Gpio8, - pub gpio9: Gpio9, - pub gpio10: Gpio10, - pub gpio11: Gpio11, - pub gpio12: Gpio12, - pub gpio13: Gpio13, - pub gpio14: Gpio14, - pub gpio15: Gpio15, - pub gpio16: Gpio16, - pub gpio17: Gpio17, - pub gpio18: Gpio18, - pub gpio19: Gpio19, - pub gpio20: Gpio20, - pub gpio21: Gpio21, - pub gpio22: Gpio22, - pub gpio23: Gpio23, - pub gpio25: Gpio25, - pub gpio26: Gpio26, - pub gpio27: Gpio27, - pub gpio32: Gpio32, - pub gpio33: Gpio33, - pub gpio34: Gpio34, - pub gpio35: Gpio35, - pub gpio36: Gpio36, - pub gpio37: Gpio37, - pub gpio38: Gpio38, - pub gpio39: Gpio39, + pub gpio0: Gpio0<'static>, + pub gpio1: Gpio1<'static>, + pub gpio2: Gpio2<'static>, + pub gpio3: Gpio3<'static>, + pub gpio4: Gpio4<'static>, + pub gpio5: Gpio5<'static>, + pub gpio6: Gpio6<'static>, + pub gpio7: Gpio7<'static>, + pub gpio8: Gpio8<'static>, + pub gpio9: Gpio9<'static>, + pub gpio10: Gpio10<'static>, + pub gpio11: Gpio11<'static>, + pub gpio12: Gpio12<'static>, + pub gpio13: Gpio13<'static>, + pub gpio14: Gpio14<'static>, + pub gpio15: Gpio15<'static>, + pub gpio16: Gpio16<'static>, + pub gpio17: Gpio17<'static>, + pub gpio18: Gpio18<'static>, + pub gpio19: Gpio19<'static>, + pub gpio20: Gpio20<'static>, + pub gpio21: Gpio21<'static>, + pub gpio22: Gpio22<'static>, + pub gpio23: Gpio23<'static>, + pub gpio25: Gpio25<'static>, + pub gpio26: Gpio26<'static>, + pub gpio27: Gpio27<'static>, + pub gpio32: Gpio32<'static>, + pub gpio33: Gpio33<'static>, + pub gpio34: Gpio34<'static>, + pub gpio35: Gpio35<'static>, + pub gpio36: Gpio36<'static>, + pub gpio37: Gpio37<'static>, + pub gpio38: Gpio38<'static>, + pub gpio39: Gpio39<'static>, } impl Pins { @@ -1734,41 +1666,41 @@ mod chip { /// already instantiated and used elsewhere pub unsafe fn new() -> Self { Self { - gpio0: Gpio0::new(), - gpio1: Gpio1::new(), - gpio2: Gpio2::new(), - gpio3: Gpio3::new(), - gpio4: Gpio4::new(), - gpio5: Gpio5::new(), - gpio6: Gpio6::new(), - gpio7: Gpio7::new(), - gpio8: Gpio8::new(), - gpio9: Gpio9::new(), - gpio10: Gpio10::new(), - gpio11: Gpio11::new(), - gpio12: Gpio12::new(), - gpio13: Gpio13::new(), - gpio14: Gpio14::new(), - gpio15: Gpio15::new(), - gpio16: Gpio16::new(), - gpio17: Gpio17::new(), - gpio18: Gpio18::new(), - gpio19: Gpio19::new(), - gpio20: Gpio20::new(), - gpio21: Gpio21::new(), - gpio22: Gpio22::new(), - gpio23: Gpio23::new(), - gpio25: Gpio25::new(), - gpio26: Gpio26::new(), - gpio27: Gpio27::new(), - gpio32: Gpio32::new(), - gpio33: Gpio33::new(), - gpio34: Gpio34::new(), - gpio35: Gpio35::new(), - gpio36: Gpio36::new(), - gpio37: Gpio37::new(), - gpio38: Gpio38::new(), - gpio39: Gpio39::new(), + gpio0: Gpio0::steal(), + gpio1: Gpio1::steal(), + gpio2: Gpio2::steal(), + gpio3: Gpio3::steal(), + gpio4: Gpio4::steal(), + gpio5: Gpio5::steal(), + gpio6: Gpio6::steal(), + gpio7: Gpio7::steal(), + gpio8: Gpio8::steal(), + gpio9: Gpio9::steal(), + gpio10: Gpio10::steal(), + gpio11: Gpio11::steal(), + gpio12: Gpio12::steal(), + gpio13: Gpio13::steal(), + gpio14: Gpio14::steal(), + gpio15: Gpio15::steal(), + gpio16: Gpio16::steal(), + gpio17: Gpio17::steal(), + gpio18: Gpio18::steal(), + gpio19: Gpio19::steal(), + gpio20: Gpio20::steal(), + gpio21: Gpio21::steal(), + gpio22: Gpio22::steal(), + gpio23: Gpio23::steal(), + gpio25: Gpio25::steal(), + gpio26: Gpio26::steal(), + gpio27: Gpio27::steal(), + gpio32: Gpio32::steal(), + gpio33: Gpio33::steal(), + gpio34: Gpio34::steal(), + gpio35: Gpio35::steal(), + gpio36: Gpio36::steal(), + gpio37: Gpio37::steal(), + gpio38: Gpio38::steal(), + gpio39: Gpio39::steal(), } } } @@ -1782,12 +1714,8 @@ mod chip { #[cfg(feature = "alloc")] use alloc::boxed::Box; - use esp_idf_sys::*; - use crate::interrupt::asynch::HalIsrNotification; - use crate::adc::{ADC1, ADC2}; - use super::*; #[allow(clippy::type_complexity)] @@ -1801,111 +1729,111 @@ mod chip { // NOTE: Gpio26 - Gpio32 (and Gpio33 - Gpio37 if using Octal RAM/Flash) are used // by SPI0/SPI1 for external PSRAM/SPI Flash and are not recommended for // other uses - pin!(Gpio0:0, IO, RTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio1:1, IO, RTC:1, ADC1:0, NODAC:0, TOUCH:1); - pin!(Gpio2:2, IO, RTC:2, ADC1:1, NODAC:0, TOUCH:2); - pin!(Gpio3:3, IO, RTC:3, ADC1:2, NODAC:0, TOUCH:3); - pin!(Gpio4:4, IO, RTC:4, ADC1:3, NODAC:0, TOUCH:4); - pin!(Gpio5:5, IO, RTC:5, ADC1:4, NODAC:0, TOUCH:5); - pin!(Gpio6:6, IO, RTC:6, ADC1:5, NODAC:0, TOUCH:6); - pin!(Gpio7:7, IO, RTC:7, ADC1:6, NODAC:0, TOUCH:7); - pin!(Gpio8:8, IO, RTC:8, ADC1:7, NODAC:0, TOUCH:8); - pin!(Gpio9:9, IO, RTC:9, ADC1:8, NODAC:0, TOUCH:9); - pin!(Gpio10:10, IO, RTC:10, ADC1:9, NODAC:0, TOUCH:10); - pin!(Gpio11:11, IO, RTC:11, ADC2:0, NODAC:0, TOUCH:11); - pin!(Gpio12:12, IO, RTC:12, ADC2:1, NODAC:0, TOUCH:12); - pin!(Gpio13:13, IO, RTC:13, ADC2:2, NODAC:0, TOUCH:13); - pin!(Gpio14:14, IO, RTC:14, ADC2:3, NODAC:0, TOUCH:14); - pin!(Gpio15:15, IO, RTC:15, ADC2:4, NODAC:0, NOTOUCH:0); - pin!(Gpio16:16, IO, RTC:16, ADC2:5, NODAC:0, NOTOUCH:0); + pin!(Gpio0:0, IO, RTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio1:1, IO, RTC:1, ADC1:ADCCH0, NODAC:0, TOUCH:1); + pin!(Gpio2:2, IO, RTC:2, ADC1:ADCCH1, NODAC:0, TOUCH:2); + pin!(Gpio3:3, IO, RTC:3, ADC1:ADCCH2, NODAC:0, TOUCH:3); + pin!(Gpio4:4, IO, RTC:4, ADC1:ADCCH3, NODAC:0, TOUCH:4); + pin!(Gpio5:5, IO, RTC:5, ADC1:ADCCH4, NODAC:0, TOUCH:5); + pin!(Gpio6:6, IO, RTC:6, ADC1:ADCCH5, NODAC:0, TOUCH:6); + pin!(Gpio7:7, IO, RTC:7, ADC1:ADCCH6, NODAC:0, TOUCH:7); + pin!(Gpio8:8, IO, RTC:8, ADC1:ADCCH7, NODAC:0, TOUCH:8); + pin!(Gpio9:9, IO, RTC:9, ADC1:ADCCH8, NODAC:0, TOUCH:9); + pin!(Gpio10:10, IO, RTC:10, ADC1:ADCCH9, NODAC:0, TOUCH:10); + pin!(Gpio11:11, IO, RTC:11, ADC2:ADCCH0, NODAC:0, TOUCH:11); + pin!(Gpio12:12, IO, RTC:12, ADC2:ADCCH1, NODAC:0, TOUCH:12); + pin!(Gpio13:13, IO, RTC:13, ADC2:ADCCH2, NODAC:0, TOUCH:13); + pin!(Gpio14:14, IO, RTC:14, ADC2:ADCCH3, NODAC:0, TOUCH:14); + pin!(Gpio15:15, IO, RTC:15, ADC2:ADCCH4, NODAC:0, NOTOUCH:0); + pin!(Gpio16:16, IO, RTC:16, ADC2:ADCCH5, NODAC:0, NOTOUCH:0); #[cfg(esp32s2)] - pin!(Gpio17:17, IO, RTC:17, ADC2:6, DAC:1, NOTOUCH:0); + pin!(Gpio17:17, IO, RTC:17, ADC2:ADCCH6, DAC:1, NOTOUCH:0); #[cfg(esp32s3)] - pin!(Gpio17:17, IO, RTC:17, ADC2:6, NODAC:0, NOTOUCH:0); + pin!(Gpio17:17, IO, RTC:17, ADC2:ADCCH6, NODAC:0, NOTOUCH:0); #[cfg(esp32s2)] - pin!(Gpio18:18, IO, RTC:18, ADC2:7, DAC:2, NOTOUCH:0); + pin!(Gpio18:18, IO, RTC:18, ADC2:ADCCH7, DAC:2, NOTOUCH:0); #[cfg(esp32s3)] - pin!(Gpio18:18, IO, RTC:18, ADC2:7, NODAC:0, NOTOUCH:0); - pin!(Gpio19:19, IO, RTC:19, ADC2:8, NODAC:0, NOTOUCH:0); - pin!(Gpio20:20, IO, RTC:20, ADC2:9, NODAC:0, NOTOUCH:0); - pin!(Gpio21:21, IO, RTC:21, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio26:26, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio27:27, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio28:28, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio29:29, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio30:30, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio31:31, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio32:32, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio33:33, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio34:34, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio35:35, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio36:36, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio37:37, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio38:38, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio39:39, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio40:40, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio41:41, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio42:42, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio43:43, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio44:44, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio45:45, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio18:18, IO, RTC:18, ADC2:ADCCH7, NODAC:0, NOTOUCH:0); + pin!(Gpio19:19, IO, RTC:19, ADC2:ADCCH8, NODAC:0, NOTOUCH:0); + pin!(Gpio20:20, IO, RTC:20, ADC2:ADCCH9, NODAC:0, NOTOUCH:0); + pin!(Gpio21:21, IO, RTC:21, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio26:26, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio27:27, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio28:28, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio29:29, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio30:30, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio31:31, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio32:32, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio33:33, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio34:34, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio35:35, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio36:36, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio37:37, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio38:38, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio39:39, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio40:40, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio41:41, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio42:42, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio43:43, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio44:44, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio45:45, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); #[cfg(esp32s2)] - pin!(Gpio46:46, Input, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio46:46, Input, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); #[cfg(esp32s3)] - pin!(Gpio46:46, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio46:46, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); #[cfg(esp32s3)] - pin!(Gpio47:47, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio47:47, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); #[cfg(esp32s3)] - pin!(Gpio48:48, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio48:48, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); pub struct Pins { - pub gpio0: Gpio0, - pub gpio1: Gpio1, - pub gpio2: Gpio2, - pub gpio3: Gpio3, - pub gpio4: Gpio4, - pub gpio5: Gpio5, - pub gpio6: Gpio6, - pub gpio7: Gpio7, - pub gpio8: Gpio8, - pub gpio9: Gpio9, - pub gpio10: Gpio10, - pub gpio11: Gpio11, - pub gpio12: Gpio12, - pub gpio13: Gpio13, - pub gpio14: Gpio14, - pub gpio15: Gpio15, - pub gpio16: Gpio16, - pub gpio17: Gpio17, - pub gpio18: Gpio18, - pub gpio19: Gpio19, - pub gpio20: Gpio20, - pub gpio21: Gpio21, - pub gpio26: Gpio26, - pub gpio27: Gpio27, - pub gpio28: Gpio28, - pub gpio29: Gpio29, - pub gpio30: Gpio30, - pub gpio31: Gpio31, - pub gpio32: Gpio32, - pub gpio33: Gpio33, - pub gpio34: Gpio34, - pub gpio35: Gpio35, - pub gpio36: Gpio36, - pub gpio37: Gpio37, - pub gpio38: Gpio38, - pub gpio39: Gpio39, - pub gpio40: Gpio40, - pub gpio41: Gpio41, - pub gpio42: Gpio42, - pub gpio43: Gpio43, - pub gpio44: Gpio44, - pub gpio45: Gpio45, - pub gpio46: Gpio46, + pub gpio0: Gpio0<'static>, + pub gpio1: Gpio1<'static>, + pub gpio2: Gpio2<'static>, + pub gpio3: Gpio3<'static>, + pub gpio4: Gpio4<'static>, + pub gpio5: Gpio5<'static>, + pub gpio6: Gpio6<'static>, + pub gpio7: Gpio7<'static>, + pub gpio8: Gpio8<'static>, + pub gpio9: Gpio9<'static>, + pub gpio10: Gpio10<'static>, + pub gpio11: Gpio11<'static>, + pub gpio12: Gpio12<'static>, + pub gpio13: Gpio13<'static>, + pub gpio14: Gpio14<'static>, + pub gpio15: Gpio15<'static>, + pub gpio16: Gpio16<'static>, + pub gpio17: Gpio17<'static>, + pub gpio18: Gpio18<'static>, + pub gpio19: Gpio19<'static>, + pub gpio20: Gpio20<'static>, + pub gpio21: Gpio21<'static>, + pub gpio26: Gpio26<'static>, + pub gpio27: Gpio27<'static>, + pub gpio28: Gpio28<'static>, + pub gpio29: Gpio29<'static>, + pub gpio30: Gpio30<'static>, + pub gpio31: Gpio31<'static>, + pub gpio32: Gpio32<'static>, + pub gpio33: Gpio33<'static>, + pub gpio34: Gpio34<'static>, + pub gpio35: Gpio35<'static>, + pub gpio36: Gpio36<'static>, + pub gpio37: Gpio37<'static>, + pub gpio38: Gpio38<'static>, + pub gpio39: Gpio39<'static>, + pub gpio40: Gpio40<'static>, + pub gpio41: Gpio41<'static>, + pub gpio42: Gpio42<'static>, + pub gpio43: Gpio43<'static>, + pub gpio44: Gpio44<'static>, + pub gpio45: Gpio45<'static>, + pub gpio46: Gpio46<'static>, #[cfg(esp32s3)] - pub gpio47: Gpio47, + pub gpio47: Gpio47<'static>, #[cfg(esp32s3)] - pub gpio48: Gpio48, + pub gpio48: Gpio48<'static>, } impl Pins { @@ -1915,53 +1843,53 @@ mod chip { /// already instantiated and used elsewhere pub unsafe fn new() -> Self { Self { - gpio0: Gpio0::new(), - gpio1: Gpio1::new(), - gpio2: Gpio2::new(), - gpio3: Gpio3::new(), - gpio4: Gpio4::new(), - gpio5: Gpio5::new(), - gpio6: Gpio6::new(), - gpio7: Gpio7::new(), - gpio8: Gpio8::new(), - gpio9: Gpio9::new(), - gpio10: Gpio10::new(), - gpio11: Gpio11::new(), - gpio12: Gpio12::new(), - gpio13: Gpio13::new(), - gpio14: Gpio14::new(), - gpio15: Gpio15::new(), - gpio16: Gpio16::new(), - gpio17: Gpio17::new(), - gpio18: Gpio18::new(), - gpio19: Gpio19::new(), - gpio20: Gpio20::new(), - gpio21: Gpio21::new(), - gpio26: Gpio26::new(), - gpio27: Gpio27::new(), - gpio28: Gpio28::new(), - gpio29: Gpio29::new(), - gpio30: Gpio30::new(), - gpio31: Gpio31::new(), - gpio32: Gpio32::new(), - gpio33: Gpio33::new(), - gpio34: Gpio34::new(), - gpio35: Gpio35::new(), - gpio36: Gpio36::new(), - gpio37: Gpio37::new(), - gpio38: Gpio38::new(), - gpio39: Gpio39::new(), - gpio40: Gpio40::new(), - gpio41: Gpio41::new(), - gpio42: Gpio42::new(), - gpio43: Gpio43::new(), - gpio44: Gpio44::new(), - gpio45: Gpio45::new(), - gpio46: Gpio46::new(), + gpio0: Gpio0::steal(), + gpio1: Gpio1::steal(), + gpio2: Gpio2::steal(), + gpio3: Gpio3::steal(), + gpio4: Gpio4::steal(), + gpio5: Gpio5::steal(), + gpio6: Gpio6::steal(), + gpio7: Gpio7::steal(), + gpio8: Gpio8::steal(), + gpio9: Gpio9::steal(), + gpio10: Gpio10::steal(), + gpio11: Gpio11::steal(), + gpio12: Gpio12::steal(), + gpio13: Gpio13::steal(), + gpio14: Gpio14::steal(), + gpio15: Gpio15::steal(), + gpio16: Gpio16::steal(), + gpio17: Gpio17::steal(), + gpio18: Gpio18::steal(), + gpio19: Gpio19::steal(), + gpio20: Gpio20::steal(), + gpio21: Gpio21::steal(), + gpio26: Gpio26::steal(), + gpio27: Gpio27::steal(), + gpio28: Gpio28::steal(), + gpio29: Gpio29::steal(), + gpio30: Gpio30::steal(), + gpio31: Gpio31::steal(), + gpio32: Gpio32::steal(), + gpio33: Gpio33::steal(), + gpio34: Gpio34::steal(), + gpio35: Gpio35::steal(), + gpio36: Gpio36::steal(), + gpio37: Gpio37::steal(), + gpio38: Gpio38::steal(), + gpio39: Gpio39::steal(), + gpio40: Gpio40::steal(), + gpio41: Gpio41::steal(), + gpio42: Gpio42::steal(), + gpio43: Gpio43::steal(), + gpio44: Gpio44::steal(), + gpio45: Gpio45::steal(), + gpio46: Gpio46::steal(), #[cfg(esp32s3)] - gpio47: Gpio47::new(), + gpio47: Gpio47::steal(), #[cfg(esp32s3)] - gpio48: Gpio48::new(), + gpio48: Gpio48::steal(), } } } @@ -1975,12 +1903,8 @@ mod chip { #[cfg(feature = "alloc")] use alloc::boxed::Box; - use esp_idf_sys::*; - use crate::interrupt::asynch::HalIsrNotification; - use crate::adc::{ADC1, ADC2}; - use super::*; #[allow(clippy::type_complexity)] @@ -1992,83 +1916,79 @@ mod chip { // NOTE: Gpio12 - Gpio17 are used by SPI0/SPI1 for external PSRAM/SPI Flash and // are not recommended for other uses - pin!(Gpio0:0, IO, RTC:0, ADC1:0, NODAC:0, NOTOUCH:0); - pin!(Gpio1:1, IO, RTC:1, ADC1:1, NODAC:0, NOTOUCH:0); - pin!(Gpio2:2, IO, RTC:2, ADC1:2, NODAC:0, NOTOUCH:0); - pin!(Gpio3:3, IO, RTC:3, ADC1:3, NODAC:0, NOTOUCH:0); - pin!(Gpio4:4, IO, RTC:4, ADC1:4, NODAC:0, NOTOUCH:0); - pin!(Gpio5:5, IO, RTC:5, ADC2:0, NODAC:0, NOTOUCH:0); - pin!(Gpio6:6, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio7:7, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio8:8, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio9:9, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio10:10, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio11:11, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio12:12, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio13:13, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio14:14, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio15:15, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio16:16, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio17:17, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio18:18, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio19:19, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio20:20, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio21:21, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio0:0, IO, RTC:0, ADC1:ADCCH0, NODAC:0, NOTOUCH:0); + pin!(Gpio1:1, IO, RTC:1, ADC1:ADCCH1, NODAC:0, NOTOUCH:0); + pin!(Gpio2:2, IO, RTC:2, ADC1:ADCCH2, NODAC:0, NOTOUCH:0); + pin!(Gpio3:3, IO, RTC:3, ADC1:ADCCH3, NODAC:0, NOTOUCH:0); + pin!(Gpio4:4, IO, RTC:4, ADC1:ADCCH4, NODAC:0, NOTOUCH:0); + pin!(Gpio5:5, IO, RTC:5, ADC2:ADCCH0, NODAC:0, NOTOUCH:0); + pin!(Gpio6:6, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio7:7, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio8:8, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio9:9, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio10:10, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio11:11, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio12:12, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio13:13, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio14:14, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio15:15, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio21:21, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); pub struct Pins { - pub gpio0: Gpio0, - pub gpio1: Gpio1, - pub gpio2: Gpio2, - pub gpio3: Gpio3, - pub gpio4: Gpio4, - pub gpio5: Gpio5, - pub gpio6: Gpio6, - pub gpio7: Gpio7, - pub gpio8: Gpio8, - pub gpio9: Gpio9, - pub gpio10: Gpio10, - pub gpio11: Gpio11, - pub gpio12: Gpio12, - pub gpio13: Gpio13, - pub gpio14: Gpio14, - pub gpio15: Gpio15, - pub gpio16: Gpio16, - pub gpio17: Gpio17, - pub gpio18: Gpio18, - pub gpio19: Gpio19, - pub gpio20: Gpio20, - pub gpio21: Gpio21, + pub gpio0: Gpio0<'static>, + pub gpio1: Gpio1<'static>, + pub gpio2: Gpio2<'static>, + pub gpio3: Gpio3<'static>, + pub gpio4: Gpio4<'static>, + pub gpio5: Gpio5<'static>, + pub gpio6: Gpio6<'static>, + pub gpio7: Gpio7<'static>, + pub gpio8: Gpio8<'static>, + pub gpio9: Gpio9<'static>, + pub gpio10: Gpio10<'static>, + pub gpio11: Gpio11<'static>, + pub gpio12: Gpio12<'static>, + pub gpio13: Gpio13<'static>, + pub gpio14: Gpio14<'static>, + pub gpio15: Gpio15<'static>, + pub gpio16: Gpio16<'static>, + pub gpio17: Gpio17<'static>, + pub gpio18: Gpio18<'static>, + pub gpio19: Gpio19<'static>, + pub gpio20: Gpio20<'static>, + pub gpio21: Gpio21<'static>, } impl Pins { - /// # Safety - /// - /// Care should be taken not to instantiate the Pins structure, if it is - /// already instantiated and used elsewhere - pub unsafe fn new() -> Self { + pub(crate) unsafe fn new() -> Self { Self { - gpio0: Gpio0::new(), - gpio1: Gpio1::new(), - gpio2: Gpio2::new(), - gpio3: Gpio3::new(), - gpio4: Gpio4::new(), - gpio5: Gpio5::new(), - gpio6: Gpio6::new(), - gpio7: Gpio7::new(), - gpio8: Gpio8::new(), - gpio9: Gpio9::new(), - gpio10: Gpio10::new(), - gpio11: Gpio11::new(), - gpio12: Gpio12::new(), - gpio13: Gpio13::new(), - gpio14: Gpio14::new(), - gpio15: Gpio15::new(), - gpio16: Gpio16::new(), - gpio17: Gpio17::new(), - gpio18: Gpio18::new(), - gpio19: Gpio19::new(), - gpio20: Gpio20::new(), - gpio21: Gpio21::new(), + gpio0: Gpio0::steal(), + gpio1: Gpio1::steal(), + gpio2: Gpio2::steal(), + gpio3: Gpio3::steal(), + gpio4: Gpio4::steal(), + gpio5: Gpio5::steal(), + gpio6: Gpio6::steal(), + gpio7: Gpio7::steal(), + gpio8: Gpio8::steal(), + gpio9: Gpio9::steal(), + gpio10: Gpio10::steal(), + gpio11: Gpio11::steal(), + gpio12: Gpio12::steal(), + gpio13: Gpio13::steal(), + gpio14: Gpio14::steal(), + gpio15: Gpio15::steal(), + gpio16: Gpio16::steal(), + gpio17: Gpio17::steal(), + gpio18: Gpio18::steal(), + gpio19: Gpio19::steal(), + gpio20: Gpio20::steal(), + gpio21: Gpio21::steal(), } } } @@ -2082,12 +2002,8 @@ mod chip { #[cfg(feature = "alloc")] use alloc::boxed::Box; - use esp_idf_sys::*; - use crate::interrupt::asynch::HalIsrNotification; - use crate::adc::ADC1; - use super::*; #[allow(clippy::type_complexity)] @@ -2099,50 +2015,50 @@ mod chip { // NOTE: Gpio12 - Gpio17 are used by SPI0/SPI1 for external PSRAM/SPI Flash and // are not recommended for other uses - pin!(Gpio0:0, IO, RTC:0, ADC1:0, NODAC:0, NOTOUCH:0); - pin!(Gpio1:1, IO, RTC:1, ADC1:1, NODAC:0, NOTOUCH:0); - pin!(Gpio2:2, IO, RTC:2, ADC1:2, NODAC:0, NOTOUCH:0); - pin!(Gpio3:3, IO, RTC:3, ADC1:3, NODAC:0, NOTOUCH:0); - pin!(Gpio4:4, IO, RTC:4, ADC1:4, NODAC:0, NOTOUCH:0); - pin!(Gpio5:5, IO, RTC:5, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio6:6, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio7:7, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio8:8, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio9:9, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio10:10, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio11:11, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio12:12, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio13:13, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio14:14, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio15:15, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio16:16, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio17:17, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio18:18, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio19:19, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio20:20, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio0:0, IO, RTC:0, ADC1:ADCCH0, NODAC:0, NOTOUCH:0); + pin!(Gpio1:1, IO, RTC:1, ADC1:ADCCH1, NODAC:0, NOTOUCH:0); + pin!(Gpio2:2, IO, RTC:2, ADC1:ADCCH2, NODAC:0, NOTOUCH:0); + pin!(Gpio3:3, IO, RTC:3, ADC1:ADCCH3, NODAC:0, NOTOUCH:0); + pin!(Gpio4:4, IO, RTC:4, ADC1:ADCCH4, NODAC:0, NOTOUCH:0); + pin!(Gpio5:5, IO, RTC:5, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio6:6, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio7:7, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio8:8, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio9:9, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio10:10, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio11:11, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio12:12, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio13:13, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio14:14, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio15:15, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); pub struct Pins { - pub gpio0: Gpio0, - pub gpio1: Gpio1, - pub gpio2: Gpio2, - pub gpio3: Gpio3, - pub gpio4: Gpio4, - pub gpio5: Gpio5, - pub gpio6: Gpio6, - pub gpio7: Gpio7, - pub gpio8: Gpio8, - pub gpio9: Gpio9, - pub gpio10: Gpio10, - pub gpio11: Gpio11, - pub gpio12: Gpio12, - pub gpio13: Gpio13, - pub gpio14: Gpio14, - pub gpio15: Gpio15, - pub gpio16: Gpio16, - pub gpio17: Gpio17, - pub gpio18: Gpio18, - pub gpio19: Gpio19, - pub gpio20: Gpio20, + pub gpio0: Gpio0<'static>, + pub gpio1: Gpio1<'static>, + pub gpio2: Gpio2<'static>, + pub gpio3: Gpio3<'static>, + pub gpio4: Gpio4<'static>, + pub gpio5: Gpio5<'static>, + pub gpio6: Gpio6<'static>, + pub gpio7: Gpio7<'static>, + pub gpio8: Gpio8<'static>, + pub gpio9: Gpio9<'static>, + pub gpio10: Gpio10<'static>, + pub gpio11: Gpio11<'static>, + pub gpio12: Gpio12<'static>, + pub gpio13: Gpio13<'static>, + pub gpio14: Gpio14<'static>, + pub gpio15: Gpio15<'static>, + pub gpio16: Gpio16<'static>, + pub gpio17: Gpio17<'static>, + pub gpio18: Gpio18<'static>, + pub gpio19: Gpio19<'static>, + pub gpio20: Gpio20<'static>, } impl Pins { @@ -2152,27 +2068,27 @@ mod chip { /// already instantiated and used elsewhere pub unsafe fn new() -> Self { Self { - gpio0: Gpio0::new(), - gpio1: Gpio1::new(), - gpio2: Gpio2::new(), - gpio3: Gpio3::new(), - gpio4: Gpio4::new(), - gpio5: Gpio5::new(), - gpio6: Gpio6::new(), - gpio7: Gpio7::new(), - gpio8: Gpio8::new(), - gpio9: Gpio9::new(), - gpio10: Gpio10::new(), - gpio11: Gpio11::new(), - gpio12: Gpio12::new(), - gpio13: Gpio13::new(), - gpio14: Gpio14::new(), - gpio15: Gpio15::new(), - gpio16: Gpio16::new(), - gpio17: Gpio17::new(), - gpio18: Gpio18::new(), - gpio19: Gpio19::new(), - gpio20: Gpio20::new(), + gpio0: Gpio0::steal(), + gpio1: Gpio1::steal(), + gpio2: Gpio2::steal(), + gpio3: Gpio3::steal(), + gpio4: Gpio4::steal(), + gpio5: Gpio5::steal(), + gpio6: Gpio6::steal(), + gpio7: Gpio7::steal(), + gpio8: Gpio8::steal(), + gpio9: Gpio9::steal(), + gpio10: Gpio10::steal(), + gpio11: Gpio11::steal(), + gpio12: Gpio12::steal(), + gpio13: Gpio13::steal(), + gpio14: Gpio14::steal(), + gpio15: Gpio15::steal(), + gpio16: Gpio16::steal(), + gpio17: Gpio17::steal(), + gpio18: Gpio18::steal(), + gpio19: Gpio19::steal(), + gpio20: Gpio20::steal(), } } } @@ -2186,12 +2102,8 @@ mod chip { #[cfg(feature = "alloc")] use alloc::boxed::Box; - use esp_idf_sys::*; - use crate::interrupt::asynch::HalIsrNotification; - use crate::adc::ADC1; - use super::*; #[allow(clippy::type_complexity)] @@ -2206,64 +2118,64 @@ mod chip { // - Gpio21 seems not to be exposed physically // - Gpio23 + Gpio24 are used by serial debug interface // - Gpio26 + Gpio27 are used by USB debug interface - pin!(Gpio0:0, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio1:1, IO, NORTC:0, ADC1:0, NODAC:0, NOTOUCH:0); - pin!(Gpio2:2, IO, NORTC:0, ADC1:1, NODAC:0, NOTOUCH:0); - pin!(Gpio3:3, IO, NORTC:0, ADC1:2, NODAC:0, NOTOUCH:0); - pin!(Gpio4:4, IO, NORTC:0, ADC1:3, NODAC:0, NOTOUCH:0); - pin!(Gpio5:5, IO, NORTC:0, ADC1:4, NODAC:0, NOTOUCH:0); - pin!(Gpio6:6, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio7:7, IO, RTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio8:8, IO, RTC:1, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio9:9, IO, RTC:2, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio10:10, IO, RTC:3, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio11:11, IO, RTC:4, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio12:12, IO, RTC:5, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio13:13, IO, RTC:6, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio14:14, IO, RTC:7, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio15:15, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio16:16, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio17:17, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio18:18, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio19:19, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio20:20, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio21:21, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio22:22, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio23:23, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio24:24, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio25:25, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio26:26, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio27:27, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio0:0, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio1:1, IO, NORTC:0, ADC1:ADCCH0, NODAC:0, NOTOUCH:0); + pin!(Gpio2:2, IO, NORTC:0, ADC1:ADCCH1, NODAC:0, NOTOUCH:0); + pin!(Gpio3:3, IO, NORTC:0, ADC1:ADCCH2, NODAC:0, NOTOUCH:0); + pin!(Gpio4:4, IO, NORTC:0, ADC1:ADCCH3, NODAC:0, NOTOUCH:0); + pin!(Gpio5:5, IO, NORTC:0, ADC1:ADCCH4, NODAC:0, NOTOUCH:0); + pin!(Gpio6:6, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio7:7, IO, RTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio8:8, IO, RTC:1, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio9:9, IO, RTC:2, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio10:10, IO, RTC:3, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio11:11, IO, RTC:4, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio12:12, IO, RTC:5, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio13:13, IO, RTC:6, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio14:14, IO, RTC:7, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio15:15, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio21:21, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio22:22, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio23:23, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio24:24, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio25:25, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio26:26, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio27:27, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); pub struct Pins { - pub gpio0: Gpio0, - pub gpio1: Gpio1, - pub gpio2: Gpio2, - pub gpio3: Gpio3, - pub gpio4: Gpio4, - pub gpio5: Gpio5, - pub gpio6: Gpio6, - pub gpio7: Gpio7, - pub gpio8: Gpio8, - pub gpio9: Gpio9, - pub gpio10: Gpio10, - pub gpio11: Gpio11, - pub gpio12: Gpio12, - pub gpio13: Gpio13, - pub gpio14: Gpio14, - pub gpio15: Gpio15, - pub gpio16: Gpio16, - pub gpio17: Gpio17, - pub gpio18: Gpio18, - pub gpio19: Gpio19, - pub gpio20: Gpio20, - pub gpio21: Gpio21, - pub gpio22: Gpio22, - pub gpio23: Gpio23, - pub gpio24: Gpio24, - pub gpio25: Gpio25, - pub gpio26: Gpio26, - pub gpio27: Gpio27, + pub gpio0: Gpio0<'static>, + pub gpio1: Gpio1<'static>, + pub gpio2: Gpio2<'static>, + pub gpio3: Gpio3<'static>, + pub gpio4: Gpio4<'static>, + pub gpio5: Gpio5<'static>, + pub gpio6: Gpio6<'static>, + pub gpio7: Gpio7<'static>, + pub gpio8: Gpio8<'static>, + pub gpio9: Gpio9<'static>, + pub gpio10: Gpio10<'static>, + pub gpio11: Gpio11<'static>, + pub gpio12: Gpio12<'static>, + pub gpio13: Gpio13<'static>, + pub gpio14: Gpio14<'static>, + pub gpio15: Gpio15<'static>, + pub gpio16: Gpio16<'static>, + pub gpio17: Gpio17<'static>, + pub gpio18: Gpio18<'static>, + pub gpio19: Gpio19<'static>, + pub gpio20: Gpio20<'static>, + pub gpio21: Gpio21<'static>, + pub gpio22: Gpio22<'static>, + pub gpio23: Gpio23<'static>, + pub gpio24: Gpio24<'static>, + pub gpio25: Gpio25<'static>, + pub gpio26: Gpio26<'static>, + pub gpio27: Gpio27<'static>, } impl Pins { @@ -2273,34 +2185,34 @@ mod chip { /// already instantiated and used elsewhere pub unsafe fn new() -> Self { Self { - gpio0: Gpio0::new(), - gpio1: Gpio1::new(), - gpio2: Gpio2::new(), - gpio3: Gpio3::new(), - gpio4: Gpio4::new(), - gpio5: Gpio5::new(), - gpio6: Gpio6::new(), - gpio7: Gpio7::new(), - gpio8: Gpio8::new(), - gpio9: Gpio9::new(), - gpio10: Gpio10::new(), - gpio11: Gpio11::new(), - gpio12: Gpio12::new(), - gpio13: Gpio13::new(), - gpio14: Gpio14::new(), - gpio15: Gpio15::new(), - gpio16: Gpio16::new(), - gpio17: Gpio17::new(), - gpio18: Gpio18::new(), - gpio19: Gpio19::new(), - gpio20: Gpio20::new(), - gpio21: Gpio21::new(), - gpio22: Gpio22::new(), - gpio23: Gpio23::new(), - gpio24: Gpio24::new(), - gpio25: Gpio25::new(), - gpio26: Gpio26::new(), - gpio27: Gpio27::new(), + gpio0: Gpio0::steal(), + gpio1: Gpio1::steal(), + gpio2: Gpio2::steal(), + gpio3: Gpio3::steal(), + gpio4: Gpio4::steal(), + gpio5: Gpio5::steal(), + gpio6: Gpio6::steal(), + gpio7: Gpio7::steal(), + gpio8: Gpio8::steal(), + gpio9: Gpio9::steal(), + gpio10: Gpio10::steal(), + gpio11: Gpio11::steal(), + gpio12: Gpio12::steal(), + gpio13: Gpio13::steal(), + gpio14: Gpio14::steal(), + gpio15: Gpio15::steal(), + gpio16: Gpio16::steal(), + gpio17: Gpio17::steal(), + gpio18: Gpio18::steal(), + gpio19: Gpio19::steal(), + gpio20: Gpio20::steal(), + gpio21: Gpio21::steal(), + gpio22: Gpio22::steal(), + gpio23: Gpio23::steal(), + gpio24: Gpio24::steal(), + gpio25: Gpio25::steal(), + gpio26: Gpio26::steal(), + gpio27: Gpio27::steal(), } } } @@ -2316,12 +2228,8 @@ mod chip { #[cfg(feature = "alloc")] use alloc::boxed::Box; - use esp_idf_sys::*; - use crate::interrupt::asynch::HalIsrNotification; - use crate::adc::ADC1; - use super::*; #[allow(clippy::type_complexity)] @@ -2335,70 +2243,70 @@ mod chip { // NOTE: Gpio26 - Gpio32 (and Gpio33 - Gpio37 if using Octal RAM/Flash) are used // by SPI0/SPI1 for external PSRAM/SPI Flash and are not recommended for // other uses - pin!(Gpio0:0, IO, RTC:0, ADC1:0, NODAC:0, NOTOUCH:0); - pin!(Gpio1:1, IO, RTC:1, ADC1:1, NODAC:0, NOTOUCH:0); - pin!(Gpio2:2, IO, RTC:2, ADC1:2, NODAC:0, NOTOUCH:0); - pin!(Gpio3:3, IO, RTC:3, ADC1:3, NODAC:0, NOTOUCH:0); - pin!(Gpio4:4, IO, RTC:4, ADC1:4, NODAC:0, NOTOUCH:0); - pin!(Gpio5:5, IO, RTC:5, ADC1:5, NODAC:0, NOTOUCH:0); - pin!(Gpio6:6, IO, RTC:6, ADC1:6, NODAC:0, NOTOUCH:0); - pin!(Gpio7:7, IO, RTC:7, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio8:8, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio9:9, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio10:10, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio11:11, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio12:12, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio13:13, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio14:14, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio15:15, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio16:16, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio17:17, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio18:18, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio19:19, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio20:20, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio21:21, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio22:22, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio23:23, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio24:24, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio25:25, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio26:26, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio27:27, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio28:28, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio29:29, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); - pin!(Gpio30:30, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio0:0, IO, RTC:0, ADC1:ADCCH0, NODAC:0, NOTOUCH:0); + pin!(Gpio1:1, IO, RTC:1, ADC1:ADCCH1, NODAC:0, NOTOUCH:0); + pin!(Gpio2:2, IO, RTC:2, ADC1:ADCCH2, NODAC:0, NOTOUCH:0); + pin!(Gpio3:3, IO, RTC:3, ADC1:ADCCH3, NODAC:0, NOTOUCH:0); + pin!(Gpio4:4, IO, RTC:4, ADC1:ADCCH4, NODAC:0, NOTOUCH:0); + pin!(Gpio5:5, IO, RTC:5, ADC1:ADCCH5, NODAC:0, NOTOUCH:0); + pin!(Gpio6:6, IO, RTC:6, ADC1:ADCCH6, NODAC:0, NOTOUCH:0); + pin!(Gpio7:7, IO, RTC:7, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio8:8, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio9:9, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio10:10, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio11:11, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio12:12, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio13:13, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio14:14, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio15:15, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio21:21, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio22:22, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio23:23, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio24:24, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio25:25, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio26:26, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio27:27, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio28:28, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio29:29, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); + pin!(Gpio30:30, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0); pub struct Pins { - pub gpio0: Gpio0, - pub gpio1: Gpio1, - pub gpio2: Gpio2, - pub gpio3: Gpio3, - pub gpio4: Gpio4, - pub gpio5: Gpio5, - pub gpio6: Gpio6, - pub gpio7: Gpio7, - pub gpio8: Gpio8, - pub gpio9: Gpio9, - pub gpio10: Gpio10, - pub gpio11: Gpio11, - pub gpio12: Gpio12, - pub gpio13: Gpio13, - pub gpio14: Gpio14, - pub gpio15: Gpio15, - pub gpio16: Gpio16, - pub gpio17: Gpio17, - pub gpio18: Gpio18, - pub gpio19: Gpio19, - pub gpio20: Gpio20, - pub gpio21: Gpio21, - pub gpio22: Gpio22, - pub gpio23: Gpio23, - pub gpio24: Gpio24, - pub gpio25: Gpio25, - pub gpio26: Gpio26, - pub gpio27: Gpio27, - pub gpio28: Gpio28, - pub gpio29: Gpio29, - pub gpio30: Gpio30, + pub gpio0: Gpio0<'static>, + pub gpio1: Gpio1<'static>, + pub gpio2: Gpio2<'static>, + pub gpio3: Gpio3<'static>, + pub gpio4: Gpio4<'static>, + pub gpio5: Gpio5<'static>, + pub gpio6: Gpio6<'static>, + pub gpio7: Gpio7<'static>, + pub gpio8: Gpio8<'static>, + pub gpio9: Gpio9<'static>, + pub gpio10: Gpio10<'static>, + pub gpio11: Gpio11<'static>, + pub gpio12: Gpio12<'static>, + pub gpio13: Gpio13<'static>, + pub gpio14: Gpio14<'static>, + pub gpio15: Gpio15<'static>, + pub gpio16: Gpio16<'static>, + pub gpio17: Gpio17<'static>, + pub gpio18: Gpio18<'static>, + pub gpio19: Gpio19<'static>, + pub gpio20: Gpio20<'static>, + pub gpio21: Gpio21<'static>, + pub gpio22: Gpio22<'static>, + pub gpio23: Gpio23<'static>, + pub gpio24: Gpio24<'static>, + pub gpio25: Gpio25<'static>, + pub gpio26: Gpio26<'static>, + pub gpio27: Gpio27<'static>, + pub gpio28: Gpio28<'static>, + pub gpio29: Gpio29<'static>, + pub gpio30: Gpio30<'static>, } impl Pins { @@ -2408,37 +2316,37 @@ mod chip { /// already instantiated and used elsewhere pub unsafe fn new() -> Self { Self { - gpio0: Gpio0::new(), - gpio1: Gpio1::new(), - gpio2: Gpio2::new(), - gpio3: Gpio3::new(), - gpio4: Gpio4::new(), - gpio5: Gpio5::new(), - gpio6: Gpio6::new(), - gpio7: Gpio7::new(), - gpio8: Gpio8::new(), - gpio9: Gpio9::new(), - gpio10: Gpio10::new(), - gpio11: Gpio11::new(), - gpio12: Gpio12::new(), - gpio13: Gpio13::new(), - gpio14: Gpio14::new(), - gpio15: Gpio15::new(), - gpio16: Gpio16::new(), - gpio17: Gpio17::new(), - gpio18: Gpio18::new(), - gpio19: Gpio19::new(), - gpio20: Gpio20::new(), - gpio21: Gpio21::new(), - gpio22: Gpio22::new(), - gpio23: Gpio23::new(), - gpio24: Gpio24::new(), - gpio25: Gpio25::new(), - gpio26: Gpio26::new(), - gpio27: Gpio27::new(), - gpio28: Gpio28::new(), - gpio29: Gpio29::new(), - gpio30: Gpio30::new(), + gpio0: Gpio0::steal(), + gpio1: Gpio1::steal(), + gpio2: Gpio2::steal(), + gpio3: Gpio3::steal(), + gpio4: Gpio4::steal(), + gpio5: Gpio5::steal(), + gpio6: Gpio6::steal(), + gpio7: Gpio7::steal(), + gpio8: Gpio8::steal(), + gpio9: Gpio9::steal(), + gpio10: Gpio10::steal(), + gpio11: Gpio11::steal(), + gpio12: Gpio12::steal(), + gpio13: Gpio13::steal(), + gpio14: Gpio14::steal(), + gpio15: Gpio15::steal(), + gpio16: Gpio16::steal(), + gpio17: Gpio17::steal(), + gpio18: Gpio18::steal(), + gpio19: Gpio19::steal(), + gpio20: Gpio20::steal(), + gpio21: Gpio21::steal(), + gpio22: Gpio22::steal(), + gpio23: Gpio23::steal(), + gpio24: Gpio24::steal(), + gpio25: Gpio25::steal(), + gpio26: Gpio26::steal(), + gpio27: Gpio27::steal(), + gpio28: Gpio28::steal(), + gpio29: Gpio29::steal(), + gpio30: Gpio30::steal(), } } } diff --git a/src/hall.rs b/src/hall.rs deleted file mode 100644 index 85f2661dc..000000000 --- a/src/hall.rs +++ /dev/null @@ -1,9 +0,0 @@ -use crate::adc; - -impl embedded_hal_0_2::adc::Channel for HallSensor { - type ID = (); - - fn channel() -> Self::ID {} -} - -crate::impl_peripheral!(HallSensor); diff --git a/src/i2c.rs b/src/i2c.rs index 9e09ffdb9..44bbb2f2e 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -8,7 +8,6 @@ use esp_idf_sys::*; use crate::delay::*; use crate::gpio::*; use crate::interrupt::InterruptType; -use crate::peripheral::Peripheral; use crate::units::*; pub use embedded_hal::i2c::Operation; @@ -210,10 +209,10 @@ pub struct I2cDriver<'d> { } impl<'d> I2cDriver<'d> { - pub fn new( - _i2c: impl Peripheral

+ 'd, - sda: impl Peripheral

+ 'd, - scl: impl Peripheral

+ 'd, + pub fn new( + _i2c: I2C, + sda: impl InputPin + OutputPin + 'd, + scl: impl InputPin + OutputPin + 'd, config: &config::Config, ) -> Result { // i2c_config_t documentation says that clock speed must be no higher than 1 MHz @@ -221,13 +220,11 @@ impl<'d> I2cDriver<'d> { return Err(EspError::from_infallible::()); } - crate::into_ref!(sda, scl); - let sys_config = i2c_config_t { mode: i2c_mode_t_I2C_MODE_MASTER, - sda_io_num: sda.pin(), + sda_io_num: sda.pin() as _, sda_pullup_en: config.sda_pullup_enabled, - scl_io_num: scl.pin(), + scl_io_num: scl.pin() as _, scl_pullup_en: config.scl_pullup_enabled, __bindgen_anon_1: i2c_config_t__bindgen_ty_1 { master: i2c_config_t__bindgen_ty_1__bindgen_ty_1 { @@ -467,20 +464,18 @@ unsafe impl Send for I2cSlaveDriver<'_> {} #[cfg(not(esp32c2))] impl<'d> I2cSlaveDriver<'d> { - pub fn new( - _i2c: impl Peripheral

+ 'd, - sda: impl Peripheral

+ 'd, - scl: impl Peripheral

+ 'd, + pub fn new( + _i2c: I2C, + sda: impl InputPin + OutputPin + 'd, + scl: impl InputPin + OutputPin + 'd, slave_addr: u8, config: &config::SlaveConfig, ) -> Result { - crate::into_ref!(sda, scl); - let sys_config = i2c_config_t { mode: i2c_mode_t_I2C_MODE_SLAVE, - sda_io_num: sda.pin(), + sda_io_num: sda.pin() as _, sda_pullup_en: config.sda_pullup_enabled, - scl_io_num: scl.pin(), + scl_io_num: scl.pin() as _, scl_pullup_en: config.scl_pullup_enabled, __bindgen_anon_1: i2c_config_t__bindgen_ty_1 { slave: i2c_config_t__bindgen_ty_1__bindgen_ty_2 { @@ -600,7 +595,7 @@ macro_rules! impl_i2c { ($i2c:ident: $port:expr) => { crate::impl_peripheral!($i2c); - impl I2c for $i2c { + impl I2c for $i2c<'_> { #[inline(always)] fn port() -> i2c_port_t { $port diff --git a/src/i2s.rs b/src/i2s.rs index 80cc9111a..677f78c67 100644 --- a/src/i2s.rs +++ b/src/i2s.rs @@ -516,9 +516,9 @@ pub trait I2s: Send + sealed::Sealed { mod sealed { pub trait Sealed {} - impl Sealed for super::I2S0 {} + impl Sealed for super::I2S0<'_> {} #[cfg(any(esp32, esp32s3))] - impl Sealed for super::I2S1 {} + impl Sealed for super::I2S1<'_> {} } pub trait I2sPort { @@ -1352,7 +1352,7 @@ macro_rules! impl_i2s { ($i2s:ident: $port:expr) => { crate::impl_peripheral!($i2s); - impl I2s for $i2s { + impl I2s for $i2s<'_> { #[inline(always)] fn port() -> i2s_port_t { $port diff --git a/src/i2s/pdm.rs b/src/i2s/pdm.rs index 98e2cefff..eb4c832b1 100644 --- a/src/i2s/pdm.rs +++ b/src/i2s/pdm.rs @@ -25,7 +25,7 @@ //! See the [`PdmTxSlotConfig documentation`][PdmTxSlotConfig] for more details. use super::*; -use crate::{gpio::*, peripheral::Peripheral}; +use crate::gpio::*; // Note on cfg settings: // esp_idf_soc_i2s_hw_version_1 and esp_idf_soc_i2s_hw_version_2 are defined *only* for ESP-IDF v5.0+. @@ -37,7 +37,7 @@ use esp_idf_sys::*; pub(super) mod config { #[allow(unused)] - use crate::{gpio::*, i2s::config::*, peripheral::*}; + use crate::{gpio::*, i2s::config::*}; use esp_idf_sys::*; /// I2S pulse density modulation (PDM) downsampling mode. @@ -174,8 +174,8 @@ pub(super) mod config { #[inline(always)] pub(super) fn as_sdk<'d>( &self, - clk: PeripheralRef<'d, impl OutputPin>, - din: PeripheralRef<'d, impl InputPin>, + clk: impl OutputPin + 'd, + din: impl InputPin + 'd, ) -> i2s_pdm_rx_config_t { i2s_pdm_rx_config_t { clk_cfg: self.clk_cfg.as_sdk(), @@ -192,10 +192,10 @@ pub(super) mod config { not(all(esp_idf_version_major = "5", esp_idf_version_minor = "0")) ))] #[inline(always)] - pub(super) fn as_sdk_multi<'d>( + pub(super) fn as_sdk_multi<'d, DIN: InputPin + 'd>( &self, - clk: PeripheralRef<'d, impl OutputPin>, - dins: &[PeripheralRef<'d, impl InputPin>], + clk: impl OutputPin + 'd, + dins: &[DIN], ) -> i2s_pdm_rx_config_t { i2s_pdm_rx_config_t { clk_cfg: self.clk_cfg.as_sdk(), @@ -298,8 +298,8 @@ pub(super) mod config { ))] pub(crate) fn as_sdk<'d>( &self, - clk: PeripheralRef<'d, impl OutputPin>, - din: PeripheralRef<'d, impl InputPin>, + clk: impl OutputPin + 'd, + din: impl InputPin + 'd, ) -> i2s_pdm_rx_gpio_config_t { let invert_flags = i2s_pdm_rx_gpio_config_t__bindgen_ty_1 { _bitfield_1: i2s_pdm_rx_gpio_config_t__bindgen_ty_1::new_bitfield_1( @@ -322,13 +322,13 @@ pub(super) mod config { ))] pub(crate) fn as_sdk<'d>( &self, - clk: PeripheralRef<'d, impl OutputPin>, - din: PeripheralRef<'d, impl InputPin>, + clk: impl OutputPin + 'd, + din: impl InputPin + 'd, ) -> i2s_pdm_rx_gpio_config_t { #[allow(clippy::unnecessary_cast)] let mut dins: [gpio_num_t; SOC_I2S_PDM_MAX_RX_LINES as usize] = [-1; SOC_I2S_PDM_MAX_RX_LINES as usize]; - dins[0] = din.pin(); + dins[0] = din.pin() as _; let pins = i2s_pdm_rx_gpio_config_t__bindgen_ty_1 { dins }; @@ -340,7 +340,7 @@ pub(super) mod config { }; i2s_pdm_rx_gpio_config_t { - clk: clk.pin(), + clk: clk.pin() as _, __bindgen_anon_1: pins, invert_flags, } @@ -355,10 +355,10 @@ pub(super) mod config { esp_idf_soc_i2s_supports_pdm_rx, not(all(esp_idf_version_major = "5", esp_idf_version_minor = "0")) ))] - pub(crate) fn as_sdk_multi<'d>( + pub(crate) fn as_sdk_multi<'d, DIN: InputPin + 'd>( &self, - clk: PeripheralRef<'d, impl OutputPin>, - dins: &[PeripheralRef<'d, impl InputPin>], + clk: impl OutputPin + 'd, + dins: &[DIN], ) -> i2s_pdm_rx_gpio_config_t { #[allow(clippy::unnecessary_cast)] let mut din_pins: [gpio_num_t; SOC_I2S_PDM_MAX_RX_LINES as usize] = @@ -370,7 +370,7 @@ pub(super) mod config { break; } - din_pins[i] = din.pin(); + din_pins[i] = din.pin() as _; } let pins = i2s_pdm_rx_gpio_config_t__bindgen_ty_1 { dins: din_pins }; @@ -383,7 +383,7 @@ pub(super) mod config { }; i2s_pdm_rx_gpio_config_t { - clk: clk.pin(), + clk: clk.pin() as _, __bindgen_anon_1: pins, invert_flags, } @@ -710,8 +710,8 @@ pub(super) mod config { #[inline(always)] pub(crate) fn as_sdk<'d>( &self, - clk: PeripheralRef<'d, impl OutputPin>, - dout: PeripheralRef<'d, impl OutputPin>, + clk: impl OutputPin + 'd, + dout: impl OutputPin + 'd, ) -> i2s_pdm_tx_config_t { i2s_pdm_tx_config_t { clk_cfg: self.clk_cfg.as_sdk(), @@ -725,9 +725,9 @@ pub(super) mod config { #[inline(always)] pub(crate) fn as_sdk<'d>( &self, - clk: PeripheralRef<'d, impl OutputPin>, - dout: PeripheralRef<'d, impl OutputPin>, - dout2: Option>, + clk: impl OutputPin + 'd, + dout: impl OutputPin + 'd, + dout2: Option, ) -> i2s_pdm_tx_config_t { i2s_pdm_tx_config_t { clk_cfg: self.clk_cfg.as_sdk(), @@ -823,8 +823,8 @@ pub(super) mod config { #[cfg(esp_idf_soc_i2s_hw_version_1)] pub(crate) fn as_sdk<'d>( &self, - clk: PeripheralRef<'d, impl OutputPin>, - dout: PeripheralRef<'d, impl OutputPin>, + clk: impl OutputPin + 'd, + dout: impl OutputPin + 'd, ) -> i2s_pdm_tx_gpio_config_t { let invert_flags = i2s_pdm_tx_gpio_config_t__bindgen_ty_1 { _bitfield_1: i2s_pdm_tx_gpio_config_t__bindgen_ty_1::new_bitfield_1( @@ -833,8 +833,8 @@ pub(super) mod config { ..Default::default() }; i2s_pdm_tx_gpio_config_t { - clk: clk.pin(), - dout: dout.pin(), + clk: clk.pin() as _, + dout: dout.pin() as _, invert_flags, } } @@ -843,9 +843,9 @@ pub(super) mod config { #[cfg(esp_idf_soc_i2s_hw_version_2)] pub(crate) fn as_sdk<'d>( &self, - clk: PeripheralRef<'d, impl OutputPin>, - dout: PeripheralRef<'d, impl OutputPin>, - dout2: Option>, + clk: impl OutputPin + 'd, + dout: impl OutputPin + 'd, + dout2: Option, ) -> i2s_pdm_tx_gpio_config_t { let invert_flags = i2s_pdm_tx_gpio_config_t__bindgen_ty_1 { _bitfield_1: i2s_pdm_tx_gpio_config_t__bindgen_ty_1::new_bitfield_1( @@ -854,14 +854,14 @@ pub(super) mod config { ..Default::default() }; let dout2 = if let Some(dout2) = dout2 { - dout2.pin() + dout2.pin() as _ } else { -1 }; i2s_pdm_tx_gpio_config_t { - clk: clk.pin(), - dout: dout.pin(), + clk: clk.pin() as _, + dout: dout.pin() as _, dout2, invert_flags, } @@ -1203,17 +1203,17 @@ impl<'d> I2sDriver<'d, I2sRx> { /// Create a new pulse density modulation (PDM) mode driver for the given I2S peripheral with only the receive /// channel open. #[allow(clippy::too_many_arguments)] - pub fn new_pdm_rx( - _i2s: impl Peripheral

+ 'd, + pub fn new_pdm_rx( + _i2s: I2S, rx_cfg: &config::PdmRxConfig, - clk: impl Peripheral

+ 'd, - din: impl Peripheral

+ 'd, + clk: impl OutputPin + 'd, + din: impl InputPin + 'd, ) -> Result { let chan_cfg = rx_cfg.channel_cfg.as_sdk(I2S::port()); let this = Self::internal_new::(&chan_cfg, true, false)?; - let rx_cfg = rx_cfg.as_sdk(clk.into_ref(), din.into_ref()); + let rx_cfg = rx_cfg.as_sdk(clk, din); // Safety: rx.chan_handle is a valid, non-null i2s_chan_handle_t, // and &rx_cfg is a valid pointer to an i2s_pdm_rx_config_t. @@ -1236,41 +1236,22 @@ impl<'d> I2sDriver<'d, I2sRx> { doc(cfg(not(all(esp_idf_version_major = "5", esp_idf_version_minor = "0")))) )] #[allow(clippy::too_many_arguments)] - pub fn new_pdm_rx_multi( - _i2s: I2SP, + pub fn new_pdm_rx_multi( + _i2s: I2S, rx_cfg: &config::PdmRxConfig, - clk: CLKP, - dins: [DINP; DINC], + clk: impl OutputPin + 'd, + dins: [DIN; DINC], ) -> Result where - I2SP: Peripheral

+ 'd, - I2S: I2s, - CLKP: Peripheral

+ 'd, - CLK: OutputPin, - DINP: Peripheral

+ 'd, - DIN: InputPin + Sized, + I2S: I2s + 'd, + DIN: InputPin + 'd, { let chan_cfg = rx_cfg.channel_cfg.as_sdk(I2S::port()); let this = Self::internal_new::(&chan_cfg, true, true)?; - // Safety: assume_init is safe to call because we are only claiming to have "initialized" the - // MaybeUninit, not the PeripheralRef itself. - let mut dins_ref: [MaybeUninit>; DINC] = - unsafe { MaybeUninit::uninit().assume_init() }; - for (i, din) in IntoIterator::into_iter(dins).enumerate() { - dins_ref[i].write(din.into_ref()); - } - - // Safety: everything is initialized, so we can safely transmute the array to the initialized type. - let dins_ref = unsafe { - core::mem::transmute_copy::<_, [crate::peripheral::PeripheralRef<'d, DIN>; DINC]>( - &dins_ref, - ) - }; - // Create the channel configuration. - let rx_cfg = rx_cfg.as_sdk_multi(clk.into_ref(), &dins_ref); + let rx_cfg = rx_cfg.as_sdk_multi(clk, &dins); // Safety: rx.chan_handle is a valid, non-null i2s_chan_handle_t, // and &rx_cfg is a valid pointer to an i2s_pdm_rx_config_t. @@ -1295,11 +1276,11 @@ impl<'d> I2sDriver<'d, I2sRx> { /// Create a new pulse density modulation (PDM) mode driver for the given I2S peripheral with only the receive /// channel open. #[allow(clippy::too_many_arguments)] - pub fn new_pdm_rx( - _i2s: impl Peripheral

+ 'd, + pub fn new_pdm_rx( + _i2s: I2S, rx_cfg: &config::PdmRxConfig, - clk: impl Peripheral

+ 'd, - din: impl Peripheral

+ 'd, + clk: impl OutputPin + 'd, + din: impl InputPin + 'd, ) -> Result { let driver_cfg = rx_cfg.as_sdk(); @@ -1313,8 +1294,8 @@ impl<'d> I2sDriver<'d, I2sRx> { // Set the pin configuration. let pin_cfg = i2s_pin_config_t { - bck_io_num: clk.into_ref().pin(), - data_in_num: din.into_ref().pin(), + bck_io_num: clk.pin() as _, + data_in_num: din.pin() as _, data_out_num: -1, mck_io_num: -1, ws_io_num: -1, @@ -1341,14 +1322,12 @@ impl<'d> I2sDriver<'d, I2sTx> { /// Create a new pulse density modulation (PDM) mode driver for the given I2S peripheral with only the transmit /// channel open. #[allow(clippy::too_many_arguments)] - pub fn new_pdm_tx( - _i2s: impl Peripheral

+ 'd, + pub fn new_pdm_tx( + _i2s: I2S, tx_cfg: &config::PdmTxConfig, - clk: impl Peripheral

+ 'd, - dout: impl Peripheral

+ 'd, - #[cfg(esp_idf_soc_i2s_hw_version_2)] dout2: Option< - impl Peripheral

+ 'd, - >, + clk: impl OutputPin + 'd, + dout: impl OutputPin + 'd, + #[cfg(esp_idf_soc_i2s_hw_version_2)] dout2: Option, ) -> Result { let chan_cfg = tx_cfg.channel_cfg.as_sdk(I2S::port()); @@ -1356,10 +1335,10 @@ impl<'d> I2sDriver<'d, I2sTx> { // Create the channel configuration. let tx_cfg = tx_cfg.as_sdk( - clk.into_ref(), - dout.into_ref(), + clk, + dout, #[cfg(esp_idf_soc_i2s_hw_version_2)] - dout2.map(|dout2| dout2.into_ref()), + dout2, ); // Safety: tx.chan_handle is a valid, non-null i2s_chan_handle_t, @@ -1391,11 +1370,11 @@ impl<'d> I2sDriver<'d, I2sTx> { /// Create a new pulse density modulation (PDM) mode driver for the given I2S peripheral with only the transmit /// channel open. #[allow(clippy::too_many_arguments)] - pub fn new_pdm_tx( - _i2s: impl Peripheral

+ 'd, + pub fn new_pdm_tx( + _i2s: I2S, tx_cfg: &config::PdmTxConfig, - clk: impl Peripheral

+ 'd, - dout: impl Peripheral

+ 'd, + clk: impl OutputPin + 'd, + dout: impl OutputPin + 'd, ) -> Result { let driver_cfg = tx_cfg.as_sdk(); @@ -1412,9 +1391,9 @@ impl<'d> I2sDriver<'d, I2sTx> { // Set the pin configuration. let pin_cfg = i2s_pin_config_t { - bck_io_num: clk.into_ref().pin(), + bck_io_num: clk.pin() as _, data_in_num: -1, - data_out_num: dout.into_ref().pin(), + data_out_num: dout.pin() as _, mck_io_num: -1, ws_io_num: -1, }; diff --git a/src/i2s/std.rs b/src/i2s/std.rs index 71a3f9251..882a113ee 100644 --- a/src/i2s/std.rs +++ b/src/i2s/std.rs @@ -13,13 +13,13 @@ //! | ESP32-H2 | I2S0 | I2S0 | use super::*; -use crate::{gpio::*, peripheral::*}; +use crate::gpio::*; use esp_idf_sys::*; pub(super) mod config { #[allow(unused)] - use crate::{gpio::*, i2s::config::*, peripheral::*}; + use crate::{gpio::*, i2s::config::*}; use esp_idf_sys::*; /// Standard mode configuration for the I2S peripheral. @@ -104,11 +104,11 @@ pub(super) mod config { #[inline(always)] pub(crate) fn as_sdk<'d>( &self, - bclk: PeripheralRef<'d, impl InputPin + OutputPin>, - din: Option>, - dout: Option>, - mclk: Option>, - ws: PeripheralRef<'d, impl InputPin + OutputPin>, + bclk: impl InputPin + OutputPin + 'd, + din: Option, + dout: Option, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> i2s_std_config_t { i2s_std_config_t { clk_cfg: self.clk_cfg.as_sdk(), @@ -316,11 +316,11 @@ pub(super) mod config { #[cfg(not(esp_idf_version_major = "4"))] pub(crate) fn as_sdk<'d>( &self, - bclk: PeripheralRef<'d, impl InputPin + OutputPin>, - din: Option>, - dout: Option>, - mclk: Option>, - ws: PeripheralRef<'d, impl InputPin + OutputPin>, + bclk: impl InputPin + OutputPin + 'd, + din: Option, + dout: Option, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> i2s_std_gpio_config_t { let invert_flags = i2s_std_gpio_config_t__bindgen_ty_1 { _bitfield_1: i2s_std_gpio_config_t__bindgen_ty_1::new_bitfield_1( @@ -332,19 +332,23 @@ pub(super) mod config { }; i2s_std_gpio_config_t { - bclk: bclk.pin(), - din: if let Some(din) = din { din.pin() } else { -1 }, + bclk: bclk.pin() as _, + din: if let Some(din) = din { + din.pin() as _ + } else { + -1 + }, dout: if let Some(dout) = dout { - dout.pin() + dout.pin() as _ } else { -1 }, mclk: if let Some(mclk) = mclk { - mclk.pin() + mclk.pin() as _ } else { -1 }, - ws: ws.pin(), + ws: ws.pin() as _, invert_flags, } } @@ -709,29 +713,23 @@ pub(super) mod config { impl<'d, Dir> I2sDriver<'d, Dir> { #[cfg(not(esp_idf_version_major = "4"))] #[allow(clippy::too_many_arguments)] - fn internal_new_std( - _i2s: impl Peripheral

+ 'd, + fn internal_new_std( + _i2s: I2S, config: &config::StdConfig, rx: bool, tx: bool, - bclk: impl Peripheral

+ 'd, - din: Option + 'd>, - dout: Option + 'd>, - mclk: Option + 'd>, - ws: impl Peripheral

+ 'd, + bclk: impl InputPin + OutputPin + 'd, + din: Option, + dout: Option, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> Result { let chan_cfg = config.channel_cfg.as_sdk(I2S::port()); let this = Self::internal_new::(&chan_cfg, rx, tx)?; // Create the channel configuration. - let std_config = config.as_sdk( - bclk.into_ref(), - din.map(|d_in| d_in.into_ref()), - dout.map(|d_out| d_out.into_ref()), - mclk.map(|m_clk| m_clk.into_ref()), - ws.into_ref(), - ); + let std_config = config.as_sdk(bclk, din, dout, mclk, ws); if rx { unsafe { @@ -752,16 +750,16 @@ impl<'d, Dir> I2sDriver<'d, Dir> { #[cfg(esp_idf_version_major = "4")] #[allow(clippy::too_many_arguments)] - pub fn internal_new_std( - _i2s: impl Peripheral

+ 'd, + pub fn internal_new_std( + _i2s: I2S, config: &config::StdConfig, rx: bool, tx: bool, - bclk: impl Peripheral

+ 'd, - din: Option + 'd>, - dout: Option + 'd>, - mclk: Option + 'd>, - ws: impl Peripheral

+ 'd, + bclk: impl InputPin + OutputPin + 'd, + din: Option, + dout: Option, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> Result { let mut driver_cfg = config.as_sdk(); @@ -777,11 +775,11 @@ impl<'d, Dir> I2sDriver<'d, Dir> { // Set the pin configuration. let pin_cfg = i2s_pin_config_t { - bck_io_num: bclk.into_ref().pin(), - data_in_num: din.map(|din| din.into_ref().pin()).unwrap_or(-1), - data_out_num: dout.map(|dout| dout.into_ref().pin()).unwrap_or(-1), - mck_io_num: mclk.map(|mclk| mclk.into_ref().pin()).unwrap_or(-1), - ws_io_num: ws.into_ref().pin(), + bck_io_num: bclk.pin() as _, + data_in_num: din.map(|din| din.pin() as _).unwrap_or(-1), + data_out_num: dout.map(|dout| dout.pin() as _).unwrap_or(-1), + mck_io_num: mclk.map(|mclk| mclk.pin() as _).unwrap_or(-1), + ws_io_num: ws.pin() as _, }; // Safety: &pin_cfg is a valid pointer to an i2s_pin_config_t. @@ -796,14 +794,14 @@ impl<'d, Dir> I2sDriver<'d, Dir> { impl<'d> I2sDriver<'d, I2sBiDir> { /// Create a new standard mode driver for the given I2S peripheral with both the receive and transmit channels open. #[allow(clippy::too_many_arguments)] - pub fn new_std_bidir( - i2s: impl Peripheral

+ 'd, + pub fn new_std_bidir( + i2s: I2S, config: &config::StdConfig, - bclk: impl Peripheral

+ 'd, - din: impl Peripheral

+ 'd, - dout: impl Peripheral

+ 'd, - mclk: Option + 'd>, - ws: impl Peripheral

+ 'd, + bclk: impl InputPin + OutputPin + 'd, + din: impl InputPin + 'd, + dout: impl OutputPin + 'd, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> Result { Self::internal_new_std( i2s, @@ -822,13 +820,13 @@ impl<'d> I2sDriver<'d, I2sBiDir> { impl<'d> I2sDriver<'d, I2sRx> { /// Create a new standard mode driver for the given I2S peripheral with only the receive channel open. #[allow(clippy::too_many_arguments)] - pub fn new_std_rx( - i2s: impl Peripheral

+ 'd, + pub fn new_std_rx( + i2s: I2S, config: &config::StdConfig, - bclk: impl Peripheral

+ 'd, - din: impl Peripheral

+ 'd, - mclk: Option + 'd>, - ws: impl Peripheral

+ 'd, + bclk: impl InputPin + OutputPin + 'd, + din: impl InputPin + 'd, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> Result { Self::internal_new_std( i2s, @@ -847,13 +845,13 @@ impl<'d> I2sDriver<'d, I2sRx> { impl<'d> I2sDriver<'d, I2sTx> { /// Create a new standard mode driver for the given I2S peripheral with only the transmit channel open. #[allow(clippy::too_many_arguments)] - pub fn new_std_tx( - i2s: impl Peripheral

+ 'd, + pub fn new_std_tx( + i2s: I2S, config: &config::StdConfig, - bclk: impl Peripheral

+ 'd, - dout: impl Peripheral

+ 'd, - mclk: Option + 'd>, - ws: impl Peripheral

+ 'd, + bclk: impl InputPin + OutputPin + 'd, + dout: impl OutputPin + 'd, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> Result { Self::internal_new_std( i2s, diff --git a/src/i2s/tdm.rs b/src/i2s/tdm.rs index dc04704f0..d012ab86b 100644 --- a/src/i2s/tdm.rs +++ b/src/i2s/tdm.rs @@ -1,12 +1,12 @@ //! Time-division multiplexing (TDM) support for I2S. use super::*; -use crate::{gpio::*, peripheral::*}; +use crate::gpio::*; use esp_idf_sys::*; pub(super) mod config { #[allow(unused)] - use crate::{gpio::*, i2s::config::*, peripheral::*}; + use crate::{gpio::*, i2s::config::*}; use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not}; use esp_idf_sys::*; @@ -57,11 +57,11 @@ pub(super) mod config { #[inline(always)] pub(super) fn as_sdk<'d>( &self, - bclk: PeripheralRef<'d, impl InputPin + OutputPin>, - din: Option>, - dout: Option>, - mclk: Option>, - ws: PeripheralRef<'d, impl InputPin + OutputPin>, + bclk: impl InputPin + OutputPin + 'd, + din: Option, + dout: Option, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> i2s_tdm_config_t { i2s_tdm_config_t { clk_cfg: self.clk_cfg.as_sdk(), @@ -284,11 +284,11 @@ pub(super) mod config { #[cfg(not(esp_idf_version_major = "4"))] pub(crate) fn as_sdk<'d>( &self, - bclk: PeripheralRef<'d, impl InputPin + OutputPin>, - din: Option>, - dout: Option>, - mclk: Option>, - ws: PeripheralRef<'d, impl InputPin + OutputPin>, + bclk: impl InputPin + OutputPin + 'd, + din: Option, + dout: Option, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> i2s_tdm_gpio_config_t { let invert_flags = i2s_tdm_gpio_config_t__bindgen_ty_1 { _bitfield_1: i2s_tdm_gpio_config_t__bindgen_ty_1::new_bitfield_1( @@ -300,19 +300,23 @@ pub(super) mod config { }; i2s_tdm_gpio_config_t { - bclk: bclk.pin(), - din: if let Some(din) = din { din.pin() } else { -1 }, + bclk: bclk.pin() as _, + din: if let Some(din) = din { + din.pin() as _ + } else { + -1 + }, dout: if let Some(dout) = dout { - dout.pin() + dout.pin() as _ } else { -1 }, mclk: if let Some(mclk) = mclk { - mclk.pin() + mclk.pin() as _ } else { -1 }, - ws: ws.pin(), + ws: ws.pin() as _, invert_flags, } } @@ -967,29 +971,23 @@ pub(super) mod config { impl<'d, Dir> I2sDriver<'d, Dir> { #[cfg(not(esp_idf_version_major = "4"))] #[allow(clippy::too_many_arguments)] - fn internal_new_tdm( - _i2s: impl Peripheral

+ 'd, + fn internal_new_tdm( + _i2s: I2S, config: &config::TdmConfig, rx: bool, tx: bool, - bclk: impl Peripheral

+ 'd, - din: Option + 'd>, - dout: Option + 'd>, - mclk: Option + 'd>, - ws: impl Peripheral

+ 'd, + bclk: impl InputPin + OutputPin + 'd, + din: Option, + dout: Option, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> Result { let chan_cfg = config.channel_cfg.as_sdk(I2S::port()); let this = Self::internal_new::(&chan_cfg, rx, tx)?; // Create the channel configuration. - let tdm_config = config.as_sdk( - bclk.into_ref(), - din.map(|d_in| d_in.into_ref()), - dout.map(|d_out| d_out.into_ref()), - mclk.map(|m_clk| m_clk.into_ref()), - ws.into_ref(), - ); + let tdm_config = config.as_sdk(bclk, din, dout, mclk, ws); if rx { unsafe { @@ -1010,16 +1008,16 @@ impl<'d, Dir> I2sDriver<'d, Dir> { #[cfg(esp_idf_version_major = "4")] #[allow(clippy::too_many_arguments)] - fn internal_new_tdm( - _i2s: impl Peripheral

+ 'd, + fn internal_new_tdm( + _i2s: I2S, config: &config::TdmConfig, rx: bool, tx: bool, - bclk: impl Peripheral

+ 'd, - din: Option + 'd>, - dout: Option + 'd>, - mclk: Option + 'd>, - ws: impl Peripheral

+ 'd, + bclk: impl InputPin + OutputPin + 'd, + din: Option, + dout: Option, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> Result { let mut driver_cfg = config.as_sdk(); @@ -1035,11 +1033,11 @@ impl<'d, Dir> I2sDriver<'d, Dir> { // Set the pin configuration. let pin_cfg = i2s_pin_config_t { - bck_io_num: bclk.into_ref().pin(), - data_in_num: din.map(|din| din.into_ref().pin()).unwrap_or(-1), - data_out_num: dout.map(|dout| dout.into_ref().pin()).unwrap_or(-1), - mck_io_num: mclk.map(|mclk| mclk.into_ref().pin()).unwrap_or(-1), - ws_io_num: ws.into_ref().pin(), + bck_io_num: bclk.pin() as _, + data_in_num: din.map(|din| din.pin() as _).unwrap_or(-1), + data_out_num: dout.map(|dout| dout.pin() as _).unwrap_or(-1), + mck_io_num: mclk.map(|mclk| mclk.pin() as _).unwrap_or(-1), + ws_io_num: ws.pin() as _, }; // Safety: &pin_cfg is a valid pointer to an i2s_pin_config_t. @@ -1056,14 +1054,14 @@ impl<'d> I2sDriver<'d, I2sBiDir> { #[cfg(not(any(esp32, esp32s2)))] #[cfg_attr(feature = "nightly", doc(cfg(not(any(esp32, esp32s2)))))] #[allow(clippy::too_many_arguments)] - pub fn new_tdm_bidir( - i2s: impl Peripheral

+ 'd, + pub fn new_tdm_bidir( + i2s: I2S, config: &config::TdmConfig, - bclk: impl Peripheral

+ 'd, - din: impl Peripheral

+ 'd, - dout: impl Peripheral

+ 'd, - mclk: Option + 'd>, - ws: impl Peripheral

+ 'd, + bclk: impl InputPin + OutputPin + 'd, + din: impl InputPin + 'd, + dout: impl OutputPin + 'd, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> Result { Self::internal_new_tdm( i2s, @@ -1084,13 +1082,13 @@ impl<'d> I2sDriver<'d, I2sRx> { #[cfg(not(any(esp32, esp32s2)))] #[cfg_attr(feature = "nightly", doc(cfg(not(any(esp32, esp32s2)))))] #[allow(clippy::too_many_arguments)] - pub fn new_tdm_rx( - i2s: impl Peripheral

+ 'd, + pub fn new_tdm_rx( + i2s: I2S, config: &config::TdmConfig, - bclk: impl Peripheral

+ 'd, - din: impl Peripheral

+ 'd, - mclk: Option + 'd>, - ws: impl Peripheral

+ 'd, + bclk: impl InputPin + OutputPin + 'd, + din: impl InputPin + 'd, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> Result { Self::internal_new_tdm( i2s, @@ -1111,13 +1109,13 @@ impl<'d> I2sDriver<'d, I2sTx> { #[cfg(not(any(esp32, esp32s2)))] #[cfg_attr(feature = "nightly", doc(cfg(not(any(esp32, esp32s2)))))] #[allow(clippy::too_many_arguments)] - pub fn new_tdm_tx( - i2s: impl Peripheral

+ 'd, + pub fn new_tdm_tx( + i2s: I2S, config: &config::TdmConfig, - bclk: impl Peripheral

+ 'd, - dout: impl Peripheral

+ 'd, - mclk: Option + 'd>, - ws: impl Peripheral

+ 'd, + bclk: impl InputPin + OutputPin + 'd, + dout: impl OutputPin + 'd, + mclk: Option, + ws: impl InputPin + OutputPin + 'd, ) -> Result { Self::internal_new_tdm( i2s, diff --git a/src/ledc.rs b/src/ledc.rs index f491c2631..8f0e82093 100644 --- a/src/ledc.rs +++ b/src/ledc.rs @@ -29,7 +29,6 @@ use core::sync::atomic::{AtomicBool, Ordering}; use esp_idf_sys::*; use crate::gpio::OutputPin; -use crate::peripheral::{Peripheral, PeripheralRef}; use crate::task::CriticalSection; use crate::units::*; @@ -90,25 +89,24 @@ pub mod config { } /// LED Control timer driver -pub struct LedcTimerDriver<'d, T> +pub struct LedcTimerDriver<'d, S> where - T: LedcTimer, + S: SpeedMode, { - _timer: PeripheralRef<'d, T>, max_duty: Duty, + timer: u8, + _speed: PhantomData, _p: PhantomData<&'d mut ()>, } -impl<'d, T> LedcTimerDriver<'d, T> +impl<'d, S> LedcTimerDriver<'d, S> where - T: LedcTimer, + S: SpeedMode, { - pub fn new( - timer: impl Peripheral

+ 'd, + pub fn new + 'd>( + _timer: T, config: &config::TimerConfig, ) -> Result { - crate::into_ref!(timer); - let timer_config = ledc_timer_config_t { speed_mode: T::SpeedMode::SPEED_MODE, timer_num: T::timer() as _, @@ -135,50 +133,51 @@ where esp!(unsafe { ledc_timer_config(&timer_config) })?; Ok(Self { - _timer: timer, max_duty: config.resolution.max_duty(), + timer: T::timer() as _, + _speed: PhantomData, _p: PhantomData, }) } /// Pauses the timer. Operation can be resumed with [`resume_timer()`]. pub fn pause(&mut self) -> Result<(), EspError> { - esp!(unsafe { ledc_timer_pause(T::SpeedMode::SPEED_MODE, self.timer()) })?; + esp!(unsafe { ledc_timer_pause(S::SPEED_MODE, self.timer()) })?; Ok(()) } /// Resumes the operation of the previously paused timer pub fn resume(&mut self) -> Result<(), EspError> { - esp!(unsafe { ledc_timer_resume(T::SpeedMode::SPEED_MODE, self.timer()) })?; + esp!(unsafe { ledc_timer_resume(S::SPEED_MODE, self.timer()) })?; Ok(()) } /// Set the frequency of the timer. pub fn set_frequency(&mut self, frequency: Hertz) -> Result<(), EspError> { - esp!(unsafe { ledc_set_freq(T::SpeedMode::SPEED_MODE, T::timer(), frequency.into()) })?; + esp!(unsafe { ledc_set_freq(S::SPEED_MODE, self.timer(), frequency.into()) })?; Ok(()) } fn reset(&mut self) -> Result<(), EspError> { - esp!(unsafe { ledc_timer_rst(T::SpeedMode::SPEED_MODE, T::timer()) })?; + esp!(unsafe { ledc_timer_rst(S::SPEED_MODE, self.timer()) })?; Ok(()) } pub fn timer(&self) -> ledc_timer_t { - T::timer() + self.timer as _ } } -impl Drop for LedcTimerDriver<'_, T> +impl Drop for LedcTimerDriver<'_, S> where - T: LedcTimer, + S: SpeedMode, { fn drop(&mut self) { self.reset().unwrap(); } } -unsafe impl Send for LedcTimerDriver<'_, T> where T: LedcTimer {} +unsafe impl Send for LedcTimerDriver<'_, S> where S: SpeedMode {} /// LED Control driver pub struct LedcDriver<'d> { @@ -196,15 +195,14 @@ pub struct LedcDriver<'d> { // and implementing Drop. impl<'d> LedcDriver<'d> { /// Creates a new LED Control driver - pub fn new( - _channel: impl Peripheral

+ 'd, + pub fn new( + _channel: C, timer_driver: B, - pin: impl Peripheral

+ 'd, + pin: impl OutputPin + 'd, ) -> Result where - C: LedcChannel::SpeedMode>, - T: LedcTimer + 'd, - B: Borrow>, + C: LedcChannel + 'd, + B: Borrow>, { if !FADE_FUNC_INSTALLED.load(Ordering::SeqCst) { let _guard = FADE_FUNC_INSTALLED_CS.enter(); @@ -225,7 +223,7 @@ impl<'d> LedcDriver<'d> { let mut driver = LedcDriver { duty: 0, hpoint: 0, - speed_mode: T::SpeedMode::SPEED_MODE, + speed_mode: C::SpeedMode::SPEED_MODE, max_duty: timer_driver.borrow().max_duty, timer: timer_driver.borrow().timer() as _, channel: C::channel() as _, @@ -239,18 +237,13 @@ impl<'d> LedcDriver<'d> { /// Applies LEDC configuration with a specific pin /// Can be used to reconfigure the LEDC driver with a different pin - pub fn config_with_pin( - &mut self, - pin: impl Peripheral

+ 'd, - ) -> Result<(), EspError> { - crate::into_ref!(pin); - + pub fn config_with_pin(&mut self, pin: impl OutputPin + 'd) -> Result<(), EspError> { let channel_config = ledc_channel_config_t { speed_mode: self.speed_mode, channel: self.channel as u32, timer_sel: self.timer as u32, intr_type: ledc_intr_type_t_LEDC_INTR_DISABLE, - gpio_num: pin.pin(), + gpio_num: pin.pin() as _, duty: self.duty, hpoint: self.hpoint as _, ..Default::default() @@ -624,7 +617,7 @@ mod chip { ($typ:ty; $instance:ident: $timer:expr) => { crate::impl_peripheral!($instance); - impl LedcTimer for $instance { + impl LedcTimer for $instance<'_> { type SpeedMode = $typ; fn timer() -> ledc_timer_t { @@ -652,7 +645,7 @@ mod chip { ($typ:ty; $instance:ident: $channel:expr) => { crate::impl_peripheral!($instance); - impl LedcChannel for $instance { + impl LedcChannel for $instance<'_> { type SpeedMode = $typ; fn channel() -> ledc_channel_t { @@ -692,20 +685,20 @@ mod chip { /// The LED Control device peripheral pub struct LEDC { - pub timer0: TIMER0, - pub timer1: TIMER1, - pub timer2: TIMER2, - pub timer3: TIMER3, - pub channel0: CHANNEL0, - pub channel1: CHANNEL1, - pub channel2: CHANNEL2, - pub channel3: CHANNEL3, - pub channel4: CHANNEL4, - pub channel5: CHANNEL5, + pub timer0: TIMER0<'static>, + pub timer1: TIMER1<'static>, + pub timer2: TIMER2<'static>, + pub timer3: TIMER3<'static>, + pub channel0: CHANNEL0<'static>, + pub channel1: CHANNEL1<'static>, + pub channel2: CHANNEL2<'static>, + pub channel3: CHANNEL3<'static>, + pub channel4: CHANNEL4<'static>, + pub channel5: CHANNEL5<'static>, #[cfg(any(esp32, esp32s2, esp32s3, esp8684))] - pub channel6: CHANNEL6, + pub channel6: CHANNEL6<'static>, #[cfg(any(esp32, esp32s2, esp32s3, esp8684))] - pub channel7: CHANNEL7, + pub channel7: CHANNEL7<'static>, } impl LEDC { @@ -718,22 +711,22 @@ mod chip { /// /// It is safe to instantiate the LEDC peripheral exactly one time. /// Care has to be taken that this has not already been done elsewhere. - pub unsafe fn new() -> Self { + pub(crate) unsafe fn new() -> Self { Self { - timer0: TIMER0::new(), - timer1: TIMER1::new(), - timer2: TIMER2::new(), - timer3: TIMER3::new(), - channel0: CHANNEL0::new(), - channel1: CHANNEL1::new(), - channel2: CHANNEL2::new(), - channel3: CHANNEL3::new(), - channel4: CHANNEL4::new(), - channel5: CHANNEL5::new(), + timer0: TIMER0::steal(), + timer1: TIMER1::steal(), + timer2: TIMER2::steal(), + timer3: TIMER3::steal(), + channel0: CHANNEL0::steal(), + channel1: CHANNEL1::steal(), + channel2: CHANNEL2::steal(), + channel3: CHANNEL3::steal(), + channel4: CHANNEL4::steal(), + channel5: CHANNEL5::steal(), #[cfg(any(esp32, esp32s2, esp32s3, esp8684))] - channel6: CHANNEL6::new(), + channel6: CHANNEL6::steal(), #[cfg(any(esp32, esp32s2, esp32s3, esp8684))] - channel7: CHANNEL7::new(), + channel7: CHANNEL7::steal(), } } } @@ -741,18 +734,18 @@ mod chip { /// The LED Control device peripheral (high speed channels, ESP32 only) #[cfg(esp32)] pub struct HLEDC { - pub timer0: HTIMER0, - pub timer1: HTIMER1, - pub timer2: HTIMER2, - pub timer3: HTIMER3, - pub channel0: HCHANNEL0, - pub channel1: HCHANNEL1, - pub channel2: HCHANNEL2, - pub channel3: HCHANNEL3, - pub channel4: HCHANNEL4, - pub channel5: HCHANNEL5, - pub channel6: HCHANNEL6, - pub channel7: HCHANNEL7, + pub timer0: HTIMER0<'static>, + pub timer1: HTIMER1<'static>, + pub timer2: HTIMER2<'static>, + pub timer3: HTIMER3<'static>, + pub channel0: HCHANNEL0<'static>, + pub channel1: HCHANNEL1<'static>, + pub channel2: HCHANNEL2<'static>, + pub channel3: HCHANNEL3<'static>, + pub channel4: HCHANNEL4<'static>, + pub channel5: HCHANNEL5<'static>, + pub channel6: HCHANNEL6<'static>, + pub channel7: HCHANNEL7<'static>, } #[cfg(esp32)] @@ -766,20 +759,20 @@ mod chip { /// /// It is safe to instantiate the HLEDC peripheral exactly one time. /// Care has to be taken that this has not already been done elsewhere. - pub unsafe fn new() -> Self { + pub(crate) unsafe fn new() -> Self { Self { - timer0: HTIMER0::new(), - timer1: HTIMER1::new(), - timer2: HTIMER2::new(), - timer3: HTIMER3::new(), - channel0: HCHANNEL0::new(), - channel1: HCHANNEL1::new(), - channel2: HCHANNEL2::new(), - channel3: HCHANNEL3::new(), - channel4: HCHANNEL4::new(), - channel5: HCHANNEL5::new(), - channel6: HCHANNEL6::new(), - channel7: HCHANNEL7::new(), + timer0: HTIMER0::steal(), + timer1: HTIMER1::steal(), + timer2: HTIMER2::steal(), + timer3: HTIMER3::steal(), + channel0: HCHANNEL0::steal(), + channel1: HCHANNEL1::steal(), + channel2: HCHANNEL2::steal(), + channel3: HCHANNEL3::steal(), + channel4: HCHANNEL4::steal(), + channel5: HCHANNEL5::steal(), + channel6: HCHANNEL6::steal(), + channel7: HCHANNEL7::steal(), } } } diff --git a/src/lib.rs b/src/lib.rs index d52853ceb..417df29c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,8 +30,6 @@ pub mod can; pub mod cpu; pub mod delay; pub mod gpio; -#[cfg(all(esp32, esp_idf_version_major = "4"))] -pub mod hall; pub mod i2c; #[cfg_attr( feature = "nightly", @@ -53,9 +51,7 @@ pub mod onewire; #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3, esp32c6))] pub mod pcnt; -pub mod peripheral; pub mod peripherals; -pub mod prelude; pub mod reset; pub mod rmt; pub mod rom; @@ -131,50 +127,39 @@ macro_rules! embedded_hal_error { }; } -#[macro_export] -#[allow(unused_macros)] -macro_rules! into_ref { - ($($name:ident),*) => { - $( - let $name = $name.into_ref(); - )* - } -} - -#[allow(unused_macros)] -macro_rules! impl_peripheral_trait { - ($type:ident) => { - unsafe impl Send for $type {} - - impl $crate::peripheral::sealed::Sealed for $type {} - - impl $crate::peripheral::Peripheral for $type { - type P = $type; - - #[inline] - unsafe fn clone_unchecked(&mut self) -> Self::P { - $type { ..*self } - } - } - }; -} - #[allow(unused_macros)] macro_rules! impl_peripheral { - ($type:ident) => { - pub struct $type(::core::marker::PhantomData<*const ()>); + ($name:ident) => { + pub struct $name<'a>(::core::marker::PhantomData<&'a mut ()>); - impl $type { + impl $name<'_> { + /// Unsafely create an instance of this peripheral out of thin air. + /// /// # Safety /// - /// Care should be taken not to instantiate this peripheral instance, if it is already instantiated and used elsewhere + /// You must ensure that you're only using one instance of this type at a time. #[inline(always)] - pub unsafe fn new() -> Self { - $type(::core::marker::PhantomData) + pub unsafe fn steal() -> Self { + Self(::core::marker::PhantomData) + } + + /// Creates a new peripheral reference with a shorter lifetime. + /// + /// Use this method if you would like to keep working with the peripheral after + /// you dropped the driver that consumes this. + /// + /// # Safety + /// + /// You must ensure that you are not using reborrowed peripherals in drivers which are + /// forgotten via `core::mem::forget`. + #[inline] + #[allow(dead_code)] + pub unsafe fn reborrow(&mut self) -> $name<'_> { + Self(::core::marker::PhantomData) } } - $crate::impl_peripheral_trait!($type); + unsafe impl Send for $name<'_> {} }; } @@ -182,5 +167,3 @@ macro_rules! impl_peripheral { pub(crate) use embedded_hal_error; #[allow(unused_imports)] pub(crate) use impl_peripheral; -#[allow(unused_imports)] -pub(crate) use impl_peripheral_trait; diff --git a/src/modem.rs b/src/modem.rs index a04b835bb..f1ac76746 100644 --- a/src/modem.rs +++ b/src/modem.rs @@ -1,112 +1,72 @@ -use core::marker::PhantomData; - -use crate::peripheral::{sealed, Peripheral}; - #[cfg(not(esp32s2))] pub use split::*; +use crate::impl_peripheral; + #[cfg(not(any(esp32h2, esp32h4)))] -pub trait WifiModemPeripheral: Peripheral

{} +pub trait WifiModemPeripheral {} #[cfg(any(esp32h2, esp32h4, esp32c6))] -pub trait ThreadModemPeripheral: Peripheral

{} +pub trait ThreadModemPeripheral {} #[cfg(not(esp32s2))] -pub trait BluetoothModemPeripheral: Peripheral

{} +pub trait BluetoothModemPeripheral {} -#[cfg(not(any(esp32s2, esp32h2, esp32h4, esp32c6)))] -pub struct Modem(PhantomData<*const ()>, WifiModem, BluetoothModem); +impl_peripheral!(Modem); -#[cfg(any(esp32h2, esp32h4))] -pub struct Modem(PhantomData<*const ()>, ThreadModem, BluetoothModem); - -#[cfg(esp32c6)] -pub struct Modem( - PhantomData<*const ()>, - WifiModem, - ThreadModem, - BluetoothModem, -); - -#[cfg(esp32s2)] -pub struct Modem(PhantomData<*const ()>); - -impl Modem { - /// # Safety - /// - /// Care should be taken not to instantiate this Mac instance, if it is already instantiated and used elsewhere - pub unsafe fn new() -> Self { - #[cfg(not(any(esp32s2, esp32h2, esp32h4, esp32c6)))] - let this = Modem(PhantomData, WifiModem::new(), BluetoothModem::new()); - - #[cfg(any(esp32h2, esp32h4))] - let this = Modem(PhantomData, ThreadModem::new(), BluetoothModem::new()); - - #[cfg(esp32c6)] - let this = Modem( - PhantomData, - WifiModem::new(), - ThreadModem::new(), - BluetoothModem::new(), - ); - - #[cfg(esp32s2)] - let this = Modem(PhantomData); - - this +#[allow(clippy::needless_lifetimes)] +impl<'d> Modem<'d> { + #[cfg(not(any(esp32s2, esp32h2, esp32h4, esp32c6)))] + pub fn split(self) -> (WifiModem<'d>, BluetoothModem<'d>) { + unsafe { (WifiModem::steal(), BluetoothModem::steal()) } } #[cfg(not(any(esp32s2, esp32h2, esp32h4, esp32c6)))] - pub fn split(self) -> (WifiModem, BluetoothModem) { - unsafe { (WifiModem::new(), BluetoothModem::new()) } - } - - #[cfg(not(any(esp32s2, esp32h2, esp32h4, esp32c6)))] - pub fn split_ref(&mut self) -> (&mut WifiModem, &mut BluetoothModem) { - (&mut self.1, &mut self.2) + pub fn split_reborrow(&mut self) -> (WifiModem<'_>, BluetoothModem<'_>) { + unsafe { (WifiModem::steal(), BluetoothModem::steal()) } } #[cfg(any(esp32h2, esp32h4))] - pub fn split(self) -> (ThreadModem, BluetoothModem) { - unsafe { (ThreadModem::new(), BluetoothModem::new()) } + pub fn split(self) -> (ThreadModem<'d>, BluetoothModem<'d>) { + unsafe { (ThreadModem::steal(), BluetoothModem::steal()) } } #[cfg(any(esp32h2, esp32h4))] - pub fn split_ref(&mut self) -> (&mut ThreadModem, &mut BluetoothModem) { - (&mut self.1, &mut self.2) + pub fn split_reborrow(&mut self) -> (ThreadModem<'_>, BluetoothModem<'_>) { + unsafe { (ThreadModem::steal(), BluetoothModem::steal()) } } #[cfg(esp32c6)] - pub fn split(self) -> (WifiModem, ThreadModem, BluetoothModem) { - unsafe { (WifiModem::new(), ThreadModem::new(), BluetoothModem::new()) } + pub fn split(self) -> (WifiModem<'d>, ThreadModem<'d>, BluetoothModem<'d>) { + unsafe { + ( + WifiModem::steal(), + ThreadModem::steal(), + BluetoothModem::steal(), + ) + } } #[cfg(esp32c6)] - pub fn split_ref(&mut self) -> (&mut WifiModem, &mut ThreadModem, &mut BluetoothModem) { - (&mut self.1, &mut self.2, &mut self.3) - } -} - -unsafe impl Send for Modem {} - -impl sealed::Sealed for Modem {} - -impl Peripheral for Modem { - type P = Self; - - unsafe fn clone_unchecked(&mut self) -> Self::P { - Self::new() + pub fn split_reborrow(&mut self) -> (WifiModem<'_>, ThreadModem<'_>, BluetoothModem<'_>) { + unsafe { + ( + WifiModem::steal(), + ThreadModem::steal(), + BluetoothModem::steal(), + ) + } } } #[cfg(not(esp32h2))] -impl WifiModemPeripheral for Modem {} +impl WifiModemPeripheral for Modem<'_> {} #[cfg(any(esp32h2, esp32c6))] -impl ThreadModemPeripheral for Modem {} +impl ThreadModemPeripheral for Modem<'_> {} #[cfg(not(esp32s2))] -impl BluetoothModemPeripheral for Modem {} +impl BluetoothModemPeripheral for Modem<'_> {} #[cfg(not(esp32s2))] mod split { @@ -114,15 +74,15 @@ mod split { crate::impl_peripheral!(WifiModem); #[cfg(not(esp32h2))] - impl super::WifiModemPeripheral for WifiModem {} + impl super::WifiModemPeripheral for WifiModem<'_> {} #[cfg(any(esp32h2, esp32c6))] crate::impl_peripheral!(ThreadModem); #[cfg(any(esp32h2, esp32c6))] - impl super::ThreadModemPeripheral for ThreadModem {} + impl super::ThreadModemPeripheral for ThreadModem<'_> {} crate::impl_peripheral!(BluetoothModem); - impl super::BluetoothModemPeripheral for BluetoothModem {} + impl super::BluetoothModemPeripheral for BluetoothModem<'_> {} } diff --git a/src/onewire.rs b/src/onewire.rs index f086868a1..450bcc422 100644 --- a/src/onewire.rs +++ b/src/onewire.rs @@ -23,7 +23,6 @@ use core::ptr; use esp_idf_sys::*; -use crate::peripheral::Peripheral; use crate::rmt::RmtChannel; /// Onewire Address type @@ -95,13 +94,13 @@ impl<'a> OWDriver<'a> { /// Create a new One Wire driver on the allocated pin. /// /// The pin will be used as an open drain output. - pub fn new( - pin: impl Peripheral

+ 'a, - _channel: impl Peripheral

+ 'a, + pub fn new( + pin: impl crate::gpio::InputPin + crate::gpio::OutputPin + 'a, + _channel: C, ) -> Result { let mut bus: onewire_bus_handle_t = ptr::null_mut(); - let pin = pin.into_ref().pin(); + let pin = pin.pin() as _; let bus_config = esp_idf_sys::onewire_bus_config_t { bus_gpio_num: pin }; let rmt_config = esp_idf_sys::onewire_bus_rmt_config_t { max_rx_bytes: 10 }; diff --git a/src/pcnt.rs b/src/pcnt.rs index b23e251fb..6e1ab1fc1 100644 --- a/src/pcnt.rs +++ b/src/pcnt.rs @@ -12,7 +12,6 @@ use esp_idf_sys::*; use enumset::EnumSetType; use crate::gpio::InputPin; -use crate::peripheral::Peripheral; #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum PcntChannel { @@ -136,22 +135,19 @@ pub struct PcntDriver<'d> { macro_rules! pin_to_number { ($pin:ident) => { match $pin { - Some(pin) => { - crate::into_ref!(pin); - pin.pin() - } + Some(pin) => pin.pin() as _, None => PCNT_PIN_NOT_USED, } }; } impl<'d> PcntDriver<'d> { - pub fn new( - _pcnt: impl Peripheral

+ 'd, - pin0: Option + 'd>, - pin1: Option + 'd>, - pin2: Option + 'd>, - pin3: Option + 'd>, + pub fn new( + _pcnt: PCNT, + pin0: Option, + pin1: Option, + pin2: Option, + pin3: Option, ) -> Result { // consume the pins and keep only the pin number. let pins = [ @@ -360,8 +356,8 @@ impl<'d> PcntDriver<'d> { // pub fn set_pin<'a>( // &mut self, // channel: PcntChannel, - // pulse_pin: Option + 'a>, - // ctrl_pin: Option + 'a>, + // pulse_pin: Option, + // ctrl_pin: Option, // ) -> Result<(), EspError> { // } @@ -637,7 +633,7 @@ macro_rules! impl_pcnt { ($pcnt:ident: $unit:expr) => { crate::impl_peripheral!($pcnt); - impl Pcnt for $pcnt { + impl Pcnt for $pcnt<'_> { #[inline(always)] fn unit() -> pcnt_unit_t { $unit diff --git a/src/peripheral.rs b/src/peripheral.rs deleted file mode 100644 index 9eb1cb9cb..000000000 --- a/src/peripheral.rs +++ /dev/null @@ -1,179 +0,0 @@ -use core::marker::PhantomData; -use core::ops::{Deref, DerefMut}; - -/// An exclusive reference to a peripheral. -/// -/// This is functionally the same as a `&'a mut T`. The reason for having a -/// dedicated struct is memory efficiency: -/// -/// Peripheral singletons are typically either zero-sized (for concrete peripehrals -/// like `PA9` or `Spi4`) or very small (for example `AnyPin` which is 1 byte). -/// However `&mut T` is always 4 bytes for 32-bit targets, even if T is zero-sized. -/// PeripheralRef stores a copy of `T` instead, so it's the same size. -/// -/// but it is the size of `T` not the size -/// of a pointer. This is useful if T is a zero sized type. -pub struct PeripheralRef<'a, T> { - inner: T, - _lifetime: PhantomData<&'a mut T>, -} - -impl<'a, T> PeripheralRef<'a, T> { - #[inline] - pub fn new(inner: T) -> Self { - Self { - inner, - _lifetime: PhantomData, - } - } - - /// Unsafely clone (duplicate) a peripheral singleton. - /// - /// # Safety - /// - /// This returns an owned clone of the peripheral. You must manually ensure - /// only one copy of the peripheral is in use at a time. For example, don't - /// create two SPI drivers on `SPI1`, because they will "fight" each other. - /// - /// You should strongly prefer using `reborrow()` instead. It returns a - /// `PeripheralRef` that borrows `self`, which allows the borrow checker - /// to enforce this at compile time. - pub unsafe fn clone_unchecked(&mut self) -> PeripheralRef<'a, T> - where - T: Peripheral

, - { - PeripheralRef::new(self.inner.clone_unchecked()) - } - - /// Reborrow into a "child" PeripheralRef. - /// - /// `self` will stay borrowed until the child PeripheralRef is dropped. - pub fn reborrow(&mut self) -> PeripheralRef<'_, T> - where - T: Peripheral

, - { - // safety: we're returning the clone inside a new PeripheralRef that borrows - // self, so user code can't use both at the same time. - PeripheralRef::new(unsafe { self.inner.clone_unchecked() }) - } - - /// Map the inner peripheral using `Into`. - /// - /// This converts from `PeripheralRef<'a, T>` to `PeripheralRef<'a, U>`, using an - /// `Into` impl to convert from `T` to `U`. - /// - /// For example, this can be useful to degrade GPIO pins: converting from PeripheralRef<'a, PB11>` to `PeripheralRef<'a, AnyPin>`. - #[inline] - pub fn map_into(self) -> PeripheralRef<'a, U> - where - T: Into, - { - PeripheralRef { - inner: self.inner.into(), - _lifetime: PhantomData, - } - } -} - -impl Deref for PeripheralRef<'_, T> { - type Target = T; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl DerefMut for PeripheralRef<'_, T> { - #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner - } -} - -/// Trait for any type that can be used as a peripheral of type `P`. -/// -/// This is used in driver constructors, to allow passing either owned peripherals (e.g. `TWISPI0`), -/// or borrowed peripherals (e.g. `&mut TWISPI0`). -/// -/// For example, if you have a driver with a constructor like this: -/// -/// ```ignore -/// impl<'d, T: Instance> Twim<'d, T> { -/// pub fn new( -/// twim: impl Peripheral

+ 'd, -/// irq: impl Peripheral

+ 'd, -/// sda: impl Peripheral

+ 'd, -/// scl: impl Peripheral

+ 'd, -/// config: Config, -/// ) -> Self { .. } -/// } -/// ``` -/// -/// You may call it with owned peripherals, which yields an instance that can live forever (`'static`): -/// -/// ```ignore -/// let mut twi: Twim<'static, ...> = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config); -/// ``` -/// -/// Or you may call it with borrowed peripherals, which yields an instance that can only live for as long -/// as the borrows last: -/// -/// ```ignore -/// let mut twi: Twim<'_, ...> = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config); -/// ``` -/// -/// # Implementation details, for HAL authors -/// -/// When writing a HAL, the intended way to use this trait is to take `impl Peripheral

` in -/// the HAL's public API (such as driver constructors), calling `.into_ref()` to obtain a `PeripheralRef`, -/// and storing that in the driver struct. -/// -/// `.into_ref()` on an owned `T` yields a `PeripheralRef<'static, T>`. -/// `.into_ref()` on an `&'a mut T` yields a `PeripheralRef<'a, T>`. -pub trait Peripheral: Sized + sealed::Sealed { - /// Peripheral singleton type - type P; - - /// Unsafely clone (duplicate) a peripheral singleton. - /// - /// # Safety - /// - /// This returns an owned clone of the peripheral. You must manually ensure - /// only one copy of the peripheral is in use at a time. For example, don't - /// create two SPI drivers on `SPI1`, because they will "fight" each other. - /// - /// You should strongly prefer using `into_ref()` instead. It returns a - /// `PeripheralRef`, which allows the borrow checker to enforce this at compile time. - unsafe fn clone_unchecked(&mut self) -> Self::P; - - /// Convert a value into a `PeripheralRef`. - /// - /// When called on an owned `T`, yields a `PeripheralRef<'static, T>`. - /// When called on an `&'a mut T`, yields a `PeripheralRef<'a, T>`. - #[inline] - fn into_ref<'a>(mut self) -> PeripheralRef<'a, Self::P> - where - Self: 'a, - { - PeripheralRef::new(unsafe { self.clone_unchecked() }) - } -} - -impl sealed::Sealed for T {} - -impl Peripheral for T -where - T::Target: Peripheral, -{ - type P = ::P; - - #[inline] - unsafe fn clone_unchecked(&mut self) -> Self::P { - self.deref_mut().clone_unchecked() - } -} - -pub(crate) mod sealed { - pub trait Sealed {} -} diff --git a/src/peripherals.rs b/src/peripherals.rs index c167b3275..b099dac07 100644 --- a/src/peripherals.rs +++ b/src/peripherals.rs @@ -38,52 +38,50 @@ use crate::usb_serial; pub struct Peripherals { pub pins: gpio::Pins, - pub uart0: uart::UART0, - pub uart1: uart::UART1, + pub uart0: uart::UART0<'static>, + pub uart1: uart::UART1<'static>, #[cfg(any(esp32, esp32s3))] - pub uart2: uart::UART2, - pub i2c0: i2c::I2C0, + pub uart2: uart::UART2<'static>, + pub i2c0: i2c::I2C0<'static>, #[cfg(not(any(esp32c3, esp32c2, esp32c6)))] - pub i2c1: i2c::I2C1, + pub i2c1: i2c::I2C1<'static>, #[cfg(esp_idf_soc_i2s_supported)] - pub i2s0: i2s::I2S0, + pub i2s0: i2s::I2S0<'static>, #[cfg(all(esp_idf_soc_i2s_supported, any(esp32, esp32s3)))] - pub i2s1: i2s::I2S1, - pub spi1: spi::SPI1, - pub spi2: spi::SPI2, + pub i2s1: i2s::I2S1<'static>, + pub spi1: spi::SPI1<'static>, + pub spi2: spi::SPI2<'static>, #[cfg(any(esp32, esp32s2, esp32s3))] - pub spi3: spi::SPI3, - pub adc1: adc::ADC1, + pub spi3: spi::SPI3<'static>, + pub adc1: adc::ADC1<'static>, #[cfg(any(esp32, esp32s2, esp32s3, esp32c3))] - pub adc2: adc::ADC2, + pub adc2: adc::ADC2<'static>, // TODO: Check the pulse counter story for c2, h2, c5, and p4 #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3, esp32c6))] - pub pcnt0: pcnt::PCNT0, + pub pcnt0: pcnt::PCNT0<'static>, #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3, esp32c6))] - pub pcnt1: pcnt::PCNT1, + pub pcnt1: pcnt::PCNT1<'static>, #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3, esp32c6))] - pub pcnt2: pcnt::PCNT2, + pub pcnt2: pcnt::PCNT2<'static>, #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3, esp32c6))] - pub pcnt3: pcnt::PCNT3, + pub pcnt3: pcnt::PCNT3<'static>, #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(esp32)] - pub pcnt4: pcnt::PCNT4, + pub pcnt4: pcnt::PCNT4<'static>, #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(esp32)] - pub pcnt5: pcnt::PCNT5, + pub pcnt5: pcnt::PCNT5<'static>, #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(esp32)] - pub pcnt6: pcnt::PCNT6, + pub pcnt6: pcnt::PCNT6<'static>, #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(esp32)] - pub pcnt7: pcnt::PCNT7, - #[cfg(all(esp32, esp_idf_version_major = "4"))] - pub hall_sensor: crate::hall::HallSensor, - pub can: can::CAN, + pub pcnt7: pcnt::PCNT7<'static>, + pub can: can::CAN<'static>, pub ledc: ledc::LEDC, #[cfg(esp32)] pub hledc: ledc::HLEDC, @@ -92,28 +90,28 @@ pub struct Peripherals { any(esp32, esp32s2, esp32s3, esp32c6, esp32p4), esp_idf_comp_ulp_enabled ))] - pub ulp: ulp::ULP, + pub ulp: ulp::ULP<'static>, #[cfg(any(all(esp32, esp_idf_eth_use_esp32_emac), esp_idf_eth_use_openeth))] - pub mac: mac::MAC, - pub modem: modem::Modem, + pub mac: mac::MAC<'static>, + pub modem: modem::Modem<'static>, #[cfg(esp_idf_soc_sdmmc_host_supported)] - pub sdmmc0: sd::mmc::SDMMC0, + pub sdmmc0: sd::mmc::SDMMC0<'static>, #[cfg(esp_idf_soc_sdmmc_host_supported)] - pub sdmmc1: sd::mmc::SDMMC1, + pub sdmmc1: sd::mmc::SDMMC1<'static>, #[cfg(all(esp_idf_soc_temp_sensor_supported, esp_idf_version_major = "5"))] - pub temp_sensor: temp_sensor::TempSensor, + pub temp_sensor: temp_sensor::TempSensor<'static>, // TODO: Check the timer story for c2, h2, c5, c6, and p4 #[cfg(not(esp_idf_version_at_least_6_0_0))] - pub timer00: timer::TIMER00, + pub timer00: timer::TIMER00<'static>, #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3))] - pub timer01: timer::TIMER01, + pub timer01: timer::TIMER01<'static>, #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(not(esp32c2))] - pub timer10: timer::TIMER10, + pub timer10: timer::TIMER10<'static>, #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3))] - pub timer11: timer::TIMER11, + pub timer11: timer::TIMER11<'static>, #[cfg(any( all( not(any(esp_idf_version_major = "4", esp_idf_version = "5.0")), @@ -121,9 +119,9 @@ pub struct Peripherals { ), any(esp_idf_version_major = "4", esp_idf_version = "5.0") ))] - pub twdt: watchdog::TWDT, + pub twdt: watchdog::TWDT<'static>, #[cfg(esp_idf_soc_usb_serial_jtag_supported)] - pub usb_serial: usb_serial::USB_SERIAL, + pub usb_serial: usb_serial::USB_SERIAL<'static>, } static TAKEN: core::sync::atomic::AtomicBool = core::sync::atomic::AtomicBool::new(false); @@ -141,7 +139,7 @@ impl Peripherals { if !TAKEN.load(core::sync::atomic::Ordering::SeqCst) { TAKEN.store(true, core::sync::atomic::Ordering::SeqCst); - Ok(unsafe { Peripherals::new() }) + Ok(unsafe { Peripherals::steal() }) } else { Err(crate::sys::EspError::from_infallible::< { crate::sys::ESP_ERR_INVALID_STATE }, @@ -153,54 +151,52 @@ impl Peripherals { /// # Safety /// /// Care should be taken not to instantiate the Peripherals structure, if it is already instantiated and used elsewhere - pub unsafe fn new() -> Self { + pub unsafe fn steal() -> Self { Self { pins: gpio::Pins::new(), - uart0: uart::UART0::new(), - uart1: uart::UART1::new(), + uart0: uart::UART0::steal(), + uart1: uart::UART1::steal(), #[cfg(any(esp32, esp32s3))] - uart2: uart::UART2::new(), - i2c0: i2c::I2C0::new(), + uart2: uart::UART2::steal(), + i2c0: i2c::I2C0::steal(), #[cfg(not(any(esp32c3, esp32c2, esp32c6)))] - i2c1: i2c::I2C1::new(), + i2c1: i2c::I2C1::steal(), #[cfg(esp_idf_soc_i2s_supported)] - i2s0: i2s::I2S0::new(), + i2s0: i2s::I2S0::steal(), #[cfg(all(esp_idf_soc_i2s_supported, any(esp32, esp32s3)))] - i2s1: i2s::I2S1::new(), - spi1: spi::SPI1::new(), - spi2: spi::SPI2::new(), + i2s1: i2s::I2S1::steal(), + spi1: spi::SPI1::steal(), + spi2: spi::SPI2::steal(), #[cfg(any(esp32, esp32s2, esp32s3))] - spi3: spi::SPI3::new(), - adc1: adc::ADC1::new(), + spi3: spi::SPI3::steal(), + adc1: adc::ADC1::steal(), #[cfg(any(esp32, esp32s2, esp32s3, esp32c3))] - adc2: adc::ADC2::new(), + adc2: adc::ADC2::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3, esp32c6))] - pcnt0: pcnt::PCNT0::new(), + pcnt0: pcnt::PCNT0::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3, esp32c6))] - pcnt1: pcnt::PCNT1::new(), + pcnt1: pcnt::PCNT1::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3, esp32c6))] - pcnt2: pcnt::PCNT2::new(), + pcnt2: pcnt::PCNT2::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3, esp32c6))] - pcnt3: pcnt::PCNT3::new(), + pcnt3: pcnt::PCNT3::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(esp32)] - pcnt4: pcnt::PCNT4::new(), + pcnt4: pcnt::PCNT4::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(esp32)] - pcnt5: pcnt::PCNT5::new(), + pcnt5: pcnt::PCNT5::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(esp32)] - pcnt6: pcnt::PCNT6::new(), + pcnt6: pcnt::PCNT6::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(esp32)] - pcnt7: pcnt::PCNT7::new(), - #[cfg(all(esp32, esp_idf_version_major = "4"))] - hall_sensor: crate::hall::HallSensor::new(), - can: can::CAN::new(), + pcnt7: pcnt::PCNT7::steal(), + can: can::CAN::steal(), ledc: ledc::LEDC::new(), #[cfg(esp32)] hledc: ledc::HLEDC::new(), @@ -209,27 +205,27 @@ impl Peripherals { any(esp32, esp32s2, esp32s3, esp32c6, esp32p4), esp_idf_comp_ulp_enabled ))] - ulp: ulp::ULP::new(), + ulp: ulp::ULP::steal(), #[cfg(any(all(esp32, esp_idf_eth_use_esp32_emac), esp_idf_eth_use_openeth))] - mac: mac::MAC::new(), - modem: modem::Modem::new(), + mac: mac::MAC::steal(), + modem: modem::Modem::steal(), #[cfg(esp_idf_soc_sdmmc_host_supported)] - sdmmc0: sd::mmc::SDMMC0::new(), + sdmmc0: sd::mmc::SDMMC0::steal(), #[cfg(esp_idf_soc_sdmmc_host_supported)] - sdmmc1: sd::mmc::SDMMC1::new(), + sdmmc1: sd::mmc::SDMMC1::steal(), #[cfg(all(esp_idf_soc_temp_sensor_supported, esp_idf_version_major = "5"))] - temp_sensor: temp_sensor::TempSensor::new(), + temp_sensor: temp_sensor::TempSensor::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] - timer00: timer::TIMER00::new(), + timer00: timer::TIMER00::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3))] - timer01: timer::TIMER01::new(), + timer01: timer::TIMER01::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(not(esp32c2))] - timer10: timer::TIMER10::new(), + timer10: timer::TIMER10::steal(), #[cfg(not(esp_idf_version_at_least_6_0_0))] #[cfg(any(esp32, esp32s2, esp32s3))] - timer11: timer::TIMER11::new(), + timer11: timer::TIMER11::steal(), #[cfg(any( all( not(any(esp_idf_version_major = "4", esp_idf_version = "5.0")), @@ -237,9 +233,9 @@ impl Peripherals { ), any(esp_idf_version_major = "4", esp_idf_version = "5.0") ))] - twdt: watchdog::TWDT::new(), + twdt: watchdog::TWDT::steal(), #[cfg(esp_idf_soc_usb_serial_jtag_supported)] - usb_serial: usb_serial::USB_SERIAL::new(), + usb_serial: usb_serial::USB_SERIAL::steal(), } } } diff --git a/src/prelude.rs b/src/prelude.rs deleted file mode 100644 index 3446780c7..000000000 --- a/src/prelude.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! The prelude. -//! -//! To use the esp_idf_hal effectively, a lot of traits and types need to be imported. -//! Instead of importing them one by one manually, the prelude contains the most -//! commonly used imports that are used around application runtime management. -//! -//! This can be imported as `use esp_idf_hal::prelude::*`. - -pub use crate::peripherals::*; -pub use crate::units::*; diff --git a/src/rmt.rs b/src/rmt.rs index e723912a6..3aa9fbd1f 100644 --- a/src/rmt.rs +++ b/src/rmt.rs @@ -721,9 +721,8 @@ mod driver { }; use esp_idf_sys::{rmt_channel_t, rmt_driver_uninstall}; - use crate::gpio::InputPin; + use crate::gpio::{InputPin, OutputPin}; use crate::interrupt::InterruptType; - use crate::{gpio::OutputPin, peripheral::Peripheral}; use super::RmtChannel; @@ -745,13 +744,11 @@ mod driver { /// To uninstall the driver just drop it. /// /// Internally this calls `rmt_config()` and `rmt_driver_install()`. - pub fn new( - _channel: impl Peripheral

+ 'd, - pin: impl Peripheral

+ 'd, + pub fn new( + _channel: C, + pin: impl OutputPin + 'd, config: &TransmitConfig, ) -> Result { - crate::into_ref!(pin); - let mut flags = 0; if config.aware_dfs { flags |= RMT_CHANNEL_FLAGS_AWARE_DFS; @@ -763,7 +760,7 @@ mod driver { let sys_config = rmt_config_t { rmt_mode: rmt_mode_t_RMT_MODE_TX, channel: C::channel(), - gpio_num: pin.pin(), + gpio_num: pin.pin() as _, clk_div: config.clock_divider, mem_block_num: config.mem_block_num, flags, @@ -1025,14 +1022,12 @@ mod driver { /// To uninstall the driver just drop it. /// /// Internally this calls `rmt_config()` and `rmt_driver_install()`. - pub fn new( - _channel: impl Peripheral

+ 'd, - pin: impl Peripheral

+ 'd, + pub fn new( + _channel: C, + pin: impl InputPin + 'd, config: &ReceiveConfig, ring_buf_size: usize, ) -> Result { - crate::into_ref!(pin); - #[cfg(not(any(esp32, esp32c2)))] let carrier_en = config.carrier.is_some(); @@ -1042,7 +1037,7 @@ mod driver { let sys_config = rmt_config_t { rmt_mode: rmt_mode_t_RMT_MODE_RX, channel: C::channel(), - gpio_num: pin.pin(), + gpio_num: pin.pin() as _, clk_div: config.clock_divider, mem_block_num: config.mem_block_num, flags: 0, @@ -1197,7 +1192,7 @@ mod chip { ($instance:ident: $channel:expr) => { crate::impl_peripheral!($instance); - impl RmtChannel for $instance { + impl RmtChannel for $instance<'_> { fn channel() -> rmt_channel_t { $channel } @@ -1221,18 +1216,18 @@ mod chip { impl_channel!(CHANNEL7: rmt_channel_t_RMT_CHANNEL_7); pub struct RMT { - pub channel0: CHANNEL0, - pub channel1: CHANNEL1, - pub channel2: CHANNEL2, - pub channel3: CHANNEL3, + pub channel0: CHANNEL0<'static>, + pub channel1: CHANNEL1<'static>, + pub channel2: CHANNEL2<'static>, + pub channel3: CHANNEL3<'static>, #[cfg(any(esp32, esp32s3))] - pub channel4: CHANNEL4, + pub channel4: CHANNEL4<'static>, #[cfg(any(esp32, esp32s3))] - pub channel5: CHANNEL5, + pub channel5: CHANNEL5<'static>, #[cfg(any(esp32, esp32s3))] - pub channel6: CHANNEL6, + pub channel6: CHANNEL6<'static>, #[cfg(any(esp32, esp32s3))] - pub channel7: CHANNEL7, + pub channel7: CHANNEL7<'static>, } impl RMT { @@ -1245,20 +1240,20 @@ mod chip { /// /// It is safe to instantiate the RMT peripheral exactly one time. /// Care has to be taken that this has not already been done elsewhere. - pub unsafe fn new() -> Self { + pub(crate) unsafe fn new() -> Self { Self { - channel0: CHANNEL0::new(), - channel1: CHANNEL1::new(), - channel2: CHANNEL2::new(), - channel3: CHANNEL3::new(), + channel0: CHANNEL0::steal(), + channel1: CHANNEL1::steal(), + channel2: CHANNEL2::steal(), + channel3: CHANNEL3::steal(), #[cfg(any(esp32, esp32s3))] - channel4: CHANNEL4::new(), + channel4: CHANNEL4::steal(), #[cfg(any(esp32, esp32s3))] - channel5: CHANNEL5::new(), + channel5: CHANNEL5::steal(), #[cfg(any(esp32, esp32s3))] - channel6: CHANNEL6::new(), + channel6: CHANNEL6::steal(), #[cfg(any(esp32, esp32s3))] - channel7: CHANNEL7::new(), + channel7: CHANNEL7::steal(), } } } diff --git a/src/sd/mmc.rs b/src/sd/mmc.rs index 00ced8d86..b0b6801b9 100644 --- a/src/sd/mmc.rs +++ b/src/sd/mmc.rs @@ -1,9 +1,7 @@ use core::marker::PhantomData; -use core::ops::Deref; use core::sync::atomic::{AtomicU8, Ordering}; use crate::gpio::{self, InputPin, OutputPin}; -use crate::peripheral::Peripheral; use crate::sys::*; /// Indicates that card detect line is not used @@ -69,13 +67,13 @@ impl<'d> SdMmcHostDriver<'d> { /// Create a new driver for the provided slot peripheral with data line width 1. #[cfg(esp_idf_soc_sdmmc_use_gpio_matrix)] #[allow(clippy::too_many_arguments)] - pub fn new_1bit( - slot: impl Peripheral

+ 'd, - cmd: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd, - d0: impl Peripheral

+ 'd, - cd: Option + 'd>, - wp: Option + 'd>, + pub fn new_1bit( + slot: impl SdMmc + 'd, + cmd: impl OutputPin + 'd, + clk: impl OutputPin + 'd, + d0: impl InputPin + OutputPin + 'd, + cd: Option, + wp: Option, config: &config::Configuration, ) -> Result { Self::new_internal( @@ -100,16 +98,16 @@ impl<'d> SdMmcHostDriver<'d> { /// Create a new driver for the provided slot peripheral with data line width 4. #[cfg(esp_idf_soc_sdmmc_use_gpio_matrix)] #[allow(clippy::too_many_arguments)] - pub fn new_4bits( - slot: impl Peripheral

+ 'd, - cmd: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd, - d0: impl Peripheral

+ 'd, - d1: impl Peripheral

+ 'd, - d2: impl Peripheral

+ 'd, - d3: impl Peripheral

+ 'd, - cd: Option + 'd>, - wp: Option + 'd>, + pub fn new_4bits( + slot: S, + cmd: impl OutputPin + 'd, + clk: impl OutputPin + 'd, + d0: impl InputPin + OutputPin + 'd, + d1: impl InputPin + OutputPin + 'd, + d2: impl InputPin + OutputPin + 'd, + d3: impl InputPin + OutputPin + 'd, + cd: Option, + wp: Option, config: &config::Configuration, ) -> Result { Self::new_internal( @@ -134,20 +132,20 @@ impl<'d> SdMmcHostDriver<'d> { /// Create a new driver for the provided slot peripheral with data line width 8. #[cfg(esp_idf_soc_sdmmc_use_gpio_matrix)] #[allow(clippy::too_many_arguments)] - pub fn new_8bits( - slot: impl Peripheral

+ 'd, - cmd: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd, - d0: impl Peripheral

+ 'd, - d1: impl Peripheral

+ 'd, - d2: impl Peripheral

+ 'd, - d3: impl Peripheral

+ 'd, - d4: impl Peripheral

+ 'd, - d5: impl Peripheral

+ 'd, - d6: impl Peripheral

+ 'd, - d7: impl Peripheral

+ 'd, - cd: Option + 'd>, - wp: Option + 'd>, + pub fn new_8bits( + slot: S, + cmd: impl OutputPin + 'd, + clk: impl OutputPin + 'd, + d0: impl InputPin + OutputPin + 'd, + d1: impl InputPin + OutputPin + 'd, + d2: impl InputPin + OutputPin + 'd, + d3: impl InputPin + OutputPin + 'd, + d4: impl InputPin + OutputPin + 'd, + d5: impl InputPin + OutputPin + 'd, + d6: impl InputPin + OutputPin + 'd, + d7: impl InputPin + OutputPin + 'd, + cd: Option, + wp: Option, config: &config::Configuration, ) -> Result { Self::new_internal( @@ -173,12 +171,12 @@ impl<'d> SdMmcHostDriver<'d> { #[cfg(not(esp_idf_soc_sdmmc_use_gpio_matrix))] #[allow(clippy::too_many_arguments)] pub fn new_slot0_1bit( - slot0: impl Peripheral

+ 'd, - cmd: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd, - d0: impl Peripheral

+ 'd, - cd: Option + 'd>, - wp: Option + 'd>, + slot0: SDMMC0<'d>, + cmd: gpio::Gpio11<'d>, + clk: gpio::Gpio6<'d>, + d0: gpio::Gpio7<'d>, + cd: Option, + wp: Option, config: &config::Configuration, ) -> Result { Self::new_internal( @@ -204,15 +202,15 @@ impl<'d> SdMmcHostDriver<'d> { #[cfg(not(esp_idf_soc_sdmmc_use_gpio_matrix))] #[allow(clippy::too_many_arguments)] pub fn new_slot0_4bits( - slot0: impl Peripheral

+ 'd, - cmd: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd, - d0: impl Peripheral

+ 'd, - d1: impl Peripheral

+ 'd, - d2: impl Peripheral

+ 'd, - d3: impl Peripheral

+ 'd, - cd: Option + 'd>, - wp: Option + 'd>, + slot0: SDMMC0<'d>, + cmd: gpio::Gpio11<'d>, + clk: gpio::Gpio6<'d>, + d0: gpio::Gpio7<'d>, + d1: gpio::Gpio8<'d>, + d2: gpio::Gpio9<'d>, + d3: gpio::Gpio10<'d>, + cd: Option, + wp: Option, config: &config::Configuration, ) -> Result { Self::new_internal( @@ -238,19 +236,19 @@ impl<'d> SdMmcHostDriver<'d> { #[cfg(not(esp_idf_soc_sdmmc_use_gpio_matrix))] #[allow(clippy::too_many_arguments)] pub fn new_slot0_8bits( - slot0: impl Peripheral

+ 'd, - cmd: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd, - d0: impl Peripheral

+ 'd, - d1: impl Peripheral

+ 'd, - d2: impl Peripheral

+ 'd, - d3: impl Peripheral

+ 'd, - d4: impl Peripheral

+ 'd, - d5: impl Peripheral

+ 'd, - d6: impl Peripheral

+ 'd, - d7: impl Peripheral

+ 'd, - cd: Option + 'd>, - wp: Option + 'd>, + slot0: SDMMC0<'d>, + cmd: gpio::Gpio11<'d>, + clk: gpio::Gpio6<'d>, + d0: gpio::Gpio7<'d>, + d1: gpio::Gpio8<'d>, + d2: gpio::Gpio9<'d>, + d3: gpio::Gpio10<'d>, + d4: gpio::Gpio16<'d>, + d5: gpio::Gpio17<'d>, + d6: gpio::Gpio5<'d>, + d7: gpio::Gpio18<'d>, + cd: Option, + wp: Option, config: &config::Configuration, ) -> Result { Self::new_internal( @@ -276,12 +274,12 @@ impl<'d> SdMmcHostDriver<'d> { #[cfg(not(esp_idf_soc_sdmmc_use_gpio_matrix))] #[allow(clippy::too_many_arguments)] pub fn new_slot1_1bit( - slot1: impl Peripheral

+ 'd, - cmd: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd, - d0: impl Peripheral

+ 'd, - cd: Option + 'd>, - wp: Option + 'd>, + slot1: SDMMC1<'d>, + cmd: gpio::Gpio15<'d>, + clk: gpio::Gpio14<'d>, + d0: gpio::Gpio2<'d>, + cd: Option, + wp: Option, config: &config::Configuration, ) -> Result { Self::new_internal( @@ -307,15 +305,15 @@ impl<'d> SdMmcHostDriver<'d> { #[cfg(not(esp_idf_soc_sdmmc_use_gpio_matrix))] #[allow(clippy::too_many_arguments)] pub fn new_slot1_4bits( - slot1: impl Peripheral

+ 'd, - cmd: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd, - d0: impl Peripheral

+ 'd, - d1: impl Peripheral

+ 'd, - d2: impl Peripheral

+ 'd, - d3: impl Peripheral

+ 'd, - cd: Option + 'd>, - wp: Option + 'd>, + slot1: SDMMC1<'d>, + cmd: gpio::Gpio15<'d>, + clk: gpio::Gpio14<'d>, + d0: gpio::Gpio2<'d>, + d1: gpio::Gpio4<'d>, + d2: gpio::Gpio12<'d>, + d3: gpio::Gpio13<'d>, + cd: Option, + wp: Option, config: &config::Configuration, ) -> Result { Self::new_internal( @@ -338,22 +336,22 @@ impl<'d> SdMmcHostDriver<'d> { } #[allow(clippy::too_many_arguments)] - fn new_internal( + fn new_internal( width: u8, internal_pullups: bool, - _slot: impl Peripheral

+ 'd, - _cmd: impl Peripheral

+ 'd, - _clk: impl Peripheral

+ 'd, - _d0: impl Peripheral

+ 'd, - _d1: Option + 'd>, - _d2: Option + 'd>, - _d3: Option + 'd>, - _d4: Option + 'd>, - _d5: Option + 'd>, - _d6: Option + 'd>, - _d7: Option + 'd>, - cd: Option + 'd>, - wp: Option + 'd>, + _slot: S, + _cmd: impl OutputPin + 'd, + _clk: impl OutputPin + 'd, + _d0: impl InputPin + OutputPin + 'd, + _d1: Option, + _d2: Option, + _d3: Option, + _d4: Option, + _d5: Option, + _d6: Option, + _d7: Option, + cd: Option, + wp: Option, ) -> Result { let slot_config = sdmmc_slot_config_t { width: width as _, @@ -363,14 +361,10 @@ impl<'d> SdMmcHostDriver<'d> { 0 }, __bindgen_anon_1: sdmmc_slot_config_t__bindgen_ty_1 { - cd: cd - .map(|cd| cd.into_ref().deref().pin()) - .unwrap_or(SDMMC_SLOT_NO_CD), + cd: cd.map(|cd| cd.pin() as _).unwrap_or(SDMMC_SLOT_NO_CD), }, __bindgen_anon_2: sdmmc_slot_config_t__bindgen_ty_2 { - wp: wp - .map(|wp| wp.into_ref().deref().pin()) - .unwrap_or(SDMMC_SLOT_NO_WP), + wp: wp.map(|wp| wp.pin() as _).unwrap_or(SDMMC_SLOT_NO_WP), }, #[cfg(any( esp_idf_soc_sdmmc_use_gpio_matrix, @@ -384,7 +378,7 @@ impl<'d> SdMmcHostDriver<'d> { esp_idf_version_full = "5.3.2" )) ))] - clk: _clk.into_ref().deref().pin(), + clk: _clk.pin() as _, #[cfg(any( esp_idf_soc_sdmmc_use_gpio_matrix, not(any( @@ -397,7 +391,7 @@ impl<'d> SdMmcHostDriver<'d> { esp_idf_version_full = "5.3.2" )) ))] - cmd: _cmd.into_ref().deref().pin(), + cmd: _cmd.pin() as _, #[cfg(any( esp_idf_soc_sdmmc_use_gpio_matrix, not(any( @@ -410,7 +404,7 @@ impl<'d> SdMmcHostDriver<'d> { esp_idf_version_full = "5.3.2" )) ))] - d0: _d0.into_ref().deref().pin(), + d0: _d0.pin() as _, #[cfg(any( esp_idf_soc_sdmmc_use_gpio_matrix, not(any( @@ -423,7 +417,7 @@ impl<'d> SdMmcHostDriver<'d> { esp_idf_version_full = "5.3.2" )) ))] - d1: _d1.map(|d1| d1.into_ref().deref().pin()).unwrap_or(-1), + d1: _d1.map(|d1| d1.pin() as _).unwrap_or(-1), #[cfg(any( esp_idf_soc_sdmmc_use_gpio_matrix, not(any( @@ -436,7 +430,7 @@ impl<'d> SdMmcHostDriver<'d> { esp_idf_version_full = "5.3.2" )) ))] - d2: _d2.map(|d2| d2.into_ref().deref().pin()).unwrap_or(-1), + d2: _d2.map(|d2| d2.pin() as _).unwrap_or(-1), #[cfg(any( esp_idf_soc_sdmmc_use_gpio_matrix, not(any( @@ -449,7 +443,7 @@ impl<'d> SdMmcHostDriver<'d> { esp_idf_version_full = "5.3.2" )) ))] - d3: _d3.map(|d3| d3.into_ref().deref().pin()).unwrap_or(-1), + d3: _d3.map(|d3| d3.pin() as _).unwrap_or(-1), #[cfg(any( esp_idf_soc_sdmmc_use_gpio_matrix, not(any( @@ -462,7 +456,7 @@ impl<'d> SdMmcHostDriver<'d> { esp_idf_version_full = "5.3.2" )) ))] - d4: _d4.map(|d4| d4.into_ref().deref().pin()).unwrap_or(-1), + d4: _d4.map(|d4| d4.pin() as _).unwrap_or(-1), #[cfg(any( esp_idf_soc_sdmmc_use_gpio_matrix, not(any( @@ -475,7 +469,7 @@ impl<'d> SdMmcHostDriver<'d> { esp_idf_version_full = "5.3.2" )) ))] - d5: _d5.map(|d5| d5.into_ref().deref().pin()).unwrap_or(-1), + d5: _d5.map(|d5| d5.pin() as _).unwrap_or(-1), #[cfg(any( esp_idf_soc_sdmmc_use_gpio_matrix, not(any( @@ -488,7 +482,7 @@ impl<'d> SdMmcHostDriver<'d> { esp_idf_version_full = "5.3.2" )) ))] - d6: _d6.map(|d6| d6.into_ref().deref().pin()).unwrap_or(-1), + d6: _d6.map(|d6| d6.pin() as _).unwrap_or(-1), #[cfg(any( esp_idf_soc_sdmmc_use_gpio_matrix, not(any( @@ -501,7 +495,7 @@ impl<'d> SdMmcHostDriver<'d> { esp_idf_version_full = "5.3.2" )) ))] - d7: _d7.map(|d7| d7.into_ref().deref().pin()).unwrap_or(-1), + d7: _d7.map(|d7| d7.pin() as _).unwrap_or(-1), }; { @@ -546,7 +540,7 @@ macro_rules! impl_slot { ($instance:ident: $slot:expr) => { crate::impl_peripheral!($instance); - impl SdMmc for $instance { + impl SdMmc for $instance<'_> { fn slot() -> u8 { $slot } diff --git a/src/sd/spi.rs b/src/sd/spi.rs index 98c83f868..8c9646253 100755 --- a/src/sd/spi.rs +++ b/src/sd/spi.rs @@ -1,10 +1,8 @@ use core::borrow::Borrow; use core::marker::PhantomData; -use core::ops::Deref; use core::sync::atomic::{AtomicU8, Ordering}; use crate::gpio::{InputPin, OutputPin}; -use crate::peripheral::Peripheral; use crate::spi::SpiDriver; use crate::sys::*; @@ -33,10 +31,10 @@ where /// - wp_active_high: Write Protect active when high (optional, default = `false`) pub fn new( spi_driver: T, - cs: Option + 'd>, - cd: Option + 'd>, - wp: Option + 'd>, - int: Option + 'd>, + cs: Option, + cd: Option, + wp: Option, + int: Option, #[cfg(not(any( esp_idf_version_major = "4", all(esp_idf_version_major = "5", esp_idf_version_minor = "0"), @@ -50,10 +48,10 @@ where #[allow(clippy::needless_update)] let dev_config = sdspi_device_config_t { host_id: spi_driver.borrow().host(), - gpio_cs: cs.map(|cs| cs.into_ref().deref().pin()).unwrap_or(-1), - gpio_cd: cd.map(|cd| cd.into_ref().deref().pin()).unwrap_or(-1), - gpio_wp: wp.map(|wp| wp.into_ref().deref().pin()).unwrap_or(-1), - gpio_int: int.map(|int| int.into_ref().deref().pin()).unwrap_or(-1), + gpio_cs: cs.map(|cs| cs.pin() as _).unwrap_or(-1), + gpio_cd: cd.map(|cd| cd.pin() as _).unwrap_or(-1), + gpio_wp: wp.map(|wp| wp.pin() as _).unwrap_or(-1), + gpio_int: int.map(|int| int.pin() as _).unwrap_or(-1), #[cfg(not(any( esp_idf_version_major = "4", all(esp_idf_version_major = "5", esp_idf_version_minor = "0"), diff --git a/src/spi.rs b/src/spi.rs index 2d6d5557a..09a14bc0c 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -48,10 +48,9 @@ use esp_idf_sys::*; use heapless::Deque; use crate::delay::{self, Ets, BLOCK}; -use crate::gpio::{AnyOutputPin, IOPin, InputPin, Level, Output, OutputMode, OutputPin, PinDriver}; +use crate::gpio::{AnyOutputPin, InputPin, Level, Output, OutputMode, OutputPin, PinDriver}; use crate::interrupt::asynch::HalIsrNotification; use crate::interrupt::InterruptType; -use crate::peripheral::Peripheral; use crate::task::embassy_sync::EspRawMutex; use crate::task::CriticalSection; @@ -431,19 +430,19 @@ impl<'d> SpiDriver<'d> { /// SPI1 can only use fixed pin for SCLK, SDO and SDI as they are shared with SPI0. #[cfg(esp32)] pub fn new_spi1( - _spi: impl Peripheral

+ 'd, - sclk: impl Peripheral

+ 'd, - sdo: impl Peripheral

+ 'd, - sdi: Option + 'd>, + _spi: SPI1<'d>, + sclk: crate::gpio::Gpio6<'d>, + sdo: crate::gpio::Gpio7<'d>, + sdi: Option>, config: &config::DriverConfig, ) -> Result { use crate::gpio::Pin; let max_transfer_size = Self::new_internal( SPI1::device(), - Some(sclk.into_ref().pin()), - Some(sdo.into_ref().pin()), - sdi.map(|p| p.into_ref().pin()), + Some(sclk.pin() as _), + Some(sdo.pin() as _), + sdi.map(|p| p.pin() as _), None, None, config, @@ -458,18 +457,18 @@ impl<'d> SpiDriver<'d> { } /// Create new instance of SPI controller for all others - pub fn new( - _spi: impl Peripheral

+ 'd, - sclk: impl Peripheral

+ 'd, - sdo: impl Peripheral

+ 'd, - sdi: Option + 'd>, + pub fn new( + _spi: SPI, + sclk: impl OutputPin + 'd, + sdo: impl OutputPin + 'd, + sdi: Option, config: &config::DriverConfig, ) -> Result { let max_transfer_size = Self::new_internal( SPI::device(), - Some(sclk.into_ref().pin()), - Some(sdo.into_ref().pin()), - sdi.map(|p| p.into_ref().pin()), + Some(sclk.pin() as _), + Some(sdo.pin() as _), + sdi.map(|p| p.pin() as _), None, None, config, @@ -483,17 +482,17 @@ impl<'d> SpiDriver<'d> { }) } - pub fn new_without_sclk( - _spi: impl Peripheral

+ 'd, - sdo: impl Peripheral

+ 'd, - sdi: Option + 'd>, + pub fn new_without_sclk( + _spi: SPI, + sdo: impl OutputPin + 'd, + sdi: Option, config: &config::DriverConfig, ) -> Result { let max_transfer_size = Self::new_internal( SPI::device(), None, - Some(sdo.into_ref().pin()), - sdi.map(|p| p.into_ref().pin()), + Some(sdo.pin() as _), + sdi.map(|p| p.pin() as _), None, None, config, @@ -507,18 +506,18 @@ impl<'d> SpiDriver<'d> { }) } - pub fn new_dual( - _spi: impl Peripheral

+ 'd, - sclk: impl Peripheral

+ 'd, - data0: impl Peripheral

+ 'd, - data1: impl Peripheral

+ 'd, + pub fn new_dual( + _spi: SPI, + sclk: impl OutputPin + 'd, + data0: impl InputPin + OutputPin + 'd, + data1: impl InputPin + OutputPin + 'd, config: &config::DriverConfig, ) -> Result { let max_transfer_size = Self::new_internal( SPI::device(), - Some(sclk.into_ref().pin()), - Some(data0.into_ref().pin()), - Some(data1.into_ref().pin()), + Some(sclk.pin() as _), + Some(data0.pin() as _), + Some(data1.pin() as _), None, None, config, @@ -532,22 +531,22 @@ impl<'d> SpiDriver<'d> { }) } - pub fn new_quad( - _spi: impl Peripheral

+ 'd, - sclk: impl Peripheral

+ 'd, - data0: impl Peripheral

+ 'd, - data1: impl Peripheral

+ 'd, - data2: impl Peripheral

+ 'd, - data3: impl Peripheral

+ 'd, + pub fn new_quad( + _spi: SPI, + sclk: impl OutputPin + 'd, + data0: impl InputPin + OutputPin + 'd, + data1: impl InputPin + OutputPin + 'd, + data2: impl InputPin + OutputPin + 'd, + data3: impl InputPin + OutputPin + 'd, config: &config::DriverConfig, ) -> Result { let max_transfer_size = Self::new_internal( SPI::device(), - Some(sclk.into_ref().pin()), - Some(data0.into_ref().pin()), - Some(data1.into_ref().pin()), - Some(data2.into_ref().pin()), - Some(data3.into_ref().pin()), + Some(sclk.pin() as _), + Some(data0.pin() as _), + Some(data1.pin() as _), + Some(data2.pin() as _), + Some(data3.pin() as _), config, )?; @@ -969,11 +968,11 @@ where impl<'d> SpiDeviceDriver<'d, SpiDriver<'d>> { #[cfg(esp32)] pub fn new_single_spi1( - spi: impl Peripheral

+ 'd, - sclk: impl Peripheral

+ 'd, - sdo: impl Peripheral

+ 'd, - sdi: Option + 'd>, - cs: Option + 'd>, + spi: SPI1<'d>, + sclk: crate::gpio::Gpio6<'d>, + sdo: crate::gpio::Gpio7<'d>, + sdi: Option>, + cs: Option, bus_config: &config::DriverConfig, config: &config::Config, ) -> Result { @@ -984,12 +983,12 @@ impl<'d> SpiDeviceDriver<'d, SpiDriver<'d>> { ) } - pub fn new_single( - spi: impl Peripheral

+ 'd, - sclk: impl Peripheral

+ 'd, - sdo: impl Peripheral

+ 'd, - sdi: Option + 'd>, - cs: Option + 'd>, + pub fn new_single( + spi: SPI, + sclk: impl OutputPin + 'd, + sdo: impl OutputPin + 'd, + sdi: Option, + cs: Option, bus_config: &config::DriverConfig, config: &config::Config, ) -> Result { @@ -1003,10 +1002,10 @@ where { pub fn new( driver: T, - cs: Option + 'd>, + cs: Option, config: &config::Config, ) -> Result { - let cs = cs.map(|cs| cs.into_ref().pin()).unwrap_or(-1); + let cs = cs.map(|cs| cs.pin() as _).unwrap_or(-1); let mut conf: spi_device_interface_config_t = config.into(); conf.spics_io_num = cs; @@ -1094,13 +1093,12 @@ where work.await } - fn run<'a, 'c, 'p, P, M>( + fn run<'a, 'c, 'p, M>( &mut self, - mut cs_pin: CsCtl<'c, 'p, P, M>, + mut cs_pin: CsCtl<'c, 'p, M>, operations: impl Iterator> + 'a, ) -> Result<(), EspError> where - P: OutputPin, M: OutputMode, { let _lock = if cs_pin.needs_bus_lock() { @@ -1149,13 +1147,12 @@ where } #[allow(dead_code)] - async fn run_async<'a, 'c, 'p, P, M>( + async fn run_async<'a, 'c, 'p, M>( &self, - mut cs_pin: CsCtl<'c, 'p, P, M>, + mut cs_pin: CsCtl<'c, 'p, M>, operations: impl Iterator> + 'a, ) -> Result<(), EspError> where - P: OutputPin, M: OutputMode, { let _async_bus_lock = if cs_pin.needs_bus_lock() { @@ -1217,7 +1214,7 @@ where fn hardware_cs_ctl<'a, 'c, 'p>( &self, operations: impl Iterator> + 'a, - ) -> Result, EspError> { + ) -> Result, EspError> { let (total_count, transactions_count, first_transaction, last_transaction) = self.spi_operations_stats(operations); @@ -1504,7 +1501,7 @@ where pub struct SpiSoftCsDeviceDriver<'d, DEVICE, DRIVER> { shared_device: DEVICE, - cs_pin: PinDriver<'d, AnyOutputPin, Output>, + cs_pin: PinDriver<'d, Output>, pre_delay_us: Option, post_delay_us: Option, _p: PhantomData DRIVER>, @@ -1517,12 +1514,10 @@ where { pub fn new( shared_device: DEVICE, - cs: impl Peripheral

+ 'd, + cs: impl OutputPin + 'd, cs_level: Level, ) -> Result { - crate::into_ref!(cs); - - let mut cs_pin: PinDriver = PinDriver::output(cs.map_into())?; + let mut cs_pin: PinDriver = PinDriver::output(cs)?; cs_pin.set_level(cs_level)?; @@ -1736,9 +1731,8 @@ impl Drop for BusLock { } } -enum CsCtl<'c, 'p, P, M> +enum CsCtl<'c, 'p, M> where - P: OutputPin, M: OutputMode, { Hardware { @@ -1747,15 +1741,14 @@ where last_transaction: Option, }, Software { - cs: &'c mut PinDriver<'p, P, M>, + cs: &'c mut PinDriver<'p, M>, pre_delay: Option, post_delay: Option, }, } -impl CsCtl<'_, '_, P, M> +impl CsCtl<'_, '_, M> where - P: OutputPin, M: OutputMode, { fn needs_bus_lock(&self) -> bool { @@ -2247,7 +2240,7 @@ macro_rules! impl_spi { ($spi:ident: $device:expr) => { crate::impl_peripheral!($spi); - impl Spi for $spi { + impl Spi for $spi<'_> { #[inline(always)] fn device() -> spi_host_device_t { $device @@ -2258,7 +2251,7 @@ macro_rules! impl_spi { macro_rules! impl_spi_any_pins { ($spi:ident) => { - impl SpiAnyPins for $spi {} + impl SpiAnyPins for $spi<'_> {} }; } diff --git a/src/task.rs b/src/task.rs index cf91deda9..0d0546f6f 100644 --- a/src/task.rs +++ b/src/task.rs @@ -597,8 +597,6 @@ pub mod watchdog { use esp_idf_sys::*; - use crate::peripheral::Peripheral; - pub type TWDTConfig = config::Config; pub mod config { @@ -666,10 +664,7 @@ pub mod watchdog { static TWDT_DRIVER_REF_COUNT: AtomicUsize = AtomicUsize::new(0); impl<'d> TWDTDriver<'d> { - pub fn new( - _twdt: impl Peripheral

+ 'd, - config: &config::Config, - ) -> Result { + pub fn new(_twdt: TWDT<'d>, config: &config::Config) -> Result { TWDT_DRIVER_REF_COUNT.fetch_add(1, Ordering::SeqCst); let init_by_idf = Self::watchdog_is_init_by_idf(); diff --git a/src/temp_sensor.rs b/src/temp_sensor.rs index 08acb40b6..dcdab1583 100644 --- a/src/temp_sensor.rs +++ b/src/temp_sensor.rs @@ -14,7 +14,6 @@ use esp_idf_sys::soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_ #[cfg(any(esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2))] use esp_idf_sys::soc_periph_temperature_sensor_clk_src_t_TEMPERATURE_SENSOR_CLK_SRC_XTAL; -use crate::peripheral::Peripheral; use core::marker::PhantomData; // -- TempSensorClockSource -- @@ -143,10 +142,7 @@ pub struct TempSensorDriver<'d> { } impl<'d> TempSensorDriver<'d> { - pub fn new( - config: &TempSensorConfig, - _sensor: impl Peripheral

+ 'd, - ) -> Result { + pub fn new(config: &TempSensorConfig, _sensor: TempSensor<'d>) -> Result { let mut sensor = core::ptr::null_mut(); esp!(unsafe { temperature_sensor_install(&config.into(), &mut sensor) })?; Ok(TempSensorDriver { diff --git a/src/timer.rs b/src/timer.rs index c19ff1903..7ca029a25 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -2,8 +2,6 @@ use core::marker::PhantomData; use esp_idf_sys::*; -use crate::peripheral::Peripheral; - #[cfg(feature = "alloc")] extern crate alloc; @@ -127,8 +125,8 @@ pub struct TimerDriver<'d> { } impl<'d> TimerDriver<'d> { - pub fn new( - _timer: impl Peripheral

+ 'd, + pub fn new( + _timer: TIMER, config: &config::Config, ) -> Result { esp!(unsafe { @@ -582,7 +580,7 @@ macro_rules! impl_timer { ($timer:ident: $group:expr, $index:expr) => { crate::impl_peripheral!($timer); - impl Timer for $timer { + impl Timer for $timer<'_> { #[inline(always)] fn group() -> timer_group_t { $group diff --git a/src/uart.rs b/src/uart.rs index 4ec046c58..cffd48eea 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -56,8 +56,6 @@ use crate::{gpio::*, task}; use embedded_hal_nb::serial::ErrorKind; use esp_idf_sys::*; -use crate::peripheral::Peripheral; - const UART_FIFO_SIZE: usize = SOC_UART_FIFO_LEN as usize; pub type UartConfig = config::Config; @@ -737,12 +735,12 @@ pub struct UartTxDriver<'d> { impl<'d> UartDriver<'d> { /// Create a new serial driver - pub fn new( - uart: impl Peripheral

+ 'd, - tx: impl Peripheral

+ 'd, - rx: impl Peripheral

+ 'd, - cts: Option + 'd>, - rts: Option + 'd>, + pub fn new( + uart: UART, + tx: impl OutputPin + 'd, + rx: impl InputPin + 'd, + cts: Option, + rts: Option, config: &config::Config, ) -> Result { let mut q_handle_raw = ptr::null_mut(); @@ -1044,11 +1042,11 @@ impl core::fmt::Write for UartDriver<'_> { impl<'d> UartRxDriver<'d> { /// Create a new serial receiver - pub fn new( - uart: impl Peripheral

+ 'd, - rx: impl Peripheral

+ 'd, - cts: Option + 'd>, - rts: Option + 'd>, + pub fn new( + uart: UART, + rx: impl InputPin + 'd, + cts: Option, + rts: Option, config: &config::Config, ) -> Result { let mut q_handle_raw = ptr::null_mut(); @@ -1269,11 +1267,11 @@ impl embedded_hal_nb::serial::Read for UartRxDriver<'_> { impl<'d> UartTxDriver<'d> { /// Create a new serial transmitter - pub fn new( - uart: impl Peripheral

+ 'd, - tx: impl Peripheral

+ 'd, - cts: Option + 'd>, - rts: Option + 'd>, + pub fn new( + uart: UART, + tx: impl OutputPin + 'd, + cts: Option, + rts: Option, config: &config::Config, ) -> Result { let mut q_handle_raw = ptr::null_mut(); @@ -1503,12 +1501,12 @@ where } impl<'d> AsyncUartDriver<'d, UartDriver<'d>> { - pub fn new( - uart: impl Peripheral

+ 'd, - tx: impl Peripheral

+ 'd, - rx: impl Peripheral

+ 'd, - cts: Option + 'd>, - rts: Option + 'd>, + pub fn new( + uart: UART, + tx: impl OutputPin + 'd, + rx: impl InputPin + 'd, + cts: Option, + rts: Option, config: &config::Config, ) -> Result { Self::wrap(UartDriver::new(uart, tx, rx, cts, rts, config)?) @@ -1686,11 +1684,11 @@ where } impl<'d> AsyncUartRxDriver<'d, UartRxDriver<'d>> { - pub fn new( - uart: impl Peripheral

+ 'd, - rx: impl Peripheral

+ 'd, - cts: Option + 'd>, - rts: Option + 'd>, + pub fn new( + uart: UART, + rx: impl InputPin + 'd, + cts: Option, + rts: Option, config: &config::Config, ) -> Result { Self::wrap(UartRxDriver::new(uart, rx, cts, rts, config)?) @@ -1789,11 +1787,11 @@ where } impl<'d> AsyncUartTxDriver<'d, UartTxDriver<'d>> { - pub fn new( - uart: impl Peripheral

+ 'd, - tx: impl Peripheral

+ 'd, - cts: Option + 'd>, - rts: Option + 'd>, + pub fn new( + uart: UART, + tx: impl OutputPin + 'd, + cts: Option, + rts: Option, config: &config::Config, ) -> Result { Self::wrap(UartTxDriver::new(uart, tx, cts, rts, config)?) @@ -1978,20 +1976,15 @@ extern "C" fn process_events(arg: *mut core::ffi::c_void) { } } -fn new_common( - _uart: impl Peripheral

, - tx: Option>, - rx: Option>, - cts: Option>, - rts: Option>, +fn new_common<'d, UART: Uart + 'd>( + _uart: UART, + tx: Option, + rx: Option, + cts: Option, + rts: Option, config: &config::Config, queue: Option<&mut QueueHandle_t>, ) -> Result<(), EspError> { - let tx = tx.map(|tx| tx.into_ref()); - let rx = rx.map(|rx| rx.into_ref()); - let cts = cts.map(|cts| cts.into_ref()); - let rts = rts.map(|rts| rts.into_ref()); - let uart_config = config.into(); esp!(unsafe { uart_param_config(UART::port(), &uart_config) })?; @@ -2001,10 +1994,10 @@ fn new_common( esp!(unsafe { _uart_set_pin6( UART::port(), - tx.as_ref().map_or(-1, |p| p.pin()), - rx.as_ref().map_or(-1, |p| p.pin()), - rts.as_ref().map_or(-1, |p| p.pin()), - cts.as_ref().map_or(-1, |p| p.pin()), + tx.as_ref().map_or(-1, |p| p.pin() as _), + rx.as_ref().map_or(-1, |p| p.pin() as _), + rts.as_ref().map_or(-1, |p| p.pin() as _), + cts.as_ref().map_or(-1, |p| p.pin() as _), -1, -1, ) @@ -2016,10 +2009,10 @@ fn new_common( esp!(unsafe { uart_set_pin( UART::port(), - tx.as_ref().map_or(-1, |p| p.pin()), - rx.as_ref().map_or(-1, |p| p.pin()), - rts.as_ref().map_or(-1, |p| p.pin()), - cts.as_ref().map_or(-1, |p| p.pin()), + tx.as_ref().map_or(-1, |p| p.pin() as _), + rx.as_ref().map_or(-1, |p| p.pin() as _), + rts.as_ref().map_or(-1, |p| p.pin() as _), + cts.as_ref().map_or(-1, |p| p.pin() as _), ) })?; } @@ -2149,7 +2142,7 @@ macro_rules! impl_uart { ($uart:ident: $port:expr) => { crate::impl_peripheral!($uart); - impl Uart for $uart { + impl Uart for $uart<'_> { fn port() -> uart_port_t { $port } diff --git a/src/ulp.rs b/src/ulp.rs index c808356ac..759b00936 100644 --- a/src/ulp.rs +++ b/src/ulp.rs @@ -77,7 +77,7 @@ impl Word { all(esp32s2, esp_idf_esp32s2_ulp_coproc_enabled), all(esp32s3, esp_idf_esp32s3_ulp_coproc_enabled) ))] -pub struct UlpDriver<'d>(crate::peripheral::PeripheralRef<'d, ULP>); +pub struct UlpDriver<'d>(PhantomData<&'d mut ()>); #[cfg(any( all(not(esp_idf_version_major = "4"), esp_idf_ulp_coproc_enabled), @@ -94,12 +94,8 @@ unsafe impl<'d> Send for UlpDriver<'d> {} all(esp32s3, esp_idf_esp32s3_ulp_coproc_enabled) ))] impl<'d> UlpDriver<'d> { - pub fn new( - ulp: impl crate::peripheral::Peripheral

+ 'd, - ) -> Result { - crate::into_ref!(ulp); - - Ok(Self(ulp)) + pub fn new(ulp: ULP<'d>) -> Result { + Ok(Self(PhantomData)) } pub fn stop(&mut self) -> Result<(), esp_idf_sys::EspError> { diff --git a/src/usb_serial.rs b/src/usb_serial.rs index a367c2379..a5e3f33b2 100644 --- a/src/usb_serial.rs +++ b/src/usb_serial.rs @@ -3,8 +3,9 @@ //! Communication through a virtualized UART-like USB-CDC interface. #![allow(non_camel_case_types)] +use core::marker::PhantomData; + use crate::io::EspIOError; -use crate::peripheral::{Peripheral, PeripheralRef}; use crate::sys::{ esp, usb_serial_jtag_driver_config_t, usb_serial_jtag_driver_install, usb_serial_jtag_driver_uninstall, usb_serial_jtag_is_connected, usb_serial_jtag_read_bytes, @@ -17,45 +18,45 @@ pub type UsbSerialConfig = config::Config; /// USB D- GPIO pin #[cfg(esp32c3)] -pub type UsbDMinGpio = gpio::Gpio18; +pub type UsbDMinGpio<'d> = gpio::Gpio18<'d>; /// USB D+ GPIO pin #[cfg(esp32c3)] -pub type UsbDPlusGpio = gpio::Gpio19; +pub type UsbDPlusGpio<'d> = gpio::Gpio19<'d>; /// USB D- GPIO pin #[cfg(esp32c5)] -pub type UsbDMinGpio = gpio::Gpio13; +pub type UsbDMinGpio<'d> = gpio::Gpio13<'d>; /// USB D+ GPIO pin #[cfg(esp32c5)] -pub type UsbDPlusGpio = gpio::Gpio14; +pub type UsbDPlusGpio<'d> = gpio::Gpio14<'d>; /// USB D- GPIO pin #[cfg(esp32c6)] -pub type UsbDMinGpio = gpio::Gpio12; +pub type UsbDMinGpio<'d> = gpio::Gpio12<'d>; /// USB D+ GPIO pin #[cfg(esp32c6)] -pub type UsbDPlusGpio = gpio::Gpio13; +pub type UsbDPlusGpio<'d> = gpio::Gpio13<'d>; /// USB D- GPIO pin #[cfg(esp32h2)] -pub type UsbDMinGpio = gpio::Gpio26; +pub type UsbDMinGpio<'d> = gpio::Gpio26<'d>; /// USB D+ GPIO pin #[cfg(esp32h2)] -pub type UsbDPlusGpio = gpio::Gpio27; +pub type UsbDPlusGpio<'d> = gpio::Gpio27<'d>; /// USB D- GPIO pin #[cfg(esp32p4)] -pub type UsbDMinGpio = gpio::Gpio24; +pub type UsbDMinGpio<'d> = gpio::Gpio24<'d>; /// USB D+ GPIO pin #[cfg(esp32p4)] -pub type UsbDPlusGpio = gpio::Gpio25; +pub type UsbDPlusGpio<'d> = gpio::Gpio25<'d>; // TODO // #[cfg(esp32p4)] -// pub type UsbDMinGpio2 = gpio::Gpio26; +// pub type UsbDMinGpio2<'d> = gpio::Gpio26<'d>; // #[cfg(esp32p4)] -// pub type UsbDPlusGpio2 = gpio::Gpio27; +// pub type UsbDPlusGpio2<'d> = gpio::Gpio27<'d>; /// USB D- GPIO pin #[cfg(esp32s3)] -pub type UsbDMinGpio = gpio::Gpio19; +pub type UsbDMinGpio<'d> = gpio::Gpio19<'d>; /// USB D+ GPIO pin #[cfg(esp32s3)] -pub type UsbDPlusGpio = gpio::Gpio20; +pub type UsbDPlusGpio<'d> = gpio::Gpio20<'d>; /// USB Serial driver configuration pub mod config { @@ -99,7 +100,7 @@ pub mod config { } /// USB-SERIAL driver -pub struct UsbSerialDriver<'d>(PeripheralRef<'d, USB_SERIAL>); +pub struct UsbSerialDriver<'d>(PhantomData<&'d mut ()>); impl<'d> UsbSerialDriver<'d> { /// Create a new USB Serial driver @@ -110,13 +111,11 @@ impl<'d> UsbSerialDriver<'d> { /// - `usb_d_min`: The USB D- GPIO pin /// - `usb_d_plus`: The USB D+ GPIO pin pub fn new( - usb_serial: impl Peripheral

+ 'd, - _usb_d_min: impl Peripheral

, - _usb_d_plus: impl Peripheral

, + _usb_serial: USB_SERIAL<'d>, + _usb_d_min: UsbDMinGpio<'d>, + _usb_d_plus: UsbDPlusGpio<'d>, config: &config::Config, ) -> Result { - crate::into_ref!(usb_serial); - let mut config = usb_serial_jtag_driver_config_t { tx_buffer_size: config.tx_buffer_size as _, rx_buffer_size: config.rx_buffer_size as _, @@ -124,7 +123,7 @@ impl<'d> UsbSerialDriver<'d> { esp!(unsafe { usb_serial_jtag_driver_install(&mut config) })?; - Ok(Self(usb_serial)) + Ok(Self(PhantomData)) } /// Check if the USB Serial is connected