[FL-3097] fbt, faploader: minimal app module implementation (#2420)
* fbt, faploader: minimal app module implementation * faploader, libs: moved API hashtable core to flipper_application * example: compound api * lib: flipper_application: naming fixes, doxygen comments * fbt: changed `requires` manifest field behavior for app extensions * examples: refactored plugin apps; faploader: changed new API naming; fbt: changed PLUGIN app type meaning * loader: dropped support for debug apps & plugin menus * moved applications/plugins -> applications/external * Restored x bit on chiplist_convert.py * git: fixed free-dap submodule path * pvs: updated submodule paths * examples: example_advanced_plugins.c: removed potential memory leak on errors * examples: example_plugins: refined requires * fbt: not deploying app modules for debug/sample apps; extra validation for .PLUGIN-type apps * apps: removed cdefines for external apps * fbt: moved ext app path definition * fbt: reworked fap_dist handling; f18: synced api_symbols.csv * fbt: removed resources_paths for extapps * scripts: reworked storage * scripts: reworked runfap.py & selfupdate.py to use new api * wip: fal runner * fbt: moved file packaging into separate module * scripts: storage: fixes * scripts: storage: minor fixes for new api * fbt: changed internal artifact storage details for external apps * scripts: storage: additional fixes and better error reporting; examples: using APP_DATA_PATH() * fbt, scripts: reworked launch_app to deploy plugins; moved old runfap.py to distfap.py * fbt: extra check for plugins descriptors * fbt: additional checks in emitter * fbt: better info message on SDK rebuild * scripts: removed requirements.txt * loader: removed remnants of plugins & debug menus * post-review fixes
This commit is contained in:
		
							
								
								
									
										92
									
								
								applications/external/dap_link/gui/dap_gui.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								applications/external/dap_link/gui/dap_gui.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| #include "dap_gui.h" | ||||
| #include "dap_gui_i.h" | ||||
|  | ||||
| #define DAP_GUI_TICK 250 | ||||
|  | ||||
| static bool dap_gui_custom_event_callback(void* context, uint32_t event) { | ||||
|     furi_assert(context); | ||||
|     DapGuiApp* app = context; | ||||
|     return scene_manager_handle_custom_event(app->scene_manager, event); | ||||
| } | ||||
|  | ||||
| static bool dap_gui_back_event_callback(void* context) { | ||||
|     furi_assert(context); | ||||
|     DapGuiApp* app = context; | ||||
|     return scene_manager_handle_back_event(app->scene_manager); | ||||
| } | ||||
|  | ||||
| static void dap_gui_tick_event_callback(void* context) { | ||||
|     furi_assert(context); | ||||
|     DapGuiApp* app = context; | ||||
|     scene_manager_handle_tick_event(app->scene_manager); | ||||
| } | ||||
|  | ||||
| DapGuiApp* dap_gui_alloc() { | ||||
|     DapGuiApp* app = malloc(sizeof(DapGuiApp)); | ||||
|     app->gui = furi_record_open(RECORD_GUI); | ||||
|     app->view_dispatcher = view_dispatcher_alloc(); | ||||
|     app->scene_manager = scene_manager_alloc(&dap_scene_handlers, app); | ||||
|     view_dispatcher_enable_queue(app->view_dispatcher); | ||||
|     view_dispatcher_set_event_callback_context(app->view_dispatcher, app); | ||||
|  | ||||
|     view_dispatcher_set_custom_event_callback(app->view_dispatcher, dap_gui_custom_event_callback); | ||||
|     view_dispatcher_set_navigation_event_callback( | ||||
|         app->view_dispatcher, dap_gui_back_event_callback); | ||||
|     view_dispatcher_set_tick_event_callback( | ||||
|         app->view_dispatcher, dap_gui_tick_event_callback, DAP_GUI_TICK); | ||||
|  | ||||
|     view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); | ||||
|  | ||||
|     app->notifications = furi_record_open(RECORD_NOTIFICATION); | ||||
|  | ||||
|     app->var_item_list = variable_item_list_alloc(); | ||||
|     view_dispatcher_add_view( | ||||
|         app->view_dispatcher, | ||||
|         DapGuiAppViewVarItemList, | ||||
|         variable_item_list_get_view(app->var_item_list)); | ||||
|  | ||||
|     app->main_view = dap_main_view_alloc(); | ||||
|     view_dispatcher_add_view( | ||||
|         app->view_dispatcher, DapGuiAppViewMainView, dap_main_view_get_view(app->main_view)); | ||||
|  | ||||
|     app->widget = widget_alloc(); | ||||
|     view_dispatcher_add_view( | ||||
|         app->view_dispatcher, DapGuiAppViewWidget, widget_get_view(app->widget)); | ||||
|  | ||||
|     scene_manager_next_scene(app->scene_manager, DapSceneMain); | ||||
|  | ||||
|     return app; | ||||
| } | ||||
|  | ||||
| void dap_gui_free(DapGuiApp* app) { | ||||
|     view_dispatcher_remove_view(app->view_dispatcher, DapGuiAppViewVarItemList); | ||||
|     variable_item_list_free(app->var_item_list); | ||||
|  | ||||
|     view_dispatcher_remove_view(app->view_dispatcher, DapGuiAppViewMainView); | ||||
|     dap_main_view_free(app->main_view); | ||||
|  | ||||
|     view_dispatcher_remove_view(app->view_dispatcher, DapGuiAppViewWidget); | ||||
|     widget_free(app->widget); | ||||
|  | ||||
|     // View dispatcher | ||||
|     view_dispatcher_free(app->view_dispatcher); | ||||
|     scene_manager_free(app->scene_manager); | ||||
|  | ||||
|     // Close records | ||||
|     furi_record_close(RECORD_GUI); | ||||
|     furi_record_close(RECORD_NOTIFICATION); | ||||
|  | ||||
|     free(app); | ||||
| } | ||||
|  | ||||
| int32_t dap_gui_thread(void* arg) { | ||||
|     DapGuiApp* app = dap_gui_alloc(); | ||||
|     app->dap_app = arg; | ||||
|  | ||||
|     notification_message_block(app->notifications, &sequence_display_backlight_enforce_on); | ||||
|     view_dispatcher_run(app->view_dispatcher); | ||||
|     notification_message_block(app->notifications, &sequence_display_backlight_enforce_auto); | ||||
|  | ||||
|     dap_gui_free(app); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										4
									
								
								applications/external/dap_link/gui/dap_gui.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								applications/external/dap_link/gui/dap_gui.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| #pragma once | ||||
| #include <stdint.h> | ||||
|  | ||||
| int32_t dap_gui_thread(void* arg); | ||||
							
								
								
									
										7
									
								
								applications/external/dap_link/gui/dap_gui_custom_event.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/external/dap_link/gui/dap_gui_custom_event.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| typedef enum { | ||||
|     DapAppCustomEventConfig, | ||||
|     DapAppCustomEventHelp, | ||||
|     DapAppCustomEventAbout, | ||||
| } DapAppCustomEvent; | ||||
							
								
								
									
										34
									
								
								applications/external/dap_link/gui/dap_gui_i.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								applications/external/dap_link/gui/dap_gui_i.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <gui/gui.h> | ||||
| #include <gui/view_dispatcher.h> | ||||
| #include <gui/scene_manager.h> | ||||
| #include <gui/modules/submenu.h> | ||||
| #include <notification/notification_messages.h> | ||||
| #include <gui/modules/variable_item_list.h> | ||||
| #include <gui/modules/widget.h> | ||||
|  | ||||
| #include "dap_gui.h" | ||||
| #include "../dap_link.h" | ||||
| #include "scenes/config/dap_scene.h" | ||||
| #include "dap_gui_custom_event.h" | ||||
| #include "views/dap_main_view.h" | ||||
|  | ||||
| typedef struct { | ||||
|     DapApp* dap_app; | ||||
|  | ||||
|     Gui* gui; | ||||
|     NotificationApp* notifications; | ||||
|     ViewDispatcher* view_dispatcher; | ||||
|     SceneManager* scene_manager; | ||||
|  | ||||
|     VariableItemList* var_item_list; | ||||
|     DapMainView* main_view; | ||||
|     Widget* widget; | ||||
| } DapGuiApp; | ||||
|  | ||||
| typedef enum { | ||||
|     DapGuiAppViewVarItemList, | ||||
|     DapGuiAppViewMainView, | ||||
|     DapGuiAppViewWidget, | ||||
| } DapGuiAppView; | ||||
							
								
								
									
										30
									
								
								applications/external/dap_link/gui/scenes/config/dap_scene.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								applications/external/dap_link/gui/scenes/config/dap_scene.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| #include "dap_scene.h" | ||||
|  | ||||
| // Generate scene on_enter handlers array | ||||
| #define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, | ||||
| void (*const dap_scene_on_enter_handlers[])(void*) = { | ||||
| #include "dap_scene_config.h" | ||||
| }; | ||||
| #undef ADD_SCENE | ||||
|  | ||||
| // Generate scene on_event handlers array | ||||
| #define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, | ||||
| bool (*const dap_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { | ||||
| #include "dap_scene_config.h" | ||||
| }; | ||||
| #undef ADD_SCENE | ||||
|  | ||||
| // Generate scene on_exit handlers array | ||||
| #define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, | ||||
| void (*const dap_scene_on_exit_handlers[])(void* context) = { | ||||
| #include "dap_scene_config.h" | ||||
| }; | ||||
| #undef ADD_SCENE | ||||
|  | ||||
| // Initialize scene handlers configuration structure | ||||
| const SceneManagerHandlers dap_scene_handlers = { | ||||
|     .on_enter_handlers = dap_scene_on_enter_handlers, | ||||
|     .on_event_handlers = dap_scene_on_event_handlers, | ||||
|     .on_exit_handlers = dap_scene_on_exit_handlers, | ||||
|     .scene_num = DapSceneNum, | ||||
| }; | ||||
							
								
								
									
										29
									
								
								applications/external/dap_link/gui/scenes/config/dap_scene.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								applications/external/dap_link/gui/scenes/config/dap_scene.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <gui/scene_manager.h> | ||||
|  | ||||
| // Generate scene id and total number | ||||
| #define ADD_SCENE(prefix, name, id) DapScene##id, | ||||
| typedef enum { | ||||
| #include "dap_scene_config.h" | ||||
|     DapSceneNum, | ||||
| } DapScene; | ||||
| #undef ADD_SCENE | ||||
|  | ||||
| extern const SceneManagerHandlers dap_scene_handlers; | ||||
|  | ||||
| // Generate scene on_enter handlers declaration | ||||
| #define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); | ||||
| #include "dap_scene_config.h" | ||||
| #undef ADD_SCENE | ||||
|  | ||||
| // Generate scene on_event handlers declaration | ||||
| #define ADD_SCENE(prefix, name, id) \ | ||||
|     bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); | ||||
| #include "dap_scene_config.h" | ||||
| #undef ADD_SCENE | ||||
|  | ||||
| // Generate scene on_exit handlers declaration | ||||
| #define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); | ||||
| #include "dap_scene_config.h" | ||||
| #undef ADD_SCENE | ||||
							
								
								
									
										4
									
								
								applications/external/dap_link/gui/scenes/config/dap_scene_config.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								applications/external/dap_link/gui/scenes/config/dap_scene_config.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| ADD_SCENE(dap, main, Main) | ||||
| ADD_SCENE(dap, config, Config) | ||||
| ADD_SCENE(dap, help, Help) | ||||
| ADD_SCENE(dap, about, About) | ||||
							
								
								
									
										68
									
								
								applications/external/dap_link/gui/scenes/dap_scene_about.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								applications/external/dap_link/gui/scenes/dap_scene_about.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| #include "../dap_gui_i.h" | ||||
|  | ||||
| #define DAP_VERSION_APP "0.1.0" | ||||
| #define DAP_DEVELOPED "Dr_Zlo" | ||||
| #define DAP_GITHUB "https://github.com/flipperdevices/flipperzero-firmware" | ||||
|  | ||||
| void dap_scene_about_on_enter(void* context) { | ||||
|     DapGuiApp* app = context; | ||||
|  | ||||
|     FuriString* temp_str; | ||||
|     temp_str = furi_string_alloc(); | ||||
|     furi_string_printf(temp_str, "\e#%s\n", "Information"); | ||||
|  | ||||
|     furi_string_cat_printf(temp_str, "Version: %s\n", DAP_VERSION_APP); | ||||
|     furi_string_cat_printf(temp_str, "Developed by: %s\n", DAP_DEVELOPED); | ||||
|     furi_string_cat_printf(temp_str, "Github: %s\n\n", DAP_GITHUB); | ||||
|  | ||||
|     furi_string_cat_printf(temp_str, "\e#%s\n", "Description"); | ||||
|     furi_string_cat_printf( | ||||
|         temp_str, "CMSIS-DAP debugger\nbased on Free-DAP\nThanks to Alex Taradov\n\n"); | ||||
|  | ||||
|     furi_string_cat_printf( | ||||
|         temp_str, | ||||
|         "Supported protocols:\n" | ||||
|         "SWD, JTAG, UART\n" | ||||
|         "DAP v1 (cmsis_backend hid), DAP v2 (cmsis_backend usb_bulk), VCP\n"); | ||||
|  | ||||
|     widget_add_text_box_element( | ||||
|         app->widget, | ||||
|         0, | ||||
|         0, | ||||
|         128, | ||||
|         14, | ||||
|         AlignCenter, | ||||
|         AlignBottom, | ||||
|         "\e#\e!                                                      \e!\n", | ||||
|         false); | ||||
|     widget_add_text_box_element( | ||||
|         app->widget, | ||||
|         0, | ||||
|         2, | ||||
|         128, | ||||
|         14, | ||||
|         AlignCenter, | ||||
|         AlignBottom, | ||||
|         "\e#\e!              DAP Link              \e!\n", | ||||
|         false); | ||||
|     widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str)); | ||||
|     furi_string_free(temp_str); | ||||
|  | ||||
|     view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewWidget); | ||||
| } | ||||
|  | ||||
| bool dap_scene_about_on_event(void* context, SceneManagerEvent event) { | ||||
|     DapGuiApp* app = context; | ||||
|     bool consumed = false; | ||||
|     UNUSED(app); | ||||
|     UNUSED(event); | ||||
|  | ||||
|     return consumed; | ||||
| } | ||||
|  | ||||
| void dap_scene_about_on_exit(void* context) { | ||||
|     DapGuiApp* app = context; | ||||
|  | ||||
|     // Clear views | ||||
|     widget_reset(app->widget); | ||||
| } | ||||
							
								
								
									
										107
									
								
								applications/external/dap_link/gui/scenes/dap_scene_config.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								applications/external/dap_link/gui/scenes/dap_scene_config.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| #include "../dap_gui_i.h" | ||||
