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 But note that it will increase code size significantly and it can happen that
application will not fit into RTC RAM 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 endmenu # LP Core (Low-power core) Coprocessor Configuration
menu "PM Configuration" menu "PM Configuration"
+264 -2
View File
@@ -32,6 +32,11 @@
#include "ulp_lp_core.h" #include "ulp_lp_core.h"
#include "ulp/ulp_var_map.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 * Pre-processor Definitions
@@ -65,7 +70,20 @@ static const struct file_operations g_esp_ulp_fops =
ulp_lp_core_cfg_t cfg = ulp_lp_core_cfg_t cfg =
{ {
#ifdef CONFIG_ESPRESSIF_ULP_WAKEUP_HP_CPU
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_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 * 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 * Name: esp_ulp_ioctl
* *
@@ -220,11 +463,30 @@ int esp_ulp_load_bin(const char *buffer, size_t buflen)
* None * None
* *
* Returned Value: * 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(); esp_ulp_register();
return ret;
} }
+4 -2
View File
@@ -30,6 +30,8 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <sys/types.h> #include <sys/types.h>
#include "espressif/esp_rtc_gpio.h"
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#undef EXTERN #undef EXTERN
@@ -72,11 +74,11 @@ int esp_ulp_load_bin(const char *buffer, size_t buflen);
* None * None
* *
* Returned Value: * 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 #ifdef __cplusplus
} }