Skip to content

Commit e87c43b

Browse files
thiagofinelonacassis
authored andcommitted
arch/xtensa/esp32s3: Add EXT1 wakeup support in power management
Introduce EXT1 wakeup functionality to the ESP32-S3 power management subsystem. With this feature, the ESP32-S3 can wake up from PM_STANDBY or PM_SLEEP when one or more RTC GPIOs trigger the EXT1 condition. Changes include: - Added EXT1 wakeup configuration and preparation logic in rtc code. - Integrated EXT1 handling in pmstandby() and pmsleep(). - New board-level Kconfig options under ESP32-S3 DevKit menu: - CONFIG_PM_EXT1_WAKEUP: enable EXT1 wakeup support - CONFIG_PM_EXT1_WAKEUP_RTC_GPIO<n>: select RTC GPIOs as wake sources - CONFIG_PM_EXT1_WAKEUP_TRIGGER_MODE: choose wakeup on HIGH or LOW level - Fixing Kconfig style - Fixing comments standard - Adding PM documentation for esp32s3-devkit Impact: - No build impact unless CONFIG_PM_EXT1_WAKEUP is enabled. - When enabled, ESP32-S3 can wake from low-power states via RTC GPIOs. - No new public API introduced; controlled via board Kconfig. Tested on ESP32-S3 DevKit: - Configured GPIO4 and GPIO5 as EXT1 wake sources. - Verified wakeup from light sleep and deep sleep on external signals. - Wakeup reason correctly reported as EXT1. Signed-off-by: Thiago Finelon <thiago.sfinelon@gmail.com>
1 parent 67d0b97 commit e87c43b

File tree

6 files changed

+341
-0
lines changed

6 files changed

+341
-0
lines changed

Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/index.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,16 @@ Enables PM support. You can define standby mode and sleep mode delay time::
637637
(20) PM_SLEEP delay (seconds)
638638
(0) PM_SLEEP delay (nanoseconds)
639639

640+
You can also define an EXT1 wakeup for both sleep modes by selecting which RTC
641+
GPIO will be used and the logic level that will trigger it::
642+
643+
$ make menuconfig
644+
-> Board Selection
645+
-> [*] PM EXT1 Wakeup
646+
PM EXT1 Wakeup Sources --->
647+
[ ] RTC_GPIO<N>
648+
(0) PM EXT1 Wakeup Trigger Mode
649+
640650
Before switching PM status, you need to query the current PM status::
641651

642652
nsh> pmconfig

Documentation/platforms/xtensa/esp32s3/index.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,18 @@ using WPA2.
610610

611611
The ``dhcpd_start`` is necessary to let your board to associate an IP to your smartphone.
612612

613+
Power Management
614+
================
615+
616+
.. tip:: Boards usually expose a pm defconfig which enables power management
617+
features. On ESP32-S3, different low power modes can be used to reduce power
618+
consumption depending on the application.
619+
620+
When using this board configuration profile, two wakeup sources are available:
621+
622+
- Timer (mandatory) : Every time the board enters sleep mode, a timer is started. Once the defined time is reached, the board wakes up.
623+
- EXT1 (optional): The board wakes up whenever the selected EXT1 GPIO is asserted to the configured level.
624+
613625
PSRAM
614626
-----
615627

arch/xtensa/src/esp32s3/esp32s3_pm.c

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "hardware/esp32s3_gpio.h"
5050

5151
#include "esp32s3_rtc.h"
52+
#include "esp32s3_rtc_gpio.h"
5253
#include "esp32s3_pm.h"
5354

5455
#include "soc/periph_defs.h"
@@ -91,6 +92,8 @@
9192
#define RTC_VDDSDIO_TIEH_1_8V 0 /* TIEH field value for 1.8V VDDSDIO */
9293
#define RTC_VDDSDIO_TIEH_3_3V 1 /* TIEH field value for 3.3V VDDSDIO */
9394

