Skip to content

Commit 02d27f4

Browse files
committed
esp32/machine_pwm.c: Retry 3 fix invert param.
Signed-off-by: Ihor Nehrutsa <[email protected]>
1 parent 80fe38c commit 02d27f4

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

ports/esp32/machine_pwm.c

+22-7
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@
3636
#include "esp_err.h"
3737
#include "driver/ledc.h"
3838
#include "soc/gpio_sig_map.h"
39+
#include "soc/ledc_periph.h"
3940
#include "esp_clk_tree.h"
4041
#include "py/mpprint.h"
4142

4243
#define debug_printf(...) // mp_printf(&mp_plat_print, __VA_ARGS__); mp_printf(&mp_plat_print, " | %d at %s\n", __LINE__, __FILE__);
44+
#define FADE 1
4345

4446
// 10-bit user interface resolution compatible with esp8266 PWM.duty()
4547
#define UI_RES_10_BIT (10)
@@ -220,14 +222,10 @@ static void reconfigure_pin(machine_pwm_obj_t *self) {
220222
if (self->channel_duty == MAX_timer_duty) {
221223
invert = !invert;
222224
}
225+
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 4, 0)
223226
gpio_set_direction(self->pin, GPIO_MODE_INPUT_OUTPUT);
224-
if (self->mode == LEDC_LOW_SPEED_MODE) {
225-
esp_rom_gpio_connect_out_signal(self->pin, LEDC_LS_SIG_OUT0_IDX + self->channel, invert, false);
226-
#if SOC_LEDC_SUPPORT_HS_MODE
227-
} else if (self->mode == LEDC_HIGH_SPEED_MODE) {
228-
esp_rom_gpio_connect_out_signal(self->pin, LEDC_HS_SIG_OUT0_IDX + self->channel, invert, false);
229227
#endif
230-
}
228+
esp_rom_gpio_connect_out_signal(self->pin, ledc_periph_signal[self->mode].sig_out0_idx + self->channel, invert, 0);
231229
}
232230

233231
static void apply_duty(machine_pwm_obj_t *self) {
@@ -253,6 +251,7 @@ static void apply_duty(machine_pwm_obj_t *self) {
253251
.intr_type = LEDC_INTR_DISABLE,
254252
.speed_mode = self->mode,
255253
.timer_sel = self->timer,
254+
.hpoint = 0,
256255
.flags.output_invert = self->output_invert,
257256
};
258257
self->output_is_inverted = false;
@@ -267,10 +266,13 @@ static void apply_duty(machine_pwm_obj_t *self) {
267266
check_esp_err(gpio_sleep_sel_dis(self->pin));
268267
chans[self->mode][self->channel].light_sleep_enable = true;
269268
}
270-
check_esp_err(ledc_bind_channel_timer(self->mode, self->channel, self->timer));
271269
} else {
270+
#if FADE
271+
check_esp_err(ledc_set_duty_and_update(self->mode, self->channel, self->channel_duty, 0));
272+
#else
272273
check_esp_err(ledc_set_duty(self->mode, self->channel, self->channel_duty));
273274
check_esp_err(ledc_update_duty(self->mode, self->channel));
275+
#endif
274276
}
275277
reconfigure_pin(self);
276278
register_channel(self->mode, self->channel, self->pin, self->timer);
@@ -282,6 +284,16 @@ static uint32_t find_suitable_duty_resolution(uint32_t src_clk_freq, uint32_t ti
282284
// limit resolution to user interface
283285
resolution = UI_RES_16_BIT;
284286
}
287+
/*
288+
// Uncomment if duty is 65536!
289+
// Note: On ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2, ESP32C6, ESP32H2, ESP32P4, due to a hardware bug,
290+
// 100% duty cycle (i.e. 2**duty_res) is not reachable when the binded timer selects the maximum duty
291+
// resolution. For example, the max duty resolution on ESP32C3 is 14-bit width, then set duty to (2**14)
292+
// will mess up the duty calculation in hardware.
293+
if (resolution >= SOC_LEDC_TIMER_BIT_WIDTH)
294+
resolution -= 1;
295+
}
296+
*/
285297
return resolution;
286298
}
287299

@@ -656,6 +668,9 @@ static mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type,
656668
// start the PWM subsystem if it's not already running
657669
if (!pwm_inited) {
658670
pwm_init();
671+
#if FADE
672+
ledc_fade_func_install(0);
673+
#endif
659674
pwm_inited = true;
660675
}
661676

0 commit comments

Comments
 (0)