Merge pull request 'Add an input sequence for hard rebooting' (#185) from jqln/hard-reset into main

Reviewed-on: https://codeberg.org/cool-tech-zone/tangara-fw/pulls/185
custom
cooljqln 3 months ago
commit 0180c9311d
  1. 2
      src/tangara/input/device_factory.cpp
  2. 50
      src/tangara/input/input_hard_reset.cpp
  3. 34
      src/tangara/input/input_hard_reset.hpp
  4. 23
      src/tangara/input/input_nav_buttons.cpp
  5. 5
      src/tangara/input/input_nav_buttons.hpp
  6. 18
      src/tangara/input/input_touch_dpad.cpp
  7. 7
      src/tangara/input/input_touch_dpad.hpp
  8. 7
      src/tangara/input/input_touch_wheel.cpp
  9. 1
      src/tangara/input/input_touch_wheel.hpp
  10. 23
      src/tangara/input/input_volume_buttons.cpp
  11. 5
      src/tangara/input/input_volume_buttons.hpp
  12. 14
      src/tangara/input/lvgl_input_driver.cpp

@ -11,6 +11,7 @@
#include "input/feedback_haptics.hpp" #include "input/feedback_haptics.hpp"
#include "input/feedback_tts.hpp" #include "input/feedback_tts.hpp"
#include "input/input_device.hpp" #include "input/input_device.hpp"
#include "input/input_hard_reset.hpp"
#include "input/input_nav_buttons.hpp" #include "input/input_nav_buttons.hpp"
#include "input/input_touch_dpad.hpp" #include "input/input_touch_dpad.hpp"
#include "input/input_touch_wheel.hpp" #include "input/input_touch_wheel.hpp"
@ -48,6 +49,7 @@ auto DeviceFactory::createInputs(drivers::NvsStorage::InputModes mode)
} }
break; break;
} }
ret.push_back(std::make_shared<HardReset>(services_->gpios()));
return ret; return ret;
} }

@ -0,0 +1,50 @@
/*
* Copyright 2025 jacqueline <me@jacqueline.id.au>
*
* SPDX-License-Identifier: GPL-3.0-only
*/
#include "input/input_hard_reset.hpp"
#include "drivers/gpios.hpp"
#include "esp_system.h"
#include "input/input_hook_actions.hpp"
namespace input {
HardReset::HardReset(drivers::IGpios& gpios) : gpios_(gpios) {}
auto HardReset::read(lv_indev_data_t* data) -> void {
bool buttons_pressed = !gpios_.Get(drivers::IGpios::Pin::kKeyUp) &&
!gpios_.Get(drivers::IGpios::Pin::kKeyDown);
if (!buttons_pressed) {
stage_ = 0;
return;
}
bool locked = gpios_.IsLocked();
if (stage_ == 0 && !locked) {
stage_++;
return;
}
if (stage_ == 1 && locked) {
stage_++;
return;
}
if (stage_ == 2 && !locked) {
// Bye!
esp_restart();
}
}
auto HardReset::name() -> std::string {
return "hard_reset";
}
auto HardReset::triggers()
-> std::vector<std::reference_wrapper<TriggerHooks>> {
return {};
}
} // namespace input

@ -0,0 +1,34 @@
/*
* Copyright 2025 jacqueline <me@jacqueline.id.au>
*
* SPDX-License-Identifier: GPL-3.0-only
*/
#pragma once
#include <cstdint>
#include "indev/lv_indev.h"
#include "drivers/gpios.hpp"
#include "input/input_device.hpp"
#include "input/input_hook.hpp"
namespace input {
class HardReset : public IInputDevice {
public:
HardReset(drivers::IGpios&);
auto read(lv_indev_data_t* data) -> void override;
auto name() -> std::string override;
auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
private:
drivers::IGpios& gpios_;
int stage_;
};
} // namespace input

@ -17,11 +17,20 @@ namespace input {
NavButtons::NavButtons(drivers::IGpios& gpios) NavButtons::NavButtons(drivers::IGpios& gpios)
: gpios_(gpios), : gpios_(gpios),
up_("upper", {}, actions::scrollUp(), actions::select(), {}), up_("upper", {}, actions::scrollUp(), actions::select(), {}),
down_("lower", {}, actions::scrollDown(), actions::select(), {}) {} down_("lower", {}, actions::scrollDown(), actions::select(), {}),
locked_(false) {}
auto NavButtons::read(lv_indev_data_t* data) -> void { auto NavButtons::read(lv_indev_data_t* data) -> void {
up_.update(!gpios_.Get(drivers::IGpios::Pin::kKeyUp), data); bool up = !gpios_.Get(drivers::IGpios::Pin::kKeyUp);
down_.update(!gpios_.Get(drivers::IGpios::Pin::kKeyDown), data); bool down = !gpios_.Get(drivers::IGpios::Pin::kKeyDown);
if ((up && down) || locked_) {
up = false;
down = false;
}
up_.update(up, data);
down_.update(down, data);
} }
auto NavButtons::name() -> std::string { auto NavButtons::name() -> std::string {
@ -33,4 +42,12 @@ auto NavButtons::triggers()
return {up_, down_}; return {up_, down_};
} }
auto NavButtons::onLock() -> void {
locked_ = true;
}
auto NavButtons::onUnlock() -> void {
locked_ = false;
}
} // namespace input } // namespace input

