summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorslord <slord@noreply.codeberg.org>2025-02-04 21:17:57 +0000
committerslord <slord@noreply.codeberg.org>2025-02-04 21:17:57 +0000
commit508c8c79102c6d095f92eaf72f42d3f61ef5e7ba (patch)
tree8ea20e3fd06a5c6f84d88eb822ba8ef5f8667bcd /src
parentff733e8f0c827e3d2d91bb7db29a85807867ab5e (diff)
parent813db15da84ee82066564b51f83be451cf121a00 (diff)
downloadtangara-fw-508c8c79102c6d095f92eaf72f42d3f61ef5e7ba.tar.gz
Merge branch 'main' into playlist-browser
Diffstat (limited to 'src')
-rw-r--r--src/drivers/include/drivers/nvs.hpp9
-rw-r--r--src/drivers/nvs.cpp21
-rw-r--r--src/tangara/input/input_device.hpp3
-rw-r--r--src/tangara/input/input_nav_buttons.cpp2
-rw-r--r--src/tangara/input/input_nav_buttons.hpp2
-rw-r--r--src/tangara/input/input_touch_dpad.cpp2
-rw-r--r--src/tangara/input/input_touch_dpad.hpp2
-rw-r--r--src/tangara/input/input_touch_wheel.cpp15
-rw-r--r--src/tangara/input/input_touch_wheel.hpp5
-rw-r--r--src/tangara/input/input_volume_buttons.cpp12
-rw-r--r--src/tangara/input/input_volume_buttons.hpp5
-rw-r--r--src/tangara/input/lvgl_input_driver.cpp31
-rw-r--r--src/tangara/input/lvgl_input_driver.hpp2
-rw-r--r--src/tangara/lua/lua_controls.cpp17
-rw-r--r--src/tangara/ui/ui_fsm.cpp1
15 files changed, 113 insertions, 16 deletions
diff --git a/src/drivers/include/drivers/nvs.hpp b/src/drivers/include/drivers/nvs.hpp
index 9725bb0f..18bc5de6 100644
--- a/src/drivers/include/drivers/nvs.hpp
+++ b/src/drivers/include/drivers/nvs.hpp
@@ -138,6 +138,14 @@ class NvsStorage {
auto PrimaryInput() -> InputModes;
auto PrimaryInput(InputModes) -> void;
+ enum class LockedInputModes : uint8_t {
+ kDisabled = 0,
+ kVolumeOnly = 1,
+ };
+
+ auto LockedInput() -> LockedInputModes;
+ auto LockedInput(LockedInputModes) -> void;
+
auto QueueRepeatMode() -> uint8_t;
auto QueueRepeatMode(uint8_t) -> void;
@@ -167,6 +175,7 @@ class NvsStorage {
Setting<uint16_t> amp_cur_vol_;
Setting<int8_t> amp_left_bias_;
Setting<uint8_t> input_mode_;
+ Setting<uint8_t> locked_input_mode_;
Setting<uint8_t> output_mode_;
Setting<std::string> theme_;
diff --git a/src/drivers/nvs.cpp b/src/drivers/nvs.cpp
index 6f0d874e..02a0058b 100644
--- a/src/drivers/nvs.cpp
+++ b/src/drivers/nvs.cpp
@@ -34,6 +34,7 @@ static constexpr char kKeyAmpMaxVolume[] = "hp_vol_max";
static constexpr char kKeyAmpCurrentVolume[] = "hp_vol";
static constexpr char kKeyAmpLeftBias[] = "hp_bias";
static constexpr char kKeyPrimaryInput[] = "in_pri";
+static constexpr char kKeyLockedInput[] = "in_locked";
static constexpr char kKeyScrollSensitivity[] = "scroll";
static constexpr char kKeyLockPolarity[] = "lockpol";
static constexpr char kKeyDisplayCols[] = "dispcols";
@@ -272,6 +273,7 @@ NvsStorage::NvsStorage(nvs_handle_t handle)
amp_cur_vol_(kKeyAmpCurrentVolume),
amp_left_bias_(kKeyAmpLeftBias),
input_mode_(kKeyPrimaryInput),
+ locked_input_mode_(kKeyLockedInput),
output_mode_(kKeyOutput),
theme_{kKeyInterfaceTheme},
bt_preferred_(kKeyBluetoothPreferred),
@@ -300,6 +302,7 @@ auto NvsStorage::Read() -> void {
amp_cur_vol_.read(handle_);
amp_left_bias_.read(handle_);
input_mode_.read(handle_);
+ locked_input_mode_.read(handle_);
output_mode_.read(handle_);
theme_.read(handle_);
bt_preferred_.read(handle_);
@@ -323,6 +326,7 @@ auto NvsStorage::Write() -> bool {
amp_cur_vol_.write(handle_);
amp_left_bias_.write(handle_);
input_mode_.write(handle_);
+ locked_input_mode_.write(handle_);
output_mode_.write(handle_);
theme_.write(handle_);
bt_preferred_.write(handle_);
@@ -570,6 +574,23 @@ auto NvsStorage::PrimaryInput(InputModes mode) -> void {
input_mode_.set(static_cast<uint8_t>(mode));
}
+auto NvsStorage::LockedInput() -> LockedInputModes {
+ std::lock_guard<std::mutex> lock{mutex_};
+ switch (locked_input_mode_.get().value_or(static_cast<uint8_t>(LockedInputModes::kDisabled))) {
+ case static_cast<uint8_t>(LockedInputModes::kDisabled):
+ return LockedInputModes::kDisabled;
+ case static_cast<uint8_t>(LockedInputModes::kVolumeOnly):
+ return LockedInputModes::kVolumeOnly;
+ default:
+ return LockedInputModes::kDisabled;
+ }
+}
+
+auto NvsStorage::LockedInput(LockedInputModes mode) -> void {
+ std::lock_guard<std::mutex> lock{mutex_};
+ locked_input_mode_.set(static_cast<uint8_t>(mode));
+}
+
auto NvsStorage::QueueRepeatMode() -> uint8_t {
std::lock_guard<std::mutex> lock{mutex_};
return queue_repeat_mode_.get().value_or(0);
diff --git a/src/tangara/input/input_device.hpp b/src/tangara/input/input_device.hpp
index 7edded3e..424c0da3 100644
--- a/src/tangara/input/input_device.hpp
+++ b/src/tangara/input/input_device.hpp
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
+#include "drivers/nvs.hpp"
#include "indev/lv_indev.h"
#include "input/input_hook.hpp"
#include "lua/property.hpp"
@@ -34,7 +35,7 @@ class IInputDevice {
}
/* Called by the LVGL driver when controls are being locked. */
- virtual auto onLock() -> void {}
+ virtual auto onLock(drivers::NvsStorage::LockedInputModes) -> void {}
/* Called by the LVGL driver when controls are being unlocked. */
virtual auto onUnlock() -> void {}
};
diff --git a/src/tangara/input/input_nav_buttons.cpp b/src/tangara/input/input_nav_buttons.cpp
index 54bef7a6..a5e10013 100644
--- a/src/tangara/input/input_nav_buttons.cpp
+++ b/src/tangara/input/input_nav_buttons.cpp
@@ -42,7 +42,7 @@ auto NavButtons::triggers()
return {up_, down_};
}
-auto NavButtons::onLock() -> void {
+auto NavButtons::onLock(drivers::NvsStorage::LockedInputModes mode) -> void {
locked_ = true;
}
diff --git a/src/tangara/input/input_nav_buttons.hpp b/src/tangara/input/input_nav_buttons.hpp
index 95d56d54..c9575fe0 100644
--- a/src/tangara/input/input_nav_buttons.hpp
+++ b/src/tangara/input/input_nav_buttons.hpp
@@ -28,7 +28,7 @@ class NavButtons : public IInputDevice {
auto name() -> std::string override;
auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
- auto onLock() -> void override;
+ auto onLock(drivers::NvsStorage::LockedInputModes) -> void override;
auto onUnlock() -> void override;
private:
diff --git a/src/tangara/input/input_touch_dpad.cpp b/src/tangara/input/input_touch_dpad.cpp
index 8ed2bdd7..25c2315b 100644
--- a/src/tangara/input/input_touch_dpad.cpp
+++ b/src/tangara/input/input_touch_dpad.cpp
@@ -65,7 +65,7 @@ auto TouchDPad::triggers()
return {centre_, up_, right_, down_, left_};
}
-auto TouchDPad::onLock() -> void {
+auto TouchDPad::onLock(drivers::NvsStorage::LockedInputModes mode) -> void {
wheel_.LowPowerMode(true);
locked_ = true;
}
diff --git a/src/tangara/input/input_touch_dpad.hpp b/src/tangara/input/input_touch_dpad.hpp
index d787bace..086f556e 100644
--- a/src/tangara/input/input_touch_dpad.hpp
+++ b/src/tangara/input/input_touch_dpad.hpp
@@ -27,7 +27,7 @@ class TouchDPad : public IInputDevice {
auto name() -> std::string override;
auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
- auto onLock() -> void override;
+ auto onLock(drivers::NvsStorage::LockedInputModes) -> void override;
auto onUnlock() -> void override;
private:
diff --git a/src/tangara/input/input_touch_wheel.cpp b/src/tangara/input/input_touch_wheel.cpp
index 19ac5211..fba8a4cd 100644
--- a/src/tangara/input/input_touch_wheel.cpp
+++ b/src/tangara/input/input_touch_wheel.cpp
@@ -21,6 +21,8 @@
#include "lua/property.hpp"
#include "ui/ui_events.hpp"
+#include "esp_timer.h"
+
namespace input {
TouchWheel::TouchWheel(drivers::NvsStorage& nvs, drivers::TouchWheel& wheel)
@@ -77,7 +79,16 @@ auto TouchWheel::read(lv_indev_data_t* data) -> void {
data->enc_diff = 0;
}
- centre_.update(wheel_data.is_button_touched && !wheel_data.is_wheel_touched,
+ // Prevent accidental center button touches while scrolling
+ if (wheel_data.is_wheel_touched) {
+ last_wheel_touch_time_ = esp_timer_get_time();
+ }
+
+ bool wheel_touch_timed_out =
+ esp_timer_get_time() - last_wheel_touch_time_ > SCROLL_TIMEOUT_US;
+
+ centre_.update(wheel_touch_timed_out && wheel_data.is_button_touched &&
+ !wheel_data.is_wheel_touched,
data);
// If the user is touching the wheel but not scrolling, then they may be
@@ -113,7 +124,7 @@ auto TouchWheel::triggers()
return {centre_, up_, right_, down_, left_};
}
-auto TouchWheel::onLock() -> void {
+auto TouchWheel::onLock(drivers::NvsStorage::LockedInputModes mode) -> void {
wheel_.LowPowerMode(true);
locked_ = true;
}
diff --git a/src/tangara/input/input_touch_wheel.hpp b/src/tangara/input/input_touch_wheel.hpp
index 982f89f4..420454b8 100644
--- a/src/tangara/input/input_touch_wheel.hpp
+++ b/src/tangara/input/input_touch_wheel.hpp
@@ -30,12 +30,14 @@ class TouchWheel : public IInputDevice {
auto name() -> std::string override;
auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
- auto onLock() -> void override;
+ auto onLock(drivers::NvsStorage::LockedInputModes) -> void override;
auto onUnlock() -> void override;
auto sensitivity() -> lua::Property&;
private:
+ const int64_t SCROLL_TIMEOUT_US = 250000; // 250ms
+
auto calculateTicks(const drivers::TouchWheelData& data) -> int8_t;
auto calculateThreshold(uint8_t sensitivity) -> uint8_t;
@@ -55,6 +57,7 @@ class TouchWheel : public IInputDevice {
uint8_t threshold_;
bool is_first_read_;
uint8_t last_angle_;
+ int64_t last_wheel_touch_time_;
};
} // namespace input
diff --git a/src/tangara/input/input_volume_buttons.cpp b/src/tangara/input/input_volume_buttons.cpp
index 7ffdfcdc..5c814ffa 100644
--- a/src/tangara/input/input_volume_buttons.cpp
+++ b/src/tangara/input/input_volume_buttons.cpp
@@ -15,13 +15,15 @@ VolumeButtons::VolumeButtons(drivers::IGpios& gpios)
: gpios_(gpios),
up_("upper", actions::volumeUp()),
down_("lower", actions::volumeDown()),
- locked_(false) {}
+ locked_() {}
auto VolumeButtons::read(lv_indev_data_t* data) -> void {
bool up = !gpios_.Get(drivers::IGpios::Pin::kKeyUp);
bool down = !gpios_.Get(drivers::IGpios::Pin::kKeyDown);
- if ((up && down) || locked_) {
+ bool input_disabled = locked_.has_value() && (locked_ != drivers::NvsStorage::LockedInputModes::kVolumeOnly);
+
+ if ((up && down) || input_disabled) {
up = false;
down = false;
}
@@ -39,12 +41,12 @@ auto VolumeButtons::triggers()
return {up_, down_};
}
-auto VolumeButtons::onLock() -> void {
- locked_ = true;
+auto VolumeButtons::onLock(drivers::NvsStorage::LockedInputModes mode) -> void {
+ locked_ = mode;
}
auto VolumeButtons::onUnlock() -> void {
- locked_ = false;
+ locked_ = {};
}
} // namespace input
diff --git a/src/tangara/input/input_volume_buttons.hpp b/src/tangara/input/input_volume_buttons.hpp
index ffb3156b..35a44390 100644
--- a/src/tangara/input/input_volume_buttons.hpp
+++ b/src/tangara/input/input_volume_buttons.hpp
@@ -27,7 +27,7 @@ class VolumeButtons : public IInputDevice {
auto name() -> std::string override;
auto triggers() -> std::vector<std::reference_wrapper<TriggerHooks>> override;
- auto onLock() -> void override;
+ auto onLock(drivers::NvsStorage::LockedInputModes) -> void override;
auto onUnlock() -> void override;
private:
@@ -36,7 +36,8 @@ class VolumeButtons : public IInputDevice {
TriggerHooks up_;
TriggerHooks down_;
- bool locked_;
+ // When locked, this contains the active mode
+ std::optional<drivers::NvsStorage::LockedInputModes> locked_;
};
} // namespace input
diff --git a/src/tangara/input/lvgl_input_driver.cpp b/src/tangara/input/lvgl_input_driver.cpp
index c008b007..2859c6a8 100644
--- a/src/tangara/input/lvgl_input_driver.cpp
+++ b/src/tangara/input/lvgl_input_driver.cpp
@@ -53,6 +53,8 @@ static void focus_cb(lv_group_t* group) {
instance->feedback(LV_EVENT_FOCUSED);
}
+namespace {
+
auto intToMode(int raw) -> std::optional<drivers::NvsStorage::InputModes> {
switch (raw) {
case 0:
@@ -68,6 +70,19 @@ auto intToMode(int raw) -> std::optional<drivers::NvsStorage::InputModes> {
}
}
+auto intToLockedMode(int raw) -> std::optional<drivers::NvsStorage::LockedInputModes> {
+ switch (raw) {
+ case 0:
+ return drivers::NvsStorage::LockedInputModes::kDisabled;
+ case 1:
+ return drivers::NvsStorage::LockedInputModes::kVolumeOnly;
+ default:
+ return {};
+ }
+}
+
+} // namespace {}
+
LvglInputDriver::LvglInputDriver(drivers::NvsStorage& nvs,
DeviceFactory& factory)
: nvs_(nvs),
@@ -85,6 +100,18 @@ LvglInputDriver::LvglInputDriver(drivers::NvsStorage& nvs,
inputs_ = factory.createInputs(*mode);
return true;
}),
+ locked_mode_(static_cast<int>(nvs.LockedInput()),
+ [&](const lua::LuaValue& val) {
+ if (!std::holds_alternative<int>(val)) {
+ return false;
+ }
+ auto mode = intToLockedMode(std::get<int>(val));
+ if (!mode) {
+ return false;
+ }
+ nvs.LockedInput(*mode);
+ return true;
+ }),
inputs_(factory.createInputs(nvs.PrimaryInput())),
feedbacks_(factory.createFeedbacks()),
is_locked_(false) {
@@ -130,9 +157,11 @@ auto LvglInputDriver::feedback(uint8_t event) -> void {
auto LvglInputDriver::lock(bool l) -> void {
is_locked_ = l;
+ auto locked_input_mode = nvs_.LockedInput();
+
for (auto&& device : inputs_) {
if (l) {
- device->onLock();
+ device->onLock(locked_input_mode);
} else {
device->onUnlock();
}
diff --git a/src/tangara/input/lvgl_input_driver.hpp b/src/tangara/input/lvgl_input_driver.hpp
index 9b62c24d..ce950621 100644
--- a/src/tangara/input/lvgl_input_driver.hpp
+++ b/src/tangara/input/lvgl_input_driver.hpp
@@ -36,6 +36,7 @@ class LvglInputDriver {
LvglInputDriver(drivers::NvsStorage& nvs, DeviceFactory&);
auto mode() -> lua::Property& { return mode_; }
+ auto lockedMode() -> lua::Property& { return locked_mode_; }
auto setGroup(lv_group_t*) -> void;
auto read(lv_indev_data_t* data) -> void;
@@ -49,6 +50,7 @@ class LvglInputDriver {
DeviceFactory& factory_;
lua::Property mode_;
+ lua::Property locked_mode_;
lv_indev_t* device_;
std::vector<std::shared_ptr<IInputDevice>> inputs_;
diff --git a/src/tangara/lua/lua_controls.cpp b/src/tangara/lua/lua_controls.cpp
index baf40891..87b7ca16 100644
--- a/src/tangara/lua/lua_controls.cpp
+++ b/src/tangara/lua/lua_controls.cpp
@@ -42,7 +42,24 @@ static auto controls_schemes(lua_State* L) -> int {
return 1;
}
+static auto locked_controls_schemes(lua_State* L) -> int {
+ lua_newtable(L);
+
+ lua_pushliteral(L, "Disabled");
+ lua_rawseti(
+ L, -2,
+ static_cast<int>(drivers::NvsStorage::LockedInputModes::kDisabled));
+
+ lua_pushliteral(L, "Volume Only");
+ lua_rawseti(
+ L, -2,
+ static_cast<int>(drivers::NvsStorage::LockedInputModes::kVolumeOnly));
+
+ return 1;
+}
+
static const struct luaL_Reg kControlsFuncs[] = {{"schemes", controls_schemes},
+ {"locked_schemes", locked_controls_schemes},
{NULL, NULL}};
static auto lua_controls(lua_State* state) -> int {
diff --git a/src/tangara/ui/ui_fsm.cpp b/src/tangara/ui/ui_fsm.cpp
index 4a54d974..1823f780 100644
--- a/src/tangara/ui/ui_fsm.cpp
+++ b/src/tangara/ui/ui_fsm.cpp
@@ -667,6 +667,7 @@ void Lua::entry() {
"controls",
{
{"scheme", &sInput->mode()},
+ {"locked_scheme", &sInput->lockedMode()},
{"lock_switch", &sLockSwitch},
{"hooks", [&](lua_State* L) { return sInput->pushHooks(L); }},
});