Skip to main content

esp_idf_hal/
lib.rs

1#![no_std]
2#![allow(async_fn_in_trait)]
3#![allow(unknown_lints)]
4#![allow(renamed_and_removed_lints)]
5#![allow(clippy::unused_unit)] // enumset
6#![allow(unexpected_cfgs)]
7#![warn(clippy::large_futures)]
8#![cfg_attr(feature = "nightly", feature(doc_cfg))]
9#![cfg_attr(target_arch = "xtensa", allow(unused_features))]
10#![cfg_attr(target_arch = "xtensa", feature(asm_experimental_arch))]
11
12#[cfg(not(esp_idf_comp_driver_enabled))]
13compile_error!("esp-idf-hal requires the `driver` ESP-IDF component to be enabled");
14
15// mutually exclusive features assert
16#[cfg(all(feature = "rmt-legacy", esp_idf_comp_espressif__onewire_bus_enabled))]
17compile_error!("the onewire component cannot be used with the legacy rmt peripheral");
18
19#[cfg(feature = "std")]
20#[allow(unused_imports)]
21#[macro_use]
22extern crate std;
23
24#[cfg(feature = "alloc")]
25#[allow(unused_imports)]
26#[macro_use]
27extern crate alloc;
28
29pub mod adc;
30pub mod can;
31pub mod cpu;
32pub mod delay;
33pub mod gpio;
34pub mod i2c;
35#[cfg_attr(
36    feature = "nightly",
37    doc(cfg(all(esp_idf_soc_i2s_supported, esp_idf_comp_driver_enabled)))
38)]
39pub mod i2s;
40pub mod interrupt;
41pub mod io;
42#[cfg(all(esp32p4, esp_idf_comp_esp_lcd_enabled, feature = "alloc"))]
43pub mod lcd;
44#[cfg(esp32p4)]
45pub mod ldo;
46pub mod ledc;
47#[cfg(any(all(esp32, esp_idf_eth_use_esp32_emac), esp_idf_eth_use_openeth))]
48pub mod mac;
49#[cfg(any(not(esp32p4), esp_idf_comp_espressif__esp_wifi_remote_enabled))]
50pub mod modem;
51#[cfg(all(
52    esp_idf_soc_rmt_supported,
53    not(feature = "rmt-legacy"),
54    esp_idf_comp_espressif__onewire_bus_enabled,
55))]
56pub mod onewire;
57
58#[cfg(all(not(feature = "pcnt-legacy"), esp_idf_soc_pcnt_supported))]
59#[cfg_attr(feature = "nightly", doc(cfg(esp_idf_soc_pcnt_supported)))]
60pub mod pcnt;
61
62#[cfg(not(esp_idf_version_at_least_6_0_0))]
63#[cfg(all(
64    any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
65    feature = "pcnt-legacy"
66))]
67#[cfg_attr(
68    all(
69        not(esp_idf_version_at_least_6_0_0),
70        any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
71        feature = "pcnt-legacy"
72    ),
73    deprecated(
74        since = "0.46.0",
75        note = "use the new `pcnt` api by disabling the `pcnt-legacy` feature"
76    )
77)]
78mod pcnt_legacy;
79
80#[cfg(not(esp_idf_version_at_least_6_0_0))]
81#[cfg(all(
82    any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
83    feature = "pcnt-legacy"
84))]
85pub mod pcnt {
86    pub use crate::pcnt_legacy::*;
87}
88
89pub mod peripherals;
90pub mod reset;
91
92#[cfg(all(
93    esp_idf_soc_rmt_supported,
94    not(feature = "rmt-legacy"),
95    feature = "alloc"
96))]
97#[cfg_attr(
98    feature = "nightly",
99    doc(cfg(all(
100        esp_idf_soc_rmt_supported,
101        not(feature = "rmt-legacy"),
102        feature = "alloc"
103    )))
104)]
105pub mod rmt;
106#[cfg(feature = "rmt-legacy")]
107#[cfg_attr(
108    feature = "rmt-legacy",
109    deprecated(
110        since = "0.46.0",
111        note = "use the new `rmt` api by disabling the `rmt-legacy` feature"
112    )
113)]
114mod rmt_legacy;
115#[cfg(feature = "rmt-legacy")]
116pub mod rmt {
117    pub use crate::rmt_legacy::*;
118}
119pub mod rom;
120pub mod sd;
121pub mod sleep;
122pub mod spi;
123pub mod sys;
124pub mod task;
125#[cfg(all(esp_idf_soc_temp_sensor_supported, esp_idf_version_major = "5"))]
126pub mod temp_sensor;
127
128#[cfg(all(
129    esp_idf_soc_gptimer_supported,
130    not(feature = "timer-legacy"),
131    feature = "alloc"
132))]
133#[cfg_attr(
134    feature = "nightly",
135    doc(cfg(all(
136        esp_idf_soc_gptimer_supported,
137        not(feature = "timer-legacy"),
138        feature = "alloc"
139    )))
140)]
141pub mod timer;
142#[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
143#[cfg_attr(
144    all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)),
145    deprecated(
146        since = "0.46.0",
147        note = "use the new `timer` api by disabling the `timer-legacy` feature"
148    )
149)]
150mod timer_legacy;
151#[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
152pub mod timer {
153    pub use crate::timer_legacy::*;
154}
155
156pub mod uart;
157#[cfg(all(
158    any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32p4),
159    esp_idf_comp_ulp_enabled
160))]
161pub mod ulp;
162pub mod units;
163#[cfg(esp_idf_soc_usb_serial_jtag_supported)]
164pub mod usb_serial;
165
166// This is used to create `embedded_hal` compatible error structs
167// that preserve original `EspError`.
168//
169// Example:
170// embedded_hal_error!(I2cError, embedded_hal::i2c::Error, embedded_hal::i2c::ErrorKind)
171#[allow(unused_macros)]
172macro_rules! embedded_hal_error {
173    ($error:ident, $errortrait:ty, $kind:ty) => {
174        #[derive(Debug, Copy, Clone, Eq, PartialEq)]
175        pub struct $error {
176            kind: $kind,
177            cause: esp_idf_sys::EspError,
178        }
179
180        impl $error {
181            pub fn new(kind: $kind, cause: esp_idf_sys::EspError) -> Self {
182                Self { kind, cause }
183            }
184            pub fn other(cause: esp_idf_sys::EspError) -> Self {
185                Self::new(<$kind>::Other, cause)
186            }
187            pub fn cause(&self) -> esp_idf_sys::EspError {
188                self.cause
189            }
190        }
191        impl From<esp_idf_sys::EspError> for $error {
192            fn from(e: esp_idf_sys::EspError) -> Self {
193                Self::other(e)
194            }
195        }
196
197        impl $errortrait for $error {
198            fn kind(&self) -> $kind {
199                self.kind
200            }
201        }
202
203        impl core::fmt::Display for $error {
204            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
205                write!(
206                    f,
207                    "{} {{ kind: {}, cause: {} }}",
208                    stringify!($error),
209                    self.kind,
210                    self.cause()
211                )
212            }
213        }
214
215        #[cfg(feature = "std")]
216        impl std::error::Error for $error {}
217    };
218}
219
220#[allow(unused_macros)]
221macro_rules! impl_peripheral {
222    ($name:ident) => {
223        pub struct $name<'a>(::core::marker::PhantomData<&'a mut ()>);
224
225        impl $name<'_> {
226            /// Unsafely create an instance of this peripheral out of thin air.
227            ///
228            /// # Safety
229            ///
230            /// You must ensure that you're only using one instance of this type at a time.
231            #[inline(always)]
232            pub unsafe fn steal() -> Self {
233                Self(::core::marker::PhantomData)
234            }
235
236            /// Creates a new peripheral reference with a shorter lifetime.
237            ///
238            /// Use this method if you would like to keep working with the peripheral after
239            /// you dropped the driver that consumes this.
240            ///
241            /// # Safety
242            ///
243            /// You must ensure that you are not using reborrowed peripherals in drivers which are
244            /// forgotten via `core::mem::forget`.
245            #[inline]
246            #[allow(dead_code)]
247            pub unsafe fn reborrow(&mut self) -> $name<'_> {
248                Self(::core::marker::PhantomData)
249            }
250        }
251
252        unsafe impl Send for $name<'_> {}
253    };
254}
255
256#[allow(unused_imports)]
257pub(crate) use embedded_hal_error;
258#[allow(unused_imports)]
259pub(crate) use impl_peripheral;
260
261#[cfg(test)]
262fn main() {}