diff --git a/data b/data index 65b6df5..2ce53eb 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 65b6df5d92f3f936e823a5c1413681aee85ab0c5 +Subproject commit 2ce53eb499e00a990be5cb0ea078e146f467ceb4 diff --git a/src/lib/button_handler.cpp b/src/lib/button_handler.cpp index ff7e259..bd4204d 100644 --- a/src/lib/button_handler.cpp +++ b/src/lib/button_handler.cpp @@ -1,7 +1,8 @@ #include "button_handler.hpp" -TaskHandle_t buttonTaskHandle = NULL; -ButtonState buttonStates[4]; +// Initialize static members +TaskHandle_t ButtonHandler::buttonTaskHandle = NULL; +ButtonState ButtonHandler::buttonStates[4] = {}; #ifdef IS_BTCLOCK_V8 #define BTN_1 256 @@ -15,7 +16,7 @@ ButtonState buttonStates[4]; #define BTN_4 256 #endif -void buttonTask(void *parameter) { +void ButtonHandler::buttonTask(void *parameter) { while (1) { ulTaskNotifyTake(pdTRUE, portMAX_DELAY); @@ -48,16 +49,6 @@ void buttonTask(void *parameter) { } } } - - // Check for long press on pressed buttons - for (int i = 0; i < 4; i++) { - if (buttonStates[i].isPressed && !buttonStates[i].longPressHandled) { - if ((currentTime - buttonStates[i].pressStartTime) >= longPressDelay) { - handleLongPress(i); - buttonStates[i].longPressHandled = true; - } - } - } } // Clear interrupt state @@ -68,56 +59,34 @@ void buttonTask(void *parameter) { } } -void handleButtonPress(int buttonIndex) { +void ButtonHandler::handleButtonPress(int buttonIndex) { TickType_t currentTime = xTaskGetTickCount(); ButtonState &state = buttonStates[buttonIndex]; if ((currentTime - state.lastPressTime) >= debounceDelay) { state.isPressed = true; - state.pressStartTime = currentTime; - state.longPressHandled = false; - - // Check for double click - if ((currentTime - state.lastPressTime) <= doubleClickDelay) { - state.clickCount++; - if (state.clickCount == 2) { - handleDoubleClick(buttonIndex); - state.clickCount = 0; - } - } else { - state.clickCount = 1; - } - state.lastPressTime = currentTime; } } -void handleButtonRelease(int buttonIndex) { - TickType_t currentTime = xTaskGetTickCount(); +void ButtonHandler::handleButtonRelease(int buttonIndex) { ButtonState &state = buttonStates[buttonIndex]; - state.isPressed = false; + if (!state.isPressed) return; // Ignore if button wasn't pressed - // If this wasn't a long press or double click, handle as single click - if (!state.longPressHandled && state.clickCount == 1 && - (currentTime - state.pressStartTime) < longPressDelay) { - handleSingleClick(buttonIndex); - state.clickCount = 0; - } + state.isPressed = false; + handleSingleClick(buttonIndex); } -// Button action handlers -void handleSingleClick(int buttonIndex) { +void ButtonHandler::handleSingleClick(int buttonIndex) { switch (buttonIndex) { case 0: toggleTimerActive(); break; case 1: - Serial.println("Button 2 single click"); ScreenHandler::nextScreen(); break; case 2: - Serial.println("Button 3 single click"); ScreenHandler::previousScreen(); break; case 3: @@ -126,15 +95,7 @@ void handleSingleClick(int buttonIndex) { } } -void handleDoubleClick(int buttonIndex) { - Serial.printf("Button %d double clicked\n", buttonIndex + 1); -} - -void handleLongPress(int buttonIndex) { - Serial.printf("Button %d long press detected\n", buttonIndex + 1); -} - -void IRAM_ATTR handleButtonInterrupt() { +void IRAM_ATTR ButtonHandler::handleButtonInterrupt() { BaseType_t xHigherPriorityTaskWoken = pdFALSE; xTaskNotifyFromISR(buttonTaskHandle, 0, eNoAction, &xHigherPriorityTaskWoken); if (xHigherPriorityTaskWoken == pdTRUE) { @@ -142,7 +103,7 @@ void IRAM_ATTR handleButtonInterrupt() { } } -void setupButtonTask() { +void ButtonHandler::setup() { xTaskCreate(buttonTask, "ButtonTask", 3072, NULL, tskIDLE_PRIORITY, &buttonTaskHandle); attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, FALLING); diff --git a/src/lib/button_handler.hpp b/src/lib/button_handler.hpp index f3f41a1..17fab6b 100644 --- a/src/lib/button_handler.hpp +++ b/src/lib/button_handler.hpp @@ -6,24 +6,6 @@ #include "lib/shared.hpp" #include "lib/timers.hpp" -extern TaskHandle_t buttonTaskHandle; - -// Task and setup functions -void buttonTask(void *pvParameters); -void IRAM_ATTR handleButtonInterrupt(); -void setupButtonTask(); - -// Individual button handlers -void handleButton1(); -void handleButton2(); -void handleButton3(); -void handleButton4(); - -// New features -const TickType_t debounceDelay = pdMS_TO_TICKS(50); -const TickType_t doubleClickDelay = pdMS_TO_TICKS(300); // Maximum time between clicks for double click -const TickType_t longPressDelay = pdMS_TO_TICKS(1000); // Time to hold for long press - // Track timing for each button struct ButtonState { TickType_t lastPressTime = 0; @@ -33,22 +15,40 @@ struct ButtonState { bool longPressHandled = false; }; -extern ButtonState buttonStates[4]; +class ButtonHandler { +private: + static const TickType_t debounceDelay = pdMS_TO_TICKS(50); + static const TickType_t doubleClickDelay = pdMS_TO_TICKS(1000); // Maximum time between clicks for double click + static const TickType_t longPressDelay = pdMS_TO_TICKS(1500); // Time to hold for long press -#ifdef IS_BTCLOCK_V8 -#define BTN_1 256 -#define BTN_2 512 -#define BTN_3 1024 -#define BTN_4 2048 -#else -#define BTN_1 2048 -#define BTN_2 1024 -#define BTN_3 512 -#define BTN_4 256 -#endif + static ButtonState buttonStates[4]; + static TaskHandle_t buttonTaskHandle; -void handleButtonPress(int buttonIndex); -void handleButtonRelease(int buttonIndex); -void handleSingleClick(int buttonIndex); -void handleDoubleClick(int buttonIndex); -void handleLongPress(int buttonIndex); + // Button handlers + static void handleButtonPress(int buttonIndex); + static void handleButtonRelease(int buttonIndex); + static void handleSingleClick(int buttonIndex); + static void handleDoubleClick(int buttonIndex); + static void handleLongPress(int buttonIndex); + + // Task function + static void buttonTask(void *pvParameters); + +public: + static void setup(); + static void IRAM_ATTR handleButtonInterrupt(); + static void suspendTask() { if (buttonTaskHandle != NULL) vTaskSuspend(buttonTaskHandle); } + static void resumeTask() { if (buttonTaskHandle != NULL) vTaskResume(buttonTaskHandle); } + + #ifdef IS_BTCLOCK_V8 + static const uint16_t BTN_1 = 256; + static const uint16_t BTN_2 = 512; + static const uint16_t BTN_3 = 1024; + static const uint16_t BTN_4 = 2048; + #else + static const uint16_t BTN_1 = 2048; + static const uint16_t BTN_2 = 1024; + static const uint16_t BTN_3 = 512; + static const uint16_t BTN_4 = 256; + #endif +}; diff --git a/src/lib/config.cpp b/src/lib/config.cpp index 4ae7e4b..4c7303c 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -100,7 +100,7 @@ void setup() setupMiningPoolStatsFetchTask(); } - setupButtonTask(); + ButtonHandler::setup(); setupOTA(); waitUntilNoneBusy(); @@ -482,7 +482,7 @@ void setupHardware() Serial.printf("Error setting pin %d to input pull up\n", i); } // Enable interrupt on CHANGE for each pin - if (!mcp1.enableInterrupt(i, FALLING)) { + if (!mcp1.enableInterrupt(i, CHANGE)) { Serial.printf("Error enabling interrupt for pin %d\n", i); } } diff --git a/src/lib/ota.cpp b/src/lib/ota.cpp index 05c45e1..0d6a57f 100644 --- a/src/lib/ota.cpp +++ b/src/lib/ota.cpp @@ -64,11 +64,10 @@ void onOTAStart() // Stop or suspend all tasks // vTaskSuspend(priceUpdateTaskHandle); // vTaskSuspend(blockUpdateTaskHandle); - vTaskSuspend(workerTaskHandle); vTaskSuspend(taskScreenRotateTaskHandle); - -// vTaskSuspend(ledTaskHandle); - vTaskSuspend(buttonTaskHandle); + vTaskSuspend(workerTaskHandle); + vTaskSuspend(eventSourceTaskHandle); + ButtonHandler::suspendTask(); // stopWebServer(); stopBlockNotify();