From f5bbafc05083e30b859d031924ba779b64dd6a5c Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 2 Jul 2026 15:20:47 +0800 Subject: [PATCH] refactor(ledc): move sleep retention config into driver layer Move per-target LEDC regdma retention descriptors out of esp_hal_ledc and into esp_driver_ledc so the driver owns its backup scope and restore flow. --- components/esp_driver_ledc/CMakeLists.txt | 3 + .../include/esp_private/ledc_priv.h | 51 ++++ .../src/esp32c5/ledc_retention.c | 162 ++++++++++++ .../src/esp32c6/ledc_retention.c | 151 +++++++++++ .../src/esp32c61/ledc_retention.c | 162 ++++++++++++ .../src/esp32h2/ledc_retention.c | 151 +++++++++++ .../src/esp32h21/ledc_retention.c | 151 +++++++++++ .../src/esp32h4/ledc_retention.c | 173 +++++++++++++ .../src/esp32p4/ledc_retention.c | 172 +++++++++++++ .../src/esp32s31/ledc_retention.c | 243 ++++++++++++++++++ components/esp_driver_ledc/src/ledc.c | 1 + .../test_apps/ledc/main/test_ledc_sleep.cpp | 2 +- components/esp_hal_ledc/esp32c5/ledc_periph.c | 154 ----------- components/esp_hal_ledc/esp32c6/ledc_periph.c | 143 ----------- .../esp_hal_ledc/esp32c61/ledc_periph.c | 154 ----------- components/esp_hal_ledc/esp32h2/ledc_periph.c | 143 ----------- .../esp_hal_ledc/esp32h21/ledc_periph.c | 143 ----------- components/esp_hal_ledc/esp32h4/ledc_periph.c | 165 ------------ components/esp_hal_ledc/esp32p4/ledc_periph.c | 164 ------------ .../esp_hal_ledc/esp32s31/ledc_periph.c | 235 ----------------- .../esp_hal_ledc/include/hal/ledc_periph.h | 31 --- 21 files changed, 1421 insertions(+), 1333 deletions(-) create mode 100644 components/esp_driver_ledc/include/esp_private/ledc_priv.h create mode 100644 components/esp_driver_ledc/src/esp32c5/ledc_retention.c create mode 100644 components/esp_driver_ledc/src/esp32c6/ledc_retention.c create mode 100644 components/esp_driver_ledc/src/esp32c61/ledc_retention.c create mode 100644 components/esp_driver_ledc/src/esp32h2/ledc_retention.c create mode 100644 components/esp_driver_ledc/src/esp32h21/ledc_retention.c create mode 100644 components/esp_driver_ledc/src/esp32h4/ledc_retention.c create mode 100644 components/esp_driver_ledc/src/esp32p4/ledc_retention.c create mode 100644 components/esp_driver_ledc/src/esp32s31/ledc_retention.c diff --git a/components/esp_driver_ledc/CMakeLists.txt b/components/esp_driver_ledc/CMakeLists.txt index e0bf8a9f865..a32f7df2d5d 100644 --- a/components/esp_driver_ledc/CMakeLists.txt +++ b/components/esp_driver_ledc/CMakeLists.txt @@ -5,6 +5,9 @@ set(public_include "include") if(CONFIG_SOC_LEDC_SUPPORTED) list(APPEND srcs "src/ledc.c") + if(CONFIG_SOC_PAU_SUPPORTED) + list(APPEND srcs "src/${target}/ledc_retention.c") + endif() if(CONFIG_SOC_ETM_SUPPORTED AND CONFIG_SOC_LEDC_SUPPORT_ETM) list(APPEND srcs "src/ledc_etm.c") diff --git a/components/esp_driver_ledc/include/esp_private/ledc_priv.h b/components/esp_driver_ledc/include/esp_private/ledc_priv.h new file mode 100644 index 00000000000..a97ee55f4ba --- /dev/null +++ b/components/esp_driver_ledc/include/esp_private/ledc_priv.h @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc_caps.h" +#include "hal/ledc_ll.h" +#include "hal/ledc_types.h" + +#if SOC_PAU_SUPPORTED +#include "soc/regdma.h" +#include "soc/retention_periph_defs.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_PAU_SUPPORTED + +#if SOC_LIGHT_SLEEP_SUPPORTED +#if SOC_PM_SUPPORT_PMU_MODEM_STATE +#define LEDC_RETENTION_ENTRY (ENTRY(0) | ENTRY(2)) +#else +#define LEDC_RETENTION_ENTRY (ENTRY(0)) +#endif +#else +#define LEDC_RETENTION_ENTRY REGDMA_SW_TRIGGER_ENTRY +#endif + +typedef struct { + const regdma_entries_config_t *regdma_entry_array; + uint32_t array_size; +} ledc_sub_reg_retention_info_t; + +typedef struct { + ledc_sub_reg_retention_info_t common; + ledc_sub_reg_retention_info_t timer[SOC_LEDC_TIMER_NUM]; + ledc_sub_reg_retention_info_t channel[SOC_LEDC_CHANNEL_NUM]; + const periph_retention_module_t module_id; +} ledc_reg_retention_info_t; + +extern const ledc_reg_retention_info_t ledc_reg_retention_info[LEDC_LL_GET(GROUP_NUM)]; +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_ledc/src/esp32c5/ledc_retention.c b/components/esp_driver_ledc/src/esp32c5/ledc_retention.c new file mode 100644 index 00000000000..3fcf370f45c --- /dev/null +++ b/components/esp_driver_ledc/src/esp32c5/ledc_retention.c @@ -0,0 +1,162 @@ +/* + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/ledc_priv.h" +#include "soc/ledc_reg.h" + +/** + * LEDC registers to be saved for sleep retention + * + * channel: + * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, + * LEDC_CHx_GAMMA_CONF_REG, LEDC_CHx_GAMMA_RANGEi_REG + * + * timer: + * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, + * + * common: + * LEDC_INT_ENA_REG, + * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, + * LEDC_CONF_REG, + * + * Note 1: Gamma parameter registers are backuped and restored. But we won't start a fade automatically after wake-up. + * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. + * + * Note 2: For timer/channel registers to get synced, update bits need to be set + * + * Note 3: Gamma RAM registers R/W relies both APB and function clock, therefore, retention requires the existence of function clock + */ +#define LEDC_COMMON_RETENTION_REGS_CNT 5 +#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) +static const uint32_t ledc_common_regs_map[4] = {0x1c00001, 0x400, 0x0, 0x0}; +static const regdma_entries_config_t ledc_common_regdma_entries[] = { + // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). + // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. + [0] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), + LEDC_INT_ENA_REG, 0, + (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M), 0, 1), + .owner = LEDC_RETENTION_ENTRY + }, + [1] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), + LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, + LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, + ledc_common_regs_map[0], ledc_common_regs_map[1], + ledc_common_regs_map[2], ledc_common_regs_map[3]), + .owner = LEDC_RETENTION_ENTRY + }, +}; + +#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ + LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 +static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; +static const uint32_t ledc_channel_gamma_regs_map[4] = {0xffff, 0x0, 0x0, 0x0}; +#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ + LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ + ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ + ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ + LEDC_DUTY_START_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ + LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ + LEDC_PARA_UP_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x04), \ + LEDC_CH##chan##_GAMMA_CONF_REG, LEDC_CH##chan##_GAMMA_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [5] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x05), \ + LEDC_CH##chan##_GAMMA_RANGE0_REG, LEDC_CH##chan##_GAMMA_RANGE0_REG, \ + SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX, 0, 0, \ + ledc_channel_gamma_regs_map[0], ledc_channel_gamma_regs_map[1], \ + ledc_channel_gamma_regs_map[2], ledc_channel_gamma_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); + +static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); +static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); +static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); + +const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ + .common = { + .regdma_entry_array = ledc_common_regdma_entries, + .array_size = ARRAY_SIZE(ledc_common_regdma_entries), + }, + .timer[0] = { + .regdma_entry_array = ledc_timer0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), + }, + .timer[1] = { + .regdma_entry_array = ledc_timer1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), + }, + .timer[2] = { + .regdma_entry_array = ledc_timer2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), + }, + .timer[3] = { + .regdma_entry_array = ledc_timer3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), + }, + .channel[0] = { + .regdma_entry_array = ledc_channel0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), + }, + .channel[1] = { + .regdma_entry_array = ledc_channel1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), + }, + .channel[2] = { + .regdma_entry_array = ledc_channel2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), + }, + .channel[3] = { + .regdma_entry_array = ledc_channel3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), + }, + .channel[4] = { + .regdma_entry_array = ledc_channel4_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), + }, + .channel[5] = { + .regdma_entry_array = ledc_channel5_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), + }, + .module_id = SLEEP_RETENTION_MODULE_LEDC, + } +}; diff --git a/components/esp_driver_ledc/src/esp32c6/ledc_retention.c b/components/esp_driver_ledc/src/esp32c6/ledc_retention.c new file mode 100644 index 00000000000..91edf3ac7a1 --- /dev/null +++ b/components/esp_driver_ledc/src/esp32c6/ledc_retention.c @@ -0,0 +1,151 @@ +/* + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/ledc_priv.h" +#include "soc/ledc_reg.h" + +/** + * LEDC registers to be saved for sleep retention + * + * channel: + * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, + * + * timer: + * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, + * + * common: + * LEDC_INT_ENA_REG, + * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, + * LEDC_CONF_REG, + * + * Note 1: Gamma feature is hard to do hardware retention, will consider to use software to do the backup and restore. + * We won't start a fade automatically after wake-up. + * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. + * + * Note 2: For timer/channel registers to get synced, update bits need to be set + * + * Note 3: Retention backup/restore does not rely on LEDC function clock enabled + */ +#define LEDC_COMMON_RETENTION_REGS_CNT 5 +#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) +static const uint32_t ledc_common_regs_map[4] = {0x1, 0x1c00000, 0x400, 0x0}; +static const regdma_entries_config_t ledc_common_regdma_entries[] = { + // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). + // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. + [0] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), + LEDC_INT_ENA_REG, 0, + (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M), 0, 1), + .owner = LEDC_RETENTION_ENTRY + }, + [1] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), + LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, + LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, + ledc_common_regs_map[0], ledc_common_regs_map[1], + ledc_common_regs_map[2], ledc_common_regs_map[3]), + .owner = LEDC_RETENTION_ENTRY + }, +}; + +#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ + LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 +static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; +#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ + LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ + ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ + ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ + LEDC_DUTY_START_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ + LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ + LEDC_PARA_UP_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); + +static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); +static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); +static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); + +const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ + .common = { + .regdma_entry_array = ledc_common_regdma_entries, + .array_size = ARRAY_SIZE(ledc_common_regdma_entries), + }, + .timer[0] = { + .regdma_entry_array = ledc_timer0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), + }, + .timer[1] = { + .regdma_entry_array = ledc_timer1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), + }, + .timer[2] = { + .regdma_entry_array = ledc_timer2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), + }, + .timer[3] = { + .regdma_entry_array = ledc_timer3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), + }, + .channel[0] = { + .regdma_entry_array = ledc_channel0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), + }, + .channel[1] = { + .regdma_entry_array = ledc_channel1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), + }, + .channel[2] = { + .regdma_entry_array = ledc_channel2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), + }, + .channel[3] = { + .regdma_entry_array = ledc_channel3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), + }, + .channel[4] = { + .regdma_entry_array = ledc_channel4_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), + }, + .channel[5] = { + .regdma_entry_array = ledc_channel5_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), + }, + .module_id = SLEEP_RETENTION_MODULE_LEDC, + } +}; diff --git a/components/esp_driver_ledc/src/esp32c61/ledc_retention.c b/components/esp_driver_ledc/src/esp32c61/ledc_retention.c new file mode 100644 index 00000000000..c41e37efe8b --- /dev/null +++ b/components/esp_driver_ledc/src/esp32c61/ledc_retention.c @@ -0,0 +1,162 @@ +/* + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/ledc_priv.h" +#include "soc/ledc_reg.h" + +/** + * LEDC registers to be saved for sleep retention + * + * channel: + * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, + * LEDC_CHx_GAMMA_CONF_REG, LEDC_CHx_GAMMA_RANGEi_REG + * + * timer: + * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, + * + * common: + * LEDC_INT_ENA_REG, + * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, + * LEDC_CONF_REG, + * + * Note 1: Gamma parameter registers are backuped and restored. But we won't start a fade automatically after wake-up. + * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. + * + * Note 2: For timer/channel registers to get synced, update bits need to be set + * + * Note 3: Gamma RAM registers R/W relies both APB and function clock, therefore, retention requires the existence of function clock + */ +#define LEDC_COMMON_RETENTION_REGS_CNT 5 +#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) +static const uint32_t ledc_common_regs_map[4] = {0x1c00001, 0x400, 0x0, 0x0}; +static const regdma_entries_config_t ledc_common_regdma_entries[] = { + // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). + // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. + [0] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), + LEDC_INT_ENA_REG, 0, + (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M), 0, 1), + .owner = LEDC_RETENTION_ENTRY + }, + [1] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), + LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, + LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, + ledc_common_regs_map[0], ledc_common_regs_map[1], + ledc_common_regs_map[2], ledc_common_regs_map[3]), + .owner = LEDC_RETENTION_ENTRY + }, +}; + +#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ + LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 +static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; +static const uint32_t ledc_channel_gamma_regs_map[4] = {0xffff, 0x0, 0x0, 0x0}; +#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ + LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ + ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ + ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ + LEDC_DUTY_START_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ + LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ + LEDC_PARA_UP_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x04), \ + LEDC_CH##chan##_GAMMA_CONF_REG, LEDC_CH##chan##_GAMMA_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [5] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x05), \ + LEDC_CH##chan##_GAMMA_RANGE0_REG, LEDC_CH##chan##_GAMMA_RANGE0_REG, \ + SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX, 0, 0, \ + ledc_channel_gamma_regs_map[0], ledc_channel_gamma_regs_map[1], \ + ledc_channel_gamma_regs_map[2], ledc_channel_gamma_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); + +static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); +static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); +static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); + +const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ + .common = { + .regdma_entry_array = ledc_common_regdma_entries, + .array_size = ARRAY_SIZE(ledc_common_regdma_entries), + }, + .timer[0] = { + .regdma_entry_array = ledc_timer0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), + }, + .timer[1] = { + .regdma_entry_array = ledc_timer1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), + }, + .timer[2] = { + .regdma_entry_array = ledc_timer2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), + }, + .timer[3] = { + .regdma_entry_array = ledc_timer3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), + }, + .channel[0] = { + .regdma_entry_array = ledc_channel0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), + }, + .channel[1] = { + .regdma_entry_array = ledc_channel1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), + }, + .channel[2] = { + .regdma_entry_array = ledc_channel2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), + }, + .channel[3] = { + .regdma_entry_array = ledc_channel3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), + }, + .channel[4] = { + .regdma_entry_array = ledc_channel4_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), + }, + .channel[5] = { + .regdma_entry_array = ledc_channel5_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), + }, + .module_id = SLEEP_RETENTION_MODULE_LEDC, + } +}; diff --git a/components/esp_driver_ledc/src/esp32h2/ledc_retention.c b/components/esp_driver_ledc/src/esp32h2/ledc_retention.c new file mode 100644 index 00000000000..50234bf8bcb --- /dev/null +++ b/components/esp_driver_ledc/src/esp32h2/ledc_retention.c @@ -0,0 +1,151 @@ +/* + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/ledc_priv.h" +#include "soc/ledc_reg.h" + +/** + * LEDC registers to be saved for sleep retention + * + * channel: + * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, + * + * timer: + * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, + * + * common: + * LEDC_INT_ENA_REG, + * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, + * LEDC_CONF_REG, + * + * Note 1: Gamma feature is hard to do hardware retention, will consider to use software to do the backup and restore. + * We won't start a fade automatically after wake-up. + * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. + * + * Note 2: For timer/channel registers to get synced, update bits need to be set + * + * Note 3: Retention backup/restore does not rely on LEDC function clock enabled + */ +#define LEDC_COMMON_RETENTION_REGS_CNT 5 +#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) +static const uint32_t ledc_common_regs_map[4] = {0x1, 0x1c00000, 0x400, 0x0}; +static const regdma_entries_config_t ledc_common_regdma_entries[] = { + // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). + // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. + [0] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), + LEDC_INT_ENA_REG, 0, + (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M), 0, 1), + .owner = LEDC_RETENTION_ENTRY + }, + [1] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), + LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, + LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, + ledc_common_regs_map[0], ledc_common_regs_map[1], + ledc_common_regs_map[2], ledc_common_regs_map[3]), + .owner = LEDC_RETENTION_ENTRY + }, +}; + +#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ + LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 +static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; +#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ + LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ + ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ + ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ + LEDC_DUTY_START_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ + LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ + LEDC_PARA_UP_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); + +static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); +static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); +static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); + +const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ + .common = { + .regdma_entry_array = ledc_common_regdma_entries, + .array_size = ARRAY_SIZE(ledc_common_regdma_entries), + }, + .timer[0] = { + .regdma_entry_array = ledc_timer0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), + }, + .timer[1] = { + .regdma_entry_array = ledc_timer1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), + }, + .timer[2] = { + .regdma_entry_array = ledc_timer2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), + }, + .timer[3] = { + .regdma_entry_array = ledc_timer3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), + }, + .channel[0] = { + .regdma_entry_array = ledc_channel0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), + }, + .channel[1] = { + .regdma_entry_array = ledc_channel1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), + }, + .channel[2] = { + .regdma_entry_array = ledc_channel2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), + }, + .channel[3] = { + .regdma_entry_array = ledc_channel3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), + }, + .channel[4] = { + .regdma_entry_array = ledc_channel4_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), + }, + .channel[5] = { + .regdma_entry_array = ledc_channel5_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), + }, + .module_id = SLEEP_RETENTION_MODULE_LEDC, + } +}; diff --git a/components/esp_driver_ledc/src/esp32h21/ledc_retention.c b/components/esp_driver_ledc/src/esp32h21/ledc_retention.c new file mode 100644 index 00000000000..50234bf8bcb --- /dev/null +++ b/components/esp_driver_ledc/src/esp32h21/ledc_retention.c @@ -0,0 +1,151 @@ +/* + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/ledc_priv.h" +#include "soc/ledc_reg.h" + +/** + * LEDC registers to be saved for sleep retention + * + * channel: + * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, + * + * timer: + * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, + * + * common: + * LEDC_INT_ENA_REG, + * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, + * LEDC_CONF_REG, + * + * Note 1: Gamma feature is hard to do hardware retention, will consider to use software to do the backup and restore. + * We won't start a fade automatically after wake-up. + * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. + * + * Note 2: For timer/channel registers to get synced, update bits need to be set + * + * Note 3: Retention backup/restore does not rely on LEDC function clock enabled + */ +#define LEDC_COMMON_RETENTION_REGS_CNT 5 +#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) +static const uint32_t ledc_common_regs_map[4] = {0x1, 0x1c00000, 0x400, 0x0}; +static const regdma_entries_config_t ledc_common_regdma_entries[] = { + // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). + // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. + [0] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), + LEDC_INT_ENA_REG, 0, + (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M), 0, 1), + .owner = LEDC_RETENTION_ENTRY + }, + [1] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), + LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, + LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, + ledc_common_regs_map[0], ledc_common_regs_map[1], + ledc_common_regs_map[2], ledc_common_regs_map[3]), + .owner = LEDC_RETENTION_ENTRY + }, +}; + +#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ + LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 +static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; +#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ + LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ + ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ + ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ + LEDC_DUTY_START_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ + LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ + LEDC_PARA_UP_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); + +static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); +static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); +static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); + +const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ + .common = { + .regdma_entry_array = ledc_common_regdma_entries, + .array_size = ARRAY_SIZE(ledc_common_regdma_entries), + }, + .timer[0] = { + .regdma_entry_array = ledc_timer0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), + }, + .timer[1] = { + .regdma_entry_array = ledc_timer1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), + }, + .timer[2] = { + .regdma_entry_array = ledc_timer2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), + }, + .timer[3] = { + .regdma_entry_array = ledc_timer3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), + }, + .channel[0] = { + .regdma_entry_array = ledc_channel0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), + }, + .channel[1] = { + .regdma_entry_array = ledc_channel1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), + }, + .channel[2] = { + .regdma_entry_array = ledc_channel2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), + }, + .channel[3] = { + .regdma_entry_array = ledc_channel3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), + }, + .channel[4] = { + .regdma_entry_array = ledc_channel4_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), + }, + .channel[5] = { + .regdma_entry_array = ledc_channel5_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), + }, + .module_id = SLEEP_RETENTION_MODULE_LEDC, + } +}; diff --git a/components/esp_driver_ledc/src/esp32h4/ledc_retention.c b/components/esp_driver_ledc/src/esp32h4/ledc_retention.c new file mode 100644 index 00000000000..c35166abb5f --- /dev/null +++ b/components/esp_driver_ledc/src/esp32h4/ledc_retention.c @@ -0,0 +1,173 @@ +/* + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/ledc_priv.h" +#include "soc/ledc_reg.h" + +/** + * LEDC registers to be saved for sleep retention + * + * channel: + * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, + * LEDC_CHx_FADE_CONF_REG, LEDC_CHx_FADE_PARAM_REG + * + * timer: + * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, + * + * common: + * LEDC_INT_ENA_REG, + * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, + * LEDC_CONF_REG, + * LEDC_CH_POWER_UP_CONF_REG, LEDC_TIMER_POWER_UP_CONF_REG + * + * Note 1: Fade parameter registers are backuped and restored. But we won't start a fade automatically after wake-up. + * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. + * + * Note 2: For timer/channel registers to get synced, update bits need to be set + * + * Note 3: Retention backup/restore does not rely on LEDC function clock enabled + */ +#define LEDC_COMMON_RETENTION_REGS_CNT 7 +#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) +static const uint32_t ledc_common_regs_map[4] = {0x1c00001, 0x1c00, 0x0, 0x0}; +static const regdma_entries_config_t ledc_common_regdma_entries[] = { + // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). + // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. + [0] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), + LEDC_INT_ENA_REG, 0, + (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M | LEDC_DUTY_CHNG_END_CH6_INT_ENA_M | LEDC_DUTY_CHNG_END_CH7_INT_ENA_M), 0, 1), + .owner = LEDC_RETENTION_ENTRY + }, + [1] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), + LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, + LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, + ledc_common_regs_map[0], ledc_common_regs_map[1], + ledc_common_regs_map[2], ledc_common_regs_map[3]), + .owner = LEDC_RETENTION_ENTRY + }, +}; + +#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ + LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 +static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; +static const uint32_t ledc_channel_gamma_regs_map[4] = {0x1, 0x0, 0x0, 0x0}; +#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ + LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ + ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ + ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ + LEDC_DUTY_START_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ + LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ + LEDC_PARA_UP_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x04), \ + LEDC_CH##chan##_FADE_CONF_REG, LEDC_CH##chan##_FADE_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [5] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x05), \ + LEDC_CH##chan##_FADE_PARAM_REG, LEDC_CH##chan##_FADE_PARAM_REG, \ + 1, 0, 0, \ + ledc_channel_gamma_regs_map[0], ledc_channel_gamma_regs_map[1], \ + ledc_channel_gamma_regs_map[2], ledc_channel_gamma_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); + +static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); +static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); +static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); +static const regdma_entries_config_t ledc_channel6_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(6); +static const regdma_entries_config_t ledc_channel7_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(7); + +const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ + .common = { + .regdma_entry_array = ledc_common_regdma_entries, + .array_size = ARRAY_SIZE(ledc_common_regdma_entries), + }, + .timer[0] = { + .regdma_entry_array = ledc_timer0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), + }, + .timer[1] = { + .regdma_entry_array = ledc_timer1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), + }, + .timer[2] = { + .regdma_entry_array = ledc_timer2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), + }, + .timer[3] = { + .regdma_entry_array = ledc_timer3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), + }, + .channel[0] = { + .regdma_entry_array = ledc_channel0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), + }, + .channel[1] = { + .regdma_entry_array = ledc_channel1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), + }, + .channel[2] = { + .regdma_entry_array = ledc_channel2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), + }, + .channel[3] = { + .regdma_entry_array = ledc_channel3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), + }, + .channel[4] = { + .regdma_entry_array = ledc_channel4_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), + }, + .channel[5] = { + .regdma_entry_array = ledc_channel5_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), + }, + .channel[6] = { + .regdma_entry_array = ledc_channel6_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel6_regdma_entries), + }, + .channel[7] = { + .regdma_entry_array = ledc_channel7_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel7_regdma_entries), + }, + .module_id = SLEEP_RETENTION_MODULE_LEDC, + } +}; diff --git a/components/esp_driver_ledc/src/esp32p4/ledc_retention.c b/components/esp_driver_ledc/src/esp32p4/ledc_retention.c new file mode 100644 index 00000000000..a4d44554dff --- /dev/null +++ b/components/esp_driver_ledc/src/esp32p4/ledc_retention.c @@ -0,0 +1,172 @@ +/* + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/ledc_priv.h" +#include "soc/ledc_reg.h" + +/** + * LEDC registers to be saved for sleep retention + * + * channel: + * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, + * LEDC_CHx_GAMMA_CONF_REG, LEDC_CHx_GAMMA_RANGEi_REG + * + * timer: + * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, + * + * common: + * LEDC_INT_ENA_REG, + * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, + * LEDC_CONF_REG, + * + * Note 1: Gamma parameter registers are backuped and restored. But we won't start a fade automatically after wake-up. + * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. + * + * Note 2: For timer/channel registers to get synced, update bits need to be set + * + * Note 3: Gamma RAM registers R/W relies both APB and function clock, therefore, retention requires the existence of function clock + */ +#define LEDC_COMMON_RETENTION_REGS_CNT 5 +#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) +static const uint32_t ledc_common_regs_map[4] = {0x1c00001, 0x400, 0x0, 0x0}; +static const regdma_entries_config_t ledc_common_regdma_entries[] = { + // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). + // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. + [0] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), + LEDC_INT_ENA_REG, 0, + (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M | LEDC_DUTY_CHNG_END_CH6_INT_ENA_M | LEDC_DUTY_CHNG_END_CH7_INT_ENA_M), 0, 1), + .owner = LEDC_RETENTION_ENTRY + }, + [1] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), + LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, + LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, + ledc_common_regs_map[0], ledc_common_regs_map[1], + ledc_common_regs_map[2], ledc_common_regs_map[3]), + .owner = LEDC_RETENTION_ENTRY + }, +}; + +#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ + LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 +static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; +static const uint32_t ledc_channel_gamma_regs_map[4] = {0xffff, 0x0, 0x0, 0x0}; +#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ + LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ + ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ + ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ + LEDC_DUTY_START_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ + LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ + LEDC_PARA_UP_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x04), \ + LEDC_CH##chan##_GAMMA_CONF_REG, LEDC_CH##chan##_GAMMA_CONF_REG, \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [5] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x05), \ + LEDC_CH##chan##_GAMMA_RANGE0_REG, LEDC_CH##chan##_GAMMA_RANGE0_REG, \ + SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX, 0, 0, \ + ledc_channel_gamma_regs_map[0], ledc_channel_gamma_regs_map[1], \ + ledc_channel_gamma_regs_map[2], ledc_channel_gamma_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); + +static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); +static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); +static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); +static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); +static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); +static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); +static const regdma_entries_config_t ledc_channel6_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(6); +static const regdma_entries_config_t ledc_channel7_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(7); + +const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ + .common = { + .regdma_entry_array = ledc_common_regdma_entries, + .array_size = ARRAY_SIZE(ledc_common_regdma_entries), + }, + .timer[0] = { + .regdma_entry_array = ledc_timer0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), + }, + .timer[1] = { + .regdma_entry_array = ledc_timer1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), + }, + .timer[2] = { + .regdma_entry_array = ledc_timer2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), + }, + .timer[3] = { + .regdma_entry_array = ledc_timer3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), + }, + .channel[0] = { + .regdma_entry_array = ledc_channel0_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), + }, + .channel[1] = { + .regdma_entry_array = ledc_channel1_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), + }, + .channel[2] = { + .regdma_entry_array = ledc_channel2_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), + }, + .channel[3] = { + .regdma_entry_array = ledc_channel3_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), + }, + .channel[4] = { + .regdma_entry_array = ledc_channel4_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), + }, + .channel[5] = { + .regdma_entry_array = ledc_channel5_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), + }, + .channel[6] = { + .regdma_entry_array = ledc_channel6_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel6_regdma_entries), + }, + .channel[7] = { + .regdma_entry_array = ledc_channel7_regdma_entries, + .array_size = ARRAY_SIZE(ledc_channel7_regdma_entries), + }, + .module_id = SLEEP_RETENTION_MODULE_LEDC, + } +}; diff --git a/components/esp_driver_ledc/src/esp32s31/ledc_retention.c b/components/esp_driver_ledc/src/esp32s31/ledc_retention.c new file mode 100644 index 00000000000..b835dfc49a9 --- /dev/null +++ b/components/esp_driver_ledc/src/esp32s31/ledc_retention.c @@ -0,0 +1,243 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/ledc_priv.h" +#include "soc/ledc_reg.h" + +/** + * LEDC registers to be saved for sleep retention + * + * channel: + * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, + * LEDC_CHx_GAMMA_CONF_REG, LEDC_CHx_GAMMA_RANGEi_REG + * + * timer: + * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, + * + * common: + * LEDC_INT_ENA_REG, + * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, + * LEDC_CONF_REG, + * LEDC_CH_POWER_UP_CONF_REG, LEDC_TIMER_POWER_UP_CONF_REG + * + * Note 1: Gamma parameter registers are backuped and restored. But we won't start a fade automatically after wake-up. + * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. + * + * Note 2: For timer/channel registers to get synced, update bits need to be set + * + * Note 3: Gamma RAM registers R/W relies both APB and function clock, therefore, retention requires the existence of function clock + */ +#define LEDC_COMMON_RETENTION_REGS_CNT 7 +#define LEDC_COMMON_RETENTION_REGS_BASE(i) (DR_REG_LEDC_BASE(i) + 0xc8) +static const uint32_t ledc_common_regs_map[4] = {0x1c00001, 0x1c00, 0x0, 0x0}; +// If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). +// Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. +#define LEDC_COMMON_RETENTION_ENTRIES(i) { \ + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_INT_ENA_REG(i), 0, \ + (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M | LEDC_DUTY_CHNG_END_CH6_INT_ENA_M | LEDC_DUTY_CHNG_END_CH7_INT_ENA_M), 0, 1), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_COMMON_RETENTION_REGS_BASE(i), LEDC_COMMON_RETENTION_REGS_BASE(i), \ + LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, \ + ledc_common_regs_map[0], ledc_common_regs_map[1], \ + ledc_common_regs_map[2], ledc_common_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +#define LEDC_TIMER_RETENTION_ENTRIES(i, timer) { \ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_TIMER##timer##_CONF_REG(i), LEDC_TIMER##timer##_CONF_REG(i), \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_TIMER##timer##_CMP_REG(i), LEDC_TIMER##timer##_CMP_REG(i), \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_TIMER##timer##_CONF_REG(i), LEDC_TIMER##timer##_PARA_UP, \ + LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 +static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; +static const uint32_t ledc_channel_gamma_regs_map[4] = {0xffff, 0x0, 0x0, 0x0}; +#define LEDC_CHANNEL_RETENTION_ENTRIES(i, chan) { \ + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ + LEDC_CH##chan##_CONF0_REG(i), LEDC_CH##chan##_CONF0_REG(i), \ + LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ + ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ + ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ + LEDC_CH##chan##_DUTY_R_REG(i), LEDC_CH##chan##_DUTY_REG(i), \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ + LEDC_CH##chan##_CONF1_REG(i), LEDC_DUTY_START_CH##chan, \ + LEDC_DUTY_START_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ + LEDC_CH##chan##_CONF0_REG(i), LEDC_PARA_UP_CH##chan, \ + LEDC_PARA_UP_CH##chan##_M, 1, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x04), \ + LEDC_CH##chan##_GAMMA_CONF_REG(i), LEDC_CH##chan##_GAMMA_CONF_REG(i), \ + 1, 0, 0), \ + .owner = LEDC_RETENTION_ENTRY }, \ + [5] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x05), \ + LEDC_CH##chan##_GAMMA_RANGE0_REG(i), LEDC_CH##chan##_GAMMA_RANGE0_REG(i), \ + SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX, 0, 0, \ + ledc_channel_gamma_regs_map[0], ledc_channel_gamma_regs_map[1], \ + ledc_channel_gamma_regs_map[2], ledc_channel_gamma_regs_map[3]), \ + .owner = LEDC_RETENTION_ENTRY }, \ +} + +static const regdma_entries_config_t ledc0_common_regdma_entries[] = LEDC_COMMON_RETENTION_ENTRIES(0); + +static const regdma_entries_config_t ledc0_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0, 0); +static const regdma_entries_config_t ledc0_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0, 1); +static const regdma_entries_config_t ledc0_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0, 2); +static const regdma_entries_config_t ledc0_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0, 3); + +static const regdma_entries_config_t ledc0_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 0); +static const regdma_entries_config_t ledc0_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 1); +static const regdma_entries_config_t ledc0_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 2); +static const regdma_entries_config_t ledc0_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 3); +static const regdma_entries_config_t ledc0_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 4); +static const regdma_entries_config_t ledc0_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 5); +static const regdma_entries_config_t ledc0_channel6_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 6); +static const regdma_entries_config_t ledc0_channel7_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 7); + +static const regdma_entries_config_t ledc1_common_regdma_entries[] = LEDC_COMMON_RETENTION_ENTRIES(1); + +static const regdma_entries_config_t ledc1_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1, 0); +static const regdma_entries_config_t ledc1_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1, 1); +static const regdma_entries_config_t ledc1_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1, 2); +static const regdma_entries_config_t ledc1_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1, 3); + +static const regdma_entries_config_t ledc1_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 0); +static const regdma_entries_config_t ledc1_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 1); +static const regdma_entries_config_t ledc1_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 2); +static const regdma_entries_config_t ledc1_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 3); +static const regdma_entries_config_t ledc1_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 4); +static const regdma_entries_config_t ledc1_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 5); +static const regdma_entries_config_t ledc1_channel6_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 6); +static const regdma_entries_config_t ledc1_channel7_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 7); + +const ledc_reg_retention_info_t ledc_reg_retention_info[2] = { + { + .common = { + .regdma_entry_array = ledc0_common_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_common_regdma_entries), + }, + .timer[0] = { + .regdma_entry_array = ledc0_timer0_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_timer0_regdma_entries), + }, + .timer[1] = { + .regdma_entry_array = ledc0_timer1_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_timer1_regdma_entries), + }, + .timer[2] = { + .regdma_entry_array = ledc0_timer2_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_timer2_regdma_entries), + }, + .timer[3] = { + .regdma_entry_array = ledc0_timer3_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_timer3_regdma_entries), + }, + .channel[0] = { + .regdma_entry_array = ledc0_channel0_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_channel0_regdma_entries), + }, + .channel[1] = { + .regdma_entry_array = ledc0_channel1_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_channel1_regdma_entries), + }, + .channel[2] = { + .regdma_entry_array = ledc0_channel2_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_channel2_regdma_entries), + }, + .channel[3] = { + .regdma_entry_array = ledc0_channel3_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_channel3_regdma_entries), + }, + .channel[4] = { + .regdma_entry_array = ledc0_channel4_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_channel4_regdma_entries), + }, + .channel[5] = { + .regdma_entry_array = ledc0_channel5_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_channel5_regdma_entries), + }, + .channel[6] = { + .regdma_entry_array = ledc0_channel6_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_channel6_regdma_entries), + }, + .channel[7] = { + .regdma_entry_array = ledc0_channel7_regdma_entries, + .array_size = ARRAY_SIZE(ledc0_channel7_regdma_entries), + }, + .module_id = SLEEP_RETENTION_MODULE_LEDC0, + }, + { + .common = { + .regdma_entry_array = ledc1_common_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_common_regdma_entries), + }, + .timer[0] = { + .regdma_entry_array = ledc1_timer0_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_timer0_regdma_entries), + }, + .timer[1] = { + .regdma_entry_array = ledc1_timer1_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_timer1_regdma_entries), + }, + .timer[2] = { + .regdma_entry_array = ledc1_timer2_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_timer2_regdma_entries), + }, + .timer[3] = { + .regdma_entry_array = ledc1_timer3_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_timer3_regdma_entries), + }, + .channel[0] = { + .regdma_entry_array = ledc1_channel0_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_channel0_regdma_entries), + }, + .channel[1] = { + .regdma_entry_array = ledc1_channel1_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_channel1_regdma_entries), + }, + .channel[2] = { + .regdma_entry_array = ledc1_channel2_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_channel2_regdma_entries), + }, + .channel[3] = { + .regdma_entry_array = ledc1_channel3_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_channel3_regdma_entries), + }, + .channel[4] = { + .regdma_entry_array = ledc1_channel4_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_channel4_regdma_entries), + }, + .channel[5] = { + .regdma_entry_array = ledc1_channel5_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_channel5_regdma_entries), + }, + .channel[6] = { + .regdma_entry_array = ledc1_channel6_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_channel6_regdma_entries), + }, + .channel[7] = { + .regdma_entry_array = ledc1_channel7_regdma_entries, + .array_size = ARRAY_SIZE(ledc1_channel7_regdma_entries), + }, + .module_id = SLEEP_RETENTION_MODULE_LEDC1, + }, +}; diff --git a/components/esp_driver_ledc/src/ledc.c b/components/esp_driver_ledc/src/ledc.c index cc7f802888e..78ebad614e8 100644 --- a/components/esp_driver_ledc/src/ledc.c +++ b/components/esp_driver_ledc/src/ledc.c @@ -26,6 +26,7 @@ #include "esp_private/esp_gpio_reserve.h" #include "esp_memory_utils.h" #include "esp_private/sleep_retention.h" +#include "esp_private/ledc_priv.h" static __attribute__((unused)) const char *LEDC_TAG = "ledc"; diff --git a/components/esp_driver_ledc/test_apps/ledc/main/test_ledc_sleep.cpp b/components/esp_driver_ledc/test_apps/ledc/main/test_ledc_sleep.cpp index f771f000254..fa244fd660c 100644 --- a/components/esp_driver_ledc/test_apps/ledc/main/test_ledc_sleep.cpp +++ b/components/esp_driver_ledc/test_apps/ledc/main/test_ledc_sleep.cpp @@ -14,8 +14,8 @@ #include "esp_private/sleep_cpu.h" #include "esp_private/esp_sleep_internal.h" #include "esp_private/esp_pmu.h" -#include "hal/ledc_periph.h" #include "esp_private/sleep_retention.h" +#include "esp_private/ledc_priv.h" #include "esp_rom_serial_output.h" // Note. Test cases in this file cannot run one after another without reset diff --git a/components/esp_hal_ledc/esp32c5/ledc_periph.c b/components/esp_hal_ledc/esp32c5/ledc_periph.c index 10605ef2840..67e01cd9d18 100644 --- a/components/esp_hal_ledc/esp32c5/ledc_periph.c +++ b/components/esp_hal_ledc/esp32c5/ledc_periph.c @@ -28,157 +28,3 @@ const ledc_signal_conn_t ledc_periph_signal[1] = { }, } }; - -/** - * LEDC registers to be saved for sleep retention - * - * channel: - * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, - * LEDC_CHx_GAMMA_CONF_REG, LEDC_CHx_GAMMA_RANGEi_REG - * - * timer: - * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, - * - * common: - * LEDC_INT_ENA_REG, - * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, - * LEDC_CONF_REG, - * - * Note 1: Gamma parameter registers are backuped and restored. But we won't start a fade automatically after wake-up. - * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. - * - * Note 2: For timer/channel registers to get synced, update bits need to be set - * - * Note 3: Gamma RAM registers R/W relies both APB and function clock, therefore, retention requires the existence of function clock - */ -#define LEDC_COMMON_RETENTION_REGS_CNT 5 -#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) -static const uint32_t ledc_common_regs_map[4] = {0x1c00001, 0x400, 0x0, 0x0}; -static const regdma_entries_config_t ledc_common_regdma_entries[] = { - // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). - // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. - [0] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), - LEDC_INT_ENA_REG, 0, - (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M), 0, 1), - .owner = LEDC_RETENTION_ENTRY - }, - [1] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), - LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, - LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, - ledc_common_regs_map[0], ledc_common_regs_map[1], - ledc_common_regs_map[2], ledc_common_regs_map[3]), - .owner = LEDC_RETENTION_ENTRY - }, -}; - -#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ - LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 -static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; -static const uint32_t ledc_channel_gamma_regs_map[4] = {0xffff, 0x0, 0x0, 0x0}; -#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ - [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ - LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ - ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ - ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ - LEDC_DUTY_START_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ - LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ - LEDC_PARA_UP_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x04), \ - LEDC_CH##chan##_GAMMA_CONF_REG, LEDC_CH##chan##_GAMMA_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [5] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x05), \ - LEDC_CH##chan##_GAMMA_RANGE0_REG, LEDC_CH##chan##_GAMMA_RANGE0_REG, \ - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX, 0, 0, \ - ledc_channel_gamma_regs_map[0], ledc_channel_gamma_regs_map[1], \ - ledc_channel_gamma_regs_map[2], ledc_channel_gamma_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); - -static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); -static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); -static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); - -const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ - .common = { - .regdma_entry_array = ledc_common_regdma_entries, - .array_size = ARRAY_SIZE(ledc_common_regdma_entries), - }, - .timer[0] = { - .regdma_entry_array = ledc_timer0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), - }, - .timer[1] = { - .regdma_entry_array = ledc_timer1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), - }, - .timer[2] = { - .regdma_entry_array = ledc_timer2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), - }, - .timer[3] = { - .regdma_entry_array = ledc_timer3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), - }, - .channel[0] = { - .regdma_entry_array = ledc_channel0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), - }, - .channel[1] = { - .regdma_entry_array = ledc_channel1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), - }, - .channel[2] = { - .regdma_entry_array = ledc_channel2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), - }, - .channel[3] = { - .regdma_entry_array = ledc_channel3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), - }, - .channel[4] = { - .regdma_entry_array = ledc_channel4_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), - }, - .channel[5] = { - .regdma_entry_array = ledc_channel5_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), - }, - .module_id = SLEEP_RETENTION_MODULE_LEDC, - } -}; diff --git a/components/esp_hal_ledc/esp32c6/ledc_periph.c b/components/esp_hal_ledc/esp32c6/ledc_periph.c index e63da7ee7e3..67e01cd9d18 100644 --- a/components/esp_hal_ledc/esp32c6/ledc_periph.c +++ b/components/esp_hal_ledc/esp32c6/ledc_periph.c @@ -28,146 +28,3 @@ const ledc_signal_conn_t ledc_periph_signal[1] = { }, } }; - -/** - * LEDC registers to be saved for sleep retention - * - * channel: - * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, - * - * timer: - * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, - * - * common: - * LEDC_INT_ENA_REG, - * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, - * LEDC_CONF_REG, - * - * Note 1: Gamma feature is hard to do hardware retention, will consider to use software to do the backup and restore. - * We won't start a fade automatically after wake-up. - * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. - * - * Note 2: For timer/channel registers to get synced, update bits need to be set - * - * Note 3: Retention backup/restore does not rely on LEDC function clock enabled - */ -#define LEDC_COMMON_RETENTION_REGS_CNT 5 -#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) -static const uint32_t ledc_common_regs_map[4] = {0x1, 0x1c00000, 0x400, 0x0}; -static const regdma_entries_config_t ledc_common_regdma_entries[] = { - // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). - // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. - [0] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), - LEDC_INT_ENA_REG, 0, - (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M), 0, 1), - .owner = LEDC_RETENTION_ENTRY - }, - [1] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), - LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, - LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, - ledc_common_regs_map[0], ledc_common_regs_map[1], - ledc_common_regs_map[2], ledc_common_regs_map[3]), - .owner = LEDC_RETENTION_ENTRY - }, -}; - -#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ - LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 -static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; -#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ - [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ - LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ - ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ - ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ - LEDC_DUTY_START_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ - LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ - LEDC_PARA_UP_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); - -static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); -static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); -static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); - -const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ - .common = { - .regdma_entry_array = ledc_common_regdma_entries, - .array_size = ARRAY_SIZE(ledc_common_regdma_entries), - }, - .timer[0] = { - .regdma_entry_array = ledc_timer0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), - }, - .timer[1] = { - .regdma_entry_array = ledc_timer1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), - }, - .timer[2] = { - .regdma_entry_array = ledc_timer2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), - }, - .timer[3] = { - .regdma_entry_array = ledc_timer3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), - }, - .channel[0] = { - .regdma_entry_array = ledc_channel0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), - }, - .channel[1] = { - .regdma_entry_array = ledc_channel1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), - }, - .channel[2] = { - .regdma_entry_array = ledc_channel2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), - }, - .channel[3] = { - .regdma_entry_array = ledc_channel3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), - }, - .channel[4] = { - .regdma_entry_array = ledc_channel4_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), - }, - .channel[5] = { - .regdma_entry_array = ledc_channel5_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), - }, - .module_id = SLEEP_RETENTION_MODULE_LEDC, - } -}; diff --git a/components/esp_hal_ledc/esp32c61/ledc_periph.c b/components/esp_hal_ledc/esp32c61/ledc_periph.c index a348bee6cea..6be36a5130c 100644 --- a/components/esp_hal_ledc/esp32c61/ledc_periph.c +++ b/components/esp_hal_ledc/esp32c61/ledc_periph.c @@ -28,157 +28,3 @@ const ledc_signal_conn_t ledc_periph_signal[1] = { }, } }; - -/** - * LEDC registers to be saved for sleep retention - * - * channel: - * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, - * LEDC_CHx_GAMMA_CONF_REG, LEDC_CHx_GAMMA_RANGEi_REG - * - * timer: - * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, - * - * common: - * LEDC_INT_ENA_REG, - * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, - * LEDC_CONF_REG, - * - * Note 1: Gamma parameter registers are backuped and restored. But we won't start a fade automatically after wake-up. - * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. - * - * Note 2: For timer/channel registers to get synced, update bits need to be set - * - * Note 3: Gamma RAM registers R/W relies both APB and function clock, therefore, retention requires the existence of function clock - */ -#define LEDC_COMMON_RETENTION_REGS_CNT 5 -#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) -static const uint32_t ledc_common_regs_map[4] = {0x1c00001, 0x400, 0x0, 0x0}; -static const regdma_entries_config_t ledc_common_regdma_entries[] = { - // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). - // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. - [0] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), - LEDC_INT_ENA_REG, 0, - (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M), 0, 1), - .owner = LEDC_RETENTION_ENTRY - }, - [1] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), - LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, - LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, - ledc_common_regs_map[0], ledc_common_regs_map[1], - ledc_common_regs_map[2], ledc_common_regs_map[3]), - .owner = LEDC_RETENTION_ENTRY - }, -}; - -#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ - LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 -static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; -static const uint32_t ledc_channel_gamma_regs_map[4] = {0xffff, 0x0, 0x0, 0x0}; -#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ - [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ - LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ - ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ - ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ - LEDC_DUTY_START_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ - LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ - LEDC_PARA_UP_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x04), \ - LEDC_CH##chan##_GAMMA_CONF_REG, LEDC_CH##chan##_GAMMA_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [5] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x05), \ - LEDC_CH##chan##_GAMMA_RANGE0_REG, LEDC_CH##chan##_GAMMA_RANGE0_REG, \ - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX, 0, 0, \ - ledc_channel_gamma_regs_map[0], ledc_channel_gamma_regs_map[1], \ - ledc_channel_gamma_regs_map[2], ledc_channel_gamma_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); - -static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); -static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); -static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); - -const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ - .common = { - .regdma_entry_array = ledc_common_regdma_entries, - .array_size = ARRAY_SIZE(ledc_common_regdma_entries), - }, - .timer[0] = { - .regdma_entry_array = ledc_timer0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), - }, - .timer[1] = { - .regdma_entry_array = ledc_timer1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), - }, - .timer[2] = { - .regdma_entry_array = ledc_timer2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), - }, - .timer[3] = { - .regdma_entry_array = ledc_timer3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), - }, - .channel[0] = { - .regdma_entry_array = ledc_channel0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), - }, - .channel[1] = { - .regdma_entry_array = ledc_channel1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), - }, - .channel[2] = { - .regdma_entry_array = ledc_channel2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), - }, - .channel[3] = { - .regdma_entry_array = ledc_channel3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), - }, - .channel[4] = { - .regdma_entry_array = ledc_channel4_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), - }, - .channel[5] = { - .regdma_entry_array = ledc_channel5_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), - }, - .module_id = SLEEP_RETENTION_MODULE_LEDC, - } -}; diff --git a/components/esp_hal_ledc/esp32h2/ledc_periph.c b/components/esp_hal_ledc/esp32h2/ledc_periph.c index e63da7ee7e3..67e01cd9d18 100644 --- a/components/esp_hal_ledc/esp32h2/ledc_periph.c +++ b/components/esp_hal_ledc/esp32h2/ledc_periph.c @@ -28,146 +28,3 @@ const ledc_signal_conn_t ledc_periph_signal[1] = { }, } }; - -/** - * LEDC registers to be saved for sleep retention - * - * channel: - * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, - * - * timer: - * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, - * - * common: - * LEDC_INT_ENA_REG, - * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, - * LEDC_CONF_REG, - * - * Note 1: Gamma feature is hard to do hardware retention, will consider to use software to do the backup and restore. - * We won't start a fade automatically after wake-up. - * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. - * - * Note 2: For timer/channel registers to get synced, update bits need to be set - * - * Note 3: Retention backup/restore does not rely on LEDC function clock enabled - */ -#define LEDC_COMMON_RETENTION_REGS_CNT 5 -#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) -static const uint32_t ledc_common_regs_map[4] = {0x1, 0x1c00000, 0x400, 0x0}; -static const regdma_entries_config_t ledc_common_regdma_entries[] = { - // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). - // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. - [0] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), - LEDC_INT_ENA_REG, 0, - (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M), 0, 1), - .owner = LEDC_RETENTION_ENTRY - }, - [1] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), - LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, - LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, - ledc_common_regs_map[0], ledc_common_regs_map[1], - ledc_common_regs_map[2], ledc_common_regs_map[3]), - .owner = LEDC_RETENTION_ENTRY - }, -}; - -#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ - LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 -static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; -#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ - [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ - LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ - ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ - ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ - LEDC_DUTY_START_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ - LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ - LEDC_PARA_UP_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); - -static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); -static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); -static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); - -const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ - .common = { - .regdma_entry_array = ledc_common_regdma_entries, - .array_size = ARRAY_SIZE(ledc_common_regdma_entries), - }, - .timer[0] = { - .regdma_entry_array = ledc_timer0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), - }, - .timer[1] = { - .regdma_entry_array = ledc_timer1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), - }, - .timer[2] = { - .regdma_entry_array = ledc_timer2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), - }, - .timer[3] = { - .regdma_entry_array = ledc_timer3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), - }, - .channel[0] = { - .regdma_entry_array = ledc_channel0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), - }, - .channel[1] = { - .regdma_entry_array = ledc_channel1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), - }, - .channel[2] = { - .regdma_entry_array = ledc_channel2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), - }, - .channel[3] = { - .regdma_entry_array = ledc_channel3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), - }, - .channel[4] = { - .regdma_entry_array = ledc_channel4_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), - }, - .channel[5] = { - .regdma_entry_array = ledc_channel5_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), - }, - .module_id = SLEEP_RETENTION_MODULE_LEDC, - } -}; diff --git a/components/esp_hal_ledc/esp32h21/ledc_periph.c b/components/esp_hal_ledc/esp32h21/ledc_periph.c index 38d428044bc..6be36a5130c 100644 --- a/components/esp_hal_ledc/esp32h21/ledc_periph.c +++ b/components/esp_hal_ledc/esp32h21/ledc_periph.c @@ -28,146 +28,3 @@ const ledc_signal_conn_t ledc_periph_signal[1] = { }, } }; - -/** - * LEDC registers to be saved for sleep retention - * - * channel: - * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, - * - * timer: - * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, - * - * common: - * LEDC_INT_ENA_REG, - * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, - * LEDC_CONF_REG, - * - * Note 1: Gamma feature is hard to do hardware retention, will consider to use software to do the backup and restore. - * We won't start a fade automatically after wake-up. - * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. - * - * Note 2: For timer/channel registers to get synced, update bits need to be set - * - * Note 3: Retention backup/restore does not rely on LEDC function clock enabled - */ -#define LEDC_COMMON_RETENTION_REGS_CNT 5 -#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) -static const uint32_t ledc_common_regs_map[4] = {0x1, 0x1c00000, 0x400, 0x0}; -static const regdma_entries_config_t ledc_common_regdma_entries[] = { - // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). - // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. - [0] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), - LEDC_INT_ENA_REG, 0, - (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M), 0, 1), - .owner = LEDC_RETENTION_ENTRY - }, - [1] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), - LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, - LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, - ledc_common_regs_map[0], ledc_common_regs_map[1], - ledc_common_regs_map[2], ledc_common_regs_map[3]), - .owner = LEDC_RETENTION_ENTRY - }, -}; - -#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ - LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 -static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; -#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ - [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ - LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ - ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ - ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ - LEDC_DUTY_START_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ - LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ - LEDC_PARA_UP_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); - -static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); -static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); -static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); - -const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ - .common = { - .regdma_entry_array = ledc_common_regdma_entries, - .array_size = ARRAY_SIZE(ledc_common_regdma_entries), - }, - .timer[0] = { - .regdma_entry_array = ledc_timer0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), - }, - .timer[1] = { - .regdma_entry_array = ledc_timer1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), - }, - .timer[2] = { - .regdma_entry_array = ledc_timer2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), - }, - .timer[3] = { - .regdma_entry_array = ledc_timer3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), - }, - .channel[0] = { - .regdma_entry_array = ledc_channel0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), - }, - .channel[1] = { - .regdma_entry_array = ledc_channel1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), - }, - .channel[2] = { - .regdma_entry_array = ledc_channel2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), - }, - .channel[3] = { - .regdma_entry_array = ledc_channel3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), - }, - .channel[4] = { - .regdma_entry_array = ledc_channel4_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), - }, - .channel[5] = { - .regdma_entry_array = ledc_channel5_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), - }, - .module_id = SLEEP_RETENTION_MODULE_LEDC, - } -}; diff --git a/components/esp_hal_ledc/esp32h4/ledc_periph.c b/components/esp_hal_ledc/esp32h4/ledc_periph.c index c55a1d45770..dc80067c807 100644 --- a/components/esp_hal_ledc/esp32h4/ledc_periph.c +++ b/components/esp_hal_ledc/esp32h4/ledc_periph.c @@ -30,168 +30,3 @@ const ledc_signal_conn_t ledc_periph_signal[1] = { }, } }; - -/** - * LEDC registers to be saved for sleep retention - * - * channel: - * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, - * LEDC_CHx_FADE_CONF_REG, LEDC_CHx_FADE_PARAM_REG - * - * timer: - * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, - * - * common: - * LEDC_INT_ENA_REG, - * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, - * LEDC_CONF_REG, - * LEDC_CH_POWER_UP_CONF_REG, LEDC_TIMER_POWER_UP_CONF_REG - * - * Note 1: Fade parameter registers are backuped and restored. But we won't start a fade automatically after wake-up. - * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. - * - * Note 2: For timer/channel registers to get synced, update bits need to be set - * - * Note 3: Retention backup/restore does not rely on LEDC function clock enabled - */ -#define LEDC_COMMON_RETENTION_REGS_CNT 7 -#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) -static const uint32_t ledc_common_regs_map[4] = {0x1c00001, 0x1c00, 0x0, 0x0}; -static const regdma_entries_config_t ledc_common_regdma_entries[] = { - // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). - // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. - [0] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), - LEDC_INT_ENA_REG, 0, - (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M | LEDC_DUTY_CHNG_END_CH6_INT_ENA_M | LEDC_DUTY_CHNG_END_CH7_INT_ENA_M), 0, 1), - .owner = LEDC_RETENTION_ENTRY - }, - [1] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), - LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, - LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, - ledc_common_regs_map[0], ledc_common_regs_map[1], - ledc_common_regs_map[2], ledc_common_regs_map[3]), - .owner = LEDC_RETENTION_ENTRY - }, -}; - -#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ - LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 -static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; -static const uint32_t ledc_channel_gamma_regs_map[4] = {0x1, 0x0, 0x0, 0x0}; -#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ - [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ - LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ - ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ - ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ - LEDC_DUTY_START_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ - LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ - LEDC_PARA_UP_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x04), \ - LEDC_CH##chan##_FADE_CONF_REG, LEDC_CH##chan##_FADE_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [5] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x05), \ - LEDC_CH##chan##_FADE_PARAM_REG, LEDC_CH##chan##_FADE_PARAM_REG, \ - 1, 0, 0, \ - ledc_channel_gamma_regs_map[0], ledc_channel_gamma_regs_map[1], \ - ledc_channel_gamma_regs_map[2], ledc_channel_gamma_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); - -static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); -static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); -static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); -static const regdma_entries_config_t ledc_channel6_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(6); -static const regdma_entries_config_t ledc_channel7_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(7); - -const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ - .common = { - .regdma_entry_array = ledc_common_regdma_entries, - .array_size = ARRAY_SIZE(ledc_common_regdma_entries), - }, - .timer[0] = { - .regdma_entry_array = ledc_timer0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), - }, - .timer[1] = { - .regdma_entry_array = ledc_timer1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), - }, - .timer[2] = { - .regdma_entry_array = ledc_timer2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), - }, - .timer[3] = { - .regdma_entry_array = ledc_timer3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), - }, - .channel[0] = { - .regdma_entry_array = ledc_channel0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), - }, - .channel[1] = { - .regdma_entry_array = ledc_channel1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), - }, - .channel[2] = { - .regdma_entry_array = ledc_channel2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), - }, - .channel[3] = { - .regdma_entry_array = ledc_channel3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), - }, - .channel[4] = { - .regdma_entry_array = ledc_channel4_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), - }, - .channel[5] = { - .regdma_entry_array = ledc_channel5_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), - }, - .channel[6] = { - .regdma_entry_array = ledc_channel6_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel6_regdma_entries), - }, - .channel[7] = { - .regdma_entry_array = ledc_channel7_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel7_regdma_entries), - }, - .module_id = SLEEP_RETENTION_MODULE_LEDC, - } -}; diff --git a/components/esp_hal_ledc/esp32p4/ledc_periph.c b/components/esp_hal_ledc/esp32p4/ledc_periph.c index 96231d56703..46607d79883 100644 --- a/components/esp_hal_ledc/esp32p4/ledc_periph.c +++ b/components/esp_hal_ledc/esp32p4/ledc_periph.c @@ -30,167 +30,3 @@ const ledc_signal_conn_t ledc_periph_signal[1] = { }, } }; - -/** - * LEDC registers to be saved for sleep retention - * - * channel: - * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, - * LEDC_CHx_GAMMA_CONF_REG, LEDC_CHx_GAMMA_RANGEi_REG - * - * timer: - * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, - * - * common: - * LEDC_INT_ENA_REG, - * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, - * LEDC_CONF_REG, - * - * Note 1: Gamma parameter registers are backuped and restored. But we won't start a fade automatically after wake-up. - * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. - * - * Note 2: For timer/channel registers to get synced, update bits need to be set - * - * Note 3: Gamma RAM registers R/W relies both APB and function clock, therefore, retention requires the existence of function clock - */ -#define LEDC_COMMON_RETENTION_REGS_CNT 5 -#define LEDC_COMMON_RETENTION_REGS_BASE (DR_REG_LEDC_BASE + 0xc8) -static const uint32_t ledc_common_regs_map[4] = {0x1c00001, 0x400, 0x0, 0x0}; -static const regdma_entries_config_t ledc_common_regdma_entries[] = { - // If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). - // Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. - [0] = { - .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), - LEDC_INT_ENA_REG, 0, - (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M | LEDC_DUTY_CHNG_END_CH6_INT_ENA_M | LEDC_DUTY_CHNG_END_CH7_INT_ENA_M), 0, 1), - .owner = LEDC_RETENTION_ENTRY - }, - [1] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), - LEDC_COMMON_RETENTION_REGS_BASE, LEDC_COMMON_RETENTION_REGS_BASE, - LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, - ledc_common_regs_map[0], ledc_common_regs_map[1], - ledc_common_regs_map[2], ledc_common_regs_map[3]), - .owner = LEDC_RETENTION_ENTRY - }, -}; - -#define LEDC_TIMER_RETENTION_ENTRIES(timer) { \ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_TIMER##timer##_CMP_REG, LEDC_TIMER##timer##_CMP_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_TIMER##timer##_CONF_REG, LEDC_TIMER##timer##_PARA_UP, \ - LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 -static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; -static const uint32_t ledc_channel_gamma_regs_map[4] = {0xffff, 0x0, 0x0, 0x0}; -#define LEDC_CHANNEL_RETENTION_ENTRIES(chan) { \ - [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_CH##chan##_CONF0_REG, LEDC_CH##chan##_CONF0_REG, \ - LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ - ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ - ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_CH##chan##_DUTY_R_REG, LEDC_CH##chan##_DUTY_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_CH##chan##_CONF1_REG, LEDC_DUTY_START_CH##chan, \ - LEDC_DUTY_START_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ - LEDC_CH##chan##_CONF0_REG, LEDC_PARA_UP_CH##chan, \ - LEDC_PARA_UP_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x04), \ - LEDC_CH##chan##_GAMMA_CONF_REG, LEDC_CH##chan##_GAMMA_CONF_REG, \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [5] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x05), \ - LEDC_CH##chan##_GAMMA_RANGE0_REG, LEDC_CH##chan##_GAMMA_RANGE0_REG, \ - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX, 0, 0, \ - ledc_channel_gamma_regs_map[0], ledc_channel_gamma_regs_map[1], \ - ledc_channel_gamma_regs_map[2], ledc_channel_gamma_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -static const regdma_entries_config_t ledc_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(3); - -static const regdma_entries_config_t ledc_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0); -static const regdma_entries_config_t ledc_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1); -static const regdma_entries_config_t ledc_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(2); -static const regdma_entries_config_t ledc_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(3); -static const regdma_entries_config_t ledc_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(4); -static const regdma_entries_config_t ledc_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(5); -static const regdma_entries_config_t ledc_channel6_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(6); -static const regdma_entries_config_t ledc_channel7_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(7); - -const ledc_reg_retention_info_t ledc_reg_retention_info[1] = {{ - .common = { - .regdma_entry_array = ledc_common_regdma_entries, - .array_size = ARRAY_SIZE(ledc_common_regdma_entries), - }, - .timer[0] = { - .regdma_entry_array = ledc_timer0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer0_regdma_entries), - }, - .timer[1] = { - .regdma_entry_array = ledc_timer1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer1_regdma_entries), - }, - .timer[2] = { - .regdma_entry_array = ledc_timer2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer2_regdma_entries), - }, - .timer[3] = { - .regdma_entry_array = ledc_timer3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_timer3_regdma_entries), - }, - .channel[0] = { - .regdma_entry_array = ledc_channel0_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel0_regdma_entries), - }, - .channel[1] = { - .regdma_entry_array = ledc_channel1_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel1_regdma_entries), - }, - .channel[2] = { - .regdma_entry_array = ledc_channel2_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel2_regdma_entries), - }, - .channel[3] = { - .regdma_entry_array = ledc_channel3_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel3_regdma_entries), - }, - .channel[4] = { - .regdma_entry_array = ledc_channel4_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel4_regdma_entries), - }, - .channel[5] = { - .regdma_entry_array = ledc_channel5_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel5_regdma_entries), - }, - .channel[6] = { - .regdma_entry_array = ledc_channel6_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel6_regdma_entries), - }, - .channel[7] = { - .regdma_entry_array = ledc_channel7_regdma_entries, - .array_size = ARRAY_SIZE(ledc_channel7_regdma_entries), - }, - .module_id = SLEEP_RETENTION_MODULE_LEDC, - } -}; diff --git a/components/esp_hal_ledc/esp32s31/ledc_periph.c b/components/esp_hal_ledc/esp32s31/ledc_periph.c index 74836eb4a54..6860a9dd820 100644 --- a/components/esp_hal_ledc/esp32s31/ledc_periph.c +++ b/components/esp_hal_ledc/esp32s31/ledc_periph.c @@ -47,238 +47,3 @@ const ledc_signal_conn_t ledc_periph_signal[2] = { }, }, }; - -/** - * LEDC registers to be saved for sleep retention - * - * channel: - * LEDC_CHx_CONF0_REG, LEDC_CHx_HPOINT_REG, LEDC_CHx_DUTY_R_REG -> LEDC_CHx_DUTY_REG, - * LEDC_CHx_GAMMA_CONF_REG, LEDC_CHx_GAMMA_RANGEi_REG - * - * timer: - * LEDC_TIMERn_CONF_REG, LEDC_TIMERn_CMP_REG, - * - * common: - * LEDC_INT_ENA_REG, - * LEDC_EVT_TASK_EN0_REG, LEDC_EVT_TASK_EN1_REG, LEDC_EVT_TASK_EN2_REG, - * LEDC_CONF_REG, - * LEDC_CH_POWER_UP_CONF_REG, LEDC_TIMER_POWER_UP_CONF_REG - * - * Note 1: Gamma parameter registers are backuped and restored. But we won't start a fade automatically after wake-up. - * Instead, we will only start a PWM with a fixed duty cycle, the same value as before entering the sleep. - * - * Note 2: For timer/channel registers to get synced, update bits need to be set - * - * Note 3: Gamma RAM registers R/W relies both APB and function clock, therefore, retention requires the existence of function clock - */ -#define LEDC_COMMON_RETENTION_REGS_CNT 7 -#define LEDC_COMMON_RETENTION_REGS_BASE(i) (DR_REG_LEDC_BASE(i) + 0xc8) -static const uint32_t ledc_common_regs_map[4] = {0x1c00001, 0x1c00, 0x0, 0x0}; -// If a fade is in process, the DUTY_CHNG_END_CHx intr bit is enabled, however, we don't want it to be restored after wake-up (no fade after wake-up). -// Therefore, we can set it to 0 before backup the LEDC_INT_ENA_REG. -#define LEDC_COMMON_RETENTION_ENTRIES(i) { \ - [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_INT_ENA_REG(i), 0, \ - (LEDC_DUTY_CHNG_END_CH0_INT_ENA_M | LEDC_DUTY_CHNG_END_CH1_INT_ENA_M | LEDC_DUTY_CHNG_END_CH2_INT_ENA_M | LEDC_DUTY_CHNG_END_CH3_INT_ENA_M | LEDC_DUTY_CHNG_END_CH4_INT_ENA_M | LEDC_DUTY_CHNG_END_CH5_INT_ENA_M | LEDC_DUTY_CHNG_END_CH6_INT_ENA_M | LEDC_DUTY_CHNG_END_CH7_INT_ENA_M), 0, 1), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_COMMON_RETENTION_REGS_BASE(i), LEDC_COMMON_RETENTION_REGS_BASE(i), \ - LEDC_COMMON_RETENTION_REGS_CNT, 0, 0, \ - ledc_common_regs_map[0], ledc_common_regs_map[1], \ - ledc_common_regs_map[2], ledc_common_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -#define LEDC_TIMER_RETENTION_ENTRIES(i, timer) { \ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_TIMER##timer##_CONF_REG(i), LEDC_TIMER##timer##_CONF_REG(i), \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_TIMER##timer##_CMP_REG(i), LEDC_TIMER##timer##_CMP_REG(i), \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_TIMER##timer##_CONF_REG(i), LEDC_TIMER##timer##_PARA_UP, \ - LEDC_TIMER##timer##_PARA_UP_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -#define LEDC_CHANNEL_RETENTION_REGS_CNT 2 -static const uint32_t ledc_channel_regs_map[4] = {0x3, 0x0, 0x0, 0x0}; -static const uint32_t ledc_channel_gamma_regs_map[4] = {0xffff, 0x0, 0x0, 0x0}; -#define LEDC_CHANNEL_RETENTION_ENTRIES(i, chan) { \ - [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x00), \ - LEDC_CH##chan##_CONF0_REG(i), LEDC_CH##chan##_CONF0_REG(i), \ - LEDC_CHANNEL_RETENTION_REGS_CNT, 0, 0, \ - ledc_channel_regs_map[0], ledc_channel_regs_map[1], \ - ledc_channel_regs_map[2], ledc_channel_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x01), \ - LEDC_CH##chan##_DUTY_R_REG(i), LEDC_CH##chan##_DUTY_REG(i), \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x02), \ - LEDC_CH##chan##_CONF1_REG(i), LEDC_DUTY_START_CH##chan, \ - LEDC_DUTY_START_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_LEDC_LINK(0x03), \ - LEDC_CH##chan##_CONF0_REG(i), LEDC_PARA_UP_CH##chan, \ - LEDC_PARA_UP_CH##chan##_M, 1, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_LEDC_LINK(0x04), \ - LEDC_CH##chan##_GAMMA_CONF_REG(i), LEDC_CH##chan##_GAMMA_CONF_REG(i), \ - 1, 0, 0), \ - .owner = LEDC_RETENTION_ENTRY }, \ - [5] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LEDC_LINK(0x05), \ - LEDC_CH##chan##_GAMMA_RANGE0_REG(i), LEDC_CH##chan##_GAMMA_RANGE0_REG(i), \ - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX, 0, 0, \ - ledc_channel_gamma_regs_map[0], ledc_channel_gamma_regs_map[1], \ - ledc_channel_gamma_regs_map[2], ledc_channel_gamma_regs_map[3]), \ - .owner = LEDC_RETENTION_ENTRY }, \ -} - -static const regdma_entries_config_t ledc0_common_regdma_entries[] = LEDC_COMMON_RETENTION_ENTRIES(0); - -static const regdma_entries_config_t ledc0_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0, 0); -static const regdma_entries_config_t ledc0_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0, 1); -static const regdma_entries_config_t ledc0_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0, 2); -static const regdma_entries_config_t ledc0_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(0, 3); - -static const regdma_entries_config_t ledc0_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 0); -static const regdma_entries_config_t ledc0_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 1); -static const regdma_entries_config_t ledc0_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 2); -static const regdma_entries_config_t ledc0_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 3); -static const regdma_entries_config_t ledc0_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 4); -static const regdma_entries_config_t ledc0_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 5); -static const regdma_entries_config_t ledc0_channel6_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 6); -static const regdma_entries_config_t ledc0_channel7_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(0, 7); - -static const regdma_entries_config_t ledc1_common_regdma_entries[] = LEDC_COMMON_RETENTION_ENTRIES(1); - -static const regdma_entries_config_t ledc1_timer0_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1, 0); -static const regdma_entries_config_t ledc1_timer1_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1, 1); -static const regdma_entries_config_t ledc1_timer2_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1, 2); -static const regdma_entries_config_t ledc1_timer3_regdma_entries[] = LEDC_TIMER_RETENTION_ENTRIES(1, 3); - -static const regdma_entries_config_t ledc1_channel0_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 0); -static const regdma_entries_config_t ledc1_channel1_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 1); -static const regdma_entries_config_t ledc1_channel2_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 2); -static const regdma_entries_config_t ledc1_channel3_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 3); -static const regdma_entries_config_t ledc1_channel4_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 4); -static const regdma_entries_config_t ledc1_channel5_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 5); -static const regdma_entries_config_t ledc1_channel6_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 6); -static const regdma_entries_config_t ledc1_channel7_regdma_entries[] = LEDC_CHANNEL_RETENTION_ENTRIES(1, 7); - -const ledc_reg_retention_info_t ledc_reg_retention_info[2] = { - { - .common = { - .regdma_entry_array = ledc0_common_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_common_regdma_entries), - }, - .timer[0] = { - .regdma_entry_array = ledc0_timer0_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_timer0_regdma_entries), - }, - .timer[1] = { - .regdma_entry_array = ledc0_timer1_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_timer1_regdma_entries), - }, - .timer[2] = { - .regdma_entry_array = ledc0_timer2_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_timer2_regdma_entries), - }, - .timer[3] = { - .regdma_entry_array = ledc0_timer3_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_timer3_regdma_entries), - }, - .channel[0] = { - .regdma_entry_array = ledc0_channel0_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_channel0_regdma_entries), - }, - .channel[1] = { - .regdma_entry_array = ledc0_channel1_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_channel1_regdma_entries), - }, - .channel[2] = { - .regdma_entry_array = ledc0_channel2_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_channel2_regdma_entries), - }, - .channel[3] = { - .regdma_entry_array = ledc0_channel3_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_channel3_regdma_entries), - }, - .channel[4] = { - .regdma_entry_array = ledc0_channel4_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_channel4_regdma_entries), - }, - .channel[5] = { - .regdma_entry_array = ledc0_channel5_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_channel5_regdma_entries), - }, - .channel[6] = { - .regdma_entry_array = ledc0_channel6_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_channel6_regdma_entries), - }, - .channel[7] = { - .regdma_entry_array = ledc0_channel7_regdma_entries, - .array_size = ARRAY_SIZE(ledc0_channel7_regdma_entries), - }, - .module_id = SLEEP_RETENTION_MODULE_LEDC0, - }, - { - .common = { - .regdma_entry_array = ledc1_common_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_common_regdma_entries), - }, - .timer[0] = { - .regdma_entry_array = ledc1_timer0_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_timer0_regdma_entries), - }, - .timer[1] = { - .regdma_entry_array = ledc1_timer1_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_timer1_regdma_entries), - }, - .timer[2] = { - .regdma_entry_array = ledc1_timer2_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_timer2_regdma_entries), - }, - .timer[3] = { - .regdma_entry_array = ledc1_timer3_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_timer3_regdma_entries), - }, - .channel[0] = { - .regdma_entry_array = ledc1_channel0_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_channel0_regdma_entries), - }, - .channel[1] = { - .regdma_entry_array = ledc1_channel1_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_channel1_regdma_entries), - }, - .channel[2] = { - .regdma_entry_array = ledc1_channel2_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_channel2_regdma_entries), - }, - .channel[3] = { - .regdma_entry_array = ledc1_channel3_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_channel3_regdma_entries), - }, - .channel[4] = { - .regdma_entry_array = ledc1_channel4_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_channel4_regdma_entries), - }, - .channel[5] = { - .regdma_entry_array = ledc1_channel5_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_channel5_regdma_entries), - }, - .channel[6] = { - .regdma_entry_array = ledc1_channel6_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_channel6_regdma_entries), - }, - .channel[7] = { - .regdma_entry_array = ledc1_channel7_regdma_entries, - .array_size = ARRAY_SIZE(ledc1_channel7_regdma_entries), - }, - .module_id = SLEEP_RETENTION_MODULE_LEDC1, - }, -}; diff --git a/components/esp_hal_ledc/include/hal/ledc_periph.h b/components/esp_hal_ledc/include/hal/ledc_periph.h index afaa977fab4..2a28bdc3be4 100644 --- a/components/esp_hal_ledc/include/hal/ledc_periph.h +++ b/components/esp_hal_ledc/include/hal/ledc_periph.h @@ -12,10 +12,6 @@ #include "hal/ledc_ll.h" #include "hal/ledc_types.h" #endif -#if SOC_PAU_SUPPORTED -#include "soc/regdma.h" -#include "soc/retention_periph_defs.h" -#endif #ifdef __cplusplus extern "C" { @@ -34,33 +30,6 @@ typedef struct { extern const ledc_signal_conn_t ledc_periph_signal[LEDC_LL_GET(GROUP_NUM)]; -#if SOC_PAU_SUPPORTED && SOC_LEDC_SUPPORT_SLEEP_RETENTION - -#if SOC_LIGHT_SLEEP_SUPPORTED -#if SOC_PHY_SUPPORTED -#define LEDC_RETENTION_ENTRY (ENTRY(0) | ENTRY(2)) -#else -#define LEDC_RETENTION_ENTRY (ENTRY(0)) -#endif -#else // !SOC_LIGHT_SLEEP_SUPPORTED -#define LEDC_RETENTION_ENTRY REGDMA_SW_TRIGGER_ENTRY -#endif - -typedef struct { - const regdma_entries_config_t *regdma_entry_array; - uint32_t array_size; -} ledc_sub_reg_retention_info_t; - -typedef struct { - ledc_sub_reg_retention_info_t common; - ledc_sub_reg_retention_info_t timer[SOC_LEDC_TIMER_NUM]; - ledc_sub_reg_retention_info_t channel[SOC_LEDC_CHANNEL_NUM]; - const periph_retention_module_t module_id; -} ledc_reg_retention_info_t; - -extern const ledc_reg_retention_info_t ledc_reg_retention_info[LEDC_LL_GET(GROUP_NUM)]; -#endif // SOC_PAU_SUPPORTED && SOC_LEDC_SUPPORT_SLEEP_RETENTION - #endif // SOC_LEDC_SUPPORTED #ifdef __cplusplus