summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorailurux <ailuruxx@gmail.com>2024-04-08 15:40:16 +1000
committerailurux <ailuruxx@gmail.com>2024-04-08 15:40:16 +1000
commitf20ca9583af5312eea65cf144803d00be6e50602 (patch)
treed6047ff952d6ad60a30ba038e6a5c72c64b8b0e7 /src
parent01ae3fee30704577f4ea37ed7f2132990135163c (diff)
parent96b62321c33ff5e146d52416dc5da3f0c240b4b0 (diff)
downloadtangara-fw-f20ca9583af5312eea65cf144803d00be6e50602.tar.gz
Merge branch 'main' of codeberg.org:cool-tech-zone/tangara-fw
Diffstat (limited to 'src')
-rw-r--r--src/audio/audio_fsm.cpp19
-rw-r--r--src/audio/bt_audio_output.cpp24
-rw-r--r--src/audio/i2s_audio_output.cpp33
-rw-r--r--src/audio/include/audio_sink.hpp3
-rw-r--r--src/audio/include/bt_audio_output.hpp2
-rw-r--r--src/audio/include/i2s_audio_output.hpp2
-rw-r--r--src/database/database.cpp8
-rw-r--r--src/drivers/include/nvs.hpp4
-rw-r--r--src/drivers/include/samd.hpp4
-rw-r--r--src/drivers/nvs.cpp14
-rw-r--r--src/drivers/samd.cpp2
-rw-r--r--src/lua/property.cpp12
-rw-r--r--src/system_fsm/include/system_events.hpp4
-rw-r--r--src/system_fsm/running.cpp16
-rw-r--r--src/system_fsm/system_fsm.cpp2
-rw-r--r--src/ui/include/ui_fsm.hpp3
-rw-r--r--src/ui/ui_fsm.cpp27
17 files changed, 145 insertions, 34 deletions
diff --git a/src/audio/audio_fsm.cpp b/src/audio/audio_fsm.cpp
index 424b0eff..a8f1260f 100644
--- a/src/audio/audio_fsm.cpp
+++ b/src/audio/audio_fsm.cpp
@@ -276,7 +276,24 @@ void AudioState::react(const system_fsm::HasPhonesChanged& ev) {
}
void AudioState::react(const SetVolume& ev) {
- // TODO.
+ if (ev.db.has_value()) {
+ if (sOutput->SetVolumeDb(ev.db.value())) {
+ commitVolume();
+ events::Ui().Dispatch(VolumeChanged{
+ .percent = sOutput->GetVolumePct(),
+ .db = sOutput->GetVolumeDb(),
+ });
+ }
+
+ } else if (ev.percent.has_value()) {
+ if (sOutput->SetVolumePct(ev.percent.value())) {
+ commitVolume();
+ events::Ui().Dispatch(VolumeChanged{
+ .percent = sOutput->GetVolumePct(),
+ .db = sOutput->GetVolumeDb(),
+ });
+ }
+ }
}
void AudioState::react(const SetVolumeLimit& ev) {
diff --git a/src/audio/bt_audio_output.cpp b/src/audio/bt_audio_output.cpp
index 04daf71f..7d6bade2 100644
--- a/src/audio/bt_audio_output.cpp
+++ b/src/audio/bt_audio_output.cpp
@@ -9,6 +9,7 @@
#include <algorithm>
#include <cstddef>
#include <cstdint>
+#include <cmath>
#include <memory>
#include <variant>
@@ -54,11 +55,30 @@ auto BluetoothAudioOutput::GetVolume() -> uint16_t {
}
auto BluetoothAudioOutput::GetVolumePct() -> uint_fast8_t {
- return static_cast<uint_fast8_t>(static_cast<int>(volume_) * 100 / 0x7f);
+ return static_cast<uint_fast8_t>(round(static_cast<int>(volume_) * 100.0 / 0x7f));
+}
+
+auto BluetoothAudioOutput::SetVolumePct(uint_fast8_t val) -> bool {
+ if (val > 100) {
+ return false;
+ }
+ uint16_t vol = (val * (0x7f))/100;
+ SetVolume(vol);
+ return true;
}
auto BluetoothAudioOutput::GetVolumeDb() -> int_fast16_t {
- return 0;
+ double pct = GetVolumePct()/100.0;
+ if (pct <= 0) {
+ pct = 0.01;
+ }
+ int_fast16_t db = log(pct) * 20;
+ return db;
+}
+
+auto BluetoothAudioOutput::SetVolumeDb(int_fast16_t val) -> bool {
+ double pct = exp(val / 20.0) * 100;
+ return SetVolumePct(pct);
}
auto BluetoothAudioOutput::AdjustVolumeUp() -> bool {
diff --git a/src/audio/i2s_audio_output.cpp b/src/audio/i2s_audio_output.cpp
index 3fb99159..bf1c3e5e 100644
--- a/src/audio/i2s_audio_output.cpp
+++ b/src/audio/i2s_audio_output.cpp
@@ -63,16 +63,21 @@ auto I2SAudioOutput::changeMode(Modes mode) -> void {
return;
}
if (mode == Modes::kOff) {
- dac_->Stop();
- dac_.reset();
+ if (dac_) {
+ dac_->Stop();
+ dac_.reset();
+ }
return;
- } else if (current_mode_ == Modes::kOff) {
- auto instance = drivers::I2SDac::create(expander_);
- if (!instance) {
- return;
+ }
+ if (current_mode_ == Modes::kOff) {
+ if (!dac_) {
+ auto instance = drivers::I2SDac::create(expander_);
+ if (!instance) {
+ return;
+ }
+ dac_.reset(*instance);
}
SetVolume(GetVolume());
- dac_.reset(*instance);
dac_->SetSource(stream());
dac_->Start();
}
@@ -111,6 +116,15 @@ auto I2SAudioOutput::GetVolumePct() -> uint_fast8_t {
return (current_volume_ - kMinVolume) * 100 / (max_volume_ - kMinVolume);
}
+auto I2SAudioOutput::SetVolumePct(uint_fast8_t val) -> bool {
+ if (val > 100) {
+ return false;
+ }
+ uint16_t vol = (val * (max_volume_ - kMinVolume))/100 + kMinVolume;
+ SetVolume(vol);
+ return true;
+}
+
auto I2SAudioOutput::GetVolumeDb() -> int_fast16_t {
// Add two before dividing in order to round correctly.
return (static_cast<int>(current_volume_) -
@@ -118,6 +132,11 @@ auto I2SAudioOutput::GetVolumeDb() -> int_fast16_t {
4;
}
+auto I2SAudioOutput::SetVolumeDb(int_fast16_t val) -> bool {
+ SetVolume(val * 4 + static_cast<int>(drivers::wm8523::kLineLevelReferenceVolume) - 2);
+ return true;
+}
+
auto I2SAudioOutput::AdjustVolumeUp() -> bool {
if (GetVolume() >= max_volume_) {
return false;
diff --git a/src/audio/include/audio_sink.hpp b/src/audio/include/audio_sink.hpp
index e11f3ce0..f31d0d75 100644
--- a/src/audio/include/audio_sink.hpp
+++ b/src/audio/include/audio_sink.hpp
@@ -59,6 +59,9 @@ class IAudioOutput {
virtual auto GetVolumePct() -> uint_fast8_t = 0;
virtual auto GetVolumeDb() -> int_fast16_t = 0;
+ virtual auto SetVolumePct(uint_fast8_t) -> bool = 0;
+ virtual auto SetVolumeDb(int_fast16_t) -> bool = 0;
+
virtual auto AdjustVolumeUp() -> bool = 0;
virtual auto AdjustVolumeDown() -> bool = 0;
diff --git a/src/audio/include/bt_audio_output.hpp b/src/audio/include/bt_audio_output.hpp
index a61e718a..74b0301a 100644
--- a/src/audio/include/bt_audio_output.hpp
+++ b/src/audio/include/bt_audio_output.hpp
@@ -35,7 +35,9 @@ class BluetoothAudioOutput : public IAudioOutput {
auto GetVolume() -> uint16_t override;
auto GetVolumePct() -> uint_fast8_t override;
+ auto SetVolumePct(uint_fast8_t val) -> bool override;
auto GetVolumeDb() -> int_fast16_t override;
+ auto SetVolumeDb(int_fast16_t) -> bool override;
auto AdjustVolumeUp() -> bool override;
auto AdjustVolumeDown() -> bool override;
diff --git a/src/audio/include/i2s_audio_output.hpp b/src/audio/include/i2s_audio_output.hpp
index 5f3fc3ff..7954257a 100644
--- a/src/audio/include/i2s_audio_output.hpp
+++ b/src/audio/include/i2s_audio_output.hpp
@@ -33,7 +33,9 @@ class I2SAudioOutput : public IAudioOutput {
auto GetVolume() -> uint16_t override;
auto GetVolumePct() -> uint_fast8_t override;
+ auto SetVolumePct(uint_fast8_t val) -> bool override;
auto GetVolumeDb() -> int_fast16_t override;
+ auto SetVolumeDb(int_fast16_t) -> bool override;
auto AdjustVolumeUp() -> bool override;
auto AdjustVolumeDown() -> bool override;
diff --git a/src/database/database.cpp b/src/database/database.cpp
index 06138983..48fb0c63 100644
--- a/src/database/database.cpp
+++ b/src/database/database.cpp
@@ -139,14 +139,14 @@ auto Database::Open(IFileGatherer& gatherer,
[&]() -> cpp::result<Database*, DatabaseError> {
leveldb::DB* db;
std::unique_ptr<leveldb::Cache> cache{
- leveldb::NewLRUCache(4 * 1024)};
+ leveldb::NewLRUCache(256 * 1024)};
leveldb::Options options;
options.env = sEnv.env();
options.write_buffer_size = 4 * 1024;
- options.max_file_size = 32;
+ options.max_file_size = 16 * 1024;
options.block_cache = cache.get();
- options.block_size = 512;
+ options.block_size = 2048;
auto status = leveldb::DB::Open(options, kDbPath, &db);
if (!status.ok()) {
@@ -299,7 +299,7 @@ auto Database::updateIndexes() -> void {
UpdateNotifier notifier{is_updating_};
leveldb::ReadOptions read_options;
- read_options.fill_cache = false;
+ read_options.fill_cache = true;
// Stage 1: verify all existing tracks are still valid.
ESP_LOGI(kTag, "verifying existing tracks");
diff --git a/src/drivers/include/nvs.hpp b/src/drivers/include/nvs.hpp
index f288f8e2..25396622 100644
--- a/src/drivers/include/nvs.hpp
+++ b/src/drivers/include/nvs.hpp
@@ -114,6 +114,9 @@ class NvsStorage {
auto PrimaryInput() -> InputModes;
auto PrimaryInput(InputModes) -> void;
+ auto DbAutoIndex() -> bool;
+ auto DbAutoIndex(bool) -> void;
+
explicit NvsStorage(nvs_handle_t);
~NvsStorage();
@@ -136,6 +139,7 @@ class NvsStorage {
Setting<uint8_t> input_mode_;
Setting<uint8_t> output_mode_;
Setting<bluetooth::MacAndName> bt_preferred_;
+ Setting<uint8_t> db_auto_index_;
util::LruCache<10, bluetooth::mac_addr_t, uint8_t> bt_volumes_;
bool bt_volumes_dirty_;
diff --git a/src/drivers/include/samd.hpp b/src/drivers/include/samd.hpp
index ac265950..55ea513c 100644
--- a/src/drivers/include/samd.hpp
+++ b/src/drivers/include/samd.hpp
@@ -48,8 +48,8 @@ class Samd {
// There is a compatible usb host attached, but USB MSC is not currently
// in use by the SAMD.
kAttachedIdle,
- // The SAMD is currently exposing the SD card via USB MSC.
- kAttachedMounted,
+ // The SAMD is currently writing to the SD card via USB MSC.
+ kAttachedBusy,
};
auto GetUsbStatus() -> UsbStatus;
diff --git a/src/drivers/nvs.cpp b/src/drivers/nvs.cpp
index 28cb542c..33d92a9f 100644
--- a/src/drivers/nvs.cpp
+++ b/src/drivers/nvs.cpp
@@ -39,6 +39,7 @@ static constexpr char kKeyScrollSensitivity[] = "scroll";
static constexpr char kKeyLockPolarity[] = "lockpol";
static constexpr char kKeyDisplayCols[] = "dispcols";
static constexpr char kKeyDisplayRows[] = "disprows";
+static constexpr char kKeyDbAutoIndex[] = "dbautoindex";
static auto nvs_get_string(nvs_handle_t nvs, const char* key)
-> std::optional<std::string> {
@@ -173,6 +174,7 @@ NvsStorage::NvsStorage(nvs_handle_t handle)
input_mode_(kKeyPrimaryInput),
output_mode_(kKeyOutput),
bt_preferred_(kKeyBluetoothPreferred),
+ db_auto_index_(kKeyDbAutoIndex),
bt_volumes_(),
bt_volumes_dirty_(false) {}
@@ -194,6 +196,7 @@ auto NvsStorage::Read() -> void {
input_mode_.read(handle_);
output_mode_.read(handle_);
bt_preferred_.read(handle_);
+ db_auto_index_.read(handle_);
readBtVolumes();
}
@@ -210,6 +213,7 @@ auto NvsStorage::Write() -> bool {
input_mode_.write(handle_);
output_mode_.write(handle_);
bt_preferred_.write(handle_);
+ db_auto_index_.write(handle_);
writeBtVolumes();
return nvs_commit(handle_) == ESP_OK;
}
@@ -370,6 +374,16 @@ auto NvsStorage::PrimaryInput(InputModes mode) -> void {
input_mode_.set(static_cast<uint8_t>(mode));
}
+auto NvsStorage::DbAutoIndex() -> bool {
+ std::lock_guard<std::mutex> lock{mutex_};
+ return db_auto_index_.get().value_or(true);
+}
+
+auto NvsStorage::DbAutoIndex(bool en) -> void {
+ std::lock_guard<std::mutex> lock{mutex_};
+ db_auto_index_.set(static_cast<uint8_t>(en));
+}
+
class VolumesParseClient : public cppbor::ParseClient {
public:
VolumesParseClient(util::LruCache<10, bluetooth::mac_addr_t, uint8_t>& out)
diff --git a/src/drivers/samd.cpp b/src/drivers/samd.cpp
index b631b4fb..e47d9cfe 100644
--- a/src/drivers/samd.cpp
+++ b/src/drivers/samd.cpp
@@ -113,7 +113,7 @@ auto Samd::UpdateUsbStatus() -> void {
usb_status_ = UsbStatus::kDetached;
}
usb_status_ =
- (raw_res & 0b10) ? UsbStatus::kAttachedMounted : UsbStatus::kAttachedIdle;
+ (raw_res & 0b10) ? UsbStatus::kAttachedBusy : UsbStatus::kAttachedIdle;
}
auto Samd::ResetToFlashSamd() -> void {
diff --git a/src/lua/property.cpp b/src/lua/property.cpp
index 200f4d5c..e136ad90 100644
--- a/src/lua/property.cpp
+++ b/src/lua/property.cpp
@@ -379,22 +379,22 @@ auto Property::Update(const LuaValue& v) -> void {
for (int i = bindings_.size() - 1; i >= 0; i--) {
auto& b = bindings_[i];
+ int top = lua_gettop(b.first);
+
lua_pushstring(b.first, kBindingsTable);
lua_gettable(b.first, LUA_REGISTRYINDEX); // REGISTRY[kBindingsTable]
int type = lua_rawgeti(b.first, -1, b.second); // push bindings[i]
// Has closure has been GCed?
if (type == LUA_TNIL) {
- // Clean up after ourselves.
- lua_pop(b.first, 1);
// Remove the binding.
bindings_.erase(bindings_.begin() + i);
- continue;
+ } else {
+ PushValue(*b.first); // push the argument
+ CallProtected(b.first, 1, 0); // invoke the closure
}
- PushValue(*b.first); // push the argument
- CallProtected(b.first, 1, 0); // invoke the closure
- lua_pop(b.first, 1); // pop the bindings table
+ lua_settop(b.first, top); // clean up after ourselves
}
}
diff --git a/src/system_fsm/include/system_events.hpp b/src/system_fsm/include/system_events.hpp
index 1be03f82..f9ab9e11 100644
--- a/src/system_fsm/include/system_events.hpp
+++ b/src/system_fsm/include/system_events.hpp
@@ -12,6 +12,7 @@
#include "bluetooth_types.hpp"
#include "database.hpp"
#include "haptics.hpp"
+#include "samd.hpp"
#include "service_locator.hpp"
#include "tinyfsm.hpp"
@@ -56,6 +57,9 @@ struct SdDetectChanged : tinyfsm::Event {
struct SamdUsbMscChanged : tinyfsm::Event {
bool en;
};
+struct SamdUsbStatusChanged : tinyfsm::Event {
+ drivers::Samd::UsbStatus new_status;
+};
struct BatteryStateChanged : tinyfsm::Event {
battery::Battery::BatteryState new_state;
diff --git a/src/system_fsm/running.cpp b/src/system_fsm/running.cpp
index a6ab5d47..8625ac66 100644
--- a/src/system_fsm/running.cpp
+++ b/src/system_fsm/running.cpp
@@ -166,13 +166,15 @@ auto Running::mountStorage() -> bool {
// Tell the database to refresh so that we pick up any changes from the newly
// mounted card.
- sServices->bg_worker().Dispatch<void>([&]() {
- auto db = sServices->database().lock();
- if (!db) {
- return;
- }
- db->updateIndexes();
- });
+ if (sServices->nvs().DbAutoIndex()) {
+ sServices->bg_worker().Dispatch<void>([&]() {
+ auto db = sServices->database().lock();
+ if (!db) {
+ return;
+ }
+ db->updateIndexes();
+ });
+ }
return true;
}
diff --git a/src/system_fsm/system_fsm.cpp b/src/system_fsm/system_fsm.cpp
index 5a1ccf8c..f502b49a 100644
--- a/src/system_fsm/system_fsm.cpp
+++ b/src/system_fsm/system_fsm.cpp
@@ -88,7 +88,7 @@ void SystemState::react(const internal::SamdInterrupt&) {
sServices->battery().Update();
}
if (usb_status != prev_usb_status) {
- ESP_LOGI(kTag, "usb status changed");
+ events::Ui().Dispatch(SamdUsbStatusChanged{.new_status = usb_status});
}
}
diff --git a/src/ui/include/ui_fsm.hpp b/src/ui/include/ui_fsm.hpp
index 5e1cc487..2bab487d 100644
--- a/src/ui/include/ui_fsm.hpp
+++ b/src/ui/include/ui_fsm.hpp
@@ -65,6 +65,7 @@ class UiState : public tinyfsm::Fsm<UiState> {
void react(const audio::VolumeLimitChanged&);
void react(const system_fsm::KeyLockChanged&);
+ void react(const system_fsm::SamdUsbStatusChanged&);
void react(const internal::DismissAlerts&);
void react(const internal::ControlSchemeChanged&);
@@ -130,8 +131,10 @@ class UiState : public tinyfsm::Fsm<UiState> {
static lua::Property sLockSwitch;
static lua::Property sDatabaseUpdating;
+ static lua::Property sDatabaseAutoUpdate;
static lua::Property sUsbMassStorageEnabled;
+ static lua::Property sUsbMassStorageBusy;
};
namespace states {
diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp
index 835da19e..28733123 100644
--- a/src/ui/ui_fsm.cpp
+++ b/src/ui/ui_fsm.cpp
@@ -43,6 +43,7 @@
#include "nvs.hpp"
#include "property.hpp"
#include "relative_wheel.hpp"
+#include "samd.hpp"
#include "screen.hpp"
#include "screen_lua.hpp"
#include "screen_splash.hpp"
@@ -282,6 +283,14 @@ lua::Property UiState::sScrollSensitivity{
lua::Property UiState::sLockSwitch{false};
lua::Property UiState::sDatabaseUpdating{false};
+lua::Property UiState::sDatabaseAutoUpdate{
+ false, [](const lua::LuaValue& val) {
+ if (!std::holds_alternative<bool>(val)) {
+ return false;
+ }
+ sServices->nvs().DbAutoIndex(std::get<bool>(val));
+ return true;
+ }};
lua::Property UiState::sUsbMassStorageEnabled{
false, [](const lua::LuaValue& val) {
@@ -294,6 +303,8 @@ lua::Property UiState::sUsbMassStorageEnabled{
return true;
}};
+lua::Property UiState::sUsbMassStorageBusy{false};
+
auto UiState::InitBootSplash(drivers::IGpios& gpios, drivers::NvsStorage& nvs)
-> bool {
// Init LVGL first, since the display driver registers itself with LVGL.
@@ -352,6 +363,11 @@ void UiState::react(const system_fsm::KeyLockChanged& ev) {
sLockSwitch.Update(ev.locking);
}
+void UiState::react(const system_fsm::SamdUsbStatusChanged& ev) {
+ sUsbMassStorageBusy.Update(ev.new_status ==
+ drivers::Samd::UsbStatus::kAttachedBusy);
+}
+
void UiState::react(const internal::ControlSchemeChanged&) {
if (!sInput) {
return;
@@ -557,14 +573,19 @@ void Lua::entry() {
"time", {
{"ticks", [&](lua_State* s) { return Ticks(s); }},
});
- registry.AddPropertyModule("database", {
- {"updating", &sDatabaseUpdating},
- });
+ registry.AddPropertyModule("database",
+ {
+ {"updating", &sDatabaseUpdating},
+ {"auto_update", &sDatabaseAutoUpdate},
+ });
registry.AddPropertyModule("usb",
{
{"msc_enabled", &sUsbMassStorageEnabled},
+ {"msc_busy", &sUsbMassStorageBusy},
});
+ sDatabaseAutoUpdate.Update(sServices->nvs().DbAutoIndex());
+
auto bt = sServices->bluetooth();
sBluetoothEnabled.Update(bt.IsEnabled());
sBluetoothConnected.Update(bt.IsConnected());