diff --git a/src/lib/functions.cpp b/src/lib/functions.cpp index c514a11..ac4dcfb 100644 --- a/src/lib/functions.cpp +++ b/src/lib/functions.cpp @@ -7,6 +7,8 @@ std::map screenNameMap; #ifndef NO_MCP Adafruit_MCP23X17 mcp; +const int MCP_INT_PIN = 8; + #endif bool timerRunning = true; int fgColor; @@ -49,6 +51,8 @@ void setupComponents() else { Serial.println("MCP23017 ok"); + pinMode(MCP_INT_PIN, INPUT); + mcp.setupInterrupts(true, false, LOW); } #endif @@ -65,6 +69,7 @@ void setupComponents() for (int i = 0; i < 4; i++) { mcp.pinMode(i, INPUT_PULLUP); + mcp.setupInterruptPin(i, LOW); } #endif } @@ -112,12 +117,13 @@ void setupPreferences() // screenNameMap = {{SCREEN_BLOCK_HEIGHT, "Block Height"}; screenNameMap = {{SCREEN_BLOCK_HEIGHT, "Block Height"}, - {SCREEN_MSCW_TIME, "Sats per dollar"}, - {SCREEN_BTC_TICKER, "Ticker"}, - {SCREEN_TIME, "Time"}, - {SCREEN_HALVING_COUNTDOWN, "Halving countdown"}}; + {SCREEN_MSCW_TIME, "Sats per dollar"}, + {SCREEN_BTC_TICKER, "Ticker"}, + {SCREEN_TIME, "Time"}, + {SCREEN_HALVING_COUNTDOWN, "Halving countdown"}}; - for (int i = 0; i < screenNameMap.size() ; i++) { + for (int i = 0; i < screenNameMap.size(); i++) + { String key = "screen" + String(i) + "Visible"; screenVisible[i] = preferences.getBool(key.c_str(), true); // Default to true if not set } @@ -149,8 +155,9 @@ void handleScreenTasks(uint screen) switch (currentScreen) { case SCREEN_BLOCK_HEIGHT: - if (blockNotifyTaskHandle) + if (blockNotifyTaskHandle) { vTaskResume(blockNotifyTaskHandle); + } break; case SCREEN_HALVING_COUNTDOWN: if (blockNotifyTaskHandle) @@ -165,8 +172,10 @@ void handleScreenTasks(uint screen) vTaskResume(getPriceTaskHandle); break; case SCREEN_TIME: - if (minuteTaskHandle) + if (minuteTaskHandle) { + TimeScreen::onActivate(); vTaskResume(minuteTaskHandle); + } break; } } @@ -192,7 +201,8 @@ void timebasedChangeTask(void *parameter) int newCurrentScreen = (getCurrentScreen() + 1) % screenCount; String key = "screen" + String(newCurrentScreen) + "Visible"; - while (!preferences.getBool(key.c_str(), true)) { + while (!preferences.getBool(key.c_str(), true)) + { newCurrentScreen = (newCurrentScreen + 1) % screenCount; key = "screen" + String(newCurrentScreen) + "Visible"; } @@ -203,6 +213,36 @@ void timebasedChangeTask(void *parameter) } } +int modulo(int x,int N) { + return (x % N + N) %N; +} + +void nextScreen() +{ + int newCurrentScreen = (getCurrentScreen() + 1) % screenCount; + String key = "screen" + String(newCurrentScreen) + "Visible"; + + while (!preferences.getBool(key.c_str(), true)) + { + newCurrentScreen = (newCurrentScreen + 1) % screenCount; + key = "screen" + String(newCurrentScreen) + "Visible"; + } + setCurrentScreen(newCurrentScreen); +} + +void previousScreen() +{ + int newCurrentScreen = modulo(getCurrentScreen() - 1, screenCount); + String key = "screen" + String(newCurrentScreen) + "Visible"; + + while (!preferences.getBool(key.c_str(), true)) + { + newCurrentScreen = modulo(newCurrentScreen - 1, screenCount); + key = "screen" + String(newCurrentScreen) + "Visible"; + } + setCurrentScreen(newCurrentScreen); +} + void setLights(int r, int g, int b) { #ifdef WITH_RGB_LED diff --git a/src/lib/functions.hpp b/src/lib/functions.hpp index 6cfa568..ceb5848 100644 --- a/src/lib/functions.hpp +++ b/src/lib/functions.hpp @@ -27,4 +27,7 @@ GFXfont getFont(uint size); int getBgColor(); int getFgColor(); -void setupSoftAP(); \ No newline at end of file +void setupSoftAP(); +void nextScreen(); +void previousScreen(); +int modulo(int x,int N); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 76cd959..3b9e505 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,9 +33,6 @@ ESP32Time rtc(3600); void setup() { Serial.begin(115200); -#ifdef ARDUINO_LOLIN_S3 - delay(2500); -#endif #ifdef ARDUINO_ESP32S3_DEV pinMode(LED_BUILTIN, OUTPUT); diff --git a/src/screens/time.cpp b/src/screens/time.cpp index dc8fcec..1d56150 100644 --- a/src/screens/time.cpp +++ b/src/screens/time.cpp @@ -26,6 +26,10 @@ void TimeScreen::onNewMinute() { TimeScreen::showScreen(); } +void TimeScreen::onActivate() { + TimeScreen::showScreen(); +} + std::array TimeScreen::getEpdContent() { return TimeScreen::epdContent; } diff --git a/src/screens/time.hpp b/src/screens/time.hpp index 21fbe91..1ee2a0c 100644 --- a/src/screens/time.hpp +++ b/src/screens/time.hpp @@ -15,6 +15,7 @@ class TimeScreen { static void init(); static void showScreen(); static void onNewMinute(); + static void onActivate(); static std::array getEpdContent(); static TimeScreen* getInstance(); }; \ No newline at end of file diff --git a/src/shared.hpp b/src/shared.hpp index 8569ff8..6f9143d 100644 --- a/src/shared.hpp +++ b/src/shared.hpp @@ -34,6 +34,7 @@ extern uint32_t moment; #ifndef NO_MCP extern Adafruit_MCP23X17 mcp; +extern const int MCP_INT_PIN; #endif #ifdef WITH_RGB_LED extern Adafruit_NeoPixel pixels; diff --git a/src/tasks/button.cpp b/src/tasks/button.cpp index 8d8eb68..c7bc515 100644 --- a/src/tasks/button.cpp +++ b/src/tasks/button.cpp @@ -1,30 +1,68 @@ +/** + * Button 1: No functionality + * Button 2: Next Screen + * Button 3: Previous Screen + * Button 4: Queue full EPD update +*/ + #include "button.hpp" #ifndef NO_MCP TaskHandle_t buttonTaskHandle = NULL; // Define a type for the event callback std::vector buttonEventCallbacks; // Define a vector to hold multiple event callbacks - +volatile boolean buttonPressed = false; void buttonTask(void *parameter) { while (1) { - for (int i = 0; i < 4; i++) + if (!digitalRead(MCP_INT_PIN)) { - if (!mcp.digitalRead(i)) - { - Serial.println("Button " + String(i) + " Pressed!"); - delay(250); + uint pin = mcp.getLastInterruptPin(); + if (pin == 3) { + xTaskCreate(fullRefresh, "FullRefresh", 2048, NULL, 1, NULL); } + else if (pin == 1) + { + nextScreen(); + } + else if (pin == 2) + { + previousScreen(); + } + + vTaskDelay(250); // debounce + mcp.clearInterrupts(); // clear } vTaskDelay(pdMS_TO_TICKS(250)); } } +void IRAM_ATTR handleButtonInterrupt() +{ + buttonPressed = true; + // Serial.println("ISR"); + // uint pin = mcp.getLastInterruptPin(); + + // if (pin == 1) + // { + // nextScreen(); + // } + // else if (pin == 2) + // { + // previousScreen(); + // } + // vTaskDelay(pdMS_TO_TICKS(250)); + + // mcp.clearInterrupts(); +} + void setupButtonTask() { - xTaskCreate(buttonTask, "MinuteTask", 2048, NULL, 1, &buttonTaskHandle); // Create the FreeRTOS task + xTaskCreate(buttonTask, "ButtonTask", 4096, NULL, 1, &buttonTaskHandle); // Create the FreeRTOS task + // Use interrupt instead of task + // attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, FALLING); } void registerNewButtonCallback(EventCallback cb) diff --git a/src/tasks/button.hpp b/src/tasks/button.hpp index 0dae2bc..644fe82 100644 --- a/src/tasks/button.hpp +++ b/src/tasks/button.hpp @@ -7,6 +7,7 @@ #include #include #include "shared.hpp" +#include "lib/functions.hpp" extern TaskHandle_t buttonTaskHandle; @@ -14,4 +15,6 @@ extern TaskHandle_t buttonTaskHandle; void buttonTask(void *pvParameters); void setupButtonTask(); void registerNewButtonCallback(EventCallback cb); +void IRAM_ATTR handleButtonInterrupt(); + #endif \ No newline at end of file diff --git a/src/tasks/epd.cpp b/src/tasks/epd.cpp index 3bde4e0..ce8e8be 100644 --- a/src/tasks/epd.cpp +++ b/src/tasks/epd.cpp @@ -2,15 +2,14 @@ #ifdef IS_S3 // reversed -const int EPD_CS[7] = {17, 21, 33, 10, 6, 4, 2}; -const int EPD_BUSY[7] = {16, 18, 37, 9, 7, 5, 3}; -const int EPD_RESET_MPD[7] = {14, 13, 12, 11, 10, 9, 8}; +// const int EPD_CS[7] = {17, 21, 33, 10, 6, 4, 2}; +// const int EPD_BUSY[7] = {16, 18, 37, 9, 7, 5, 3}; +// const int EPD_RESET_MPD[7] = {14, 13, 12, 11, 10, 9, 8}; + +const int EPD_CS[7] = {2, 4, 6, 10, 33, 21, 17}; +const int EPD_BUSY[7] = {3, 5, 7, 9, 37, 18, 16}; +const int EPD_RESET_MPD[7] = {8, 9, 10, 11, 12, 13, 14}; -//const int EPD_CS[7] = {2, 4, 6, 10, 33, 21, 17}; -//const int EPD_BUSY[7] = {3, 5, 7, 9, 37, 18, 16}; -//const int EPD_RESET_MPD[7] = {8, 9, 10, 11, 12, 13, 14}; -// const int EPD_CS[7] = {2, 4, 10, 38, 34, 21, 17}; -// const int EPD_BUSY[7] = {3, 5, 9, 36, 35, 18, 16}; const int EPD_DC = 14; const int RST_PIN = 15; #elif defined(IS_S2) @@ -90,6 +89,7 @@ void setupDisplays() void resetAllDisplays() { + #ifdef NO_MCP digitalWrite(RST_PIN, HIGH); pinMode(RST_PIN, OUTPUT); delay(20); @@ -97,16 +97,11 @@ void resetAllDisplays() delay(20); digitalWrite(RST_PIN, HIGH); delay(200); - - // for (int i = 8; i < 16; i++) { - // mcp.digitalWrite(i, HIGH); - // mcp.pinMode(i, OUTPUT); - // delay(20); - // mcp.digitalWrite(i, LOW); - // delay(20); - // mcp.digitalWrite(i, HIGH); - // delay(200); - // } + #else + for (int i = 0; i < displaySize; i++) { + resetSingleDisplay(i); + } + #endif NO_MCP } void resetSingleDisplay(int i) @@ -318,10 +313,8 @@ void updateDisplay(void *pvParameters) if (epdContent[epdIndex].compareTo(currentEpdContent[epdIndex]) != 0) { currentEpdContent[epdIndex] = epdContent[epdIndex]; -// resetSingleDisplay(epdIndex); #ifndef NO_MCP displays[epdIndex].init(0, false); - delay(displays[epdIndex].epd2.power_on_time); resetSingleDisplay(epdIndex); #endif // displays[epdIndex].init(0, false); @@ -344,7 +337,6 @@ void updateDisplay(void *pvParameters) } displays[epdIndex].display(updatePartial); - // displays[epdIndex].powerOff(); displays[epdIndex].hibernate(); #endif } @@ -356,9 +348,8 @@ void showSetupQr(String ssid, String password) { int displayIndex = 6; - const String text = "WIFI:S:" + ssid + ";T:WPA;P:" + password + ";;"; // User-supplied text + const String text = "WIFI:S:" + ssid + ";T:WPA;P:" + password + ";;"; -// genQrCode(text, &qrcode); uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX]; bool ok = qrcodegen_encodeText(text.c_str(), tempBuffer, qrcode, qrcodegen_Ecc_LOW, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true); @@ -367,8 +358,7 @@ void showSetupQr(String ssid, String password) const int padding = floor(float(displays[displayIndex].width() - (size * 4)) / 2); const int paddingY = floor(float(displays[displayIndex].height() - (size * 4)) / 2); - // displays[displayIndex].setRotation(0); - // displays[displayIndex].setFullWindow(); + displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height()); displays[displayIndex].firstPage(); @@ -439,8 +429,6 @@ void showSetupQr(String ssid, String password) for (int i = 1; i < displaySize; (i = i+2)) { displays[i].setPartialWindow(0, 0, displays[i].width(), displays[i].height()); -// displays[i].firstPage(); - displays[i].fillScreen(GxEPD_WHITE); displays[i].display(true); }