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.
This commit is contained in:
parent
5b2929a0e6
commit
7775523b2d
@ -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)
|
#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) {
|
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 resolution = timers[TIMER_IDX(self->mode, self->timer)].duty_resolution;
|
||||||
int duty = ledc_get_duty(self->mode, self->channel);
|
int duty = ledc_get_duty(self->mode, self->channel);
|
||||||
if (resolution <= UI_RES_16_BIT) {
|
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) {
|
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
|
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) {
|
STATIC uint32_t get_duty_ns(machine_pwm_obj_t *self) {
|
||||||
|
pwm_is_active(self);
|
||||||
return duty_to_ns(self, get_duty_u16(self));
|
return duty_to_ns(self, get_duty_u16(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void set_duty_u16(machine_pwm_obj_t *self, int duty) {
|
STATIC void set_duty_u16(machine_pwm_obj_t *self, int duty) {
|
||||||
|
pwm_is_active(self);
|
||||||
if ((duty < 0) || (duty > UI_MAX_DUTY)) {
|
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);
|
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) {
|
STATIC void set_duty_u10(machine_pwm_obj_t *self, int duty) {
|
||||||
|
pwm_is_active(self);
|
||||||
if ((duty < 0) || (duty > MAX_DUTY_U10)) {
|
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);
|
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) {
|
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))) {
|
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));
|
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
|
// Set's and get's methods of PWM class
|
||||||
|
|
||||||
STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) {
|
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));
|
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) {
|
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)) {
|
if ((freq <= 0) || (freq > 40000000)) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("freqency must be from 1Hz to 40MHz"));
|
mp_raise_ValueError(MP_ERROR_TEXT("freqency must be from 1Hz to 40MHz"));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user