@ -28,11 +28,16 @@ class NavButtons : public IInputDevice {
auto name() -> std::string override; auto name() -> std::string override;
auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override; auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
auto onLock() -> void override;
auto onUnlock() -> void override;
private: private:
drivers::IGpios& gpios_; drivers::IGpios& gpios_;
TriggerHooks up_; TriggerHooks up_;
TriggerHooks down_; TriggerHooks down_;
bool locked_;
}; };
} // namespace input } // namespace input

@ -25,9 +25,14 @@ TouchDPad::TouchDPad(drivers::TouchWheel& wheel)
up_("up", actions::scrollUp(), {}, {}, actions::scrollUp()), up_("up", actions::scrollUp(), {}, {}, actions::scrollUp()),
right_("right", actions::select(), {}, {}, {}), right_("right", actions::select(), {}, {}, {}),
down_("down", actions::scrollDown(), {}, {}, actions::scrollDown()), down_("down", actions::scrollDown(), {}, {}, actions::scrollDown()),
left_("left", actions::goBack(), {}, {}, {}) {} left_("left", actions::goBack(), {}, {}, {}),
locked_(false) {}
auto TouchDPad::read(lv_indev_data_t* data) -> void { auto TouchDPad::read(lv_indev_data_t* data) -> void {
if (locked_) {
return;
}
wheel_.Update(); wheel_.Update();
auto wheel_data = wheel_.GetTouchWheelData(); auto wheel_data = wheel_.GetTouchWheelData();
@ -60,4 +65,15 @@ auto TouchDPad::triggers()
return {centre_, up_, right_, down_, left_}; return {centre_, up_, right_, down_, left_};
} }
auto TouchDPad::onLock() -> void {
wheel_.LowPowerMode(true);
locked_ = true;
}
auto TouchDPad::onUnlock() -> void {
wheel_.LowPowerMode(false);
wheel_.Recalibrate();
locked_ = false;
}
} // namespace input } // namespace input

@ -11,10 +11,10 @@
#include "indev/lv_indev.h" #include "indev/lv_indev.h"
#include "drivers/haptics.hpp" #include "drivers/haptics.hpp"
#include "drivers/touchwheel.hpp"
#include "input/input_device.hpp" #include "input/input_device.hpp"
#include "input/input_hook.hpp" #include "input/input_hook.hpp"
#include "input/input_trigger.hpp" #include "input/input_trigger.hpp"
#include "drivers/touchwheel.hpp"
namespace input { namespace input {
@ -27,6 +27,9 @@ class TouchDPad : public IInputDevice {
auto name() -> std::string override; auto name() -> std::string override;
auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override; auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
auto onLock() -> void override;
auto onUnlock() -> void override;
private: private:
drivers::TouchWheel& wheel_; drivers::TouchWheel& wheel_;
@ -35,6 +38,8 @@ class TouchDPad : public IInputDevice {
TriggerHooks right_; TriggerHooks right_;
TriggerHooks down_; TriggerHooks down_;
TriggerHooks left_; TriggerHooks left_;
bool locked_;
}; };
} // namespace input } // namespace input

@ -48,12 +48,17 @@ TouchWheel::TouchWheel(drivers::NvsStorage& nvs, drivers::TouchWheel& wheel)
actions::scrollToBottom(), actions::scrollToBottom(),
actions::scrollToBottom()), actions::scrollToBottom()),
left_("left", {}, {}, actions::goBack(), {}), left_("left", {}, {}, actions::goBack(), {}),
locked_(false),
is_scrolling_(false), is_scrolling_(false),
threshold_(calculateThreshold(nvs.ScrollSensitivity())), threshold_(calculateThreshold(nvs.ScrollSensitivity())),
is_first_read_(true), is_first_read_(true),
last_angle_(0) {} last_angle_(0) {}
auto TouchWheel::read(lv_indev_data_t* data) -> void { auto TouchWheel::read(lv_indev_data_t* data) -> void {
if (locked_) {
return;
}
wheel_.Update(); wheel_.Update();
auto wheel_data = wheel_.GetTouchWheelData(); auto wheel_data = wheel_.GetTouchWheelData();
int8_t ticks = calculateTicks(wheel_data); int8_t ticks = calculateTicks(wheel_data);
@ -110,11 +115,13 @@ auto TouchWheel::triggers()
auto TouchWheel::onLock() -> void { auto TouchWheel::onLock() -> void {
wheel_.LowPowerMode(true); wheel_.LowPowerMode(true);
locked_ = true;
} }
auto TouchWheel::onUnlock() -> void { auto TouchWheel::onUnlock() -> void {
wheel_.LowPowerMode(false); wheel_.LowPowerMode(false);
wheel_.Recalibrate(); wheel_.Recalibrate();
locked_ = false;
} }
auto TouchWheel::sensitivity() -> lua::Property& { auto TouchWheel::sensitivity() -> lua::Property& {

@ -50,6 +50,7 @@ class TouchWheel : public IInputDevice {
TriggerHooks down_; TriggerHooks down_;
TriggerHooks left_; TriggerHooks left_;
bool locked_;
bool is_scrolling_; bool is_scrolling_;
uint8_t threshold_; uint8_t threshold_;
bool is_first_read_; bool is_first_read_;

@ -14,11 +14,20 @@ namespace input {
VolumeButtons::VolumeButtons(drivers::IGpios& gpios) VolumeButtons::VolumeButtons(drivers::IGpios& gpios)
: gpios_(gpios), : gpios_(gpios),
up_("upper", actions::volumeUp()), up_("upper", actions::volumeUp()),
down_("lower", actions::volumeDown()) {} down_("lower", actions::volumeDown()),
locked_(false) {}
auto VolumeButtons::read(lv_indev_data_t* data) -> void { auto VolumeButtons::read(lv_indev_data_t* data) -> void {
up_.update(!gpios_.Get(drivers::IGpios::Pin::kKeyUp), data); bool up = !gpios_.Get(drivers::IGpios::Pin::kKeyUp);
down_.update(!gpios_.Get(drivers::IGpios::Pin::kKeyDown), data); bool down = !gpios_.Get(drivers::IGpios::Pin::kKeyDown);
if ((up && down) || locked_) {
up = false;
down = false;
}
up_.update(up, data);
down_.update(down, data);
} }
auto VolumeButtons::name() -> std::string { auto VolumeButtons::name() -> std::string {
@ -30,4 +39,12 @@ auto VolumeButtons::triggers()
return {up_, down_}; return {up_, down_};
} }
auto VolumeButtons::onLock() -> void {
locked_ = true;
}
auto VolumeButtons::onUnlock() -> void {
locked_ = false;
}
} // namespace input } // namespace input

@ -27,11 +27,16 @@ class VolumeButtons : public IInputDevice {
auto name() -> std::string override; auto name() -> std::string override;
auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override; auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
auto onLock() -> void override;
auto onUnlock() -> void override;
private: private:
drivers::IGpios& gpios_; drivers::IGpios& gpios_;
TriggerHooks up_; TriggerHooks up_;
TriggerHooks down_; TriggerHooks down_;
bool locked_;
}; };
} // namespace input } // namespace input

@ -114,11 +114,6 @@ auto LvglInputDriver::setGroup(lv_group_t* g) -> void {
} }
auto LvglInputDriver::read(lv_indev_data_t* data) -> void { auto LvglInputDriver::read(lv_indev_data_t* data) -> void {
// TODO: we should pass lock state on to the individual devices, since they
// may wish to either ignore the lock state, or power down until unlock.
if (is_locked_) {
return;
}
for (auto&& device : inputs_) { for (auto&& device : inputs_) {
device->read(data); device->read(data);
} }
@ -218,10 +213,17 @@ auto LvglInputDriver::pushHooks(lua_State* L) -> int {
lua_newtable(L); lua_newtable(L);
for (auto& dev : inputs_) { for (auto& dev : inputs_) {
auto triggers = dev->triggers();
if (triggers.empty()) {
// Some devices, e.g. hard reset, have no triggers. Don't include them
// in the hooks table.
continue;
}
lua_pushlstring(L, dev->name().data(), dev->name().size()); lua_pushlstring(L, dev->name().data(), dev->name().size());
lua_newtable(L); lua_newtable(L);
for (auto& trigger : dev->triggers()) { for (auto& trigger : triggers) {
lua_pushlstring(L, trigger.get().name().data(), lua_pushlstring(L, trigger.get().name().data(),
trigger.get().name().size()); trigger.get().name().size());
LuaTrigger** lua_obj = reinterpret_cast<LuaTrigger**>( LuaTrigger** lua_obj = reinterpret_cast<LuaTrigger**>(

Loading…
Cancel
Save