LEDC and ISR in Arduino

jlderoui
Posts: 2
Joined: Thu Nov 12, 2020 11:48 am

LEDC and ISR in Arduino

Postby jlderoui » Thu Nov 12, 2020 12:20 pm

Hello,

Noob with ESP32, I am trying to write a sound library using LEDC.
I want to use LEDC as a 1 bit D/A, sampling a waveform table.
Therefore I need to change the duty cycle every time the counter reaches the duty cycle ( overflows).
I did not find how to setup LEDC to call an ISR function in Arduino.
Did I miss something?

Thanks for your help.
JLD

jlderoui
Posts: 2
Joined: Thu Nov 12, 2020 11:48 am

Re: LEDC and ISR in Arduino

Postby jlderoui » Thu Nov 12, 2020 10:04 pm

The basic LECD function in Arduino don't seem to allow manage LECD ISR.
I therefore looked at using ESP IDF since it seems to work under Arduino.
I put a simple test program but have issues with the ISR option (see below).
When setting ledc_channel.intr_type to LEDC_INTR_FADE_END, it does compile but when I set it to LEDC_INTR_MAX, which is what I believe I need to get an interrupt when counter overflows, there is a compile error, stating it is not declared in scope!
Would really appreciate some help.
Regards,
JLD

Code: Select all

#include "driver/ledc.h"
#define LEDC_HS_CH0_GPIO    18

ledc_timer_config_t ledc_timer;
ledc_channel_config_t ledc_channel;

void IRAM_ATTR ledc_isr_routine(void *param) {
}

void initlecd() {
  // set LEDC timer
  ledc_timer.speed_mode       = LEDC_HIGH_SPEED_MODE;
  ledc_timer.duty_resolution  = LEDC_TIMER_13_BIT;
  ledc_timer.timer_num        = LEDC_TIMER_0;           
  ledc_timer.freq_hz          = 1000;                   

  // set LEDC channel
  ledc_channel.channel    = LEDC_CHANNEL_0;
  ledc_channel.duty       = 4000;
  ledc_channel.gpio_num   = LEDC_HS_CH0_GPIO;
  ledc_channel.speed_mode = LEDC_HIGH_SPEED_MODE;
//ledc_channel.intr_type  = LEDC_INTR_MAX;
  ledc_channel.intr_type  = LEDC_INTR_FADE_END;
  ledc_channel.timer_sel  = LEDC_TIMER_0;
// Set timer configuration
  ledc_timer_config(&ledc_timer);
// Set channel configuration
  ledc_channel_config(&ledc_channel);
// Set ISR 
  ledc_isr_register(ledc_isr_routine, NULL, ESP_INTR_FLAG_IRAM, NULL);
}

void setup() {
    initlecd();
}

void loop() {
  while (1) {
  }
}

fnoguez
Posts: 6
Joined: Mon Sep 07, 2020 2:03 am

Re: LEDC and ISR in Arduino

Postby fnoguez » Thu Dec 03, 2020 3:19 pm

Hi jilderoui
I' m facing very similar problem and I think the issue can be the ESP-IDF release you are using.
I compiled your code in Platformio with same results:
src\main.cpp: In function 'void initlecd()':
src\main.cpp:23:29: error: 'LEDC_INTR_MAX' was not declared in this scope.
In release 3.3, https://github.com/espressif/arduino-es ... ver/ledc.h
LEDC_INTR_MAX is declared.
I don't really know how to switch release versions in Platformio, I'm very new to ESP32 and C/C++.
If you find the way , can you please share it in this thread?

Best wishes
Fernando

fnoguez
Posts: 6
Joined: Mon Sep 07, 2020 2:03 am

Re: LEDC and ISR in Arduino

Postby fnoguez » Thu Dec 03, 2020 3:38 pm

I'm sorry!
I double checked and LEDC_INTR_MAX is not declared :cry:

abel-lisco
Posts: 6
Joined: Tue Dec 22, 2020 6:37 pm

Re: LEDC and ISR in Arduino

Postby abel-lisco » Tue Jan 12, 2021 5:13 am

Hi all,
I am not sure I understand the application you are trying to develop, but I have been working lately with the ledc API, and perhaps I can provide some info (from the API reference).
first, the type declaration is:
"
enum ledc_intr_type_t
Values:
LEDC_INTR_DISABLE = 0
Disable LEDC interrupt
LEDC_INTR_FADE_END
Enable LEDC interrupt
LEDC_INTR_MAX
"
"When configuring an LEDC channel, one of the parameters selected within ledc_channel_config_t is ledc_intr_type_t which triggers an interrupt on fade completion."

The only valid values are
LEDC_INTR_DISABLE
LEDC_INTR_FADE_END

I understood that LEDC_INTR_MAX behaves like and "non valid value", I could not find any other explanation about it, because the interrupt can only be enabled or disabled. I assumed that also because a similar syntax appears in other types, with that meaning.

However, the interrupt is fired when the fade cycle ends, so it is expected you perform a complete "fade" operation, either ledc_set_fade_with_time or ledc_fade_with_step.

And here comes my confusion: you are saying you want "to use LEDC as a 1 bit D/A, sampling a waveform table. Therefore I need to change the duty cycle every time the counter reaches the duty cycle

My understanding is that ledc will provide you a steady stream of pulses or a perfect fade cycle, but not one pulse at a time, so you cannot control de duty cycle of the "next" pulse.

You will get one interrupt for the whole fade cycle, not for each pulse.

i am not an expert, but it seems you need to design your application in a different way.

If you want to do some prototyping, I just posted a repository, with one Arduino sketch to do "interactive" prototyping with the ledc and esp32-hal-ledc (Arduiino) libraries.
There is one function in the Arduino library (hal-ledc) that is not implemented in the sketch, "tone()", but for the rest it may provide you a quick "hands on" on ledc.
the repository is at https://abellisco.github.io/liscolab

Hope this helped

Who is online

Users browsing this forum: Google [Bot] and 65 guests