Remove Peripheral/PeripheralRef (#529)

* Remove Peripheral/PeripheralRef

* Make ADC unit and channel structs more readable by avoiding const generics

* Remove unused parameter

* fix forgotten reference to the old ADCU syntax

* Mention that we have removed the prelude module

* try_into methods for changing the pin type
This commit is contained in:
ivmarkov 2025-09-03 13:13:32 +02:00 committed by GitHub
parent 676f0043de
commit 2af4695aac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 2005 additions and 2397 deletions

View File

@ -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+

View File

@ -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

View File

@ -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 {

View File

@ -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;

View File

@ -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<P = impl I2c> + 'd,
sda: AnyIOPin,
scl: AnyIOPin,
i2c: impl I2c + 'd,
sda: AnyIOPin<'d>,
scl: AnyIOPin<'d>,
baudrate: Hertz,
) -> anyhow::Result<I2cDriver<'d>> {
let config = I2cConfig::new().baudrate(baudrate);
@ -39,9 +37,9 @@ fn i2c_master_init<'d>(
}
fn i2c_slave_init<'d>(
i2c: impl Peripheral<P = impl I2c> + 'd,
sda: AnyIOPin,
scl: AnyIOPin,
i2c: impl I2c + 'd,
sda: AnyIOPin<'d>,
scl: AnyIOPin<'d>,
buflen: usize,
slave_addr: u8,
) -> anyhow::Result<I2cSlaveDriver<'d>> {

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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;

View File

@ -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: Pcnt>(
pcnt: impl Peripheral<P = PCNT> + 'd,
pin_a: impl Peripheral<P = impl InputPin> + 'd,
pin_b: impl Peripheral<P = impl InputPin> + 'd,
pub fn new(
pcnt: impl Pcnt + 'd,
pin_a: impl InputPin + 'd,
pin_b: impl InputPin + 'd,
) -> Result<Self, EspError> {
let mut unit = PcntDriver::new(
pcnt,

View File

@ -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<P = impl RmtChannel> + 'd,
led: impl Peripheral<P = impl OutputPin> + 'd,
channel: impl RmtChannel + 'd,
led: impl OutputPin + 'd,
config: &TransmitConfig,
message: &str,
) -> anyhow::Result<TxRmtDriver<'d>> {

View File

@ -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,
};

View File

@ -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},
};

View File

