Skip to content

Commit 2ffd4b2

Browse files
authored
Merge pull request #2 from HW-Lab-Hardware-Design-Agency/js_lvgl
Finish JS support
2 parents b2af76e + 53f6e0c commit 2ffd4b2

File tree

7 files changed

+3666
-107
lines changed

7 files changed

+3666
-107
lines changed

websocket/dynamic_js.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "dynamic_js.h"
2+
#include <Arduino.h>
3+
#include <WiFi.h>
4+
#include <FS.h>
5+
#include <SD_MMC.h>
6+
7+
#include "pins_config.h"
8+
#include "rm67162.h"
9+
#include "lvgl_elk.h" // Contains init_lvgl_display(), init_lv_fs(), etc.
10+
11+
void dynamic_js_setup() {
12+
Serial.println("DYNAMIC_JS: Setting up Elk + script.js scenario...");
13+
14+
// If needed, mount the SD again (or confirm it’s already mounted):
15+
SD_MMC.setPins(PIN_SD_CLK, PIN_SD_CMD, PIN_SD_D0);
16+
if(!SD_MMC.begin("/sdcard", true, false, 1000000)) {
17+
Serial.println("Card Mount Failed => can't run dynamic JS code properly");
18+
return;
19+
}
20+
21+
// 1) Wi-Fi (station mode) - or skip if already connected
22+
WiFi.mode(WIFI_STA);
23+
24+
// 2) Initialize LVGL display
25+
init_lvgl_display();
26+
27+
// 3) 'S' driver for normal SD usage
28+
init_lv_fs();
29+
30+
// 4) 'M' driver for memory usage (GIF)
31+
init_mem_fs();
32+
33+
// 5) Init memory storage
34+
init_ram_images();
35+
36+
// 6) Spawn Elk task
37+
xTaskCreatePinnedToCore(
38+
elk_task,
39+
"ElkTask",
40+
16384,
41+
NULL,
42+
1,
43+
NULL,
44+
1
45+
);
46+
47+
Serial.println("DYNAMIC_JS: setup done!");
48+
}
49+
50+
void dynamic_js_loop() {
51+
// The Elk code runs in the FreeRTOS task (elk_task),
52+
// so we typically only do minimal work here
53+
delay(500);
54+
}

websocket/dynamic_js.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
3+
// Functions to set up and loop your “dynamic” (Elk + script.js) code
4+
void dynamic_js_setup();
5+
void dynamic_js_loop();

