Skip to content

Commit 53f6e0c

Browse files
committed
Finish logic to decide between dynamic and fallback apps.
1 parent ea64892 commit 53f6e0c

File tree

5 files changed

+210
-147
lines changed

5 files changed

+210
-147
lines changed

websocket/dynamic_js.cpp

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,27 @@
1-
// dynamic_js.cpp
2-
1+
#include "dynamic_js.h"
32
#include <Arduino.h>
43
#include <WiFi.h>
54
#include <FS.h>
65
#include <SD_MMC.h>
6+
77
#include "pins_config.h"
88
#include "rm67162.h"
9-
#include "lvgl_elk.h"
10-
11-
// A flag or state variable to indicate setup success or not.
12-
static bool dynamicJsSetupDone = false;
13-
static unsigned long lastRetryAttempt = 0; // If you want a timed retry
9+
#include "lvgl_elk.h" // Contains init_lvgl_display(), init_lv_fs(), etc.
1410

1511
void dynamic_js_setup() {
1612
Serial.println("DYNAMIC_JS: Setting up Elk + script.js scenario...");
1713

18-
// 0) Remount SD card
14+
// If needed, mount the SD again (or confirm it’s already mounted):
1915
SD_MMC.setPins(PIN_SD_CLK, PIN_SD_CMD, PIN_SD_D0);
20-
if(!SD_MMC.begin("/sdcard", true, false, 20)) {
21-
Serial.println("Card Mount Failed => dynamic setup fails");
22-
dynamicJsSetupDone = false; // Mark as failed
16+
if(!SD_MMC.begin("/sdcard", true, false, 1000000)) {
17+
Serial.println("Card Mount Failed => can't run dynamic JS code properly");
2318
return;
2419
}
2520

26-
// 1) Wi-Fi (station mode)
21+
// 1) Wi-Fi (station mode) - or skip if already connected
2722
WiFi.mode(WIFI_STA);
2823

29-
// 2) LVGL display
24+
// 2) Initialize LVGL display
3025
init_lvgl_display();
3126

3227
// 3) 'S' driver for normal SD usage
@@ -35,41 +30,25 @@ void dynamic_js_setup() {
3530
// 4) 'M' driver for memory usage (GIF)
3631
init_mem_fs();
3732

38-
// 5) Init memory storage for RamImage
39-
for (int i = 0; i < MAX_RAM_IMAGES; i++) {
40-
g_ram_images[i].used = false;
41-
g_ram_images[i].buffer = NULL;
42-
g_ram_images[i].size = 0;
43-
}
33+
// 5) Init memory storage
34+
init_ram_images();
4435

45-
// 6) Create the Elk task
36+
// 6) Spawn Elk task
4637
xTaskCreatePinnedToCore(
47-
elk_task, // function pointer
48-
"ElkTask", // name of the task
49-
16384, // stack size in bytes (16KB)
50-
NULL, // parameter
51-
1, // priority
52-
NULL, // task handle
53-
1 // pin to core 1 (or 0 if you want)
38+
elk_task,
39+
"ElkTask",
40+
16384,
41+
NULL,
42+
1,
43+
NULL,
44+
1
5445
);
5546

56-
// If we reach here, assume success
57-
dynamicJsSetupDone = true;
5847
Serial.println("DYNAMIC_JS: setup done!");
5948
}
6049

6150
void dynamic_js_loop() {
62-
// If setup not done, try to do it (or re-do it)
63-
if(!dynamicJsSetupDone) {
64-
// Optionally limit how often we retry
65-
unsigned long now = millis();
66-
if(now - lastRetryAttempt > 5000) {
67-
lastRetryAttempt = now;
68-
Serial.println("DYNAMIC_JS: Trying dynamic_js_setup() again...");
69-
dynamic_js_setup();
70-
}
71-
}
72-
73-
// Otherwise, if setup *did* succeed, just wait or do minimal tasks
74-
delay(1000);
51+
// The Elk code runs in the FreeRTOS task (elk_task),
52+
// so we typically only do minimal work here
53+
delay(500);
7554
}

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: 75 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,88 @@
1-
// fallback.cpp
2-
#include <Arduino.h>
3-
#include "lvgl.h"
4-
#include "rm67162.h"
5-
#include "notification.h" // Contains 'extern const lv_img_dsc_t notification;'
6-
7-
// External objects
8-
extern lv_disp_draw_buf_t draw_buf; // or create local if you prefer
9-
extern lv_color_t *buf; // or create local
10-
extern bool fallbackActive; // Exposed globally for your main
11-
12-
// The GIF from notification.h
13-
extern const lv_img_dsc_t notification;
14-
15-
// We'll keep these static to avoid collisions
16-
static lv_obj_t *label = nullptr;
17-
static lv_obj_t *gif = nullptr;
18-
19-
static void my_disp_flush_fallback(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
20-
// Display flush provided by rm67162 or your custom driver
21-
// e.g.:
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) {
2219
uint32_t w = (area->x2 - area->x1 + 1);
2320
uint32_t h = (area->y2 - area->y1 + 1);
2421
lcd_PushColors(area->x1, area->y1, w, h, (uint16_t *)&color_p->full);
2522
lv_disp_flush_ready(disp);
2623
}
2724

25+
// Animation callback
2826
static void scroll_anim_cb(void *var, int32_t v) {
2927
lv_obj_set_y((lv_obj_t *)var, v);
3028
}
3129

30+
// Helper to create the scrolling animation
3231
static void create_scroll_animation(lv_obj_t *obj, int32_t start, int32_t end, uint32_t duration) {
3332
lv_anim_t a;
3433
lv_anim_init(&a);
3534
lv_anim_set_var(&a, obj);
3635
lv_anim_set_values(&a, start, end);
3736
lv_anim_set_time(&a, duration);
3837
lv_anim_set_exec_cb(&a, scroll_anim_cb);
39-
lv_anim_set_path_cb(&a, lv_anim_path_ease_in_out);
38+
lv_anim_set_path_cb(&a, lv_anim_path_ease_in_out); // Smooth
4039
lv_anim_set_repeat_count(&a, 2); // Repeat twice
4140

42-
// When animation finishes, hide label, show GIF
41+
// On animation finish, hide label, show GIF
4342
lv_anim_set_ready_cb(&a, [](lv_anim_t *anim) {
44-
lv_obj_t *obj = static_cast<lv_obj_t *>(anim->var);
45-
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN); // Hide text
46-
lv_obj_clear_flag(gif, LV_OBJ_FLAG_HIDDEN);// Show GIF
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);
4746
});
47+
4848
lv_anim_start(&a);
4949
}
5050

