Skip to content

Commit

Permalink
Merge branch 'feat/rmt_sleep_retention_esp32p4' into 'master'
Browse files Browse the repository at this point in the history
feat(rmt): support sleep retention on esp32p4

Closes IDF-9936

See merge request espressif/esp-idf!31390
  • Loading branch information
suda-morris committed Jun 12, 2024
2 parents 11bbd9b + 31fd725 commit 15cebb6
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 4 deletions.
17 changes: 15 additions & 2 deletions components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "esp_timer.h"
#include "esp_sleep.h"
#include "esp_private/sleep_cpu.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/esp_pmu.h"
#include "test_util_rmt_encoders.h"
#include "test_board.h"

Expand Down Expand Up @@ -91,18 +93,29 @@ static void test_rmt_tx_rx_sleep_retention(bool back_up_before_sleep)

// Note: don't enable the RMT channel before going to sleep, ensure no power management lock is acquired by RMT

esp_sleep_context_t sleep_ctx;
esp_sleep_set_sleep_context(&sleep_ctx);
printf("go to light sleep for 2 seconds\r\n");
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP
#if ESP_SLEEP_POWER_DOWN_CPU
TEST_ESP_OK(sleep_cpu_configure(true));
#endif
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(2 * 1000 * 1000));
TEST_ESP_OK(esp_light_sleep_start());

printf("Waked up! Let's see if RMT driver can still work...\r\n");
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP
#if ESP_SLEEP_POWER_DOWN_CPU
TEST_ESP_OK(sleep_cpu_configure(false));
#endif

printf("check if the sleep happened as expected\r\n");
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
#if SOC_RMT_SUPPORT_SLEEP_RETENTION
if (back_up_before_sleep) {
printf("sleep_ctx.sleep_flags=%lx\r\n", sleep_ctx.sleep_flags);
TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP);
}
#endif

TEST_ESP_OK(rmt_enable(tx_channel));
TEST_ESP_OK(rmt_enable(rx_channel));

Expand Down
3 changes: 3 additions & 0 deletions components/esp_driver_rmt/test_apps/rmt/sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_UNITY_ENABLE_64BIT=y
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096

# primitives for checking sleep internal state
CONFIG_ESP_SLEEP_DEBUG=y
2 changes: 2 additions & 0 deletions components/hal/esp32p4/include/hal/rmt_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ extern "C" {
#define RMT_LL_EVENT_TX_MASK(channel) (RMT_LL_EVENT_TX_DONE(channel) | RMT_LL_EVENT_TX_THRES(channel) | RMT_LL_EVENT_TX_LOOP_END(channel))
#define RMT_LL_EVENT_RX_MASK(channel) (RMT_LL_EVENT_RX_DONE(channel) | RMT_LL_EVENT_RX_THRES(channel))

#define RMT_LL_SLEEP_RETENTION_MODULE_ID(group_id) (SLEEP_RETENTION_MODULE_RMT0)

#define RMT_LL_MAX_LOOP_COUNT_PER_BATCH 1023
#define RMT_LL_MAX_FILTER_VALUE 255
#define RMT_LL_MAX_IDLE_VALUE 32767
Expand Down
8 changes: 8 additions & 0 deletions components/soc/esp32p4/include/soc/Kconfig.soc_caps.in
Original file line number Diff line number Diff line change
Expand Up @@ -979,10 +979,18 @@ config SOC_RMT_SUPPORT_XTAL
bool
default y

config SOC_RMT_SUPPORT_RC_FAST
bool
default y

config SOC_RMT_SUPPORT_DMA
bool
default y

config SOC_RMT_SUPPORT_SLEEP_RETENTION
bool
default y

config SOC_LCD_I80_BUSES
int
default 1
Expand Down
3 changes: 3 additions & 0 deletions components/soc/esp32p4/include/soc/retention_periph_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ typedef enum periph_retention_module {
SLEEP_RETENTION_MODULE_UART2 = 9,
SLEEP_RETENTION_MODULE_UART3 = 10,
SLEEP_RETENTION_MODULE_UART4 = 11,
SLEEP_RETENTION_MODULE_RMT0 = 12,

SLEEP_RETENTION_MODULE_MAX = 31
} periph_retention_module_t;
Expand All @@ -52,6 +53,7 @@ typedef enum periph_retention_module_bitmap {
SLEEP_RETENTION_MODULE_BM_UART2 = BIT(SLEEP_RETENTION_MODULE_UART2),
SLEEP_RETENTION_MODULE_BM_UART3 = BIT(SLEEP_RETENTION_MODULE_UART3),
SLEEP_RETENTION_MODULE_BM_UART4 = BIT(SLEEP_RETENTION_MODULE_UART4),
SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0),

SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
} periph_retention_module_bitmap_t;
Expand All @@ -67,6 +69,7 @@ typedef enum periph_retention_module_bitmap {
| SLEEP_RETENTION_MODULE_BM_UART2 \
| SLEEP_RETENTION_MODULE_BM_UART3 \
| SLEEP_RETENTION_MODULE_BM_UART4 \
| SLEEP_RETENTION_MODULE_BM_RMT0 \
)

