mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(ledc): add ETM support for LEDC peripheral
Closes https://github.com/espressif/esp-idf/issues/11855
This commit is contained in:
@@ -5,6 +5,10 @@ set(public_include "include")
|
||||
|
||||
if(CONFIG_SOC_LEDC_SUPPORTED)
|
||||
list(APPEND srcs "src/ledc.c")
|
||||
|
||||
if(CONFIG_SOC_ETM_SUPPORTED AND CONFIG_SOC_LEDC_SUPPORT_ETM)
|
||||
list(APPEND srcs "src/ledc_etm.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "linux")
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "driver/ledc_etm.h"
|
||||
#include "hal/ledc_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -385,6 +386,25 @@ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, ledc_timer_t timer_sel);
|
||||
*/
|
||||
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_timer_t timer_sel);
|
||||
|
||||
#if SOC_LEDC_SUPPORT_ETM
|
||||
/**
|
||||
* @brief Configure the maximum timer overflow times for the LEDC channel to be used to trigger `LEDC_ETM_EVENT_CHANNEL_REACH_MAX_OVF_CNT` ETM event
|
||||
*
|
||||
* When the overflow counter maximum value is re-configured, the counter will also be reset.
|
||||
* Timer can be paused before calling this API by calling `ledc_timer_pause()`, and resumed afterwards by calling `ledc_timer_resume()`.
|
||||
*
|
||||
* @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
|
||||
* @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The timer overflow counter maximum value. To disable the timer overflow count, set this parameter to 0.
|
||||
*
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_ERR_INVALID_STATE Channel not initialized
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t ledc_channel_configure_maximum_timer_ovf_cnt(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set LEDC fade function.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_etm.h"
|
||||
#include "hal/ledc_types.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if SOC_LEDC_SUPPORT_ETM
|
||||
|
||||
/**
|
||||
* @brief LEDC timer ETM event configuration
|
||||
*/
|
||||
typedef struct {
|
||||
ledc_timer_etm_event_type_t event_type; /*!< LEDC timer ETM event type */
|
||||
} ledc_timer_etm_event_config_t;
|
||||
|
||||
/**
|
||||
* @brief LEDC channel ETM event configuration
|
||||
*/
|
||||
typedef struct {
|
||||
ledc_channel_etm_event_type_t event_type; /*!< LEDC channel ETM event type */
|
||||
} ledc_channel_etm_event_config_t;
|
||||
|
||||
/**
|
||||
* @brief Get the ETM timer event for LEDC
|
||||
*
|
||||
* @note The created ETM event object can be deleted later by calling `esp_etm_del_event`
|
||||
*
|
||||
* @param[in] speed_mode Select the LEDC channel group with specified speed mode
|
||||
* @param[in] timer_sel LEDC timer index, select from ledc_timer_t
|
||||
* @param[in] config LEDC timer ETM event configuration
|
||||
* @param[out] out_event Returned ETM event handle
|
||||
* @return
|
||||
* - ESP_OK: Get ETM event successfully
|
||||
* - ESP_ERR_INVALID_ARG: Get ETM event failed because of invalid argument
|
||||
* - ESP_ERR_NO_MEM: Get ETM event failed because of no memory
|
||||
*/
|
||||
esp_err_t ledc_timer_new_etm_event(ledc_mode_t speed_mode, ledc_timer_t timer_sel, const ledc_timer_etm_event_config_t *config, esp_etm_event_handle_t *out_event);
|
||||
|
||||
/**
|
||||
* @brief Get the ETM channel event for LEDC
|
||||
*
|
||||
* @note The created ETM event object can be deleted later by calling `esp_etm_del_event`
|
||||
*
|
||||
* @param[in] speed_mode Select the LEDC channel group with specified speed mode
|
||||
* @param[in] channel LEDC channel index, select from ledc_channel_t
|
||||
* @param[in] config LEDC channel ETM event configuration
|
||||
* @param[out] out_event Returned ETM event handle
|
||||
* @return
|
||||
* - ESP_OK: Get ETM event successfully
|
||||
* - ESP_ERR_INVALID_ARG: Get ETM event failed because of invalid argument
|
||||
* - ESP_ERR_NO_MEM: Get ETM event failed because of no memory
|
||||
*/
|
||||
esp_err_t ledc_channel_new_etm_event(ledc_mode_t speed_mode, ledc_channel_t channel, const ledc_channel_etm_event_config_t *config, esp_etm_event_handle_t *out_event);
|
||||
|
||||
/**
|
||||
* @brief LEDC timer ETM task configuration
|
||||
*/
|
||||
typedef struct {
|
||||
ledc_timer_etm_task_type_t task_type; /*!< LEDC timer ETM task type */
|
||||
} ledc_timer_etm_task_config_t;
|
||||
|
||||
/**
|
||||
* @brief LEDC channel ETM task configuration
|
||||
*/
|
||||
typedef struct {
|
||||
ledc_channel_etm_task_type_t task_type; /*!< LEDC channel ETM task type */
|
||||
} ledc_channel_etm_task_config_t;
|
||||
|
||||
/**
|
||||
* @brief Get the ETM timer task for LEDC
|
||||
*
|
||||
* @note The created ETM task object can be deleted later by calling `esp_etm_del_task`
|
||||
*
|
||||
* @param[in] speed_mode Select the LEDC channel group with specified speed mode
|
||||
* @param[in] timer_sel LEDC timer index, select from ledc_timer_t
|
||||
* @param[in] config LEDC timer ETM task configuration
|
||||
* @param[out] out_task Returned ETM task handle
|
||||
* @return
|
||||
* - ESP_OK: Get ETM task successfully
|
||||
* - ESP_ERR_INVALID_ARG: Get ETM task failed because of invalid argument
|
||||
* - ESP_ERR_NO_MEM: Get ETM task failed because of no memory
|
||||
*/
|
||||
esp_err_t ledc_timer_new_etm_task(ledc_mode_t speed_mode, ledc_timer_t timer_sel, const ledc_timer_etm_task_config_t *config, esp_etm_task_handle_t *out_task);
|
||||
|
||||
/**
|
||||
* @brief Get the ETM channel task for LEDC
|
||||
*
|
||||
* @note The created ETM task object can be deleted later by calling `esp_etm_del_task`
|
||||
*
|
||||
* @param[in] speed_mode Select the LEDC channel group with specified speed mode
|
||||
* @param[in] channel LEDC channel index, select from ledc_channel_t
|
||||
* @param[in] config LEDC channel ETM task configuration
|
||||
* @param[out] out_task Returned ETM task handle
|
||||
* @return
|
||||
* - ESP_OK: Get ETM task successfully
|
||||
* - ESP_ERR_INVALID_ARG: Get ETM task failed because of invalid argument
|
||||
* - ESP_ERR_NO_MEM: Get ETM task failed because of no memory
|
||||
*/
|
||||
esp_err_t ledc_channel_new_etm_task(ledc_mode_t speed_mode, ledc_channel_t channel, const ledc_channel_etm_task_config_t *config, esp_etm_task_handle_t *out_task);
|
||||
|
||||
#endif // SOC_LEDC_SUPPORT_ETM
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -277,6 +277,7 @@ static IRAM_ATTR esp_err_t ledc_duty_config(ledc_mode_t speed_mode, ledc_channel
|
||||
// Clear left-off LEDC gamma ram registers, random data in ram could cause output waveform error
|
||||
ledc_hal_clear_left_off_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 1);
|
||||
#endif
|
||||
ESP_EARLY_LOGD(LEDC_TAG, "duty_config: duty-%d, dir-%d, cycle-%d, scale-%d, step-%d", duty_val, duty_direction, duty_cycle, duty_scale, duty_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -392,6 +393,21 @@ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, ledc_timer_t timer_sel)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_LEDC_SUPPORT_ETM
|
||||
esp_err_t ledc_channel_configure_maximum_timer_ovf_cnt(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_ARG_CHECK(max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX, "max_ovf_cnt");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
|
||||
ledc_hal_channel_configure_maximum_timer_ovf_cnt(&(p_ledc_obj[speed_mode]->ledc_hal), channel, max_ovf_cnt);
|
||||
ledc_ls_channel_update(speed_mode, channel);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t ledc_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, ledc_isr_handle_t *handle)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_check.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "esp_private/etm_interface.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "hal/ledc_ll.h"
|
||||
|
||||
#define TAG "ledc_etm"
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
esp_etm_event_t evt_base;
|
||||
esp_etm_task_t task_base;
|
||||
};
|
||||
ledc_mode_t speed_mode;
|
||||
volatile uint32_t *en_reg_addr;
|
||||
uint32_t en_bit;
|
||||
} ledc_etm_event_task_t;
|
||||
|
||||
static portMUX_TYPE s_ledc_etm_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static esp_err_t ledc_del_etm_event(esp_etm_event_t *event)
|
||||
{
|
||||
ledc_etm_event_task_t *etm_event = __containerof(event, ledc_etm_event_task_t, evt_base);
|
||||
|
||||
if (etm_event->en_reg_addr != 0) {
|
||||
portENTER_CRITICAL(&s_ledc_etm_spinlock);
|
||||
ledc_ll_etm_enable_evt_task(LEDC_LL_GET_HW(), etm_event->speed_mode, etm_event->en_reg_addr, etm_event->en_bit, false);
|
||||
portEXIT_CRITICAL(&s_ledc_etm_spinlock);
|
||||
}
|
||||
|
||||
free(etm_event);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t ledc_del_etm_task(esp_etm_task_t *task)
|
||||
{
|
||||
ledc_etm_event_task_t *etm_task = __containerof(task, ledc_etm_event_task_t, task_base);
|
||||
|
||||
if (etm_task->en_reg_addr != 0) {
|
||||
portENTER_CRITICAL(&s_ledc_etm_spinlock);
|
||||
ledc_ll_etm_enable_evt_task(LEDC_LL_GET_HW(), etm_task->speed_mode, etm_task->en_reg_addr, etm_task->en_bit, false);
|
||||
portEXIT_CRITICAL(&s_ledc_etm_spinlock);
|
||||
}
|
||||
|
||||
free(etm_task);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_new_etm_event(ledc_mode_t speed_mode, ledc_timer_t timer_sel, const ledc_timer_etm_event_config_t *config, esp_etm_event_handle_t *out_event)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(speed_mode < LEDC_SPEED_MODE_MAX && timer_sel < LEDC_TIMER_MAX && config && config->event_type < LEDC_TIMER_ETM_EVENT_MAX && out_event, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
|
||||
ledc_etm_event_task_t *event = heap_caps_calloc(1, sizeof(ledc_etm_event_task_t), MALLOC_CAP_DEFAULT);
|
||||
ESP_RETURN_ON_FALSE(event, ESP_ERR_NO_MEM, TAG, "no memory for ETM event");
|
||||
|
||||
uint32_t evt_id = LEDC_LL_ETM_TIMER_EVENT_ID(speed_mode, timer_sel, config->event_type);
|
||||
volatile uint32_t *en_reg = LEDC_LL_ETM_TIMER_EVENT_EN_REG(speed_mode, config->event_type);
|
||||
uint32_t en_bit = LEDC_LL_ETM_TIMER_EVENT_EN_BIT(speed_mode, timer_sel, config->event_type);
|
||||
|
||||
portENTER_CRITICAL(&s_ledc_etm_spinlock);
|
||||
ledc_ll_etm_enable_evt_task(LEDC_LL_GET_HW(), speed_mode, en_reg, en_bit, true);
|
||||
portEXIT_CRITICAL(&s_ledc_etm_spinlock);
|
||||
event->speed_mode = speed_mode;
|
||||
event->en_reg_addr = en_reg;
|
||||
event->en_bit = en_bit;
|
||||
event->evt_base.event_id = evt_id;
|
||||
event->evt_base.trig_periph = ETM_TRIG_PERIPH_LEDC;
|
||||
event->evt_base.del = ledc_del_etm_event;
|
||||
|
||||
*out_event = &event->evt_base;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_channel_new_etm_event(ledc_mode_t speed_mode, ledc_channel_t channel, const ledc_channel_etm_event_config_t *config, esp_etm_event_handle_t *out_event)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(speed_mode < LEDC_SPEED_MODE_MAX && channel < LEDC_CHANNEL_MAX && config && config->event_type < LEDC_CHANNEL_ETM_EVENT_MAX && out_event, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
|
||||
ledc_etm_event_task_t *event = heap_caps_calloc(1, sizeof(ledc_etm_event_task_t), MALLOC_CAP_DEFAULT);
|
||||
ESP_RETURN_ON_FALSE(event, ESP_ERR_NO_MEM, TAG, "no memory for ETM event");
|
||||
|
||||
uint32_t evt_id = LEDC_LL_ETM_CHANNEL_EVENT_ID(speed_mode, channel, config->event_type);
|
||||
volatile uint32_t *en_reg = LEDC_LL_ETM_CHANNEL_EVENT_EN_REG(speed_mode, config->event_type);
|
||||
uint32_t en_bit = LEDC_LL_ETM_CHANNEL_EVENT_EN_BIT(speed_mode, channel, config->event_type);
|
||||
|
||||
portENTER_CRITICAL(&s_ledc_etm_spinlock);
|
||||
ledc_ll_etm_enable_evt_task(LEDC_LL_GET_HW(), speed_mode, en_reg, en_bit, true);
|
||||
portEXIT_CRITICAL(&s_ledc_etm_spinlock);
|
||||
event->speed_mode = speed_mode;
|
||||
event->en_reg_addr = en_reg;
|
||||
event->en_bit = en_bit;
|
||||
event->evt_base.event_id = evt_id;
|
||||
event->evt_base.trig_periph = ETM_TRIG_PERIPH_LEDC;
|
||||
event->evt_base.del = ledc_del_etm_event;
|
||||
|
||||
*out_event = &event->evt_base;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_new_etm_task(ledc_mode_t speed_mode, ledc_timer_t timer_sel, const ledc_timer_etm_task_config_t *config, esp_etm_task_handle_t *out_task)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(speed_mode < LEDC_SPEED_MODE_MAX && timer_sel < LEDC_TIMER_MAX && config && config->task_type < LEDC_TIMER_ETM_TASK_MAX && out_task, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
|
||||
ledc_etm_event_task_t *task = heap_caps_calloc(1, sizeof(ledc_etm_event_task_t), MALLOC_CAP_DEFAULT);
|
||||
ESP_RETURN_ON_FALSE(task, ESP_ERR_NO_MEM, TAG, "no memory for ETM task");
|
||||
|
||||
uint32_t task_id = LEDC_LL_ETM_TIMER_TASK_ID(speed_mode, timer_sel, config->task_type);
|
||||
volatile uint32_t *en_reg = LEDC_LL_ETM_TIMER_TASK_EN_REG(speed_mode, config->task_type);
|
||||
uint32_t en_bit = LEDC_LL_ETM_TIMER_TASK_EN_BIT(speed_mode, timer_sel, config->task_type);
|
||||
|
||||
portENTER_CRITICAL(&s_ledc_etm_spinlock);
|
||||
ledc_ll_etm_enable_evt_task(LEDC_LL_GET_HW(), speed_mode, en_reg, en_bit, true);
|
||||
portEXIT_CRITICAL(&s_ledc_etm_spinlock);
|
||||
task->speed_mode = speed_mode;
|
||||
task->en_reg_addr = en_reg;
|
||||
task->en_bit = en_bit;
|
||||
task->task_base.task_id = task_id;
|
||||
task->task_base.trig_periph = ETM_TRIG_PERIPH_LEDC;
|
||||
task->task_base.del = ledc_del_etm_task;
|
||||
|
||||
*out_task = &task->task_base;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_channel_new_etm_task(ledc_mode_t speed_mode, ledc_channel_t channel, const ledc_channel_etm_task_config_t *config, esp_etm_task_handle_t *out_task)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(speed_mode < LEDC_SPEED_MODE_MAX && channel < LEDC_CHANNEL_MAX && config && config->task_type < LEDC_CHANNEL_ETM_TASK_MAX && out_task, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
|
||||
ledc_etm_event_task_t *task = heap_caps_calloc(1, sizeof(ledc_etm_event_task_t), MALLOC_CAP_DEFAULT);
|
||||
ESP_RETURN_ON_FALSE(task, ESP_ERR_NO_MEM, TAG, "no memory for ETM task");
|
||||
|
||||
uint32_t task_id = LEDC_LL_ETM_CHANNEL_TASK_ID(speed_mode, channel, config->task_type);
|
||||
volatile uint32_t *en_reg = LEDC_LL_ETM_CHANNEL_TASK_EN_REG(speed_mode, config->task_type);
|
||||
uint32_t en_bit = LEDC_LL_ETM_CHANNEL_TASK_EN_BIT(speed_mode, channel, config->task_type);
|
||||
|
||||
portENTER_CRITICAL(&s_ledc_etm_spinlock);
|
||||
ledc_ll_etm_enable_evt_task(LEDC_LL_GET_HW(), speed_mode, en_reg, en_bit, true);
|
||||
portEXIT_CRITICAL(&s_ledc_etm_spinlock);
|
||||
task->speed_mode = speed_mode;
|
||||
task->en_reg_addr = en_reg;
|
||||
task->en_bit = en_bit;
|
||||
task->task_base.task_id = task_id;
|
||||
task->task_base.trig_periph = ETM_TRIG_PERIPH_LEDC;
|
||||
task->task_base.del = ledc_del_etm_task;
|
||||
|
||||
*out_task = &task->task_base;
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -6,6 +6,10 @@ if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED)
|
||||
list(APPEND srcs "test_ledc_sleep.cpp")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_ETM_SUPPORTED AND CONFIG_SOC_LEDC_SUPPORT_ETM)
|
||||
list(APPEND srcs "test_ledc_etm.cpp")
|
||||
endif()
|
||||
|
||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "test_ledc_utils.h"
|
||||
#include "esp_etm.h"
|
||||
#include "esp_attr.h"
|
||||
#include "driver/uart.h"
|
||||
|
||||
TEST_CASE("ledc etm event and task", "[ledc]")
|
||||
{
|
||||
// Generate a PWM signal with certain number of pulses
|
||||
|
||||
ledc_timer_config_t ledc_time_config = create_default_timer_config();
|
||||
TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
|
||||
|
||||
ledc_channel_config_t ledc_ch_config = initialize_channel_config();
|
||||
TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
|
||||
ledc_timer_pause(TEST_SPEED_MODE, LEDC_TIMER_0);
|
||||
TEST_ESP_OK(ledc_channel_configure_maximum_timer_ovf_cnt(TEST_SPEED_MODE, LEDC_CHANNEL_0, 500));
|
||||
|
||||
esp_etm_channel_config_t etm_config = {};
|
||||
esp_etm_channel_handle_t etm_channel_a = NULL;
|
||||
TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel_a));
|
||||
|
||||
esp_etm_event_handle_t event_handle = NULL;
|
||||
ledc_channel_etm_event_config_t event_config = {
|
||||
.event_type = LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT,
|
||||
};
|
||||
TEST_ESP_OK(ledc_channel_new_etm_event(TEST_SPEED_MODE, LEDC_CHANNEL_0, &event_config, &event_handle));
|
||||
|
||||
esp_etm_task_handle_t task_handle_a = NULL;
|
||||
ledc_timer_etm_task_config_t task_config_a = {
|
||||
.task_type = LEDC_TIMER_ETM_TASK_PAUSE,
|
||||
};
|
||||
TEST_ESP_OK(ledc_timer_new_etm_task(TEST_SPEED_MODE, LEDC_TIMER_0, &task_config_a, &task_handle_a));
|
||||
|
||||
TEST_ESP_OK(esp_etm_channel_connect(etm_channel_a, event_handle, task_handle_a));
|
||||
|
||||
TEST_ESP_OK(esp_etm_channel_enable(etm_channel_a));
|
||||
|
||||
// use UART auto baud rate detection feature to count the PWM pulse count
|
||||
uart_bitrate_detect_config_t conf = {
|
||||
.rx_io_num = PULSE_IO,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
};
|
||||
uart_bitrate_res_t res = {};
|
||||
|
||||
uart_detect_bitrate_start(UART_NUM_1, &conf);
|
||||
TEST_ESP_OK(ledc_timer_rst(TEST_SPEED_MODE, LEDC_TIMER_0));
|
||||
TEST_ESP_OK(ledc_timer_resume(TEST_SPEED_MODE, LEDC_TIMER_0));
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
uart_detect_bitrate_stop(UART_NUM_1, true, &res);
|
||||
uint32_t pulse_count = (res.edge_cnt + 1) / 2;
|
||||
TEST_ASSERT_INT32_WITHIN(1, 500, pulse_count);
|
||||
|
||||
TEST_ESP_OK(esp_etm_channel_disable(etm_channel_a));
|
||||
|
||||
TEST_ESP_OK(esp_etm_del_event(event_handle));
|
||||
TEST_ESP_OK(esp_etm_del_task(task_handle_a));
|
||||
TEST_ESP_OK(esp_etm_del_channel(etm_channel_a));
|
||||
}
|
||||
@@ -30,6 +30,7 @@ typedef enum {
|
||||
ETM_TRIG_PERIPH_I2S, /*!< ETM trigger source: I2S */
|
||||
ETM_TRIG_PERIPH_LP_CORE, /*!< ETM trigger source: Low-Power Core */
|
||||
ETM_TRIG_PERIPH_MODEM, /*!< ETM trigger source: Modem */
|
||||
ETM_TRIG_PERIPH_LEDC, /*!< ETM trigger source: LEDC */
|
||||
} etm_trigger_peripheral_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,10 +20,13 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_DUTY_NUM_CH0_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_DUTY_CYCLE_CH0_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_DUTY_SCALE_CH0_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_CH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
|
||||
@@ -587,6 +590,51 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_reset = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,10 +21,13 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_DUTY_NUM_LSCH0_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_DUTY_CYCLE_LSCH0_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_DUTY_SCALE_LSCH0_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_LSCH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_LSCH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
|
||||
@@ -589,6 +592,51 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_rst = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -23,14 +24,105 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_CH0_GAMMA_RANGE0_DUTY_NUM_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_CH0_GAMMA_RANGE0_DUTY_CYCLE_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_CH0_GAMMA_RANGE0_SCALE_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_CH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
#define LEDC_LL_GLOBAL_CLOCKS SOC_LEDC_CLKS
|
||||
|
||||
// Channel tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_ID(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = LEDC_TASK_DUTY_SCALE_UPDATE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = LEDC_TASK_SIG_OUT_DIS_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = LEDC_TASK_OVF_CNT_RST_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = LEDC_TASK_GAMMA_RESTART_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = LEDC_TASK_GAMMA_PAUSE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = LEDC_TASK_GAMMA_RESUME_CH0, \
|
||||
}}[(group)][(task)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_BIT(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = BIT(LEDC_TASK_DUTY_SCALE_UPDATE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = BIT(LEDC_TASK_SIG_OUT_DIS_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = BIT(LEDC_TASK_OVF_CNT_RST_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = BIT(LEDC_TASK_GAMMA_RESTART_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = BIT(LEDC_TASK_GAMMA_PAUSE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = BIT(LEDC_TASK_GAMMA_RESUME_CH0_EN_S), \
|
||||
}}[(group)][(task)] << (channel))
|
||||
|
||||
// Channel events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_ID(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = LEDC_EVT_DUTY_CHNG_END_CH0, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = LEDC_EVT_OVF_CNT_PLS_CH0, \
|
||||
}}[(group)][(event)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_BIT(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = BIT(LEDC_EVT_DUTY_CHNG_END_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = BIT(LEDC_EVT_OVF_CNT_PLS_CH0_EN_S), \
|
||||
}}[(group)][(event)] << (channel))
|
||||
|
||||
// Timer tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_TASK_ID(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = LEDC_TASK_TIMER0_RST, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = LEDC_TASK_TIMER0_RESUME, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = LEDC_TASK_TIMER0_PAUSE, \
|
||||
}}[(group)][(task)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_BIT(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = BIT(LEDC_TASK_TIMER0_RST_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
}}[(group)][(task)] << (timer))
|
||||
|
||||
// Timer events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_ID(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = LEDC_EVT_TIME_OVF_TIMER0, \
|
||||
}}[(group)][(event)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_BIT(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = BIT(LEDC_EVT_TIME_OVF_TIMER0_EN_S), \
|
||||
}}[(group)][(event)] << (timer))
|
||||
|
||||
/**
|
||||
* @brief Enable peripheral register clock
|
||||
*
|
||||
@@ -587,6 +679,69 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable ETM event/task
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param reg_addr Register address to control the ETM event/task
|
||||
* @param bit Bit position in the register
|
||||
* @param enable Enable or disable the ETM event/task
|
||||
*/
|
||||
static inline void ledc_ll_etm_enable_evt_task(ledc_dev_t *hw, ledc_mode_t speed_mode, volatile uint32_t *reg_addr, uint32_t bit, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
REG_SET_BIT(reg_addr, bit);
|
||||
} else {
|
||||
REG_CLR_BIT(reg_addr, bit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_reset = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "hal/assert.h"
|
||||
#include "esp_rom_sys.h" //for sync issue workaround
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -24,10 +25,13 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_CH0_GAMMA_DUTY_NUM_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_CH0_GAMMA_DUTY_CYCLE_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_CH0_GAMMA_SCALE_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_CH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
#define LEDC_LL_GLOBAL_CLOCKS SOC_LEDC_CLKS
|
||||
@@ -35,6 +39,94 @@ extern "C" {
|
||||
#define LEDC_LL_GLOBAL_CLK_NC_BY_DEFAULT 1
|
||||
#define LEDC_LL_GLOBAL_CLK_DEFAULT LEDC_SLOW_CLK_RC_FAST // The temporal global clock source to set to at least make the LEDC core clock on
|
||||
|
||||
// Channel tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_ID(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = LEDC_TASK_DUTY_SCALE_UPDATE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = LEDC_TASK_SIG_OUT_DIS_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = LEDC_TASK_OVF_CNT_RST_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = LEDC_TASK_GAMMA_RESTART_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = LEDC_TASK_GAMMA_PAUSE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = LEDC_TASK_GAMMA_RESUME_CH0, \
|
||||
}}[(group)][(task)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_BIT(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = BIT(LEDC_TASK_DUTY_SCALE_UPDATE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = BIT(LEDC_TASK_SIG_OUT_DIS_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = BIT(LEDC_TASK_OVF_CNT_RST_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = BIT(LEDC_TASK_GAMMA_RESTART_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = BIT(LEDC_TASK_GAMMA_PAUSE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = BIT(LEDC_TASK_GAMMA_RESUME_CH0_EN_S), \
|
||||
}}[(group)][(task)] << (channel))
|
||||
|
||||
// Channel events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_ID(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = LEDC_EVT_DUTY_CHNG_END_CH0, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = LEDC_EVT_OVF_CNT_PLS_CH0, \
|
||||
}}[(group)][(event)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_BIT(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = BIT(LEDC_EVT_DUTY_CHNG_END_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = BIT(LEDC_EVT_OVF_CNT_PLS_CH0_EN_S), \
|
||||
}}[(group)][(event)] << (channel))
|
||||
|
||||
// Timer tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_TASK_ID(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = LEDC_TASK_TIMER0_RST, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = LEDC_TASK_TIMER0_RESUME, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = LEDC_TASK_TIMER0_PAUSE, \
|
||||
}}[(group)][(task)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_BIT(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = BIT(LEDC_TASK_TIMER0_RST_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
}}[(group)][(task)] << (timer))
|
||||
|
||||
// Timer events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_ID(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = LEDC_EVT_TIME_OVF_TIMER0, \
|
||||
}}[(group)][(event)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_BIT(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = BIT(LEDC_EVT_TIME_OVF_TIMER0_EN_S), \
|
||||
}}[(group)][(event)] << (timer))
|
||||
|
||||
/**
|
||||
* @brief Enable peripheral register clock
|
||||
*
|
||||
@@ -709,6 +801,69 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable ETM event/task
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param reg_addr Register address to control the ETM event/task
|
||||
* @param bit Bit position in the register
|
||||
* @param enable Enable or disable the ETM event/task
|
||||
*/
|
||||
static inline void ledc_ll_etm_enable_evt_task(ledc_dev_t *hw, ledc_mode_t speed_mode, volatile uint32_t *reg_addr, uint32_t bit, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
REG_SET_BIT(reg_addr, bit);
|
||||
} else {
|
||||
REG_CLR_BIT(reg_addr, bit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_reset = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -23,14 +24,105 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_CH0_GAMMA_RANGE0_DUTY_NUM_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_CH0_GAMMA_RANGE0_DUTY_CYCLE_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_CH0_GAMMA_RANGE0_SCALE_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_CH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
#define LEDC_LL_GLOBAL_CLOCKS SOC_LEDC_CLKS
|
||||
|
||||
// Channel tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_ID(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = LEDC_TASK_DUTY_SCALE_UPDATE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = LEDC_TASK_SIG_OUT_DIS_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = LEDC_TASK_OVF_CNT_RST_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = LEDC_TASK_GAMMA_RESTART_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = LEDC_TASK_GAMMA_PAUSE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = LEDC_TASK_GAMMA_RESUME_CH0, \
|
||||
}}[(group)][(task)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_BIT(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = BIT(LEDC_TASK_DUTY_SCALE_UPDATE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = BIT(LEDC_TASK_SIG_OUT_DIS_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = BIT(LEDC_TASK_OVF_CNT_RST_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = BIT(LEDC_TASK_GAMMA_RESTART_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = BIT(LEDC_TASK_GAMMA_PAUSE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = BIT(LEDC_TASK_GAMMA_RESUME_CH0_EN_S), \
|
||||
}}[(group)][(task)] << (channel))
|
||||
|
||||
// Channel events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_ID(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = LEDC_EVT_DUTY_CHNG_END_CH0, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = LEDC_EVT_OVF_CNT_PLS_CH0, \
|
||||
}}[(group)][(event)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_BIT(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = BIT(LEDC_EVT_DUTY_CHNG_END_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = BIT(LEDC_EVT_OVF_CNT_PLS_CH0_EN_S), \
|
||||
}}[(group)][(event)] << (channel))
|
||||
|
||||
// Timer tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_TASK_ID(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = LEDC_TASK_TIMER0_RST, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = LEDC_TASK_TIMER0_RESUME, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = LEDC_TASK_TIMER0_PAUSE, \
|
||||
}}[(group)][(task)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_BIT(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = BIT(LEDC_TASK_TIMER0_RST_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
}}[(group)][(task)] << (timer))
|
||||
|
||||
// Timer events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_ID(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = LEDC_EVT_TIME_OVF_TIMER0, \
|
||||
}}[(group)][(event)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_BIT(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = BIT(LEDC_EVT_TIME_OVF_TIMER0_EN_S), \
|
||||
}}[(group)][(event)] << (timer))
|
||||
|
||||
/**
|
||||
* @brief Enable peripheral register clock
|
||||
*
|
||||
@@ -587,6 +679,71 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable ETM event/task
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param reg_addr Register address to control the ETM event/task
|
||||
* @param bit Bit position in the register
|
||||
* @param enable Enable or disable the ETM event/task
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_etm_enable_evt_task(ledc_dev_t *hw, ledc_mode_t speed_mode, volatile uint32_t *reg_addr, uint32_t bit, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
REG_SET_BIT(reg_addr, bit);
|
||||
} else {
|
||||
REG_CLR_BIT(reg_addr, bit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_reset = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "hal/assert.h"
|
||||
#include "esp_rom_sys.h" //for sync issue workaround
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -24,14 +25,105 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_CH0_GAMMA_DUTY_NUM_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_CH0_GAMMA_DUTY_CYCLE_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_CH0_GAMMA_SCALE_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_CH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
#define LEDC_LL_GLOBAL_CLOCKS SOC_LEDC_CLKS
|
||||
|
||||
// Channel tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_ID(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = LEDC_TASK_DUTY_SCALE_UPDATE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = LEDC_TASK_SIG_OUT_DIS_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = LEDC_TASK_OVF_CNT_RST_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = LEDC_TASK_GAMMA_RESTART_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = LEDC_TASK_GAMMA_PAUSE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = LEDC_TASK_GAMMA_RESUME_CH0, \
|
||||
}}[(group)][(task)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_BIT(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = BIT(LEDC_TASK_DUTY_SCALE_UPDATE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = BIT(LEDC_TASK_SIG_OUT_DIS_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = BIT(LEDC_TASK_OVF_CNT_RST_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = BIT(LEDC_TASK_GAMMA_RESTART_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = BIT(LEDC_TASK_GAMMA_PAUSE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = BIT(LEDC_TASK_GAMMA_RESUME_CH0_EN_S), \
|
||||
}}[(group)][(task)] << (channel))
|
||||
|
||||
// Channel events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_ID(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = LEDC_EVT_DUTY_CHNG_END_CH0, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = LEDC_EVT_OVF_CNT_PLS_CH0, \
|
||||
}}[(group)][(event)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_BIT(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = BIT(LEDC_EVT_DUTY_CHNG_END_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = BIT(LEDC_EVT_OVF_CNT_PLS_CH0_EN_S), \
|
||||
}}[(group)][(event)] << (channel))
|
||||
|
||||
// Timer tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_TASK_ID(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = LEDC_TASK_TIMER0_RST, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = LEDC_TASK_TIMER0_RESUME, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = LEDC_TASK_TIMER0_PAUSE, \
|
||||
}}[(group)][(task)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_BIT(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = BIT(LEDC_TASK_TIMER0_RST_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
}}[(group)][(task)] << (timer))
|
||||
|
||||
// Timer events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_ID(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = LEDC_EVT_TIME_OVF_TIMER0, \
|
||||
}}[(group)][(event)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_BIT(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = BIT(LEDC_EVT_TIME_OVF_TIMER0_EN_S), \
|
||||
}}[(group)][(event)] << (timer))
|
||||
|
||||
/**
|
||||
* @brief Enable peripheral register clock
|
||||
*
|
||||
@@ -706,6 +798,69 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable ETM event/task
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param reg_addr Register address to control the ETM event/task
|
||||
* @param bit Bit position in the register
|
||||
* @param enable Enable or disable the ETM event/task
|
||||
*/
|
||||
static inline void ledc_ll_etm_enable_evt_task(ledc_dev_t *hw, ledc_mode_t speed_mode, volatile uint32_t *reg_addr, uint32_t bit, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
REG_SET_BIT(reg_addr, bit);
|
||||
} else {
|
||||
REG_CLR_BIT(reg_addr, bit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_reset = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "hal/assert.h"
|
||||
#include "esp_rom_sys.h" //for sync issue workaround
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -24,14 +25,105 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_CH0_GAMMA_DUTY_NUM_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_CH0_GAMMA_DUTY_CYCLE_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_CH0_GAMMA_SCALE_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_CH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
#define LEDC_LL_GLOBAL_CLOCKS SOC_LEDC_CLKS
|
||||
|
||||
// Channel tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_ID(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = LEDC_TASK_DUTY_SCALE_UPDATE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = LEDC_TASK_SIG_OUT_DIS_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = LEDC_TASK_OVF_CNT_RST_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = LEDC_TASK_GAMMA_RESTART_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = LEDC_TASK_GAMMA_PAUSE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = LEDC_TASK_GAMMA_RESUME_CH0, \
|
||||
}}[(group)][(task)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_BIT(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = BIT(LEDC_TASK_DUTY_SCALE_UPDATE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = BIT(LEDC_TASK_SIG_OUT_DIS_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = BIT(LEDC_TASK_OVF_CNT_RST_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = BIT(LEDC_TASK_GAMMA_RESTART_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = BIT(LEDC_TASK_GAMMA_PAUSE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = BIT(LEDC_TASK_GAMMA_RESUME_CH0_EN_S), \
|
||||
}}[(group)][(task)] << (channel))
|
||||
|
||||
// Channel events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_ID(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = LEDC_EVT_DUTY_CHNG_END_CH0, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = LEDC_EVT_OVF_CNT_PLS_CH0, \
|
||||
}}[(group)][(event)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_BIT(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = BIT(LEDC_EVT_DUTY_CHNG_END_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = BIT(LEDC_EVT_OVF_CNT_PLS_CH0_EN_S), \
|
||||
}}[(group)][(event)] << (channel))
|
||||
|
||||
// Timer tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_TASK_ID(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = LEDC_TASK_TIMER0_RST, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = LEDC_TASK_TIMER0_RESUME, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = LEDC_TASK_TIMER0_PAUSE, \
|
||||
}}[(group)][(task)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_BIT(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = BIT(LEDC_TASK_TIMER0_RST_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
}}[(group)][(task)] << (timer))
|
||||
|
||||
// Timer events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_ID(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = LEDC_EVT_TIME_OVF_TIMER0, \
|
||||
}}[(group)][(event)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_BIT(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = BIT(LEDC_EVT_TIME_OVF_TIMER0_EN_S), \
|
||||
}}[(group)][(event)] << (timer))
|
||||
|
||||
/**
|
||||
* @brief Enable peripheral register clock
|
||||
*
|
||||
@@ -705,6 +797,71 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable ETM event/task
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param reg_addr Register address to control the ETM event/task
|
||||
* @param bit Bit position in the register
|
||||
* @param enable Enable or disable the ETM event/task
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_etm_enable_evt_task(ledc_dev_t *hw, ledc_mode_t speed_mode, volatile uint32_t *reg_addr, uint32_t bit, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
REG_SET_BIT(reg_addr, bit);
|
||||
} else {
|
||||
REG_CLR_BIT(reg_addr, bit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_reset = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -23,14 +24,105 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_CH0_FADE_PARAM_DUTY_NUM_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_CH0_FADE_PARAM_DUTY_CYCLE_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_CH0_FADE_PARAM_SCALE_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_CH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
#define LEDC_LL_GLOBAL_CLOCKS SOC_LEDC_CLKS
|
||||
|
||||
// Channel tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_ID(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = LEDC_TASK_DUTY_SCALE_UPDATE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = LEDC_TASK_SIG_OUT_DIS_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = LEDC_TASK_OVF_CNT_RST_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = LEDC_TASK_FADE_RESTART_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = LEDC_TASK_FADE_PAUSE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = LEDC_TASK_FADE_RESUME_CH0, \
|
||||
}}[(group)][(task)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_BIT(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = BIT(LEDC_TASK_DUTY_SCALE_UPDATE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = BIT(LEDC_TASK_SIG_OUT_DIS_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = BIT(LEDC_TASK_OVF_CNT_RST_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = BIT(LEDC_TASK_FADE_RESTART_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = BIT(LEDC_TASK_FADE_PAUSE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = BIT(LEDC_TASK_FADE_RESUME_CH0_EN_S), \
|
||||
}}[(group)][(task)] << (channel))
|
||||
|
||||
// Channel events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_ID(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = LEDC_EVT_DUTY_CHNG_END_CH0, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = LEDC_EVT_OVF_CNT_PLS_CH0, \
|
||||
}}[(group)][(event)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_BIT(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = BIT(LEDC_EVT_DUTY_CHNG_END_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = BIT(LEDC_EVT_OVF_CNT_PLS_CH0_EN_S), \
|
||||
}}[(group)][(event)] << (channel))
|
||||
|
||||
// Timer tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_TASK_ID(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = LEDC_TASK_TIMER0_RST, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = LEDC_TASK_TIMER0_RESUME, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = LEDC_TASK_TIMER0_PAUSE, \
|
||||
}}[(group)][(task)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_BIT(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = BIT(LEDC_TASK_TIMER0_RST_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
}}[(group)][(task)] << (timer))
|
||||
|
||||
// Timer events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_ID(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = LEDC_EVT_TIME_OVF_TIMER0, \
|
||||
}}[(group)][(event)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_BIT(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = BIT(LEDC_EVT_TIME_OVF_TIMER0_EN_S), \
|
||||
}}[(group)][(event)] << (timer))
|
||||
|
||||
/**
|
||||
* @brief Enable peripheral register clock
|
||||
*
|
||||
@@ -534,6 +626,71 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable ETM event/task
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param reg_addr Register address to control the ETM event/task
|
||||
* @param bit Bit position in the register
|
||||
* @param enable Enable or disable the ETM event/task
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_etm_enable_evt_task(ledc_dev_t *hw, ledc_mode_t speed_mode, volatile uint32_t *reg_addr, uint32_t bit, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
REG_SET_BIT(reg_addr, bit);
|
||||
} else {
|
||||
REG_CLR_BIT(reg_addr, bit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-5), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_reset = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -23,14 +24,105 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_CH0_GAMMA_RANGE0_DUTY_NUM_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_CH0_GAMMA_RANGE0_DUTY_CYCLE_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_CH0_GAMMA_RANGE0_SCALE_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_CH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
#define LEDC_LL_GLOBAL_CLOCKS SOC_LEDC_CLKS
|
||||
|
||||
// Channel tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_ID(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = LEDC_TASK_DUTY_SCALE_UPDATE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = LEDC_TASK_SIG_OUT_DIS_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = LEDC_TASK_OVF_CNT_RST_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = LEDC_TASK_GAMMA_RESTART_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = LEDC_TASK_GAMMA_PAUSE_CH0, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = LEDC_TASK_GAMMA_RESUME_CH0, \
|
||||
}}[(group)][(task)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN2_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_TASK_EN_BIT(group, channel, task) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_TASK_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE] = BIT(LEDC_TASK_DUTY_SCALE_UPDATE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS] = BIT(LEDC_TASK_SIG_OUT_DIS_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST] = BIT(LEDC_TASK_OVF_CNT_RST_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESTART] = BIT(LEDC_TASK_GAMMA_RESTART_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_PAUSE] = BIT(LEDC_TASK_GAMMA_PAUSE_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_TASK_FADE_RESUME] = BIT(LEDC_TASK_GAMMA_RESUME_CH0_EN_S), \
|
||||
}}[(group)][(task)] << (channel))
|
||||
|
||||
// Channel events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_ID(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = LEDC_EVT_DUTY_CHNG_END_CH0, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = LEDC_EVT_OVF_CNT_PLS_CH0, \
|
||||
}}[(group)][(event)] + (channel))
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_CHANNEL_EVENT_EN_BIT(group, channel, event) \
|
||||
((uint32_t [1][LEDC_CHANNEL_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_CHANNEL_ETM_EVENT_FADE_END] = BIT(LEDC_EVT_DUTY_CHNG_END_CH0_EN_S), \
|
||||
[LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT] = BIT(LEDC_EVT_OVF_CNT_PLS_CH0_EN_S), \
|
||||
}}[(group)][(event)] << (channel))
|
||||
|
||||
// Timer tasks: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_TASK_ID(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = LEDC_TASK_TIMER0_RST, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = LEDC_TASK_TIMER0_RESUME, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = LEDC_TASK_TIMER0_PAUSE, \
|
||||
}}[(group)][(task)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_REG(group, task) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = (volatile uint32_t *)LEDC_EVT_TASK_EN1_REG, \
|
||||
}}[(group)][(task)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_TASK_EN_BIT(group, timer, task) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_TASK_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_TASK_RST] = BIT(LEDC_TASK_TIMER0_RST_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_RESUME] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
[LEDC_TIMER_ETM_TASK_PAUSE] = BIT(LEDC_TASK_TIMER0_PAUSE_RESUME_EN_S), \
|
||||
}}[(group)][(task)] << (timer))
|
||||
|
||||
// Timer events: ID, enable register and bit
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_ID(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = LEDC_EVT_TIME_OVF_TIMER0, \
|
||||
}}[(group)][(event)] + (timer))
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_REG(group, event) \
|
||||
((volatile uint32_t *[1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = (volatile uint32_t *)LEDC_EVT_TASK_EN0_REG, \
|
||||
}}[(group)][(event)])
|
||||
|
||||
#define LEDC_LL_ETM_TIMER_EVENT_EN_BIT(group, timer, event) \
|
||||
((uint32_t [1][LEDC_TIMER_ETM_EVENT_MAX]){{ \
|
||||
[LEDC_TIMER_ETM_EVENT_OVF] = BIT(LEDC_EVT_TIME_OVF_TIMER0_EN_S), \
|
||||
}}[(group)][(event)] << (timer))
|
||||
|
||||
/**
|
||||
* @brief Enable peripheral register clock
|
||||
*
|
||||
@@ -336,7 +428,7 @@ static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode,
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
@@ -350,7 +442,7 @@ static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param hpoint_val LEDC hpoint value(max: 0xfffff)
|
||||
*
|
||||
* @return None
|
||||
@@ -365,7 +457,7 @@ static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, le
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param hpoint_val Pointer to accept the LEDC hpoint value(max: 0xfffff)
|
||||
*
|
||||
* @return None
|
||||
@@ -380,7 +472,7 @@ static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, le
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_val LEDC duty value, the range of duty setting is [0, (2**duty_resolution)]
|
||||
*
|
||||
* @return None
|
||||
@@ -395,7 +487,7 @@ static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_val Pointer to accept the LEDC duty value
|
||||
*
|
||||
* @return None
|
||||
@@ -410,7 +502,7 @@ static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param range Gamma fade range index, 0 ~ SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX
|
||||
* @param dir LEDC duty change direction, increase or decrease
|
||||
* @param cycle The duty cycles
|
||||
@@ -436,7 +528,7 @@ static inline void ledc_ll_set_fade_param_range(ledc_dev_t *hw, ledc_mode_t spee
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param range_num Total number of ranges (1 - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX) of the fading configured
|
||||
*
|
||||
* @return None
|
||||
@@ -451,7 +543,7 @@ static inline void ledc_ll_set_range_number(ledc_dev_t *hw, ledc_mode_t speed_mo
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param range_num Pointer to accept fade range number
|
||||
*
|
||||
* @return None
|
||||
@@ -466,7 +558,7 @@ static inline void ledc_ll_get_range_number(ledc_dev_t *hw, ledc_mode_t speed_mo
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param range Gamma fade range index to get, 0 ~ SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX
|
||||
* @param dir Pointer to accept fade direction value
|
||||
* @param cycle Pointer to accept fade cycle value
|
||||
@@ -492,7 +584,7 @@ static inline void ledc_ll_get_fade_param_range(ledc_dev_t *hw, ledc_mode_t spee
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param sig_out_en The output enable status
|
||||
*
|
||||
* @return None
|
||||
@@ -508,7 +600,7 @@ static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
@@ -522,7 +614,7 @@ static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param idle_level The output idle level
|
||||
*
|
||||
* @return None
|
||||
@@ -538,7 +630,7 @@ static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param fade_end_intr_en The fade end interrupt enable status
|
||||
*
|
||||
* @return None
|
||||
@@ -555,7 +647,7 @@ static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param intr_status The fade end interrupt status
|
||||
*
|
||||
* @return None
|
||||
@@ -572,7 +664,7 @@ static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
@@ -587,7 +679,7 @@ static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
@@ -602,7 +694,7 @@ static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_sel Pointer to accept the LEDC timer index
|
||||
*
|
||||
* @return None
|
||||
@@ -612,6 +704,69 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable ETM event/task
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param reg_addr Register address to control the ETM event/task
|
||||
* @param bit Bit position in the register
|
||||
* @param enable Enable or disable the ETM event/task
|
||||
*/
|
||||
static inline void ledc_ll_etm_enable_evt_task(ledc_dev_t *hw, ledc_mode_t speed_mode, volatile uint32_t *reg_addr, uint32_t bit, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
REG_SET_BIT(reg_addr, bit);
|
||||
} else {
|
||||
REG_CLR_BIT(reg_addr, bit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_reset = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,10 +21,13 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_DUTY_NUM_LSCH0_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_DUTY_CYCLE_LSCH0_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_DUTY_SCALE_LSCH0_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_LSCH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_LSCH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
|
||||
@@ -628,6 +631,51 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_rst = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,10 +21,13 @@ extern "C" {
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_CHANNEL_SUPPORT_OVF_CNT 1
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_DUTY_NUM_LSCH0_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_DUTY_CYCLE_LSCH0_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_DUTY_SCALE_LSCH0_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_LSCH0_V)
|
||||
#define LEDC_LL_OVF_CNT_MAX (LEDC_OVF_NUM_LSCH0_V + 1)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
|
||||
@@ -589,6 +592,51 @@ static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_m
|
||||
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param enable True to enable; false to disable
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_enable_timer_ovt_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, bool enable)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the maximum timer overflow count for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow count
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_set_maximum_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
HAL_ASSERT(max_ovf_cnt > 0 && max_ovf_cnt <= LEDC_LL_OVF_CNT_MAX);
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_num = max_ovf_cnt - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the timer overflow counter for the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, low-speed mode only
|
||||
* @param channel LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_channel_reset_timer_ovf_cnt(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel].conf0.ovf_cnt_rst = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -248,6 +248,19 @@ typedef struct {
|
||||
*/
|
||||
void ledc_hal_init(ledc_hal_context_t *hal, ledc_mode_t speed_mode);
|
||||
|
||||
#if LEDC_LL_CHANNEL_SUPPORT_OVF_CNT
|
||||
/**
|
||||
* @brief Configure the maximum timer overflow times for the LEDC channel
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel LEDC channel index, select from ledc_channel_t
|
||||
* @param max_ovf_cnt The maximum timer overflow times. To disable the timer overflow count, set this parameter to 0.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_channel_configure_maximum_timer_ovf_cnt(ledc_hal_context_t *hal, ledc_channel_t channel, uint32_t max_ovf_cnt);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Update channel configure when select low speed mode
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -139,6 +139,56 @@ typedef enum {
|
||||
LEDC_FADE_MAX,
|
||||
} ledc_fade_mode_t;
|
||||
|
||||
#if SOC_LEDC_SUPPORT_ETM
|
||||
/**
|
||||
* @brief LEDC channel related specific tasks that supported by the ETM module
|
||||
*/
|
||||
typedef enum {
|
||||
LEDC_CHANNEL_ETM_TASK_FADE_SCALE_UPDATE, /*!< Update newly configured scale for the fade on the channel */
|
||||
LEDC_CHANNEL_ETM_TASK_SIG_OUT_DIS, /*!< Disable signal output on the channel */
|
||||
LEDC_CHANNEL_ETM_TASK_OVF_CNT_RST, /*!< Reset channel's timer overflow counter */
|
||||
LEDC_CHANNEL_ETM_TASK_FADE_RESTART, /* Restart the last fade on the channel, the replay will start from last configured duty
|
||||
(note that, for a single fade, the duty may be configured to a new value in ISR,
|
||||
so it may not be the initial value you configured before fade) */
|
||||
LEDC_CHANNEL_ETM_TASK_FADE_PAUSE, /*!< Pause fading on the channel */
|
||||
LEDC_CHANNEL_ETM_TASK_FADE_RESUME, /*!< Resume fading on the channel */
|
||||
LEDC_CHANNEL_ETM_TASK_MAX,
|
||||
} ledc_channel_etm_task_type_t;
|
||||
|
||||
/**
|
||||
* @brief LEDC timer related specific tasks that supported by the ETM module
|
||||
*/
|
||||
typedef enum {
|
||||
LEDC_TIMER_ETM_TASK_RST, /*!< Reset the timer
|
||||
When timer is reset, a timer overflow equivalent signal is sent to the channel, so any newly configured parameter is able to get updated
|
||||
This is not the case on C6/H2/P4/C5/H4/H21, on such targets, no timer overflow equivalent signal is sent to the channel, i.e. newly configured parameter is not able to get updated when this ETM task is triggered */
|
||||
LEDC_TIMER_ETM_TASK_RESUME, /*!< Resume the timer
|
||||
Note that the ETM timer pause/resume task must be used in pair
|
||||
Pause by ETM task and resume by calling `ledc_timer_resume` is not allowed, vice versa */
|
||||
LEDC_TIMER_ETM_TASK_PAUSE, /*!< Pause the timer */
|
||||
LEDC_TIMER_ETM_TASK_MAX,
|
||||
} ledc_timer_etm_task_type_t;
|
||||
|
||||
/**
|
||||
* @brief LEDC channel related specific events that supported by the ETM module
|
||||
*/
|
||||
typedef enum {
|
||||
LEDC_CHANNEL_ETM_EVENT_FADE_END, /*!< Channel fading ended */
|
||||
LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT, /*!< Channel has reached the maximum timer overflow count
|
||||
The maximum overflow count value can be set with `ledc_channel_configure_maximum_timer_ovf_cnt` */
|
||||
LEDC_CHANNEL_ETM_EVENT_MAX,
|
||||
} ledc_channel_etm_event_type_t;
|
||||
|
||||
/**
|
||||
* @brief LEDC timer related specific events that supported by the ETM module
|
||||
*/
|
||||
typedef enum {
|
||||
LEDC_TIMER_ETM_EVENT_OVF, /*!< Timer overflow happened */
|
||||
LEDC_TIMER_ETM_EVENT_MAX,
|
||||
} ledc_timer_etm_event_type_t;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -63,3 +63,16 @@ void ledc_hal_get_fade_param(ledc_hal_context_t *hal, ledc_channel_t channel_num
|
||||
ledc_ll_get_fade_param_range(hal->dev, hal->speed_mode, channel_num, range, dir, cycle, scale, step);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LEDC_LL_CHANNEL_SUPPORT_OVF_CNT
|
||||
void ledc_hal_channel_configure_maximum_timer_ovf_cnt(ledc_hal_context_t *hal, ledc_channel_t channel, uint32_t max_ovf_cnt)
|
||||
{
|
||||
if (max_ovf_cnt == 0) {
|
||||
ledc_ll_channel_enable_timer_ovt_cnt(hal->dev, hal->speed_mode, channel, false);
|
||||
} else {
|
||||
ledc_ll_channel_enable_timer_ovt_cnt(hal->dev, hal->speed_mode, channel, true);
|
||||
ledc_ll_channel_set_maximum_timer_ovf_cnt(hal->dev, hal->speed_mode, channel, max_ovf_cnt);
|
||||
ledc_ll_channel_reset_timer_ovf_cnt(hal->dev, hal->speed_mode, channel);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -783,6 +783,10 @@ config SOC_LEDC_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LEDC_SUPPORT_ETM
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MMU_PERIPH_NUM
|
||||
int
|
||||
default 1
|
||||
|
||||
@@ -315,6 +315,7 @@
|
||||
#define SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX (16)
|
||||
#define SOC_LEDC_FADE_PARAMS_BIT_WIDTH (10)
|
||||
#define SOC_LEDC_SUPPORT_SLEEP_RETENTION (1)
|
||||
#define SOC_LEDC_SUPPORT_ETM (1)
|
||||
|
||||
/*-------------------------- MMU CAPS ----------------------------------------*/
|
||||
#define SOC_MMU_PERIPH_NUM (1U)
|
||||
|
||||
@@ -707,6 +707,10 @@ config SOC_LEDC_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LEDC_SUPPORT_ETM
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MMU_PAGE_SIZE_CONFIGURABLE
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -291,6 +291,7 @@
|
||||
#define SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX (16)
|
||||
#define SOC_LEDC_FADE_PARAMS_BIT_WIDTH (10)
|
||||
#define SOC_LEDC_SUPPORT_SLEEP_RETENTION (1)
|
||||
#define SOC_LEDC_SUPPORT_ETM (1)
|
||||
|
||||
/*-------------------------- MMU CAPS ----------------------------------------*/
|
||||
#define SOC_MMU_PAGE_SIZE_CONFIGURABLE (1)
|
||||
|
||||
@@ -643,6 +643,10 @@ config SOC_LEDC_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LEDC_SUPPORT_ETM
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MMU_PAGE_SIZE_CONFIGURABLE
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -262,6 +262,7 @@
|
||||
#define SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX (16)
|
||||
#define SOC_LEDC_FADE_PARAMS_BIT_WIDTH (10)
|
||||
#define SOC_LEDC_SUPPORT_SLEEP_RETENTION (1)
|
||||
#define SOC_LEDC_SUPPORT_ETM (1)
|
||||
|
||||
/*-------------------------- MMU CAPS ----------------------------------------*/
|
||||
#define SOC_MMU_PAGE_SIZE_CONFIGURABLE (1)
|
||||
|
||||
@@ -715,6 +715,10 @@ config SOC_LEDC_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LEDC_SUPPORT_ETM
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MPU_CONFIGURABLE_REGIONS_SUPPORTED
|
||||
bool
|
||||
default n
|
||||
|
||||
@@ -310,6 +310,7 @@
|
||||
#define SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX (16)
|
||||
#define SOC_LEDC_FADE_PARAMS_BIT_WIDTH (10)
|
||||
#define SOC_LEDC_SUPPORT_SLEEP_RETENTION (1)
|
||||
#define SOC_LEDC_SUPPORT_ETM (1)
|
||||
|
||||
/*-------------------------- MPU CAPS ----------------------------------------*/
|
||||
#define SOC_MPU_CONFIGURABLE_REGIONS_SUPPORTED 0
|
||||
|
||||
@@ -511,6 +511,10 @@ config SOC_LEDC_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LEDC_SUPPORT_ETM
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -287,6 +287,7 @@
|
||||
#define SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX (16)
|
||||
#define SOC_LEDC_FADE_PARAMS_BIT_WIDTH (10)
|
||||
#define SOC_LEDC_SUPPORT_SLEEP_RETENTION (1)
|
||||
#define SOC_LEDC_SUPPORT_ETM (1)
|
||||
|
||||
/*-------------------------- MPU CAPS ----------------------------------------*/
|
||||
// #define SOC_MPU_CONFIGURABLE_REGIONS_SUPPORTED 0
|
||||
|
||||
@@ -491,6 +491,10 @@ config SOC_LEDC_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LEDC_SUPPORT_ETM
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MMU_PAGE_SIZE_CONFIGURABLE
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -288,6 +288,7 @@
|
||||
#define SOC_LEDC_SUPPORT_FADE_STOP (1)
|
||||
#define SOC_LEDC_FADE_PARAMS_BIT_WIDTH (10)
|
||||
#define SOC_LEDC_SUPPORT_SLEEP_RETENTION (1)
|
||||
#define SOC_LEDC_SUPPORT_ETM (1)
|
||||
|
||||
/*-------------------------- MMU CAPS ----------------------------------------*/
|
||||
#define SOC_MMU_PAGE_SIZE_CONFIGURABLE (1)
|
||||
|
||||
@@ -1091,6 +1091,10 @@ config SOC_LEDC_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LEDC_SUPPORT_ETM
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MMU_PERIPH_NUM
|
||||
int
|
||||
default 2
|
||||
|
||||
@@ -399,6 +399,7 @@
|
||||
#define SOC_LEDC_SUPPORT_FADE_STOP (1)
|
||||
#define SOC_LEDC_FADE_PARAMS_BIT_WIDTH (10)
|
||||
#define SOC_LEDC_SUPPORT_SLEEP_RETENTION (1)
|
||||
#define SOC_LEDC_SUPPORT_ETM (1)
|
||||
|
||||
/*-------------------------- MMU CAPS ----------------------------------------*/
|
||||
#define SOC_MMU_PERIPH_NUM (2U)
|
||||
|
||||
@@ -107,6 +107,7 @@ INPUT = \
|
||||
$(PROJECT_PATH)/components/esp_driver_gptimer/include/driver/gptimer_etm.h \
|
||||
$(PROJECT_PATH)/components/esp_driver_gptimer/include/driver/gptimer_types.h \
|
||||
$(PROJECT_PATH)/components/esp_driver_ledc/include/driver/ledc.h \
|
||||
$(PROJECT_PATH)/components/esp_driver_ledc/include/driver/ledc_etm.h \
|
||||
$(PROJECT_PATH)/components/esp_driver_mcpwm/include/driver/mcpwm_cap.h \
|
||||
$(PROJECT_PATH)/components/esp_driver_mcpwm/include/driver/mcpwm_cmpr.h \
|
||||
$(PROJECT_PATH)/components/esp_driver_mcpwm/include/driver/mcpwm_etm.h \
|
||||
|
||||
@@ -74,6 +74,7 @@ Other Peripheral Events
|
||||
:SOC_ANA_CMPR_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/ana_cmpr` for how to get the ETM event handle from analog comparator.
|
||||
:SOC_TEMPERATURE_SENSOR_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/temp_sensor` for how to get the ETM event handle from temperature sensor.
|
||||
:SOC_I2S_SUPPORTS_ETM: - Refer to :doc:`/api-reference/peripherals/i2s` for how to get the ETM event handle from I2S.
|
||||
:SOC_LEDC_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/ledc` for how to get the ETM event handle from LEDC.
|
||||
|
||||
.. _etm-task:
|
||||
|
||||
@@ -101,6 +102,7 @@ Other Peripheral Tasks
|
||||
:SOC_TIMER_SUPPORT_ETM: - Refer to :ref:`gptimer-etm-event-and-task` for how to get the ETM task handle from GPTimer.
|
||||
:SOC_TEMPERATURE_SENSOR_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/temp_sensor` for how to get the ETM task handle from temperature sensor.
|
||||
:SOC_I2S_SUPPORTS_ETM: - Refer to :doc:`/api-reference/peripherals/i2s` for how to get the ETM task handle from I2S.
|
||||
:SOC_LEDC_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/ledc` for how to get the ETM task handle from LEDC.
|
||||
|
||||
.. _etm-channel-control:
|
||||
|
||||
|
||||
@@ -354,6 +354,21 @@ There are several individual timer-specific functions that can be used to change
|
||||
|
||||
The first function is called "behind the scenes" by :cpp:func:`ledc_timer_config` to provide a startup of a timer after it is configured.
|
||||
|
||||
.. only:: SOC_LEDC_SUPPORT_ETM and SOC_ETM_SUPPORTED
|
||||
|
||||
LEDC's ETM Events and Tasks
|
||||
---------------------------
|
||||
|
||||
LEDC can generate various events that can be connected to the :doc:`ETM </api-reference/peripherals/etm>` module. Timer's supported events are listed in :cpp:type:`ledc_timer_etm_event_type_t`, and channel's supported events are listed in :cpp:type:`ledc_channel_etm_event_type_t`. Users can create an ``ETM event`` handle by calling :cpp:func:`ledc_timer_new_etm_event` or :cpp:func:`ledc_channel_new_etm_event` respectively.
|
||||
LEDC also supports some tasks that can be triggered by other events and executed automatically. Timer's supported tasks are listed in :cpp:type:`ledc_timer_etm_task_type_t`, and channel's supported tasks are listed in :cpp:type:`ledc_channel_etm_task_type_t`. Users can create an ``ETM task`` handle by calling :cpp:func:`ledc_timer_new_etm_task` or :cpp:func:`ledc_channel_new_etm_task` respectively.
|
||||
|
||||
Some useful applications of ETM with LEDC are:
|
||||
|
||||
* To generate a PWM signal with certain number of pulses
|
||||
* To synchronize the PWM period with an external signal
|
||||
* To start / stop the PWM signal output or a fading without CPU intervention
|
||||
|
||||
For how to connect the LEDC events and tasks to the ETM channel, please refer to the :doc:`ETM </api-reference/peripherals/etm>` documentation.
|
||||
|
||||
Power Management
|
||||
----------------
|
||||
@@ -418,6 +433,7 @@ Application Example
|
||||
* :example:`peripherals/ledc/ledc_basic` demonstrates how to use the LEDC to generate a PWM signal in LOW SPEED mode.
|
||||
* :example:`peripherals/ledc/ledc_fade` demonstrates how to control the intensity of LEDs using the LEDC fade functionality.
|
||||
:SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED: * :example:`peripherals/ledc/ledc_gamma_curve_fade` demonstrates how to use the LEDC for color control of RGB LEDs with gamma correction.
|
||||
:SOC_LEDC_SUPPORT_ETM and SOC_ETM_SUPPORTED: * :example:`peripherals/ledc/ledc_dimmer` demonstrates how to use the LEDC and ETM to generate TRIAC gate trigger pulses that are synchronized to the mains zero‑cross.
|
||||
|
||||
|
||||
API Reference
|
||||
@@ -425,3 +441,7 @@ API Reference
|
||||
|
||||
.. include-build-file:: inc/ledc.inc
|
||||
.. include-build-file:: inc/ledc_types.inc
|
||||
|
||||
.. only:: SOC_LEDC_SUPPORT_ETM and SOC_ETM_SUPPORTED
|
||||
|
||||
.. include-build-file:: inc/ledc_etm.inc
|
||||
|
||||
@@ -74,6 +74,7 @@ GPIO **边沿** 事件是最常见的事件类型,任何 GPIO 管脚均可触
|
||||
:SOC_ANA_CMPR_SUPPORT_ETM: - 要了解如何从模拟比较器获取 ETM 事件句柄,请参阅 :doc:`/api-reference/peripherals/ana_cmpr`。
|
||||
:SOC_TEMPERATURE_SENSOR_SUPPORT_ETM: - 要了解如何从温度传感器获取 ETM 事件句柄,请参阅 :doc:`/api-reference/peripherals/temp_sensor`。
|
||||
:SOC_I2S_SUPPORTS_ETM: - 要了解如何从 I2S 获取 ETM 事件句柄,请参阅 :doc:`/api-reference/peripherals/i2s`。
|
||||
:SOC_LEDC_SUPPORT_ETM: - 要了解如何从 LEDC 获取 ETM 事件句柄,请参阅 :doc:`/api-reference/peripherals/ledc`。
|
||||
|
||||
.. _etm-task:
|
||||
|
||||
@@ -101,6 +102,7 @@ GPIO 任务是最常见的任务类型。一个 GPIO 可以采取一个或多个
|
||||
:SOC_TIMER_SUPPORT_ETM: - 要了解如何从 GPTimer 获取 ETM 任务句柄,请参阅 :ref:`gptimer-etm-event-and-task`。
|
||||
:SOC_TEMPERATURE_SENSOR_SUPPORT_ETM: - 要了解如何从温度传感器获取 ETM 任务句柄,请参阅 :doc:`/api-reference/peripherals/temp_sensor`。
|
||||
:SOC_I2S_SUPPORTS_ETM: - 要了解如何从 I2S 获取 ETM 任务句柄,请参阅 :doc:`/api-reference/peripherals/i2s`。
|
||||
:SOC_LEDC_SUPPORT_ETM: - 要了解如何从 LEDC 获取 ETM 任务句柄,请参阅 :doc:`/api-reference/peripherals/ledc`。
|
||||
|
||||
.. _etm-channel-control:
|
||||
|
||||
|
||||
@@ -354,6 +354,21 @@ LED PWM 控制器 API 有多种方式即时改变 PWM 频率:
|
||||
|
||||
第一个定时器复位函数在函数 :cpp:func:`ledc_timer_config` 内部完成所有定时器配置后会被调用一次。
|
||||
|
||||
.. only:: SOC_LEDC_SUPPORT_ETM and SOC_ETM_SUPPORTED
|
||||
|
||||
LEDC 的 ETM 事件和任务
|
||||
----------------------
|
||||
|
||||
LEDC 可以生成多种事件,这些事件可以连接到 :doc:`ETM </api-reference/peripherals/etm>` 模块。定时器支持的事件列在 :cpp:type:`ledc_timer_etm_event_type_t` 中,通道支持的事件列在 :cpp:type:`ledc_channel_etm_event_type_t` 中。用户可以分别通过调用 :cpp:func:`ledc_timer_new_etm_event` 或 :cpp:func:`ledc_channel_new_etm_event` 来创建 ``ETM event`` 句柄。
|
||||
LEDC 还支持一些可由其他事件触发并自动执行的任务。定时器支持的任务列在 :cpp:type:`ledc_timer_etm_task_type_t` 中,通道支持的任务列在 :cpp:type:`ledc_channel_etm_task_type_t` 中。用户可以分别通过调用 :cpp:func:`ledc_timer_new_etm_task` 或 :cpp:func:`ledc_channel_new_etm_task` 来创建 ``ETM task`` 句柄。
|
||||
|
||||
一些使用 ETM 与 LEDC 结合的实用应用包括:
|
||||
|
||||
* 生成一段特定脉冲数的 PWM 信号
|
||||
* 同步 PWM 周期与外部信号
|
||||
* 无需 CPU 干预即可开始 / 停止 PWM 信号输出或一次渐变
|
||||
|
||||
关于如何将 LEDC 事件和任务连接到 ETM 通道,请参考 :doc:`ETM </api-reference/peripherals/etm>` 文档。
|
||||
|
||||
电源管理
|
||||
--------
|
||||
@@ -418,6 +433,7 @@ LED PWM 控制器 API 会在设定的频率和占空比分辨率超过 LED PWM
|
||||
* :example:`peripherals/ledc/ledc_basic` 演示了如何使用 LEDC 生成低速模式的 PWM 信号。
|
||||
* :example:`peripherals/ledc/ledc_fade` 演示了如何使用 LEDC 实现 LED 亮度的渐变控制。
|
||||
:SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED: * :example:`peripherals/ledc/ledc_gamma_curve_fade` 演示了如何使用 LEDC 对 RGB LED 实现带伽马校正的颜色控制。
|
||||
:SOC_LEDC_SUPPORT_ETM and SOC_ETM_SUPPORTED: * :example:`peripherals/ledc/ledc_dimmer` 演示了如何使用 LEDC 和 ETM 生成与交流电零交叉同步的 TRIAC 门触发脉冲。
|
||||
|
||||
|
||||
API 参考
|
||||
@@ -425,3 +441,7 @@ API 参考
|
||||
|
||||
.. include-build-file:: inc/ledc.inc
|
||||
.. include-build-file:: inc/ledc_types.inc
|
||||
|
||||
.. only:: SOC_LEDC_SUPPORT_ETM and SOC_ETM_SUPPORTED
|
||||
|
||||
.. include-build-file:: inc/ledc_etm.inc
|
||||
|
||||
@@ -272,6 +272,12 @@ examples/peripherals/ledc:
|
||||
depends_components:
|
||||
- esp_driver_ledc
|
||||
|
||||
examples/peripherals/ledc/ledc_dimmer:
|
||||
disable:
|
||||
- if: SOC_ETM_SUPPORTED != 1 or SOC_LEDC_SUPPORT_ETM != 1
|
||||
depends_components:
|
||||
- esp_driver_ledc
|
||||
|
||||
examples/peripherals/ledc/ledc_gamma_curve_fade:
|
||||
disable:
|
||||
- if: SOC_LEDC_SUPPORTED != 1 or SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED != 1
|
||||
|
||||
@@ -49,7 +49,6 @@ static void example_ledc_init(void)
|
||||
.speed_mode = LEDC_MODE,
|
||||
.channel = LEDC_CHANNEL,
|
||||
.timer_sel = LEDC_TIMER,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = LEDC_OUTPUT_IO,
|
||||
.duty = 0, // Set duty to 0%
|
||||
.hpoint = 0,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
idf_build_set_property(MINIMAL_BUILD ON)
|
||||
project(ledc_dimmer)
|
||||
@@ -0,0 +1,63 @@
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-P4 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# LEDC Dimmer Example
|
||||
|
||||
This example demonstrates how to generate TRIAC gate trigger pulses that are synchronized to the mains zero‑cross using LEDC and ETM. As a simplified demonstration, it simulates the 50 Hz zero‑cross AC mains detector input using a GPIO that toggles at 50 Hz, and uses ETM to reset the LEDC timer on each edge (every half-cycle) for synchronization. By shifting the LEDC `hpoint` (phase angle) after each reset, the gate pulse moves within the half‑cycle, achieving dimming.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* A development board with any Espressif SoC that has ETM functionality (e.g., ESP32C61-DevKitC etc.)
|
||||
* A USB cable for power supply and programming
|
||||
|
||||
## Signals and pins
|
||||
|
||||
| Signal | GPIO |
|
||||
| --------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
||||
| Reference wave (50 Hz square from a AC mains detection circuit) | GPIO3 (configured as input/output in this demo to simulate the square wave) |
|
||||
| Gate trigger pulse (LEDC output) | GPIO2 |
|
||||
|
||||
Expected observation if connect an oscilloscope or logic analyzer:
|
||||
|
||||
- A 50 Hz square wave on `GPIO3`.
|
||||
- Short pulses on `GPIO2` that occur once each half‑cycle, moving left/right (earlier/later) every 2 seconds as the brightness ramps down and up.
|
||||
|
||||
## Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
|
||||
```bash
|
||||
idf.py build
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(Replace PORT with the name of the serial port to use.)
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the [ESP‑IDF Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Adapting to real mains dimming (advanced)
|
||||
|
||||
If you want to control a real TRIAC load (lamp):
|
||||
|
||||
1. Replace the simulated reference wave with a proper zero‑cross detector feeding an isolated input GPIO.
|
||||
- Configure `REFERENCE_WAVE_IO` as input only, remove the toggling task, and ensure ETM still triggers on both edges. Or to normalize the AC mains to some analog signal, and use analog comparator to trigger a ETM event.
|
||||
2. Drive the TRIAC gate through an opto‑triac from the LEDC output GPIO with proper current‑limit resistor.
|
||||
|
||||
Here shows a simplified schematic for reference:
|
||||
|
||||

|
||||
|
||||
And here is an actual timing diagrams (AC mains + dimmer output waveforms with phase angle):
|
||||
|
||||

|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Pulse timing not updating on C6/C5/H2/P4/H4/H21 → Check the notes in the example source file. For such targets, LEDC timer period should be shorter than the half-cycle of the mains, so that timer overflow could happen to update the duty parameters.
|
||||
- Please make sure (hpoint + duty) is always less than (2 ** timer_resolution), otherwise, behavior is unexpected.
|
||||
|
||||
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 152 KiB |
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "ledc_dimmer_example_main.c"
|
||||
PRIV_REQUIRES esp_driver_ledc esp_driver_gpio
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_check.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_etm.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define REFERENCE_WAVE_IO (3) // Reference wave GPIO
|
||||
#define GATE_TRIGGER_PULSE_IO (2) // Gate trigger pulse GPIO
|
||||
#define LEDC_TIMER LEDC_TIMER_0
|
||||
#define LEDC_MODE LEDC_LOW_SPEED_MODE
|
||||
#define LEDC_CHANNEL LEDC_CHANNEL_0
|
||||
#define LEDC_DUTY_RES LEDC_TIMER_13_BIT // Set duty resolution to 13 bits
|
||||
#define LEDC_DUTY (400) // Set duty to 400 out of 8192 (13-bit)
|
||||
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32H21
|
||||
// On such targets. due to hardware limitation, LEDC timer reset ETM task won't sync newly configured duty parameters.
|
||||
// Therefore, the LEDC timer frequency should be higher than 100 Hz (2 * 50 Hz) to ensure a timer overflow happens before the timer reset to update the duty parameters.
|
||||
#define LEDC_FREQUENCY (120) // Frequency in Hertz. Set frequency at 120 Hz
|
||||
#define LEDC_HPOINT_INITIAL (1640) // Initial hpoint value (to ensure no pulse between timer overflow and timer reset)
|
||||
#else
|
||||
#define LEDC_FREQUENCY (80) // Frequency in Hertz. Set frequency at 80 Hz
|
||||
#define LEDC_HPOINT_INITIAL (0) // Initial hpoint value
|
||||
#endif
|
||||
|
||||
// For C6/C5/H2/P4/H4/H21:
|
||||
// 120Hz 8192-step PWM cycle in 100Hz -> (1640, 8192 - LEDC_DUTY) steps for a 84% ~ 21% dimming (this is the limitation due to the hardware)
|
||||
// For other targets:
|
||||
// 100Hz in a 80Hz 8192-step PWM cycle -> (0, 6554) steps for a 100% ~ 0% dimming
|
||||
// Overall, we want to increase and decrease the brightness in 10 steps, so each step is:
|
||||
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32H21
|
||||
#define LEDC_HPOINT_STEP (615)
|
||||
#else
|
||||
#define LEDC_HPOINT_STEP (655)
|
||||
#endif
|
||||
|
||||
// Simulate a signal comes from the 50Hz mains AC supply
|
||||
// Use GPIO + vTaskDelay to output a 50Hz square wave as the reference signal
|
||||
static void reference_wave_init(void)
|
||||
{
|
||||
gpio_config_t io_conf = {};
|
||||
io_conf.mode = GPIO_MODE_INPUT_OUTPUT;
|
||||
io_conf.pin_bit_mask = (1ULL << REFERENCE_WAVE_IO);
|
||||
ESP_ERROR_CHECK(gpio_config(&io_conf));
|
||||
}
|
||||
|
||||
static void reference_wave_task(void *arg)
|
||||
{
|
||||
while (1) {
|
||||
// Set the reference wave high
|
||||
ESP_ERROR_CHECK(gpio_set_level(REFERENCE_WAVE_IO, 1));
|
||||
vTaskDelay(pdMS_TO_TICKS(10)); // High for 10ms
|
||||
|
||||
// Set the reference wave low
|
||||
ESP_ERROR_CHECK(gpio_set_level(REFERENCE_WAVE_IO, 0));
|
||||
vTaskDelay(pdMS_TO_TICKS(10)); // Low for 10ms
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the gate trigger pulse signal using LEDC
|
||||
static void gate_trigger_pulse_signal_init(void)
|
||||
{
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = LEDC_MODE,
|
||||
.duty_resolution = LEDC_DUTY_RES,
|
||||
.timer_num = LEDC_TIMER,
|
||||
.freq_hz = LEDC_FREQUENCY,
|
||||
.clk_cfg = LEDC_AUTO_CLK
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
|
||||
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.speed_mode = LEDC_MODE,
|
||||
.channel = LEDC_CHANNEL,
|
||||
.timer_sel = LEDC_TIMER,
|
||||
.gpio_num = GATE_TRIGGER_PULSE_IO,
|
||||
.duty = LEDC_DUTY,
|
||||
.hpoint = LEDC_HPOINT_INITIAL
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
gate_trigger_pulse_signal_init();
|
||||
vTaskDelay(pdMS_TO_TICKS(50)); // Wait for the LEDC to run for at least one cycle
|
||||
|
||||
reference_wave_init();
|
||||
xTaskCreate(reference_wave_task, "reference_wave_task", 2048, NULL, 5, NULL);
|
||||
|
||||
// Connect reference wave GPIO toggle event to LEDC timer reset task, so that the timing frame of the gate trigger pulse
|
||||
// can be synchronized to the reference wave signal
|
||||
esp_etm_channel_config_t etm_config = {};
|
||||
esp_etm_channel_handle_t etm_channel = NULL;
|
||||
ESP_ERROR_CHECK(esp_etm_new_channel(&etm_config, &etm_channel));
|
||||
|
||||
esp_etm_event_handle_t gpio_event = NULL;
|
||||
gpio_etm_event_config_t gpio_event_config = {
|
||||
.edge = GPIO_ETM_EVENT_EDGE_ANY,
|
||||
};
|
||||
ESP_ERROR_CHECK(gpio_new_etm_event(&gpio_event_config, &gpio_event));
|
||||
ESP_ERROR_CHECK(gpio_etm_event_bind_gpio(gpio_event, REFERENCE_WAVE_IO));
|
||||
|
||||
esp_etm_task_handle_t ledc_task = NULL;
|
||||
ledc_timer_etm_task_config_t ledc_task_config = {
|
||||
.task_type = LEDC_TIMER_ETM_TASK_RST,
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_timer_new_etm_task(LEDC_MODE, LEDC_TIMER, &ledc_task_config, &ledc_task));
|
||||
|
||||
ESP_ERROR_CHECK(esp_etm_channel_connect(etm_channel, gpio_event, ledc_task));
|
||||
|
||||
ESP_ERROR_CHECK(esp_etm_channel_enable(etm_channel));
|
||||
|
||||
int cnt = 0;
|
||||
bool dimming = true; // controls the dimming direction
|
||||
uint32_t hpoint = LEDC_HPOINT_INITIAL;
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
if (dimming) {
|
||||
// Decrease brightness
|
||||
if (cnt < 10) {
|
||||
hpoint += LEDC_HPOINT_STEP;
|
||||
cnt++;
|
||||
} else if (cnt == 10) {
|
||||
dimming = false;
|
||||
}
|
||||
} else {
|
||||
// Increase brightness
|
||||
if (cnt > 0) {
|
||||
hpoint -= LEDC_HPOINT_STEP;
|
||||
cnt--;
|
||||
} else if (cnt == 0) {
|
||||
dimming = true;
|
||||
}
|
||||
}
|
||||
ESP_ERROR_CHECK(ledc_set_duty_with_hpoint(LEDC_MODE, LEDC_CHANNEL, LEDC_DUTY, hpoint));
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user