8000 esp32/machine_pwm: Rebase source code. · micropython/micropython@0c9cbc4 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0c9cbc4

Browse files
committed
esp32/machine_pwm: Rebase source code.
Signed-off-by: Yoann Darche <yoannd@hotmail.com>
1 parent bb6284f commit 0c9cbc4

File tree

1 file changed

+48
-113
lines changed

1 file changed

+48
-113
lines changed

ports/esp32/machine_pwm.c

Lines changed: 48 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -113,44 +113,6 @@ static ledc_timer_config_t timers[PWM_TIMER_MAX];
113113
#define EMPIRIC_FREQ (10) // Hz
114114
#endif
115115

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-
154116
// Config of timer upon which we run all PWM'ed GPIO pins
155117
static bool pwm_inited = false;
156118

@@ -287,8 +249,8 @@ static void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_conf
287249

288250
uint32_t src_clock_freq;
289251

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)."));
292254
}
293255

294256
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
310272
timer->clk_cfg = LEDC_AUTO_CLK;
311273

312274
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);
314276
} else {
315277
check_esp_err(err);
316278
}
@@ -489,7 +451,7 @@ static int is_timer_with_different_clock(int current_timer_idx, ledc_clk_cfg_t r
489451
return false;
490452
}
491453

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
493455
static int find_clock_in_use() {
494456

495457
ledc_clk_cfg_t found_clk = LEDC_AUTO_CLK;
@@ -522,8 +484,6 @@ static bool check_freq(machine_pwm_obj_t *self, int freq) {
522484
return true;
523485
}
524486

525-
#endif
526-
527487
// Find a free PWM channel, also spot if our pin is already mentioned.
528488
// Return channel_idx. Use CHANNEL_IDX_TO_MODE(channel_idx) and CHANNEL_IDX_TO_CHANNEL(channel_idx) to get mode and channel
529489
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
570530

571531
int clk_src = timers[TIMER_IDX(self->mode, self->timer)].clk_cfg;
572532
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");
574534
}
575535
#if SOC_LEDC_SUPPORT_APB_CLOCK
576536
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");
578538
}
579539
#endif
580540
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
581541
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");
583543
}
584544
#endif
585545
#if SOC_LEDC_SUPPORT_REF_TICK
586546
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");
588548
}
589549
#endif
590550
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
591551
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");
593553
}
594554
#endif
595555
else {
596556
mp_printf(print, ", clock=UNKNOWN");
597557
}
598558

559+
599560
if (self->lightsleepenabled) {
600561
mp_printf(print, ", light sleep enabled");
601562
}
@@ -606,13 +567,12 @@ static void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_p
606567
// This called from pwm.init() method
607568
static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
608569
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 };
610571
static const mp_arg_t allowed_args[] = {
611572
{ MP_QSTR_freq, MP_ARG_INT, {.u_int = -1} },
612573
{ MP_QSTR_duty, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
613574
{ MP_QSTR_duty_u16, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
614575
{ 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} },
616576
{ MP_QSTR_light_sleep_enable, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
617577
};
618578
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,
621581

622582
int freq = args[ARG_freq].u_int;
623583

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;
634586

635587
if (args[ARG_lightSleepEnable].u_int > 0) {
636588
// The light sleep enabled is requested
637589
// => 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;
647592
self->lightsleepenabled = true;
648-
649593
} else {
650594
self->lightsleepenabled = false;
651-
}
652-
653-
// if auto clock => Determine the best clock
654-
if (pwm_src_clock == PWM_AUTO_CLK) {
655595

596+
// Choose appropriate clock from best available clock
656597
#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) {
659600
pwm_src_clock = pwm_clk;
660601
} else {
602+
661603
#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.
666611
#endif
667612
}
668613
#else
669614
#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.
671622
#endif
672-
#if SOC_LEDC_SUPPORT_APB_CLOCK
673-
pwm_src_clock = PWM_APB_CLK;
674623
#endif
675624

676625
#if SOC_LEDC_SUPPORT_REF_TICK
677626
if (freq < EMPIRIC_FREQ) {
678-
pwm_src_clock = PWM_REF_TICK; // 1 MHz
627+
pwm_src_clock = LEDC_USE_REF_TICK; // 1 MHz
679628
}
680629
#endif
681-
#endif
682630
}
631+
632+
// Check for clock source conflic in case of ESP32-S3/C3/C6
683633
#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."));
689638
}
690-
#endif
691639

640+
#endif
692641

693642
// Note: High Speed Mode (available on ESP32 only, not on S2/S3), only supports REF_TICK(1MHz) and APB_CLK(80MHz)
694643
// 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,
720669
}
721670
}
722671

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);
731673

732674

733675

@@ -736,16 +678,16 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
736678
int current_timer_idx = chans[channel_idx].timer_idx;
737679
bool current_in_use = is_timer_in_use(channel_idx, current_timer_idx);
738680
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);
740682
} else {
741683
timer_idx = chans[channel_idx].timer_idx;
742684
}
743685

744686
if (timer_idx == -1) {
745687
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);
747689
} 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);
749691
}
750692
}
751693
if (timer_idx == -1) {
@@ -754,7 +696,7 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
754696

755697
#if !(PWM_SUPPORT_INDEP_CLOCK_SRC)
756698
// 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)) {
758700
mp_raise_ValueError(MP_ERROR_TEXT("one or more active timers use a different clock source, which is not supported by the current SoC."));
759701
}
760702
#endif
@@ -785,7 +727,7 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
785727
self->active = true;
786728

787729
// 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);
789731

790732
// Set duty cycle?
791733
if (duty_u16 != -1) {
@@ -851,14 +793,7 @@ static mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) {
851793
static void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) {
852794
pwm_is_active(self);
853795

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);
862797

863798
if (freq == timers[TIMER_IDX(self->mode, self->timer)].freq_hz) {
864799
return;

0 commit comments

Comments
 (0)
0