Integrate BLE keyboard host functionality for page-turner remotes. Adds device pairing, button mapping, preset configurations for Free2/Free3 remotes, and persistent storage of mappings. Migrates from open-x4-sdk to freeink-sdk submodule which includes the BleKeyboardHost library. Implements CPU frequency locking during BLE operations to prevent watchdog timeouts.
81 lines
3.9 KiB
C++
81 lines
3.9 KiB
C++
#pragma once
|
|
|
|
#include <HalGPIO.h>
|
|
|
|
class GfxRenderer;
|
|
|
|
class MappedInputManager {
|
|
public:
|
|
enum class Button { Back, Confirm, Left, Right, Up, Down, Power, PageBack, PageForward, NavNext, NavPrevious };
|
|
// Number of values in Button (Back..NavPrevious). Used to size the BLE overlay and
|
|
// to clamp persisted BLE mappings. Keep in sync with the enum above.
|
|
static constexpr uint8_t kButtonCount = 11;
|
|
|
|
struct Labels {
|
|
const char* btn1;
|
|
const char* btn2;
|
|
const char* btn3;
|
|
const char* btn4;
|
|
};
|
|
|
|
MappedInputManager(HalGPIO& gpio, const GfxRenderer& renderer) : gpio(gpio), renderer(renderer) {}
|
|
|
|
void update() const { gpio.update(); }
|
|
bool wasPressed(Button button) const;
|
|
bool wasReleased(Button button) const;
|
|
bool isPressed(Button button) const;
|
|
bool wasAnyPressed() const;
|
|
bool wasAnyReleased() const;
|
|
unsigned long getHeldTime() const;
|
|
Labels mapLabels(const char* back, const char* confirm, const char* previous, const char* next) const;
|
|
// Returns the raw front button index that was pressed this frame (or -1 if none).
|
|
int getPressedFrontButton() const;
|
|
|
|
// --- BLE page-turner overlay -------------------------------------------------
|
|
// Drain decoded key events from the FreeInk BLE HID host and translate the ones
|
|
// bound in SETTINGS.bleKeyMap into per-frame logical-button edges that OR into
|
|
// wasPressed()/isPressed()/wasReleased(). Call once per main-loop iteration,
|
|
// right after gpio.update() and BleHid.poll(). No-ops when BLE is compiled out.
|
|
void pollBle();
|
|
// True when a mapped BLE key produced an edge this frame — keeps the inactivity
|
|
// / auto-sleep timer alive while a remote is the only input device in use.
|
|
bool bleHadActivityThisFrame() const { return bleActivityThisFrame; }
|
|
// Capture mode: while on, pollBle() stops mapping events and instead stashes the
|
|
// raw decoded key identity so the button-mapping UI can read it without racing the
|
|
// live mapping over the single popKey() queue.
|
|
void setBleCaptureMode(bool on);
|
|
// Pop a captured (kind, value) key identity grabbed while in capture mode.
|
|
// Returns false when nothing has been captured since the last call.
|
|
bool takeCapturedBleKey(uint8_t& kind, uint8_t& value);
|
|
|
|
// True when the control axis is flipped relative to the physical buttons: the user opted into
|
|
// orientation-following front buttons AND the screen is *currently rendered* rotated (INVERTED /
|
|
// LANDSCAPE_CCW). Keyed on the live renderer orientation rather than the persisted reader setting,
|
|
// so portrait UI (home, settings) never swaps while the reader and its menus do.
|
|
[[nodiscard]] bool isNavDirectionSwapped() const;
|
|
|
|
private:
|
|
HalGPIO& gpio;
|
|
// Logical-to-physical button mapping depends on what the user is actually looking at: when the
|
|
// screen is rendered rotated, the directional buttons must flip to match. The renderer is the only
|
|
// authority on the *live* orientation (the reader rotates it and restores portrait on exit), so we
|
|
// read it here instead of CrossPointSettings.orientation, which is just the persisted reader
|
|
// preference and stays "rotated" even while portrait UI like home/settings is on screen.
|
|
const GfxRenderer& renderer;
|
|
|
|
bool mapButton(Button button, bool (HalGPIO::*fn)(uint8_t) const) const;
|
|
// OR-in the BLE overlay for a logical button, mirroring mapButton()'s composite
|
|
// handling of NavNext/NavPrevious so a remote key bound to Up/Down/Left/Right also
|
|
// drives list navigation.
|
|
bool bleEdge(const bool* arr, Button button) const;
|
|
|
|
// Per-frame BLE overlay, indexed by (uint8_t)Button.
|
|
bool blePressEdge[kButtonCount] = {}; // press edge this frame -> wasPressed / isPressed
|
|
bool bleReleaseEdge[kButtonCount] = {}; // release edge this frame -> wasReleased
|
|
bool bleActivityThisFrame = false;
|
|
bool bleCaptureMode = false;
|
|
bool bleHasCaptured = false;
|
|
uint8_t bleCapturedKind = 0xFF;
|
|
uint8_t bleCapturedValue = 0;
|
|
};
|