There is a task that runs on core 1 that changes the LED when the controller enters different states that are set by tasks running on Core 0. e.g. BLE connected, Wifi connected...etc. The code can fade a single color via ledc just fine, say green or blue by itself. But when it attempts to mix 2 colors (blue and red) via ledc fade a WDT exception is being triggered.
Here is the configuration of the ledc timer, I'm using low speed mode.
Code: Select all
// configure the timer for the PWM DML 4/2/2024
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE, // timer mode
.duty_resolution = LEDC_TIMER_13_BIT, // resolution of PWM duty
.timer_num = LEDC_TIMER_1, // timer index
.freq_hz = 5000, // frequency of PWM signal
.clk_cfg = LEDC_AUTO_CLK, // Auto select the source clock
};Code: Select all
void LEDTask::fadeLED(int r, int g, int b, int fadeTime){
xSemaphoreTake(counting_sem, portMAX_DELAY);
xSemaphoreTake(counting_sem, portMAX_DELAY);
xSemaphoreTake(counting_sem, portMAX_DELAY);
ledc_set_fade_with_time(this->ledc_channel[R_CHANNEL].speed_mode,this->ledc_channel[R_CHANNEL].channel, r, fadeTime);
ledc_set_fade_with_time(this->ledc_channel[G_CHANNEL].speed_mode,this->ledc_channel[G_CHANNEL].channel, g, fadeTime);
ledc_set_fade_with_time(this->ledc_channel[B_CHANNEL].speed_mode,this->ledc_channel[B_CHANNEL].channel, b, fadeTime);
ledc_fade_start(this->ledc_channel[R_CHANNEL].speed_mode, this->ledc_channel[R_CHANNEL].channel, LEDC_FADE_NO_WAIT);
ledc_fade_start(this->ledc_channel[G_CHANNEL].speed_mode, this->ledc_channel[G_CHANNEL].channel, LEDC_FADE_NO_WAIT);
ledc_fade_start(this->ledc_channel[B_CHANNEL].speed_mode, this->ledc_channel[B_CHANNEL].channel, LEDC_FADE_NO_WAIT);
}Code: Select all
--- 0x40094bff: ledc_ll_set_duty_start at C:/Users/david/OneDrive/Documents/.espressif/v5.5.4/esp-idf/components/hal/esp32/include/hal/ledc_ll.h:487Code: Select all
static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num)
{
// wait until the last duty change took effect (duty_start bit will be self-cleared when duty update or fade is done)
// this is necessary on ESP32 only, otherwise, internal logic might mess up (later targets with SOC_LEDC_SUPPORT_FADE_STOP allow to re-configure parameters while last update is still in progress)
while (hw->channel_group[speed_mode].channel[channel_num].conf1.duty_start);
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_start = 1;
}While debugging this I also learned that the fade length that I'm using seems to have some bearing on this. The LED fades in and out over the course of 4 seconds, 2 sec in and 2 sec out. If I shorten this to 200 ms, 100ms in and 100ms out it doesn't trigger the WDT. Perhaps that is because the WDT task length is 300ms by default.
All this being said, I have not yet been able to recreate my issue with the ledc_fade example. Though the example is very simple and runs on a single core. I will attempt to modify it to use a couple of tasks that simulate what my code is doing and see if I can recreate the error in an example simple enough to share.
Does anyone have any thoughts on the empty while loop? It wasn't there in 5.1.2 but does show up in 5.2.6 and later.