mirror of
https://github.com/esp-rs/esp-idf-hal.git
synced 2025-09-26 20:00:35 +00:00
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:
parent
676f0043de
commit
2af4695aac
@ -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+
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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>> {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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>> {
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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},
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
396
src/adc.rs
396
src/adc.rs
@ -1,5 +1,7 @@
|
||||
//! Analog to Digital Converter peripheral control.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use esp_idf_sys::*;
|
||||
|
||||
#[cfg(all(
|
||||
@ -20,10 +22,82 @@ pub use continuous::{
|
||||
))]
|
||||
pub use oneshot_legacy::*;
|
||||
|
||||
pub trait Adc: Send {
|
||||
/// A trait designating the ADC Unit
|
||||
///
|
||||
/// An associated type provided by ADC peripherals
|
||||
pub trait AdcUnit: 'static {
|
||||
/// Return the ESP-IDF ADC unit identifier.
|
||||
fn unit() -> adc_unit_t;
|
||||
}
|
||||
|
||||
macro_rules! impl_adcu {
|
||||
($adcu:ident: $unit:expr) => {
|
||||
pub struct $adcu;
|
||||
|
||||
impl AdcUnit for $adcu {
|
||||
fn unit() -> adc_unit_t {
|
||||
$unit
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_adcu!(ADCU1: adc_unit_t_ADC_UNIT_1);
|
||||
#[cfg(any(esp32, esp32s2, esp32s3, esp32c3))]
|
||||
impl_adcu!(ADCU2: adc_unit_t_ADC_UNIT_2);
|
||||
|
||||
/// A trait designating the ADC channel
|
||||
///
|
||||
/// An associated type provided by ADC pins
|
||||
pub trait AdcChannel: 'static {
|
||||
/// The ADC unit this channel is associated with.
|
||||
type AdcUnit: AdcUnit;
|
||||
|
||||
/// Return the ESP-IDF ADC unit identifier.
|
||||
fn unit() -> adc_unit_t {
|
||||
Self::AdcUnit::unit()
|
||||
}
|
||||
|
||||
/// Return the ESP-IDF ADC channel identifier.
|
||||
fn channel() -> adc_channel_t;
|
||||
}
|
||||
|
||||
macro_rules! impl_adcch {
|
||||
($adcch:ident: $unit:expr) => {
|
||||
pub struct $adcch<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];
|
||||
|
||||
|
23
src/can.rs
23
src/can.rs
@ -44,7 +44,6 @@ use esp_idf_sys::*;
|
||||
use crate::cpu::Core;
|
||||
use crate::delay::{self, BLOCK, NON_BLOCK};
|
||||
use crate::interrupt::InterruptType;
|
||||
use crate::peripheral::{Peripheral, PeripheralRef};
|
||||
use crate::task::asynch::Notification;
|
||||
use crate::{gpio::*, task};
|
||||
|
||||
@ -384,22 +383,20 @@ pub enum Alert {
|
||||
}
|
||||
|
||||
/// CAN abstraction
|
||||
pub struct CanDriver<'d>(PeripheralRef<'d, CAN>, EnumSet<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)?)
|
||||
|
2142
src/gpio.rs
2142
src/gpio.rs
File diff suppressed because it is too large
Load Diff
@ -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);
|
31
src/i2c.rs
31
src/i2c.rs
@ -8,7 +8,6 @@ use esp_idf_sys::*;
|
||||
use crate::delay::*;
|
||||
use crate::gpio::*;
|
||||
use crate::interrupt::InterruptType;
|
||||
use crate::peripheral::Peripheral;
|
||||
use crate::units::*;
|
||||
|
||||
pub use embedded_hal::i2c::Operation;
|
||||
@ -210,10 +209,10 @@ pub struct I2cDriver<'d> {
|
||||
}
|
||||
|
||||
impl<'d> I2cDriver<'d> {
|
||||
pub fn new<I2C: 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
|
||||
|
@ -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
|
||||
|
151
src/i2s/pdm.rs
151
src/i2s/pdm.rs
@ -25,7 +25,7 @@
|
||||
//! See the [`PdmTxSlotConfig documentation`][PdmTxSlotConfig] for more details.
|
||||
|
||||
use super::*;
|
||||
use crate::{gpio::*, peripheral::Peripheral};
|
||||
use crate::gpio::*;
|
||||
|
||||
// Note on cfg settings:
|
||||
// esp_idf_soc_i2s_hw_version_1 and esp_idf_soc_i2s_hw_version_2 are defined *only* for ESP-IDF v5.0+.
|
||||
@ -37,7 +37,7 @@ use esp_idf_sys::*;
|
||||
|
||||
pub(super) mod config {
|
||||
#[allow(unused)]
|
||||
use crate::{gpio::*, i2s::config::*, peripheral::*};
|
||||
use crate::{gpio::*, i2s::config::*};
|
||||
use esp_idf_sys::*;
|
||||
|
||||
/// I2S pulse density modulation (PDM) downsampling mode.
|
||||
@ -174,8 +174,8 @@ pub(super) mod config {
|
||||
#[inline(always)]
|
||||
pub(super) fn as_sdk<'d>(
|
||||
&self,
|
||||
clk: PeripheralRef<'d, impl OutputPin>,
|
||||
din: PeripheralRef<'d, impl InputPin>,
|
||||
clk: impl OutputPin + 'd,
|
||||
din: impl InputPin + 'd,
|
||||
) -> i2s_pdm_rx_config_t {
|
||||
i2s_pdm_rx_config_t {
|
||||
clk_cfg: self.clk_cfg.as_sdk(),
|
||||
@ -192,10 +192,10 @@ pub(super) mod config {
|
||||
not(all(esp_idf_version_major = "5", esp_idf_version_minor = "0"))
|
||||
))]
|
||||
#[inline(always)]
|
||||
pub(super) fn as_sdk_multi<'d>(
|
||||
pub(super) fn as_sdk_multi<'d, DIN: InputPin + 'd>(
|
||||
&self,
|
||||
clk: PeripheralRef<'d, impl OutputPin>,
|
||||
dins: &[PeripheralRef<'d, impl InputPin>],
|
||||
clk: impl OutputPin + 'd,
|
||||
dins: &[DIN],
|
||||
) -> i2s_pdm_rx_config_t {
|
||||
i2s_pdm_rx_config_t {
|
||||
clk_cfg: self.clk_cfg.as_sdk(),
|
||||
@ -298,8 +298,8 @@ pub(super) mod config {
|
||||
))]
|
||||
pub(crate) fn as_sdk<'d>(
|
||||
&self,
|
||||
clk: PeripheralRef<'d, impl OutputPin>,
|
||||
din: PeripheralRef<'d, impl InputPin>,
|
||||
clk: impl OutputPin + 'd,
|
||||
din: impl InputPin + 'd,
|
||||
) -> i2s_pdm_rx_gpio_config_t {
|
||||
let invert_flags = i2s_pdm_rx_gpio_config_t__bindgen_ty_1 {
|
||||
_bitfield_1: i2s_pdm_rx_gpio_config_t__bindgen_ty_1::new_bitfield_1(
|
||||
@ -322,13 +322,13 @@ pub(super) mod config {
|
||||
))]
|
||||
pub(crate) fn as_sdk<'d>(
|
||||
&self,
|
||||
clk: PeripheralRef<'d, impl OutputPin>,
|
||||
din: PeripheralRef<'d, impl InputPin>,
|
||||
clk: impl OutputPin + 'd,
|
||||
din: impl InputPin + 'd,
|
||||
) -> i2s_pdm_rx_gpio_config_t {
|
||||
#[allow(clippy::unnecessary_cast)]
|
||||
let mut dins: [gpio_num_t; SOC_I2S_PDM_MAX_RX_LINES as usize] =
|
||||
[-1; SOC_I2S_PDM_MAX_RX_LINES as usize];
|
||||
dins[0] = din.pin();
|
||||
dins[0] = din.pin() as _;
|
||||
|
||||
let pins = i2s_pdm_rx_gpio_config_t__bindgen_ty_1 { dins };
|
||||
|
||||
@ -340,7 +340,7 @@ pub(super) mod config {
|
||||
};
|
||||
|
||||
i2s_pdm_rx_gpio_config_t {
|
||||
clk: clk.pin(),
|
||||
clk: clk.pin() as _,
|
||||
__bindgen_anon_1: pins,
|
||||
invert_flags,
|
||||
}
|
||||
@ -355,10 +355,10 @@ pub(super) mod config {
|
||||
esp_idf_soc_i2s_supports_pdm_rx,
|
||||
not(all(esp_idf_version_major = "5", esp_idf_version_minor = "0"))
|
||||
))]
|
||||
pub(crate) fn as_sdk_multi<'d>(
|
||||
pub(crate) fn as_sdk_multi<'d, DIN: InputPin + 'd>(
|
||||
&self,
|
||||
clk: PeripheralRef<'d, impl OutputPin>,
|
||||
dins: &[PeripheralRef<'d, impl InputPin>],
|
||||
clk: impl OutputPin + 'd,
|
||||
dins: &[DIN],
|
||||
) -> i2s_pdm_rx_gpio_config_t {
|
||||
#[allow(clippy::unnecessary_cast)]
|
||||
let mut din_pins: [gpio_num_t; SOC_I2S_PDM_MAX_RX_LINES as usize] =
|
||||
@ -370,7 +370,7 @@ pub(super) mod config {
|
||||
break;
|
||||
}
|
||||
|
||||
din_pins[i] = din.pin();
|
||||
din_pins[i] = din.pin() as _;
|
||||
}
|
||||
|
||||
let pins = i2s_pdm_rx_gpio_config_t__bindgen_ty_1 { dins: din_pins };
|
||||
@ -383,7 +383,7 @@ pub(super) mod config {
|
||||
};
|
||||
|
||||
i2s_pdm_rx_gpio_config_t {
|
||||
clk: clk.pin(),
|
||||
clk: clk.pin() as _,
|
||||
__bindgen_anon_1: pins,
|
||||
invert_flags,
|
||||
}
|
||||
@ -710,8 +710,8 @@ pub(super) mod config {
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_sdk<'d>(
|
||||
&self,
|
||||
clk: PeripheralRef<'d, impl OutputPin>,
|
||||
dout: PeripheralRef<'d, impl OutputPin>,
|
||||
clk: impl OutputPin + 'd,
|
||||
dout: impl OutputPin + 'd,
|
||||
) -> i2s_pdm_tx_config_t {
|
||||
i2s_pdm_tx_config_t {
|
||||
clk_cfg: self.clk_cfg.as_sdk(),
|
||||
@ -725,9 +725,9 @@ pub(super) mod config {
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_sdk<'d>(
|
||||
&self,
|
||||
clk: PeripheralRef<'d, impl OutputPin>,
|
||||
dout: PeripheralRef<'d, impl OutputPin>,
|
||||
dout2: Option<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,
|
||||
};
|
||||
|
122
src/i2s/std.rs
122
src/i2s/std.rs
@ -13,13 +13,13 @@
|
||||
//! | ESP32-H2 | I2S0 | I2S0 |
|
||||
|
||||
use super::*;
|
||||
use crate::{gpio::*, peripheral::*};
|
||||
use crate::gpio::*;
|
||||
|
||||
use esp_idf_sys::*;
|
||||
|
||||
pub(super) mod config {
|
||||
#[allow(unused)]
|
||||
use crate::{gpio::*, i2s::config::*, peripheral::*};
|
||||
use crate::{gpio::*, i2s::config::*};
|
||||
use esp_idf_sys::*;
|
||||
|
||||
/// Standard mode configuration for the I2S peripheral.
|
||||
@ -104,11 +104,11 @@ pub(super) mod config {
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_sdk<'d>(
|
||||
&self,
|
||||
bclk: PeripheralRef<'d, impl InputPin + OutputPin>,
|
||||
din: Option<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,
|
||||
|
122
src/i2s/tdm.rs
122
src/i2s/tdm.rs
@ -1,12 +1,12 @@
|
||||
//! Time-division multiplexing (TDM) support for I2S.
|
||||
use super::*;
|
||||
use crate::{gpio::*, peripheral::*};
|
||||
use crate::gpio::*;
|
||||
|
||||
use esp_idf_sys::*;
|
||||
|
||||
pub(super) mod config {
|
||||
#[allow(unused)]
|
||||
use crate::{gpio::*, i2s::config::*, peripheral::*};
|
||||
use crate::{gpio::*, i2s::config::*};
|
||||
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not};
|
||||
use esp_idf_sys::*;
|
||||
|
||||
@ -57,11 +57,11 @@ pub(super) mod config {
|
||||
#[inline(always)]
|
||||
pub(super) fn as_sdk<'d>(
|
||||
&self,
|
||||
bclk: PeripheralRef<'d, impl InputPin + OutputPin>,
|
||||
din: Option<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,
|
||||
|
163
src/ledc.rs
163
src/ledc.rs
@ -29,7 +29,6 @@ use core::sync::atomic::{AtomicBool, Ordering};
|
||||
use esp_idf_sys::*;
|
||||
|
||||
use crate::gpio::OutputPin;
|
||||
use crate::peripheral::{Peripheral, PeripheralRef};
|
||||
use crate::task::CriticalSection;
|
||||
use crate::units::*;
|
||||
|
||||
@ -90,25 +89,24 @@ pub mod config {
|
||||
}
|
||||
|
||||
/// LED Control timer driver
|
||||
pub struct LedcTimerDriver<'d, T>
|
||||
pub struct LedcTimerDriver<'d, S>
|
||||
where
|
||||
T: LedcTimer,
|
||||
S: SpeedMode,
|
||||
{
|
||||
_timer: PeripheralRef<'d, T>,
|
||||
max_duty: Duty,
|
||||
timer: u8,
|
||||
_speed: PhantomData<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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
65
src/lib.rs
65
src/lib.rs
@ -30,8 +30,6 @@ pub mod can;
|
||||
pub mod cpu;
|
||||
pub mod delay;
|
||||
pub mod gpio;
|
||||
#[cfg(all(esp32, esp_idf_version_major = "4"))]
|
||||
pub mod hall;
|
||||
pub mod i2c;
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
@ -53,9 +51,7 @@ pub mod onewire;
|
||||
#[cfg(not(esp_idf_version_at_least_6_0_0))]
|
||||
#[cfg(any(esp32, esp32s2, esp32s3, esp32c6))]
|
||||
pub mod pcnt;
|
||||
pub mod peripheral;
|
||||
pub mod peripherals;
|
||||
pub mod prelude;
|
||||
pub mod reset;
|
||||
pub mod rmt;
|
||||
pub mod rom;
|
||||
@ -131,50 +127,39 @@ macro_rules! embedded_hal_error {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! into_ref {
|
||||
($($name:ident),*) => {
|
||||
$(
|
||||
let $name = $name.into_ref();
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! impl_peripheral_trait {
|
||||
($type:ident) => {
|
||||
unsafe impl Send for $type {}
|
||||
|
||||
impl $crate::peripheral::sealed::Sealed for $type {}
|
||||
|
||||
impl $crate::peripheral::Peripheral for $type {
|
||||
type P = $type;
|
||||
|
||||
#[inline]
|
||||
unsafe fn clone_unchecked(&mut self) -> Self::P {
|
||||
$type { ..*self }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! impl_peripheral {
|
||||
($type:ident) => {
|
||||
pub struct $type(::core::marker::PhantomData<*const ()>);
|
||||
($name:ident) => {
|
||||
pub struct $name<'a>(::core::marker::PhantomData<&'a mut ()>);
|
||||
|
||||
impl $type {
|
||||
impl $name<'_> {
|
||||
/// Unsafely create an instance of this peripheral out of thin air.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Care should be taken not to instantiate this peripheral instance, if it is already instantiated and used elsewhere
|
||||
/// You must ensure that you're only using one instance of this type at a time.
|
||||
#[inline(always)]
|
||||
pub unsafe fn new() -> Self {
|
||||
$type(::core::marker::PhantomData)
|
||||
pub unsafe fn steal() -> Self {
|
||||
Self(::core::marker::PhantomData)
|
||||
}
|
||||
|
||||
/// Creates a new peripheral reference with a shorter lifetime.
|
||||
///
|
||||
/// Use this method if you would like to keep working with the peripheral after
|
||||
/// you dropped the driver that consumes this.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that you are not using reborrowed peripherals in drivers which are
|
||||
/// forgotten via `core::mem::forget`.
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub unsafe fn reborrow(&mut self) -> $name<'_> {
|
||||
Self(::core::marker::PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
$crate::impl_peripheral_trait!($type);
|
||||
unsafe impl Send for $name<'_> {}
|
||||
};
|
||||
}
|
||||
|
||||
@ -182,5 +167,3 @@ macro_rules! impl_peripheral {
|
||||
pub(crate) use embedded_hal_error;
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use impl_peripheral;
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use impl_peripheral_trait;
|
||||
|
118
src/modem.rs
118
src/modem.rs
@ -1,112 +1,72 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::peripheral::{sealed, Peripheral};
|
||||
|
||||
#[cfg(not(esp32s2))]
|
||||
pub use split::*;
|
||||
|
||||
use crate::impl_peripheral;
|
||||
|
||||
#[cfg(not(any(esp32h2, esp32h4)))]
|
||||
pub trait WifiModemPeripheral: Peripheral<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<'_> {}
|
||||
}
|
||||
|
@ -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 };
|
||||
|
24
src/pcnt.rs
24
src/pcnt.rs
@ -12,7 +12,6 @@ use esp_idf_sys::*;
|
||||
use enumset::EnumSetType;
|
||||
|
||||
use crate::gpio::InputPin;
|
||||
use crate::peripheral::Peripheral;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum PcntChannel {
|
||||
@ -136,22 +135,19 @@ pub struct PcntDriver<'d> {
|
||||
macro_rules! pin_to_number {
|
||||
($pin:ident) => {
|
||||
match $pin {
|
||||
Some(pin) => {
|
||||
crate::into_ref!(pin);
|
||||
pin.pin()
|
||||
}
|
||||
Some(pin) => pin.pin() as _,
|
||||
None => PCNT_PIN_NOT_USED,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<'d> PcntDriver<'d> {
|
||||
pub fn new<PCNT: 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
|
||||
|
@ -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 {}
|
||||
}
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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::*;
|
59
src/rmt.rs
59
src/rmt.rs
@ -721,9 +721,8 @@ mod driver {
|
||||
};
|
||||
use esp_idf_sys::{rmt_channel_t, rmt_driver_uninstall};
|
||||
|
||||
use crate::gpio::InputPin;
|
||||
use crate::gpio::{InputPin, OutputPin};
|
||||
use crate::interrupt::InterruptType;
|
||||
use crate::{gpio::OutputPin, peripheral::Peripheral};
|
||||
|
||||
use super::RmtChannel;
|
||||
|
||||
@ -745,13 +744,11 @@ mod driver {
|
||||
/// To uninstall the driver just drop it.
|
||||
///
|
||||
/// Internally this calls `rmt_config()` and `rmt_driver_install()`.
|
||||
pub fn new<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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
208
src/sd/mmc.rs
208
src/sd/mmc.rs
@ -1,9 +1,7 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::Deref;
|
||||
use core::sync::atomic::{AtomicU8, Ordering};
|
||||
|
||||
use crate::gpio::{self, InputPin, OutputPin};
|
||||
use crate::peripheral::Peripheral;
|
||||
use crate::sys::*;
|
||||
|
||||
/// Indicates that card detect line is not used
|
||||
@ -69,13 +67,13 @@ impl<'d> SdMmcHostDriver<'d> {
|
||||
/// Create a new driver for the provided slot peripheral with data line width 1.
|
||||
#[cfg(esp_idf_soc_sdmmc_use_gpio_matrix)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new_1bit<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
|
||||
}
|
||||
|
@ -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"),
|
||||
|
143
src/spi.rs
143
src/spi.rs
@ -48,10 +48,9 @@ use esp_idf_sys::*;
|
||||
use heapless::Deque;
|
||||
|
||||
use crate::delay::{self, Ets, BLOCK};
|
||||
use crate::gpio::{AnyOutputPin, IOPin, InputPin, Level, Output, OutputMode, OutputPin, PinDriver};
|
||||
use crate::gpio::{AnyOutputPin, InputPin, Level, Output, OutputMode, OutputPin, PinDriver};
|
||||
use crate::interrupt::asynch::HalIsrNotification;
|
||||
use crate::interrupt::InterruptType;
|
||||
use crate::peripheral::Peripheral;
|
||||
use crate::task::embassy_sync::EspRawMutex;
|
||||
use crate::task::CriticalSection;
|
||||
|
||||
@ -431,19 +430,19 @@ impl<'d> SpiDriver<'d> {
|
||||
/// SPI1 can only use fixed pin for SCLK, SDO and SDI as they are shared with SPI0.
|
||||
#[cfg(esp32)]
|
||||
pub fn new_spi1(
|
||||
_spi: impl Peripheral<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<'_> {}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
101
src/uart.rs
101
src/uart.rs
@ -56,8 +56,6 @@ use crate::{gpio::*, task};
|
||||
use embedded_hal_nb::serial::ErrorKind;
|
||||
use esp_idf_sys::*;
|
||||
|
||||
use crate::peripheral::Peripheral;
|
||||
|
||||
const UART_FIFO_SIZE: usize = SOC_UART_FIFO_LEN as usize;
|
||||
|
||||
pub type UartConfig = config::Config;
|
||||
@ -737,12 +735,12 @@ pub struct UartTxDriver<'d> {
|
||||
|
||||
impl<'d> UartDriver<'d> {
|
||||
/// Create a new serial driver
|
||||
pub fn new<UART: 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
|
||||
}
|
||||
|
10
src/ulp.rs
10
src/ulp.rs
@ -77,7 +77,7 @@ impl Word {
|
||||
all(esp32s2, esp_idf_esp32s2_ulp_coproc_enabled),
|
||||
all(esp32s3, esp_idf_esp32s3_ulp_coproc_enabled)
|
||||
))]
|
||||
pub struct UlpDriver<'d>(crate::peripheral::PeripheralRef<'d, ULP>);
|
||||
pub struct UlpDriver<'d>(PhantomData<&'d mut ()>);
|
||||
|
||||
#[cfg(any(
|
||||
all(not(esp_idf_version_major = "4"), esp_idf_ulp_coproc_enabled),
|
||||
@ -94,12 +94,8 @@ unsafe impl<'d> Send for UlpDriver<'d> {}
|
||||
all(esp32s3, esp_idf_esp32s3_ulp_coproc_enabled)
|
||||
))]
|
||||
impl<'d> UlpDriver<'d> {
|
||||
pub fn new(
|
||||
ulp: impl crate::peripheral::Peripheral<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> {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user