ulp: added sleep support for lp core

Added support for running LP core while hp core sleeps, as well
as waking up the hp core.
This commit is contained in:
Marius Vikhammer 2023-03-09 14:14:09 +08:00
parent 269ff98449
commit 359b237cc5
33 changed files with 307 additions and 27 deletions

View File

@ -51,6 +51,9 @@ extern "C" {
#define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only) #define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only)
#define RTC_BT_TRIG_EN PMU_BLE_SOC_WAKEUP_EN //!< BT wakeup (light sleep only) #define RTC_BT_TRIG_EN PMU_BLE_SOC_WAKEUP_EN //!< BT wakeup (light sleep only)
#define RTC_USB_TRIG_EN PMU_USB_WAKEUP_EN #define RTC_USB_TRIG_EN PMU_USB_WAKEUP_EN
#if SOC_LP_CORE_SUPPORTED
#define RTC_LP_CORE_TRIG_EN PMU_LP_CORE_WAKEUP_EN //!< LP core wakeup
#endif //SOC_LP_CORE_SUPPORTED
#define RTC_XTAL32K_DEAD_TRIG_EN 0 // TODO #define RTC_XTAL32K_DEAD_TRIG_EN 0 // TODO
#define RTC_BROWNOUT_DET_TRIG_EN 0 // TODO #define RTC_BROWNOUT_DET_TRIG_EN 0 // TODO
@ -82,6 +85,9 @@ extern "C" {
#define PMU_UART1_WAKEUP_EN BIT(7) #define PMU_UART1_WAKEUP_EN BIT(7)
#define PMU_SDIO_WAKEUP_EN BIT(8) #define PMU_SDIO_WAKEUP_EN BIT(8)
#define PMU_BLE_SOC_WAKEUP_EN BIT(10) #define PMU_BLE_SOC_WAKEUP_EN BIT(10)
#if SOC_LP_CORE_SUPPORTED
#define PMU_LP_CORE_WAKEUP_EN BIT(11)
#endif //SOC_LP_CORE_SUPPORTED
#define PMU_USB_WAKEUP_EN BIT(14) #define PMU_USB_WAKEUP_EN BIT(14)

View File

@ -273,6 +273,7 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
pmu_ll_hp_clear_wakeup_intr_status(PMU_instance()->hal->dev); pmu_ll_hp_clear_wakeup_intr_status(PMU_instance()->hal->dev);
pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev); pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev);
pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev); pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev);
pmu_ll_hp_clear_sw_intr_status(PMU_instance()->hal->dev);
/* Start entry into sleep mode */ /* Start entry into sleep mode */
pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev); pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev);

View File

