1 #include "../../lv_examples.h"
2 #if LV_USE_OBSERVER && LV_USE_ARC && LV_USE_LABEL && LV_USE_BUTTON && LV_USE_SPINNER && LV_BUILD_EXAMPLES
3
4 typedef enum {
5 FW_UPDATE_STATE_IDLE,
6 FW_UPDATE_STATE_CONNECTING,
7 FW_UPDATE_STATE_CONNECTED,
8 FW_UPDATE_STATE_DOWNLOADING,
9 FW_UPDATE_STATE_CANCEL,
10 FW_UPDATE_STATE_READY,
11 } fw_update_state_t;
12
13 static void fw_upload_manager_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
14 static void fw_update_btn_clicked_event_cb(lv_event_t * e);
15 static void fw_update_close_event_cb(lv_event_t * e);
16 static void fw_update_win_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
17
18 static lv_subject_t fw_download_percent_subject;
19 static lv_subject_t fw_update_status_subject;
20
21 /**
22 * Show how to handle a complete firmware update process with observers.
23 * Normally it's hard to implement a firmware update process because in some cases
24 * - the App needs to was for the UI (wait for a button press)
25 * - the UI needs to wait for the App (connecting or downloading)
26 * With observers these complex mechanisms can be implemented a simple and clean way.
27 */
lv_example_observer_5(void)28 void lv_example_observer_5(void)
29 {
30 lv_subject_init_int(&fw_download_percent_subject, 0);
31 lv_subject_init_int(&fw_update_status_subject, FW_UPDATE_STATE_IDLE);
32
33 lv_subject_add_observer(&fw_update_status_subject, fw_upload_manager_observer_cb, NULL);
34
35 /*Create start FW update button*/
36 lv_obj_t * btn = lv_button_create(lv_screen_active());
37 lv_obj_add_event_cb(btn, fw_update_btn_clicked_event_cb, LV_EVENT_CLICKED, NULL);
38 lv_obj_center(btn);
39 lv_obj_t * label = lv_label_create(btn);
40 lv_label_set_text(label, "Firmware update");
41 }
42
fw_update_btn_clicked_event_cb(lv_event_t * e)43 static void fw_update_btn_clicked_event_cb(lv_event_t * e)
44 {
45 LV_UNUSED(e);
46 lv_obj_t * win = lv_win_create(lv_screen_active());
47 lv_obj_set_size(win, lv_pct(90), lv_pct(90));
48 lv_obj_set_height(lv_win_get_header(win), 40);
49 lv_obj_set_style_radius(win, 8, 0);
50 lv_obj_set_style_shadow_width(win, 24, 0);
51 lv_obj_set_style_shadow_offset_x(win, 2, 0);
52 lv_obj_set_style_shadow_offset_y(win, 3, 0);
53 lv_obj_set_style_shadow_color(win, lv_color_hex3(0x888), 0);
54 lv_win_add_title(win, "Firmware update");
55 lv_obj_t * btn = lv_win_add_button(win, LV_SYMBOL_CLOSE, 40);
56 lv_obj_add_event_cb(btn, fw_update_close_event_cb, LV_EVENT_CLICKED, NULL);
57 lv_obj_center(win);
58
59 lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_IDLE);
60 lv_subject_add_observer_obj(&fw_update_status_subject, fw_update_win_observer_cb, win, NULL);
61 }
62
fw_update_close_event_cb(lv_event_t * e)63 static void fw_update_close_event_cb(lv_event_t * e)
64 {
65 LV_UNUSED(e);
66 lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_CANCEL);
67 }
68
restart_btn_click_event_cb(lv_event_t * e)69 static void restart_btn_click_event_cb(lv_event_t * e)
70 {
71 lv_obj_t * win = lv_event_get_user_data(e);
72 lv_obj_delete(win);
73 lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_IDLE);
74 }
75
fw_update_win_observer_cb(lv_observer_t * observer,lv_subject_t * subject)76 static void fw_update_win_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
77 {
78 lv_obj_t * win = lv_observer_get_target(observer);
79 lv_obj_t * cont = lv_win_get_content(win);
80 fw_update_state_t status = lv_subject_get_int(&fw_update_status_subject);
81 if(status == FW_UPDATE_STATE_IDLE) {
82 lv_obj_clean(cont);
83 lv_obj_t * spinner = lv_spinner_create(cont);
84 lv_obj_center(spinner);
85 lv_obj_set_size(spinner, 130, 130);
86
87 lv_obj_t * label = lv_label_create(cont);
88 lv_label_set_text(label, "Connecting");
89 lv_obj_center(label);
90
91 lv_subject_set_int(subject, FW_UPDATE_STATE_CONNECTING);
92 }
93 else if(status == FW_UPDATE_STATE_DOWNLOADING) {
94 lv_obj_clean(cont);
95 lv_obj_t * arc = lv_arc_create(cont);
96 lv_arc_bind_value(arc, &fw_download_percent_subject);
97 lv_obj_center(arc);
98 lv_obj_set_size(arc, 130, 130);
99 lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE);
100
101 lv_obj_t * label = lv_label_create(cont);
102 lv_label_bind_text(label, &fw_download_percent_subject, "%d %%");
103 lv_obj_center(label);
104 }
105 else if(status == FW_UPDATE_STATE_READY) {
106 lv_obj_clean(cont);
107 lv_obj_t * label = lv_label_create(cont);
108 lv_label_set_text(label, "Firmware update is ready");
109 lv_obj_align(label, LV_ALIGN_CENTER, 0, -20);
110
111 lv_obj_t * btn = lv_button_create(cont);
112 lv_obj_align(btn, LV_ALIGN_CENTER, 0, 20);
113 lv_obj_add_event_cb(btn, restart_btn_click_event_cb, LV_EVENT_CLICKED, win);
114
115 label = lv_label_create(btn);
116 lv_label_set_text(label, "Restart");
117 }
118 else if(status == FW_UPDATE_STATE_CANCEL) {
119 lv_obj_delete(win);
120 }
121 }
122
connect_timer_cb(lv_timer_t * t)123 static void connect_timer_cb(lv_timer_t * t)
124 {
125 if(lv_subject_get_int(&fw_update_status_subject) != FW_UPDATE_STATE_CANCEL) {
126 lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_CONNECTED);
127 }
128 lv_timer_delete(t);
129 }
130
download_timer_cb(lv_timer_t * t)131 static void download_timer_cb(lv_timer_t * t)
132 {
133 if(lv_subject_get_int(&fw_update_status_subject) == FW_UPDATE_STATE_CANCEL) {
134 lv_timer_delete(t);
135 return;
136 }
137
138 int32_t v = lv_subject_get_int(&fw_download_percent_subject);
139 if(v < 100) {
140 lv_subject_set_int(&fw_download_percent_subject, v + 1);
141 }
142 else {
143 lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_READY);
144 lv_timer_delete(t);
145 }
146 }
147
148 /**
149 * Emulate connection and FW downloading by timers
150 */
fw_upload_manager_observer_cb(lv_observer_t * observer,lv_subject_t * subject)151 static void fw_upload_manager_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
152 {
153 LV_UNUSED(subject);
154 LV_UNUSED(observer);
155
156 fw_update_state_t state = lv_subject_get_int(&fw_update_status_subject);
157 if(state == FW_UPDATE_STATE_CONNECTING) {
158 lv_timer_create(connect_timer_cb, 2000, NULL);
159 }
160 else if(state == FW_UPDATE_STATE_CONNECTED) {
161 lv_subject_set_int(&fw_download_percent_subject, 0);
162 lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_DOWNLOADING);
163 lv_timer_create(download_timer_cb, 50, NULL);
164 }
165 }
166
167 #endif
168