From f5c938d61fc648f8b4fc23d45de7e7c6f9153a93 Mon Sep 17 00:00:00 2001 From: Mitchell M Date: Fri, 10 Apr 2026 07:58:31 -0500 Subject: [PATCH] switch to event based input system (untested) --- main/drivers/CMakeLists.txt | 4 +- main/drivers/event_based_bottom_half.cpp | 326 ++++++++++++++++ main/drivers/inputs.cpp | 475 +++++++++++++++++++++++ main/drivers/inputs.hpp | 275 +++++++++++++ main/drivers/pins.h | 48 +++ 5 files changed, 1127 insertions(+), 1 deletion(-) create mode 100644 main/drivers/event_based_bottom_half.cpp create mode 100644 main/drivers/inputs.cpp create mode 100644 main/drivers/inputs.hpp create mode 100644 main/drivers/pins.h diff --git a/main/drivers/CMakeLists.txt b/main/drivers/CMakeLists.txt index fa0c42f..19df298 100644 --- a/main/drivers/CMakeLists.txt +++ b/main/drivers/CMakeLists.txt @@ -4,7 +4,9 @@ set(SOURCES "TM1640/TM1640.cpp" "SparkFunBQ27441/SparkFunBQ27441.cpp" "esp_lcd_ili9488/esp_lcd_ili9488.c" - "bottom_half.cpp" + # "bottom_half.cpp" + "event_based_bottom_half.cpp" + "inputs.cpp" "char_lcd.cpp" "game_timer.cpp" "i2c_lcd_pcf8574.c" diff --git a/main/drivers/event_based_bottom_half.cpp b/main/drivers/event_based_bottom_half.cpp new file mode 100644 index 0000000..194542a --- /dev/null +++ b/main/drivers/event_based_bottom_half.cpp @@ -0,0 +1,326 @@ +#include "bottom_half.h" +#include "inputs.hpp" + +#include + +static uint8_t reverse_4_bits(uint8_t value) { + return static_cast(((value & 0x1) << 3) | + ((value & 0x2) << 1) | + ((value & 0x4) >> 1) | + ((value & 0x8) >> 3)); +} + +static KeypadKey map_input_keypad_key(InputKeypadKey key) { + switch (key) { + case InputKeypadKey::K0: return KeypadKey::k0; + case InputKeypadKey::K1: return KeypadKey::k1; + case InputKeypadKey::K2: return KeypadKey::k2; + case InputKeypadKey::K3: return KeypadKey::k3; + case InputKeypadKey::K4: return KeypadKey::k4; + case InputKeypadKey::K5: return KeypadKey::k5; + case InputKeypadKey::K6: return KeypadKey::k6; + case InputKeypadKey::K7: return KeypadKey::k7; + case InputKeypadKey::K8: return KeypadKey::k8; + case InputKeypadKey::K9: return KeypadKey::k9; + case InputKeypadKey::A: return KeypadKey::ka; + case InputKeypadKey::B: return KeypadKey::kb; + case InputKeypadKey::C: return KeypadKey::kc; + case InputKeypadKey::D: return KeypadKey::kd; + case InputKeypadKey::STAR: return KeypadKey::star; + case InputKeypadKey::POUND: return KeypadKey::pound; + default: return KeypadKey::k0; + } +} + +static uint8_t get_fingerprint_touch_state() { + InputsState current = InputsController::get_input_state(); + return static_cast((current.touch_state >> 4) & 0x1); +} + +static bool touch_state_initialized = false; +static bool touch_state_last = false; + +static bool update_fingerprint_transition(bool want_pressed) { + bool current = get_fingerprint_touch_state(); + if (!touch_state_initialized) { + touch_state_last = current; + touch_state_initialized = true; + return false; + } + + bool transition = want_pressed ? (current && !touch_state_last) + : (!current && touch_state_last); + touch_state_last = current; + return transition; +} + +static std::array pending_switch_flips; +static size_t pending_switch_flip_count = 0; + +static void push_pending_switch_flip(const SwitchFlip& event) { + if (pending_switch_flip_count < pending_switch_flips.size()) { + pending_switch_flips[pending_switch_flip_count++] = event; + return; + } + + // Drop the oldest event if the buffer is full. + for (size_t i = 1; i < pending_switch_flips.size(); ++i) { + pending_switch_flips[i - 1] = pending_switch_flips[i]; + } + pending_switch_flips.back() = event; +} + +static bool pop_pending_switch_flip(bool want_up, SwitchFlip& out) { + for (size_t i = 0; i < pending_switch_flip_count; ++i) { + if (pending_switch_flips[i].is_up() == want_up) { + out = pending_switch_flips[i]; + for (size_t j = i + 1; j < pending_switch_flip_count; ++j) { + pending_switch_flips[j - 1] = pending_switch_flips[j]; + } + --pending_switch_flip_count; + return true; + } + } + return false; +} + +static void clear_pending_switch_flips() { + pending_switch_flip_count = 0; +} + +static std::array pending_switch_touches; +static size_t pending_switch_touch_count = 0; + +static void push_pending_switch_touch(const SwitchTouch& event) { + if (pending_switch_touch_count < pending_switch_touches.size()) { + pending_switch_touches[pending_switch_touch_count++] = event; + return; + } + + for (size_t i = 1; i < pending_switch_touches.size(); ++i) { + pending_switch_touches[i - 1] = pending_switch_touches[i]; + } + pending_switch_touches.back() = event; +} + +static bool pop_pending_switch_touch(bool want_touched, SwitchTouch& out) { + for (size_t i = 0; i < pending_switch_touch_count; ++i) { + if (pending_switch_touches[i].is_touched() == want_touched) { + out = pending_switch_touches[i]; + for (size_t j = i + 1; j < pending_switch_touch_count; ++j) { + pending_switch_touches[j - 1] = pending_switch_touches[j]; + } + --pending_switch_touch_count; + return true; + } + } + return false; +} + +static void clear_pending_switch_touches() { + pending_switch_touch_count = 0; +} + +void init_bottom_half() { + init_expander(); + clear_all_pressed_released(); +} + +void clear_all_pressed_released() { + InputsController::clear_all_events(); + clear_pending_switch_flips(); + clear_pending_switch_touches(); + touch_state_initialized = false; +} + +bool get_keypad_pressed(KeypadKey* kp) { + auto opt = InputsController::get_keypad_press(); + if (!opt.has_value()) { + return false; + } + + if (kp != nullptr) { + *kp = map_input_keypad_key(opt.value()); + } + return true; +} + +bool get_keypad_released(KeypadKey* kp) { + auto opt = InputsController::get_keypad_release(); + if (!opt.has_value()) { + return false; + } + + if (kp != nullptr) { + *kp = map_input_keypad_key(opt.value()); + } + return true; +} + +char char_of_keypad_key(KeypadKey kp) { + switch (kp) { + case KeypadKey::k1: return '1'; + case KeypadKey::k2: return '2'; + case KeypadKey::k3: return '3'; + case KeypadKey::k4: return '4'; + case KeypadKey::k5: return '5'; + case KeypadKey::k6: return '6'; + case KeypadKey::k7: return '7'; + case KeypadKey::k8: return '8'; + case KeypadKey::k9: return '9'; + case KeypadKey::k0: return '0'; + case KeypadKey::ka: return 'A'; + case KeypadKey::kb: return 'B'; + case KeypadKey::kc: return 'C'; + case KeypadKey::kd: return 'D'; + case KeypadKey::star: return '*'; + case KeypadKey::pound: return '#'; + default: return ' '; + } +} + +static bool take_button(ButtonKey* button, std::optional