From 6dc8b897d6add200794b1082144549a05a20dd32 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sat, 10 Feb 2024 22:51:59 +0100 Subject: [PATCH] Display orientation setting (#38) - Implemented display orientation in Display app - Increased LVGL task stack for T-Deck --- boards/lilygo_tdeck/config.h | 7 +- tactility/src/apps/settings/display/display.c | 86 ++++++++++++++++--- tactility/src/hardware.c | 26 +++++- tactility/src/tactility.c | 11 --- 4 files changed, 98 insertions(+), 32 deletions(-) diff --git a/boards/lilygo_tdeck/config.h b/boards/lilygo_tdeck/config.h index 57f2e5af..be08431a 100644 --- a/boards/lilygo_tdeck/config.h +++ b/boards/lilygo_tdeck/config.h @@ -31,16 +31,15 @@ // LVGL // The minimum task stack seems to be about 3500, but that crashes the wifi app in some scenarios -#define TDECK_LVGL_TASK_STACK_DEPTH 4000 +// At 4000, it crashes when the fps renderer is available +#define TDECK_LVGL_TASK_STACK_DEPTH 8192 // Dipslay backlight (PWM) #define TDECK_LCD_BACKLIGHT_LEDC_TIMER LEDC_TIMER_0 #define TDECK_LCD_BACKLIGHT_LEDC_MODE LEDC_LOW_SPEED_MODE -#define TDECK_LCD_BACKLIGHT_LEDC_OUTPUT_IO TDECK_LCD_PIN_BACKLIGHT #define TDECK_LCD_BACKLIGHT_LEDC_CHANNEL LEDC_CHANNEL_0 #define TDECK_LCD_BACKLIGHT_LEDC_DUTY_RES LEDC_TIMER_8_BIT -#define TDECK_LCD_BACKLIGHT_LEDC_DUTY (191) -#define TDECK_LCD_BACKLIGHT_LEDC_FREQUENCY (1000) +#define TDECK_LCD_BACKLIGHT_LEDC_FREQUENCY (4000) // Touch (GT911) #define TDECK_TOUCH_I2C_BUS_HANDLE TDECK_I2C_BUS_HANDLE diff --git a/tactility/src/apps/settings/display/display.c b/tactility/src/apps/settings/display/display.c index b8a359b9..e22f72ed 100644 --- a/tactility/src/apps/settings/display/display.c +++ b/tactility/src/apps/settings/display/display.c @@ -6,11 +6,13 @@ #include "ui/spacer.h" #include "ui/toolbar.h" +#define TAG "display" + static bool backlight_duty_set = false; static uint8_t backlight_duty = 255; -static void slider_event_cb(lv_event_t* e) { - lv_obj_t* slider = lv_event_get_target(e); +static void slider_event_cb(lv_event_t* event) { + lv_obj_t* slider = lv_event_get_target(event); const Config* config = tt_get_config(); SetBacklightDuty set_backlight_duty = config->hardware->display.set_backlight_duty; @@ -24,6 +26,46 @@ static void slider_event_cb(lv_event_t* e) { } } +#define ORIENTATION_LANDSCAPE 0 +#define ORIENTATION_LANDSCAPE_FLIPPED 1 +#define ORIENTATION_PORTRAIT_LEFT 2 +#define ORIENTATION_PORTRAIT_RIGHT 3 + +static int orientation_setting_to_display_orientation(int setting) { + if (setting == ORIENTATION_LANDSCAPE_FLIPPED) { + return LV_DISP_ROT_180; + } else if (setting == ORIENTATION_PORTRAIT_LEFT) { + return LV_DISP_ROT_270; + } else if (setting == ORIENTATION_PORTRAIT_RIGHT) { + return LV_DISP_ROT_90; + } else { + return LV_DISP_ROT_NONE; + } +} + +static int display_orientation_to_orientation_setting(int orientation) { + if (orientation == LV_DISP_ROT_90) { + return ORIENTATION_PORTRAIT_RIGHT; + } else if (orientation == LV_DISP_ROT_180) { + return ORIENTATION_LANDSCAPE_FLIPPED; + } else if (orientation == LV_DISP_ROT_270) { + return ORIENTATION_PORTRAIT_LEFT; + } else { + return ORIENTATION_LANDSCAPE; + } +} + +static void on_orientation_set(lv_event_t* event) { + lv_obj_t* dropdown = lv_event_get_target(event); + int selected = lv_dropdown_get_selected(dropdown); + TT_LOG_I(TAG, "Selected %d", selected); + int rotation = orientation_setting_to_display_orientation(selected); + if (lv_disp_get_rotation(lv_disp_get_default()) != rotation) { + lv_disp_set_rotation(lv_disp_get_default(), rotation); + tt_preferences()->put_int32("display", "rotation", rotation); + } +} + static void app_show(TT_UNUSED App app, lv_obj_t* parent) { lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); @@ -32,31 +74,47 @@ static void app_show(TT_UNUSED App app, lv_obj_t* parent) { lv_obj_t* wrapper = lv_obj_create(parent); lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); lv_obj_set_width(wrapper, LV_PCT(100)); + lv_obj_set_style_border_width(wrapper, 0, 0); lv_obj_set_flex_grow(wrapper, 1); - lv_obj_t* label = lv_label_create(wrapper); - lv_label_set_text(label, "Brightness"); + lv_obj_t* brightness_wrapper = lv_obj_create(wrapper); + lv_obj_set_size(brightness_wrapper, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_t* brightness_label = lv_label_create(brightness_wrapper); + lv_label_set_text(brightness_label, "Brightness"); - tt_lv_spacer_create(wrapper, 1, 2); - - lv_obj_t* slider = lv_slider_create(wrapper); - lv_obj_set_width(slider, LV_PCT(100)); - lv_slider_set_range(slider, 0, 255); - lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL); + lv_obj_t* brightness_slider = lv_slider_create(brightness_wrapper); + lv_obj_set_width(brightness_slider, LV_PCT(100)); + lv_slider_set_range(brightness_slider, 0, 255); + lv_obj_add_event_cb(brightness_slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL); + lv_obj_set_pos(brightness_slider, 0, 30); const Config* config = tt_get_config(); SetBacklightDuty set_backlight_duty = config->hardware->display.set_backlight_duty; if (set_backlight_duty == NULL) { - lv_slider_set_value(slider, 255, LV_ANIM_OFF); - lv_obj_add_state(slider, LV_STATE_DISABLED); + lv_slider_set_value(brightness_slider, 255, LV_ANIM_OFF); + lv_obj_add_state(brightness_slider, LV_STATE_DISABLED); } else { int32_t value = 255; tt_preferences()->opt_int32("display", "backlight_duty", &value); - lv_slider_set_value(slider, value, LV_ANIM_OFF); + lv_slider_set_value(brightness_slider, value, LV_ANIM_OFF); } + + lv_obj_t* orientation_wrapper = lv_obj_create(wrapper); + lv_obj_set_size(orientation_wrapper, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_t* orientation_label = lv_label_create(orientation_wrapper); + lv_label_set_text(orientation_label, "Orientation"); + lv_obj_align(orientation_label, LV_ALIGN_LEFT_MID, 0, 0); + lv_obj_t* orientation_dropdown = lv_dropdown_create(orientation_wrapper); + lv_dropdown_set_options(orientation_dropdown, "Landscape\nLandscape (flipped)\nPortrait Left\nPortrait Right"); + lv_obj_align(orientation_dropdown, LV_ALIGN_RIGHT_MID, 0, 0); + lv_obj_add_event_cb(orientation_dropdown, on_orientation_set, LV_EVENT_VALUE_CHANGED, NULL); + int orientation_selected = display_orientation_to_orientation_setting( + lv_disp_get_rotation(lv_disp_get_default()) + ); + lv_dropdown_set_selected(orientation_dropdown, orientation_selected); } -static void app_hide(App app) { +static void app_hide(TT_UNUSED App app) { if (backlight_duty_set) { tt_preferences()->put_int32("display", "backlight_duty", backlight_duty); } diff --git a/tactility/src/hardware.c b/tactility/src/hardware.c index 7d1fa4e6..50a7484e 100644 --- a/tactility/src/hardware.c +++ b/tactility/src/hardware.c @@ -1,11 +1,29 @@ #include "hardware_i.h" + +#include "lvgl.h" +#include "preferences.h" #include "sdcard_i.h" #define TAG "hardware" -typedef struct { - bool initialized; -} Hardware; +static void init_display_settings(const HardwareConfig* config) { + SetBacklightDuty set_backlight_duty = config->display.set_backlight_duty; + if (set_backlight_duty != NULL) { + int32_t backlight_duty = 200; + if (!tt_preferences()->opt_int32("display", "backlight_duty", &backlight_duty)) { + tt_preferences()->put_int32("display", "backlight_duty", backlight_duty); + } + int32_t safe_backlight_duty = TT_MIN(backlight_duty, 255); + set_backlight_duty((uint8_t)safe_backlight_duty); + } + + int32_t rotation; + if (tt_preferences()->opt_int32("display", "rotation", &rotation)) { + if (rotation != LV_DISP_ROT_NONE) { + lv_disp_set_rotation(lv_disp_get_default(), rotation); + } + } +} void tt_hardware_init(const HardwareConfig* config) { if (config->bootstrap != NULL) { @@ -21,4 +39,6 @@ void tt_hardware_init(const HardwareConfig* config) { tt_check(config->init_lvgl, "lvlg init not set"); tt_check(config->init_lvgl(), "lvgl init failed"); + + init_display_settings(config); } diff --git a/tactility/src/tactility.c b/tactility/src/tactility.c index 581b2924..ac4d5f4b 100644 --- a/tactility/src/tactility.c +++ b/tactility/src/tactility.c @@ -2,7 +2,6 @@ #include "app_manifest_registry.h" #include "hardware_i.h" -#include "preferences.h" #include "service_registry.h" #include "services/loader/loader.h" @@ -97,16 +96,6 @@ TT_UNUSED void tt_init(const Config* config) { tt_hardware_init(config->hardware); - SetBacklightDuty set_backlight_duty = config->hardware->display.set_backlight_duty; - if (set_backlight_duty != NULL) { - int32_t backlight_duty = 200; - if (!tt_preferences()->opt_int32("display", "backlight_duty", &backlight_duty)) { - tt_preferences()->put_int32("display", "backlight_duty", backlight_duty); - } - int32_t safe_backlight_duty = TT_MIN(backlight_duty, 255); - set_backlight_duty((uint8_t)safe_backlight_duty); - } - // Note: the order of starting apps and services is critical! // System services are registered first so the apps below can use them register_and_start_system_services();