feat: add HalDisplay and HalGPIO (#522)

## Summary

Extracted some changes from
https://github.com/crosspoint-reader/crosspoint-reader/pull/500 to make
reviewing easier

This PR adds HAL (Hardware Abstraction Layer) for display and GPIO
components, making it easier to write a stub or an emulated
implementation of the hardware.

SD card HAL will be added via another PR, because it's a bit more
tricky.

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? **NO**
This commit is contained in:
Xuan-Son Nguyen
2026-01-27 18:50:15 +01:00
committed by GitHub
parent 172916afd4
commit da4d3b5ea5
14 changed files with 322 additions and 148 deletions

View File

@@ -19,20 +19,20 @@ struct SideLayoutMap {
// Order matches CrossPointSettings::FRONT_BUTTON_LAYOUT.
constexpr FrontLayoutMap kFrontLayouts[] = {
{InputManager::BTN_BACK, InputManager::BTN_CONFIRM, InputManager::BTN_LEFT, InputManager::BTN_RIGHT},
{InputManager::BTN_LEFT, InputManager::BTN_RIGHT, InputManager::BTN_BACK, InputManager::BTN_CONFIRM},
{InputManager::BTN_CONFIRM, InputManager::BTN_LEFT, InputManager::BTN_BACK, InputManager::BTN_RIGHT},
{InputManager::BTN_BACK, InputManager::BTN_CONFIRM, InputManager::BTN_RIGHT, InputManager::BTN_LEFT},
{HalGPIO::BTN_BACK, HalGPIO::BTN_CONFIRM, HalGPIO::BTN_LEFT, HalGPIO::BTN_RIGHT},
{HalGPIO::BTN_LEFT, HalGPIO::BTN_RIGHT, HalGPIO::BTN_BACK, HalGPIO::BTN_CONFIRM},
{HalGPIO::BTN_CONFIRM, HalGPIO::BTN_LEFT, HalGPIO::BTN_BACK, HalGPIO::BTN_RIGHT},
{HalGPIO::BTN_BACK, HalGPIO::BTN_CONFIRM, HalGPIO::BTN_RIGHT, HalGPIO::BTN_LEFT},
};
// Order matches CrossPointSettings::SIDE_BUTTON_LAYOUT.
constexpr SideLayoutMap kSideLayouts[] = {
{InputManager::BTN_UP, InputManager::BTN_DOWN},
{InputManager::BTN_DOWN, InputManager::BTN_UP},
{HalGPIO::BTN_UP, HalGPIO::BTN_DOWN},
{HalGPIO::BTN_DOWN, HalGPIO::BTN_UP},
};
} // namespace
bool MappedInputManager::mapButton(const Button button, bool (InputManager::*fn)(uint8_t) const) const {
bool MappedInputManager::mapButton(const Button button, bool (HalGPIO::*fn)(uint8_t) const) const {
const auto frontLayout = static_cast<CrossPointSettings::FRONT_BUTTON_LAYOUT>(SETTINGS.frontButtonLayout);
const auto sideLayout = static_cast<CrossPointSettings::SIDE_BUTTON_LAYOUT>(SETTINGS.sideButtonLayout);
const auto& front = kFrontLayouts[frontLayout];
@@ -40,41 +40,39 @@ bool MappedInputManager::mapButton(const Button button, bool (InputManager::*fn)
switch (button) {
case Button::Back:
return (inputManager.*fn)(front.back);
return (gpio.*fn)(front.back);
case Button::Confirm:
return (inputManager.*fn)(front.confirm);
return (gpio.*fn)(front.confirm);
case Button::Left:
return (inputManager.*fn)(front.left);
return (gpio.*fn)(front.left);
case Button::Right:
return (inputManager.*fn)(front.right);
return (gpio.*fn)(front.right);
case Button::Up:
return (inputManager.*fn)(InputManager::BTN_UP);
return (gpio.*fn)(HalGPIO::BTN_UP);
case Button::Down:
return (inputManager.*fn)(InputManager::BTN_DOWN);
return (gpio.*fn)(HalGPIO::BTN_DOWN);
case Button::Power:
return (inputManager.*fn)(InputManager::BTN_POWER);
return (gpio.*fn)(HalGPIO::BTN_POWER);
case Button::PageBack:
return (inputManager.*fn)(side.pageBack);
return (gpio.*fn)(side.pageBack);
case Button::PageForward:
return (inputManager.*fn)(side.pageForward);
return (gpio.*fn)(side.pageForward);
}
return false;
}
bool MappedInputManager::wasPressed(const Button button) const { return mapButton(button, &InputManager::wasPressed); }
bool MappedInputManager::wasPressed(const Button button) const { return mapButton(button, &HalGPIO::wasPressed); }
bool MappedInputManager::wasReleased(const Button button) const {
return mapButton(button, &InputManager::wasReleased);
}
bool MappedInputManager::wasReleased(const Button button) const { return mapButton(button, &HalGPIO::wasReleased); }
bool MappedInputManager::isPressed(const Button button) const { return mapButton(button, &InputManager::isPressed); }
bool MappedInputManager::isPressed(const Button button) const { return mapButton(button, &HalGPIO::isPressed); }
bool MappedInputManager::wasAnyPressed() const { return inputManager.wasAnyPressed(); }
bool MappedInputManager::wasAnyPressed() const { return gpio.wasAnyPressed(); }
bool MappedInputManager::wasAnyReleased() const { return inputManager.wasAnyReleased(); }
bool MappedInputManager::wasAnyReleased() const { return gpio.wasAnyReleased(); }
unsigned long MappedInputManager::getHeldTime() const { return inputManager.getHeldTime(); }
unsigned long MappedInputManager::getHeldTime() const { return gpio.getHeldTime(); }
MappedInputManager::Labels MappedInputManager::mapLabels(const char* back, const char* confirm, const char* previous,
const char* next) const {
@@ -91,4 +89,4 @@ MappedInputManager::Labels MappedInputManager::mapLabels(const char* back, const
default:
return {back, confirm, previous, next};
}
}
}