diff options
| author | ailurux <ailuruxx@gmail.com> | 2024-04-08 15:40:16 +1000 |
|---|---|---|
| committer | ailurux <ailuruxx@gmail.com> | 2024-04-08 15:40:16 +1000 |
| commit | f20ca9583af5312eea65cf144803d00be6e50602 (patch) | |
| tree | d6047ff952d6ad60a30ba038e6a5c72c64b8b0e7 /src | |
| parent | 01ae3fee30704577f4ea37ed7f2132990135163c (diff) | |
| parent | 96b62321c33ff5e146d52416dc5da3f0c240b4b0 (diff) | |
| download | tangara-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.cpp | 19 | ||||
| -rw-r--r-- | src/audio/bt_audio_output.cpp | 24 | ||||
| -rw-r--r-- | src/audio/i2s_audio_output.cpp | 33 | ||||
| -rw-r--r-- | src/audio/include/audio_sink.hpp | 3 | ||||
| -rw-r--r-- | src/audio/include/bt_audio_output.hpp | 2 | ||||
| -rw-r--r-- | src/audio/include/i2s_audio_output.hpp | 2 | ||||
| -rw-r--r-- | src/database/database.cpp | 8 | ||||
| -rw-r--r-- | src/drivers/include/nvs.hpp | 4 | ||||
| -rw-r--r-- | src/drivers/include/samd.hpp | 4 | ||||
| -rw-r--r-- | src/drivers/nvs.cpp | 14 | ||||
| -rw-r--r-- | src/drivers/samd.cpp | 2 | ||||
| -rw-r--r-- | src/lua/property.cpp | 12 | ||||
| -rw-r--r-- | src/system_fsm/include/system_events.hpp | 4 | ||||
| -rw-r--r-- | src/system_fsm/running.cpp | 16 | ||||
| -rw-r--r-- | src/system_fsm/system_fsm.cpp | 2 | ||||
| -rw-r--r-- | src/ui/include/ui_fsm.hpp | 3 | ||||
| -rw-r--r-- | src/ui/ui_fsm.cpp | 27 |
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()); |
