Skip to content

Commit 4224948

Browse files
committed
WIP
1 parent 8704e99 commit 4224948

File tree

9 files changed

+404
-222
lines changed

9 files changed

+404
-222
lines changed

inc/sp140/lvgl/lv_conf.h

Lines changed: 345 additions & 157 deletions
Large diffs are not rendered by default.

inc/sp140/lvgl/lvgl_core.h

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
1-
#ifndef LVGL_CORE_H
2-
#define LVGL_CORE_H
1+
#ifndef LVGL_CORE_H // NOLINT(build/header_guard)
2+
#define LVGL_CORE_H // NOLINT(build/header_guard)
33

44
#include <lvgl.h>
55
#include <Adafruit_ST7735.h>
6+
#include <SPI.h>
67
#include "../structs.h"
78

9+
// LVGL buffer size - adjust based on available memory
10+
#define LVGL_BUFFER_SIZE 160 * 10 // 10 rows of display width
11+
812
// Display dimensions
9-
#define SCREEN_WIDTH 160
13+
#define SCREEN_WIDTH 160
1014
#define SCREEN_HEIGHT 128
1115

12-
// LVGL buffer size - optimize for our display
13-
// Use 1/4 of the screen size to balance memory usage and performance
14-
#define LVGL_BUFFER_SIZE (SCREEN_WIDTH * (SCREEN_HEIGHT / 4))
16+
// LVGL refresh time in milliseconds
17+
#define LVGL_REFRESH_TIME 10
1518

16-
// LVGL refresh time in ms - match the config file setting
17-
#define LVGL_REFRESH_TIME 40
19+
// External variables from main sketch
20+
extern int8_t displayCS;
1821

19-
// Core LVGL globals
20-
extern int8_t displayCS; // Display chip select pin
21-
extern lv_disp_drv_t disp_drv;
22-
extern lv_disp_draw_buf_t draw_buf;
22+
// Global variables
23+
extern lv_display_t* disp;
2324
extern lv_color_t buf[LVGL_BUFFER_SIZE];
2425
extern Adafruit_ST7735* tft_driver;
2526
extern uint32_t lvgl_last_update;
2627

27-
// Core function declarations
28+
// Function declarations
2829
void setupLvglBuffer();
2930
void setupLvglDisplay(const STR_DEVICE_DATA_140_V1& deviceData, int8_t dc_pin, int8_t rst_pin, SPIClass* spi);
30-
void lvgl_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p);
31+
void lvgl_flush_cb(lv_display_t* disp, const lv_area_t* area, uint8_t* px_map);
3132
void lv_tick_handler();
3233
void updateLvgl();
3334
void displayLvglSplash(const STR_DEVICE_DATA_140_V1& deviceData, int duration);

platformio.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ build_flags =
3535
-D LV_CONF_INCLUDE_SIMPLE
3636
-I inc/sp140/lvgl
3737
-D LV_LVGL_H_INCLUDE_SIMPLE
38+
-D LV_USE_DRAW_SW_BLEND_HELIUM=0
39+
-D LV_USE_DRAW_ARM2D_SYNC=0
40+
-D LV_USE_NATIVE_HELIUM_ASM=0
3841

3942
build_type = debug
4043
debug_speed = 12000
@@ -54,7 +57,7 @@ lib_deps =
5457
https://github.com/rlogiacco/CircularBuffer@1.4.0
5558
https://github.com/openppg/SINE-ESC-CAN
5659
https://github.com/openppg/ANT-BMS-CAN#97170331e1faedb5435657806ad6f9579de9552f
57-
lvgl/lvgl@^8.4.0
60+
lvgl/lvgl@^9.3.0
5861
lib_ignore =
5962
Adafruit SleepyDog Library
6063
${extra.lib_ignore}

src/assets/img/cruise-control-340255-30.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_CRUISE_CO
5656

