Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 59 additions & 16 deletions src/utility/Power_Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,12 @@ namespace m5

void Power_Class::deepSleep(std::uint64_t micro_seconds, bool touch_wakeup)
{
if (micro_seconds == 0)
{ // A wakeup time of zero means "do not sleep".
// ( This check comes before the display is put to sleep. )
M5_LOGW("deepSleep: micro_seconds is 0. not sleeping. ( use Power.sleep_no_timer to sleep without a timer wakeup )");
return;
}
M5.Display.sleep();
M5.Display.waitDisplay();
#if defined (M5UNIFIED_PC_BUILD)
Expand All @@ -1287,32 +1293,52 @@ namespace m5
{
wpin = GPIO_NUM_4;
}
bool pin_wakeup_enabled = false;
if (touch_wakeup && wpin < GPIO_NUM_MAX)
{
#if SOC_PM_SUPPORT_EXT0_WAKEUP
esp_sleep_enable_ext0_wakeup((gpio_num_t)wpin, false);
pin_wakeup_enabled = (ESP_OK == esp_sleep_enable_ext0_wakeup((gpio_num_t)wpin, false));
#elif SOC_PM_SUPPORT_EXT1_WAKEUP && SOC_RTCIO_PIN_COUNT > 0
const uint64_t ext_wakeup_pin_1_mask = 1ULL << _wakeupPin;
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(ext_wakeup_pin_1_mask, ESP_EXT1_WAKEUP_ANY_LOW));
if (rtc_gpio_is_valid_gpio((gpio_num_t)wpin))
{
const uint64_t ext_wakeup_pin_1_mask = 1ULL << wpin;
pin_wakeup_enabled = (ESP_OK == esp_sleep_enable_ext1_wakeup_io(ext_wakeup_pin_1_mask, ESP_EXT1_WAKEUP_ANY_LOW));
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
ESP_ERROR_CHECK(rtc_gpio_pullup_dis((gpio_num_t)_wakeupPin));
ESP_ERROR_CHECK(rtc_gpio_pulldown_en((gpio_num_t)_wakeupPin));
if (pin_wakeup_enabled)
{
rtc_gpio_pullup_dis((gpio_num_t)wpin);
rtc_gpio_pulldown_en((gpio_num_t)wpin);
}
#endif
}
#endif
while (m5gfx::gpio_in(wpin) == false)
if (pin_wakeup_enabled)
{
// Issue #91, ( M5Paper wakes too soon from deep sleep when touch wakeup is enabled - with solution )
M5.update();
m5gfx::delay(10);
while (m5gfx::gpio_in(wpin) == false)
{
// Issue #91, ( M5Paper wakes too soon from deep sleep when touch wakeup is enabled - with solution )
M5.update();
m5gfx::delay(10);
}
}
else
{ // The wakeup pin is not an RTC IO. ( ex. M5PaperS3 touch INT = GPIO48 )
// Such a pin can wake up from light sleep, but not from deep sleep.
M5_LOGW("deepSleep: GPIO%d cannot be used as a deep sleep wakeup source.", (int)wpin);
}
}
if (micro_seconds > 0)
if (micro_seconds != sleep_no_timer)
{
esp_sleep_enable_timer_wakeup(micro_seconds);
}
else
{
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
if (!pin_wakeup_enabled)
{ // Neither a timer nor a wakeup pin was configured by this call.
// Unless another wakeup source has been set up, the device will not wake up until it is reset.
M5_LOGW("deepSleep: no timer or pin wakeup source is enabled.");
}
}
#endif
esp_deep_sleep_start();
Expand All @@ -1321,6 +1347,11 @@ namespace m5

void Power_Class::lightSleep(std::uint64_t micro_seconds, bool touch_wakeup)
{
if (micro_seconds == 0)
{ // A wakeup time of zero means "do not sleep".
M5_LOGW("lightSleep: micro_seconds is 0. not sleeping. ( use Power.sleep_no_timer to sleep without a timer wakeup )");
return;
}
#if defined (M5UNIFIED_PC_BUILD)
(void)micro_seconds;
(void)touch_wakeup;
Expand All @@ -1342,31 +1373,43 @@ namespace m5
{
wpin = GPIO_NUM_4;
}
bool pin_wakeup_enabled = false;
if (touch_wakeup && wpin < GPIO_NUM_MAX)
{
if (M5.getBoard() == board_t::board_M5PaperS3)
{
// M5PaperS3 touch interrupt pin (GPIO48) is not RTC IO
// and therefore not supported in EXT0 wakeup
gpio_wakeup_enable((gpio_num_t)wpin, gpio_int_type_t::GPIO_INTR_LOW_LEVEL);
esp_sleep_enable_gpio_wakeup();
pin_wakeup_enabled = (ESP_OK == gpio_wakeup_enable((gpio_num_t)wpin, gpio_int_type_t::GPIO_INTR_LOW_LEVEL))
&& (ESP_OK == esp_sleep_enable_gpio_wakeup());
}
else
{
#if SOC_PM_SUPPORT_EXT0_WAKEUP
esp_sleep_enable_ext0_wakeup((gpio_num_t)wpin, false);
pin_wakeup_enabled = (ESP_OK == esp_sleep_enable_ext0_wakeup((gpio_num_t)wpin, false));
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_AUTO);
#endif
}
while (m5gfx::gpio_in(wpin) == false)
if (pin_wakeup_enabled)
{
while (m5gfx::gpio_in(wpin) == false)
{
m5gfx::delay(10);
}
}
else
{
m5gfx::delay(10);
M5_LOGW("lightSleep: wakeup by GPIO%d is not enabled.", (int)wpin);
}
}
if (micro_seconds > 0){
if (micro_seconds != sleep_no_timer){
esp_sleep_enable_timer_wakeup(micro_seconds);
}else{
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
if (!pin_wakeup_enabled)
{ // Neither a timer nor a wakeup pin was configured by this call.
M5_LOGW("lightSleep: no timer or pin wakeup source is enabled.");
}
}
esp_light_sleep_start();
if (M5.getBoard() == board_t::board_M5PaperS3)
Expand Down
15 changes: 11 additions & 4 deletions src/utility/Power_Class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,20 @@ namespace m5
/// @attention CoreInk と M5Paper は USB接続中はRTCタイマー起動が出来ない。;
void timerSleep(const rtc_date_t& date, const rtc_time_t& time);

/// Value for micro_seconds of deepSleep / lightSleep, meaning "sleep without a timer wakeup".
/// The device sleeps until a wakeup pin or another wakeup source is triggered.
static constexpr std::uint64_t sleep_no_timer = ~0ull;

/// ESP32 deepsleep
/// @param micro_seconds Number of micro seconds to wakeup.
void deepSleep(std::uint64_t micro_seconds = 0, bool touch_wakeup = true);
/// @param micro_seconds Number of micro seconds to wakeup. 0 = do not sleep. sleep_no_timer = no timer wakeup.
/// @param touch_wakeup Enable wakeup by the wakeup pin of the device, if it has one.
/// @attention Waking up from deep sleep restarts the program from the beginning.
void deepSleep(std::uint64_t micro_seconds = sleep_no_timer, bool touch_wakeup = true);

/// ESP32 lightsleep
/// @param micro_seconds Number of micro seconds to wakeup.
void lightSleep(std::uint64_t micro_seconds = 0, bool touch_wakeup = true);
/// @param micro_seconds Number of micro seconds to wakeup. 0 = do not sleep. sleep_no_timer = no timer wakeup.
/// @param touch_wakeup Enable wakeup by the wakeup pin of the device, if it has one.
void lightSleep(std::uint64_t micro_seconds = sleep_no_timer, bool touch_wakeup = true);

/// Get the remaining battery power.
/// @return 0-100 level
Expand Down
2 changes: 1 addition & 1 deletion src/utility/RTC_Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace m5

if (instance == nullptr)
{
instance.reset(new PCF8563_Class(PCF8563_Class::DEFAULT_ADDRESS, 400000));
instance.reset(new PCF8563_Class(PCF8563_Class::DEFAULT_ADDRESS, 400000, i2c));
}

if (instance->begin())
Expand Down
Loading