summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-09-04 16:17:55 +1000
committerjacqueline <me@jacqueline.id.au>2023-09-04 16:17:55 +1000
commitd5d6e3993cd67238ff245446e69e2f200c3fd0e5 (patch)
tree6245939ab341694363eac8bc24ab1b91b5140c6e /src/drivers
parent6d831fa7a8c50e15424814fd2be1dd3951e06a4f (diff)
downloadtangara-fw-d5d6e3993cd67238ff245446e69e2f200c3fd0e5.tar.gz
Support changing max volume, persisted to nvs
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/include/nvs.hpp6
-rw-r--r--src/drivers/include/wm8523.hpp20
-rw-r--r--src/drivers/nvs.cpp33
-rw-r--r--src/drivers/wm8523.cpp17
4 files changed, 76 insertions, 0 deletions
diff --git a/src/drivers/include/nvs.hpp b/src/drivers/include/nvs.hpp
index bc88f88d..d7b3dfdd 100644
--- a/src/drivers/include/nvs.hpp
+++ b/src/drivers/include/nvs.hpp
@@ -37,6 +37,12 @@ class NvsStorage {
auto ScreenBrightness() -> std::future<uint_fast8_t>;
auto ScreenBrightness(uint_fast8_t) -> std::future<bool>;
+ auto AmpMaxVolume() -> std::future<uint16_t>;
+ auto AmpMaxVolume(uint16_t) -> std::future<bool>;
+
+ auto AmpCurrentVolume() -> std::future<uint16_t>;
+ auto AmpCurrentVolume(uint16_t) -> std::future<bool>;
+
explicit NvsStorage(std::unique_ptr<tasks::Worker>, nvs_handle_t);
~NvsStorage();
diff --git a/src/drivers/include/wm8523.hpp b/src/drivers/include/wm8523.hpp
index 6dc2e56e..b13cf34b 100644
--- a/src/drivers/include/wm8523.hpp
+++ b/src/drivers/include/wm8523.hpp
@@ -5,12 +5,32 @@
*/
#pragma once
+#include <stdint.h>
#include <cstdint>
#include <optional>
namespace drivers {
namespace wm8523 {
+extern const uint16_t kAbsoluteMaxVolume;
+
+extern const uint16_t kAbsoluteMinVolume;
+
+extern const uint16_t kMaxVolumeBeforeClipping;
+
+extern const uint16_t kLineLevelReferenceVolume;
+
+extern const uint16_t kDefaultVolume;
+extern const uint16_t kDefaultMaxVolume;
+
+constexpr auto VolumeToDb(uint16_t vol) -> int_fast8_t {
+ return (vol - kLineLevelReferenceVolume) / 4;
+}
+
+constexpr auto DbToVolume(int_fast8_t db) -> uint16_t {
+ return (db * 4) + kLineLevelReferenceVolume;
+}
+
enum class Register : uint8_t {
kReset = 0,
kRevision = 1,
diff --git a/src/drivers/nvs.cpp b/src/drivers/nvs.cpp
index c2832bf4..7bd1afe2 100644
--- a/src/drivers/nvs.cpp
+++ b/src/drivers/nvs.cpp
@@ -17,6 +17,7 @@
#include "nvs.h"
#include "nvs_flash.h"
#include "tasks.hpp"
+#include "wm8523.hpp"
namespace drivers {
@@ -27,6 +28,8 @@ static constexpr char kKeyVersion[] = "ver";
static constexpr char kKeyBluetooth[] = "bt";
static constexpr char kKeyOutput[] = "out";
static constexpr char kKeyBrightness[] = "bright";
+static constexpr char kKeyAmpMaxVolume[] = "hp_vol_max";
+static constexpr char kKeyAmpCurrentVolume[] = "hp_vol";
auto NvsStorage::OpenSync() -> NvsStorage* {
esp_err_t err = nvs_flash_init();
@@ -154,4 +157,34 @@ auto NvsStorage::ScreenBrightness(uint_fast8_t val) -> std::future<bool> {
});
}
+auto NvsStorage::AmpMaxVolume() -> std::future<uint16_t> {
+ return writer_->Dispatch<uint16_t>([&]() -> uint16_t {
+ uint16_t out = wm8523::kDefaultMaxVolume;
+ nvs_get_u16(handle_, kKeyAmpMaxVolume, &out);
+ return out;
+ });
+}
+
+auto NvsStorage::AmpMaxVolume(uint16_t val) -> std::future<bool> {
+ return writer_->Dispatch<bool>([&]() {
+ nvs_set_u16(handle_, kKeyAmpMaxVolume, val);
+ return nvs_commit(handle_) == ESP_OK;
+ });
+}
+
+auto NvsStorage::AmpCurrentVolume() -> std::future<uint16_t> {
+ return writer_->Dispatch<uint16_t>([&]() -> uint16_t {
+ uint16_t out = wm8523::kDefaultVolume;
+ nvs_get_u16(handle_, kKeyAmpCurrentVolume, &out);
+ return out;
+ });
+}
+
+auto NvsStorage::AmpCurrentVolume(uint16_t val) -> std::future<bool> {
+ return writer_->Dispatch<bool>([&]() {
+ nvs_set_u16(handle_, kKeyAmpCurrentVolume, val);
+ return nvs_commit(handle_) == ESP_OK;
+ });
+}
+
} // namespace drivers
diff --git a/src/drivers/wm8523.cpp b/src/drivers/wm8523.cpp
index e1dffd51..5f6c8053 100644
--- a/src/drivers/wm8523.cpp
+++ b/src/drivers/wm8523.cpp
@@ -15,6 +15,23 @@
namespace drivers {
namespace wm8523 {
+const uint16_t kAbsoluteMaxVolume = 0x1ff;
+const uint16_t kAbsoluteMinVolume = 0b0;
+
+// This is 3dB below what the DAC considers to be '0dB', and 9.5dB above line
+// level reference.
+const uint16_t kMaxVolumeBeforeClipping = 0x184;
+
+// This is 12.5 dB below what the DAC considers to be '0dB'.
+const uint16_t kLineLevelReferenceVolume = 0x15E;
+
+// Default to -24 dB, which I will claim is 'arbitrarily chosen to be safe but
+// audible', but is in fact just a nice value for my headphones in particular.
+const uint16_t kDefaultVolume = kLineLevelReferenceVolume - 96;
+
+// Default to +6dB == 2Vrms == 'CD Player'
+const uint16_t kDefaultMaxVolume = kLineLevelReferenceVolume + 12;
+
static const uint8_t kAddress = 0b0011010;
auto ReadRegister(Register reg) -> std::optional<uint16_t> {