1 /*
2  * Copyright (c) 2017 Vitor Massaru Iha <vitor@massaru.org>
3  * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT espressif_esp32_ledc
9 
10 /* Include esp-idf headers first to avoid redefining BIT() macro */
11 #include <hal/ledc_hal.h>
12 #include <hal/ledc_types.h>
13 
14 #include <soc.h>
15 #include <errno.h>
16 #include <string.h>
17 #include <zephyr/drivers/pwm.h>
18 #include <zephyr/kernel.h>
19 #include <zephyr/drivers/pinctrl.h>
20 #include <zephyr/drivers/clock_control.h>
21 
22 #include <zephyr/logging/log.h>
23 LOG_MODULE_REGISTER(pwm_ledc_esp32, CONFIG_PWM_LOG_LEVEL);
24 
25 #if SOC_LEDC_SUPPORT_APB_CLOCK
26 #define CLOCK_SOURCE LEDC_APB_CLK
27 #elif SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
28 #define CLOCK_SOURCE LEDC_SCLK
29 #if defined(CONFIG_SOC_SERIES_ESP32C2)
30 #define SCLK_CLK_FREQ MHZ(60)
31 #elif defined(CONFIG_SOC_SERIES_ESP32C6)
32 #define SCLK_CLK_FREQ MHZ(80)
33 #endif
34 #endif
35 
36 struct pwm_ledc_esp32_data {
37 	ledc_hal_context_t hal;
38 	struct k_sem cmd_sem;
39 };
40 
41 struct pwm_ledc_esp32_channel_config {
42 	const uint8_t idx;
43 	const uint8_t channel_num;
44 	const uint8_t timer_num;
45 	uint32_t freq;
46 	const ledc_mode_t speed_mode;
47 	uint8_t resolution;
48 	ledc_clk_src_t clock_src;
49 	uint32_t duty_val;
50 };
51 
52 struct pwm_ledc_esp32_config {
53 	const struct pinctrl_dev_config *pincfg;
54 	const struct device *clock_dev;
55 	const clock_control_subsys_t clock_subsys;
56 	struct pwm_ledc_esp32_channel_config *channel_config;
57 	const int channel_len;
58 };
59 
get_channel_config(const struct device * dev,int channel_id)60 static struct pwm_ledc_esp32_channel_config *get_channel_config(const struct device *dev,
61 	int channel_id)
62 {
63 	struct pwm_ledc_esp32_config *config =
64 		(struct pwm_ledc_esp32_config *) dev->config;
65 
66 	for (uint8_t i = 0; i < config->channel_len; i++) {
67 		if (config->channel_config[i].idx == channel_id) {
68 			return &config->channel_config[i];
69 		}
70 	}
71 	return NULL;
72 }
73 
pwm_led_esp32_low_speed_update(const struct device * dev,int speed_mode,int channel)74 static void pwm_led_esp32_low_speed_update(const struct device *dev, int speed_mode, int channel)
75 {
76 	struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data;
77 
78 	if (speed_mode == LEDC_LOW_SPEED_MODE) {
79 		ledc_hal_ls_channel_update(&data->hal, channel);
80 	}
81 }
82 
pwm_led_esp32_update_duty(const struct device * dev,int speed_mode,int channel)83 static void pwm_led_esp32_update_duty(const struct device *dev, int speed_mode, int channel)
84 {
85 	struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data;
86 
87 	ledc_hal_set_sig_out_en(&data->hal, channel, true);
88 	ledc_hal_set_duty_start(&data->hal, channel, true);
89 
90 	pwm_led_esp32_low_speed_update(dev, speed_mode, channel);
91 }
92 
pwm_led_esp32_duty_set(const struct device * dev,struct pwm_ledc_esp32_channel_config * channel)93 static void pwm_led_esp32_duty_set(const struct device *dev,
94 	struct pwm_ledc_esp32_channel_config *channel)
95 {
96 	struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data;
97 
98 	ledc_hal_set_hpoint(&data->hal, channel->channel_num, 0);
99 	ledc_hal_set_duty_int_part(&data->hal, channel->channel_num, channel->duty_val);
100 	ledc_hal_set_duty_direction(&data->hal, channel->channel_num, 1);
101 	ledc_hal_set_duty_num(&data->hal, channel->channel_num, 1);
102 	ledc_hal_set_duty_cycle(&data->hal, channel->channel_num, 1);
103 	ledc_hal_set_duty_scale(&data->hal, channel->channel_num, 0);
104 	pwm_led_esp32_low_speed_update(dev, channel->speed_mode, channel->channel_num);
105 	pwm_led_esp32_update_duty(dev, channel->speed_mode, channel->channel_num);
106 }
107 
pwm_led_esp32_configure_pinctrl(const struct device * dev)108 static int pwm_led_esp32_configure_pinctrl(const struct device *dev)
109 {
110 	int ret;
111 	struct pwm_ledc_esp32_config *config = (struct pwm_ledc_esp32_config *) dev->config;
112 
113 	ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
114 	if (ret < 0) {
115 		LOG_ERR("PWM pinctrl setup failed (%d)", ret);
116 		return ret;
117 	}
118 	return 0;
119 }
120 
pwm_led_esp32_bind_channel_timer(const struct device * dev,struct pwm_ledc_esp32_channel_config * channel)121 static void pwm_led_esp32_bind_channel_timer(const struct device *dev,
122 	struct pwm_ledc_esp32_channel_config *channel)
123 {
124 	struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data;
125 
126 	ledc_hal_bind_channel_timer(&data->hal, channel->channel_num, channel->timer_num);
127 
128 	pwm_led_esp32_low_speed_update(dev, channel->speed_mode, channel->channel_num);
129 }
130 
pwm_led_esp32_calculate_max_resolution(struct pwm_ledc_esp32_channel_config * channel)131 static int pwm_led_esp32_calculate_max_resolution(struct pwm_ledc_esp32_channel_config *channel)
132 {
133 	/**
134 	 * Max duty resolution can be obtained with
135 	 * max_res = log2(CLK_FREQ/FREQ)
136 	 */
137 #if SOC_LEDC_SUPPORT_APB_CLOCK
138 	uint64_t clock_freq = channel->clock_src == LEDC_APB_CLK ? APB_CLK_FREQ : REF_CLK_FREQ;
139 #elif SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
140 	uint64_t clock_freq = SCLK_CLK_FREQ;
141 #endif
142 	uint32_t max_precision_n = clock_freq/channel->freq;
143 
144 	for (uint8_t i = 0; i <= SOC_LEDC_TIMER_BIT_WIDTH; i++) {
145 		max_precision_n /= 2;
146 		if (!max_precision_n) {
147 			channel->resolution =  i;
148 			return 0;
149 		}
150 	}
151 	return -EINVAL;
152 
153 }
154 
pwm_led_esp32_timer_config(struct pwm_ledc_esp32_channel_config * channel)155 static int pwm_led_esp32_timer_config(struct pwm_ledc_esp32_channel_config *channel)
156 {
157 	/**
158 	 * Calculate max resolution based on the given frequency and the pwm clock.
159 	 *
160 	 * There are 2 clock resources for PWM:
161 	 *
162 	 * 1. APB_CLK (80MHz)
163 	 * 2. REF_TICK (1MHz)
164 	 *
165 	 * The low speed timers can be sourced from:
166 	 *
167 	 * 1. APB_CLK (80MHz)
168 	 * 2. RTC_CLK (8Mhz)
169 	 *
170 	 * The APB_CLK is mostly used
171 	 *
172 	 * First we try to find the largest resolution using the APB_CLK source.
173 	 * If the given frequency doesn't support it, we move to the next clock source.
174 	 */
175 
176 #if SOC_LEDC_SUPPORT_APB_CLOCK
177 	channel->clock_src = LEDC_APB_CLK;
178 #endif
179 	if (!pwm_led_esp32_calculate_max_resolution(channel)) {
180 		return 0;
181 	}
182 
183 #if SOC_LEDC_SUPPORT_REF_TICK
184 	channel->clock_src = LEDC_REF_TICK;
185 	if (!pwm_led_esp32_calculate_max_resolution(channel)) {
186 		return 0;
187 	}
188 #endif
189 
190 	/**
191 	 * ESP32 - S2,S3 and C3 variants have only 14 bits counter.
192 	 * where as the plain ESP32 variant has 20 bits counter.
193 	 * application failed to set low frequency(1Hz) in S2, S3 and C3 variants.
194 	 * to get very low frequencies on these variants,
195 	 * frequency needs to be tuned with 18 bits clock divider.
196 	 * so select the slow clock source (1MHz) with highest counter resolution.
197 	 * this can be handled on the func 'pwm_led_esp32_timer_set' with 'prescaler'.
198 	 */
199 	channel->resolution = SOC_LEDC_TIMER_BIT_WIDTH;
200 	return 0;
201 }
202 
pwm_led_esp32_timer_set(const struct device * dev,struct pwm_ledc_esp32_channel_config * channel)203 static int pwm_led_esp32_timer_set(const struct device *dev,
204 	struct pwm_ledc_esp32_channel_config *channel)
205 {
206 	int prescaler = 0;
207 	uint32_t precision = (0x1 << channel->resolution);
208 	struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data;
209 
210 	__ASSERT_NO_MSG(channel->freq > 0);
211 
212 	switch (channel->clock_src) {
213 #if SOC_LEDC_SUPPORT_APB_CLOCK
214 	case LEDC_APB_CLK:
215 		/** This expression comes from ESP32 Espressif's Technical Reference
216 		 * Manual chapter 13.2.2 Timers.
217 		 * div_num is a fixed point value (Q10.8).
218 		 */
219 		prescaler = ((uint64_t) APB_CLK_FREQ << 8) / channel->freq / precision;
220 	break;
221 #endif
222 #if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
223 	case LEDC_SCLK:
224 		prescaler = ((uint64_t) SCLK_CLK_FREQ << 8) / channel->freq / precision;
225 	break;
226 #endif
227 #if SOC_LEDC_SUPPORT_REF_TICK
228 	case LEDC_REF_TICK:
229 		prescaler = ((uint64_t) REF_CLK_FREQ << 8) / channel->freq / precision;
230 	break;
231 #endif
232 	default:
233 		LOG_ERR("Invalid clock source (%d)", channel->clock_src);
234 		return -EINVAL;
235 	}
236 
237 	if (prescaler < 0x100 || prescaler > 0x3FFFF) {
238 		LOG_ERR("Prescaler out of range: %#X", prescaler);
239 		return -EINVAL;
240 	}
241 
242 	if (channel->speed_mode == LEDC_LOW_SPEED_MODE) {
243 		ledc_hal_set_slow_clk_sel(&data->hal, channel->clock_src);
244 	}
245 
246 	ledc_hal_set_clock_divider(&data->hal, channel->timer_num, prescaler);
247 	ledc_hal_set_duty_resolution(&data->hal, channel->timer_num, channel->resolution);
248 	ledc_hal_set_clock_source(&data->hal, channel->timer_num, channel->clock_src);
249 
250 	if (channel->speed_mode == LEDC_LOW_SPEED_MODE) {
251 		ledc_hal_ls_timer_update(&data->hal, channel->timer_num);
252 	}
253 
254 	/* reset low speed timer */
255 	ledc_hal_timer_rst(&data->hal, channel->timer_num);
256 
257 	return 0;
258 }
259 
pwm_led_esp32_get_cycles_per_sec(const struct device * dev,uint32_t channel_idx,uint64_t * cycles)260 static int pwm_led_esp32_get_cycles_per_sec(const struct device *dev,
261 					    uint32_t channel_idx, uint64_t *cycles)
262 {
263 	struct pwm_ledc_esp32_channel_config *channel = get_channel_config(dev, channel_idx);
264 
265 	if (!channel) {
266 		LOG_ERR("Error getting channel %d", channel_idx);
267 		return -EINVAL;
268 	}
269 
270 #if SOC_LEDC_SUPPORT_APB_CLOCK
271 	*cycles = channel->clock_src == LEDC_APB_CLK ? APB_CLK_FREQ : REF_CLK_FREQ;
272 #elif SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
273 	*cycles = SCLK_CLK_FREQ;
274 #endif
275 
276 	return 0;
277 }
278 
pwm_led_esp32_set_cycles(const struct device * dev,uint32_t channel_idx,uint32_t period_cycles,uint32_t pulse_cycles,pwm_flags_t flags)279 static int pwm_led_esp32_set_cycles(const struct device *dev, uint32_t channel_idx,
280 				    uint32_t period_cycles,
281 				    uint32_t pulse_cycles, pwm_flags_t flags)
282 {
283 	int ret;
284 	uint64_t clk_freq;
285 	struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data;
286 	struct pwm_ledc_esp32_channel_config *channel = get_channel_config(dev, channel_idx);
287 
288 	if (!channel) {
289 		LOG_ERR("Error getting channel %d", channel_idx);
290 		return -EINVAL;
291 	}
292 
293 	/* Update PWM frequency according to period_cycles */
294 	ret = pwm_led_esp32_get_cycles_per_sec(dev, channel_idx, &clk_freq);
295 	if (ret < 0) {
296 		return ret;
297 	}
298 
299 	channel->freq = (uint32_t) (clk_freq/period_cycles);
300 	if (!channel->freq) {
301 		channel->freq = 1;
302 	}
303 
304 	k_sem_take(&data->cmd_sem, K_FOREVER);
305 
306 	ledc_hal_init(&data->hal, channel->speed_mode);
307 
308 	ret = pwm_led_esp32_timer_config(channel);
309 	if (ret < 0) {
310 		k_sem_give(&data->cmd_sem);
311 		return ret;
312 	}
313 
314 	ret = pwm_led_esp32_timer_set(dev, channel);
315 	if (ret < 0) {
316 		k_sem_give(&data->cmd_sem);
317 		return ret;
318 	}
319 
320 	pwm_led_esp32_bind_channel_timer(dev, channel);
321 
322 	/* Update PWM duty  */
323 
324 	double duty_cycle = (double) pulse_cycles / (double) period_cycles;
325 
326 	channel->duty_val = (uint32_t)((double) (1 << channel->resolution) * duty_cycle);
327 
328 	pwm_led_esp32_duty_set(dev, channel);
329 
330 	ret = pwm_led_esp32_configure_pinctrl(dev);
331 	if (ret < 0) {
332 		k_sem_give(&data->cmd_sem);
333 		return ret;
334 	}
335 
336 	k_sem_give(&data->cmd_sem);
337 
338 	return ret;
339 }
340 
341 
pwm_led_esp32_init(const struct device * dev)342 int pwm_led_esp32_init(const struct device *dev)
343 {
344 	const struct pwm_ledc_esp32_config *config = dev->config;
345 
346 	if (!device_is_ready(config->clock_dev)) {
347 		LOG_ERR("clock control device not ready");
348 		return -ENODEV;
349 	}
350 
351 	/* Enable peripheral */
352 	clock_control_on(config->clock_dev, config->clock_subsys);
353 
354 	return 0;
355 }
356 
357 static DEVICE_API(pwm, pwm_led_esp32_api) = {
358 	.set_cycles = pwm_led_esp32_set_cycles,
359 	.get_cycles_per_sec = pwm_led_esp32_get_cycles_per_sec,
360 };
361 
362 PINCTRL_DT_INST_DEFINE(0);
363 
364 #define CHANNEL_CONFIG(node_id)                                                \
365 	{                                                                      \
366 		.idx = DT_REG_ADDR(node_id),                                   \
367 		.channel_num = DT_REG_ADDR(node_id) % 8,                       \
368 		.timer_num = DT_PROP(node_id, timer),                          \
369 		.speed_mode = DT_REG_ADDR(node_id) < SOC_LEDC_CHANNEL_NUM      \
370 				      ? LEDC_LOW_SPEED_MODE                    \
371 				      : !LEDC_LOW_SPEED_MODE,                  \
372 		.clock_src = CLOCK_SOURCE,                                     \
373 	},
374 
375 static struct pwm_ledc_esp32_channel_config channel_config[] = {
376 	DT_INST_FOREACH_CHILD(0, CHANNEL_CONFIG)
377 };
378 
379 static struct pwm_ledc_esp32_config pwm_ledc_esp32_config = {
380 	.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
381 	.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)),
382 	.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(0, offset),
383 	.channel_config = channel_config,
384 	.channel_len = ARRAY_SIZE(channel_config),
385 };
386 
387 static struct pwm_ledc_esp32_data pwm_ledc_esp32_data = {
388 	.hal = {
389 		.dev = (ledc_dev_t *) DT_INST_REG_ADDR(0),
390 	},
391 	.cmd_sem = Z_SEM_INITIALIZER(pwm_ledc_esp32_data.cmd_sem, 1, 1),
392 };
393 
394 DEVICE_DT_INST_DEFINE(0, &pwm_led_esp32_init, NULL,
395 			&pwm_ledc_esp32_data,
396 			&pwm_ledc_esp32_config,
397 			POST_KERNEL,
398 			CONFIG_PWM_INIT_PRIORITY,
399 			&pwm_led_esp32_api);
400