diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f0818a..f5c2a51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ target_sources(app PRIVATE src/modules/ble_battery_module.c src/modules/ble_bond_module.c src/modules/ble_slot_ctrl_module.c + src/modules/display_module.c src/modules/hid_tx_manager_module.c src/modules/keyboard_module.c src/modules/led_state_module.c diff --git a/app.overlay b/app.overlay index d4f648b..7fb05e7 100644 --- a/app.overlay +++ b/app.overlay @@ -1,6 +1,10 @@ #include / { + chosen { + zephyr,display = &st7789v3; + }; + zephyr,user { vbat-en-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; io-channels = <&adc 5>, <&adc 7>; @@ -78,3 +82,15 @@ qdec: &qdec { status = "okay"; }; + +&spi2 { + status = "okay"; +}; + +&mipi_dbi { + status = "okay"; +}; + +&st7789v3 { + status = "okay"; +}; diff --git a/pm_static.yml b/pm_static.yml index 2f28ea2..92a5e85 100644 --- a/pm_static.yml +++ b/pm_static.yml @@ -12,26 +12,20 @@ mcuboot_pad: app: address: 0xc200 - end_address: 0x82000 + end_address: 0xf8000 region: flash_primary - size: 0x75e00 + size: 0xebe00 mcuboot_primary: address: 0xc000 - end_address: 0x82000 + end_address: 0xf8000 orig_span: &id001 - mcuboot_pad - app region: flash_primary - size: 0x76000 + size: 0xec000 span: *id001 -mcuboot_secondary: - address: 0x82000 - end_address: 0xf8000 - region: flash_primary - size: 0x76000 - settings_storage: address: 0xf8000 end_address: 0x100000 diff --git a/prj.conf b/prj.conf index ab337ce..0211b9a 100644 --- a/prj.conf +++ b/prj.conf @@ -5,15 +5,16 @@ CONFIG_ASSERT=y CONFIG_ASSERT_VERBOSE=y CONFIG_RESET_ON_FATAL_ERROR=n CONFIG_FAULT_DUMP=2 +CONFIG_SIZE_OPTIMIZATIONS=y -CONFIG_ZCBOR=y -CONFIG_BOOTLOADER_MCUBOOT=y -CONFIG_MCUMGR=y -CONFIG_MCUMGR_TRANSPORT_BT=y -CONFIG_MCUMGR_GRP_IMG=y -CONFIG_MCUMGR_GRP_OS=y -CONFIG_IMG_MANAGER=y -CONFIG_STREAM_FLASH=y +CONFIG_ZCBOR=n +CONFIG_BOOTLOADER_MCUBOOT=n +CONFIG_MCUMGR=n +CONFIG_MCUMGR_TRANSPORT_BT=n +CONFIG_MCUMGR_GRP_IMG=n +CONFIG_MCUMGR_GRP_OS=n +CONFIG_IMG_MANAGER=n +CONFIG_STREAM_FLASH=n CONFIG_BT=y CONFIG_BT_PERIPHERAL=y @@ -78,5 +79,15 @@ CONFIG_ADC=y CONFIG_I2C=y CONFIG_IP5305=y CONFIG_SENSOR=y +CONFIG_DISPLAY=y +CONFIG_MIPI_DBI=y +CONFIG_ST7789V=y +CONFIG_LVGL=y +CONFIG_LV_CONF_MINIMAL=y +CONFIG_LV_BUILD_EXAMPLES=n +CONFIG_LV_BUILD_DEMOS=n +CONFIG_LV_USE_LABEL=y +CONFIG_LV_FONT_MONTSERRAT_14=y +CONFIG_LV_Z_MEM_POOL_SIZE=16384 CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=4096 diff --git a/src/modules/display_module.c b/src/modules/display_module.c new file mode 100644 index 0000000..e708409 --- /dev/null +++ b/src/modules/display_module.c @@ -0,0 +1,122 @@ +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#define MODULE display +#include + +#include +LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); + +#define DISPLAY_UPDATE_PERIOD_MS 10 + +struct display_ctx { + const struct device *dev; + struct k_work_delayable refresh_work; + lv_obj_t *hello_label; + lv_obj_t *count_label; + uint32_t tick_count; + bool initialized; +}; + +static struct display_ctx disp = { + .dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)), +}; + +static void display_refresh_work_fn(struct k_work *work) +{ + char count_str[12]; + uint32_t wait_ms; + + ARG_UNUSED(work); + + if (!disp.initialized) { + return; + } + + lvgl_lock(); + + if ((disp.tick_count % 100U) == 0U) { + snprintk(count_str, sizeof(count_str), "%u", disp.tick_count / 100U); + lv_label_set_text(disp.count_label, count_str); + } + + wait_ms = lv_timer_handler(); + lvgl_unlock(); + + disp.tick_count++; + k_work_reschedule(&disp.refresh_work, + K_MSEC(MAX(wait_ms, DISPLAY_UPDATE_PERIOD_MS))); +} + +static int display_demo_init(void) +{ + int err; + + if (!device_is_ready(disp.dev)) { + LOG_ERR("Display device not ready"); + return -ENODEV; + } + + disp.tick_count = 0U; + k_work_init_delayable(&disp.refresh_work, display_refresh_work_fn); + + lvgl_lock(); + lv_obj_clean(lv_screen_active()); + + disp.hello_label = lv_label_create(lv_screen_active()); + lv_label_set_text(disp.hello_label, "LVGL demo running"); + lv_obj_align(disp.hello_label, LV_ALIGN_CENTER, 0, -12); + + disp.count_label = lv_label_create(lv_screen_active()); + lv_label_set_text(disp.count_label, "0"); + lv_obj_align(disp.count_label, LV_ALIGN_BOTTOM_MID, 0, -12); + + lv_timer_handler(); + lvgl_unlock(); + + err = display_blanking_off(disp.dev); + if (err) { + LOG_ERR("Display blanking off failed: %d", err); + return err; + } + + disp.initialized = true; + k_work_reschedule(&disp.refresh_work, K_MSEC(DISPLAY_UPDATE_PERIOD_MS)); + + LOG_INF("LVGL display demo initialized"); + return 0; +} + +static bool app_event_handler(const struct app_event_header *aeh) +{ + if (is_module_state_event(aeh)) { + const struct module_state_event *event = cast_module_state_event(aeh); + + if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) { + int err = display_demo_init(); + + if (err) { + module_set_state(MODULE_STATE_ERROR); + } else { + module_set_state(MODULE_STATE_READY); + } + } + + return false; + } + + __ASSERT_NO_MSG(false); + return false; +} + +APP_EVENT_LISTENER(MODULE, app_event_handler); +APP_EVENT_SUBSCRIBE(MODULE, module_state_event); diff --git a/sysbuild.conf b/sysbuild.conf index 721a76f..e7326b9 100644 --- a/sysbuild.conf +++ b/sysbuild.conf @@ -1 +1 @@ -SB_CONFIG_BOOTLOADER_MCUBOOT=y \ No newline at end of file +SB_CONFIG_BOOTLOADER_MCUBOOT=n