From 7a7bcc6ed83c5d689c37e12bcb23ee22dbaf677f Mon Sep 17 00:00:00 2001 From: Tomasz Duda Date: Wed, 21 Feb 2024 22:03:18 +0100 Subject: [PATCH] start impl preferences --- esphome/components/nrf52/gpio.py | 2 +- esphome/components/zephyr/gpio.cpp | 16 ++--- esphome/components/zephyr/gpio.h | 2 +- esphome/components/zephyr/preferences.cpp | 88 ++++++++++++++++++++--- esphome/components/zephyr/preferences.h | 4 +- 5 files changed, 88 insertions(+), 24 deletions(-) diff --git a/esphome/components/nrf52/gpio.py b/esphome/components/nrf52/gpio.py index 0357edfe89..90e8ce8f5c 100644 --- a/esphome/components/nrf52/gpio.py +++ b/esphome/components/nrf52/gpio.py @@ -12,7 +12,7 @@ from esphome.components.zephyr.const import ( zephyr_ns, ) -GPIOPin = zephyr_ns.class_("GPIOPin", cg.InternalGPIOPin) +GPIOPin = zephyr_ns.class_("ZephyrGPIOPin", cg.InternalGPIOPin) def _translate_pin(value): diff --git a/esphome/components/zephyr/gpio.cpp b/esphome/components/zephyr/gpio.cpp index e2e55c045b..be2337307e 100644 --- a/esphome/components/zephyr/gpio.cpp +++ b/esphome/components/zephyr/gpio.cpp @@ -38,18 +38,18 @@ struct ISRPinArg { bool inverted; }; -ISRInternalGPIOPin GPIOPin::to_isr() const { +ISRInternalGPIOPin ZephyrGPIOPin::to_isr() const { auto *arg = new ISRPinArg{}; arg->pin = pin_; arg->inverted = inverted_; return ISRInternalGPIOPin((void *) arg); } -void GPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const { +void ZephyrGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const { // TODO } -void GPIOPin::setup() { +void ZephyrGPIOPin::setup() { const struct device *gpio = nullptr; if (pin_ < 32) { #define GPIO0 DT_NODELABEL(gpio0) @@ -75,27 +75,27 @@ void GPIOPin::setup() { pin_mode(flags_); } -void GPIOPin::pin_mode(gpio::Flags flags) { +void ZephyrGPIOPin::pin_mode(gpio::Flags flags) { if (nullptr == gpio_) { return; } gpio_pin_configure(gpio_, pin_, flags_to_mode(flags, pin_, inverted_, value_)); } -std::string GPIOPin::dump_summary() const { +std::string ZephyrGPIOPin::dump_summary() const { char buffer[32]; snprintf(buffer, sizeof(buffer), "GPIO%u", pin_); return buffer; } -bool GPIOPin::digital_read() { +bool ZephyrGPIOPin::digital_read() { if (nullptr == gpio_) { return false; } return bool(gpio_pin_get(gpio_, pin_) != inverted_); } -void GPIOPin::digital_write(bool value) { +void ZephyrGPIOPin::digital_write(bool value) { // make sure that value is not ignored since it can be inverted e.g. on switch side // that way init state should be correct value_ = value; @@ -104,7 +104,7 @@ void GPIOPin::digital_write(bool value) { } gpio_pin_set(gpio_, pin_, value != inverted_ ? 1 : 0); } -void GPIOPin::detach_interrupt() const { +void ZephyrGPIOPin::detach_interrupt() const { // TODO } diff --git a/esphome/components/zephyr/gpio.h b/esphome/components/zephyr/gpio.h index 1054e568e0..7af424f360 100644 --- a/esphome/components/zephyr/gpio.h +++ b/esphome/components/zephyr/gpio.h @@ -6,7 +6,7 @@ struct device; namespace esphome { namespace zephyr { -class GPIOPin : public InternalGPIOPin { +class ZephyrGPIOPin : public InternalGPIOPin { public: void set_pin(uint8_t pin) { pin_ = pin; } void set_inverted(bool inverted) { inverted_ = inverted; } diff --git a/esphome/components/zephyr/preferences.cpp b/esphome/components/zephyr/preferences.cpp index bbb4d762de..408cbeb347 100644 --- a/esphome/components/zephyr/preferences.cpp +++ b/esphome/components/zephyr/preferences.cpp @@ -1,19 +1,90 @@ #ifdef USE_ZEPHYR #include "esphome/core/preferences.h" +#include "esphome/core/log.h" namespace esphome { namespace zephyr { -class Preferences : public ESPPreferences { +static const char *const TAG = "esp32.preferences"; + +struct NVSData { + std::string key; + std::vector data; +}; + +static std::vector s_pending_save; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + +class ZephyrPreferenceBackend : public ESPPreferenceBackend { + public: + std::string key; + // uint32_t nvs_handle; + bool save(const uint8_t *data, size_t len) override { + // try find in pending saves and update that + for (auto &obj : s_pending_save) { + if (obj.key == key) { + obj.data.assign(data, data + len); + return true; + } + } + NVSData save{}; + save.key = key; + save.data.assign(data, data + len); + s_pending_save.emplace_back(save); + ESP_LOGVV(TAG, "s_pending_save: key: %s, len: %d", key.c_str(), len); + return true; + } + + bool load(uint8_t *data, size_t len) override { + // try find in pending saves and load from that + for (auto &obj : s_pending_save) { + if (obj.key == key) { + if (obj.data.size() != len) { + // size mismatch + return false; + } + memcpy(data, obj.data.data(), len); + return true; + } + } + + // TODO + + // size_t actual_len; + // esp_err_t err = nvs_get_blob(nvs_handle, key.c_str(), nullptr, &actual_len); + // if (err != 0) { + // ESP_LOGV(TAG, "nvs_get_blob('%s'): %s - the key might not be set yet", key.c_str(), esp_err_to_name(err)); + // return false; + // } + // if (actual_len != len) { + // ESP_LOGVV(TAG, "NVS length does not match (%u!=%u)", actual_len, len); + // return false; + // } + // err = nvs_get_blob(nvs_handle, key.c_str(), data, &len); + // if (err != 0) { + // ESP_LOGV(TAG, "nvs_get_blob('%s') failed: %s", key.c_str(), esp_err_to_name(err)); + // return false; + // } else { + // ESP_LOGVV(TAG, "nvs_get_blob: key: %s, len: %d", key.c_str(), len); + // } + return true; + } +}; + +class ZephyrPreferences : public ESPPreferences { public: ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash) override { return make_preference(length, type); } ESPPreferenceObject make_preference(size_t length, uint32_t type) override { - // TODO - return {}; + auto *pref = new ZephyrPreferenceBackend(); // NOLINT(cppcoreguidelines-owning-memory) + // pref->nvs_handle = nvs_handle; + + uint32_t keyval = type; + pref->key = str_sprintf("%" PRIu32, keyval); + + return ESPPreferenceObject(pref); } bool sync() override { @@ -25,22 +96,17 @@ class Preferences : public ESPPreferences { // TODO return true; } - - // protected: - // uint8_t *eeprom_sector_; }; void setup_preferences() { - auto *prefs = new Preferences(); // NOLINT(cppcoreguidelines-owning-memory) + auto *prefs = new ZephyrPreferences(); // NOLINT(cppcoreguidelines-owning-memory) global_preferences = prefs; } -// TODO -// void preferences_prevent_write(bool prevent) { s_prevent_write = prevent; } -} // namespace nrf52 +} // namespace zephyr ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) } // namespace esphome -#endif // USE_RP2040 +#endif diff --git a/esphome/components/zephyr/preferences.h b/esphome/components/zephyr/preferences.h index a85a704acf..6a37e41b46 100644 --- a/esphome/components/zephyr/preferences.h +++ b/esphome/components/zephyr/preferences.h @@ -6,10 +6,8 @@ namespace esphome { namespace zephyr { void setup_preferences(); -// TODO -// void preferences_prevent_write(bool prevent); } // namespace zephyr } // namespace esphome -#endif // USE_RP2040 +#endif