Skip to content

Commit f9260ae

Browse files
Raffael Rostagnocfriedt
authored andcommitted
drivers: pwm: ledc: esp32: Fix RC_FAST and REF_TICK
Depending on clock config init, some devices might be initialized with RC_FAST clock enabled but not calibrated. Logic to detect if clock is calibrated was fixed for this reason. Also, logic to set RC_FAST and REF_TICK for devices with timer specific clocks (ESP32 and ESP32-S2) was also fixed. Signed-off-by: Raffael Rostagno <[email protected]>
1 parent ea7f01b commit f9260ae

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

drivers/pwm/pwm_led_esp32.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,19 @@ static int pwm_led_esp32_timer_config(struct pwm_ledc_esp32_channel_config *chan
153153
*/
154154
for (int i = 0; i < clock_src_num; i++) {
155155
if (clock_src[i] == LEDC_SLOW_CLK_RC_FAST) {
156-
/* RC_FAST requires enabling and calibrating */
157-
if (!rtc_dig_8m_enabled() && !periph_rtc_dig_clk8m_enable()) {
158-
/* skip RC_FAST as clock source */
159-
continue;
156+
uint32_t rc_fast_freq = periph_rtc_dig_clk8m_get_freq();
157+
158+
if (!rtc_dig_8m_enabled() || rc_fast_freq == 0) {
159+
/* RC_FAST requires enabling and calibrating */
160+
if (!periph_rtc_dig_clk8m_enable()) {
161+
/* skip RC_FAST as clock source */
162+
continue;
163+
}
164+
rc_fast_freq = periph_rtc_dig_clk8m_get_freq();
160165
}
166+
161167
channel->clock_src = clock_src[i];
162-
channel->clock_src_hz = periph_rtc_dig_clk8m_get_freq();
168+
channel->clock_src_hz = rc_fast_freq;
163169
} else {
164170
channel->clock_src = clock_src[i];
165171
esp_clk_tree_src_get_freq_hz(channel->clock_src,
@@ -198,12 +204,27 @@ static int pwm_led_esp32_timer_set(const struct device *dev,
198204
}
199205

200206
if (channel->speed_mode == LEDC_LOW_SPEED_MODE) {
201-
ledc_hal_set_slow_clk_sel(&data->hal, channel->clock_src);
207+
#if SOC_LEDC_SUPPORT_REF_TICK
208+
/* When the source clock of LOW_SPEED timer is timer-specific
209+
* (REF_TICK), global clock MUST be set to APB_CLK.
210+
*/
211+
ledc_clk_src_t global_clk = channel->clock_src == LEDC_REF_TICK
212+
? LEDC_SLOW_CLK_APB
213+
: channel->clock_src;
214+
#else
215+
ledc_clk_src_t global_clk = channel->clock_src;
216+
#endif
217+
ledc_hal_set_slow_clk_sel(&data->hal, global_clk);
202218
}
203219

204220
ledc_hal_set_clock_divider(&data->hal, channel->timer_num, prescaler);
205221
ledc_hal_set_duty_resolution(&data->hal, channel->timer_num, channel->resolution);
206-
ledc_hal_set_clock_source(&data->hal, channel->timer_num, channel->clock_src);
222+
223+
#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
224+
ledc_clk_src_t timer_clk =
225+
channel->clock_src == LEDC_REF_TICK ? channel->clock_src : LEDC_SCLK;
226+
ledc_hal_set_clock_source(&data->hal, channel->timer_num, timer_clk);
227+
#endif
207228

208229
if (channel->speed_mode == LEDC_LOW_SPEED_MODE) {
209230
ledc_hal_ls_timer_update(&data->hal, channel->timer_num);
@@ -377,7 +398,9 @@ int pwm_led_esp32_init(const struct device *dev)
377398
channel->clock_src = highspd_clks[0];
378399
}
379400
#endif
401+
#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
380402
ledc_hal_set_clock_source(&data->hal, channel->timer_num, channel->clock_src);
403+
#endif
381404

382405
esp_clk_tree_src_get_freq_hz(channel->clock_src,
383406
ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED,

0 commit comments

Comments
 (0)