You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
3.6 KiB
151 lines
3.6 KiB
/*
|
|
* Copyright 2023 jacqueline <me@jacqueline.id.au>
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-only
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <memory>
|
|
#include <optional>
|
|
|
|
#include "esp_err.h"
|
|
#include "nvs.h"
|
|
|
|
#include "bluetooth_types.hpp"
|
|
#include "lru_cache.hpp"
|
|
#include "tasks.hpp"
|
|
|
|
namespace drivers {
|
|
|
|
/*
|
|
* Wrapper for a single NVS setting, with its backing value cached in memory.
|
|
* NVS values that are just plain old data should generally use these for
|
|
* simpler implementation.
|
|
*/
|
|
template <typename T>
|
|
class Setting {
|
|
public:
|
|
Setting(const char* name) : name_(name), val_(), dirty_(false) {}
|
|
|
|
auto set(const std::optional<T>&& v) -> void {
|
|
if (val_.has_value() != v.has_value() || *val_ != *v) {
|
|
val_ = v;
|
|
dirty_ = true;
|
|
}
|
|
}
|
|
auto get() -> std::optional<T>& { return val_; }
|
|
|
|
/* Reads the stored value from NVS and parses it into the correct type. */
|
|
auto load(nvs_handle_t) -> std::optional<T>;
|
|
/* Encodes the given value and writes it to NVS. */
|
|
auto store(nvs_handle_t, T v) -> void;
|
|
|
|
auto read(nvs_handle_t nvs) -> void { val_ = load(nvs); }
|
|
auto write(nvs_handle_t nvs) -> void {
|
|
if (!dirty_) {
|
|
return;
|
|
}
|
|
dirty_ = false;
|
|
if (val_) {
|
|
store(nvs, *val_);
|
|
} else {
|
|
nvs_erase_key(nvs, name_);
|
|
}
|
|
}
|
|
|
|
private:
|
|
const char* name_;
|
|
std::optional<T> val_;
|
|
bool dirty_;
|
|
};
|
|
|
|
class NvsStorage {
|
|
public:
|
|
static auto OpenSync() -> NvsStorage*;
|
|
|
|
auto Read() -> void;
|
|
auto Write() -> bool;
|
|
|
|
auto LockPolarity() -> bool;
|
|
auto LockPolarity(bool) -> void;
|
|
|
|
auto DisplaySize()
|
|
-> std::pair<std::optional<uint16_t>, std::optional<uint16_t>>;
|
|
auto DisplaySize(std::pair<std::optional<uint16_t>, std::optional<uint16_t>>)
|
|
-> void;
|
|
|
|
auto PreferredBluetoothDevice() -> std::optional<bluetooth::MacAndName>;
|
|
auto PreferredBluetoothDevice(std::optional<bluetooth::MacAndName>) -> void;
|
|
|
|
auto BluetoothVolume(const bluetooth::mac_addr_t&) -> uint8_t;
|
|
auto BluetoothVolume(const bluetooth::mac_addr_t&, uint8_t) -> void;
|
|
|
|
enum class Output : uint8_t {
|
|
kHeadphones = 0,
|
|
kBluetooth = 1,
|
|
};
|
|
auto OutputMode() -> Output;
|
|
auto OutputMode(Output) -> void;
|
|
|
|
auto ScreenBrightness() -> uint_fast8_t;
|
|
auto ScreenBrightness(uint_fast8_t) -> void;
|
|
|
|
auto ScrollSensitivity() -> uint_fast8_t;
|
|
auto ScrollSensitivity(uint_fast8_t) -> void;
|
|
|
|
auto AmpMaxVolume() -> uint16_t;
|
|
auto AmpMaxVolume(uint16_t) -> void;
|
|
|
|
auto AmpCurrentVolume() -> uint16_t;
|
|
auto AmpCurrentVolume(uint16_t) -> void;
|
|
|
|
auto AmpLeftBias() -> int_fast8_t;
|
|
auto AmpLeftBias(int_fast8_t) -> void;
|
|
|
|
enum class InputModes : uint8_t {
|
|
kButtonsOnly = 0,
|
|
kButtonsWithWheel = 1,
|
|
kDirectionalWheel = 2,
|
|
kRotatingWheel = 3,
|
|
};
|
|
|
|
auto PrimaryInput() -> InputModes;
|
|
auto PrimaryInput(InputModes) -> void;
|
|
|
|
auto DbAutoIndex() -> bool;
|
|
auto DbAutoIndex(bool) -> void;
|
|
|
|
explicit NvsStorage(nvs_handle_t);
|
|
~NvsStorage();
|
|
|
|
private:
|
|
auto DowngradeSchemaSync() -> bool;
|
|
auto SchemaVersionSync() -> uint8_t;
|
|
|
|
std::mutex mutex_;
|
|
nvs_handle_t handle_;
|
|
|
|
Setting<uint8_t> lock_polarity_;
|
|
Setting<uint16_t> display_cols_;
|
|
Setting<uint16_t> display_rows_;
|
|
|
|
Setting<uint8_t> brightness_;
|
|
Setting<uint8_t> sensitivity_;
|
|
Setting<uint16_t> amp_max_vol_;
|
|
Setting<uint16_t> amp_cur_vol_;
|
|
Setting<int8_t> amp_left_bias_;
|
|
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_;
|
|
|
|
auto readBtVolumes() -> void;
|
|
auto writeBtVolumes() -> void;
|
|
};
|
|
|
|
} // namespace drivers
|
|
|