88 uint8_t channel, uint8_t &bit_depth,
float frequency) {
90 bit_depth = bit_depth_opt.value_or(0);
92 ESP_LOGE(TAG,
"Frequency %f can't be achieved with any bit depth",
frequency);
95 ledc_timer_config_t timer_conf{};
96 timer_conf.speed_mode = speed_mode;
97 timer_conf.duty_resolution =
static_cast<ledc_timer_bit_t
>(bit_depth);
98 timer_conf.timer_num = timer_num;
100 timer_conf.clk_cfg = DEFAULT_CLK;
103 int attempt_count_max = SETUP_ATTEMPT_COUNT_MAX;
104 esp_err_t init_result = ESP_FAIL;
105 while (attempt_count_max > 0 && init_result != ESP_OK) {
106 init_result = ledc_timer_config(&timer_conf);
107 if (init_result != ESP_OK) {
108 ESP_LOGW(TAG,
"Unable to initialize timer with frequency %.1f and bit depth of %u",
frequency, bit_depth);
109 if (bit_depth <= 1) {
113 timer_conf.duty_resolution =
static_cast<ledc_timer_bit_t
>(--bit_depth);
127 ESP_LOGW(TAG,
"Not yet initialized");
132 state = 1.0f -
state;
136 const float duty_rounded = roundf(
state * max_duty);
137 auto duty =
static_cast<uint32_t>(duty_rounded);
142 ESP_LOGV(TAG,
"Setting duty: %" PRIu32
" on channel %u", duty, this->
channel_);
144 auto chan_num =
static_cast<ledc_channel_t
>(this->
channel_ % 8);
146 if (duty == max_duty) {
147 ledc_stop(speed_mode, chan_num, 1);
149 }
else if (duty == 0) {
150 ledc_stop(speed_mode, chan_num, 0);
153#if !defined(SOC_LEDC_SUPPORT_FADE_STOP)
154 if (ledc_duty_update_pending(speed_mode, chan_num)) {
155 ESP_LOGV(TAG,
"Skipping LEDC duty update on channel %u while previous duty_start is still set", this->
channel_);
159 ledc_set_duty_with_hpoint(speed_mode, chan_num, duty, hpoint);
160 ledc_update_duty(speed_mode, chan_num);
166 if (!ledc_peripheral_reset_done) {
167 ESP_LOGV(TAG,
"Resetting LEDC peripheral to clear stale state after reboot");
169#if !defined(CLANG_TIDY)
170#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 1, 0)
171 PERIPH_RCC_ATOMIC() { ledc_ll_reset_register(0); }
172#elif ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
173 PERIPH_RCC_ATOMIC() {
174 ledc_ll_enable_reset_reg(
true);
175 ledc_ll_enable_reset_reg(
false);
178 periph_module_reset(PERIPH_LEDC_MODULE);
181 ledc_peripheral_reset_done =
true;
185 auto timer_num =
static_cast<ledc_timer_t
>((this->
channel_ % 8) / 2);
186 auto chan_num =
static_cast<ledc_channel_t
>(this->
channel_ % 8);
188 esp_err_t timer_init_result =
191 if (timer_init_result != ESP_OK) {
192 ESP_LOGE(TAG,
"Frequency %f can't be achieved with computed bit depth %u", this->
frequency_, this->
bit_depth_);
198 ESP_LOGV(TAG,
"Configured frequency %f with bit depth %u, angle %.1f° hpoint %u", this->
frequency_, this->
bit_depth_,
201 ledc_channel_config_t chan_conf{};
202 chan_conf.gpio_num =
static_cast<gpio_num_t
>(this->
pin_->
get_pin());
203 chan_conf.speed_mode = speed_mode;
204 chan_conf.channel = chan_num;
205#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 0, 0)
206 chan_conf.intr_type = LEDC_INTR_DISABLE;
208 chan_conf.timer_sel = timer_num;
210 chan_conf.hpoint = hpoint;
211 ledc_channel_config(&chan_conf);