@ -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,

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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<U: AdcUnit>(PhantomData<U>);
impl<U: AdcUnit> AdcChannel for $adcch<U> {
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<Resolution> 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<C>,
_t: PhantomData<&'d mut ()>,
}
impl<'d, const A: adc_atten_t, T: ADCPin> AdcChannelDriver<'d, A, T> {
pub fn new(pin: impl Peripheral<P = T> + 'd) -> Result<Self, EspError> {
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<AdcChannel = C> + 'd) -> Result<Self, EspError> {
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<const A: adc_atten_t, T: ADCPin> embedded_hal_0_2::adc::Channel<T::Adc>
for AdcChannelDriver<'_, A, T>
impl<const A: adc_atten_t, C: AdcChannel> embedded_hal_0_2::adc::Channel<C::AdcUnit>
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<esp_adc_cal_characteristics_t>; adc_atten_t_ADC_ATTEN_DB_11 as usize + 1],
>,
_unit: PhantomData<ADCU>,
_t: PhantomData<&'d mut ()>,
}
unsafe impl<ADC: Adc> Send for AdcDriver<'_, ADC> {}
unsafe impl<ADCU: AdcUnit> 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<P = ADC> + 'd,
pub fn new<ADC: Adc<AdcUnit = ADCU> + 'd>(
_adc: ADC,
config: &config::Config,
) -> Result<Self, EspError> {
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<const A: adc_atten_t, T>(
pub fn read<const A: adc_atten_t, C: AdcChannel<AdcUnit = ADCU>>(
&mut self,
pin: &mut AdcChannelDriver<'_, A, T>,
) -> Result<u16, EspError>
where
T: ADCPin<Adc = ADC>,
{
self.read_internal(ADC::unit(), pin.pin().adc_channel(), A)
}
#[inline(always)]
pub fn read_raw<const A: adc_atten_t, T>(
&mut self,
pin: &mut AdcChannelDriver<'_, A, T>,
) -> Result<u16, EspError>
where
T: ADCPin<Adc = ADC>,
{
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<u16, EspError> {
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<const A: adc_atten_t, C: AdcChannel<AdcUnit = ADCU>>(
&mut self,
_pin: &mut AdcChannelDriver<'_, A, C>,
) -> Result<u16, EspError> {
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<T::Adc, u16, AdcChannelDriver<'c, A, T>>
for AdcDriver<'_, T::Adc>
impl<'c, const A: adc_atten_t, C>
embedded_hal_0_2::adc::OneShot<C::AdcUnit, u16, AdcChannelDriver<'c, A, C>>
for AdcDriver<'_, C::AdcUnit>
where
T: ADCPin,
C: AdcChannel,
{
type Error = EspError;
fn read(&mut self, pin: &mut AdcChannelDriver<'c, A, T>) -> nb::Result<u16, Self::Error> {
self.read_internal(T::Adc::unit(), pin.pin.adc_channel(), A)
fn read(&mut self, _pin: &mut AdcChannelDriver<'c, A, C>) -> nb::Result<u16, Self::Error> {
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<super::ADC1, u16, crate::hall::HallSensor>
for AdcDriver<'_, super::ADC1>
{
type Error = EspError;
fn read(
&mut self,
hall_sensor: &mut crate::hall::HallSensor,
) -> nb::Result<u16, Self::Error> {
AdcDriver::read_hall(self, hall_sensor).map_err(to_nb_err)
}
}
}
fn to_nb_err(err: EspError) -> nb::Error<EspError> {
@ -448,21 +489,18 @@ fn to_nb_err(err: EspError) -> nb::Error<EspError> {
}
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<AdcDriver<'d, T::Adc>>,
C: AdcChannel,
M: Borrow<AdcDriver<'d, C::AdcUnit>>,
{
adc: M,
_pin: PeripheralRef<'d, T>,
_channel: PhantomData<C>,
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<AdcDriver<'d, T::Adc>>,
C: AdcChannel,
M: Borrow<AdcDriver<'d, C::AdcUnit>>,
{
pub fn new(
adc: M,
pin: impl Peripheral<P = T> + 'd,
pin: impl ADCPin<AdcChannel = C> + 'd,
config: &config::AdcChannelConfig,
) -> Result<Self, EspError> {
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<u16, EspError> {
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<T::Adc> for AdcChannelDriver<'d, T, M>
impl<'d, C, M> embedded_hal_0_2::adc::Channel<C::AdcUnit> for AdcChannelDriver<'d, C, M>
where
T: ADCPin,
M: Borrow<AdcDriver<'d, T::Adc>>,
C: AdcChannel,
M: Borrow<AdcDriver<'d, C::AdcUnit>>,
{
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<AdcDriver<'d, T::Adc>>,
C: AdcChannel,
M: Borrow<AdcDriver<'d, C::AdcUnit>>,
{
}
pub struct AdcDriver<'d, ADC: Adc> {
pub struct AdcDriver<'d, U> {
handle: adc_oneshot_unit_handle_t,
_adc: PeripheralRef<'d, ADC>,
_unit: PhantomData<U>,
_t: PhantomData<&'d mut ()>,
}
impl<'d, ADC: Adc> AdcDriver<'d, ADC> {
pub fn new(adc: impl Peripheral<P = ADC> + 'd) -> Result<Self, EspError> {
crate::into_ref!(adc);
impl<'d, U> AdcDriver<'d, U>
where
U: AdcUnit + 'd,
{
pub fn new<ADC: Adc<AdcUnit = U> + 'd>(_adc: ADC) -> Result<Self, EspError> {
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<T, M>(&self, channel: &mut AdcChannelDriver<'d, T, M>) -> Result<u16, EspError>
pub fn read<C, M>(&self, channel: &mut AdcChannelDriver<'d, C, M>) -> Result<u16, EspError>
where
T: ADCPin,
M: Borrow<AdcDriver<'d, T::Adc>>,
C: AdcChannel<AdcUnit = U>,
M: Borrow<AdcDriver<'d, U>>,
{
let raw = self.read_raw(channel)?;
self.raw_to_mv(channel, raw)
}
#[inline(always)]
pub fn read_raw<T, M>(
pub fn read_raw<C, M>(
&self,
_channel: &mut AdcChannelDriver<'d, T, M>,
_channel: &mut AdcChannelDriver<'d, C, M>,
) -> Result<u16, EspError>
where
T: ADCPin,
M: Borrow<AdcDriver<'d, T::Adc>>,
C: AdcChannel<AdcUnit = U>,
M: Borrow<AdcDriver<'d, U>>,
{
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<T, M>(
pub fn raw_to_mv<C, M>(
&self,
channel: &AdcChannelDriver<'d, T, M>,
channel: &AdcChannelDriver<'d, C, M>,
raw: u16,
) -> Result<u16, EspError>
where
T: ADCPin,
M: Borrow<AdcDriver<'d, T::Adc>>,
C: AdcChannel<AdcUnit = U>,
M: Borrow<AdcDriver<'d, U>>,
{
channel.converter.raw_to_mv(raw)
}
}
impl<ADC: Adc> Drop for AdcDriver<'_, ADC> {
impl<U> 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<T::Adc, u16, AdcChannelDriver<'d, T, M>>
for AdcDriver<'d, T::Adc>
impl<'d, C, M> embedded_hal_0_2::adc::OneShot<C::AdcUnit, u16, AdcChannelDriver<'d, C, M>>
for AdcDriver<'d, C::AdcUnit>
where
T: ADCPin,
M: Borrow<AdcDriver<'d, T::Adc>>,
C: AdcChannel,
M: Borrow<AdcDriver<'d, C::AdcUnit>>,
{
type Error = EspError;
fn read(&mut self, pin: &mut AdcChannelDriver<'d, T, M>) -> nb::Result<u16, Self::Error> {
fn read(&mut self, pin: &mut AdcChannelDriver<'d, C, M>) -> nb::Result<u16, Self::Error> {
AdcDriver::read(self, pin).map_err(to_nb_err)
}
}
unsafe impl<ADC: Adc> Send for AdcDriver<'_, ADC> {}
unsafe impl<ADC: Adc> Sync for AdcDriver<'_, ADC> {}
unsafe impl<U: AdcUnit> Send for AdcDriver<'_, U> {}
unsafe impl<U: AdcUnit> 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<T> = Attenuated<{ attenuation::DB_12 }, T>;
pub trait AdcChannels {
type Adc: Adc;
type AdcUnit: AdcUnit;
type Iterator<'a>: Iterator<Item = (adc_channel_t, adc_atten_t)>
where
Self: 'a;
@ -1069,10 +1116,9 @@ pub mod continuous {
impl<P> AdcChannels for P
where
P: Peripheral,
P::P: ADCPin,
P: ADCPin,
{
type Adc = <<P as Peripheral>::P as ADCPin>::Adc;
type AdcUnit = <P::AdcChannel as AdcChannel>::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<O>(other: O) -> ChainedAdcChannels<Self, O>
where
A: Adc,
O: AdcChannels<Adc = A>,
O: AdcChannels<AdcUnit = A>,
{
ChainedAdcChannels {
first: Self(PhantomData),
@ -1142,9 +1188,9 @@ pub mod continuous {
impl<A> AdcChannels for EmptyAdcChannels<A>
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<O>(self, other: O) -> ChainedAdcChannels<Self, O>
where
F: AdcChannels,
S: AdcChannels<Adc = F::Adc>,
O: AdcChannels<Adc = F::Adc>,
S: AdcChannels<AdcUnit = F::AdcUnit>,
O: AdcChannels<AdcUnit = F::AdcUnit>,
{
ChainedAdcChannels {
first: self,
@ -1178,9 +1224,9 @@ pub mod continuous {
impl<F, S> AdcChannels for ChainedAdcChannels<F, S>
where
F: AdcChannels,
S: AdcChannels<Adc = F::Adc>,
S: AdcChannels<AdcUnit = F::AdcUnit>,
{
type Adc = F::Adc;
type AdcUnit = F::AdcUnit;
type Iterator<'a>
= core::iter::Chain<F::Iterator<'a>, 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<P = super::ADC1> + 'd,
_i2s: impl Peripheral<P = crate::i2s::I2S0> + 'd,
adc: super::ADC1<'d>,
_i2s: crate::i2s::I2S0<'d>,
config: &config::Config,
channels: impl AdcChannels<Adc = super::ADC1> + 'd,
channels: impl AdcChannels<AdcUnit = super::ADCU1> + 'd,
) -> Result<Self, EspError> {
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<P = super::ADC1> + 'd,
_spi: impl Peripheral<P = crate::spi::SPI3> + 'd,
adc: super::ADC1<'d>,
_spi: crate::spi::SPI3<'d>,
config: &config::Config,
channels: impl AdcChannels<Adc = super::ADC1> + 'd,
channels: impl AdcChannels<AdcUnit = super::ADCU1> + 'd,
) -> Result<Self, EspError> {
Self::internal_new(adc, config, channels)
}
/// Initialize ADC continuous driver with configuration and channels.
#[cfg(not(any(esp32, esp32s2)))]
pub fn new<A: Adc>(
adc: impl Peripheral<P = A> + 'd,
pub fn new<A: Adc + 'd>(
adc: A,
config: &config::Config,
channels: impl AdcChannels<Adc = A> + 'd,
channels: impl AdcChannels<AdcUnit = A::AdcUnit> + 'd,
) -> Result<Self, EspError> {
Self::internal_new(adc, config, channels)
}
fn internal_new<A: Adc>(
_adc: impl Peripheral<P = A> + 'd,
fn internal_new<A: Adc + 'd>(
_adc: A,
config: &config::Config,
channels: impl AdcChannels<Adc = A> + 'd,
channels: impl AdcChannels<AdcUnit = A::AdcUnit> + 'd,
) -> Result<Self, EspError> {
let mut patterns = [adc_digi_pattern_config_t::default(); 32];

View File

@ -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<Alert>, bool);
pub struct CanDriver<'d>(PhantomData<&'d mut ()>, EnumSet<Alert>, bool);
impl<'d> CanDriver<'d> {
pub fn new(
can: impl Peripheral<P = CAN> + 'd,
tx: impl Peripheral<P = impl OutputPin> + 'd,
rx: impl Peripheral<P = impl InputPin> + 'd,
_can: CAN<'d>,
tx: impl OutputPin + 'd,
rx: impl InputPin + 'd,
config: &config::Config,
) -> Result<Self, EspError> {
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<P = CAN> + 'd,
tx: impl Peripheral<P = impl OutputPin> + 'd,
rx: impl Peripheral<P = impl InputPin> + 'd,
can: CAN<'d>,
tx: impl OutputPin + 'd,
rx: impl InputPin + 'd,
config: &config::Config,
) -> Result<Self, EspError> {
Self::wrap(CanDriver::new(can, tx, rx, config)?)

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
use crate::adc;
impl embedded_hal_0_2::adc::Channel<adc::ADC1> for HallSensor {
type ID = ();
fn channel() -> Self::ID {}
}
crate::impl_peripheral!(HallSensor);

View File

@ -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: I2c>(
_i2c: impl Peripheral<P = I2C> + 'd,
sda: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
scl: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
pub fn new<I2C: I2c + 'd>(
_i2c: I2C,
sda: impl InputPin + OutputPin + 'd,
scl: impl InputPin + OutputPin + 'd,
config: &config::Config,
) -> Result<Self, EspError> {
// 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::<ESP_ERR_INVALID_ARG>());
}
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: I2c>(
_i2c: impl Peripheral<P = I2C> + 'd,
sda: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
scl: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
pub fn new<I2C: I2c + 'd>(
_i2c: I2C,
sda: impl InputPin + OutputPin + 'd,
scl: impl InputPin + OutputPin + 'd,
slave_addr: u8,
config: &config::SlaveConfig,
) -> Result<Self, EspError> {
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

View File

@ -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

View File

@ -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<PeripheralRef<'d, impl OutputPin>>,
clk: impl OutputPin + 'd,
dout: impl OutputPin + 'd,
dout2: Option<impl OutputPin + 'd>,
) -> 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<PeripheralRef<'d, impl OutputPin>>,
clk: impl OutputPin + 'd,
dout: impl OutputPin + 'd,
dout2: Option<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(
@ -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: I2s>(
_i2s: impl Peripheral<P = I2S> + 'd,
pub fn new_pdm_rx<I2S: I2s + 'd>(
_i2s: I2S,
rx_cfg: &config::PdmRxConfig,
clk: impl Peripheral<P = impl OutputPin> + 'd,
din: impl Peripheral<P = impl InputPin> + 'd,
clk: impl OutputPin + 'd,
din: impl InputPin + 'd,
) -> Result<Self, EspError> {
let chan_cfg = rx_cfg.channel_cfg.as_sdk(I2S::port());
let this = Self::internal_new::<I2S>(&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, CLK, CLKP, DIN, DINP, const DINC: usize>(
_i2s: I2SP,
pub fn new_pdm_rx_multi<I2S, DIN, const DINC: usize>(
_i2s: I2S,
rx_cfg: &config::PdmRxConfig,
clk: CLKP,
dins: [DINP; DINC],
clk: impl OutputPin + 'd,
dins: [DIN; DINC],
) -> Result<Self, EspError>
where
I2SP: Peripheral<P = I2S> + 'd,
I2S: I2s,
CLKP: Peripheral<P = CLK> + 'd,
CLK: OutputPin,
DINP: Peripheral<P = DIN> + '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::<I2S>(&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<crate::peripheral::PeripheralRef<'d, DIN>>; 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: I2s>(
_i2s: impl Peripheral<P = I2S> + 'd,
pub fn new_pdm_rx<I2S: I2s + 'd>(
_i2s: I2S,
rx_cfg: &config::PdmRxConfig,
clk: impl Peripheral<P = impl OutputPin> + 'd,
din: impl Peripheral<P = impl InputPin> + 'd,
clk: impl OutputPin + 'd,
din: impl InputPin + 'd,
) -> Result<Self, EspError> {
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: I2s>(
_i2s: impl Peripheral<P = I2S> + 'd,
pub fn new_pdm_tx<I2S: I2s + 'd>(
_i2s: I2S,
tx_cfg: &config::PdmTxConfig,
clk: impl Peripheral<P = impl OutputPin> + 'd,
dout: impl Peripheral<P = impl OutputPin> + 'd,
#[cfg(esp_idf_soc_i2s_hw_version_2)] dout2: Option<
impl Peripheral<P = impl OutputPin> + 'd,
>,
clk: impl OutputPin + 'd,
dout: impl OutputPin + 'd,
#[cfg(esp_idf_soc_i2s_hw_version_2)] dout2: Option<impl OutputPin + 'd>,
) -> Result<Self, EspError> {
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: I2s>(
_i2s: impl Peripheral<P = I2S> + 'd,
pub fn new_pdm_tx<I2S: I2s + 'd>(
_i2s: I2S,
tx_cfg: &config::PdmTxConfig,
clk: impl Peripheral<P = impl OutputPin> + 'd,
dout: impl Peripheral<P = impl OutputPin> + 'd,
clk: impl OutputPin + 'd,
dout: impl OutputPin + 'd,
) -> Result<Self, EspError> {
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,
};

View File

@ -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<PeripheralRef<'d, impl InputPin>>,
dout: Option<PeripheralRef<'d, impl OutputPin>>,
mclk: Option<PeripheralRef<'d, impl InputPin + OutputPin>>,
ws: PeripheralRef<'d, impl InputPin + OutputPin>,
bclk: impl InputPin + OutputPin + 'd,
din: Option<impl InputPin + 'd>,
dout: Option<impl OutputPin + 'd>,
mclk: Option<impl InputPin + OutputPin + 'd>,
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<PeripheralRef<'d, impl InputPin>>,
dout: Option<PeripheralRef<'d, impl OutputPin>>,
mclk: Option<PeripheralRef<'d, impl InputPin + OutputPin>>,
ws: PeripheralRef<'d, impl InputPin + OutputPin>,
bclk: impl InputPin + OutputPin + 'd,
din: Option<impl InputPin + 'd>,
dout: Option<impl OutputPin + 'd>,
mclk: Option<impl InputPin + OutputPin + 'd>,
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: I2s>(
_i2s: impl Peripheral<P = I2S> + 'd,
fn internal_new_std<I2S: I2s + 'd>(
_i2s: I2S,
config: &config::StdConfig,
rx: bool,
tx: bool,
bclk: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
din: Option<impl Peripheral<P = impl InputPin> + 'd>,
dout: Option<impl Peripheral<P = impl OutputPin> + 'd>,
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
bclk: impl InputPin + OutputPin + 'd,
din: Option<impl InputPin + 'd>,
dout: Option<impl OutputPin + 'd>,
mclk: Option<impl InputPin + OutputPin + 'd>,
ws: impl InputPin + OutputPin + 'd,
) -> Result<Self, EspError> {
let chan_cfg = config.channel_cfg.as_sdk(I2S::port());
let this = Self::internal_new::<I2S>(&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: I2s>(
_i2s: impl Peripheral<P = I2S> + 'd,
pub fn internal_new_std<I2S: I2s + 'd>(
_i2s: I2S,
config: &config::StdConfig,
rx: bool,
tx: bool,
bclk: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
din: Option<impl Peripheral<P = impl InputPin> + 'd>,
dout: Option<impl Peripheral<P = impl OutputPin> + 'd>,
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
bclk: impl InputPin + OutputPin + 'd,
din: Option<impl InputPin + 'd>,
dout: Option<impl OutputPin + 'd>,
mclk: Option<impl InputPin + OutputPin + 'd>,
ws: impl InputPin + OutputPin + 'd,
) -> Result<Self, EspError> {
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: I2s>(
i2s: impl Peripheral<P = I2S> + 'd,
pub fn new_std_bidir<I2S: I2s + 'd>(
i2s: I2S,
config: &config::StdConfig,
bclk: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
din: impl Peripheral<P = impl InputPin> + 'd,
dout: impl Peripheral<P = impl OutputPin> + 'd,
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
bclk: impl InputPin + OutputPin + 'd,
din: impl InputPin + 'd,
dout: impl OutputPin + 'd,
mclk: Option<impl InputPin + OutputPin + 'd>,
ws: impl InputPin + OutputPin + 'd,
) -> Result<Self, EspError> {
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: I2s>(
i2s: impl Peripheral<P = I2S> + 'd,
pub fn new_std_rx<I2S: I2s + 'd>(
i2s: I2S,
config: &config::StdConfig,
bclk: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
din: impl Peripheral<P = impl InputPin> + 'd,
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
bclk: impl InputPin + OutputPin + 'd,
din: impl InputPin + 'd,
mclk: Option<impl InputPin + OutputPin + 'd>,
ws: impl InputPin + OutputPin + 'd,
) -> Result<Self, EspError> {
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: I2s>(
i2s: impl Peripheral<P = I2S> + 'd,
pub fn new_std_tx<I2S: I2s + 'd>(
i2s: I2S,
config: &config::StdConfig,
bclk: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
dout: impl Peripheral<P = impl OutputPin> + 'd,
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
bclk: impl InputPin + OutputPin + 'd,
dout: impl OutputPin + 'd,
mclk: Option<impl InputPin + OutputPin + 'd>,
ws: impl InputPin + OutputPin + 'd,
) -> Result<Self, EspError> {
Self::internal_new_std(
i2s,

View File

@ -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<PeripheralRef<'d, impl InputPin>>,
dout: Option<PeripheralRef<'d, impl OutputPin>>,
mclk: Option<PeripheralRef<'d, impl InputPin + OutputPin>>,
ws: PeripheralRef<'d, impl InputPin + OutputPin>,
bclk: impl InputPin + OutputPin + 'd,
din: Option<impl InputPin + 'd>,
dout: Option<impl OutputPin + 'd>,
mclk: Option<impl InputPin + OutputPin + 'd>,
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<PeripheralRef<'d, impl InputPin>>,
dout: Option<PeripheralRef<'d, impl OutputPin>>,
mclk: Option<PeripheralRef<'d, impl InputPin + OutputPin>>,
ws: PeripheralRef<'d, impl InputPin + OutputPin>,
bclk: impl InputPin + OutputPin + 'd,
din: Option<impl InputPin + 'd>,
dout: Option<impl OutputPin + 'd>,
mclk: Option<impl InputPin + OutputPin + 'd>,
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: I2s>(
_i2s: impl Peripheral<P = I2S> + 'd,
fn internal_new_tdm<I2S: I2s + 'd>(
_i2s: I2S,
config: &config::TdmConfig,
rx: bool,
tx: bool,
bclk: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
din: Option<impl Peripheral<P = impl InputPin> + 'd>,
dout: Option<impl Peripheral<P = impl OutputPin> + 'd>,
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
bclk: impl InputPin + OutputPin + 'd,
din: Option<impl InputPin + 'd>,
dout: Option<impl OutputPin + 'd>,
mclk: Option<impl InputPin + OutputPin + 'd>,
ws: impl InputPin + OutputPin + 'd,
) -> Result<Self, EspError> {
let chan_cfg = config.channel_cfg.as_sdk(I2S::port());
let this = Self::internal_new::<I2S>(&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: I2s>(
_i2s: impl Peripheral<P = I2S> + 'd,
fn internal_new_tdm<I2S: I2s + 'd>(
_i2s: I2S,
config: &config::TdmConfig,
rx: bool,
tx: bool,
bclk: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
din: Option<impl Peripheral<P = impl InputPin> + 'd>,
dout: Option<impl Peripheral<P = impl OutputPin> + 'd>,
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
bclk: impl InputPin + OutputPin + 'd,
din: Option<impl InputPin + 'd>,
dout: Option<impl OutputPin + 'd>,
mclk: Option<impl InputPin + OutputPin + 'd>,
ws: impl InputPin + OutputPin + 'd,
) -> Result<Self, EspError> {
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: I2s>(
i2s: impl Peripheral<P = I2S> + 'd,
pub fn new_tdm_bidir<I2S: I2s + 'd>(
i2s: I2S,
config: &config::TdmConfig,
bclk: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
din: impl Peripheral<P = impl InputPin> + 'd,
dout: impl Peripheral<P = impl OutputPin> + 'd,
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
bclk: impl InputPin + OutputPin + 'd,
din: impl InputPin + 'd,
dout: impl OutputPin + 'd,
mclk: Option<impl InputPin + OutputPin + 'd>,
ws: impl InputPin + OutputPin + 'd,
) -> Result<Self, EspError> {
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: I2s>(
i2s: impl Peripheral<P = I2S> + 'd,
pub fn new_tdm_rx<I2S: I2s + 'd>(
i2s: I2S,
config: &config::TdmConfig,
bclk: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
din: impl Peripheral<P = impl InputPin> + 'd,
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
bclk: impl InputPin + OutputPin + 'd,
din: impl InputPin + 'd,
mclk: Option<impl InputPin + OutputPin + 'd>,
ws: impl InputPin + OutputPin + 'd,
) -> Result<Self, EspError> {
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: I2s>(
i2s: impl Peripheral<P = I2S> + 'd,
pub fn new_tdm_tx<I2S: I2s + 'd>(
i2s: I2S,
config: &config::TdmConfig,
bclk: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
dout: impl Peripheral<P = impl OutputPin> + 'd,
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
bclk: impl InputPin + OutputPin + 'd,
dout: impl OutputPin + 'd,
mclk: Option<impl InputPin + OutputPin + 'd>,
ws: impl InputPin + OutputPin + 'd,
) -> Result<Self, EspError> {
Self::internal_new_tdm(
i2s,

View File

@ -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<S>,
_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<P = T> + 'd,
pub fn new<T: LedcTimer<SpeedMode = S> + 'd>(
_timer: T,
config: &config::TimerConfig,
) -> Result<Self, EspError> {
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<T> Drop for LedcTimerDriver<'_, T>
impl<S> Drop for LedcTimerDriver<'_, S>
where
T: LedcTimer,
S: SpeedMode,
{
fn drop(&mut self) {
self.reset().unwrap();
}
}
unsafe impl<T> Send for LedcTimerDriver<'_, T> where T: LedcTimer {}
unsafe impl<S> 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<C, T, B>(
_channel: impl Peripheral<P = C> + 'd,
pub fn new<C, B>(
_channel: C,
timer_driver: B,
pin: impl Peripheral<P = impl OutputPin> + 'd,
pin: impl OutputPin + 'd,
) -> Result<Self, EspError>
where
C: LedcChannel<SpeedMode = <T as LedcTimer>::SpeedMode>,
T: LedcTimer + 'd,
B: Borrow<LedcTimerDriver<'d, T>>,
C: LedcChannel + 'd,
B: Borrow<LedcTimerDriver<'d, C::SpeedMode>>,
{
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<P = impl OutputPin> + '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(),
}
}
}

View File

@ -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;

View File

@ -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<P = Self> {}
pub trait WifiModemPeripheral {}
#[cfg(any(esp32h2, esp32h4, esp32c6))]
pub trait ThreadModemPeripheral: Peripheral<P = Self> {}
pub trait ThreadModemPeripheral {}
#[cfg(not(esp32s2))]
pub trait BluetoothModemPeripheral: Peripheral<P = Self> {}
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<'_> {}
}

View File

@ -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<C: RmtChannel>(
pin: impl Peripheral<P = impl crate::gpio::InputPin + crate::gpio::OutputPin> + 'a,
_channel: impl Peripheral<P = C> + 'a,
pub fn new<C: RmtChannel + 'a>(
pin: impl crate::gpio::InputPin + crate::gpio::OutputPin + 'a,
_channel: C,
) -> Result<Self, EspError> {
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 };

View File

@ -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: Pcnt>(
_pcnt: impl Peripheral<P = PCNT> + 'd,
pin0: Option<impl Peripheral<P = impl InputPin> + 'd>,
pin1: Option<impl Peripheral<P = impl InputPin> + 'd>,
pin2: Option<impl Peripheral<P = impl InputPin> + 'd>,
pin3: Option<impl Peripheral<P = impl InputPin> + 'd>,
pub fn new<PCNT: Pcnt + 'd>(
_pcnt: PCNT,
pin0: Option<impl InputPin + 'd>,
pin1: Option<impl InputPin + 'd>,
pin2: Option<impl InputPin + 'd>,
pin3: Option<impl InputPin + 'd>,
) -> Result<Self, EspError> {
// 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<impl Peripheral<P = impl InputPin> + 'a>,
// ctrl_pin: Option<impl Peripheral<P = impl InputPin> + 'a>,
// pulse_pin: Option<impl InputPin + 'a>,
// ctrl_pin: Option<impl InputPin + 'a>,
// ) -> 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

View File

@ -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<P = T>,
{
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<P = T>,
{
// 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<U>(self) -> PeripheralRef<'a, U>
where
T: Into<U>,
{
PeripheralRef {
inner: self.inner.into(),
_lifetime: PhantomData,
}
}
}
impl<T> Deref for PeripheralRef<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> 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<P = T> + 'd,
/// irq: impl Peripheral<P = T::Interrupt> + 'd,
/// sda: impl Peripheral<P = impl GpioPin> + 'd,
/// scl: impl Peripheral<P = impl GpioPin> + '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<P = ..>` 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<T: DerefMut> sealed::Sealed for T {}
impl<T: DerefMut> Peripheral for T
where
T::Target: Peripheral,
{
type P = <T::Target as Peripheral>::P;
#[inline]
unsafe fn clone_unchecked(&mut self) -> Self::P {
self.deref_mut().clone_unchecked()
}
}
pub(crate) mod sealed {
pub trait Sealed {}
}

View File

@ -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(),
}
}
}

View File

@ -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::*;

View File

@ -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<C: RmtChannel>(
_channel: impl Peripheral<P = C> + 'd,
pin: impl Peripheral<P = impl OutputPin> + 'd,
pub fn new<C: RmtChannel + 'd>(
_channel: C,
pin: impl OutputPin + 'd,
config: &TransmitConfig,
) -> Result<Self, EspError> {
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<C: RmtChannel>(
_channel: impl Peripheral<P = C> + 'd,
pin: impl Peripheral<P = impl InputPin> + 'd,
pub fn new<C: RmtChannel + 'd>(
_channel: C,
pin: impl InputPin + 'd,
config: &ReceiveConfig,
ring_buf_size: usize,
) -> Result<Self, EspError> {
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(),
}
}
}

View File

@ -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<S: SdMmc>(
slot: impl Peripheral<P = S> + 'd,
cmd: impl Peripheral<P = impl OutputPin> + 'd,
clk: impl Peripheral<P = impl OutputPin> + 'd,
d0: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
cd: Option<impl Peripheral<P = impl InputPin> + 'd>,
wp: Option<impl Peripheral<P = impl InputPin> + 'd>,
pub fn new_1bit(
slot: impl SdMmc + 'd,
cmd: impl OutputPin + 'd,
clk: impl OutputPin + 'd,
d0: impl InputPin + OutputPin + 'd,
cd: Option<impl InputPin + 'd>,
wp: Option<impl InputPin + 'd>,
config: &config::Configuration,
) -> Result<Self, EspError> {
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<S: SdMmc>(
slot: impl Peripheral<P = S> + 'd,
cmd: impl Peripheral<P = impl OutputPin> + 'd,
clk: impl Peripheral<P = impl OutputPin> + 'd,
d0: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
d1: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
d2: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
d3: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
cd: Option<impl Peripheral<P = impl InputPin> + 'd>,
wp: Option<impl Peripheral<P = impl InputPin> + 'd>,
pub fn new_4bits<S: SdMmc + 'd>(
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<impl InputPin + 'd>,
wp: Option<impl InputPin + 'd>,
config: &config::Configuration,
) -> Result<Self, EspError> {
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<S: SdMmc>(
slot: impl Peripheral<P = S> + 'd,
cmd: impl Peripheral<P = impl OutputPin> + 'd,
clk: impl Peripheral<P = impl OutputPin> + 'd,
d0: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
d1: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
d2: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
d3: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
d4: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
d5: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
d6: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
d7: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
cd: Option<impl Peripheral<P = impl InputPin> + 'd>,
wp: Option<impl Peripheral<P = impl InputPin> + 'd>,
pub fn new_8bits<S: SdMmc + 'd>(
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<impl InputPin + 'd>,
wp: Option<impl InputPin + 'd>,
config: &config::Configuration,
) -> Result<Self, EspError> {
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<P = SDMMC0> + 'd,
cmd: impl Peripheral<P = gpio::Gpio11> + 'd,
clk: impl Peripheral<P = gpio::Gpio6> + 'd,
d0: impl Peripheral<P = gpio::Gpio7> + 'd,
cd: Option<impl Peripheral<P = impl InputPin> + 'd>,
wp: Option<impl Peripheral<P = impl InputPin> + 'd>,
slot0: SDMMC0<'d>,
cmd: gpio::Gpio11<'d>,
clk: gpio::Gpio6<'d>,
d0: gpio::Gpio7<'d>,
cd: Option<impl InputPin + 'd>,
wp: Option<impl InputPin + 'd>,
config: &config::Configuration,
) -> Result<Self, EspError> {
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<P = SDMMC0> + 'd,
cmd: impl Peripheral<P = gpio::Gpio11> + 'd,
clk: impl Peripheral<P = gpio::Gpio6> + 'd,
d0: impl Peripheral<P = gpio::Gpio7> + 'd,
d1: impl Peripheral<P = gpio::Gpio8> + 'd,
d2: impl Peripheral<P = gpio::Gpio9> + 'd,
d3: impl Peripheral<P = gpio::Gpio10> + 'd,
cd: Option<impl Peripheral<P = impl InputPin> + 'd>,
wp: Option<impl Peripheral<P = impl InputPin> + '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<impl InputPin + 'd>,
wp: Option<impl InputPin + 'd>,
config: &config::Configuration,
) -> Result<Self, EspError> {
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<P = SDMMC0> + 'd,
cmd: impl Peripheral<P = gpio::Gpio11> + 'd,
clk: impl Peripheral<P = gpio::Gpio6> + 'd,
d0: impl Peripheral<P = gpio::Gpio7> + 'd,
d1: impl Peripheral<P = gpio::Gpio8> + 'd,
d2: impl Peripheral<P = gpio::Gpio9> + 'd,
d3: impl Peripheral<P = gpio::Gpio10> + 'd,
d4: impl Peripheral<P = gpio::Gpio16> + 'd,
d5: impl Peripheral<P = gpio::Gpio17> + 'd,
d6: impl Peripheral<P = gpio::Gpio5> + 'd,
d7: impl Peripheral<P = gpio::Gpio18> + 'd,
cd: Option<impl Peripheral<P = impl InputPin> + 'd>,
wp: Option<impl Peripheral<P = impl InputPin> + '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<impl InputPin + 'd>,
wp: Option<impl InputPin + 'd>,
config: &config::Configuration,
) -> Result<Self, EspError> {
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<P = SDMMC1> + 'd,
cmd: impl Peripheral<P = gpio::Gpio15> + 'd,
clk: impl Peripheral<P = gpio::Gpio14> + 'd,
d0: impl Peripheral<P = gpio::Gpio2> + 'd,
cd: Option<impl Peripheral<P = impl InputPin> + 'd>,
wp: Option<impl Peripheral<P = impl InputPin> + 'd>,
slot1: SDMMC1<'d>,
cmd: gpio::Gpio15<'d>,
clk: gpio::Gpio14<'d>,
d0: gpio::Gpio2<'d>,
cd: Option<impl InputPin + 'd>,
wp: Option<impl InputPin + 'd>,
config: &config::Configuration,
) -> Result<Self, EspError> {
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<P = SDMMC1> + 'd,
cmd: impl Peripheral<P = gpio::Gpio15> + 'd,
clk: impl Peripheral<P = gpio::Gpio14> + 'd,
d0: impl Peripheral<P = gpio::Gpio2> + 'd,
d1: impl Peripheral<P = gpio::Gpio4> + 'd,
d2: impl Peripheral<P = gpio::Gpio12> + 'd,
d3: impl Peripheral<P = gpio::Gpio13> + 'd,
cd: Option<impl Peripheral<P = impl InputPin> + 'd>,
wp: Option<impl Peripheral<P = impl InputPin> + '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<impl InputPin + 'd>,
wp: Option<impl InputPin + 'd>,
config: &config::Configuration,
) -> Result<Self, EspError> {
Self::new_internal(
@ -338,22 +336,22 @@ impl<'d> SdMmcHostDriver<'d> {
}
#[allow(clippy::too_many_arguments)]
fn new_internal<S: SdMmc>(
fn new_internal<S: SdMmc + 'd>(
width: u8,
internal_pullups: bool,
_slot: impl Peripheral<P = S> + 'd,
_cmd: impl Peripheral<P = impl OutputPin> + 'd,
_clk: impl Peripheral<P = impl OutputPin> + 'd,
_d0: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
_d1: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
_d2: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
_d3: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
_d4: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
_d5: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
_d6: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
_d7: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
cd: Option<impl Peripheral<P = impl InputPin> + 'd>,
wp: Option<impl Peripheral<P = impl InputPin> + 'd>,
_slot: S,
_cmd: impl OutputPin + 'd,
_clk: impl OutputPin + 'd,
_d0: impl InputPin + OutputPin + 'd,
_d1: Option<impl InputPin + OutputPin + 'd>,
_d2: Option<impl InputPin + OutputPin + 'd>,
_d3: Option<impl InputPin + OutputPin + 'd>,
_d4: Option<impl InputPin + OutputPin + 'd>,
_d5: Option<impl InputPin + OutputPin + 'd>,
_d6: Option<impl InputPin + OutputPin + 'd>,
_d7: Option<impl InputPin + OutputPin + 'd>,
cd: Option<impl InputPin + 'd>,
wp: Option<impl InputPin + 'd>,
) -> Result<Self, EspError> {
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
}

View File

@ -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<impl Peripheral<P = impl OutputPin> + 'd>,
cd: Option<impl Peripheral<P = impl InputPin> + 'd>,
wp: Option<impl Peripheral<P = impl InputPin> + 'd>,
int: Option<impl Peripheral<P = impl InputPin> + 'd>,
cs: Option<impl OutputPin + 'd>,
cd: Option<impl InputPin + 'd>,
wp: Option<impl InputPin + 'd>,
int: Option<impl InputPin + 'd>,
#[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"),

View File

@ -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<P = SPI1> + 'd,
sclk: impl Peripheral<P = crate::gpio::Gpio6> + 'd,
sdo: impl Peripheral<P = crate::gpio::Gpio7> + 'd,
sdi: Option<impl Peripheral<P = crate::gpio::Gpio8> + 'd>,
_spi: SPI1<'d>,
sclk: crate::gpio::Gpio6<'d>,
sdo: crate::gpio::Gpio7<'d>,
sdi: Option<crate::gpio::Gpio8<'d>>,
config: &config::DriverConfig,
) -> Result<Self, EspError> {
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: SpiAnyPins>(
_spi: impl Peripheral<P = SPI> + 'd,
sclk: impl Peripheral<P = impl OutputPin> + 'd,
sdo: impl Peripheral<P = impl OutputPin> + 'd,
sdi: Option<impl Peripheral<P = impl InputPin> + 'd>,
pub fn new<SPI: SpiAnyPins + 'd>(
_spi: SPI,
sclk: impl OutputPin + 'd,
sdo: impl OutputPin + 'd,
sdi: Option<impl InputPin + 'd>,
config: &config::DriverConfig,
) -> Result<Self, EspError> {
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: SpiAnyPins>(
_spi: impl Peripheral<P = SPI> + 'd,
sdo: impl Peripheral<P = impl OutputPin> + 'd,
sdi: Option<impl Peripheral<P = impl InputPin> + 'd>,
pub fn new_without_sclk<SPI: SpiAnyPins + 'd>(
_spi: SPI,
sdo: impl OutputPin + 'd,
sdi: Option<impl InputPin + 'd>,
config: &config::DriverConfig,
) -> Result<Self, EspError> {
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: SpiAnyPins>(
_spi: impl Peripheral<P = SPI> + 'd,
sclk: impl Peripheral<P = impl OutputPin> + 'd,
data0: impl Peripheral<P = impl IOPin> + 'd,
data1: impl Peripheral<P = impl IOPin> + 'd,
pub fn new_dual<SPI: SpiAnyPins + 'd>(
_spi: SPI,
sclk: impl OutputPin + 'd,
data0: impl InputPin + OutputPin + 'd,
data1: impl InputPin + OutputPin + 'd,
config: &config::DriverConfig,
) -> Result<Self, EspError> {
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: SpiAnyPins>(
_spi: impl Peripheral<P = SPI> + 'd,
sclk: impl Peripheral<P = impl OutputPin> + 'd,
data0: impl Peripheral<P = impl IOPin> + 'd,
data1: impl Peripheral<P = impl IOPin> + 'd,
data2: impl Peripheral<P = impl IOPin> + 'd,
data3: impl Peripheral<P = impl IOPin> + 'd,
pub fn new_quad<SPI: SpiAnyPins + 'd>(
_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<Self, EspError> {
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<P = SPI1> + 'd,
sclk: impl Peripheral<P = crate::gpio::Gpio6> + 'd,
sdo: impl Peripheral<P = crate::gpio::Gpio7> + 'd,
sdi: Option<impl Peripheral<P = crate::gpio::Gpio8> + 'd>,
cs: Option<impl Peripheral<P = impl OutputPin> + 'd>,
spi: SPI1<'d>,
sclk: crate::gpio::Gpio6<'d>,
sdo: crate::gpio::Gpio7<'d>,
sdi: Option<crate::gpio::Gpio8<'d>>,
cs: Option<impl OutputPin + 'd>,
bus_config: &config::DriverConfig,
config: &config::Config,
) -> Result<Self, EspError> {
@ -984,12 +983,12 @@ impl<'d> SpiDeviceDriver<'d, SpiDriver<'d>> {
)
}
pub fn new_single<SPI: SpiAnyPins>(
spi: impl Peripheral<P = SPI> + 'd,
sclk: impl Peripheral<P = impl OutputPin> + 'd,
sdo: impl Peripheral<P = impl OutputPin> + 'd,
sdi: Option<impl Peripheral<P = impl InputPin> + 'd>,
cs: Option<impl Peripheral<P = impl OutputPin> + 'd>,
pub fn new_single<SPI: SpiAnyPins + 'd>(
spi: SPI,
sclk: impl OutputPin + 'd,
sdo: impl OutputPin + 'd,
sdi: Option<impl InputPin + 'd>,
cs: Option<impl OutputPin + 'd>,
bus_config: &config::DriverConfig,
config: &config::Config,
) -> Result<Self, EspError> {
@ -1003,10 +1002,10 @@ where
{
pub fn new(
driver: T,
cs: Option<impl Peripheral<P = impl OutputPin> + 'd>,
cs: Option<impl OutputPin + 'd>,
config: &config::Config,
) -> Result<Self, EspError> {
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<Item = Operation<'a>> + '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<Item = Operation<'a>> + '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<Item = Operation<'a>> + 'a,
) -> Result<CsCtl<'c, 'p, AnyOutputPin, Output>, EspError> {
) -> Result<CsCtl<'c, 'p, Output>, 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<u32>,
post_delay_us: Option<u32>,
_p: PhantomData<fn() -> DRIVER>,
@ -1517,12 +1514,10 @@ where
{
pub fn new(
shared_device: DEVICE,
cs: impl Peripheral<P = impl OutputPin> + 'd,
cs: impl OutputPin + 'd,
cs_level: Level,
) -> Result<Self, EspError> {
crate::into_ref!(cs);
let mut cs_pin: PinDriver<AnyOutputPin, Output> = PinDriver::output(cs.map_into())?;
let mut cs_pin: PinDriver<Output> = 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<usize>,
},
Software {
cs: &'c mut PinDriver<'p, P, M>,
cs: &'c mut PinDriver<'p, M>,
pre_delay: Option<u32>,
post_delay: Option<u32>,
},
}
impl<P, M> CsCtl<'_, '_, P, M>
impl<M> 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<'_> {}
};
}

View File

@ -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<P = TWDT> + 'd,
config: &config::Config,
) -> Result<Self, EspError> {
pub fn new(_twdt: TWDT<'d>, config: &config::Config) -> Result<Self, EspError> {
TWDT_DRIVER_REF_COUNT.fetch_add(1, Ordering::SeqCst);
let init_by_idf = Self::watchdog_is_init_by_idf();

View File

@ -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<P = TempSensor> + 'd,
) -> Result<Self, EspError> {
pub fn new(config: &TempSensorConfig, _sensor: TempSensor<'d>) -> Result<Self, EspError> {
let mut sensor = core::ptr::null_mut();
esp!(unsafe { temperature_sensor_install(&config.into(), &mut sensor) })?;
Ok(TempSensorDriver {

View File

@ -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: Timer>(
_timer: impl Peripheral<P = TIMER> + 'd,
pub fn new<TIMER: Timer + 'd>(
_timer: TIMER,
config: &config::Config,
) -> Result<Self, EspError> {
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

View File

@ -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: Uart>(
uart: impl Peripheral<P = UART> + 'd,
tx: impl Peripheral<P = impl OutputPin> + 'd,
rx: impl Peripheral<P = impl InputPin> + 'd,
cts: Option<impl Peripheral<P = impl InputPin> + 'd>,
rts: Option<impl Peripheral<P = impl OutputPin> + 'd>,
pub fn new<UART: Uart + 'd>(
uart: UART,
tx: impl OutputPin + 'd,
rx: impl InputPin + 'd,
cts: Option<impl InputPin + 'd>,
rts: Option<impl OutputPin + 'd>,
config: &config::Config,
) -> Result<Self, EspError> {
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: Uart>(
uart: impl Peripheral<P = UART> + 'd,
rx: impl Peripheral<P = impl InputPin> + 'd,
cts: Option<impl Peripheral<P = impl InputPin> + 'd>,
rts: Option<impl Peripheral<P = impl OutputPin> + 'd>,
pub fn new<UART: Uart + 'd>(
uart: UART,
rx: impl InputPin + 'd,
cts: Option<impl InputPin + 'd>,
rts: Option<impl OutputPin + 'd>,
config: &config::Config,
) -> Result<Self, EspError> {
let mut q_handle_raw = ptr::null_mut();
@ -1269,11 +1267,11 @@ impl embedded_hal_nb::serial::Read<u8> for UartRxDriver<'_> {
impl<'d> UartTxDriver<'d> {
/// Create a new serial transmitter
pub fn new<UART: Uart>(
uart: impl Peripheral<P = UART> + 'd,
tx: impl Peripheral<P = impl OutputPin> + 'd,
cts: Option<impl Peripheral<P = impl InputPin> + 'd>,
rts: Option<impl Peripheral<P = impl OutputPin> + 'd>,
pub fn new<UART: Uart + 'd>(
uart: UART,
tx: impl OutputPin + 'd,
cts: Option<impl InputPin + 'd>,
rts: Option<impl OutputPin + 'd>,
config: &config::Config,
) -> Result<Self, EspError> {
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<P = impl Uart> + 'd,
tx: impl Peripheral<P = impl OutputPin> + 'd,
rx: impl Peripheral<P = impl InputPin> + 'd,
cts: Option<impl Peripheral<P = impl InputPin> + 'd>,
rts: Option<impl Peripheral<P = impl OutputPin> + 'd>,
pub fn new<UART: Uart + 'd>(
uart: UART,
tx: impl OutputPin + 'd,
rx: impl InputPin + 'd,
cts: Option<impl InputPin + 'd>,
rts: Option<impl OutputPin + 'd>,
config: &config::Config,
) -> Result<Self, EspError> {
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<P = impl Uart> + 'd,
rx: impl Peripheral<P = impl InputPin> + 'd,
cts: Option<impl Peripheral<P = impl InputPin> + 'd>,
rts: Option<impl Peripheral<P = impl OutputPin> + 'd>,
pub fn new<UART: Uart + 'd>(
uart: UART,
rx: impl InputPin + 'd,
cts: Option<impl InputPin + 'd>,
rts: Option<impl OutputPin + 'd>,
config: &config::Config,
) -> Result<Self, EspError> {
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<P = impl Uart> + 'd,
tx: impl Peripheral<P = impl OutputPin> + 'd,
cts: Option<impl Peripheral<P = impl InputPin> + 'd>,
rts: Option<impl Peripheral<P = impl OutputPin> + 'd>,
pub fn new<UART: Uart + 'd>(
uart: UART,
tx: impl OutputPin + 'd,
cts: Option<impl InputPin + 'd>,
rts: Option<impl OutputPin + 'd>,
config: &config::Config,
) -> Result<Self, EspError> {
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: Uart>(
_uart: impl Peripheral<P = UART>,
tx: Option<impl Peripheral<P = impl OutputPin>>,
rx: Option<impl Peripheral<P = impl InputPin>>,
cts: Option<impl Peripheral<P = impl InputPin>>,
rts: Option<impl Peripheral<P = impl OutputPin>>,
fn new_common<'d, UART: Uart + 'd>(
_uart: UART,
tx: Option<impl OutputPin + 'd>,
rx: Option<impl InputPin + 'd>,
cts: Option<impl InputPin + 'd>,
rts: Option<impl OutputPin + 'd>,
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<UART: Uart>(
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<UART: Uart>(
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
}

View File

@ -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<P = ULP> + 'd,
) -> Result<Self, esp_idf_sys::EspError> {
crate::into_ref!(ulp);
Ok(Self(ulp))
pub fn new(ulp: ULP<'d>) -> Result<Self, esp_idf_sys::EspError> {
Ok(Self(PhantomData))
}
pub fn stop(&mut self) -> Result<(), esp_idf_sys::EspError> {

View File

@ -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<P = USB_SERIAL> + 'd,
_usb_d_min: impl Peripheral<P = UsbDMinGpio>,
_usb_d_plus: impl Peripheral<P = UsbDPlusGpio>,
_usb_serial: USB_SERIAL<'d>,
_usb_d_min: UsbDMinGpio<'d>,
_usb_d_plus: UsbDPlusGpio<'d>,
config: &config::Config,
) -> Result<Self, EspError> {
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