diff --git a/src/DateTimeWatchFace.cpp b/src/DateTimeWatchFace.cpp new file mode 100644 index 0000000..0534632 --- /dev/null +++ b/src/DateTimeWatchFace.cpp @@ -0,0 +1,20 @@ +// Self +#include "DateTimeWatchFace.h" + +// Fonts +#include + +void CDateTimeWatchFace::Draw(CWatchyExpanded::ADisplay& display, const tmElements_t& time) +{ + CTimeWatchFace::Draw(display, time); + + m_currentLocalTime.tm_wday = time.Wday - 1; + m_currentLocalTime.tm_year = time.Year + 1970 - 1900; + m_currentLocalTime.tm_mon = time.Month - 1; + m_currentLocalTime.tm_mday = time.Day; + + char buffer[32]; + strftime(buffer, sizeof(buffer), "%a %b %d, %Y", &m_currentLocalTime); + display.print(buffer); + display.println(); +}; diff --git a/src/DateTimeWatchFace.h b/src/DateTimeWatchFace.h new file mode 100644 index 0000000..9e84a87 --- /dev/null +++ b/src/DateTimeWatchFace.h @@ -0,0 +1,17 @@ +#pragma once + +// Time +#include + +// Expanded +#include "WatchFace.h" +#include "WatchyExpanded.h" + +// Faces +#include "TimeWatchFace.h" + +class CDateTimeWatchFace : public CTimeWatchFace +{ + public: + void Draw(CWatchyExpanded::ADisplay& display, const tmElements_t& time) override; +}; diff --git a/src/TimeWatchFace.cpp b/src/TimeWatchFace.cpp new file mode 100644 index 0000000..af00a4f --- /dev/null +++ b/src/TimeWatchFace.cpp @@ -0,0 +1,22 @@ +// Self +#include "TimeWatchFace.h" + +// Fonts +#include + +void CTimeWatchFace::Draw(CWatchyExpanded::ADisplay& display, const tmElements_t& time) +{ + display.setFullWindow(); + display.fillScreen(GxEPD_BLACK); + display.setFont(&FreeMonoBold9pt7b); + display.setCursor(0, 15); + + m_currentLocalTime.tm_hour = time.Hour; + m_currentLocalTime.tm_min = time.Minute; + m_currentLocalTime.tm_sec = time.Second; + + display.print("Time: "); + char buffer[20]; + strftime(buffer, sizeof(buffer), " %I:%M %p", &m_currentLocalTime); + display.println(buffer); +}; diff --git a/src/TimeWatchFace.h b/src/TimeWatchFace.h new file mode 100644 index 0000000..9f17385 --- /dev/null +++ b/src/TimeWatchFace.h @@ -0,0 +1,17 @@ +#pragma once + +// Time +#include + +// Expanded +#include "WatchFace.h" +#include "WatchyExpanded.h" + +class CTimeWatchFace : public CWatchFace +{ + public: + void Draw(CWatchyExpanded::ADisplay& display, const tmElements_t& time) override; + + protected: + tm m_currentLocalTime; +}; diff --git a/src/WatchyApp.h b/src/WatchyApp.h new file mode 100644 index 0000000..3bf4591 --- /dev/null +++ b/src/WatchyApp.h @@ -0,0 +1,7 @@ +#pragma once + +class CWatchyApp +{ + +}; + diff --git a/src/WatchyExpanded.cpp b/src/WatchyExpanded.cpp index 7ca412c..f435799 100644 --- a/src/WatchyExpanded.cpp +++ b/src/WatchyExpanded.cpp @@ -6,46 +6,16 @@ // Wire #include -// Fonts -#include +// Faces +#include "TimeWatchFace.h" +#include "DateTimeWatchFace.h" -// Expanded -#include "WatchFace.h" +RTC_DATA_ATTR SExpandedData g_data; -RTC_DATA_ATTR bool g_displayFullInit = true; - -class CBasicWatch : public CWatchFace +CWatchyExpanded::CWatchyExpanded() : m_display(GxEPD2_154_D67(wcd::cs, wcd::dc, wcd::reset, wcd::busy)), m_data(g_data) { - public: - void Draw(CWatchyExpanded::ADisplay& display, const tmElements_t& time) override - { - display.setFullWindow(); - display.fillScreen(GxEPD_BLACK); - display.setFont(&FreeMonoBold9pt7b); - display.setCursor(0, 15); - - tm currentLocalTime; - currentLocalTime.tm_wday = time.Wday - 1; - currentLocalTime.tm_year = time.Year + 1970 - 1900; - currentLocalTime.tm_mon = time.Month - 1; - currentLocalTime.tm_mday = time.Day; - currentLocalTime.tm_hour = time.Hour; - currentLocalTime.tm_min = time.Minute; - currentLocalTime.tm_sec = time.Second; - - display.print("Time: "); - char buffer[20]; - strftime(buffer, sizeof(buffer), " %I:%M %p", ¤tLocalTime); - display.println(buffer); - - strftime(buffer, sizeof(buffer), "%a %b %d, %Y", ¤tLocalTime); - display.print(buffer); - }; -}; - -CWatchyExpanded::CWatchyExpanded() : m_display(GxEPD2_154_D67(wcd::cs, wcd::dc, wcd::reset, wcd::busy)) -{ - AddWatchFace(new CBasicWatch); + AddWatchFace(new CTimeWatchFace); + AddWatchFace(new CDateTimeWatchFace); } void CWatchyExpanded::AddWatchFace(CWatchFace* pFace) @@ -53,38 +23,46 @@ void CWatchyExpanded::AddWatchFace(CWatchFace* pFace) m_faces.push_back(pFace); } -void CWatchyExpanded::Init() +void CWatchyExpanded::Run() { const esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause(); //get wake up reason Wire.begin(SDA, SCL); //init i2c m_rtc.init(); // Init the display here for all cases, if unused, it will do nothing - m_display.init(0, g_displayFullInit, 10, true); // 10ms by spec, and fast pulldown reset + m_display.init(0, m_data.m_init, 10, true); // 10ms by spec, and fast pulldown reset + //Init(); m_display.epd2.setBusyCallback(DisplayBusyCallback); switch (wakeup_reason) { case ESP_SLEEP_WAKEUP_EXT0: //RTC Alarm if(m_guiState == wc::kWatchFace_State) - { - m_rtc.read(m_currentTime); - UpdateScreen(false); //partial updates on tick - } - break; - // case ESP_SLEEP_WAKEUP_EXT1: //button Press - // handleButtonPress(); - // break; + m_UpdateWatchFace = true; + break; + case ESP_SLEEP_WAKEUP_EXT1: //button Press + HandleButtonPress(); + break; default: //reset m_rtc.config(""); - //_bmaConfig(); - m_rtc.read(m_currentTime); - UpdateScreen(true); //full update on reset break; } + if (m_UpdateWatchFace) + { + m_rtc.read(m_currentTime); + UpdateScreen(false); // full update + } DeepSleep(); } +void CWatchyExpanded::Init() +{ + if (!m_data.m_init) + return; + + m_data.m_init = false; +} + void CWatchyExpanded::DisplayBusyCallback(const void*) { gpio_wakeup_enable(static_cast(wcd::busy), GPIO_INTR_LOW_LEVEL); @@ -92,24 +70,64 @@ void CWatchyExpanded::DisplayBusyCallback(const void*) esp_light_sleep_start(); } -void CWatchyExpanded::UpdateScreen(const bool fullUpdate) +void CWatchyExpanded::UpdateScreen(const bool partial_update) { m_display.setFullWindow(); - m_faces[m_face]->Draw(m_display, m_currentTime); - m_display.display(fullUpdate); //partial refresh + m_currentTime.Month = 4; + m_faces[m_data.m_face % m_faces.size()]->Draw(m_display, m_currentTime); + m_display.display(partial_update); //partial refresh m_guiState = wc::kWatchFace_State; } void CWatchyExpanded::DeepSleep() { m_display.hibernate(); - g_displayFullInit = false; + m_data.m_init = false; m_rtc.clearAlarm(); //resets the alarm flag in the RTC - for(int i=0; i<40; i++) // Set pins 0-39 to input to avoid power leaking out + for(int i = 0; i < 40; ++i) // Set pins 0-39 to input to avoid power leaking out pinMode(i, INPUT); esp_sleep_enable_ext0_wakeup(wc::rtc_pin, 0); //enable deep sleep wake on RTC interrupt esp_sleep_enable_ext1_wakeup(wc::btn_pin_mask, ESP_EXT1_WAKEUP_ANY_HIGH); //enable deep sleep wake on button press esp_deep_sleep_start(); } + +void CWatchyExpanded::HandleButtonPress() +{ + const uint64_t kWakeupBit = esp_sleep_get_ext1_wakeup_status(); + if (kWakeupBit & wc::up_btn_mask) + BackFace(); + else if (kWakeupBit & wc::down_btn_mask) + ForwardFace(); +} + +void CWatchyExpanded::BackFace() +{ + --m_data.m_face; + m_UpdateWatchFace = true; +} + +void CWatchyExpanded::ForwardFace() +{ + ++m_data.m_face; + m_UpdateWatchFace = true; +} + +void CWatchyExpanded::_bmaConfig() +{ + //if (m_sensor.begin(_readRegister, _writeRegister, delay) == false) + // return; //fail to init BMA +} + +uint16_t CWatchyExpanded::_readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len) +{ + Wire.beginTransmission(address); + Wire.write(reg); + Wire.endTransmission(); + Wire.requestFrom((uint8_t)address, (uint8_t)len); + uint8_t i = 0; + while (Wire.available()) + data[++i] = Wire.read(); + return 0; +} diff --git a/src/WatchyExpanded.h b/src/WatchyExpanded.h index c9e650f..be0ce72 100644 --- a/src/WatchyExpanded.h +++ b/src/WatchyExpanded.h @@ -17,6 +17,13 @@ // Defs class CWatchFace; +class CWatchyApp; + +struct SExpandedData +{ + bool m_init = true; + std::uint8_t m_face = 0; +}; class CWatchyExpanded { @@ -25,6 +32,7 @@ class CWatchyExpanded void AddWatchFace(CWatchFace* pFace); void Init(); + void Run(); using ADisplay = GxEPD2_BW; @@ -33,12 +41,21 @@ class CWatchyExpanded void UpdateScreen(const bool fullUpdate); void DeepSleep(); + void HandleButtonPress(); + void BackFace(); + void ForwardFace(); + + void _bmaConfig(); + static uint16_t _readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len); std::vector m_faces; - std::int8_t m_face = 0; + std::vector m_apps; ADisplay m_display; tmElements_t m_currentTime; - std::int8_t m_guiState = wc::kWatchFace_State; + std::int8_t m_guiState = 0; WatchyRTC m_rtc; + SExpandedData& m_data; + bool m_UpdateWatchFace = false; + //BMA423 m_sensor; };