From 632d7ccccf36b1ae44666127014e399ecfc57f4b Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sat, 2 Nov 2024 23:40:26 +0100 Subject: [PATCH] Implemented power management (#67) - Implemented HAL for for power management - Implemented the Power app (accessible via Settings app) - Implemented status bar icon for battery status --- README.md | 12 +- app-sim/src/hardware_config.c | 9 +- app-sim/src/main.c | 2 +- app-sim/src/power.c | 34 +++++ boards/lilygo_tdeck/lilygo_tdeck.c | 3 +- boards/m5stack_core2/source/display.cpp | 5 + boards/m5stack_core2/source/m5stack_core2.c | 4 +- boards/m5stack_core2/source/power.cpp | 34 +++++ boards/m5stack_core2/source/touch.cpp | 2 +- .../waveshare_s3_touch/waveshare_s3_touch.c | 4 +- boards/yellow_board/yellow_board.c | 3 +- data/assets/app_icon_power_settings.png | Bin 0 -> 299 bytes data/assets/power_020.png | Bin 0 -> 256 bytes data/assets/power_040.png | Bin 0 -> 261 bytes data/assets/power_060.png | Bin 0 -> 268 bytes data/assets/power_080.png | Bin 0 -> 262 bytes data/assets/power_100.png | Bin 0 -> 259 bytes data/assets_sources/Desktop Icons.svg | 69 +++++++++-- docs/ideas.md | 2 + tactility-headless/src/assets.h | 8 ++ tactility-headless/src/hardware_config.h | 6 + tactility-headless/src/power.c | 1 + tactility-headless/src/power.h | 24 ++++ tactility/src/apps/settings/display/display.c | 1 - tactility/src/apps/settings/power/power.c | 116 ++++++++++++++++++ .../src/apps/system/system_info/system_info.c | 3 + .../statusbar_updater/statusbar_updater.c | 49 +++++++- tactility/src/tactility.c | 6 + tactility/src/ui/statusbar.c | 2 + 29 files changed, 373 insertions(+), 26 deletions(-) create mode 100644 app-sim/src/power.c create mode 100644 boards/m5stack_core2/source/power.cpp create mode 100644 data/assets/app_icon_power_settings.png create mode 100644 data/assets/power_020.png create mode 100644 data/assets/power_040.png create mode 100644 data/assets/power_060.png create mode 100644 data/assets/power_080.png create mode 100644 data/assets/power_100.png create mode 100644 tactility-headless/src/power.c create mode 100644 tactility-headless/src/power.h create mode 100644 tactility/src/apps/settings/power/power.c diff --git a/README.md b/README.md index 35056373..90008ec9 100644 --- a/README.md +++ b/README.md @@ -73,12 +73,12 @@ Implementing drivers can take some effort, so Tactility provides support for sev Predefined configurations are available for: -| Device | Screen&Touch | SD card | Other | -|------------------------------------------|--------------|---------|----------| -| [LilyGo T-Deck][tdeck] | ✅ | ✅ | Keyboard | -| [Waveshare S3 Touch][waveshare_s3_touch] | ✅ | ⏳ | | -| Yellow Board 2432S024C (\*) | ✅ | ✅ | | -| [M5Stack Core2][m5stack] | ✅ | ✅ | | +| Device | Screen&Touch | SD card | Power | Other | +|------------------------------------------|--------------|---------|-------|----------| +| [M5Stack Core2][m5stack] | ✅ | ✅ | ✅ | | +| [LilyGo T-Deck][tdeck] | ✅ | ✅ | | Keyboard | +| [Waveshare S3 Touch][waveshare_s3_touch] | ✅ | ⏳ | | | +| Yellow Board 2432S024C (\*) | ✅ | ✅ | | | - ✅: Capable and implemented - ⏳: Capable but not yet implemented diff --git a/app-sim/src/hardware_config.c b/app-sim/src/hardware_config.c index 3fbea738..4912a433 100644 --- a/app-sim/src/hardware_config.c +++ b/app-sim/src/hardware_config.c @@ -5,6 +5,8 @@ #define TAG "hardware" +extern const Power power; + static bool lvgl_init() { lv_init(); lvgl_task_start(); @@ -22,7 +24,12 @@ TT_UNUSED static void lvgl_deinit() { #endif } -HardwareConfig sim_hardware = { +const HardwareConfig sim_hardware = { .bootstrap = NULL, .init_graphics = &lvgl_init, + .display = { + .set_backlight_duty = NULL, + }, + .power = &power, + .sdcard = NULL }; diff --git a/app-sim/src/main.c b/app-sim/src/main.c index 4642916a..273939a5 100644 --- a/app-sim/src/main.c +++ b/app-sim/src/main.c @@ -1,7 +1,7 @@ #include "hello_world/hello_world.h" #include "tactility.h" -extern HardwareConfig sim_hardware; +extern const HardwareConfig sim_hardware; void app_main() { static const Config config = { diff --git a/app-sim/src/power.c b/app-sim/src/power.c new file mode 100644 index 00000000..e4d2ab14 --- /dev/null +++ b/app-sim/src/power.c @@ -0,0 +1,34 @@ +#include "power.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static bool is_charging_enabled = false; + +static bool power_is_charging() { + return is_charging_enabled; +} + +static void power_set_charging_enabled(bool enabled) { + is_charging_enabled = enabled; +} + +static uint8_t power_get_charge_level() { + return 204; +} + +static int32_t power_get_current() { + return is_charging_enabled ? 100 : -50; +} + +const Power power = { + .is_charging = &power_is_charging, + .set_charging_enabled = &power_set_charging_enabled, + .get_charge_level = &power_get_charge_level, + .get_current = &power_get_current +}; + +#ifdef __cplusplus +} +#endif diff --git a/boards/lilygo_tdeck/lilygo_tdeck.c b/boards/lilygo_tdeck/lilygo_tdeck.c index d1d9c15e..59b5108f 100644 --- a/boards/lilygo_tdeck/lilygo_tdeck.c +++ b/boards/lilygo_tdeck/lilygo_tdeck.c @@ -13,5 +13,6 @@ const HardwareConfig lilygo_tdeck = { .set_backlight_duty = &tdeck_backlight_set }, .init_graphics = &tdeck_init_lvgl, - .sdcard = &tdeck_sdcard + .sdcard = &tdeck_sdcard, + .power = NULL }; diff --git a/boards/m5stack_core2/source/display.cpp b/boards/m5stack_core2/source/display.cpp index df866f7a..99670c49 100644 --- a/boards/m5stack_core2/source/display.cpp +++ b/boards/m5stack_core2/source/display.cpp @@ -32,7 +32,12 @@ lv_disp_t* core2_display_init() { const esp_lcd_panel_dev_config_t panel_config = { .reset_gpio_num = GPIO_NUM_NC, .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR, + .data_endian = LCD_RGB_DATA_ENDIAN_BIG, .bits_per_pixel = CORE2_LCD_BITS_PER_PIXEL, + .flags = { + .reset_active_high = false + }, + .vendor_config = nullptr }; esp_lcd_panel_handle_t panel_handle; diff --git a/boards/m5stack_core2/source/m5stack_core2.c b/boards/m5stack_core2/source/m5stack_core2.c index c8cc3b52..90364154 100644 --- a/boards/m5stack_core2/source/m5stack_core2.c +++ b/boards/m5stack_core2/source/m5stack_core2.c @@ -3,6 +3,7 @@ #include "lvgl_i.h" extern const SdCard core2_sdcard; +extern Power core2_power; // Making it const fails the build const HardwareConfig m5stack_core2 = { .bootstrap = &core2_bootstrap, @@ -10,5 +11,6 @@ const HardwareConfig m5stack_core2 = { .set_backlight_duty = NULL }, .init_graphics = &core2_lvgl_init, - .sdcard = &core2_sdcard + .sdcard = &core2_sdcard, + .power = &core2_power }; diff --git a/boards/m5stack_core2/source/power.cpp b/boards/m5stack_core2/source/power.cpp new file mode 100644 index 00000000..c88512e6 --- /dev/null +++ b/boards/m5stack_core2/source/power.cpp @@ -0,0 +1,34 @@ +#include "power.h" +#include "M5Unified.hpp" + +#ifdef __cplusplus +extern "C" { +#endif + +static bool power_is_charging() { + return M5.Power.isCharging() == m5::Power_Class::is_charging; +} + +static void power_set_charging_enabled(bool enabled) { + M5.Power.setBatteryCharge(enabled); +} + +static uint8_t power_get_charge_level() { + uint16_t scaled = (uint16_t)M5.Power.getBatteryLevel() * 255 / 100; + return (uint8_t)scaled; +} + +static int32_t power_get_current() { + return M5.Power.getBatteryCurrent(); +} + +Power core2_power = { + .is_charging = &power_is_charging, + .set_charging_enabled = &power_set_charging_enabled, + .get_charge_level = &power_get_charge_level, + .get_current = &power_get_current +}; + +#ifdef __cplusplus +} +#endif diff --git a/boards/m5stack_core2/source/touch.cpp b/boards/m5stack_core2/source/touch.cpp index 847e5b03..94d2c43d 100644 --- a/boards/m5stack_core2/source/touch.cpp +++ b/boards/m5stack_core2/source/touch.cpp @@ -9,7 +9,7 @@ extern "C" { #endif static void read_touch(TT_UNUSED lv_indev_t* indev, lv_indev_data_t* data) { - static lgfx::touch_point_t point; + lgfx::touch_point_t point; // Making it static makes it unreliable bool touched = M5.Lcd.getTouch(&point) > 0; if (touched) { data->point.x = point.x; diff --git a/boards/waveshare_s3_touch/waveshare_s3_touch.c b/boards/waveshare_s3_touch/waveshare_s3_touch.c index 9e65a13b..15ae87e8 100644 --- a/boards/waveshare_s3_touch/waveshare_s3_touch.c +++ b/boards/waveshare_s3_touch/waveshare_s3_touch.c @@ -9,5 +9,7 @@ const HardwareConfig waveshare_s3_touch = { .display = { .set_backlight_duty = NULL // TODO: This requires implementing the CH422G IO expander }, - .init_graphics = &ws3t_init_lvgl + .init_graphics = &ws3t_init_lvgl, + .sdcard = NULL, + .power = NULL }; diff --git a/boards/yellow_board/yellow_board.c b/boards/yellow_board/yellow_board.c index b678092e..0a57eee5 100644 --- a/boards/yellow_board/yellow_board.c +++ b/boards/yellow_board/yellow_board.c @@ -12,5 +12,6 @@ const HardwareConfig yellow_board_24inch_cap = { .set_backlight_duty = &twodotfour_backlight_set }, .init_graphics = &twodotfour_lvgl_init, - .sdcard = &twodotfour_sdcard + .sdcard = &twodotfour_sdcard, + .power = NULL }; diff --git a/data/assets/app_icon_power_settings.png b/data/assets/app_icon_power_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..41ba02daa9dceb5dc7e969226d4f38143c40349b GIT binary patch literal 299 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#X!0Ygc<#+)i{6*$r9Iy zlHmNblJdl&REF~Ma=pyF?Be9af>gcyqV(DCY@~pSc6hothFJ7ooovW;C_upF{xSLH zCdC^PAH)tew8lo|KjM6|x9Ndx&ebTzoek;&QxX&p3QXF%{g;sAoPTHEo!hWz)s~5u zyZ*H`x&)e(%cNg4>D}1o;uRX38d+wdv`N$L>5fm?uUE$9eaOpWIK%TGevgcyqV(DCY@~pSdOcknLo9laPB!Fg3J`F)uh1f~ zw~bZwq0)sa2L1Ghl5cX~c66pMSop^|`J=b}{Fas5W^UiTIr65OyX&-S?uG_-fv^ho z+uMa!lgcyqV(DCY@~pSCV9FzhFJ6-oovl@C_upVd@rY_ zNKC7%m-(V4#f*994w>HYwz3wCah5t=o~yI$^m9&0i5Z&jX38tyeiAWp=|6Ud1ELiq@4vnFugOj%E)=ox~6`?%4s?ETYi|=F)E!@^ElDqn+9|pgQu&X%Q~loCIDq? BTVntK literal 0 HcmV?d00001 diff --git a/data/assets/power_060.png b/data/assets/power_060.png new file mode 100644 index 0000000000000000000000000000000000000000..9600ceabbdfcba3e5d2dc74f7c00df4698533db6 GIT binary patch literal 268 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#X!0Ygc<#+)i{6*$r9Iy zlHmNblJdl&REF~Ma=pyF?Be9af>gcyqV(DCY@~pSW_r3fhFJ6-oxG8k$xwhL{h&S* zhlfTZL)XJ#t_8AO3m8?HvKDYCDP{d=x!}#v$ozZhagX}WwO8NGDM>$VW@@_9>p!!? z1Fj?To94cCW{|qQ`{3NA(heRi)&{35{I~V126()C&6E&&LQf?&tL+BE+ZEY82R5@^ zxOs1h^Bv~PJs&T+a~=r0wDY`*rn>&a&qB}d7iYNM*6;l%eV;j2xg+%7G>{`1JYD@< J);T3K0RR)PVX*)J literal 0 HcmV?d00001 diff --git a/data/assets/power_080.png b/data/assets/power_080.png new file mode 100644 index 0000000000000000000000000000000000000000..a3dd78ffe779cc2e5c40fe5b95781f7531a5c0a2 GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#X!0Ygc<#+)i{6*$r9Iy zlHmNblJdl&REF~Ma=pyF?Be9af>gcyqV(DCY@~pSCVRR#hFJ6-ovg@rC_upFzLPXd z40GT~*8@ciGV0C+Oe}KVO-ctJW>2V<&gP~uhIcn`C zf$ayjIDh!###X?t$85IZN+`qU{=j&XSK4m>kC}6XYGipCn1VdR;OXk;vd$@?2>@s< BTCD&8 literal 0 HcmV?d00001 diff --git a/data/assets/power_100.png b/data/assets/power_100.png new file mode 100644 index 0000000000000000000000000000000000000000..4098f9683815cc881937e1fc2ac2a1f633264314 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#X!0Ygc<#+)i{6*$r9Iy zlHmNblJdl&REF~Ma=pyF?Be9af>gcyqV(DCY@~pSCV09yhFJ6-oxG9vkOPnFd__Ul zHI5S}NxoQkmO;n;AkUXATRcR31ULilEmpiV)ss*2UC!&;==()0rW{$+@vq&1L0rK% z!TM_m9~GyHYzpBr@4LU_rW>V4