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