95+
#define RTC_EXT0_TRIG_EN BIT(0) /* External wakeup source 0 */
96+
#define RTC_EXT1_TRIG_EN BIT(1) /* External wakeup source 1 */
9497
#define RTC_GPIO_TRIG_EN BIT(2) /* GPIO wakeup */
9598
#define RTC_TIMER_TRIG_EN BIT(3) /* Timer wakeup */
9699
#define RTC_WIFI_TRIG_EN BIT(5) /* Wi-Fi wakeup (light sleep only) */
@@ -429,6 +432,40 @@ static uint32_t IRAM_ATTR esp32s3_get_power_down_flags(void)
429432
return pd_flags;
430433
}
431434

435+
/****************************************************************************
436+
* Name: esp32s3_ext1_wakeup_prepare
437+
*
438+
* Description:
439+
* Configure gpio to wake-up
440+
*
441+
* Input Parameters:
442+
* None
443+
*
444+
* Returned Value:
445+
* None
446+
*
447+
****************************************************************************/
448+
449+
static void IRAM_ATTR esp32s3_ext1_wakeup_prepare(void)
450+
{
451+
static bool ext1_rtc_gpio_mask_configured = false;
452+
if (ext1_rtc_gpio_mask_configured == false)
453+
{
454+
for (int i = 0; i < RTC_GPIO_NUMBER; i++)
455+
{
456+
if (g_config.ext1_rtc_gpio_mask & BIT(i))
457+
{
458+
esp32s3_configrtcio(i, RTC_INPUT_FUNCTION_RTCIO);
459+
}
460+
}
461+
462+
ext1_rtc_gpio_mask_configured = true;
463+
}
464+
465+
esp32s3_rtc_ext1_prepare(g_config.ext1_trigger_mode,
466+
g_config.ext1_rtc_gpio_mask);
467+
}
468+
432469
/****************************************************************************
433470
* Name: esp32s3_timer_wakeup_prepare
434471
*
@@ -596,6 +633,11 @@ static int IRAM_ATTR esp32s3_sleep_start(uint32_t pd_flags)
596633
esp32s3_timer_wakeup_prepare();
597634
}
598635

636+
if (g_config.wakeup_triggers & RTC_EXT1_TRIG_EN)
637+
{
638+
esp32s3_ext1_wakeup_prepare();
639+
}
640+
599641
result = esp32s3_rtc_sleep_start(g_config.wakeup_triggers, 0);
600642

601643
/* Restore CPU frequency */
@@ -865,6 +907,94 @@ void IRAM_ATTR esp32s3_periph_inform_out_sleep_overhead(uint32_t us)
865907
}
866908
}
867909

910+
/****************************************************************************
911+
* Name: esp32s3_sleep_enable_ext1_wakeup
912+
*
913+
* Description:
914+
* Enable wakeup by ext1 gpio
915+
*
916+
* Input Parameters:
917+
* None
918+
*
919+
* Returned Value:
920+
* None
921+
*
922+
****************************************************************************/
923+
924+
void IRAM_ATTR esp32s3_sleep_enable_ext1_wakeup(void)
925+
{
926+
g_config.wakeup_triggers |= RTC_EXT1_TRIG_EN;
927+
928+
#ifdef CONFIG_PM_EXT1_WAKEUP_TRIGGER_MODE
929+
g_config.ext1_trigger_mode = CONFIG_PM_EXT1_WAKEUP_TRIGGER_MODE;
930+
#endif
931+
932+
g_config.ext1_rtc_gpio_mask = 0U;
933+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO0
934+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_0_GPIO_NUM);
935+
#endif
936+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO1
937+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_1_GPIO_NUM);
938+
#endif
939+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO2
940+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_2_GPIO_NUM);
941+
#endif
942+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO3
943+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_3_GPIO_NUM);
944+
#endif
945+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO4
946+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_4_GPIO_NUM);
947+
#endif
948+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO5
949+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_5_GPIO_NUM);
950+
#endif
951+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO6
952+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_6_GPIO_NUM);
953+
#endif
954+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO7
955+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_7_GPIO_NUM);
956+
#endif
957+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO8
958+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_8_GPIO_NUM);
959+
#endif
960+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO9
961+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_9_GPIO_NUM);
962+
#endif
963+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO10
964+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_10_GPIO_NUM);
965+
#endif
966+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO11
967+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_11_GPIO_NUM);
968+
#endif
969+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO12
970+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_12_GPIO_NUM);
971+
#endif
972+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO13
973+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_13_GPIO_NUM);
974+
#endif
975+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO14
976+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_14_GPIO_NUM);
977+
#endif
978+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO15
979+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_15_GPIO_NUM);
980+
#endif
981+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO16
982+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_16_GPIO_NUM);
983+
#endif
984+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO17
985+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_17_GPIO_NUM);
986+
#endif
987+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO18
988+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_18_GPIO_NUM);
989+
#endif
990+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO19
991+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_19_GPIO_NUM);
992+
#endif
993+
#ifdef CONFIG_PM_EXT1_WAKEUP_RTC_GPIO20
994+
g_config.ext1_rtc_gpio_mask |= BIT(RTCIO_CHANNEL_20_GPIO_NUM);
995+
#endif
996+
}
997+
868998
/****************************************************************************
869999
* Name: esp32s3_sleep_enable_timer_wakeup
8701000
*
@@ -1025,6 +1155,10 @@ void esp32s3_pmstandby(uint64_t time_in_us)
10251155
{
10261156
uint64_t rtc_diff_us;
10271157

1158+
#ifdef CONFIG_PM_EXT1_WAKEUP
1159+
esp32s3_sleep_enable_ext1_wakeup();
1160+
#endif
1161+
10281162
/* Don't power down XTAL - powering it up takes different time on. */
10291163

