mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Compare commits
41 Commits
f0e62c6675
...
f2b32984a9
Author | SHA1 | Date | |
---|---|---|---|
|
f2b32984a9 | ||
|
46acfdce96 | ||
|
945af68d74 | ||
|
5d792910be | ||
|
82a29b7d21 | ||
|
0c9d7c9dd0 | ||
|
3629909b11 | ||
|
3a35b26de1 | ||
|
2a6be654cd | ||
|
3000402fcf | ||
|
b0712b6a2b | ||
|
e051b921b8 | ||
|
98fdb1a97f | ||
|
c01512f4b0 | ||
|
19d512ebee | ||
|
9be8822b61 | ||
|
1d7241acc1 | ||
|
903c11ff1a | ||
|
e24005c8db | ||
|
1ac6043bce | ||
|
52002bf92d | ||
|
bc0404ae03 | ||
|
46350e362e | ||
|
6be09eb5b8 | ||
|
3b6f8b1f3d | ||
|
9529c4ece4 | ||
|
a30ed69f69 | ||
|
180bc4bd8c | ||
|
d9c15bb772 | ||
|
d70f24e414 | ||
|
446528d40f | ||
|
28f12bfb47 | ||
|
675fac1a6c | ||
|
f0903aef6b | ||
|
32c7694f56 | ||
|
c36674eaa8 | ||
|
02cd0253a1 | ||
|
7667d9ebbe | ||
|
fcd751e79c | ||
|
200241b9aa | ||
|
82c8973add |
@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
||||
|
@ -24,7 +24,7 @@ def test_app_update(dut: Dut) -> None:
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
# TODO: [ESP32C61] IDF-9245, IDF-9247, IDF-10983
|
||||
# TODO: [ESP32C61] IDF-9245, IDF-10983
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='C61 has not supported deep sleep')
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit b8ef2c474d392a88ea7e6626f89acf1fa5f30e4a
|
||||
Subproject commit 5c913171361dac0821e15e83cc0cf604149e1b84
|
@ -1 +1 @@
|
||||
Subproject commit 7e4f538a23591dfd361b90415eb517c6fc901a40
|
||||
Subproject commit 62b04f185717f31c57b802d5059e13b0d4d12b0c
|
@ -469,6 +469,11 @@ static const esp_err_msg_t esp_err_msg_table[] = {
|
||||
# endif
|
||||
# ifdef ESP_ERR_DPP_AUTH_TIMEOUT
|
||||
ERR_TBL_IT(ESP_ERR_DPP_AUTH_TIMEOUT), /* 12442 0x309a DPP Auth response was not received in time */
|
||||
# endif
|
||||
# ifdef ESP_ERR_DPP_INVALID_LIST
|
||||
ERR_TBL_IT(ESP_ERR_DPP_INVALID_LIST), /* 12443 0x309b Channel list given in
|
||||
esp_supp_dpp_bootstrap_gen() is not
|
||||
valid or too big */
|
||||
# endif
|
||||
// components/esp_common/include/esp_err.h
|
||||
# ifdef ESP_ERR_MESH_BASE
|
||||
|
@ -273,4 +273,13 @@ menu "Hardware Settings"
|
||||
config ESP_SPI_BUS_LOCK_FUNCS_IN_IRAM
|
||||
bool
|
||||
default n
|
||||
|
||||
config ESP_CLK_RC32K_NOT_TO_USE
|
||||
bool
|
||||
default y if IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C61
|
||||
default n
|
||||
help
|
||||
Due to the poor low-temperature characteristics of
|
||||
RC32K (it cannot operate below -40 degrees Celsius),
|
||||
please avoid using it whenever possible
|
||||
endmenu
|
||||
|
@ -19,7 +19,7 @@ esp_err_t sleep_clock_system_retention_init(void *arg)
|
||||
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(0), PCR_AHB_FREQ_CONF_REG, 0, PCR_AHB_DIV_NUM, 1, 0), .owner = ENTRY(0) | ENTRY(1) }, /* Set AHB bus frequency to XTAL frequency */
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(1), PCR_BUS_CLK_UPDATE_REG, 1, PCR_BUS_CLOCK_UPDATE, 1, 0), .owner = ENTRY(0) | ENTRY(1) },
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
[2] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(2), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 74, 0, 0, 0xffffffff, 0xffffffff, 0x7f7, 0x0), .owner = ENTRY(0) | ENTRY(1) },
|
||||
[2] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(2), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 75, 0, 0, 0xffffffff, 0xffffffff, 0x200007f7, 0x0), .owner = ENTRY(0) | ENTRY(1) },
|
||||
#endif
|
||||
};
|
||||
esp_err_t err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_SYS_CLK, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
|
||||
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_private/sleep_clock.h"
|
||||
#include "soc/pcr_reg.h"
|
||||
#include "modem/modem_syscon_reg.h"
|
||||
|
||||
static const char *TAG = "sleep_clock";
|
||||
|
||||
esp_err_t sleep_clock_system_retention_init(void *arg)
|
||||
{
|
||||
const static sleep_retention_entries_config_t pcr_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 63, 0, 0, 0xfd73ffff, 0xfdffffff, 0xe001, 0x0), .owner = ENTRY(0) | ENTRY(1) },
|
||||
};
|
||||
|
||||
esp_err_t err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_SYS_CLK, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
|
||||
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention");
|
||||
ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
|
||||
esp_err_t sleep_clock_modem_retention_init(void *arg)
|
||||
{
|
||||
#define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1)
|
||||
|
||||
const static sleep_retention_entries_config_t modem_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */
|
||||
};
|
||||
|
||||
esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM);
|
||||
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 1 level priority");
|
||||
ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization");
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool clock_domain_pd_allowed(void)
|
||||
{
|
||||
const uint32_t inited_modules = sleep_retention_get_inited_modules();
|
||||
const uint32_t created_modules = sleep_retention_get_created_modules();
|
||||
const uint32_t sys_clk_dep_modules = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH));
|
||||
|
||||
/* The clock and reset of MODEM (WiFi, BLE and 15.4) modules are managed
|
||||
* through MODEM_SYSCON, when one or more MODEMs are initialized, it is
|
||||
* necessary to check the state of CLOCK_MODEM to determine MODEM domain on
|
||||
* or off. The clock and reset of digital peripherals are managed through
|
||||
* PCR, with TOP domain similar to MODEM domain. */
|
||||
uint32_t modem_clk_dep_modules = 0;
|
||||
#if SOC_WIFI_SUPPORTED
|
||||
modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | BIT(SLEEP_RETENTION_MODULE_WIFI_BB);
|
||||
#endif
|
||||
#if SOC_BT_SUPPORTED
|
||||
modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB);
|
||||
#endif
|
||||
#if SOC_IEEE802154_SUPPORTED
|
||||
modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB);
|
||||
#endif
|
||||
|
||||
uint32_t mask = 0;
|
||||
if (inited_modules & sys_clk_dep_modules) {
|
||||
mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
|
||||
}
|
||||
if (inited_modules & modem_clk_dep_modules) {
|
||||
#if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED
|
||||
mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM);
|
||||
#endif
|
||||
}
|
||||
return ((inited_modules & mask) == (created_modules & mask));
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, SECONDARY, BIT(0), 106)
|
||||
{
|
||||
sleep_retention_module_init_param_t init_param = {
|
||||
.cbs = { .create = { .handle = sleep_clock_system_retention_init, .arg = NULL } },
|
||||
.attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE
|
||||
};
|
||||
sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM, &init_param);
|
||||
|
||||
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
|
||||
init_param = (sleep_retention_module_init_param_t) {
|
||||
.cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } },
|
||||
.attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE
|
||||
};
|
||||
sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_MODEM, &init_param);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
162
components/esp_hw_support/lowpower/port/esp32c61/sleep_mmu.c
Normal file
162
components/esp_hw_support/lowpower/port/esp32c61/sleep_mmu.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#include "esp_private/startup_internal.h"
|
||||
|
||||
static const char *TAG = "sleep_mmu";
|
||||
|
||||
typedef struct {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
} mmu_domain_dev_regs_region_t;
|
||||
|
||||
typedef struct {
|
||||
mmu_domain_dev_regs_region_t *region;
|
||||
int region_num;
|
||||
uint32_t *regs_frame;
|
||||
} mmu_domain_dev_sleep_frame_t;
|
||||
|
||||
/**
|
||||
* Internal structure which holds all requested light sleep mmu retention parameters
|
||||
*/
|
||||
typedef struct {
|
||||
struct {
|
||||
mmu_domain_dev_sleep_frame_t *mmu_table_frame;
|
||||
} retent;
|
||||
} sleep_mmu_retention_t;
|
||||
|
||||
static DRAM_ATTR __attribute__((unused)) sleep_mmu_retention_t s_mmu_retention;
|
||||
|
||||
static void * mmu_domain_dev_sleep_frame_alloc_and_init(const mmu_domain_dev_regs_region_t *regions, const int region_num)
|
||||
{
|
||||
const int region_sz = sizeof(mmu_domain_dev_regs_region_t) * region_num;
|
||||
int regs_frame_sz = 0;
|
||||
for (int num = 0; num < region_num; num++) {
|
||||
regs_frame_sz += regions[num].end - regions[num].start;
|
||||
}
|
||||
void *frame = heap_caps_malloc(sizeof(mmu_domain_dev_sleep_frame_t) + region_sz + regs_frame_sz, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||
if (frame) {
|
||||
mmu_domain_dev_regs_region_t *region = (mmu_domain_dev_regs_region_t *)(frame + sizeof(mmu_domain_dev_sleep_frame_t));
|
||||
memcpy(region, regions, region_num * sizeof(mmu_domain_dev_regs_region_t));
|
||||
void *regs_frame = frame + sizeof(mmu_domain_dev_sleep_frame_t) + region_sz;
|
||||
memset(regs_frame, 0, regs_frame_sz);
|
||||
*(mmu_domain_dev_sleep_frame_t *)frame = (mmu_domain_dev_sleep_frame_t) {
|
||||
.region = region,
|
||||
.region_num = region_num,
|
||||
.regs_frame = (uint32_t *)regs_frame
|
||||
};
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
static inline void * mmu_domain_mmu_table_sleep_frame_alloc_and_init(void)
|
||||
{
|
||||
#define MMU_TABLE_SIZE (512 * 4)
|
||||
const static mmu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = SPI_MEM_MMU_ITEM_CONTENT_REG(0), .end = SPI_MEM_MMU_ITEM_CONTENT_REG(0) + MMU_TABLE_SIZE}
|
||||
};
|
||||
return mmu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
|
||||
}
|
||||
|
||||
static IRAM_ATTR void mmu_domain_dev_regs_save(mmu_domain_dev_sleep_frame_t *frame)
|
||||
{
|
||||
assert(frame);
|
||||
mmu_domain_dev_regs_region_t *region = frame->region;
|
||||
uint32_t *regs_frame = frame->regs_frame;
|
||||
|
||||
int offset = 0;
|
||||
for (int i = 0; i < frame->region_num; i++) {
|
||||
for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) {
|
||||
REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), offset);
|
||||
regs_frame[offset++] = REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static IRAM_ATTR void mmu_domain_dev_regs_restore(mmu_domain_dev_sleep_frame_t *frame)
|
||||
{
|
||||
assert(frame);
|
||||
mmu_domain_dev_regs_region_t *region = frame->region;
|
||||
uint32_t *regs_frame = frame->regs_frame;
|
||||
|
||||
int offset = 0;
|
||||
for (int i = 0; i < frame->region_num; i++) {
|
||||
for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) {
|
||||
REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), offset);
|
||||
REG_WRITE(SPI_MEM_MMU_ITEM_CONTENT_REG(0),regs_frame[offset++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IRAM_ATTR void esp_sleep_mmu_retention(bool backup_or_restore)
|
||||
{
|
||||
if (backup_or_restore) {
|
||||
mmu_domain_dev_regs_save(s_mmu_retention.retent.mmu_table_frame);
|
||||
} else {
|
||||
mmu_domain_dev_regs_restore(s_mmu_retention.retent.mmu_table_frame);
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t esp_sleep_mmu_retention_deinit_impl(void)
|
||||
{
|
||||
if (s_mmu_retention.retent.mmu_table_frame) {
|
||||
heap_caps_free((void *)s_mmu_retention.retent.mmu_table_frame);
|
||||
s_mmu_retention.retent.mmu_table_frame = NULL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_sleep_mmu_retention_init_impl(void)
|
||||
{
|
||||
if (s_mmu_retention.retent.mmu_table_frame == NULL) {
|
||||
void *frame = mmu_domain_mmu_table_sleep_frame_alloc_and_init();
|
||||
if (frame == NULL) {
|
||||
goto err;
|
||||
}
|
||||
s_mmu_retention.retent.mmu_table_frame = (mmu_domain_dev_sleep_frame_t *)frame;
|
||||
}
|
||||
return ESP_OK;
|
||||
err:
|
||||
esp_sleep_mmu_retention_deinit();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t esp_sleep_mmu_retention_init(void)
|
||||
{
|
||||
return esp_sleep_mmu_retention_init_impl();
|
||||
}
|
||||
|
||||
esp_err_t esp_sleep_mmu_retention_deinit(void)
|
||||
{
|
||||
return esp_sleep_mmu_retention_deinit_impl();
|
||||
}
|
||||
|
||||
bool mmu_domain_pd_allowed(void)
|
||||
{
|
||||
return (s_mmu_retention.retent.mmu_table_frame != NULL);
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(sleep_mmu_startup_init, SECONDARY, BIT(0), 108)
|
||||
{
|
||||
esp_err_t ret;
|
||||
ret = esp_sleep_mmu_retention_init();
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGW(TAG, "Failed to enable TOP power down during light sleep.");
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
@ -423,7 +423,7 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
|
||||
esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) (
|
||||
(last_src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST :
|
||||
(last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL :
|
||||
#if !SOC_CLK_RC32K_NOT_TO_USE
|
||||
#if !CONFIG_ESP_CLK_RC32K_NOT_TO_USE
|
||||
(last_src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K :
|
||||
#endif
|
||||
(last_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K :
|
||||
@ -431,7 +431,7 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
|
||||
esp_sleep_pd_domain_t pu_domain = (esp_sleep_pd_domain_t) (
|
||||
(src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST :
|
||||
(src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL :
|
||||
#if !SOC_CLK_RC32K_NOT_TO_USE
|
||||
#if !CONFIG_ESP_CLK_RC32K_NOT_TO_USE
|
||||
(src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K :
|
||||
#endif
|
||||
(src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K :
|
||||
@ -486,7 +486,7 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module)
|
||||
esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) (
|
||||
(last_src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST :
|
||||
(last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL :
|
||||
#if !SOC_CLK_RC32K_NOT_TO_USE
|
||||
#if !CONFIG_ESP_CLK_RC32K_NOT_TO_USE
|
||||
(last_src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K :
|
||||
#endif
|
||||
(last_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K :
|
||||
|
@ -34,44 +34,44 @@ static void esp_cpu_configure_invalid_regions(void)
|
||||
__attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X;
|
||||
__attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X;
|
||||
|
||||
// ROM uses some PMA entries, so we need to clear them before using them in ESP-IDF
|
||||
|
||||
// 0. Gap at bottom of address space
|
||||
PMA_ENTRY_SET_NAPOT(0, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_NAPOT(0, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE);
|
||||
|
||||
// 1. Gap between debug region & IROM
|
||||
PMA_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 2. ROM has configured the ROM region to be cacheable, so we just need to lock the configuration
|
||||
PMA_ENTRY_SET_TOR(3, SOC_IROM_MASK_LOW, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(4, SOC_DROM_MASK_HIGH, PMA_TOR | PMA_RX);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(3, SOC_IROM_MASK_LOW, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(4, SOC_DROM_MASK_HIGH, PMA_TOR | PMA_RX);
|
||||
|
||||
// 3. Gap between ROM & RAM
|
||||
PMA_ENTRY_SET_TOR(5, SOC_DROM_MASK_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(6, SOC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(5, SOC_DROM_MASK_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(6, SOC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 4. Gap between DRAM and I_Cache
|
||||
PMA_ENTRY_SET_TOR(7, SOC_IRAM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(8, SOC_IROM_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(7, SOC_IRAM_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(8, SOC_IROM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 5. ROM has configured the MSPI region with RX permission, we should add W attribute for psram and lock the configuration
|
||||
// This function sets invalid regions but this is a valid memory region configuration that could have
|
||||
// been configured using PMP as well, but due to insufficient PMP entries we are configuring this using PMA.
|
||||
// This entry is also required to be set using PMA because the region needs to be configured as cacheable.
|
||||
PMA_ENTRY_SET_NAPOT(9, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_RWX);
|
||||
PMA_RESET_AND_ENTRY_SET_NAPOT(9, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_RWX);
|
||||
|
||||
// 6. Gap between D_Cache & LP_RAM
|
||||
PMA_ENTRY_SET_TOR(10, SOC_DROM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(11, SOC_RTC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(10, SOC_DROM_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(11, SOC_RTC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 7. Gap between LP memory & peripheral addresses
|
||||
PMA_ENTRY_SET_TOR(12, SOC_RTC_IRAM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(13, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(12, SOC_RTC_IRAM_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 8. End of address space
|
||||
PMA_ENTRY_SET_TOR(14, SOC_PERIPHERAL_HIGH, PMA_NONE);
|
||||
|
||||
PMA_ENTRY_CFG_RESET(15);
|
||||
PMA_ENTRY_SET_TOR(15, UINT32_MAX, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(14, SOC_PERIPHERAL_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(15, UINT32_MAX, PMA_TOR | PMA_NONE);
|
||||
}
|
||||
|
||||
void esp_cpu_configure_region_protection(void)
|
||||
|
@ -17,7 +17,7 @@ if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
endif()
|
||||
|
||||
# TODO: [ESP32C61] IDF-9250
|
||||
# TODO: [ESP32C61] IDF-9304
|
||||
if(CONFIG_IDF_TARGET_ESP32C61)
|
||||
list(REMOVE_ITEM srcs
|
||||
"sar_periph_ctrl.c"
|
||||
|
@ -35,34 +35,41 @@ static void esp_cpu_configure_invalid_regions(void)
|
||||
__attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X;
|
||||
__attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X;
|
||||
|
||||
// ROM uses some PMA entries, so we need to clear them before using them in ESP-IDF
|
||||
|
||||
// 0. Gap at bottom of address space
|
||||
PMA_ENTRY_SET_NAPOT(0, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_NAPOT(0, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE);
|
||||
|
||||
// 1. Gap between debug region & IROM
|
||||
PMA_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 3. Gap between ROM & RAM
|
||||
PMA_ENTRY_SET_TOR(3, SOC_DROM_MASK_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(4, SOC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(3, SOC_DROM_MASK_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(4, SOC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 4. Gap between DRAM and I_Cache
|
||||
PMA_ENTRY_SET_TOR(5, SOC_IRAM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(5, SOC_IRAM_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 5. ROM has configured the MSPI region with RX permission, we should add W attribute for psram and lock the configuration
|
||||
// This function sets invalid regions but this is a valid memory region configuration that could have
|
||||
// been configured using PMP as well, but due to insufficient PMP entries we are configuring this using PMA.
|
||||
// This entry is also required to be set using PMA because the region needs to be configured as cacheable.
|
||||
PMA_ENTRY_SET_NAPOT(7, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_RWX);
|
||||
PMA_RESET_AND_ENTRY_SET_NAPOT(7, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_RWX);
|
||||
|
||||
// 6. Gap between D_Cache & peripheral addresses
|
||||
PMA_ENTRY_SET_TOR(8, SOC_DROM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(9, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(8, SOC_DROM_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(9, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 7. End of address space
|
||||
PMA_ENTRY_SET_TOR(10, SOC_PERIPHERAL_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(11, UINT32_MAX, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(10, SOC_PERIPHERAL_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(11, UINT32_MAX, PMA_TOR | PMA_NONE);
|
||||
|
||||
PMA_ENTRY_CFG_RESET(12);
|
||||
PMA_ENTRY_CFG_RESET(13);
|
||||
PMA_ENTRY_CFG_RESET(14);
|
||||
PMA_ENTRY_CFG_RESET(15);
|
||||
}
|
||||
|
||||
void esp_cpu_configure_region_protection(void)
|
||||
|
@ -10,8 +10,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// TODO: IDF-9247
|
||||
|
||||
#define PMU_EXT0_WAKEUP_EN BIT(0)
|
||||
#define PMU_EXT1_WAKEUP_EN BIT(1)
|
||||
#define PMU_GPIO_WAKEUP_EN BIT(2)
|
||||
|
@ -476,12 +476,12 @@ typedef struct pmu_sleep_machine_constant {
|
||||
.reset_wait_time_us = 1, \
|
||||
.power_supply_wait_time_us = 20, \
|
||||
.power_up_wait_time_us = 2, \
|
||||
.regdma_s2m_work_time_us = 172, \
|
||||
.regdma_s2a_work_time_us = 480, \
|
||||
.regdma_m2a_work_time_us = 278, \
|
||||
.regdma_a2s_work_time_us = 382, \
|
||||
.regdma_rf_on_work_time_us = 70, \
|
||||
.regdma_rf_off_work_time_us = 23, \
|
||||
.regdma_s2m_work_time_us = 270, \
|
||||
.regdma_s2a_work_time_us = 666, \
|
||||
.regdma_m2a_work_time_us = 296, \
|
||||
.regdma_a2s_work_time_us = 586, \
|
||||
.regdma_rf_on_work_time_us = 138, \
|
||||
.regdma_rf_off_work_time_us = 28, \
|
||||
.xtal_wait_stable_time_us = 250, \
|
||||
.pll_wait_stable_time_us = 1 \
|
||||
} \
|
||||
|
@ -38,42 +38,44 @@ static void esp_cpu_configure_invalid_regions(void)
|
||||
__attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X;
|
||||
__attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X;
|
||||
|
||||
// ROM uses some PMA entries, so we need to clear them before using them in ESP-IDF
|
||||
|
||||
// 0. Gap at bottom of address space
|
||||
PMA_ENTRY_SET_NAPOT(0, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_NAPOT(0, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE);
|
||||
|
||||
// 1. Gap between CPU subsystem region & HP TCM
|
||||
PMA_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(2, SOC_TCM_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(2, SOC_TCM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 2. Gap between HP TCM and CPU Peripherals
|
||||
PMA_ENTRY_SET_TOR(3, SOC_TCM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(4, CPU_PERIPH_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(3, SOC_TCM_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(4, CPU_PERIPH_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 3. Gap between CPU Peripherals and I_Cache
|
||||
PMA_ENTRY_SET_TOR(5, CPU_PERIPH_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(5, CPU_PERIPH_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 4. Gap between I_Cache and external memory range
|
||||
PMA_ENTRY_SET_NAPOT(7, SOC_DROM_HIGH, SOC_EXTRAM_LOW - SOC_DROM_HIGH, PMA_NAPOT | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_NAPOT(7, SOC_DROM_HIGH, SOC_EXTRAM_LOW - SOC_DROM_HIGH, PMA_NAPOT | PMA_NONE);
|
||||
|
||||
// 5. Gap between external memory and ROM
|
||||
PMA_ENTRY_SET_TOR(8, SOC_EXTRAM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(9, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(8, SOC_EXTRAM_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(9, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 6. Gap between ROM and internal memory
|
||||
PMA_ENTRY_SET_TOR(10, SOC_IROM_MASK_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(11, SOC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(10, SOC_IROM_MASK_HIGH, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(11, SOC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 7. Gap between internal memory and HP peripherals
|
||||
PMA_ENTRY_SET_NAPOT(12, SOC_DRAM_HIGH, SOC_PERIPHERAL_LOW - SOC_DRAM_HIGH, PMA_NAPOT | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_NAPOT(12, SOC_DRAM_HIGH, SOC_PERIPHERAL_LOW - SOC_DRAM_HIGH, PMA_NAPOT | PMA_NONE);
|
||||
|
||||
// 8. Special case - This whitelists the External flash/RAM, HP ROM and HP L2MEM regions and make them cacheable.
|
||||
// At the startup, this is done using PMA entry 15 by the ROM code.
|
||||
PMA_ENTRY_SET_NAPOT(13, SOC_IROM_LOW, SOC_PERIPHERAL_LOW - SOC_IROM_LOW, PMA_NAPOT | PMA_RWX);
|
||||
PMA_RESET_AND_ENTRY_SET_NAPOT(13, SOC_IROM_LOW, SOC_PERIPHERAL_LOW - SOC_IROM_LOW, PMA_NAPOT | PMA_RWX);
|
||||
|
||||
// 9. Gap between Uncacheable L2 Mem and end of address space
|
||||
PMA_ENTRY_SET_TOR(14, CACHE_LL_L2MEM_NON_CACHE_ADDR(SOC_DRAM_HIGH), PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(15, UINT32_MAX, PMA_TOR | PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(14, CACHE_LL_L2MEM_NON_CACHE_ADDR(SOC_DRAM_HIGH), PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(15, UINT32_MAX, PMA_TOR | PMA_NONE);
|
||||
}
|
||||
|
||||
void esp_cpu_configure_region_protection(void)
|
||||
|
@ -157,8 +157,8 @@
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (318)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56)
|
||||
#elif CONFIG_IDF_TARGET_ESP32C61
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (318)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56)
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (1148) //TODO: PM-231
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (107)
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
|
||||
@ -189,8 +189,12 @@
|
||||
#endif
|
||||
|
||||
#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD
|
||||
#if CONFIG_IDF_TARGET_ESP32C61
|
||||
#define SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US (1232)
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5
|
||||
#define SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US (1220)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Minimal amount of time we can sleep for
|
||||
#define LIGHT_SLEEP_MIN_TIME_US 200
|
||||
@ -705,7 +709,7 @@ FORCE_INLINE_ATTR void misc_modules_wake_prepare(uint32_t pd_flags)
|
||||
#if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP
|
||||
sleep_console_usj_pad_restore();
|
||||
#endif
|
||||
#if !CONFIG_IDF_TARGET_ESP32C61
|
||||
#if !CONFIG_IDF_TARGET_ESP32C61 // TODO: IDF-9304
|
||||
sar_periph_ctrl_power_enable();
|
||||
#endif
|
||||
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_RTCCNTL
|
||||
@ -2359,7 +2363,7 @@ static uint32_t get_power_down_flags(void)
|
||||
}
|
||||
#endif
|
||||
#if SOC_PM_SUPPORT_RC32K_PD
|
||||
#if !SOC_CLK_RC32K_NOT_TO_USE
|
||||
#if !CONFIG_ESP_CLK_RC32K_NOT_TO_USE
|
||||
if (s_config.domain[ESP_PD_DOMAIN_RC32K].pd_option != ESP_PD_OPTION_ON) {
|
||||
pd_flags |= PMU_SLEEP_PD_RC32K;
|
||||
}
|
||||
|
@ -751,7 +751,7 @@ void IRAM_ATTR call_start_cpu0(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SOC_DEEP_SLEEP_SUPPORTED //TODO: IDF-9245
|
||||
#if SOC_DEEP_SLEEP_SUPPORTED
|
||||
// Need to unhold the IOs that were hold right before entering deep sleep, which are used as wakeup pins
|
||||
if (rst_reas[0] == RESET_REASON_CORE_DEEP_SLEEP) {
|
||||
esp_deep_sleep_wakeup_io_reset();
|
||||
|
@ -82,10 +82,12 @@ SECONDARY: 103: esp_security_init in components/esp_security/src/init.c on BIT(0
|
||||
SECONDARY: 105: esp_sleep_startup_init in components/esp_hw_support/sleep_gpio.c on BIT(0)
|
||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_clock.c on BIT(0)
|
||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c6/sleep_clock.c on BIT(0)
|
||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c61/sleep_clock.c on BIT(0)
|
||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32h2/sleep_clock.c on BIT(0)
|
||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c on BIT(0)
|
||||
SECONDARY: 107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0)
|
||||
SECONDARY: 108: sleep_mmu_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c on BIT(0)
|
||||
SECONDARY: 108: sleep_mmu_startup_init in components/esp_hw_support/lowpower/port/esp32c61/sleep_mmu.c on BIT(0)
|
||||
|
||||
# app_trace has to be initialized before systemview
|
||||
SECONDARY: 115: esp_apptrace_init in components/app_trace/app_trace.c on ESP_SYSTEM_INIT_ALL_CORES
|
||||
|
@ -4,7 +4,7 @@ menu "Serial flasher config"
|
||||
config ESPTOOLPY_NO_STUB
|
||||
bool "Disable download stub"
|
||||
default y if IDF_ENV_FPGA || IDF_ENV_BRINGUP
|
||||
default y if IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C61 # TODO: IDF-8631, IDF-9241 to be removed
|
||||
default y if IDF_TARGET_ESP32C61 # TODO: IDF-9241 to be removed
|
||||
default n
|
||||
|
||||
help
|
||||
|
@ -81,15 +81,44 @@ err:
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
static void prvTaskDeleteWithCaps( TaskHandle_t xTaskToDelete )
|
||||
{
|
||||
/* Return value unused if asserts are disabled */
|
||||
BaseType_t __attribute__( ( unused ) ) xResult;
|
||||
StaticTask_t * pxTaskBuffer;
|
||||
StackType_t * puxStackBuffer;
|
||||
|
||||
/* The task to be deleted must not be running.
|
||||
* So we suspend the task before deleting it. */
|
||||
vTaskSuspend( xTaskToDelete );
|
||||
|
||||
/* Wait for the task to be suspended */
|
||||
while( eRunning == eTaskGetState( xTaskToDelete ) )
|
||||
{
|
||||
taskYIELD();
|
||||
}
|
||||
|
||||
configASSERT( eRunning != eTaskGetState( xTaskToDelete ) );
|
||||
|
||||
xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer );
|
||||
configASSERT( xResult == pdTRUE );
|
||||
configASSERT( puxStackBuffer != NULL );
|
||||
configASSERT( pxTaskBuffer != NULL );
|
||||
|
||||
/* We can delete the task and free the memory buffers. */
|
||||
vTaskDelete( xTaskToDelete );
|
||||
|
||||
/* Free the memory buffers */
|
||||
heap_caps_free( puxStackBuffer );
|
||||
vPortFree( pxTaskBuffer );
|
||||
}
|
||||
|
||||
static void prvTaskDeleteWithCapsTask( void * pvParameters )
|
||||
{
|
||||
TaskHandle_t xTaskToDelete = ( TaskHandle_t ) pvParameters;
|
||||
|
||||
/* The task to be deleted must not be running */
|
||||
configASSERT( eRunning != eTaskGetState( xTaskToDelete ) );
|
||||
|
||||
/* Delete the WithCaps task */
|
||||
vTaskDeleteWithCaps( xTaskToDelete );
|
||||
prvTaskDeleteWithCaps( xTaskToDelete );
|
||||
|
||||
/* Delete the temporary clean up task */
|
||||
vTaskDelete( NULL );
|
||||
@ -98,7 +127,7 @@ err:
|
||||
void vTaskDeleteWithCaps( TaskHandle_t xTaskToDelete )
|
||||
{
|
||||
/* THIS FUNCTION SHOULD NOT BE CALLED FROM AN INTERRUPT CONTEXT. */
|
||||
/*TODO: Update it to use portASSERT_IF_IN_ISR() instead. (IDF-10540) */
|
||||
/* TODO: Update it to use portASSERT_IF_IN_ISR() instead. (IDF-10540) */
|
||||
vPortAssertIfInISR();
|
||||
|
||||
TaskHandle_t xCurrentTaskHandle = xTaskGetCurrentTaskHandle();
|
||||
@ -151,60 +180,8 @@ err:
|
||||
}
|
||||
}
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
else if( eRunning == eTaskGetState( xTaskToDelete ) )
|
||||
{
|
||||
/* The WithCaps task is running on another core.
|
||||
* We suspend the task first and then delete it. */
|
||||
vTaskSuspend( xTaskToDelete );
|
||||
|
||||
/* Wait for the task to be suspended */
|
||||
while( eRunning == eTaskGetState( xTaskToDelete ) )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
|
||||
// Return value unused if asserts are disabled
|
||||
BaseType_t __attribute__((unused)) xResult;
|
||||
StaticTask_t * pxTaskBuffer;
|
||||
StackType_t * puxStackBuffer;
|
||||
|
||||
xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer );
|
||||
configASSERT( xResult == pdTRUE );
|
||||
configASSERT( puxStackBuffer != NULL );
|
||||
configASSERT( pxTaskBuffer != NULL );
|
||||
|
||||
/* Delete the task */
|
||||
vTaskDelete( xTaskToDelete );
|
||||
|
||||
/* Free the memory buffers */
|
||||
heap_caps_free( puxStackBuffer );
|
||||
vPortFree( pxTaskBuffer );
|
||||
}
|
||||
#endif /* if ( configNUM_CORES > 1 ) */
|
||||
else
|
||||
{
|
||||
/* The WithCaps task is not running and is being deleted
|
||||
* from another task's context. */
|
||||
configASSERT( eRunning != eTaskGetState( xTaskToDelete ) );
|
||||
|
||||
// Return value unused if asserts are disabled
|
||||
BaseType_t __attribute__((unused)) xResult;
|
||||
StaticTask_t * pxTaskBuffer;
|
||||
StackType_t * puxStackBuffer;
|
||||
|
||||
xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer );
|
||||
configASSERT( xResult == pdTRUE );
|
||||
configASSERT( puxStackBuffer != NULL );
|
||||
configASSERT( pxTaskBuffer != NULL );
|
||||
|
||||
/* We can delete the task and free the memory buffers. */
|
||||
vTaskDelete( xTaskToDelete );
|
||||
|
||||
/* Free the memory buffers */
|
||||
heap_caps_free( puxStackBuffer );
|
||||
vPortFree( pxTaskBuffer );
|
||||
} /* if( ( xTaskToDelete == NULL ) || ( xTaskToDelete == xCurrentTaskHandle ) ) */
|
||||
/* Delete the WithCaps task */
|
||||
prvTaskDeleteWithCaps( xTaskToDelete );
|
||||
}
|
||||
|
||||
#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||
@ -262,8 +239,8 @@ err:
|
||||
|
||||
void vQueueDeleteWithCaps( QueueHandle_t xQueue )
|
||||
{
|
||||
// Return value unused if asserts are disabled
|
||||
BaseType_t __attribute__((unused)) xResult;
|
||||
/* Return value unused if asserts are disabled */
|
||||
BaseType_t __attribute__( ( unused ) ) xResult;
|
||||
StaticQueue_t * pxQueueBuffer;
|
||||
uint8_t * pucQueueStorageBuffer;
|
||||
|
||||
@ -335,8 +312,8 @@ err:
|
||||
|
||||
void vSemaphoreDeleteWithCaps( SemaphoreHandle_t xSemaphore )
|
||||
{
|
||||
// Return value unused if asserts are disabled
|
||||
BaseType_t __attribute__((unused)) xResult;
|
||||
/* Return value unused if asserts are disabled */
|
||||
BaseType_t __attribute__( ( unused ) ) xResult;
|
||||
StaticSemaphore_t * pxSemaphoreBuffer;
|
||||
|
||||
/* Retrieve the buffer used to create the semaphore before deleting it
|
||||
@ -408,8 +385,8 @@ err:
|
||||
void vStreamBufferGenericDeleteWithCaps( StreamBufferHandle_t xStreamBuffer,
|
||||
BaseType_t xIsMessageBuffer )
|
||||
{
|
||||
// Return value unused if asserts are disabled
|
||||
BaseType_t __attribute__((unused)) xResult;
|
||||
/* Return value unused if asserts are disabled */
|
||||
BaseType_t __attribute__( ( unused ) ) xResult;
|
||||
StaticStreamBuffer_t * pxStaticStreamBuffer;
|
||||
uint8_t * pucStreamBufferStorageArea;
|
||||
|
||||
|
@ -89,6 +89,34 @@ TEST_CASE("IDF additions: Task creation with memory caps and self deletion", "[f
|
||||
xTaskNotifyGive(task_handle);
|
||||
}
|
||||
|
||||
#if CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
|
||||
|
||||
TEST_CASE("IDF additions: Task creation with SPIRAM memory caps and self deletion stress test", "[freertos]")
|
||||
{
|
||||
#define TEST_NUM_TASKS 5
|
||||
#define TEST_NUM_ITERATIONS 1000
|
||||
TaskHandle_t task_handle[TEST_NUM_TASKS];
|
||||
StackType_t *puxStackBuffer;
|
||||
StaticTask_t *pxTaskBuffer;
|
||||
|
||||
for (int j = 0; j < TEST_NUM_ITERATIONS; j++) {
|
||||
for (int i = 0; i < TEST_NUM_TASKS; i++) {
|
||||
// Create a task with caps
|
||||
TEST_ASSERT_EQUAL(pdPASS, xTaskCreateWithCaps(task_with_caps_self_delete, "task", 4096, NULL, UNITY_FREERTOS_PRIORITY, &task_handle[i], MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT));
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, task_handle);
|
||||
// Get the task's memory
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xTaskGetStaticBuffers(task_handle[i], &puxStackBuffer, &pxTaskBuffer));
|
||||
}
|
||||
|
||||
for (int i = 0; i < TEST_NUM_TASKS; i++) {
|
||||
// Notify the task to delete itself
|
||||
xTaskNotifyGive(task_handle[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
|
||||
|
||||
#if ( CONFIG_FREERTOS_NUMBER_OF_CORES > 1 )
|
||||
|
||||
static void task_with_caps_running_on_other_core(void *arg)
|
||||
|
@ -5,6 +5,7 @@ CONFIG_IDF_TARGET="esp32"
|
||||
# Enable SPIRAM
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_OCCUPY_NO_HOST=y
|
||||
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
|
||||
|
||||
# Disable encrypted flash reads/writes to save IRAM in this build configuration
|
||||
CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=n
|
||||
|
172
components/hal/esp32c61/include/hal/pau_ll.h
Normal file
172
components/hal/esp32c61/include/hal/pau_ll.h
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for ESP32-C61 PAU(Power Assist Unit) register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/pau_reg.h"
|
||||
#include "soc/pau_struct.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "hal/pau_types.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void pau_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
PCR.regdma_conf.regdma_clk_en = 1;
|
||||
PCR.regdma_conf.regdma_rst_en = 0;
|
||||
} else {
|
||||
PCR.regdma_conf.regdma_clk_en = 0;
|
||||
PCR.regdma_conf.regdma_rst_en = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t pau_ll_get_regdma_backup_flow_error(pau_dev_t *dev)
|
||||
{
|
||||
return dev->regdma_conf.flow_err;
|
||||
}
|
||||
|
||||
static inline void pau_ll_select_regdma_entry_link(pau_dev_t *dev, int link)
|
||||
{
|
||||
dev->regdma_conf.link_sel = link;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_entry_link_backup_direction(pau_dev_t *dev, bool to_mem)
|
||||
{
|
||||
dev->regdma_conf.to_mem = to_mem ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_entry_link_backup_start_enable(pau_dev_t *dev)
|
||||
{
|
||||
dev->regdma_conf.start = 1;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_entry_link_backup_start_disable(pau_dev_t *dev)
|
||||
{
|
||||
dev->regdma_conf.start = 0;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_select_wifimac_link(pau_dev_t *dev)
|
||||
{
|
||||
dev->regdma_conf.sel_mac = 1;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_deselect_wifimac_link(pau_dev_t *dev)
|
||||
{
|
||||
dev->regdma_conf.sel_mac = 0;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_wifimac_link_backup_direction(pau_dev_t *dev, bool to_mem)
|
||||
{
|
||||
dev->regdma_conf.to_mem_mac = to_mem ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_wifimac_link_backup_start_enable(pau_dev_t *dev)
|
||||
{
|
||||
dev->regdma_conf.start_mac = 1;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_wifimac_link_backup_start_disable(pau_dev_t *dev)
|
||||
{
|
||||
dev->regdma_conf.start_mac = 0;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_link0_addr(pau_dev_t *dev, void *link_addr)
|
||||
{
|
||||
dev->regdma_link_0_addr.val = (uint32_t)link_addr;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_link1_addr(pau_dev_t *dev, void *link_addr)
|
||||
{
|
||||
dev->regdma_link_1_addr.val = (uint32_t)link_addr;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_link2_addr(pau_dev_t *dev, void *link_addr)
|
||||
{
|
||||
dev->regdma_link_2_addr.val = (uint32_t)link_addr;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_link3_addr(pau_dev_t *dev, void *link_addr)
|
||||
{
|
||||
dev->regdma_link_3_addr.val = (uint32_t)link_addr;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_wifimac_link_addr(pau_dev_t *dev, void *link_addr)
|
||||
{
|
||||
dev->regdma_link_mac_addr.val = (uint32_t)link_addr;
|
||||
}
|
||||
|
||||
static inline uint32_t pau_ll_get_regdma_current_link_addr(pau_dev_t *dev)
|
||||
{
|
||||
return dev->regdma_current_link_addr.val;
|
||||
}
|
||||
|
||||
static inline uint32_t pau_ll_get_regdma_backup_addr(pau_dev_t *dev)
|
||||
{
|
||||
return dev->regdma_backup_addr.val;
|
||||
}
|
||||
|
||||
static inline uint32_t pau_ll_get_regdma_memory_addr(pau_dev_t *dev)
|
||||
{
|
||||
return dev->regdma_mem_addr.val;
|
||||
}
|
||||
|
||||
static inline uint32_t pau_ll_get_regdma_intr_raw_signal(pau_dev_t *dev)
|
||||
{
|
||||
return dev->int_raw.val;
|
||||
}
|
||||
|
||||
static inline uint32_t pau_ll_get_regdma_intr_status(pau_dev_t *dev)
|
||||
{
|
||||
return dev->int_st.val;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_backup_done_intr_enable(pau_dev_t *dev)
|
||||
{
|
||||
dev->int_ena.done_int_ena = 1;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_backup_done_intr_disable(pau_dev_t *dev)
|
||||
{
|
||||
dev->int_ena.done_int_ena = 0;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_backup_error_intr_enable(pau_dev_t *dev, bool enable)
|
||||
{
|
||||
dev->int_ena.error_int_ena = enable;
|
||||
}
|
||||
|
||||
static inline void pau_ll_clear_regdma_backup_done_intr_state(pau_dev_t *dev)
|
||||
{
|
||||
dev->int_clr.done_int_clr = 1;
|
||||
}
|
||||
|
||||
static inline void pau_ll_clear_regdma_backup_error_intr_state(pau_dev_t *dev)
|
||||
{
|
||||
dev->int_clr.error_int_clr = 1;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_link_wait_retry_count(pau_dev_t *dev, int count)
|
||||
{
|
||||
dev->regdma_bkp_conf.link_tout_thres = count;
|
||||
}
|
||||
|
||||
static inline void pau_ll_set_regdma_link_wait_read_interval(pau_dev_t *dev, int interval)
|
||||
{
|
||||
dev->regdma_bkp_conf.read_interval = interval;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -24,6 +24,7 @@ extern "C" {
|
||||
// Get timer group register base address with giving group number
|
||||
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
|
||||
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
|
||||
#define TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id) ((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER: SLEEP_RETENTION_MODULE_TG1_TIMER)
|
||||
|
||||
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
|
||||
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \
|
||||
|
@ -64,6 +64,10 @@ extern "C" {
|
||||
((hw) == &UART1) ? PCR.uart1_##reg_suffix.uart1_##field_suffix : \
|
||||
PCR.uart2_##reg_suffix.uart2_##field_suffix)
|
||||
|
||||
// UART sleep retention module
|
||||
#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \
|
||||
(uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : -1)
|
||||
|
||||
// Define UART interrupts
|
||||
typedef enum {
|
||||
UART_INTR_RXFIFO_FULL = (0x1 << 0),
|
||||
|
@ -59,7 +59,7 @@ void IRAM_ATTR modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_conte
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain)
|
||||
uint32_t IRAM_ATTR modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain)
|
||||
{
|
||||
HAL_ASSERT(domain < MODEM_CLOCK_DOMAIN_MAX);
|
||||
uint32_t bitmap = 0;
|
||||
|
@ -4,8 +4,6 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The HAL layer for PAU (ESP32-C61 specific part)
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "esp_attr.h"
|
||||
#include "hal/pau_hal.h"
|
||||
@ -59,3 +57,14 @@ void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal)
|
||||
pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */
|
||||
pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
|
||||
}
|
||||
|
||||
void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t time)
|
||||
{
|
||||
}
|
||||
|
||||
void pau_hal_set_regdma_wait_timeout(pau_hal_context_t *hal, int count, int interval)
|
||||
{
|
||||
HAL_ASSERT(count > 0 && interval > 0);
|
||||
pau_ll_set_regdma_link_wait_retry_count(hal->dev, count);
|
||||
pau_ll_set_regdma_link_wait_read_interval(hal->dev, interval);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for ESP32-C6 PAU(Power Assist Unit) register operations
|
||||
// The LL layer for ESP32-P4 PAU(Power Assist Unit) register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -12,6 +12,11 @@
|
||||
#include "heap_memory_layout.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
/* Memory layout for ESP32C61 SoC
|
||||
* Note that the external memory is not represented in this file since
|
||||
* it is handled by the esp_psram component
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Memory type descriptors. These describe the capabilities of a type of memory in the SoC.
|
||||
* Each type of memory map consists of one or more regions in the address space.
|
||||
@ -27,16 +32,14 @@
|
||||
|
||||
/* Index of memory in `soc_memory_types[]` */
|
||||
enum {
|
||||
SOC_MEMORY_TYPE_RAM = 0,
|
||||
SOC_MEMORY_TYPE_RTCRAM = 1,
|
||||
SOC_MEMORY_TYPE_NUM,
|
||||
SOC_MEMORY_TYPE_RAM,
|
||||
};
|
||||
|
||||
/* COMMON_CAPS is the set of attributes common to all types of memory on this chip */
|
||||
#ifdef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
|
||||
#define ESP32C6_MEM_COMMON_CAPS (MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT | MALLOC_CAP_8BIT)
|
||||
#define ESP32C61_MEM_COMMON_CAPS (MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT | MALLOC_CAP_8BIT)
|
||||
#else
|
||||
#define ESP32C6_MEM_COMMON_CAPS (MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_EXEC)
|
||||
#define ESP32C61_MEM_COMMON_CAPS (MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_EXEC)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -45,10 +48,9 @@ enum {
|
||||
* if no memory caps matched or the allocation is failed, it will go to columns Medium Priority Matching and Low Priority Matching
|
||||
* in turn to continue matching.
|
||||
*/
|
||||
const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = {
|
||||
const soc_memory_type_desc_t soc_memory_types[] = {
|
||||
/* Mem Type Name High Priority Matching Medium Priority Matching Low Priority Matching */
|
||||
[SOC_MEMORY_TYPE_RAM] = { "RAM", { ESP32C6_MEM_COMMON_CAPS | MALLOC_CAP_DMA, 0, 0 }},
|
||||
[SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, ESP32C6_MEM_COMMON_CAPS, 0 }},
|
||||
[SOC_MEMORY_TYPE_RAM] = { "RAM", { ESP32C61_MEM_COMMON_CAPS | MALLOC_CAP_DMA, 0, 0 }},
|
||||
};
|
||||
|
||||
const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memory_type_desc_t);
|
||||
@ -64,19 +66,17 @@ const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memor
|
||||
/**
|
||||
* Register the shared buffer area of the last memory block into the heap during heap initialization
|
||||
*/
|
||||
#define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE)
|
||||
#define APP_USABLE_DIRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE)
|
||||
|
||||
const soc_memory_region_t soc_memory_regions[] = {
|
||||
{ 0x40800000, 0x20000, SOC_MEMORY_TYPE_RAM, 0x40800000, false}, //D/IRAM level0, can be used as trace memory
|
||||
{ 0x40820000, 0x20000, SOC_MEMORY_TYPE_RAM, 0x40820000, false}, //D/IRAM level1, can be used as trace memory
|
||||
{ 0x40840000, (APP_USABLE_DRAM_END-0x40840000), SOC_MEMORY_TYPE_RAM, 0x40840000, false}, //D/IRAM level2, can be used as trace memory
|
||||
{ APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH-APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_RAM, APP_USABLE_DRAM_END, true}, //D/IRAM level3, can be used as trace memory (ROM reserved area)
|
||||
{ SOC_DIRAM_DRAM_LOW, (APP_USABLE_DIRAM_END - SOC_DIRAM_DRAM_LOW), SOC_MEMORY_TYPE_RAM, SOC_DIRAM_IRAM_LOW, false}, //D/IRAM, can be used as trace memory
|
||||
{ APP_USABLE_DIRAM_END, (SOC_DIRAM_DRAM_HIGH - APP_USABLE_DIRAM_END), SOC_MEMORY_TYPE_RAM, APP_USABLE_DIRAM_END, true}, //D/IRAM, can be used as trace memory (ROM reserved area)
|
||||
};
|
||||
|
||||
const size_t soc_memory_region_count = sizeof(soc_memory_regions) / sizeof(soc_memory_region_t);
|
||||
|
||||
|
||||
extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_slow_end;
|
||||
extern int _data_start, _heap_start, _iram_start, _iram_end;
|
||||
|
||||
/**
|
||||
* Reserved memory regions.
|
||||
|
@ -3,9 +3,6 @@
|
||||
components/heap/test_apps/heap_tests:
|
||||
disable:
|
||||
- if: IDF_TARGET == "linux"
|
||||
- if: IDF_TARGET in ["esp32c61"]
|
||||
temporary: true
|
||||
reason: not support yet # TODO: [esp32c61] IDF-9858
|
||||
- if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1
|
||||
- if: CONFIG_NAME == "psram_all_ext" and SOC_SPIRAM_SUPPORTED != 1
|
||||
# These 3 configs are build only for non-nightly, buildig for a single target is sufficient
|
||||
|
@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
@ -6,7 +6,6 @@ from pytest_embedded import Dut
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='support TBD') # TODO [ESP32C61] IDF-9858 IDF-10989
|
||||
@pytest.mark.nightly_run
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
@ -40,7 +39,6 @@ def test_heap_poisoning_qemu(dut: Dut) -> None:
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='support TBD') # TODO [ESP32C61] IDF-9858 IDF-10989
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
@ -52,9 +50,14 @@ def test_heap_in_flash(dut: Dut) -> None:
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.parametrize(
|
||||
'target',
|
||||
[
|
||||
'esp32',
|
||||
'esp32s2',
|
||||
'esp32s3',
|
||||
]
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
@ -67,7 +70,12 @@ def test_heap(dut: Dut) -> None:
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.parametrize(
|
||||
'target',
|
||||
[
|
||||
'esp32',
|
||||
]
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
@ -86,7 +94,12 @@ def test_heap_misc_options(dut: Dut) -> None:
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.parametrize(
|
||||
'target',
|
||||
[
|
||||
'esp32',
|
||||
]
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
|
@ -1355,11 +1355,15 @@ menu "LWIP"
|
||||
choice LWIP_HOOK_IP6_INPUT
|
||||
prompt "IPv6 packet input"
|
||||
depends on LWIP_IPV6
|
||||
default LWIP_HOOK_IP6_INPUT_NONE
|
||||
default LWIP_HOOK_IP6_INPUT_DEFAULT
|
||||
help
|
||||
Enables custom IPv6 packet input.
|
||||
Setting this to "default" provides weak implementation
|
||||
stub that could be overwritten in application code.
|
||||
Setting this to "default" provides weak IDF implementation,
|
||||
which drops all incoming IPv6 traffic if the interface has no link local address.
|
||||
(this default implementation is "weak" and could be still overwritten
|
||||
in the application if some additional IPv6 input packet filtering is needed)
|
||||
Setting this to "none" removes this default filter and conforms to the lwIP
|
||||
implementation (which accepts multicasts even if the interface has no link local address)
|
||||
Setting this to "custom" provides hook's declaration
|
||||
only and expects the application to implement it.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -56,11 +56,25 @@ const ip_addr_t *__weak lwip_hook_ip6_select_source_address(struct netif *netif,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT
|
||||
/**
|
||||
* @brief The default IPv6 input hook checks if we already have an IPv6 address (netif->ip6_addr[0] is link local),
|
||||
* so we drop all incoming IPv6 packets if the input netif has no LL address.
|
||||
*
|
||||
* LWIP accepts IPv6 multicast packets even if the ip6_addr[] for the given address wasn't set,
|
||||
* this may cause trouble if we enable IPv6 SLAAC (LWIP_IPV6_AUTOCONFIG), but have not created any LL address.
|
||||
* If the router sends a packet to all nodes 0xff01::1 with RDNSS servers, it would be accepted and rewrite
|
||||
* DNS server info with IPv6 values (which won't be routable without any IPv6 address assigned)
|
||||
*/
|
||||
int __weak lwip_hook_ip6_input(struct pbuf *p, struct netif *inp)
|
||||
{
|
||||
LWIP_UNUSED_ARG(p);
|
||||
LWIP_UNUSED_ARG(inp);
|
||||
|
||||
/* Check if the first IPv6 address (link-local) is unassigned (all zeros).
|
||||
* If the address is empty, it indicates that no link-local address has been configured,
|
||||
* and the interface should not accept incoming IPv6 traffic. */
|
||||
if (ip6_addr_isany(ip_2_ip6(&inp->ip6_addr[0]))) {
|
||||
/* We don't have an LL address -> eat this packet here, so it won't get accepted on the input netif */
|
||||
pbuf_free(p);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -142,6 +142,18 @@ extern "C" {
|
||||
RV_WRITE_CSR((CSR_PMAADDR0) + (ENTRY) , 0); \
|
||||
} while(0)
|
||||
|
||||
/* Reset and set the configuration of a particular TOR PMACFG entry */
|
||||
#define PMA_RESET_AND_ENTRY_SET_TOR(ENTRY, ADDR, CFG) do {\
|
||||
PMA_ENTRY_CFG_RESET(ENTRY); \
|
||||
PMA_ENTRY_SET_TOR(ENTRY, ADDR, CFG); \
|
||||
} while(0)
|
||||
|
||||
/* Reset and set the configuration of a particular NAPOT PMACFG entry */
|
||||
#define PMA_RESET_AND_ENTRY_SET_NAPOT(ENTRY, ADDR, SIZE, CFG) do {\
|
||||
PMA_ENTRY_CFG_RESET(ENTRY); \
|
||||
PMA_ENTRY_SET_NAPOT(ENTRY, ADDR, SIZE, CFG); \
|
||||
} while(0)
|
||||
|
||||
/********************************************************
|
||||
Trigger Module register fields (Debug specification)
|
||||
********************************************************/
|
||||
|
@ -1359,10 +1359,6 @@ config SOC_CLK_LP_FAST_SUPPORT_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_RC32K_NOT_TO_USE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_RCC_IS_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
@ -579,7 +579,6 @@
|
||||
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
|
||||
#define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< Support to connect an external oscillator, not a crystal */
|
||||
#define SOC_CLK_LP_FAST_SUPPORT_XTAL (1) /*!< Support XTAL clock as the LP_FAST clock source */
|
||||
#define SOC_CLK_RC32K_NOT_TO_USE (1) /*!< Due to the poor low-temperature characteristics of RC32K (it cannot operate below -40 degrees Celsius), please avoid using it whenever possible. */
|
||||
#define SOC_RCC_IS_INDEPENDENT 1 /*!< Reset and Clock Control is independent, thanks to the PCR registers */
|
||||
|
||||
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
|
||||
|
@ -107,6 +107,10 @@ config SOC_LP_TIMER_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LP_AON_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_TREE_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
@ -127,10 +131,18 @@ config SOC_REG_I2C_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PAU_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LIGHT_SLEEP_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_DEEP_SLEEP_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
@ -295,6 +307,10 @@ config SOC_GPIO_OUT_RANGE_MAX
|
||||
int
|
||||
default 21
|
||||
|
||||
config SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK
|
||||
int
|
||||
default 0
|
||||
@ -659,6 +675,14 @@ config SOC_TIMER_GROUP_SUPPORT_RC_FAST
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TIMER_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MWDT_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_EFUSE_DIS_DOWNLOAD_ICACHE
|
||||
bool
|
||||
default n
|
||||
@ -759,6 +783,10 @@ config SOC_UART_SUPPORT_WAKEUP_INT
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_UART_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND
|
||||
bool
|
||||
default y
|
||||
@ -783,6 +811,14 @@ config SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH
|
||||
int
|
||||
default 12
|
||||
|
||||
config SOC_PM_SUPPORT_EXT1_WAKEUP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_SUPPORT_CPU_PD
|
||||
bool
|
||||
default y
|
||||
@ -807,6 +843,10 @@ config SOC_PM_SUPPORT_VDDSDIO_PD
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_SUPPORT_TOP_PD
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_SUPPORT_HP_AON_PD
|
||||
bool
|
||||
default y
|
||||
@ -829,16 +869,32 @@ config SOC_PM_CPU_RETENTION_BY_SW
|
||||
|
||||
config SOC_PM_MODEM_RETENTION_BY_REGDMA
|
||||
bool
|
||||
default n
|
||||
default y
|
||||
|
||||
config SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_PAU_LINK_NUM
|
||||
int
|
||||
default 4
|
||||
|
||||
config SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_PAU_REGDMA_LINK_WIFIMAC
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
|
||||
bool
|
||||
default y
|
||||
@ -859,10 +915,6 @@ config SOC_CLK_LP_FAST_SUPPORT_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_RC32K_NOT_TO_USE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_RCC_IS_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
@ -35,7 +35,7 @@
|
||||
#define DR_REG_PAU_BASE 0x60093000
|
||||
#define DR_REG_HP_SYSTEM_BASE 0x60095000
|
||||
#define DR_REG_PCR_BASE 0x60096000
|
||||
#define DR_REG_TEE_REG_BASE 0x60098000
|
||||
#define DR_REG_TEE_BASE 0x60098000
|
||||
#define DR_REG_HP_APM_BASE 0x60099000
|
||||
#define DR_REG_MISC_BASE 0x6009F000
|
||||
#define DR_REG_MODEM0_BASE 0x600A0000
|
||||
@ -61,4 +61,3 @@
|
||||
#define DR_REG_INTPRI_BASE 0x600C5000
|
||||
#define DR_REG_CACHE_BASE 0x600C8000
|
||||
#define DR_REG_CLINT_M_BASE 0x20000000
|
||||
#define DR_REG_TEE_BASE DR_REG_TEE_REG_BASE
|
||||
|
@ -18,23 +18,29 @@ typedef enum periph_retention_module {
|
||||
/* clock module, which includes system and modem */
|
||||
SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1,
|
||||
SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2,
|
||||
|
||||
/* modem module, which includes WiFi, BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_WIFI_MAC = 10,
|
||||
SLEEP_RETENTION_MODULE_WIFI_BB = 11,
|
||||
SLEEP_RETENTION_MODULE_BLE_MAC = 12,
|
||||
SLEEP_RETENTION_MODULE_BT_BB = 13,
|
||||
SLEEP_RETENTION_MODULE_802154_MAC = 14,
|
||||
|
||||
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
|
||||
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
|
||||
SLEEP_RETENTION_MODULE_SYS_PERIPH = 16,
|
||||
|
||||
SLEEP_RETENTION_MODULE_GDMA_CH0 = 24,
|
||||
SLEEP_RETENTION_MODULE_GDMA_CH1 = 25,
|
||||
SLEEP_RETENTION_MODULE_GDMA_CH2 = 26,
|
||||
SLEEP_RETENTION_MODULE_I2C0 = 27,
|
||||
* TEE, APM, IOMUX, SPIMEM, SysTimer, etc.. */
|
||||
SLEEP_RETENTION_MODULE_SYS_PERIPH = 3,
|
||||
/* Timer Group by target */
|
||||
SLEEP_RETENTION_MODULE_TG0_WDT = 4,
|
||||
SLEEP_RETENTION_MODULE_TG1_WDT = 5,
|
||||
SLEEP_RETENTION_MODULE_TG0_TIMER = 6,
|
||||
SLEEP_RETENTION_MODULE_TG1_TIMER = 7,
|
||||
/* GDMA by channel */
|
||||
SLEEP_RETENTION_MODULE_GDMA_CH0 = 8,
|
||||
SLEEP_RETENTION_MODULE_GDMA_CH1 = 9,
|
||||
SLEEP_RETENTION_MODULE_GDMA_CH2 = 10,
|
||||
/* MISC Peripherals */
|
||||
SLEEP_RETENTION_MODULE_I2C0 = 12,
|
||||
SLEEP_RETENTION_MODULE_UART0 = 14,
|
||||
SLEEP_RETENTION_MODULE_UART1 = 15,
|
||||
|
||||
/* Modem module, which includes WiFi, BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
|
||||
SLEEP_RETENTION_MODULE_WIFI_BB = 27,
|
||||
SLEEP_RETENTION_MODULE_BLE_MAC = 28,
|
||||
SLEEP_RETENTION_MODULE_BT_BB = 29,
|
||||
SLEEP_RETENTION_MODULE_802154_MAC = 30,
|
||||
SLEEP_RETENTION_MODULE_MAX = 31
|
||||
} periph_retention_module_t;
|
||||
|
||||
@ -42,26 +48,44 @@ typedef enum periph_retention_module_bitmap {
|
||||
/* clock module, which includes system and modem */
|
||||
SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM),
|
||||
SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM),
|
||||
|
||||
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
|
||||
* TEE, APM, IOMUX, SPIMEM, SysTimer, etc.. */
|
||||
SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
|
||||
/* Timer Group by target*/
|
||||
SLEEP_RETENTION_MODULE_BM_TASK_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT),
|
||||
SLEEP_RETENTION_MODULE_BM_INT_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT),
|
||||
SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER),
|
||||
SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER),
|
||||
/* GDMA by channel */
|
||||
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
|
||||
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
|
||||
SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2),
|
||||
/* MISC Peripherals */
|
||||
SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0),
|
||||
SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0),
|
||||
SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1),
|
||||
/* 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),
|
||||
SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC),
|
||||
SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB),
|
||||
SLEEP_RETENTION_MODULE_BM_802154_MAC = BIT(SLEEP_RETENTION_MODULE_802154_MAC),
|
||||
|
||||
/* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM,
|
||||
* TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */
|
||||
SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH),
|
||||
|
||||
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
|
||||
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
|
||||
SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2),
|
||||
SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0),
|
||||
|
||||
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
|
||||
} periph_retention_module_bitmap_t;
|
||||
|
||||
#define TOP_DOMAIN_PERIPHERALS_BM ( SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \
|
||||
| SLEEP_RETENTION_MODULE_BM_TASK_WDT \
|
||||
| SLEEP_RETENTION_MODULE_BM_INT_WDT \
|
||||
| SLEEP_RETENTION_MODULE_BM_TG0_TIMER \
|
||||
| SLEEP_RETENTION_MODULE_BM_TG1_TIMER \
|
||||
| SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2C0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_UART0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_UART1 \
|
||||
)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -146,20 +146,21 @@
|
||||
* should be defined statically!
|
||||
*/
|
||||
|
||||
#define SOC_IROM_LOW 0x42000000
|
||||
#define SOC_IROM_HIGH 0x44000000
|
||||
#define SOC_EXTRAM_DATA_LOW 0x42000000
|
||||
#define SOC_EXTRAM_DATA_HIGH 0x44000000
|
||||
#define SOC_DROM_LOW SOC_IROM_LOW
|
||||
#define SOC_DROM_HIGH SOC_IROM_HIGH
|
||||
#define SOC_IROM_MASK_LOW 0x40000000
|
||||
#define SOC_IROM_MASK_HIGH 0x40040000
|
||||
#define SOC_DROM_MASK_LOW 0x40000000
|
||||
#define SOC_DROM_MASK_HIGH 0x40040000
|
||||
#define SOC_IRAM_LOW 0x40800000
|
||||
#define SOC_IRAM_HIGH 0x40850000
|
||||
#define SOC_DRAM_LOW 0x40800000
|
||||
#define SOC_DRAM_HIGH 0x40850000
|
||||
#define SOC_IROM_LOW 0x42000000
|
||||
#define SOC_IROM_HIGH 0x44000000
|
||||
#define SOC_EXTRAM_DATA_LOW 0x42000000
|
||||
#define SOC_EXTRAM_DATA_HIGH 0x44000000
|
||||
#define SOC_EXTRAM_DATA_SIZE (SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW)
|
||||
#define SOC_DROM_LOW SOC_IROM_LOW
|
||||
#define SOC_DROM_HIGH SOC_IROM_HIGH
|
||||
#define SOC_IROM_MASK_LOW 0x40000000
|
||||
#define SOC_IROM_MASK_HIGH 0x40040000
|
||||
#define SOC_DROM_MASK_LOW 0x40000000
|
||||
#define SOC_DROM_MASK_HIGH 0x40040000
|
||||
#define SOC_IRAM_LOW 0x40800000
|
||||
#define SOC_IRAM_HIGH 0x40850000
|
||||
#define SOC_DRAM_LOW 0x40800000
|
||||
#define SOC_DRAM_HIGH 0x40850000
|
||||
|
||||
//First and last words of the D/IRAM region, for both the DRAM address as well as the IRAM alias.
|
||||
#define SOC_DIRAM_IRAM_LOW 0x40800000
|
||||
@ -196,7 +197,7 @@
|
||||
#define SOC_CPU_SUBSYSTEM_HIGH 0x30000000
|
||||
|
||||
// Start (highest address) of ROM boot stack, only relevant during early boot
|
||||
#define SOC_ROM_STACK_START 0x4084c9f0
|
||||
#define SOC_ROM_STACK_START 0x4084ea70
|
||||
#define SOC_ROM_STACK_SIZE 0x2000
|
||||
|
||||
//On RISC-V CPUs, the interrupt sources are all external interrupts, whose type, source and priority are configured by SW.
|
||||
|
@ -48,7 +48,7 @@
|
||||
#define SOC_APM_SUPPORTED 1 /*!< Support for APM peripheral */
|
||||
#define SOC_PMU_SUPPORTED 1
|
||||
#define SOC_LP_TIMER_SUPPORTED 1
|
||||
// \#define SOC_LP_AON_SUPPORTED 1
|
||||
#define SOC_LP_AON_SUPPORTED 1
|
||||
// \#define SOC_LP_PERIPHERALS_SUPPORTED 1
|
||||
#define SOC_CLK_TREE_SUPPORTED 1
|
||||
// \#define SOC_ASSIST_DEBUG_SUPPORTED 1 //TODO: [ESP32C61] IDF-9269
|
||||
@ -59,8 +59,9 @@
|
||||
#define SOC_REG_I2C_SUPPORTED 1
|
||||
// \#define SOC_ETM_SUPPORTED 0
|
||||
// \#define SOC_SDIO_SLAVE_SUPPORTED 0
|
||||
// \#define SOC_PAU_SUPPORTED 0
|
||||
#define SOC_PAU_SUPPORTED 1
|
||||
#define SOC_LIGHT_SLEEP_SUPPORTED 1
|
||||
#define SOC_DEEP_SLEEP_SUPPORTED 1
|
||||
#define SOC_PM_SUPPORTED 1
|
||||
#define SOC_ECDSA_SUPPORTED 1
|
||||
#define SOC_SPIRAM_SUPPORTED 1
|
||||
@ -179,7 +180,7 @@
|
||||
#define SOC_GPIO_OUT_RANGE_MAX 21
|
||||
|
||||
// GPIO0~6 on ESP32C61 can support chip deep sleep wakeup
|
||||
// \#define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) //TODO: IDF-9245
|
||||
#define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1)
|
||||
#define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK (0ULL | BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6)
|
||||
#define SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT (7)
|
||||
|
||||
@ -348,10 +349,12 @@
|
||||
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
|
||||
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
||||
#define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1)
|
||||
#define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1)
|
||||
// #define SOC_TIMER_SUPPORT_ETM (1)
|
||||
|
||||
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
|
||||
// #define SOC_MWDT_SUPPORT_XTAL (1)
|
||||
#define SOC_MWDT_SUPPORT_SLEEP_RETENTION (1)
|
||||
|
||||
/*-------------------------- eFuse CAPS----------------------------*/
|
||||
#define SOC_EFUSE_DIS_DOWNLOAD_ICACHE 0
|
||||
@ -390,7 +393,7 @@
|
||||
#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */
|
||||
#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */
|
||||
#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */
|
||||
|
||||
#define SOC_UART_SUPPORT_SLEEP_RETENTION (1)
|
||||
// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled
|
||||
#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1)
|
||||
|
||||
@ -414,15 +417,15 @@
|
||||
// #define SOC_PM_SUPPORT_WIFI_WAKEUP (1)
|
||||
// #define SOC_PM_SUPPORT_BEACON_WAKEUP (1)
|
||||
// #define SOC_PM_SUPPORT_BT_WAKEUP (1)
|
||||
// #define SOC_PM_SUPPORT_EXT1_WAKEUP (1)
|
||||
// #define SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN (1) /*!<Supports one bit per pin to configure the EXT1 trigger level */
|
||||
#define SOC_PM_SUPPORT_EXT1_WAKEUP (1)
|
||||
#define SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN (1) /*!<Supports one bit per pin to configure the EXT1 trigger level */
|
||||
#define SOC_PM_SUPPORT_CPU_PD (1)
|
||||
#define SOC_PM_SUPPORT_MODEM_PD (1)
|
||||
#define SOC_PM_SUPPORT_XTAL32K_PD (1)
|
||||
#define SOC_PM_SUPPORT_RC32K_PD (1)
|
||||
#define SOC_PM_SUPPORT_RC_FAST_PD (1)
|
||||
#define SOC_PM_SUPPORT_VDDSDIO_PD (1)
|
||||
// \#define SOC_PM_SUPPORT_TOP_PD (1)
|
||||
#define SOC_PM_SUPPORT_TOP_PD (1)
|
||||
#define SOC_PM_SUPPORT_HP_AON_PD (1)
|
||||
#define SOC_PM_SUPPORT_MAC_BB_PD (1)
|
||||
#define SOC_PM_SUPPORT_RTC_PERIPH_PD (1)
|
||||
@ -431,12 +434,16 @@
|
||||
/* macro redefine for pass esp_wifi headers md5sum check */
|
||||
#define MAC_SUPPORT_PMU_MODEM_STATE SOC_PM_SUPPORT_PMU_MODEM_STATE
|
||||
|
||||
// #define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*!<Supports CRC only the stub code in RTC memory */
|
||||
|
||||
#define SOC_PM_CPU_RETENTION_BY_SW (1)
|
||||
#define SOC_PM_MODEM_RETENTION_BY_REGDMA (0)
|
||||
#define SOC_PM_MODEM_RETENTION_BY_REGDMA (1)
|
||||
#define SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN (1)
|
||||
#define SOC_PM_PAU_LINK_NUM (4)
|
||||
#define SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD (1)
|
||||
|
||||
#define SOC_PM_PAU_LINK_NUM (4)
|
||||
#define SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR (1)
|
||||
#define SOC_PM_PAU_REGDMA_LINK_WIFIMAC (1)
|
||||
|
||||
#define SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE (1)
|
||||
|
||||
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
|
||||
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
|
||||
@ -445,7 +452,6 @@
|
||||
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
|
||||
#define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< Support to connect an external oscillator, not a crystal */
|
||||
#define SOC_CLK_LP_FAST_SUPPORT_XTAL (1) /*!< Support XTAL clock as the LP_FAST clock source */
|
||||
#define SOC_CLK_RC32K_NOT_TO_USE (1) /*!< Due to the poor low-temperature characteristics of RC32K (it cannot operate below -40 degrees Celsius), please avoid using it whenever possible. */
|
||||
#define SOC_RCC_IS_INDEPENDENT 1 /*!< Reset and Clock Control is independent, thanks to the PCR registers */
|
||||
|
||||
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/regdma.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Provide access to interrupt matrix configuration registers retention
|
||||
* context definition.
|
||||
*
|
||||
* This is an internal function of the sleep retention driver, and is not
|
||||
* useful for external use.
|
||||
*/
|
||||
#define INT_MTX_RETENTION_LINK_LEN 1
|
||||
extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN];
|
||||
|
||||
/**
|
||||
* @brief Provide access to hp_system configuration registers retention
|
||||
* context definition.
|
||||
*
|
||||
* This is an internal function of the sleep retention driver, and is not
|
||||
* useful for external use.
|
||||
*/
|
||||
#define HP_SYSTEM_RETENTION_LINK_LEN 1
|
||||
extern const regdma_entries_config_t hp_system_regs_retention[HP_SYSTEM_RETENTION_LINK_LEN];
|
||||
|
||||
/**
|
||||
* @brief Provide access to TEE_APM configuration registers retention
|
||||
* context definition.
|
||||
*
|
||||
* This is an internal function of the sleep retention driver, and is not
|
||||
* useful for external use.
|
||||
*/
|
||||
#define TEE_APM_RETENTION_LINK_LEN 2
|
||||
extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LINK_LEN];
|
||||
#define TEE_APM_HIGH_PRI_RETENTION_LINK_LEN 1
|
||||
extern const regdma_entries_config_t tee_apm_highpri_regs_retention[TEE_APM_HIGH_PRI_RETENTION_LINK_LEN];
|
||||
|
||||
/**
|
||||
* @brief Provide access to IOMUX configuration registers retention
|
||||
* context definition.
|
||||
*
|
||||
* This is an internal function of the sleep retention driver, and is not
|
||||
* useful for external use.
|
||||
*/
|
||||
#define IOMUX_RETENTION_LINK_LEN 7
|
||||
extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_LEN];
|
||||
|
||||
/**
|
||||
* @brief Provide access to spimem configuration registers retention
|
||||
* context definition.
|
||||
*
|
||||
* This is an internal function of the sleep retention driver, and is not
|
||||
* useful for external use.
|
||||
*/
|
||||
#define SPIMEM_RETENTION_LINK_LEN 8
|
||||
extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN];
|
||||
|
||||
/**
|
||||
* @brief Provide access to systimer configuration registers retention
|
||||
* context definition.
|
||||
*
|
||||
* This is an internal function of the sleep retention driver, and is not
|
||||
* useful for external use.
|
||||
*/
|
||||
#define SYSTIMER_RETENTION_LINK_LEN 19
|
||||
extern const regdma_entries_config_t systimer_regs_retention[SYSTIMER_RETENTION_LINK_LEN];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -769,9 +769,9 @@ extern "C" {
|
||||
* Version control register
|
||||
*/
|
||||
#define TEE_DATE 0x0FFFFFFFU
|
||||
#define TEE_DATE_REG_M (TEE_DATE_REG_V << TEE_DATE_REG_S)
|
||||
#define TEE_DATE_REG_V 0x0FFFFFFFU
|
||||
#define TEE_DATE_REG_S 0
|
||||
#define TEE_DATE_M (TEE_DATE_REG_V << TEE_DATE_REG_S)
|
||||
#define TEE_DATE_V 0x0FFFFFFFU
|
||||
#define TEE_DATE_S 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
121
components/soc/esp32c61/system_retention_periph.c
Normal file
121
components/soc/esp32c61/system_retention_periph.c
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/regdma.h"
|
||||
#include "soc/system_periph_retention.h"
|
||||
#include "soc/timer_periph.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#include "soc/systimer_reg.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#include "soc/hp_system_reg.h"
|
||||
#include "soc/tee_reg.h"
|
||||
#include "soc/hp_apm_reg.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/interrupt_matrix_reg.h"
|
||||
|
||||
/* Interrupt Matrix Registers Context */
|
||||
#define N_REGS_INTR_MATRIX() (((INTERRUPT_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_CORE0_BASE) / 4) + 1)
|
||||
const regdma_entries_config_t intr_matrix_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_CORE0_BASE, DR_REG_INTERRUPT_CORE0_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */
|
||||
};
|
||||
_Static_assert(ARRAY_SIZE(intr_matrix_regs_retention) == INT_MTX_RETENTION_LINK_LEN, "Inconsistent INT_MTX retention link length definitions");
|
||||
|
||||
/* HP System Registers Context */
|
||||
#define N_REGS_HP_SYSTEM() (((HP_SYSTEM_CLOCK_GATE_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1)
|
||||
const regdma_entries_config_t hp_system_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* hp system */
|
||||
};
|
||||
_Static_assert(ARRAY_SIZE(hp_system_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent HP_SYSTEM retention link length definitions");
|
||||
|
||||
/* TEE/APM Registers Context */
|
||||
#define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1)
|
||||
#define N_REGS_APM() (((HP_APM_CLOCK_GATE_REG - DR_REG_HP_APM_BASE) / 4) + 1)
|
||||
const regdma_entries_config_t tee_apm_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(0), DR_REG_HP_APM_BASE, DR_REG_HP_APM_BASE, N_REGS_APM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* apm */
|
||||
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */
|
||||
};
|
||||
const regdma_entries_config_t tee_apm_highpri_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) }
|
||||
};
|
||||
_Static_assert((ARRAY_SIZE(tee_apm_regs_retention) == TEE_APM_RETENTION_LINK_LEN) && (ARRAY_SIZE(tee_apm_highpri_regs_retention) == TEE_APM_HIGH_PRI_RETENTION_LINK_LEN), "Inconsistent TEE_APM retention link length definitions");
|
||||
|
||||
/* IO MUX Registers Context */
|
||||
#define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_U_PAD_SPID - REG_IO_MUX_BASE) / 4) + 1)
|
||||
#define N_REGS_IOMUX_1() (((GPIO_FUNC21_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1)
|
||||
#define N_REGS_IOMUX_2() (((GPIO_FUNC121_IN_SEL_CFG_REG - GPIO_FUNC0_IN_SEL_CFG_REG) / 4) + 1)
|
||||
#define N_REGS_IOMUX_3() (((GPIO_PIN21_REG - GPIO_PIN0_REG) / 4) + 1)
|
||||
#define N_REGS_IOMUX_4() (1)
|
||||
#define N_REGS_IOMUX_5() (1)
|
||||
#define N_REGS_IOMUX_6() (1)
|
||||
|
||||
const regdma_entries_config_t iomux_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x00), REG_IO_MUX_BASE, REG_IO_MUX_BASE, N_REGS_IOMUX_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* io_mux */
|
||||
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), GPIO_FUNC0_OUT_SEL_CFG_REG, GPIO_FUNC0_OUT_SEL_CFG_REG, N_REGS_IOMUX_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x02), GPIO_FUNC0_IN_SEL_CFG_REG, GPIO_FUNC0_IN_SEL_CFG_REG, N_REGS_IOMUX_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), GPIO_PIN0_REG, GPIO_PIN0_REG, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x04), GPIO_STATUS_REG, GPIO_STATUS_REG, N_REGS_IOMUX_4(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x05), GPIO_ENABLE_REG, GPIO_ENABLE_REG, N_REGS_IOMUX_5(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x06), GPIO_OUT_REG, GPIO_OUT_REG, N_REGS_IOMUX_6(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }
|
||||
};
|
||||
_Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "Inconsistent IOMUX retention link length definitions");
|
||||
|
||||
/* Memory SPI Registers Context */
|
||||
#define N_REGS_SPI1_MEM_0() (((SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1)
|
||||
#define N_REGS_SPI1_MEM_1() (1)
|
||||
#define N_REGS_SPI1_MEM_2() (1)
|
||||
#define N_REGS_SPI0_MEM_0() (((SPI_SMEM_DDR_REG(0) - REG_SPI_MEM_BASE(0)) / 4) + 1)
|
||||
#define N_REGS_SPI0_MEM_1() (((SPI_SMEM_AC_REG(0) - SPI_FMEM_PMS0_ATTR_REG(0)) / 4) + 1)
|
||||
#define N_REGS_SPI0_MEM_2() (1)
|
||||
#define N_REGS_SPI0_MEM_3() (((SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0) - SPI_MEM_MMU_POWER_CTRL_REG(0)) / 4) + 1)
|
||||
const regdma_entries_config_t flash_spimem_regs_retention[] = {
|
||||
/* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */
|
||||
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), REG_SPI_MEM_BASE(1), REG_SPI_MEM_BASE(1), N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */
|
||||
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_TIMING_CALI_REG(1), SPI_MEM_TIMING_CALI_REG(1), N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI_MEM_CLOCK_GATE_REG(1), SPI_MEM_CLOCK_GATE_REG(1), N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
|
||||
/* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */
|
||||
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), REG_SPI_MEM_BASE(0), REG_SPI_MEM_BASE(0), N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi0_mem */
|
||||
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), SPI_FMEM_PMS0_ATTR_REG(0), SPI_FMEM_PMS0_ATTR_REG(0), N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
/* Note: spimem register should set update reg to make the configuration take effect */
|
||||
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SPIMEM_LINK(0x07), SPI_MEM_TIMING_CALI_REG(0), SPI_MEM_TIMING_CALI_UPDATE, SPI_MEM_TIMING_CALI_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }
|
||||
};
|
||||
_Static_assert(ARRAY_SIZE(flash_spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions");
|
||||
|
||||
/* Systimer Registers Context */
|
||||
#define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1)
|
||||
const regdma_entries_config_t systimer_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x00), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_UPDATE_M, SYSTIMER_TIMER_UNIT0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer */
|
||||
[1] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x01), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_VALUE_VALID, SYSTIMER_TIMER_UNIT0_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x02), SYSTIMER_UNIT0_VALUE_HI_REG, SYSTIMER_UNIT0_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x03), SYSTIMER_UNIT0_LOAD_REG, SYSTIMER_TIMER_UNIT0_LOAD_M, SYSTIMER_TIMER_UNIT0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
|
||||
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x04), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_UPDATE_M, SYSTIMER_TIMER_UNIT1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x05), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_VALUE_VALID, SYSTIMER_TIMER_UNIT1_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x06), SYSTIMER_UNIT1_VALUE_HI_REG, SYSTIMER_UNIT1_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x07), SYSTIMER_UNIT1_LOAD_REG, SYSTIMER_TIMER_UNIT1_LOAD_M, SYSTIMER_TIMER_UNIT1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
|
||||
[8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x08), SYSTIMER_TARGET0_HI_REG, SYSTIMER_TARGET0_HI_REG, N_REGS_SYSTIMER_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer target value & period */
|
||||
|
||||
[9] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x09), SYSTIMER_COMP0_LOAD_REG, SYSTIMER_TIMER_COMP0_LOAD, SYSTIMER_TIMER_COMP0_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[10] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0a), SYSTIMER_COMP1_LOAD_REG, SYSTIMER_TIMER_COMP1_LOAD, SYSTIMER_TIMER_COMP1_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[11] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0b), SYSTIMER_COMP2_LOAD_REG, SYSTIMER_TIMER_COMP2_LOAD, SYSTIMER_TIMER_COMP2_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
|
||||
[12] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0c), SYSTIMER_TARGET0_CONF_REG, 0, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[13] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0d), SYSTIMER_TARGET0_CONF_REG, SYSTIMER_TARGET0_PERIOD_MODE_M, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
|
||||
[14] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0e), SYSTIMER_TARGET1_CONF_REG, 0, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[15] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0f), SYSTIMER_TARGET1_CONF_REG, SYSTIMER_TARGET1_PERIOD_MODE_M, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
|
||||
[16] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x10), SYSTIMER_TARGET2_CONF_REG, 0, SYSTIMER_TARGET2_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
|
||||
[17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer work enable */
|
||||
[18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */
|
||||
};
|
||||
_Static_assert(ARRAY_SIZE(systimer_regs_retention) == SYSTIMER_RETENTION_LINK_LEN, "Inconsistent Systimer retention link length definitions");
|
@ -22,3 +22,112 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Registers in retention context:
|
||||
* TIMG_T0CONFIG_REG
|
||||
* TIMG_T0ALARMLO_REG
|
||||
* TIMG_T0ALARMHI_REG
|
||||
* TIMG_T0LOADLO_REG
|
||||
* TIMG_T0LOADHI_REG
|
||||
* TIMG_INT_ENA_TIMERS_REG
|
||||
* TIMG_REGCLK_REG
|
||||
*/
|
||||
#define TG_TIMER_RETENTION_REGS_CNT 7
|
||||
static const uint32_t tg_timer_regs_map[4] = {0x100000f1, 0x80000000, 0x0, 0x0};
|
||||
|
||||
const regdma_entries_config_t tg0_timer_regdma_entries[] = {
|
||||
// backup stage: trigger a soft capture
|
||||
[0] = {
|
||||
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x00),
|
||||
TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
// backup stage: wait for the capture done
|
||||
[1] = {
|
||||
.config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x01),
|
||||
TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
// backup stage: save the captured counter value
|
||||
// restore stage: store the captured counter value to the loader register
|
||||
[2] = {
|
||||
.config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x02),
|
||||
TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
[3] = {
|
||||
.config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03),
|
||||
TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
// restore stage: trigger a soft reload, so the timer can continue from where it was backed up
|
||||
[4] = {
|
||||
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x04),
|
||||
TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
// backup stage: save other configuration and status registers
|
||||
// restore stage: restore the configuration and status registers
|
||||
[5] = {
|
||||
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x05),
|
||||
TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0),
|
||||
TG_TIMER_RETENTION_REGS_CNT, 0, 0,
|
||||
tg_timer_regs_map[0], tg_timer_regs_map[1],
|
||||
tg_timer_regs_map[2], tg_timer_regs_map[3]),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
};
|
||||
|
||||
const regdma_entries_config_t tg1_timer_regdma_entries[] = {
|
||||
// backup stage: trigger a soft capture
|
||||
[0] = {
|
||||
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x00),
|
||||
TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
// backup stage: wait for the capture done
|
||||
[1] = {
|
||||
.config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x01),
|
||||
TIMG_T0UPDATE_REG(1), 0x0, TIMG_T0_UPDATE_M, 0, 1),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
// backup stage: save the captured counter value
|
||||
// restore stage: store the captured counter value to the loader register
|
||||
[2] = {
|
||||
.config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x02),
|
||||
TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
[3] = {
|
||||
.config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03),
|
||||
TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
// restore stage: trigger a soft reload, so the timer can continue from where it was backed up
|
||||
[4] = {
|
||||
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x04),
|
||||
TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
// backup stage: save other configuration and status registers
|
||||
// restore stage: restore the configuration and status registers
|
||||
[5] = {
|
||||
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x05),
|
||||
TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1),
|
||||
TG_TIMER_RETENTION_REGS_CNT, 0, 0,
|
||||
tg_timer_regs_map[0], tg_timer_regs_map[1],
|
||||
tg_timer_regs_map[2], tg_timer_regs_map[3]),
|
||||
.owner = TIMG_RETENTION_ENTRY
|
||||
},
|
||||
};
|
||||
|
||||
const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS] = {
|
||||
[0] = {
|
||||
.regdma_entry_array = tg0_timer_regdma_entries,
|
||||
.array_size = ARRAY_SIZE(tg0_timer_regdma_entries)
|
||||
},
|
||||
[1] = {
|
||||
.regdma_entry_array = tg1_timer_regdma_entries,
|
||||
.array_size = ARRAY_SIZE(tg1_timer_regdma_entries)
|
||||
},
|
||||
};
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "soc/uart_periph.h"
|
||||
#include "soc/uart_reg.h"
|
||||
|
||||
/*
|
||||
Bunch of constants for every UART peripheral: GPIO signals, irqs, hw addr of registers etc
|
||||
@ -108,3 +109,52 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = {
|
||||
.irq = ETS_UART2_INTR_SOURCE,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* UART registers to be saved during sleep retention
|
||||
*
|
||||
* Reset TXFIFO and RXFIFO
|
||||
* UART registers require set the reg_update bit to make the configuration take effect
|
||||
*
|
||||
* UART_INT_ENA_REG, UART_CLKDIV_SYNC_REG, UART_RX_FILT_REG, UART_CONF0_SYNC_REG, UART_CONF1_REG,
|
||||
* UART_HWFC_CONF_SYNC_REG, UART_SLEEP_CONF0_REG, UART_SLEEP_CONF1_REG, UART_SLEEP_CONF2_REG,
|
||||
* UART_SWFC_CONF0_SYNC_REG, UART_SWFC_CONF1_REG, UART_TXBRK_CONF_SYNC_REG, UART_IDLE_CONF_SYNC_REG,
|
||||
* UART_RS485_CONF_SYNC_REG, UART_AT_CMD_PRECNT_SYNC_REG, UART_AT_CMD_POSTCNT_SYNC_REG, UART_AT_CMD_GAPTOUT_SYNC_REG,
|
||||
* UART_AT_CMD_CHAR_SYNC_REG, UART_MEM_CONF_REG, UART_TOUT_CONF_SYNC_REG, UART_ID_REG
|
||||
*/
|
||||
#define UART_RETENTION_ADDR_MAP_REGS_CNT 21
|
||||
#define UART_RETENTION_REGS_BASE(i) UART_INT_ENA_REG(i)
|
||||
static const uint32_t uart_regs_map[4] = {0x7fff6d, 0x10, 0x0, 0x0};
|
||||
#define UART_SLEEP_RETENTION_ENTRIES(uart_num) { \
|
||||
[0] = {.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_UART_LINK(0x00), \
|
||||
UART_RETENTION_REGS_BASE(uart_num), UART_RETENTION_REGS_BASE(uart_num), \
|
||||
UART_RETENTION_ADDR_MAP_REGS_CNT, 0, 0, \
|
||||
uart_regs_map[0], uart_regs_map[1], \
|
||||
uart_regs_map[2], uart_regs_map[3] \
|
||||
), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
[1] = {.config = REGDMA_LINK_WRITE_INIT(REGDMA_UART_LINK(0x01), \
|
||||
UART_REG_UPDATE_REG(uart_num), UART_REG_UPDATE, \
|
||||
UART_REG_UPDATE_M, 1, 0 \
|
||||
), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
[2] = {.config = REGDMA_LINK_WAIT_INIT(REGDMA_UART_LINK(0x02), \
|
||||
UART_REG_UPDATE_REG(uart_num), 0x0, \
|
||||
UART_REG_UPDATE_M, 1, 0 \
|
||||
), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
}
|
||||
|
||||
static const regdma_entries_config_t uart0_regdma_entries[] = UART_SLEEP_RETENTION_ENTRIES(0);
|
||||
static const regdma_entries_config_t uart1_regdma_entries[] = UART_SLEEP_RETENTION_ENTRIES(1);
|
||||
|
||||
const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM] = {
|
||||
[0] = {
|
||||
.regdma_entry_array = uart0_regdma_entries,
|
||||
.array_size = ARRAY_SIZE(uart0_regdma_entries),
|
||||
},
|
||||
[1] = {
|
||||
.regdma_entry_array = uart1_regdma_entries,
|
||||
.array_size = ARRAY_SIZE(uart1_regdma_entries),
|
||||
},
|
||||
};
|
||||
|
@ -5,3 +5,28 @@
|
||||
*/
|
||||
|
||||
#include "soc/wdt_periph.h"
|
||||
|
||||
#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG
|
||||
|
||||
static const regdma_entries_config_t tg0_wdt_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x02), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x04), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x05), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
};
|
||||
|
||||
static const regdma_entries_config_t tg1_wdt_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x05), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||
};
|
||||
|
||||
const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = {
|
||||
[0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)},
|
||||
[1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)},
|
||||
};
|
||||
|
@ -52,7 +52,8 @@ endif()
|
||||
if(CONFIG_ULP_COPROC_TYPE_LP_CORE)
|
||||
list(APPEND srcs
|
||||
"lp_core/lp_core.c"
|
||||
"lp_core/shared/ulp_lp_core_memory_shared.c")
|
||||
"lp_core/shared/ulp_lp_core_memory_shared.c"
|
||||
"lp_core/shared/ulp_lp_core_critical_section_shared.c")
|
||||
|
||||
if(CONFIG_SOC_ULP_LP_UART_SUPPORTED)
|
||||
list(APPEND srcs "lp_core/lp_core_uart.c")
|
||||
|
@ -125,7 +125,8 @@ function(ulp_apply_default_sources ulp_app_name)
|
||||
"${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_i2c.c"
|
||||
"${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_spi.c"
|
||||
"${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_ubsan.c"
|
||||
"${IDF_PATH}/components/ulp/lp_core/shared/ulp_lp_core_lp_adc_shared.c")
|
||||
"${IDF_PATH}/components/ulp/lp_core/shared/ulp_lp_core_lp_adc_shared.c"
|
||||
"${IDF_PATH}/components/ulp/lp_core/shared/ulp_lp_core_critical_section_shared.c")
|
||||
|
||||
set(target_folder ${IDF_TARGET})
|
||||
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
LOCK_CANDIDATE_LP_CORE = 0,
|
||||
LOCK_CANDIDATE_HP_CORE_0,
|
||||
#if CONFIG_FREERTOS_NUMBER_OF_CORES > 1
|
||||
LOCK_CANDIDATE_HP_CORE_1,
|
||||
#endif
|
||||
LOCK_CANDIDATE_NUM_MAX,
|
||||
} ulp_lp_core_spinlock_candidate_t;
|
||||
|
||||
typedef struct {
|
||||
volatile int level[LOCK_CANDIDATE_NUM_MAX];
|
||||
volatile int last_to_enter[LOCK_CANDIDATE_NUM_MAX - 1];
|
||||
volatile unsigned int prev_int_level;
|
||||
} ulp_lp_core_spinlock_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the spinlock that protects shared resources between main CPU and LP CPU.
|
||||
*
|
||||
* @note The spinlock can be initialized in either main program or LP program.
|
||||
*
|
||||
* @param lock Pointer to lock struct
|
||||
*/
|
||||
void ulp_lp_core_spinlock_init(ulp_lp_core_spinlock_t *lock);
|
||||
|
||||
/**
|
||||
* @brief Enter the critical section that protects shared resources between main CPU and LP CPU.
|
||||
*
|
||||
* @note This critical section is designed for being used by multiple threads, it is safe to try to enter it
|
||||
* simultaneously from multiple threads on multiple main CPU cores and LP CPU.
|
||||
*
|
||||
* @note This critical section does not support nesting entering and exiting.
|
||||
*
|
||||
* @param lock Pointer to lock struct
|
||||
*/
|
||||
void ulp_lp_core_enter_critical(ulp_lp_core_spinlock_t *lock);
|
||||
|
||||
/**
|
||||
* @brief Exit the critical section that protect shared resource between main CPU and LP CPU.
|
||||
*
|
||||
* @note This critical section does not support nesting entering and exiting.
|
||||
*
|
||||
* @param lock Pointer to lock struct
|
||||
*/
|
||||
void ulp_lp_core_exit_critical(ulp_lp_core_spinlock_t *lock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "ulp_lp_core_critical_section_shared.h"
|
||||
#include "esp_cpu.h"
|
||||
#if IS_ULP_COCPU
|
||||
#include "ulp_lp_core_interrupts.h"
|
||||
#endif
|
||||
|
||||
/* Masked interrupt threshold varies between different types of interrupt controller */
|
||||
#if !SOC_INT_CLIC_SUPPORTED
|
||||
#define INT_MASK_THRESHOLD RVHAL_EXCM_LEVEL
|
||||
#else /* SOC_INT_CLIC_SUPPORTED */
|
||||
#define INT_MASK_THRESHOLD RVHAL_EXCM_LEVEL_CLIC
|
||||
#endif /* !SOC_INIT_CLIC_SUPPORTED */
|
||||
|
||||
void ulp_lp_core_spinlock_init(ulp_lp_core_spinlock_t *lock)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < LOCK_CANDIDATE_NUM_MAX; i++) {
|
||||
lock->level[i] = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < LOCK_CANDIDATE_NUM_MAX - 1; i++) {
|
||||
lock->last_to_enter[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if RTC_MEM_AMO_INSTRUCTIONS_VERIFIED
|
||||
/* ULP spinlock ACQ/REL functions also have a hardware implementation base on AMOSWAP instructions,
|
||||
which has much better performance but have not been thoroughly verified yet on RTC memory. This set
|
||||
of implementation will be adapted once it's verified.
|
||||
*/
|
||||
static void ulp_lp_core_spinlock_acquire(ulp_lp_core_spinlock_t *lock)
|
||||
{
|
||||
|
||||
/* Based on sample code for AMOSWAP from RISCV specs v2.1 */
|
||||
asm volatile(
|
||||
"li t0, 1\n" // Initialize swap value.
|
||||
"1:\n"
|
||||
"lw t1, (%0)\n" // Check if lock is held.
|
||||
"bnez t1, 1b\n" // Retry if held.
|
||||
"amoswap.w.aq t1, t0, (%0)\n" // Attempt to acquire lock.
|
||||
"bnez t1, 1b\n" // Retry if held.
|
||||
:
|
||||
: "r"(lock)
|
||||
: "t0", "t1", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
static void ulp_lp_core_spinlock_release(ulp_lp_core_spinlock_t *lock)
|
||||
{
|
||||
asm volatile(
|
||||
"amoswap.w.rl x0, x0, (%0)\n" // Release lock by storing 0
|
||||
:
|
||||
: "r"(lock)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
#else // !RTC_MEM_AMO_INSTRUCTIONS_VERIFIED
|
||||
/**
|
||||
* @brief Obtain the id of current lock candidate.
|
||||
*
|
||||
* @return lock candidate id
|
||||
*/
|
||||
static int ulp_lp_core_spinlock_get_candidate_id(void)
|
||||
{
|
||||
int lock_candidate_id = 0;
|
||||
#if !IS_ULP_COCPU
|
||||
/* Refer to ulp_lp_core_spinlock_candidate_t, each HP_CORE lock candidate's index is the core id plus 1 */
|
||||
lock_candidate_id = esp_cpu_get_core_id() + 1;
|
||||
#else
|
||||
lock_candidate_id = LOCK_CANDIDATE_LP_CORE;
|
||||
#endif
|
||||
return lock_candidate_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Software lock implementation is based on the filter algorithm, which is a generalization of Peterson's algorithm, https://en.wikipedia.org/wiki/Peterson%27s_algorithm#Filter_algorithm:_Peterson's_algorithm_for_more_than_two_processes
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Attempt to acquire the lock. Spins until lock is acquired.
|
||||
*
|
||||
* @note This lock is designed for being used by multiple threads, it is safe to try to acquire it
|
||||
* simultaneously from multiple threads on multiple main CPU cores and LP CPU.
|
||||
*
|
||||
* @note This function is private to ulp lp core critical section and shall not be called from anywhere else.
|
||||
*
|
||||
* @param lock Pointer to lock struct, shared with ULP
|
||||
*/
|
||||
static void ulp_lp_core_spinlock_acquire(ulp_lp_core_spinlock_t *lock)
|
||||
{
|
||||
/* Level index */
|
||||
int lv = 0;
|
||||
/* Candidate index */
|
||||
int candidate = 0;
|
||||
|
||||
/* Index of the current lock candidate */
|
||||
int lock_candidate_id = ulp_lp_core_spinlock_get_candidate_id();
|
||||
|
||||
for (lv = 0; lv < (int)LOCK_CANDIDATE_NUM_MAX - 1; lv++) {
|
||||
/* Each candidate has to go through all the levels in order to get the spinlock. Start by notifying other candidates, we have reached level `lv` */
|
||||
lock->level[lock_candidate_id] = lv;
|
||||
/* Notify other candidates we are the latest one who entered level `lv` */
|
||||
lock->last_to_enter[lv] = lock_candidate_id;
|
||||
/* If there is any candidate that reached the same or a higher level than this candidate, wait for it to finish. Advance to the next level if another candidate becomes the latest one to arrive at our current level */
|
||||
for (candidate = 0; candidate < (int)LOCK_CANDIDATE_NUM_MAX; candidate++) {
|
||||
while ((candidate != lock_candidate_id) && (lock->level[candidate] >= lv && lock->last_to_enter[lv] == lock_candidate_id)) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release the lock.
|
||||
*
|
||||
* @note This function is private to ulp lp core critical section and shall not be called from anywhere else.
|
||||
*
|
||||
* @param lock Pointer to lock struct, shared with ULP
|
||||
*/
|
||||
static void ulp_lp_core_spinlock_release(ulp_lp_core_spinlock_t *lock)
|
||||
{
|
||||
int lock_candidate_id = ulp_lp_core_spinlock_get_candidate_id();
|
||||
|
||||
lock->level[lock_candidate_id] = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ulp_lp_core_enter_critical(ulp_lp_core_spinlock_t *lock)
|
||||
{
|
||||
/* disable interrupt */
|
||||
#if !IS_ULP_COCPU // HP core
|
||||
unsigned prev_int_level = rv_utils_set_intlevel_regval(INT_MASK_THRESHOLD);
|
||||
lock->prev_int_level = prev_int_level;
|
||||
#else // LP core
|
||||
ulp_lp_core_intr_disable();
|
||||
#endif
|
||||
/* Busy-wait to acquire the spinlock. Use caution when deploying this lock in time-sensitive scenarios. */
|
||||
ulp_lp_core_spinlock_acquire(lock);
|
||||
}
|
||||
|
||||
void ulp_lp_core_exit_critical(ulp_lp_core_spinlock_t *lock)
|
||||
{
|
||||
ulp_lp_core_spinlock_release(lock);
|
||||
|
||||
/* re-enable interrupt */
|
||||
#if !IS_ULP_COCPU // HP core
|
||||
unsigned prev_int_level = lock->prev_int_level;
|
||||
rv_utils_restore_intlevel_regval(prev_int_level);
|
||||
#else // LP core
|
||||
ulp_lp_core_intr_enable();
|
||||
#endif
|
||||
}
|
@ -17,11 +17,14 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_DPP_AUTH_TIMEOUT_SECS 1
|
||||
#define ESP_DPP_MAX_CHAN_COUNT 5
|
||||
|
||||
#define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */
|
||||
#define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */
|
||||
#define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */
|
||||
#define ESP_ERR_DPP_AUTH_TIMEOUT (ESP_ERR_WIFI_BASE + 154) /*!< DPP Auth response was not received in time */
|
||||
#define ESP_ERR_DPP_INVALID_LIST (ESP_ERR_WIFI_BASE + 155) /*!< Channel list given in esp_supp_dpp_bootstrap_gen() is not valid or too big */
|
||||
|
||||
/** @brief Types of Bootstrap Methods for DPP. */
|
||||
typedef enum dpp_bootstrap_type {
|
||||
DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */
|
||||
@ -83,6 +86,7 @@ esp_err_t esp_supp_dpp_deinit(void);
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_DPP_INVALID_LIST: Channel list not valid
|
||||
* - ESP_FAIL: Failure
|
||||
*/
|
||||
esp_err_t
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/ieee802_11_common.h"
|
||||
#include "esp_wps_i.h"
|
||||
#include "rsn_supp/wpa.h"
|
||||
#include "rsn_supp/pmksa_cache.h"
|
||||
@ -575,6 +576,7 @@ static void esp_dpp_task(void *pvParameters)
|
||||
break;
|
||||
}
|
||||
channel = p->chan_list[counter++ % p->num_chan];
|
||||
wpa_printf(MSG_DEBUG, "Listening on channel=%d", channel);
|
||||
ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel,
|
||||
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb);
|
||||
if (ret != ESP_OK) {
|
||||
@ -687,47 +689,81 @@ static void offchan_event_handler(void *arg, esp_event_base_t event_base,
|
||||
static char *esp_dpp_parse_chan_list(const char *chan_list)
|
||||
{
|
||||
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
|
||||
char *uri_channels = os_zalloc(14 * 6 + 1);
|
||||
const char *pos = chan_list;
|
||||
const char *pos2;
|
||||
char *pos3 = uri_channels;
|
||||
size_t max_uri_len = ESP_DPP_MAX_CHAN_COUNT * 8 + strlen(" chan=") + 1;
|
||||
|
||||
char *uri_channels = os_zalloc(max_uri_len);
|
||||
if (!uri_channels) {
|
||||
wpa_printf(MSG_WARNING, "DPP: URI allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *uri_ptr = uri_channels;
|
||||
params->num_chan = 0;
|
||||
|
||||
os_memcpy(pos3, " chan=", strlen(" chan="));
|
||||
pos3 += strlen(" chan=");
|
||||
/* Append " chan=" at the beginning of the URI */
|
||||
strcpy(uri_ptr, " chan=");
|
||||
uri_ptr += strlen(" chan=");
|
||||
|
||||
while (pos && *pos) {
|
||||
int channel;
|
||||
int len = strlen(chan_list);
|
||||
while (*chan_list && params->num_chan < ESP_DPP_MAX_CHAN_COUNT) {
|
||||
int channel = 0;
|
||||
|
||||
pos2 = pos;
|
||||
while (*pos2 >= '0' && *pos2 <= '9') {
|
||||
pos2++;
|
||||
/* Parse the channel number */
|
||||
while (*chan_list >= '0' && *chan_list <= '9') {
|
||||
channel = channel * 10 + (*chan_list - '0');
|
||||
chan_list++;
|
||||
}
|
||||
if (*pos2 == ',' || *pos2 == ' ' || *pos2 == '\0') {
|
||||
channel = atoi(pos);
|
||||
if (channel < 1 || channel > 14) {
|
||||
os_free(uri_channels);
|
||||
return NULL;
|
||||
|
||||
/* Validate the channel number */
|
||||
if (CHANNEL_TO_BIT_NUMBER(channel) == 0) {
|
||||
wpa_printf(MSG_WARNING, "DPP: Skipping invalid channel %d", channel);
|
||||
/* Skip to the next valid entry */
|
||||
while (*chan_list == ',' || *chan_list == ' ') {
|
||||
chan_list++;
|
||||
}
|
||||
params->chan_list[params->num_chan++] = channel;
|
||||
os_memcpy(pos3, "81/", strlen("81/"));
|
||||
pos3 += strlen("81/");
|
||||
os_memcpy(pos3, pos, (pos2 - pos));
|
||||
pos3 += (pos2 - pos);
|
||||
*pos3++ = ',';
|
||||
|
||||
pos = pos2 + 1;
|
||||
}
|
||||
while (*pos == ',' || *pos == ' ' || *pos == '\0') {
|
||||
pos++;
|
||||
continue; // Skip the bad channel and move to the next one
|
||||
}
|
||||
|
||||
if (((int)(pos - chan_list) >= len)) {
|
||||
break;
|
||||
/* Get the operating class for the channel */
|
||||
u8 oper_class = get_operating_class(channel, 0);
|
||||
if (oper_class == 0) {
|
||||
wpa_printf(MSG_WARNING, "DPP: Skipping channel %d due to missing operating class", channel);
|
||||
/* Skip to the next valid entry */
|
||||
while (*chan_list == ',' || *chan_list == ' ') {
|
||||
chan_list++;
|
||||
}
|
||||
continue; /* Skip to the next channel if no operating class found */
|
||||
}
|
||||
|
||||
/* Add the valid channel to the list */
|
||||
params->chan_list[params->num_chan++] = channel;
|
||||
|
||||
/* Check if there's space left in uri_channels buffer */
|
||||
size_t remaining_space = max_uri_len - (uri_ptr - uri_channels);
|
||||
if (remaining_space <= 8) { // Oper class + "/" + channel + "," + null terminator
|
||||
wpa_printf(MSG_ERROR, "DPP: Not enough space in URI buffer");
|
||||
os_free(uri_channels);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Append the operating class and channel to the URI */
|
||||
uri_ptr += sprintf(uri_ptr, "%d/%d,", oper_class, channel);
|
||||
|
||||
/* Skip any delimiters (comma or space) */
|
||||
while (*chan_list == ',' || *chan_list == ' ') {
|
||||
chan_list++;
|
||||
}
|
||||
}
|
||||
*(pos3 - 1) = ' ';
|
||||
|
||||
if (!params->num_chan) {
|
||||
wpa_printf(MSG_ERROR, "DPP: No valid channel in the list");
|
||||
os_free(uri_channels);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Replace the last comma with a space if there was content added */
|
||||
if (uri_ptr > uri_channels && *(uri_ptr - 1) == ',') {
|
||||
*(uri_ptr - 1) = ' ';
|
||||
}
|
||||
|
||||
return uri_channels;
|
||||
}
|
||||
@ -742,10 +778,16 @@ esp_supp_dpp_bootstrap_gen(const char *chan_list, enum dpp_bootstrap_type type,
|
||||
}
|
||||
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
|
||||
char *uri_chan_list = esp_dpp_parse_chan_list(chan_list);
|
||||
|
||||
if (params->num_chan > ESP_DPP_MAX_CHAN_COUNT) {
|
||||
os_free(uri_chan_list);
|
||||
return ESP_ERR_DPP_INVALID_LIST;
|
||||
}
|
||||
|
||||
char *command = os_zalloc(1200);
|
||||
int ret;
|
||||
|
||||
if (!uri_chan_list || !command || params->num_chan >= 14 || params->num_chan == 0) {
|
||||
if (!uri_chan_list || !command || params->num_chan > ESP_DPP_MAX_CHAN_COUNT || params->num_chan == 0) {
|
||||
wpa_printf(MSG_ERROR, "Invalid Channel list - %s", chan_list);
|
||||
if (command) {
|
||||
os_free(command);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "esp_wifi_types.h"
|
||||
#include "esp_wpa3_i.h"
|
||||
#include "esp_wps.h"
|
||||
#include "esp_wps_i.h"
|
||||
|
||||
#define WIFI_PASSWORD_LEN_MAX 65
|
||||
|
||||
@ -236,6 +237,9 @@ bool hostap_deinit(void *data)
|
||||
esp_wifi_unset_appie_internal(WIFI_APPIE_WPA);
|
||||
esp_wifi_unset_appie_internal(WIFI_APPIE_ASSOC_RESP);
|
||||
|
||||
#ifdef CONFIG_WPS_REGISTRAR
|
||||
wifi_ap_wps_disable_internal();
|
||||
#endif
|
||||
#ifdef CONFIG_SAE
|
||||
wpa3_hostap_auth_deinit();
|
||||
/* Wait till lock is released by wpa3 task */
|
||||
|
@ -167,22 +167,31 @@ int esp_handle_beacon_probe(u8 type, u8 *frame, size_t len, u8 *sender,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WNM
|
||||
void get_scan_channel_bitmap(struct wpa_supplicant *wpa_s, wifi_scan_config_t *params)
|
||||
static void get_scan_channel_bitmap(struct wpa_supplicant *wpa_s, wifi_scan_config_t *params)
|
||||
{
|
||||
const int MAX_2GHZ_CHANNEL = 14;
|
||||
|
||||
if (!wpa_s->wnm_num_neighbor_report) {
|
||||
wpa_printf(MSG_DEBUG, "No Neighbor Report to gather scan channel list");
|
||||
return;
|
||||
}
|
||||
params->channel_bitmap.ghz_2_channels = 0;
|
||||
params->channel_bitmap.ghz_5_channels = 0;
|
||||
|
||||
for (int i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
|
||||
struct neighbor_report *nei;
|
||||
nei = &wpa_s->wnm_neighbor_report_elements[i];
|
||||
params->channel_bitmap.ghz_2_channels |= (1 << nei->channel_number);
|
||||
struct neighbor_report *nei = &wpa_s->wnm_neighbor_report_elements[i];
|
||||
|
||||
if (nei->channel_number <= MAX_2GHZ_CHANNEL) {
|
||||
params->channel_bitmap.ghz_2_channels |= CHANNEL_TO_BIT(nei->channel_number);
|
||||
} else {
|
||||
params->channel_bitmap.ghz_5_channels |= CHANNEL_TO_BIT(nei->channel_number);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /*CONFIG_WNM*/
|
||||
|
||||
static int issue_scan(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_driver_scan_params *scan_params)
|
||||
{
|
||||
|
@ -367,16 +367,19 @@ int wpa3_hostap_post_evt(uint32_t evt_id, uint32_t data)
|
||||
if (g_wpa3_hostap_evt_queue == NULL) {
|
||||
WPA3_HOSTAP_AUTH_API_UNLOCK();
|
||||
os_free(evt);
|
||||
wpa_printf(MSG_DEBUG, "hostap evt queue NULL");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
} else {
|
||||
os_free(evt);
|
||||
wpa_printf(MSG_DEBUG, "g_wpa3_hostap_auth_api_lock not found");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (evt->id == SIG_WPA3_RX_CONFIRM || evt->id == SIG_TASK_DEL) {
|
||||
/* prioritising confirm for completing handshake for committed sta */
|
||||
if (os_queue_send_to_front(g_wpa3_hostap_evt_queue, &evt, 0) != pdPASS) {
|
||||
WPA3_HOSTAP_AUTH_API_UNLOCK();
|
||||
wpa_printf(MSG_DEBUG, "failed to add msg to queue front");
|
||||
os_free(evt);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@ -384,6 +387,7 @@ int wpa3_hostap_post_evt(uint32_t evt_id, uint32_t data)
|
||||
if (os_queue_send(g_wpa3_hostap_evt_queue, &evt, 0) != pdPASS) {
|
||||
WPA3_HOSTAP_AUTH_API_UNLOCK();
|
||||
os_free(evt);
|
||||
wpa_printf(MSG_DEBUG, "failed to send msg to queue");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ void wifi_station_wps_msg_timeout(void *data, void *user_ctx);
|
||||
void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx);
|
||||
void wifi_station_wps_success(void *data, void *user_ctx);
|
||||
void wifi_station_wps_timeout(void *data, void *user_ctx);
|
||||
int wps_delete_timer(void);
|
||||
|
||||
struct wps_sm *gWpsSm = NULL;
|
||||
static wps_factory_information_t *s_factory_info = NULL;
|
||||
@ -440,9 +441,9 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
|
||||
return false;
|
||||
}
|
||||
esp_wifi_enable_sta_privacy_internal();
|
||||
os_memset(sm->ssid[0], 0, SSID_MAX_LEN);
|
||||
os_memcpy(sm->ssid[0], (char *)&scan->ssid[2], (int)scan->ssid[1]);
|
||||
sm->ssid_len[0] = scan->ssid[1];
|
||||
os_memset(sm->creds[0].ssid, 0, SSID_MAX_LEN);
|
||||
os_memcpy(sm->creds[0].ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]);
|
||||
sm->creds[0].ssid_len = scan->ssid[1];
|
||||
if (scan->bssid && memcmp(sm->bssid, scan->bssid, ETH_ALEN) != 0) {
|
||||
wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR,
|
||||
MAC2STR(sm->bssid), MAC2STR(scan->bssid));
|
||||
@ -468,7 +469,7 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
|
||||
}
|
||||
}
|
||||
wpabuf_free(buf);
|
||||
wpa_printf(MSG_DEBUG, "wps discover [%s] ", (char *)sm->ssid);
|
||||
wpa_printf(MSG_DEBUG, "wps discover [%s] ", (char *)sm->creds[0].ssid);
|
||||
sm->channel = scan->chan;
|
||||
|
||||
return true;
|
||||
@ -623,14 +624,14 @@ int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res)
|
||||
if (expd->opcode != WSC_Start) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d "
|
||||
"in WAIT_START state", expd->opcode);
|
||||
return ESP_FAIL;
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: Received start");
|
||||
sm->state = WPA_MESG;
|
||||
} else if (expd->opcode == WSC_Start) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d",
|
||||
expd->opcode);
|
||||
return ESP_FAIL;
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
flag = *(u8 *)(ubuf + sizeof(struct eap_expand));
|
||||
@ -793,8 +794,7 @@ static int wps_sm_init(struct wps_sm *sm)
|
||||
sm->scan_cnt = 0;
|
||||
sm->discover_ssid_cnt = 0;
|
||||
os_bzero(sm->bssid, ETH_ALEN);
|
||||
os_bzero(sm->ssid, sizeof(sm->ssid));
|
||||
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
|
||||
os_bzero(sm->creds, sizeof(sm->creds));
|
||||
sm->ap_cred_cnt = 0;
|
||||
|
||||
return 0;
|
||||
@ -835,7 +835,8 @@ int wps_finish(void)
|
||||
if (sm->wps->state == WPS_FINISHED) {
|
||||
wpa_printf(MSG_DEBUG, "wps finished------>");
|
||||
wps_set_status(WPS_STATUS_SUCCESS);
|
||||
wps_stop_connection_timers(sm);
|
||||
/* WPS finished, dequeue all timers */
|
||||
wps_delete_timer();
|
||||
|
||||
if (sm->ap_cred_cnt == 1) {
|
||||
wifi_config_t *config = os_zalloc(sizeof(wifi_config_t));
|
||||
@ -845,12 +846,21 @@ int wps_finish(void)
|
||||
}
|
||||
|
||||
esp_wifi_get_config(WIFI_IF_STA, config);
|
||||
os_memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]);
|
||||
os_memcpy(config->sta.password, sm->key[0], sm->key_len[0]);
|
||||
esp_wifi_disconnect();
|
||||
os_memcpy(config->sta.ssid, sm->creds[0].ssid, sm->creds[0].ssid_len);
|
||||
os_memcpy(config->sta.password, sm->creds[0].key, sm->creds[0].key_len);
|
||||
os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN);
|
||||
#ifndef CONFIG_WPS_STRICT
|
||||
/* Some APs support AES in WPA IE, enable connection with them */
|
||||
if (sm->creds[0].auth_type == WPS_AUTH_WPAPSK &&
|
||||
(sm->creds[0].encr_type & WPS_ENCR_AES)) {
|
||||
config->sta.threshold.authmode = WIFI_AUTH_WPA_PSK;
|
||||
}
|
||||
#endif
|
||||
config->sta.bssid_set = 0;
|
||||
config->sta.sae_pwe_h2e = 0;
|
||||
esp_wifi_set_config(WIFI_IF_STA, config);
|
||||
esp_wifi_connect();
|
||||
|
||||
os_free(config);
|
||||
}
|
||||
@ -863,8 +873,7 @@ int wps_finish(void)
|
||||
if (sm->ignore_sel_reg) {
|
||||
sm->discover_ssid_cnt = 0;
|
||||
esp_wifi_disconnect();
|
||||
os_bzero(sm->ssid, sizeof(sm->ssid));
|
||||
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
|
||||
os_bzero(sm->creds, sizeof(sm->creds));
|
||||
wps_add_discard_ap(sm->bssid);
|
||||
} else {
|
||||
ret = wps_stop_process(WPS_FAIL_REASON_NORMAL);
|
||||
@ -1087,6 +1096,8 @@ int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len)
|
||||
wpa_printf(MSG_DEBUG, "sm->wps->state = %d", sm->wps->state);
|
||||
wps_start_msg_timer();
|
||||
}
|
||||
} else if (ret == ESP_ERR_INVALID_STATE) {
|
||||
ret = ESP_OK;
|
||||
} else {
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
@ -1313,8 +1324,7 @@ wifi_station_wps_msg_timeout_internal(void)
|
||||
if (sm->ignore_sel_reg) {
|
||||
esp_wifi_disconnect();
|
||||
wps_add_discard_ap(sm->bssid);
|
||||
os_bzero(sm->ssid, sizeof(sm->ssid));
|
||||
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
|
||||
os_bzero(sm->creds, sizeof(sm->creds));
|
||||
os_bzero(sm->bssid, ETH_ALEN);
|
||||
sm->discover_ssid_cnt = 0;
|
||||
wifi_wps_scan(NULL, NULL);
|
||||
@ -1344,8 +1354,8 @@ void wifi_station_wps_success_internal(void)
|
||||
if (sm->ap_cred_cnt > 1) {
|
||||
evt.ap_cred_cnt = sm->ap_cred_cnt;
|
||||
for (i = 0; i < MAX_WPS_AP_CRED; i++) {
|
||||
os_memcpy(evt.ap_cred[i].ssid, sm->ssid[i], sm->ssid_len[i]);
|
||||
os_memcpy(evt.ap_cred[i].passphrase, sm->key[i], sm->key_len[i]);
|
||||
os_memcpy(evt.ap_cred[i].ssid, sm->creds[i].ssid, sm->creds[i].ssid_len);
|
||||
os_memcpy(evt.ap_cred[i].passphrase, sm->creds[i].key, sm->creds[i].key_len);
|
||||
}
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_SUCCESS, &evt,
|
||||
sizeof(evt), OS_BLOCK);
|
||||
@ -1383,17 +1393,13 @@ void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx)
|
||||
|
||||
static int save_credentials_cb(void *ctx, const struct wps_credential *cred)
|
||||
{
|
||||
if (!gWpsSm || !cred || gWpsSm->ap_cred_cnt > 2) {
|
||||
struct wps_credential *creds;
|
||||
if (!gWpsSm || !cred || gWpsSm->ap_cred_cnt > MAX_CRED_COUNT) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
os_memset(gWpsSm->ssid[gWpsSm->ap_cred_cnt], 0x00, sizeof(gWpsSm->ssid[gWpsSm->ap_cred_cnt]));
|
||||
os_memset(gWpsSm->key[gWpsSm->ap_cred_cnt], 0x00, sizeof(gWpsSm->key[gWpsSm->ap_cred_cnt]));
|
||||
|
||||
os_memcpy(gWpsSm->ssid[gWpsSm->ap_cred_cnt], cred->ssid, cred->ssid_len);
|
||||
gWpsSm->ssid_len[gWpsSm->ap_cred_cnt] = cred->ssid_len;
|
||||
os_memcpy(gWpsSm->key[gWpsSm->ap_cred_cnt], cred->key, cred->key_len);
|
||||
gWpsSm->key_len[gWpsSm->ap_cred_cnt] = cred->key_len;
|
||||
creds = &gWpsSm->creds[gWpsSm->ap_cred_cnt];
|
||||
memcpy(creds, cred, sizeof(*creds));
|
||||
|
||||
gWpsSm->ap_cred_cnt++;
|
||||
|
||||
@ -1646,14 +1652,15 @@ wifi_wps_scan_done(void *arg, ETS_STATUS status)
|
||||
esp_wifi_disconnect();
|
||||
|
||||
os_memcpy(wifi_config.sta.bssid, sm->bssid, ETH_ALEN);
|
||||
os_memcpy(wifi_config.sta.ssid, (char *)sm->ssid[0], sm->ssid_len[0]);
|
||||
os_memcpy(wifi_config.sta.ssid, (char *)sm->creds[0].ssid, sm->creds[0].ssid_len);
|
||||
wifi_config.sta.bssid_set = 1;
|
||||
wifi_config.sta.channel = sm->channel;
|
||||
wpa_printf(MSG_INFO, "WPS: connecting to %s, bssid=" MACSTR,
|
||||
(char *)sm->ssid[0], MAC2STR(wifi_config.sta.bssid));
|
||||
(char *)sm->creds[0].ssid, MAC2STR(wifi_config.sta.bssid));
|
||||
esp_wifi_set_config(0, &wifi_config);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPS: neg start");
|
||||
wifi_config.sta.failure_retry_cnt = 2;
|
||||
esp_wifi_connect();
|
||||
sm->state = WAIT_START;
|
||||
eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL);
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "esp_wps.h"
|
||||
#include "wps/wps.h"
|
||||
#include "wps/wps_attr_parse.h"
|
||||
|
||||
/* WPS message flag */
|
||||
enum wps_msg_flag {
|
||||
@ -57,15 +59,6 @@ struct discard_ap_list_t {
|
||||
u8 bssid[6];
|
||||
};
|
||||
|
||||
#ifndef MAX_PASSPHRASE_LEN
|
||||
#define MAX_PASSPHRASE_LEN 64
|
||||
#endif
|
||||
|
||||
#ifndef MAX_CRED_COUNT
|
||||
#define MAX_CRED_COUNT 10
|
||||
#endif
|
||||
|
||||
#define WPS_OUTBUF_SIZE 500
|
||||
struct wps_sm {
|
||||
u8 state;
|
||||
struct wps_config *wps_cfg;
|
||||
@ -75,10 +68,7 @@ struct wps_sm {
|
||||
u8 identity_len;
|
||||
u8 ownaddr[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 ssid[MAX_CRED_COUNT][SSID_MAX_LEN];
|
||||
u8 ssid_len[MAX_CRED_COUNT];
|
||||
char key[MAX_CRED_COUNT][MAX_PASSPHRASE_LEN];
|
||||
u8 key_len[MAX_CRED_COUNT];
|
||||
struct wps_credential creds[MAX_CRED_COUNT];
|
||||
u8 ap_cred_cnt;
|
||||
struct wps_device_data *dev;
|
||||
u8 uuid[16];
|
||||
@ -148,3 +138,4 @@ static inline int wps_set_status(uint32_t status)
|
||||
bool is_wps_enabled(void);
|
||||
int wps_init_cfg_pin(struct wps_config *cfg);
|
||||
void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx);
|
||||
int wifi_ap_wps_disable_internal(void);
|
||||
|
@ -357,16 +357,54 @@ int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
|
||||
|
||||
u8 get_operating_class(u8 chan, int sec_channel)
|
||||
{
|
||||
u8 op_class;
|
||||
u8 op_class = 0;
|
||||
|
||||
if (chan < 1 || chan > 14)
|
||||
return 0;
|
||||
if (sec_channel == 1)
|
||||
op_class = 83;
|
||||
else if (sec_channel == -1)
|
||||
op_class = 84;
|
||||
else
|
||||
op_class = 81;
|
||||
if (chan >= 1 && chan < 14) {
|
||||
if (sec_channel == 1)
|
||||
op_class = 83;
|
||||
else if (sec_channel == -1)
|
||||
op_class = 84;
|
||||
else
|
||||
op_class = 81;
|
||||
}
|
||||
|
||||
if (chan == 14)
|
||||
op_class = 82;
|
||||
|
||||
#if SOC_WIFI_SUPPORT_5G
|
||||
if (chan >= 36 && chan <= 48) {
|
||||
if (sec_channel == 1)
|
||||
op_class = 116;
|
||||
else if (sec_channel == -1)
|
||||
op_class = 117;
|
||||
else
|
||||
op_class = 115;
|
||||
}
|
||||
if (chan >= 52 && chan <= 64) {
|
||||
if (sec_channel == 1)
|
||||
op_class = 119;
|
||||
else if (sec_channel == -1)
|
||||
op_class = 120;
|
||||
else
|
||||
op_class = 118;
|
||||
}
|
||||
if (chan >= 149 && chan <= 177) {
|
||||
if (sec_channel == 1)
|
||||
op_class = 126;
|
||||
else if (sec_channel == -1)
|
||||
op_class = 127;
|
||||
else
|
||||
op_class = 125;
|
||||
}
|
||||
if (chan >= 100 && chan <= 144) {
|
||||
if (sec_channel == 1)
|
||||
op_class = 122;
|
||||
else if (sec_channel == -1)
|
||||
op_class = 123;
|
||||
else
|
||||
op_class = 121;
|
||||
}
|
||||
#endif
|
||||
|
||||
return op_class;
|
||||
}
|
||||
|
@ -84,7 +84,11 @@ struct wps_parse_attr {
|
||||
u16 oob_dev_password_len;
|
||||
|
||||
/* attributes that can occur multiple times */
|
||||
#ifdef ESP_SUPPLICANT
|
||||
#define MAX_CRED_COUNT MAX_WPS_AP_CRED
|
||||
#else
|
||||
#define MAX_CRED_COUNT 10
|
||||
#endif
|
||||
#define MAX_REQ_DEV_TYPE_COUNT 10
|
||||
|
||||
unsigned int num_cred;
|
||||
|
@ -32,9 +32,9 @@ examples/system/deep_sleep:
|
||||
|
||||
examples/system/deep_sleep_wake_stub:
|
||||
disable:
|
||||
- if: IDF_TARGET in ["esp32c2", "esp32p4", "esp32c61"]
|
||||
- if: ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB != 1
|
||||
temporary: true
|
||||
reason: target(s) is not supported yet # TODO: [esp32c61] IDF-9245
|
||||
reason: target(s) is not supported yet
|
||||
|
||||
examples/system/efuse:
|
||||
enable:
|
||||
@ -299,6 +299,12 @@ examples/system/ulp/lp_core/gpio_intr_pulse_counter:
|
||||
depends_components:
|
||||
- ulp
|
||||
|
||||
examples/system/ulp/lp_core/inter_cpu_critical_section/:
|
||||
enable:
|
||||
- if: SOC_LP_CORE_SUPPORTED == 1
|
||||
depends_components:
|
||||
- ulp
|
||||
|
||||
examples/system/ulp/lp_core/interrupt:
|
||||
enable:
|
||||
- if: SOC_LP_CORE_SUPPORTED == 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# Deep Sleep Example
|
||||
|
||||
|
@ -41,6 +41,7 @@ menu "Example Configuration"
|
||||
default 2 if !IDF_TARGET_ESP32H2
|
||||
default 10 if IDF_TARGET_ESP32H2
|
||||
range 0 7 if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C5
|
||||
range 0 6 if IDF_TARGET_ESP32C61
|
||||
range 7 14 if IDF_TARGET_ESP32H2
|
||||
range 0 21 if IDF_TARGET_ESP32S2
|
||||
range 0 21 if IDF_TARGET_ESP32S3
|
||||
@ -116,6 +117,7 @@ menu "Example Configuration"
|
||||
default 4 if !IDF_TARGET_ESP32H2
|
||||
default 11 if IDF_TARGET_ESP32H2
|
||||
range 0 7 if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C5
|
||||
range 0 6 if IDF_TARGET_ESP32C61
|
||||
range 7 14 if IDF_TARGET_ESP32H2
|
||||
range 0 21 if IDF_TARGET_ESP32S2
|
||||
range 0 21 if IDF_TARGET_ESP32S3
|
||||
@ -270,6 +272,7 @@ menu "Example Configuration"
|
||||
int "Enable wakeup from GPIO"
|
||||
default 0
|
||||
range 0 7 if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C5
|
||||
range 0 6 if IDF_TARGET_ESP32C61
|
||||
range 0 15 if IDF_TARGET_ESP32P4
|
||||
range 0 5 if !IDF_TARGET_ESP32C6 && !IDF_TARGET_ESP32C5
|
||||
|
||||
|
@ -20,6 +20,7 @@ CONFIGS = [
|
||||
pytest.mark.esp32c3,
|
||||
pytest.mark.esp32c5,
|
||||
pytest.mark.esp32c6,
|
||||
pytest.mark.esp32c61,
|
||||
pytest.mark.esp32h2,
|
||||
pytest.mark.esp32p4,
|
||||
pytest.mark.esp32c2,
|
||||
|
@ -71,7 +71,8 @@ void app_main(void)
|
||||
int64_t t2 = esp_timer_get_time();
|
||||
ESP_LOGI(TAG, "Woke up from light sleep, time since boot: %lld us", t2);
|
||||
|
||||
assert(llabs((t2 - t1) - 500000) < 1200);
|
||||
// TODO: PM-232
|
||||
assert(((t2 - t1 - 500000) < 1000) && ((t2 - t1 - 500000) > -2000));
|
||||
#endif
|
||||
|
||||
/* Let the timer run for a little bit more */
|
||||
|
@ -81,7 +81,7 @@ def test_esp_timer(dut: Dut) -> None:
|
||||
logging.info('Enter sleep: {}, exit sleep: {}, slept: {}'.format(
|
||||
sleep_enter_time, sleep_exit_time, sleep_time))
|
||||
|
||||
assert abs(sleep_time - LIGHT_SLEEP_TIME) < 1200
|
||||
assert -2000 < sleep_time - LIGHT_SLEEP_TIME < 1000
|
||||
|
||||
for i in range(5, 7):
|
||||
match = dut.expect(PERIODIC_TIMER_REGEX, timeout=2)
|
||||
|
@ -62,5 +62,6 @@ def test_light_sleep(dut: Dut) -> None:
|
||||
logging.info('Went to sleep again')
|
||||
|
||||
match = dut.expect(EXIT_SLEEP_REGEX)
|
||||
assert match.group(1).decode('utf8') == 'timer' and int(match.group(3)) >= WAKEUP_INTERVAL_MS - 1 and int(match.group(3)) <= WAKEUP_INTERVAL_MS + 1
|
||||
# TODO: Need to support dynamically change retention overhead for chips which support pmu (PM-232)
|
||||
assert match.group(1).decode('utf8') == 'timer' and int(match.group(3)) >= WAKEUP_INTERVAL_MS - 2 and int(match.group(3)) <= WAKEUP_INTERVAL_MS + 1
|
||||
logging.info('Woke up from timer again')
|
||||
|
@ -0,0 +1,7 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
list(APPEND SDKCONFIG_DEFAULTS "sdkconfig.defaults")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(lp_inter_cpu_critical_section_example)
|
@ -0,0 +1,34 @@
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 |
|
||||
| ----------------- | -------- | -------- | -------- |
|
||||
|
||||
# LP Core simple example with inter-CPU critical section:
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
## Overview
|
||||
This example demonstrates the use of an inter-CPU critical section to safeguard shared resources between the main program and the ULP (Ultra-Low-Power) processor.
|
||||
|
||||
In this example, a global shared counter `shared_cnt` is incremented by both the high-performance CPU (HP CPU) and the low-power CPU (LP CPU) in turn. To ensure mutual exclusion, a global inter-CPU spinlock is used. With this protection in place, both the HP and LP CPUs attempt to increment the shared counter 100,000 times each.
|
||||
|
||||
The inter-CPU critical section is implemented using a global spinlock of type ulp_lp_core_spinlock_t. This type of spinlock is especially designed to protect shared resources between main program and ULP program. It supports multiple threads to attempt to enter critical section simultaneously, while eventually only one thread can succeed. This spinlock must be declared within the ULP program and shall be initialized in either the main program or the ULP program before using it. Note that this critical section doesn't support nested entering and exiting.
|
||||
|
||||
## How to use this example
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project.
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
To observe the mutual exclusion between HP and LP CPUs straight forward, the output of LP CPU is routed to HP CPU‘s console.
|
||||
|
||||
## Example output
|
||||
```
|
||||
LP CPU's increment starts, shared counter = 0
|
||||
core 0 started, cnt = 5868
|
||||
HP CPU's increment ends, shared counter = 165882
|
||||
LP CPU's increment ends, shared counter = 250000
|
||||
...
|
||||
```
|
@ -0,0 +1,24 @@
|
||||
# Register the component
|
||||
idf_component_register(SRCS "lp_inter_cpu_critical_section_main.c"
|
||||
INCLUDE_DIRS ""
|
||||
REQUIRES ulp)
|
||||
#
|
||||
# ULP support additions to component CMakeLists.txt.
|
||||
#
|
||||
# 1. The LP Core app name must be unique (if multiple components use LP Core).
|
||||
set(ulp_app_name lp_core_${COMPONENT_NAME})
|
||||
#
|
||||
# 2. Specify all C files.
|
||||
# Files should be placed into a separate directory (in this case, lp_core/),
|
||||
# which should not be added to COMPONENT_SRCS.
|
||||
set(ulp_lp_core_sources "lp_core/main.c")
|
||||
|
||||
#
|
||||
# 3. List all the component source files which include automatically
|
||||
# generated LP Core export file, ${ulp_app_name}.h:
|
||||
set(ulp_exp_dep_srcs "lp_inter_cpu_critical_section_main..c")
|
||||
|
||||
#
|
||||
# 4. Call function to build ULP binary and embed in project using the argument
|
||||
# values above.
|
||||
ulp_embed_binary(${ulp_app_name} "${ulp_lp_core_sources}" "${ulp_exp_dep_srcs}")
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "ulp_lp_core_print.h"
|
||||
#include "ulp_lp_core_utils.h"
|
||||
#include "ulp_lp_core_critical_section_shared.h"
|
||||
|
||||
volatile uint32_t shared_cnt = 0;
|
||||
ulp_lp_core_spinlock_t lp_spinlock;
|
||||
|
||||
int main (void)
|
||||
{
|
||||
/* Initialize the inter-processor spinlock. This must be done on either of HP core and LP core */
|
||||
ulp_lp_core_spinlock_init(&lp_spinlock);
|
||||
|
||||
/* Delay 10ms in case of interleaved console output */
|
||||
ulp_lp_core_delay_us(10000);
|
||||
|
||||
lp_core_printf("LP CPU's increment starts, shared counter = %d\r\n", shared_cnt);
|
||||
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
ulp_lp_core_enter_critical(&lp_spinlock);
|
||||
shared_cnt++;
|
||||
ulp_lp_core_exit_critical(&lp_spinlock);
|
||||
}
|
||||
|
||||
lp_core_printf("LP CPU's increment ends, shared counter = %d\r\n", shared_cnt);
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "lp_core_main.h"
|
||||
#include "ulp_lp_core.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "ulp_lp_core_critical_section_shared.h"
|
||||
|
||||
extern const uint8_t lp_core_main_bin_start[] asm("_binary_lp_core_main_bin_start");
|
||||
extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_main_bin_end");
|
||||
|
||||
static void lp_core_init(void)
|
||||
{
|
||||
/* Set LP core wakeup source as the HP CPU */
|
||||
ulp_lp_core_cfg_t cfg = {
|
||||
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
|
||||
.lp_timer_sleep_duration_us = 10000,
|
||||
};
|
||||
|
||||
/* Load LP core firmware */
|
||||
ESP_ERROR_CHECK(ulp_lp_core_load_binary(lp_core_main_bin_start, (lp_core_main_bin_end - lp_core_main_bin_start)));
|
||||
|
||||
/* Run LP core */
|
||||
ESP_ERROR_CHECK(ulp_lp_core_run(&cfg));
|
||||
|
||||
printf("LP core loaded with firmware and running successfully\n");
|
||||
}
|
||||
|
||||
|
||||
static void inc_num_spinlock_iter(void *arg)
|
||||
{
|
||||
int core_id = esp_cpu_get_core_id();
|
||||
|
||||
/* Delay 100ms in case of interleaved console output and ensure LP CPU starts first */
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
printf("core %d started, cnt = %ld\n", core_id, ulp_shared_cnt);
|
||||
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
ulp_lp_core_enter_critical((ulp_lp_core_spinlock_t*)&ulp_lp_spinlock);
|
||||
ulp_shared_cnt++;
|
||||
ulp_lp_core_exit_critical((ulp_lp_core_spinlock_t*)&ulp_lp_spinlock);
|
||||
}
|
||||
|
||||
printf("HP CPU's increment ends, shared counter = %ld\n", ulp_shared_cnt);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
/* If user is using USB-serial-jtag then idf monitor needs some time to
|
||||
* re-connect to the USB port. We wait 1 sec here to allow for it to make the reconnection
|
||||
* before we print anything. Otherwise the chip will go back to sleep again before the user
|
||||
* has time to monitor any output.
|
||||
*/
|
||||
|
||||
/* Load LP Core binary and start the coprocessor */
|
||||
|
||||
lp_core_init();
|
||||
|
||||
// create tasks on each core which would be accessing a shared resource protected by spinlock
|
||||
for (int core_id = 0; core_id < CONFIG_FREERTOS_NUMBER_OF_CORES; core_id++) {
|
||||
xTaskCreatePinnedToCore(inc_num_spinlock_iter, NULL, 4096, NULL, 3, NULL, core_id);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.esp32c5
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.generic
|
||||
def test_lp_core_critical_section_main_1_task(dut: Dut) -> None:
|
||||
dut.expect("LP CPU's increment starts, shared counter = 0")
|
||||
dut.expect(r'core 0 started, cnt = \d+')
|
||||
# Either LP and HP can stop increasing earlier
|
||||
dut.expect('increment ends, shared counter = 200000')
|
||||
|
||||
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.generic
|
||||
def test_lp_core_critical_section_main_2_tasks(dut: Dut) -> None:
|
||||
dut.expect("LP CPU's increment starts, shared counter = 0")
|
||||
dut.expect(r'core 0 started, cnt = \d+')
|
||||
dut.expect(r'core 1 started, cnt = \d+')
|
||||
# Either LP and HP can stop increasing earlier
|
||||
dut.expect('increment ends, shared counter = 300000')
|
@ -0,0 +1,11 @@
|
||||
# Enable LP Core
|
||||
CONFIG_ULP_COPROC_ENABLED=y
|
||||
CONFIG_ULP_COPROC_TYPE_LP_CORE=y
|
||||
CONFIG_ULP_COPROC_RESERVE_MEM=8192
|
||||
|
||||
# Route LP Core output to HP
|
||||
CONFIG_ULP_PANIC_OUTPUT_ENABLE=y
|
||||
CONFIG_ULP_HP_UART_CONSOLE_PRINT=y
|
||||
|
||||
# Extend Task Watchdog timeout period to 10 seconds
|
||||
CONFIG_ESP_TASK_WDT_TIMEOUT_S=10
|
@ -57,12 +57,22 @@ examples/wifi/itwt:
|
||||
examples/wifi/power_save:
|
||||
<<: *wifi_depends_default
|
||||
disable:
|
||||
- if: (SOC_WIFI_SUPPORTED != 1)
|
||||
- if: SOC_WIFI_SUPPORTED != 1
|
||||
- if: IDF_TARGET in ["esp32c61"]
|
||||
temporary: true
|
||||
reason: PM-234
|
||||
disable_test:
|
||||
- if: IDF_TARGET == "esp32c61"
|
||||
temporary: true
|
||||
reason: lack of runners
|
||||
depends_components:
|
||||
- esp_wifi
|
||||
- esp_phy
|
||||
- esp_netif
|
||||
- lwip
|
||||
- esp_event
|
||||
- esp_coex
|
||||
- wpa_supplicant
|
||||
- esp_driver_uart
|
||||
|
||||
examples/wifi/wifi_aware:
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# Wifi Power Save Example
|
||||
|
||||
|
@ -628,13 +628,14 @@ def test_panic_delay(dut: PanicTestDut) -> None:
|
||||
#########################
|
||||
|
||||
# Memprot-related tests are supported only on targets with PMS/PMA peripheral;
|
||||
# currently ESP32-S2, ESP32-C3, ESP32-C2, ESP32-H2, ESP32-C6, ESP32-P4 and ESP32-C5 are supported
|
||||
# currently ESP32-S2, ESP32-C3, ESP32-C2, ESP32-H2, ESP32-C6, ESP32-P4, ESP32-C5 and ESP32-C61 are supported
|
||||
CONFIGS_MEMPROT_IDRAM = [
|
||||
pytest.param('memprot_esp32s2', marks=[pytest.mark.esp32s2]),
|
||||
pytest.param('memprot_esp32c3', marks=[pytest.mark.esp32c3]),
|
||||
pytest.param('memprot_esp32c2', marks=[pytest.mark.esp32c2]),
|
||||
pytest.param('memprot_esp32c5', marks=[pytest.mark.esp32c5]),
|
||||
pytest.param('memprot_esp32c6', marks=[pytest.mark.esp32c6]),
|
||||
pytest.param('memprot_esp32c61', marks=[pytest.mark.esp32c61]),
|
||||
pytest.param('memprot_esp32h2', marks=[pytest.mark.esp32h2]),
|
||||
pytest.param('memprot_esp32p4', marks=[pytest.mark.esp32p4])
|
||||
]
|
||||
@ -659,6 +660,7 @@ CONFIGS_MEMPROT_RTC_SLOW_MEM = [
|
||||
CONFIGS_MEMPROT_FLASH_IDROM = [
|
||||
pytest.param('memprot_esp32c5', marks=[pytest.mark.esp32c5]),
|
||||
pytest.param('memprot_esp32c6', marks=[pytest.mark.esp32c6]),
|
||||
pytest.param('memprot_esp32c61', marks=[pytest.mark.esp32c61]),
|
||||
pytest.param('memprot_esp32h2', marks=[pytest.mark.esp32h2]),
|
||||
pytest.param('memprot_esp32p4', marks=[pytest.mark.esp32p4])
|
||||
]
|
||||
@ -666,6 +668,7 @@ CONFIGS_MEMPROT_FLASH_IDROM = [
|
||||
CONFIGS_MEMPROT_INVALID_REGION_PROTECTION_USING_PMA = [
|
||||
pytest.param('memprot_esp32c5', marks=[pytest.mark.esp32c5]),
|
||||
pytest.param('memprot_esp32c6', marks=[pytest.mark.esp32c6]),
|
||||
pytest.param('memprot_esp32c61', marks=[pytest.mark.esp32c61]),
|
||||
pytest.param('memprot_esp32h2', marks=[pytest.mark.esp32h2]),
|
||||
pytest.param('memprot_esp32p4', marks=[pytest.mark.esp32p4])
|
||||
]
|
||||
@ -704,7 +707,7 @@ def test_iram_reg1_write_violation(dut: PanicTestDut, test_func_name: str) -> No
|
||||
dut.expect_backtrace()
|
||||
elif dut.target == 'esp32c3':
|
||||
dut.expect_exact(r'Test error: Test function has returned')
|
||||
elif dut.target in ['esp32c2', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4']:
|
||||
else:
|
||||
dut.expect_gme('Store access fault')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
@ -729,7 +732,7 @@ def test_iram_reg2_write_violation(dut: PanicTestDut, test_func_name: str) -> No
|
||||
dut.expect(r' operation type: (\S+)')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
elif dut.target in ['esp32c2', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4']:
|
||||
else:
|
||||
dut.expect_gme('Store access fault')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
@ -754,7 +757,7 @@ def test_iram_reg3_write_violation(dut: PanicTestDut, test_func_name: str) -> No
|
||||
dut.expect(r' operation type: (\S+)')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
elif dut.target in ['esp32c2', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4']:
|
||||
else:
|
||||
dut.expect_gme('Store access fault')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
@ -781,7 +784,7 @@ def test_iram_reg4_write_violation(dut: PanicTestDut, test_func_name: str) -> No
|
||||
dut.expect(r' operation type: (\S+)')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
elif dut.target in ['esp32c2', 'esp32c6', 'eps32h2']:
|
||||
else:
|
||||
dut.expect_gme('Store access fault')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
@ -801,7 +804,7 @@ def test_dram_reg1_execute_violation(dut: PanicTestDut, test_func_name: str) ->
|
||||
dut.expect(r'Unknown operation at address [0-9xa-f]+ not permitted \((\S+)\)')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_backtrace(corrupted=True)
|
||||
elif dut.target in ['esp32c3', 'esp32c2', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4']:
|
||||
else:
|
||||
dut.expect_gme('Instruction access fault')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
@ -820,7 +823,7 @@ def test_dram_reg2_execute_violation(dut: PanicTestDut, test_func_name: str) ->
|
||||
dut.expect_gme('InstructionFetchError')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_backtrace(corrupted=True)
|
||||
elif dut.target in ['esp32c3', 'esp32c2', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4']:
|
||||
else:
|
||||
dut.expect_gme('Instruction access fault')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
@ -876,7 +879,7 @@ def test_rtc_fast_reg3_execute_violation(dut: PanicTestDut, test_func_name: str)
|
||||
dut.expect(r' operation type: (\S+)')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
elif dut.target in ['esp32c5', 'esp32c6', 'esp32h2', 'esp32p4']:
|
||||
else:
|
||||
dut.expect_gme('Instruction access fault')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_stack_dump()
|
||||
|
Loading…
Reference in New Issue
Block a user