mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
Merge branch 'feature/lp_core_gpio_wakeup' into 'master'
feat(lp_core): added support for LP-IO as LP-core wakeup source Closes IDF-10200 See merge request espressif/esp-idf!31828
This commit is contained in:
commit
1f1954378e
@ -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].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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,7 +133,7 @@ esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg)
|
||||
}
|
||||
#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");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
@ -293,6 +293,12 @@ examples/system/ulp/lp_core/gpio_intr_pulse_counter:
|
||||
depends_components:
|
||||
- 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/:
|
||||
enable:
|
||||
- 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
|
Loading…
x
Reference in New Issue
Block a user