Skip to content

Commit c8ba6cf

Browse files
committed
Merge branch 'feature/rtc_gpio_isolate' into 'master'
Add rtc_gpio_isolate function, use it in deep sleep examples See merge request idf/esp-idf!1936
2 parents eb935c2 + af6cfc5 commit c8ba6cf

File tree

7 files changed

+63
-8
lines changed

7 files changed

+63
-8
lines changed

components/driver/include/driver/rtc_io.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,24 @@ esp_err_t rtc_gpio_hold_en(gpio_num_t gpio_num);
224224
*/
225225
esp_err_t rtc_gpio_hold_dis(gpio_num_t gpio_num);
226226

227+
/**
228+
* @brief Helper function to disconnect internal circuits from an RTC IO
229+
* This function disables input, output, pullup, pulldown, and enables
230+
* hold feature for an RTC IO.
231+
* Use this function if an RTC IO needs to be disconnected from internal
232+
* circuits in deep sleep, to minimize leakage current.
233+
*
234+
* In particular, for ESP32-WROVER module, call
235+
* rtc_gpio_isolate(GPIO_NUM_12) before entering deep sleep, to reduce
236+
* deep sleep current.
237+
*
238+
* @param gpio_num GPIO number (e.g. GPIO_NUM_12).
239+
* @return
240+
* - ESP_OK on success
241+
* - ESP_ERR_INVALID_ARG if GPIO is not an RTC IO
242+
*/
243+
esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num);
244+
227245
/**
228246
* @brief Disable force hold signal for all RTC IOs
229247
*

components/driver/rtc_module.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,19 @@ esp_err_t rtc_gpio_hold_dis(gpio_num_t gpio_num)
381381
return ESP_OK;
382382
}
383383

384+
esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num)
385+
{
386+
if (rtc_gpio_desc[gpio_num].reg == 0) {
387+
return ESP_ERR_INVALID_ARG;
388+
}
389+
390+
rtc_gpio_pullup_dis(gpio_num);
391+
rtc_gpio_pulldown_dis(gpio_num);
392+
rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED);
393+
rtc_gpio_hold_en(gpio_num);
394+
395+
return ESP_OK;
396+
}
384397

385398
void rtc_gpio_force_hold_dis_all()
386399
{

docs/api-reference/system/sleep_modes.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,20 @@ The following function can be used to enter deep sleep once wakeup sources are c
122122

123123
.. doxygenfunction:: esp_deep_sleep_start
124124

125+
Configuring IOs
126+
---------------
127+
128+
Some ESP32 IOs have internal pullups or pulldowns, which are enabled by default. If an external circuit drives this pin in deep sleep mode, current consumption may increase due to current flowing through these pullups and pulldowns.
129+
130+
To isolate a pin, preventing extra current draw, call :cpp:func:`rtc_gpio_isolate` function.
131+
132+
For example, on ESP32-WROVER module, GPIO12 is pulled up externally. GPIO12 also has an internal pulldown in the ESP32 chip. This means that in deep sleep, some current will flow through these external and internal resistors, increasing deep sleep current above the minimal possible value.
133+
Add the following code before :cpp:func:`esp_deep_sleep_start` to remove this extra current:
134+
135+
```c++
136+
rtc_gpio_isolate(GPIO_NUM_12);
137+
```
138+
125139
Checking sleep wakeup cause
126140
---------------------------
127141

examples/system/console/main/cmd_system.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ static int deep_sleep(int argc, char** argv)
155155

156156
ESP_ERROR_CHECK( esp_sleep_enable_ext1_wakeup(1ULL << io_num, level) );
157157
}
158+
rtc_gpio_isolate(GPIO_NUM_12);
158159
esp_deep_sleep_start();
159160
}
160161

examples/system/deep_sleep/main/deep_sleep_example_main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ void app_main()
157157
esp_sleep_enable_ulp_wakeup();
158158
#endif
159159

160+
// Isolate GPIO12 pin from external circuits. This is needed for modules
161+
// which have an external pull-up resistor on GPIO12 (such as ESP32-WROVER)
162+
// to minimize current consumption.
163+
rtc_gpio_isolate(GPIO_NUM_12);
164+
160165
printf("Entering deep sleep\n");
161166
gettimeofday(&sleep_enter_time, NULL);
162167

examples/system/ulp/main/ulp_example_main.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,13 @@ static void init_ulp_program()
6868
rtc_gpio_pullup_dis(gpio_num);
6969
rtc_gpio_hold_en(gpio_num);
7070

71-
/* Disable pullup on GPIO15, in case it is connected to ground to suppress
72-
* boot messages.
71+
/* Disconnect GPIO12 and GPIO15 to remove current drain through
72+
* pullup/pulldown resistors.
73+
* GPIO15 may be connected to ground to suppress boot messages.
74+
* GPIO12 may be pulled high to select flash voltage.
7375
*/
74-
rtc_gpio_pullup_dis(GPIO_NUM_15);
75-
rtc_gpio_hold_en(GPIO_NUM_15);
76+
rtc_gpio_isolate(GPIO_NUM_12);
77+
rtc_gpio_isolate(GPIO_NUM_15);
7678

7779
/* Set ULP wake up period to T = 20ms (3095 cycles of RTC_SLOW_CLK clock).
7880
* Minimum pulse width has to be T * (ulp_debounce_counter + 1) = 80ms.

examples/system/ulp_adc/main/ulp_adc_example_main.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,13 @@ static void init_ulp_program()
7474
/* Set ULP wake up period to 20ms */
7575
ulp_set_wakeup_period(0, 20000);
7676

77-
/* Disable pullup on GPIO15, in case it is connected to ground to suppress
78-
* boot messages.
77+
/* Disconnect GPIO12 and GPIO15 to remove current drain through
78+
* pullup/pulldown resistors.
79+
* GPIO15 may be connected to ground to suppress boot messages.
80+
* GPIO12 may be pulled high to select flash voltage.
7981
*/
80-
rtc_gpio_pullup_dis(GPIO_NUM_15);
81-
rtc_gpio_hold_en(GPIO_NUM_15);
82+
rtc_gpio_isolate(GPIO_NUM_12);
83+
rtc_gpio_isolate(GPIO_NUM_15);
8284
}
8385

8486
static void start_ulp_program()

0 commit comments

Comments
 (0)