DIV by zero in ledc.c -> ledc_set_fade_with_step() fnc in case of scale =0
Posted: Tue Oct 31, 2017 7:59 pm
Hello,
I started to investigate about a strange behaviour. In case of decrease of the duty the scale used for division without to check scale is not 0. Please update.
The problematic part
step_num = (duty_cur - target_duty) / scale;
I started to investigate about a strange behaviour. In case of decrease of the duty the scale used for division without to check scale is not 0. Please update.
The problematic part
step_num = (duty_cur - target_duty) / scale;
Code: Select all
esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel, int target_duty, int scale, int cycle_num)
{
LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, LEDC_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
LEDC_CHECK(channel < LEDC_CHANNEL_MAX, LEDC_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK , LEDC_FADE_INIT_ERROR_STR, ESP_FAIL);
int timer_sel = LEDC.channel_group[speed_mode].channel[channel].conf0.timer_sel;
int max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.bit_num)) - 1;
LEDC_CHECK(target_duty <= max_duty, LEDC_FADE_TARGET_ERR_STR, ESP_ERR_INVALID_ARG);
//disable the interrupt, so the operation will not mess up
ledc_enable_intr_type(speed_mode, channel, LEDC_INTR_DISABLE);
portENTER_CRITICAL(&ledc_spinlock);
int duty_cur = LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> LEDC_DUTY_DECIMAL_BIT_NUM;
int duty_delta = target_duty > duty_cur ? target_duty - duty_cur : duty_cur - target_duty;
if (duty_delta == 0) {
portEXIT_CRITICAL(&ledc_spinlock);
return ESP_OK;
}
s_ledc_fade_rec[speed_mode][channel]->speed_mode = speed_mode;
s_ledc_fade_rec[speed_mode][channel]->target_duty = target_duty;
s_ledc_fade_rec[speed_mode][channel]->cycle_num = cycle_num;
s_ledc_fade_rec[speed_mode][channel]->scale = scale;
int step_num;
if (duty_cur > target_duty) {
s_ledc_fade_rec[speed_mode][channel]->direction = LEDC_DUTY_DIR_DECREASE;
[color=#FF0000]step_num = (duty_cur - target_duty) / scale;[/color]
step_num = step_num > LEDC_STEP_NUM_MAX ? LEDC_STEP_NUM_MAX : step_num;
} else {
s_ledc_fade_rec[speed_mode][channel]->direction = LEDC_DUTY_DIR_INCREASE;
step_num = (target_duty - duty_cur) / scale;
step_num = step_num > LEDC_STEP_NUM_MAX ? LEDC_STEP_NUM_MAX : step_num;
}
portEXIT_CRITICAL(&ledc_spinlock);
ledc_set_fade(
speed_mode,
channel,
duty_cur,
s_ledc_fade_rec[speed_mode][channel]->direction,
step_num,
s_ledc_fade_rec[speed_mode][channel]->cycle_num,
s_ledc_fade_rec[speed_mode][channel]->scale
);
ESP_LOGD(LEDC_TAG, "cur duty: %d; target: %d, step: %d, cycle: %d; scale: %d\n",
LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> LEDC_DUTY_DECIMAL_BIT_NUM,
target_duty,
step_num,
s_ledc_fade_rec[speed_mode][channel]->cycle_num,
s_ledc_fade_rec[speed_mode][channel]->scale
);
int bit_num_ch0 = (speed_mode == LEDC_HIGH_SPEED_MODE) ? LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S : LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
LEDC.int_clr.val |= BIT(bit_num_ch0 + channel);
ledc_enable_intr_type(speed_mode, channel, LEDC_INTR_FADE_END);
return ESP_OK;
}