Skip to content

Commit d816622

Browse files
committed
Merge branch 'feature/vbat_support_on_h2' into 'master'
feat(vbat): Add vbat support on esp32h2 See merge request espressif/esp-idf!36436
2 parents 4f8bf6b + f37de0d commit d816622

File tree

5 files changed

+340
-7
lines changed

5 files changed

+340
-7
lines changed

components/esp_hw_support/power_supply/port/esp32h2/Kconfig.power

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,154 @@ menu "Power Supplier"
6262

6363
endmenu
6464

65+
66+
menu "RTC Backup Battery"
67+
68+
config ESP_VBAT_INIT_AUTO
69+
bool "Enable VBAT power supply for RTC battery"
70+
default n
71+
depends on SOC_VBAT_SUPPORTED
72+
help
73+
Enable this option to allow the use of a button cell battery to power the RTC (Real-Time Clock) domain.
74+
When this option is enabled, the hardware will configure VBAT as the power supply source for the RTC.
75+
76+
- Ensure a compatible battery (2.5V ~ 3.6V) is connected to the VBAT pin.
77+
- The VBAT battery provides power to retain RTC state and keep low-power peripherals active
78+
during deep sleep.
79+
- When this option is disabled, the RTC battery input (VBAT) must not be left floating.
80+
81+
config ESP_VBAT_USE_RECHARGEABLE_BATTERY
82+
bool "The battery for RTC battery is a rechargeable battery"
83+
default n
84+
depends on ESP_VBAT_INIT_AUTO
85+
help
86+
Select this option if the RTC backup battery used in your design is a rechargeable battery.
87+
88+
When enabled, the system will configure the RTC battery management circuitry to operate
89+
in a mode suitable for charging a rechargeable battery. This includes enabling
90+
charging current regulation via resistor and voltage monitoring to ensure safe and efficient charging.
91+
92+
Use this option carefully to avoid damage to non-rechargeable batteries.
93+
94+
choice ESP_VBAT_DET_LVL_LOW_SEL
95+
prompt "VBAT start charging voltage level"
96+
default ESP_VBAT_DET_LVL_LOW_SEL_2
97+
depends on ESP_VBAT_USE_RECHARGEABLE_BATTERY
98+
help
99+
The brownout detector will start charging when the supply voltage drops below the selected threshold.
100+
This ensures that the power supply is maintained at a stable level.
101+
102+
config ESP_VBAT_DET_LVL_LOW_SEL_7
103+
bool "2.94V"
104+
config ESP_VBAT_DET_LVL_LOW_SEL_6
105+
bool "2.88V"
106+
config ESP_VBAT_DET_LVL_LOW_SEL_5
107+
bool "2.83V"
108+
config ESP_VBAT_DET_LVL_LOW_SEL_4
109+
bool "2.78V"
110+
config ESP_VBAT_DET_LVL_LOW_SEL_3
111+
bool "2.73V"
112+
config ESP_VBAT_DET_LVL_LOW_SEL_2
113+
bool "2.67V"
114+
config ESP_VBAT_DET_LVL_LOW_SEL_1
115+
bool "2.62V"
116+
config ESP_VBAT_DET_LVL_LOW_SEL_0
117+
bool "2.57V"
118+
endchoice
119+
120+
choice ESP_VBAT_DET_LVL_HIGH_SEL
121+
prompt "VBAT stop charging voltage level"
122+
default ESP_VBAT_DET_LVL_HIGH_SEL_7
123+
depends on ESP_VBAT_USE_RECHARGEABLE_BATTERY
124+
help
125+
The brownout detector will stop charging when the supply voltage arrives the selected threshold.
126+
127+
config ESP_VBAT_DET_LVL_HIGH_SEL_7
128+
bool "2.94V"
129+
config ESP_VBAT_DET_LVL_HIGH_SEL_6
130+
bool "2.88V"
131+
config ESP_VBAT_DET_LVL_HIGH_SEL_5
132+
bool "2.83V"
133+
config ESP_VBAT_DET_LVL_HIGH_SEL_4
134+
bool "2.78V"
135+
config ESP_VBAT_DET_LVL_HIGH_SEL_3
136+
bool "2.73V"
137+
config ESP_VBAT_DET_LVL_HIGH_SEL_2
138+
bool "2.67V"
139+
config ESP_VBAT_DET_LVL_HIGH_SEL_1
140+
bool "2.62V"
141+
config ESP_VBAT_DET_LVL_HIGH_SEL_0
142+
bool "2.57V"
143+
endchoice
144+
145+
choice ESP_VBAT_BROWNOUT_DET_LVL_SEL
146+
prompt "VBAT brownout voltage level"
147+
default ESP_VBAT_BROWNOUT_DET_LVL_SEL_0
148+
depends on ESP_VBAT_INIT_AUTO
149+
help
150+
The brownout detector will git a brownout signal when vbat brownout detected.
151+
152+
config ESP_VBAT_BROWNOUT_DET_LVL_SEL_7
153+
bool "2.94V"
154+
config ESP_VBAT_BROWNOUT_DET_LVL_SEL_6
155+
bool "2.88V"
156+
config ESP_VBAT_BROWNOUT_DET_LVL_SEL_5
157+
bool "2.83V"
158+
config ESP_VBAT_BROWNOUT_DET_LVL_SEL_4
159+
bool "2.78V"
160+
config ESP_VBAT_BROWNOUT_DET_LVL_SEL_3
161+
bool "2.73V"
162+
config ESP_VBAT_BROWNOUT_DET_LVL_SEL_2
163+
bool "2.67V"
164+
config ESP_VBAT_BROWNOUT_DET_LVL_SEL_1
165+
bool "2.62V"
166+
config ESP_VBAT_BROWNOUT_DET_LVL_SEL_0
167+
bool "2.57V"
168+
endchoice
169+
170+
config ESP_VBAT_DET_LVL_LOW
171+
int
172+
depends on ESP_VBAT_USE_RECHARGEABLE_BATTERY
173+
default 0 if ESP_VBAT_DET_LVL_LOW_SEL_0
174+
default 1 if ESP_VBAT_DET_LVL_LOW_SEL_1
175+
default 2 if ESP_VBAT_DET_LVL_LOW_SEL_2
176+
default 3 if ESP_VBAT_DET_LVL_LOW_SEL_3
177+
default 4 if ESP_VBAT_DET_LVL_LOW_SEL_4
178+
default 5 if ESP_VBAT_DET_LVL_LOW_SEL_5
179+
default 6 if ESP_VBAT_DET_LVL_LOW_SEL_6
180+
default 7 if ESP_VBAT_DET_LVL_LOW_SEL_7
181+
182+
config ESP_VBAT_DET_LVL_HIGH
183+
int
184+
depends on ESP_VBAT_USE_RECHARGEABLE_BATTERY
185+
default 0 if ESP_VBAT_DET_LVL_HIGH_SEL_0
186+
default 1 if ESP_VBAT_DET_LVL_HIGH_SEL_1
187+
default 2 if ESP_VBAT_DET_LVL_HIGH_SEL_2
188+
default 3 if ESP_VBAT_DET_LVL_HIGH_SEL_3
189+
default 4 if ESP_VBAT_DET_LVL_HIGH_SEL_4
190+
default 5 if ESP_VBAT_DET_LVL_HIGH_SEL_5
191+
default 6 if ESP_VBAT_DET_LVL_HIGH_SEL_6
192+
default 7 if ESP_VBAT_DET_LVL_HIGH_SEL_7
193+
194+
config ESP_VBAT_BROWNOUT_DET_LVL
195+
int
196+
default 0 if ESP_VBAT_BROWNOUT_DET_LVL_SEL_0
197+
default 1 if ESP_VBAT_BROWNOUT_DET_LVL_SEL_1
198+
default 2 if ESP_VBAT_BROWNOUT_DET_LVL_SEL_2
199+
default 3 if ESP_VBAT_BROWNOUT_DET_LVL_SEL_3
200+
default 4 if ESP_VBAT_BROWNOUT_DET_LVL_SEL_4
201+
default 5 if ESP_VBAT_BROWNOUT_DET_LVL_SEL_5
202+
default 6 if ESP_VBAT_BROWNOUT_DET_LVL_SEL_6
203+
default 7 if ESP_VBAT_BROWNOUT_DET_LVL_SEL_7
204+
205+
config ESP_VBAT_CHARGER_CIRCUIT_RESISTOR_VAL
206+
int "vbat charger circuit resistor value (ohms), should be multiple of 500"
207+
depends on ESP_VBAT_USE_RECHARGEABLE_BATTERY
208+
range 1000 8500
209+
default 1000
210+
help
211+
The resistor value of charger circuit.
212+
213+
endmenu
214+
65215
endmenu
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*******************************************************************************
8+
* NOTICE
9+
* The ll is not public api, don't use in application code.
10+
* See readme.md in hal/readme.md
11+
******************************************************************************/
12+
13+
#pragma once
14+
15+
#include <stdbool.h>
16+
#include "esp_bit_defs.h"
17+
#include "soc/lp_analog_peri_struct.h"
18+
#include "hal/regi2c_ctrl.h"
19+
#include "soc/regi2c_brownout.h"
20+
21+
22+
typedef enum {
23+
VBAT_LL_CHARGER_UPVOLTAGE_INTR = BIT(27),
24+
VBAT_LL_CHARGER_UNDERVOLTAGE_INTR = BIT(28),
25+
VBAT_LL_BROWNOUT_INTR = BIT(30),
26+
} vbat_ll_intr_t;
27+
28+
#define VBAT_LL_CHARGER_MASK (BIT(27)|BIT(28))
29+
#define VBAT_LL_DETECT_MASK (BIT(30))
30+
31+
#ifdef __cplusplus
32+
extern "C" {
33+
#endif
34+
35+
/**
36+
* @brief Set vbat brownout threshold voltage
37+
*
38+
* @param threshold vbat brownout threshold
39+
*/
40+
static inline void vbat_ll_set_brownout_threshold(uint8_t threshold)
41+
{
42+
// Give same value
43+
REGI2C_WRITE_MASK(I2C_BOD, I2C_PMU_OR_DREF_VBAT_L, threshold);
44+
REGI2C_WRITE_MASK(I2C_BOD, I2C_PMU_OR_DREF_VBAT_H, threshold);
45+
}
46+
47+
/**
48+
* @brief Set vbat charge threshold voltage
49+
*
50+
* @param threshold vbat charge threshold
51+
*/
52+
static inline void vbat_ll_set_charger_threshold(uint8_t threshold_l, uint8_t threshold_h)
53+
{
54+
REGI2C_WRITE_MASK(I2C_BOD, I2C_BIAS_OR_DREF_VBAT_CHARGER_L, threshold_l);
55+
REGI2C_WRITE_MASK(I2C_BOD, I2C_BIAS_OR_DREF_VBAT_CHARGER_H, threshold_h);
56+
}
57+
58+
/**
59+
* @brief Enable or disable the VBAT charger comparator
60+
*
61+
* @param enable Set to `true` to enable the comparator, or `false` to disable it.
62+
*/
63+
static inline void vbat_ll_enable_charger_comparator(bool enable)
64+
{
65+
REGI2C_WRITE_MASK(I2C_BOD, I2C_BIAS_OR_FORCE_PU_VBAT_CHARGER, enable);
66+
}
67+
68+
/**
69+
* @brief Set the under voltage filter time for the charger detector
70+
*
71+
* @param time_tick The filter time in ticks (unit depends on the hardware implementation).
72+
*/
73+
static inline void vbat_ll_set_undervoltage_filter_time(uint32_t time_tick)
74+
{
75+
LP_ANA_PERI.vddbat_charge_cntl.vddbat_charge_undervoltage_target = time_tick;
76+
}
77+
78+
/**
79+
* @brief Set the upvoltage filter time for the charger detector
80+
*
81+
* @param time_tick The filter time in ticks (unit depends on the hardware implementation).
82+
*/
83+
static inline void vbat_ll_set_upvoltage_filter_time(uint32_t time_tick)
84+
{
85+
LP_ANA_PERI.vddbat_charge_cntl.vddbat_charge_upvoltage_target = time_tick;
86+
}
87+
88+
/**
89+
* @brief Set the charger resistor value for VBAT charging
90+
*
91+
* @param resistor Resistor value to be set (unit depends on the hardware implementation).
92+
*/
93+
static inline void vbat_ll_set_charger_resistor(uint32_t resistor)
94+
{
95+
REGI2C_WRITE_MASK(I2C_BOD, I2C_BIAS_OR_DRES_CHARGER, resistor);
96+
}
97+
98+
/*
99+
* @brief Start or stop the VBAT battery charging process
100+
*
101+
* @param start Set to true to start charging, or false to stop charging.
102+
*/
103+
static inline void vbat_ll_start_battery_charge(bool start)
104+
{
105+
LP_ANA_PERI.vddbat_bod_cntl.vddbat_charger = start;
106+
}
107+
108+
/**
109+
* @brief Enable the interrupt mask for vbat usage
110+
*
111+
* @param mask A bitmask representing the interrupts to enable.
112+
* Each bit corresponds to a specific interrupt source.
113+
* @param enable true for enabling the interrupt, otherwise false.
114+
*
115+
* @note Avoid concurrency risky with brownout_ll_intr_enable
116+
*/
117+
static inline void vbat_ll_enable_intr_mask(uint32_t mask, bool enable)
118+
{
119+
if (enable) {
120+
LP_ANA_PERI.int_ena.val |= mask;
121+
} else {
122+
LP_ANA_PERI.int_ena.val &= ~mask;
123+
}
124+
}
125+
126+
/**
127+
* @brief Clear the interrupt mask for vbat usage
128+
*
129+
* @param mask A bitmask representing the interrupts to clear.
130+
* Each bit corresponds to a specific interrupt source.
131+
*/
132+
static inline void vbat_ll_clear_intr_mask(uint32_t mask)
133+
{
134+
LP_ANA_PERI.int_clr.val = mask;
135+
}
136+
137+
/**
138+
* @brief Get the current interrupt mask for vbat usage
139+
*
140+
* @param intr_status Pointer to a variable where the interrupt status mask will be stored.
141+
* The function will write the current interrupt status to this variable.
142+
*/
143+
static inline void vbat_ll_get_interrupt_status(uint32_t *intr_status)
144+
{
145+
*intr_status = LP_ANA_PERI.int_st.val;
146+
}
147+
148+
/**
149+
* @brief Clear the VBAT count for charge detection
150+
*
151+
* This function clears the internal counter that tracks the number of charge events detected
152+
* related to the VBAT power supply. It is typically used to reset the count for monitoring purposes.
153+
*/
154+
static inline void vbat_ll_clear_count(void)
155+
{
156+
LP_ANA_PERI.vddbat_charge_cntl.vddbat_charge_cnt_clr = 1;
157+
LP_ANA_PERI.vddbat_charge_cntl.vddbat_charge_cnt_clr = 0;
158+
}
159+
160+
#ifdef __cplusplus
161+
}
162+
#endif