51-
// ------------------------------------------------------------------
52-
// Fallback setup
53-
// ------------------------------------------------------------------
5451
void fallback_setup() {
55-
Serial.println("FALLBACK: Setting up LVGL + scrolling label + GIF...");
52+
Serial.println("FALLBACK: Setting up scrolling label + GIF...");
5653

57-
// 1) Minimal LVGL init if not already done
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.
5857
lv_init();
59-
// 2) Screen on
58+
59+
// 2) Power on the screen, set backlight
6060
pinMode(PIN_LED, OUTPUT);
6161
digitalWrite(PIN_LED, HIGH);
6262

63-
// 3) Init your AMOLED driver, set rotation
63+
// 3) Init your display driver
6464
rm67162_init();
6565
lcd_setRotation(1);
6666

67-
// 4) Allocate buffer
68-
buf = (lv_color_t *)ps_malloc(sizeof(lv_color_t) * LVGL_LCD_BUF_SIZE);
69-
if(!buf) {
70-
Serial.println("FALLBACK: Buffer alloc failed");
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");
7171
return;
7272
}
7373

74-
// 5) Initialize draw buffer
75-
lv_disp_draw_buf_init(&draw_buf, buf, NULL, LVGL_LCD_BUF_SIZE);
74+
lv_disp_draw_buf_init(&fbDrawBuf, fbBuf, nullptr, LVGL_LCD_BUF_SIZE);
7675

77-
// 6) Register display driver
76+
// 5) Register fallback display driver
7877
static lv_disp_drv_t disp_drv;
7978
lv_disp_drv_init(&disp_drv);
80-
disp_drv.hor_res = 536;
79+
disp_drv.hor_res = 536;
8180
disp_drv.ver_res = 240;
82-
disp_drv.flush_cb = my_disp_flush_fallback;
83-
disp_drv.draw_buf = &draw_buf;
81+
disp_drv.flush_cb = fallback_disp_flush;
82+
disp_drv.draw_buf = &fbDrawBuf;
8483
lv_disp_drv_register(&disp_drv);
8584

86-
// 7) Style
85+
// 6) Create a style for the label
8786
static lv_style_t style;
8887
lv_style_init(&style);
8988
lv_style_set_text_font(&style, &lv_font_montserrat_40);
@@ -92,47 +91,47 @@ void fallback_setup() {
9291
lv_style_set_pad_all(&style, 5);
9392
lv_style_set_text_align(&style, LV_TEXT_ALIGN_CENTER);
9493

95-
// 8) Create label
96-
label = lv_label_create(lv_scr_act());
97-
lv_obj_add_style(label, &style, 0);
98-
lv_label_set_text(label,
99-
"This is fallback: a long text that will scroll automatically.\n"
100-
"Add more text to test scrolling.\n"
101-
"Eventually it shows a GIF afterwards."
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"
102104
);
103-
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
104-
lv_obj_set_width(label, 525);
105-
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
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);
106108

107-
// 9) Create scroll animation (10 seconds for a full scroll)
108-
create_scroll_animation(label, 240, -lv_obj_get_height(label), 10000);
109+
// 8) Create the scroll animation
110+
create_scroll_animation(fb_label, 240, -lv_obj_get_height(fb_label), 10000);
109111

110-
// 10) Create the GIF
111-
gif = lv_gif_create(lv_scr_act());
112-
lv_gif_set_src(gif, &notification);
113-
lv_obj_align(gif, LV_ALIGN_CENTER, 0, 0);
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);
114116

115-
// Initially hide label, show GIF
116-
lv_obj_add_flag(label, LV_OBJ_FLAG_HIDDEN);
117-
lv_obj_clear_flag(gif, LV_OBJ_FLAG_HIDDEN);
118-
119-
Serial.println("FALLBACK: Setup complete");
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);
120120
}
121121

122-
// ------------------------------------------------------------------
123-
// Fallback loop
124-
// ------------------------------------------------------------------
125122
void fallback_loop() {
123+
// Let LVGL run
126124
lv_timer_handler();
127125

128-
// If there's serial input, re-animate the label with new text
126+
// If serial data arrives, treat that as an input to update label
129127
if (Serial.available()) {
130-
String received = Serial.readStringUntil('\n');
131-
lv_label_set_text(label, received.c_str());
132-
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
133-
lv_obj_clear_flag(label, LV_OBJ_FLAG_HIDDEN);
134-
lv_obj_add_flag(gif, LV_OBJ_FLAG_HIDDEN);
135-
136-
create_scroll_animation(label, 240, -lv_obj_get_height(label), 10000);
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);
137136
}
138137
}

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)