nvs work
This commit is contained in:
parent
0caf28c86a
commit
da781c23f1
@ -1,3 +1,138 @@
|
|||||||
#include "hwdata.h"
|
#include "hwdata.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
static const char* TAG = "hwdata";
|
||||||
|
|
||||||
|
HWData::HWData()
|
||||||
|
: compat_mode(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
HWData::HWData(HWData1 data, bool compat_mode)
|
||||||
|
: compat_mode(compat_mode),
|
||||||
|
inner(data)
|
||||||
|
{}
|
||||||
|
|
||||||
|
esp_err_t HWData::save(nvs_handle_t handle, bool force) {
|
||||||
|
if (compat_mode && !force) {
|
||||||
|
ESP_LOGW(TAG, "Not saving due to being in compatability mode.");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
return inner.save(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWData HWData::load(nvs_handle_t handle) {
|
||||||
|
esp_err_t err;
|
||||||
|
|
||||||
|
uint16_t stored_version = 0;
|
||||||
|
err = nvs_get_u16(handle, "version", &stored_version);
|
||||||
|
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||||
|
ESP_LOGE(TAG, "No NVS data found! using defaults");
|
||||||
|
return HWData();
|
||||||
|
} else if (err != ESP_OK) {
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(err);
|
||||||
|
ESP_LOGE(TAG, "Other esp error! using defaults");
|
||||||
|
return HWData();
|
||||||
|
}
|
||||||
|
|
||||||
|
HWData1 data;
|
||||||
|
switch (stored_version) {
|
||||||
|
case 0:
|
||||||
|
ESP_LOGE(TAG, "HWData version was 0! using defaults");
|
||||||
|
return HWData();
|
||||||
|
case 1:
|
||||||
|
data.load(handle);
|
||||||
|
return HWData(data, false);
|
||||||
|
default:
|
||||||
|
ESP_LOGW(TAG, "Max currently supported version is %d, but saved version is %d. Loading version %d anyway!", CURRENT_HWDATA_VERSION, stored_version, CURRENT_HWDATA_VERSION);
|
||||||
|
data.load(handle);
|
||||||
|
return HWData(data, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HWData1::HWData1() {}
|
||||||
|
|
||||||
|
esp_err_t HWData1::save(nvs_handle_t handle) const {
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u16(handle, "version", 1));
|
||||||
|
|
||||||
|
// Serial number
|
||||||
|
ESP_ERROR_CHECK(nvs_set_str(handle, "serial_num", serial_num.c_str()));
|
||||||
|
|
||||||
|
// Revisions
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "rev_ctrl_maj", rev_ctrl_maj));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "rev_ctrl_min", rev_ctrl_min));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "rev_exp_maj", rev_exp_maj));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "rev_exp_min", rev_exp_min));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "rev_ft_maj", rev_ft_maj));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "rev_ft_min", rev_ft_min));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "rev_fb_maj", rev_fb_maj));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "rev_fb_min", rev_fb_min));
|
||||||
|
|
||||||
|
// Enums
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "sseg_color_t", static_cast<uint8_t>(sseg_color_t)));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "sseg_color_b", static_cast<uint8_t>(sseg_color_b)));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "lcd_color", static_cast<uint8_t>(lcd_color)));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "button_type", static_cast<uint8_t>(button_type)));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "tft_type", static_cast<uint8_t>(tft_type)));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "bat_type", static_cast<uint8_t>(bat_type)));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "shape1", static_cast<uint8_t>(shape1)));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "shape2", static_cast<uint8_t>(shape2)));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "shape3", static_cast<uint8_t>(shape3)));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "shape4", static_cast<uint8_t>(shape4)));
|
||||||
|
|
||||||
|
// Other fields
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "switch_pos", switch_pos));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "has_speaker", has_speaker));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "has_mic", has_mic));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "has_ir", has_ir));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "has_rfid", has_rfid));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "has_fp", has_fp));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "has_fp_hall", has_fp_hall));
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u8(handle, "has_close_hall", has_close_hall));
|
||||||
|
|
||||||
|
// Battery capacity
|
||||||
|
ESP_ERROR_CHECK(nvs_set_u16(handle, "bat_cap", bat_cap));
|
||||||
|
|
||||||
|
return nvs_commit(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWData1::load(nvs_handle_t handle) {
|
||||||
|
char buf[128];
|
||||||
|
size_t required_size = sizeof(buf);
|
||||||
|
esp_err_t err = nvs_get_str(handle, "serial_num", buf, &required_size);
|
||||||
|
serial_num = (err == ESP_OK) ? std::string(buf) : "";
|
||||||
|
|
||||||
|
nvs_get_u8(handle, "rev_ctrl_maj", &rev_ctrl_maj);
|
||||||
|
nvs_get_u8(handle, "rev_ctrl_min", &rev_ctrl_min);
|
||||||
|
nvs_get_u8(handle, "rev_exp_maj", &rev_exp_maj);
|
||||||
|
nvs_get_u8(handle, "rev_exp_min", &rev_exp_min);
|
||||||
|
nvs_get_u8(handle, "rev_ft_maj", &rev_ft_maj);
|
||||||
|
nvs_get_u8(handle, "rev_ft_min", &rev_ft_min);
|
||||||
|
nvs_get_u8(handle, "rev_fb_maj", &rev_fb_maj);
|
||||||
|
nvs_get_u8(handle, "rev_fb_min", &rev_fb_min);
|
||||||
|
|
||||||
|
uint8_t tmp;
|
||||||
|
if (nvs_get_u8(handle, "sseg_color_t", &tmp) == ESP_OK) sseg_color_t = static_cast<SSegColor>(tmp);
|
||||||
|
if (nvs_get_u8(handle, "sseg_color_b", &tmp) == ESP_OK) sseg_color_b = static_cast<SSegColor>(tmp);
|
||||||
|
if (nvs_get_u8(handle, "lcd_color", &tmp) == ESP_OK) lcd_color = static_cast<LCDColor>(tmp);
|
||||||
|
if (nvs_get_u8(handle, "button_type", &tmp) == ESP_OK) button_type = static_cast<ButtonType>(tmp);
|
||||||
|
if (nvs_get_u8(handle, "tft_type", &tmp) == ESP_OK) tft_type = static_cast<TFTType>(tmp);
|
||||||
|
if (nvs_get_u8(handle, "bat_type", &tmp) == ESP_OK) bat_type = static_cast<BatType>(tmp);
|
||||||
|
nvs_get_u16(handle, "bat_cap", &bat_cap);
|
||||||
|
|
||||||
|
if (nvs_get_u8(handle, "shape1", &tmp) == ESP_OK) shape1 = static_cast<Shape>(tmp);
|
||||||
|
if (nvs_get_u8(handle, "shape2", &tmp) == ESP_OK) shape2 = static_cast<Shape>(tmp);
|
||||||
|
if (nvs_get_u8(handle, "shape3", &tmp) == ESP_OK) shape3 = static_cast<Shape>(tmp);
|
||||||
|
if (nvs_get_u8(handle, "shape4", &tmp) == ESP_OK) shape4 = static_cast<Shape>(tmp);
|
||||||
|
|
||||||
|
nvs_get_u8(handle, "switch_pos", &switch_pos);
|
||||||
|
nvs_get_u8(handle, "has_speaker", &tmp); has_speaker = tmp;
|
||||||
|
nvs_get_u8(handle, "has_mic", &tmp); has_mic = tmp;
|
||||||
|
nvs_get_u8(handle, "has_ir", &tmp); has_ir = tmp;
|
||||||
|
nvs_get_u8(handle, "has_rfid", &tmp); has_rfid = tmp;
|
||||||
|
nvs_get_u8(handle, "has_fp", &tmp); has_fp = tmp;
|
||||||
|
nvs_get_u8(handle, "has_fp_hall", &tmp); has_fp_hall = tmp;
|
||||||
|
nvs_get_u8(handle, "has_close_hall", &tmp); has_close_hall = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,133 @@
|
|||||||
#ifndef HWDATA_H
|
#ifndef HWDATA_H
|
||||||
#define HWDATA_H
|
#define HWDATA_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
|
#define CURRENT_HWDATA_VERSION 1
|
||||||
|
#define CURRENT_HWDATA_STRUCT HWData1
|
||||||
|
|
||||||
|
enum class SSegColor : uint8_t {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
NONE = 1,
|
||||||
|
OTHER = 2,
|
||||||
|
RED = 3,
|
||||||
|
ORANGE = 4,
|
||||||
|
YELLOW = 5,
|
||||||
|
GREEN = 6,
|
||||||
|
BLUE = 7,
|
||||||
|
PURPLE = 8,
|
||||||
|
WHITE = 9,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class LCDColor : uint8_t {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
NONE = 1,
|
||||||
|
OTHER = 2,
|
||||||
|
BLACK_GREEN = 3,
|
||||||
|
WHITE_BLUE = 4,
|
||||||
|
BLACK_SKY = 5,
|
||||||
|
BLACK_WHITE = 6,
|
||||||
|
WHITE_BLACK = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ButtonType : uint8_t {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
NONE = 1,
|
||||||
|
OTHER = 2,
|
||||||
|
WHITE = 3,
|
||||||
|
BROWN = 4,
|
||||||
|
RED = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class TFTType : uint8_t {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
NONE = 1,
|
||||||
|
OTHER = 2,
|
||||||
|
EAST_RISING = 3,
|
||||||
|
SHENZHEN = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BatType : uint8_t {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
NONE = 1,
|
||||||
|
OTHER = 2,
|
||||||
|
BAT_18650 = 3,
|
||||||
|
LIPO = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Shape : uint8_t {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
OTHER = 1,
|
||||||
|
CIRCLE = 2,
|
||||||
|
SQUARE = 3,
|
||||||
|
TRIANGLE = 4,
|
||||||
|
X = 5,
|
||||||
|
STAR = 6,
|
||||||
|
SPADE = 7,
|
||||||
|
DIAMOND = 8,
|
||||||
|
CLUB = 9,
|
||||||
|
HEART = 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief Version 1 of HWData, kept constant for migrations
|
||||||
|
struct HWData1 {
|
||||||
|
std::string serial_num;
|
||||||
|
uint8_t rev_ctrl_maj;
|
||||||
|
uint8_t rev_ctrl_min;
|
||||||
|
uint8_t rev_exp_maj;
|
||||||
|
uint8_t rev_exp_min;
|
||||||
|
uint8_t rev_ft_maj;
|
||||||
|
uint8_t rev_ft_min;
|
||||||
|
uint8_t rev_fb_maj;
|
||||||
|
uint8_t rev_fb_min;
|
||||||
|
|
||||||
|
SSegColor sseg_color_t;
|
||||||
|
SSegColor sseg_color_b;
|
||||||
|
LCDColor lcd_color;
|
||||||
|
uint8_t switch_pos;
|
||||||
|
ButtonType button_type;
|
||||||
|
TFTType tft_type;
|
||||||
|
BatType bat_type;
|
||||||
|
uint16_t bat_cap;
|
||||||
|
|
||||||
|
Shape shape1;
|
||||||
|
Shape shape2;
|
||||||
|
Shape shape3;
|
||||||
|
Shape shape4;
|
||||||
|
|
||||||
|
bool has_speaker;
|
||||||
|
bool has_mic;
|
||||||
|
bool has_ir;
|
||||||
|
bool has_rfid;
|
||||||
|
bool has_fp;
|
||||||
|
bool has_fp_hall;
|
||||||
|
bool has_close_hall;
|
||||||
|
|
||||||
|
HWData1();
|
||||||
|
|
||||||
|
esp_err_t save(nvs_handle_t handle) const;
|
||||||
|
void load(nvs_handle_t handle);
|
||||||
|
|
||||||
|
// Add migration method as necessary
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @brief The current version of HWData, to be stored
|
||||||
|
struct HWData {
|
||||||
|
/// @brief `true` if there is some issue in loading, and we are doing a "best effort" to be compatible
|
||||||
|
/// We should make no writes to NVS if this is `true`.
|
||||||
|
volatile bool compat_mode;
|
||||||
|
HWData1 inner;
|
||||||
|
|
||||||
|
HWData();
|
||||||
|
HWData(HWData1 data, bool compat_mode);
|
||||||
|
|
||||||
|
esp_err_t save(nvs_handle_t handle, bool force = false);
|
||||||
|
static HWData load(nvs_handle_t handle);
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* HWDATA_H */
|
#endif /* HWDATA_H */
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
#include "nvs.h"
|
#include "nvs.h"
|
||||||
#include "nvs_flash.h"
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "bottom_half.h"
|
#include "bottom_half.h"
|
||||||
#include "char_lcd.h"
|
#include "char_lcd.h"
|
||||||
|
|
||||||
static const char* TAG = "nvs";
|
static const char* TAG = "nvs";
|
||||||
|
|
||||||
nvs_handle_t hw_handle;
|
static const char* HWDATA_NAMESPACE = "hwdata";
|
||||||
|
static HWData hw_data;
|
||||||
|
|
||||||
bool init_nvs() {
|
bool init_nvs() {
|
||||||
|
ESP_LOGI(TAG, "Initializing NVS...");
|
||||||
esp_err_t ret = nvs_flash_init();
|
esp_err_t ret = nvs_flash_init();
|
||||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
// NVS partition was truncated, erase and retry
|
// NVS partition was truncated, erase and retry
|
||||||
@ -32,7 +33,31 @@ bool init_nvs() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(ret);
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
nvs_handle_t hw_handle;
|
||||||
|
ret = nvs_open(HWDATA_NAMESPACE, NVS_READONLY, &hw_handle);
|
||||||
|
if (ret == ESP_ERR_NVS_NOT_FOUND) {
|
||||||
|
ESP_LOGW(TAG, "Partition \"%s\" has not been initialized. Loading defaults.", HWDATA_NAMESPACE);
|
||||||
|
hw_data = HWData();
|
||||||
|
} else {
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
hw_data = HWData::load(hw_handle);
|
||||||
|
nvs_close(hw_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "NVS initialized!");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HWData& get_hw_data() {
|
||||||
|
return hw_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_hw_data(bool force) {
|
||||||
|
nvs_handle_t hw_handle;
|
||||||
|
ESP_ERROR_CHECK(nvs_open(HWDATA_NAMESPACE, NVS_READWRITE, &hw_handle));
|
||||||
|
hw_data.save(hw_handle);
|
||||||
|
nvs_close(hw_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
#ifndef NVS_H
|
#ifndef NVS_H
|
||||||
#define NVS_H
|
#define NVS_H
|
||||||
|
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
#include "hwdata.h"
|
||||||
|
|
||||||
/// @brief Initializes the NVS.
|
/// @brief Initializes the NVS.
|
||||||
bool init_nvs();
|
bool init_nvs();
|
||||||
|
|
||||||
|
/// Gets the HWData stored in NVS.
|
||||||
|
HWData& get_hw_data();
|
||||||
|
|
||||||
#endif /* NVS_H */
|
#endif /* NVS_H */
|
||||||
Loading…
Reference in New Issue
Block a user