10301164
esp32s3_sleep_enable_timer_wakeup(time_in_us);
@@ -1094,6 +1228,10 @@ void IRAM_ATTR esp32s3_deep_sleep_start(void)
10941228

10951229
void esp32s3_pmsleep(uint64_t time_in_us)
10961230
{
1231+
#ifdef CONFIG_PM_EXT1_WAKEUP
1232+
esp32s3_sleep_enable_ext1_wakeup();
1233+
#endif
1234+
10971235
esp32s3_sleep_enable_timer_wakeup(time_in_us);
10981236
esp32s3_deep_sleep_start();
10991237
}

arch/xtensa/src/esp32s3/esp32s3_rtc.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,6 +2431,18 @@ int IRAM_ATTR esp32s3_rtc_sleep_start(uint32_t wakeup_opt,
24312431
return reject;
24322432
}
24332433

2434+
void esp32s3_rtc_ext1_prepare(uint32_t trigger_mode, uint32_t rtc_gpio_mask)
2435+
{
2436+
if (rtc_gpio_mask > 0)
2437+
{
2438+
modifyreg32(RTC_CNTL_RTC_EXT_WAKEUP1_REG, 0 ,
2439+
RTC_CNTL_EXT_WAKEUP1_STATUS_CLR | rtc_gpio_mask);
2440+
modifyreg32(RTC_CNTL_RTC_EXT_WAKEUP_CONF_REG, 0,
2441+
(trigger_mode << RTC_CNTL_EXT_WAKEUP1_LV_S) | \
2442+
RTC_CNTL_GPIO_WAKEUP_FILTER);
2443+
}
2444+
}
2445+
24342446
/****************************************************************************
24352447
* Name: esp32s3_rtc_clk_cpu_freq_set_config
24362448
*

arch/xtensa/src/esp32s3/esp32s3_rtc.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,23 @@ int esp_rtc_clk_get_cpu_freq(void);
514514

515515
void esp32s3_rtc_sleep_init(uint32_t flags);
516516

517+
/****************************************************************************
518+
* Name: esp32s3_rtc_ext1_prepare
519+
*
520+
* Description:
521+
* Configure RTC_EXT1 wakeup sources
522+
*
523+
* Input Parameters:
524+
* trigger_mode - trigger mode for RTC_EXT1 wakeup sources
525+
* rtc_gpio_mask - mask of GPIOs to be used as RTC_EXT1 wakeup sources
526+
*
527+
* Returned Value:
528+
* None
529+
*
530+
****************************************************************************/
531+
532+
void esp32s3_rtc_ext1_prepare(uint32_t trigger_mode, uint32_t rtc_gpio_mask);
533+
517534
/****************************************************************************
518535
* Name: esp32s3_rtc_sleep_start
519536
*

0 commit comments

Comments
 (0)