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
2826static 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
3231static 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- // ------------------------------------------------------------------
5451void 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 , ¬ification);
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 , ¬ification); // 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- // ------------------------------------------------------------------
125122void 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}
0 commit comments