websocket/fallback.cpp

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#include "fallback.h"
2+
#include "pins_config.h"
3+
#include "rm67162.h" // LCD driver
4+
#include <lvgl.h> // Ensure you have LVGL
5+
#include <WiFi.h> // (If you need Wi-Fi info in fallback)
6+
#include <FS.h> // Possibly for file ops
7+
#include <SD_MMC.h> // If needed for fallback?
8+
9+
// We'll store references to the fallback label + gif
10+
static lv_obj_t* fb_label = nullptr;
11+
static lv_obj_t* fb_gif = nullptr;
12+
13+
// A local display buffer/driver just for fallback, if you want separate from dynamic
14+
static lv_disp_draw_buf_t fbDrawBuf;
15+
static lv_color_t* fbBuf = nullptr;
16+
17+
// The flush callback
18+
static void fallback_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
19+
uint32_t w = (area->x2 - area->x1 + 1);
20+
uint32_t h = (area->y2 - area->y1 + 1);
21+
lcd_PushColors(area->x1, area->y1, w, h, (uint16_t *)&color_p->full);
22+
lv_disp_flush_ready(disp);
23+
}
24+
25+
// Animation callback
26+
static void scroll_anim_cb(void *var, int32_t v) {
27+
lv_obj_set_y((lv_obj_t *)var, v);
28+
}
29+
30+
// Helper to create the scrolling animation
31+
static void create_scroll_animation(lv_obj_t *obj, int32_t start, int32_t end, uint32_t duration) {
32+
lv_anim_t a;
33+
lv_anim_init(&a);
34+
lv_anim_set_var(&a, obj);
35+
lv_anim_set_values(&a, start, end);
36+
lv_anim_set_time(&a, duration);
37+
lv_anim_set_exec_cb(&a, scroll_anim_cb);
38+
lv_anim_set_path_cb(&a, lv_anim_path_ease_in_out); // Smooth
39+
lv_anim_set_repeat_count(&a, 2); // Repeat twice
40+
41+
// On animation finish, hide label, show GIF
42+
lv_anim_set_ready_cb(&a, [](lv_anim_t *anim) {
43+
lv_obj_t *obj = (lv_obj_t *)anim->var;
44+
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
45+
lv_obj_clear_flag(fb_gif, LV_OBJ_FLAG_HIDDEN);
46+
});
47+
48+
lv_anim_start(&a);
49+
}
50+
51+
void fallback_setup() {
52+
Serial.println("FALLBACK: Setting up scrolling label + GIF...");
53+
54+
// 1) Minimal LVGL init (only if not already done).
55+
// If your main code calls lv_init() elsewhere,
56+
// you might skip or check if it’s safe to call again.
57+
lv_init();
58+
59+
// 2) Power on the screen, set backlight
60+
pinMode(PIN_LED, OUTPUT);
61+
digitalWrite(PIN_LED, HIGH);
62+
63+
// 3) Init your display driver
64+
rm67162_init();
65+
lcd_setRotation(1);
66+
67+
// 4) Allocate a buffer for fallback usage
68+
fbBuf = (lv_color_t*) ps_malloc(sizeof(lv_color_t) * LVGL_LCD_BUF_SIZE);
69+
if(!fbBuf) {
70+
Serial.println("FALLBACK: Failed to allocate buffer");
71+
return;
72+
}
73+
74+
lv_disp_draw_buf_init(&fbDrawBuf, fbBuf, nullptr, LVGL_LCD_BUF_SIZE);
75+
76+
// 5) Register fallback display driver
77+
static lv_disp_drv_t disp_drv;
78+
lv_disp_drv_init(&disp_drv);
79+
disp_drv.hor_res = 536;
80+
disp_drv.ver_res = 240;
81+
disp_drv.flush_cb = fallback_disp_flush;
82+
disp_drv.draw_buf = &fbDrawBuf;
83+
lv_disp_drv_register(&disp_drv);
84+
85+
// 6) Create a style for the label
86+
static lv_style_t style;
87+
lv_style_init(&style);
88+
lv_style_set_text_font(&style, &lv_font_montserrat_40);
89+
lv_style_set_text_color(&style, lv_color_white());
90+
lv_style_set_bg_color(&style, lv_color_black());
91+
lv_style_set_pad_all(&style, 5);
92+
lv_style_set_text_align(&style, LV_TEXT_ALIGN_CENTER);
93+
94+
// 7) Create the label
95+
fb_label = lv_label_create(lv_scr_act());
96+
lv_obj_add_style(fb_label, &style, 0);
97+
lv_label_set_text(fb_label,
98+
"/\\_/\\\n"
99+
"= ( • . • ) =\n"
100+
" / \\ \n"
101+
"Welcome to Webscreen! This is the Notification App, you can also run apps from the SD card.\n"
102+
" \n"
103+
" \n"
104+
);
105+
lv_label_set_long_mode(fb_label, LV_LABEL_LONG_WRAP);
106+
lv_obj_set_width(fb_label, 525);
107+
lv_obj_align(fb_label, LV_ALIGN_CENTER, 0, 0);
108+
109+
// 8) Create the scroll animation
110+
create_scroll_animation(fb_label, 240, -lv_obj_get_height(fb_label), 10000);
111+
112+
// 9) Create the GIF
113+
fb_gif = lv_gif_create(lv_scr_act());
114+
lv_gif_set_src(fb_gif, &notification); // from notification.h
115+
lv_obj_align(fb_gif, LV_ALIGN_CENTER, 0, 0);
116+
117+
// Show label first, hide GIF
118+
lv_obj_clear_flag(fb_label, LV_OBJ_FLAG_HIDDEN);
119+
lv_obj_add_flag(fb_gif, LV_OBJ_FLAG_HIDDEN);
120+
}
121+
122+
void fallback_loop() {
123+
// Let LVGL run
124+
lv_timer_handler();
125+
126+
// If serial data arrives, treat that as an input to update label
127+
if (Serial.available()) {
128+
String line = Serial.readStringUntil('\n');
129+
lv_label_set_text(fb_label, line.c_str());
130+
lv_obj_align(fb_label, LV_ALIGN_CENTER, 0, 0);
131+
lv_obj_clear_flag(fb_label, LV_OBJ_FLAG_HIDDEN);
132+
lv_obj_add_flag(fb_gif, LV_OBJ_FLAG_HIDDEN);
133+
134+
// re-run animation
135+
create_scroll_animation(fb_label, 240, -lv_obj_get_height(fb_label), 10000);
136+
}
137+
}

websocket/fallback.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#pragma once
2+
3+
#include <Arduino.h>
4+
#include "lvgl.h" // For LVGL types
5+
#include "notification.h" // For the GIF data
6+
// extern const lv_img_dsc_t notification; // Typically declared in notification.h
7+
8+
// Public API
9+
void fallback_setup();
10+
void fallback_loop();

0 commit comments

Comments
 (0)