arch/risc-v/espressif: Add ULP wakeup modes

Add ULP wakeup modes for esp32[-c6|-p4]

Signed-off-by: Eren Terzioglu <eren.terzioglu@espressif.com>
This commit is contained in:
Eren Terzioglu
2026-04-15 18:18:44 +02:00
committed by simbit18
parent 5e29129d97
commit ac26b63556
3 changed files with 533 additions and 4 deletions
+265
View File
@@ -643,6 +643,271 @@ config ESPRESSIF_ULP_ENABLE_UBSAN
But note that it will increase code size significantly and it can happen that
application will not fit into RTC RAM
choice ESPRESSIF_ULP_WAKEUP_SOURCE
prompt "LP Coprocessor wakeup source"
default ESPRESSIF_ULP_WAKEUP_HP_CPU
config ESPRESSIF_ULP_WAKEUP_HP_CPU
bool "Wakeup by HP core"
config ESPRESSIF_ULP_WAKEUP_LP_UART
depends on ESPRESSIF_LP_UART
bool "Wakeup by LP UART RX"
config ESPRESSIF_ULP_WAKEUP_LP_IO
bool "Wakeup by LP IO interrupt"
config ESPRESSIF_ULP_WAKEUP_LP_TIMER
bool "Wakeup by LP timer"
endchoice # ESPRESSIF_ULP_WAKEUP_SOURCE
menu "ULP Wakeup LP IO Sources"
depends on ESPRESSIF_ULP_WAKEUP_LP_IO
menu "GPIOs to wakeup ULP when low"
config ESPRESSIF_ULP_WAKEUP_LP_IO0_LOW
bool "LP_IO0"
default n
---help---
Wakeup ULP when LP_GPIO0 is low.
config ESPRESSIF_ULP_WAKEUP_LP_IO1_LOW
bool "LP_IO1"
default n
---help---
Wakeup ULP when LP_GPIO1 is low.
config ESPRESSIF_ULP_WAKEUP_LP_IO2_LOW
bool "LP_IO2"
default n
---help---
Wakeup ULP when LP_GPIO2 is low.
config ESPRESSIF_ULP_WAKEUP_LP_IO3_LOW
bool "LP_IO3"
default n
---help---
Wakeup ULP when LP_GPIO3 is low.
config ESPRESSIF_ULP_WAKEUP_LP_IO4_LOW
bool "LP_IO4"
default n
---help---
Wakeup ULP when LP_GPIO4 is low.
config ESPRESSIF_ULP_WAKEUP_LP_IO5_LOW
bool "LP_IO5"
default n
---help---
Wakeup ULP when LP_GPIO5 is low.
config ESPRESSIF_ULP_WAKEUP_LP_IO6_LOW
bool "LP_IO6"
default n
---help---
Wakeup ULP when LP_GPIO6 is low.
config ESPRESSIF_ULP_WAKEUP_LP_IO7_LOW
bool "LP_IO7"
default n
---help---
Wakeup ULP when LP_GPIO7 is low.
config ESPRESSIF_ULP_WAKEUP_LP_IO8_LOW
bool "LP_IO8"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO8 is low
config ESPRESSIF_ULP_WAKEUP_LP_IO9_LOW
bool "LP_IO9"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO9 is low
config ESPRESSIF_ULP_WAKEUP_LP_IO10_LOW
bool "LP_IO10"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO10 is low
config ESPRESSIF_ULP_WAKEUP_LP_IO11_LOW
bool "LP_IO11"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO11 is low
config ESPRESSIF_ULP_WAKEUP_LP_IO12_LOW
bool "LP_IO12"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO12 is low
config ESPRESSIF_ULP_WAKEUP_LP_IO13_LOW
bool "LP_IO13"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO13 is low
config ESPRESSIF_ULP_WAKEUP_LP_IO14_LOW
bool "LP_IO14"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO14 is low
endmenu # GPIOs to wakeup ULP when low
menu "GPIOs to wakeup ULP when high"
config ESPRESSIF_ULP_WAKEUP_LP_IO0_HIGH
bool "LP_IO0"
default n
---help---
Wakeup ULP when LP_GPIO0 is high.
config ESPRESSIF_ULP_WAKEUP_LP_IO1_HIGH
bool "LP_IO1"
default n
---help---
Wakeup ULP when LP_GPIO1 is high.
config ESPRESSIF_ULP_WAKEUP_LP_IO2_HIGH
bool "LP_IO2"
default n
---help---
Wakeup ULP when LP_GPIO2 is high.
config ESPRESSIF_ULP_WAKEUP_LP_IO3_HIGH
bool "LP_IO3"
default n
---help---
Wakeup ULP when LP_GPIO3 is high.
config ESPRESSIF_ULP_WAKEUP_LP_IO4_HIGH
bool "LP_IO4"
default n
---help---
Wakeup ULP when LP_GPIO4 is high.
config ESPRESSIF_ULP_WAKEUP_LP_IO5_HIGH
bool "LP_IO5"
default n
---help---
Wakeup ULP when LP_GPIO5 is high.
config ESPRESSIF_ULP_WAKEUP_LP_IO6_HIGH
bool "LP_IO6"
default n
---help---
Wakeup ULP when LP_GPIO6 is high.
config ESPRESSIF_ULP_WAKEUP_LP_IO7_HIGH
bool "LP_IO7"
default n
---help---
Wakeup ULP when LP_GPIO7 is high.
config ESPRESSIF_ULP_WAKEUP_LP_IO8_HIGH
bool "LP_IO8"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO8 is high
config ESPRESSIF_ULP_WAKEUP_LP_IO9_HIGH
bool "LP_IO9"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO9 is high
config ESPRESSIF_ULP_WAKEUP_LP_IO10_HIGH
bool "LP_IO10"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO10 is high
config ESPRESSIF_ULP_WAKEUP_LP_IO11_HIGH
bool "LP_IO11"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO11 is high
config ESPRESSIF_ULP_WAKEUP_LP_IO12_HIGH
bool "LP_IO12"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO12 is high
config ESPRESSIF_ULP_WAKEUP_LP_IO13_HIGH
bool "LP_IO13"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO13 is high
config ESPRESSIF_ULP_WAKEUP_LP_IO14_HIGH
bool "LP_IO14"
default n
depends on ARCH_CHIP_ESP32P4
---help---
Wakeup ULP when LP_GPIO14 is high
endmenu # GPIOs to wakeup ULP when high
endmenu # ULP Wakeup LP IO Sources
config ESPRESSIF_ULP_WAKEUP_SLEEP_DURATION_US
int "Sleep duration of LP Coprocessor in us"
depends on ESPRESSIF_ULP_WAKEUP_LP_TIMER
default 1000000
choice ESPRESSIF_ULP_WAKEUP_LPUART_MODE
prompt "LP Coprocessor UART Wakeup Mode"
depends on ESPRESSIF_ULP_WAKEUP_LP_UART
default ESPRESSIF_ULP_WAKEUP_LPUART_START_BIT_MODE
config ESPRESSIF_ULP_WAKEUP_LPUART_ACTIVE_EDGE_THRESHOLD_MODE
bool "Wake-up triggered by active edge threshold"
config ESPRESSIF_ULP_WAKEUP_LPUART_FIFO_THRESHOLD_MODE
bool "Wake-up triggered by the number of bytes received in the RX FIFO"
config ESPRESSIF_ULP_WAKEUP_LPUART_START_BIT_MODE
bool "Wake-up triggered by the detection of a start bit"
config ESPRESSIF_ULP_WAKEUP_LPUART_CHAR_SEQ_MODE
bool "Wake-up triggered by detecting a specific character sequence"
endchoice # ESPRESSIF_ULP_WAKEUP_LPUART_MODE
config ESPRESSIF_ULP_WAKEUP_LPUART_ACTIVE_EDGE_THRESHOLD
int "Number of RXD edge changes to to trigger wake-up"
depends on ESPRESSIF_ULP_WAKEUP_LPUART_ACTIVE_EDGE_THRESHOLD_MODE
default 3
config ESPRESSIF_ULP_WAKEUP_LPUART_FIFO_THRESHOLD
int "Number of bytes needed to receive in the RX FIFO to trigger wake-up"
depends on ESPRESSIF_ULP_WAKEUP_LPUART_FIFO_THRESHOLD_MODE
default 8
config ESPRESSIF_ULP_WAKEUP_LPUART_CHAR_SEQ
string "Character sequence to trigger wake-up"
depends on ESPRESSIF_ULP_WAKEUP_LPUART_CHAR_SEQ_MODE
default "esp"
endmenu # LP Core (Low-power core) Coprocessor Configuration
menu "PM Configuration"
+264 -2
View File
@@ -32,6 +32,11 @@
#include "ulp_lp_core.h"
#include "ulp/ulp_var_map.h"
#include "esp_ulp.h"
#include "driver/rtc_io.h"
#include "ulp_lp_core_lp_uart_shared.h"
#include "hal/uart_ll.h"
/****************************************************************************
* Pre-processor Definitions
@@ -65,7 +70,20 @@ static const struct file_operations g_esp_ulp_fops =
ulp_lp_core_cfg_t cfg =
{
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_HP_CPU
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_TIMER
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER,
.lp_timer_sleep_duration_us =
CONFIG_ESPRESSIF_ULP_WAKEUP_SLEEP_DURATION_US,
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_IO,
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_UART
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_UART,
#endif
};
/****************************************************************************
@@ -76,6 +94,231 @@ ulp_lp_core_cfg_t cfg =
* Private Functions
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_UART
/****************************************************************************
* Name: esp_ulp_wakeup_lpuart_init
*
* Description:
* Configure LPUART to use as ULP wakeup source.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success, or -1 (ERROR) in case of failure.
*
****************************************************************************/
static int esp_ulp_wakeup_lpuart_init(void)
{
uart_wakeup_cfg_t wake_up_cfg =
{
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LPUART_ACTIVE_EDGE_THRESHOLD_MODE
.wakeup_mode = UART_WK_MODE_ACTIVE_THRESH,
.rx_edge_threshold =
CONFIG_ESPRESSIF_ULP_WAKEUP_LPUART_ACTIVE_EDGE_THRESHOLD
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LPUART_FIFO_THRESHOLD_MODE
.wakeup_mode = UART_WK_MODE_FIFO_THRESH,
.rx_fifo_threshold = CONFIG_ESPRESSIF_ULP_WAKEUP_LPUART_FIFO_THRESHOLD
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LPUART_START_BIT_MODE
.wakeup_mode = UART_WK_MODE_START_BIT,
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LPUART_CHAR_SEQ_MODE
.wakeup_mode = UART_WK_MODE_CHAR_SEQ,
.wake_chars_seq = CONFIG_ESPRESSIF_ULP_WAKEUP_LPUART_CHAR_SEQ
#endif
};
return uart_wakeup_setup(LP_UART_NUM_0, &wake_up_cfg);
}
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO
/****************************************************************************
* Name: esp_ulp_get_high_io_mask
*
* Description:
* Get ULP wakeup high IO mask value from configured wakeup pins.
*
* Input Parameters:
* None
*
* Returned Value:
* A 64-bit unsigned integer where each bit corresponds to an RTC GPIO pin
* that has been configured high as an ULP wakeup source.
*
****************************************************************************/
static uint64_t esp_ulp_get_high_io_mask(void)
{
uint64_t io_mask = 0;
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO0_HIGH
io_mask |= BIT(0);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO1_HIGH
io_mask |= BIT(1);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO2_HIGH
io_mask |= BIT(2);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO3_HIGH
io_mask |= BIT(3);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO4_HIGH
io_mask |= BIT(4);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO5_HIGH
io_mask |= BIT(5);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO6_HIGH
io_mask |= BIT(6);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO7_HIGH
io_mask |= BIT(7);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO8_HIGH
io_mask |= BIT(8);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO9_HIGH
io_mask |= BIT(9);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO10_HIGH
io_mask |= BIT(10);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO11_HIGH
io_mask |= BIT(11);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO12_HIGH
io_mask |= BIT(12);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO13_HIGH
io_mask |= BIT(13);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO14_HIGH
io_mask |= BIT(14);
#endif
return io_mask;
}
/****************************************************************************
* Name: esp_ulp_get_low_io_mask
*
* Description:
* Get ULP wakeup low IO mask value from configured wakeup pins.
*
* Input Parameters:
* None
*
* Returned Value:
* A 64-bit unsigned integer where each bit corresponds to an RTC GPIO pin
* that has been configured low as an ULP wakeup source.
*
****************************************************************************/
static uint64_t esp_ulp_get_low_io_mask(void)
{
uint64_t io_mask = 0;
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO0_LOW
io_mask |= BIT(0);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO1_LOW
io_mask |= BIT(1);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO2_LOW
io_mask |= BIT(2);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO3_LOW
io_mask |= BIT(3);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO4_LOW
io_mask |= BIT(4);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO5_LOW
io_mask |= BIT(5);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO6_LOW
io_mask |= BIT(6);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO7_LOW
io_mask |= BIT(7);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO8_LOW
io_mask |= BIT(8);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO9_LOW
io_mask |= BIT(9);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO10_LOW
io_mask |= BIT(10);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO11_LOW
io_mask |= BIT(11);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO12_LOW
io_mask |= BIT(12);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO13_LOW
io_mask |= BIT(13);
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO14_LOW
io_mask |= BIT(14);
#endif
return io_mask;
}
/****************************************************************************
* Name: esp_ulp_wakeup_io_init
*
* Description:
* Configure GPIO to use as ULP wakeup source.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success, or -1 (ERROR) in case of failure.
*
****************************************************************************/
static int esp_ulp_wakeup_io_init(void)
{
int ret = OK;
int pin_mask;
gpio_int_type_t wake_up_type;
uint64_t io_mask_low = esp_ulp_get_low_io_mask();
uint64_t io_mask_high = esp_ulp_get_high_io_mask();
for (int i = 0; i < CONFIG_SOC_RTCIO_PIN_COUNT; i++)
{
pin_mask = BIT(i);
if ((io_mask_low & pin_mask) != 0 ||
(io_mask_high & pin_mask) != 0)
{
ret = esp_rtcio_config_gpio(i, ESP_RTC_GPIO_MODE_INPUT_OUTPUT);
if (ret != OK)
{
ferr("Failed to configure pin: %d\n", i);
return ret;
}
wake_up_type = GPIO_INTR_HIGH_LEVEL;
if ((io_mask_low & pin_mask) != 0)
{
wake_up_type = GPIO_INTR_LOW_LEVEL;
}
rtc_gpio_wakeup_enable(i, wake_up_type);
}
}
return OK;
}
#endif
/****************************************************************************
* Name: esp_ulp_ioctl
*
@@ -220,11 +463,30 @@ int esp_ulp_load_bin(const char *buffer, size_t buflen)
* None
*
* Returned Value:
* None
* Returns OK on success; a negated errno value on failure
*
****************************************************************************/
void esp_ulp_init(void)
int esp_ulp_init(void)
{
int ret = OK;
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_IO
ret = esp_ulp_wakeup_io_init();
if (ret != OK)
{
return ret;
}
#endif
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_LP_UART
esp_ulp_wakeup_lpuart_init();
if (ret != OK)
{
ferr("Failed to LP UART wakeup\n");
return ret;
}
#endif
esp_ulp_register();
return ret;
}
+4 -2
View File
@@ -30,6 +30,8 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include "espressif/esp_rtc_gpio.h"
#ifndef __ASSEMBLY__
#undef EXTERN
@@ -72,11 +74,11 @@ int esp_ulp_load_bin(const char *buffer, size_t buflen);
* None
*
* Returned Value:
* None
* Returns OK on success; a negated errno value on failure
*
****************************************************************************/
void esp_ulp_init(void);
int esp_ulp_init(void);
#ifdef __cplusplus
}