components/soc/esp32h2/include/soc/Kconfig.soc_caps.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ config SOC_BOD_SUPPORTED
179179
bool
180180
default y
181181

182+
config SOC_VBAT_SUPPORTED
183+
bool
184+
default y
185+
182186
config SOC_APM_SUPPORTED
183187
bool
184188
default y

components/soc/esp32h2/include/soc/regi2c_brownout.h

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -19,12 +19,12 @@
1919
#define I2C_BOD I2C_PMU
2020
#define I2C_BOD_HOSTID I2C_PMU_HOSTID
2121

22-
#define I2C_PMU_OR_DREFL_VBAT 17
23-
#define I2C_PMU_OR_DREFL_VBAT_MSB 4
24-
#define I2C_PMU_OR_DREFL_VBAT_LSB 2
25-
#define I2C_PMU_OR_DREFH_VBAT 17
26-
#define I2C_PMU_OR_DREFH_VBAT_MSB 7
27-
#define I2C_PMU_OR_DREFH_VBAT_LSB 5
22+
#define I2C_PMU_OR_DREF_VBAT_L 17
23+
#define I2C_PMU_OR_DREF_VBAT_L_MSB 4
24+
#define I2C_PMU_OR_DREF_VBAT_L_LSB 2
25+
#define I2C_PMU_OR_DREF_VBAT_H 17
26+
#define I2C_PMU_OR_DREF_VBAT_H_MSB 7
27+
#define I2C_PMU_OR_DREF_VBAT_H_LSB 5
2828

