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