How to use LEDC PWM in low speed mode?
-
- Posts: 1
- Joined: Thu Jan 19, 2017 8:49 am
How to use LEDC PWM in low speed mode?
Hi!
I am using the ledc pwm to control the servo motor,it worked well.
And nowi I need to control more than 8 , i have been checked ESP32 datasheet, there has 16 channel can use, 8 in High speed mode , 8 in Low speed mode.
But the ledc library doesn't support low speed mode right now, is there any way to use led pwn in low speed mode?
Like write the register directly?
thanks!
I am using the ledc pwm to control the servo motor,it worked well.
And nowi I need to control more than 8 , i have been checked ESP32 datasheet, there has 16 channel can use, 8 in High speed mode , 8 in Low speed mode.
But the ledc library doesn't support low speed mode right now, is there any way to use led pwn in low speed mode?
Like write the register directly?
thanks!
-
- Posts: 9764
- Joined: Thu Nov 26, 2015 4:08 am
Re: How to use LEDC PWM in low speed mode?
Not sure if the driver doesn't support all 16 channels... they may just not be supporting the low-speed option of the low-speed channels. But anyway, if you want to poke at the registers yourself, the LED PWM controller is documented in the TRM: https://espressif.com/en/content/esp32- ... nce-manual . Don't forget to actually turn the peripheral on, and you should get it going pretty quickly.
Re: How to use LEDC PWM in low speed mode?
hi jeroen,ESP_Sprite wrote:Not sure if the driver doesn't support all 16 channels... they may just not be supporting the low-speed option of the low-speed channels. But anyway, if you want to poke at the registers yourself, the LED PWM controller is documented in the TRM: https://espressif.com/en/content/esp32- ... nce-manual . Don't forget to actually turn the peripheral on, and you should get it going pretty quickly.
high speed channels works,
one question, same here - next is here low speed,
for low speed can we turn the peripheral on on same way like high speed?
Code: Select all
// Enable LEDC PWM peripheral
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_LEDC_CLK_EN);
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_LEDC_RST);
rudi
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
Re: How to use LEDC PWM in low speed mode?
hi guys,
my wsock test with highspeed pwm on RGB on wRover Kit V2
debug prints on uart console
duty set by wifi browser/wsock.
if you want you can see here a short animation sequence
Abridged versions
works.
if i test in an other project the low speed pwm
same procedure, only change H to L
my lowspeed pwm on RGB on wRover Kit V2
works not.
i am not sure in the LOW Speed setup, think there is one or two code lines missing,
do we need to set low clk too then ?
where is my thinking wrong?
best wishes
rudi
btw:
you find a runing websocket server from Thomas here
tried after high speed register code then an high speed api code and it works,
a try to change the highspeed api to lowspeed api does not work too.
my wsock test with highspeed pwm on RGB on wRover Kit V2
debug prints on uart console
duty set by wifi browser/wsock.
if you want you can see here a short animation sequence
Abridged versions
Code: Select all
/* highspeed pwm test */
/* duty VARs for set duty later example by uart or wifi or other */
uint32_t dutyCycleR=0, dutyCycleG=0, dutyCycleB=0;
// highspeed
void pwm_highspeed_setup()
{
/* Enable LED PWM peripheral */
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_LEDC_CLK_EN);
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_LEDC_RST);
/* set high timer*/
WRITE_PERI_REG (LEDC_HSTIMER0_CONF_REG, (1<<25)|(0b000000001000000000<<5)|10);
/* set high speed channel 2 */
WRITE_PERI_REG (LEDC_HSCH2_CONF0_REG, (1<<3)|(1<<2));
WRITE_PERI_REG (LEDC_HSCH2_HPOINT_REG, 0 );
WRITE_PERI_REG (LEDC_HSCH2_DUTY_REG, 0);
WRITE_PERI_REG (LEDC_HSCH2_CONF1_REG, (1<<31));
/* set high speed channel 3 */
WRITE_PERI_REG (LEDC_HSCH3_CONF0_REG, (1<<3)|(1<<2));
WRITE_PERI_REG (LEDC_HSCH3_HPOINT_REG, 0 );
WRITE_PERI_REG (LEDC_HSCH3_DUTY_REG, 0);
WRITE_PERI_REG (LEDC_HSCH3_CONF1_REG, (1<<31));
/* set high speed channel 4 */
WRITE_PERI_REG (LEDC_HSCH4_CONF0_REG, (1<<3)|(1<<2));
WRITE_PERI_REG (LEDC_HSCH4_HPOINT_REG, 0 );
WRITE_PERI_REG (LEDC_HSCH4_DUTY_REG, 0);
WRITE_PERI_REG (LEDC_HSCH4_CONF1_REG, (1<<31));
// R= 0 G= 2 B= 4
/* set gpio out enable */
WRITE_PERI_REG (GPIO_ENABLE_REG, (1<<0)|(1<<2)|(1<<4));
/* set LEDC_HS_SIG_OUT to the Green, Blue, Red gpio */
// info: LEDC_HS_SIG_OUT0_IDX is 71
// https://github.com/espressif/esp-idf/blob/master/components/esp32/include/soc/gpio_sig_map.h#L154
// setting is SIG_OUT + HighSpeedChannel here in the test 2, 3, and 4
WRITE_PERI_REG (GPIO_FUNC2_OUT_SEL_CFG_REG, (1<<10)|73); // G 71 + cn 2
WRITE_PERI_REG (GPIO_FUNC4_OUT_SEL_CFG_REG, (1<<10)|74); // B 71 + cn 3
WRITE_PERI_REG (GPIO_FUNC0_OUT_SEL_CFG_REG, (1<<10)|75); // R 71 + cn 4
/* GPIO MUX */
WRITE_PERI_REG (PERIPHS_IO_MUX_GPIO2_U, (3<<10)|(1<<8));
WRITE_PERI_REG (PERIPHS_IO_MUX_GPIO4_U, (3<<10)|(1<<8));
WRITE_PERI_REG (PERIPHS_IO_MUX_GPIO0_U, (3<<10)|(1<<8));
}
// highspeed
void pwm_highspeed_update()
{
/*chn-2 update duty green led */
WRITE_PERI_REG (LEDC_HSCH2_DUTY_REG, (dutyCycleG * DUTY_CYCLE_MAX / 100) << 4);
WRITE_PERI_REG (LEDC_HSCH2_CONF1_REG, (1<<31));
/*chn-3 update blue led */
WRITE_PERI_REG (LEDC_HSCH3_DUTY_REG, (dutyCycleB * DUTY_CYCLE_MAX / 100) << 4);
WRITE_PERI_REG (LEDC_HSCH3_CONF1_REG, (1<<31));
/*chn-4 update red led */
WRITE_PERI_REG (LEDC_HSCH4_DUTY_REG, (dutyCycleR * DUTY_CYCLE_MAX / 100) << 4);
WRITE_PERI_REG (LEDC_HSCH4_CONF1_REG, (1<<31));
}
void pwm_high_init(void)
{
/* setup PWM */
pwm_highspeed_setup();
/* set duty vars to all 50 "prozent" */
dutyCycleR=50;
dutyCycleG=50;
dutyCycleB=50;
/* update duty */
pwm_highspeed_update();
}
if i test in an other project the low speed pwm
same procedure, only change H to L
my lowspeed pwm on RGB on wRover Kit V2
Code: Select all
/* duty VARs for set duty later example by uart or wifi or other */
uint32_t dutyCycleR=0, dutyCycleG=0, dutyCycleB=0;
// lowspeed
void pwm_lowspeed_setup()
{
/* Enable LED PWM peripheral */
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_LEDC_CLK_EN);
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_LEDC_RST);
/* set low timer*/
WRITE_PERI_REG (LEDC_LSTIMER0_CONF_REG, (1<<25)|(0b000000001000000000<<5)|10);
/* set low speed channel 2 */
WRITE_PERI_REG (LEDC_LSCH2_CONF0_REG, (1<<3)|(1<<2));
WRITE_PERI_REG (LEDC_LSCH2_HPOINT_REG, 0 );
WRITE_PERI_REG (LEDC_LSCH2_DUTY_REG, 0);
WRITE_PERI_REG (LEDC_LSCH2_CONF1_REG, (1<<31));
/* set low speed channel 3 */
WRITE_PERI_REG (LEDC_LSCH3_CONF0_REG, (1<<3)|(1<<2));
WRITE_PERI_REG (LEDC_LSCH3_HPOINT_REG, 0 );
WRITE_PERI_REG (LEDC_LSCH3_DUTY_REG, 0);
WRITE_PERI_REG (LEDC_LSCH3_CONF1_REG, (1<<31));
/* set low speed channel 4 */
WRITE_PERI_REG (LEDC_LSCH4_CONF0_REG, (1<<3)|(1<<2));
WRITE_PERI_REG (LEDC_LSCH4_HPOINT_REG, 0 );
WRITE_PERI_REG (LEDC_LSCH4_DUTY_REG, 0);
WRITE_PERI_REG (LEDC_LSCH4_CONF1_REG, (1<<31));
// R= 0 G= 2 B= 4
/* set gpio out enable */
WRITE_PERI_REG (GPIO_ENABLE_REG, (1<<0)|(1<<2)|(1<<4));
/* set LEDC_LS_SIG_OUT to the Green, Blue, Red gpio */
// info: LEDC_LS_SIG_OUT0_IDX is 79
// https://github.com/espressif/esp-idf/blob/master/components/esp32/include/soc/gpio_sig_map.h#L170
// setting is SIG_OUT + LowSpeedChannel here in the test 2, 3, and 4
WRITE_PERI_REG (GPIO_FUNC2_OUT_SEL_CFG_REG, (1<<10)|81); // G 79 + cn 2
WRITE_PERI_REG (GPIO_FUNC4_OUT_SEL_CFG_REG, (1<<10)|82); // B 79 + cn 3
WRITE_PERI_REG (GPIO_FUNC0_OUT_SEL_CFG_REG, (1<<10)|83); // R 79 + cn 4
/* GPIO MUX */
WRITE_PERI_REG (PERIPHS_IO_MUX_GPIO2_U, (3<<10)|(1<<8));
WRITE_PERI_REG (PERIPHS_IO_MUX_GPIO4_U, (3<<10)|(1<<8));
WRITE_PERI_REG (PERIPHS_IO_MUX_GPIO0_U, (3<<10)|(1<<8));
}
// lowspeed
void pwm_lowspeed_update()
{
/*chn-2 update duty green led */
WRITE_PERI_REG (LEDC_LSCH2_DUTY_REG, (dutyCycleG * DUTY_CYCLE_MAX / 100) << 4);
WRITE_PERI_REG (LEDC_LSCH2_CONF1_REG, (1<<31));
/*chn-3 update blue led */
WRITE_PERI_REG (LEDC_LSCH3_DUTY_REG, (dutyCycleB * DUTY_CYCLE_MAX / 100) << 4);
WRITE_PERI_REG (LEDC_LSCH3_CONF1_REG, (1<<31));
/*chn-4 update red led */
WRITE_PERI_REG (LEDC_LSCH4_DUTY_REG, (dutyCycleR * DUTY_CYCLE_MAX / 100) << 4);
WRITE_PERI_REG (LEDC_LSCH4_CONF1_REG, (1<<31));
}
void pwm_low_init(void)
{
/* setup PWM */
pwm_lowspeed_setup();
/* set duty to all 50 "prozent" */
dutyCycleR=50;
dutyCycleG=50;
dutyCycleB=50;
/* update duty */
pwm_lowspeed_update();
}
works not.
i am not sure in the LOW Speed setup, think there is one or two code lines missing,
do we need to set low clk too then ?
where is my thinking wrong?
best wishes
rudi
btw:
you find a runing websocket server from Thomas here
tried after high speed register code then an high speed api code and it works,
Code: Select all
/* includes */
#include "driver/ledc.h"
#include "esp_err.h"
/* channels */
#define LED_R_PWM_CHANNEL LEDC_CHANNEL_1
#define LED_G_PWM_CHANNEL LEDC_CHANNEL_2
#define LED_B_PWM_CHANNEL LEDC_CHANNEL_3
/* timer */
#define LED_PWM_TIMER LEDC_TIMER_1
// #define LED_PWM_BIT_NUM LEDC_TIMER_10_BIT // 1024 ( 1023 )
#define LED_PWM_BIT_NUM LEDC_TIMER_8_BIT // 256 ( 255 )
/* used GPIO */
/* wRover Kit 2*/
#define LED_BLUE GPIO_NUM_4
#define LED_RED GPIO_NUM_0
#define LED_GREEN GPIO_NUM_2
void led_pwm_init(void)
{
ledc_channel_config_t ledc_channel_r = {0}, ledc_channel_g = {0}, ledc_channel_b = {0} ;
/* set channel r */
ledc_channel_r.gpio_num = LED_RED;
ledc_channel_r.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_channel_r.channel = LED_R_PWM_CHANNEL;
ledc_channel_r.intr_type = LEDC_INTR_DISABLE;
ledc_channel_r.timer_sel = LED_PWM_TIMER;
ledc_channel_r.duty = 0;
/* set channel g */
ledc_channel_g.gpio_num = LED_GREEN;
ledc_channel_g.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_channel_g.channel = LED_G_PWM_CHANNEL;
ledc_channel_g.intr_type = LEDC_INTR_DISABLE;
ledc_channel_g.timer_sel = LED_PWM_TIMER;
ledc_channel_g.duty = 0;
/* set channel b */
ledc_channel_b.gpio_num = LED_BLUE;
ledc_channel_b.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_channel_b.channel = LED_B_PWM_CHANNEL;
ledc_channel_b.intr_type = LEDC_INTR_DISABLE;
ledc_channel_b.timer_sel = LED_PWM_TIMER;
ledc_channel_b.duty = 0;
/* set timer */
ledc_timer_config_t ledc_timer = {0};
ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_timer.bit_num = LED_PWM_BIT_NUM;
ledc_timer.timer_num = LED_PWM_TIMER;
ledc_timer.freq_hz = 25000;
ESP_ERROR_CHECK( ledc_channel_config(&ledc_channel_r) );
ESP_ERROR_CHECK( ledc_channel_config(&ledc_channel_g) );
ESP_ERROR_CHECK( ledc_channel_config(&ledc_channel_b) );
ESP_ERROR_CHECK( ledc_timer_config(&ledc_timer) );
}
void led_pwm_set(uint32_t led_r_duty, uint32_t led_g_duty, uint32_t led_b_duty ) {
/* LED R */
ESP_ERROR_CHECK( ledc_set_duty(LEDC_HIGH_SPEED_MODE, LED_R_PWM_CHANNEL, led_r_duty) );
ESP_ERROR_CHECK( ledc_update_duty(LEDC_HIGH_SPEED_MODE, LED_R_PWM_CHANNEL) );
/* LED G */
ESP_ERROR_CHECK( ledc_set_duty(LEDC_HIGH_SPEED_MODE, LED_G_PWM_CHANNEL, led_g_duty) );
ESP_ERROR_CHECK( ledc_update_duty(LEDC_HIGH_SPEED_MODE, LED_G_PWM_CHANNEL) );
/* LED B */
ESP_ERROR_CHECK( ledc_set_duty(LEDC_HIGH_SPEED_MODE, LED_B_PWM_CHANNEL, led_b_duty) );
ESP_ERROR_CHECK( ledc_update_duty(LEDC_HIGH_SPEED_MODE, LED_B_PWM_CHANNEL) );
}
void pwm_init(void) {
/* init PWM */
printf("\nRGB 255 PWM setup by API\n");
led_pwm_init();
/* set R= 155 G= 208 B= 223 */
/* call it in your cb if you need new value on the RGB */
printf("\nset duty\nR=155\nG=208\nB=223\n");
led_pwm_set(155, 208, 223 );
}
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
Re: How to use LEDC PWM in low speed mode?
hi guys,taken [url=http://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf]from the technical site 91[/url] wrote:
The low-speed timers l_timerx on the low-speed channel differ from the high-speed timers h_timerx
in two aspects:
1.
Where the high-speed timer clock source can be clocked from REF_TICK or APB_CLK, the low speed
timers are sourced from either REF_TICK or SLOW_CLOCK. The SLOW_CLOCK source can be either
APB_CLK (80 MHz) or 8 MHz, and can be selected using LEDC_APB_CLK_SEL.
2.
The high-speed counter and divider are glitch-free, which means that if the software modifies the maximum
counter or divisor value, the update will come into effect after the next overflow interrupt. In contrast, the
low-speed counter and divider will update these values only when LEDC_LSTIMERx_PARA_UP is set.
slow speed pwm need two things more?
LEDC_APB_CLK_SEL
https://github.com/espressif/esp-idf/bl ... eg.h#L2403
Code: Select all
/* LEDC_APB_CLK_SEL : R/W ;bitpos:[0] ;default: 1'b0 ; */
/*description: This bit is used to set the frequency of slow_clk. 1'b1:80mhz 1'b0:8mhz*/
https://github.com/espressif/esp-idf/bl ... eg.h#L1619
Code: Select all
/* LEDC_LSTIMER0_PARA_UP : R/W ;bitpos:[26] ;default: 1'h0 ; */
/*description: Set this bit to update reg_div_num_lstime0 and reg_lstimer0_lim.*/
my setup for low speed looks like is missing something
example timer (1<<26)
Code: Select all
/* set low timer*/
WRITE_PERI_REG (LEDC_LSTIMER0_CONF_REG, (1<<25)|(0b000000001000000000<<5)|10);
Code: Select all
WRITE_PERI_REG (LEDC_LSCH2_CONF0_REG, (1<<3)|(1<<2));
best wishes
rudi
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
Re: How to use LEDC PWM in low speed mode?
update
APB_CLK (80 MHz) or 8 MHz, and can be selected using LEDC_APB_CLK_SEL
and this change/set to 80mhz works:
LEDC_CONF_REG: 0x1
channel bind works too,
LED get on if Clock set to 80mhz
but i am not sure, that i use the right config for the low speed timer , this (1<<26) is not right.
i play with duty and measurement, can't see a difference, perhabs the update code is wrong?
pausing
best wishes
rudi
ok, SLOW_CLOCK source can be either#define LEDC_CONF_REG (DR_REG_LEDC_BASE + 0x0190)
/* LEDC_APB_CLK_SEL : R/W ;bitpos:[0] ;default: 1'b0 ; */
/*description: This bit is used to set the frequency of slow_clk. 1'b1:80mhz 1'b0:8mhz*/
APB_CLK (80 MHz) or 8 MHz, and can be selected using LEDC_APB_CLK_SEL
and this change/set to 80mhz works:
Code: Select all
//80mhz
WRITE_PERI_REG (LEDC_CONF_REG, (1<<0));
__asm__ __volatile__("nop;nop;nop;nop;nop;nop;nop;nop;");
Code: Select all
uint32_t val=0;
val = READ_PERI_REG (LEDC_CONF_REG);
__asm__ __volatile__("nop;nop;nop;nop;nop;nop;nop;nop;");
printf("LEDC_CONF_REG: 0x%X\n", val);
channel bind works too,
LED get on if Clock set to 80mhz
Code: Select all
/* LEDC_LS_SIG_OUT0_IDX 79 */
WRITE_PERI_REG (GPIO_FUNC2_OUT_SEL_CFG_REG, (1<<10)|82); // Green 79 + cn 3
WRITE_PERI_REG (GPIO_FUNC4_OUT_SEL_CFG_REG, (1<<10)|83); // Blue 79 + cn 4
WRITE_PERI_REG (GPIO_FUNC0_OUT_SEL_CFG_REG, (1<<10)|81); // Red 79 + cn 2
Code: Select all
WRITE_PERI_REG (LEDC_LSTIMER0_CONF_REG, (1<<26) | (1<<25)| (0b000000001000000000<<5)|10);
Code: Select all
WRITE_PERI_REG (LEDC_LSCH2_DUTY_REG, (dutyCycleG * DUTY_CYCLE_MAX / 100) << 4);
WRITE_PERI_REG (LEDC_LSCH2_CONF1_REG, (1<<31));
WRITE_PERI_REG (LEDC_LSCH3_DUTY_REG, (dutyCycleB * DUTY_CYCLE_MAX / 100) << 4);
WRITE_PERI_REG (LEDC_LSCH3_CONF1_REG, (1<<31));
WRITE_PERI_REG (LEDC_LSCH4_DUTY_REG, (dutyCycleR * DUTY_CYCLE_MAX / 100) << 4);
WRITE_PERI_REG (LEDC_LSCH4_CONF1_REG, (1<<31));
best wishes
rudi
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
Re: How to use LEDC PWM in low speed mode?
I think doc forgot to mention you also have to strobe LEDC_PARA_UP_LSCHx bitrudi ;-) wrote:
Code: Select all
WRITE_PERI_REG (LEDC_LSCH2_DUTY_REG, (dutyCycleG * DUTY_CYCLE_MAX / 100) << 4); WRITE_PERI_REG (LEDC_LSCH2_CONF1_REG, (1<<31)); WRITE_PERI_REG (LEDC_LSCH3_DUTY_REG, (dutyCycleB * DUTY_CYCLE_MAX / 100) << 4); WRITE_PERI_REG (LEDC_LSCH3_CONF1_REG, (1<<31)); WRITE_PERI_REG (LEDC_LSCH4_DUTY_REG, (dutyCycleR * DUTY_CYCLE_MAX / 100) << 4); WRITE_PERI_REG (LEDC_LSCH4_CONF1_REG, (1<<31));
- rajkumar patel
- Posts: 29
- Joined: Mon Apr 10, 2017 12:43 pm
- Location: india
Re: How to use LEDC PWM in low speed mode?
hi,
i've up and run given #ledc_fade.c example. and i was also wondering about going for low speed channel mode, but i found that in #ledc.h espressif_team has already clarified about this boundary(as of now). it's mentioned like, they only support high speed channel mode for now and low speed mode will be availed soon.
thanks.
i've up and run given #ledc_fade.c example. and i was also wondering about going for low speed channel mode, but i found that in #ledc.h espressif_team has already clarified about this boundary(as of now). it's mentioned like, they only support high speed channel mode for now and low speed mode will be availed soon.
thanks.
Regards,
Rajkumar M. Patel
Rajkumar M. Patel
Re: How to use LEDC PWM in low speed mode?
I would like to revisit this thread because our dev group wants to use more than 8 ledc-channels.
It still appears to me that the low speed mode channels do not work. I have tried going after the example and enabling two timers, one for high speed and one for low speed mode. However, as soon as two timers are present, everything turns black, meaning our lamps don't work in either channels. It appears that only one timer at a time is supported. However, how then do I put some channels in low speed mode while others still operate in high speed mode?
Is it true that this is still not possible?
It still appears to me that the low speed mode channels do not work. I have tried going after the example and enabling two timers, one for high speed and one for low speed mode. However, as soon as two timers are present, everything turns black, meaning our lamps don't work in either channels. It appears that only one timer at a time is supported. However, how then do I put some channels in low speed mode while others still operate in high speed mode?
Is it true that this is still not possible?
Re: How to use LEDC PWM in low speed mode?
*push*
Sorry, need that info because we're planning our devices around it
Sorry, need that info because we're planning our devices around it
Who is online
Users browsing this forum: No registered users and 130 guests