1use core::borrow::Borrow;
26use core::marker::PhantomData;
27use core::sync::atomic::{AtomicBool, Ordering};
28
29use esp_idf_sys::*;
30
31use crate::gpio::OutputPin;
32use crate::task::CriticalSection;
33use crate::units::*;
34
35pub use chip::*;
36
37type Duty = u32;
38type HPoint = Duty;
39
40const IDLE_LEVEL: u32 = 0;
41
42static FADE_FUNC_INSTALLED: AtomicBool = AtomicBool::new(false);
43static FADE_FUNC_INSTALLED_CS: CriticalSection = CriticalSection::new();
44
45crate::embedded_hal_error!(
46 PwmError,
47 embedded_hal::pwm::Error,
48 embedded_hal::pwm::ErrorKind
49);
50
51pub mod config {
53 use super::*;
54
55 pub use chip::Resolution;
56
57 #[derive(Clone, Debug, Eq, PartialEq)]
58 pub struct TimerConfig {
59 pub frequency: Hertz,
60 pub resolution: Resolution,
61 }
62
63 impl TimerConfig {
64 pub const fn new() -> Self {
65 Self {
66 frequency: Hertz(1000),
67 resolution: Resolution::Bits8,
68 }
69 }
70
71 #[must_use]
72 pub fn frequency(mut self, f: Hertz) -> Self {
73 self.frequency = f;
74 self
75 }
76
77 #[must_use]
78 pub fn resolution(mut self, r: Resolution) -> Self {
79 self.resolution = r;
80 self
81 }
82 }
83
84 impl Default for TimerConfig {
85 fn default() -> Self {
86 Self::new()
87 }
88 }
89}
90
91pub struct LedcTimerDriver<'d, S>
93where
94 S: SpeedMode,
95{
96 max_duty: Duty,
97 timer: u8,
98 _speed: PhantomData<S>,
99 _p: PhantomData<&'d mut ()>,
100}
101
102impl<'d, S> LedcTimerDriver<'d, S>
103where
104 S: SpeedMode,
105{
106 pub fn new<T: LedcTimer<SpeedMode = S> + 'd>(
107 _timer: T,
108 config: &config::TimerConfig,
109 ) -> Result<Self, EspError> {
110 let timer_config = ledc_timer_config_t {
111 speed_mode: T::SpeedMode::SPEED_MODE,
112 timer_num: T::timer() as _,
113 #[cfg(esp_idf_version_major = "4")]
114 __bindgen_anon_1: ledc_timer_config_t__bindgen_ty_1 {
115 duty_resolution: config.resolution.timer_bits(),
116 },
117 #[cfg(not(esp_idf_version_major = "4"))]
118 duty_resolution: config.resolution.timer_bits(),
119 freq_hz: config.frequency.into(),
120 #[cfg(not(esp_idf_version_at_least_5_1_0))]
121 clk_cfg: ledc_clk_cfg_t_LEDC_AUTO_CLK,
122 #[cfg(esp_idf_version_at_least_5_1_0)]
123 clk_cfg: soc_periph_ledc_clk_src_legacy_t_LEDC_AUTO_CLK,
124 #[cfg(not(any(
125 esp_idf_version_major = "4",
126 all(esp_idf_version_major = "5", esp_idf_version_minor = "0"),
127 all(esp_idf_version_major = "5", esp_idf_version_minor = "1")
128 )))]
129 deconfigure: false,
130 };
131
132 esp!(unsafe { ledc_timer_config(&timer_config) })?;
134
135 Ok(Self {
136 max_duty: config.resolution.max_duty(),
137 timer: T::timer() as _,
138 _speed: PhantomData,
139 _p: PhantomData,
140 })
141 }
142
143 pub fn pause(&mut self) -> Result<(), EspError> {
145 esp!(unsafe { ledc_timer_pause(S::SPEED_MODE, self.timer()) })?;
146 Ok(())
147 }
148
149 pub fn resume(&mut self) -> Result<(), EspError> {
151 esp!(unsafe { ledc_timer_resume(S::SPEED_MODE, self.timer()) })?;
152 Ok(())
153 }
154
155 pub fn set_frequency(&mut self, frequency: Hertz) -> Result<(), EspError> {
157 esp!(unsafe { ledc_set_freq(S::SPEED_MODE, self.timer(), frequency.into()) })?;
158 Ok(())
159 }
160
161 fn reset(&mut self) -> Result<(), EspError> {
162 esp!(unsafe { ledc_timer_rst(S::SPEED_MODE, self.timer()) })?;
163 Ok(())
164 }
165
166 pub fn timer(&self) -> ledc_timer_t {
167 self.timer as _
168 }
169}
170
171impl<S> Drop for LedcTimerDriver<'_, S>
172where
173 S: SpeedMode,
174{
175 fn drop(&mut self) {
176 self.reset().unwrap();
177 }
178}
179
180unsafe impl<S> Send for LedcTimerDriver<'_, S> where S: SpeedMode {}
181
182pub struct LedcDriver<'d> {
184 channel: u8,
185 timer: u8,
186 duty: Duty,
187 hpoint: HPoint,
188 speed_mode: ledc_mode_t,
189 max_duty: Duty,
190 _p: PhantomData<&'d mut ()>,
191}
192
193impl<'d> LedcDriver<'d> {
197 pub fn new<C, B>(
199 _channel: C,
200 timer_driver: B,
201 pin: impl OutputPin + 'd,
202 ) -> Result<Self, EspError>
203 where
204 C: LedcChannel + 'd,
205 B: Borrow<LedcTimerDriver<'d, C::SpeedMode>>,
206 {
207 if !FADE_FUNC_INSTALLED.load(Ordering::SeqCst) {
208 let _guard = FADE_FUNC_INSTALLED_CS.enter();
209
210 if !FADE_FUNC_INSTALLED.load(Ordering::SeqCst) {
211 esp!(unsafe { ledc_fade_func_install(0) })?;
218
219 FADE_FUNC_INSTALLED.store(true, Ordering::SeqCst);
220 }
221 }
222
223 let mut driver = LedcDriver {
224 duty: 0,
225 hpoint: 0,
226 speed_mode: C::SpeedMode::SPEED_MODE,
227 max_duty: timer_driver.borrow().max_duty,
228 timer: timer_driver.borrow().timer() as _,
229 channel: C::channel() as _,
230 _p: PhantomData,
231 };
232
233 driver.config_with_pin(pin)?;
234
235 Ok(driver)
236 }
237
238 pub fn config_with_pin(&mut self, pin: impl OutputPin + 'd) -> Result<(), EspError> {
241 let channel_config = ledc_channel_config_t {
242 speed_mode: self.speed_mode,
243 channel: self.channel as u32,
244 timer_sel: self.timer as u32,
245 intr_type: ledc_intr_type_t_LEDC_INTR_DISABLE,
246 gpio_num: pin.pin() as _,
247 duty: self.duty,
248 hpoint: self.hpoint as _,
249 ..Default::default()
250 };
251
252 esp!(unsafe { ledc_channel_config(&channel_config) })?;
255 Ok(())
256 }
257
258 pub fn get_duty(&self) -> Duty {
259 self.duty
260 }
261
262 pub fn get_hpoint(&self) -> HPoint {
263 self.hpoint
264 }
265
266 pub fn get_max_duty(&self) -> Duty {
267 self.max_duty
268 }
269
270 pub fn disable(&mut self) -> Result<(), EspError> {
271 self.update_duty(0, 0)?;
272 Ok(())
273 }
274
275 pub fn enable(&mut self) -> Result<(), EspError> {
276 self.update_duty(self.duty, self.hpoint)?;
277 Ok(())
278 }
279
280 pub fn set_duty(&mut self, duty: Duty) -> Result<(), EspError> {
281 self.set_duty_with_hpoint(duty, self.hpoint)
282 }
283
284 pub fn set_hpoint(&mut self, hpoint: HPoint) -> Result<(), EspError> {
285 self.set_duty_with_hpoint(self.duty, hpoint)
286 }
287
288 pub fn set_duty_with_hpoint(&mut self, duty: Duty, hpoint: HPoint) -> Result<(), EspError> {
289 let max_duty = self.get_max_duty();
292 let clamped_duty = duty.min(max_duty);
293 let clamped_hpoint = hpoint.min(max_duty);
294 self.duty = clamped_duty;
295 self.hpoint = clamped_hpoint;
296 self.update_duty(clamped_duty, clamped_hpoint)?;
297 Ok(())
298 }
299
300 fn stop(&mut self) -> Result<(), EspError> {
301 esp!(unsafe { ledc_stop(self.speed_mode, self.channel(), IDLE_LEVEL,) })?;
302 Ok(())
303 }
304
305 fn update_duty(&mut self, duty: Duty, hpoint: HPoint) -> Result<(), EspError> {
306 esp!(unsafe { ledc_set_duty_and_update(self.speed_mode, self.channel(), duty, hpoint) })?;
307 Ok(())
308 }
309
310 pub fn channel(&self) -> ledc_channel_t {
311 self.channel as _
312 }
313
314 pub fn timer(&self) -> ledc_timer_t {
315 self.timer as _
316 }
317
318 pub fn fade_with_time(
320 &mut self,
321 target_duty: u32,
322 fade_time_ms: i32,
323 wait: bool,
324 ) -> Result<(), EspError> {
325 let max_duty = self.get_max_duty();
326 if target_duty > max_duty {
327 return Err(EspError::from_infallible::<ESP_ERR_INVALID_ARG>());
328 }
329
330 let fade_mode = if wait {
331 ledc_fade_mode_t_LEDC_FADE_WAIT_DONE
332 } else {
333 ledc_fade_mode_t_LEDC_FADE_NO_WAIT
334 };
335
336 unsafe {
337 esp!(ledc_set_fade_with_time(
338 self.speed_mode,
339 self.channel(),
340 target_duty,
341 fade_time_ms
342 ))?;
343 esp!(ledc_fade_start(self.speed_mode, self.channel(), fade_mode))?;
344 }
345 Ok(())
346 }
347
348 pub fn fade_with_step(
350 &mut self,
351 target_duty: u32,
352 step_size: u32,
353 step_time_ms: u32,
354 wait: bool,
355 ) -> Result<(), EspError> {
356 let max_duty = self.get_max_duty();
357 if target_duty > max_duty {
358 return Err(EspError::from_infallible::<ESP_ERR_INVALID_ARG>());
359 }
360
361 let fade_mode = if wait {
362 ledc_fade_mode_t_LEDC_FADE_WAIT_DONE
363 } else {
364 ledc_fade_mode_t_LEDC_FADE_NO_WAIT
365 };
366
367 unsafe {
368 esp!(ledc_set_fade_with_step(
369 self.speed_mode,
370 self.channel(),
371 target_duty,
372 step_size,
373 step_time_ms,
374 ))?;
375
376 esp!(ledc_fade_start(self.speed_mode, self.channel(), fade_mode))?;
377 }
378 Ok(())
379 }
380
381 #[cfg(not(any(esp32, esp_idf_version_major = "4")))]
382 pub fn fade_stop(&mut self) -> Result<(), EspError> {
384 unsafe {
385 esp!(ledc_fade_stop(self.speed_mode, self.channel()))?;
386 }
387 Ok(())
388 }
389}
390
391impl Drop for LedcDriver<'_> {
392 fn drop(&mut self) {
393 self.stop().unwrap();
394 }
395}
396
397unsafe impl Send for LedcDriver<'_> {}
398
399impl embedded_hal::pwm::ErrorType for LedcDriver<'_> {
400 type Error = PwmError;
401}
402
403fn to_pwm_err(err: EspError) -> PwmError {
404 PwmError::other(err)
405}
406
407impl embedded_hal::pwm::SetDutyCycle for LedcDriver<'_> {
408 fn max_duty_cycle(&self) -> u16 {
409 let duty = self.get_max_duty();
410 let duty_cap: u16 = if duty > u16::MAX as u32 {
411 u16::MAX
412 } else {
413 duty as u16
414 };
415 duty_cap
416 }
417
418 fn set_duty_cycle(&mut self, duty: u16) -> Result<(), PwmError> {
419 self.set_duty(duty as u32).map_err(to_pwm_err)
420 }
421
422 fn set_duty_cycle_fully_on(&mut self) -> Result<(), PwmError> {
423 self.set_duty(self.get_max_duty()).map_err(to_pwm_err)
424 }
425
426 fn set_duty_cycle_fully_off(&mut self) -> Result<(), PwmError> {
427 self.set_duty(0).map_err(to_pwm_err)
428 }
429
430 fn set_duty_cycle_fraction(&mut self, num: u16, denom: u16) -> Result<(), PwmError> {
431 let duty = num as u32 * self.max_duty_cycle() as u32 / denom as u32;
432 self.set_duty_cycle(duty as u16)
433 }
434
435 fn set_duty_cycle_percent(&mut self, percent: u8) -> Result<(), PwmError> {
436 self.set_duty_cycle_fraction(percent as u16, 100)
437 }
438}
439
440impl embedded_hal_0_2::PwmPin for LedcDriver<'_> {
441 type Duty = Duty;
442
443 fn disable(&mut self) {
444 if let Err(e) = self.disable() {
445 panic!("disabling PWM failed: {e}");
446 }
447 }
448
449 fn enable(&mut self) {
450 if let Err(e) = self.enable() {
451 panic!("enabling PWM failed: {e}");
452 }
453 }
454
455 fn get_duty(&self) -> Self::Duty {
456 self.get_duty()
457 }
458
459 fn get_max_duty(&self) -> Self::Duty {
460 self.get_max_duty()
461 }
462
463 fn set_duty(&mut self, duty: Duty) {
464 if let Err(e) = self.set_duty(duty) {
465 panic!("updating duty failed: {e}");
466 }
467 }
468}
469
470mod chip {
471 use esp_idf_sys::*;
472
473 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
474 pub enum Resolution {
475 Bits1,
476 Bits2,
477 Bits3,
478 Bits4,
479 Bits5,
480 Bits6,
481 Bits7,
482 Bits8,
483 Bits9,
484 Bits10,
485 Bits11,
486 Bits12,
487 Bits13,
488 Bits14,
489 #[cfg(esp32)]
490 Bits15,
491 #[cfg(esp32)]
492 Bits16,
493 #[cfg(esp32)]
494 Bits17,
495 #[cfg(esp32)]
496 Bits18,
497 #[cfg(esp32)]
498 Bits19,
499 #[cfg(esp32)]
500 Bits20,
501 }
502
503 impl Resolution {
504 pub const fn bits(&self) -> usize {
505 match self {
506 Resolution::Bits1 => 1,
507 Resolution::Bits2 => 2,
508 Resolution::Bits3 => 3,
509 Resolution::Bits4 => 4,
510 Resolution::Bits5 => 5,
511 Resolution::Bits6 => 6,
512 Resolution::Bits7 => 7,
513 Resolution::Bits8 => 8,
514 Resolution::Bits9 => 9,
515 Resolution::Bits10 => 10,
516 Resolution::Bits11 => 11,
517 Resolution::Bits12 => 12,
518 Resolution::Bits13 => 13,
519 Resolution::Bits14 => 14,
520 #[cfg(esp32)]
521 Resolution::Bits15 => 15,
522 #[cfg(esp32)]
523 Resolution::Bits16 => 16,
524 #[cfg(esp32)]
525 Resolution::Bits17 => 17,
526 #[cfg(esp32)]
527 Resolution::Bits18 => 18,
528 #[cfg(esp32)]
529 Resolution::Bits19 => 19,
530 #[cfg(esp32)]
531 Resolution::Bits20 => 20,
532 }
533 }
534
535 pub const fn max_duty(&self) -> u32 {
536 if cfg!(esp32) && self.bits() == 20 || cfg!(not(esp32)) && self.bits() == 14 {
538 (1 << self.bits()) - 1
539 } else {
540 1 << self.bits()
541 }
542 }
543
544 pub(crate) const fn timer_bits(&self) -> ledc_timer_bit_t {
545 match self {
546 Resolution::Bits1 => ledc_timer_bit_t_LEDC_TIMER_1_BIT,
547 Resolution::Bits2 => ledc_timer_bit_t_LEDC_TIMER_2_BIT,
548 Resolution::Bits3 => ledc_timer_bit_t_LEDC_TIMER_3_BIT,
549 Resolution::Bits4 => ledc_timer_bit_t_LEDC_TIMER_4_BIT,
550 Resolution::Bits5 => ledc_timer_bit_t_LEDC_TIMER_5_BIT,
551 Resolution::Bits6 => ledc_timer_bit_t_LEDC_TIMER_6_BIT,
552 Resolution::Bits7 => ledc_timer_bit_t_LEDC_TIMER_7_BIT,
553 Resolution::Bits8 => ledc_timer_bit_t_LEDC_TIMER_8_BIT,
554 Resolution::Bits9 => ledc_timer_bit_t_LEDC_TIMER_9_BIT,
555 Resolution::Bits10 => ledc_timer_bit_t_LEDC_TIMER_10_BIT,
556 Resolution::Bits11 => ledc_timer_bit_t_LEDC_TIMER_11_BIT,
557 Resolution::Bits12 => ledc_timer_bit_t_LEDC_TIMER_12_BIT,
558 Resolution::Bits13 => ledc_timer_bit_t_LEDC_TIMER_13_BIT,
559 Resolution::Bits14 => ledc_timer_bit_t_LEDC_TIMER_14_BIT,
560 #[cfg(esp32)]
561 Resolution::Bits15 => ledc_timer_bit_t_LEDC_TIMER_15_BIT,
562 #[cfg(esp32)]
563 Resolution::Bits16 => ledc_timer_bit_t_LEDC_TIMER_16_BIT,
564 #[cfg(esp32)]
565 Resolution::Bits17 => ledc_timer_bit_t_LEDC_TIMER_17_BIT,
566 #[cfg(esp32)]
567 Resolution::Bits18 => ledc_timer_bit_t_LEDC_TIMER_18_BIT,
568 #[cfg(esp32)]
569 Resolution::Bits19 => ledc_timer_bit_t_LEDC_TIMER_19_BIT,
570 #[cfg(esp32)]
571 Resolution::Bits20 => ledc_timer_bit_t_LEDC_TIMER_20_BIT,
572 }
573 }
574 }
575
576 pub trait SpeedMode: Send + Sync + 'static {
580 const SPEED_MODE: ledc_mode_t;
581 const HIGH_SPEED: bool;
582 }
583
584 pub struct LowSpeed;
586
587 impl SpeedMode for LowSpeed {
588 const SPEED_MODE: ledc_mode_t = ledc_mode_t_LEDC_LOW_SPEED_MODE;
589 const HIGH_SPEED: bool = false;
590 }
591
592 #[cfg(esp32)]
593 pub struct HighSpeed;
595
596 #[cfg(esp32)]
597 impl SpeedMode for HighSpeed {
598 const SPEED_MODE: ledc_mode_t = ledc_mode_t_LEDC_HIGH_SPEED_MODE;
599 const HIGH_SPEED: bool = true;
600 }
601
602 pub trait LedcTimer {
604 type SpeedMode: SpeedMode;
605
606 fn timer() -> ledc_timer_t;
607 }
608
609 pub trait LedcChannel {
611 type SpeedMode: SpeedMode;
612
613 fn channel() -> ledc_channel_t;
614 }
615
616 macro_rules! impl_timer {
617 ($typ:ty; $instance:ident: $timer:expr) => {
618 crate::impl_peripheral!($instance);
619
620 impl LedcTimer for $instance<'_> {
621 type SpeedMode = $typ;
622
623 fn timer() -> ledc_timer_t {
624 $timer
625 }
626 }
627 };
628 }
629
630 impl_timer!(LowSpeed; TIMER0: ledc_timer_t_LEDC_TIMER_0);
631 impl_timer!(LowSpeed; TIMER1: ledc_timer_t_LEDC_TIMER_1);
632 impl_timer!(LowSpeed; TIMER2: ledc_timer_t_LEDC_TIMER_2);
633 impl_timer!(LowSpeed; TIMER3: ledc_timer_t_LEDC_TIMER_3);
634
635 #[cfg(esp32)]
636 impl_timer!(HighSpeed; HTIMER0: ledc_timer_t_LEDC_TIMER_0);
637 #[cfg(esp32)]
638 impl_timer!(HighSpeed; HTIMER1: ledc_timer_t_LEDC_TIMER_1);
639 #[cfg(esp32)]
640 impl_timer!(HighSpeed; HTIMER2: ledc_timer_t_LEDC_TIMER_2);
641 #[cfg(esp32)]
642 impl_timer!(HighSpeed; HTIMER3: ledc_timer_t_LEDC_TIMER_3);
643
644 macro_rules! impl_channel {
645 ($typ:ty; $instance:ident: $channel:expr) => {
646 crate::impl_peripheral!($instance);
647
648 impl LedcChannel for $instance<'_> {
649 type SpeedMode = $typ;
650
651 fn channel() -> ledc_channel_t {
652 $channel
653 }
654 }
655 };
656 }
657
658 impl_channel!(LowSpeed; CHANNEL0: ledc_channel_t_LEDC_CHANNEL_0);
659 impl_channel!(LowSpeed; CHANNEL1: ledc_channel_t_LEDC_CHANNEL_1);
660 impl_channel!(LowSpeed; CHANNEL2: ledc_channel_t_LEDC_CHANNEL_2);
661 impl_channel!(LowSpeed; CHANNEL3: ledc_channel_t_LEDC_CHANNEL_3);
662 impl_channel!(LowSpeed; CHANNEL4: ledc_channel_t_LEDC_CHANNEL_4);
663 impl_channel!(LowSpeed; CHANNEL5: ledc_channel_t_LEDC_CHANNEL_5);
664 #[cfg(any(esp32, esp32s2, esp32s3, esp8684))]
665 impl_channel!(LowSpeed; CHANNEL6: ledc_channel_t_LEDC_CHANNEL_6);
666 #[cfg(any(esp32, esp32s2, esp32s3, esp8684))]
667 impl_channel!(LowSpeed; CHANNEL7: ledc_channel_t_LEDC_CHANNEL_7);
668
669 #[cfg(esp32)]
670 impl_channel!(HighSpeed; HCHANNEL0: ledc_channel_t_LEDC_CHANNEL_0);
671 #[cfg(esp32)]
672 impl_channel!(HighSpeed; HCHANNEL1: ledc_channel_t_LEDC_CHANNEL_1);
673 #[cfg(esp32)]
674 impl_channel!(HighSpeed; HCHANNEL2: ledc_channel_t_LEDC_CHANNEL_2);
675 #[cfg(esp32)]
676 impl_channel!(HighSpeed; HCHANNEL3: ledc_channel_t_LEDC_CHANNEL_3);
677 #[cfg(esp32)]
678 impl_channel!(HighSpeed; HCHANNEL4: ledc_channel_t_LEDC_CHANNEL_4);
679 #[cfg(esp32)]
680 impl_channel!(HighSpeed; HCHANNEL5: ledc_channel_t_LEDC_CHANNEL_5);
681 #[cfg(esp32)]
682 impl_channel!(HighSpeed; HCHANNEL6: ledc_channel_t_LEDC_CHANNEL_6);
683 #[cfg(esp32)]
684 impl_channel!(HighSpeed; HCHANNEL7: ledc_channel_t_LEDC_CHANNEL_7);
685
686 pub struct LEDC {
688 pub timer0: TIMER0<'static>,
689 pub timer1: TIMER1<'static>,
690 pub timer2: TIMER2<'static>,
691 pub timer3: TIMER3<'static>,
692 pub channel0: CHANNEL0<'static>,
693 pub channel1: CHANNEL1<'static>,
694 pub channel2: CHANNEL2<'static>,
695 pub channel3: CHANNEL3<'static>,
696 pub channel4: CHANNEL4<'static>,
697 pub channel5: CHANNEL5<'static>,
698 #[cfg(any(esp32, esp32s2, esp32s3, esp8684))]
699 pub channel6: CHANNEL6<'static>,
700 #[cfg(any(esp32, esp32s2, esp32s3, esp8684))]
701 pub channel7: CHANNEL7<'static>,
702 }
703
704 impl LEDC {
705 pub(crate) unsafe fn new() -> Self {
715 Self {
716 timer0: TIMER0::steal(),
717 timer1: TIMER1::steal(),
718 timer2: TIMER2::steal(),
719 timer3: TIMER3::steal(),
720 channel0: CHANNEL0::steal(),
721 channel1: CHANNEL1::steal(),
722 channel2: CHANNEL2::steal(),
723 channel3: CHANNEL3::steal(),
724 channel4: CHANNEL4::steal(),
725 channel5: CHANNEL5::steal(),
726 #[cfg(any(esp32, esp32s2, esp32s3, esp8684))]
727 channel6: CHANNEL6::steal(),
728 #[cfg(any(esp32, esp32s2, esp32s3, esp8684))]
729 channel7: CHANNEL7::steal(),
730 }
731 }
732 }
733
734 #[cfg(esp32)]
736 pub struct HLEDC {
737 pub timer0: HTIMER0<'static>,
738 pub timer1: HTIMER1<'static>,
739 pub timer2: HTIMER2<'static>,
740 pub timer3: HTIMER3<'static>,
741 pub channel0: HCHANNEL0<'static>,
742 pub channel1: HCHANNEL1<'static>,
743 pub channel2: HCHANNEL2<'static>,
744 pub channel3: HCHANNEL3<'static>,
745 pub channel4: HCHANNEL4<'static>,
746 pub channel5: HCHANNEL5<'static>,
747 pub channel6: HCHANNEL6<'static>,
748 pub channel7: HCHANNEL7<'static>,
749 }
750
751 #[cfg(esp32)]
752 impl HLEDC {
753 pub(crate) unsafe fn new() -> Self {
763 Self {
764 timer0: HTIMER0::steal(),
765 timer1: HTIMER1::steal(),
766 timer2: HTIMER2::steal(),
767 timer3: HTIMER3::steal(),
768 channel0: HCHANNEL0::steal(),
769 channel1: HCHANNEL1::steal(),
770 channel2: HCHANNEL2::steal(),
771 channel3: HCHANNEL3::steal(),
772 channel4: HCHANNEL4::steal(),
773 channel5: HCHANNEL5::steal(),
774 channel6: HCHANNEL6::steal(),
775 channel7: HCHANNEL7::steal(),
776 }
777 }
778 }
779}