2023-05-29 13:03:05 +03:00
|
|
|
#include "Watchy.h"
|
|
|
|
|
|
|
|
WatchyDisplayBase Watchy::m_displayBase;
|
2023-05-29 18:25:28 +03:00
|
|
|
WatchyDisplay Watchy::m_display(Watchy::m_displayBase);
|
2023-05-29 13:03:05 +03:00
|
|
|
WatchyRTC Watchy::m_RTC;
|
|
|
|
|
|
|
|
RTC_DATA_ATTR bool g_displayFullInit = true;
|
|
|
|
|
|
|
|
Watchy::Watchy()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Watchy::Init()
|
|
|
|
{
|
|
|
|
esp_sleep_wakeup_cause_t wakeup_reason;
|
|
|
|
wakeup_reason = esp_sleep_get_wakeup_cause();
|
|
|
|
|
|
|
|
Wire.begin(SDA, SCL);
|
|
|
|
m_RTC.init();
|
|
|
|
|
|
|
|
m_display.epd2.selectSPI(SPI, SPISettings(20000000, MSBFIRST, SPI_MODE0));
|
|
|
|
m_display.init(0, g_displayFullInit, 10, true);
|
|
|
|
m_display.epd2.setBusyCallback(DisplayBusyCallback);
|
|
|
|
|
2023-05-29 18:25:28 +03:00
|
|
|
Setup();
|
|
|
|
|
2023-05-29 13:03:05 +03:00
|
|
|
switch(wakeup_reason) {
|
|
|
|
case ESP_SLEEP_WAKEUP_EXT0:
|
2023-05-29 18:25:28 +03:00
|
|
|
{
|
2023-05-29 13:03:05 +03:00
|
|
|
// RTC interrupt
|
|
|
|
ShowWatchFace(true);
|
|
|
|
break;
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
2023-05-29 13:03:05 +03:00
|
|
|
case ESP_SLEEP_WAKEUP_EXT1:
|
2023-05-29 18:25:28 +03:00
|
|
|
{
|
2023-05-29 13:03:05 +03:00
|
|
|
// Button press
|
2023-05-29 18:25:28 +03:00
|
|
|
uint64_t wakeupBit = esp_sleep_get_ext1_wakeup_status();
|
|
|
|
HandleButtonPress(wakeupBit);
|
2023-05-29 13:03:05 +03:00
|
|
|
break;
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
2023-05-29 13:03:05 +03:00
|
|
|
default:
|
2023-05-29 18:25:28 +03:00
|
|
|
{
|
2023-05-29 13:03:05 +03:00
|
|
|
ConnectWiFi();
|
|
|
|
SyncNTPTime();
|
|
|
|
DisconnectWiFi();
|
|
|
|
|
|
|
|
ShowWatchFace(false);
|
|
|
|
break;
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
2023-05-29 13:03:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
DeepSleep();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Watchy::DeepSleep()
|
|
|
|
{
|
|
|
|
m_display.hibernate();
|
|
|
|
if (g_displayFullInit) { // For some reason, seems to be enabled on first boot
|
|
|
|
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_displayFullInit = false; // Notify not to init it again
|
|
|
|
m_RTC.clearAlarm(); // resets the alarm flag in the RTC
|
|
|
|
|
|
|
|
// Set GPIOs 0-39 to input to avoid power leaking out
|
|
|
|
const uint64_t ignore = 0b11110001000000110000100111000010; // Ignore some GPIOs due to resets
|
|
|
|
for (int i = 0; i < GPIO_NUM_MAX; i++) {
|
|
|
|
if ((ignore >> i) & 0b1)
|
|
|
|
continue;
|
|
|
|
pinMode(i, INPUT);
|
|
|
|
}
|
|
|
|
esp_sleep_enable_ext0_wakeup((gpio_num_t)RTC_INT_PIN,
|
|
|
|
0); // enable deep sleep wake on RTC interrupt
|
|
|
|
esp_sleep_enable_ext1_wakeup(
|
|
|
|
BTN_PIN_MASK,
|
|
|
|
ESP_EXT1_WAKEUP_ANY_HIGH); // enable deep sleep wake on button press
|
|
|
|
esp_deep_sleep_start();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Watchy::DisplayBusyCallback(const void *)
|
|
|
|
{
|
|
|
|
gpio_wakeup_enable((gpio_num_t)DISPLAY_BUSY, GPIO_INTR_LOW_LEVEL);
|
|
|
|
esp_sleep_enable_gpio_wakeup();
|
|
|
|
esp_light_sleep_start();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Watchy::VibeMotor(uint8_t intervalMs, uint8_t length)
|
|
|
|
{
|
|
|
|
pinMode(VIB_MOTOR_PIN, OUTPUT);
|
|
|
|
bool motorOn = false;
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
motorOn = !motorOn;
|
|
|
|
digitalWrite(VIB_MOTOR_PIN, motorOn);
|
|
|
|
delay(intervalMs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
float Watchy::GetBatteryVoltage()
|
|
|
|
{
|
|
|
|
return analogReadMilliVolts(BATT_ADC_PIN) / 1000.0f * 2.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Watchy::ConnectWiFi()
|
|
|
|
{
|
|
|
|
if(WiFi.begin(WIFI_SSID, WIFI_PASS) == WL_CONNECT_FAILED) {
|
|
|
|
Serial.begin(9600);
|
|
|
|
Serial.println("Failed to connect to WiFi");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(WiFi.waitForConnectResult() != WL_CONNECTED) {
|
|
|
|
Serial.begin(9600);
|
|
|
|
Serial.println("Failed to connect to WiFi");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Watchy::SyncNTPTime()
|
|
|
|
{
|
|
|
|
WiFiUDP ntpUDP;
|
|
|
|
// GMT offset should be, RTC class will adjust to local time
|
2023-05-29 20:00:46 +03:00
|
|
|
NTPClient timeClient(ntpUDP, NTP_SERVER, 0);
|
2023-05-29 13:03:05 +03:00
|
|
|
timeClient.begin();
|
|
|
|
bool success = timeClient.forceUpdate();
|
|
|
|
if (!success) {
|
|
|
|
Serial.begin(9600);
|
|
|
|
Serial.println("Failed to get NTP time");
|
|
|
|
}
|
|
|
|
tmElements_t tm;
|
|
|
|
breakTime((time_t)timeClient.getEpochTime(), tm);
|
|
|
|
m_RTC.set(tm);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Watchy::DisconnectWiFi()
|
|
|
|
{
|
|
|
|
WiFi.mode(WIFI_OFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Watchy::ShowWatchFace(bool partialRefresh)
|
|
|
|
{
|
2023-05-29 18:25:28 +03:00
|
|
|
DrawWatchFace(partialRefresh);
|
2023-05-29 13:03:05 +03:00
|
|
|
}
|