84 uint8_t channel, uint8_t &bit_depth,
float frequency) {
86 bit_depth = bit_depth_opt.value_or(0);
88 ESP_LOGE(TAG,
"Frequency %f can't be achieved with any bit depth",
frequency);
91 ledc_timer_config_t timer_conf{};
92 timer_conf.speed_mode = speed_mode;
93 timer_conf.duty_resolution =
static_cast<ledc_timer_bit_t
>(bit_depth);
94 timer_conf.timer_num = timer_num;
96 timer_conf.clk_cfg = DEFAULT_CLK;
99 int attempt_count_max = SETUP_ATTEMPT_COUNT_MAX;
100 esp_err_t init_result = ESP_FAIL;
101 while (attempt_count_max > 0 && init_result != ESP_OK) {
102 init_result = ledc_timer_config(&timer_conf);
103 if (init_result != ESP_OK) {
104 ESP_LOGW(TAG,
"Unable to initialize timer with frequency %.1f and bit depth of %u",
frequency, bit_depth);
105 if (bit_depth <= 1) {
109 timer_conf.duty_resolution =
static_cast<ledc_timer_bit_t
>(--bit_depth);
123 ESP_LOGW(TAG,
"Not yet initialized");
128 state = 1.0f -
state;
132 const float duty_rounded = roundf(
state * max_duty);
133 auto duty =
static_cast<uint32_t>(duty_rounded);
138 ESP_LOGV(TAG,
"Setting duty: %" PRIu32
" on channel %u", duty, this->
channel_);
140 auto chan_num =
static_cast<ledc_channel_t
>(this->
channel_ % 8);
142 if (duty == max_duty) {
143 ledc_stop(speed_mode, chan_num, 1);
145 }
else if (duty == 0) {
146 ledc_stop(speed_mode, chan_num, 0);
149#if !defined(SOC_LEDC_SUPPORT_FADE_STOP)
150 if (ledc_duty_update_pending(speed_mode, chan_num)) {
151 ESP_LOGV(TAG,
"Skipping LEDC duty update on channel %u while previous duty_start is still set", this->
channel_);
155 ledc_set_duty_with_hpoint(speed_mode, chan_num, duty, hpoint);
156 ledc_update_duty(speed_mode, chan_num);
162 if (!ledc_peripheral_reset_done) {
163 ESP_LOGV(TAG,
"Resetting LEDC peripheral to clear stale state after reboot");
164 periph_module_reset(PERIPH_LEDC_MODULE);
165 ledc_peripheral_reset_done =
true;
169 auto timer_num =
static_cast<ledc_timer_t
>((this->
channel_ % 8) / 2);
170 auto chan_num =
static_cast<ledc_channel_t
>(this->
channel_ % 8);
172 esp_err_t timer_init_result =
175 if (timer_init_result != ESP_OK) {
176 ESP_LOGE(TAG,
"Frequency %f can't be achieved with computed bit depth %u", this->
frequency_, this->
bit_depth_);
182 ESP_LOGV(TAG,
"Configured frequency %f with bit depth %u, angle %.1f° hpoint %u", this->
frequency_, this->
bit_depth_,
185 ledc_channel_config_t chan_conf{};
187 chan_conf.speed_mode = speed_mode;
188 chan_conf.channel = chan_num;
189 chan_conf.intr_type = LEDC_INTR_DISABLE;
190 chan_conf.timer_sel = timer_num;
192 chan_conf.hpoint = hpoint;
193 ledc_channel_config(&chan_conf);