fully implement Key press handeling in HAL for esp32 hardware and switch hardware to use the refactored UI
make UI add widgets on button presses as a demo
This commit is contained in:
parent
7434f0b4da
commit
4a5c83c8b9
8 changed files with 113 additions and 29 deletions
|
@ -35,17 +35,19 @@ public:
|
||||||
Aux1,
|
Aux1,
|
||||||
Aux2,
|
Aux2,
|
||||||
Aux3,
|
Aux3,
|
||||||
Aux4
|
Aux4,
|
||||||
|
INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
class KeyEvent {
|
class KeyEvent {
|
||||||
public:
|
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) {}
|
KeyEvent(const KeyId aId, const Type aType) : mId(aId), mType(aType) {}
|
||||||
|
|
||||||
const KeyId mId;
|
KeyId mId = KeyId::INVALID;
|
||||||
const Type mType;
|
Type mType = Type::INVALID;
|
||||||
};
|
};
|
||||||
|
|
||||||
KeyPressAbstract();
|
KeyPressAbstract();
|
||||||
|
|
|
@ -1,25 +1,61 @@
|
||||||
#include "keys.hpp"
|
#include "keys.hpp"
|
||||||
|
|
||||||
Keys::Keys() {}
|
Keys::Keys() {
|
||||||
void Keys::HandleKeyPresses(){
|
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<Keys *>(aSelf);
|
||||||
|
while (true) {
|
||||||
|
self->GrabKeys();
|
||||||
|
vTaskDelay(5 / portTICK_PERIOD_MS); // 5 ms between key grabs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Keys::KeyProccessor(void *aSelf) {
|
||||||
|
auto self = reinterpret_cast<Keys *>(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() {
|
void Keys::GrabKeys() {
|
||||||
customKeypad.getKey(); // Populate key list
|
if (!customKeypad.getKeys()) {
|
||||||
for (int i = 0; i < LIST_MAX;
|
return; // no activity return early.
|
||||||
i++) { // Handle multiple keys (Not really necessary in this case)
|
}
|
||||||
|
for (int i = 0; i < LIST_MAX; i++) {
|
||||||
if (customKeypad.key[i].kstate == PRESSED ||
|
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....
|
// May need to think about resetting sleep timer in key handler....
|
||||||
// standbyTimer =
|
// standbyTimer =
|
||||||
// sleepTimeout; // Reset the sleep timer when a button is pressed
|
// sleepTimeout; // Reset the sleep timer when a button is
|
||||||
int keyCode = customKeypad.key[i].kcode;
|
// pressed
|
||||||
// Queue Keys here!!
|
auto eventType = customKeypad.key[i].kstate == PRESSED
|
||||||
Serial.println(customKeypad.key[i].kchar);
|
? 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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
#include "KeyPressAbstract.hpp"
|
#include "KeyPressAbstract.hpp"
|
||||||
#include "omoteconfig.h"
|
#include "omoteconfig.h"
|
||||||
#include <Keypad.h> // modified for inverted logic
|
#include <Keypad.h> // modified for inverted logic
|
||||||
|
#include <map>
|
||||||
|
|
||||||
class Keys : public KeyPressAbstract {
|
class Keys : public KeyPressAbstract {
|
||||||
public:
|
public:
|
||||||
|
@ -13,6 +14,9 @@ protected:
|
||||||
void GrabKeys();
|
void GrabKeys();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void KeyGrabberTask(void *aSelf);
|
||||||
|
static void KeyProccessor(void *aSelf);
|
||||||
|
|
||||||
QueueHandle_t mKeyPressQueueHandle;
|
QueueHandle_t mKeyPressQueueHandle;
|
||||||
TaskHandle_t mKeyGrabbingTask;
|
TaskHandle_t mKeyGrabbingTask;
|
||||||
TaskHandle_t mKeyHandlingTask;
|
TaskHandle_t mKeyHandlingTask;
|
||||||
|
@ -23,11 +27,46 @@ private:
|
||||||
// define the symbols on the buttons of the keypads
|
// define the symbols on the buttons of the keypads
|
||||||
char hexaKeys[ROWS][COLS] = {
|
char hexaKeys[ROWS][COLS] = {
|
||||||
{'s', '^', '-', 'm', 'r'}, // source, channel+, Volume-, mute, record
|
{'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
|
{'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
|
{'?', '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<char, KeyId> 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,
|
byte rowPins[ROWS] = {SW_A, SW_B, SW_C, SW_D,
|
||||||
SW_E}; // connect to the row pinouts of the keypad
|
SW_E}; // connect to the row pinouts of the keypad
|
||||||
byte colPins[COLS] = {SW_1, SW_2, SW_3, SW_4,
|
byte colPins[COLS] = {SW_1, SW_2, SW_3, SW_4,
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
using namespace UI::Page;
|
using namespace UI::Page;
|
||||||
|
|
||||||
SettingsPage::SettingsPage() : Base(ID::Pages::Settings) {
|
SettingsPage::SettingsPage(std::shared_ptr<HardwareAbstract> aHardware)
|
||||||
|
: Base(ID::Pages::Settings), mHardware(aHardware) {
|
||||||
SetBgColor(lv_color_make(255, 0, 0));
|
SetBgColor(lv_color_make(255, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
#include "HardwareAbstract.hpp"
|
||||||
#include "PageBase.hpp"
|
#include "PageBase.hpp"
|
||||||
|
|
||||||
namespace UI::Page {
|
namespace UI::Page {
|
||||||
class SettingsPage : public Base {
|
class SettingsPage : public Base {
|
||||||
public:
|
public:
|
||||||
SettingsPage();
|
SettingsPage(std::shared_ptr<HardwareAbstract> aHardware = nullptr);
|
||||||
|
|
||||||
bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
|
bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
|
||||||
|
|
||||||
|
@ -13,5 +14,6 @@ protected:
|
||||||
void OnShow() override;
|
void OnShow() override;
|
||||||
|
|
||||||
std::vector<Widget::Base *> sliders;
|
std::vector<Widget::Base *> sliders;
|
||||||
|
std::shared_ptr<HardwareAbstract> mHardware;
|
||||||
};
|
};
|
||||||
} // namespace UI::Page
|
} // namespace UI::Page
|
||||||
|
|
|
@ -3,16 +3,17 @@
|
||||||
|
|
||||||
using namespace UI::Screen;
|
using namespace UI::Screen;
|
||||||
|
|
||||||
HomeScreen::HomeScreen()
|
HomeScreen::HomeScreen(std::shared_ptr<HardwareAbstract> aHardware)
|
||||||
: Base(UI::ID::Screens::Home), mTabView(ID(ID::Pages::INVALID_PAGE_ID)) {
|
: Base(UI::ID::Screens::Home), mHardware(aHardware),
|
||||||
|
mTabView(ID(ID::Pages::INVALID_PAGE_ID)) {
|
||||||
SetBgColor(lv_color_black());
|
SetBgColor(lv_color_black());
|
||||||
SetPushAnimation(LV_SCR_LOAD_ANIM_FADE_IN);
|
SetPushAnimation(LV_SCR_LOAD_ANIM_FADE_IN);
|
||||||
|
|
||||||
AddElement(&mTabView); // Adds Tabview to Homescreen
|
AddElement(&mTabView); // Adds Tabview to Homescreen
|
||||||
|
|
||||||
// Adds pages to the Tab view
|
// Adds pages to the Tab view
|
||||||
mTabView.AddTab(std::make_unique<Page::SettingsPage>(), "Settings");
|
mTabView.AddTab(std::make_unique<Page::SettingsPage>(aHardware), "Settings");
|
||||||
mTabView.AddTab(std::make_unique<Page::SettingsPage>(), "Settings1");
|
mTabView.AddTab(std::make_unique<Page::SettingsPage>(aHardware), "Settings1");
|
||||||
}
|
}
|
||||||
|
|
||||||
void HomeScreen::SetBgColor(lv_color_t value, lv_style_selector_t selector) {
|
void HomeScreen::SetBgColor(lv_color_t value, lv_style_selector_t selector) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "HardwareAbstract.hpp"
|
||||||
#include "PageBase.hpp"
|
#include "PageBase.hpp"
|
||||||
#include "ScreenBase.hpp"
|
#include "ScreenBase.hpp"
|
||||||
#include "TabView.hpp"
|
#include "TabView.hpp"
|
||||||
|
@ -7,7 +8,7 @@ namespace UI::Screen {
|
||||||
|
|
||||||
class HomeScreen : public Base {
|
class HomeScreen : public Base {
|
||||||
public:
|
public:
|
||||||
HomeScreen();
|
HomeScreen(std::shared_ptr<HardwareAbstract> aHardware = nullptr);
|
||||||
|
|
||||||
void SetBgColor(lv_color_t value,
|
void SetBgColor(lv_color_t value,
|
||||||
lv_style_selector_t selector = LV_PART_MAIN) override;
|
lv_style_selector_t selector = LV_PART_MAIN) override;
|
||||||
|
@ -19,6 +20,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Page::TabView mTabView;
|
Page::TabView mTabView;
|
||||||
|
std::shared_ptr<HardwareAbstract> mHardware = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace UI::Screen
|
} // namespace UI::Screen
|
|
@ -1,24 +1,25 @@
|
||||||
// OMOTE firmware for ESP32
|
// OMOTE firmware for ESP32
|
||||||
// 2023 Maximilian Kern
|
// 2023 Maximilian Kern
|
||||||
|
|
||||||
|
#include "BasicUI.hpp"
|
||||||
#include "HardwareRevX.hpp"
|
#include "HardwareRevX.hpp"
|
||||||
#include "OmoteUI.hpp"
|
|
||||||
#include "omoteconfig.h"
|
#include "omoteconfig.h"
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
|
||||||
std::shared_ptr<HardwareRevX> hal = nullptr;
|
std::shared_ptr<HardwareRevX> hal = nullptr;
|
||||||
|
std::shared_ptr<UI::UIBase> ui = nullptr;
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
hal = HardwareRevX::getInstance();
|
hal = HardwareRevX::getInstance();
|
||||||
hal->init();
|
hal->init();
|
||||||
|
|
||||||
auto ui = UI::Basic::OmoteUI::getInstance(hal);
|
auto ui = UI::BasicUI(hal);
|
||||||
ui->layout_UI();
|
// ui->layout_UI();
|
||||||
|
|
||||||
lv_timer_handler(); // Run the LVGL UI once before the loop takes over
|
lv_timer_handler(); // Run the LVGL UI once before the loop takes over
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
HardwareRevX::getInstance()->loopHandler();
|
hal->loopHandler();
|
||||||
UI::Basic::OmoteUI::getInstance()->loopHandler();
|
ui->loopHandler();
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue