LowPower
LowPowerESP32.h
1 #pragma once
2 
3 #include "LowPowerCommon.h"
4 #include "driver/gpio.h"
5 #include "driver/rtc_io.h"
6 #include "esp32-hal-touch.h"
7 #include "esp_wifi.h"
8 
9 #define TOUCH_THREASHOLD 40
10 
11 namespace low_power {
12 
14 enum class wakeup_t { ext0, ext1 };
15 
16 #if defined(CONFIG_IDF_TARGET_ESP32C3) || \
17  defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2)
18 #define ESP_STD_SLEEP 0
19 #else
20 #define ESP_STD_SLEEP 1
21 
22 #endif
23 
48  public:
49  bool isProcessingOnSleep(sleep_mode_enum_t sleep_mode) {
50  bool result = false;
51  switch (sleep_mode) {
52  case sleep_mode_enum_t::noSleep:
53  result = true;
54  break;
55  case sleep_mode_enum_t::lightSleep:
56  result = false;
57  break;
58  case sleep_mode_enum_t::deepSleep:
59  result = false;
60  break;
61  case sleep_mode_enum_t::modemSleep:
62  result = true;
63  break;
64  }
65  return result;
66  }
67 
69  bool sleep(void) override {
70  switch (sleep_mode) {
71  case sleep_mode_enum_t::lightSleep:
72  esp_light_sleep_start();
73  return true;
74  case sleep_mode_enum_t::deepSleep:
75  esp_deep_sleep_start();
76  return true;
77  case sleep_mode_enum_t::noSleep:
78  wifiSetPS(WIFI_PS_NONE);
79  delay(sleep_time_us / 1000);
80  return true;
81 
82  case sleep_mode_enum_t::modemSleep:
83  wifiSetPS(WIFI_PS_MAX_MODEM);
84  delay(sleep_time_us / 1000);
85  // wifiSetPS(WIFI_PS_MIN_MODEM);
86  return true;
87  }
88  return false;
89  }
90 
91  bool setSleepTime(uint32_t time, time_unit_t time_unit) override {
92  if (sleep_mode == sleep_mode_enum_t::modemSleep) return false;
93  sleep_time_us = toUs(time, time_unit);
94  return esp_sleep_enable_timer_wakeup(toUs(time, time_unit)) == ESP_OK;
95  }
96 
97 #if ESP_STD_SLEEP
98  bool addWakeupPin(int pin, pin_change_t change_type) override {
99  if (sleep_mode == sleep_mode_enum_t::modemSleep) return false;
100  pin_mask |= 1 << pin;
101  switch (change_type) {
102  case pin_change_t::on_high: {
103  if (wakeup_type == wakeup_t::ext0)
104  esp_sleep_enable_ext0_wakeup((gpio_num_t)pin, 1);
105  else
106  esp_sleep_enable_ext1_wakeup_io(pin_mask,
107  ESP_EXT1_WAKEUP_ANY_HIGH);
108 
109  // gpio is tied to GND in order to wake up in HIGH
110  rtc_gpio_pulldown_en((gpio_num_t)pin);
111  // Disable PULL_UP in order to allow it to wakeup on HIGH
112  rtc_gpio_pullup_dis((gpio_num_t)pin);
113  } break;
114 
115  case pin_change_t::on_low: {
116  if (wakeup_type == wakeup_t::ext0)
117  esp_sleep_enable_ext0_wakeup((gpio_num_t)pin, 0);
118  else
119  esp_sleep_enable_ext1_wakeup_io(pin_mask,
120  ESP_EXT1_WAKEUP_ALL_LOW);
121 
122  rtc_gpio_pullup_en((gpio_num_t)pin);
123  rtc_gpio_pulldown_dis((gpio_num_t)pin);
124  } break;
125 
126  default:
127  // unsupported change type
128  return false;
129  }
130  return true;
131  }
132 #endif
133 
134 #if CONFIG_IDF_TARGET_ESP32H2
135  bool addWakeupPin(int pin, pin_change_t change_type) override {
136  if (sleep_mode == sleep_mode_enum_t::modemSleep) return false;
137 
138  gpio_wakeup_enable((gpio_num_t)pin, change_type == pin_change_t::on_high
139  ? GPIO_INTR_POSEDGE
140  : GPIO_INTR_NEGEDGE);
141  esp_sleep_enable_gpio_wakeup();
142  return true;
143  }
144 #endif
145 
146 #if !ESP_STD_SLEEP && !CONFIG_IDF_TARGET_ESP32H2
147  bool addWakeupPin(int pin, pin_change_t change_type) override {
148  if (sleep_mode == sleep_mode_enum_t::modemSleep) return false;
149  pin_mask |= 1 << pin;
150  if (sleep_mode == sleep_mode_enum_t::deepSleep) {
151  esp_deep_sleep_enable_gpio_wakeup(pin_mask,
152  change_type == pin_change_t::on_high
153  ? ESP_GPIO_WAKEUP_GPIO_HIGH
154  : ESP_GPIO_WAKEUP_GPIO_LOW);
155  return true;
156  }
157  if (sleep_mode == sleep_mode_enum_t::lightSleep) {
158  gpio_wakeup_enable((gpio_num_t)pin, change_type == pin_change_t::on_high
159  ? GPIO_INTR_POSEDGE
160  : GPIO_INTR_NEGEDGE);
161  esp_sleep_enable_gpio_wakeup();
162  return true;
163  }
164  return false;
165  }
166 #endif
167 
169  bool addWakeupTouchPin(int pin, int touch_threshold = TOUCH_THREASHOLD) {
170 #if ESP_STD_SLEEP
171  if (!isTouchPin(pin)) return false;
172  touchSleepWakeUpEnable(pin, touch_threshold);
173  return true;
174 #else
175  return false;
176 #endif
177  }
178 
187  void setWakeupType(wakeup_t wakeup) { wakeup_type = wakeup; }
188 
189  bool isModeSupported(sleep_mode_enum_t sleep_mode) override { return true; }
190 
192  void clear() override {
194  touch_pins.clear();
195  wifiSetPS(WIFI_PS_NONE);
196  sleep_time_us = 0;
197  pin_mask = 0;
198  }
199 
200  void setCpuFrequencyMhz(int mhz){
201  ::setCpuFrequencyMhz(mhz);
202  }
203 
204  protected:
205  wakeup_t wakeup_type = wakeup_t::ext1;
206  uint32_t sleep_time_us = 0;
207  std::vector<int> touch_pins;
208  uint32_t pin_mask = 0;
209 
210  void wifiSetPS(wifi_ps_type_t type) {
211 #if !CONFIG_IDF_TARGET_ESP32H2
212  esp_wifi_set_ps(type);
213 #endif
214  }
215 
216  bool isTouchPin(int pin) {
217  for (int tp : touch_pins) {
218  if (tp == pin) return true;
219  }
220  return false;
221  }
222 };
223 
224 RTC_DATA_ATTR static ArduinoLowPowerESP32 LowPower;
225 
226 } // namespace low_power
Common API for power saving modes for different processor architectures.
Definition: LowPowerCommon.h:33
virtual void clear()
reset the processing
Definition: LowPowerCommon.h:117
Low Power Management for ESP32:
Definition: LowPowerESP32.h:47
void clear() override
Reset to the initial state.
Definition: LowPowerESP32.h:192
bool addWakeupTouchPin(int pin, int touch_threshold=TOUCH_THREASHOLD)
Wakup by touch pin.
Definition: LowPowerESP32.h:169
void setWakeupType(wakeup_t wakeup)
There are two types for ESP32, ext0 and ext1 . ext0 uses RTC_IO to wakeup thus requires RTC periphera...
Definition: LowPowerESP32.h:187
bool sleep(void) override
sets processor into sleep mode
Definition: LowPowerESP32.h:69
bool setSleepTime(uint32_t time, time_unit_t time_unit) override
Defines the sleep time.
Definition: LowPowerESP32.h:91
bool isModeSupported(sleep_mode_enum_t sleep_mode) override
Provides information if the indicated mode is supported.
Definition: LowPowerESP32.h:189
bool isProcessingOnSleep(sleep_mode_enum_t sleep_mode)
Returns true if processing is possible in the current sleep mode.
Definition: LowPowerESP32.h:49
bool addWakeupPin(int pin, pin_change_t change_type) override
Defines the wakup pin.
Definition: LowPowerESP32.h:98