|  | ||||
| static const char* swd_pins[] = {[DapSwdPinsPA7PA6] = "2,3", [DapSwdPinsPA14PA13] = "10,12"}; | ||||
| static const char* uart_pins[] = {[DapUartTypeUSART1] = "13,14", [DapUartTypeLPUART1] = "15,16"}; | ||||
| static const char* uart_swap[] = {[DapUartTXRXNormal] = "No", [DapUartTXRXSwap] = "Yes"}; | ||||
|  | ||||
| static void swd_pins_cb(VariableItem* item) { | ||||
|     DapGuiApp* app = variable_item_get_context(item); | ||||
|     uint8_t index = variable_item_get_current_value_index(item); | ||||
|  | ||||
|     variable_item_set_current_value_text(item, swd_pins[index]); | ||||
|  | ||||
|     DapConfig* config = dap_app_get_config(app->dap_app); | ||||
|     config->swd_pins = index; | ||||
|     dap_app_set_config(app->dap_app, config); | ||||
| } | ||||
|  | ||||
| static void uart_pins_cb(VariableItem* item) { | ||||
|     DapGuiApp* app = variable_item_get_context(item); | ||||
|     uint8_t index = variable_item_get_current_value_index(item); | ||||
|  | ||||
|     variable_item_set_current_value_text(item, uart_pins[index]); | ||||
|  | ||||
|     DapConfig* config = dap_app_get_config(app->dap_app); | ||||
|     config->uart_pins = index; | ||||
|     dap_app_set_config(app->dap_app, config); | ||||
| } | ||||
|  | ||||
| static void uart_swap_cb(VariableItem* item) { | ||||
|     DapGuiApp* app = variable_item_get_context(item); | ||||
|     uint8_t index = variable_item_get_current_value_index(item); | ||||
|  | ||||
|     variable_item_set_current_value_text(item, uart_swap[index]); | ||||
|  | ||||
|     DapConfig* config = dap_app_get_config(app->dap_app); | ||||
|     config->uart_swap = index; | ||||
|     dap_app_set_config(app->dap_app, config); | ||||
| } | ||||
|  | ||||
| static void ok_cb(void* context, uint32_t index) { | ||||
|     DapGuiApp* app = context; | ||||
|     switch(index) { | ||||
|     case 3: | ||||
|         view_dispatcher_send_custom_event(app->view_dispatcher, DapAppCustomEventHelp); | ||||
|         break; | ||||
|     case 4: | ||||
|         view_dispatcher_send_custom_event(app->view_dispatcher, DapAppCustomEventAbout); | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void dap_scene_config_on_enter(void* context) { | ||||
|     DapGuiApp* app = context; | ||||
|     VariableItemList* var_item_list = app->var_item_list; | ||||
|     VariableItem* item; | ||||
|     DapConfig* config = dap_app_get_config(app->dap_app); | ||||
|  | ||||
|     item = variable_item_list_add( | ||||
|         var_item_list, "SWC SWD Pins", COUNT_OF(swd_pins), swd_pins_cb, app); | ||||
|     variable_item_set_current_value_index(item, config->swd_pins); | ||||
|     variable_item_set_current_value_text(item, swd_pins[config->swd_pins]); | ||||
|  | ||||
|     item = | ||||
|         variable_item_list_add(var_item_list, "UART Pins", COUNT_OF(uart_pins), uart_pins_cb, app); | ||||
|     variable_item_set_current_value_index(item, config->uart_pins); | ||||
|     variable_item_set_current_value_text(item, uart_pins[config->uart_pins]); | ||||
|  | ||||
|     item = variable_item_list_add( | ||||
|         var_item_list, "Swap TX RX", COUNT_OF(uart_swap), uart_swap_cb, app); | ||||
|     variable_item_set_current_value_index(item, config->uart_swap); | ||||
|     variable_item_set_current_value_text(item, uart_swap[config->uart_swap]); | ||||
|  | ||||
|     variable_item_list_add(var_item_list, "Help and Pinout", 0, NULL, NULL); | ||||
|     variable_item_list_add(var_item_list, "About", 0, NULL, NULL); | ||||
|  | ||||
|     variable_item_list_set_selected_item( | ||||
|         var_item_list, scene_manager_get_scene_state(app->scene_manager, DapSceneConfig)); | ||||
|  | ||||
|     variable_item_list_set_enter_callback(var_item_list, ok_cb, app); | ||||
|  | ||||
|     view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewVarItemList); | ||||
| } | ||||
|  | ||||
| bool dap_scene_config_on_event(void* context, SceneManagerEvent event) { | ||||
|     DapGuiApp* app = context; | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         if(event.event == DapAppCustomEventHelp) { | ||||
|             scene_manager_next_scene(app->scene_manager, DapSceneHelp); | ||||
|             return true; | ||||
|         } else if(event.event == DapAppCustomEventAbout) { | ||||
|             scene_manager_next_scene(app->scene_manager, DapSceneAbout); | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| void dap_scene_config_on_exit(void* context) { | ||||
|     DapGuiApp* app = context; | ||||
|     scene_manager_set_scene_state( | ||||
|         app->scene_manager, | ||||
|         DapSceneConfig, | ||||
|         variable_item_list_get_selected_item_index(app->var_item_list)); | ||||
|     variable_item_list_reset(app->var_item_list); | ||||
| } | ||||
							
								
								
									
										102
									
								
								applications/external/dap_link/gui/scenes/dap_scene_help.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								applications/external/dap_link/gui/scenes/dap_scene_help.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| #include "../dap_gui_i.h" | ||||
|  | ||||
| void dap_scene_help_on_enter(void* context) { | ||||
|     DapGuiApp* app = context; | ||||
|     DapConfig* config = dap_app_get_config(app->dap_app); | ||||
|     FuriString* string = furi_string_alloc(); | ||||
|  | ||||
|     furi_string_cat(string, "CMSIS DAP/DAP Link v2\r\n"); | ||||
|     furi_string_cat_printf(string, "Serial: %s\r\n", dap_app_get_serial(app->dap_app)); | ||||
|     furi_string_cat( | ||||
|         string, | ||||
|         "Pinout:\r\n" | ||||
|         "\e#SWD:\r\n"); | ||||
|  | ||||
|     switch(config->swd_pins) { | ||||
|     case DapSwdPinsPA7PA6: | ||||
|         furi_string_cat( | ||||
|             string, | ||||
|             "    SWC: 2 [A7]\r\n" | ||||
|             "    SWD: 3 [A6]\r\n"); | ||||
|         break; | ||||
|     case DapSwdPinsPA14PA13: | ||||
|         furi_string_cat( | ||||
|             string, | ||||
|             "    SWC: 10 [SWC]\r\n" | ||||
|             "    SWD: 12 [SIO]\r\n"); | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     furi_string_cat(string, "\e#JTAG:\r\n"); | ||||
|     switch(config->swd_pins) { | ||||
|     case DapSwdPinsPA7PA6: | ||||
|         furi_string_cat( | ||||
|             string, | ||||
|             "    TCK: 2 [A7]\r\n" | ||||
|             "    TMS: 3 [A6]\r\n" | ||||
|             "    RST: 4 [A4]\r\n" | ||||
|             "    TDO: 5 [B3]\r\n" | ||||
|             "    TDI: 6 [B2]\r\n"); | ||||
|         break; | ||||
|     case DapSwdPinsPA14PA13: | ||||
|         furi_string_cat( | ||||
|             string, | ||||
|             "    RST: 4 [A4]\r\n" | ||||
|             "    TDO: 5 [B3]\r\n" | ||||
|             "    TDI: 6 [B2]\r\n" | ||||
|             "    TCK: 10 [SWC]\r\n" | ||||
|             "    TMS: 12 [SIO]\r\n"); | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     furi_string_cat(string, "\e#UART:\r\n"); | ||||
|     switch(config->uart_pins) { | ||||
|     case DapUartTypeUSART1: | ||||
|         if(config->uart_swap == DapUartTXRXNormal) { | ||||
|             furi_string_cat( | ||||
|                 string, | ||||
|                 "    TX: 13 [TX]\r\n" | ||||
|                 "    RX: 14 [RX]\r\n"); | ||||
|         } else { | ||||
|             furi_string_cat( | ||||
|                 string, | ||||
|                 "    RX: 13 [TX]\r\n" | ||||
|                 "    TX: 14 [RX]\r\n"); | ||||
|         } | ||||
|         break; | ||||
|     case DapUartTypeLPUART1: | ||||
|         if(config->uart_swap == DapUartTXRXNormal) { | ||||
|             furi_string_cat( | ||||
|                 string, | ||||
|                 "    TX: 15 [C1]\r\n" | ||||
|                 "    RX: 16 [C0]\r\n"); | ||||
|         } else { | ||||
|             furi_string_cat( | ||||
|                 string, | ||||
|                 "    RX: 15 [C1]\r\n" | ||||
|                 "    TX: 16 [C0]\r\n"); | ||||
|         } | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     widget_add_text_scroll_element(app->widget, 0, 0, 128, 64, furi_string_get_cstr(string)); | ||||
|     furi_string_free(string); | ||||
|     view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewWidget); | ||||
| } | ||||
|  | ||||
| bool dap_scene_help_on_event(void* context, SceneManagerEvent event) { | ||||
|     UNUSED(context); | ||||
|     UNUSED(event); | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| void dap_scene_help_on_exit(void* context) { | ||||
|     DapGuiApp* app = context; | ||||
|     widget_reset(app->widget); | ||||
| } | ||||
							
								
								
									
										154
									
								
								applications/external/dap_link/gui/scenes/dap_scene_main.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								applications/external/dap_link/gui/scenes/dap_scene_main.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | ||||
| #include "../dap_gui_i.h" | ||||
| #include "../../dap_link.h" | ||||
|  | ||||
| typedef struct { | ||||
|     DapState dap_state; | ||||
|     bool dap_active; | ||||
|     bool tx_active; | ||||
|     bool rx_active; | ||||
| } DapSceneMainState; | ||||
|  | ||||
| static bool process_dap_state(DapGuiApp* app) { | ||||
|     DapSceneMainState* state = | ||||
|         (DapSceneMainState*)scene_manager_get_scene_state(app->scene_manager, DapSceneMain); | ||||
|     if(state == NULL) return true; | ||||
|  | ||||
|     DapState* prev_state = &state->dap_state; | ||||
|     DapState next_state; | ||||
|     dap_app_get_state(app->dap_app, &next_state); | ||||
|     bool need_to_update = false; | ||||
|  | ||||
|     if(prev_state->dap_mode != next_state.dap_mode) { | ||||
|         switch(next_state.dap_mode) { | ||||
|         case DapModeDisconnected: | ||||
|             dap_main_view_set_mode(app->main_view, DapMainViewModeDisconnected); | ||||
|             notification_message(app->notifications, &sequence_blink_stop); | ||||
|             break; | ||||
|         case DapModeSWD: | ||||
|             dap_main_view_set_mode(app->main_view, DapMainViewModeSWD); | ||||
|             notification_message(app->notifications, &sequence_blink_start_blue); | ||||
|             break; | ||||
|         case DapModeJTAG: | ||||
|             dap_main_view_set_mode(app->main_view, DapMainViewModeJTAG); | ||||
|             notification_message(app->notifications, &sequence_blink_start_magenta); | ||||
|             break; | ||||
|         } | ||||
|         need_to_update = true; | ||||
|     } | ||||
|  | ||||
|     if(prev_state->dap_version != next_state.dap_version) { | ||||
|         switch(next_state.dap_version) { | ||||
|         case DapVersionUnknown: | ||||
|             dap_main_view_set_version(app->main_view, DapMainViewVersionUnknown); | ||||
|             break; | ||||
|         case DapVersionV1: | ||||
|             dap_main_view_set_version(app->main_view, DapMainViewVersionV1); | ||||
|             break; | ||||
|         case DapVersionV2: | ||||
|             dap_main_view_set_version(app->main_view, DapMainViewVersionV2); | ||||
|             break; | ||||
|         } | ||||
|         need_to_update = true; | ||||
|     } | ||||
|  | ||||
|     if(prev_state->usb_connected != next_state.usb_connected) { | ||||
|         dap_main_view_set_usb_connected(app->main_view, next_state.usb_connected); | ||||
|         need_to_update = true; | ||||
|     } | ||||
|  | ||||
|     if(prev_state->dap_counter != next_state.dap_counter) { | ||||
|         if(!state->dap_active) { | ||||
|             state->dap_active = true; | ||||
|             dap_main_view_set_dap(app->main_view, state->dap_active); | ||||
|             need_to_update = true; | ||||
|         } | ||||
|     } else { | ||||
|         if(state->dap_active) { | ||||
|             state->dap_active = false; | ||||
|             dap_main_view_set_dap(app->main_view, state->dap_active); | ||||
|             need_to_update = true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if(prev_state->cdc_baudrate != next_state.cdc_baudrate) { | ||||
|         dap_main_view_set_baudrate(app->main_view, next_state.cdc_baudrate); | ||||
|         need_to_update = true; | ||||
|     } | ||||
|  | ||||
|     if(prev_state->cdc_tx_counter != next_state.cdc_tx_counter) { | ||||
|         if(!state->tx_active) { | ||||
|             state->tx_active = true; | ||||
|             dap_main_view_set_tx(app->main_view, state->tx_active); | ||||
|             need_to_update = true; | ||||
|             notification_message(app->notifications, &sequence_blink_start_red); | ||||
|         } | ||||
|     } else { | ||||
|         if(state->tx_active) { | ||||
|             state->tx_active = false; | ||||
|             dap_main_view_set_tx(app->main_view, state->tx_active); | ||||
|             need_to_update = true; | ||||
|             notification_message(app->notifications, &sequence_blink_stop); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if(prev_state->cdc_rx_counter != next_state.cdc_rx_counter) { | ||||
|         if(!state->rx_active) { | ||||
|             state->rx_active = true; | ||||
|             dap_main_view_set_rx(app->main_view, state->rx_active); | ||||
|             need_to_update = true; | ||||
|             notification_message(app->notifications, &sequence_blink_start_green); | ||||
|         } | ||||
|     } else { | ||||
|         if(state->rx_active) { | ||||
|             state->rx_active = false; | ||||
|             dap_main_view_set_rx(app->main_view, state->rx_active); | ||||
|             need_to_update = true; | ||||
|             notification_message(app->notifications, &sequence_blink_stop); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if(need_to_update) { | ||||
|         dap_main_view_update(app->main_view); | ||||
|     } | ||||
|  | ||||
|     *prev_state = next_state; | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| static void dap_scene_main_on_left(void* context) { | ||||
|     DapGuiApp* app = (DapGuiApp*)context; | ||||
|     view_dispatcher_send_custom_event(app->view_dispatcher, DapAppCustomEventConfig); | ||||
| } | ||||
|  | ||||
| void dap_scene_main_on_enter(void* context) { | ||||
|     DapGuiApp* app = context; | ||||
|     DapSceneMainState* state = malloc(sizeof(DapSceneMainState)); | ||||
|     dap_main_view_set_left_callback(app->main_view, dap_scene_main_on_left, app); | ||||
|     view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewMainView); | ||||
|     scene_manager_set_scene_state(app->scene_manager, DapSceneMain, (uint32_t)state); | ||||
| } | ||||
|  | ||||
| bool dap_scene_main_on_event(void* context, SceneManagerEvent event) { | ||||
|     DapGuiApp* app = context; | ||||
|  | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         if(event.event == DapAppCustomEventConfig) { | ||||
|             scene_manager_next_scene(app->scene_manager, DapSceneConfig); | ||||
|             return true; | ||||
|         } | ||||
|     } else if(event.type == SceneManagerEventTypeTick) { | ||||
|         return process_dap_state(app); | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| void dap_scene_main_on_exit(void* context) { | ||||
|     DapGuiApp* app = context; | ||||
|     DapSceneMainState* state = | ||||
|         (DapSceneMainState*)scene_manager_get_scene_state(app->scene_manager, DapSceneMain); | ||||
|     scene_manager_set_scene_state(app->scene_manager, DapSceneMain, (uint32_t)NULL); | ||||
|     FURI_SW_MEMBARRIER(); | ||||
|     free(state); | ||||
|     notification_message(app->notifications, &sequence_blink_stop); | ||||
| } | ||||
							
								
								
									
										189
									
								
								applications/external/dap_link/gui/views/dap_main_view.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								applications/external/dap_link/gui/views/dap_main_view.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,189 @@ | ||||
| #include "dap_main_view.h" | ||||
| #include "dap_link_icons.h" | ||||
| #include <gui/elements.h> | ||||
|  | ||||
| // extern const Icon I_ArrowDownEmpty_12x18; | ||||
| // extern const Icon I_ArrowDownFilled_12x18; | ||||
| // extern const Icon I_ArrowUpEmpty_12x18; | ||||
| // extern const Icon I_ArrowUpFilled_12x18; | ||||
|  | ||||
| struct DapMainView { | ||||
|     View* view; | ||||
|     DapMainViewButtonCallback cb_left; | ||||
|     void* cb_context; | ||||
| }; | ||||
|  | ||||
| typedef struct { | ||||
|     DapMainViewMode mode; | ||||
|     DapMainViewVersion version; | ||||
|     bool usb_connected; | ||||
|     uint32_t baudrate; | ||||
|     bool dap_active; | ||||
|     bool tx_active; | ||||
|     bool rx_active; | ||||
| } DapMainViewModel; | ||||
|  | ||||
| static void dap_main_view_draw_callback(Canvas* canvas, void* _model) { | ||||
|     DapMainViewModel* model = _model; | ||||
|     UNUSED(model); | ||||
|     canvas_clear(canvas); | ||||
|     elements_button_left(canvas, "Config"); | ||||
|  | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_draw_box(canvas, 0, 0, 127, 11); | ||||
|     canvas_set_color(canvas, ColorWhite); | ||||
|  | ||||
|     const char* header_string; | ||||
|     if(model->usb_connected) { | ||||
|         if(model->version == DapMainViewVersionV1) { | ||||
|             header_string = "DAP Link V1 Connected"; | ||||
|         } else if(model->version == DapMainViewVersionV2) { | ||||
|             header_string = "DAP Link V2 Connected"; | ||||
|         } else { | ||||
|             header_string = "DAP Link Connected"; | ||||
|         } | ||||
|     } else { | ||||
|         header_string = "DAP Link"; | ||||
|     } | ||||
|  | ||||
|     canvas_draw_str_aligned(canvas, 64, 9, AlignCenter, AlignBottom, header_string); | ||||
|  | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     if(model->dap_active) { | ||||
|         canvas_draw_icon(canvas, 14, 16, &I_ArrowUpFilled_12x18); | ||||
|         canvas_draw_icon(canvas, 28, 16, &I_ArrowDownFilled_12x18); | ||||
|     } else { | ||||
|         canvas_draw_icon(canvas, 14, 16, &I_ArrowUpEmpty_12x18); | ||||
|         canvas_draw_icon(canvas, 28, 16, &I_ArrowDownEmpty_12x18); | ||||
|     } | ||||
|  | ||||
|     switch(model->mode) { | ||||
|     case DapMainViewModeDisconnected: | ||||
|         canvas_draw_str_aligned(canvas, 26, 38, AlignCenter, AlignTop, "----"); | ||||
|         break; | ||||
|     case DapMainViewModeSWD: | ||||
|         canvas_draw_str_aligned(canvas, 26, 38, AlignCenter, AlignTop, "SWD"); | ||||
|         break; | ||||
|     case DapMainViewModeJTAG: | ||||
|         canvas_draw_str_aligned(canvas, 26, 38, AlignCenter, AlignTop, "JTAG"); | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     if(model->tx_active) { | ||||
|         canvas_draw_icon(canvas, 87, 16, &I_ArrowUpFilled_12x18); | ||||
|     } else { | ||||
|         canvas_draw_icon(canvas, 87, 16, &I_ArrowUpEmpty_12x18); | ||||
|     } | ||||
|  | ||||
|     if(model->rx_active) { | ||||
|         canvas_draw_icon(canvas, 101, 16, &I_ArrowDownFilled_12x18); | ||||
|     } else { | ||||
|         canvas_draw_icon(canvas, 101, 16, &I_ArrowDownEmpty_12x18); | ||||
|     } | ||||
|  | ||||
|     canvas_draw_str_aligned(canvas, 100, 38, AlignCenter, AlignTop, "UART"); | ||||
|  | ||||
|     canvas_draw_line(canvas, 44, 52, 123, 52); | ||||
|     if(model->baudrate == 0) { | ||||
|         canvas_draw_str(canvas, 45, 62, "Baud: ????"); | ||||
|     } else { | ||||
|         char baudrate_str[18]; | ||||
|         snprintf(baudrate_str, 18, "Baud: %lu", model->baudrate); | ||||
|         canvas_draw_str(canvas, 45, 62, baudrate_str); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static bool dap_main_view_input_callback(InputEvent* event, void* context) { | ||||
|     furi_assert(context); | ||||
|     DapMainView* dap_main_view = context; | ||||
|     bool consumed = false; | ||||
|  | ||||
|     if(event->type == InputTypeShort) { | ||||
|         if(event->key == InputKeyLeft) { | ||||
|             if(dap_main_view->cb_left) { | ||||
|                 dap_main_view->cb_left(dap_main_view->cb_context); | ||||
|             } | ||||
|             consumed = true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return consumed; | ||||
| } | ||||
|  | ||||
| DapMainView* dap_main_view_alloc() { | ||||
|     DapMainView* dap_main_view = malloc(sizeof(DapMainView)); | ||||
|  | ||||
|     dap_main_view->view = view_alloc(); | ||||
|     view_allocate_model(dap_main_view->view, ViewModelTypeLocking, sizeof(DapMainViewModel)); | ||||
|     view_set_context(dap_main_view->view, dap_main_view); | ||||
|     view_set_draw_callback(dap_main_view->view, dap_main_view_draw_callback); | ||||
|     view_set_input_callback(dap_main_view->view, dap_main_view_input_callback); | ||||
|     return dap_main_view; | ||||
| } | ||||
|  | ||||
| void dap_main_view_free(DapMainView* dap_main_view) { | ||||
|     view_free(dap_main_view->view); | ||||
|     free(dap_main_view); | ||||
| } | ||||
|  | ||||
| View* dap_main_view_get_view(DapMainView* dap_main_view) { | ||||
|     return dap_main_view->view; | ||||
| } | ||||
|  | ||||
| void dap_main_view_set_left_callback( | ||||
|     DapMainView* dap_main_view, | ||||
|     DapMainViewButtonCallback callback, | ||||
|     void* context) { | ||||
|     with_view_model( | ||||
|         dap_main_view->view, | ||||
|         DapMainViewModel * model, | ||||
|         { | ||||
|             UNUSED(model); | ||||
|             dap_main_view->cb_left = callback; | ||||
|             dap_main_view->cb_context = context; | ||||
|         }, | ||||
|         true); | ||||
| } | ||||
|  | ||||
| void dap_main_view_set_mode(DapMainView* dap_main_view, DapMainViewMode mode) { | ||||
|     with_view_model( | ||||
|         dap_main_view->view, DapMainViewModel * model, { model->mode = mode; }, false); | ||||
| } | ||||
|  | ||||
| void dap_main_view_set_dap(DapMainView* dap_main_view, bool active) { | ||||
|     with_view_model( | ||||
|         dap_main_view->view, DapMainViewModel * model, { model->dap_active = active; }, false); | ||||
| } | ||||
|  | ||||
| void dap_main_view_set_tx(DapMainView* dap_main_view, bool active) { | ||||
|     with_view_model( | ||||
|         dap_main_view->view, DapMainViewModel * model, { model->tx_active = active; }, false); | ||||
| } | ||||
|  | ||||
| void dap_main_view_set_rx(DapMainView* dap_main_view, bool active) { | ||||
|     with_view_model( | ||||
|         dap_main_view->view, DapMainViewModel * model, { model->rx_active = active; }, false); | ||||
| } | ||||
|  | ||||
| void dap_main_view_set_baudrate(DapMainView* dap_main_view, uint32_t baudrate) { | ||||
|     with_view_model( | ||||
|         dap_main_view->view, DapMainViewModel * model, { model->baudrate = baudrate; }, false); | ||||
| } | ||||
|  | ||||
| void dap_main_view_update(DapMainView* dap_main_view) { | ||||
|     with_view_model( | ||||
|         dap_main_view->view, DapMainViewModel * model, { UNUSED(model); }, true); | ||||
| } | ||||
|  | ||||
| void dap_main_view_set_version(DapMainView* dap_main_view, DapMainViewVersion version) { | ||||
|     with_view_model( | ||||
|         dap_main_view->view, DapMainViewModel * model, { model->version = version; }, false); | ||||
| } | ||||
|  | ||||
| void dap_main_view_set_usb_connected(DapMainView* dap_main_view, bool connected) { | ||||
|     with_view_model( | ||||
|         dap_main_view->view, | ||||
|         DapMainViewModel * model, | ||||
|         { model->usb_connected = connected; }, | ||||
|         false); | ||||
| } | ||||
							
								
								
									
										45
									
								
								applications/external/dap_link/gui/views/dap_main_view.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								applications/external/dap_link/gui/views/dap_main_view.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| #pragma once | ||||
| #include <gui/view.h> | ||||
|  | ||||
| typedef struct DapMainView DapMainView; | ||||
|  | ||||
| typedef void (*DapMainViewButtonCallback)(void* context); | ||||
|  | ||||
| typedef enum { | ||||
|     DapMainViewVersionUnknown, | ||||
|     DapMainViewVersionV1, | ||||
|     DapMainViewVersionV2, | ||||
| } DapMainViewVersion; | ||||
|  | ||||
| typedef enum { | ||||
|     DapMainViewModeDisconnected, | ||||
|     DapMainViewModeSWD, | ||||
|     DapMainViewModeJTAG, | ||||
| } DapMainViewMode; | ||||
|  | ||||
| DapMainView* dap_main_view_alloc(); | ||||
|  | ||||
| void dap_main_view_free(DapMainView* dap_main_view); | ||||
|  | ||||
| View* dap_main_view_get_view(DapMainView* dap_main_view); | ||||
|  | ||||
| void dap_main_view_set_left_callback( | ||||
|     DapMainView* dap_main_view, | ||||
|     DapMainViewButtonCallback callback, | ||||
|     void* context); | ||||
|  | ||||
| void dap_main_view_set_mode(DapMainView* dap_main_view, DapMainViewMode mode); | ||||
|  | ||||
| void dap_main_view_set_version(DapMainView* dap_main_view, DapMainViewVersion version); | ||||
|  | ||||
| void dap_main_view_set_dap(DapMainView* dap_main_view, bool active); | ||||
|  | ||||
| void dap_main_view_set_tx(DapMainView* dap_main_view, bool active); | ||||
|  | ||||
| void dap_main_view_set_rx(DapMainView* dap_main_view, bool active); | ||||
|  | ||||
| void dap_main_view_set_usb_connected(DapMainView* dap_main_view, bool connected); | ||||
|  | ||||
| void dap_main_view_set_baudrate(DapMainView* dap_main_view, uint32_t baudrate); | ||||
|  | ||||
| void dap_main_view_update(DapMainView* dap_main_view); | ||||
		Reference in New Issue
	
	Block a user