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