#ifdef __cplusplus
Expand Down
3 changes: 2 additions & 1 deletion components/soc/esp32p4/include/soc/soc_caps.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,9 @@
#define SOC_RMT_SUPPORT_TX_SYNCHRO 1 /*!< Support coordinate a group of TX channels to start simultaneously */
#define SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY 1 /*!< TX carrier can be modulated to data phase only */
#define SOC_RMT_SUPPORT_XTAL 1 /*!< Support set XTAL clock as the RMT clock source */
// #define SOC_RMT_SUPPORT_RC_FAST 1 /*!< Support set RC_FAST clock as the RMT clock source */
#define SOC_RMT_SUPPORT_RC_FAST 1 /*!< Support set RC_FAST clock as the RMT clock source */
#define SOC_RMT_SUPPORT_DMA 1 /*!< RMT peripheral can connect to DMA channel */
#define SOC_RMT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up RMT registers before sleep */

/*-------------------------- LCD CAPS ----------------------------------------*/
/* I80 bus and RGB timing generator can't work at the same time */
Expand Down
32 changes: 31 additions & 1 deletion components/soc/esp32p4/rmt_periph.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "soc/rmt_periph.h"
#include "soc/rmt_reg.h"
#include "soc/gpio_sig_map.h"

const rmt_signal_conn_t rmt_periph_signals = {
Expand Down Expand Up @@ -48,3 +49,32 @@ const rmt_signal_conn_t rmt_periph_signals = {
}
}
};

/**
* RMT Registers to be saved during sleep retention
* - Channel configuration registers, e.g.: RMT_CH0CONF0_REG, RMT_CH3CONF0_REG, RMT_CH3CONF1_REG, RMT_CH0_TX_LIM_REG, RMT_CH3_RX_LIM_REG
* - TX synchronization registers, e.g.: RMT_TX_SIM_REG
* - Interrupt enable registers, e.g.: RMT_INT_ENA_REG
* - Carrier duty registers, e.g.: RMT_CH0CARRIER_DUTY_REG, RMT_CH3_RX_CARRIER_RM_REG
* - Global configuration registers, e.g.: RMT_SYS_CONF_REG
*/
#define RMT_RETENTION_REGS_CNT 31
#define RMT_RETENTION_REGS_BASE (DR_REG_RMT_BASE + 0x20)
static const uint32_t rmt_regs_map[4] = {0xff400fff, 0x3ff, 0x0, 0x0};
static const regdma_entries_config_t rmt_regdma_entries[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_RMT_LINK(0x00),
RMT_RETENTION_REGS_BASE, RMT_RETENTION_REGS_BASE,
RMT_RETENTION_REGS_CNT, 0, 0,
rmt_regs_map[0], rmt_regs_map[1],
rmt_regs_map[2], rmt_regs_map[3]),
.owner = ENTRY(0),
},
};

const rmt_reg_retention_info_t rmt_reg_retention_info[SOC_RMT_GROUPS] = {
[0] = {
.regdma_entry_array = rmt_regdma_entries,
.array_size = ARRAY_SIZE(rmt_regdma_entries)
},
};

0 comments on commit 15cebb6

Please sign in to comment.