2929
#define I2C_PMU_OR_XPD_DIGDET 18
3030
#define I2C_PMU_OR_XPD_DIGDET_MSB 0
@@ -44,6 +44,22 @@
4444
#define I2C_PMU_OR_DREFH_VDDA_MSB 7
4545
#define I2C_PMU_OR_DREFH_VDDA_LSB 5
4646

47+
#define I2C_BIAS_OR_DREF_VBAT_CHARGER_L 20
48+
#define I2C_BIAS_OR_DREF_VBAT_CHARGER_L_MSB 4
49+
#define I2C_BIAS_OR_DREF_VBAT_CHARGER_L_LSB 2
50+
#define I2C_BIAS_OR_DREF_VBAT_CHARGER_H 20
51+
#define I2C_BIAS_OR_DREF_VBAT_CHARGER_H_MSB 7
52+
#define I2C_BIAS_OR_DREF_VBAT_CHARGER_H_LSB 5
53+
54+
#define I2C_BIAS_OR_FORCE_PU_VBAT_CHARGER 20
55+
#define I2C_BIAS_OR_FORCE_PU_VBAT_CHARGER_MSB 0
56+
#define I2C_BIAS_OR_FORCE_PU_VBAT_CHARGER_LSB 0
57+
58+
/** Change the charging current by adjusting the value of the series resistor. 1kΩ + N * 0.5kΩ */
59+
#define I2C_BIAS_OR_DRES_CHARGER 15
60+
#define I2C_BIAS_OR_DRES_CHARGER_MSB 7
61+
#define I2C_BIAS_OR_DRES_CHARGER_LSB 4
62+
4763
#define I2C_BOD_THRESHOLD_L I2C_PMU_OR_DREFL_VDDA
4864
#define I2C_BOD_THRESHOLD_L_MSB I2C_PMU_OR_DREFL_VDDA_MSB
4965
#define I2C_BOD_THRESHOLD_L_LSB I2C_PMU_OR_DREFL_VDDA_LSB

components/soc/esp32h2/include/soc/soc_caps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
#define SOC_FLASH_ENC_SUPPORTED 1
7878
#define SOC_SECURE_BOOT_SUPPORTED 1
7979
#define SOC_BOD_SUPPORTED 1
80+
#define SOC_VBAT_SUPPORTED 1
8081
#define SOC_APM_SUPPORTED 1 /*!< Support for APM peripheral */
8182
#define SOC_PMU_SUPPORTED 1
8283
#define SOC_LP_TIMER_SUPPORTED 1

0 commit comments

Comments
 (0)