LEDC unstable frequency

ardiehl
Posts: 7
Joined: Fri Oct 27, 2017 10:44 pm

LEDC unstable frequency

Postby ardiehl » Sat Nov 17, 2018 2:13 pm

esp-idf v3.1.1
I'm tying to generate an 1 KHz frequency uning ledc (without fade) and the frequency is not stable. How can i fix this ?
SDS00002.png
SDS00002.png (19.48 KiB) Viewed 15952 times
Code is as follows:

Code: Select all

#define J1772_LEDC_TIMER      LEDC_TIMER_0
#define J1772_LEDC_CHANNEL    LEDC_CHANNEL_0
#define J1772_LEDC_TIMER_RES  LEDC_TIMER_10_BIT
#define J1772_DUTY_MAX        1023

void ledc_init() {
	esp_err_t err;
	/* Prepare and set configuration of timers
	 * that will be used by LED Controller */
	ledc_timer_config_t ledc_timer;
	memset((void *)&ledc_timer,0,sizeof(ledc_timer));
	ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;		// timer mode
	ledc_timer.duty_resolution = J1772_LEDC_TIMER_RES;	// resolution of PWM duty
	ledc_timer.timer_num = J1772_LEDC_TIMER;		// timer index
	ledc_timer.freq_hz = 1000;				// frequency of PWM signal
	//ledc_timer_resume(LEDC_HIGH_SPEED_MODE, J1772_LEDC_TIMER);

	// Set configuration of timer0 for high speed channels
	err = ledc_timer_config(&ledc_timer);
	ledc_channel_config_t ledc_channel = {
			.gpio_num   = j1772_pilot_GPIO,
			.speed_mode = LEDC_HIGH_SPEED_MODE,
			.channel    = J1772_LEDC_CHANNEL,
			.intr_type  = LEDC_INTR_DISABLE,
			.timer_sel  = J1772_LEDC_TIMER,
			.duty       = J1772_DUTY_MAX,
			.hpoint     = 0					// TODO: AD 10.11.2018: new, does 0 work (0xfffff does not work)
	};
	err = ledc_channel_config(&ledc_channel);
}

void ledcSetDuty (int pwmPercent) {
	const char * ME = __func__;

	if ((pwmPercent == 0) | (pwmPercent == 100)) {
		// set the port to 0 or 1 without pwm, 100% is unstable, we get glitches
		ledc_stop(LEDC_HIGH_SPEED_MODE, J1772_LEDC_CHANNEL, (pwmPercent == 100) );
	} else {
		uint32_t duty;
		duty = (pwmPercent * J1772_DUTY_MAX) / 100;	// duty for timer (0..1023)
		esp_err_t err;
		err = ledc_set_duty(LEDC_HIGH_SPEED_MODE, J1772_LEDC_CHANNEL, duty);
		if (err != ESP_OK) ESP_LOGE(TAG, "ledc_set_duty returned %d", err);
		ledc_update_duty(LEDC_HIGH_SPEED_MODE, J1772_LEDC_CHANNEL);
	}
}

ledc_init();
ledcSetDuty (50);

weithh
Posts: 2
Joined: Sun Nov 25, 2018 4:12 am

Re: LEDC unstable frequency

Postby weithh » Sun Nov 25, 2018 4:21 am

Just faced the same thing, but also noticed that when esp32 is busy with display rendering PWM frequency is fine.
Check your menuconfig -> component config -> power management -> support for power management. In my case after disabling it frequency finally became stable.

Also if someone can suggest a way to keep power management turned on and not loose frequency stability i wold be glad to hear it.

ESP_igrr
Posts: 2072
Joined: Tue Dec 01, 2015 8:37 am

Re: LEDC unstable frequency

Postby ESP_igrr » Sun Nov 25, 2018 10:53 am

Hi weithh, have you tried

https://docs.espressif.com/projects/esp ... al-drivers

The following peripherals can work even when APB frequency is changing:
...
LEDC: if REF_TICK is used as clock source (see ledc_timer_config() function).

weithh
Posts: 2
Joined: Sun Nov 25, 2018 4:12 am

Re: LEDC unstable frequency

Postby weithh » Sun Nov 25, 2018 12:29 pm

ESP_igrr wrote:
Sun Nov 25, 2018 10:53 am
Hi weithh, have you tried

