diff --git a/Platformio/HAL/HardwareModules/KeyPressAbstract.hpp b/Platformio/HAL/HardwareModules/KeyPressAbstract.hpp index 2b10f0a..6d73ac4 100644 --- a/Platformio/HAL/HardwareModules/KeyPressAbstract.hpp +++ b/Platformio/HAL/HardwareModules/KeyPressAbstract.hpp @@ -35,17 +35,19 @@ public: Aux1, Aux2, Aux3, - Aux4 + Aux4, + INVALID }; class KeyEvent { public: - enum class Type { Press, Release }; + enum class Type { Press, Release, INVALID }; + KeyEvent() = default; KeyEvent(const KeyId aId, const Type aType) : mId(aId), mType(aType) {} - const KeyId mId; - const Type mType; + KeyId mId = KeyId::INVALID; + Type mType = Type::INVALID; }; KeyPressAbstract(); diff --git a/Platformio/HAL/Targets/ESP32/keys/keys.cpp b/Platformio/HAL/Targets/ESP32/keys/keys.cpp index f08b212..27b5936 100644 --- a/Platformio/HAL/Targets/ESP32/keys/keys.cpp +++ b/Platformio/HAL/Targets/ESP32/keys/keys.cpp @@ -1,25 +1,61 @@ #include "keys.hpp" -Keys::Keys() {} -void Keys::HandleKeyPresses(){ +Keys::Keys() { + static constexpr auto MaxQueueableKeyPresses = 5; + mKeyPressQueueHandle = xQueueCreate(MaxQueueableKeyPresses, sizeof(KeyEvent)); + xTaskCreate(KeyGrabberTask, "KeyGrabber", 1024, this, 1, &mKeyGrabbingTask); + xTaskCreate(KeyProccessor, "KeyProccessor", 4096, this, 1, &mKeyHandlingTask); +} +void Keys::KeyGrabberTask(void *aSelf) { + auto self = reinterpret_cast(aSelf); + while (true) { + self->GrabKeys(); + vTaskDelay(5 / portTICK_PERIOD_MS); // 5 ms between key grabs + } +} +void Keys::KeyProccessor(void *aSelf) { + auto self = reinterpret_cast(aSelf); + while (true) { + self->HandleKeyPresses(); + vTaskDelay(50 / portTICK_PERIOD_MS); + } +} + +void Keys::HandleKeyPresses() { + KeyPressAbstract::KeyEvent eventToHandle; + while (xQueueReceive(mKeyPressQueueHandle, &eventToHandle, 0) == pdTRUE) { + if (mKeyEventHandler) { + mKeyEventHandler(eventToHandle); + } + } }; -void Keys::QueueKeyEvent(KeyEvent aJustOccuredKeyEvent){ +void Keys::QueueKeyEvent(KeyEvent aJustOccuredKeyEvent) { + BaseType_t higherPriorityTaskAwoke; + xQueueSendFromISR(mKeyPressQueueHandle, &aJustOccuredKeyEvent, + &higherPriorityTaskAwoke); }; void Keys::GrabKeys() { - customKeypad.getKey(); // Populate key list - for (int i = 0; i < LIST_MAX; - i++) { // Handle multiple keys (Not really necessary in this case) + if (!customKeypad.getKeys()) { + return; // no activity return early. + } + for (int i = 0; i < LIST_MAX; i++) { if (customKeypad.key[i].kstate == PRESSED || - customKeypad.key[i].kstate == HOLD) { + customKeypad.key[i].kstate == RELEASED) { // May need to think about resetting sleep timer in key handler.... // standbyTimer = - // sleepTimeout; // Reset the sleep timer when a button is pressed - int keyCode = customKeypad.key[i].kcode; - // Queue Keys here!! - Serial.println(customKeypad.key[i].kchar); + // sleepTimeout; // Reset the sleep timer when a button is + // pressed + auto eventType = customKeypad.key[i].kstate == PRESSED + ? KeyEvent::Type::Press + : KeyEvent::Type::Release; + const auto keyChar = customKeypad.key[i].kchar; + auto stateChange = customKeypad.key[i].stateChanged; + if (charKeyToKeyIds.count(keyChar) > 0 && stateChange) { + QueueKeyEvent(KeyEvent(charKeyToKeyIds.at(keyChar), eventType)); + } } } } \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/keys/keys.hpp b/Platformio/HAL/Targets/ESP32/keys/keys.hpp index 9fa58c4..98cc13e 100644 --- a/Platformio/HAL/Targets/ESP32/keys/keys.hpp +++ b/Platformio/HAL/Targets/ESP32/keys/keys.hpp @@ -2,6 +2,7 @@ #include "KeyPressAbstract.hpp" #include "omoteconfig.h" #include // modified for inverted logic +#include class Keys : public KeyPressAbstract { public: @@ -13,6 +14,9 @@ protected: void GrabKeys(); private: + static void KeyGrabberTask(void *aSelf); + static void KeyProccessor(void *aSelf); + QueueHandle_t mKeyPressQueueHandle; TaskHandle_t mKeyGrabbingTask; TaskHandle_t mKeyHandlingTask; @@ -23,11 +27,46 @@ private: // define the symbols on the buttons of the keypads char hexaKeys[ROWS][COLS] = { {'s', '^', '-', 'm', 'r'}, // source, channel+, Volume-, mute, record - {'i', 'r', '+', 'k', 'd'}, // info, right, Volume+, OK, down + {'i', 'R', '+', 'k', 'd'}, // info, right, Volume+, OK, down {'4', 'v', '1', '3', '2'}, // blue, channel-, red, yellow, green - {'>', 'o', 'b', 'u', 'l'}, // forward, off, back, up, left + {'>', 'o', 'b', 'u', 'L'}, // forward, off, back, up, left {'?', 'p', 'c', '<', '='} // ?, play, config, rewind, stop }; + // TODO what is '?' lol + + // TODO Should be able to optomize this out by reordering Ids at some point + // or even using interrupts to trigger key press queueing + static inline const std::map charKeyToKeyIds{ + {'o', KeyId::Power}, + // Top 4 Buttons left to right + {'=', KeyId::Stop}, + {'<', KeyId::Rewind}, + {'p', KeyId::Play}, + {'>', KeyId::FastForward}, + // Buttons around D Pad + {'c', KeyId::Menu}, + {'i', KeyId::Info}, + {'b', KeyId::Back}, + {'s', KeyId::Source}, + // D Pad + {'u', KeyId::Up}, + {'d', KeyId::Down}, + {'L', KeyId::Left}, + {'R', KeyId::Right}, + {'k', KeyId::Center}, + // Volume Channel and 2 between + {'+', KeyId::VolUp}, + {'-', KeyId::VolDown}, + {'m', KeyId::Mute}, + {'r', KeyId::Record}, + {'^', KeyId::ChannelUp}, + {'v', KeyId::ChannelDown}, + // Bottom 4 buttons left to right + {'1', KeyId::Aux1}, + {'2', KeyId::Aux2}, + {'3', KeyId::Aux3}, + {'4', KeyId::Aux4}}; + byte rowPins[ROWS] = {SW_A, SW_B, SW_C, SW_D, SW_E}; // connect to the row pinouts of the keypad byte colPins[COLS] = {SW_1, SW_2, SW_3, SW_4, diff --git a/Platformio/OmoteUI/core/page/SettingsPage.cpp b/Platformio/OmoteUI/core/page/SettingsPage.cpp index 7ae354c..e715df6 100644 --- a/Platformio/OmoteUI/core/page/SettingsPage.cpp +++ b/Platformio/OmoteUI/core/page/SettingsPage.cpp @@ -3,7 +3,8 @@ using namespace UI::Page; -SettingsPage::SettingsPage() : Base(ID::Pages::Settings) { +SettingsPage::SettingsPage(std::shared_ptr aHardware) + : Base(ID::Pages::Settings), mHardware(aHardware) { SetBgColor(lv_color_make(255, 0, 0)); } diff --git a/Platformio/OmoteUI/core/page/SettingsPage.hpp b/Platformio/OmoteUI/core/page/SettingsPage.hpp index c2d5f7b..759bacd 100644 --- a/Platformio/OmoteUI/core/page/SettingsPage.hpp +++ b/Platformio/OmoteUI/core/page/SettingsPage.hpp @@ -1,9 +1,10 @@ +#include "HardwareAbstract.hpp" #include "PageBase.hpp" namespace UI::Page { class SettingsPage : public Base { public: - SettingsPage(); + SettingsPage(std::shared_ptr aHardware = nullptr); bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override; @@ -13,5 +14,6 @@ protected: void OnShow() override; std::vector sliders; + std::shared_ptr mHardware; }; } // namespace UI::Page diff --git a/Platformio/OmoteUI/core/screen/HomeScreen.cpp b/Platformio/OmoteUI/core/screen/HomeScreen.cpp index d8a43c2..855beaf 100644 --- a/Platformio/OmoteUI/core/screen/HomeScreen.cpp +++ b/Platformio/OmoteUI/core/screen/HomeScreen.cpp @@ -3,16 +3,17 @@ using namespace UI::Screen; -HomeScreen::HomeScreen() - : Base(UI::ID::Screens::Home), mTabView(ID(ID::Pages::INVALID_PAGE_ID)) { +HomeScreen::HomeScreen(std::shared_ptr aHardware) + : Base(UI::ID::Screens::Home), mHardware(aHardware), + mTabView(ID(ID::Pages::INVALID_PAGE_ID)) { SetBgColor(lv_color_black()); SetPushAnimation(LV_SCR_LOAD_ANIM_FADE_IN); AddElement(&mTabView); // Adds Tabview to Homescreen // Adds pages to the Tab view - mTabView.AddTab(std::make_unique(), "Settings"); - mTabView.AddTab(std::make_unique(), "Settings1"); + mTabView.AddTab(std::make_unique(aHardware), "Settings"); + mTabView.AddTab(std::make_unique(aHardware), "Settings1"); } void HomeScreen::SetBgColor(lv_color_t value, lv_style_selector_t selector) { diff --git a/Platformio/OmoteUI/core/screen/HomeScreen.hpp b/Platformio/OmoteUI/core/screen/HomeScreen.hpp index b211d14..2646bde 100644 --- a/Platformio/OmoteUI/core/screen/HomeScreen.hpp +++ b/Platformio/OmoteUI/core/screen/HomeScreen.hpp @@ -1,4 +1,5 @@ #pragma once +#include "HardwareAbstract.hpp" #include "PageBase.hpp" #include "ScreenBase.hpp" #include "TabView.hpp" @@ -7,7 +8,7 @@ namespace UI::Screen { class HomeScreen : public Base { public: - HomeScreen(); + HomeScreen(std::shared_ptr aHardware = nullptr); void SetBgColor(lv_color_t value, lv_style_selector_t selector = LV_PART_MAIN) override; @@ -19,6 +20,7 @@ protected: private: Page::TabView mTabView; + std::shared_ptr mHardware = nullptr; }; } // namespace UI::Screen \ No newline at end of file diff --git a/Platformio/src/main.cpp b/Platformio/src/main.cpp index ff6aa36..708aebf 100644 --- a/Platformio/src/main.cpp +++ b/Platformio/src/main.cpp @@ -1,24 +1,25 @@ // OMOTE firmware for ESP32 // 2023 Maximilian Kern +#include "BasicUI.hpp" #include "HardwareRevX.hpp" -#include "OmoteUI.hpp" #include "omoteconfig.h" #include std::shared_ptr hal = nullptr; +std::shared_ptr ui = nullptr; void setup() { hal = HardwareRevX::getInstance(); hal->init(); - auto ui = UI::Basic::OmoteUI::getInstance(hal); - ui->layout_UI(); + auto ui = UI::BasicUI(hal); + // ui->layout_UI(); lv_timer_handler(); // Run the LVGL UI once before the loop takes over } void loop() { - HardwareRevX::getInstance()->loopHandler(); - UI::Basic::OmoteUI::getInstance()->loopHandler(); + hal->loopHandler(); + ui->loopHandler(); } \ No newline at end of file