LED Control (LEDC)
Introduction
The LED control (LEDC) peripheral is primarily designed to control the intensity of LEDs, although it can also be used to generate PWM signals for other purposes. It has 6 channels which can generate independent waveforms that can be used, for example, to drive RGB LED devices.
The PWM controller can automatically increase or decrease the duty cycle gradually, allowing for fades without any processor interference.
Functionality Overview
Setting up a channel of the LEDC is done in three steps. Note that unlike ESP32, ESP32-H2 only supports configuring channels in "low speed" mode.
Timer Configuration by specifying the PWM signal's frequency and duty cycle resolution.
Channel Configuration by associating it with the timer and GPIO to output the PWM signal.
Change PWM Signal that drives the output in order to change LED's intensity. This can be done under the full control of software or with hardware fading functions.
As an optional step, it is also possible to set up an interrupt on fade end.
Note
For an initial setup, it is recommended to configure for the timers first (by calling ledc_timer_config()
), and then for the channels (by calling ledc_channel_config()
). This ensures the PWM frequency is at the desired value since the appearance of the PWM signal from the IO pad.
Timer Configuration
Setting the timer is done by calling the function ledc_timer_config()
and passing the data structure ledc_timer_config_t
that contains the following configuration settings:
Speed mode (value must be
LEDC_LOW_SPEED_MODE
)Timer number
ledc_timer_t
PWM signal frequency in Hz
Resolution of PWM duty
Source clock
ledc_clk_cfg_t
The frequency and the duty resolution are interdependent. The higher the PWM frequency, the lower the duty resolution which is available, and vice versa. This relationship might be important if you are planning to use this API for purposes other than changing the intensity of LEDs. For more details, see Section Supported Range of Frequency and Duty Resolutions.
The source clock can also limit the PWM frequency. The higher the source clock frequency, the higher the maximum PWM frequency can be configured.
Clock name |
Clock freq |
Clock capabilities |
---|---|---|
PLL_96M_CLK |
96 MHz |
/ |
RC_FAST_CLK |
~ 8 MHz |
Dynamic Frequency Scaling compatible, Light sleep compatible |
XTAL_CLK |
32 MHz |
Dynamic Frequency Scaling compatible |
Note
On ESP32-H2, if RC_FAST_CLK is chosen as the LEDC clock source, an internal calibration will be performed to get the exact frequency of the clock. This ensures the accuracy of output PWM signal frequency.
For ESP32-H2, all timers share one clock source. In other words, it is impossible to use different clock sources for different timers.
The LEDC driver offers a helper function ledc_find_suitable_duty_resolution()
to find the maximum possible resolution for the timer, given the source clock frequency and the desired PWM signal frequency.
When a timer is no longer needed by any channel, it can be deconfigured by calling the same function ledc_timer_config()
. The configuration structure ledc_timer_config_t
passes in should be:
ledc_timer_config_t::speed_mode
The speed mode of the timer which wants to be deconfigured belongs to (ledc_mode_t
)ledc_timer_config_t::timer_num
The ID of the timers which wants to be deconfigured (ledc_timer_t
)ledc_timer_config_t::deconfigure
Set this to true so that the timer specified can be deconfigured
Channel Configuration
When the timer is set up, configure the desired channel (one out of ledc_channel_t
). This is done by calling the function ledc_channel_config()
.
Similar to the timer configuration, the channel setup function should be passed a structure ledc_channel_config_t
that contains the channel's configuration parameters.
At this point, the channel should start operating and generating the PWM signal on the selected GPIO, as configured in ledc_channel_config_t
, with the frequency specified in the timer settings and the given duty cycle. The channel operation (signal generation) can be suspended at any time by calling the function ledc_stop()
.
Change PWM Signal
Once the channel starts operating and generating the PWM signal with the constant duty cycle and frequency, there are a couple of ways to change this signal. When driving LEDs, primarily the duty cycle is changed to vary the light intensity.
The following two sections describe how to change the duty cycle using software and hardware fading. If required, the signal's frequency can also be changed; it is covered in Section Change PWM Frequency.
Note
All the timers and channels in the ESP32-H2's LED PWM Controller only support low speed mode. Any change of PWM settings must be explicitly triggered by software (see below).
Change PWM Duty Cycle Using Software
To set the duty cycle, use the dedicated function ledc_set_duty()
. After that, call ledc_update_duty()
to activate the changes. To check the currently set value, use the corresponding _get_
function ledc_get_duty()
.
Another way to set the duty cycle, as well as some other channel parameters, is by calling ledc_channel_config()
covered in Section Channel Configuration.
The range of the duty cycle values passed to functions depends on selected duty_resolution
and should be from 0
to (2 ** duty_resolution)
. For example, if the selected duty resolution is 10, then the duty cycle values can range from 0 to 1024. This provides the resolution of ~ 0.1%.
Warning
On ESP32-H2, when channel's binded timer selects its maximum duty resolution, the duty cycle value cannot be set to (2 ** duty_resolution)
. Otherwise, the internal duty counter in the hardware will overflow and be messed up.
Change PWM Duty Cycle Using Hardware
The LEDC hardware provides the means to gradually transition from one duty cycle value to another. To use this functionality, enable fading with ledc_fade_func_install()
and then configure it by calling one of the available fading functions:
On ESP32-H2, the hardware additionally allows to perform up to 16 consecutive linear fades without CPU intervention. This feature can be useful if you want to do a fade with gamma correction.
The luminance perceived by human eyes does not have a linear relationship with the PWM duty cycle. In order to make human feel the LED is dimming or lightening linearly, the change in duty cycle should be non-linear, which is the so-called gamma correction. The LED controller can simulate a gamma curve fading by piecewise linear approximation. ledc_fill_multi_fade_param_list()
is a function that can help to construct the parameters for the piecewise linear fades. First, you need to allocate a memory block for saving the fade parameters, then by providing start/end PWM duty cycle values, gamma correction function, and the total number of desired linear segments to the helper function, it will fill the calculation results into the allocated space. You can also construct the array of ledc_fade_param_config_t
manually. Once the fade parameter structs are prepared, a consecutive fading can be configured by passing the pointer to the prepared ledc_fade_param_config_t
list and the total number of fade ranges to ledc_set_multi_fade()
.
Start fading with ledc_fade_start()
. A fade can be operated in blocking or non-blocking mode, please check ledc_fade_mode_t
for the difference between the two available fade modes. Note that with either fade mode, the next fade or fixed-duty update will not take effect until the last fade finishes or is stopped. ledc_fade_stop()
has to be called to stop a fade that is in progress.
To get a notification about the completion of a fade operation, a fade end callback function can be registered for each channel by calling ledc_cb_register()
after the fade service being installed. The fade end callback prototype is defined in ledc_cb_t
, where you should return a boolean value from the callback function, indicating whether a high priority task is woken up by this callback function. It is worth mentioning, the callback and the function invoked by itself should be placed in IRAM, as the interrupt service routine is in IRAM. ledc_cb_register()
will print a warning message if it finds the addresses of callback and user context are incorrect.
If not required anymore, fading and an associated interrupt can be disabled with ledc_fade_func_uninstall()
.
Change PWM Frequency
The LEDC API provides several ways to change the PWM frequency "on the fly":
Set the frequency by calling
ledc_set_freq()
. There is a corresponding functionledc_get_freq()
to check the current frequency.Change the frequency and the duty resolution by calling
ledc_bind_channel_timer()
to bind some other timer to the channel.Change the channel's timer by calling
ledc_channel_config()
.
More Control Over PWM
There are several lower level timer-specific functions that can be used to change PWM settings:
The first two functions are called "behind the scenes" by ledc_channel_config()
to provide a startup of a timer after it is configured.
Use Interrupts
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.
For registration of a handler to address this interrupt, call ledc_isr_register()
.
Supported Range of Frequency and Duty Resolutions
The LED PWM Controller is designed primarily to drive LEDs. It provides a large flexibility of PWM duty cycle settings. For instance, the PWM frequency of 5 kHz can have the maximum duty resolution of 13 bits. This means that the duty can be set anywhere from 0 to 100% with a resolution of ~ 0.012% (2 ** 13 = 8192 discrete levels of the LED intensity). Note, however, that these parameters depend on the clock signal clocking the LED PWM Controller timer which in turn clocks the channel (see timer configuration and the ESP32-H2 Technical Reference Manual > LED PWM Controller (LEDC) [PDF]).
The LEDC can be used for generating signals at much higher frequencies that are sufficient enough to clock other devices, e.g., a digital camera module. In this case, the maximum available frequency is 40 MHz with duty resolution of 1 bit. This means that the duty cycle is fixed at 50% and cannot be adjusted.
The LEDC API is designed to report an error when trying to set a frequency and a duty resolution that exceed the range of LEDC's hardware. For example, an attempt to set the frequency to 20 MHz and the duty resolution to 3 bits results in the following error reported on a serial monitor:
E (196) ledc: requested frequency and duty resolution cannot be achieved, try reducing freq_hz or duty_resolution. div_param=128
In such a situation, either the duty resolution or the frequency must be reduced. For example, setting the duty resolution to 2 resolves this issue and makes it possible to set the duty cycle at 25% steps, i.e., at 25%, 50% or 75%.
The LEDC driver also captures and reports attempts to configure frequency/duty resolution combinations that are below the supported minimum, e.g.,:
E (196) ledc: requested frequency and duty resolution cannot be achieved, try increasing freq_hz or duty_resolution. div_param=128000000
The duty resolution is normally set using ledc_timer_bit_t
. This enumeration covers the range from 10 to 15 bits. If a smaller duty resolution is required (from 10 down to 1), enter the equivalent numeric values directly.
Application Example
The LEDC basic example: peripherals/ledc/ledc_basic.
The LEDC change duty cycle and fading control example: peripherals/ledc/ledc_fade.
The LEDC color control with Gamma correction on RGB LED example: peripherals/ledc/ledc_gamma_curve_fade.
API Reference
Header File
This header file can be included with:
#include "driver/ledc.h"
This header file is a part of the API provided by the
esp_driver_ledc
component. To declare that your component depends onesp_driver_ledc
, add the following to your CMakeLists.txt:REQUIRES esp_driver_ledc
or
PRIV_REQUIRES esp_driver_ledc
Functions
-
esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf)
LEDC channel configuration Configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC duty.
- Parameters
ledc_conf -- Pointer of LEDC channel configure struct
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
-
uint32_t ledc_find_suitable_duty_resolution(uint32_t src_clk_freq, uint32_t timer_freq)
Helper function to find the maximum possible duty resolution in bits for ledc_timer_config()
- Parameters
src_clk_freq -- LEDC timer source clock frequency (Hz) (See doxygen comments of
ledc_clk_cfg_t
or get fromesp_clk_tree_src_get_freq_hz
)timer_freq -- Desired LEDC timer frequency (Hz)
- Returns
0 The timer frequency cannot be achieved
Others The largest duty resolution value to be set
-
esp_err_t ledc_timer_config(const ledc_timer_config_t *timer_conf)
LEDC timer configuration Configure LEDC timer with the given source timer/frequency(Hz)/duty_resolution.
- Parameters
timer_conf -- Pointer of LEDC timer configure struct
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current duty_resolution.
ESP_ERR_INVALID_STATE Timer cannot be de-configured because timer is not configured or is not paused
-
esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
LEDC update channel parameters.
Note
Call this function to activate the LEDC updated parameters. After ledc_set_duty, we need to call this function to update the settings. And the new LEDC parameters don't take effect until the next PWM cycle.
Note
ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to control one LEDC channel in different tasks at the same time. A thread-safe version of API is ledc_set_duty_and_update
Note
If
CONFIG_LEDC_CTRL_FUNC_IN_IRAM
is enabled, this function will be placed in the IRAM by linker, makes it possible to execute even when the Cache is disabled.Note
This function is allowed to run within ISR context.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
-
esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t ledc_channel)
Set LEDC output gpio.
Note
This function only routes the LEDC signal to GPIO through matrix, other LEDC resources initialization are not involved. Please use
ledc_channel_config()
instead to fully configure a LEDC channel.- Parameters
gpio_num -- The LEDC output gpio
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
ledc_channel -- LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
-
esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level)
LEDC stop. Disable LEDC output, and set idle level.
Note
If
CONFIG_LEDC_CTRL_FUNC_IN_IRAM
is enabled, this function will be placed in the IRAM by linker, makes it possible to execute even when the Cache is disabled.Note
This function is allowed to run within ISR context.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
idle_level -- Set output idle level after LEDC stops.
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
-
esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz)
LEDC set channel frequency (Hz)
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
timer_num -- LEDC timer index (0-3), select from ledc_timer_t
freq_hz -- Set the LEDC frequency
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current duty_resolution.
-
uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num)
LEDC get channel frequency (Hz)
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
timer_num -- LEDC timer index (0-3), select from ledc_timer_t
- Returns
0 error
Others Current LEDC frequency
-
esp_err_t ledc_set_duty_with_hpoint(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty, uint32_t hpoint)
LEDC set duty and hpoint value Only after calling ledc_update_duty will the duty update.
Note
ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to control one LEDC channel in different tasks at the same time. A thread-safe version of API is ledc_set_duty_and_update
Note
For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. Other duty operations will have to wait until the fade operation has finished.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
duty -- Set the LEDC duty, the range of duty setting is [0, (2**duty_resolution)]
hpoint -- Set the LEDC hpoint value, the range is [0, (2**duty_resolution)-1]
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
-
int ledc_get_hpoint(ledc_mode_t speed_mode, ledc_channel_t channel)
LEDC get hpoint value, the counter value when the output is set high level.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
- Returns
LEDC_ERR_VAL if parameter error
Others Current hpoint value of LEDC channel
-
esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty)
LEDC set duty This function do not change the hpoint value of this channel. if needed, please call ledc_set_duty_with_hpoint. only after calling ledc_update_duty will the duty update.
Note
ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to control one LEDC channel in different tasks at the same time. A thread-safe version of API is ledc_set_duty_and_update.
Note
For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. Other duty operations will have to wait until the fade operation has finished.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
duty -- Set the LEDC duty, the range of duty setting is [0, (2**duty_resolution)]
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
-
uint32_t ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
LEDC get duty This function returns the duty at the present PWM cycle. You shouldn't expect the function to return the new duty in the same cycle of calling ledc_update_duty, because duty update doesn't take effect until the next cycle.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
- Returns
LEDC_ERR_DUTY if parameter error
Others Current LEDC duty
-
esp_err_t ledc_set_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty, ledc_duty_direction_t fade_direction, uint32_t step_num, uint32_t duty_cycle_num, uint32_t duty_scale)
LEDC set gradient Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect.
Note
For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. Other duty operations will have to wait until the fade operation has finished.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
duty -- Set the start of the gradient duty, the range of duty setting is [0, (2**duty_resolution)]
fade_direction -- Set the direction of the gradient
step_num -- Set the number of the gradient
duty_cycle_num -- Set how many LEDC tick each time the gradient lasts
duty_scale -- Set gradient change amplitude
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
-
esp_err_t ledc_isr_register(void (*fn)(void*), void *arg, int intr_alloc_flags, ledc_isr_handle_t *handle)
Register LEDC interrupt handler, the handler is an ISR. The handler will be attached to the same CPU core that this function is running on.
- Parameters
fn -- Interrupt handler function.
arg -- User-supplied argument passed to the handler function.
intr_alloc_flags -- Flags used to allocate the interrupt. One or multiple (ORred) ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
handle -- Pointer to return handle. If non-NULL, a handle for the interrupt will be returned here.
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Failed to find available interrupt source
-
esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider, uint32_t duty_resolution, ledc_clk_src_t clk_src)
Configure LEDC settings.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
timer_sel -- Timer index (0-3), there are 4 timers in LEDC module
clock_divider -- Timer clock divide value, the timer clock is divided from the selected clock source
duty_resolution -- Resolution of duty setting in number of bits. The range is [1, SOC_LEDC_TIMER_BIT_WIDTH]
clk_src -- Select LEDC source clock.
- Returns
(-1) Parameter error
Other Current LEDC duty
-
esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, ledc_timer_t timer_sel)
Reset LEDC timer.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
timer_sel -- LEDC timer index (0-3), select from ledc_timer_t
- Returns
ESP_ERR_INVALID_ARG Parameter error
ESP_OK Success
-
esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, ledc_timer_t timer_sel)
Pause LEDC timer counter.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
timer_sel -- LEDC timer index (0-3), select from ledc_timer_t
- Returns
ESP_ERR_INVALID_ARG Parameter error
ESP_OK Success
-
esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, ledc_timer_t timer_sel)
Resume LEDC timer.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
timer_sel -- LEDC timer index (0-3), select from ledc_timer_t
- Returns
ESP_ERR_INVALID_ARG Parameter error
ESP_OK Success
-
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_timer_t timer_sel)
Bind LEDC channel with the selected timer.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
timer_sel -- LEDC timer index (0-3), select from ledc_timer_t
- Returns
ESP_ERR_INVALID_ARG Parameter error
ESP_OK Success
-
esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t scale, uint32_t cycle_num)
Set LEDC fade function.
Note
Call ledc_fade_func_install() once before calling this function. Call ledc_fade_start() after this to start fading.
Note
ledc_set_fade_with_step, ledc_set_fade_with_time and ledc_fade_start are not thread-safe, do not call these functions to control one LEDC channel in different tasks at the same time. A thread-safe version of API is ledc_set_fade_step_and_start
Note
For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. Other duty operations will have to wait until the fade operation has finished.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
target_duty -- Target duty of fading [0, (2**duty_resolution)]
scale -- Controls the increase or decrease step scale.
cycle_num -- increase or decrease the duty every cycle_num cycles
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_INVALID_STATE Channel not initialized
ESP_FAIL Fade function init error
-
esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int max_fade_time_ms)
Set LEDC fade function, with a limited time.
Note
Call ledc_fade_func_install() once before calling this function. Call ledc_fade_start() after this to start fading.
Note
ledc_set_fade_with_step, ledc_set_fade_with_time and ledc_fade_start are not thread-safe, do not call these functions to control one LEDC channel in different tasks at the same time. A thread-safe version of API is ledc_set_fade_step_and_start
Note
For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. Other duty operations will have to wait until the fade operation has finished.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
target_duty -- Target duty of fading [0, (2**duty_resolution)]
max_fade_time_ms -- The maximum time of the fading ( ms ).
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_INVALID_STATE Channel not initialized
ESP_FAIL Fade function init error
-
esp_err_t ledc_fade_func_install(int intr_alloc_flags)
Install LEDC fade function. This function will occupy interrupt of LEDC module.
- Parameters
intr_alloc_flags -- Flags used to allocate the interrupt. One or multiple (ORred) ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Intr flag error
ESP_ERR_NOT_FOUND Failed to find available interrupt source
ESP_ERR_INVALID_STATE Fade function already installed
-
void ledc_fade_func_uninstall(void)
Uninstall LEDC fade function.
-
esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_fade_mode_t fade_mode)
Start LEDC fading.
Note
Call ledc_fade_func_install() once before calling this function. Call this API right after ledc_set_fade_with_time or ledc_set_fade_with_step before to start fading.
Note
Starting fade operation with this API is not thread-safe, use with care.
Note
For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. Other duty operations will have to wait until the fade operation has finished.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel number
fade_mode -- Whether to block until fading done. See ledc_types.h ledc_fade_mode_t for more info. Note that this function will not return until fading to the target duty if LEDC_FADE_WAIT_DONE mode is selected.
- Returns
ESP_OK Success
ESP_ERR_INVALID_STATE Channel not initialized or fade function not installed.
ESP_ERR_INVALID_ARG Parameter error.
-
esp_err_t ledc_fade_stop(ledc_mode_t speed_mode, ledc_channel_t channel)
Stop LEDC fading. The duty of the channel is guaranteed to be fixed at most one PWM cycle after the function returns.
Note
This API can be called if a new fixed duty or a new fade want to be set while the last fade operation is still running in progress.
Note
Call this API will abort the fading operation only if it was started by calling ledc_fade_start with LEDC_FADE_NO_WAIT mode.
Note
If a fade was started with LEDC_FADE_WAIT_DONE mode, calling this API afterwards has no use in stopping the fade. Fade will continue until it reaches the target duty.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel number
- Returns
ESP_OK Success
ESP_ERR_INVALID_STATE Channel not initialized
ESP_ERR_INVALID_ARG Parameter error
ESP_FAIL Fade function init error
-
esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty, uint32_t hpoint)
A thread-safe API to set duty for LEDC channel and return when duty updated.
Note
For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. Other duty operations will have to wait until the fade operation has finished.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
duty -- Set the LEDC duty, the range of duty setting is [0, (2**duty_resolution)]
hpoint -- Set the LEDC hpoint value, the range is [0, (2**duty_resolution)-1]
- Returns
ESP_OK Success
ESP_ERR_INVALID_STATE Channel not initialized
ESP_ERR_INVALID_ARG Parameter error
ESP_FAIL Fade function init error
-
esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t max_fade_time_ms, ledc_fade_mode_t fade_mode)
A thread-safe API to set and start LEDC fade function, with a limited time.
Note
Call ledc_fade_func_install() once, before calling this function.
Note
For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. Other duty operations will have to wait until the fade operation has finished.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
target_duty -- Target duty of fading [0, (2**duty_resolution)]
max_fade_time_ms -- The maximum time of the fading ( ms ).
fade_mode -- choose blocking or non-blocking mode
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_INVALID_STATE Channel not initialized
ESP_FAIL Fade function init error
-
esp_err_t ledc_set_fade_step_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t scale, uint32_t cycle_num, ledc_fade_mode_t fade_mode)
A thread-safe API to set and start LEDC fade function.
Note
Call ledc_fade_func_install() once before calling this function.
Note
For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. Other duty operations will have to wait until the fade operation has finished.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
target_duty -- Target duty of fading [0, (2**duty_resolution)]
scale -- Controls the increase or decrease step scale.
cycle_num -- increase or decrease the duty every cycle_num cycles
fade_mode -- choose blocking or non-blocking mode
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_INVALID_STATE Channel not initialized
ESP_FAIL Fade function init error
-
esp_err_t ledc_cb_register(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_cbs_t *cbs, void *user_arg)
LEDC callback registration function.
Note
The callback is called from an ISR, it must never attempt to block, and any FreeRTOS API called must be ISR capable.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
cbs -- Group of LEDC callback functions
user_arg -- user registered data for the callback function
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_INVALID_STATE Channel not initialized
ESP_FAIL Fade function init error
-
esp_err_t ledc_set_multi_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t start_duty, const ledc_fade_param_config_t *fade_params_list, uint32_t list_len)
Set a LEDC multi-fade.
Note
Call
ledc_fade_func_install()
once before calling this function. Callledc_fade_start()
after this to start fading.Note
This function is not thread-safe, do not call it to control one LEDC channel in different tasks at the same time. A thread-safe version of API is ledc_set_multi_fade_and_start
Note
This function does not prohibit from duty overflow. User should take care of this by themselves. If duty overflow happens, the PWM signal will suddenly change from 100% duty cycle to 0%, or the other way around.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
start_duty -- Set the start of the gradient duty, the range of duty setting is [0, (2**duty_resolution)]
fade_params_list -- Pointer to the array of fade parameters for a multi-fade
list_len -- Length of the fade_params_list, i.e. number of fade ranges for a multi-fade (1 - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX)
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_INVALID_STATE Channel not initialized
ESP_FAIL Fade function init error
-
esp_err_t ledc_set_multi_fade_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t start_duty, const ledc_fade_param_config_t *fade_params_list, uint32_t list_len, ledc_fade_mode_t fade_mode)
A thread-safe API to set and start LEDC multi-fade function.
Note
Call
ledc_fade_func_install()
once before calling this function.Note
Fade will always begin from the current duty cycle. Make sure it is stable and synchronized to the desired initial value before calling this function. Otherwise, you may see unexpected duty change.
Note
This function does not prohibit from duty overflow. User should take care of this by themselves. If duty overflow happens, the PWM signal will suddenly change from 100% duty cycle to 0%, or the other way around.
- Parameters
speed_mode -- Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
start_duty -- Set the start of the gradient duty, the range of duty setting is [0, (2**duty_resolution)]
fade_params_list -- Pointer to the array of fade parameters for a multi-fade
list_len -- Length of the fade_params_list, i.e. number of fade ranges for a multi-fade (1 - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX)
fade_mode -- Choose blocking or non-blocking mode
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_INVALID_STATE Channel not initialized
ESP_FAIL Fade function init error
-
esp_err_t ledc_fill_multi_fade_param_list(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t start_duty, uint32_t end_duty, uint32_t linear_phase_num, uint32_t max_fade_time_ms, uint32_t (*gamma_correction_operator)(uint32_t), uint32_t fade_params_list_size, ledc_fade_param_config_t *fade_params_list, uint32_t *hw_fade_range_num)
Helper function to fill the fade params for a multi-fade. Useful if desires a gamma curve fading.
Note
The fade params are calculated based on the given start_duty and end_duty. If the duty is not at the start duty (gamma-corrected) when the fade begins, you may see undesired brightness change. Therefore, please always remember thet when passing the fade_params to either
ledc_set_multi_fade
orledc_set_multi_fade_and start
, the start_duty argument has to be the gamma-corrected start_duty.- Parameters
speed_mode -- [in] Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- [in] LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
start_duty -- [in] Duty cycle [0, (2**duty_resolution)] where the multi-fade begins with. This value should be a non-gamma-corrected duty cycle.
end_duty -- [in] Duty cycle [0, (2**duty_resolution)] where the multi-fade ends with. This value should be a non-gamma-corrected duty cycle.
linear_phase_num -- [in] Number of linear fades to simulate a gamma curved fade (1 - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX)
max_fade_time_ms -- [in] The maximum time of the fading ( ms ).
gamma_correction_operator -- [in] User provided gamma correction function. The function argument should be able to take any value within [0, (2**duty_resolution)]. And returns the gamma-corrected duty cycle.
fade_params_list_size -- [in] The size of the fade_params_list user allocated (1 - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX)
fade_params_list -- [out] Pointer to the array of ledc_fade_param_config_t structure
hw_fade_range_num -- [out] Number of fade ranges for this multi-fade
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_INVALID_STATE Channel not initialized
ESP_FAIL Required number of hardware ranges exceeds the size of the ledc_fade_param_config_t array user allocated
-
esp_err_t ledc_read_fade_param(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t range, uint32_t *dir, uint32_t *cycle, uint32_t *scale, uint32_t *step)
Get the fade parameters that are stored in gamma ram for a certain fade range.
Gamma ram is where saves the fade parameters for each fade range. The fade parameters are written in during fade configuration. When fade begins, the duty will change according to the parameters in gamma ram.
- Parameters
speed_mode -- [in] Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
channel -- [in] LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
range -- [in] Range index (0 - (SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX-1)), it specifies to which range in gamma ram to read
dir -- [out] Pointer to accept fade direction value
cycle -- [out] Pointer to accept fade cycle value
scale -- [out] Pointer to accept fade scale value
step -- [out] Pointer to accept fade step value
- Returns
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_INVALID_STATE Channel not initialized
Structures
-
struct ledc_channel_config_t
Configuration parameters of LEDC channel for ledc_channel_config function.
Public Members
-
int gpio_num
the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16
-
ledc_mode_t speed_mode
LEDC speed speed_mode, high-speed mode (only exists on esp32) or low-speed mode
-
ledc_channel_t channel
LEDC channel (0 - LEDC_CHANNEL_MAX-1)
-
ledc_intr_type_t intr_type
configure interrupt, Fade interrupt enable or Fade interrupt disable
-
ledc_timer_t timer_sel
Select the timer source of channel (0 - LEDC_TIMER_MAX-1)
-
uint32_t duty
LEDC channel duty, the range of duty setting is [0, (2**duty_resolution)]
-
int hpoint
LEDC channel hpoint value, the range is [0, (2**duty_resolution)-1]
-
unsigned int output_invert
Enable (1) or disable (0) gpio output invert
-
struct ledc_channel_config_t::[anonymous] flags
LEDC flags
-
int gpio_num
-
struct ledc_timer_config_t
Configuration parameters of LEDC timer for ledc_timer_config function.
Public Members
-
ledc_mode_t speed_mode
LEDC speed speed_mode, high-speed mode (only exists on esp32) or low-speed mode
-
ledc_timer_bit_t duty_resolution
LEDC channel duty resolution
-
ledc_timer_t timer_num
The timer source of channel (0 - LEDC_TIMER_MAX-1)
-
uint32_t freq_hz
LEDC timer frequency (Hz)
-
ledc_clk_cfg_t clk_cfg
Configure LEDC source clock from ledc_clk_cfg_t. Note that LEDC_USE_RC_FAST_CLK and LEDC_USE_XTAL_CLK are non-timer-specific clock sources. You can not have one LEDC timer uses RC_FAST_CLK as the clock source and have another LEDC timer uses XTAL_CLK as its clock source. All chips except esp32 and esp32s2 do not have timer-specific clock sources, which means clock source for all timers must be the same one.
-
bool deconfigure
Set this field to de-configure a LEDC timer which has been configured before Note that it will not check whether the timer wants to be de-configured is binded to any channel. Also, the timer has to be paused first before it can be de-configured. When this field is set, duty_resolution, freq_hz, clk_cfg fields are ignored.
-
ledc_mode_t speed_mode
-
struct ledc_cb_param_t
LEDC callback parameter.
Public Members
-
ledc_cb_event_t event
Event name
-
uint32_t speed_mode
Speed mode of the LEDC channel group
-
uint32_t channel
LEDC channel (0 - LEDC_CHANNEL_MAX-1)
-
uint32_t duty
LEDC current duty of the channel, the range of duty is [0, (2**duty_resolution)]
-
ledc_cb_event_t event
-
struct ledc_cbs_t
Group of supported LEDC callbacks.
Note
The callbacks are all running under ISR environment
-
struct ledc_fade_param_config_t
Structure for the fade parameters for one hardware fade to be written to gamma wr register.
* duty ^ ONE HW LINEAR FADE * | * | * | * | * start_duty + scale * n = end_duty |. . . . . . . . . . . . . . . . . . . . . . . . . .+- * | | * | | * | +--------+ * | | . * | | . * | -------+ . * | . . * | . . * | . . * | . . * ^ --- |. . . . . . . . . .+-------- . * scale| | | . * | | | . * v --- |. . . . .+---------+ . * | | . . * | | . . * start_duty +---------+ . . * | . . . * | . . . * +-----------------------------------------------------------> * PWM cycle * | | | | * | 1 step | 1 step | | * |<------->|<------->| | * | m cycles m cycles | * | | * <---------------------------------------------------> * n total steps * cycles = m * n *
Note
Be aware of the maximum value available on each element
Public Members
-
uint32_t dir
Duty change direction. Set 1 as increase, 0 as decrease
-
uint32_t cycle_num
Number of PWM cycles of each step [0, 2**SOC_LEDC_FADE_PARAMS_BIT_WIDTH-1]
-
uint32_t scale
Duty change of each step [0, 2**SOC_LEDC_FADE_PARAMS_BIT_WIDTH-1]
-
uint32_t step_num
Total number of steps in one hardware fade [0, 2**SOC_LEDC_FADE_PARAMS_BIT_WIDTH-1]
-
uint32_t dir
Macros
-
LEDC_ERR_DUTY
-
LEDC_ERR_VAL
Type Definitions
-
typedef intr_handle_t ledc_isr_handle_t
-
typedef bool (*ledc_cb_t)(const ledc_cb_param_t *param, void *user_arg)
Type of LEDC event callback.
- Param param
LEDC callback parameter
- Param user_arg
User registered data
- Return
Whether a high priority task has been waken up by this function
Enumerations
Header File
This header file can be included with:
#include "hal/ledc_types.h"
Type Definitions
-
typedef soc_periph_ledc_clk_src_legacy_t ledc_clk_cfg_t
LEDC clock source configuration struct.
In theory, the following enumeration shall be placed in LEDC driver's header. However, as the next enumeration,
ledc_clk_src_t
, makes the use of some of these values and to avoid mutual inclusion of the headers, we must define it here.
Enumerations
-
enum ledc_mode_t
Values:
-
enumerator LEDC_LOW_SPEED_MODE
LEDC low speed speed_mode
-
enumerator LEDC_SPEED_MODE_MAX
LEDC speed limit
-
enumerator LEDC_LOW_SPEED_MODE
-
enum ledc_intr_type_t
Values:
-
enumerator LEDC_INTR_DISABLE
Disable LEDC interrupt
-
enumerator LEDC_INTR_FADE_END
Enable LEDC interrupt
-
enumerator LEDC_INTR_MAX
-
enumerator LEDC_INTR_DISABLE
-
enum ledc_duty_direction_t
Values:
-
enumerator LEDC_DUTY_DIR_DECREASE
LEDC duty decrease direction
-
enumerator LEDC_DUTY_DIR_INCREASE
LEDC duty increase direction
-
enumerator LEDC_DUTY_DIR_MAX
-
enumerator LEDC_DUTY_DIR_DECREASE
-
enum ledc_slow_clk_sel_t
LEDC global clock sources.
Values:
-
enumerator LEDC_SLOW_CLK_RC_FAST
LEDC low speed timer clock source is RC_FAST clock
-
enumerator LEDC_SLOW_CLK_PLL_DIV
LEDC low speed timer clock source is a PLL_DIV clock
-
enumerator LEDC_SLOW_CLK_XTAL
LEDC low speed timer clock source XTAL clock
-
enumerator LEDC_SLOW_CLK_RTC8M
Alias of 'LEDC_SLOW_CLK_RC_FAST'
-
enumerator LEDC_SLOW_CLK_RC_FAST
-
enum ledc_clk_src_t
LEDC timer-specific clock sources.
Note: Setting numeric values to match ledc_clk_cfg_t values are a hack to avoid collision with LEDC_AUTO_CLK in the driver, as these enums have very similar names and user may pass one of these by mistake.
Values:
-
enumerator LEDC_SCLK
Selecting this value for LEDC_TICK_SEL_TIMER let the hardware take its source clock from LEDC_CLK_SEL
-
enumerator LEDC_SCLK
-
enum ledc_timer_t
Values:
-
enumerator LEDC_TIMER_0
LEDC timer 0
-
enumerator LEDC_TIMER_1
LEDC timer 1
-
enumerator LEDC_TIMER_2
LEDC timer 2
-
enumerator LEDC_TIMER_3
LEDC timer 3
-
enumerator LEDC_TIMER_MAX
-
enumerator LEDC_TIMER_0
-
enum ledc_channel_t
Values:
-
enumerator LEDC_CHANNEL_0
LEDC channel 0
-
enumerator LEDC_CHANNEL_1
LEDC channel 1
-
enumerator LEDC_CHANNEL_2
LEDC channel 2
-
enumerator LEDC_CHANNEL_3
LEDC channel 3
-
enumerator LEDC_CHANNEL_4
LEDC channel 4
-
enumerator LEDC_CHANNEL_5
LEDC channel 5
-
enumerator LEDC_CHANNEL_MAX
-
enumerator LEDC_CHANNEL_0
-
enum ledc_timer_bit_t
Values:
-
enumerator LEDC_TIMER_1_BIT
LEDC PWM duty resolution of 1 bits
-
enumerator LEDC_TIMER_2_BIT
LEDC PWM duty resolution of 2 bits
-
enumerator LEDC_TIMER_3_BIT
LEDC PWM duty resolution of 3 bits
-
enumerator LEDC_TIMER_4_BIT
LEDC PWM duty resolution of 4 bits
-
enumerator LEDC_TIMER_5_BIT
LEDC PWM duty resolution of 5 bits
-
enumerator LEDC_TIMER_6_BIT
LEDC PWM duty resolution of 6 bits
-
enumerator LEDC_TIMER_7_BIT
LEDC PWM duty resolution of 7 bits
-
enumerator LEDC_TIMER_8_BIT
LEDC PWM duty resolution of 8 bits
-
enumerator LEDC_TIMER_9_BIT
LEDC PWM duty resolution of 9 bits
-
enumerator LEDC_TIMER_10_BIT
LEDC PWM duty resolution of 10 bits
-
enumerator LEDC_TIMER_11_BIT
LEDC PWM duty resolution of 11 bits
-
enumerator LEDC_TIMER_12_BIT
LEDC PWM duty resolution of 12 bits
-
enumerator LEDC_TIMER_13_BIT
LEDC PWM duty resolution of 13 bits
-
enumerator LEDC_TIMER_14_BIT
LEDC PWM duty resolution of 14 bits
-
enumerator LEDC_TIMER_15_BIT
LEDC PWM duty resolution of 15 bits
-
enumerator LEDC_TIMER_16_BIT
LEDC PWM duty resolution of 16 bits
-
enumerator LEDC_TIMER_17_BIT
LEDC PWM duty resolution of 17 bits
-
enumerator LEDC_TIMER_18_BIT
LEDC PWM duty resolution of 18 bits
-
enumerator LEDC_TIMER_19_BIT
LEDC PWM duty resolution of 19 bits
-
enumerator LEDC_TIMER_20_BIT
LEDC PWM duty resolution of 20 bits
-
enumerator LEDC_TIMER_BIT_MAX
-
enumerator LEDC_TIMER_1_BIT