1 /*
2 * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 /* LEDC tested by PCNT in some case
7 * PCNT can get the LEDC waveform frequency
8 *
9 * test environment of UT_T1_LEDC:
10 * 1. connect GPIO18 with GPIO4
11 * 2. connect GPIO5 to 3.3v (in case of it is pulled down by default)
12 *
13 * some calculation related with duty:
14 * real duty = duty/2^duty_resolution
15 */
16 #include <esp_types.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <malloc.h>
20 #include <string.h>
21 #include "freertos/FreeRTOS.h"
22 #include "freertos/task.h"
23 #include "freertos/semphr.h"
24 #include "freertos/queue.h"
25 #include "unity.h"
26 #include "soc/ledc_periph.h"
27 #include "esp_system.h"
28 #include "driver/ledc.h"
29 #include "driver/gpio.h"
30
31 #define PULSE_IO 18
32 #define PCNT_INPUT_IO 4
33 #define PCNT_CTRL_FLOATING_IO 5
34 #define HIGHEST_LIMIT 10000
35 #define LOWEST_LIMIT -10000
36
37 #define TEST_PWM_FREQ 2000
38
39 #if SOC_LEDC_SUPPORT_HS_MODE
40 #define TEST_SPEED_MODE LEDC_HIGH_SPEED_MODE
41 #define SPEED_MODE_LIST {LEDC_HIGH_SPEED_MODE, LEDC_LOW_SPEED_MODE}
42 #else
43 #define TEST_SPEED_MODE LEDC_LOW_SPEED_MODE
44 #define SPEED_MODE_LIST {LEDC_LOW_SPEED_MODE}
45 #endif
46
initialize_channel_config(void)47 static ledc_channel_config_t initialize_channel_config(void)
48 {
49 ledc_channel_config_t config;
50 memset(&config, 0, sizeof(ledc_channel_config_t));
51 config.gpio_num = PULSE_IO;
52 config.speed_mode = TEST_SPEED_MODE;
53 config.channel = LEDC_CHANNEL_0;
54 config.intr_type = LEDC_INTR_DISABLE;
55 config.timer_sel = LEDC_TIMER_0;
56 config.duty = 4000;
57 config.hpoint = 0;
58 return config;
59 }
60
create_default_timer_config(void)61 static ledc_timer_config_t create_default_timer_config(void)
62 {
63 ledc_timer_config_t ledc_time_config;
64 memset(&ledc_time_config, 0, sizeof(ledc_timer_config_t));
65 ledc_time_config.speed_mode = TEST_SPEED_MODE;
66 ledc_time_config.duty_resolution = LEDC_TIMER_13_BIT;
67 ledc_time_config.timer_num = LEDC_TIMER_0;
68 ledc_time_config.freq_hz = TEST_PWM_FREQ;
69 ledc_time_config.clk_cfg = LEDC_USE_APB_CLK;
70 return ledc_time_config;
71 }
72
fade_setup(void)73 static void fade_setup(void)
74 {
75 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
76 ledc_ch_config.duty = 0;
77 ledc_timer_config_t ledc_time_config = create_default_timer_config();
78
79 TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
80 TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
81 vTaskDelay(5 / portTICK_PERIOD_MS);
82
83 //initialize fade service
84 TEST_ESP_OK(ledc_fade_func_install(0));
85 }
86
timer_duty_set_get(ledc_mode_t speed_mode,ledc_channel_t channel,uint32_t duty)87 static void timer_duty_set_get(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty)
88 {
89 TEST_ESP_OK(ledc_set_duty(speed_mode, channel, duty));
90 TEST_ESP_OK(ledc_update_duty(speed_mode, channel));
91 vTaskDelay(100 / portTICK_RATE_MS);
92 TEST_ASSERT_EQUAL_INT32(duty, ledc_get_duty(speed_mode, channel));
93 }
94
95 // use logic analyzer to view
timer_duty_test(ledc_channel_t channel,ledc_timer_bit_t timer_bit,ledc_timer_t timer,ledc_mode_t speed_mode)96 static void timer_duty_test(ledc_channel_t channel, ledc_timer_bit_t timer_bit, ledc_timer_t timer, ledc_mode_t speed_mode)
97 {
98 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
99 ledc_ch_config.speed_mode = speed_mode;
100 ledc_ch_config.channel = channel;
101 ledc_ch_config.timer_sel = timer;
102
103 ledc_timer_config_t ledc_time_config = create_default_timer_config();
104 ledc_time_config.speed_mode = speed_mode;
105 ledc_time_config.duty_resolution = timer_bit;
106 ledc_time_config.timer_num = timer;
107
108 TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
109 TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
110
111 // duty ratio: (2^duty)/(2^timer_bit)
112 timer_duty_set_get(ledc_ch_config.speed_mode, ledc_ch_config.channel, 0);
113 timer_duty_set_get(ledc_ch_config.speed_mode, ledc_ch_config.channel, 1);
114 timer_duty_set_get(ledc_ch_config.speed_mode, ledc_ch_config.channel, 1 << 12); // 50% duty
115 timer_duty_set_get(ledc_ch_config.speed_mode, ledc_ch_config.channel, (1 << 13) - 1);
116 timer_duty_set_get(ledc_ch_config.speed_mode, ledc_ch_config.channel, (1 << 13) - 2);
117 }
118
119 #if SOC_PCNT_SUPPORTED
120 #include "driver/pcnt.h" // TODO: C3 doesn't have PCNT peripheral
121
122 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
123 //no runners
124
125 // use PCNT to test the waveform of LEDC
wave_count(int last_time)126 static int16_t wave_count(int last_time)
127 {
128 int16_t test_counter;
129 pcnt_config_t pcnt_config = {
130 .pulse_gpio_num = PCNT_INPUT_IO,
131 .ctrl_gpio_num = PCNT_CTRL_FLOATING_IO,
132 .channel = PCNT_CHANNEL_0,
133 .unit = PCNT_UNIT_0,
134 .pos_mode = PCNT_COUNT_INC,
135 .neg_mode = PCNT_COUNT_DIS,
136 .lctrl_mode = PCNT_MODE_REVERSE,
137 .hctrl_mode = PCNT_MODE_KEEP,
138 .counter_h_lim = HIGHEST_LIMIT,
139 .counter_l_lim = LOWEST_LIMIT,
140 };
141 TEST_ESP_OK(pcnt_unit_config(&pcnt_config));
142
143 // initialize first
144 TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
145 TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
146 vTaskDelay(100 / portTICK_RATE_MS);
147 TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
148 TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
149
150 vTaskDelay(last_time / portTICK_RATE_MS);
151 TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
152 return test_counter;
153 }
154
155 // the PCNT will count the frequency of it
frequency_set_get(ledc_mode_t speed_mode,ledc_timer_t timer,uint32_t freq_hz,int16_t real_freq,int16_t error)156 static void frequency_set_get(ledc_mode_t speed_mode, ledc_timer_t timer, uint32_t freq_hz, int16_t real_freq, int16_t error)
157 {
158 int16_t count;
159 TEST_ESP_OK(ledc_set_freq(speed_mode, timer, freq_hz));
160 count = wave_count(1000);
161 TEST_ASSERT_INT16_WITHIN(error, count, real_freq);
162 TEST_ASSERT_EQUAL_INT32(ledc_get_freq(speed_mode, timer), real_freq);
163 }
164
timer_frequency_test(ledc_channel_t channel,ledc_timer_bit_t timer_bit,ledc_timer_t timer,ledc_mode_t speed_mode)165 static void timer_frequency_test(ledc_channel_t channel, ledc_timer_bit_t timer_bit, ledc_timer_t timer, ledc_mode_t speed_mode)
166 {
167 ledc_channel_config_t ledc_ch_config = {
168 .gpio_num = PULSE_IO,
169 .speed_mode = speed_mode,
170 .channel = channel,
171 .intr_type = LEDC_INTR_DISABLE,
172 .timer_sel = timer,
173 .duty = 4000,
174 .hpoint = 0,
175 };
176 ledc_timer_config_t ledc_time_config = {
177 .speed_mode = speed_mode,
178 .duty_resolution = timer_bit,
179 .timer_num = timer,
180 .freq_hz = 5000,
181 .clk_cfg = LEDC_USE_APB_CLK,
182 };
183 TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
184 TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
185 frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 100, 100, 2);
186 frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 5000, 5000, 5);
187 frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 9000, 9025, 5);
188 }
189
190 #endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
191
192 #endif // SOC_PCNT_SUPPORTED
193
194 TEST_CASE("LEDC channel config wrong gpio", "[ledc]")
195 {
196 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
197 ledc_ch_config.gpio_num = GPIO_NUM_MAX;
198 TEST_ASSERT(ledc_channel_config(&ledc_ch_config) == ESP_ERR_INVALID_ARG);
199 }
200
201 TEST_CASE("LEDC channel config wrong speed", "[ledc]")
202 {
203 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
204 ledc_ch_config.speed_mode = LEDC_SPEED_MODE_MAX;
205 TEST_ASSERT(ledc_channel_config(&ledc_ch_config) == ESP_ERR_INVALID_ARG);
206 }
207
208 TEST_CASE("LEDC channel config wrong channel", "[ledc]")
209 {
210 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
211 ledc_ch_config.channel = LEDC_CHANNEL_MAX;
212 TEST_ASSERT(ledc_channel_config(&ledc_ch_config) == ESP_ERR_INVALID_ARG);
213 }
214
215 TEST_CASE("LEDC channel config wrong interrupt type", "[ledc]")
216 {
217 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
218 ledc_ch_config.intr_type = 2;
219 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, ledc_channel_config(&ledc_ch_config));
220 }
221
222 TEST_CASE("LEDC wrong timer", "[ledc]")
223 {
224 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
225 ledc_ch_config.timer_sel = LEDC_TIMER_MAX;
226 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, ledc_channel_config(&ledc_ch_config));
227 }
228
229 TEST_CASE("LEDC channel config basic parameter test", "[ledc]")
230 {
231 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
232 TEST_ASSERT_EQUAL(ESP_OK, ledc_channel_config(&ledc_ch_config));
233 }
234
235 TEST_CASE("LEDC wrong duty resolution", "[ledc]")
236 {
237 ledc_timer_config_t ledc_time_config = create_default_timer_config();
238 ledc_time_config.duty_resolution = LEDC_TIMER_BIT_MAX;
239 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, ledc_timer_config(&ledc_time_config));
240 }
241
242 TEST_CASE("LEDC timer config wrong timer", "[ledc]")
243 {
244 ledc_timer_config_t ledc_time_config = create_default_timer_config();
245 ledc_time_config.timer_num = LEDC_TIMER_MAX;
246 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, ledc_timer_config(&ledc_time_config));
247 }
248
249 TEST_CASE("LEDC timer config wrong speed mode", "[ledc]")
250 {
251 ledc_timer_config_t ledc_time_config = create_default_timer_config();
252 ledc_time_config.speed_mode = LEDC_SPEED_MODE_MAX;
253 TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, ledc_timer_config(&ledc_time_config));
254 }
255
256 TEST_CASE("LEDC timer config basic parameter test", "[ledc]")
257 {
258 ledc_timer_config_t ledc_time_config = create_default_timer_config();
259 TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
260 }
261
262 TEST_CASE("LEDC error log channel and timer config", "[ledc]")
263 {
264 const ledc_mode_t test_speed_mode = TEST_SPEED_MODE;
265 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
266 ledc_timer_config_t ledc_time_config = create_default_timer_config();
267 TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
268 TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
269
270 uint32_t current_level = LEDC.channel_group[test_speed_mode].channel[LEDC_CHANNEL_0].conf0.idle_lv;
271 TEST_ESP_OK(ledc_stop(test_speed_mode, LEDC_CHANNEL_0, !current_level));
272 vTaskDelay(1000 / portTICK_RATE_MS);
273 TEST_ASSERT_EQUAL_INT32(LEDC.channel_group[test_speed_mode].channel[LEDC_CHANNEL_0].conf0.idle_lv, !current_level);
274 }
275
276 TEST_CASE("LEDC iterate over all channel and timer configs", "[ledc]")
277 {
278 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
279 ledc_timer_config_t ledc_time_config = create_default_timer_config();
280
281 // use all kinds of speed mode, channel, timer combination to test all of possible configuration
282 ledc_mode_t speed_mode[LEDC_SPEED_MODE_MAX] = SPEED_MODE_LIST;
283 ledc_channel_t channels[8] = {LEDC_CHANNEL_0, LEDC_CHANNEL_1, LEDC_CHANNEL_2, LEDC_CHANNEL_3, LEDC_CHANNEL_4, LEDC_CHANNEL_5};
284 ledc_timer_t timer_select[4] = {LEDC_TIMER_0, LEDC_TIMER_1, LEDC_TIMER_2, LEDC_TIMER_3};
285
286 for (int i = 0; i < LEDC_SPEED_MODE_MAX; i++) {
287 ledc_ch_config.speed_mode = speed_mode[i];
288 ledc_time_config.speed_mode = speed_mode[i];
289 for (int j = 0; j < 8; j++) {
290 ledc_ch_config.channel = channels[j];
291 for (int k = 0; k < 4; k++) {
292 ledc_ch_config.timer_sel = timer_select[k];
293 ledc_time_config.timer_num = timer_select[k];
294 TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
295 TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
296 }
297 }
298 }
299 }
300
301 TEST_CASE("LEDC memory leak test", "[ledc]")
302 {
303 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
304 TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
305
306 ledc_timer_config_t ledc_time_config = create_default_timer_config();
307 TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
308
309 uint32_t size = esp_get_free_heap_size();
310 uint32_t i;
311
312 // install and uninstall for 1000 times to test whether memory leaking exists
313 for (i = 0; i <= 1000; i++) {
314 TEST_ESP_OK(ledc_fade_func_install(0));
315 ledc_fade_func_uninstall();
316 }
317 TEST_ASSERT_INT32_WITHIN(100, size, esp_get_free_heap_size());
318 TEST_ESP_OK(ledc_stop(ledc_time_config.speed_mode, LEDC_CHANNEL_0, 0));
319 }
320
321 // duty should be manually checked from the waveform using a logic analyzer
322 // this test is enabled only for testting the settings
323 TEST_CASE("LEDC set and get duty", "[ledc]")
324 {
325 ledc_timer_t timer_list[4] = {LEDC_TIMER_0, LEDC_TIMER_1, LEDC_TIMER_2, LEDC_TIMER_3};
326 ledc_mode_t speed_mode_list[LEDC_SPEED_MODE_MAX] = SPEED_MODE_LIST;
327 for(int i=0; i<LEDC_TIMER_MAX-1; i++) {
328 for(int j=0; j<LEDC_SPEED_MODE_MAX; j++) {
329 timer_duty_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, timer_list[i], speed_mode_list[j]);
330 }
331 }
332 }
333
334 TEST_CASE("LEDC fade with time", "[ledc]")
335 {
336 const ledc_mode_t test_speed_mode = TEST_SPEED_MODE;
337 fade_setup();
338
339 TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 200));
340 TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE));
341 TEST_ASSERT_EQUAL_INT32(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
342
343 TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 0, 200));
344 TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT));
345 // duty should not be too far from initial value
346 TEST_ASSERT_INT32_WITHIN(20, 4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
347 vTaskDelay(210 / portTICK_PERIOD_MS);
348 TEST_ASSERT_EQUAL_INT32(0, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
349
350 //deinitialize fade service
351 ledc_fade_func_uninstall();
352 }
353
354 TEST_CASE("LEDC fade with step", "[ledc]")
355 {
356 const ledc_mode_t test_speed_mode = TEST_SPEED_MODE;
357 fade_setup();
358
359 TEST_ESP_OK(ledc_set_fade_with_step(test_speed_mode, LEDC_CHANNEL_0, 4000, 4, 1));
360 TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE));
361 TEST_ASSERT_EQUAL_INT32(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
362
363 TEST_ESP_OK(ledc_set_fade_with_step(test_speed_mode, LEDC_CHANNEL_0, 0, 4, 1));
364 TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT));
365 // duty should not be too far from initial value
366 TEST_ASSERT_INT32_WITHIN(20, 4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
367 vTaskDelay(525 / portTICK_PERIOD_MS);
368 TEST_ASSERT_EQUAL_INT32(0, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
369
370 //scaler=0 check
371 TEST_ASSERT(ledc_set_fade_with_step(test_speed_mode, LEDC_CHANNEL_0, 4000, 0, 1) == ESP_ERR_INVALID_ARG);
372
373 //deinitialize fade service
374 ledc_fade_func_uninstall();
375 }
376
377 TEST_CASE("LEDC fast switching duty with fade_wait_done", "[ledc]")
378 {
379 const ledc_mode_t test_speed_mode = TEST_SPEED_MODE;
380 fade_setup();
381
382 // fade function will block until fading to the target duty
383 int64_t fade_start, fade_stop;
384 fade_start = esp_timer_get_time();
385 TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 200));
386 TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE));
387 TEST_ASSERT_EQUAL_INT32(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
388 TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 1000, 150));
389 TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE));
390 TEST_ASSERT_EQUAL_INT32(1000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
391 fade_stop = esp_timer_get_time();
392 int time_ms = (fade_stop - fade_start) / 1000;
393 TEST_ASSERT_TRUE(fabs(time_ms - 350) < 20);
394
395 // next duty update will not take place until last fade reaches its target duty
396 TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 200));
397 TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE));
398 TEST_ASSERT_EQUAL_INT32(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
399 TEST_ESP_OK(ledc_set_duty(test_speed_mode, LEDC_CHANNEL_0, 500));
400 TEST_ESP_OK(ledc_update_duty(test_speed_mode, LEDC_CHANNEL_0));
401 vTaskDelay(5 / portTICK_PERIOD_MS);
402 TEST_ASSERT_EQUAL_INT32(500, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
403
404 //deinitialize fade service
405 ledc_fade_func_uninstall();
406 }
407
408 TEST_CASE("LEDC fast switching duty with fade_no_wait", "[ledc]")
409 {
410 const ledc_mode_t test_speed_mode = TEST_SPEED_MODE;
411 fade_setup();
412
413 // fade function returns immediately, but next fade still needs to wait for last fade ends
414 int64_t fade_start, first_fade_complete;
415 fade_start = esp_timer_get_time();
416 TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 200));
417 TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT));
418 TEST_ASSERT_LESS_THAN(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
419 TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 1000, 150));
420 TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT));
421 first_fade_complete = esp_timer_get_time();
422 // duty should not be too far from first fade target duty
423 TEST_ASSERT_INT32_WITHIN(20, 4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
424 int time_ms = (first_fade_complete - fade_start) / 1000;
425 TEST_ASSERT_TRUE(fabs(time_ms - 200) < 20);
426 vTaskDelay(158 / portTICK_PERIOD_MS);
427 TEST_ASSERT_EQUAL_INT32(1000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
428
429 // next duty update will not take place until last fade reaches its target duty
430 TEST_ESP_OK(ledc_set_fade_with_time(test_speed_mode, LEDC_CHANNEL_0, 4000, 200));
431 TEST_ESP_OK(ledc_fade_start(test_speed_mode, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT));
432 TEST_ASSERT_LESS_THAN(4000, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
433 TEST_ESP_OK(ledc_set_duty(test_speed_mode, LEDC_CHANNEL_0, 500));
434 TEST_ESP_OK(ledc_update_duty(test_speed_mode, LEDC_CHANNEL_0));
435 vTaskDelay(5 / portTICK_PERIOD_MS);
436 TEST_ASSERT_EQUAL_INT32(500, ledc_get_duty(test_speed_mode, LEDC_CHANNEL_0));
437
438 //deinitialize fade service
439 ledc_fade_func_uninstall();
440 }
441
442 #if SOC_PCNT_SUPPORTED
443
444 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
445
446 TEST_CASE("LEDC set and get frequency", "[ledc][test_env=UT_T1_LEDC][timeout=60][ignore]")
447 {
448 #if SOC_LEDC_SUPPORT_HS_MODE
449 timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_0, LEDC_HIGH_SPEED_MODE);
450 timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_1, LEDC_HIGH_SPEED_MODE);
451 timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_2, LEDC_HIGH_SPEED_MODE);
452 timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_3, LEDC_HIGH_SPEED_MODE);
453 #endif // SOC_LEDC_SUPPORT_HS_MODE
454 timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_0, LEDC_LOW_SPEED_MODE);
455 timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_1, LEDC_LOW_SPEED_MODE);
456 timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_2, LEDC_LOW_SPEED_MODE);
457 timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_3, LEDC_LOW_SPEED_MODE);
458 }
459
460 TEST_CASE("LEDC timer set", "[ledc][test_env=UT_T1_LEDC]")
461 {
462 const ledc_mode_t test_speed_mode = TEST_SPEED_MODE;
463 ledc_channel_config_t ledc_ch_config = {
464 .gpio_num = PULSE_IO,
465 .speed_mode = test_speed_mode,
466 .channel = LEDC_CHANNEL_0,
467 .intr_type = LEDC_INTR_DISABLE,
468 .timer_sel = LEDC_TIMER_0,
469 .duty = 800,
470 .hpoint = 0,
471 };
472 TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
473
474 ledc_timer_config_t ledc_time_config = {
475 .speed_mode = test_speed_mode,
476 .duty_resolution = 13,
477 .timer_num = LEDC_TIMER_0,
478 .freq_hz = 5000,
479 .clk_cfg = LEDC_USE_APB_CLK,
480 };
481 TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
482
483 uint32_t freq_get;
484 uint32_t count;
485 //set timer 0 as 250Hz, use REF_TICK
486 TEST_ESP_OK(ledc_timer_set(test_speed_mode, LEDC_TIMER_0, 1000, 10, LEDC_REF_TICK));
487 TEST_ESP_OK(ledc_timer_rst(test_speed_mode, LEDC_TIMER_0));
488 TEST_ASSERT_EQUAL_INT32(ledc_get_freq(test_speed_mode, LEDC_TIMER_0), 250);
489 freq_get = ledc_get_freq(test_speed_mode, LEDC_TIMER_0);
490 count = wave_count(1000);
491 TEST_ASSERT_UINT32_WITHIN(10, count, freq_get);
492
493 //set timer 3 as 500Hz, use APB_CLK
494 TEST_ESP_OK(ledc_timer_set(test_speed_mode, LEDC_TIMER_0, 5000, 13, LEDC_APB_CLK));
495 TEST_ESP_OK(ledc_timer_rst(test_speed_mode, LEDC_TIMER_0));
496 TEST_ASSERT_EQUAL_INT32(ledc_get_freq(test_speed_mode, LEDC_TIMER_0), 500);
497 freq_get = ledc_get_freq(test_speed_mode, LEDC_TIMER_0);
498 count = wave_count(1000);
499 TEST_ASSERT_UINT32_WITHIN(50, count, freq_get);
500
501 printf("Bind channel 0 to timer 0\n");
502 TEST_ESP_OK(ledc_bind_channel_timer(test_speed_mode, LEDC_CHANNEL_0, LEDC_TIMER_0));
503 vTaskDelay(1000 / portTICK_RATE_MS);
504 TEST_ASSERT_EQUAL_INT32(ledc_get_freq(test_speed_mode, LEDC_TIMER_0), 500);
505
506 uint32_t current_level = LEDC.channel_group[test_speed_mode].channel[LEDC_CHANNEL_0].conf0.idle_lv;
507 TEST_ESP_OK(ledc_stop(test_speed_mode, LEDC_CHANNEL_0, !current_level));
508 vTaskDelay(1000 / portTICK_RATE_MS);
509 TEST_ASSERT_EQUAL_INT32( LEDC.channel_group[test_speed_mode].channel[LEDC_CHANNEL_0].conf0.idle_lv, !current_level);
510 }
511
512 TEST_CASE("LEDC timer pause and resume", "[ledc][test_env=UT_T1_LEDC]")
513 {
514 const ledc_mode_t test_speed_mode = TEST_SPEED_MODE;
515 int16_t count;
516 ledc_channel_config_t ledc_ch_config = {
517 .gpio_num = PULSE_IO,
518 .speed_mode = test_speed_mode,
519 .channel = LEDC_CHANNEL_0,
520 .intr_type = LEDC_INTR_DISABLE,
521 .timer_sel = LEDC_TIMER_0,
522 .duty = 4000,
523 .hpoint = 0,
524 };
525 TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
526
527 ledc_timer_config_t ledc_time_config = {
528 .speed_mode = test_speed_mode,
529 .duty_resolution = LEDC_TIMER_13_BIT,
530 .timer_num = LEDC_TIMER_0,
531 .freq_hz = 5000,
532 .clk_cfg = LEDC_USE_APB_CLK,
533 };
534 TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
535
536 count = wave_count(1000);
537 TEST_ASSERT_INT16_WITHIN(5, count, 5000);
538
539 //pause ledc timer, when pause it, will get no waveform count
540 printf("Pause ledc timer\n");
541 TEST_ESP_OK(ledc_timer_pause(test_speed_mode, LEDC_TIMER_0));
542 vTaskDelay(10 / portTICK_RATE_MS);
543 count = wave_count(1000);
544 TEST_ASSERT_INT16_WITHIN(5, count, 0);
545 TEST_ASSERT_EQUAL_UINT32(count, 0);
546
547 //resume ledc timer
548 printf("Resume ledc timer\n");
549 TEST_ESP_OK(ledc_timer_resume(test_speed_mode, LEDC_TIMER_0));
550 vTaskDelay(10 / portTICK_RATE_MS);
551 count = wave_count(1000);
552 TEST_ASSERT_UINT32_WITHIN(5, count, 5000);
553
554 //reset ledc timer
555 printf("reset ledc timer\n");
556 TEST_ESP_OK(ledc_timer_rst(test_speed_mode, LEDC_TIMER_0));
557 vTaskDelay(100 / portTICK_RATE_MS);
558 TEST_ASSERT_UINT32_WITHIN(5, count, 5000);
559 }
560
ledc_cpu_reset_test_first_stage(void)561 static void ledc_cpu_reset_test_first_stage(void)
562 {
563 ledc_channel_config_t ledc_ch_config = initialize_channel_config();
564 TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
565
566 ledc_timer_config_t ledc_time_config = create_default_timer_config();
567 TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
568 vTaskDelay(50 / portTICK_RATE_MS);
569 esp_restart();
570 }
571
ledc_cpu_reset_test_second_stage(void)572 static void ledc_cpu_reset_test_second_stage(void)
573 {
574 TEST_ASSERT_EQUAL(ESP_RST_SW, esp_reset_reason());
575 int16_t count;
576 count = wave_count(1000);
577 TEST_ASSERT_UINT32_WITHIN(5, count, TEST_PWM_FREQ);
578 }
579
580 TEST_CASE_MULTIPLE_STAGES("LEDC software reset test",
581 "[ledc][test_env=UT_T1_LEDC]",
582 ledc_cpu_reset_test_first_stage,
583 ledc_cpu_reset_test_second_stage);
584
585 #endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
586
587 #endif // SOC_PCNT_SUPPORTED
588