https://docs.espressif.com/projects/esp ... al-drivers
This whole led control thing is not my top priority right now, i just noticed flickering of display backlight when frequency changing.

I saw that there is another clock source in manual diagram, but didn't found nice way to configure it.
Configuration structure doesn't have clock selector and as far as i digged into it, clock can be selected only with this function, which is not quite straigtforward and doesn't have examples.

Code: Select all

ledc_timer_config_t timer_config = {};
timer_config.timer_num = ledc_timer;
timer_config.duty_resolution = LEDC_TIMER_12_BIT;
timer_config.freq_hz = 1000U;
timer_config.speed_mode = LEDC_HIGH_SPEED_MODE;
ESP_ERROR_CHECK(ledc_timer_config(&timer_config));

ESP_ERROR_CHECK(ledc_timer_set(
	LEDC_HIGH_SPEED_MODE, ledc_timer, RESOLUTION, 256, LEDC_REF_TICK
));
This way with no errors reported PWM signal just stopped.

Also it may be worth mentioning about this clock scaling behaviour in ledc docs, since it quite easy to forget about enabled power management and then get lost in debugging. Basically i have shot myself in the foot by enabling it, without reading whole page of documentation.

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: LEDC unstable frequency

Postby ESP_houwenxiang » Wed Nov 28, 2018 6:57 am

Hi, ardiehl
Have you solved your problem? I tested your code but didn't reproduce it.
wookooho

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: LEDC unstable frequency

Postby ESP_houwenxiang » Mon Dec 03, 2018 3:34 am

Hi, @ardiehl

We have not reproduced this issue with your code, have you solved this problem?
wookooho

ardiehl
Posts: 7
Joined: Fri Oct 27, 2017 10:44 pm

Re: LEDC unstable frequency

Postby ardiehl » Tue Dec 04, 2018 10:33 am

the problem is still present. It works when i do not enable "Enable dynamic frequency scaling (DFS) at startup"
If this option is enabled, the ledc frequency is >99% wrong, it looks like this (half the requested frequency and unstable)
PilotWrong.png
PilotWrong.png (20.2 KiB) Viewed 15707 times
with disabled "enable "Enable dynamic frequency scaling (DFS) at startup" it looks like this:
PilotOk.png
PilotOk.png (16.84 KiB) Viewed 15707 times
This is 1KHz and it is rock solid stable.

In case you would like to reproduce this, i have uploaded my project to
http://ardiehl.de/tmp/evse-031.tar.bz2
tested it with a devkit-c board, pwm pin is GPIO23
Flash it and type

Code: Select all

j -t
pilot -p 50
and you should see a clean 1 KHz signal

idf-version v3.1.1-rc2-2-gd1d2ce8c2-dirty

Btw, in the documentation for power management i found this:

The following peripherals can work even when APB frequency is changing:
LEDC: if REF_TICK is used as clock source (see ledc_timer_config() function).

However, i can not find anything regarding "REF_TICK" in the ledc_timer_config documentation, ledc_timer_config_t has the following members only

Code: Select all

ledc_mode_t speed_mode
ledc_timer_bit_t duty_resolution
ledc_timer_bit_t bit_num
ledc_timer_t timer_num
uint32_t freq_hz

User avatar
loboris
Posts: 514
Joined: Wed Dec 21, 2016 7:40 pm

Re: LEDC unstable frequency

Postby loboris » Tue Dec 04, 2018 6:46 pm


ardiehl
Posts: 7
Joined: Fri Oct 27, 2017 10:44 pm

Re: LEDC unstable frequency

Postby ardiehl » Tue Dec 04, 2018 9:22 pm

Thx, there is
uint32_t tick_sel: 1; /*This bit is used to choose apb_clk or ref_tick for high speed timer. 1'b1:apb_clk 0:ref_tick*/
in the ledc soc struct. However, i have not found a way to influence this via the ledc driver, any hint ?

User avatar
loboris
Posts: 514
Joined: Wed Dec 21, 2016 7:40 pm

Re: LEDC unstable frequency

Postby loboris » Tue Dec 04, 2018 10:24 pm

This value can be set by set by ledc_timer_set() function (source).
clk_src parameter can be LEDC_APB_CLK or LEDC_REF_TICK

Who is online

Users browsing this forum: Bing [Bot] and 58 guests