mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
feat(parlio): support sleep retention
This commit is contained in:
parent
e9fc43f5da
commit
b6645acafe
@ -41,6 +41,9 @@ typedef struct {
|
||||
i.e. high level of valid gpio to enable the clock output, low to disable */
|
||||
uint32_t io_loop_back: 1; /*!< For debug/test, the signal output from the GPIO will be fed to the input path as well */
|
||||
uint32_t io_no_init: 1 __attribute__((deprecated)); /*!< Deprecated. Driver won't change the GPIO configuration in inilization. */
|
||||
uint32_t allow_pd: 1; /*!< Set to allow power down. When this flag set, the driver will backup/restore the PARLIO registers before/after entering/exist sleep mode.
|
||||
By this approach, the system can power off PARLIO's power domain.
|
||||
This can save power, but at the expense of more RAM being consumed. */
|
||||
} flags; /*!< RX driver flags */
|
||||
} parlio_rx_unit_config_t;
|
||||
|
||||
|
@ -40,6 +40,9 @@ typedef struct {
|
||||
the output clock will be controlled by the MSB bit of the data bus,
|
||||
i.e. by data_gpio_nums[PARLIO_TX_UNIT_MAX_DATA_WIDTH-1]. High level to enable the clock output, low to disable */
|
||||
uint32_t io_loop_back: 1; /*!< For debug/test, the signal output from the GPIO will be fed to the input path as well */
|
||||
uint32_t allow_pd: 1; /*!< Set to allow power down. When this flag set, the driver will backup/restore the PARLIO registers before/after entering/exist sleep mode.
|
||||
By this approach, the system can power off PARLIO's power domain.
|
||||
This can save power, but at the expense of more RAM being consumed. */
|
||||
} flags; /*!< Extra configuration flags */
|
||||
} parlio_tx_unit_config_t;
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "soc/parlio_periph.h"
|
||||
#include "hal/parlio_ll.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#include "parlio_private.h"
|
||||
|
||||
static const char *TAG = "parlio";
|
||||
@ -46,6 +47,23 @@ parlio_group_t *parlio_acquire_group_handle(int group_id)
|
||||
parlio_ll_enable_bus_clock(group_id, true);
|
||||
parlio_ll_reset_register(group_id);
|
||||
}
|
||||
#if PARLIO_USE_RETENTION_LINK
|
||||
sleep_retention_module_t module_id = parlio_reg_retention_info[group_id].retention_module;
|
||||
sleep_retention_module_init_param_t init_param = {
|
||||
.cbs = {
|
||||
.create = {
|
||||
.handle = parlio_create_sleep_retention_link_cb,
|
||||
.arg = group,
|
||||
},
|
||||
},
|
||||
.depends = SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM
|
||||
};
|
||||
// we only do retention init here. Allocate retention module in the unit initialization
|
||||
if (sleep_retention_module_init(module_id, &init_param) != ESP_OK) {
|
||||
// even though the sleep retention module init failed, PARLIO driver should still work, so just warning here
|
||||
ESP_LOGW(TAG, "init sleep retention failed %d, power domain may be turned off during sleep", group_id);
|
||||
}
|
||||
#endif // PARLIO_USE_RETENTION_LINK
|
||||
// hal layer initialize
|
||||
parlio_hal_init(&group->hal);
|
||||
group->dma_align = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
||||
@ -87,6 +105,16 @@ void parlio_release_group_handle(parlio_group_t *group)
|
||||
_lock_release(&s_platform.mutex);
|
||||
|
||||
if (do_deinitialize) {
|
||||
#if PARLIO_USE_RETENTION_LINK
|
||||
const periph_retention_module_t module_id = parlio_reg_retention_info[group_id].retention_module;
|
||||
if (sleep_retention_get_created_modules() & BIT(module_id)) {
|
||||
assert(sleep_retention_get_inited_modules() & BIT(module_id));
|
||||
sleep_retention_module_free(module_id);
|
||||
}
|
||||
if (sleep_retention_get_inited_modules() & BIT(module_id)) {
|
||||
sleep_retention_module_deinit(module_id);
|
||||
}
|
||||
#endif // PARLIO_USE_RETENTION_LINK
|
||||
free(group);
|
||||
ESP_LOGD(TAG, "del group(%d)", group_id);
|
||||
}
|
||||
@ -147,3 +175,32 @@ void parlio_unregister_unit_from_group(parlio_unit_base_handle_t unit)
|
||||
/* the parlio unit has a reference of the group, release it now */
|
||||
parlio_release_group_handle(group);
|
||||
}
|
||||
|
||||
#if PARLIO_USE_RETENTION_LINK
|
||||
esp_err_t parlio_create_sleep_retention_link_cb(void *arg)
|
||||
{
|
||||
parlio_group_t *group = (parlio_group_t *)arg;
|
||||
int group_id = group->group_id;
|
||||
sleep_retention_module_t module_id = parlio_reg_retention_info[group_id].retention_module;
|
||||
esp_err_t err = sleep_retention_entries_create(parlio_reg_retention_info[group_id].regdma_entry_array,
|
||||
parlio_reg_retention_info[group_id].array_size,
|
||||
REGDMA_LINK_PRI_PARLIO, module_id);
|
||||
ESP_RETURN_ON_ERROR(err, TAG, "create retention link failed");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void parlio_create_retention_module(parlio_group_t *group)
|
||||
{
|
||||
int group_id = group->group_id;
|
||||
sleep_retention_module_t module_id = parlio_reg_retention_info[group_id].retention_module;
|
||||
|
||||
_lock_acquire(&s_platform.mutex);
|
||||
if ((sleep_retention_get_inited_modules() & BIT(module_id)) && !(sleep_retention_get_created_modules() & BIT(module_id))) {
|
||||
if (sleep_retention_module_allocate(module_id) != ESP_OK) {
|
||||
// even though the sleep retention module create failed, PARLIO driver should still work, so just warning here
|
||||
ESP_LOGW(TAG, "create retention module failed, power domain can't turn off");
|
||||
}
|
||||
}
|
||||
_lock_release(&s_platform.mutex);
|
||||
}
|
||||
#endif // PARLIO_USE_RETENTION_LINK
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/esp_gpio_reserve.h"
|
||||
#include "esp_private/gpio.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
|
||||
#if CONFIG_PARLIO_ISR_IRAM_SAFE
|
||||
#define PARLIO_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
|
||||
@ -44,6 +45,9 @@
|
||||
#define PARLIO_INTR_ALLOC_FLAG (ESP_INTR_FLAG_LOWMED | PARLIO_INTR_ALLOC_FLAG_SHARED)
|
||||
#endif
|
||||
|
||||
// Use retention link only when the target supports sleep retention is enabled
|
||||
#define PARLIO_USE_RETENTION_LINK (SOC_PARLIO_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
|
||||
|
||||
#if defined(SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS) // Parlio uses GDMA
|
||||
#if defined(SOC_GDMA_BUS_AHB) && (SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS == SOC_GDMA_BUS_AHB)
|
||||
typedef dma_descriptor_align4_t parlio_dma_desc_t;
|
||||
@ -149,6 +153,11 @@ esp_err_t parlio_register_unit_to_group(parlio_unit_base_handle_t unit);
|
||||
*/
|
||||
void parlio_unregister_unit_from_group(parlio_unit_base_handle_t unit);
|
||||
|
||||
#if PARLIO_USE_RETENTION_LINK
|
||||
esp_err_t parlio_create_sleep_retention_link_cb(void *arg);
|
||||
void parlio_create_retention_module(parlio_group_t *group);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -620,6 +620,10 @@ esp_err_t parlio_new_rx_unit(const parlio_rx_unit_config_t *config, parlio_rx_un
|
||||
esp_err_t ret = ESP_OK;
|
||||
parlio_rx_unit_handle_t unit = NULL;
|
||||
|
||||
#if !SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
ESP_RETURN_ON_FALSE(config->flags.allow_pd == 0, ESP_ERR_NOT_SUPPORTED, TAG, "register back up is not supported");
|
||||
#endif // SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
|
||||
/* Allocate unit memory */
|
||||
unit = heap_caps_calloc(1, sizeof(parlio_rx_unit_t), PARLIO_MEM_ALLOC_CAPS);
|
||||
ESP_GOTO_ON_FALSE(unit, ESP_ERR_NO_MEM, err, TAG, "no memory for rx unit");
|
||||
@ -676,6 +680,12 @@ esp_err_t parlio_new_rx_unit(const parlio_rx_unit_config_t *config, parlio_rx_un
|
||||
}
|
||||
#endif // SOC_PARLIO_RX_CLK_SUPPORT_GATING
|
||||
|
||||
#if PARLIO_USE_RETENTION_LINK
|
||||
if (config->flags.allow_pd != 0) {
|
||||
parlio_create_retention_module(group);
|
||||
}
|
||||
#endif // PARLIO_USE_RETENTION_LINK
|
||||
|
||||
/* return RX unit handle */
|
||||
*ret_unit = unit;
|
||||
|
||||
|
@ -270,7 +270,7 @@ static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const par
|
||||
#endif
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
PARLIO_CLOCK_SRC_ATOMIC() {
|
||||
// turn on the tx module clock to sync the register configuration to the module
|
||||
// turn on the tx module clock to sync the clock divider configuration because of the CDC (Cross Domain Crossing)
|
||||
parlio_ll_tx_enable_clock(hal->regs, true);
|
||||
parlio_ll_tx_set_clock_source(hal->regs, clk_src);
|
||||
// set clock division
|
||||
@ -309,6 +309,10 @@ esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_un
|
||||
ESP_RETURN_ON_FALSE(config->flags.clk_gate_en == 0, ESP_ERR_NOT_SUPPORTED, TAG, "clock gating is not supported");
|
||||
#endif // SOC_PARLIO_TX_CLK_SUPPORT_GATING
|
||||
|
||||
#if !SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
ESP_RETURN_ON_FALSE(config->flags.allow_pd == 0, ESP_ERR_NOT_SUPPORTED, TAG, "register back up is not supported");
|
||||
#endif // SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
|
||||
// malloc unit memory
|
||||
uint32_t mem_caps = PARLIO_MEM_ALLOC_CAPS;
|
||||
unit = heap_caps_calloc(1, sizeof(parlio_tx_unit_t) + sizeof(parlio_tx_trans_desc_t) * config->trans_queue_depth, mem_caps);
|
||||
@ -381,6 +385,12 @@ esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_un
|
||||
// GPIO Matrix/MUX configuration
|
||||
ESP_GOTO_ON_ERROR(parlio_tx_unit_configure_gpio(unit, config), err, TAG, "configure gpio failed");
|
||||
|
||||
#if PARLIO_USE_RETENTION_LINK
|
||||
if (config->flags.allow_pd != 0) {
|
||||
parlio_create_retention_module(group);
|
||||
}
|
||||
#endif // PARLIO_USE_RETENTION_LINK
|
||||
|
||||
portMUX_INITIALIZE(&unit->spinlock);
|
||||
atomic_init(&unit->fsm, PARLIO_TX_FSM_INIT);
|
||||
// return TX unit handle
|
||||
@ -468,13 +478,11 @@ static void IRAM_ATTR parlio_tx_do_transaction(parlio_tx_unit_t *tx_unit, parlio
|
||||
while (parlio_ll_tx_is_ready(hal->regs) == false);
|
||||
// turn on the core clock after we start the TX unit
|
||||
parlio_ll_tx_start(hal->regs, true);
|
||||
PARLIO_CLOCK_SRC_ATOMIC() {
|
||||
parlio_ll_tx_enable_clock(hal->regs, true);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t parlio_tx_unit_enable(parlio_tx_unit_handle_t tx_unit)
|
||||
{
|
||||
parlio_hal_context_t *hal = &tx_unit->base.group->hal;
|
||||
ESP_RETURN_ON_FALSE(tx_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
parlio_tx_fsm_t expected_fsm = PARLIO_TX_FSM_INIT;
|
||||
if (atomic_compare_exchange_strong(&tx_unit->fsm, &expected_fsm, PARLIO_TX_FSM_ENABLE_WAIT)) {
|
||||
@ -489,6 +497,11 @@ esp_err_t parlio_tx_unit_enable(parlio_tx_unit_handle_t tx_unit)
|
||||
ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "unit not in init state");
|
||||
}
|
||||
|
||||
// enable clock output
|
||||
PARLIO_CLOCK_SRC_ATOMIC() {
|
||||
parlio_ll_tx_enable_clock(hal->regs, true);
|
||||
}
|
||||
|
||||
// check if we need to start one pending transaction
|
||||
parlio_tx_trans_desc_t *t = NULL;
|
||||
expected_fsm = PARLIO_TX_FSM_ENABLE;
|
||||
@ -531,6 +544,10 @@ esp_err_t parlio_tx_unit_disable(parlio_tx_unit_handle_t tx_unit)
|
||||
|
||||
// stop the TX engine
|
||||
parlio_hal_context_t *hal = &tx_unit->base.group->hal;
|
||||
// disable clock output
|
||||
PARLIO_CLOCK_SRC_ATOMIC() {
|
||||
parlio_ll_tx_enable_clock(hal->regs, false);
|
||||
}
|
||||
gdma_stop(tx_unit->dma_chan);
|
||||
parlio_ll_tx_start(hal->regs, false);
|
||||
parlio_ll_enable_interrupt(hal->regs, PARLIO_LL_EVENT_TX_EOF, false);
|
||||
@ -621,9 +638,6 @@ static void IRAM_ATTR parlio_tx_default_isr(void *args)
|
||||
|
||||
if (status & PARLIO_LL_EVENT_TX_EOF) {
|
||||
parlio_ll_clear_interrupt_status(hal->regs, PARLIO_LL_EVENT_TX_EOF);
|
||||
PARLIO_CLOCK_SRC_ATOMIC() {
|
||||
parlio_ll_tx_enable_clock(hal->regs, false);
|
||||
}
|
||||
parlio_ll_tx_start(hal->regs, false);
|
||||
|
||||
parlio_tx_trans_desc_t *trans_desc = NULL;
|
||||
|
@ -7,6 +7,10 @@ if(CONFIG_PARLIO_ISR_IRAM_SAFE)
|
||||
list(REMOVE_ITEM srcs "test_parlio_rx.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED AND CONFIG_PM_ENABLE)
|
||||
list(APPEND srcs "test_parlio_sleep.c")
|
||||
endif()
|
||||
|
||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(SRCS ${srcs}
|
||||
|
@ -56,14 +56,14 @@ extern "C" {
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define TEST_CLK_GPIO 33
|
||||
#define TEST_VALID_GPIO 36
|
||||
#define TEST_DATA0_GPIO 20
|
||||
#define TEST_DATA1_GPIO 21
|
||||
#define TEST_DATA2_GPIO 22
|
||||
#define TEST_DATA3_GPIO 23
|
||||
#define TEST_DATA4_GPIO 45
|
||||
#define TEST_DATA5_GPIO 46
|
||||
#define TEST_DATA6_GPIO 47
|
||||
#define TEST_DATA7_GPIO 48
|
||||
#define TEST_DATA0_GPIO 0
|
||||
#define TEST_DATA1_GPIO 1
|
||||
#define TEST_DATA2_GPIO 2
|
||||
#define TEST_DATA3_GPIO 3
|
||||
#define TEST_DATA4_GPIO 4
|
||||
#define TEST_DATA5_GPIO 5
|
||||
#define TEST_DATA6_GPIO 6
|
||||
#define TEST_DATA7_GPIO 7
|
||||
#else
|
||||
#error "Unsupported target"
|
||||
#endif
|
||||
|
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "unity.h"
|
||||
#include "driver/parlio_tx.h"
|
||||
#include "driver/parlio_rx.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/parl_io_struct.h"
|
||||
#include "esp_private/sleep_cpu.h"
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "esp_attr.h"
|
||||
#include "test_board.h"
|
||||
|
||||
TEST_PARLIO_CALLBACK_ATTR
|
||||
static bool test_parlio_rx_done_callback(parlio_rx_unit_handle_t rx_unit, const parlio_rx_event_data_t *edata, void *user_ctx)
|
||||
{
|
||||
BaseType_t high_task_wakeup = pdFALSE;
|
||||
TaskHandle_t task = (TaskHandle_t)user_ctx;
|
||||
vTaskNotifyGiveFromISR(task, &high_task_wakeup);
|
||||
return high_task_wakeup == pdTRUE;
|
||||
}
|
||||
|
||||
#define TEST_PAYLOAD_SIZE 64
|
||||
static void test_parlio_sleep_retention(bool allow_pd)
|
||||
{
|
||||
printf("install parlio tx unit\r\n");
|
||||
parlio_tx_unit_handle_t tx_unit = NULL;
|
||||
parlio_tx_unit_config_t tx_config = {
|
||||
.clk_src = PARLIO_CLK_SRC_DEFAULT,
|
||||
.data_width = 4,
|
||||
.clk_in_gpio_num = -1, // use internal clock source
|
||||
.valid_gpio_num = TEST_VALID_GPIO,
|
||||
.clk_out_gpio_num = TEST_CLK_GPIO,
|
||||
.data_gpio_nums = {
|
||||
TEST_DATA0_GPIO,
|
||||
TEST_DATA1_GPIO,
|
||||
TEST_DATA2_GPIO,
|
||||
TEST_DATA3_GPIO,
|
||||
},
|
||||
.output_clk_freq_hz = 1 * 1000 * 1000,
|
||||
.trans_queue_depth = 8,
|
||||
.max_transfer_size = 128,
|
||||
.bit_pack_order = PARLIO_BIT_PACK_ORDER_MSB,
|
||||
.sample_edge = PARLIO_SAMPLE_EDGE_POS,
|
||||
.flags.allow_pd = allow_pd,
|
||||
};
|
||||
TEST_ESP_OK(parlio_new_tx_unit(&tx_config, &tx_unit));
|
||||
|
||||
printf("send packets and check event is fired\r\n");
|
||||
parlio_transmit_config_t transmit_config = {
|
||||
.idle_value = 0x00,
|
||||
};
|
||||
uint8_t tx_payload[TEST_PAYLOAD_SIZE] = {0};
|
||||
for (int i = 0; i < TEST_PAYLOAD_SIZE; i++) {
|
||||
tx_payload[i] = i;
|
||||
}
|
||||
|
||||
printf("install parlio rx unit\r\n");
|
||||
parlio_rx_unit_handle_t rx_unit = NULL;
|
||||
parlio_rx_delimiter_handle_t deli = NULL;
|
||||
|
||||
parlio_rx_unit_config_t rx_config = {
|
||||
.trans_queue_depth = 10,
|
||||
.max_recv_size = 1024,
|
||||
.data_width = 4,
|
||||
.clk_src = PARLIO_CLK_SRC_DEFAULT,
|
||||
.ext_clk_freq_hz = 0,
|
||||
.clk_in_gpio_num = -1,
|
||||
.exp_clk_freq_hz = 1 * 1000 * 1000,
|
||||
.clk_out_gpio_num = -1,
|
||||
.valid_gpio_num = TEST_VALID_GPIO,
|
||||
.data_gpio_nums = {
|
||||
TEST_DATA0_GPIO,
|
||||
TEST_DATA1_GPIO,
|
||||
TEST_DATA2_GPIO,
|
||||
TEST_DATA3_GPIO,
|
||||
},
|
||||
.flags = {
|
||||
.clk_gate_en = false,
|
||||
.allow_pd = allow_pd,
|
||||
}
|
||||
};
|
||||
rx_config.flags.free_clk = 1;
|
||||
TEST_ESP_OK(parlio_new_rx_unit(&rx_config, &rx_unit));
|
||||
|
||||
parlio_rx_level_delimiter_config_t lvl_deli_cfg = {
|
||||
.valid_sig_line_id = PARLIO_RX_UNIT_MAX_DATA_WIDTH - 1,
|
||||
.sample_edge = PARLIO_SAMPLE_EDGE_POS,
|
||||
.bit_pack_order = PARLIO_BIT_PACK_ORDER_MSB,
|
||||
.eof_data_len = TEST_PAYLOAD_SIZE,
|
||||
.timeout_ticks = 0,
|
||||
.flags = {
|
||||
.active_low_en = 0,
|
||||
},
|
||||
};
|
||||
TEST_ESP_OK(parlio_new_rx_level_delimiter(&lvl_deli_cfg, &deli));
|
||||
|
||||
printf("register receive_done event callback\r\n");
|
||||
parlio_rx_event_callbacks_t rx_cbs = {
|
||||
.on_receive_done = test_parlio_rx_done_callback,
|
||||
};
|
||||
TEST_ESP_OK(parlio_rx_unit_register_event_callbacks(rx_unit, &rx_cbs, xTaskGetCurrentTaskHandle()));
|
||||
|
||||
parlio_receive_config_t recv_config = {
|
||||
.delimiter = deli,
|
||||
.flags.partial_rx_en = false,
|
||||
};
|
||||
__attribute__((aligned(TEST_PAYLOAD_SIZE))) uint8_t rx_payload[TEST_PAYLOAD_SIZE] = {0};
|
||||
|
||||
// go to sleep
|
||||
esp_sleep_context_t sleep_ctx;
|
||||
esp_sleep_set_sleep_context(&sleep_ctx);
|
||||
printf("go to light sleep for 2 seconds\r\n");
|
||||
#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 PARLIO driver can still work...\r\n");
|
||||
#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_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
// check if the power domain also is powered down
|
||||
TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP);
|
||||
#endif
|
||||
esp_sleep_set_sleep_context(NULL);
|
||||
|
||||
printf("Testing tx and rx after sleep...\n");
|
||||
TEST_ESP_OK(parlio_tx_unit_enable(tx_unit));
|
||||
TEST_ESP_OK(parlio_rx_unit_enable(rx_unit, 1));
|
||||
TEST_ESP_OK(parlio_rx_unit_receive(rx_unit, rx_payload, TEST_PAYLOAD_SIZE, &recv_config));
|
||||
TEST_ESP_OK(parlio_tx_unit_transmit(tx_unit, tx_payload, TEST_PAYLOAD_SIZE * sizeof(uint8_t) * 8, &transmit_config));
|
||||
TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)));
|
||||
for (int i = 0; i < TEST_PAYLOAD_SIZE; i++) {
|
||||
printf("%.2d ", (rx_payload[i]));
|
||||
TEST_ASSERT_EQUAL(tx_payload[i], rx_payload[i]);
|
||||
if ((i + 1) % 16 == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
TEST_ESP_OK(parlio_tx_unit_disable(tx_unit));
|
||||
TEST_ESP_OK(parlio_del_tx_unit(tx_unit));
|
||||
TEST_ESP_OK(parlio_rx_unit_disable(rx_unit));
|
||||
TEST_ESP_OK(parlio_del_rx_delimiter(deli));
|
||||
TEST_ESP_OK(parlio_del_rx_unit(rx_unit));
|
||||
}
|
||||
|
||||
TEST_CASE("parlio light sleep", "[parlio]")
|
||||
{
|
||||
test_parlio_sleep_retention(false);
|
||||
#if SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
test_parlio_sleep_retention(true);
|
||||
#endif
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
CONFIG_PM_ENABLE=y
|
||||
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
|
@ -3,3 +3,6 @@
|
||||
#
|
||||
CONFIG_ESP_TASK_WDT_INIT=n
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
|
||||
# primitives for checking sleep internal state
|
||||
CONFIG_ESP_SLEEP_DEBUG=y
|
||||
|
@ -915,6 +915,10 @@ config SOC_PARLIO_TX_SIZE_BY_DMA
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MPI_MEM_BLOCKS_NUM
|
||||
int
|
||||
default 4
|
||||
|
@ -39,6 +39,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_I2S0 = 16,
|
||||
SLEEP_RETENTION_MODULE_ETM0 = 17,
|
||||
SLEEP_RETENTION_MODULE_TEMP_SENSOR = 18,
|
||||
SLEEP_RETENTION_MODULE_PARLIO0 = 19,
|
||||
|
||||
/* modem module, which includes WiFi, BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
|
||||
@ -80,6 +81,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
SLEEP_RETENTION_MODULE_BM_I2S0 = BIT(SLEEP_RETENTION_MODULE_I2S0),
|
||||
SLEEP_RETENTION_MODULE_BM_ETM0 = BIT(SLEEP_RETENTION_MODULE_ETM0),
|
||||
SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR = BIT(SLEEP_RETENTION_MODULE_TEMP_SENSOR),
|
||||
SLEEP_RETENTION_MODULE_BM_PARLIO0 = BIT(SLEEP_RETENTION_MODULE_PARLIO0),
|
||||
|
||||
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
|
||||
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
|
||||
@ -103,6 +105,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
| SLEEP_RETENTION_MODULE_BM_I2S0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_ETM0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR \
|
||||
| SLEEP_RETENTION_MODULE_BM_PARLIO0 \
|
||||
)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -370,6 +370,7 @@
|
||||
#define SOC_PARLIO_RX_CLK_SUPPORT_OUTPUT 1 /*!< Support output RX clock to a GPIO */
|
||||
#define SOC_PARLIO_TRANS_BIT_ALIGN 1 /*!< Support bit alignment in transaction */
|
||||
#define SOC_PARLIO_TX_SIZE_BY_DMA 1 /*!< Transaction length is controlled by DMA instead of indicated by register */
|
||||
#define SOC_PARLIO_SUPPORT_SLEEP_RETENTION 1 /*!< Support back up registers before sleep */
|
||||
|
||||
/*--------------------------- MPI CAPS ---------------------------------------*/
|
||||
#define SOC_MPI_MEM_BLOCKS_NUM (4)
|
||||
|
@ -48,3 +48,31 @@ const parlio_signal_conn_t parlio_periph_signals = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* PARLIO Registers to be saved during sleep retention
|
||||
* - Tx Configuration registers, e.g.: PARL_IO_TX_DATA_CFG_REG, PARL_IO_TX_GENRL_CFG_REG
|
||||
* - Rx Configuration registers, e.g.: PARL_IO_RX_MODE_CFG_REG, PARL_IO_RX_DATA_CFG_REG, PARL_IO_RX_GENRL_CFG_REG
|
||||
* - CLK Configuration registers, e.g.: PARL_IO_RX_CLK_CFG_REG, PARL_IO_TX_CLK_CFG_REG
|
||||
* - Interrupt enable registers, e.g.: PARL_IO_INT_ENA_REG
|
||||
*/
|
||||
#define PARLIO_RETENTION_REGS_CNT 8
|
||||
#define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0)
|
||||
static const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0};
|
||||
static const regdma_entries_config_t parlio_regs_retention[] = {
|
||||
// backup stage: save configuration registers
|
||||
// restore stage: restore the configuration registers
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PARLIO_LINK(0x00), \
|
||||
PARLIO_RETENTION_REGS_BASE, PARLIO_RETENTION_REGS_BASE, \
|
||||
PARLIO_RETENTION_REGS_CNT, 0, 0, \
|
||||
parlio_regs_map[0], parlio_regs_map[1], \
|
||||
parlio_regs_map[2], parlio_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
};
|
||||
const parlio_reg_retention_info_t parlio_reg_retention_info[SOC_PARLIO_GROUPS] = {
|
||||
[0] = {
|
||||
.regdma_entry_array = parlio_regs_retention,
|
||||
.array_size = ARRAY_SIZE(parlio_regs_retention),
|
||||
.retention_module = SLEEP_RETENTION_MODULE_PARLIO0
|
||||
},
|
||||
};
|
||||
|
@ -907,6 +907,10 @@ config SOC_PARLIO_TX_RX_SHARE_INTERRUPT
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MPI_MEM_BLOCKS_NUM
|
||||
int
|
||||
default 4
|
||||
|
@ -41,6 +41,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_TEMP_SENSOR = 18,
|
||||
SLEEP_RETENTION_MODULE_TWAI0 = 19,
|
||||
SLEEP_RETENTION_MODULE_TWAI1 = 20,
|
||||
SLEEP_RETENTION_MODULE_PARLIO0 = 21,
|
||||
|
||||
/* Modem module, which includes WiFi, BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
|
||||
@ -78,6 +79,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR = BIT(SLEEP_RETENTION_MODULE_TEMP_SENSOR),
|
||||
SLEEP_RETENTION_MODULE_BM_TWAI0 = BIT(SLEEP_RETENTION_MODULE_TWAI0),
|
||||
SLEEP_RETENTION_MODULE_BM_TWAI1 = BIT(SLEEP_RETENTION_MODULE_TWAI1),
|
||||
SLEEP_RETENTION_MODULE_BM_PARLIO0 = BIT(SLEEP_RETENTION_MODULE_PARLIO0),
|
||||
/* modem module, which includes WiFi, BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC),
|
||||
SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB),
|
||||
@ -105,6 +107,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
| SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR \
|
||||
| SLEEP_RETENTION_MODULE_BM_TWAI0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_TWAI1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_PARLIO0 \
|
||||
)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -349,6 +349,7 @@
|
||||
#define SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH 16 /*!< Number of data lines of the TX unit */
|
||||
#define SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH 16 /*!< Number of data lines of the RX unit */
|
||||
#define SOC_PARLIO_TX_RX_SHARE_INTERRUPT 1 /*!< TX and RX unit share the same interrupt source number */
|
||||
#define SOC_PARLIO_SUPPORT_SLEEP_RETENTION 1 /*!< Support back up registers before sleep */
|
||||
|
||||
/*--------------------------- MPI CAPS ---------------------------------------*/
|
||||
#define SOC_MPI_MEM_BLOCKS_NUM (4)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -64,3 +64,29 @@ const parlio_signal_conn_t parlio_periph_signals = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* PARLIO Registers to be saved during sleep retention
|
||||
* - Configuration registers, e.g.: PARL_IO_RX_CFG0_REG, PARL_IO_RX_CFG1_REG, PARL_IO_TX_CFG0_REG, PARL_IO_TX_CFG1_REG, PARL_IO_CLK_REG
|
||||
* - Interrupt enable registers, e.g.: PARL_IO_INT_ENA_REG
|
||||
*/
|
||||
#define PARLIO_RETENTION_REGS_CNT 6
|
||||
#define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0)
|
||||
static const uint32_t parlio_regs_map[4] = {0x2f, 0x0, 0x100, 0x0};
|
||||
static const regdma_entries_config_t parlio_regs_retention[] = {
|
||||
// backup stage: save configuration registers
|
||||
// restore stage: restore the configuration registers
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PARLIO_LINK(0x00), \
|
||||
PARLIO_RETENTION_REGS_BASE, PARLIO_RETENTION_REGS_BASE, \
|
||||
PARLIO_RETENTION_REGS_CNT, 0, 0, \
|
||||
parlio_regs_map[0], parlio_regs_map[1], \
|
||||
parlio_regs_map[2], parlio_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
};
|
||||
const parlio_reg_retention_info_t parlio_reg_retention_info[SOC_PARLIO_GROUPS] = {
|
||||
[0] = {
|
||||
.regdma_entry_array = parlio_regs_retention,
|
||||
.array_size = ARRAY_SIZE(parlio_regs_retention),
|
||||
.retention_module = SLEEP_RETENTION_MODULE_PARLIO0
|
||||
},
|
||||
};
|
||||
|
@ -903,6 +903,10 @@ config SOC_PARLIO_TRANS_BIT_ALIGN
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MPI_MEM_BLOCKS_NUM
|
||||
int
|
||||
default 4
|
||||
|
@ -41,6 +41,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_ETM0 = 18,
|
||||
SLEEP_RETENTION_MODULE_TEMP_SENSOR = 19,
|
||||
SLEEP_RETENTION_MODULE_TWAI0 = 20,
|
||||
SLEEP_RETENTION_MODULE_PARLIO0 = 21,
|
||||
|
||||
/* Modem module, which includes BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_BLE_MAC = 28,
|
||||
@ -76,6 +77,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
SLEEP_RETENTION_MODULE_BM_ETM0 = BIT(SLEEP_RETENTION_MODULE_ETM0),
|
||||
SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR = BIT(SLEEP_RETENTION_MODULE_TEMP_SENSOR),
|
||||
SLEEP_RETENTION_MODULE_BM_TWAI0 = BIT(SLEEP_RETENTION_MODULE_TWAI0),
|
||||
SLEEP_RETENTION_MODULE_BM_PARLIO0 = BIT(SLEEP_RETENTION_MODULE_PARLIO0),
|
||||
/* modem module, which includes BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC),
|
||||
SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB),
|
||||
@ -101,6 +103,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
| SLEEP_RETENTION_MODULE_BM_ETM0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR \
|
||||
| SLEEP_RETENTION_MODULE_BM_TWAI0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_PARLIO0 \
|
||||
)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -346,6 +346,7 @@
|
||||
#define SOC_PARLIO_RX_CLK_SUPPORT_GATING 1 /*!< Support gating RX clock */
|
||||
#define SOC_PARLIO_RX_CLK_SUPPORT_OUTPUT 1 /*!< Support output RX clock to a GPIO */
|
||||
#define SOC_PARLIO_TRANS_BIT_ALIGN 1 /*!< Support bit alignment in transaction */
|
||||
#define SOC_PARLIO_SUPPORT_SLEEP_RETENTION 1 /*!< Support back up registers before sleep */
|
||||
|
||||
/*--------------------------- MPI CAPS ---------------------------------------*/
|
||||
#define SOC_MPI_MEM_BLOCKS_NUM (4)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -48,3 +48,31 @@ const parlio_signal_conn_t parlio_periph_signals = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* PARLIO Registers to be saved during sleep retention
|
||||
* - Tx Configuration registers, e.g.: PARL_IO_TX_DATA_CFG_REG, PARL_IO_TX_GENRL_CFG_REG
|
||||
* - Rx Configuration registers, e.g.: PARL_IO_RX_MODE_CFG_REG, PARL_IO_RX_DATA_CFG_REG, PARL_IO_RX_GENRL_CFG_REG
|
||||
* - CLK Configuration registers, e.g.: PARL_IO_RX_CLK_CFG_REG, PARL_IO_TX_CLK_CFG_REG
|
||||
* - Interrupt enable registers, e.g.: PARL_IO_INT_ENA_REG
|
||||
*/
|
||||
#define PARLIO_RETENTION_REGS_CNT 8
|
||||
#define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0)
|
||||
static const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0};
|
||||
static const regdma_entries_config_t parlio_regs_retention[] = {
|
||||
// backup stage: save configuration registers
|
||||
// restore stage: restore the configuration registers
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PARLIO_LINK(0x00), \
|
||||
PARLIO_RETENTION_REGS_BASE, PARLIO_RETENTION_REGS_BASE, \
|
||||
PARLIO_RETENTION_REGS_CNT, 0, 0, \
|
||||
parlio_regs_map[0], parlio_regs_map[1], \
|
||||
parlio_regs_map[2], parlio_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
};
|
||||
const parlio_reg_retention_info_t parlio_reg_retention_info[SOC_PARLIO_GROUPS] = {
|
||||
[0] = {
|
||||
.regdma_entry_array = parlio_regs_retention,
|
||||
.array_size = ARRAY_SIZE(parlio_regs_retention),
|
||||
.retention_module = SLEEP_RETENTION_MODULE_PARLIO0
|
||||
},
|
||||
};
|
||||
|
@ -1287,6 +1287,10 @@ config SOC_PARLIO_TX_SIZE_BY_DMA
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MPI_MEM_BLOCKS_NUM
|
||||
int
|
||||
default 4
|
||||
|
@ -25,22 +25,21 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_TG1_WDT = 4,
|
||||
SLEEP_RETENTION_MODULE_TG0_TIMER = 5,
|
||||
SLEEP_RETENTION_MODULE_TG1_TIMER = 6,
|
||||
/* MISC Peripherals */
|
||||
SLEEP_RETENTION_MODULE_UART0 = 7,
|
||||
SLEEP_RETENTION_MODULE_UART1 = 8,
|
||||
SLEEP_RETENTION_MODULE_UART2 = 9,
|
||||
SLEEP_RETENTION_MODULE_UART3 = 10,
|
||||
SLEEP_RETENTION_MODULE_UART4 = 11,
|
||||
SLEEP_RETENTION_MODULE_RMT0 = 12,
|
||||
/* AHB_DMA by channel */
|
||||
SLEEP_RETENTION_MODULE_AHB_DMA_CH0 = 13,
|
||||
SLEEP_RETENTION_MODULE_AHB_DMA_CH1 = 14,
|
||||
SLEEP_RETENTION_MODULE_AHB_DMA_CH2 = 15,
|
||||
SLEEP_RETENTION_MODULE_AHB_DMA_CH0 = 7,
|
||||
SLEEP_RETENTION_MODULE_AHB_DMA_CH1 = 8,
|
||||
SLEEP_RETENTION_MODULE_AHB_DMA_CH2 = 9,
|
||||
/* AXI_DMA by channel */
|
||||
SLEEP_RETENTION_MODULE_AXI_DMA_CH0 = 16,
|
||||
SLEEP_RETENTION_MODULE_AXI_DMA_CH1 = 17,
|
||||
SLEEP_RETENTION_MODULE_AXI_DMA_CH2 = 18,
|
||||
|
||||
SLEEP_RETENTION_MODULE_AXI_DMA_CH0 = 10,
|
||||
SLEEP_RETENTION_MODULE_AXI_DMA_CH1 = 11,
|
||||
SLEEP_RETENTION_MODULE_AXI_DMA_CH2 = 12,
|
||||
/* MISC Peripherals */
|
||||
SLEEP_RETENTION_MODULE_UART0 = 13,
|
||||
SLEEP_RETENTION_MODULE_UART1 = 14,
|
||||
SLEEP_RETENTION_MODULE_UART2 = 15,
|
||||
SLEEP_RETENTION_MODULE_UART3 = 16,
|
||||
SLEEP_RETENTION_MODULE_UART4 = 17,
|
||||
SLEEP_RETENTION_MODULE_RMT0 = 18,
|
||||
SLEEP_RETENTION_MODULE_I2S0 = 19,
|
||||
SLEEP_RETENTION_MODULE_I2S1 = 20,
|
||||
SLEEP_RETENTION_MODULE_I2S2 = 21,
|
||||
@ -50,6 +49,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_TWAI0 = 25,
|
||||
SLEEP_RETENTION_MODULE_TWAI1 = 26,
|
||||
SLEEP_RETENTION_MODULE_TWAI2 = 27,
|
||||
SLEEP_RETENTION_MODULE_PARLIO0 = 28,
|
||||
|
||||
SLEEP_RETENTION_MODULE_MAX = 31
|
||||
} periph_retention_module_t;
|
||||
@ -89,6 +89,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
SLEEP_RETENTION_MODULE_BM_TWAI0 = BIT(SLEEP_RETENTION_MODULE_TWAI0),
|
||||
SLEEP_RETENTION_MODULE_BM_TWAI1 = BIT(SLEEP_RETENTION_MODULE_TWAI1),
|
||||
SLEEP_RETENTION_MODULE_BM_TWAI2 = BIT(SLEEP_RETENTION_MODULE_TWAI2),
|
||||
SLEEP_RETENTION_MODULE_BM_PARLIO0 = BIT(SLEEP_RETENTION_MODULE_PARLIO0),
|
||||
|
||||
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
|
||||
} periph_retention_module_bitmap_t;
|
||||
@ -114,11 +115,12 @@ typedef enum periph_retention_module_bitmap {
|
||||
| SLEEP_RETENTION_MODULE_BM_I2S1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2S2 \
|
||||
| SLEEP_RETENTION_MODULE_BM_ETM0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2C0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2C1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_TWAI0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_TWAI1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_TWAI2 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2C0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2C1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_TWAI0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_TWAI1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_TWAI2 \
|
||||
| SLEEP_RETENTION_MODULE_BM_PARLIO0 \
|
||||
)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -465,6 +465,7 @@
|
||||
#define SOC_PARLIO_RX_CLK_SUPPORT_OUTPUT 1 /*!< Support output RX clock to a GPIO */
|
||||
#define SOC_PARLIO_TRANS_BIT_ALIGN 1 /*!< Support bit alignment in transaction */
|
||||
#define SOC_PARLIO_TX_SIZE_BY_DMA 1 /*!< Transaction length is controlled by DMA instead of indicated by register */
|
||||
#define SOC_PARLIO_SUPPORT_SLEEP_RETENTION 1 /*!< Support back up registers before sleep */
|
||||
|
||||
/*--------------------------- MPI CAPS ---------------------------------------*/
|
||||
#define SOC_MPI_MEM_BLOCKS_NUM (4)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -64,3 +64,31 @@ const parlio_signal_conn_t parlio_periph_signals = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* PARLIO Registers to be saved during sleep retention
|
||||
* - Tx Configuration registers, e.g.: PARL_IO_TX_DATA_CFG_REG, PARL_IO_TX_GENRL_CFG_REG
|
||||
* - Rx Configuration registers, e.g.: PARL_IO_RX_MODE_CFG_REG, PARL_IO_RX_DATA_CFG_REG, PARL_IO_RX_GENRL_CFG_REG
|
||||
* - CLK Configuration registers, e.g.: PARL_IO_RX_CLK_CFG_REG, PARL_IO_TX_CLK_CFG_REG
|
||||
* - Interrupt enable registers, e.g.: PARL_IO_INT_ENA_REG
|
||||
*/
|
||||
#define PARLIO_RETENTION_REGS_CNT 8
|
||||
#define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0)
|
||||
static const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0};
|
||||
static const regdma_entries_config_t parlio_regs_retention[] = {
|
||||
// backup stage: save configuration registers
|
||||
// restore stage: restore the configuration registers
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PARLIO_LINK(0x00),
|
||||
PARLIO_RETENTION_REGS_BASE, PARLIO_RETENTION_REGS_BASE,
|
||||
PARLIO_RETENTION_REGS_CNT, 0, 0,
|
||||
parlio_regs_map[0], parlio_regs_map[1],
|
||||
parlio_regs_map[2], parlio_regs_map[3]),
|
||||
.owner = ENTRY(0)},
|
||||
};
|
||||
const parlio_reg_retention_info_t parlio_reg_retention_info[SOC_PARLIO_GROUPS] = {
|
||||
[0] = {
|
||||
.regdma_entry_array = parlio_regs_retention,
|
||||
.array_size = ARRAY_SIZE(parlio_regs_retention),
|
||||
.retention_module = SLEEP_RETENTION_MODULE_PARLIO0
|
||||
},
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -13,6 +13,10 @@
|
||||
#include "soc/parl_io_reg.h"
|
||||
#include "soc/parl_io_struct.h"
|
||||
#endif
|
||||
#include "soc/regdma.h"
|
||||
#if SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
#include "soc/retention_periph_defs.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -39,6 +43,16 @@ typedef struct {
|
||||
|
||||
extern const parlio_signal_conn_t parlio_periph_signals;
|
||||
|
||||
#if SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
typedef struct {
|
||||
const periph_retention_module_t retention_module;
|
||||
const regdma_entries_config_t *regdma_entry_array;
|
||||
uint32_t array_size;
|
||||
} parlio_reg_retention_info_t;
|
||||
|
||||
extern const parlio_reg_retention_info_t parlio_reg_retention_info[SOC_PARLIO_GROUPS];
|
||||
#endif // SOC_PARLIO_SUPPORT_SLEEP_RETENTION
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -57,6 +57,7 @@ extern "C" {
|
||||
#define REGDMA_ETM_LINK(_pri) ((0x1F << 8) | _pri)
|
||||
#define REGDMA_TSENS_LINK(_pri) ((0x20 << 8) | _pri)
|
||||
#define REGDMA_TWAI_LINK(_pri) ((0x21 << 8) | _pri)
|
||||
#define REGDMA_PARLIO_LINK(_pri) ((0x22 << 8) | _pri)
|
||||
#define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri)
|
||||
|
||||
#define REGDMA_LINK_PRI_SYS_CLK REGDMA_LINK_PRI_0
|
||||
@ -75,6 +76,7 @@ extern "C" {
|
||||
#define REGDMA_LINK_PRI_GPTIMER REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_I2C REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_I2S REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_PARLIO REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_UART REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_TEMPERATURE_SENSOR REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_TWAI REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
|
@ -158,6 +158,7 @@ The following peripheral drivers are not aware of DFS yet. Applications need to
|
||||
:SOC_UART_SUPPORT_SLEEP_RETENTION: - All UARTs
|
||||
:SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION: - Temperature Sensor
|
||||
:SOC_TWAI_SUPPORT_SLEEP_RETENTION: - All TWAIs
|
||||
:SOC_PARLIO_SUPPORT_SLEEP_RETENTION: - PARL_IO
|
||||
|
||||
The following peripherals are not yet supported:
|
||||
|
||||
@ -173,7 +174,6 @@ The following peripheral drivers are not aware of DFS yet. Applications need to
|
||||
- MCPWM
|
||||
- SARADC
|
||||
- SDIO
|
||||
- PARL_IO
|
||||
|
||||
For peripherals that do not support Light-sleep context retention, if the Power management is enabled, the ``ESP_PM_NO_LIGHT_SLEEP`` lock should be held when the peripheral is working to avoid losing the working context of the peripheral when entering sleep.
|
||||
|
||||
|
@ -158,6 +158,7 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求,
|
||||
:SOC_UART_SUPPORT_SLEEP_RETENTION: - All UARTs
|
||||
:SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION: - Temperature Sensor
|
||||
:SOC_TWAI_SUPPORT_SLEEP_RETENTION: - All TWAIs
|
||||
:SOC_PARLIO_SUPPORT_SLEEP_RETENTION: - PARL_IO
|
||||
|
||||
以下外设尚未支持:
|
||||
|
||||
@ -173,7 +174,6 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求,
|
||||
- MCPWM
|
||||
- SARADC
|
||||
- SDIO
|
||||
- PARL_IO
|
||||
|
||||
对于未支持 Light-sleep 上下文备份的外设,若启用了电源管理功能,应在外设工作时持有 ``ESP_PM_NO_LIGHT_SLEEP`` 锁以避免进入休眠导致外设工作上下文丢失。
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user