@@ -113,44 +113,6 @@ static ledc_timer_config_t timers[PWM_TIMER_MAX];
113
113
#define EMPIRIC_FREQ (10) // Hz
114
114
#endif
115
115
116
- // Clock alias values (used by clock parameter)
117
- // PWM_LAST_CLK_IDX is not clock by a maker to identify outofindex values
118
- // PWM_AUTO_CLK is used in order to auto determinate the clock (no specific clock has been required)
119
- enum { PWM_AUTO_CLK , PWM_APB_CLK , PWM_RC_FAST_CLK , PWM_REF_TICK , PWM_XTAL_CLK , PWM_PLL_CLK , _PWM_LAST_CLK_IDX };
120
- static const ledc_clk_cfg_t clk_source_map [] = {
121
- -2 ,
122
- #if SOC_LEDC_SUPPORT_APB_CLOCK
123
- LEDC_USE_APB_CLK ,
124
- #else
125
- -1 ,
126
- #endif
127
- LEDC_USE_RC_FAST_CLK , // LEDC_USE_RC_FAST_CLK == LEDC_USE_RTC8M_CLK
128
- #if SOC_LEDC_SUPPORT_REF_TICK
129
- LEDC_USE_REF_TICK ,
130
- #else
131
- -1 ,
132
- #endif
133
- #if SOC_LEDC_SUPPORT_XTAL_CLOCK
134
- LEDC_USE_XTAL_CLK ,
135
- #else
136
- -1 ,
137
- #endif
138
- #if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
139
- LEDC_USE_PLL_DIV_CLK ,
140
- #else
141
- -1 ,
142
- #endif
143
- };
144
-
145
- // MicroPython bindings for ESP32-PWM
146
- #define MICROPY_PY_MACHINE_PWM_CLASS_CONSTANTS \
147
- { MP_ROM_QSTR(MP_QSTR_PWM_AUTO_CLK), MP_ROM_INT(PWM_AUTO_CLK) }, \
148
- { MP_ROM_QSTR(MP_QSTR_PWM_APB_CLK), MP_ROM_INT(PWM_APB_CLK) }, \
149
- { MP_ROM_QSTR(MP_QSTR_PWM_RC_FAST_CLK), MP_ROM_INT(PWM_RC_FAST_CLK) }, \
150
- { MP_ROM_QSTR(MP_QSTR_PWM_REF_TICK), MP_ROM_INT(PWM_REF_TICK) }, \
151
- { MP_ROM_QSTR(MP_QSTR_PWM_XTAL_CLK), MP_ROM_INT(PWM_XTAL_CLK) }, \
152
- { MP_ROM_QSTR(MP_QSTR_PWM_PLL_CLK), MP_ROM_INT(PWM_PLL_CLK) }, \
153
-
154
116
// Config of timer upon which we run all PWM'ed GPIO pins
155
117
static bool pwm_inited = false;
156
118
@@ -287,8 +249,8 @@ static void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_conf
287
249
288
250
uint32_t src_clock_freq ;
289
251
290
- if (esp_clk_tree_src_get_freq_hz (led_src_clock , ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX , & src_clock_freq ) != ESP_OK ) {
291
- mp_raise_ValueError (MP_ERROR_TEXT ("Error on getting reference clock frequency." ));
252
+ if (esp_clk_tree_src_get_freq_hz (led_src_clock , ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED , & src_clock_freq ) != ESP_OK ) {
253
+ mp_raise_ValueError (MP_ERROR_TEXT ("Error on getting reference clock frequency (FREQ_PRECISION_CACHED) ." ));
292
254
}
293
255
294
256
uint32_t res = ledc_find_suitable_duty_resolution (src_clock_freq , freq );
@@ -310,7 +272,7 @@ static void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_conf
310
272
timer -> clk_cfg = LEDC_AUTO_CLK ;
311
273
312
274
if (err == ESP_FAIL ) {
313
- mp_raise_msg_varg (& mp_type_ValueError , MP_ERROR_TEXT ("unreachable frequency %d" ), freq );
275
+ mp_raise_msg_varg (& mp_type_ValueError , MP_ERROR_TEXT ("unreachable frequency %d :: precision=%d " ), freq , res );
314
276
} else {
315
277
check_esp_err (err );
316
278
}
@@ -489,7 +451,7 @@ static int is_timer_with_different_clock(int current_timer_idx, ledc_clk_cfg_t r
489
451
return false;
490
452
}
491
453
492
- // This check if a clock is already set in the timer list, if yes, return the PWM_XXX_CLK value
454
+ // This check if a clock is already set in the timer list, if yes, return the LEDC_XXX value
493
455
static int find_clock_in_use () {
494
456
495
457
ledc_clk_cfg_t found_clk = LEDC_AUTO_CLK ;
@@ -522,8 +484,6 @@ static bool check_freq(machine_pwm_obj_t *self, int freq) {
522
484
return true;
523
485
}
524
486
525
- #endif
526
-
527
487
// Find a free PWM channel, also spot if our pin is already mentioned.
528
488
// Return channel_idx. Use CHANNEL_IDX_TO_MODE(channel_idx) and CHANNEL_IDX_TO_CHANNEL(channel_idx) to get mode and channel
529
489
static int find_channel (int pin , int mode ) {
@@ -570,32 +530,33 @@ static void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_p
570
530
571
531
int clk_src = timers [TIMER_IDX (self -> mode , self -> timer )].clk_cfg ;
572
532
if (clk_src == LEDC_USE_RC_FAST_CLK ) {
573
- mp_printf (print , ", clock=PWM_RC_FAST_CLK(%d)" , PWM_RC_FAST_CLK );
533
+ mp_printf (print , ", clock=RC_FAST_CLK" );
574
534
}
575
535
#if SOC_LEDC_SUPPORT_APB_CLOCK
576
536
else if (clk_src == LEDC_USE_APB_CLK ) {
577
- mp_printf (print , ", clock=PWM_APB_CLK(%d)" , PWM_APB_CLK );
537
+ mp_printf (print , ", clock=APB_CLK" );
578
538
}
579
539
#endif
580
540
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
581
541
else if (clk_src == LEDC_USE_XTAL_CLK ) {
582
- mp_printf (print , ", clock=PWM_XTAL_CLK(%d)" , PWM_XTAL_CLK );
542
+ mp_printf (print , ", clock=XTAL_CLK" );
583
543
}
584
544
#endif
585
545
#if SOC_LEDC_SUPPORT_REF_TICK
586
546
else if (clk_src == LEDC_USE_REF_TICK ) {
587
- mp_printf (print , ", clock=PWM_REF_TICK(%d)" , PWM_REF_TICK );
547
+ mp_printf (print , ", clock=REF_TICK" );
588
548
}
589
549
#endif
590
550
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
591
551
else if (clk_src == LEDC_USE_PLL_DIV_CLK ) {
592
- mp_printf (print , ", clock=PWM_PLL_CLK(%d)" , PWM_PLL_CLK );
552
+ mp_printf (print , ", clock=PLL_CLK" );
593
553
}
594
554
#endif
595
555
else {
596
556
mp_printf (print , ", clock=UNKNOWN" );
597
557
}
598
558
559
+
599
560
if (self -> lightsleepenabled ) {
600
561
mp_printf (print , ", light sleep enabled" );
601
562
}
@@ -606,13 +567,12 @@ static void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_p
606
567
// This called from pwm.init() method
607
568
static void mp_machine_pwm_init_helper (machine_pwm_obj_t * self ,
608
569
size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
609
- enum { ARG_freq , ARG_duty , ARG_duty_u16 , ARG_duty_ns , ARG_clock , ARG_lightSleepEnable };
570
+ enum { ARG_freq , ARG_duty , ARG_duty_u16 , ARG_duty_ns , ARG_lightSleepEnable };
610
571
static const mp_arg_t allowed_args [] = {
611
572
{ MP_QSTR_freq , MP_ARG_INT , {.u_int = -1 } },
612
573
{ MP_QSTR_duty , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = -1 } },
613
574
{ MP_QSTR_duty_u16 , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = -1 } },
614
575
{ MP_QSTR_duty_ns , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = -1 } },
615
- { MP_QSTR_clock , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = PWM_AUTO_CLK } },
616
576
{ MP_QSTR_light_sleep_enable , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
617
577
};
618
578
mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
@@ -621,74 +581,63 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
621
581
622
582
int freq = args [ARG_freq ].u_int ;
623
583
624
- // ***************************** Decode clok and light sleep mode *********************************
625
- int pwm_src_clock = args [ARG_clock ].u_int ;
626
- if (pwm_src_clock >= _PWM_LAST_CLK_IDX ) {
627
- mp_raise_ValueError (MP_ERROR_TEXT ("Bad value for clock." ));
628
- }
629
-
630
- // Check if the clock is available:
631
- if (clk_source_map [pwm_src_clock ] < 0 ) {
632
- mp_raise_ValueError (MP_ERROR_TEXT ("Clock source not available for this Soc." ));
633
- }
584
+ // *********************** Decode light sleep mode and choose clock source ************************
585
+ ledc_clk_cfg_t pwm_src_clock = LEDC_AUTO_CLK ;
634
586
635
587
if (args [ARG_lightSleepEnable ].u_int > 0 ) {
636
588
// The light sleep enabled is requested
637
589
// => GPIO need to be in the not disabled list
638
-
639
- if (pwm_src_clock == PWM_AUTO_CLK ) {
640
- // In case of Clock auto select, with sleep mode the clock will be PWM_RC_FAST_CLK
641
- pwm_src_clock = PWM_RC_FAST_CLK ;
642
- }
643
- // Check if the source clock is valid for light sleep (only LEDC_USE_RC_FAST_CLK is valid )
644
- else if (pwm_src_clock != PWM_RC_FAST_CLK ) {
645
- mp_raise_ValueError (MP_ERROR_TEXT ("only PWM_RC_FAST_CLK is allowed with light sleep enabled" ));
646
- }
590
+ // => CLK has to be RC_FAST_CLK
591
+ pwm_src_clock = LEDC_USE_RC_FAST_CLK ;
647
592
self -> lightsleepenabled = true;
648
-
649
593
} else {
650
594
self -> lightsleepenabled = false;
651
- }
652
-
653
- // if auto clock => Determine the best clock
654
- if (pwm_src_clock == PWM_AUTO_CLK ) {
655
595
596
+ // Choose appropriate clock from best available clock
656
597
#if !(PWM_SUPPORT_INDEP_CLOCK_SRC )
657
- int pwm_clk = find_clock_in_use ();
658
- if (pwm_clk != PWM_AUTO_CLK ) {
598
+ ledc_clk_cfg_t pwm_clk = find_clock_in_use ();
599
+ if (pwm_clk != LEDC_AUTO_CLK ) {
659
600
pwm_src_clock = pwm_clk ;
660
601
} else {
602
+
661
603
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
662
- pwm_src_clock = PWM_PLL_CLK ;
663
- #endif
664
- #if SOC_LEDC_SUPPORT_APB_CLOCK
665
- pwm_src_clock = PWM_APB_CLK ;
604
+ pwm_src_clock = LEDC_USE_PLL_DIV_CLK ;
605
+ #elif SOC_LEDC_SUPPORT_APB_CLOCK
606
+ pwm_src_clock = LEDC_USE_APB_CLK ;
607
+ #elif SOC_LEDC_SUPPORT_XTAL_CLOCK
608
+ pwm_src_clock = LEDC_USE_XTAL_CLK ;
609
+ #else
610
+ #error No supported PWM / LEDC clocks.
666
611
#endif
667
612
}
668
613
#else
669
614
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
670
- pwm_src_clock = PWM_PLL_CLK ;
615
+ pwm_src_clock = LEDC_USE_PLL_DIV_CLK ;
616
+ #elif SOC_LEDC_SUPPORT_APB_CLOCK
617
+ pwm_src_clock = LEDC_USE_APB_CLK ;
618
+ #elif SOC_LEDC_SUPPORT_XTAL_CLOCK
619
+ pwm_src_clock = LEDC_USE_XTAL_CLK ;
620
+ #else
621
+ #error No supported PWM / LEDC clocks.
671
622
#endif
672
- #if SOC_LEDC_SUPPORT_APB_CLOCK
673
- pwm_src_clock = PWM_APB_CLK ;
674
623
#endif
675
624
676
625
#if SOC_LEDC_SUPPORT_REF_TICK
677
626
if (freq < EMPIRIC_FREQ ) {
678
- pwm_src_clock = PWM_REF_TICK ; // 1 MHz
627
+ pwm_src_clock = LEDC_USE_REF_TICK ; // 1 MHz
679
628
}
680
629
#endif
681
- #endif
682
630
}
631
+
632
+ // Check for clock source conflic in case of ESP32-S3/C3/C6
683
633
#if !(PWM_SUPPORT_INDEP_CLOCK_SRC )
684
- else {
685
- int pwm_clk = find_clock_in_use ();
686
- if ((pwm_clk != PWM_AUTO_CLK ) && (pwm_clk != pwm_src_clock )) {
687
- mp_raise_ValueError (MP_ERROR_TEXT ("one or more active timers use a different clock source, not supported by the current SoC." ));
688
- }
634
+
635
+ ledc_clk_cfg_t pwm_clk = find_clock_in_use ();
636
+ if ((pwm_clk != LEDC_AUTO_CLK ) && (pwm_clk != pwm_src_clock )) {
637
+ mp_raise_ValueError (MP_ERROR_TEXT ("one or more active timers use a different clock source, not supported by the current SoC." ));
689
638
}
690
- #endif
691
639
640
+ #endif
692
641
693
642
// Note: High Speed Mode (available on ESP32 only, not on S2/S3), only supports REF_TICK(1MHz) and APB_CLK(80MHz)
694
643
// Low Speed Mode (avail. on ESP32, S2, S3, C3, C6) supports [REF_TICK(1MHz)], RC_FAST_CLK(8Mhz) and APB_CLK(80MHz)
@@ -720,14 +669,7 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
720
669
}
721
670
}
722
671
723
- if (self -> lightsleepenabled ) {
724
- if ((freq <= 0 ) || (freq > 8000000 )) {
725
- mp_raise_ValueError (MP_ERROR_TEXT ("frequency must be from 1Hz to 8MHz" ));
726
- }
727
- } else
728
- if ((freq <= 0 ) || (freq > 40000000 )) {
729
- mp_raise_ValueError (MP_ERROR_TEXT ("frequency must be from 1Hz to 40MHz" ));
730
- }
672
+ check_freq (self , freq );
731
673
732
674
733
675
@@ -736,16 +678,16 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
736
678
int current_timer_idx = chans [channel_idx ].timer_idx ;
737
679
bool current_in_use = is_timer_in_use (channel_idx , current_timer_idx );
738
680
if (current_in_use ) {
739
- timer_idx = find_timer (freq , SAME_FREQ_OR_FREE , CHANNEL_IDX_TO_MODE (channel_idx ), clk_source_map [ pwm_src_clock ] );
681
+ timer_idx = find_timer (freq , SAME_FREQ_OR_FREE , CHANNEL_IDX_TO_MODE (channel_idx ), pwm_src_clock );
740
682
} else {
741
683
timer_idx = chans [channel_idx ].timer_idx ;
742
684
}
743
685
744
686
if (timer_idx == -1 ) {
745
687
if (self -> lightsleepenabled ) {
746
- timer_idx = find_timer (freq , SAME_FREQ_OR_FREE , 0 , clk_source_map [ pwm_src_clock ] );
688
+ timer_idx = find_timer (freq , SAME_FREQ_OR_FREE , 0 , pwm_src_clock );
747
689
} else {
748
- timer_idx = find_timer (freq , SAME_FREQ_OR_FREE , ANY_MODE , clk_source_map [ pwm_src_clock ] );
690
+ timer_idx = find_timer (freq , SAME_FREQ_OR_FREE , ANY_MODE , pwm_src_clock );
749
691
}
750
692
}
751
693
if (timer_idx == -1 ) {
@@ -754,7 +696,7 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
754
696
755
697
#if !(PWM_SUPPORT_INDEP_CLOCK_SRC )
756
698
// Check for the clock source consistency in case of ESP32-S3/C3 and C6
757
- if (is_timer_with_different_clock (timer_idx , clk_source_map [ pwm_src_clock ] )) {
699
+ if (is_timer_with_different_clock (timer_idx , pwm_src_clock )) {
758
700
mp_raise_ValueError (MP_ERROR_TEXT ("one or more active timers use a different clock source, which is not supported by the current SoC." ));
759
701
}
760
702
#endif
@@ -785,7 +727,7 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
785
727
self -> active = true;
786
728
787
729
// Set timer frequency
788
- set_freq (self , freq , & timers [timer_idx ], clk_source_map [ pwm_src_clock ] );
730
+ set_freq (self , freq , & timers [timer_idx ], pwm_src_clock );
789
731
790
732
// Set duty cycle?
791
733
if (duty_u16 != -1 ) {
@@ -851,14 +793,7 @@ static mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) {
851
793
static void mp_machine_pwm_freq_set (machine_pwm_obj_t * self , mp_int_t freq ) {
852
794
pwm_is_active (self );
853
795
854
- if (self -> lightsleepenabled ) {
855
- if ((freq <= 0 ) || (freq > 8000000 )) {
856
- mp_raise_ValueError (MP_ERROR_TEXT ("frequency must be from 1Hz to 8MHz" ));
857
- }
858
- } else
859
- if ((freq <= 0 ) || (freq > 40000000 )) {
860
- mp_raise_ValueError (MP_ERROR_TEXT ("frequency must be from 1Hz to 40MHz" ));
861
- }
796
+ check_freq (self , freq );
862
797
863
798
if (freq == timers [TIMER_IDX (self -> mode , self -> timer )].freq_hz ) {
864
799
return ;
0 commit comments