1use crate::adc;
2use crate::can;
3use crate::gpio;
4use crate::i2c;
5#[cfg(esp_idf_soc_i2s_supported)]
6use crate::i2s;
7#[cfg(all(esp32p4, esp_idf_comp_esp_lcd_enabled, feature = "alloc"))]
8use crate::lcd;
9#[cfg(esp32p4)]
10use crate::ldo;
11use crate::ledc;
12#[cfg(any(all(esp32, esp_idf_eth_use_esp32_emac), esp_idf_eth_use_openeth))]
13use crate::mac;
14#[cfg(any(not(esp32p4), esp_idf_comp_espressif__esp_wifi_remote_enabled))]
15use crate::modem;
16#[cfg(not(esp_idf_version_at_least_6_0_0))]
17#[cfg(all(
18 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
19 feature = "pcnt-legacy"
20))]
21use crate::pcnt;
22#[cfg(feature = "rmt-legacy")]
23use crate::rmt_legacy;
24#[cfg(esp_idf_soc_sdmmc_host_supported)]
25use crate::sd;
26use crate::spi;
27#[cfg(any(
28 all(
29 not(any(esp_idf_version_major = "4", esp_idf_version = "5.0")),
30 esp_idf_esp_task_wdt_en
31 ),
32 any(esp_idf_version_major = "4", esp_idf_version = "5.0")
33))]
34use crate::task::watchdog;
35#[cfg(all(esp_idf_soc_temp_sensor_supported, esp_idf_version_major = "5"))]
36use crate::temp_sensor;
37#[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
38use crate::timer;
39use crate::uart;
40#[cfg(all(
41 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32p4),
42 esp_idf_comp_ulp_enabled
43))]
44use crate::ulp;
45#[cfg(esp_idf_soc_usb_serial_jtag_supported)]
46use crate::usb_serial;
47
48pub struct Peripherals {
49 pub pins: gpio::Pins,
50 pub uart0: uart::UART0<'static>,
51 pub uart1: uart::UART1<'static>,
52 #[cfg(any(esp32, esp32s3, esp32p4))]
53 pub uart2: uart::UART2<'static>,
54 #[cfg(esp32p4)]
55 pub uart3: uart::UART3<'static>,
56 #[cfg(esp32p4)]
57 pub uart4: uart::UART4<'static>,
58 pub i2c0: i2c::I2C0<'static>,
59 #[cfg(not(any(esp32c3, esp32c2, esp32c5, esp32c6, esp32c61)))]
60 pub i2c1: i2c::I2C1<'static>,
61 #[cfg(esp_idf_soc_i2s_supported)]
62 pub i2s0: i2s::I2S0<'static>,
63 #[cfg(all(esp_idf_soc_i2s_supported, any(esp32, esp32s3, esp32p4)))]
64 pub i2s1: i2s::I2S1<'static>,
65 #[cfg(all(esp_idf_soc_i2s_supported, esp32p4))]
66 pub i2s2: i2s::I2S2<'static>,
67 pub spi1: spi::SPI1<'static>,
68 pub spi2: spi::SPI2<'static>,
69 #[cfg(any(esp32, esp32s2, esp32s3, esp32p4))]
70 pub spi3: spi::SPI3<'static>,
71 pub adc1: adc::ADC1<'static>,
72 #[cfg(any(esp32, esp32s2, esp32s3, esp32c3))]
73 pub adc2: adc::ADC2<'static>,
74 #[cfg(not(esp_idf_version_at_least_6_0_0))]
76 #[cfg(all(
77 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
78 feature = "pcnt-legacy"
79 ))]
80 pub pcnt0: pcnt::PCNT0<'static>,
81 #[cfg(not(esp_idf_version_at_least_6_0_0))]
82 #[cfg(all(
83 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
84 feature = "pcnt-legacy"
85 ))]
86 pub pcnt1: pcnt::PCNT1<'static>,
87 #[cfg(not(esp_idf_version_at_least_6_0_0))]
88 #[cfg(all(
89 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
90 feature = "pcnt-legacy"
91 ))]
92 pub pcnt2: pcnt::PCNT2<'static>,
93 #[cfg(not(esp_idf_version_at_least_6_0_0))]
94 #[cfg(all(
95 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
96 feature = "pcnt-legacy"
97 ))]
98 pub pcnt3: pcnt::PCNT3<'static>,
99 #[cfg(not(esp_idf_version_at_least_6_0_0))]
100 #[cfg(all(esp32, feature = "pcnt-legacy"))]
101 pub pcnt4: pcnt::PCNT4<'static>,
102 #[cfg(not(esp_idf_version_at_least_6_0_0))]
103 #[cfg(all(esp32, feature = "pcnt-legacy"))]
104 pub pcnt5: pcnt::PCNT5<'static>,
105 #[cfg(not(esp_idf_version_at_least_6_0_0))]
106 #[cfg(all(esp32, feature = "pcnt-legacy"))]
107 pub pcnt6: pcnt::PCNT6<'static>,
108 #[cfg(not(esp_idf_version_at_least_6_0_0))]
109 #[cfg(all(esp32, feature = "pcnt-legacy"))]
110 pub pcnt7: pcnt::PCNT7<'static>,
111 pub can: can::CAN<'static>,
112 pub ledc: ledc::LEDC,
113 #[cfg(esp32p4)]
114 pub ldo1: ldo::LDO1<'static, ldo::Fixed>,
115 #[cfg(esp32p4)]
116 pub ldo2: ldo::LDO2<'static, ldo::Fixed>,
117 #[cfg(esp32p4)]
118 pub ldo3: ldo::LDO3<'static, ldo::Adjustable>,
119 #[cfg(esp32p4)]
120 pub ldo4: ldo::LDO4<'static, ldo::Adjustable>,
121 #[cfg(all(esp32p4, esp_idf_comp_esp_lcd_enabled, feature = "alloc"))]
122 pub dsi: lcd::DSI<'static>,
123 #[cfg(esp32)]
124 pub hledc: ledc::HLEDC,
125 #[cfg(feature = "rmt-legacy")]
126 pub rmt: rmt_legacy::RMT,
127 #[cfg(all(
128 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32p4),
129 esp_idf_comp_ulp_enabled
130 ))]
131 pub ulp: ulp::ULP<'static>,
132 #[cfg(any(all(esp32, esp_idf_eth_use_esp32_emac), esp_idf_eth_use_openeth))]
133 pub mac: mac::MAC<'static>,
134 #[cfg(any(not(esp32p4), esp_idf_comp_espressif__esp_wifi_remote_enabled))]
135 pub modem: modem::Modem<'static>,
136 #[cfg(esp_idf_soc_sdmmc_host_supported)]
137 pub sdmmc0: sd::mmc::SDMMC0<'static>,
138 #[cfg(esp_idf_soc_sdmmc_host_supported)]
139 pub sdmmc1: sd::mmc::SDMMC1<'static>,
140 #[cfg(all(esp_idf_soc_temp_sensor_supported, esp_idf_version_major = "5"))]
141 pub temp_sensor: temp_sensor::TempSensor<'static>,
142 #[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
144 pub timer00: timer::TIMER00<'static>,
145 #[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
146 #[cfg(any(esp32, esp32s2, esp32s3))]
147 pub timer01: timer::TIMER01<'static>,
148 #[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
149 #[cfg(not(esp32c2))]
150 pub timer10: timer::TIMER10<'static>,
151 #[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
152 #[cfg(any(esp32, esp32s2, esp32s3))]
153 pub timer11: timer::TIMER11<'static>,
154 #[cfg(any(
155 all(
156 not(any(esp_idf_version_major = "4", esp_idf_version = "5.0")),
157 esp_idf_esp_task_wdt_en
158 ),
159 any(esp_idf_version_major = "4", esp_idf_version = "5.0")
160 ))]
161 pub twdt: watchdog::TWDT<'static>,
162 #[cfg(esp_idf_soc_usb_serial_jtag_supported)]
163 pub usb_serial: usb_serial::USB_SERIAL<'static>,
164}
165
166static TAKEN: core::sync::atomic::AtomicBool = core::sync::atomic::AtomicBool::new(false);
167static TAKEN_CS: crate::task::CriticalSection = crate::task::CriticalSection::new();
168
169impl Peripherals {
170 pub fn take() -> Result<Self, crate::sys::EspError> {
171 if TAKEN.load(core::sync::atomic::Ordering::SeqCst) {
172 Err(crate::sys::EspError::from_infallible::<
173 { crate::sys::ESP_ERR_INVALID_STATE },
174 >())
175 } else {
176 let _guard = TAKEN_CS.enter();
177
178 if !TAKEN.load(core::sync::atomic::Ordering::SeqCst) {
179 TAKEN.store(true, core::sync::atomic::Ordering::SeqCst);
180
181 Ok(unsafe { Peripherals::steal() })
182 } else {
183 Err(crate::sys::EspError::from_infallible::<
184 { crate::sys::ESP_ERR_INVALID_STATE },
185 >())
186 }
187 }
188 }
189
190 pub unsafe fn steal() -> Self {
194 Self {
195 pins: gpio::Pins::new(),
196 uart0: uart::UART0::steal(),
197 uart1: uart::UART1::steal(),
198 #[cfg(any(esp32, esp32s3, esp32p4))]
199 uart2: uart::UART2::steal(),
200 #[cfg(esp32p4)]
201 uart3: uart::UART3::steal(),
202 #[cfg(esp32p4)]
203 uart4: uart::UART4::steal(),
204 i2c0: i2c::I2C0::steal(),
205 #[cfg(not(any(esp32c3, esp32c2, esp32c5, esp32c6, esp32c61)))]
206 i2c1: i2c::I2C1::steal(),
207 #[cfg(esp_idf_soc_i2s_supported)]
208 i2s0: i2s::I2S0::steal(),
209 #[cfg(all(esp_idf_soc_i2s_supported, any(esp32, esp32s3, esp32p4)))]
210 i2s1: i2s::I2S1::steal(),
211 #[cfg(all(esp_idf_soc_i2s_supported, esp32p4))]
212 i2s2: i2s::I2S2::steal(),
213 spi1: spi::SPI1::steal(),
214 spi2: spi::SPI2::steal(),
215 #[cfg(any(esp32, esp32s2, esp32s3, esp32p4))]
216 spi3: spi::SPI3::steal(),
217 adc1: adc::ADC1::steal(),
218 #[cfg(any(esp32, esp32s2, esp32s3, esp32c3))]
219 adc2: adc::ADC2::steal(),
220 #[cfg(not(esp_idf_version_at_least_6_0_0))]
221 #[cfg(all(
222 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
223 feature = "pcnt-legacy"
224 ))]
225 pcnt0: pcnt::PCNT0::steal(),
226 #[cfg(not(esp_idf_version_at_least_6_0_0))]
227 #[cfg(all(
228 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
229 feature = "pcnt-legacy"
230 ))]
231 pcnt1: pcnt::PCNT1::steal(),
232 #[cfg(not(esp_idf_version_at_least_6_0_0))]
233 #[cfg(all(
234 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
235 feature = "pcnt-legacy"
236 ))]
237 pcnt2: pcnt::PCNT2::steal(),
238 #[cfg(not(esp_idf_version_at_least_6_0_0))]
239 #[cfg(all(
240 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32c61),
241 feature = "pcnt-legacy"
242 ))]
243 pcnt3: pcnt::PCNT3::steal(),
244 #[cfg(not(esp_idf_version_at_least_6_0_0))]
245 #[cfg(all(esp32, feature = "pcnt-legacy"))]
246 pcnt4: pcnt::PCNT4::steal(),
247 #[cfg(not(esp_idf_version_at_least_6_0_0))]
248 #[cfg(all(esp32, feature = "pcnt-legacy"))]
249 pcnt5: pcnt::PCNT5::steal(),
250 #[cfg(not(esp_idf_version_at_least_6_0_0))]
251 #[cfg(all(esp32, feature = "pcnt-legacy"))]
252 pcnt6: pcnt::PCNT6::steal(),
253 #[cfg(not(esp_idf_version_at_least_6_0_0))]
254 #[cfg(all(esp32, feature = "pcnt-legacy"))]
255 pcnt7: pcnt::PCNT7::steal(),
256 can: can::CAN::steal(),
257 ledc: ledc::LEDC::new(),
258 #[cfg(esp32p4)]
259 ldo1: ldo::LDO1::steal(),
260 #[cfg(esp32p4)]
261 ldo2: ldo::LDO2::steal(),
262 #[cfg(esp32p4)]
263 ldo3: ldo::LDO3::steal(),
264 #[cfg(esp32p4)]
265 ldo4: ldo::LDO4::steal(),
266 #[cfg(all(esp32p4, esp_idf_comp_esp_lcd_enabled, feature = "alloc"))]
267 dsi: lcd::DSI::steal(),
268 #[cfg(esp32)]
269 hledc: ledc::HLEDC::new(),
270 #[cfg(feature = "rmt-legacy")]
271 rmt: rmt_legacy::RMT::new(),
272 #[cfg(all(
273 any(esp32, esp32s2, esp32s3, esp32c5, esp32c6, esp32p4),
274 esp_idf_comp_ulp_enabled
275 ))]
276 ulp: ulp::ULP::steal(),
277 #[cfg(any(all(esp32, esp_idf_eth_use_esp32_emac), esp_idf_eth_use_openeth))]
278 mac: mac::MAC::steal(),
279 #[cfg(any(not(esp32p4), esp_idf_comp_espressif__esp_wifi_remote_enabled))]
280 modem: modem::Modem::steal(),
281 #[cfg(esp_idf_soc_sdmmc_host_supported)]
282 sdmmc0: sd::mmc::SDMMC0::steal(),
283 #[cfg(esp_idf_soc_sdmmc_host_supported)]
284 sdmmc1: sd::mmc::SDMMC1::steal(),
285 #[cfg(all(esp_idf_soc_temp_sensor_supported, esp_idf_version_major = "5"))]
286 temp_sensor: temp_sensor::TempSensor::steal(),
287 #[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
288 timer00: timer::TIMER00::steal(),
289 #[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
290 #[cfg(any(esp32, esp32s2, esp32s3))]
291 timer01: timer::TIMER01::steal(),
292 #[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
293 #[cfg(not(esp32c2))]
294 timer10: timer::TIMER10::steal(),
295 #[cfg(all(feature = "timer-legacy", not(esp_idf_version_at_least_6_0_0)))]
296 #[cfg(any(esp32, esp32s2, esp32s3))]
297 timer11: timer::TIMER11::steal(),
298 #[cfg(any(
299 all(
300 not(any(esp_idf_version_major = "4", esp_idf_version = "5.0")),
301 esp_idf_esp_task_wdt_en
302 ),
303 any(esp_idf_version_major = "4", esp_idf_version = "5.0")
304 ))]
305 twdt: watchdog::TWDT::steal(),
306 #[cfg(esp_idf_soc_usb_serial_jtag_supported)]
307 usb_serial: usb_serial::USB_SERIAL::steal(),
308 }
309 }
310}