From 7775523b2ded41ee8929522341c242eee43e9a48 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 25 Sep 2022 15:50:37 +0200 Subject: [PATCH] esp32/machine_pwm: Verify PWM is active when config methods are called. Checks are added for pwm.freq(), pwm_duty(), pwm_duty_u10() and pwm.duty_u16(). This avoids a core dump on ESP32C3, and misleading error messages on Xtensa ESP32 devices. --- ports/esp32/machine_pwm.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ports/esp32/machine_pwm.c b/ports/esp32/machine_pwm.c index 2a456c71c7..99bef88e9a 100644 --- a/ports/esp32/machine_pwm.c +++ b/ports/esp32/machine_pwm.c @@ -298,7 +298,14 @@ STATIC int duty_to_ns(machine_pwm_obj_t *self, int duty) { #define get_duty_raw(self) ledc_get_duty(self->mode, self->channel) +STATIC void pwm_is_active(machine_pwm_obj_t *self) { + if (self->active == false) { + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("PWM inactive")); + } +} + STATIC uint32_t get_duty_u16(machine_pwm_obj_t *self) { + pwm_is_active(self); int resolution = timers[TIMER_IDX(self->mode, self->timer)].duty_resolution; int duty = ledc_get_duty(self->mode, self->channel); if (resolution <= UI_RES_16_BIT) { @@ -310,14 +317,17 @@ STATIC uint32_t get_duty_u16(machine_pwm_obj_t *self) { } STATIC uint32_t get_duty_u10(machine_pwm_obj_t *self) { + pwm_is_active(self); return get_duty_u16(self) >> 6; // Scale down from 16 bit to 10 bit resolution } STATIC uint32_t get_duty_ns(machine_pwm_obj_t *self) { + pwm_is_active(self); return duty_to_ns(self, get_duty_u16(self)); } STATIC void set_duty_u16(machine_pwm_obj_t *self, int duty) { + pwm_is_active(self); if ((duty < 0) || (duty > UI_MAX_DUTY)) { mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("duty_u16 must be from 0 to %d"), UI_MAX_DUTY); } @@ -356,6 +366,7 @@ STATIC void set_duty_u16(machine_pwm_obj_t *self, int duty) { } STATIC void set_duty_u10(machine_pwm_obj_t *self, int duty) { + pwm_is_active(self); if ((duty < 0) || (duty > MAX_DUTY_U10)) { mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("duty must be from 0 to %u"), MAX_DUTY_U10); } @@ -365,6 +376,7 @@ STATIC void set_duty_u10(machine_pwm_obj_t *self, int duty) { } STATIC void set_duty_ns(machine_pwm_obj_t *self, int ns) { + pwm_is_active(self); if ((ns < 0) || (ns > duty_to_ns(self, UI_MAX_DUTY))) { mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("duty_ns must be from 0 to %d ns"), duty_to_ns(self, UI_MAX_DUTY)); } @@ -598,10 +610,12 @@ STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) { // Set's and get's methods of PWM class STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) { + pwm_is_active(self); return MP_OBJ_NEW_SMALL_INT(ledc_get_freq(self->mode, self->timer)); } STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) { + pwm_is_active(self); if ((freq <= 0) || (freq > 40000000)) { mp_raise_ValueError(MP_ERROR_TEXT("freqency must be from 1Hz to 40MHz")); }