Skip to content

Commit e3383f0

Browse files
committed
feat(example): support esp32p4 VBAT under volt wakeup in deepsleep example
1 parent 9b5944b commit e3383f0

10 files changed

+239
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
2+
3+
examples/lowpower/vbat:
4+
enable:
5+
- if: SOC_VBAT_SUPPORTED == 1
6+
disable_test:
7+
- if: IDF_TARGET in ["esp32h2"]
8+
temporary: true
9+
reason: not supported yet

examples/lowpower/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
2+
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
3+
4+
# System Examples
5+
6+
Configuration and management of ESP chips lowpower related features.
7+
8+
See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples.

examples/lowpower/vbat/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# The following lines of boilerplate have to be in your project's CMakeLists
2+
# in this exact order for cmake to work correctly
3+
cmake_minimum_required(VERSION 3.16)
4+
5+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
6+
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
7+
idf_build_set_property(MINIMAL_BUILD ON)
8+
project(vbat)

examples/lowpower/vbat/README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
| Supported Targets | ESP32-H2 | ESP32-P4 |
2+
| ----------------- | -------- | -------- |
3+
4+
# VBAT Example
5+
6+
(See the README.md file in the upper level 'examples' directory for more information about examples.)
7+
8+
When the application is idle and the chip enters deepsleep, you may want to turn off the main power to save power (because the main power usually also drives other power-consuming devices on the board), but you also want the ESP chip to maintain the RTC timing and wake-up functions. Or you want to enter deepsleep mode that only maintains RTC timing but with another power supply when the main power is about to undervoltage. In these cases, you can use this feature, which allows the chip to switch to backup battery power when entering deepsleep.
9+
10+
This example demonstrates the ESP backup battery power supply solution, which has the following features:
11+
12+
- Supports using backup power (VBAT) during deepsleep, and RTC Timer can keep timing after the main power is lost.
13+
- Supports automatic power switching by PMU during sleep/wake-up, automatically switches to backup power supply when entering sleep mode and switches to main power supply when waking up.
14+
- Support battery voltage detection, wake up the chip and switch to the main power supply when undervoltage occurs.
15+
- Support battery charging, automatically stop charging when threshold voltage is reached, and charging current can be configured.
16+
- Supports selection of chip status when charging the battery, options include keep active, entering lightsleep or entering deepsleep.
17+
18+
## How to use example
19+
20+
### Hardware Required
21+
22+
This example should be run on a development board with a backup battery. Currently the following development boards are supported:
23+
- [ESP32-P4-Function-EV-Board Rev](https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html#esp32-p4-function-ev-board)
24+
25+
```
26+
0(%1)NC ┌──────────┐
27+
BAT ─────^^^^─────┐ │ │
28+
│ │ │
29+
│ │ ESP32-P4 │
30+
│ │ │
31+
ESP_3V3 ─────^^^^─────┴────┤VBAT │
32+
0(%1) └──────────┘
33+
```
34+
35+
By default, the ESP_VBAT power supply on this development board is shorted to ESP_3V3 through a 0 Ω resistor.
36+
37+
**You need to re-solder the resistor 0 Ω on ESP_3V3 to the empty pad on BAT. (You can find the resistor position on the schematic doc of the development board). Then connect `RTC_Battery +` to the positive terminal of the battery and `RTC_Battery -` to the negative terminal of the battery.**
38+
39+
### Configure the project
40+
41+
```
42+
idf.py menuconfig
43+
```
44+
45+
- If you are using a non-rechargeable battery, VBAT brownout wakeup can be enabled via `Component config → Hardware Settings → Power Supplier → RTC Backup Battery`.
46+
- If you are using a rechargeable battery, the automatic wake-up charging feature can be enabled via `Component config → Hardware Settings → Power Supplier → RTC Backup Battery -> The battery for RTC battery is a rechargeable battery`.
47+
- The charging current limiting resistor can be configured via `Component config → Hardware Settings → Power Supplier → RTC Backup Battery -> vbat charger circuit resistor value (ohms)`.
48+
- The chip state while waiting for battery charging the battery can be selected by `Example Configuration → Configure the chip state while waiting for battery charging`.
49+
- The period to check whether the battery has been charged done can be selected by `Battery charging done check period (in seconds)`.
50+
51+
### Build and Flash
52+
53+
Build the project and flash it to the board, then run monitor tool to view serial output:
54+
55+
```
56+
idf.py -p PORT flash monitor
57+
```
58+
59+
(Replace PORT with the name of the serial port to use.)
60+
61+
(To exit the serial monitor, type ``Ctrl-]``.)
62+
63+
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
64+
65+
## Example Output
66+
67+
On initial startup, this example will detect that this is the first boot and output the following log:
68+
69+
```
70+
...
71+
I (271) main_task: Started on CPU0
72+
I (281) main_task: Calling app_main()
73+
Not a deep sleep reset
74+
Current RTC Time: 110106 (us)
75+
Entering deep sleep
76+
```
77+
78+
Then the chip will then enter deep sleep, and switch to VBAT power supply.
79+
80+
If non-rechargeable battery is used, nothing will happens when VBAT is undervoltage by default, but if `CONFIG_ESP_VBAT_WAKEUP_CHIP_ON_VBAT_BROWNOUT` is enabled, when the battery voltage drops to the configured brownout threshold `ESP_VBAT_BROWNOUT_DET_LVL_SEL`, the chip will wake up and go to sleep again, but will not switch to VBAT power during deepsleep.
81+
82+
```
83+
W VBAT: RTC battery voltage low, please change battery...
84+
Battery is low, VBAT power will not be used during deep sleep!
85+
Current RTC Time: 18493666 (us)
86+
Entering deep sleep
87+
```
88+
89+
If rechargeable battery is used, when the battery voltage drops to the configured charging threshold (`CONFIG_ESP_VBAT_DET_LVL_LOW_SEL`), the chip will wake up and start charge the battery, when the battery voltage rises to the configured stop charging threshold (`CONFIG_ESP_VBAT_DET_LVL_HIGH_SEL`), the chip will stop charging the battery and re-enter deepsleep, and so on. The following log will be output:
90+
91+
```
92+
...
93+
W VBAT: RTC battery voltage low, start charging...
94+
Wake up from Low power VBAT
95+
Battery is low, waiting for charging to complete before going to sleep!
96+
W VBAT: RTC battery voltage reaches high limit , stop charging...
97+
Current RTC Time: 20753113 (us)
98+
Entering deep sleep
99+
...
100+
```
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
set(srcs "vbat_example_main.c")
2+
set(includes ".")
3+
4+
idf_component_register(SRCS ${srcs}
5+
PRIV_REQUIRES esp_pm
6+
INCLUDE_DIRS ${includes})
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
menu "Example Configuration"
2+
choice EXAMPLE_STATE_WHILE_WAITING_BATTERY_CHARGE_DONE
3+
bool "Configure the chip state while waiting for battery charging"
4+
default EXAMPLE_WAITING_BATTERY_CHARGING_IN_ACTIVE
5+
depends on ESP_VBAT_USE_RECHARGEABLE_BATTERY
6+
help
7+
Select chip state when waiting battery charging done
8+
9+
config EXAMPLE_WAITING_BATTERY_CHARGING_IN_ACTIVE
10+
bool "Waiting for battery charging in active state"
11+
config EXAMPLE_WAITING_BATTERY_CHARGING_IN_LIGHT_SLEEP
12+
bool "Waiting for battery charging in light sleep state"
13+
select PM_ENABLE
14+
select FREERTOS_USE_TICKLESS_IDLE
15+
config EXAMPLE_WAITING_BATTERY_CHARGING_IN_DEEP_SLEEP
16+
bool "Waiting for battery charging in deep sleep state"
17+
endchoice
18+
19+
config EXAMPLE_VBAT_CHARGING_DONE_CHECK_PERIOD
20+
int "Battery charging done check period (in seconds)"
21+
default 60
22+
depends on ESP_VBAT_USE_RECHARGEABLE_BATTERY
23+
help
24+
Period in seconds to check whether the battery has been charged done
25+
26+
endmenu
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Unlicense OR CC0-1.0
5+
*/
6+
7+
#include <stdio.h>
8+
#include <time.h>
9+
#include "sdkconfig.h"
10+
#include "soc/soc_caps.h"
11+
#include "esp_vbat.h"
12+
#include "esp_pm.h"
13+
#include "esp_rtc_time.h"
14+
#include "esp_sleep.h"
15+
16+
void app_main(void)
17+
{
18+
#if CONFIG_EXAMPLE_WAITING_BATTERY_CHARGING_IN_LIGHT_SLEEP
19+
esp_pm_config_t pm_config = {
20+
.max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ,
21+
.min_freq_mhz = CONFIG_XTAL_FREQ,
22+
.light_sleep_enable = true
23+
};
24+
ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
25+
#endif
26+
27+
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_VBAT_UNDER_VOLT) {
28+
#if CONFIG_ESP_VBAT_USE_RECHARGEABLE_BATTERY
29+
printf("Wake up from VBAT low power\n");
30+
#else
31+
printf("Wake up from VBAT brownout\n");
32+
#endif
33+
} else if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_TIMER) {
34+
printf("Wake up from Timer\n");
35+
} else {
36+
printf("Not a deep sleep reset\n");
37+
}
38+
39+
esp_err_t sleep_result;
40+
do {
41+
#if CONFIG_ESP_VBAT_USE_RECHARGEABLE_BATTERY
42+
if (esp_vbat_get_battery_state() == ESP_VBAT_STATE_CHARGING) {
43+
#if CONFIG_EXAMPLE_WAITING_BATTERY_CHARGING_IN_DEEP_SLEEP
44+
printf("Battery is charging, wake up the chip every %d seconds to check whether the battery is charged done !\n", CONFIG_EXAMPLE_VBAT_CHARGING_DONE_CHECK_PERIOD);
45+
esp_sleep_enable_timer_wakeup(CONFIG_EXAMPLE_VBAT_CHARGING_DONE_CHECK_PERIOD * 1000 * 1000);
46+
#else
47+
printf("Battery is low, waiting for charging to complete before going to deep sleep!\n");
48+
do {
49+
// Task will enter block state in `esp_vbat_wait_battery_charge_done`, staying in active state or
50+
// entering lightsleep is determined by esp_pm configuration.
51+
if (esp_vbat_wait_battery_charge_done(CONFIG_EXAMPLE_VBAT_CHARGING_DONE_CHECK_PERIOD * 1000 / portTICK_PERIOD_MS) == ESP_OK) {
52+
printf("Battery charging done!\n");
53+
break;
54+
}
55+
} while (1);
56+
#endif
57+
}
58+
#else
59+
if (esp_vbat_get_battery_state() == ESP_VBAT_STATE_LOWBATTERY) {
60+
printf("Battery is low, VBAT power will not be used during deep sleep!\n");
61+
}
62+
#endif
63+
64+
#if CONFIG_EXAMPLE_WAITING_BATTERY_CHARGING_IN_LIGHT_SLEEP
65+
// Disable auto-lightsleep configured timer wakeup source here.
66+
pm_config.light_sleep_enable = false;
67+
ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
68+
#endif
69+
70+
// enter deep sleep
71+
printf("Current RTC Time: %lld (us)\n", esp_rtc_get_time_us());
72+
printf("Entering deep sleep\n");
73+
sleep_result = esp_deep_sleep_try_to_start();
74+
vTaskDelay(1000 / portTICK_PERIOD_MS);
75+
printf("Failed to enter deepsleep, please check wakeup source setting and state!\n");
76+
} while (sleep_result != ESP_OK);
77+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_ESP_VBAT_USE_RECHARGEABLE_BATTERY=n
2+
CONFIG_ESP_VBAT_WAKEUP_CHIP_ON_VBAT_BROWNOUT=y
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_ESP_VBAT_USE_RECHARGEABLE_BATTERY=y
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Generic config
2+
CONFIG_ESP_VBAT_INIT_AUTO=y

0 commit comments

Comments
 (0)