@ -533,8 +533,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
} }
#endif #endif
#if !CONFIG_IDF_TARGET_ESP32C6 // TODO IDF-7012 Add sleep support for lp core #if CONFIG_ULP_COPROC_TYPE_FSM
#if CONFIG_ULP_COPROC_ENABLED
// Enable ULP wakeup // Enable ULP wakeup
if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) {
#ifdef CONFIG_IDF_TARGET_ESP32 #ifdef CONFIG_IDF_TARGET_ESP32
@ -544,7 +543,6 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
#endif #endif
} }
#endif #endif
#endif //!CONFIG_IDF_TARGET_ESP32C6
misc_modules_sleep_prepare(deep_sleep); misc_modules_sleep_prepare(deep_sleep);
@ -1075,7 +1073,7 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) { } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) {
s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN); s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN);
} }
#if CONFIG_ULP_COPROC_ENABLED && !CONFIG_IDF_TARGET_ESP32C6 // TODO IDF-7012 Add sleep support for lp core #if CONFIG_ULP_COPROC_TYPE_FSM
else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) { else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN; s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN;
} }
@ -1109,6 +1107,9 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void)
#elif CONFIG_ULP_COPROC_TYPE_RISCV #elif CONFIG_ULP_COPROC_TYPE_RISCV
s_config.wakeup_triggers |= (RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN); s_config.wakeup_triggers |= (RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN);
return ESP_OK; return ESP_OK;
#elif CONFIG_ULP_COPROC_TYPE_LP_CORE
s_config.wakeup_triggers |= RTC_LP_CORE_TRIG_EN;
return ESP_OK;
#else #else
return ESP_ERR_NOT_SUPPORTED; return ESP_ERR_NOT_SUPPORTED;
#endif //CONFIG_ULP_COPROC_TYPE_FSM #endif //CONFIG_ULP_COPROC_TYPE_FSM
@ -1494,7 +1495,7 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
} else if (wakeup_cause & RTC_TOUCH_TRIG_EN) { } else if (wakeup_cause & RTC_TOUCH_TRIG_EN) {
return ESP_SLEEP_WAKEUP_TOUCHPAD; return ESP_SLEEP_WAKEUP_TOUCHPAD;
#endif #endif
#if SOC_ULP_SUPPORTED #if SOC_ULP_FSM_SUPPORTED
} else if (wakeup_cause & RTC_ULP_TRIG_EN) { } else if (wakeup_cause & RTC_ULP_TRIG_EN) {
return ESP_SLEEP_WAKEUP_ULP; return ESP_SLEEP_WAKEUP_ULP;
#endif #endif
@ -1511,6 +1512,10 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
return ESP_SLEEP_WAKEUP_ULP; return ESP_SLEEP_WAKEUP_ULP;
} else if (wakeup_cause & RTC_COCPU_TRAP_TRIG_EN) { } else if (wakeup_cause & RTC_COCPU_TRAP_TRIG_EN) {
return ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG; return ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG;
#endif
#if SOC_LP_CORE_SUPPORTED
} else if (wakeup_cause & RTC_LP_CORE_TRIG_EN) {
return ESP_SLEEP_WAKEUP_ULP;
#endif #endif
} else { } else {
return ESP_SLEEP_WAKEUP_UNDEFINED; return ESP_SLEEP_WAKEUP_UNDEFINED;

View File

@ -18,7 +18,7 @@ static adc_ll_controller_t get_controller(adc_unit_t unit, adc_hal_work_mode_t w
{ {
if (unit == ADC_UNIT_1) { if (unit == ADC_UNIT_1) {
switch (work_mode) { switch (work_mode) {
#if SOC_ULP_SUPPORTED #if SOC_ULP_HAS_ADC
case ADC_HAL_ULP_FSM_MODE: case ADC_HAL_ULP_FSM_MODE:
return ADC_LL_CTRL_ULP; return ADC_LL_CTRL_ULP;
#endif #endif
@ -35,7 +35,7 @@ static adc_ll_controller_t get_controller(adc_unit_t unit, adc_hal_work_mode_t w
} }
} else { } else {
switch (work_mode) { switch (work_mode) {
#if SOC_ULP_SUPPORTED #if SOC_ULP_HAS_ADC
case ADC_HAL_ULP_FSM_MODE: case ADC_HAL_ULP_FSM_MODE:
return ADC_LL_CTRL_ULP; return ADC_LL_CTRL_ULP;
#endif #endif

View File

@ -506,6 +506,11 @@ FORCE_INLINE_ATTR bool pmu_ll_hp_is_sleep_reject(pmu_dev_t *hw)
return (hw->hp_ext.int_raw.reject == 1); return (hw->hp_ext.int_raw.reject == 1);
} }
FORCE_INLINE_ATTR void pmu_ll_hp_clear_sw_intr_status(pmu_dev_t *hw)
{
hw->hp_ext.int_clr.sw = 1;
}
FORCE_INLINE_ATTR void pmu_ll_hp_clear_wakeup_intr_status(pmu_dev_t *hw) FORCE_INLINE_ATTR void pmu_ll_hp_clear_wakeup_intr_status(pmu_dev_t *hw)
{ {
hw->hp_ext.int_clr.wakeup = 1; hw->hp_ext.int_clr.wakeup = 1;

View File

@ -846,3 +846,7 @@ config SOC_BT_CLASSIC_SUPPORTED
config SOC_BLE_DEVICE_PRIVACY_SUPPORTED config SOC_BLE_DEVICE_PRIVACY_SUPPORTED
bool bool
default n default n
config SOC_ULP_HAS_ADC
bool
default y

View File

@ -414,3 +414,6 @@
#define SOC_BLE_MESH_SUPPORTED (1) /*!< Support BLE MESH */ #define SOC_BLE_MESH_SUPPORTED (1) /*!< Support BLE MESH */
#define SOC_BT_CLASSIC_SUPPORTED (1) /*!< Support Bluetooth Classic hardware */ #define SOC_BT_CLASSIC_SUPPORTED (1) /*!< Support Bluetooth Classic hardware */
#define SOC_BLE_DEVICE_PRIVACY_SUPPORTED (0) /*!< Support BLE device privacy mode */ #define SOC_BLE_DEVICE_PRIVACY_SUPPORTED (0) /*!< Support BLE device privacy mode */
/*-------------------------- ULP CAPS ----------------------------------------*/
#define SOC_ULP_HAS_ADC (1) /* ADC can be accessed from ULP */

View File

@ -71,6 +71,10 @@ config SOC_SUPPORTS_SECURE_DL_MODE
bool bool
default y default y
config SOC_ULP_SUPPORTED
bool
default y
config SOC_LP_CORE_SUPPORTED config SOC_LP_CORE_SUPPORTED
bool bool
default y default y

View File

@ -42,6 +42,7 @@
#define SOC_TEMP_SENSOR_SUPPORTED 1 #define SOC_TEMP_SENSOR_SUPPORTED 1
#define SOC_WIFI_SUPPORTED 1 #define SOC_WIFI_SUPPORTED 1
#define SOC_SUPPORTS_SECURE_DL_MODE 1 #define SOC_SUPPORTS_SECURE_DL_MODE 1
#define SOC_ULP_SUPPORTED 1
#define SOC_LP_CORE_SUPPORTED 1 #define SOC_LP_CORE_SUPPORTED 1
#define SOC_EFUSE_KEY_PURPOSE_FIELD 1 #define SOC_EFUSE_KEY_PURPOSE_FIELD 1
#define SOC_RTC_FAST_MEM_SUPPORTED 1 #define SOC_RTC_FAST_MEM_SUPPORTED 1

View File

@ -1078,3 +1078,7 @@ config SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW
config SOC_WIFI_NAN_SUPPORT config SOC_WIFI_NAN_SUPPORT
bool bool
default y default y
config SOC_ULP_HAS_ADC
bool
default y

View File

@ -461,3 +461,5 @@
#define SOC_WIFI_MESH_SUPPORT (1) /*!< Support WIFI MESH */ #define SOC_WIFI_MESH_SUPPORT (1) /*!< Support WIFI MESH */
#define SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW (1) /*!< Support delta early time for rf phy on/off */ #define SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW (1) /*!< Support delta early time for rf phy on/off */
#define SOC_WIFI_NAN_SUPPORT (1) /*!< Support WIFI Aware (NAN) */ #define SOC_WIFI_NAN_SUPPORT (1) /*!< Support WIFI Aware (NAN) */
/*-------------------------- ULP CAPS ----------------------------------------*/
#define SOC_ULP_HAS_ADC (1) /* ADC can be accessed from ULP */

View File

@ -1254,3 +1254,7 @@ config SOC_BLE_50_SUPPORTED
config SOC_BLE_DEVICE_PRIVACY_SUPPORTED config SOC_BLE_DEVICE_PRIVACY_SUPPORTED
bool bool
default y default y
config SOC_ULP_HAS_ADC
bool
default y

View File

@ -507,3 +507,6 @@
#define SOC_BLE_MESH_SUPPORTED (1) /*!< Support BLE MESH */ #define SOC_BLE_MESH_SUPPORTED (1) /*!< Support BLE MESH */
#define SOC_BLE_50_SUPPORTED (1) /*!< Support Bluetooth 5.0 */ #define SOC_BLE_50_SUPPORTED (1) /*!< Support Bluetooth 5.0 */
#define SOC_BLE_DEVICE_PRIVACY_SUPPORTED (1) /*!< Support BLE device privacy mode */ #define SOC_BLE_DEVICE_PRIVACY_SUPPORTED (1) /*!< Support BLE device privacy mode */
/*-------------------------- ULP CAPS ----------------------------------------*/
#define SOC_ULP_HAS_ADC (1) /* ADC can be accessed from ULP */

View File

@ -5,7 +5,7 @@ components/ulp/test_apps/lp_core:
- if: SOC_LP_CORE_SUPPORTED != 1 - if: SOC_LP_CORE_SUPPORTED != 1
components/ulp/test_apps/ulp_fsm: components/ulp/test_apps/ulp_fsm:
enable: enable:
- if: SOC_ULP_SUPPORTED == 1 - if: SOC_ULP_FSM_SUPPORTED == 1
components/ulp/test_apps/ulp_riscv: components/ulp/test_apps/ulp_riscv:
disable: disable:

View File

@ -3,7 +3,7 @@ idf_build_get_property(target IDF_TARGET)
set(srcs "") set(srcs "")
set(includes "") set(includes "")
if(CONFIG_SOC_ULP_SUPPORTED OR CONFIG_SOC_RISCV_COPROC_SUPPORTED) if(CONFIG_ULP_COPROC_TYPE_FSM OR CONFIG_SOC_RISCV_COPROC_SUPPORTED)
list(APPEND srcs list(APPEND srcs
"ulp_common/ulp_common.c" "ulp_common/ulp_common.c"

View File

@ -79,7 +79,9 @@ if(ULP_COCPU_IS_RISCV)
elseif(ULP_COCPU_IS_LP_CORE) elseif(ULP_COCPU_IS_LP_CORE)
list(APPEND ULP_S_SOURCES list(APPEND ULP_S_SOURCES
"${IDF_PATH}/components/ulp/lp_core/lp_core/start.S" "${IDF_PATH}/components/ulp/lp_core/lp_core/start.S"
"${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_startup.c") "${IDF_PATH}/components/ulp/lp_core/lp_core/vector.S"
"${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_startup.c"
"${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_utils.c")
target_link_options(${ULP_APP_NAME} PRIVATE "-nostartfiles") target_link_options(${ULP_APP_NAME} PRIVATE "-nostartfiles")
target_link_options(${ULP_APP_NAME} PRIVATE "-Wl,--no-warn-rwx-segments") target_link_options(${ULP_APP_NAME} PRIVATE "-Wl,--no-warn-rwx-segments")

View File

@ -9,7 +9,7 @@ set(CMAKE_C_FLAGS "-Os -march=rv32imac_zicsr_zifencei -mdiv -fdata-sections -ffu
CACHE STRING "C Compiler Base Flags") CACHE STRING "C Compiler Base Flags")
set(CMAKE_CXX_FLAGS "-Os -march=rv32imac_zicsr_zifencei -mdiv -fdata-sections -ffunction-sections" set(CMAKE_CXX_FLAGS "-Os -march=rv32imac_zicsr_zifencei -mdiv -fdata-sections -ffunction-sections"
CACHE STRING "C++ Compiler Base Flags") CACHE STRING "C++ Compiler Base Flags")
set(CMAKE_ASM_FLAGS "-march=rv32imac -x assembler-with-cpp" set(CMAKE_ASM_FLAGS "-march=rv32imac_zicsr_zifencei -x assembler-with-cpp"
CACHE STRING "Assembler Base Flags") CACHE STRING "Assembler Base Flags")
set(CMAKE_EXE_LINKER_FLAGS "-march=rv32imac_zicsr_zifencei --specs=nano.specs --specs=nosys.specs" set(CMAKE_EXE_LINKER_FLAGS "-march=rv32imac_zicsr_zifencei --specs=nano.specs --specs=nosys.specs"
CACHE STRING "Linker Base Flags") CACHE STRING "Linker Base Flags")

View File

@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* @brief Wakeup main CPU from sleep or deep sleep.
*
* This raises a software interrupt signal, if the
* main CPU has configured the ULP as a wakeup source
* calling this function will make the main CPU to
* exit from sleep or deep sleep.
*/
void ulp_lp_core_wakeup_main_processor(void);
/**
* @brief Makes the co-processor busy wait for a certain number of microseconds
*
* @param us Number of microseconds to busy-wait for
*/
void ulp_lp_core_delay_us(uint32_t us);
#ifdef __cplusplus
}
#endif

View File

@ -7,20 +7,28 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_log.h" #include "esp_log.h"
#include "soc/pmu_reg.h" #include "soc/pmu_reg.h"
#include "soc/lp_aon_reg.h"
#include "soc/lpperi_reg.h" #include "soc/lpperi_reg.h"
#include "hal/misc.h" #include "hal/misc.h"
#include "ulp_common.h" #include "ulp_common.h"
#include "ulp_lp_core.h" #include "ulp_lp_core.h"
const static char* TAG = "ulp-lp-core"; const static char* TAG = "ulp-lp-core";
esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg) esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg)
{ {
/* Enable LP-Core */
REG_CLR_BIT(LP_AON_LPCORE_REG, LP_AON_LPCORE_DISABLE);
/* Allow LP core to access LP memory during sleep */
REG_CLR_BIT(LP_AON_LPBUS_REG, LP_AON_FAST_MEM_MUX_SEL);
REG_SET_BIT(LP_AON_LPBUS_REG, LP_AON_FAST_MEM_MUX_SEL_UPDATE);
REG_SET_FIELD(PMU_LP_CPU_PWR1_REG, PMU_LP_CPU_WAKEUP_EN, 1); REG_SET_FIELD(PMU_LP_CPU_PWR1_REG, PMU_LP_CPU_WAKEUP_EN, 1);
/* Enable JTAG debugging */
REG_CLR_BIT(LPPERI_CPU_REG, LPPERI_LPCORE_DBGM_UNAVALIABLE);
switch(cfg->wakeup_source) { switch(cfg->wakeup_source) {
case ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU: case ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU:
REG_SET_FIELD(PMU_HP_LP_CPU_COMM_REG, PMU_HP_TRIGGER_LP, 1); REG_SET_FIELD(PMU_HP_LP_CPU_COMM_REG, PMU_HP_TRIGGER_LP, 1);
@ -41,6 +49,10 @@ esp_err_t ulp_lp_core_load_binary(const uint8_t* program_binary, size_t program_
return ESP_ERR_INVALID_SIZE; return ESP_ERR_INVALID_SIZE;
} }
/* Turn off LP CPU before loading binary */
REG_SET_FIELD(PMU_LP_CPU_PWR1_REG, PMU_LP_CPU_WAKEUP_EN, 0);
REG_SET_FIELD(PMU_LP_CPU_PWR1_REG, PMU_LP_CPU_SLEEP_REQ, 1);
uint8_t* base = (uint8_t*) RTC_SLOW_MEM; uint8_t* base = (uint8_t*) RTC_SLOW_MEM;
//Start by clearing memory reserved with zeros, this will also will initialize the bss: //Start by clearing memory reserved with zeros, this will also will initialize the bss:

View File

@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "riscv/csr.h"
#include "soc/soc.h"
#include "soc/pmu_reg.h"
/* LP_FAST_CLK is not very accurate, for now use a rough estimate */
#define LP_CORE_CPU_FREQUENCY_HZ 16000000
/**
* @brief Wakeup main CPU from sleep or deep sleep.
*
* This raises a software interrupt signal, if the
* main CPU has configured the ULP as a wakeup source
* calling this function will make the main CPU to
* exit from sleep or deep sleep.
*/
void ulp_lp_core_wakeup_main_processor(void)
{
REG_SET_FIELD(PMU_HP_LP_CPU_COMM_REG, PMU_LP_TRIGGER_HP, 1);
}
/**
* @brief Makes the co-processor busy wait for a certain number of microseconds
*
* @param us Number of microseconds to busy-wait for
*/
void ulp_lp_core_delay_us(uint32_t us)
{
uint32_t start = RV_READ_CSR(mcycle);
uint32_t end = us * (LP_CORE_CPU_FREQUENCY_HZ / 1000000);
while ((RV_READ_CSR(mcycle) - start) < end) {
/* nothing to do */
}
}

View File

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
.section .init.vector,"ax"
/* This is the vector table. It is currently empty, but will be populated
* with exception and interrupt handlers when this is supported
*/
.align 0x4, 0xff
.global _vector_table
.type _vector_table, @function
_vector_table:
.option push
.option norvc
.rept 32
nop
.endr
.option pop
.size _vector_table, .-_vector_table

View File

@ -3,7 +3,7 @@ set(lp_core_sources "lp_core/test_main.c")
idf_component_register(SRCS ${app_sources} idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "lp_core" INCLUDE_DIRS "lp_core"
REQUIRES ulp unity REQUIRES ulp unity esp_timer
WHOLE_ARCHIVE) WHOLE_ARCHIVE)
set(lp_core_app_name lp_core_test_app) set(lp_core_app_name lp_core_test_app)

View File

@ -8,6 +8,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "test_shared.h" #include "test_shared.h"
#include "ulp_lp_core_utils.h"
volatile lp_core_test_commands_t main_cpu_command = LP_CORE_NO_COMMAND; volatile lp_core_test_commands_t main_cpu_command = LP_CORE_NO_COMMAND;
@ -33,10 +35,48 @@ void handle_commands(lp_core_test_commands_t cmd)
/* Set the command reply status */ /* Set the command reply status */
main_cpu_reply = LP_CORE_COMMAND_OK; main_cpu_reply = LP_CORE_COMMAND_OK;
main_cpu_command = LP_CORE_NO_COMMAND;
break;
case LP_CORE_DELAY_TEST:
counter++;
/* Echo the command ID back to the main CPU */
command_resp = LP_CORE_DELAY_TEST;
ulp_lp_core_delay_us(test_data_in);
main_cpu_reply = LP_CORE_COMMAND_OK;
main_cpu_command = LP_CORE_NO_COMMAND;
break;
case LP_CORE_DEEP_SLEEP_WAKEUP_SHORT_DELAY_TEST:
/* Echo the command ID back to the main CPU */
command_resp = LP_CORE_DEEP_SLEEP_WAKEUP_SHORT_DELAY_TEST;
/* Set the command reply status */
main_cpu_reply = LP_CORE_COMMAND_OK;
main_cpu_command = LP_CORE_NO_COMMAND;
ulp_lp_core_delay_us(1000*1000);
ulp_lp_core_wakeup_main_processor();
break;
case LP_CORE_DEEP_SLEEP_WAKEUP_LONG_DELAY_TEST:
/* Echo the command ID back to the main CPU */
command_resp = LP_CORE_DEEP_SLEEP_WAKEUP_LONG_DELAY_TEST;
/* Set the command reply status */
main_cpu_reply = LP_CORE_COMMAND_OK;
main_cpu_command = LP_CORE_NO_COMMAND;
ulp_lp_core_delay_us(10000*1000);
ulp_lp_core_wakeup_main_processor();
break; break;
case LP_CORE_NO_COMMAND: case LP_CORE_NO_COMMAND:
main_cpu_reply = LP_CORE_COMMAND_OK; main_cpu_reply = LP_CORE_COMMAND_NOK;
break; break;
default: default:
@ -49,7 +89,7 @@ int main (void)
{ {
while (1) { while (1) {
handle_commands(main_cpu_command); handle_commands(main_cpu_command);
} }
return 0; return 0;
} }

View File

@ -9,6 +9,9 @@
typedef enum{ typedef enum{
LP_CORE_READ_WRITE_TEST = 1, LP_CORE_READ_WRITE_TEST = 1,
LP_CORE_DELAY_TEST,
LP_CORE_DEEP_SLEEP_WAKEUP_SHORT_DELAY_TEST,
LP_CORE_DEEP_SLEEP_WAKEUP_LONG_DELAY_TEST,
LP_CORE_NO_COMMAND, LP_CORE_NO_COMMAND,
} lp_core_test_commands_t; } lp_core_test_commands_t;

View File

@ -10,6 +10,8 @@
#include "ulp_lp_core.h" #include "ulp_lp_core.h"
#include "test_shared.h" #include "test_shared.h"
#include "unity.h" #include "unity.h"
#include "esp_sleep.h"
#include "esp_timer.h"
extern const uint8_t lp_core_main_bin_start[] asm("_binary_lp_core_test_app_bin_start"); extern const uint8_t lp_core_main_bin_start[] asm("_binary_lp_core_test_app_bin_start");
extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_test_app_bin_end"); extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_test_app_bin_end");
@ -59,4 +61,80 @@ TEST_CASE("LP core and main CPU are able to exchange data", "[lp_core]")
/* Clear test data */ /* Clear test data */
ulp_main_cpu_command = LP_CORE_NO_COMMAND; ulp_main_cpu_command = LP_CORE_NO_COMMAND;
ulp_command_resp = LP_CORE_NO_COMMAND;
} }
TEST_CASE("Test LP core delay", "[lp_core]")
{
int64_t start, diff;
const uint32_t delay_period_us = 5000000;
const uint32_t delta_us = 500000; // RTC FAST is not very accurate
/* Load ULP RISC-V firmware and start the coprocessor */
load_and_start_lp_core_firmware();
/* Setup test data */
ulp_test_data_in = delay_period_us;
ulp_main_cpu_command = LP_CORE_DELAY_TEST;
/* Wait till we receive the correct command response */
while (ulp_command_resp != LP_CORE_DELAY_TEST) {
}
start = esp_timer_get_time();
/* Wait till we receive COMMAND_OK reply */
while (ulp_main_cpu_reply != LP_CORE_COMMAND_OK) {
}
diff = esp_timer_get_time() - start;
printf("Waited for %" PRIi64 "us, expected: %" PRIi32 "us\n", diff, delay_period_us);
TEST_ASSERT_INT_WITHIN(delta_us, delay_period_us, diff);
/* Clear test data */
ulp_main_cpu_command = LP_CORE_NO_COMMAND;
ulp_command_resp = LP_CORE_NO_COMMAND;
}
static void do_ulp_wakeup_deepsleep(lp_core_test_commands_t ulp_cmd)
{
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
load_and_start_lp_core_firmware();
/* Setup wakeup triggers */
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
/* Setup test data */
ulp_main_cpu_command = ulp_cmd;
/* Enter Deep Sleep */
esp_deep_sleep_start();
UNITY_TEST_FAIL(__LINE__, "Should not get here!");
}
static void check_reset_reason_ulp_wakeup(void)
{
TEST_ASSERT_EQUAL(ESP_SLEEP_WAKEUP_ULP, esp_sleep_get_wakeup_cause());
}
static void do_ulp_wakeup_after_short_delay_deepsleep(void)
{
do_ulp_wakeup_deepsleep(LP_CORE_DEEP_SLEEP_WAKEUP_SHORT_DELAY_TEST);
}
static void do_ulp_wakeup_after_long_delay_deepsleep(void)
{
do_ulp_wakeup_deepsleep(LP_CORE_DEEP_SLEEP_WAKEUP_LONG_DELAY_TEST);
}
TEST_CASE_MULTIPLE_STAGES("LP-core is able to wakeup main CPU from deep sleep after a short delay", "[ulp]",
do_ulp_wakeup_after_short_delay_deepsleep,
check_reset_reason_ulp_wakeup);
/* Certain erroneous wake-up triggers happen only after sleeping for a few seconds */
TEST_CASE_MULTIPLE_STAGES("LP-core is able to wakeup main CPU from deep sleep after a long delay", "[ulp]",
do_ulp_wakeup_after_long_delay_deepsleep,
check_reset_reason_ulp_wakeup);

View File

@ -321,7 +321,7 @@ static void do_ulp_wakeup_after_long_delay_deepsleep(void)
do_ulp_wakeup_deepsleep(RISCV_DEEP_SLEEP_WAKEUP_LONG_DELAY_TEST, true); do_ulp_wakeup_deepsleep(RISCV_DEEP_SLEEP_WAKEUP_LONG_DELAY_TEST, true);
} }
/* Certain erroneous wake-up triggers happen only after a sleeping for a few seconds */ /* Certain erroneous wake-up triggers happen only after sleeping for a few seconds */
TEST_CASE_MULTIPLE_STAGES("ULP-RISC-V is able to wakeup main CPU from deep sleep after a long delay", "[ulp]", TEST_CASE_MULTIPLE_STAGES("ULP-RISC-V is able to wakeup main CPU from deep sleep after a long delay", "[ulp]",
do_ulp_wakeup_after_long_delay_deepsleep, do_ulp_wakeup_after_long_delay_deepsleep,
check_reset_reason_ulp_wakeup); check_reset_reason_ulp_wakeup);

View File

@ -18,7 +18,7 @@ extern "C" {
* @brief Wakeup main CPU from sleep or deep sleep. * @brief Wakeup main CPU from sleep or deep sleep.
* *
* This raises a software interrupt signal, if the * This raises a software interrupt signal, if the
* main CPU is configured the ULP as a wakeup source * main CPU has configured the ULP as a wakeup source
* calling this function will make the main CPU to * calling this function will make the main CPU to
* exit from sleep or deep sleep. * exit from sleep or deep sleep.
*/ */

View File

@ -104,9 +104,9 @@ FTDI_JTAG_DOCS = ['api-guides/jtag-debugging/configure-ft2232h-jtag.rst']
USB_SERIAL_JTAG_DOCS = ['api-guides/jtag-debugging/configure-builtin-jtag.rst', USB_SERIAL_JTAG_DOCS = ['api-guides/jtag-debugging/configure-builtin-jtag.rst',
'api-guides/usb-serial-jtag-console.rst'] 'api-guides/usb-serial-jtag-console.rst']
ULP_DOCS = ['api-reference/system/ulp.rst', ULP_FSM_DOCS = ['api-reference/system/ulp.rst',
'api-reference/system/ulp_macros.rst', 'api-reference/system/ulp_macros.rst',
'api-reference/system/ulp_instruction_set.rst'] 'api-reference/system/ulp_instruction_set.rst']
RISCV_COPROC_DOCS = ['api-reference/system/ulp-risc-v.rst',] RISCV_COPROC_DOCS = ['api-reference/system/ulp-risc-v.rst',]
@ -183,7 +183,7 @@ conditional_include_dict = {'SOC_BT_SUPPORTED':BT_DOCS,
'SOC_DAC_SUPPORTED':DAC_DOCS, 'SOC_DAC_SUPPORTED':DAC_DOCS,
'SOC_ETM_SUPPORTED':ETM_DOCS, 'SOC_ETM_SUPPORTED':ETM_DOCS,
'SOC_TOUCH_SENSOR_SUPPORTED':TOUCH_SENSOR_DOCS, 'SOC_TOUCH_SENSOR_SUPPORTED':TOUCH_SENSOR_DOCS,
'SOC_ULP_SUPPORTED':ULP_DOCS, 'SOC_ULP_FSM_SUPPORTED':ULP_FSM_DOCS,
'SOC_RISCV_COPROC_SUPPORTED':RISCV_COPROC_DOCS, 'SOC_RISCV_COPROC_SUPPORTED':RISCV_COPROC_DOCS,
'SOC_DIG_SIGN_SUPPORTED':['api-reference/peripherals/ds.rst'], 'SOC_DIG_SIGN_SUPPORTED':['api-reference/peripherals/ds.rst'],
'SOC_HMAC_SUPPORTED':['api-reference/peripherals/hmac.rst'], 'SOC_HMAC_SUPPORTED':['api-reference/peripherals/hmac.rst'],

View File

@ -18,7 +18,7 @@ GPIO Summary
.. list:: .. list::
- In Deep-sleep mode - In Deep-sleep mode
:SOC_ULP_SUPPORTED: - The :doc:`Ultra Low Power co-processor <../../api-reference/system/ulp>` is running :SOC_ULP_SUPPORTED and not esp32c6: - The :doc:`Ultra Low Power co-processor <../../api-reference/system/ulp>` is running
- Analog functions such as ADC/DAC/etc are in use. - Analog functions such as ADC/DAC/etc are in use.

View File

@ -37,7 +37,7 @@ System API
system_time system_time
:SOC_ASYNC_MEMCPY_SUPPORTED: async_memcpy :SOC_ASYNC_MEMCPY_SUPPORTED: async_memcpy
:esp32: himem :esp32: himem
:SOC_ULP_SUPPORTED: ulp :SOC_ULP_FSM_SUPPORTED: ulp
:SOC_RISCV_COPROC_SUPPORTED: ulp-risc-v :SOC_RISCV_COPROC_SUPPORTED: ulp-risc-v
wdts wdts

View File

@ -18,7 +18,7 @@ GPIO 汇总
.. list:: .. list::
- 处于 Deep-sleep 模式时 - 处于 Deep-sleep 模式时
:SOC_ULP_SUPPORTED: - :doc:`超低功耗协处理器 (ULP) <../../api-reference/system/ulp>` 运行时 :SOC_ULP_SUPPORTED and not esp32c6: - :doc:`超低功耗协处理器 (ULP) <../../api-reference/system/ulp>` 运行时
- 使用 ADC/DAC 等模拟功能时 - 使用 ADC/DAC 等模拟功能时

View File

@ -37,7 +37,7 @@ System API
system_time system_time
:SOC_ASYNC_MEMCPY_SUPPORTED: async_memcpy :SOC_ASYNC_MEMCPY_SUPPORTED: async_memcpy
:esp32: himem :esp32: himem
:SOC_ULP_SUPPORTED: ulp :SOC_ULP_FSM_SUPPORTED: ulp
:SOC_RISCV_COPROC_SUPPORTED: ulp-risc-v :SOC_RISCV_COPROC_SUPPORTED: ulp-risc-v
wdts wdts

View File

@ -175,7 +175,7 @@ examples/system/task_watchdog:
examples/system/ulp_fsm/ulp: examples/system/ulp_fsm/ulp:
disable: disable:
- if: SOC_ULP_SUPPORTED != 1 - if: SOC_ULP_FSM_SUPPORTED != 1
examples/system/ulp_fsm/ulp_adc: examples/system/ulp_fsm/ulp_adc:
enable: enable: