You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.7 KiB
129 lines
3.7 KiB
#include "watchos.h"
|
|
#include "Module_Power.h"
|
|
|
|
void Module_Power::start()
|
|
{
|
|
// TODO: Fetch input module to poll for button presses
|
|
|
|
m_last_tick = 0;
|
|
m_light_sleep_accumulator = 0;
|
|
m_deep_sleep_accumulator = 0;
|
|
m_did_light_sleep = false;
|
|
|
|
switch (esp_sleep_get_wakeup_cause())
|
|
{
|
|
// Interactive
|
|
case ESP_SLEEP_WAKEUP_EXT1: // Button press
|
|
m_light_sleep_delay = MODULE_POWER_INTERACTIVE_LIGHT_SLEEP_DELAY_MS;
|
|
m_deep_sleep_delay = MODULE_POWER_INTERACTIVE_DEEP_SLEEP_DELAY_MS;
|
|
break;
|
|
// Non-interactive
|
|
case ESP_SLEEP_WAKEUP_EXT0: // External RTC
|
|
case ESP_SLEEP_WAKEUP_TIMER: // Internal RTC
|
|
default: // Reset or something else
|
|
m_light_sleep_delay = MODULE_POWER_NONINTERACTIVE_LIGHT_SLEEP_DELAY_MS;
|
|
m_deep_sleep_delay = MODULE_POWER_NONINTERACTIVE_DEEP_SLEEP_DELAY_MS;
|
|
break;
|
|
}
|
|
|
|
watchos::subscribe(this, WATCHOS_MODULE_INPUT, WATCHOS_EVENT_TYPE_INPUT_PRESSED);
|
|
}
|
|
|
|
void Module_Power::tick()
|
|
{
|
|
if (m_last_tick == 0)
|
|
{
|
|
m_last_tick = millis();
|
|
}
|
|
else
|
|
{
|
|
if (m_light_sleep_enabled)
|
|
{
|
|
m_light_sleep_accumulator += millis() - m_last_tick;
|
|
}
|
|
if (m_deep_sleep_enabled)
|
|
{
|
|
m_deep_sleep_accumulator += millis() - m_last_tick;
|
|
}
|
|
}
|
|
|
|
m_last_tick = millis();
|
|
|
|
Event* e;
|
|
while (this->hasEvent())
|
|
{
|
|
e = this->getEvent();
|
|
|
|
if (e->source == WATCHOS_MODULE_INPUT && e->event == WATCHOS_EVENT_TYPE_INPUT_PRESSED)
|
|
{
|
|
watchos::debug("Resetting accumulators");
|
|
m_light_sleep_delay = MODULE_POWER_INTERACTIVE_LIGHT_SLEEP_DELAY_MS;
|
|
m_deep_sleep_delay = MODULE_POWER_INTERACTIVE_DEEP_SLEEP_DELAY_MS;
|
|
m_light_sleep_accumulator = 0;
|
|
m_deep_sleep_accumulator = 0;
|
|
}
|
|
|
|
this->popEvent();
|
|
}
|
|
|
|
if (m_deep_sleep_accumulator > m_deep_sleep_delay)
|
|
{
|
|
watchos::debug("Going into deep sleep");
|
|
//watchos::debug("Power: light %d/%d; heavy %d/%d", m_light_sleep_accumulator, m_light_sleep_delay, m_deep_sleep_accumulator, m_deep_sleep_delay);
|
|
|
|
watchos::kernel()->suspend();
|
|
|
|
// TODO: Configure a... hourly? alarm to wake up and refresh other things.
|
|
// Interrogate tasks for next requested wakeup?
|
|
if (m_did_light_sleep)
|
|
{
|
|
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
|
|
}
|
|
|
|
esp_sleep_enable_ext0_wakeup(HW_RTC, 0);
|
|
esp_sleep_enable_ext1_wakeup(HW_BUTTON_MASK, ESP_EXT1_WAKEUP_ANY_HIGH);
|
|
// Turn off RTC -- needs to be on to handle ext0/ext1 interrupts properly I guess
|
|
//esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
|
|
// Turn off RTC fast mem
|
|
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
|
|
// Keep RTC slow ram on explicitly
|
|
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON);
|
|
esp_deep_sleep_start();
|
|
}
|
|
else if (m_light_sleep_accumulator > m_light_sleep_delay)
|
|
{
|
|
//watchos::debug("Going into light sleep");
|
|
//watchos::debug("Power: light %d/%d; heavy %d/%d", m_light_sleep_accumulator, m_light_sleep_delay, m_deep_sleep_accumulator, m_deep_sleep_delay);
|
|
m_did_light_sleep = true;
|
|
// If nothing else happens, wake up when it's time to hibernate.
|
|
esp_sleep_enable_timer_wakeup((m_deep_sleep_delay - m_deep_sleep_accumulator) * 1000);
|
|
// Wake up if the RTC fires
|
|
esp_sleep_enable_ext0_wakeup(HW_RTC, 0);
|
|
// Wake up if any button is pressed
|
|
esp_sleep_enable_ext1_wakeup(HW_BUTTON_MASK, ESP_EXT1_WAKEUP_ANY_HIGH);
|
|
// Go into light sleep
|
|
esp_light_sleep_start();
|
|
// And we're back, let everything continue!
|
|
m_light_sleep_accumulator = 0;
|
|
}
|
|
}
|
|
|
|
void Module_Power::disableLightSleep()
|
|
{
|
|
m_light_sleep_enabled = false;
|
|
}
|
|
|
|
void Module_Power::enableLightSleep()
|
|
{
|
|
m_light_sleep_enabled = true;
|
|
}
|
|
|
|
void Module_Power::disableDeepSleep()
|
|
{
|
|
m_deep_sleep_enabled = false;
|
|
}
|
|
|
|
void Module_Power::enableDeepSleep()
|
|
{
|
|
m_deep_sleep_enabled = true;
|
|
}
|