1use core::cell::RefCell;
4
5use critical_section::{CriticalSection, Mutex};
6
7use crate::peripherals::SYSTEM;
8
9#[doc(hidden)]
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18#[repr(u8)]
19#[cfg_attr(feature = "defmt", derive(defmt::Format))]
20pub enum Peripheral {
21 #[cfg(spi2)]
23 Spi2,
24 #[cfg(spi3)]
26 Spi3,
27 #[cfg(i2c0)]
29 I2cExt0,
30 #[cfg(i2c1)]
32 I2cExt1,
33 #[cfg(rmt)]
35 Rmt,
36 #[cfg(ledc)]
38 Ledc,
39 #[cfg(mcpwm0)]
41 Mcpwm0,
42 #[cfg(mcpwm1)]
44 Mcpwm1,
45 #[cfg(pcnt)]
47 Pcnt,
48 #[cfg(apb_saradc)]
50 ApbSarAdc,
51 #[cfg(gdma)]
53 Gdma,
54 #[cfg(pdma)]
56 Dma,
57 #[cfg(i2s0)]
59 I2s0,
60 #[cfg(i2s1)]
62 I2s1,
63 #[cfg(usb0)]
65 Usb,
66 #[cfg(aes)]
68 Aes,
69 #[cfg(twai0)]
71 Twai0,
72 #[cfg(twai1)]
74 Twai1,
75 #[cfg(timg0)]
77 Timg0,
78 #[cfg(timg1)]
80 Timg1,
81 #[cfg(sha)]
83 Sha,
84 #[cfg(usb_device)]
86 UsbDevice,
87 #[cfg(uart0)]
89 Uart0,
90 #[cfg(uart1)]
92 Uart1,
93 #[cfg(uart2)]
95 Uart2,
96 #[cfg(rsa)]
98 Rsa,
99 #[cfg(parl_io)]
101 ParlIo,
102 #[cfg(hmac)]
104 Hmac,
105 #[cfg(ecc)]
107 Ecc,
108 #[cfg(soc_etm)]
110 Etm,
111 #[cfg(trace0)]
113 Trace0,
114 #[cfg(lcd_cam)]
116 LcdCam,
117 #[cfg(systimer)]
119 Systimer,
120 #[cfg(tsens)]
122 Tsens,
123}
124
125impl Peripheral {
126 const KEEP_ENABLED: &[Peripheral] = &[
127 Peripheral::Uart0,
128 #[cfg(usb_device)]
129 Peripheral::UsbDevice,
130 #[cfg(systimer)]
131 Peripheral::Systimer,
132 Peripheral::Timg0,
133 ];
134
135 const COUNT: usize = Self::ALL.len();
136
137 const ALL: &[Self] = &[
138 #[cfg(spi2)]
139 Self::Spi2,
140 #[cfg(spi3)]
141 Self::Spi3,
142 #[cfg(i2c0)]
143 Self::I2cExt0,
144 #[cfg(i2c1)]
145 Self::I2cExt1,
146 #[cfg(rmt)]
147 Self::Rmt,
148 #[cfg(ledc)]
149 Self::Ledc,
150 #[cfg(mcpwm0)]
151 Self::Mcpwm0,
152 #[cfg(mcpwm1)]
153 Self::Mcpwm1,
154 #[cfg(pcnt)]
155 Self::Pcnt,
156 #[cfg(apb_saradc)]
157 Self::ApbSarAdc,
158 #[cfg(gdma)]
159 Self::Gdma,
160 #[cfg(pdma)]
161 Self::Dma,
162 #[cfg(i2s0)]
163 Self::I2s0,
164 #[cfg(i2s1)]
165 Self::I2s1,
166 #[cfg(usb0)]
167 Self::Usb,
168 #[cfg(aes)]
169 Self::Aes,
170 #[cfg(twai0)]
171 Self::Twai0,
172 #[cfg(twai1)]
173 Self::Twai1,
174 #[cfg(timg0)]
175 Self::Timg0,
176 #[cfg(timg1)]
177 Self::Timg1,
178 #[cfg(sha)]
179 Self::Sha,
180 #[cfg(usb_device)]
181 Self::UsbDevice,
182 #[cfg(uart0)]
183 Self::Uart0,
184 #[cfg(uart1)]
185 Self::Uart1,
186 #[cfg(uart2)]
187 Self::Uart2,
188 #[cfg(rsa)]
189 Self::Rsa,
190 #[cfg(parl_io)]
191 Self::ParlIo,
192 #[cfg(hmac)]
193 Self::Hmac,
194 #[cfg(ecc)]
195 Self::Ecc,
196 #[cfg(soc_etm)]
197 Self::Etm,
198 #[cfg(trace0)]
199 Self::Trace0,
200 #[cfg(lcd_cam)]
201 Self::LcdCam,
202 #[cfg(systimer)]
203 Self::Systimer,
204 #[cfg(tsens)]
205 Self::Tsens,
206 ];
207}
208
209impl Peripheral {
210 pub fn try_from(value: u8) -> Option<Peripheral> {
211 if value >= Peripheral::COUNT as u8 {
212 return None;
213 }
214
215 Some(unsafe { core::mem::transmute::<u8, Peripheral>(value) })
216 }
217}
218
219static PERIPHERAL_REF_COUNT: Mutex<RefCell<[usize; Peripheral::COUNT]>> =
220 Mutex::new(RefCell::new([0; Peripheral::COUNT]));
221
222pub(crate) fn disable_peripherals() {
226 critical_section::with(|cs| {
228 for p in Peripheral::ALL {
229 if Peripheral::KEEP_ENABLED.contains(p) {
230 continue;
231 }
232 PeripheralClockControl::enable_forced_with_cs(*p, false, true, cs);
233 }
234 })
235}
236
237#[derive(Debug, PartialEq, Eq)]
238#[cfg_attr(feature = "defmt", derive(defmt::Format))]
239pub(crate) struct PeripheralGuard {
240 peripheral: Peripheral,
241}
242
243impl PeripheralGuard {
244 pub(crate) fn new_with(p: Peripheral, init: fn()) -> Self {
245 if !Peripheral::KEEP_ENABLED.contains(&p) && PeripheralClockControl::enable(p) {
246 PeripheralClockControl::reset(p);
247 init();
248 }
249
250 Self { peripheral: p }
251 }
252
253 pub(crate) fn new(p: Peripheral) -> Self {
254 Self::new_with(p, || {})
255 }
256}
257
258impl Drop for PeripheralGuard {
259 fn drop(&mut self) {
260 if !Peripheral::KEEP_ENABLED.contains(&self.peripheral) {
261 PeripheralClockControl::disable(self.peripheral);
262 }
263 }
264}
265
266#[derive(Debug)]
267#[cfg_attr(feature = "defmt", derive(defmt::Format))]
268pub(crate) struct GenericPeripheralGuard<const P: u8> {}
269
270impl<const P: u8> GenericPeripheralGuard<P> {
271 pub(crate) fn new_with(init: fn(CriticalSection<'_>)) -> Self {
272 let peripheral = unwrap!(Peripheral::try_from(P));
273 critical_section::with(|cs| {
274 if !Peripheral::KEEP_ENABLED.contains(&peripheral)
275 && PeripheralClockControl::enable_with_cs(peripheral, cs)
276 {
277 PeripheralClockControl::reset(peripheral);
278 init(cs);
279 }
280 });
281
282 Self {}
283 }
284
285 pub(crate) fn new() -> Self {
286 Self::new_with(|_| {})
287 }
288}
289
290impl<const P: u8> Drop for GenericPeripheralGuard<P> {
291 fn drop(&mut self) {
292 let peripheral = unwrap!(Peripheral::try_from(P));
293 if !Peripheral::KEEP_ENABLED.contains(&peripheral) {
294 PeripheralClockControl::disable(peripheral);
295 }
296 }
297}
298
299pub(crate) struct PeripheralClockControl;
301
302#[cfg(not(any(esp32c6, esp32h2)))]
303impl PeripheralClockControl {
304 fn enable_internal(peripheral: Peripheral, enable: bool, _cs: CriticalSection<'_>) {
305 debug!("Enable {:?} {}", peripheral, enable);
306
307 let system = SYSTEM::regs();
308
309 #[cfg(esp32)]
310 let (perip_clk_en0, peri_clk_en) = { (&system.perip_clk_en(), &system.peri_clk_en()) };
311 #[cfg(not(esp32))]
312 let perip_clk_en0 = &system.perip_clk_en0();
313
314 #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))]
315 let perip_clk_en1 = &system.perip_clk_en1();
316
317 match peripheral {
318 #[cfg(spi2)]
319 Peripheral::Spi2 => {
320 perip_clk_en0.modify(|_, w| w.spi2_clk_en().bit(enable));
321 }
322 #[cfg(spi3)]
323 Peripheral::Spi3 => {
324 perip_clk_en0.modify(|_, w| w.spi3_clk_en().bit(enable));
325 }
326 #[cfg(all(i2c0, esp32))]
327 Peripheral::I2cExt0 => {
328 perip_clk_en0.modify(|_, w| w.i2c0_ext0_clk_en().bit(enable));
329 }
330 #[cfg(all(i2c0, not(esp32)))]
331 Peripheral::I2cExt0 => {
332 perip_clk_en0.modify(|_, w| w.i2c_ext0_clk_en().bit(enable));
333 }
334 #[cfg(i2c1)]
335 Peripheral::I2cExt1 => {
336 perip_clk_en0.modify(|_, w| w.i2c_ext1_clk_en().bit(enable));
337 }
338 #[cfg(rmt)]
339 Peripheral::Rmt => {
340 perip_clk_en0.modify(|_, w| w.rmt_clk_en().bit(enable));
341 }
342 #[cfg(ledc)]
343 Peripheral::Ledc => {
344 perip_clk_en0.modify(|_, w| w.ledc_clk_en().bit(enable));
345 }
346 #[cfg(mcpwm0)]
347 Peripheral::Mcpwm0 => {
348 perip_clk_en0.modify(|_, w| w.pwm0_clk_en().bit(enable));
349 }
350 #[cfg(mcpwm1)]
351 Peripheral::Mcpwm1 => {
352 perip_clk_en0.modify(|_, w| w.pwm1_clk_en().bit(enable));
353 }
354 #[cfg(pcnt)]
355 Peripheral::Pcnt => {
356 perip_clk_en0.modify(|_, w| w.pcnt_clk_en().bit(enable));
357 }
358 #[cfg(apb_saradc)]
359 Peripheral::ApbSarAdc => {
360 perip_clk_en0.modify(|_, w| w.apb_saradc_clk_en().bit(enable));
361 }
362 #[cfg(gdma)]
363 Peripheral::Gdma => {
364 perip_clk_en1.modify(|_, w| w.dma_clk_en().bit(enable));
365 }
366 #[cfg(esp32)]
367 Peripheral::Dma => {
368 perip_clk_en0.modify(|_, w| w.spi_dma_clk_en().bit(enable));
369 }
370 #[cfg(esp32s2)]
371 Peripheral::Dma => {
372 perip_clk_en0.modify(|_, w| w.spi2_dma_clk_en().bit(enable));
373 perip_clk_en0.modify(|_, w| w.spi3_dma_clk_en().bit(enable));
374 perip_clk_en1.modify(|_, w| w.crypto_dma_clk_en().bit(enable));
375 }
376 #[cfg(esp32c3)]
377 Peripheral::I2s0 => {
378 perip_clk_en0.modify(|_, w| w.i2s1_clk_en().bit(enable));
380 }
381 #[cfg(any(esp32s3, esp32, esp32s2))]
382 Peripheral::I2s0 => {
383 perip_clk_en0.modify(|_, w| w.i2s0_clk_en().bit(enable));
384 }
385 #[cfg(any(esp32s3, esp32))]
386 Peripheral::I2s1 => {
387 perip_clk_en0.modify(|_, w| w.i2s1_clk_en().bit(enable));
388 }
389 #[cfg(usb0)]
390 Peripheral::Usb => {
391 perip_clk_en0.modify(|_, w| w.usb_clk_en().bit(enable));
392 }
393 #[cfg(twai0)]
394 Peripheral::Twai0 => {
395 perip_clk_en0.modify(|_, w| w.twai_clk_en().bit(enable));
396 }
397 #[cfg(esp32)]
398 Peripheral::Aes => {
399 peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | enable as u32) });
400 }
401 #[cfg(any(esp32c3, esp32s2, esp32s3))]
402 Peripheral::Aes => {
403 perip_clk_en1.modify(|_, w| w.crypto_aes_clk_en().bit(enable));
404 }
405 #[cfg(timg0)]
406 Peripheral::Timg0 => {
407 #[cfg(any(esp32c3, esp32s2, esp32s3))]
408 perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable));
409 perip_clk_en0.modify(|_, w| w.timergroup_clk_en().bit(enable));
410 }
411 #[cfg(timg1)]
412 Peripheral::Timg1 => {
413 #[cfg(any(esp32c3, esp32s2, esp32s3))]
414 perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable));
415 perip_clk_en0.modify(|_, w| w.timergroup1_clk_en().bit(enable));
416 }
417 #[cfg(sha)]
418 Peripheral::Sha => {
419 #[cfg(not(esp32))]
420 perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().bit(enable));
421 }
422 #[cfg(esp32c3)]
423 Peripheral::UsbDevice => {
424 perip_clk_en0.modify(|_, w| w.usb_device_clk_en().bit(enable));
425 }
426 #[cfg(esp32s3)]
427 Peripheral::UsbDevice => {
428 perip_clk_en1.modify(|_, w| w.usb_device_clk_en().bit(enable));
429 }
430 #[cfg(uart0)]
431 Peripheral::Uart0 => {
432 perip_clk_en0.modify(|_, w| w.uart_clk_en().bit(enable));
433 }
434 #[cfg(uart1)]
435 Peripheral::Uart1 => {
436 perip_clk_en0.modify(|_, w| w.uart1_clk_en().bit(enable));
437 }
438 #[cfg(all(uart2, esp32s3))]
439 Peripheral::Uart2 => {
440 perip_clk_en1.modify(|_, w| w.uart2_clk_en().set_bit());
441 }
442 #[cfg(all(uart2, esp32))]
443 Peripheral::Uart2 => {
444 perip_clk_en0.modify(|_, w| w.uart2_clk_en().bit(enable));
445 }
446 #[cfg(all(rsa, esp32))]
447 Peripheral::Rsa => {
448 peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | ((enable as u32) << 2)) });
449 }
450 #[cfg(all(rsa, any(esp32c3, esp32s2, esp32s3)))]
451 Peripheral::Rsa => {
452 perip_clk_en1.modify(|_, w| w.crypto_rsa_clk_en().bit(enable));
453 system
454 .rsa_pd_ctrl()
455 .modify(|_, w| w.rsa_mem_pd().bit(!enable));
456 }
457 #[cfg(hmac)]
458 Peripheral::Hmac => {
459 perip_clk_en1.modify(|_, w| w.crypto_hmac_clk_en().bit(enable));
460 }
461 #[cfg(ecc)]
462 Peripheral::Ecc => {
463 perip_clk_en1.modify(|_, w| w.crypto_ecc_clk_en().bit(enable));
464 }
465 #[cfg(lcd_cam)]
466 Peripheral::LcdCam => {
467 perip_clk_en1.modify(|_, w| w.lcd_cam_clk_en().bit(enable));
468 }
469 #[cfg(systimer)]
470 Peripheral::Systimer => {
471 perip_clk_en0.modify(|_, w| w.systimer_clk_en().bit(enable));
472 }
473 #[cfg(tsens)]
474 Peripheral::Tsens => {
475 perip_clk_en1.modify(|_, w| w.tsens_clk_en().bit(enable));
476 }
477 }
478 }
479
480 pub(crate) fn reset(peripheral: Peripheral) {
482 debug!("Reset {:?}", peripheral);
483 let system = SYSTEM::regs();
484
485 #[cfg(esp32)]
486 let (perip_rst_en0, peri_rst_en) = (system.perip_rst_en(), system.peri_rst_en());
487 #[cfg(not(esp32))]
488 let perip_rst_en0 = system.perip_rst_en0();
489
490 #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))]
491 let perip_rst_en1 = system.perip_rst_en1();
492
493 critical_section::with(|_cs| match peripheral {
494 #[cfg(spi2)]
495 Peripheral::Spi2 => {
496 perip_rst_en0.modify(|_, w| w.spi2_rst().set_bit());
497 perip_rst_en0.modify(|_, w| w.spi2_rst().clear_bit());
498 }
499 #[cfg(spi3)]
500 Peripheral::Spi3 => {
501 perip_rst_en0.modify(|_, w| w.spi3_rst().set_bit());
502 perip_rst_en0.modify(|_, w| w.spi3_rst().clear_bit());
503 }
504 #[cfg(all(i2c0, esp32))]
505 Peripheral::I2cExt0 => {
506 perip_rst_en0.modify(|_, w| w.i2c0_ext0_rst().set_bit());
507 perip_rst_en0.modify(|_, w| w.i2c0_ext0_rst().clear_bit());
508 }
509 #[cfg(all(i2c0, not(esp32)))]
510 Peripheral::I2cExt0 => {
511 perip_rst_en0.modify(|_, w| w.i2c_ext0_rst().set_bit());
512 perip_rst_en0.modify(|_, w| w.i2c_ext0_rst().clear_bit());
513 }
514 #[cfg(i2c1)]
515 Peripheral::I2cExt1 => {
516 perip_rst_en0.modify(|_, w| w.i2c_ext1_rst().set_bit());
517 perip_rst_en0.modify(|_, w| w.i2c_ext1_rst().clear_bit());
518 }
519 #[cfg(rmt)]
520 Peripheral::Rmt => {
521 perip_rst_en0.modify(|_, w| w.rmt_rst().set_bit());
522 perip_rst_en0.modify(|_, w| w.rmt_rst().clear_bit());
523 }
524 #[cfg(ledc)]
525 Peripheral::Ledc => {
526 perip_rst_en0.modify(|_, w| w.ledc_rst().set_bit());
527 perip_rst_en0.modify(|_, w| w.ledc_rst().clear_bit());
528 }
529 #[cfg(mcpwm0)]
530 Peripheral::Mcpwm0 => {
531 perip_rst_en0.modify(|_, w| w.pwm0_rst().set_bit());
532 perip_rst_en0.modify(|_, w| w.pwm0_rst().clear_bit());
533 }
534 #[cfg(mcpwm1)]
535 Peripheral::Mcpwm1 => {
536 perip_rst_en0.modify(|_, w| w.pwm1_rst().set_bit());
537 perip_rst_en0.modify(|_, w| w.pwm1_rst().clear_bit());
538 }
539 #[cfg(pcnt)]
540 Peripheral::Pcnt => {
541 perip_rst_en0.modify(|_, w| w.pcnt_rst().set_bit());
542 perip_rst_en0.modify(|_, w| w.pcnt_rst().clear_bit());
543 }
544 #[cfg(apb_saradc)]
545 Peripheral::ApbSarAdc => {
546 perip_rst_en0.modify(|_, w| w.apb_saradc_rst().set_bit());
547 perip_rst_en0.modify(|_, w| w.apb_saradc_rst().clear_bit());
548 }
549 #[cfg(gdma)]
550 Peripheral::Gdma => {
551 perip_rst_en1.modify(|_, w| w.dma_rst().set_bit());
552 perip_rst_en1.modify(|_, w| w.dma_rst().clear_bit());
553 }
554 #[cfg(esp32)]
555 Peripheral::Dma => {
556 perip_rst_en0.modify(|_, w| w.spi_dma_rst().set_bit());
557 perip_rst_en0.modify(|_, w| w.spi_dma_rst().clear_bit());
558 }
559 #[cfg(esp32s2)]
560 Peripheral::Dma => {
561 perip_rst_en0.modify(|_, w| w.spi2_dma_rst().set_bit());
562 perip_rst_en0.modify(|_, w| w.spi2_dma_rst().clear_bit());
563 perip_rst_en0.modify(|_, w| w.spi3_dma_rst().set_bit());
564 perip_rst_en0.modify(|_, w| w.spi3_dma_rst().clear_bit());
565 perip_rst_en1.modify(|_, w| w.crypto_dma_rst().set_bit());
566 perip_rst_en1.modify(|_, w| w.crypto_dma_rst().clear_bit());
567 }
568 #[cfg(esp32c3)]
569 Peripheral::I2s0 => {
570 perip_rst_en0.modify(|_, w| w.i2s1_rst().set_bit());
572 perip_rst_en0.modify(|_, w| w.i2s1_rst().clear_bit());
573 }
574 #[cfg(any(esp32s3, esp32, esp32s2))]
575 Peripheral::I2s0 => {
576 perip_rst_en0.modify(|_, w| w.i2s0_rst().set_bit());
577 perip_rst_en0.modify(|_, w| w.i2s0_rst().clear_bit());
578 }
579 #[cfg(any(esp32s3, esp32))]
580 Peripheral::I2s1 => {
581 perip_rst_en0.modify(|_, w| w.i2s1_rst().set_bit());
582 perip_rst_en0.modify(|_, w| w.i2s1_rst().clear_bit());
583 }
584 #[cfg(usb0)]
585 Peripheral::Usb => {
586 perip_rst_en0.modify(|_, w| w.usb_rst().set_bit());
587 perip_rst_en0.modify(|_, w| w.usb_rst().clear_bit());
588 }
589 #[cfg(twai0)]
590 Peripheral::Twai0 => {
591 perip_rst_en0.modify(|_, w| w.twai_rst().set_bit());
592 perip_rst_en0.modify(|_, w| w.twai_rst().clear_bit());
593 }
594 #[cfg(esp32)]
595 Peripheral::Aes => {
596 peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() | 1) });
597 peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & (!1)) });
598 }
599 #[cfg(any(esp32c3, esp32s2, esp32s3))]
600 Peripheral::Aes => {
601 perip_rst_en1.modify(|_, w| w.crypto_aes_rst().set_bit());
602 perip_rst_en1.modify(|_, w| w.crypto_aes_rst().clear_bit());
603 }
604 #[cfg(timg0)]
605 Peripheral::Timg0 => {
606 #[cfg(any(esp32c3, esp32s2, esp32s3))]
607 perip_rst_en0.modify(|_, w| w.timers_rst().set_bit());
608 perip_rst_en0.modify(|_, w| w.timergroup_rst().set_bit());
609 #[cfg(any(esp32c3, esp32s2, esp32s3))]
610 perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit());
611 perip_rst_en0.modify(|_, w| w.timergroup_rst().clear_bit());
612 }
613 #[cfg(timg1)]
614 Peripheral::Timg1 => {
615 #[cfg(any(esp32c3, esp32s2, esp32s3))]
616 perip_rst_en0.modify(|_, w| w.timers_rst().set_bit());
617 perip_rst_en0.modify(|_, w| w.timergroup1_rst().set_bit());
618 #[cfg(any(esp32c3, esp32s2, esp32s3))]
619 perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit());
620 perip_rst_en0.modify(|_, w| w.timergroup1_rst().clear_bit());
621 }
622 #[cfg(sha)]
623 Peripheral::Sha => {
624 #[cfg(not(esp32))]
625 perip_rst_en1.modify(|_, w| w.crypto_sha_rst().set_bit());
626 #[cfg(not(esp32))]
627 perip_rst_en1.modify(|_, w| w.crypto_sha_rst().clear_bit());
628 }
629 #[cfg(esp32c3)]
630 Peripheral::UsbDevice => {
631 perip_rst_en0.modify(|_, w| w.usb_device_rst().set_bit());
632 perip_rst_en0.modify(|_, w| w.usb_device_rst().clear_bit());
633 }
634 #[cfg(esp32s3)]
635 Peripheral::UsbDevice => {
636 perip_rst_en1.modify(|_, w| w.usb_device_rst().set_bit());
637 perip_rst_en1.modify(|_, w| w.usb_device_rst().clear_bit());
638 }
639 #[cfg(uart0)]
640 Peripheral::Uart0 => {
641 perip_rst_en0.modify(|_, w| w.uart_rst().set_bit());
642 perip_rst_en0.modify(|_, w| w.uart_rst().clear_bit());
643 }
644 #[cfg(uart1)]
645 Peripheral::Uart1 => {
646 perip_rst_en0.modify(|_, w| w.uart1_rst().set_bit());
647 perip_rst_en0.modify(|_, w| w.uart1_rst().clear_bit());
648 }
649 #[cfg(all(uart2, esp32s3))]
650 Peripheral::Uart2 => {
651 perip_rst_en1.modify(|_, w| w.uart2_rst().set_bit());
652 perip_rst_en1.modify(|_, w| w.uart2_rst().clear_bit());
653 }
654 #[cfg(all(uart2, esp32))]
655 Peripheral::Uart2 => {
656 perip_rst_en0.modify(|_, w| w.uart2_rst().set_bit());
657 perip_rst_en0.modify(|_, w| w.uart2_rst().clear_bit());
658 }
659 #[cfg(all(rsa, esp32))]
660 Peripheral::Rsa => {
661 peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() | (1 << 2)) });
662 peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << 2)) });
663 }
664 #[cfg(all(rsa, any(esp32c3, esp32s2, esp32s3)))]
665 Peripheral::Rsa => {
666 perip_rst_en1.modify(|_, w| w.crypto_rsa_rst().set_bit());
667 perip_rst_en1.modify(|_, w| w.crypto_rsa_rst().clear_bit());
668 }
669 #[cfg(hmac)]
670 Peripheral::Hmac => {
671 perip_rst_en1.modify(|_, w| w.crypto_hmac_rst().set_bit());
672 perip_rst_en1.modify(|_, w| w.crypto_hmac_rst().clear_bit());
673 }
674 #[cfg(ecc)]
675 Peripheral::Ecc => {
676 perip_rst_en1.modify(|_, w| w.crypto_ecc_rst().set_bit());
677 perip_rst_en1.modify(|_, w| w.crypto_ecc_rst().clear_bit());
678 }
679 #[cfg(lcd_cam)]
680 Peripheral::LcdCam => {
681 perip_rst_en1.modify(|_, w| w.lcd_cam_rst().set_bit());
682 perip_rst_en1.modify(|_, w| w.lcd_cam_rst().clear_bit());
683 }
684 #[cfg(systimer)]
685 Peripheral::Systimer => {
686 perip_rst_en0.modify(|_, w| w.systimer_rst().set_bit());
687 perip_rst_en0.modify(|_, w| w.systimer_rst().clear_bit());
688 }
689 #[cfg(all(tsens, esp32c6))]
690 Peripheral::Tsens => {
691 perip_rst_en0.modify(|_, w| w.tsens_rst().set_bit());
692 perip_rst_en0.modify(|_, w| w.tsens_rst().clear_bit());
693 }
694 #[cfg(all(tsens, esp32c3))]
695 Peripheral::Tsens => {
696 perip_rst_en1.modify(|_, w| w.tsens_rst().set_bit());
697 perip_rst_en1.modify(|_, w| w.tsens_rst().clear_bit());
698 }
699 });
700 }
701}
702
703#[cfg(any(esp32c6, esp32h2))]
704impl PeripheralClockControl {
705 fn enable_internal(peripheral: Peripheral, enable: bool, _cs: CriticalSection<'_>) {
706 debug!("Enable {:?} {}", peripheral, enable);
707 let system = SYSTEM::regs();
708
709 match peripheral {
710 #[cfg(spi2)]
711 Peripheral::Spi2 => {
712 system
713 .spi2_conf()
714 .modify(|_, w| w.spi2_clk_en().bit(enable));
715 }
716 #[cfg(i2c0)]
717 Peripheral::I2cExt0 => {
718 system
719 .i2c0_conf()
720 .modify(|_, w| w.i2c0_clk_en().bit(enable));
721 }
722 #[cfg(i2c1)]
723 Peripheral::I2cExt1 => {
724 system
725 .i2c1_conf()
726 .modify(|_, w| w.i2c1_clk_en().bit(enable));
727 }
728 #[cfg(rmt)]
729 Peripheral::Rmt => {
730 system.rmt_conf().modify(|_, w| w.rmt_clk_en().bit(enable));
731 }
732 #[cfg(ledc)]
733 Peripheral::Ledc => {
734 system
735 .ledc_conf()
736 .modify(|_, w| w.ledc_clk_en().bit(enable));
737 }
738 #[cfg(mcpwm0)]
739 Peripheral::Mcpwm0 => {
740 system.pwm_conf().modify(|_, w| w.pwm_clk_en().bit(enable));
741 }
742 #[cfg(mcpwm1)]
743 Peripheral::Mcpwm1 => {
744 system.pwm_conf.modify(|_, w| w.pwm_clk_en().bit(enable));
745 }
746 #[cfg(apb_saradc)]
747 Peripheral::ApbSarAdc => {
748 system
749 .saradc_conf()
750 .modify(|_, w| w.saradc_reg_clk_en().bit(enable));
751 }
752 #[cfg(gdma)]
753 Peripheral::Gdma => {
754 system
755 .gdma_conf()
756 .modify(|_, w| w.gdma_clk_en().bit(enable));
757 }
758 #[cfg(i2s0)]
759 Peripheral::I2s0 => {
760 system.i2s_conf().modify(|_, w| w.i2s_clk_en().bit(enable));
761 }
762 #[cfg(twai0)]
763 Peripheral::Twai0 => {
764 system
765 .twai0_conf()
766 .modify(|_, w| w.twai0_clk_en().bit(enable));
767
768 if enable {
769 system.twai0_func_clk_conf().modify(|_, w| {
771 w.twai0_func_clk_en()
772 .set_bit()
773 .twai0_func_clk_sel()
774 .variant(false)
775 });
776 }
777 }
778 #[cfg(twai1)]
779 Peripheral::Twai1 => {
780 system
781 .twai1_conf()
782 .modify(|_, w| w.twai1_clk_en().bit(enable));
783 }
784 #[cfg(aes)]
785 Peripheral::Aes => {
786 system.aes_conf().modify(|_, w| w.aes_clk_en().bit(enable));
787 }
788 #[cfg(pcnt)]
789 Peripheral::Pcnt => {
790 system
791 .pcnt_conf()
792 .modify(|_, w| w.pcnt_clk_en().bit(enable));
793 }
794 #[cfg(timg0)]
795 Peripheral::Timg0 => {
796 system
797 .timergroup0_timer_clk_conf()
798 .modify(|_, w| w.tg0_timer_clk_en().bit(enable));
799 }
800 #[cfg(timg1)]
801 Peripheral::Timg1 => {
802 system
803 .timergroup1_timer_clk_conf()
804 .modify(|_, w| w.tg1_timer_clk_en().bit(enable));
805 }
806 #[cfg(sha)]
807 Peripheral::Sha => {
808 system.sha_conf().modify(|_, w| w.sha_clk_en().bit(enable));
809 }
810 #[cfg(usb_device)]
811 Peripheral::UsbDevice => {
812 system
813 .usb_device_conf()
814 .modify(|_, w| w.usb_device_clk_en().bit(enable));
815 }
816 #[cfg(uart0)]
817 Peripheral::Uart0 => {
818 system.uart(0).conf().modify(|_, w| w.clk_en().bit(enable));
819 }
820 #[cfg(uart1)]
821 Peripheral::Uart1 => {
822 system.uart(1).conf().modify(|_, w| w.clk_en().bit(enable));
823 }
824 #[cfg(rsa)]
825 Peripheral::Rsa => {
826 system.rsa_conf().modify(|_, w| w.rsa_clk_en().bit(enable));
827 system
828 .rsa_pd_ctrl()
829 .modify(|_, w| w.rsa_mem_pd().clear_bit());
830 }
831 #[cfg(parl_io)]
832 Peripheral::ParlIo => {
833 system
834 .parl_io_conf()
835 .modify(|_, w| w.parl_clk_en().bit(enable));
836 }
837 #[cfg(hmac)]
838 Peripheral::Hmac => {
839 system
840 .hmac_conf()
841 .modify(|_, w| w.hmac_clk_en().bit(enable));
842 }
843 #[cfg(ecc)]
844 Peripheral::Ecc => {
845 system.ecc_conf().modify(|_, w| w.ecc_clk_en().bit(enable));
846 }
847 #[cfg(soc_etm)]
848 Peripheral::Etm => {
849 system.etm_conf().modify(|_, w| w.etm_clk_en().bit(enable));
850 }
851 #[cfg(trace0)]
852 Peripheral::Trace0 => {
853 system
854 .trace_conf()
855 .modify(|_, w| w.trace_clk_en().bit(enable));
856 }
857 #[cfg(systimer)]
858 Peripheral::Systimer => {
859 system
860 .systimer_conf()
861 .modify(|_, w| w.systimer_clk_en().bit(enable));
862 }
863 #[cfg(tsens)]
864 Peripheral::Tsens => {
865 system
866 .tsens_clk_conf()
867 .modify(|_, w| w.tsens_clk_en().bit(enable));
868
869 system
870 .tsens_clk_conf()
871 .modify(|_, w| w.tsens_clk_sel().bit(enable));
872 }
873 }
874 }
875
876 pub(crate) fn reset(peripheral: Peripheral) {
878 debug!("Reset {:?}", peripheral);
879
880 let system = SYSTEM::regs();
881
882 match peripheral {
883 #[cfg(spi2)]
884 Peripheral::Spi2 => {
885 system.spi2_conf().modify(|_, w| w.spi2_rst_en().set_bit());
886 system
887 .spi2_conf()
888 .modify(|_, w| w.spi2_rst_en().clear_bit());
889 }
890 #[cfg(i2c0)]
891 Peripheral::I2cExt0 => {
892 #[cfg(any(esp32c6, esp32h2))]
893 {
894 system.i2c0_conf().modify(|_, w| w.i2c0_rst_en().set_bit());
895 system
896 .i2c0_conf()
897 .modify(|_, w| w.i2c0_rst_en().clear_bit());
898 }
899 }
900 #[cfg(i2c1)]
901 Peripheral::I2cExt1 => {
902 #[cfg(esp32h2)]
903 {
904 system.i2c1_conf().modify(|_, w| w.i2c1_rst_en().set_bit());
905 system
906 .i2c1_conf()
907 .modify(|_, w| w.i2c1_rst_en().clear_bit());
908 }
909 }
910 #[cfg(rmt)]
911 Peripheral::Rmt => {
912 system.rmt_conf().modify(|_, w| w.rmt_rst_en().set_bit());
913 system.rmt_conf().modify(|_, w| w.rmt_rst_en().clear_bit());
914 }
915 #[cfg(ledc)]
916 Peripheral::Ledc => {
917 system.ledc_conf().modify(|_, w| w.ledc_rst_en().set_bit());
918 system
919 .ledc_conf()
920 .modify(|_, w| w.ledc_rst_en().clear_bit());
921 }
922 #[cfg(mcpwm0)]
923 Peripheral::Mcpwm0 => {
924 system.pwm_conf().modify(|_, w| w.pwm_rst_en().set_bit());
925 system.pwm_conf().modify(|_, w| w.pwm_rst_en().clear_bit());
926 }
927 #[cfg(mcpwm1)]
928 Peripheral::Mcpwm1 => {
929 system.pwm_conf.modify(|_, w| w.pwm_rst_en().set_bit());
930 system.pwm_conf.modify(|_, w| w.pwm_rst_en().clear_bit());
931 }
932 #[cfg(apb_saradc)]
933 Peripheral::ApbSarAdc => {
934 system
935 .saradc_conf()
936 .modify(|_, w| w.saradc_reg_rst_en().set_bit());
937 system
938 .saradc_conf()
939 .modify(|_, w| w.saradc_reg_rst_en().clear_bit());
940 }
941 #[cfg(gdma)]
942 Peripheral::Gdma => {
943 system.gdma_conf().modify(|_, w| w.gdma_rst_en().set_bit());
944 system
945 .gdma_conf()
946 .modify(|_, w| w.gdma_rst_en().clear_bit());
947 }
948 #[cfg(i2s0)]
949 Peripheral::I2s0 => {
950 system.i2s_conf().modify(|_, w| w.i2s_rst_en().set_bit());
951 system.i2s_conf().modify(|_, w| w.i2s_rst_en().clear_bit());
952 }
953 #[cfg(twai0)]
954 Peripheral::Twai0 => {
955 system
956 .twai0_conf()
957 .modify(|_, w| w.twai0_rst_en().set_bit());
958 system
959 .twai0_conf()
960 .modify(|_, w| w.twai0_rst_en().clear_bit());
961 }
962 #[cfg(twai1)]
963 Peripheral::Twai1 => {
964 system
965 .twai1_conf()
966 .modify(|_, w| w.twai1_rst_en().set_bit());
967 system
968 .twai1_conf()
969 .modify(|_, w| w.twai1_rst_en().clear_bit());
970 }
971 #[cfg(aes)]
972 Peripheral::Aes => {
973 system.aes_conf().modify(|_, w| w.aes_rst_en().set_bit());
974 system.aes_conf().modify(|_, w| w.aes_rst_en().clear_bit());
975 }
976 #[cfg(pcnt)]
977 Peripheral::Pcnt => {
978 system.pcnt_conf().modify(|_, w| w.pcnt_rst_en().set_bit());
979 system
980 .pcnt_conf()
981 .modify(|_, w| w.pcnt_rst_en().clear_bit());
982 }
983 #[cfg(timg0)]
984 Peripheral::Timg0 => {
985 }
987 #[cfg(timg1)]
988 Peripheral::Timg1 => {
989 }
991 #[cfg(sha)]
992 Peripheral::Sha => {
993 system.sha_conf().modify(|_, w| w.sha_rst_en().set_bit());
994 system.sha_conf().modify(|_, w| w.sha_rst_en().clear_bit());
995 }
996 #[cfg(usb_device)]
997 Peripheral::UsbDevice => {
998 system
999 .usb_device_conf()
1000 .modify(|_, w| w.usb_device_rst_en().set_bit());
1001 system
1002 .usb_device_conf()
1003 .modify(|_, w| w.usb_device_rst_en().clear_bit());
1004 }
1005 #[cfg(uart0)]
1006 Peripheral::Uart0 => {
1007 system.uart(0).conf().modify(|_, w| w.rst_en().set_bit());
1008 system.uart(0).conf().modify(|_, w| w.rst_en().clear_bit());
1009 }
1010 #[cfg(uart1)]
1011 Peripheral::Uart1 => {
1012 system.uart(1).conf().modify(|_, w| w.rst_en().set_bit());
1013 system.uart(1).conf().modify(|_, w| w.rst_en().clear_bit());
1014 }
1015 #[cfg(rsa)]
1016 Peripheral::Rsa => {
1017 system.rsa_conf().modify(|_, w| w.rsa_rst_en().set_bit());
1018 system.rsa_conf().modify(|_, w| w.rsa_rst_en().clear_bit());
1019 }
1020 #[cfg(parl_io)]
1021 Peripheral::ParlIo => {
1022 system
1023 .parl_io_conf()
1024 .modify(|_, w| w.parl_rst_en().set_bit());
1025 system
1026 .parl_io_conf()
1027 .modify(|_, w| w.parl_rst_en().clear_bit());
1028 }
1029 #[cfg(hmac)]
1030 Peripheral::Hmac => {
1031 system.hmac_conf().modify(|_, w| w.hmac_rst_en().set_bit());
1032 system
1033 .hmac_conf()
1034 .modify(|_, w| w.hmac_rst_en().clear_bit());
1035 }
1036 #[cfg(ecc)]
1037 Peripheral::Ecc => {
1038 system.ecc_conf().modify(|_, w| w.ecc_rst_en().set_bit());
1039 system.ecc_conf().modify(|_, w| w.ecc_rst_en().clear_bit());
1040 }
1041 #[cfg(soc_etm)]
1042 Peripheral::Etm => {
1043 system.etm_conf().modify(|_, w| w.etm_rst_en().set_bit());
1044 system.etm_conf().modify(|_, w| w.etm_rst_en().clear_bit());
1045 }
1046 #[cfg(trace0)]
1047 Peripheral::Trace0 => {
1048 system
1049 .trace_conf()
1050 .modify(|_, w| w.trace_rst_en().set_bit());
1051 system
1052 .trace_conf()
1053 .modify(|_, w| w.trace_rst_en().clear_bit());
1054 }
1055 #[cfg(systimer)]
1056 Peripheral::Systimer => {
1057 system
1058 .systimer_conf()
1059 .modify(|_, w| w.systimer_rst_en().set_bit());
1060 system
1061 .systimer_conf()
1062 .modify(|_, w| w.systimer_rst_en().clear_bit());
1063 }
1064 #[cfg(tsens)]
1065 Peripheral::Tsens => {
1066 system
1067 .tsens_clk_conf()
1068 .modify(|_, w| w.tsens_rst_en().set_bit());
1069 system
1070 .tsens_clk_conf()
1071 .modify(|_, w| w.tsens_rst_en().clear_bit());
1072 }
1073 }
1074 }
1075}
1076
1077impl PeripheralClockControl {
1078 pub(crate) fn enable(peripheral: Peripheral) -> bool {
1085 Self::enable_forced(peripheral, true, false)
1086 }
1087
1088 pub(crate) fn enable_with_cs(peripheral: Peripheral, cs: CriticalSection<'_>) -> bool {
1095 Self::enable_forced_with_cs(peripheral, true, false, cs)
1096 }
1097
1098 pub(crate) fn disable(peripheral: Peripheral) -> bool {
1107 Self::enable_forced(peripheral, false, false)
1108 }
1109
1110 pub(crate) fn enable_forced(peripheral: Peripheral, enable: bool, force: bool) -> bool {
1111 critical_section::with(|cs| Self::enable_forced_with_cs(peripheral, enable, force, cs))
1112 }
1113
1114 pub(crate) fn enable_forced_with_cs(
1115 peripheral: Peripheral,
1116 enable: bool,
1117 force: bool,
1118 cs: CriticalSection<'_>,
1119 ) -> bool {
1120 let mut ref_counts = PERIPHERAL_REF_COUNT.borrow_ref_mut(cs);
1121 let ref_count = &mut ref_counts[peripheral as usize];
1122 if !force {
1123 if enable {
1124 let prev = *ref_count;
1125 *ref_count += 1;
1126 trace!("Enable {:?} {} -> {}", peripheral, prev, *ref_count);
1127 if prev > 0 {
1128 return false;
1129 }
1130 } else {
1131 let prev = *ref_count;
1132 *ref_count -= 1;
1133 trace!("Disable {:?} {} -> {}", peripheral, prev, *ref_count);
1134 if prev > 1 {
1135 return false;
1136 }
1137 assert!(prev != 0);
1138 };
1139 } else if !enable {
1140 assert!(*ref_count == 0);
1141 }
1142
1143 if !enable {
1144 Self::reset(peripheral);
1145 }
1146
1147 Self::enable_internal(peripheral, enable, cs);
1148
1149 true
1150 }
1151}
1152
1153#[cfg(any(esp32, esp32s3))]
1154#[allow(unused_imports)]
1155pub use crate::soc::cpu_control::*;
1156
1157#[derive(Debug, Copy, Clone, PartialEq, Eq, strum::FromRepr)]
1161#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1162#[repr(C)]
1163pub enum Cpu {
1164 ProCpu = 0,
1166 #[cfg(multi_core)]
1168 AppCpu = 1,
1169}
1170
1171impl Cpu {
1172 pub const COUNT: usize = 1 + cfg!(multi_core) as usize;
1174
1175 #[inline(always)]
1177 pub fn current() -> Self {
1178 match raw_core() {
1183 0 => Cpu::ProCpu,
1184 #[cfg(all(multi_core, riscv))]
1185 1 => Cpu::AppCpu,
1186 #[cfg(all(multi_core, xtensa))]
1187 0x2000 => Cpu::AppCpu,
1188 _ => unreachable!(),
1189 }
1190 }
1191
1192 #[inline(always)]
1194 pub(crate) fn other() -> impl Iterator<Item = Self> {
1195 cfg_if::cfg_if! {
1196 if #[cfg(multi_core)] {
1197 match Self::current() {
1198 Cpu::ProCpu => [Cpu::AppCpu].into_iter(),
1199 Cpu::AppCpu => [Cpu::ProCpu].into_iter(),
1200 }
1201 } else {
1202 [].into_iter()
1203 }
1204 }
1205 }
1206
1207 #[inline(always)]
1209 pub(crate) fn all() -> impl Iterator<Item = Self> {
1210 cfg_if::cfg_if! {
1211 if #[cfg(multi_core)] {
1212 [Cpu::ProCpu, Cpu::AppCpu].into_iter()
1213 } else {
1214 [Cpu::ProCpu].into_iter()
1215 }
1216 }
1217 }
1218}
1219
1220#[inline(always)]
1228pub(crate) fn raw_core() -> usize {
1229 cfg_if::cfg_if! {
1231 if #[cfg(all(multi_core, riscv))] {
1232 riscv::register::mhartid::read()
1233 } else if #[cfg(all(multi_core, xtensa))] {
1234 (xtensa_lx::get_processor_id() & 0x2000) as usize
1235 } else {
1236 0
1237 }
1238 }
1239}
1240
1241use crate::rtc_cntl::SocResetReason;
1242
1243#[derive(Debug, Copy, Clone)]
1245#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1246#[instability::unstable]
1247pub enum SleepSource {
1248 Undefined = 0,
1250 All,
1253 Ext0,
1255 Ext1,
1257 Timer,
1259 TouchPad,
1261 Ulp,
1263 Gpio,
1265 Uart,
1267 Wifi,
1269 Cocpu,
1271 CocpuTrapTrig,
1273 BT,
1275}
1276
1277#[inline]
1279pub fn software_reset() -> ! {
1280 crate::rom::software_reset()
1281}
1282
1283#[instability::unstable]
1285#[inline]
1286pub fn software_reset_cpu(cpu: Cpu) {
1287 crate::rom::software_reset_cpu(cpu as u32)
1288}
1289
1290#[instability::unstable]
1293#[inline]
1294pub fn reset_reason() -> Option<SocResetReason> {
1295 crate::rtc_cntl::reset_reason(Cpu::current())
1296}
1297
1298#[instability::unstable]
1300#[inline]
1301pub fn wakeup_cause() -> SleepSource {
1302 crate::rtc_cntl::wakeup_cause()
1303}