implemented furi from flipper zero
added cmsis_core, furi, mlib and nanobake implemented basic app structure from furi implemented basic placeholder apps
This commit is contained in:
@@ -1,33 +1,40 @@
|
||||
#include "system_info.h"
|
||||
#include "nanobake.h"
|
||||
#include <core_defines.h>
|
||||
#include <thread.h>
|
||||
|
||||
#include <esp_lvgl_port.h>
|
||||
#include <nb_platform.h>
|
||||
static int32_t system_info_entry_point(void* param) {
|
||||
UNUSED(param);
|
||||
|
||||
static void prv_on_create(nb_platform_t _Nonnull* platform, lv_obj_t _Nonnull* lv_parent) {
|
||||
lvgl_port_lock(0);
|
||||
// Wait for all apps to start
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
|
||||
lv_obj_t* cpu_label = lv_label_create(lv_parent);
|
||||
lv_label_set_recolor(cpu_label, true);
|
||||
lv_obj_set_width(cpu_label, (lv_coord_t)platform->display->horizontal_resolution);
|
||||
lv_obj_set_style_text_align(cpu_label, LV_TEXT_ALIGN_LEFT, 0);
|
||||
lv_label_set_text(cpu_label, "CPU usage: ?");
|
||||
lv_obj_align(cpu_label, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||
size_t system_service_count = nanobake_get_app_thread_count();
|
||||
printf("Running apps:\n");
|
||||
for (int i = 0; i < system_service_count; ++i) {
|
||||
FuriThreadId thread_id = nanobake_get_app_thread_id(i);
|
||||
const char* appid = furi_thread_get_appid(thread_id);
|
||||
const char* name = furi_thread_get_name(thread_id);
|
||||
bool is_suspended = furi_thread_is_suspended(thread_id);
|
||||
const char* status = is_suspended ? "suspended" : "active";
|
||||
bool is_service = furi_thread_mark_is_service(thread_id);
|
||||
const char* type = is_service ? "service" : "app";
|
||||
printf(" - [%s, %s] %s (%s)\n", type, status, name, appid);
|
||||
}
|
||||
|
||||
lv_obj_t* mem_free_label = lv_label_create(lv_parent);
|
||||
lv_label_set_recolor(mem_free_label, true);
|
||||
lv_obj_set_width(mem_free_label, (lv_coord_t)platform->display->horizontal_resolution);
|
||||
lv_obj_set_style_text_align(mem_free_label, LV_TEXT_ALIGN_LEFT, 0);
|
||||
lv_label_set_text(mem_free_label, "Memory: ?");
|
||||
lv_obj_align(mem_free_label, LV_ALIGN_TOP_LEFT, 0, 15);
|
||||
printf("Heap memory available: %d / %d\n",
|
||||
heap_caps_get_free_size(MALLOC_CAP_DEFAULT),
|
||||
heap_caps_get_total_size(MALLOC_CAP_DEFAULT)
|
||||
);
|
||||
|
||||
lvgl_port_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
nb_app_t system_info_app = {
|
||||
.id = "systeminfo",
|
||||
.name = "System Info",
|
||||
.type = SYSTEM,
|
||||
.on_create = &prv_on_create,
|
||||
.on_update = NULL,
|
||||
.on_destroy = NULL
|
||||
.entry_point = &system_info_entry_point,
|
||||
.stack_size = 2048,
|
||||
.priority = 10
|
||||
};
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
#ifndef NANOBAKE_SYSTEM_INFO_H
|
||||
#define NANOBAKE_SYSTEM_INFO_H
|
||||
#pragma once
|
||||
|
||||
#include "nb_app.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern nb_app_t system_info_app;
|
||||
|
||||
#endif // NANOBAKE_SYSTEM_INFO_H
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "nb_applications.h"
|
||||
|
||||
// System services
|
||||
extern const nb_app_t desktop_app;
|
||||
extern const nb_app_t gui_app;
|
||||
extern const nb_app_t loader_app;
|
||||
|
||||
// System apps
|
||||
extern const nb_app_t system_info_app;
|
||||
|
||||
const nb_app_t* const FLIPPER_SERVICES[] = {
|
||||
&desktop_app,
|
||||
&gui_app,
|
||||
&loader_app
|
||||
};
|
||||
|
||||
const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(nb_app_t*);
|
||||
|
||||
const nb_app_t* const FLIPPER_SYSTEM_APPS[] = {
|
||||
&system_info_app
|
||||
};
|
||||
|
||||
const size_t FLIPPER_SYSTEM_APPS_COUNT = sizeof(FLIPPER_SYSTEM_APPS) / sizeof(nb_app_t*);
|
||||
|
||||
const FlipperInternalOnStartHook FLIPPER_ON_SYSTEM_START[] = {
|
||||
};
|
||||
|
||||
const size_t FLIPPER_ON_SYSTEM_START_COUNT = sizeof(FLIPPER_ON_SYSTEM_START) / sizeof(FlipperInternalOnStartHook);
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "nb_app.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*FlipperInternalOnStartHook)(void);
|
||||
|
||||
extern const nb_app_t* const FLIPPER_SERVICES[];
|
||||
extern const size_t FLIPPER_SERVICES_COUNT;
|
||||
|
||||
extern const nb_app_t* const FLIPPER_SYSTEM_APPS[];
|
||||
extern const size_t FLIPPER_SYSTEM_APPS_COUNT;
|
||||
|
||||
extern const FlipperInternalOnStartHook FLIPPER_ON_SYSTEM_START[];
|
||||
extern const size_t FLIPPER_ON_SYSTEM_START_COUNT;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "desktop.h"
|
||||
#include "nb_hardware.h"
|
||||
#include <esp_lvgl_port.h>
|
||||
#include "core_defines.h"
|
||||
#include <esp_log.h>
|
||||
|
||||
//nb_desktop_t* shared_desktop = NULL;
|
||||
|
||||
static int32_t prv_desktop_main(void* param) {
|
||||
UNUSED(param);
|
||||
printf("desktop app init\n");
|
||||
// nb_desktop_t* desktop = desktop_alloc();
|
||||
// shared_desktop = desktop;
|
||||
|
||||
// lvgl_port_lock(0);
|
||||
//
|
||||
// lv_obj_t* label = lv_label_create(lv_parent);
|
||||
// lv_label_set_recolor(label, true);
|
||||
// lv_obj_set_width(label, (lv_coord_t)platform->display->horizontal_resolution);
|
||||
// lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_LEFT, 0);
|
||||
// lv_label_set_text(label, "Desktop app");
|
||||
// lv_obj_align(label, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||
//
|
||||
// lvgl_port_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const nb_app_t desktop_app = {
|
||||
.id = "desktop",
|
||||
.name = "Desktop",
|
||||
.type = SERVICE,
|
||||
.entry_point = &prv_desktop_main,
|
||||
.stack_size = 2048,
|
||||
.priority = 10
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "nb_app.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const nb_app_t desktop_app;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "gui.h"
|
||||
#include "core_defines.h"
|
||||
#include "check.h"
|
||||
|
||||
static int32_t prv_gui_main(void* param) {
|
||||
UNUSED(param);
|
||||
printf("gui app init\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const nb_app_t gui_app = {
|
||||
.id = "gui",
|
||||
.name = "GUI",
|
||||
.type = STARTUP,
|
||||
.entry_point = &prv_gui_main,
|
||||
.stack_size = 2048,
|
||||
.priority = 10
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "nb_app.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const nb_app_t gui_app;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "loader.h"
|
||||
#include "core_defines.h"
|
||||
|
||||
static int32_t prv_loader_main(void* param) {
|
||||
UNUSED(param);
|
||||
printf("loader app init\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const nb_app_t loader_app = {
|
||||
.id = "loader",
|
||||
.name = "Loader",
|
||||
.type = STARTUP,
|
||||
.entry_point = &prv_loader_main,
|
||||
.stack_size = 2048,
|
||||
.priority = 10
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "nb_app.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const nb_app_t loader_app;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,15 +1,104 @@
|
||||
#include "nanobake.h"
|
||||
#include "applications/main/system_info/system_info.h"
|
||||
#include "nb_hardware.h"
|
||||
#include "nb_lvgl.h"
|
||||
#include "applications/nb_applications.h"
|
||||
#include <esp_log.h>
|
||||
#include <m-list.h>
|
||||
// Furi
|
||||
#include <thread.h>
|
||||
#include <kernel.h>
|
||||
#include <record.h>
|
||||
#include <check.h>
|
||||
|
||||
void nb_app_start(nb_platform_t _Nonnull* platform, nb_app_t _Nonnull* config) {
|
||||
lv_obj_t* scr = lv_scr_act();
|
||||
ESP_ERROR_CHECK(nb_app_validate(config));
|
||||
config->on_create(platform, scr);
|
||||
static const char* TAG = "nanobake";
|
||||
|
||||
M_LIST_DEF(thread_ids, FuriThreadId);
|
||||
|
||||
static void prv_furi_init() {
|
||||
// TODO: can we remove the suspend-resume logic?
|
||||
if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
|
||||
vTaskSuspendAll();
|
||||
}
|
||||
|
||||
furi_record_init();
|
||||
|
||||
xTaskResumeAll();
|
||||
}
|
||||
|
||||
extern void nanobake_run(nb_platform_config_t _Nonnull* config) {
|
||||
nb_platform_t _Nonnull* platform = nb_platform_create(config);
|
||||
thread_ids_t prv_thread_ids;
|
||||
|
||||
nb_app_start(platform, config->apps[0]);
|
||||
// nb_app_start(platform, &system_info_app);
|
||||
FuriThreadId nanobake_get_app_thread_id(size_t index) {
|
||||
return *thread_ids_get(prv_thread_ids, index);
|
||||
}
|
||||
|
||||
size_t nanobake_get_app_thread_count() {
|
||||
return thread_ids_size(prv_thread_ids);
|
||||
}
|
||||
|
||||
extern void nanobake_start(nb_config_t _Nonnull* config) {
|
||||
prv_furi_init();
|
||||
|
||||
nb_hardware_t _Nonnull* hardware = nb_hardware_alloc(config);
|
||||
nb_lvgl_init(hardware);
|
||||
|
||||
thread_ids_init(prv_thread_ids);
|
||||
|
||||
ESP_LOGI(TAG, "Starting services");
|
||||
|
||||
for(size_t i = 0; i < FLIPPER_SERVICES_COUNT; i++) {
|
||||
ESP_LOGI(TAG, "Starting system service \"%s\"", FLIPPER_SERVICES[i]->name);
|
||||
|
||||
FuriThread* thread = furi_thread_alloc_ex(
|
||||
FLIPPER_SERVICES[i]->name,
|
||||
FLIPPER_SERVICES[i]->stack_size,
|
||||
FLIPPER_SERVICES[i]->entry_point,
|
||||
NULL
|
||||
);
|
||||
furi_thread_mark_as_service(thread);
|
||||
furi_thread_set_appid(thread, FLIPPER_SERVICES[i]->id);
|
||||
furi_thread_start(thread);
|
||||
|
||||
FuriThreadId thread_id = furi_thread_get_id(thread);
|
||||
thread_ids_push_back(prv_thread_ids, thread_id);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Starting system apps");
|
||||
|
||||
for(size_t i = 0; i < FLIPPER_SYSTEM_APPS_COUNT; i++) {
|
||||
ESP_LOGI(TAG, "Starting system app \"%s\"", FLIPPER_SYSTEM_APPS[i]->name);
|
||||
|
||||
FuriThread* thread = furi_thread_alloc_ex(
|
||||
FLIPPER_SYSTEM_APPS[i]->name,
|
||||
FLIPPER_SYSTEM_APPS[i]->stack_size,
|
||||
FLIPPER_SYSTEM_APPS[i]->entry_point,
|
||||
NULL
|
||||
);
|
||||
furi_thread_mark_as_service(thread);
|
||||
furi_thread_set_appid(thread, FLIPPER_SYSTEM_APPS[i]->id);
|
||||
furi_thread_start(thread);
|
||||
|
||||
FuriThreadId thread_id = furi_thread_get_id(thread);
|
||||
thread_ids_push_back(prv_thread_ids, thread_id);
|
||||
}
|
||||
|
||||
// ESP_LOGI(TAG, "Starting external apps");
|
||||
//
|
||||
// size_t external_apps_count = sizeof(*config->apps);
|
||||
// for(size_t i = 0; i < FLIPPER_SERVICES_COUNT; i++) {
|
||||
// ESP_LOGI(TAG, "Starting external app \"%s\"", FLIPPER_[i]->name);
|
||||
//
|
||||
// FuriThread* thread = furi_thread_alloc_ex(
|
||||
// FLIPPER_SERVICES[i]->name,
|
||||
// FLIPPER_SERVICES[i]->stack_size,
|
||||
// FLIPPER_SERVICES[i]->entry_point,
|
||||
// NULL
|
||||
// );
|
||||
// furi_thread_set_appid(thread, FLIPPER_SERVICES[i]->id);
|
||||
// furi_thread_start(thread);
|
||||
//
|
||||
// FuriThreadId thread_id = furi_thread_get_id(thread);
|
||||
// thread_ids_push_back(prv_thread_ids, thread_id);
|
||||
// }
|
||||
|
||||
ESP_LOGI(TAG, "Startup complete");
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#include "nb_app.h"
|
||||
#include <esp_check.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char* TAG = "nb_app";
|
||||
|
||||
esp_err_t nb_app_validate(nb_app_t* _Nonnull app) {
|
||||
ESP_RETURN_ON_FALSE(
|
||||
strlen(app->id) < NB_APP_ID_LENGTH,
|
||||
ESP_FAIL,
|
||||
TAG,
|
||||
"app id cannot be larger than %d characters",
|
||||
NB_APP_ID_LENGTH - 1
|
||||
);
|
||||
|
||||
ESP_RETURN_ON_FALSE(
|
||||
strlen(app->name) < NB_APP_NAME_LENGTH,
|
||||
ESP_FAIL,
|
||||
TAG,
|
||||
"app name cannot be larger than %d characters",
|
||||
NB_APP_NAME_LENGTH - 1
|
||||
);
|
||||
|
||||
ESP_RETURN_ON_FALSE(
|
||||
(app->on_update == NULL) == (app->update_task_priority == 0 && app->update_task_priority == 0),
|
||||
ESP_FAIL,
|
||||
TAG,
|
||||
"app update is inconsistently configured"
|
||||
);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef NANOBAKE_NB_ASSERT_H
|
||||
#define NANOBAKE_NB_ASSERT_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <esp_log.h>
|
||||
|
||||
#define NB_ASSERT(x, message) do { \
|
||||
if (!(x)) { \
|
||||
ESP_LOGE("assert", message); \
|
||||
_esp_error_check_failed( \
|
||||
x, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__ASSERT_FUNC, \
|
||||
#x \
|
||||
); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif //NANOBAKE_NB_ASSERT_H
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "nb_display.h"
|
||||
#include "nb_assert.h"
|
||||
#include <check.h>
|
||||
|
||||
nb_display_t _Nonnull* nb_display_create(nb_display_driver_t _Nonnull* driver) {
|
||||
nb_display_t _Nonnull* nb_display_alloc(nb_display_driver_t _Nonnull* driver) {
|
||||
nb_display_t _Nonnull* display = malloc(sizeof(nb_display_t));
|
||||
NB_ASSERT(driver->create_display(display), "failed to create display");
|
||||
furi_check(driver->create_display(display), "failed to create display");
|
||||
return display;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "nb_hardware.h"
|
||||
#include "nb_display.h"
|
||||
#include "nb_touch.h"
|
||||
|
||||
#include <esp_check.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_lvgl_port.h>
|
||||
|
||||
#include <check.h>
|
||||
|
||||
static const char* TAG = "nb_hardware";
|
||||
|
||||
nb_hardware_t _Nonnull* nb_hardware_alloc(nb_config_t _Nonnull* config) {
|
||||
nb_hardware_t* platform = malloc(sizeof(nb_hardware_t));
|
||||
|
||||
furi_check(config->display_driver != NULL, "no display driver configured");
|
||||
nb_display_driver_t display_driver = config->display_driver();
|
||||
ESP_LOGI(TAG, "display with driver %s", display_driver.name);
|
||||
platform->display = nb_display_alloc(&display_driver);
|
||||
|
||||
if (config->touch_driver != NULL) {
|
||||
nb_touch_driver_t touch_driver = config->touch_driver();
|
||||
ESP_LOGI(TAG, "touch with driver %s", touch_driver.name);
|
||||
platform->touch = nb_touch_alloc(&touch_driver);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "no touch configured");
|
||||
platform->touch = NULL;
|
||||
}
|
||||
|
||||
|
||||
return platform;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#include "nb_internal.h"
|
||||
|
||||
const char* nbi_tag = "nanobake";
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef NANOBAKE_NB_INTERNAL_H
|
||||
#define NANOBAKE_NB_INTERNAL_H
|
||||
|
||||
extern const char* nbi_tag;
|
||||
|
||||
#endif // NANOBAKE_NB_INTERNAL_H
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "nb_lvgl.h"
|
||||
#include "nb_hardware.h"
|
||||
#include <esp_check.h>
|
||||
#include <check.h>
|
||||
|
||||
static const char* TAG = "nb_lvgl";
|
||||
|
||||
nb_lvgl_t nb_lvgl_init(nb_hardware_t* platform) {
|
||||
nb_lvgl_t lvgl;
|
||||
|
||||
const lvgl_port_cfg_t lvgl_cfg = {
|
||||
.task_priority = 4,
|
||||
.task_stack = 4096,
|
||||
.task_affinity = -1, // core pinning
|
||||
.task_max_sleep_ms = 500,
|
||||
.timer_period_ms = 5
|
||||
};
|
||||
furi_check(lvgl_port_init(&lvgl_cfg) == ESP_OK, "lvgl port init failed");
|
||||
nb_display_t _Nonnull* display = platform->display;
|
||||
// Add display
|
||||
ESP_LOGD(TAG, "lvgl add display");
|
||||
const lvgl_port_display_cfg_t disp_cfg = {
|
||||
.io_handle = display->io_handle,
|
||||
.panel_handle = display->display_handle,
|
||||
.buffer_size = display->horizontal_resolution * display->draw_buffer_height * (display->bits_per_pixel / 8),
|
||||
.double_buffer = 0,
|
||||
.hres = display->horizontal_resolution,
|
||||
.vres = display->vertical_resolution,
|
||||
.monochrome = false,
|
||||
/* Rotation values must be same as defined in driver */
|
||||
// TODO: expose data from driver
|
||||
.rotation = {
|
||||
.swap_xy = false,
|
||||
.mirror_x = true,
|
||||
.mirror_y = false,
|
||||
},
|
||||
.flags = {
|
||||
.buff_dma = true,
|
||||
}
|
||||
};
|
||||
lvgl.disp = lvgl_port_add_disp(&disp_cfg);
|
||||
|
||||
// Add touch
|
||||
if (platform->touch != NULL) {
|
||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||
.disp = lvgl.disp,
|
||||
.handle = platform->touch->touch_handle,
|
||||
};
|
||||
lvgl.touch_indev = lvgl_port_add_touch(&touch_cfg);
|
||||
furi_check(lvgl.touch_indev != NULL, "failed to add touch to lvgl");
|
||||
}
|
||||
|
||||
return lvgl;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <esp_lvgl_port.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;
|
||||
};
|
||||
|
||||
typedef struct nb_hardware nb_hardware_t;
|
||||
|
||||
extern nb_lvgl_t nb_lvgl_init(nb_hardware_t* platform);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,81 +0,0 @@
|
||||
#include "nb_platform.h"
|
||||
#include "nb_display.h"
|
||||
#include "nb_touch.h"
|
||||
|
||||
#include <esp_check.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_lvgl_port.h>
|
||||
|
||||
#include <nb_assert.h>
|
||||
|
||||
static const char* TAG = "nb_platform";
|
||||
|
||||
static esp_err_t prv_lvgl_init(
|
||||
nb_platform_t* platform
|
||||
) {
|
||||
const lvgl_port_cfg_t lvgl_cfg = {
|
||||
.task_priority = 4,
|
||||
.task_stack = 4096,
|
||||
.task_affinity = -1, // core pinning
|
||||
.task_max_sleep_ms = 500,
|
||||
.timer_period_ms = 5
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "lvgl port init failed");
|
||||
nb_display_t _Nonnull* display = platform->display;
|
||||
// Add display
|
||||
ESP_LOGD(TAG, "lvgl add display");
|
||||
const lvgl_port_display_cfg_t disp_cfg = {
|
||||
.io_handle = display->io_handle,
|
||||
.panel_handle = display->display_handle,
|
||||
.buffer_size = display->horizontal_resolution * display->draw_buffer_height * (display->bits_per_pixel / 8),
|
||||
.double_buffer = 1,
|
||||
.hres = display->horizontal_resolution,
|
||||
.vres = display->vertical_resolution,
|
||||
.monochrome = false,
|
||||
/* Rotation values must be same as defined in driver */
|
||||
// TODO: expose data from driver
|
||||
.rotation = {
|
||||
.swap_xy = false,
|
||||
.mirror_x = true,
|
||||
.mirror_y = false,
|
||||
},
|
||||
.flags = {
|
||||
.buff_dma = true,
|
||||
}
|
||||
};
|
||||
platform->lvgl->disp = lvgl_port_add_disp(&disp_cfg);
|
||||
|
||||
// Add touch
|
||||
if (platform->touch != NULL) {
|
||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||
.disp = platform->lvgl->disp,
|
||||
.handle = platform->touch->touch_handle,
|
||||
};
|
||||
platform->lvgl->touch_indev = lvgl_port_add_touch(&touch_cfg);
|
||||
ESP_RETURN_ON_FALSE(platform->lvgl->touch_indev != NULL, ESP_FAIL, TAG, "failed to add touch to lvgl");
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
nb_platform_t _Nonnull* nb_platform_create(nb_platform_config_t _Nonnull* config) {
|
||||
nb_platform_t* platform = malloc(sizeof(nb_platform_t));
|
||||
|
||||
NB_ASSERT(config->display_driver != NULL, "no display driver configured");
|
||||
nb_display_driver_t display_driver = config->display_driver();
|
||||
ESP_LOGI(TAG, "display with driver %s", display_driver.name);
|
||||
platform->display = nb_display_create(&display_driver);
|
||||
|
||||
if (config->touch_driver != NULL) {
|
||||
nb_touch_driver_t touch_driver = config->touch_driver();
|
||||
ESP_LOGI(TAG, "touch with driver %s", touch_driver.name);
|
||||
platform->touch = nb_touch_create(&touch_driver);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "no touch configured");
|
||||
platform->touch = NULL;
|
||||
}
|
||||
|
||||
NB_ASSERT(prv_lvgl_init(platform) == ESP_OK, "failed to init lvgl");
|
||||
|
||||
return platform;
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
#include "nb_touch.h"
|
||||
#include "nb_assert.h"
|
||||
#include <esp_check.h>
|
||||
#include "check.h"
|
||||
|
||||
nb_touch_t _Nonnull* nb_touch_create(nb_touch_driver_t _Nonnull* driver) {
|
||||
nb_touch_t _Nonnull* nb_touch_alloc(nb_touch_driver_t _Nonnull* driver) {
|
||||
nb_touch_t _Nonnull* touch = malloc(sizeof(nb_touch_t));
|
||||
bool success = driver->create_touch(
|
||||
&(touch->io_handle),
|
||||
&(touch->touch_handle)
|
||||
);
|
||||
NB_ASSERT(success, "touch driver failed");
|
||||
furi_check(success, "touch driver failed");
|
||||
return touch;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user