5757
const lv_img_dsc_t cruise_control_340255_30 = {
5858
{
59-
LV_IMG_CF_ALPHA_1BIT,
59+
LV_COLOR_FORMAT_A1,
6060
0,
6161
0,
6262
30,

src/assets/img/energy-539741-26.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_ENERGY_53
5353
const lv_img_dsc_t energy_539741_26 = {
5454
// Header struct (lv_img_header_t)
5555
{
56-
LV_IMG_CF_ALPHA_1BIT, // Color format
56+
LV_COLOR_FORMAT_A1, // Color format
5757
0, // Always zero
5858
0, // Reserved
5959
24, // Width

src/assets/img/warning_2135850_30.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_WARNING_2
5757
const lv_img_dsc_t warning_2135850_30 = {
5858
// Header struct (lv_img_header_t)
5959
{
60-
LV_IMG_CF_ALPHA_1BIT, // Color format
60+
LV_COLOR_FORMAT_A1, // Color format
6161
0, // Always zero
6262
0, // Reserved
6363
30, // Width

src/sp140/lvgl/lvgl_core.cpp

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
#include "../../../inc/sp140/esp32s3-config.h"
44

55
// Global variables for core LVGL functionality
6-
lv_disp_drv_t disp_drv;
7-
lv_disp_draw_buf_t draw_buf;
6+
lv_display_t* disp = nullptr;
87
lv_color_t buf[LVGL_BUFFER_SIZE];
98
Adafruit_ST7735* tft_driver = nullptr;
109
uint32_t lvgl_last_update = 0;
@@ -14,11 +13,6 @@ void setupLvglBuffer() {
1413
USBSerial.println("Initializing LVGL");
1514
lv_init();
1615
USBSerial.println("LVGL initialized");
17-
18-
// Setup buffer for LVGL
19-
USBSerial.println("Setting up LVGL buffer");
20-
lv_disp_draw_buf_init(&draw_buf, buf, NULL, LVGL_BUFFER_SIZE);
21-
USBSerial.println("LVGL buffer initialized");
2216
}
2317

2418
void setupLvglDisplay(const STR_DEVICE_DATA_140_V1& deviceData, int8_t dc_pin, int8_t rst_pin, SPIClass* spi) {
@@ -37,33 +31,29 @@ void setupLvglDisplay(const STR_DEVICE_DATA_140_V1& deviceData, int8_t dc_pin, i
3731
// Initialize LVGL buffer
3832
setupLvglBuffer();
3933

40-
// Initialize display driver
41-
static lv_disp_drv_t disp_drv;
42-
lv_disp_drv_init(&disp_drv);
34+
// Create display with LVGL v9 API
35+
disp = lv_display_create(SCREEN_WIDTH, SCREEN_HEIGHT);
4336

44-
// Set display driver properties
45-
disp_drv.hor_res = SCREEN_WIDTH;
46-
disp_drv.ver_res = SCREEN_HEIGHT;
47-
disp_drv.flush_cb = lvgl_flush_cb;
48-
disp_drv.draw_buf = &draw_buf;
37+
// Set up the draw buffer
38+
lv_display_set_buffers(disp, buf, NULL, sizeof(buf), LV_DISPLAY_RENDER_MODE_PARTIAL);
4939

50-
// Register the display driver
51-
lv_disp_drv_register(&disp_drv);
40+
// Set the flush callback
41+
lv_display_set_flush_cb(disp, lvgl_flush_cb);
5242

5343
// Set LVGL default theme - using default font
5444
lv_theme_t* theme = lv_theme_default_init(
55-
lv_disp_get_default(), // Display
56-
lv_palette_main(LV_PALETTE_BLUE), // Primary color
57-
lv_palette_main(LV_PALETTE_AMBER), // Secondary color
58-
deviceData.theme == 1, // Dark mode
59-
LV_FONT_DEFAULT); // Default font
45+
disp, // Display
46+
lv_palette_main(LV_PALETTE_BLUE), // Primary color
47+
lv_palette_main(LV_PALETTE_AMBER),// Secondary color
48+
deviceData.theme == 1, // Dark mode
49+
LV_FONT_DEFAULT); // Default font
6050

61-
lv_disp_set_theme(lv_disp_get_default(), theme);
51+
lv_display_set_theme(disp, theme);
6252
}
6353

6454
// Optimize the flush callback to minimize SPI transfers
6555
// CS pin management is handled here where actual SPI communication occurs
66-
void lvgl_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) {
56+
void lvgl_flush_cb(lv_display_t* disp, const lv_area_t* area, uint8_t* px_map) {
6757
// Make sure display CS is selected
6858
digitalWrite(displayCS, LOW);
6959

@@ -76,14 +66,14 @@ void lvgl_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color
7666

7767
// Push colors - using DMA if available
7868
uint32_t len = w * h;
79-
tft_driver->writePixels((uint16_t*)color_p, len);
69+
tft_driver->writePixels((uint16_t*)px_map, len);
8070
tft_driver->endWrite();
8171

8272
// Deselect display CS when done
8373
digitalWrite(displayCS, HIGH);
8474

8575
// Indicate to LVGL that flush is done
86-
lv_disp_flush_ready(disp);
76+
lv_display_flush_ready(disp);
8777
}
8878

8979
// LVGL tick handler - to be called from timer or in main loop
@@ -104,7 +94,7 @@ void updateLvgl() {
10494
// Update LVGL at the defined refresh rate
10595
if (current_ms - lvgl_last_update > LVGL_REFRESH_TIME) {
10696
lv_tick_handler();
107-
lv_task_handler();
97+
lv_timer_handler();
10898
lvgl_last_update = current_ms;
10999
}
110100
}
@@ -114,10 +104,10 @@ void displayLvglSplash(const STR_DEVICE_DATA_140_V1& deviceData, int duration) {
114104

115105
// Create a new screen for the splash
116106
lv_obj_t* splash_screen = lv_obj_create(NULL);
117-
lv_scr_load(splash_screen);
107+
lv_screen_load(splash_screen);
118108

119109
// Disable scrollbars
120-
lv_obj_clear_flag(splash_screen, LV_OBJ_FLAG_SCROLLABLE);
110+
lv_obj_remove_flag(splash_screen, LV_OBJ_FLAG_SCROLLABLE);
121111

122112
// Set background color based on theme
123113
lv_obj_set_style_bg_color(splash_screen,
@@ -139,7 +129,7 @@ void displayLvglSplash(const STR_DEVICE_DATA_140_V1& deviceData, int duration) {
139129
lv_anim_init(&title_anim);
140130
lv_anim_set_var(&title_anim, title_label);
141131
lv_anim_set_values(&title_anim, 0, 255);
142-
lv_anim_set_time(&title_anim, 500);
132+
lv_anim_set_duration(&title_anim, 500);
143133
lv_anim_set_exec_cb(&title_anim, [](void* var, int32_t value) {
144134
lv_obj_set_style_opa((lv_obj_t*)var, value, 0);
145135
});

src/sp140/lvgl/lvgl_main_screen.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ void setupMainScreen(bool darkMode) {
405405
// Draw divider lines
406406
// Create horizontal line between top and middle sections
407407
lv_obj_t* h_line1 = lv_line_create(main_screen);
408-
static lv_point_t h_line1_points[] = {{0, 37}, {SCREEN_WIDTH, 37}};
408+
static lv_point_precise_t h_line1_points[] = {{0, 37}, {SCREEN_WIDTH, 37}};
409409
lv_line_set_points(h_line1, h_line1_points, 2);
410410
lv_obj_set_style_line_color(h_line1,
411411
LVGL_GRAY,
@@ -414,7 +414,7 @@ void setupMainScreen(bool darkMode) {
414414

415415
// Create horizontal line between middle and bottom sections (stop at new section boundary)
416416
lv_obj_t* h_line2 = lv_line_create(main_screen);
417-
static lv_point_t h_line2_points[] = {{0, 70}, {148, 70}};
417+
static lv_point_precise_t h_line2_points[] = {{0, 70}, {148, 70}};
418418
lv_line_set_points(h_line2, h_line2_points, 2);
419419
lv_obj_set_style_line_color(h_line2,
420420
LVGL_GRAY,
@@ -423,7 +423,7 @@ void setupMainScreen(bool darkMode) {
423423

424424
// Create vertical line in middle section (shifted left by 6 pixels)
425425
lv_obj_t* v_line1 = lv_line_create(main_screen);
426-
static lv_point_t v_line1_points[] = {{102, 37}, {102, 70}};
426+
static lv_point_precise_t v_line1_points[] = {{102, 37}, {102, 70}};
427427
lv_line_set_points(v_line1, v_line1_points, 2);
428428
lv_obj_set_style_line_color(v_line1,
429429
LVGL_GRAY,
@@ -432,7 +432,7 @@ void setupMainScreen(bool darkMode) {
432432

433433
// Create vertical line in bottom section (moved left 3px)
434434
lv_obj_t* v_line2 = lv_line_create(main_screen);
435-
static lv_point_t v_line2_points[] = {{117, 70}, {117, 128}};
435+
static lv_point_precise_t v_line2_points[] = {{117, 70}, {117, 128}};
436436
lv_line_set_points(v_line2, v_line2_points, 2);
437437
lv_obj_set_style_line_color(v_line2,
438438
LVGL_GRAY,
@@ -441,7 +441,7 @@ void setupMainScreen(bool darkMode) {
441441

442442
// Create vertical line for new far-right section (12px from right edge)
443443
lv_obj_t* v_line3 = lv_line_create(main_screen);
444-
static lv_point_t v_line3_points[] = {{148, 37}, {148, 128}};
444+
static lv_point_precise_t v_line3_points[] = {{148, 37}, {148, 128}};
445445
lv_line_set_points(v_line3, v_line3_points, 2);
446446
lv_obj_set_style_line_color(v_line3,
447447
LVGL_GRAY,
@@ -451,7 +451,7 @@ void setupMainScreen(bool darkMode) {
451451
// Create horizontal dividers for temperature section
452452
// Line between B and E at Y=89 (start from moved vertical line)
453453
lv_obj_t* h_line3 = lv_line_create(main_screen);
454-
static lv_point_t h_line3_points[] = {{117, 89}, {148, 89}};
454+
static lv_point_precise_t h_line3_points[] = {{117, 89}, {148, 89}};
455455
lv_line_set_points(h_line3, h_line3_points, 2);
456456
lv_obj_set_style_line_color(h_line3,
457457
LVGL_GRAY,
@@ -460,7 +460,7 @@ void setupMainScreen(bool darkMode) {
460460

461461
// Line between E and M at Y=109 (start from moved vertical line)
462462
lv_obj_t* h_line4 = lv_line_create(main_screen);
463-
static lv_point_t h_line4_points[] = {{117, 109}, {148, 109}};
463+
static lv_point_precise_t h_line4_points[] = {{117, 109}, {148, 109}};
464464
lv_line_set_points(h_line4, h_line4_points, 2);
465465
lv_obj_set_style_line_color(h_line4,
466466
LVGL_GRAY,
@@ -478,8 +478,8 @@ void setupMainScreen(bool darkMode) {
478478
lv_obj_add_flag(arm_indicator, LV_OBJ_FLAG_HIDDEN);
479479

480480
// Create cruise control icon (initially hidden)
481-
cruise_icon_img = lv_img_create(main_screen);
482-
lv_img_set_src(cruise_icon_img, &cruise_control_340255_30); // Use the new 30x30 image descriptor
481+
cruise_icon_img = lv_image_create(main_screen);
482+
lv_image_set_src(cruise_icon_img, &cruise_control_340255_30); // Use the new 30x30 image descriptor
483483

484484
// Set icon color using recoloring based on theme
485485
lv_color_t icon_color;
@@ -496,8 +496,8 @@ void setupMainScreen(bool darkMode) {
496496
lv_obj_add_flag(cruise_icon_img, LV_OBJ_FLAG_HIDDEN); // Hide initially
497497

498498
// Create charging icon (initially hidden)
499-
charging_icon_img = lv_img_create(main_screen);
500-
lv_img_set_src(charging_icon_img, &energy_539741_26);
499+
charging_icon_img = lv_image_create(main_screen);
500+
lv_image_set_src(charging_icon_img, &energy_539741_26);
501501
lv_obj_align_to(charging_icon_img, battery_label, LV_ALIGN_OUT_RIGHT_MID, 3, 0); // Align to right of battery label
502502

503503
// Set charging icon color based on theme
@@ -508,8 +508,8 @@ void setupMainScreen(bool darkMode) {
508508
lv_obj_add_flag(charging_icon_img, LV_OBJ_FLAG_HIDDEN); // Hide initially
509509

510510
// Create arm fail warning icon (initially hidden)
511-
arm_fail_warning_icon_img = lv_img_create(main_screen);
512-
lv_img_set_src(arm_fail_warning_icon_img, &warning_2135850_30);
511+
arm_fail_warning_icon_img = lv_image_create(main_screen);
512+
lv_image_set_src(arm_fail_warning_icon_img, &warning_2135850_30);
513513
// Align in the same position as the cruise icon
514514
lv_obj_align(arm_fail_warning_icon_img, LV_ALIGN_CENTER, 12, -9);
515515

@@ -529,7 +529,7 @@ void setupMainScreen(bool darkMode) {
529529
lv_obj_set_style_border_width(spinner_overlay, 0, LV_PART_MAIN);
530530

531531
// Create spinning animation at the top center - now place on top of overlay
532-
spinner = lv_spinner_create(spinner_overlay, 1000, 60); // 1000ms period, 60 arcade width
532+
spinner = lv_spinner_create(spinner_overlay); // LVGL v9 simplified API
533533
lv_obj_set_size(spinner, 80, 80); // Even larger spinner for visibility
534534
lv_obj_align(spinner, LV_ALIGN_CENTER, 0, 0); // Position at center of screen
535535

@@ -559,7 +559,7 @@ void setupMainScreen(bool darkMode) {
559559

560560
// Create horizontal divider line running from section start to screen edge
561561
climb_rate_divider_lines[i] = lv_line_create(main_screen);
562-
static lv_point_t line_points[13][2]; // Static array for all line points
562+
static lv_point_precise_t line_points[13][2]; // Static array for all line points
563563
line_points[i][0].x = 148; // Start at section boundary
564564
line_points[i][0].y = y_pos;
565565
line_points[i][1].x = 160; // End at screen edge
@@ -615,5 +615,5 @@ void setupMainScreen(bool darkMode) {
615615
setupAlertCounterUI(darkMode);
616616

617617
// Load the screen
618-
lv_scr_load(main_screen);
618+
lv_screen_load(main_screen);
619619
}

src/sp140/sp140.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ void setup() {
618618

619619
// Explicitly load the main screen to make it active
620620
if (main_screen != NULL) {
621-
lv_scr_load(main_screen);
621+
lv_screen_load(main_screen);
622622
USBSerial.println("Main screen loaded");
623623
} else {
624624
USBSerial.println("Error: Main screen object is NULL after setup attempt.");

0 commit comments

Comments
 (0)