forked from espressif/esp-idf
feat(lp_core): added support for LP-IO as LP-core wakeup source
This commit is contained in:
@@ -309,6 +309,14 @@ static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t ty
|
|||||||
{
|
{
|
||||||
LP_IO.pin[rtcio_num].wakeup_enable = 1;
|
LP_IO.pin[rtcio_num].wakeup_enable = 1;
|
||||||
LP_IO.pin[rtcio_num].int_type = type;
|
LP_IO.pin[rtcio_num].int_type = type;
|
||||||
|
|
||||||
|
/* Work around for HW issue,
|
||||||
|
need to also enable this clk, otherwise it will
|
||||||
|
not trigger a wake-up on the ULP. This is not needed
|
||||||
|
for triggering a wakeup on HP CPU, but always setting this
|
||||||
|
has no side-effects.
|
||||||
|
*/
|
||||||
|
LP_IO.date.clk_en = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -130,7 +130,7 @@ esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cfg->wakeup_source & (ULP_LP_CORE_WAKEUP_SOURCE_LP_UART | ULP_LP_CORE_WAKEUP_SOURCE_LP_IO)) {
|
if (cfg->wakeup_source & (ULP_LP_CORE_WAKEUP_SOURCE_LP_UART)) {
|
||||||
ESP_LOGE(TAG, "Wake-up source not yet supported");
|
ESP_LOGE(TAG, "Wake-up source not yet supported");
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
@@ -299,6 +299,12 @@ examples/system/ulp/lp_core/gpio_intr_pulse_counter:
|
|||||||
depends_components:
|
depends_components:
|
||||||
- ulp
|
- ulp
|
||||||
|
|
||||||
|
examples/system/ulp/lp_core/gpio_wakeup:
|
||||||
|
enable:
|
||||||
|
- if: (SOC_LP_CORE_SUPPORTED == 1) and (SOC_RTCIO_PIN_COUNT > 0)
|
||||||
|
depends_components:
|
||||||
|
- ulp
|
||||||
|
|
||||||
examples/system/ulp/lp_core/inter_cpu_critical_section/:
|
examples/system/ulp/lp_core/inter_cpu_critical_section/:
|
||||||
enable:
|
enable:
|
||||||
- if: SOC_LP_CORE_SUPPORTED == 1
|
- if: SOC_LP_CORE_SUPPORTED == 1
|
||||||
|
6
examples/system/ulp/lp_core/gpio_wakeup/CMakeLists.txt
Normal file
6
examples/system/ulp/lp_core/gpio_wakeup/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||||
|
# in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(ulp_lp_core_gpio_wakeup_example)
|
26
examples/system/ulp/lp_core/gpio_wakeup/README.md
Normal file
26
examples/system/ulp/lp_core/gpio_wakeup/README.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 |
|
||||||
|
| ----------------- | -------- | -------- | -------- |
|
||||||
|
# ULP-LP-Core simple example with GPIO Interrupt:
|
||||||
|
|
||||||
|
This example demonstrates how to program the LP-Core coprocessor to wake up from a RTC IO interrupt, instead of waking periodically from the ULP timer.
|
||||||
|
|
||||||
|
ULP program written in C can be found across `ulp/main.c`. The build system compiles and links this program, converts it into binary format, and embeds it into the .rodata section of the ESP-IDF application.
|
||||||
|
|
||||||
|
At runtime, the main code running on the ESP (found in lp_core_gpio_wake_up_example_main.c) loads ULP program into the `RTC_SLOW_MEM` memory region using `ulp_lp_core_load_binary` function. The main code then configures the ULP GPIO wakeup source and starts the coprocessor by using `ulp_lp_core_run` followed by putting the chip into deep sleep mode.
|
||||||
|
|
||||||
|
When the wakeup source pin is pulled low the LP-Core coprocessor is woken up, sends a wakeup signal to the main CPU and goes back to sleep again.
|
||||||
|
|
||||||
|
In this example the input signal is connected to GPIO2. To change the pin number, check the Chip Pin List document and adjust `WAKEUP_PIN` variable in main.c.
|
||||||
|
|
||||||
|
|
||||||
|
## Example output
|
||||||
|
|
||||||
|
```
|
||||||
|
Not a LP-Core wakeup, initializing it!
|
||||||
|
Entering deep sleep
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
LP-Core woke up the main CPU!
|
||||||
|
Entering deep sleep
|
||||||
|
```
|
27
examples/system/ulp/lp_core/gpio_wakeup/main/CMakeLists.txt
Normal file
27
examples/system/ulp/lp_core/gpio_wakeup/main/CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Set usual component variables
|
||||||
|
set(COMPONENT_SRCS "lp_core_gpio_wake_up_example_main.c")
|
||||||
|
set(COMPONENT_ADD_INCLUDEDIRS "")
|
||||||
|
set(COMPONENT_REQUIRES ulp driver)
|
||||||
|
|
||||||
|
register_component()
|
||||||
|
|
||||||
|
#
|
||||||
|
# ULP support additions to component CMakeLists.txt.
|
||||||
|
#
|
||||||
|
# 1. The ULP app name must be unique (if multiple components use ULP).
|
||||||
|
set(ulp_app_name ulp_${COMPONENT_NAME})
|
||||||
|
#
|
||||||
|
# 2. Specify all C and Assembly source files.
|
||||||
|
# Files should be placed into a separate directory (in this case, ulp/),
|
||||||
|
# which should not be added to COMPONENT_SRCS.
|
||||||
|
set(ulp_riscv_sources "ulp/main.c")
|
||||||
|
|
||||||
|
#
|
||||||
|
# 3. List all the component source files which include automatically
|
||||||
|
# generated ULP export file, ${ulp_app_name}.h:
|
||||||
|
set(ulp_exp_dep_srcs "lp_core_gpio_wake_up_example_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_riscv_sources}" "${ulp_exp_dep_srcs}")
|
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
/* ULP LP-Core GPIO wake-up example
|
||||||
|
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "esp_sleep.h"
|
||||||
|
#include "driver/rtc_io.h"
|
||||||
|
#include "ulp_lp_core.h"
|
||||||
|
#include "ulp_main.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
#define WAKEUP_PIN 2
|
||||||
|
|
||||||
|
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
|
||||||
|
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
|
||||||
|
|
||||||
|
static void init_ulp_program(void);
|
||||||
|
|
||||||
|
static void wakeup_gpio_init(void)
|
||||||
|
{
|
||||||
|
/* Configure the button GPIO as input, enable wakeup */
|
||||||
|
rtc_gpio_init(WAKEUP_PIN);
|
||||||
|
rtc_gpio_set_direction(WAKEUP_PIN, RTC_GPIO_MODE_INPUT_ONLY);
|
||||||
|
rtc_gpio_pulldown_dis(WAKEUP_PIN);
|
||||||
|
rtc_gpio_pullup_en(WAKEUP_PIN);
|
||||||
|
rtc_gpio_wakeup_enable(WAKEUP_PIN, GPIO_INTR_LOW_LEVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
|
||||||
|
wakeup_gpio_init();
|
||||||
|
|
||||||
|
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||||
|
/* not a wakeup from ULP, load the firmware */
|
||||||
|
if (cause != ESP_SLEEP_WAKEUP_ULP) {
|
||||||
|
printf("Not a ULP wakeup, initializing it! \n");
|
||||||
|
init_ulp_program();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ULP read and detected a change in WAKEUP_PIN, prints */
|
||||||
|
if (cause == ESP_SLEEP_WAKEUP_ULP) {
|
||||||
|
printf("ULP woke up the main CPU! \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go back to sleep, only the ULP will run */
|
||||||
|
printf("Entering deep sleep\n\n");
|
||||||
|
|
||||||
|
/* Small delay to ensure the messages are printed */
|
||||||
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup());
|
||||||
|
|
||||||
|
esp_deep_sleep_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_ulp_program(void)
|
||||||
|
{
|
||||||
|
esp_err_t err = ulp_lp_core_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start));
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
|
/* Start the program */
|
||||||
|
ulp_lp_core_cfg_t cfg = {
|
||||||
|
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_IO,
|
||||||
|
};
|
||||||
|
|
||||||
|
err = ulp_lp_core_run(&cfg);
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
}
|
23
examples/system/ulp/lp_core/gpio_wakeup/main/ulp/main.c
Normal file
23
examples/system/ulp/lp_core/gpio_wakeup/main/ulp/main.c
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "ulp_lp_core.h"
|
||||||
|
#include "ulp_lp_core_utils.h"
|
||||||
|
#include "ulp_lp_core_gpio.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
ulp_lp_core_wakeup_main_processor();
|
||||||
|
|
||||||
|
/* Wakeup interrupt is a level interrupt, wait 1 sec to
|
||||||
|
allow user to release button to avoid waking up the ULP multiple times */
|
||||||
|
ulp_lp_core_delay_us(1000*1000);
|
||||||
|
ulp_lp_core_gpio_clear_intr_status();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
# Enable ULP
|
||||||
|
CONFIG_ULP_COPROC_ENABLED=y
|
||||||
|
CONFIG_ULP_COPROC_TYPE_LP_CORE=y
|
||||||
|
CONFIG_ULP_COPROC_RESERVE_MEM=8128
|
||||||
|
# Set log level to Warning to produce clean output
|
||||||
|
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
|
||||||
|
CONFIG_BOOTLOADER_LOG_LEVEL=2
|
||||||
|
CONFIG_LOG_DEFAULT_LEVEL_WARN=y
|
||||||
|
CONFIG_LOG_DEFAULT_LEVEL=2
|
Reference in New Issue
Block a user