26
26
// Include the header where settings_custom_event_callback is declared
27
27
#include "settings_ui.h"
28
28
29
+ #define UART_INIT_STACK_SIZE 2048
30
+
31
+ static int32_t init_uart_task (void * context ) {
32
+ AppState * state = context ;
33
+
34
+ // Add some delay to let system stabilize
35
+ furi_delay_ms (50 );
36
+
37
+ state -> uart_context = uart_init (state );
38
+ if (state -> uart_context ) {
39
+ FURI_LOG_I ("Ghost_ESP" , "UART initialized successfully" );
40
+ } else {
41
+ FURI_LOG_E ("Ghost_ESP" , "UART initialization failed" );
42
+ }
43
+ return 0 ;
44
+ }
45
+
46
+
29
47
int32_t ghost_esp_app (void * p ) {
30
48
UNUSED (p );
31
49
32
- uint8_t attempts = 0 ;
50
+ // Quick power check and initialization
33
51
bool otg_was_enabled = furi_hal_power_is_otg_enabled ();
34
- while (!furi_hal_power_is_otg_enabled () && attempts ++ < 5 ) {
35
- furi_hal_power_enable_otg ();
36
- furi_delay_ms (10 );
52
+ if (!otg_was_enabled ) {
53
+ uint8_t attempts = 0 ;
54
+ while (!furi_hal_power_is_otg_enabled () && attempts ++ < 3 ) {
55
+ furi_hal_power_enable_otg ();
56
+ furi_delay_ms (10 );
57
+ }
58
+ furi_delay_ms (50 );
37
59
}
38
- furi_delay_ms (200 );
39
60
40
- // Set up UI
61
+ // Set up bare minimum UI state
41
62
AppState * state = malloc (sizeof (AppState ));
42
63
if (!state ) return -1 ;
43
64
memset (state , 0 , sizeof (AppState )); // Zero all memory first
44
65
45
- // Initialize text buffers
66
+ // Initialize essential text buffers with minimal size
46
67
state -> textBoxBuffer = malloc (1 );
47
68
if (state -> textBoxBuffer ) {
48
69
state -> textBoxBuffer [0 ] = '\0' ;
@@ -53,50 +74,75 @@ int32_t ghost_esp_app(void* p) {
53
74
memset (state -> input_buffer , 0 , 32 );
54
75
}
55
76
56
- // Initialize UI components
77
+ // Initialize UI components - core components first
57
78
state -> view_dispatcher = view_dispatcher_alloc ();
58
79
state -> main_menu = main_menu_alloc ();
80
+ if (!state -> view_dispatcher || !state -> main_menu ) {
81
+ // Clean up and exit if core components fail
82
+ if (state -> view_dispatcher ) view_dispatcher_free (state -> view_dispatcher );
83
+ if (state -> main_menu ) main_menu_free (state -> main_menu );
84
+ free (state -> textBoxBuffer );
85
+ free (state -> input_buffer );
86
+ free (state );
87
+ return -1 ;
88
+ }
89
+
90
+ // Allocate remaining UI components
59
91
state -> wifi_menu = submenu_alloc ();
60
92
state -> ble_menu = submenu_alloc ();
61
93
state -> gps_menu = submenu_alloc ();
62
94
state -> text_box = text_box_alloc ();
63
95
state -> settings_menu = variable_item_list_alloc ();
64
96
state -> text_input = text_input_alloc ();
65
97
state -> confirmation_view = confirmation_view_alloc ();
98
+ state -> settings_actions_menu = submenu_alloc ();
66
99
67
- // Set headers after allocation
100
+ // Set headers - only for successfully allocated components
68
101
if (state -> main_menu ) main_menu_set_header (state -> main_menu , "Select a Utility" );
69
102
if (state -> wifi_menu ) submenu_set_header (state -> wifi_menu , "Select a Wifi Utility" );
70
103
if (state -> ble_menu ) submenu_set_header (state -> ble_menu , "Select a Bluetooth Utility" );
71
104
if (state -> gps_menu ) submenu_set_header (state -> gps_menu , "Select a GPS Utility" );
72
105
if (state -> text_input ) text_input_set_header_text (state -> text_input , "Enter Your Text" );
106
+ if (state -> settings_actions_menu ) submenu_set_header (state -> settings_actions_menu , "Settings" );
73
107
74
- // Initialize storage and load settings before UART
108
+ // Initialize settings and configuration early
75
109
settings_storage_init ();
76
110
if (settings_storage_load (& state -> settings , GHOST_ESP_APP_SETTINGS_FILE ) != SETTINGS_OK ) {
77
111
memset (& state -> settings , 0 , sizeof (Settings ));
78
112
state -> settings .stop_on_back_index = 1 ;
79
113
settings_storage_save (& state -> settings , GHOST_ESP_APP_SETTINGS_FILE );
80
114
}
81
115
116
+ // Initialize filter config
117
+ state -> filter_config = malloc (sizeof (FilterConfig ));
118
+ if (state -> filter_config ) {
119
+ state -> filter_config -> enabled = state -> settings .enable_filtering_index ;
120
+ state -> filter_config -> show_ble_status = true;
121
+ state -> filter_config -> show_wifi_status = true;
122
+ state -> filter_config -> show_flipper_devices = true;
123
+ state -> filter_config -> show_wifi_networks = true;
124
+ state -> filter_config -> strip_ansi_codes = true;
125
+ state -> filter_config -> add_prefixes = true;
126
+ }
127
+
82
128
// Set up settings UI context
83
129
state -> settings_ui_context .settings = & state -> settings ;
84
130
state -> settings_ui_context .send_uart_command = send_uart_command ;
85
131
state -> settings_ui_context .switch_to_view = NULL ;
86
132
state -> settings_ui_context .show_confirmation_view = show_confirmation_view_wrapper ;
87
133
state -> settings_ui_context .context = state ;
88
- state -> settings_actions_menu = submenu_alloc ();
89
- if (state -> settings_actions_menu ) {
90
- submenu_set_header (state -> settings_actions_menu , "Settings Actions" );
91
- }
92
134
93
135
// Initialize settings menu
94
136
settings_setup_gui (state -> settings_menu , & state -> settings_ui_context );
95
137
96
- // Initialize UART after settings are ready
97
- state -> uart_context = uart_init (state );
138
+ // Start UART init in background thread
139
+ FuriThread * uart_init_thread = furi_thread_alloc_ex (
140
+ "UartInit" ,
141
+ UART_INIT_STACK_SIZE , // Increased stack size
142
+ init_uart_task ,
143
+ state );
98
144
99
- // Add views if view_dispatcher exists
145
+ // Add views to dispatcher - check each component before adding
100
146
if (state -> view_dispatcher ) {
101
147
if (state -> main_menu ) view_dispatcher_add_view (state -> view_dispatcher , 0 , main_menu_get_view (state -> main_menu ));
102
148
if (state -> wifi_menu ) view_dispatcher_add_view (state -> view_dispatcher , 1 , submenu_get_view (state -> wifi_menu ));
@@ -108,14 +154,16 @@ int32_t ghost_esp_app(void* p) {
108
154
if (state -> confirmation_view ) view_dispatcher_add_view (state -> view_dispatcher , 7 , confirmation_view_get_view (state -> confirmation_view ));
109
155
if (state -> settings_actions_menu ) view_dispatcher_add_view (state -> view_dispatcher , 8 , submenu_get_view (state -> settings_actions_menu ));
110
156
111
- view_dispatcher_set_custom_event_callback (state -> view_dispatcher , settings_custom_event_callback );
112
-
157
+ view_dispatcher_set_custom_event_callback (state -> view_dispatcher , settings_custom_event_callback );
113
158
}
114
159
115
- // Show main menu
160
+ // Show main menu immediately
116
161
show_main_menu (state );
117
162
118
- // Set up GUI
163
+ // Initialize UART in background
164
+ state -> uart_context = uart_init (state );
165
+
166
+ // Set up and run GUI
119
167
Gui * gui = furi_record_open ("gui" );
120
168
if (gui && state -> view_dispatcher ) {
121
169
view_dispatcher_attach_to_gui (state -> view_dispatcher , gui , ViewDispatcherTypeFullscreen );
@@ -125,13 +173,18 @@ int32_t ghost_esp_app(void* p) {
125
173
}
126
174
furi_record_close ("gui" );
127
175
176
+ // Wait for UART initialization to complete
177
+ furi_thread_join (uart_init_thread );
178
+ furi_thread_free (uart_init_thread );
179
+
128
180
// Start cleanup - first remove views
129
181
if (state -> view_dispatcher ) {
130
182
for (size_t i = 0 ; i <= 8 ; i ++ ) {
131
183
view_dispatcher_remove_view (state -> view_dispatcher , i );
132
184
}
133
185
}
134
186
187
+
135
188
// Clear callbacks before cleanup
136
189
if (state -> confirmation_view ) {
137
190
confirmation_view_set_ok_callback (state -> confirmation_view , NULL , NULL );
@@ -197,7 +250,11 @@ int32_t ghost_esp_app(void* p) {
197
250
free (state -> textBoxBuffer );
198
251
state -> textBoxBuffer = NULL ;
199
252
}
200
-
253
+ // Add filter config cleanup
254
+ if (state -> filter_config ) {
255
+ free (state -> filter_config );
256
+ state -> filter_config = NULL ;
257
+ }
201
258
// Final state cleanup
202
259
free (state );
203
260
0 commit comments