TOLO: a whole boot load of changes, too many to list but a lot of stuff is working now.

This commit is contained in:
Morgan 'ARR\!' Allen 2024-11-15 11:41:07 -08:00
parent e3e76f57b3
commit 0cd6971e70
8 changed files with 168 additions and 66 deletions

View file

@ -6,6 +6,10 @@ if(${ESP_PLATFORM})
list(APPEND SRCS src/cfglr_nvs.c src/cfglr_signal_idf_event.c) list(APPEND SRCS src/cfglr_nvs.c src/cfglr_signal_idf_event.c)
endif() endif()
# make LVGL configurable
list(APPEND REQUIRES lvgl)
list(APPEND SRCS src/cfglr_signal_lvgl.c)
idf_component_register( idf_component_register(
SRCS ${SRCS} SRCS ${SRCS}
INCLUDE_DIRS "include" INCLUDE_DIRS "include"

View file

@ -7,10 +7,14 @@
#define CFGLR_LOGI(TAG, STR, ...) ESP_LOGI(TAG, STR, ##__VA_ARGS__) #define CFGLR_LOGI(TAG, STR, ...) ESP_LOGI(TAG, STR, ##__VA_ARGS__)
#define CFGLR_LOGD(TAG, STR, ...) ESP_LOGD(TAG, STR, ##__VA_ARGS__) #define CFGLR_LOGD(TAG, STR, ...) ESP_LOGD(TAG, STR, ##__VA_ARGS__)
#define CFGLR_LOGE(TAG, STR, ...) ESP_LOGE(TAG, STR, ##__VA_ARGS__)
#define CFGLR_LOGW(TAG, STR, ...) ESP_LOGW(TAG, STR, ##__VA_ARGS__)
#else #else
#define CFGLR_LOGI(TAG, STR, ...) print(TAG); printf(STR, ##__VA_ARGS__); #define CFGLR_LOGI(TAG, STR, ...) print(TAG); printf(STR, ##__VA_ARGS__);
#define CFGLR_LOGD(TAG, STR, ...) print(TAG); printf(STR, ##__VA_ARGS__); #define CFGLR_LOGD(TAG, STR, ...) print(TAG); printf(STR, ##__VA_ARGS__);
#define CFGLR_LOGE(TAG, STR, ...) print(TAG); printf(STR, ##__VA_ARGS__);
#define CFGLR_LOGW(TAG, STR, ...) print(TAG); printf(STR, ##__VA_ARGS__);
#endif #endif
#endif #endif

View file

@ -0,0 +1,16 @@
#ifndef _CFGLR_SIGNAL_LVGL_H_
#define _CFGLR_SIGNAL_LVGL_H_
#include "configulator.h"
uint8_t cfglr_signaler_lvgl_init(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_handle_t *handle);
uint8_t cfglr_signaler_lvgl_dispatch(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_signal_e sig);
#define CFGLR_SIGNALER_LVGL(KEY, LV_OBJ) {\
.key = KEY,\
.init = &cfglr_signaler_lvgl_init,\
.dispatch = &cfglr_signaler_lvgl_dispatch,\
.handle = LV_OBJ,\
}
#endif

View file

@ -4,7 +4,7 @@
#include <stdint.h> #include <stdint.h>
#define CFGLR_BACKENDS_MAX (04) #define CFGLR_BACKENDS_MAX (04)
#define CFGLR_ELEMENTS_MAX (04) #define CFGLR_ELEMENTS_MAX (12)
#define CFGLR_SIGNALERS_MAX (04) #define CFGLR_SIGNALERS_MAX (04)
typedef enum { typedef enum {
@ -28,30 +28,35 @@ typedef enum {
#define CFGLR_DATATYPE_COUNT (uint8_t)(CFGLR_DATATYPE_BIN - CFGLR_DATATYPE_U8) #define CFGLR_DATATYPE_COUNT (uint8_t)(CFGLR_DATATYPE_BIN - CFGLR_DATATYPE_U8)
typedef struct {
const char *key;
uint8_t dirty;
cfglr_datatype_e datatype;
uint8_t datatype_size;
void *data;
void *default_data;
} cfglr_element_t;
typedef struct cfglr_signaler cfglr_signaler_t; typedef struct cfglr_signaler cfglr_signaler_t;
typedef struct cfglr_handle_struct cfglr_handle_t; typedef struct cfglr_handle_struct cfglr_handle_t;
typedef struct cfglr_element cfglr_element_t;
typedef void (*cfglr_signaler_init_t)(cfglr_signaler_t *signaler, cfglr_handle_t *handle); typedef void (*cfglr_signaler_init_t)(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_handle_t *handle);
typedef void (*cfglr_signaler_dispatch_t)(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_signal_e sig); typedef void (*cfglr_signaler_dispatch_t)(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_signal_e sig);
struct cfglr_signaler { struct cfglr_signaler {
const char *key;
cfglr_signaler_dispatch_t dispatch; cfglr_signaler_dispatch_t dispatch;
cfglr_signaler_init_t init; cfglr_signaler_init_t init;
void *handle; void *handle;
}; };
struct cfglr_element {
const char *key;
uint8_t dirty;
uint8_t signaler_count;
cfglr_datatype_e datatype;
// TODO precalcualte sizes in an array and use datatype enum to look up
uint8_t datatype_size;
void *data;
void *default_data;
cfglr_handle_t *handle;
cfglr_signaler_t signalers[CFGLR_SIGNALERS_MAX];
};
#define CFGLR_ELEMENT(KEY, TYPE, DEFAULT, SIZE) (cfglr_element_t){\ #define CFGLR_ELEMENT(KEY, TYPE, DEFAULT, SIZE) (cfglr_element_t){\
.key = KEY,\ .key = KEY,\
.dirty = 1,\
.datatype = TYPE,\ .datatype = TYPE,\
.datatype_size = SIZE,\ .datatype_size = SIZE,\
.default_data = (void*)DEFAULT,\ .default_data = (void*)DEFAULT,\
@ -59,7 +64,10 @@ struct cfglr_signaler {
#define CFGLR_ELEMENT_U8(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_U8, DEFAULT, sizeof(uint8_t)) #define CFGLR_ELEMENT_U8(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_U8, DEFAULT, sizeof(uint8_t))
#define CFGLR_ELEMENT_I8(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_I8, DEFAULT, sizeof(int8_t)) #define CFGLR_ELEMENT_I8(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_I8, DEFAULT, sizeof(int8_t))
#define CFGLR_ELEMENT_U16(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_U16, DEFAULT, sizeof(uint16_t))
#define CFGLR_ELEMENT_I16(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_I16, DEFAULT, sizeof(int16_t))
#define CFGLR_ELEMENT_U32(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_U32, DEFAULT, sizeof(uint32_t))
#define CFGLR_ELEMENT_I32(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_I32, DEFAULT, sizeof(int32_t))
#define CFGLR_ELEMENT_U64(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_U64, DEFAULT, sizeof(uint64_t)) #define CFGLR_ELEMENT_U64(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_U64, DEFAULT, sizeof(uint64_t))
#define CFGLR_ELEMENT_I64(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_I64, DEFAULT, sizeof(int64_t)) #define CFGLR_ELEMENT_I64(KEY, DEFAULT) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_I64, DEFAULT, sizeof(int64_t))
@ -70,6 +78,7 @@ typedef void (*cfglr_backend_close_t)(cfglr_backend_t *backend, cfglr_handle_t *
typedef uint16_t (*cfglr_backend_get_t)(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle); typedef uint16_t (*cfglr_backend_get_t)(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle);
typedef uint16_t (*cfglr_backend_set_t)(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle); typedef uint16_t (*cfglr_backend_set_t)(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle);
uint16_t cfglr_commit(cfglr_element_t *element);
uint16_t cfglr_commit_data(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle); uint16_t cfglr_commit_data(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle);
struct cfglr_backend { struct cfglr_backend {
@ -92,9 +101,7 @@ struct cfglr_handle_struct {
uint8_t store_default; uint8_t store_default;
uint8_t backend_count; uint8_t backend_count;
uint8_t element_count; uint8_t element_count;
uint8_t signaler_count; cfglr_backend_t backend;
cfglr_signaler_t signalers[CFGLR_SIGNALERS_MAX];
cfglr_backend_t backends[CFGLR_BACKENDS_MAX];
cfglr_element_t elements[CFGLR_ELEMENTS_MAX]; cfglr_element_t elements[CFGLR_ELEMENTS_MAX];
}; };
@ -103,5 +110,6 @@ uint8_t cfglr_fetch_data(cfglr_backend_t *backend, cfglr_element_t *element, cfg
#include "cfglr_nvs.h" #include "cfglr_nvs.h"
#include "cfglr_signaler_idf_event.h" #include "cfglr_signaler_idf_event.h"
#include "cfglr_signaler_lvgl.h"
#endif//__CONFIGULATOR_H__ #endif//__CONFIGULATOR_H__

View file

@ -4,7 +4,10 @@
void cfglr_backend_nvs_open(cfglr_backend_t *backend, cfglr_handle_t *handle) { void cfglr_backend_nvs_open(cfglr_backend_t *backend, cfglr_handle_t *handle) {
CFGLR_LOGI(TAG, "opening NVS partition: %s", handle->namespace); CFGLR_LOGI(TAG, "opening NVS partition: %s", handle->namespace);
esp_err_t err = nvs_open(handle->namespace, NVS_READWRITE, (nvs_handle_t*)&backend->handle); esp_err_t err = nvs_open(handle->namespace, NVS_READWRITE, (nvs_handle_t*)&backend->handle);
ESP_ERROR_CHECK(err);
} }
void cfglr_backend_nvs_close(cfglr_backend_t *backend, cfglr_handle_t *handle) { void cfglr_backend_nvs_close(cfglr_backend_t *backend, cfglr_handle_t *handle) {
@ -24,7 +27,6 @@ uint16_t cfglr_backend_nvs_get(cfglr_backend_t *backend, cfglr_element_t *elemen
err = nvs_get_i8((nvs_handle_t)backend->handle, element->key, (int8_t*)element->data); err = nvs_get_i8((nvs_handle_t)backend->handle, element->key, (int8_t*)element->data);
break; break;
/*
case CFGLR_DATATYPE_U16: case CFGLR_DATATYPE_U16:
err = nvs_get_u16((nvs_handle_t)backend->handle, element->key, (uint16_t*)element->data); err = nvs_get_u16((nvs_handle_t)backend->handle, element->key, (uint16_t*)element->data);
break; break;
@ -48,13 +50,13 @@ uint16_t cfglr_backend_nvs_get(cfglr_backend_t *backend, cfglr_element_t *elemen
case CFGLR_DATATYPE_I64: case CFGLR_DATATYPE_I64:
err = nvs_get_i64((nvs_handle_t)backend->handle, element->key, (int64_t*)element->data); err = nvs_get_i64((nvs_handle_t)backend->handle, element->key, (int64_t*)element->data);
break; break;
*/
default: default:
CFGLR_LOGI(TAG, "unhandlable datatype: %d", element->datatype); CFGLR_LOGI(TAG, "unhandlable datatype: %d", element->datatype);
} }
if(err == ESP_ERR_NVS_NOT_FOUND) { if(err == ESP_ERR_NVS_NOT_FOUND) {
CFGLR_LOGI(TAG, "NOT FOUN!!!!");
} else if(err != ESP_OK) { } else if(err != ESP_OK) {
ESP_ERROR_CHECK(err); ESP_ERROR_CHECK(err);
} else if(err == ESP_OK) { } else if(err == ESP_OK) {
@ -70,37 +72,40 @@ uint16_t cfglr_backend_nvs_get(cfglr_backend_t *backend, cfglr_element_t *elemen
uint16_t cfglr_backend_nvs_set(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle) { uint16_t cfglr_backend_nvs_set(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle) {
esp_err_t err = ESP_OK; esp_err_t err = ESP_OK;
CFGLR_LOGI(TAG, "setting %s", element->key);
switch(element->datatype) { switch(element->datatype) {
case CFGLR_DATATYPE_U8: case CFGLR_DATATYPE_U8:
err = nvs_set_u8((nvs_handle_t)backend->handle, element->key, (uint8_t)element->data); CFGLR_LOGI(TAG, "value %d", *(int*)element->data);
err = nvs_set_u8((nvs_handle_t)backend->handle, element->key, *(uint8_t*)element->data);
break; break;
case CFGLR_DATATYPE_I8: case CFGLR_DATATYPE_I8:
err = nvs_set_i8((nvs_handle_t)backend->handle, element->key, (int8_t)element->data); err = nvs_set_i8((nvs_handle_t)backend->handle, element->key, *(int8_t*)element->data);
break; break;
case CFGLR_DATATYPE_U16: case CFGLR_DATATYPE_U16:
err = nvs_set_u16((nvs_handle_t)backend->handle, element->key, (uint16_t)element->data); err = nvs_set_u16((nvs_handle_t)backend->handle, element->key, *(uint16_t*)element->data);
break; break;
case CFGLR_DATATYPE_I16: case CFGLR_DATATYPE_I16:
err = nvs_set_i16((nvs_handle_t)backend->handle, element->key, (int16_t)element->data); err = nvs_set_i16((nvs_handle_t)backend->handle, element->key, *(int16_t*)element->data);
break; break;
case CFGLR_DATATYPE_U32: case CFGLR_DATATYPE_U32:
err = nvs_set_u32((nvs_handle_t)backend->handle, element->key, (uint32_t)element->data); err = nvs_set_u32((nvs_handle_t)backend->handle, element->key, *(uint32_t*)element->data);
break; break;
case CFGLR_DATATYPE_I32: case CFGLR_DATATYPE_I32:
err = nvs_set_i32((nvs_handle_t)backend->handle, element->key, (int32_t)element->data); err = nvs_set_i32((nvs_handle_t)backend->handle, element->key, *(int32_t*)element->data);
break; break;
case CFGLR_DATATYPE_U64: case CFGLR_DATATYPE_U64:
err = nvs_set_u64((nvs_handle_t)backend->handle, element->key, (uint64_t)element->data); err = nvs_set_u64((nvs_handle_t)backend->handle, element->key, *(uint64_t*)element->data);
break; break;
case CFGLR_DATATYPE_I64: case CFGLR_DATATYPE_I64:
err = nvs_set_i64((nvs_handle_t)backend->handle, element->key, (int64_t)element->data); err = nvs_set_i64((nvs_handle_t)backend->handle, element->key, *(int64_t*)element->data);
break; break;
case CFGLR_DATATYPE_STR: case CFGLR_DATATYPE_STR:
@ -113,6 +118,8 @@ uint16_t cfglr_backend_nvs_set(cfglr_backend_t *backend, cfglr_element_t *elemen
CFGLR_LOGI(TAG, "unhandlable datatype: %d", element->datatype); CFGLR_LOGI(TAG, "unhandlable datatype: %d", element->datatype);
} }
err = nvs_commit((nvs_handle_t)backend->handle);
if(err == ESP_OK) { if(err == ESP_OK) {
} }

View file

@ -12,6 +12,10 @@ const char* cfglr_signal_names[] = {
"CFGLR_SIGNAL_DELETE", "CFGLR_SIGNAL_DELETE",
}; };
uint8_t cfglr_signaler_idf_init(cfglr_signaler_t *signaler, cfglr_handle_t *handle) {
return 0;
}
uint8_t cfglr_signaler_idf_dispatch(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_signal_e sig) { uint8_t cfglr_signaler_idf_dispatch(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_signal_e sig) {
CFGLR_LOGI(TAG, "dispatch: %s", cfglr_signal_names[sig]); CFGLR_LOGI(TAG, "dispatch: %s", cfglr_signal_names[sig]);

49
src/cfglr_signal_lvgl.c Normal file
View file

@ -0,0 +1,49 @@
#include "cfglr_log.h"
#include "cfglr_signaler_lvgl.h"
#include "lvgl.h"
#define TAG "CFGLR_SIG_LVGL"
void cfglr_signaler_lvgl_change_cb(lv_event_t *e) {
lv_obj_t *target = lv_event_get_current_target(e);
cfglr_element_t *element = lv_event_get_user_data(e);
if(lv_obj_check_type(target, &lv_checkbox_class)) {
lv_state_t state = lv_obj_get_state(target);
uint8_t mon = *(int*)element->data;
// A new event is pushed when dispatching so the loop needs to be broken if the value
// didn't actually change.
if(mon != (state & LV_STATE_CHECKED)) {
CFGLR_LOGD(TAG, "element->data: %p %d", element->data, *(uint8_t*)element->data);
*(int*)(element->data) = (state & LV_STATE_CHECKED);
cfglr_commit(element);
}
}
}
uint8_t cfglr_signaler_lvgl_init(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_handle_t *handle) {
CFGLR_LOGI(TAG, "init");
CFGLR_LOGI(TAG, "ui handle: %p", signaler->handle);
lv_obj_add_event_cb((lv_obj_t*)signaler->handle, cfglr_signaler_lvgl_change_cb, LV_EVENT_VALUE_CHANGED, element);
return 0;
}
uint8_t cfglr_signaler_lvgl_dispatch(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_signal_e sig) {
CFGLR_LOGI(TAG, "dispatch: %d", *(uint8_t*)element->data);
if(strstr(element->key, "monitor") != NULL) {
if(*(uint8_t*)element->data == 1) {
lv_obj_add_state((lv_obj_t*)signaler->handle, LV_STATE_CHECKED);
} else {
lv_obj_clear_state((lv_obj_t*)signaler->handle, LV_STATE_CHECKED);
}
lv_event_send((lv_obj_t*)signaler->handle, LV_EVENT_VALUE_CHANGED, NULL);
}
return 0;
}

View file

@ -5,75 +5,85 @@
#define TAG "CFGLR" #define TAG "CFGLR"
uint8_t cfglr_init(cfglr_handle_t *handle) { uint8_t cfglr_init(cfglr_handle_t *handle) {
uint8_t tick = 0; cfglr_backend_t *backend = &handle->backend;
cfglr_backend_t *backend;
cfglr_element_t *element; cfglr_element_t *element;
cfglr_signaler_t *signaler; cfglr_signaler_t *signaler;
handle->backend_count = 0;
handle->element_count = 0; handle->element_count = 0;
CFGLR_LOGI(TAG, "initializing backends"); CFGLR_LOGI(TAG, "initializing backend");
while((backend = &handle->backends[tick])) {
if(backend->open == NULL) break;
if(backend->open != NULL) {
CFGLR_LOGI(TAG, "opening backend");
backend->open(backend, handle); backend->open(backend, handle);
// do error validation
++handle->backend_count;
++tick;
} }
tick = 0;
CFGLR_LOGI(TAG, "initializing signalers");
while((signaler = &handle->signalers[tick])) {
if(signaler->dispatch == NULL) break;
if(signaler->init != NULL) {
signaler->init(signaler, handle);
}
++handle->signaler_count;
++tick;
}
tick = 0;
CFGLR_LOGI(TAG, "initializing elements"); CFGLR_LOGI(TAG, "initializing elements");
while((element = &handle->elements[tick])) { while((element = &handle->elements[handle->element_count])) {
if(element->key == NULL) break; if(element->key == NULL) break;
CFGLR_LOGD(TAG, "Initializing element: %s", element->key); CFGLR_LOGI(TAG, "Initializing element: %s", element->key);
CFGLR_LOGD(TAG, "size: %d", element->datatype_size); CFGLR_LOGI(TAG, "size: %d", element->datatype_size);
CFGLR_LOGD(TAG, "default: %d", (int)element->default_data); CFGLR_LOGI(TAG, "default: %d", (int)element->default_data);
element->handle = handle;
element->data = (void*)malloc(element->datatype_size); element->data = (void*)malloc(element->datatype_size);
CFGLR_LOGW(TAG, "malloc: %d @ %p", element->datatype_size, element->data);
for(uint8_t i = 0; i < handle->backend_count; i++) { //CFGLR_LOGI(TAG, "element->data: %p", element->data);
if(handle->backends[i].get(&handle->backends[i], element, handle) == 0) {
for(uint8_t j = 0; j < handle->signaler_count; j++) { while((signaler = &element->signalers[element->signaler_count])) {
handle->signalers[i].dispatch(&handle->signalers[i], element, CFGLR_SIGNAL_LOADED); if(signaler->init == NULL && signaler->dispatch == NULL) break;
if(signaler->init != NULL) {
signaler->init(signaler, element, handle);
} }
element->signaler_count++;
}
bool dispatch = false;
if(handle->backend.get(&handle->backend, element, handle) == 0) {
dispatch = true;
} else {
CFGLR_LOGI(TAG, "failed to load %s, setting default", element->key);
memcpy((void*)element->data, (void*)&element->default_data, element->datatype_size);
if(handle->backend.set(&handle->backend, element, handle) == 0) {
dispatch = true;
}
}
if(dispatch) {
for(uint8_t i = 0; i < element->signaler_count; i++) {
element->signalers[i].dispatch(&element->signalers[i], element, CFGLR_SIGNAL_LOADED);
} }
} }
++handle->element_count; ++handle->element_count;
++tick;
} }
return 0; return 0;
} }
uint16_t cfglr_commit(cfglr_element_t *element) {
cfglr_handle_t *handle = element->handle;
cfglr_commit_data(&handle->backend, element, handle);
return 0;
}
uint16_t cfglr_commit_data(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle) { uint16_t cfglr_commit_data(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle) {
uint16_t ret = backend->set(backend, element, handle); uint16_t ret = backend->set(backend, element, handle);
CFGLR_LOGI(TAG, "%s = %d (ret %d) %p", element->key, (uint8_t)&element->data, ret, element->data);
if(ret == 0) { if(ret == 0) {
for(uint8_t i = 0; i < handle->signaler_count; i++) { for(uint8_t i = 0; i < element->signaler_count; i++) {
handle->signalers[i].dispatch(&handle->signalers[i], element, CFGLR_SIGNAL_CHANGE); element->signalers[i].dispatch(&element->signalers[i], element, CFGLR_SIGNAL_CHANGE);
} }
} }