various improvements

stopped using private header folder (for ease of development - for now)
implemented basic gui service (WIP)
added sdkconfig.defaults to the repo
updated docs
This commit is contained in:
Ken Van Hoeylandt
2023-12-27 13:57:20 +01:00
parent aa24b84eb6
commit f4088f5762
22 changed files with 202 additions and 50 deletions
@@ -1,9 +1,100 @@
#include "gui.h"
#include "core_defines.h"
#include "check.h"
#include <record.h>
#include <mutex.h>
#include <check.h>
#include <m-dict.h>
#include <m-core.h>
typedef struct screen screen_t;
struct screen {
screen_id_t id;
lv_obj_t* parent;
on_init_lvgl _Nonnull callback;
};
static screen_id_t screen_counter = 0;
DICT_DEF2(screen_dict, screen_id_t, M_BASIC_OPLIST, screen_t, M_POD_OPLIST)
typedef struct Gui Gui;
struct Gui {
// TODO: use mutex
FuriMutex* mutex;
screen_dict_t screens;
};
Gui* gui_alloc() {
Gui* gui = malloc(sizeof(Gui));
screen_dict_init(gui->screens);
gui->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
return gui;
}
void gui_free(Gui* gui) {
screen_dict_clear(gui->screens);
furi_mutex_free(gui->mutex);
free(gui);
}
void gui_lock(Gui* gui) {
furi_assert(gui);
furi_check(furi_mutex_acquire(gui->mutex, FuriWaitForever) == FuriStatusOk);
}
void gui_unlock(Gui* gui) {
furi_assert(gui);
furi_check(furi_mutex_release(gui->mutex) == FuriStatusOk);
}
screen_id_t gui_screen_create(Gui* gui, on_init_lvgl callback) {
screen_id_t id = screen_counter++;
screen_t screen = {
.id = id,
.parent = NULL,
.callback = callback
};
screen_dict_set_at(gui->screens, id, screen);
// TODO: notify desktop of change
// TODO: have desktop update views
lv_obj_t* parent = lv_scr_act();
gui_screen_set_parent(gui, id, parent);
// TODO: call from desktop
screen.callback(gui_screen_get_parent(gui, id), id);
return id;
}
lv_obj_t* gui_screen_get_parent(Gui* gui, screen_id_t id) {
screen_t* screen = screen_dict_get(gui->screens, id);
furi_check(screen != NULL);
return screen->parent;
}
void gui_screen_set_parent(Gui* gui, screen_id_t id, lv_obj_t* parent) {
screen_t* screen = screen_dict_get(gui->screens, id);
furi_check(screen != NULL);
screen->parent = parent;
}
void gui_screen_free(Gui* gui, screen_id_t id) {
screen_t* screen = screen_dict_get(gui->screens, id);
furi_check(screen != NULL);
// TODO: notify? use callback? (done from desktop service)
lv_obj_clean(screen->parent);
screen_dict_erase(gui->screens, id);
}
static int32_t prv_gui_main(void* param) {
UNUSED(param);
Gui* gui = gui_alloc();
furi_record_create(RECORD_GUI, gui);
printf("gui app init\n");
return 0;
}
@@ -6,6 +6,19 @@
extern "C" {
#endif
#define RECORD_GUI "gui"
typedef uint16_t screen_id_t;
typedef struct Gui Gui;
typedef void (*on_init_lvgl)(lv_obj_t*, screen_id_t);
screen_id_t gui_screen_create(Gui* gui, on_init_lvgl callback);
void gui_screen_free(Gui* gui, screen_id_t id);
// TODO make internal
void gui_screen_set_parent(Gui* gui, screen_id_t id, lv_obj_t* parent);
lv_obj_t* gui_screen_get_parent(Gui* gui, screen_id_t id);
extern const nb_app_t gui_app;
#ifdef __cplusplus
+1 -1
View File
@@ -58,7 +58,7 @@ static void prv_start_app(const nb_app_t _Nonnull* app) {
thread_ids_push_back(prv_thread_ids, thread_id);
}
extern void nanobake_start(nb_config_t _Nonnull* config) {
__attribute__((unused)) extern void nanobake_start(nb_config_t _Nonnull* config) {
prv_furi_init();
nb_hardware_t hardware = nb_hardware_create(config);
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "nb_hardware.h"
#include "nb_app.h"
#include "nb_config.h"
#ifdef __cplusplus
extern "C" {
#endif
// Forward declarations
typedef void* FuriThreadId;
typedef struct nb_lvgl nb_lvgl_t;
__attribute__((unused)) extern void nanobake_start(nb_config_t _Nonnull * config);
extern FuriThreadId nanobake_get_app_thread_id(size_t index);
extern size_t nanobake_get_app_thread_count();
#ifdef __cplusplus
}
#endif
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#include <stdio.h>
#include <esp_err.h>
#include <lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
#define NB_APP_ID_LENGTH 32
#define NB_APP_NAME_LENGTH 32
typedef enum nb_app_type nb_app_type_t;
enum nb_app_type {
SERVICE,
SYSTEM,
USER
};
typedef struct nb_app nb_app_t;
typedef int32_t (*nb_app_entry_point) (void _Nonnull* parameter);
struct nb_app {
const char id[NB_APP_ID_LENGTH];
const char name[NB_APP_NAME_LENGTH];
const nb_app_type_t type;
const nb_app_entry_point _Nullable entry_point;
const size_t stack_size;
const uint32_t priority;
};
#ifdef __cplusplus
}
#endif
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include "nb_display.h"
#include "nb_touch.h"
#include "nb_app.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef nb_touch_driver_t (*create_touch_driver)();
typedef nb_display_driver_t (*create_display_driver)();
typedef struct nb_config nb_config_t;
struct nb_config {
// Required driver for display
const create_display_driver _Nonnull display_driver;
// Optional driver for touch input
const create_touch_driver _Nullable touch_driver;
// List of user applications
const size_t apps_count;
const nb_app_t* const apps[];
};
#ifdef __cplusplus
}
#endif
+7
View File
@@ -3,6 +3,13 @@
nb_display_t _Nonnull* nb_display_alloc(nb_display_driver_t _Nonnull* driver) {
nb_display_t _Nonnull* display = malloc(sizeof(nb_display_t));
memset(display, 0, sizeof(nb_display_t));
furi_check(driver->create_display(display), "failed to create display");
furi_check(display->io_handle != NULL);
furi_check(display->display_handle != NULL);
furi_check(display->horizontal_resolution != 0);
furi_check(display->vertical_resolution != 0);
furi_check(display->draw_buffer_height > 0);
furi_check(display->bits_per_pixel > 0);
return display;
}
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#include <esp_lcd_panel_io.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct nb_display nb_display_t;
struct nb_display {
uint16_t horizontal_resolution;
uint16_t vertical_resolution;
uint16_t draw_buffer_height;
uint16_t bits_per_pixel;
esp_lcd_panel_io_handle_t _Nonnull io_handle;
esp_lcd_panel_handle_t _Nonnull display_handle;
bool mirror_x;
bool mirror_y;
bool swap_xy;
};
typedef struct nb_display_driver nb_display_driver_t;
struct nb_display_driver {
char name[32];
bool (*create_display)(nb_display_t* display);
};
/**
* @param[in] driver
* @return allocated display object
*/
nb_display_t _Nonnull* nb_display_alloc(nb_display_driver_t _Nonnull* driver);
#ifdef __cplusplus
}
#endif
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "nb_display.h"
#include "nb_touch.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct nb_hardware nb_hardware_t;
struct nb_hardware {
nb_display_t* _Nonnull display;
nb_touch_t* _Nullable touch;
};
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -28,7 +28,7 @@ nb_lvgl_t nb_lvgl_init(nb_hardware_t _Nonnull* hardware) {
.vres = display->vertical_resolution,
.monochrome = false,
.rotation = {
.swap_xy = false,
.swap_xy = display->swap_xy,
.mirror_x = display->mirror_x,
.mirror_y = display->mirror_y,
},
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include <lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct nb_lvgl nb_lvgl_t;
struct nb_lvgl {
lv_disp_t* _Nonnull disp;
lv_indev_t* _Nullable touch_indev;
};
#ifdef __cplusplus
}
#endif
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "esp_lcd_touch.h"
#include <esp_lcd_panel_io.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct nb_touch_driver nb_touch_driver_t;
struct nb_touch_driver {
char name[32];
bool (*create_touch)(esp_lcd_panel_io_handle_t* io_handle, esp_lcd_touch_handle_t* touch_handle);
};
typedef struct nb_touch nb_touch_t;
struct nb_touch {
esp_lcd_panel_io_handle_t _Nonnull io_handle;
esp_lcd_touch_handle_t _Nonnull touch_handle;
};
/**
* @param[in] driver
* @return a newly allocated instance
*/
nb_touch_t _Nonnull* nb_touch_alloc(nb_touch_driver_t _Nonnull* driver);
#ifdef __cplusplus
}
#endif