From ad421a81bc73c23a5d3c8355a4624cf489bb95f7 Mon Sep 17 00:00:00 2001 From: SG Date: Fri, 23 Jul 2021 22:20:19 +1000 Subject: [PATCH] [FL-1191][FL-1524] Filesystem rework (#568) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * FS-Api: removed datetime manipulation functions and most of the file flags * Filesystem: common proxy api * Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance. * Storage: sd mount and sd file open * Storage: sd file close * Storage: temporary test app * Storage: free filedata on close * Storage: sd file read and write * Storage: added internal storage (LittleFS) * Storage: renamed internal commands * Storage: seek, tell, truncate, size, sync, eof * Storage: error descriptions * Storage: directory management api (open, close, read, rewind) * Storage: common management api (stat, fs_stat, remove, rename, mkdir) * Dolphin app and Notifications app now use raw storage. * Storage: storage statuses renamed. Implemented sd card icon. * Storage: added raw sd-card api. * Storage settings: work started * Assets: use new icons approach * Storage settings: working storage settings * Storage: completely redesigned api, no longer sticking out FS_Api * Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file * Storage: cli info and format commands * Storage-cli: file list * Storage: a simpler and more reliable api * FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service. * Storage-cli: accommodate to the new cli api. * Storage: filesystem api is separated into internal and common api. * Cli: added the ability to print the list of free heap blocks * Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags. * Storage settings: added the ability to benchmark the SD card. * Gui module file select: uses new storage api * Apps: removed deprecated sd_card_test application * Args lib: support for enquoted arguments * Dialogs: a new gui app for simple non-asynchronous apps * Dialogs: view holder for easy single view work * File worker: use new storage api * IButton and lfrrfid apps: save keys to any storage * Apps: fix ibutton and lfrfid stack, remove sd_card_test. * SD filesystem: app removed * File worker: fixed api pointer type * Subghz: loading assets using the new storage api * NFC: use the new storage api * Dialogs: the better api for the message element * Archive: use new storage api * Irda: changed assest path, changed app path * FileWorker: removed unused file_buf_cnt * Storage: copying and renaming files now works between storages * Storage cli: read, copy, remove, rename commands * Archive: removed commented code * Storage cli: write command * Applications: add SRV_STORAGE and SRV_DIALOGS * Internal-storage: removed * Storage: improved api * Storage app: changed api pointer from StorageApp to Storage * Storage: better file_id handling * Storage: more consistent errors * Loader: support for NULL icons * Storage: do nothing with the lfs file or directory if it is not open * Storage: fix typo * Storage: minor float usage cleanup, rename some symbols. * Storage: compact doxygen comments. Co-authored-by: あく --- applications/applications.c | 59 +- applications/applications.mk | 46 +- applications/archive/archive.c | 121 +-- applications/archive/archive_i.h | 22 +- applications/archive/archive_views.h | 2 +- applications/cli/cli_commands.c | 5 + applications/dialogs/dialogs-api-lock.h | 8 + applications/dialogs/dialogs-api.c | 62 ++ applications/dialogs/dialogs-i.h | 15 + applications/dialogs/dialogs-message.h | 45 + .../dialogs/dialogs-module-file-select.c | 59 ++ .../dialogs/dialogs-module-file-select.h | 12 + applications/dialogs/dialogs-module-message.c | 152 +++ applications/dialogs/dialogs-module-message.h | 12 + applications/dialogs/dialogs.c | 39 + applications/dialogs/dialogs.h | 128 +++ .../view_holder.h => dialogs/view-holder.h} | 0 .../{sd-filesystem => dialogs}/view_holder.c | 2 +- applications/dolphin/dolphin_state.c | 128 ++- applications/gui/modules/file_select.c | 176 ++-- applications/gui/modules/file_select.h | 2 - applications/ibutton/ibutton-app.cpp | 17 +- applications/ibutton/ibutton-app.h | 4 +- .../ibutton/scene/ibutton-scene-save-name.cpp | 1 - .../ibutton/scene/ibutton-scene-start.cpp | 1 - .../internal-storage/internal-storage-i.h | 62 -- .../internal-storage/internal-storage.c | 252 ----- .../internal-storage/internal-storage.h | 40 - applications/irda/irda-app-brute-force.hpp | 1 - applications/irda/irda-app-file-parser.cpp | 2 +- applications/irda/irda-app-file-parser.hpp | 2 +- applications/irda/irda-app-remote-manager.cpp | 2 +- applications/irda/irda-app-remote-manager.hpp | 3 +- applications/irda/scene/irda-app-scene.hpp | 6 +- applications/lfrfid/lfrfid-app.cpp | 6 +- applications/lfrfid/lfrfid-app.h | 4 - applications/loader/loader.c | 13 +- applications/nfc/nfc_device.c | 2 +- applications/notification/notification-app.c | 78 +- applications/notification/notification-app.h | 2 +- applications/sd-card-test/sd-card-test.cpp | 892 ---------------- .../sd-filesystem/sd-filesystem-api.c | 739 -------------- applications/sd-filesystem/sd-filesystem.c | 956 ------------------ applications/sd-filesystem/sd-filesystem.h | 145 --- .../scenes/storage-settings-benchmark.c | 161 +++ .../scenes/storage-settings-scene-config.h | 8 + .../storage-settings-scene-eject-confirm.c | 68 ++ .../scenes/storage-settings-scene-ejected.c | 65 ++ .../storage-settings-scene-format-confirm.c | 67 ++ .../storage-settings-scene-formatting.c | 85 ++ .../storage-settings-scene-internal-info.c | 68 ++ .../scenes/storage-settings-scene-sd-info.c | 74 ++ .../scenes/storage-settings-scene-start.c | 104 ++ .../scenes/storage-settings-scene.c | 30 + .../scenes/storage-settings-scene.h | 29 + .../storage-settings/storage-settings.c | 75 ++ .../storage-settings/storage-settings.h | 47 + applications/storage/filesystem-api-defines.h | 59 ++ .../storage/filesystem-api-internal.h | 192 ++++ applications/storage/filesystem-api.c | 38 + applications/storage/storage-cli.c | 350 +++++++ applications/storage/storage-external-api.c | 383 +++++++ applications/storage/storage-glue.c | 212 ++++ applications/storage/storage-glue.h | 79 ++ applications/storage/storage-i.h | 27 + applications/storage/storage-message.h | 142 +++ applications/storage/storage-processing.c | 584 +++++++++++ applications/storage/storage-processing.h | 16 + applications/storage/storage-sd-api.c | 21 + applications/storage/storage-sd-api.h | 34 + applications/storage/storage-test-app.c | 341 +++++++ applications/storage/storage.c | 96 ++ applications/storage/storage.h | 235 +++++ applications/storage/storages/sd-notify.c | 82 ++ applications/storage/storages/sd-notify.h | 17 + applications/storage/storages/storage-ext.c | 547 ++++++++++ applications/storage/storages/storage-ext.h | 16 + applications/storage/storages/storage-int.c | 690 +++++++++++++ applications/storage/storages/storage-int.h | 13 + applications/subghz/subghz_cli.c | 4 +- applications/subghz/views/subghz_capture.c | 5 +- assets/compiled/assets_icons.c | 568 +++++------ assets/compiled/assets_icons.h | 158 +-- core/furi/memmgr_heap.c | 14 + core/furi/memmgr_heap.h | 5 + firmware/targets/f6/Src/fatfs/ffconf.h | 18 +- lib/app-scened-template/file-worker.c | 119 ++- lib/app-scened-template/file-worker.h | 37 +- lib/args/args.c | 17 + lib/args/args.h | 14 +- lib/common-api/filesystem-api.h | 329 ------ lib/common-api/sd-card-api.h | 25 - lib/file_reader/file_reader.cpp | 48 - lib/file_reader/file_reader.h | 44 - lib/subghz/subghz_keystore.c | 15 +- 95 files changed, 6451 insertions(+), 4349 deletions(-) create mode 100644 applications/dialogs/dialogs-api-lock.h create mode 100644 applications/dialogs/dialogs-api.c create mode 100644 applications/dialogs/dialogs-i.h create mode 100644 applications/dialogs/dialogs-message.h create mode 100644 applications/dialogs/dialogs-module-file-select.c create mode 100644 applications/dialogs/dialogs-module-file-select.h create mode 100644 applications/dialogs/dialogs-module-message.c create mode 100644 applications/dialogs/dialogs-module-message.h create mode 100644 applications/dialogs/dialogs.c create mode 100644 applications/dialogs/dialogs.h rename applications/{sd-filesystem/view_holder.h => dialogs/view-holder.h} (100%) rename applications/{sd-filesystem => dialogs}/view_holder.c (99%) delete mode 100644 applications/internal-storage/internal-storage-i.h delete mode 100644 applications/internal-storage/internal-storage.c delete mode 100644 applications/internal-storage/internal-storage.h delete mode 100644 applications/sd-card-test/sd-card-test.cpp delete mode 100644 applications/sd-filesystem/sd-filesystem-api.c delete mode 100644 applications/sd-filesystem/sd-filesystem.c delete mode 100644 applications/sd-filesystem/sd-filesystem.h create mode 100644 applications/storage-settings/scenes/storage-settings-benchmark.c create mode 100644 applications/storage-settings/scenes/storage-settings-scene-config.h create mode 100644 applications/storage-settings/scenes/storage-settings-scene-eject-confirm.c create mode 100644 applications/storage-settings/scenes/storage-settings-scene-ejected.c create mode 100644 applications/storage-settings/scenes/storage-settings-scene-format-confirm.c create mode 100644 applications/storage-settings/scenes/storage-settings-scene-formatting.c create mode 100644 applications/storage-settings/scenes/storage-settings-scene-internal-info.c create mode 100644 applications/storage-settings/scenes/storage-settings-scene-sd-info.c create mode 100644 applications/storage-settings/scenes/storage-settings-scene-start.c create mode 100644 applications/storage-settings/scenes/storage-settings-scene.c create mode 100644 applications/storage-settings/scenes/storage-settings-scene.h create mode 100644 applications/storage-settings/storage-settings.c create mode 100644 applications/storage-settings/storage-settings.h create mode 100644 applications/storage/filesystem-api-defines.h create mode 100644 applications/storage/filesystem-api-internal.h create mode 100644 applications/storage/filesystem-api.c create mode 100644 applications/storage/storage-cli.c create mode 100644 applications/storage/storage-external-api.c create mode 100644 applications/storage/storage-glue.c create mode 100644 applications/storage/storage-glue.h create mode 100644 applications/storage/storage-i.h create mode 100644 applications/storage/storage-message.h create mode 100644 applications/storage/storage-processing.c create mode 100644 applications/storage/storage-processing.h create mode 100644 applications/storage/storage-sd-api.c create mode 100644 applications/storage/storage-sd-api.h create mode 100644 applications/storage/storage-test-app.c create mode 100644 applications/storage/storage.c create mode 100644 applications/storage/storage.h create mode 100644 applications/storage/storages/sd-notify.c create mode 100644 applications/storage/storages/sd-notify.h create mode 100644 applications/storage/storages/storage-ext.c create mode 100644 applications/storage/storages/storage-ext.h create mode 100644 applications/storage/storages/storage-int.c create mode 100644 applications/storage/storages/storage-int.h delete mode 100644 lib/common-api/filesystem-api.h delete mode 100644 lib/common-api/sd-card-api.h delete mode 100644 lib/file_reader/file_reader.cpp delete mode 100644 lib/file_reader/file_reader.h diff --git a/applications/applications.c b/applications/applications.c index 4ea627d6..c5850aa2 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -19,26 +19,26 @@ int32_t nfc_task(void* p); int32_t dolphin_task(void* p); int32_t power_task(void* p); int32_t bt_task(void* p); -int32_t sd_card_test(void* p); int32_t application_vibro(void* p); int32_t app_gpio_test(void* p); int32_t app_ibutton(void* p); int32_t cli_task(void* p); int32_t music_player(void* p); int32_t sdnfc(void* p); -int32_t sd_filesystem(void* p); int32_t subghz_app(void* p); int32_t gui_test(void* p); int32_t keypad_test(void* p); int32_t scene_app(void* p); int32_t passport(void* p); int32_t app_accessor(void* p); -int32_t internal_storage_task(void* p); int32_t app_archive(void* p); int32_t notification_app(void* p); int32_t scened_app(void* p); int32_t lfrfid_app(void* p); int32_t lfrfid_debug_app(void* p); +int32_t storage_app(void* p); +int32_t storage_app_test(void* p); +int32_t dialogs_app(void* p); // On system start hooks declaration void irda_cli_init(); @@ -47,9 +47,11 @@ void subghz_cli_init(); void bt_cli_init(); void lfrfid_cli_init(); void ibutton_cli_init(); +void storage_cli_init(); // Settings int32_t notification_app_settings(void* p); +int32_t storage_settings(void* p); const FlipperApplication FLIPPER_SERVICES[] = { #ifdef SRV_CLI @@ -81,17 +83,6 @@ const FlipperApplication FLIPPER_SERVICES[] = { {.app = loader, .name = "loader", .stack_size = 1024, .icon = &A_Plugins_14}, #endif -#ifdef SRV_SD_FILESYSTEM - {.app = sd_filesystem, .name = "sd_filesystem", .stack_size = 4096, .icon = &A_Plugins_14}, -#endif - -#ifdef SRV_INTERNAL_STORAGE - {.app = internal_storage_task, - .name = "internal_storage", - .stack_size = 2048, - .icon = &A_Plugins_14}, -#endif - #ifdef SRV_DOLPHIN {.app = dolphin_task, .name = "dolphin_task", .stack_size = 1024, .icon = &A_Plugins_14}, #endif @@ -105,8 +96,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { #endif #ifdef SRV_LF_RFID - // TODO: fix stack size when sd api will be in separate thread - {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 4096, .icon = &A_Plugins_14}, + {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 2048, .icon = &A_Plugins_14}, #endif #ifdef SRV_IRDA @@ -128,16 +118,12 @@ const FlipperApplication FLIPPER_SERVICES[] = { .icon = &A_Plugins_14}, #endif -#ifdef SRV_SD_TEST - {.app = sd_card_test, .name = "sd_card_test", .stack_size = 4096, .icon = &A_Plugins_14}, -#endif - #ifdef SRV_MUSIC_PLAYER {.app = music_player, .name = "music player", .stack_size = 1024, .icon = &A_Plugins_14}, #endif #ifdef SRV_IBUTTON - {.app = app_ibutton, .name = "ibutton", .stack_size = 4096, .icon = &A_Plugins_14}, + {.app = app_ibutton, .name = "ibutton", .stack_size = 2048, .icon = &A_Plugins_14}, #endif #ifdef SRV_GPIO_DEMO @@ -164,6 +150,17 @@ const FlipperApplication FLIPPER_SERVICES[] = { {.app = notification_app, .name = "notification", .stack_size = 1024, .icon = &A_Plugins_14}, #endif +#ifdef SRV_STORAGE + {.app = storage_app, .name = "storage", .stack_size = 4096, .icon = &A_Plugins_14}, +#endif + +#ifdef SRV_STORAGE_TEST + {.app = storage_app_test, .name = "storage test", .stack_size = 1024, .icon = &A_Plugins_14}, +#endif + +#ifdef SRV_DIALOGS + {.app = dialogs_app, .name = "dialogs", .stack_size = 1024, .icon = &A_Plugins_14}, +#endif }; const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); @@ -172,7 +169,7 @@ const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperA const FlipperApplication FLIPPER_APPS[] = { #ifdef APP_IBUTTON - {.app = app_ibutton, .name = "iButton", .stack_size = 4096, .icon = &A_iButton_14}, + {.app = app_ibutton, .name = "iButton", .stack_size = 2048, .icon = &A_iButton_14}, #endif #ifdef APP_NFC @@ -186,7 +183,7 @@ const FlipperApplication FLIPPER_APPS[] = { #ifdef APP_LF_RFID // TODO: fix stack size when sd api will be in separate thread - {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 4096, .icon = &A_125khz_14}, + {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 2048, .icon = &A_125khz_14}, #endif #ifdef APP_IRDA @@ -219,6 +216,9 @@ const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { #ifdef SRV_BT bt_cli_init, #endif +#ifdef SRV_STORAGE + storage_cli_init, +#endif }; const size_t FLIPPER_ON_SYSTEM_START_COUNT = @@ -255,10 +255,6 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .icon = &A_Plugins_14}, #endif -#ifdef APP_SD_TEST - {.app = sd_card_test, .name = "sd_card_test", .stack_size = 4096, .icon = &A_Plugins_14}, -#endif - #ifdef APP_VIBRO_DEMO {.app = application_vibro, .name = "vibro", .stack_size = 1024, .icon = &A_Plugins_14}, #endif @@ -326,10 +322,11 @@ const size_t FLIPPER_SCENE_APPS_COUNT = sizeof(FLIPPER_SCENE_APPS) / sizeof(Flip // Settings menu const FlipperApplication FLIPPER_SETTINGS_APPS[] = { #ifdef SRV_NOTIFICATION - {.app = notification_app_settings, - .name = "Notification", - .stack_size = 1024, - .icon = &A_Plugins_14}, + {.app = notification_app_settings, .name = "Notification", .stack_size = 1024, .icon = NULL}, +#endif + +#ifdef SRV_STORAGE + {.app = storage_settings, .name = "Storage", .stack_size = 2048, .icon = NULL}, #endif }; diff --git a/applications/applications.mk b/applications/applications.mk index 7c06bf51..cfc91d60 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -16,10 +16,10 @@ SRV_MENU = 1 SRV_POWER = 1 SRV_BT = 1 SRV_CLI = 1 -SRV_SD_FILESYSTEM = 1 -SRV_INTERNAL_STORAGE = 1 SRV_DOLPHIN = 1 SRV_NOTIFICATION = 1 +SRV_STORAGE = 1 +SRV_DIALOGS = 1 # Main Apps APP_IRDA = 1 @@ -189,19 +189,6 @@ SRV_INPUT = 1 SRV_GUI = 1 endif -SRV_SD_TEST ?= 0 -ifeq ($(SRV_SD_TEST), 1) -CFLAGS += -DSRV_SD_TEST -APP_SD_TEST = 1 -endif -APP_SD_TEST ?= 0 -ifeq ($(APP_SD_TEST), 1) -CFLAGS += -DAPP_SD_TEST -SRV_INPUT = 1 -SRV_GUI = 1 -SRV_SD_FILESYSTEM = 1 -endif - SRV_SPEAKER_DEMO ?= 0 ifeq ($(SRV_SPEAKER_DEMO), 1) CFLAGS += -DSRV_SPEAKER_DEMO @@ -282,15 +269,6 @@ ifeq ($(APP_GUI_TEST), 1) CFLAGS += -DAPP_GUI_TEST endif -SRV_SDNFC ?= 0 -ifeq ($(SRV_SDNFC), 1) -CFLAGS += -DSRV_SDNFC -APP_SDNFC = 1 -endif -APP_SDNFC ?= 0 -ifeq ($(APP_SDNFC), 1) -CFLAGS += -DAPP_SDNFC -endif # device drivers SRV_GUI ?= 0 @@ -298,16 +276,6 @@ ifeq ($(SRV_GUI), 1) CFLAGS += -DSRV_GUI endif -SRV_SD_FILESYSTEM ?= 0 -ifeq ($(SRV_SD_FILESYSTEM), 1) -CFLAGS += -DSRV_SD_FILESYSTEM -endif - -SRV_INTERNAL_STORAGE ?= 0 -ifeq ($(SRV_INTERNAL_STORAGE), 1) -CFLAGS += -DSRV_INTERNAL_STORAGE -endif - SRV_INPUT ?= 0 ifeq ($(SRV_INPUT), 1) CFLAGS += -DSRV_INPUT @@ -323,3 +291,13 @@ SRV_NOTIFICATION ?= 0 ifeq ($(SRV_NOTIFICATION), 1) CFLAGS += -DSRV_NOTIFICATION endif + +SRV_STORAGE ?= 0 +ifeq ($(SRV_STORAGE), 1) +CFLAGS += -DSRV_STORAGE +endif + +SRV_DIALOGS ?= 0 +ifeq ($(SRV_DIALOGS), 1) +CFLAGS += -DSRV_DIALOGS +endif \ No newline at end of file diff --git a/applications/archive/archive.c b/applications/archive/archive.c index 0ba8f3ef..9ed91e76 100644 --- a/applications/archive/archive.c +++ b/applications/archive/archive.c @@ -3,18 +3,17 @@ static bool archive_get_filenames(ArchiveApp* archive); static bool is_favorite(ArchiveApp* archive, ArchiveFile_t* file) { - FS_Common_Api* common_api = &archive->fs_api->common; FileInfo file_info; FS_Error fr; string_t path; - string_init_printf(path, "favorites/%s", string_get_cstr(file->name)); + string_init_printf(path, "%s/%s", get_favorites_path(), string_get_cstr(file->name)); - fr = common_api->info(string_get_cstr(path), &file_info, NULL, 0); + fr = storage_common_stat(archive->api, string_get_cstr(path), &file_info); FURI_LOG_I("FAV", "%d", fr); string_clear(path); - return fr == 0 || fr == 2; + return (fr == FSE_OK || fr == FSE_EXIST); } static void update_offset(ArchiveApp* archive) { @@ -147,14 +146,11 @@ static void set_file_type(ArchiveFile_t* file, FileInfo* file_info) { static bool archive_get_filenames(ArchiveApp* archive) { furi_assert(archive); - FS_Dir_Api* dir_api = &archive->fs_api->dir; + ArchiveFile_t item; FileInfo file_info; - File directory; + File* directory = storage_file_alloc(archive->api); char name[MAX_NAME_LEN]; - bool result; - - result = dir_api->open(&directory, string_get_cstr(archive->browser.path)); with_view_model( archive->view_archive_main, (ArchiveViewModel * model) { @@ -162,51 +158,50 @@ static bool archive_get_filenames(ArchiveApp* archive) { return true; }); - if(!result) { - dir_api->close(&directory); + if(!storage_dir_open(directory, string_get_cstr(archive->browser.path))) { + storage_dir_close(directory); + storage_file_free(directory); return false; } while(1) { - result = dir_api->read(&directory, &file_info, name, MAX_NAME_LEN); - - if(directory.error_id == FSE_NOT_EXIST || name[0] == 0) { + if(!storage_dir_read(directory, &file_info, name, MAX_NAME_LEN)) { break; } - if(result) { - uint16_t files_cnt; - with_view_model( - archive->view_archive_main, (ArchiveViewModel * model) { - files_cnt = files_array_size(model->files); + uint16_t files_cnt; + with_view_model( + archive->view_archive_main, (ArchiveViewModel * model) { + files_cnt = files_array_size(model->files); - return true; - }); + return true; + }); - if(files_cnt > MAX_FILES) { - break; - } else if(directory.error_id == FSE_OK) { - if(filter_by_extension(archive, &file_info, name)) { - ArchiveFile_t_init(&item); - string_init_set(item.name, name); - set_file_type(&item, &file_info); + if(files_cnt > MAX_FILES) { + break; + } else if(storage_file_get_error(directory) == FSE_OK) { + if(filter_by_extension(archive, &file_info, name)) { + ArchiveFile_t_init(&item); + string_init_set(item.name, name); + set_file_type(&item, &file_info); - with_view_model( - archive->view_archive_main, (ArchiveViewModel * model) { - files_array_push_back(model->files, item); - return true; - }); + with_view_model( + archive->view_archive_main, (ArchiveViewModel * model) { + files_array_push_back(model->files, item); + return true; + }); - ArchiveFile_t_clear(&item); - } - } else { - dir_api->close(&directory); - return false; + ArchiveFile_t_clear(&item); } + } else { + storage_dir_close(directory); + storage_file_free(directory); + return false; } } - dir_api->close(&directory); + storage_dir_close(directory); + storage_file_free(directory); return true; } @@ -226,17 +221,7 @@ static uint32_t archive_previous_callback(void* context) { static void archive_add_to_favorites(ArchiveApp* archive) { furi_assert(archive); - FS_Common_Api* common_api = &archive->fs_api->common; - common_api->mkdir("favorites"); - - FS_File_Api* file_api = &archive->fs_api->file; - File src; - File dst; - - bool fr; - uint16_t buffer[MAX_FILE_SIZE]; - uint16_t bw = 0; - uint16_t br = 0; + storage_common_mkdir(archive->api, get_favorites_path()); string_t buffer_src; string_t buffer_dst; @@ -246,22 +231,10 @@ static void archive_add_to_favorites(ArchiveApp* archive) { "%s/%s", string_get_cstr(archive->browser.path), string_get_cstr(archive->browser.name)); - string_init_printf(buffer_dst, "/favorites/%s", string_get_cstr(archive->browser.name)); + string_init_printf( + buffer_dst, "%s/%s", get_favorites_path(), string_get_cstr(archive->browser.name)); - fr = file_api->open(&src, string_get_cstr(buffer_src), FSAM_READ, FSOM_OPEN_EXISTING); - FURI_LOG_I("FATFS", "OPEN: %d", fr); - fr = file_api->open(&dst, string_get_cstr(buffer_dst), FSAM_WRITE, FSOM_CREATE_ALWAYS); - FURI_LOG_I("FATFS", "CREATE: %d", fr); - - for(;;) { - br = file_api->read(&src, &buffer, sizeof(buffer)); - if(br == 0) break; - bw = file_api->write(&dst, &buffer, sizeof(buffer)); - if(bw < br) break; - } - - file_api->close(&src); - file_api->close(&dst); + storage_common_copy(archive->api, string_get_cstr(buffer_src), string_get_cstr(buffer_dst)); string_clear(buffer_src); string_clear(buffer_dst); @@ -271,7 +244,6 @@ static void archive_text_input_callback(void* context) { furi_assert(context); ArchiveApp* archive = (ArchiveApp*)context; - FS_Common_Api* common_api = &archive->fs_api->common; string_t buffer_src; string_t buffer_dst; @@ -299,7 +271,7 @@ static void archive_text_input_callback(void* context) { }); string_cat(buffer_dst, known_ext[file->type]); - common_api->rename(string_get_cstr(buffer_src), string_get_cstr(buffer_dst)); + storage_common_rename(archive->api, string_get_cstr(buffer_src), string_get_cstr(buffer_dst)); view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewMain); @@ -371,23 +343,22 @@ static void archive_delete_file(ArchiveApp* archive, ArchiveFile_t* file, bool f furi_assert(archive); furi_assert(file); - FS_Common_Api* common_api = &archive->fs_api->common; string_t path; string_init(path); if(!fav && !orig) { string_printf( path, "%s/%s", string_get_cstr(archive->browser.path), string_get_cstr(file->name)); - common_api->remove(string_get_cstr(path)); + storage_common_remove(archive->api, string_get_cstr(path)); } else { // remove from favorites - string_printf(path, "favorites/%s", string_get_cstr(file->name)); - common_api->remove(string_get_cstr(path)); + string_printf(path, "%s/%s", get_favorites_path(), string_get_cstr(file->name)); + storage_common_remove(archive->api, string_get_cstr(path)); if(orig) { // remove original file string_printf( path, "%s/%s", get_default_path(file->type), string_get_cstr(file->name)); - common_api->remove(string_get_cstr(path)); + storage_common_remove(archive->api, string_get_cstr(path)); } } @@ -604,8 +575,8 @@ void archive_free(ArchiveApp* archive) { text_input_free(archive->text_input); - furi_record_close("sdcard"); - archive->fs_api = NULL; + furi_record_close("storage"); + archive->api = NULL; furi_record_close("gui"); archive->gui = NULL; furi_record_close("loader"); @@ -623,7 +594,7 @@ ArchiveApp* archive_alloc() { archive->app_thread = furi_thread_alloc(); archive->gui = furi_record_open("gui"); archive->loader = furi_record_open("loader"); - archive->fs_api = furi_record_open("sdcard"); + archive->api = furi_record_open("storage"); archive->text_input = text_input_alloc(); archive->view_archive_main = view_alloc(); diff --git a/applications/archive/archive_i.h b/applications/archive/archive_i.h index a742696f..38991f7b 100644 --- a/applications/archive/archive_i.h +++ b/applications/archive/archive_i.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include "archive_views.h" #include "applications.h" @@ -41,13 +41,13 @@ static const char* known_ext[] = { }; static const char* tab_default_paths[] = { - [ArchiveTabFavorites] = "favorites", - [ArchiveTabIButton] = "ibutton", - [ArchiveTabNFC] = "nfc", - [ArchiveTabSubOne] = "subone", - [ArchiveTabLFRFID] = "lfrfid", - [ArchiveTabIrda] = "irda", - [ArchiveTabBrowser] = "/", + [ArchiveTabFavorites] = "/any/favorites", + [ArchiveTabIButton] = "/any/ibutton", + [ArchiveTabNFC] = "/any/nfc", + [ArchiveTabSubOne] = "/any/subone", + [ArchiveTabLFRFID] = "/any/lfrfid", + [ArchiveTabIrda] = "/any/irda", + [ArchiveTabBrowser] = "/any", }; static inline const char* get_tab_ext(ArchiveTabEnum tab) { @@ -84,6 +84,10 @@ static inline const char* get_default_path(ArchiveFileTypeEnum type) { } } +static inline const char* get_favorites_path() { + return tab_default_paths[ArchiveTabFavorites]; +} + typedef enum { EventTypeTick, EventTypeKey, @@ -118,6 +122,6 @@ struct ArchiveApp { View* view_archive_main; TextInput* text_input; - FS_Api* fs_api; + Storage* api; ArchiveBrowser browser; }; diff --git a/applications/archive/archive_views.h b/applications/archive/archive_views.h index 54258daf..ca7772d4 100644 --- a/applications/archive/archive_views.h +++ b/applications/archive/archive_views.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #define MAX_LEN_PX 100 #define MAX_NAME_LEN 255 diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index 8d43a34c..1ee535b5 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -375,6 +375,10 @@ void cli_command_free(Cli* cli, string_t args, void* context) { printf("Maximum heap block: %d\r\n", memmgr_heap_get_max_free_block()); } +void cli_command_free_blocks(Cli* cli, string_t args, void* context) { + memmgr_heap_printf_free_blocks(); +} + void cli_commands_init(Cli* cli) { cli_add_command(cli, "!", CliCommandFlagParallelSafe, cli_command_device_info, NULL); cli_add_command(cli, "device_info", CliCommandFlagParallelSafe, cli_command_device_info, NULL); @@ -386,6 +390,7 @@ void cli_commands_init(Cli* cli) { cli_add_command(cli, "log", CliCommandFlagParallelSafe, cli_command_log, NULL); cli_add_command(cli, "ps", CliCommandFlagParallelSafe, cli_command_ps, NULL); cli_add_command(cli, "free", CliCommandFlagParallelSafe, cli_command_free, NULL); + cli_add_command(cli, "free_blocks", CliCommandFlagParallelSafe, cli_command_free_blocks, NULL); cli_add_command(cli, "vibro", CliCommandFlagDefault, cli_command_vibro, NULL); cli_add_command(cli, "led", CliCommandFlagDefault, cli_command_led, NULL); diff --git a/applications/dialogs/dialogs-api-lock.h b/applications/dialogs/dialogs-api-lock.h new file mode 100644 index 00000000..fe9e934f --- /dev/null +++ b/applications/dialogs/dialogs-api-lock.h @@ -0,0 +1,8 @@ +#pragma once +#define API_LOCK_INIT_LOCKED() osSemaphoreNew(1, 0, NULL); + +#define API_LOCK_WAIT_UNTIL_UNLOCK_AND_FREE(_lock) \ + osSemaphoreAcquire(_lock, osWaitForever); \ + osSemaphoreDelete(_lock); + +#define API_LOCK_UNLOCK(_lock) osSemaphoreRelease(_lock); \ No newline at end of file diff --git a/applications/dialogs/dialogs-api.c b/applications/dialogs/dialogs-api.c new file mode 100644 index 00000000..5ad9cedc --- /dev/null +++ b/applications/dialogs/dialogs-api.c @@ -0,0 +1,62 @@ +#include "dialogs-i.h" +#include "dialogs-api-lock.h" + +/****************** File select ******************/ + +bool dialog_file_select_show( + DialogsApp* context, + const char* path, + const char* extension, + char* result, + uint8_t result_size, + const char* preselected_filename) { + osSemaphoreId_t semaphore = API_LOCK_INIT_LOCKED(); + furi_check(semaphore != NULL); + + DialogsAppData data = { + .file_select = { + .path = path, + .extension = extension, + .result = result, + .result_size = result_size, + .preselected_filename = preselected_filename, + }}; + + DialogsAppReturn return_data; + DialogsAppMessage message = { + .semaphore = semaphore, + .command = DialogsAppCommandFileOpen, + .data = &data, + .return_data = &return_data, + }; + + furi_check(osMessageQueuePut(context->message_queue, &message, 0, osWaitForever) == osOK); + API_LOCK_WAIT_UNTIL_UNLOCK_AND_FREE(semaphore); + + return return_data.bool_value; +} + +/****************** Message ******************/ + +DialogMessageButton dialog_message_show(DialogsApp* context, const DialogMessage* dialog_message) { + osSemaphoreId_t semaphore = API_LOCK_INIT_LOCKED(); + furi_check(semaphore != NULL); + + DialogsAppData data = { + .dialog = { + .message = dialog_message, + }}; + + DialogsAppReturn return_data; + DialogsAppMessage message = { + .semaphore = semaphore, + .command = DialogsAppCommandDialog, + .data = &data, + .return_data = &return_data, + }; + + furi_check(osMessageQueuePut(context->message_queue, &message, 0, osWaitForever) == osOK); + API_LOCK_WAIT_UNTIL_UNLOCK_AND_FREE(semaphore); + + return return_data.dialog_value; +} diff --git a/applications/dialogs/dialogs-i.h b/applications/dialogs/dialogs-i.h new file mode 100644 index 00000000..a68373f6 --- /dev/null +++ b/applications/dialogs/dialogs-i.h @@ -0,0 +1,15 @@ +#pragma once +#include "dialogs.h" +#include "dialogs-message.h" +#include "view-holder.h" + +#ifdef __cplusplus +extern "C" { +#endif +struct DialogsApp { + osMessageQueueId_t message_queue; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/dialogs/dialogs-message.h b/applications/dialogs/dialogs-message.h new file mode 100644 index 00000000..0bb6d86f --- /dev/null +++ b/applications/dialogs/dialogs-message.h @@ -0,0 +1,45 @@ +#pragma once +#include +#include "dialogs-i.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + const char* path; + const char* extension; + char* result; + uint8_t result_size; + const char* preselected_filename; +} DialogsAppMessageDataFileSelect; + +typedef struct { + const DialogMessage* message; +} DialogsAppMessageDataDialog; + +typedef union { + DialogsAppMessageDataFileSelect file_select; + DialogsAppMessageDataDialog dialog; +} DialogsAppData; + +typedef union { + bool bool_value; + DialogMessageButton dialog_value; +} DialogsAppReturn; + +typedef enum { + DialogsAppCommandFileOpen, + DialogsAppCommandDialog, +} DialogsAppCommand; + +typedef struct { + osSemaphoreId_t semaphore; + DialogsAppCommand command; + DialogsAppData* data; + DialogsAppReturn* return_data; +} DialogsAppMessage; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/dialogs/dialogs-module-file-select.c b/applications/dialogs/dialogs-module-file-select.c new file mode 100644 index 00000000..1f2abb40 --- /dev/null +++ b/applications/dialogs/dialogs-module-file-select.c @@ -0,0 +1,59 @@ +#include "dialogs-i.h" +#include "dialogs-api-lock.h" +#include + +typedef struct { + osSemaphoreId_t semaphore; + bool result; +} DialogsAppFileSelectContext; + +static void dialogs_app_file_select_back_callback(void* context) { + furi_assert(context); + DialogsAppFileSelectContext* file_select_context = context; + file_select_context->result = false; + API_LOCK_UNLOCK(file_select_context->semaphore); +} + +static void dialogs_app_file_select_callback(bool result, void* context) { + furi_assert(context); + DialogsAppFileSelectContext* file_select_context = context; + file_select_context->result = result; + API_LOCK_UNLOCK(file_select_context->semaphore); +} + +bool dialogs_app_process_module_file_select(const DialogsAppMessageDataFileSelect* data) { + bool ret = false; + Gui* gui = furi_record_open("gui"); + + DialogsAppFileSelectContext* file_select_context = + furi_alloc(sizeof(DialogsAppFileSelectContext)); + file_select_context->semaphore = API_LOCK_INIT_LOCKED(); + + ViewHolder* view_holder = view_holder_alloc(); + view_holder_attach_to_gui(view_holder, gui); + view_holder_set_back_callback( + view_holder, dialogs_app_file_select_back_callback, file_select_context); + + FileSelect* file_select = file_select_alloc(); + file_select_set_callback(file_select, dialogs_app_file_select_callback, file_select_context); + file_select_set_filter(file_select, data->path, data->extension); + file_select_set_result_buffer(file_select, data->result, data->result_size); + file_select_init(file_select); + if(data->preselected_filename != NULL) { + file_select_set_selected_file(file_select, data->preselected_filename); + } + + view_holder_set_view(view_holder, file_select_get_view(file_select)); + view_holder_start(view_holder); + API_LOCK_WAIT_UNTIL_UNLOCK_AND_FREE(file_select_context->semaphore); + + ret = file_select_context->result; + + free(file_select_context); + view_holder_stop(view_holder); + view_holder_free(view_holder); + file_select_free(file_select); + furi_record_close("gui"); + + return ret; +} \ No newline at end of file diff --git a/applications/dialogs/dialogs-module-file-select.h b/applications/dialogs/dialogs-module-file-select.h new file mode 100644 index 00000000..7303406a --- /dev/null +++ b/applications/dialogs/dialogs-module-file-select.h @@ -0,0 +1,12 @@ +#pragma once +#include "dialogs-message.h" + +#ifdef __cplusplus +extern "C" { +#endif + +bool dialogs_app_process_module_file_select(const DialogsAppMessageDataFileSelect* data); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/dialogs/dialogs-module-message.c b/applications/dialogs/dialogs-module-message.c new file mode 100644 index 00000000..77e727ef --- /dev/null +++ b/applications/dialogs/dialogs-module-message.c @@ -0,0 +1,152 @@ +#include "dialogs-i.h" +#include "dialogs-api-lock.h" +#include + +typedef struct { + osSemaphoreId_t semaphore; + DialogMessageButton result; +} DialogsAppMessageContext; + +struct DialogMessage { + const char* header_text; + uint8_t header_text_x; + uint8_t header_text_y; + Align header_horizontal; + Align header_vertical; + const char* dialog_text; + uint8_t dialog_text_x; + uint8_t dialog_text_y; + Align dialog_text_horizontal; + Align dialog_text_vertical; + const Icon* icon; + uint8_t icon_x; + uint8_t icon_y; + const char* left_button_text; + const char* center_button_text; + const char* right_button_text; +}; + +static void dialogs_app_message_back_callback(void* context) { + furi_assert(context); + DialogsAppMessageContext* message_context = context; + message_context->result = DialogMessageButtonBack; + API_LOCK_UNLOCK(message_context->semaphore); +} + +static void dialogs_app_message_callback(DialogExResult result, void* context) { + furi_assert(context); + DialogsAppMessageContext* message_context = context; + switch(result) { + case DialogExResultLeft: + message_context->result = DialogMessageButtonLeft; + break; + case DialogExResultRight: + message_context->result = DialogMessageButtonRight; + break; + case DialogExResultCenter: + message_context->result = DialogMessageButtonCenter; + break; + } + API_LOCK_UNLOCK(message_context->semaphore); +} + +DialogMessageButton dialogs_app_process_module_message(const DialogsAppMessageDataDialog* data) { + DialogMessageButton ret = DialogMessageButtonBack; + Gui* gui = furi_record_open("gui"); + const DialogMessage* message = data->message; + DialogsAppMessageContext* message_context = furi_alloc(sizeof(DialogsAppMessageContext)); + message_context->semaphore = API_LOCK_INIT_LOCKED(); + + ViewHolder* view_holder = view_holder_alloc(); + view_holder_attach_to_gui(view_holder, gui); + view_holder_set_back_callback(view_holder, dialogs_app_message_back_callback, message_context); + + DialogEx* dialog_ex = dialog_ex_alloc(); + dialog_ex_set_result_callback(dialog_ex, dialogs_app_message_callback); + dialog_ex_set_context(dialog_ex, message_context); + dialog_ex_set_header( + dialog_ex, + message->header_text, + message->header_text_x, + message->header_text_y, + message->header_horizontal, + message->header_vertical); + dialog_ex_set_text( + dialog_ex, + message->dialog_text, + message->dialog_text_x, + message->dialog_text_y, + message->dialog_text_horizontal, + message->dialog_text_vertical); + dialog_ex_set_icon(dialog_ex, message->icon_x, message->icon_y, message->icon); + dialog_ex_set_left_button_text(dialog_ex, message->left_button_text); + dialog_ex_set_center_button_text(dialog_ex, message->center_button_text); + dialog_ex_set_right_button_text(dialog_ex, message->right_button_text); + + view_holder_set_view(view_holder, dialog_ex_get_view(dialog_ex)); + view_holder_start(view_holder); + API_LOCK_WAIT_UNTIL_UNLOCK_AND_FREE(message_context->semaphore); + + ret = message_context->result; + + free(message_context); + view_holder_stop(view_holder); + view_holder_free(view_holder); + dialog_ex_free(dialog_ex); + furi_record_close("gui"); + + return ret; +} + +DialogMessage* dialog_message_alloc() { + DialogMessage* message = furi_alloc(sizeof(DialogMessage)); + return message; +} + +void dialog_message_free(DialogMessage* message) { + free(message); +} + +void dialog_message_set_text( + DialogMessage* message, + const char* text, + uint8_t x, + uint8_t y, + Align horizontal, + Align vertical) { + message->dialog_text = text; + message->dialog_text_x = x; + message->dialog_text_y = y; + message->dialog_text_horizontal = horizontal; + message->dialog_text_vertical = vertical; +} + +void dialog_message_set_header( + DialogMessage* message, + const char* text, + uint8_t x, + uint8_t y, + Align horizontal, + Align vertical) { + message->header_text = text; + message->header_text_x = x; + message->header_text_y = y; + message->header_horizontal = horizontal; + message->header_vertical = vertical; +} + +void dialog_message_set_icon(DialogMessage* message, const Icon* icon, uint8_t x, uint8_t y) { + message->icon = icon; + message->icon_x = x; + message->icon_y = y; +} + +void dialog_message_set_buttons( + DialogMessage* message, + const char* left, + const char* center, + const char* right) { + message->left_button_text = left; + message->center_button_text = center; + message->right_button_text = right; +} \ No newline at end of file diff --git a/applications/dialogs/dialogs-module-message.h b/applications/dialogs/dialogs-module-message.h new file mode 100644 index 00000000..770aad33 --- /dev/null +++ b/applications/dialogs/dialogs-module-message.h @@ -0,0 +1,12 @@ +#pragma once +#include "dialogs-message.h" + +#ifdef __cplusplus +extern "C" { +#endif + +DialogMessageButton dialogs_app_process_module_message(const DialogsAppMessageDataDialog* data); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/dialogs/dialogs.c b/applications/dialogs/dialogs.c new file mode 100644 index 00000000..41c607da --- /dev/null +++ b/applications/dialogs/dialogs.c @@ -0,0 +1,39 @@ +#include "dialogs-i.h" +#include "dialogs-api-lock.h" +#include "dialogs-module-file-select.h" +#include "dialogs-module-message.h" + +static DialogsApp* dialogs_app_alloc() { + DialogsApp* app = malloc(sizeof(DialogsApp)); + app->message_queue = osMessageQueueNew(8, sizeof(DialogsAppMessage), NULL); + + return app; +} + +static void dialogs_app_process_message(DialogsApp* app, DialogsAppMessage* message) { + switch(message->command) { + case DialogsAppCommandFileOpen: + message->return_data->bool_value = + dialogs_app_process_module_file_select(&message->data->file_select); + break; + case DialogsAppCommandDialog: + message->return_data->dialog_value = + dialogs_app_process_module_message(&message->data->dialog); + break; + } + API_LOCK_UNLOCK(message->semaphore); +} + +int32_t dialogs_app(void* p) { + DialogsApp* app = dialogs_app_alloc(); + furi_record_create("dialogs", app); + + DialogsAppMessage message; + while(1) { + if(osMessageQueueGet(app->message_queue, &message, NULL, osWaitForever) == osOK) { + dialogs_app_process_message(app, &message); + } + } + + return 0; +} \ No newline at end of file diff --git a/applications/dialogs/dialogs.h b/applications/dialogs/dialogs.h new file mode 100644 index 00000000..6c756148 --- /dev/null +++ b/applications/dialogs/dialogs.h @@ -0,0 +1,128 @@ +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************** COMMON ******************/ + +typedef struct DialogsApp DialogsApp; + +/****************** FILE SELECT ******************/ + +/** + * Shows and processes the file selection dialog + * @param context api pointer + * @param path path to directory + * @param extension file extension to be offered for selection + * @param selected_filename buffer where the selected filename will be saved + * @param selected_filename_size and the size of this buffer + * @param preselected_filename filename to be preselected + * @return bool whether a file was selected + */ +bool dialog_file_select_show( + DialogsApp* context, + const char* path, + const char* extension, + char* result, + uint8_t result_size, + const char* preselected_filename); + +/****************** MESSAGE ******************/ + +/** + * Message result type + */ +typedef enum { + DialogMessageButtonBack, + DialogMessageButtonLeft, + DialogMessageButtonCenter, + DialogMessageButtonRight, +} DialogMessageButton; + +/** + * Message struct + */ +typedef struct DialogMessage DialogMessage; + +/** + * Allocate and fill message + * @return DialogMessage* + */ +DialogMessage* dialog_message_alloc(); + +/** + * Free message struct + * @param message message pointer + */ +void dialog_message_free(DialogMessage* message); + +/** + * Set message text + * @param message message pointer + * @param text text, can be NULL if you don't want to display the text + * @param x x position + * @param y y position + * @param horizontal horizontal alignment + * @param vertical vertical alignment + */ +void dialog_message_set_text( + DialogMessage* message, + const char* text, + uint8_t x, + uint8_t y, + Align horizontal, + Align vertical); + +/** + * Set message header + * @param message message pointer + * @param text text, can be NULL if you don't want to display the header + * @param x x position + * @param y y position + * @param horizontal horizontal alignment + * @param vertical vertical alignment + */ +void dialog_message_set_header( + DialogMessage* message, + const char* text, + uint8_t x, + uint8_t y, + Align horizontal, + Align vertical); + +/** + * Set message icon + * @param message message pointer + * @param icon icon pointer, can be NULL if you don't want to display the icon + * @param x x position + * @param y y position + */ +void dialog_message_set_icon(DialogMessage* message, const Icon* icon, uint8_t x, uint8_t y); + +/** + * Set message buttons text, button text can be NULL if you don't want to display and process some buttons + * @param message message pointer + * @param left left button text, can be NULL if you don't want to display the left button + * @param center center button text, can be NULL if you don't want to display the center button + * @param right right button text, can be NULL if you don't want to display the right button + */ +void dialog_message_set_buttons( + DialogMessage* message, + const char* left, + const char* center, + const char* right); + +/** + * Show message from filled struct + * @param context api pointer + * @param message message struct pointer to be shown + * @return DialogMessageButton type + */ +DialogMessageButton dialog_message_show(DialogsApp* context, const DialogMessage* message); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/sd-filesystem/view_holder.h b/applications/dialogs/view-holder.h similarity index 100% rename from applications/sd-filesystem/view_holder.h rename to applications/dialogs/view-holder.h diff --git a/applications/sd-filesystem/view_holder.c b/applications/dialogs/view_holder.c similarity index 99% rename from applications/sd-filesystem/view_holder.c rename to applications/dialogs/view_holder.c index a7f82d79..c4e116ec 100644 --- a/applications/sd-filesystem/view_holder.c +++ b/applications/dialogs/view_holder.c @@ -1,4 +1,4 @@ -#include "view_holder.h" +#include "view-holder.h" #include struct ViewHolder { diff --git a/applications/dolphin/dolphin_state.c b/applications/dolphin/dolphin_state.c index d9429b45..99b561f1 100644 --- a/applications/dolphin/dolphin_state.c +++ b/applications/dolphin/dolphin_state.c @@ -1,10 +1,9 @@ #include "dolphin_state.h" - -#include +#include #include #include -#define DOLPHIN_STORE_KEY "dolphin_state" +#define DOLPHIN_STORE_KEY "/int/dolphin.state" #define DOLPHIN_STORE_HEADER_MAGIC 0xD0 #define DOLPHIN_STORE_HEADER_VERSION 0x01 #define DOLPHIN_LVL_THRESHOLD 20.0f @@ -34,24 +33,24 @@ typedef struct { } DolphinStore; struct DolphinState { - InternalStorage* internal_storage; + Storage* fs_api; DolphinStoreData data; }; DolphinState* dolphin_state_alloc() { DolphinState* dolphin_state = furi_alloc(sizeof(DolphinState)); - dolphin_state->internal_storage = furi_record_open("internal-storage"); + dolphin_state->fs_api = furi_record_open("storage"); return dolphin_state; } void dolphin_state_free(DolphinState* dolphin_state) { - furi_record_close("internal-storage"); + furi_record_close("storage"); free(dolphin_state); } bool dolphin_state_save(DolphinState* dolphin_state) { DolphinStore store; - FURI_LOG_I("dolphin-state", "Saving state to internal-storage"); + FURI_LOG_I("dolphin-state", "Saving state to \"%s\"", DOLPHIN_STORE_KEY); // Calculate checksum uint8_t* source = (uint8_t*)&dolphin_state->data; uint8_t checksum = 0; @@ -66,60 +65,95 @@ bool dolphin_state_save(DolphinState* dolphin_state) { store.header.timestamp = 0; // Set data store.data = dolphin_state->data; + // Store - int ret = internal_storage_write_key( - dolphin_state->internal_storage, DOLPHIN_STORE_KEY, (uint8_t*)&store, sizeof(DolphinStore)); - if(ret != sizeof(DolphinStore)) { - FURI_LOG_E("dolphin-state", "Save failed. Storage returned: %d", ret); - return false; + File* file = storage_file_alloc(dolphin_state->fs_api); + bool save_result = storage_file_open(file, DOLPHIN_STORE_KEY, FSAM_WRITE, FSOM_CREATE_ALWAYS); + + if(save_result) { + uint16_t bytes_count = storage_file_write(file, &store, sizeof(DolphinStore)); + + if(bytes_count != sizeof(DolphinStore)) { + save_result = false; + } } + if(!save_result) { + FURI_LOG_E( + "dolphin-state", + "Save failed. Storage returned: %s", + storage_file_get_error_desc(file)); + } + + storage_file_close(file); + storage_file_free(file); + FURI_LOG_I("dolphin-state", "Saved"); - return true; + return save_result; } bool dolphin_state_load(DolphinState* dolphin_state) { DolphinStore store; // Read Dolphin State Store - FURI_LOG_I("dolphin-state", "Loading state from internal-storage"); - int ret = internal_storage_read_key( - dolphin_state->internal_storage, DOLPHIN_STORE_KEY, (uint8_t*)&store, sizeof(DolphinStore)); - if(ret != sizeof(DolphinStore)) { - FURI_LOG_E("dolphin-state", "Load failed. Storage returned: %d", ret); - return false; + FURI_LOG_I("dolphin-state", "Loading state from \"%s\"", DOLPHIN_STORE_KEY); + + File* file = storage_file_alloc(dolphin_state->fs_api); + bool load_result = storage_file_open(file, DOLPHIN_STORE_KEY, FSAM_READ, FSOM_OPEN_EXISTING); + + if(load_result) { + uint16_t bytes_count = storage_file_read(file, &store, sizeof(DolphinStore)); + + if(bytes_count != sizeof(DolphinStore)) { + load_result = false; + } } - FURI_LOG_I("dolphin-state", "State loaded, verifying header"); - if(store.header.magic == DOLPHIN_STORE_HEADER_MAGIC && - store.header.version == DOLPHIN_STORE_HEADER_VERSION) { - FURI_LOG_I( - "dolphin-state", - "Magic(%d) and Version(%d) match", - store.header.magic, - store.header.version); - uint8_t checksum = 0; - const uint8_t* source = (const uint8_t*)&store.data; - for(size_t i = 0; i < sizeof(DolphinStoreData); i++) { - checksum += source[i]; - } - if(store.header.checksum == checksum) { - FURI_LOG_I("dolphin-state", "Checksum(%d) match", store.header.checksum); - dolphin_state->data = store.data; - return true; - } else { - FURI_LOG_E( - "dolphin-state", "Checksum(%d != %d) mismatch", store.header.checksum, checksum); - } - } else { + if(!load_result) { FURI_LOG_E( "dolphin-state", - "Magic(%d != %d) and Version(%d != %d) mismatch", - store.header.magic, - DOLPHIN_STORE_HEADER_MAGIC, - store.header.version, - DOLPHIN_STORE_HEADER_VERSION); + "Load failed. Storage returned: %s", + storage_file_get_error_desc(file)); + } else { + FURI_LOG_I("dolphin-state", "State loaded, verifying header"); + if(store.header.magic == DOLPHIN_STORE_HEADER_MAGIC && + store.header.version == DOLPHIN_STORE_HEADER_VERSION) { + FURI_LOG_I( + "dolphin-state", + "Magic(%d) and Version(%d) match", + store.header.magic, + store.header.version); + uint8_t checksum = 0; + const uint8_t* source = (const uint8_t*)&store.data; + for(size_t i = 0; i < sizeof(DolphinStoreData); i++) { + checksum += source[i]; + } + + if(store.header.checksum == checksum) { + FURI_LOG_I("dolphin-state", "Checksum(%d) match", store.header.checksum); + dolphin_state->data = store.data; + } else { + FURI_LOG_E( + "dolphin-state", + "Checksum(%d != %d) mismatch", + store.header.checksum, + checksum); + load_result = false; + } + } else { + FURI_LOG_E( + "dolphin-state", + "Magic(%d != %d) and Version(%d != %d) mismatch", + store.header.magic, + DOLPHIN_STORE_HEADER_MAGIC, + store.header.version, + DOLPHIN_STORE_HEADER_VERSION); + load_result = false; + } } - return false; + + storage_file_close(file); + storage_file_free(file); + return load_result; } void dolphin_state_clear(DolphinState* dolphin_state) { diff --git a/applications/gui/modules/file_select.c b/applications/gui/modules/file_select.c index 9c398865..1b68e46f 100644 --- a/applications/gui/modules/file_select.c +++ b/applications/gui/modules/file_select.c @@ -2,13 +2,14 @@ #include #include #include +#include #define FILENAME_COUNT 4 struct FileSelect { // public View* view; - FS_Api* fs_api; + Storage* fs_api; const char* path; const char* extension; @@ -180,6 +181,8 @@ static bool file_select_init_inner(FileSelect* file_select) { FileSelect* file_select_alloc() { FileSelect* file_select = furi_alloc(sizeof(FileSelect)); file_select->view = view_alloc(); + file_select->fs_api = furi_record_open("storage"); + view_set_context(file_select->view, file_select); view_allocate_model(file_select->view, ViewModelTypeLockFree, sizeof(FileSelectModel)); view_set_draw_callback(file_select->view, file_select_draw_callback); @@ -210,6 +213,7 @@ void file_select_free(FileSelect* file_select) { }); view_free(file_select->view); free(file_select); + furi_record_close("storage"); } View* file_select_get_view(FileSelect* file_select) { @@ -217,11 +221,6 @@ View* file_select_get_view(FileSelect* file_select) { return file_select->view; } -void file_select_set_api(FileSelect* file_select, FS_Api* fs_api) { - furi_assert(file_select); - file_select->fs_api = fs_api; -} - void file_select_set_callback(FileSelect* file_select, FileSelectCallback callback, void* context) { file_select->context = context; file_select->callback = callback; @@ -272,13 +271,12 @@ bool file_select_fill_strings(FileSelect* file_select) { furi_assert(file_select->extension); FileInfo file_info; - File directory; - bool result; - FS_Dir_Api* dir_api = &file_select->fs_api->dir; + File* directory = storage_file_alloc(file_select->fs_api); + uint8_t string_counter = 0; uint16_t file_counter = 0; const uint8_t name_length = 100; - char* name = calloc(name_length, sizeof(char)); + char* name = furi_alloc(name_length); uint16_t first_file_index = 0; with_view_model( @@ -287,59 +285,50 @@ bool file_select_fill_strings(FileSelect* file_select) { return false; }); - if(name == NULL) { - return false; - } - - result = dir_api->open(&directory, file_select->path); - - if(!result) { - dir_api->close(&directory); + if(!storage_dir_open(directory, file_select->path)) { + storage_dir_close(directory); + storage_file_free(directory); free(name); return false; } while(1) { - result = dir_api->read(&directory, &file_info, name, name_length); - - if(directory.error_id == FSE_NOT_EXIST || name[0] == 0) { + if(!storage_dir_read(directory, &file_info, name, name_length)) { break; } - if(result) { - if(directory.error_id == FSE_OK) { - if(filter_file(file_select, &file_info, name)) { - if(file_counter >= first_file_index) { - with_view_model( - file_select->view, (FileSelectModel * model) { - string_set_str(model->filename[string_counter], name); + if(storage_file_get_error(directory) == FSE_OK) { + if(filter_file(file_select, &file_info, name)) { + if(file_counter >= first_file_index) { + with_view_model( + file_select->view, (FileSelectModel * model) { + string_set_str(model->filename[string_counter], name); - if(strcmp(file_select->extension, "*") != 0) { - string_replace_all_str( - model->filename[string_counter], - file_select->extension, - ""); - } + if(strcmp(file_select->extension, "*") != 0) { + string_replace_all_str( + model->filename[string_counter], file_select->extension, ""); + } - return true; - }); - string_counter++; + return true; + }); + string_counter++; - if(string_counter >= FILENAME_COUNT) { - break; - } + if(string_counter >= FILENAME_COUNT) { + break; } - file_counter++; } - } else { - dir_api->close(&directory); - free(name); - return false; + file_counter++; } + } else { + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return false; } } - dir_api->close(&directory); + storage_dir_close(directory); + storage_file_free(directory); free(name); return true; } @@ -351,42 +340,33 @@ bool file_select_fill_count(FileSelect* file_select) { furi_assert(file_select->extension); FileInfo file_info; - File directory; - bool result; - FS_Dir_Api* dir_api = &file_select->fs_api->dir; + File* directory = storage_file_alloc(file_select->fs_api); + uint16_t file_counter = 0; const uint8_t name_length = 100; - char* name = calloc(name_length, sizeof(char)); + char* name = furi_alloc(name_length); - if(name == NULL) { - return false; - } - - result = dir_api->open(&directory, file_select->path); - - if(!result) { - dir_api->close(&directory); + if(!storage_dir_open(directory, file_select->path)) { + storage_dir_close(directory); + storage_file_free(directory); free(name); return false; } while(1) { - result = dir_api->read(&directory, &file_info, name, name_length); - - if(directory.error_id == FSE_NOT_EXIST || name[0] == 0) { + if(!storage_dir_read(directory, &file_info, name, name_length)) { break; } - if(result) { - if(directory.error_id == FSE_OK) { - if(filter_file(file_select, &file_info, name)) { - file_counter++; - } - } else { - dir_api->close(&directory); - free(name); - return false; + if(storage_file_get_error(directory) == FSE_OK) { + if(filter_file(file_select, &file_info, name)) { + file_counter++; } + } else { + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return false; } } @@ -396,7 +376,8 @@ bool file_select_fill_count(FileSelect* file_select) { return false; }); - dir_api->close(&directory); + storage_dir_close(directory); + storage_file_free(directory); free(name); return true; } @@ -411,16 +392,10 @@ void file_select_set_selected_file_internal(FileSelect* file_select, const char* if(strlen(filename) == 0) return; FileInfo file_info; - File directory; - bool result; - FS_Dir_Api* dir_api = &file_select->fs_api->dir; + File* directory = storage_file_alloc(file_select->fs_api); + const uint8_t name_length = 100; - char* name = calloc(name_length, sizeof(char)); - - if(name == NULL) { - return; - } - + char* name = furi_alloc(name_length); uint16_t file_position = 0; bool file_found = false; @@ -430,38 +405,34 @@ void file_select_set_selected_file_internal(FileSelect* file_select, const char* string_cat_str(filename_str, file_select->extension); } - result = dir_api->open(&directory, file_select->path); - - if(!result) { + if(!storage_dir_open(directory, file_select->path)) { string_clear(filename_str); - dir_api->close(&directory); + storage_dir_close(directory); + storage_file_free(directory); free(name); return; } while(1) { - result = dir_api->read(&directory, &file_info, name, name_length); - - if(directory.error_id == FSE_NOT_EXIST || name[0] == 0) { + if(!storage_dir_read(directory, &file_info, name, name_length)) { break; } - if(result) { - if(directory.error_id == FSE_OK) { - if(filter_file(file_select, &file_info, name)) { - if(strcmp(string_get_cstr(filename_str), name) == 0) { - file_found = true; - break; - } - - file_position++; + if(storage_file_get_error(directory) == FSE_OK) { + if(filter_file(file_select, &file_info, name)) { + if(strcmp(string_get_cstr(filename_str), name) == 0) { + file_found = true; + break; } - } else { - string_clear(filename_str); - dir_api->close(&directory); - free(name); - return; + + file_position++; } + } else { + string_clear(filename_str); + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return; } } @@ -488,7 +459,8 @@ void file_select_set_selected_file_internal(FileSelect* file_select, const char* } string_clear(filename_str); - dir_api->close(&directory); + storage_dir_close(directory); + storage_file_free(directory); free(name); } diff --git a/applications/gui/modules/file_select.h b/applications/gui/modules/file_select.h index 26a64cd6..5f666d5a 100644 --- a/applications/gui/modules/file_select.h +++ b/applications/gui/modules/file_select.h @@ -1,6 +1,5 @@ #pragma once #include -#include #ifdef __cplusplus extern "C" { @@ -15,7 +14,6 @@ FileSelect* file_select_alloc(); void file_select_free(FileSelect* file_select); View* file_select_get_view(FileSelect* file_select); -void file_select_set_api(FileSelect* file_select, FS_Api* fs_api); void file_select_set_callback(FileSelect* file_select, FileSelectCallback callback, void* context); void file_select_set_filter(FileSelect* file_select, const char* path, const char* extension); void file_select_set_result_buffer(FileSelect* file_select, char* buffer, uint8_t buffer_size); diff --git a/applications/ibutton/ibutton-app.cpp b/applications/ibutton/ibutton-app.cpp index a154b762..46b0516b 100644 --- a/applications/ibutton/ibutton-app.cpp +++ b/applications/ibutton/ibutton-app.cpp @@ -5,7 +5,7 @@ #include #include -const char* iButtonApp::app_folder = "ibutton"; +const char* iButtonApp::app_folder = "/any/ibutton"; const char* iButtonApp::app_extension = ".ibtn"; void iButtonApp::run(void* args) { @@ -13,6 +13,8 @@ void iButtonApp::run(void* args) { bool consumed; bool exit = false; + make_app_folder(); + if(args && load_key((const char*)args)) { current_scene = Scene::SceneEmulate; } @@ -218,15 +220,13 @@ void iButtonApp::generate_random_name(char* name, uint8_t max_name_size) { // file managment bool iButtonApp::save_key(const char* key_name) { + // Create ibutton directory if necessary + make_app_folder(); + FileWorkerCpp file_worker; string_t key_file_name; bool result = false; - // Create ibutton directory if necessary - if(!file_worker.mkdir(app_folder)) { - return false; - }; - // First remove key if it was saved string_init_printf(key_file_name, "%s/%s%s", app_folder, get_key()->get_name(), app_extension); if(!file_worker.remove(string_get_cstr(key_file_name))) { @@ -370,4 +370,9 @@ bool iButtonApp::delete_key() { string_clear(file_name); return result; +} + +void iButtonApp::make_app_folder() { + FileWorkerCpp file_worker; + file_worker.mkdir(app_folder); } \ No newline at end of file diff --git a/applications/ibutton/ibutton-app.h b/applications/ibutton/ibutton-app.h index 4da97ebf..27ed3a68 100644 --- a/applications/ibutton/ibutton-app.h +++ b/applications/ibutton/ibutton-app.h @@ -25,9 +25,6 @@ #include "helpers/key-worker.h" -#include -#include - #include "one_wire_master.h" #include "maxim_crc.h" #include "ibutton-key.h" @@ -142,4 +139,5 @@ private: static const char* app_extension; bool load_key_data(string_t key_path); + void make_app_folder(); }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton-scene-save-name.cpp b/applications/ibutton/scene/ibutton-scene-save-name.cpp index 75676a80..2d41cc41 100644 --- a/applications/ibutton/scene/ibutton-scene-save-name.cpp +++ b/applications/ibutton/scene/ibutton-scene-save-name.cpp @@ -4,7 +4,6 @@ #include "../ibutton-event.h" #include "../ibutton-key.h" #include -#include void iButtonSceneSaveName::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); diff --git a/applications/ibutton/scene/ibutton-scene-start.cpp b/applications/ibutton/scene/ibutton-scene-start.cpp index 168ace47..ba0ff15f 100644 --- a/applications/ibutton/scene/ibutton-scene-start.cpp +++ b/applications/ibutton/scene/ibutton-scene-start.cpp @@ -3,7 +3,6 @@ #include "../ibutton-view-manager.h" #include "../ibutton-event.h" #include -#include typedef enum { SubmenuIndexRead, diff --git a/applications/internal-storage/internal-storage-i.h b/applications/internal-storage/internal-storage-i.h deleted file mode 100644 index c8b3ac8d..00000000 --- a/applications/internal-storage/internal-storage-i.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "internal-storage.h" -#include -#include -#include - -#define INTERNAL_STORAGE_THREAD_FLAG_CALL_COMPLETE (1) - -struct InternalStorage { - osMessageQueueId_t queue; - InternalStorageState state; - const size_t start_address; - const size_t start_page; - struct lfs_config config; - lfs_t lfs; -}; - -typedef struct { - const char* key; - uint8_t* buffer; - size_t size; - int ret; -} InternalStorageCommandKey; - -typedef void (*InternalStorageCommandFunction)(InternalStorage* internal_storage, void* data); - -typedef struct { - osThreadId thread; - InternalStorageCommandFunction function; - void* data; -} InternalStorageCommand; - -int internal_storage_device_read( - const struct lfs_config* c, - lfs_block_t block, - lfs_off_t off, - void* buffer, - lfs_size_t size); - -int internal_storage_device_prog( - const struct lfs_config* c, - lfs_block_t block, - lfs_off_t off, - const void* buffer, - lfs_size_t size); - -int internal_storage_device_erase(const struct lfs_config* c, lfs_block_t block); - -int internal_storage_device_sync(const struct lfs_config* c); - -InternalStorage* internal_storage_alloc(); - -void internal_storage_free(InternalStorage* internal_storage); - -int32_t internal_storage_task(void* p); - -void _internal_storage_read_key(InternalStorage* internal_storage, InternalStorageCommandKey* data); - -void _internal_storage_write_key( - InternalStorage* internal_storage, - InternalStorageCommandKey* data); diff --git a/applications/internal-storage/internal-storage.c b/applications/internal-storage/internal-storage.c deleted file mode 100644 index 32867bd3..00000000 --- a/applications/internal-storage/internal-storage.c +++ /dev/null @@ -1,252 +0,0 @@ -#include "internal-storage-i.h" - -int internal_storage_device_read( - const struct lfs_config* c, - lfs_block_t block, - lfs_off_t off, - void* buffer, - lfs_size_t size) { - InternalStorage* internal_storage = c->context; - size_t address = internal_storage->start_address + block * c->block_size + off; - - FURI_LOG_D( - "internal-storage", - "Device read: block %d, off %d, buffer: %p, size %d, translated address: %p", - block, - off, - buffer, - size, - address); - - memcpy(buffer, (void*)address, size); - - return 0; -} - -int internal_storage_device_prog( - const struct lfs_config* c, - lfs_block_t block, - lfs_off_t off, - const void* buffer, - lfs_size_t size) { - InternalStorage* internal_storage = c->context; - size_t address = internal_storage->start_address + block * c->block_size + off; - - FURI_LOG_D( - "internal-storage", - "Device prog: block %d, off %d, buffer: %p, size %d, translated address: %p", - block, - off, - buffer, - size, - address); - - int ret = 0; - while(size > 0) { - if(!api_hal_flash_write_dword(address, *(uint64_t*)buffer)) { - ret = -1; - break; - } - address += c->prog_size; - buffer += c->prog_size; - size -= c->prog_size; - } - - return ret; -} - -int internal_storage_device_erase(const struct lfs_config* c, lfs_block_t block) { - InternalStorage* internal_storage = c->context; - size_t page = internal_storage->start_page + block; - - FURI_LOG_D("internal-storage", "Device erase: page %d, translated page: %d", block, page); - - if(api_hal_flash_erase(page, 1)) { - return 0; - } else { - return -1; - } -} - -int internal_storage_device_sync(const struct lfs_config* c) { - FURI_LOG_D("internal-storage", "Device sync: skipping, cause "); - return 0; -} - -InternalStorage* internal_storage_alloc() { - InternalStorage* internal_storage = furi_alloc(sizeof(InternalStorage)); - - internal_storage->queue = osMessageQueueNew(8, sizeof(InternalStorageCommand), NULL); - - // Internal storage start address - internal_storage->state = InternalStorageStateInitializing; - - // Internal storage start address - *(size_t*)(&internal_storage->start_address) = api_hal_flash_get_free_page_start_address(); - *(size_t*)(&internal_storage->start_page) = - (internal_storage->start_address - api_hal_flash_get_base()) / - api_hal_flash_get_page_size(); - - // LFS configuration - // Glue and context - internal_storage->config.context = internal_storage; - internal_storage->config.read = internal_storage_device_read; - internal_storage->config.prog = internal_storage_device_prog; - internal_storage->config.erase = internal_storage_device_erase; - internal_storage->config.sync = internal_storage_device_sync; - // Block device description - internal_storage->config.read_size = api_hal_flash_get_read_block_size(); - internal_storage->config.prog_size = api_hal_flash_get_write_block_size(); - internal_storage->config.block_size = api_hal_flash_get_page_size(); - internal_storage->config.block_count = api_hal_flash_get_free_page_count(); - internal_storage->config.block_cycles = api_hal_flash_get_cycles_count(); - internal_storage->config.cache_size = 16; - internal_storage->config.lookahead_size = 16; - - return internal_storage; -} - -void internal_storage_free(InternalStorage* internal_storage) { - furi_assert(internal_storage); - free(internal_storage); -} - -int32_t internal_storage_task(void* p) { - FURI_LOG_I("internal-storage", "Starting"); - InternalStorage* internal_storage = internal_storage_alloc(); - FURI_LOG_I( - "internal-storage", - "Config: start %p, read %d, write %d, page size: %d, page count: %d, cycles: %d", - internal_storage->start_address, - internal_storage->config.read_size, - internal_storage->config.prog_size, - internal_storage->config.block_size, - internal_storage->config.block_count, - internal_storage->config.block_cycles); - - int err; - ApiHalBootFlag boot_flags = api_hal_boot_get_flags(); - if(boot_flags & ApiHalBootFlagFactoryReset) { - // Factory reset - err = lfs_format(&internal_storage->lfs, &internal_storage->config); - if(err == 0) { - FURI_LOG_I("internal-storage", "Factory reset: Format successful, trying to mount"); - api_hal_boot_set_flags(boot_flags & ~ApiHalBootFlagFactoryReset); - err = lfs_mount(&internal_storage->lfs, &internal_storage->config); - if(err == 0) { - FURI_LOG_I("internal-storage", "Factory reset: Mounted"); - internal_storage->state = InternalStorageStateReady; - } else { - FURI_LOG_E("internal-storage", "Factory reset: Mount after format failed"); - internal_storage->state = InternalStorageStateBroken; - } - } else { - FURI_LOG_E("internal-storage", "Factory reset: Format failed"); - internal_storage->state = InternalStorageStateBroken; - } - } else { - // Normal - err = lfs_mount(&internal_storage->lfs, &internal_storage->config); - if(err == 0) { - FURI_LOG_I("internal-storage", "Mounted"); - internal_storage->state = InternalStorageStateReady; - } else { - FURI_LOG_E("internal-storage", "Mount failed, formatting"); - err = lfs_format(&internal_storage->lfs, &internal_storage->config); - if(err == 0) { - FURI_LOG_I("internal-storage", "Format successful, trying to mount"); - err = lfs_mount(&internal_storage->lfs, &internal_storage->config); - if(err == 0) { - FURI_LOG_I("internal-storage", "Mounted"); - internal_storage->state = InternalStorageStateReady; - } else { - FURI_LOG_E("internal-storage", "Mount after format failed"); - internal_storage->state = InternalStorageStateBroken; - } - } else { - FURI_LOG_E("internal-storage", "Format failed"); - internal_storage->state = InternalStorageStateBroken; - } - } - } - - furi_record_create("internal-storage", internal_storage); - - InternalStorageCommand command; - while(1) { - furi_check( - osMessageQueueGet(internal_storage->queue, &command, NULL, osWaitForever) == osOK); - command.function(internal_storage, command.data); - osThreadFlagsSet(command.thread, INTERNAL_STORAGE_THREAD_FLAG_CALL_COMPLETE); - } - - lfs_unmount(&internal_storage->lfs); - internal_storage_free(internal_storage); - - return 0; -} - -void _internal_storage_read_key(InternalStorage* internal_storage, InternalStorageCommandKey* data) { - lfs_file_t file; - int ret = lfs_file_open(&internal_storage->lfs, &file, data->key, LFS_O_RDONLY); - if(ret == 0) { - ret = lfs_file_read(&internal_storage->lfs, &file, data->buffer, data->size); - lfs_file_close(&internal_storage->lfs, &file); - } - data->ret = ret; -} - -int internal_storage_read_key( - InternalStorage* internal_storage, - const char* key, - uint8_t* buffer, - size_t size) { - osThreadId_t caller_thread = osThreadGetId(); - if(caller_thread == 0) { - return -1; - } - - InternalStorageCommandKey data = {.key = key, .buffer = buffer, .size = size, .ret = 0}; - InternalStorageCommand command = { - .thread = caller_thread, - .function = (InternalStorageCommandFunction)_internal_storage_read_key, - .data = &data, - }; - furi_check(osMessageQueuePut(internal_storage->queue, &command, 0, osWaitForever) == osOK); - osThreadFlagsWait(INTERNAL_STORAGE_THREAD_FLAG_CALL_COMPLETE, osFlagsWaitAny, osWaitForever); - return data.ret; -} - -void _internal_storage_write_key( - InternalStorage* internal_storage, - InternalStorageCommandKey* data) { - lfs_file_t file; - int ret = lfs_file_open( - &internal_storage->lfs, &file, data->key, LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC); - if(ret == 0) { - ret = lfs_file_write(&internal_storage->lfs, &file, data->buffer, data->size); - lfs_file_close(&internal_storage->lfs, &file); - } - data->ret = ret; -} - -int internal_storage_write_key( - InternalStorage* internal_storage, - const char* key, - uint8_t* buffer, - size_t size) { - osThreadId_t caller_thread = osThreadGetId(); - if(caller_thread == 0) { - return -1; - } - - InternalStorageCommandKey data = {.key = key, .buffer = buffer, .size = size, .ret = 0}; - InternalStorageCommand command = { - .thread = caller_thread, - .function = (InternalStorageCommandFunction)_internal_storage_write_key, - .data = &data, - }; - furi_check(osMessageQueuePut(internal_storage->queue, &command, 0, osWaitForever) == osOK); - osThreadFlagsWait(INTERNAL_STORAGE_THREAD_FLAG_CALL_COMPLETE, osFlagsWaitAny, osWaitForever); - return data.ret; -} diff --git a/applications/internal-storage/internal-storage.h b/applications/internal-storage/internal-storage.h deleted file mode 100644 index 5d0a2018..00000000 --- a/applications/internal-storage/internal-storage.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -#include -#include - -/* Internal storage state */ -typedef enum { - InternalStorageStateInitializing, - InternalStorageStateReady, - InternalStorageStateBroken, -} InternalStorageState; - -typedef struct InternalStorage InternalStorage; - -/** Read key, blocking api - * @param internal_storage - InternalStorage instance - * @param key - file name to read data from - * @param buffer - pointer to data buffer - * @param size - buffer size - * @return negative on error, otherwise data read - */ -int internal_storage_read_key( - InternalStorage* internal_storage, - const char* key, - uint8_t* buffer, - size_t size); - -/** Write key, blocking api - * @param internal_storage - InternalStorage instance - * @param key - file name to store data to - * @param buffer - pointer to data buffer - * @param size - buffer size - * @return negative on error, otherwise data written - */ -int internal_storage_write_key( - InternalStorage* internal_storage, - const char* key, - uint8_t* buffer, - size_t size); diff --git a/applications/irda/irda-app-brute-force.hpp b/applications/irda/irda-app-brute-force.hpp index a7794301..ef9ab80d 100644 --- a/applications/irda/irda-app-brute-force.hpp +++ b/applications/irda/irda-app-brute-force.hpp @@ -6,7 +6,6 @@ class IrdaAppBruteForce { const char* universal_db_filename; - File file; std::string current_record; std::unique_ptr file_parser; diff --git a/applications/irda/irda-app-file-parser.cpp b/applications/irda/irda-app-file-parser.cpp index 288100ae..11fd563e 100644 --- a/applications/irda/irda-app-file-parser.cpp +++ b/applications/irda/irda-app-file-parser.cpp @@ -13,7 +13,7 @@ #include uint32_t const IrdaAppFileParser::max_line_length = ((9 + 1) * 512 + 100); -const char* IrdaAppFileParser::irda_directory = "/irda"; +const char* IrdaAppFileParser::irda_directory = "/any/irda"; const char* IrdaAppFileParser::irda_extension = ".ir"; uint32_t const IrdaAppFileParser::max_raw_timings_in_signal = 512; diff --git a/applications/irda/irda-app-file-parser.hpp b/applications/irda/irda-app-file-parser.hpp index 1195f8c3..2ece1a30 100644 --- a/applications/irda/irda-app-file-parser.hpp +++ b/applications/irda/irda-app-file-parser.hpp @@ -1,8 +1,8 @@ #pragma once -#include #include #include #include "irda-app-signal.h" +#include class IrdaAppFileParser { public: diff --git a/applications/irda/irda-app-remote-manager.cpp b/applications/irda/irda-app-remote-manager.cpp index 3536b074..4c339e85 100644 --- a/applications/irda/irda-app-remote-manager.cpp +++ b/applications/irda/irda-app-remote-manager.cpp @@ -1,5 +1,5 @@ #include "irda-app-remote-manager.hpp" -#include "filesystem-api.h" +#include #include "furi.h" #include "furi/check.h" #include "gui/modules/button_menu.h" diff --git a/applications/irda/irda-app-remote-manager.hpp b/applications/irda/irda-app-remote-manager.hpp index 1d835ca7..e8e0a48c 100644 --- a/applications/irda/irda-app-remote-manager.hpp +++ b/applications/irda/irda-app-remote-manager.hpp @@ -5,8 +5,7 @@ #include #include #include -#include -#include +#include #include "irda-app-signal.h" class IrdaAppRemoteButton { diff --git a/applications/irda/scene/irda-app-scene.hpp b/applications/irda/scene/irda-app-scene.hpp index a90f5f49..3b110901 100644 --- a/applications/irda/scene/irda-app-scene.hpp +++ b/applications/irda/scene/irda-app-scene.hpp @@ -148,14 +148,16 @@ protected: class IrdaAppSceneUniversalTV : public IrdaAppSceneUniversalCommon { public: void on_enter(IrdaApp* app) final; - IrdaAppSceneUniversalTV() : IrdaAppSceneUniversalCommon("/assets/ext/irda/tv.ir") {} + IrdaAppSceneUniversalTV() + : IrdaAppSceneUniversalCommon("/ext/irda/universal/tv.ir") { + } ~IrdaAppSceneUniversalTV() {} }; class IrdaAppSceneUniversalAudio : public IrdaAppSceneUniversalCommon { public: void on_enter(IrdaApp* app) final; - IrdaAppSceneUniversalAudio() : IrdaAppSceneUniversalCommon("/assets/ext/irda/audio.ir") {} + IrdaAppSceneUniversalAudio() : IrdaAppSceneUniversalCommon("/ext/irda/universal/audio.ir") {} ~IrdaAppSceneUniversalAudio() {} }; diff --git a/applications/lfrfid/lfrfid-app.cpp b/applications/lfrfid/lfrfid-app.cpp index 8fd0354e..351aec49 100644 --- a/applications/lfrfid/lfrfid-app.cpp +++ b/applications/lfrfid/lfrfid-app.cpp @@ -19,13 +19,11 @@ #include #include -const char* LfRfidApp::app_folder = "lfrfid"; +const char* LfRfidApp::app_folder = "/any/lfrfid"; const char* LfRfidApp::app_extension = ".rfid"; LfRfidApp::LfRfidApp() : scene_controller{this} - , fs_api{"sdcard"} - , sd_ex_api{"sdcard-ex"} , notification{"notification"} , text_store(40) { api_hal_power_insomnia_enter(); @@ -41,6 +39,8 @@ LfRfidApp::~LfRfidApp() { void LfRfidApp::run(void* _args) { const char* args = reinterpret_cast(_args); + make_app_folder(); + if(strlen(args)) { load_key_data(args, &worker.key); scene_controller.add_scene(SceneType::Emulate, new LfRfidAppSceneEmulate()); diff --git a/applications/lfrfid/lfrfid-app.h b/applications/lfrfid/lfrfid-app.h index 823c81ff..cc126410 100644 --- a/applications/lfrfid/lfrfid-app.h +++ b/applications/lfrfid/lfrfid-app.h @@ -15,8 +15,6 @@ #include #include "view/container-vm.h" -#include -#include #include #include "helpers/rfid-worker.h" @@ -64,8 +62,6 @@ public: ~LfRfidApp(); LfRfidApp(); - RecordController fs_api; - RecordController sd_ex_api; RecordController notification; RfidWorker worker; diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 9ec39ccc..85649264 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -183,7 +183,7 @@ static void loader_build_menu() { menu, menu_item_alloc_function( FLIPPER_APPS[i].name, - icon_animation_alloc(FLIPPER_APPS[i].icon), + FLIPPER_APPS[i].icon ? icon_animation_alloc(FLIPPER_APPS[i].icon) : NULL, loader_menu_callback, (void*)&FLIPPER_APPS[i])); @@ -213,7 +213,8 @@ static void loader_build_menu() { menu_plugins, menu_item_alloc_function( FLIPPER_PLUGINS[i].name, - icon_animation_alloc(FLIPPER_PLUGINS[i].icon), + FLIPPER_PLUGINS[i].icon ? icon_animation_alloc(FLIPPER_PLUGINS[i].icon) : + NULL, loader_menu_callback, (void*)&FLIPPER_PLUGINS[i])); @@ -245,7 +246,9 @@ static void loader_build_menu() { menu_debug, menu_item_alloc_function( FLIPPER_DEBUG_APPS[i].name, - icon_animation_alloc(FLIPPER_DEBUG_APPS[i].icon), + FLIPPER_DEBUG_APPS[i].icon ? + icon_animation_alloc(FLIPPER_DEBUG_APPS[i].icon) : + NULL, loader_menu_callback, (void*)&FLIPPER_DEBUG_APPS[i])); @@ -277,7 +280,9 @@ static void loader_build_menu() { menu_debug, menu_item_alloc_function( FLIPPER_SETTINGS_APPS[i].name, - icon_animation_alloc(FLIPPER_SETTINGS_APPS[i].icon), + FLIPPER_SETTINGS_APPS[i].icon ? + icon_animation_alloc(FLIPPER_SETTINGS_APPS[i].icon) : + NULL, loader_menu_callback, (void*)&FLIPPER_SETTINGS_APPS[i])); } diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c index 7037044a..d22e63e7 100755 --- a/applications/nfc/nfc_device.c +++ b/applications/nfc/nfc_device.c @@ -6,7 +6,7 @@ #define NFC_DEVICE_MAX_DATA_LEN 14 -static const char* nfc_app_folder = "nfc"; +static const char* nfc_app_folder = "/any/nfc"; static const char* nfc_app_extension = ".nfc"; static bool nfc_device_read_hex(string_t str, uint8_t* buff, uint16_t len) { diff --git a/applications/notification/notification-app.c b/applications/notification/notification-app.c index c5193a91..ffc90487 100644 --- a/applications/notification/notification-app.c +++ b/applications/notification/notification-app.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "notification.h" #include "notification-messages.h" #include "notification-app.h" @@ -309,24 +309,30 @@ void notification_process_internal_message(NotificationApp* app, NotificationApp } } -static void notification_load_settings(NotificationApp* app) { +static bool notification_load_settings(NotificationApp* app) { NotificationSettings settings; - InternalStorage* internal_storage = furi_record_open("internal-storage"); + File* file = storage_file_alloc(furi_record_open("storage")); const size_t settings_size = sizeof(NotificationSettings); - FURI_LOG_I("notification", "Loading state from internal-storage"); - int ret = internal_storage_read_key( - internal_storage, NOTIFICATION_SETTINGS_PATH, (uint8_t*)&settings, settings_size); + FURI_LOG_I("notification", "loading settings from \"%s\"", NOTIFICATION_SETTINGS_PATH); + bool fs_result = + storage_file_open(file, NOTIFICATION_SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING); - if(ret != settings_size) { - FURI_LOG_E("notification", "Load failed. Storage returned: %d", ret); - } else { - FURI_LOG_I("notification", "Load success", ret); + if(fs_result) { + uint16_t bytes_count = storage_file_read(file, &settings, settings_size); + + if(bytes_count != settings_size) { + fs_result = false; + } + } + + if(fs_result) { + FURI_LOG_I("notification", "load success"); if(settings.version != NOTIFICATION_SETTINGS_VERSION) { FURI_LOG_E( "notification", - "Version(%d != %d) mismatch", + "version(%d != %d) mismatch", app->settings.version, NOTIFICATION_SETTINGS_VERSION); } else { @@ -334,26 +340,50 @@ static void notification_load_settings(NotificationApp* app) { memcpy(&app->settings, &settings, settings_size); osKernelUnlock(); } + } else { + FURI_LOG_E("notification", "load failed, %s", storage_file_get_error_desc(file)); } - furi_record_close("internal-storage"); + storage_file_close(file); + storage_file_free(file); + furi_record_close("storage"); + + return fs_result; }; -static void notification_save_settings(NotificationApp* app) { - InternalStorage* internal_storage = furi_record_open("internal-storage"); +static bool notification_save_settings(NotificationApp* app) { + NotificationSettings settings; + File* file = storage_file_alloc(furi_record_open("storage")); const size_t settings_size = sizeof(NotificationSettings); - FURI_LOG_I("notification", "Saving state to internal-storage"); - int ret = internal_storage_write_key( - internal_storage, NOTIFICATION_SETTINGS_PATH, (uint8_t*)&app->settings, settings_size); + FURI_LOG_I("notification", "saving settings to \"%s\"", NOTIFICATION_SETTINGS_PATH); - if(ret != settings_size) { - FURI_LOG_E("notification", "Save failed. Storage returned: %d", ret); - } else { - FURI_LOG_I("notification", "Saved"); + osKernelLock(); + memcpy(&settings, &app->settings, settings_size); + osKernelUnlock(); + + bool fs_result = + storage_file_open(file, NOTIFICATION_SETTINGS_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS); + + if(fs_result) { + uint16_t bytes_count = storage_file_write(file, &settings, settings_size); + + if(bytes_count != settings_size) { + fs_result = false; + } } - furi_record_close("internal-storage"); + if(fs_result) { + FURI_LOG_I("notification", "save success"); + } else { + FURI_LOG_E("notification", "save failed, %s", storage_file_get_error_desc(file)); + } + + storage_file_close(file); + storage_file_free(file); + furi_record_close("storage"); + + return fs_result; }; static void input_event_callback(const void* value, void* context) { @@ -407,7 +437,9 @@ static NotificationApp* notification_app_alloc() { int32_t notification_app(void* p) { NotificationApp* app = notification_app_alloc(); - notification_load_settings(app); + if(!notification_load_settings(app)) { + notification_save_settings(app); + } notification_vibro_off(); notification_sound_off(); diff --git a/applications/notification/notification-app.h b/applications/notification/notification-app.h index 38f2504e..a6e5ba84 100644 --- a/applications/notification/notification-app.h +++ b/applications/notification/notification-app.h @@ -31,7 +31,7 @@ typedef struct { } NotificationLedLayer; #define NOTIFICATION_SETTINGS_VERSION 0x01 -#define NOTIFICATION_SETTINGS_PATH "notification_settings" +#define NOTIFICATION_SETTINGS_PATH "/int/notification.settings" typedef struct { uint8_t version; diff --git a/applications/sd-card-test/sd-card-test.cpp b/applications/sd-card-test/sd-card-test.cpp deleted file mode 100644 index 5183f8e8..00000000 --- a/applications/sd-card-test/sd-card-test.cpp +++ /dev/null @@ -1,892 +0,0 @@ -#include "app-template.h" -#include "stm32_adafruit_sd.h" -#include "fnv1a-hash.h" -#include "filesystem-api.h" -#include "cli/cli.h" -#include "callback-connector.h" -#include - -// event enumeration type -typedef uint8_t event_t; - -class SdTestState { -public: - // state data - static const uint8_t lines_count = 6; - const char* line[lines_count]; - - // state initializer - SdTestState() { - for(uint8_t i = 0; i < lines_count; i++) { - line[i] = ""; - } - } -}; - -// events class -class SdTestEvent { -public: - // events enum - static const event_t EventTypeTick = 0; - static const event_t EventTypeKey = 1; - - // payload - union { - InputEvent input; - } value; - - // event type - event_t type; -}; - -// our app derived from base AppTemplate class -// with template variables -class SdTest : public AppTemplate { -public: - // vars - const uint32_t benchmark_data_size = 4096; - uint8_t* benchmark_data; - FS_Api* fs_api; - NotificationApp* notification; - - // consts - static const uint32_t BENCHMARK_ERROR = UINT_MAX; - - // funcs - void run(); - void render(Canvas* canvas); - template void set_text(std::initializer_list list); - template void set_error(std::initializer_list list); - void wait_for_button(InputKey input_button); - bool ask(InputKey input_button_cancel, InputKey input_button_ok); - void blink_red(); - void blink_green(); - - // "tests" - void detect_sd_card(); - void show_warning(); - void get_sd_card_info(); - - bool prepare_benchmark_data(); - void free_benchmark_data(); - void write_benchmark(); - uint32_t - write_benchmark_internal(const uint32_t size, const uint32_t tcount, bool silent = false); - - void read_benchmark(); - uint32_t read_benchmark_internal( - const uint32_t size, - const uint32_t count, - File* file, - bool silent = false); - - void hash_benchmark(); - - // cli tests - void cli_read_benchmark(Cli* cli, string_t args, void* _ctx); - void cli_write_benchmark(Cli* cli, string_t args, void* _ctx); -}; - -// start app -void SdTest::run() { - app_ready(); - - fs_api = static_cast(furi_record_open("sdcard")); - notification = static_cast(furi_record_open("notification")); - - if(fs_api == NULL) { - set_error({"cannot get sdcard api"}); - exit(); - } - - Cli* cli = static_cast(furi_record_open("cli")); - - // read_benchmark and write_benchmark signatures are same. so we must use tags - auto cli_read_cb = cbc::obtain_connector<0>(this, &SdTest::cli_read_benchmark); - cli_add_command(cli, "sd_read_test", CliCommandFlagDefault, cli_read_cb, this); - - auto cli_write_cb = cbc::obtain_connector<1>(this, &SdTest::cli_write_benchmark); - cli_add_command(cli, "sd_write_test", CliCommandFlagDefault, cli_write_cb, this); - - detect_sd_card(); - get_sd_card_info(); - show_warning(); - - set_text({"preparing benchmark data"}); - bool data_prepared = prepare_benchmark_data(); - if(data_prepared) { - set_text({"benchmark data prepared"}); - } else { - set_error({"cannot allocate buffer", "for benchmark data"}); - } - - write_benchmark(); - read_benchmark(); - hash_benchmark(); - free_benchmark_data(); - - set_text({ - "test complete", - "", - "", - "", - "", - "press BACK to exit", - }); - wait_for_button(InputKeyBack); - - furi_record_close("notification"); - exit(); -} - -// detect sd card insertion -void SdTest::detect_sd_card() { - const uint8_t str_buffer_size = 40; - const uint8_t dots_animation_size = 4; - char str_buffer[str_buffer_size]; - const char dots[dots_animation_size][4] = {"", ".", "..", "..."}; - uint8_t i = 0; - - // detect sd card pin - while(fs_api->common.get_fs_info(NULL, NULL) == FSE_NOT_READY) { - delay(100); - - snprintf(str_buffer, str_buffer_size, "Waiting%s", dots[i]); - set_text({static_cast(str_buffer), "Please insert sd card"}); - - if(i < (dots_animation_size - 1)) { - i++; - } else { - i = 0; - } - } - - blink_green(); -} - -// show warning about test -void SdTest::show_warning() { - set_text( - {"!!Warning!!", - "during the tests", - "files can be overwritten", - "or data on card may be lost", - "", - "press UP DOWN OK to continue"}); - - wait_for_button(InputKeyUp); - wait_for_button(InputKeyDown); - wait_for_button(InputKeyOk); -} - -// get info about sd card, label, sn -// sector, cluster, total and free size -void SdTest::get_sd_card_info() { - const uint8_t str_buffer_size = 26; - char str_buffer[2][str_buffer_size]; - FS_Error result; - uint64_t bytes_total, bytes_free; - int __attribute__((unused)) snprintf_count = 0; - - result = fs_api->common.get_fs_info(&bytes_total, &bytes_free); - if(result != FSE_OK) set_error({"get_fs_info error", fs_api->error.get_desc(result)}); - - snprintf( - str_buffer[0], str_buffer_size, "%lu KB total", static_cast(bytes_total / 1024)); - snprintf( - str_buffer[1], str_buffer_size, "%lu KB free", static_cast(bytes_free / 1024)); - - set_text( - {static_cast(str_buffer[0]), - static_cast(str_buffer[1]), - "", - "", - "", - "press OK to continue"}); - - blink_green(); - - wait_for_button(InputKeyOk); -} - -// prepare benchmark data (allocate data in ram) -bool SdTest::prepare_benchmark_data() { - bool result = true; - benchmark_data = static_cast(malloc(benchmark_data_size)); - - if(benchmark_data == NULL) { - result = false; - } - - for(size_t i = 0; i < benchmark_data_size; i++) { - benchmark_data[i] = static_cast(i); - } - - return result; -} - -void SdTest::free_benchmark_data() { - free(benchmark_data); -} - -// write speed test -void SdTest::write_benchmark() { - const uint32_t b1_size = 1; - const uint32_t b8_size = 8; - const uint32_t b32_size = 32; - const uint32_t b256_size = 256; - const uint32_t b4096_size = 4096; - - const uint32_t benchmark_data_size = 16384 * 4; - - uint32_t benchmark_bps = 0; - - const uint8_t str_buffer_size = 32; - char str_buffer[6][str_buffer_size] = {"", "", "", "", "", ""}; - auto string_list = { - static_cast(str_buffer[0]), - static_cast(str_buffer[1]), - static_cast(str_buffer[2]), - static_cast(str_buffer[3]), - static_cast(str_buffer[4]), - static_cast(str_buffer[5])}; - - set_text({"write speed test", "procedure can be lengthy", "please wait"}); - delay(100); - - // 1b test - benchmark_bps = write_benchmark_internal(b1_size, benchmark_data_size / b1_size); - snprintf(str_buffer[0], str_buffer_size, "1-byte: %lu bps", benchmark_bps); - set_text(string_list); - delay(100); - - // 8b test - benchmark_bps = write_benchmark_internal(b8_size, benchmark_data_size / b8_size); - snprintf(str_buffer[1], str_buffer_size, "8-byte: %lu bps", benchmark_bps); - set_text(string_list); - delay(100); - - // 32b test - benchmark_bps = write_benchmark_internal(b32_size, benchmark_data_size / b32_size); - snprintf(str_buffer[2], str_buffer_size, "32-byte: %lu bps", benchmark_bps); - set_text(string_list); - delay(100); - - // 256b test - benchmark_bps = write_benchmark_internal(b256_size, benchmark_data_size / b256_size); - snprintf(str_buffer[3], str_buffer_size, "256-byte: %lu bps", benchmark_bps); - set_text(string_list); - delay(100); - - // 4096b test - benchmark_bps = write_benchmark_internal(b4096_size, benchmark_data_size / b4096_size); - snprintf(str_buffer[4], str_buffer_size, "4096-byte: %lu bps", benchmark_bps); - snprintf(str_buffer[5], str_buffer_size, "press OK to continue"); - set_text(string_list); - - blink_green(); - - wait_for_button(InputKeyOk); -} - -uint32_t SdTest::write_benchmark_internal(const uint32_t size, const uint32_t count, bool silent) { - uint32_t start_tick, stop_tick, benchmark_bps = 0, benchmark_time, bytes_written; - File file; - - const uint8_t str_buffer_size = 32; - char str_buffer[str_buffer_size]; - - if(!fs_api->file.open(&file, "write.test", FSAM_WRITE, FSOM_OPEN_ALWAYS)) { - if(!silent) { - snprintf(str_buffer, str_buffer_size, "in %lu-byte write test", size); - set_error({"cannot open file ", static_cast(str_buffer)}); - } else { - benchmark_bps = BENCHMARK_ERROR; - } - } - - start_tick = osKernelGetTickCount(); - for(size_t i = 0; i < count; i++) { - bytes_written = fs_api->file.write(&file, benchmark_data, size); - if(bytes_written != size || file.error_id != FSE_OK) { - if(!silent) { - snprintf(str_buffer, str_buffer_size, "in %lu-byte write test", size); - set_error({"cannot write to file ", static_cast(str_buffer)}); - } else { - benchmark_bps = BENCHMARK_ERROR; - break; - } - } - } - stop_tick = osKernelGetTickCount(); - - if(!fs_api->file.close(&file)) { - if(!silent) { - snprintf(str_buffer, str_buffer_size, "in %lu-byte write test", size); - set_error({"cannot close file ", static_cast(str_buffer)}); - } else { - benchmark_bps = BENCHMARK_ERROR; - } - } - - if(benchmark_bps != BENCHMARK_ERROR) { - benchmark_time = stop_tick - start_tick; - benchmark_bps = (count * size) * osKernelGetTickFreq() / benchmark_time; - } - - return benchmark_bps; -} - -// read speed test -void SdTest::read_benchmark() { - const uint32_t benchmark_data_size = 16384 * 8; - uint32_t bytes_written; - uint32_t benchmark_bps = 0; - - const uint8_t str_buffer_size = 32; - char str_buffer[6][str_buffer_size] = {"", "", "", "", "", ""}; - auto string_list = { - static_cast(str_buffer[0]), - static_cast(str_buffer[1]), - static_cast(str_buffer[2]), - static_cast(str_buffer[3]), - static_cast(str_buffer[4]), - static_cast(str_buffer[5])}; - - File file; - - const uint32_t b1_size = 1; - const uint32_t b8_size = 8; - const uint32_t b32_size = 32; - const uint32_t b256_size = 256; - const uint32_t b4096_size = 4096; - - // prepare data for read test - set_text({"prepare data", "for read speed test", "procedure can be lengthy", "please wait"}); - delay(100); - - if(!fs_api->file.open(&file, "read.test", FSAM_WRITE, FSOM_OPEN_ALWAYS)) { - set_error({"cannot open file ", "in prepare read"}); - } - - for(size_t i = 0; i < benchmark_data_size / b4096_size; i++) { - bytes_written = fs_api->file.write(&file, benchmark_data, b4096_size); - if(bytes_written != b4096_size || file.error_id != FSE_OK) { - set_error({"cannot write to file ", "in prepare read"}); - } - } - - if(!fs_api->file.close(&file)) { - set_error({"cannot close file ", "in prepare read"}); - } - - // test start - set_text({"read speed test", "procedure can be lengthy", "please wait"}); - delay(100); - - // open file - if(!fs_api->file.open(&file, "read.test", FSAM_READ, FSOM_OPEN_EXISTING)) { - set_error({"cannot open file ", "in read benchmark"}); - } - - // 1b test - benchmark_bps = read_benchmark_internal(b1_size, benchmark_data_size / b1_size, &file); - snprintf(str_buffer[0], str_buffer_size, "1-byte: %lu bps", benchmark_bps); - set_text(string_list); - delay(100); - - // 8b test - benchmark_bps = read_benchmark_internal(b8_size, benchmark_data_size / b8_size, &file); - snprintf(str_buffer[1], str_buffer_size, "8-byte: %lu bps", benchmark_bps); - set_text(string_list); - delay(100); - - // 32b test - benchmark_bps = read_benchmark_internal(b32_size, benchmark_data_size / b32_size, &file); - snprintf(str_buffer[2], str_buffer_size, "32-byte: %lu bps", benchmark_bps); - set_text(string_list); - delay(100); - - // 256b test - benchmark_bps = read_benchmark_internal(b256_size, benchmark_data_size / b256_size, &file); - snprintf(str_buffer[3], str_buffer_size, "256-byte: %lu bps", benchmark_bps); - set_text(string_list); - delay(100); - - // 4096b test - benchmark_bps = read_benchmark_internal(b4096_size, benchmark_data_size / b4096_size, &file); - snprintf(str_buffer[4], str_buffer_size, "4096-byte: %lu bps", benchmark_bps); - snprintf(str_buffer[5], str_buffer_size, "press OK to continue"); - set_text(string_list); - - // close file - if(!fs_api->file.close(&file)) { - set_error({"cannot close file ", "in read test"}); - } - - blink_green(); - - wait_for_button(InputKeyOk); -} - -uint32_t SdTest::read_benchmark_internal( - const uint32_t size, - const uint32_t count, - File* file, - bool silent) { - uint32_t start_tick, stop_tick, benchmark_bps = 0, benchmark_time, bytes_readed; - - const uint8_t str_buffer_size = 32; - char str_buffer[str_buffer_size]; - uint8_t* read_buffer; - - read_buffer = static_cast(malloc(size)); - - if(read_buffer == NULL) { - if(!silent) { - snprintf(str_buffer, str_buffer_size, "in %lu-byte read test", size); - set_error({"cannot allocate memory", static_cast(str_buffer)}); - } else { - benchmark_bps = BENCHMARK_ERROR; - } - } - - fs_api->file.seek(file, 0, true); - - start_tick = osKernelGetTickCount(); - for(size_t i = 0; i < count; i++) { - bytes_readed = fs_api->file.read(file, read_buffer, size); - if(bytes_readed != size || file->error_id != FSE_OK) { - if(!silent) { - snprintf(str_buffer, str_buffer_size, "in %lu-byte read test", size); - set_error({"cannot read from file ", static_cast(str_buffer)}); - } else { - benchmark_bps = BENCHMARK_ERROR; - break; - } - } - } - stop_tick = osKernelGetTickCount(); - - free(read_buffer); - - if(benchmark_bps != BENCHMARK_ERROR) { - benchmark_time = stop_tick - start_tick; - benchmark_bps = (count * size) * osKernelGetTickFreq() / benchmark_time; - } - - return benchmark_bps; -} - -// hash benchmark, store data to sd with known hash -// then read, calculate hash and compare both hashes -void SdTest::hash_benchmark() { - uint32_t mcu_data_hash = FNV_1A_INIT; - uint32_t sdcard_data_hash = FNV_1A_INIT; - uint8_t* read_buffer; - uint32_t bytes_readed; - - uint32_t bytes_written; - - const uint8_t str_buffer_size = 32; - char str_buffer[3][str_buffer_size] = {"", "", ""}; - - File file; - - const uint32_t b4096_size = 4096; - const uint32_t benchmark_count = 20; - - // prepare data for hash test - set_text({"prepare data", "for hash test"}); - delay(100); - - // write data to test file and calculate hash - if(!fs_api->file.open(&file, "hash.test", FSAM_WRITE, FSOM_OPEN_ALWAYS)) { - set_error({"cannot open file ", "in prepare hash"}); - } - - for(uint32_t i = 0; i < benchmark_count; i++) { - mcu_data_hash = fnv1a_buffer_hash(benchmark_data, b4096_size, mcu_data_hash); - bytes_written = fs_api->file.write(&file, benchmark_data, b4096_size); - - if(bytes_written != b4096_size || file.error_id != FSE_OK) { - set_error({"cannot write to file ", "in prepare hash"}); - } - - snprintf(str_buffer[0], str_buffer_size, "writing %lu of %lu x 4k", i, benchmark_count); - set_text({"prepare data", "for hash test", static_cast(str_buffer[0])}); - delay(100); - } - - if(!fs_api->file.close(&file)) { - set_error({"cannot close file ", "in prepare hash"}); - } - - // show hash of data located in mcu memory - snprintf(str_buffer[0], str_buffer_size, "hash in mcu 0x%lx", mcu_data_hash); - set_text({str_buffer[0]}); - delay(100); - - // read data from sd card and calculate hash - read_buffer = static_cast(malloc(b4096_size)); - - if(read_buffer == NULL) { - set_error({"cannot allocate memory", "in hash test"}); - } - - if(!fs_api->file.open(&file, "hash.test", FSAM_READ, FSOM_OPEN_EXISTING)) { - set_error({"cannot open file ", "in hash test"}); - } - - for(uint32_t i = 0; i < benchmark_count; i++) { - bytes_readed = fs_api->file.read(&file, read_buffer, b4096_size); - sdcard_data_hash = fnv1a_buffer_hash(read_buffer, b4096_size, sdcard_data_hash); - - if(bytes_readed != b4096_size || file.error_id != FSE_OK) { - set_error({"cannot read from file ", "in hash test"}); - } - - snprintf(str_buffer[1], str_buffer_size, "reading %lu of %lu x 4k", i, benchmark_count); - set_text({str_buffer[0], str_buffer[1]}); - delay(100); - } - - if(!fs_api->file.close(&file)) { - set_error({"cannot close file ", "in hash test"}); - } - - free(read_buffer); - - snprintf(str_buffer[1], str_buffer_size, "hash in sdcard 0x%lx", sdcard_data_hash); - if(mcu_data_hash == sdcard_data_hash) { - snprintf(str_buffer[2], str_buffer_size, "hashes are equal, press OK"); - set_text( - {static_cast(str_buffer[0]), - static_cast(str_buffer[1]), - "", - "", - "", - static_cast(str_buffer[2])}); - } else { - snprintf(str_buffer[2], str_buffer_size, "hash error, press BACK to exit"); - set_error( - {static_cast(str_buffer[0]), - static_cast(str_buffer[1]), - "", - "", - "", - static_cast(str_buffer[2])}); - } - - blink_green(); - - wait_for_button(InputKeyOk); -} - -void SdTest::cli_read_benchmark(Cli* cli, string_t args, void* _ctx) { - SdTest* _this = static_cast(_ctx); - - const uint32_t benchmark_data_size = 16384 * 8; - uint32_t bytes_written; - uint32_t benchmark_bps = 0; - File file; - - const uint32_t b1_size = 1; - const uint32_t b8_size = 8; - const uint32_t b32_size = 32; - const uint32_t b256_size = 256; - const uint32_t b4096_size = 4096; - - const uint8_t str_buffer_size = 64; - char str_buffer[str_buffer_size]; - - printf("preparing benchmark data\r\n"); - bool data_prepared = _this->prepare_benchmark_data(); - if(data_prepared) { - printf("benchmark data prepared\r\n"); - } else { - printf("error: cannot allocate buffer for benchmark data\r\n"); - } - - // prepare data for read test - printf("prepare data for read speed test, procedure can be lengthy, please wait\r\n"); - - if(!_this->fs_api->file.open(&file, "read.test", FSAM_WRITE, FSOM_OPEN_ALWAYS)) { - printf("error: cannot open file in prepare read\r\n"); - } - - for(size_t i = 0; i < benchmark_data_size / b4096_size; i++) { - bytes_written = _this->fs_api->file.write(&file, benchmark_data, b4096_size); - if(bytes_written != b4096_size || file.error_id != FSE_OK) { - printf("error: cannot write to file in prepare read\r\n"); - } - } - - if(!_this->fs_api->file.close(&file)) { - printf("error: cannot close file in prepare read\r\n"); - } - - // test start - printf("read speed test, procedure can be lengthy, please wait\r\n"); - - // open file - if(!_this->fs_api->file.open(&file, "read.test", FSAM_READ, FSOM_OPEN_EXISTING)) { - printf("error: cannot open file in read benchmark\r\n"); - } - - // 1b test - benchmark_bps = - _this->read_benchmark_internal(b1_size, benchmark_data_size / b1_size, &file, true); - if(benchmark_bps == BENCHMARK_ERROR) { - printf("error: in 1-byte read test\r\n"); - } else { - snprintf(str_buffer, str_buffer_size, "1-byte: %lu bytes per second\r\n", benchmark_bps); - printf(str_buffer); - } - - // 8b test - benchmark_bps = - _this->read_benchmark_internal(b8_size, benchmark_data_size / b8_size, &file, true); - if(benchmark_bps == BENCHMARK_ERROR) { - printf("error: in 8-byte read test\r\n"); - } else { - snprintf(str_buffer, str_buffer_size, "8-byte: %lu bytes per second\r\n", benchmark_bps); - printf(str_buffer); - } - - // 32b test - benchmark_bps = - _this->read_benchmark_internal(b32_size, benchmark_data_size / b32_size, &file, true); - if(benchmark_bps == BENCHMARK_ERROR) { - printf("error: in 32-byte read test\r\n"); - } else { - snprintf(str_buffer, str_buffer_size, "32-byte: %lu bytes per second\r\n", benchmark_bps); - printf(str_buffer); - } - - // 256b test - benchmark_bps = - _this->read_benchmark_internal(b256_size, benchmark_data_size / b256_size, &file, true); - if(benchmark_bps == BENCHMARK_ERROR) { - printf("error: in 256-byte read test\r\n"); - } else { - snprintf(str_buffer, str_buffer_size, "256-byte: %lu bytes per second\r\n", benchmark_bps); - printf(str_buffer); - } - - // 4096b test - benchmark_bps = - _this->read_benchmark_internal(b4096_size, benchmark_data_size / b4096_size, &file, true); - if(benchmark_bps == BENCHMARK_ERROR) { - printf("error: in 4096-byte read test\r\n"); - } else { - snprintf( - str_buffer, str_buffer_size, "4096-byte: %lu bytes per second\r\n", benchmark_bps); - printf(str_buffer); - } - - // close file - if(!_this->fs_api->file.close(&file)) { - printf("error: cannot close file\r\n"); - } - - _this->free_benchmark_data(); - - printf("test completed\r\n"); -} - -void SdTest::cli_write_benchmark(Cli* cli, string_t args, void* _ctx) { - SdTest* _this = static_cast(_ctx); - - const uint32_t b1_size = 1; - const uint32_t b8_size = 8; - const uint32_t b32_size = 32; - const uint32_t b256_size = 256; - const uint32_t b4096_size = 4096; - - const uint32_t benchmark_data_size = 16384 * 4; - - uint32_t benchmark_bps = 0; - - const uint8_t str_buffer_size = 64; - char str_buffer[str_buffer_size]; - - printf("preparing benchmark data\r\n"); - bool data_prepared = _this->prepare_benchmark_data(); - if(data_prepared) { - printf("benchmark data prepared\r\n"); - } else { - printf("error: cannot allocate buffer for benchmark data\r\n"); - } - - printf("write speed test, procedure can be lengthy, please wait\r\n"); - - // 1b test - benchmark_bps = _this->write_benchmark_internal(b1_size, benchmark_data_size / b1_size, true); - if(benchmark_bps == BENCHMARK_ERROR) { - printf("error: in 1-byte write test\r\n"); - } else { - snprintf(str_buffer, str_buffer_size, "1-byte: %lu bytes per second\r\n", benchmark_bps); - printf(str_buffer); - } - - // 8b test - benchmark_bps = _this->write_benchmark_internal(b8_size, benchmark_data_size / b8_size, true); - if(benchmark_bps == BENCHMARK_ERROR) { - printf("error: in 8-byte write test\r\n"); - } else { - snprintf(str_buffer, str_buffer_size, "8-byte: %lu bytes per second\r\n", benchmark_bps); - printf(str_buffer); - } - - // 32b test - benchmark_bps = - _this->write_benchmark_internal(b32_size, benchmark_data_size / b32_size, true); - if(benchmark_bps == BENCHMARK_ERROR) { - printf("error: in 32-byte write test\r\n"); - } else { - snprintf(str_buffer, str_buffer_size, "32-byte: %lu bytes per second\r\n", benchmark_bps); - printf(str_buffer); - } - - // 256b test - benchmark_bps = - _this->write_benchmark_internal(b256_size, benchmark_data_size / b256_size, true); - if(benchmark_bps == BENCHMARK_ERROR) { - printf("error: in 256-byte write test\r\n"); - } else { - snprintf(str_buffer, str_buffer_size, "256-byte: %lu bytes per second\r\n", benchmark_bps); - printf(str_buffer); - } - - // 4096b test - benchmark_bps = - _this->write_benchmark_internal(b4096_size, benchmark_data_size / b4096_size, true); - if(benchmark_bps == BENCHMARK_ERROR) { - printf("error: in 4096-byte write test\r\n"); - } else { - snprintf( - str_buffer, str_buffer_size, "4096-byte: %lu bytes per second\r\n", benchmark_bps); - printf(str_buffer); - } - - _this->free_benchmark_data(); - - printf("test completed\r\n"); -} - -// wait for button press -void SdTest::wait_for_button(InputKey input_button) { - SdTestEvent event; - osMessageQueueReset(event_queue); - while(1) { - osStatus_t result = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); - - if(result == osOK && event.type == SdTestEvent::EventTypeKey) { - if(event.value.input.type == InputTypeShort) { - if(event.value.input.key == InputKeyBack) { - exit(); - } else { - if(event.value.input.key == input_button) { - blink_green(); - break; - } else { - blink_red(); - } - } - } - } - } - osMessageQueueReset(event_queue); -} - -// ask user to proceed or cancel -bool SdTest::ask(InputKey input_button_cancel, InputKey input_button_ok) { - bool return_result; - SdTestEvent event; - osMessageQueueReset(event_queue); - while(1) { - osStatus_t result = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); - - if(result == osOK && event.type == SdTestEvent::EventTypeKey) { - if(event.value.input.type == InputTypeShort) { - if(event.value.input.key == InputKeyBack) { - exit(); - } else { - if(event.value.input.key == input_button_ok) { - blink_green(); - return_result = true; - break; - } else if(event.value.input.key == input_button_cancel) { - blink_green(); - return_result = false; - break; - } else { - blink_red(); - } - } - } - } - } - osMessageQueueReset(event_queue); - return return_result; -} - -// blink red led -void SdTest::blink_red() { - notification_message(notification, &sequence_blink_red_100); -} - -// blink green led -void SdTest::blink_green() { - notification_message(notification, &sequence_blink_green_100); -} - -// set text, but with infinite loop -template void SdTest::set_error(std::initializer_list list) { - set_text(list); - blink_red(); - wait_for_button(InputKeyBack); - exit(); -} - -// set text, sort of variadic function -template void SdTest::set_text(std::initializer_list list) { - uint8_t line_position = 0; - acquire_state(); - printf("------------------------\r\n"); - - // set line strings from args - for(auto element : list) { - state.line[line_position] = element; - printf("%s\n", element); - line_position++; - if(line_position == state.lines_count) break; - } - - // set empty lines - for(; line_position < state.lines_count; line_position++) { - state.line[line_position] = ""; - printf("\r\n"); - } - - printf("------------------------\r\n"); - release_state(); - update_gui(); -} - -// render app -void SdTest::render(Canvas* canvas) { - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - for(uint8_t i = 0; i < state.lines_count; i++) { - canvas_draw_str(canvas, 0, (i + 1) * 10, state.line[i]); - } -} - -// app enter function -extern "C" int32_t sd_card_test(void* p) { - SdTest* app = new SdTest(); - app->run(); - return 0; -} \ No newline at end of file diff --git a/applications/sd-filesystem/sd-filesystem-api.c b/applications/sd-filesystem/sd-filesystem-api.c deleted file mode 100644 index a4c52949..00000000 --- a/applications/sd-filesystem/sd-filesystem-api.c +++ /dev/null @@ -1,739 +0,0 @@ -#include "fatfs.h" -#include "filesystem-api.h" -#include "sd-filesystem.h" - -/******************* Global vars for api *******************/ - -static SdFsInfo* fs_info; - -/******************* Core Functions *******************/ - -bool _fs_init(SdFsInfo* _fs_info) { - bool result = true; - _fs_info->mutex = osMutexNew(NULL); - if(_fs_info->mutex == NULL) result = false; - - for(uint8_t i = 0; i < SD_FS_MAX_FILES; i++) { - _fs_info->files[i].thread_id = NULL; - } - - _fs_info->path = "0:/"; - _fs_info->status = SD_NO_CARD; - - // store pointer for api fns - fs_info = _fs_info; - - return result; -} - -bool _fs_lock(SdFsInfo* fs_info) { - api_hal_power_insomnia_enter(); - return (osMutexAcquire(fs_info->mutex, osWaitForever) == osOK); -} - -bool _fs_unlock(SdFsInfo* fs_info) { - api_hal_power_insomnia_exit(); - return (osMutexRelease(fs_info->mutex) == osOK); -} - -SDError _get_filedata(SdFsInfo* fs_info, File* file, FileData** filedata, FiledataFilter filter) { - SDError error = SD_OK; - _fs_lock(fs_info); - - if(fs_info->status == SD_OK) { - if(file != NULL && file->file_id < SD_FS_MAX_FILES) { - if(fs_info->files[file->file_id].thread_id == osThreadGetId()) { - if(filter == FDF_ANY) { - // any type - *filedata = &fs_info->files[file->file_id]; - } else if(filter == FDF_FILE) { - // file type - if(!fs_info->files[file->file_id].is_dir) { - *filedata = &fs_info->files[file->file_id]; - } else { - error = SD_NOT_A_FILE; - } - } else if(filter == FDF_DIR) { - // dir type - if(fs_info->files[file->file_id].is_dir) { - *filedata = &fs_info->files[file->file_id]; - } else { - error = SD_NOT_A_DIR; - } - } - } else { - error = SD_OTHER_APP; - } - } else { - error = SD_INVALID_PARAMETER; - } - } else { - error = SD_NO_CARD; - } - - _fs_unlock(fs_info); - return error; -} - -SDError _get_file(SdFsInfo* fs_info, File* file, FileData** filedata) { - return _get_filedata(fs_info, file, filedata, FDF_FILE); -} - -SDError _get_dir(SdFsInfo* fs_info, File* file, FileData** filedata) { - return _get_filedata(fs_info, file, filedata, FDF_DIR); -} - -SDError _get_any(SdFsInfo* fs_info, File* file, FileData** filedata) { - return _get_filedata(fs_info, file, filedata, FDF_ANY); -} - -SDError _fs_status(SdFsInfo* fs_info) { - SDError result; - - _fs_lock(fs_info); - result = fs_info->status; - _fs_unlock(fs_info); - - return result; -} - -void _fs_on_client_app_exit(SdFsInfo* fs_info) { - _fs_lock(fs_info); - for(uint8_t i = 0; i < SD_FS_MAX_FILES; i++) { - if(fs_info->files[i].thread_id == osThreadGetId()) { - if(fs_info->files[i].is_dir) { - // TODO close dir - } else { - // TODO close file - } - } - } - _fs_unlock(fs_info); -} - -FS_Error _fs_parse_error(SDError error) { - FS_Error result; - switch(error) { - case SD_OK: - result = FSE_OK; - break; - case SD_INT_ERR: - result = FSE_INTERNAL; - break; - case SD_NO_FILE: - result = FSE_NOT_EXIST; - break; - case SD_NO_PATH: - result = FSE_NOT_EXIST; - break; - case SD_INVALID_NAME: - result = FSE_INVALID_NAME; - break; - case SD_DENIED: - result = FSE_DENIED; - break; - case SD_EXIST: - result = FSE_EXIST; - break; - case SD_INVALID_OBJECT: - result = FSE_INTERNAL; - break; - case SD_WRITE_PROTECTED: - result = FSE_INTERNAL; - break; - case SD_INVALID_DRIVE: - result = FSE_INTERNAL; - break; - case SD_NOT_ENABLED: - result = FSE_INTERNAL; - break; - case SD_NO_FILESYSTEM: - result = FSE_NOT_READY; - break; - case SD_MKFS_ABORTED: - result = FSE_INTERNAL; - break; - case SD_TIMEOUT: - result = FSE_INTERNAL; - break; - case SD_LOCKED: - result = FSE_INTERNAL; - break; - case SD_NOT_ENOUGH_CORE: - result = FSE_INTERNAL; - break; - case SD_TOO_MANY_OPEN_FILES: - result = FSE_INTERNAL; - break; - case SD_INVALID_PARAMETER: - result = FSE_INVALID_PARAMETER; - break; - case SD_NO_CARD: - result = FSE_NOT_READY; - break; - case SD_NOT_A_FILE: - result = FSE_INVALID_PARAMETER; - break; - case SD_NOT_A_DIR: - result = FSE_INVALID_PARAMETER; - break; - case SD_OTHER_APP: - result = FSE_INTERNAL; - break; - - default: - result = FSE_INTERNAL; - break; - } - - return result; -} - -/******************* File Functions *******************/ - -// Open/Create a file -bool fs_file_open(File* file, const char* path, FS_AccessMode access_mode, FS_OpenMode open_mode) { - SDFile* sd_file = NULL; - - _fs_lock(fs_info); - for(uint8_t index = 0; index < SD_FS_MAX_FILES; index++) { - FileData* filedata = &fs_info->files[index]; - - if(filedata->thread_id == NULL) { - file->file_id = index; - - memset(&(filedata->data), 0, sizeof(SDFileDirStorage)); - filedata->thread_id = osThreadGetId(); - filedata->is_dir = false; - sd_file = &(filedata->data.file); - - break; - } - } - _fs_unlock(fs_info); - - if(sd_file == NULL) { - file->internal_error_id = SD_TOO_MANY_OPEN_FILES; - } else { - uint8_t _mode = 0; - - if(access_mode & FSAM_READ) _mode |= FA_READ; - if(access_mode & FSAM_WRITE) _mode |= FA_WRITE; - if(open_mode & FSOM_OPEN_EXISTING) _mode |= FA_OPEN_EXISTING; - if(open_mode & FSOM_OPEN_ALWAYS) _mode |= FA_OPEN_ALWAYS; - if(open_mode & FSOM_OPEN_APPEND) _mode |= FA_OPEN_APPEND; - if(open_mode & FSOM_CREATE_NEW) _mode |= FA_CREATE_NEW; - if(open_mode & FSOM_CREATE_ALWAYS) _mode |= FA_CREATE_ALWAYS; - - file->internal_error_id = f_open(sd_file, path, _mode); - } - - // TODO on exit - //furiac_onexit(_fs_on_client_app_exit, fs_info); - - file->error_id = _fs_parse_error(file->internal_error_id); - return (file->internal_error_id == SD_OK); -} - -// Close an opened file -bool fs_file_close(File* file) { - FileData* filedata = NULL; - file->internal_error_id = _get_file(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - file->internal_error_id = f_close(&filedata->data.file); - - _fs_lock(fs_info); - filedata->thread_id = NULL; - _fs_unlock(fs_info); - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return (file->internal_error_id == SD_OK); -} - -// Read data from the file -uint16_t fs_file_read(File* file, void* buff, uint16_t const bytes_to_read) { - FileData* filedata = NULL; - uint16_t bytes_readed = 0; - - file->internal_error_id = _get_file(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - file->internal_error_id = f_read(&filedata->data.file, buff, bytes_to_read, &bytes_readed); - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return bytes_readed; -} - -// Write data to the file -uint16_t fs_file_write(File* file, const void* buff, uint16_t const bytes_to_write) { - FileData* filedata = NULL; - uint16_t bytes_written = 0; - - file->internal_error_id = _get_file(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - file->internal_error_id = - f_write(&filedata->data.file, buff, bytes_to_write, &bytes_written); - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return bytes_written; -} - -// Move read/write pointer, expand size -bool fs_file_seek(File* file, const uint32_t offset, const bool from_start) { - FileData* filedata = NULL; - - file->internal_error_id = _get_file(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - if(from_start) { - file->internal_error_id = f_lseek(&filedata->data.file, offset); - } else { - uint64_t position = f_tell(&filedata->data.file); - position += offset; - file->internal_error_id = f_lseek(&filedata->data.file, position); - } - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return (file->internal_error_id == SD_OK); -} - -// Tell pointer position -uint64_t fs_file_tell(File* file) { - FileData* filedata = NULL; - uint64_t position = 0; - file->internal_error_id = _get_file(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - position = f_tell(&filedata->data.file); - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return position; -} - -// Truncate file size to current pointer value -bool fs_file_truncate(File* file) { - FileData* filedata = NULL; - - file->internal_error_id = _get_file(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - file->internal_error_id = f_truncate(&filedata->data.file); - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return (file->internal_error_id == SD_OK); -} - -// Flush cached data -bool fs_file_sync(File* file) { - FileData* filedata = NULL; - - file->internal_error_id = _get_file(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - file->internal_error_id = f_sync(&filedata->data.file); - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return (file->internal_error_id == SD_OK); -} - -// Get size -uint64_t fs_file_size(File* file) { - FileData* filedata = NULL; - uint64_t size = 0; - file->internal_error_id = _get_file(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - size = f_size(&filedata->data.file); - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return size; -} - -// Test EOF -bool fs_file_eof(File* file) { - FileData* filedata = NULL; - bool eof = true; - file->internal_error_id = _get_file(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - eof = f_eof(&filedata->data.file); - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return eof; -} - -/******************* Dir Functions *******************/ - -// Open directory -bool fs_dir_open(File* file, const char* path) { - SDDir* sd_dir = NULL; - - _fs_lock(fs_info); - for(uint8_t index = 0; index < SD_FS_MAX_FILES; index++) { - FileData* filedata = &fs_info->files[index]; - - if(filedata->thread_id == NULL) { - file->file_id = index; - - memset(&(filedata->data), 0, sizeof(SDFileDirStorage)); - filedata->thread_id = osThreadGetId(); - filedata->is_dir = true; - sd_dir = &(filedata->data.dir); - - break; - } - } - _fs_unlock(fs_info); - - if(sd_dir == NULL) { - file->internal_error_id = SD_TOO_MANY_OPEN_FILES; - } else { - file->internal_error_id = f_opendir(sd_dir, path); - } - - // TODO on exit - //furiac_onexit(_fs_on_client_app_exit, fs_info); - - file->error_id = _fs_parse_error(file->internal_error_id); - return (file->internal_error_id == SD_OK); -} - -// Close directory -bool fs_dir_close(File* file) { - FileData* filedata = NULL; - file->internal_error_id = _get_dir(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - file->internal_error_id = f_closedir(&filedata->data.dir); - - _fs_lock(fs_info); - filedata->thread_id = NULL; - _fs_unlock(fs_info); - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return (file->internal_error_id == SD_OK); -} - -// Read next file info and name from directory -bool fs_dir_read(File* file, FileInfo* fileinfo, char* name, const uint16_t name_length) { - FileData* filedata = NULL; - file->internal_error_id = _get_dir(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - SDFileInfo _fileinfo; - file->internal_error_id = f_readdir(&filedata->data.dir, &_fileinfo); - - if(fileinfo != NULL) { - fileinfo->date.value = _fileinfo.fdate; - fileinfo->time.value = _fileinfo.ftime; - fileinfo->size = _fileinfo.fsize; - fileinfo->flags = 0; - - if(_fileinfo.fattrib & AM_RDO) fileinfo->flags |= FSF_READ_ONLY; - if(_fileinfo.fattrib & AM_HID) fileinfo->flags |= FSF_HIDDEN; - if(_fileinfo.fattrib & AM_SYS) fileinfo->flags |= FSF_SYSTEM; - if(_fileinfo.fattrib & AM_DIR) fileinfo->flags |= FSF_DIRECTORY; - if(_fileinfo.fattrib & AM_ARC) fileinfo->flags |= FSF_ARCHIVE; - } - - if(name != NULL && name_length > 0) { - strlcpy(name, _fileinfo.fname, name_length); - } - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return (file->internal_error_id == SD_OK); -} - -bool fs_dir_rewind(File* file) { - FileData* filedata = NULL; - file->internal_error_id = _get_dir(fs_info, file, &filedata); - - if(file->internal_error_id == SD_OK) { - file->internal_error_id = f_readdir(&filedata->data.dir, NULL); - } - - file->error_id = _fs_parse_error(file->internal_error_id); - return (file->internal_error_id == SD_OK); -} - -/******************* Common FS Functions *******************/ - -// Get info about file/dir -FS_Error - fs_common_info(const char* path, FileInfo* fileinfo, char* name, const uint16_t name_length) { - SDFileInfo _fileinfo; - SDError fresult = _fs_status(fs_info); - - if(fresult == SD_OK) { - fresult = f_stat(path, &_fileinfo); - if((FRESULT)fresult == FR_OK) { - if(fileinfo != NULL) { - fileinfo->date.value = _fileinfo.fdate; - fileinfo->time.value = _fileinfo.ftime; - fileinfo->size = _fileinfo.fsize; - fileinfo->flags = 0; - - if(_fileinfo.fattrib & AM_RDO) fileinfo->flags |= FSF_READ_ONLY; - if(_fileinfo.fattrib & AM_HID) fileinfo->flags |= FSF_HIDDEN; - if(_fileinfo.fattrib & AM_SYS) fileinfo->flags |= FSF_SYSTEM; - if(_fileinfo.fattrib & AM_DIR) fileinfo->flags |= FSF_DIRECTORY; - if(_fileinfo.fattrib & AM_ARC) fileinfo->flags |= FSF_ARCHIVE; - } - - if(name != NULL && name_length > 0) { - strlcpy(name, _fileinfo.fname, name_length); - } - } - } - - return _fs_parse_error(fresult); -} - -// Delete file/dir -// File/dir must not have read-only attribute. -// File/dir must be empty. -// File/dir must not be opened, or the FAT volume can be collapsed. FF_FS_LOCK fix that. -FS_Error fs_common_remove(const char* path) { - SDError fresult = _fs_status(fs_info); - - if(fresult == SD_OK) { - fresult = f_unlink(path); - } - - return _fs_parse_error(fresult); -} - -// Rename file/dir -// File/dir must not be opened, or the FAT volume can be collapsed. FF_FS_LOCK fix that. -FS_Error fs_common_rename(const char* old_path, const char* new_path) { - SDError fresult = _fs_status(fs_info); - - if(fresult == SD_OK) { - fresult = f_rename(old_path, new_path); - } - - return _fs_parse_error(fresult); -} - -// Set attributes of file/dir -// For example: -// set "read only" flag and remove "hidden" flag -// fs_common_set_attr("file.txt", FSF_READ_ONLY, FSF_READ_ONLY | FSF_HIDDEN); -FS_Error fs_common_set_attr(const char* path, uint8_t attr, uint8_t mask) { - SDError fresult = _fs_status(fs_info); - - if(fresult == SD_OK) { - uint8_t _mask = 0; - uint8_t _attr = 0; - - if(mask & FSF_READ_ONLY) _mask |= AM_RDO; - if(mask & FSF_HIDDEN) _mask |= AM_HID; - if(mask & FSF_SYSTEM) _mask |= AM_SYS; - if(mask & FSF_DIRECTORY) _mask |= AM_DIR; - if(mask & FSF_ARCHIVE) _mask |= AM_ARC; - - if(attr & FSF_READ_ONLY) _attr |= AM_RDO; - if(attr & FSF_HIDDEN) _attr |= AM_HID; - if(attr & FSF_SYSTEM) _attr |= AM_SYS; - if(attr & FSF_DIRECTORY) _attr |= AM_DIR; - if(attr & FSF_ARCHIVE) _attr |= AM_ARC; - - fresult = f_chmod(path, attr, mask); - } - - return _fs_parse_error(fresult); -} - -// Set time of file/dir -FS_Error fs_common_set_time(const char* path, FileDateUnion date, FileTimeUnion time) { - SDError fresult = _fs_status(fs_info); - - if(fresult == SD_OK) { - SDFileInfo _fileinfo; - - _fileinfo.fdate = date.value; - _fileinfo.ftime = time.value; - - fresult = f_utime(path, &_fileinfo); - } - - return _fs_parse_error(fresult); -} - -// Create new directory -FS_Error fs_common_mkdir(const char* path) { - SDError fresult = _fs_status(fs_info); - - if(fresult == SD_OK) { - fresult = f_mkdir(path); - } - - return _fs_parse_error(fresult); -} - -// Get common info about FS -FS_Error fs_get_fs_info(uint64_t* total_space, uint64_t* free_space) { - SDError fresult = _fs_status(fs_info); - - if(fresult == SD_OK) { - DWORD free_clusters; - FATFS* fs; - - fresult = f_getfree("0:/", &free_clusters, &fs); - if((FRESULT)fresult == FR_OK) { - uint32_t total_sectors = (fs->n_fatent - 2) * fs->csize; - uint32_t free_sectors = free_clusters * fs->csize; - - uint16_t sector_size = _MAX_SS; -#if _MAX_SS != _MIN_SS - sector_size = fs->ssize; -#endif - - if(total_space != NULL) { - *total_space = (uint64_t)total_sectors * (uint64_t)sector_size; - } - - if(free_space != NULL) { - *free_space = (uint64_t)free_sectors * (uint64_t)sector_size; - } - } - } - - return _fs_parse_error(fresult); -} - -/******************* Error Reporting Functions *******************/ - -// Get common error description -const char* fs_error_get_desc(FS_Error error_id) { - const char* result; - switch(error_id) { - case(FSE_OK): - result = "OK"; - break; - case(FSE_NOT_READY): - result = "filesystem not ready"; - break; - case(FSE_EXIST): - result = "file/dir already exist"; - break; - case(FSE_NOT_EXIST): - result = "file/dir not exist"; - break; - case(FSE_INVALID_PARAMETER): - result = "invalid parameter"; - break; - case(FSE_DENIED): - result = "access denied"; - break; - case(FSE_INVALID_NAME): - result = "invalid name/path"; - break; - case(FSE_INTERNAL): - result = "internal error"; - break; - case(FSE_NOT_IMPLEMENTED): - result = "function not implemented"; - break; - default: - result = "unknown error"; - break; - } - return result; -} - -// Get internal error description -const char* fs_error_get_internal_desc(uint32_t internal_error_id) { - const char* result; - switch(internal_error_id) { - case(SD_OK): - result = "OK"; - break; - case(SD_DISK_ERR): - result = "disk error"; - break; - case(SD_INT_ERR): - result = "internal error"; - break; - case(SD_NO_FILE): - result = "no file"; - break; - case(SD_NO_PATH): - result = "no path"; - break; - case(SD_INVALID_NAME): - result = "invalid name"; - break; - case(SD_DENIED): - result = "access denied"; - break; - case(SD_EXIST): - result = "file/dir exist"; - break; - case(SD_INVALID_OBJECT): - result = "invalid object"; - break; - case(SD_WRITE_PROTECTED): - result = "write protected"; - break; - case(SD_INVALID_DRIVE): - result = "invalid drive"; - break; - case(SD_NOT_ENABLED): - result = "not enabled"; - break; - case(SD_NO_FILESYSTEM): - result = "no filesystem"; - break; - case(SD_MKFS_ABORTED): - result = "aborted"; - break; - case(SD_TIMEOUT): - result = "timeout"; - break; - case(SD_LOCKED): - result = "file locked"; - break; - case(SD_NOT_ENOUGH_CORE): - result = "not enough memory"; - break; - case(SD_TOO_MANY_OPEN_FILES): - result = "too many open files"; - break; - case(SD_INVALID_PARAMETER): - result = "invalid parameter"; - break; - case(SD_NO_CARD): - result = "no SD Card"; - break; - case(SD_NOT_A_FILE): - result = "not a file"; - break; - case(SD_NOT_A_DIR): - result = "not a directory"; - break; - case(SD_OTHER_APP): - result = "opened by other app"; - break; - case(SD_LOW_LEVEL_ERR): - result = "low level error"; - break; - default: - result = "unknown error"; - break; - } - return result; -} \ No newline at end of file diff --git a/applications/sd-filesystem/sd-filesystem.c b/applications/sd-filesystem/sd-filesystem.c deleted file mode 100644 index 124c796c..00000000 --- a/applications/sd-filesystem/sd-filesystem.c +++ /dev/null @@ -1,956 +0,0 @@ -#include "fatfs.h" -#include "filesystem-api.h" -#include "sd-filesystem.h" -#include "menu/menu.h" -#include "menu/menu_item.h" -#include "cli/cli.h" -#include "api-hal-sd.h" - -#include -#include - -typedef enum { - FST_FAT12 = FS_FAT12, - FST_FAT16 = FS_FAT16, - FST_FAT32 = FS_FAT32, - FST_EXFAT = FS_EXFAT, -} SDFsType; - -typedef struct { - SDFsType fs_type; - uint32_t kb_total; - uint32_t kb_free; - uint16_t cluster_size; - uint16_t sector_size; - char label[34]; - SDError error; -} SDInfo; - -typedef enum { - SdAppEventTypeBack, - SdAppEventTypeOK, - SdAppEventTypeFormat, - SdAppEventTypeInfo, - SdAppEventTypeEject, - SdAppEventTypeFileSelect, - SdAppEventTypeCheckError, - SdAppEventTypeShowError, -} SdAppEventType; - -typedef struct { - const char* path; - const char* extension; - char* result; - uint8_t result_size; - const char* selected_filename; -} SdAppFileSelectData; - -typedef struct { - bool result; -} SdAppFileSelectResultEvent; - -typedef struct { - SdAppEventType type; - union { - SdAppFileSelectData file_select_data; - const char* error_text; - } payload; -} SdAppEvent; - -static void sd_icon_draw_callback(Canvas* canvas, void* context); -bool sd_api_file_select( - SdApp* sd_app, - const char* path, - const char* extension, - char* result, - uint8_t result_size, - const char* selected_filename); -void sd_api_check_error(SdApp* sd_app); -void sd_api_show_error(SdApp* sd_app, const char* error_text); - -/******************* Allocators *******************/ - -FS_Api* fs_api_alloc() { - FS_Api* fs_api = furi_alloc(sizeof(FS_Api)); - - // fill file api - fs_api->file.open = fs_file_open; - fs_api->file.close = fs_file_close; - fs_api->file.read = fs_file_read; - fs_api->file.write = fs_file_write; - fs_api->file.seek = fs_file_seek; - fs_api->file.tell = fs_file_tell; - fs_api->file.truncate = fs_file_truncate; - fs_api->file.size = fs_file_size; - fs_api->file.sync = fs_file_sync; - fs_api->file.eof = fs_file_eof; - - // fill dir api - fs_api->dir.open = fs_dir_open; - fs_api->dir.close = fs_dir_close; - fs_api->dir.read = fs_dir_read; - fs_api->dir.rewind = fs_dir_rewind; - - // fill common api - fs_api->common.info = fs_common_info; - fs_api->common.remove = fs_common_remove; - fs_api->common.rename = fs_common_rename; - fs_api->common.set_attr = fs_common_set_attr; - fs_api->common.mkdir = fs_common_mkdir; - fs_api->common.set_time = fs_common_set_time; - fs_api->common.get_fs_info = fs_get_fs_info; - - // fill errors api - fs_api->error.get_desc = fs_error_get_desc; - fs_api->error.get_internal_desc = fs_error_get_internal_desc; - - return fs_api; -} - -SdApp* sd_app_alloc() { - SdApp* sd_app = furi_alloc(sizeof(SdApp)); - - // init inner fs data - furi_check(_fs_init(&sd_app->info)); - - sd_app->event_queue = osMessageQueueNew(8, sizeof(SdAppEvent), NULL); - sd_app->result_receiver = osMessageQueueNew(1, sizeof(SdAppFileSelectResultEvent), NULL); - - // init icon view_port - sd_app->icon.view_port = view_port_alloc(); - sd_app->icon.mounted = &I_SDcardMounted_11x8; - sd_app->icon.fail = &I_SDcardFail_11x8; - view_port_set_width(sd_app->icon.view_port, icon_get_width(sd_app->icon.mounted)); - view_port_draw_callback_set(sd_app->icon.view_port, sd_icon_draw_callback, sd_app); - view_port_enabled_set(sd_app->icon.view_port, false); - - // init sd card api - sd_app->sd_card_api.context = sd_app; - sd_app->sd_card_api.file_select = sd_api_file_select; - sd_app->sd_card_api.check_error = sd_api_check_error; - sd_app->sd_card_api.show_error = sd_api_show_error; - - sd_app->sd_app_state = SdAppStateBackground; - string_init(sd_app->text_holder); - - return sd_app; -} - -/******************* Internal sd card related fns *******************/ - -void get_sd_info(SdApp* sd_app, SDInfo* sd_info) { - uint32_t free_clusters, free_sectors, total_sectors; - FATFS* fs; - - // clean data - memset(sd_info, 0, sizeof(SDInfo)); - - // get fs info - _fs_lock(&sd_app->info); - sd_info->error = f_getlabel(sd_app->info.path, sd_info->label, NULL); - if(sd_info->error == SD_OK) { - sd_info->error = f_getfree(sd_app->info.path, &free_clusters, &fs); - } - _fs_unlock(&sd_app->info); - - if(sd_info->error == SD_OK) { - // calculate size - total_sectors = (fs->n_fatent - 2) * fs->csize; - free_sectors = free_clusters * fs->csize; - - uint16_t sector_size = _MAX_SS; -#if _MAX_SS != _MIN_SS - sector_size = fs->ssize; -#endif - - sd_info->fs_type = fs->fs_type; - - sd_info->kb_total = total_sectors / 1024 * sector_size; - sd_info->kb_free = free_sectors / 1024 * sector_size; - sd_info->cluster_size = fs->csize; - sd_info->sector_size = sector_size; - } -} - -const char* get_fs_type_text(SDFsType fs_type) { - switch(fs_type) { - case(FST_FAT12): - return "FAT12"; - break; - case(FST_FAT16): - return "FAT16"; - break; - case(FST_FAT32): - return "FAT32"; - break; - case(FST_EXFAT): - return "EXFAT"; - break; - default: - return "UNKNOWN"; - break; - } -} - -void app_sd_format_internal(SdApp* sd_app) { - uint8_t* work_area; - - _fs_lock(&sd_app->info); - work_area = malloc(_MAX_SS); - if(work_area == NULL) { - sd_app->info.status = SD_NOT_ENOUGH_CORE; - } else { - sd_app->info.status = f_mkfs(sd_app->info.path, FM_ANY, 0, work_area, _MAX_SS); - free(work_area); - - if(sd_app->info.status == SD_OK) { - // set label and mount card - f_setlabel("Flipper SD"); - sd_app->info.status = f_mount(&sd_app->info.fat_fs, sd_app->info.path, 1); - } - } - - _fs_unlock(&sd_app->info); -} - -const NotificationSequence sd_sequence_success = { - &message_green_255, - &message_delay_50, - &message_green_0, - &message_delay_50, - &message_green_255, - &message_delay_50, - &message_green_0, - &message_delay_50, - &message_green_255, - &message_delay_50, - &message_green_0, - &message_delay_50, - NULL, -}; - -const NotificationSequence sd_sequence_error = { - &message_red_255, - &message_delay_50, - &message_red_0, - &message_delay_50, - &message_red_255, - &message_delay_50, - &message_red_0, - &message_delay_50, - &message_red_255, - &message_delay_50, - &message_red_0, - &message_delay_50, - NULL, -}; - -const NotificationSequence sd_sequence_eject = { - &message_blue_255, - &message_delay_50, - &message_blue_0, - &message_delay_50, - &message_blue_255, - &message_delay_50, - &message_blue_0, - &message_delay_50, - &message_blue_255, - &message_delay_50, - &message_blue_0, - &message_delay_50, - NULL, -}; - -const NotificationSequence sd_sequence_wait = { - &message_red_255, - &message_blue_255, - &message_do_not_reset, - NULL, -}; - -const NotificationSequence sd_sequence_wait_off = { - &message_red_0, - &message_blue_0, - NULL, -}; - -void app_sd_notify_wait(SdApp* sd_app) { - notification_message(sd_app->notifications, &sd_sequence_wait); -} - -void app_sd_notify_wait_off(SdApp* sd_app) { - notification_message(sd_app->notifications, &sd_sequence_wait_off); -} - -void app_sd_notify_success(SdApp* sd_app) { - notification_message(sd_app->notifications, &sd_sequence_success); -} - -void app_sd_notify_eject(SdApp* sd_app) { - notification_message(sd_app->notifications, &sd_sequence_eject); -} - -void app_sd_notify_error(SdApp* sd_app) { - notification_message(sd_app->notifications, &sd_sequence_error); -} - -bool app_sd_mount_card(SdApp* sd_app) { - bool result = false; - const uint8_t max_init_counts = 10; - uint8_t counter = max_init_counts; - uint8_t bsp_result; - - _fs_lock(&sd_app->info); - - while(result == false && counter > 0 && hal_sd_detect()) { - app_sd_notify_wait(sd_app); - - if((counter % 10) == 0) { - // power reset sd card - bsp_result = BSP_SD_Init(true); - } else { - bsp_result = BSP_SD_Init(false); - } - - if(bsp_result) { - // bsp error - sd_app->info.status = SD_LOW_LEVEL_ERR; - } else { - sd_app->info.status = f_mount(&sd_app->info.fat_fs, sd_app->info.path, 1); - - if(sd_app->info.status == SD_OK || sd_app->info.status == SD_NO_FILESYSTEM) { - FATFS* fs; - uint32_t free_clusters; - - sd_app->info.status = f_getfree(sd_app->info.path, &free_clusters, &fs); - - if(sd_app->info.status == SD_OK || sd_app->info.status == SD_NO_FILESYSTEM) { - result = true; - } - } - } - app_sd_notify_wait_off(sd_app); - - if(!result) { - delay(1000); - FURI_LOG_E( - "SD FILESYSTEM", - "init(%d), error: %s\r\n", - counter, - fs_error_get_internal_desc(sd_app->info.status)); - - counter--; - } - } - - _fs_unlock(&sd_app->info); - return result; -} - -void app_sd_unmount_card(SdApp* sd_app) { - _fs_lock(&sd_app->info); - - // set status - sd_app->info.status = SD_NO_CARD; - view_port_enabled_set(sd_app->icon.view_port, false); - - // close files - for(uint8_t index = 0; index < SD_FS_MAX_FILES; index++) { - FileData* filedata = &sd_app->info.files[index]; - - if(filedata->thread_id != NULL) { - if(filedata->is_dir) { - f_closedir(&filedata->data.dir); - } else { - f_close(&filedata->data.file); - } - filedata->thread_id = NULL; - } - } - - // unmount volume - f_mount(0, sd_app->info.path, 0); - - _fs_unlock(&sd_app->info); -} - -bool app_sd_make_path(const char* path) { - furi_assert(path); - - if(*path) { - char* file_path = strdup(path); - // Make parent directories - for(char* p = strchr(file_path + 1, '/'); p; p = strchr(p + 1, '/')) { - *p = '\0'; - SDError result = f_mkdir(file_path); - - if(result != SD_OK) { - if(result != SD_EXIST) { - *p = '/'; - free(file_path); - return false; - } - } - *p = '/'; - } - // Make origin directory - SDError result = f_mkdir(file_path); - if(result != SD_OK) { - if(result != SD_EXIST) { - free(file_path); - return false; - } - } - - free(file_path); - } - - return true; -} - -/******************* Draw callbacks *******************/ - -static void sd_icon_draw_callback(Canvas* canvas, void* context) { - furi_assert(canvas); - furi_assert(context); - SdApp* sd_app = context; - - switch(sd_app->info.status) { - case SD_NO_CARD: - break; - case SD_OK: - canvas_draw_icon(canvas, 0, 0, sd_app->icon.mounted); - break; - default: - canvas_draw_icon(canvas, 0, 0, sd_app->icon.fail); - break; - } -} - -/******************* SD-api callbacks *******************/ - -bool sd_api_file_select( - SdApp* sd_app, - const char* path, - const char* extension, - char* result, - uint8_t result_size, - const char* selected_filename) { - bool retval = false; - - SdAppEvent message = { - .type = SdAppEventTypeFileSelect, - .payload = { - .file_select_data = { - .path = path, - .extension = extension, - .result = result, - .result_size = result_size, - .selected_filename = selected_filename, - }}}; - - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); - - SdAppFileSelectResultEvent event; - while(1) { - osStatus_t event_status = - osMessageQueueGet(sd_app->result_receiver, &event, NULL, osWaitForever); - if(event_status == osOK) { - retval = event.result; - break; - } - } - - if(!retval) { - sd_api_check_error(sd_app); - } - - return retval; -} - -void sd_api_check_error(SdApp* sd_app) { - SdAppEvent message = {.type = SdAppEventTypeCheckError}; - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); -} - -void sd_api_show_error(SdApp* sd_app, const char* error_text) { - SdAppEvent message = {.type = SdAppEventTypeShowError, .payload.error_text = error_text}; - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); -} - -/******************* View callbacks *******************/ - -void app_view_back_callback(void* context) { - furi_assert(context); - SdApp* sd_app = context; - SdAppEvent message = {.type = SdAppEventTypeBack}; - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); -} - -void app_view_dialog_callback(DialogExResult result, void* context) { - furi_assert(context); - SdApp* sd_app = context; - - if(result == DialogExResultLeft) { - SdAppEvent message = {.type = SdAppEventTypeBack}; - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); - } else if(result == DialogExResultRight) { - SdAppEvent message = {.type = SdAppEventTypeOK}; - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); - } -} - -void app_view_file_select_callback(bool result, void* context) { - furi_assert(context); - SdApp* sd_app = context; - - if(result) { - SdAppEvent message = {.type = SdAppEventTypeOK}; - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); - } else { - SdAppEvent message = {.type = SdAppEventTypeBack}; - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); - } -} - -/******************* Menu callbacks *******************/ - -void app_sd_info_callback(void* context) { - furi_assert(context); - SdApp* sd_app = context; - SdAppEvent message = {.type = SdAppEventTypeInfo}; - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); -} - -void app_sd_format_callback(void* context) { - furi_assert(context); - SdApp* sd_app = context; - SdAppEvent message = {.type = SdAppEventTypeFormat}; - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); -} - -void app_sd_eject_callback(void* context) { - furi_assert(context); - SdApp* sd_app = context; - SdAppEvent message = {.type = SdAppEventTypeEject}; - furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); -} - -/******************* Cli callbacks *******************/ - -static void cli_sd_format(Cli* cli, string_t args, void* _ctx) { - SdApp* sd_app = (SdApp*)_ctx; - - printf("Formatting SD card, all data will be lost. Are you sure (y/n)?\r\n"); - char c = cli_getc(cli); - if(c == 'y' || c == 'Y') { - printf("Formatting, please wait...\r\n"); - // format card - app_sd_format_internal(sd_app); - - if(sd_app->info.status != SD_OK) { - printf("SD card format error: "); - printf(fs_error_get_internal_desc(sd_app->info.status)); - printf("\r\n"); - } else { - printf("SD card was successfully formatted.\r\n"); - } - } else { - printf("Cancelled.\r\n"); - } -} - -static void cli_sd_info(Cli* cli, string_t args, void* _ctx) { - SdApp* sd_app = (SdApp*)_ctx; - SDInfo sd_info; - - get_sd_info(sd_app, &sd_info); - printf("SD Status: %s\r\n", fs_error_get_internal_desc(sd_app->info.status)); - - if(sd_info.error == SD_OK) { - const char* fs_type = get_fs_type_text(sd_info.fs_type); - printf("Label: %s\r\n", sd_info.label); - printf("Filesystem: %s\r\n", fs_type); - printf("Cluster: %d sectors\r\n", sd_info.cluster_size); - printf("Sector: %d bytes\r\n", sd_info.sector_size); - printf("%lu KB total\r\n", sd_info.kb_total); - printf("%lu KB free\r\n", sd_info.kb_free); - } else { - printf("SD Info error: %s\r\n", fs_error_get_internal_desc(sd_info.error)); - } -} - -/******************* Test *******************/ - -bool try_to_alloc_view_holder(SdApp* sd_app, Gui* gui) { - bool result = false; - - _fs_lock(&sd_app->info); - - if(sd_app->view_holder == NULL) { - sd_app->view_holder = view_holder_alloc(); - view_holder_attach_to_gui(sd_app->view_holder, gui); - view_holder_set_back_callback(sd_app->view_holder, app_view_back_callback, sd_app); - result = true; - } - - _fs_unlock(&sd_app->info); - - return result; -} - -DialogEx* alloc_and_attach_dialog(SdApp* sd_app) { - DialogEx* dialog = dialog_ex_alloc(); - dialog_ex_set_context(dialog, sd_app); - dialog_ex_set_result_callback(dialog, app_view_dialog_callback); - view_holder_set_view(sd_app->view_holder, dialog_ex_get_view(dialog)); - view_holder_set_free_callback(sd_app->view_holder, (FreeCallback)dialog_ex_free, dialog); - return dialog; -} - -FileSelect* alloc_and_attach_file_select(SdApp* sd_app) { - FileSelect* file_select = file_select_alloc(); - file_select_set_callback(file_select, app_view_file_select_callback, sd_app); - view_holder_set_view(sd_app->view_holder, file_select_get_view(file_select)); - view_holder_set_free_callback( - sd_app->view_holder, (FreeCallback)file_select_free, file_select); - return file_select; -} - -void free_view_holder(SdApp* sd_app) { - _fs_lock(&sd_app->info); - - if(sd_app->view_holder) { - view_holder_free(sd_app->view_holder); - sd_app->view_holder = NULL; - } - - _fs_unlock(&sd_app->info); -} - -void app_reset_state(SdApp* sd_app) { - _fs_lock(&sd_app->info); - if(sd_app->view_holder) { - view_holder_stop(sd_app->view_holder); - } - _fs_unlock(&sd_app->info); - - free_view_holder(sd_app); - string_set_str(sd_app->text_holder, ""); - sd_app->sd_app_state = SdAppStateBackground; -} - -/******************* Main app *******************/ - -int32_t sd_filesystem(void* p) { - SdApp* sd_app = sd_app_alloc(); - FS_Api* fs_api = fs_api_alloc(); - - Gui* gui = furi_record_open("gui"); - Cli* cli = furi_record_open("cli"); - sd_app->notifications = furi_record_open("notification"); - ValueMutex* menu_vm = furi_record_open("menu"); - - gui_add_view_port(gui, sd_app->icon.view_port, GuiLayerStatusBarLeft); - - cli_add_command(cli, "sd_format", CliCommandFlagDefault, cli_sd_format, sd_app); - cli_add_command(cli, "sd_info", CliCommandFlagDefault, cli_sd_info, sd_app); - - // add api record - furi_record_create("sdcard", fs_api); - - // init menu - // TODO menu icon - MenuItem* menu_item; - menu_item = menu_item_alloc_menu("SD Card", icon_animation_alloc(&I_SDcardMounted_11x8)); - - menu_item_subitem_add( - menu_item, menu_item_alloc_function("Info", NULL, app_sd_info_callback, sd_app)); - menu_item_subitem_add( - menu_item, menu_item_alloc_function("Format", NULL, app_sd_format_callback, sd_app)); - menu_item_subitem_add( - menu_item, menu_item_alloc_function("Eject", NULL, app_sd_eject_callback, sd_app)); - - // add item to menu - furi_check(menu_vm); - with_value_mutex( - menu_vm, (Menu * menu) { menu_item_add(menu, menu_item); }); - - FURI_LOG_I("SD FILESYSTEM", "start"); - - // add api record - furi_record_create("sdcard", fs_api); - furi_record_create("sdcard-ex", &sd_app->sd_card_api); - - // sd card cycle - bool sd_was_present = true; - - // init detect pins - hal_sd_detect_init(); - - while(true) { - if(sd_was_present) { - if(hal_sd_detect()) { - FURI_LOG_I("SD FILESYSTEM", "Card detected"); - app_sd_mount_card(sd_app); - - if(sd_app->info.status != SD_OK) { - FURI_LOG_E( - "SD FILESYSTEM", - "sd init error: %s", - fs_error_get_internal_desc(sd_app->info.status)); - app_sd_notify_error(sd_app); - } else { - FURI_LOG_I("SD FILESYSTEM", "sd init ok"); - app_sd_notify_success(sd_app); - } - - view_port_enabled_set(sd_app->icon.view_port, true); - sd_was_present = false; - - if(!hal_sd_detect()) { - FURI_LOG_I("SD FILESYSTEM", "card removed"); - - view_port_enabled_set(sd_app->icon.view_port, false); - app_sd_unmount_card(sd_app); - sd_was_present = true; - } - } - } else { - if(!hal_sd_detect()) { - FURI_LOG_I("SD FILESYSTEM", "card removed"); - - view_port_enabled_set(sd_app->icon.view_port, false); - app_sd_unmount_card(sd_app); - sd_was_present = true; - app_sd_notify_eject(sd_app); - } - } - - SdAppEvent event; - osStatus_t event_status = osMessageQueueGet(sd_app->event_queue, &event, NULL, 1000); - - const uint8_t y_1_line = 32; - const uint8_t y_2_line = 32; - const uint8_t y_4_line = 26; - - if(event_status == osOK) { - switch(event.type) { - case SdAppEventTypeOK: - switch(sd_app->sd_app_state) { - case SdAppStateFormat: { - DialogEx* dialog = view_holder_get_free_context(sd_app->view_holder); - dialog_ex_set_left_button_text(dialog, NULL); - dialog_ex_set_right_button_text(dialog, NULL); - dialog_ex_set_header( - dialog, "Formatting...", 64, y_1_line, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog, NULL, 0, 0, AlignCenter, AlignCenter); - sd_app->sd_app_state = SdAppStateFormatInProgress; - delay(100); - app_sd_format_internal(sd_app); - app_sd_notify_success(sd_app); - dialog_ex_set_left_button_text(dialog, "Back"); - dialog_ex_set_header( - dialog, "SD card formatted", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text( - dialog, "Press back to return", 64, y_1_line, AlignCenter, AlignCenter); - sd_app->sd_app_state = SdAppStateFormatCompleted; - }; break; - case SdAppStateEject: { - DialogEx* dialog = view_holder_get_free_context(sd_app->view_holder); - dialog_ex_set_right_button_text(dialog, NULL); - dialog_ex_set_header( - dialog, "SD card ejected", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text( - dialog, - "Now the SD card\ncan be removed.", - 64, - y_2_line, - AlignCenter, - AlignCenter); - sd_app->sd_app_state = SdAppStateEjected; - app_sd_unmount_card(sd_app); - app_sd_notify_eject(sd_app); - }; break; - case SdAppStateFileSelect: { - SdAppFileSelectResultEvent retval = {.result = true}; - furi_check( - osMessageQueuePut(sd_app->result_receiver, &retval, 0, osWaitForever) == - osOK); - app_reset_state(sd_app); - }; break; - default: - break; - } - break; - case SdAppEventTypeBack: - switch(sd_app->sd_app_state) { - case SdAppStateFormatInProgress: - break; - case SdAppStateFileSelect: { - SdAppFileSelectResultEvent retval = {.result = false}; - furi_check( - osMessageQueuePut(sd_app->result_receiver, &retval, 0, osWaitForever) == - osOK); - app_reset_state(sd_app); - }; break; - - default: - app_reset_state(sd_app); - break; - } - break; - case SdAppEventTypeFormat: - if(try_to_alloc_view_holder(sd_app, gui)) { - DialogEx* dialog = alloc_and_attach_dialog(sd_app); - dialog_ex_set_left_button_text(dialog, "Back"); - dialog_ex_set_right_button_text(dialog, "Format"); - dialog_ex_set_header( - dialog, "Format SD card?", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text( - dialog, "All data will be lost.", 64, y_1_line, AlignCenter, AlignCenter); - view_holder_start(sd_app->view_holder); - sd_app->sd_app_state = SdAppStateFormat; - } - break; - case SdAppEventTypeInfo: - if(try_to_alloc_view_holder(sd_app, gui)) { - DialogEx* dialog = alloc_and_attach_dialog(sd_app); - dialog_ex_set_left_button_text(dialog, "Back"); - - SDInfo sd_info; - get_sd_info(sd_app, &sd_info); - - if(sd_info.error == SD_OK) { - string_printf( - sd_app->text_holder, - "Label: %s\nType: %s\n%lu KB total\n%lu KB free", - sd_info.label, - get_fs_type_text(sd_info.fs_type), - sd_info.kb_total, - sd_info.kb_free); - dialog_ex_set_text( - dialog, - string_get_cstr(sd_app->text_holder), - 4, - y_4_line, - AlignLeft, - AlignCenter); - view_holder_start(sd_app->view_holder); - } else { - string_printf( - sd_app->text_holder, - "SD status: %s\n SD info: %s", - fs_error_get_internal_desc(_fs_status(&sd_app->info)), - fs_error_get_internal_desc(sd_info.error)); - dialog_ex_set_header(dialog, "Error", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text( - dialog, - string_get_cstr(sd_app->text_holder), - 64, - y_2_line, - AlignCenter, - AlignCenter); - view_holder_start(sd_app->view_holder); - } - - sd_app->sd_app_state = SdAppStateInfo; - } - break; - case SdAppEventTypeEject: - if(try_to_alloc_view_holder(sd_app, gui)) { - DialogEx* dialog = alloc_and_attach_dialog(sd_app); - dialog_ex_set_left_button_text(dialog, "Back"); - dialog_ex_set_right_button_text(dialog, "Eject"); - dialog_ex_set_header( - dialog, "Eject SD card?", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text( - dialog, - "SD card will be\nunavailable", - 64, - y_2_line, - AlignCenter, - AlignCenter); - view_holder_start(sd_app->view_holder); - sd_app->sd_app_state = SdAppStateEject; - } - break; - case SdAppEventTypeFileSelect: - if(!app_sd_make_path(event.payload.file_select_data.path)) { - SdAppFileSelectResultEvent retval = {.result = false}; - furi_check( - osMessageQueuePut(sd_app->result_receiver, &retval, 0, osWaitForever) == - osOK); - break; - } - if(try_to_alloc_view_holder(sd_app, gui)) { - FileSelect* file_select = alloc_and_attach_file_select(sd_app); - SdAppFileSelectData* file_select_data = &event.payload.file_select_data; - - file_select_set_api(file_select, fs_api); - file_select_set_filter( - file_select, file_select_data->path, file_select_data->extension); - file_select_set_result_buffer( - file_select, file_select_data->result, file_select_data->result_size); - if(!file_select_init(file_select)) { - SdAppFileSelectResultEvent retval = {.result = false}; - furi_check( - osMessageQueuePut( - sd_app->result_receiver, &retval, 0, osWaitForever) == osOK); - app_reset_state(sd_app); - } else { - sd_app->sd_app_state = SdAppStateFileSelect; - if(file_select_data->selected_filename != NULL) { - file_select_set_selected_file( - file_select, file_select_data->selected_filename); - } - view_holder_start(sd_app->view_holder); - } - } else { - SdAppFileSelectResultEvent retval = {.result = false}; - furi_check( - osMessageQueuePut(sd_app->result_receiver, &retval, 0, osWaitForever) == - osOK); - } - break; - case SdAppEventTypeCheckError: - if(sd_app->info.status != SD_OK) { - if(try_to_alloc_view_holder(sd_app, gui)) { - DialogEx* dialog = alloc_and_attach_dialog(sd_app); - dialog_ex_set_left_button_text(dialog, "Back"); - if(sd_app->info.status == SD_NO_CARD) { - dialog_ex_set_text( - dialog, - "SD card\nnot found", - 88, - y_1_line, - AlignCenter, - AlignCenter); - dialog_ex_set_icon(dialog, 5, 6, &I_SDQuestion_35x43); - } else { - dialog_ex_set_text( - dialog, "SD card\nerror", 88, y_1_line, AlignCenter, AlignCenter); - dialog_ex_set_icon(dialog, 5, 10, &I_SDError_43x35); - } - sd_app->sd_app_state = SdAppStateCheckError; - view_holder_start(sd_app->view_holder); - } - } - break; - case SdAppEventTypeShowError: - if(try_to_alloc_view_holder(sd_app, gui)) { - DialogEx* dialog = alloc_and_attach_dialog(sd_app); - dialog_ex_set_left_button_text(dialog, "Back"); - dialog_ex_set_text( - dialog, event.payload.error_text, 88, y_1_line, AlignCenter, AlignCenter); - dialog_ex_set_icon(dialog, 5, 6, &I_SDQuestion_35x43); - sd_app->sd_app_state = SdAppStateShowError; - view_holder_start(sd_app->view_holder); - } - break; - } - } - } - - return 0; -} diff --git a/applications/sd-filesystem/sd-filesystem.h b/applications/sd-filesystem/sd-filesystem.h deleted file mode 100644 index ca22468e..00000000 --- a/applications/sd-filesystem/sd-filesystem.h +++ /dev/null @@ -1,145 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include "sd-card-api.h" -#include "view_holder.h" -#include - -#define SD_FS_MAX_FILES _FS_LOCK -#define SD_STATE_LINES_COUNT 6 - -/* api data */ -typedef FIL SDFile; -typedef DIR SDDir; -typedef FILINFO SDFileInfo; - -/* storage for file/directory objects*/ -typedef union { - SDFile file; - SDDir dir; -} SDFileDirStorage; - -typedef enum { - SD_OK = FR_OK, - SD_DISK_ERR = FR_DISK_ERR, - SD_INT_ERR = FR_INT_ERR, - SD_NO_FILE = FR_NO_FILE, - SD_NO_PATH = FR_NO_PATH, - SD_INVALID_NAME = FR_INVALID_NAME, - SD_DENIED = FR_DENIED, - SD_EXIST = FR_EXIST, - SD_INVALID_OBJECT = FR_INVALID_OBJECT, - SD_WRITE_PROTECTED = FR_WRITE_PROTECTED, - SD_INVALID_DRIVE = FR_INVALID_DRIVE, - SD_NOT_ENABLED = FR_NOT_ENABLED, - SD_NO_FILESYSTEM = FR_NO_FILESYSTEM, - SD_MKFS_ABORTED = FR_MKFS_ABORTED, - SD_TIMEOUT = FR_TIMEOUT, - SD_LOCKED = FR_LOCKED, - SD_NOT_ENOUGH_CORE = FR_NOT_ENOUGH_CORE, - SD_TOO_MANY_OPEN_FILES = FR_TOO_MANY_OPEN_FILES, - SD_INVALID_PARAMETER = FR_INVALID_PARAMETER, - SD_NO_CARD, - SD_NOT_A_FILE, - SD_NOT_A_DIR, - SD_OTHER_APP, - SD_LOW_LEVEL_ERR, -} SDError; - -typedef enum { - FDF_DIR, - FDF_FILE, - FDF_ANY, -} FiledataFilter; - -typedef struct { - osThreadId_t thread_id; - bool is_dir; - SDFileDirStorage data; -} FileData; - -/* application data */ -typedef struct { - ViewPort* view_port; - const Icon* mounted; - const Icon* fail; -} SdFsIcon; - -typedef struct { - osMutexId_t mutex; - FileData files[SD_FS_MAX_FILES]; - SDError status; - char* path; - FATFS fat_fs; -} SdFsInfo; - -typedef enum { - SdAppStateBackground, - SdAppStateFormat, - SdAppStateFormatInProgress, - SdAppStateFormatCompleted, - SdAppStateInfo, - SdAppStateEject, - SdAppStateEjected, - SdAppStateFileSelect, - SdAppStateCheckError, - SdAppStateShowError, -} SdAppState; - -struct SdApp { - SdFsInfo info; - SdFsIcon icon; - - SdCard_Api sd_card_api; - SdAppState sd_app_state; - - ViewHolder* view_holder; - osMessageQueueId_t result_receiver; - - osMessageQueueId_t event_queue; - string_t text_holder; - - NotificationApp* notifications; -}; - -/* core api fns */ -bool _fs_init(SdFsInfo* _fs_info); -bool _fs_lock(SdFsInfo* fs_info); -bool _fs_unlock(SdFsInfo* fs_info); -SDError _fs_status(SdFsInfo* fs_info); - -/* sd api fns */ -bool fs_file_open(File* file, const char* path, FS_AccessMode access_mode, FS_OpenMode open_mode); -bool fs_file_close(File* file); -uint16_t fs_file_read(File* file, void* buff, uint16_t bytes_to_read); -uint16_t fs_file_write(File* file, const void* buff, uint16_t bytes_to_write); -bool fs_file_seek(File* file, uint32_t offset, bool from_start); -uint64_t fs_file_tell(File* file); -bool fs_file_truncate(File* file); -uint64_t fs_file_size(File* file); -bool fs_file_sync(File* file); -bool fs_file_eof(File* file); - -/* dir api */ -bool fs_dir_open(File* file, const char* path); -bool fs_dir_close(File* file); -bool fs_dir_read(File* file, FileInfo* fileinfo, char* name, uint16_t name_length); -bool fs_dir_rewind(File* file); - -/* common api */ -FS_Error - fs_common_info(const char* path, FileInfo* fileinfo, char* name, const uint16_t name_length); -FS_Error fs_common_remove(const char* path); -FS_Error fs_common_rename(const char* old_path, const char* new_path); -FS_Error fs_common_set_attr(const char* path, uint8_t attr, uint8_t mask); -FS_Error fs_common_mkdir(const char* path); -FS_Error fs_common_set_time(const char* path, FileDateUnion date, FileTimeUnion time); -FS_Error fs_get_fs_info(uint64_t* total_space, uint64_t* free_space); - -/* errors api */ -const char* fs_error_get_desc(FS_Error error_id); -const char* fs_error_get_internal_desc(uint32_t internal_error_id); \ No newline at end of file diff --git a/applications/storage-settings/scenes/storage-settings-benchmark.c b/applications/storage-settings/scenes/storage-settings-benchmark.c new file mode 100644 index 00000000..260e06a5 --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-benchmark.c @@ -0,0 +1,161 @@ +#include "../storage-settings.h" + +#define BENCH_DATA_SIZE 4096 +#define BENCH_COUNT 6 +#define BENCH_REPEATS 4 +#define BENCH_FILE "/ext/rwfiletest.bin" + +static void + storage_settings_scene_benchmark_dialog_callback(DialogExResult result, void* context) { + StorageSettings* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, result); +} + +static bool storage_settings_bench_write( + Storage* api, + uint16_t size, + const uint8_t* data, + uint32_t* speed) { + File* file = storage_file_alloc(api); + bool result = true; + if(storage_file_open(file, BENCH_FILE, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + uint32_t ticks; + ticks = osKernelGetTickCount(); + + for(size_t repeat = 0; repeat < BENCH_REPEATS; repeat++) { + for(size_t i = 0; i < BENCH_DATA_SIZE / size; i++) { + if(storage_file_write(file, (data + i * size), size) != size) { + result = false; + break; + } + } + } + + ticks = osKernelGetTickCount() - ticks; + *speed = BENCH_DATA_SIZE * osKernelGetTickFreq() * BENCH_REPEATS; + *speed /= ticks; + *speed /= 1024; + } + storage_file_close(file); + storage_file_free(file); + return result; +} + +static bool + storage_settings_bench_read(Storage* api, uint16_t size, uint8_t* data, uint32_t* speed) { + File* file = storage_file_alloc(api); + bool result = true; + *speed = -1; + + if(storage_file_open(file, BENCH_FILE, FSAM_READ, FSOM_OPEN_EXISTING)) { + uint32_t ticks; + ticks = osKernelGetTickCount(); + + for(size_t repeat = 0; repeat < BENCH_REPEATS; repeat++) { + for(size_t i = 0; i < BENCH_DATA_SIZE / size; i++) { + if(storage_file_read(file, (data + i * size), size) != size) { + result = false; + break; + } + } + } + + ticks = osKernelGetTickCount() - ticks; + *speed = BENCH_DATA_SIZE * osKernelGetTickFreq() * BENCH_REPEATS; + *speed /= ticks; + *speed /= 1024; + } + storage_file_close(file); + storage_file_free(file); + return result; +} + +static void storage_settings_benchmark(StorageSettings* app) { + DialogEx* dialog_ex = app->dialog_ex; + uint8_t* bench_data; + dialog_ex_set_header(dialog_ex, "Preparing data...", 64, 32, AlignCenter, AlignCenter); + + bench_data = malloc(BENCH_DATA_SIZE); + for(size_t i = 0; i < BENCH_DATA_SIZE; i++) { + bench_data[i] = (uint8_t)i; + } + + uint16_t bench_size[BENCH_COUNT] = {1, 8, 32, 256, 1024, 4096}; + uint32_t bench_w_speed[BENCH_COUNT] = {0, 0, 0, 0, 0, 0}; + uint32_t bench_r_speed[BENCH_COUNT] = {0, 0, 0, 0, 0, 0}; + + dialog_ex_set_header(dialog_ex, "Benchmarking...", 64, 32, AlignCenter, AlignCenter); + for(size_t i = 0; i < BENCH_COUNT; i++) { + if(!storage_settings_bench_write(app->fs_api, bench_size[i], bench_data, &bench_w_speed[i])) + break; + + if(i > 0) string_cat_printf(app->text_string, "\n"); + string_cat_printf(app->text_string, "%ub : W %luK ", bench_size[i], bench_w_speed[i]); + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text( + dialog_ex, string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter); + + if(!storage_settings_bench_read(app->fs_api, bench_size[i], bench_data, &bench_r_speed[i])) + break; + + string_cat_printf(app->text_string, "R %luK", bench_r_speed[i]); + dialog_ex_set_text( + dialog_ex, string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter); + } + + free(bench_data); +} + +void storage_settings_scene_benchmark_on_enter(void* context) { + StorageSettings* app = context; + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_context(dialog_ex, app); + dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_benchmark_dialog_callback); + view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); + + if(storage_sd_status(app->fs_api) != FSE_OK) { + dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text( + dialog_ex, + "If an SD card is inserted,\r\npull it out and reinsert it", + 64, + 32, + AlignCenter, + AlignCenter); + dialog_ex_set_left_button_text(dialog_ex, "Back"); + } else { + storage_settings_benchmark(app); + notification_message(app->notification, &sequence_blink_green_100); + } +} + +bool storage_settings_scene_benchmark_on_event(void* context, SceneManagerEvent event) { + StorageSettings* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case DialogExResultLeft: + consumed = scene_manager_previous_scene(app->scene_manager); + break; + } + } + return consumed; +} + +void storage_settings_scene_benchmark_on_exit(void* context) { + StorageSettings* app = context; + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); + + string_clean(app->text_string); +} diff --git a/applications/storage-settings/scenes/storage-settings-scene-config.h b/applications/storage-settings/scenes/storage-settings-scene-config.h new file mode 100644 index 00000000..1191a376 --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-scene-config.h @@ -0,0 +1,8 @@ +ADD_SCENE(storage_settings, start, Start) +ADD_SCENE(storage_settings, unmount_confirm, UnmountConfirm) +ADD_SCENE(storage_settings, unmounted, Unmounted) +ADD_SCENE(storage_settings, format_confirm, FormatConfirm) +ADD_SCENE(storage_settings, formatting, Formatting) +ADD_SCENE(storage_settings, sd_info, SDInfo) +ADD_SCENE(storage_settings, internal_info, InternalInfo) +ADD_SCENE(storage_settings, benchmark, Benchmark) \ No newline at end of file diff --git a/applications/storage-settings/scenes/storage-settings-scene-eject-confirm.c b/applications/storage-settings/scenes/storage-settings-scene-eject-confirm.c new file mode 100644 index 00000000..ec40352d --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-scene-eject-confirm.c @@ -0,0 +1,68 @@ +#include "../storage-settings.h" + +static void + storage_settings_scene_unmount_confirm_dialog_callback(DialogExResult result, void* context) { + StorageSettings* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, result); +} + +void storage_settings_scene_unmount_confirm_on_enter(void* context) { + StorageSettings* app = context; + FS_Error sd_status = storage_sd_status(app->fs_api); + DialogEx* dialog_ex = app->dialog_ex; + dialog_ex_set_left_button_text(dialog_ex, "Back"); + + if(sd_status == FSE_NOT_READY) { + dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text( + dialog_ex, + "If an SD card is inserted,\r\npull it out and reinsert it", + 64, + 32, + AlignCenter, + AlignCenter); + } else { + dialog_ex_set_right_button_text(dialog_ex, "Unmount"); + dialog_ex_set_header(dialog_ex, "Unmount SD card?", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text( + dialog_ex, "SD card will be\nunavailable", 64, 32, AlignCenter, AlignCenter); + } + + dialog_ex_set_context(dialog_ex, app); + dialog_ex_set_result_callback( + dialog_ex, storage_settings_scene_unmount_confirm_dialog_callback); + + view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); +} + +bool storage_settings_scene_unmount_confirm_on_event(void* context, SceneManagerEvent event) { + StorageSettings* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case DialogExResultLeft: + consumed = scene_manager_previous_scene(app->scene_manager); + break; + case DialogExResultRight: + scene_manager_next_scene(app->scene_manager, StorageSettingsUnmounted); + consumed = true; + break; + } + } + return consumed; +} + +void storage_settings_scene_unmount_confirm_on_exit(void* context) { + StorageSettings* app = context; + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); +} diff --git a/applications/storage-settings/scenes/storage-settings-scene-ejected.c b/applications/storage-settings/scenes/storage-settings-scene-ejected.c new file mode 100644 index 00000000..1ab2a6d9 --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-scene-ejected.c @@ -0,0 +1,65 @@ +#include "../storage-settings.h" + +static void + storage_settings_scene_unmounted_dialog_callback(DialogExResult result, void* context) { + StorageSettings* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, result); +} + +void storage_settings_scene_unmounted_on_enter(void* context) { + StorageSettings* app = context; + FS_Error error = storage_sd_unmount(app->fs_api); + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_left_button_text(dialog_ex, "Back"); + + if(error == FSE_OK) { + dialog_ex_set_header(dialog_ex, "SD card unmounted", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text( + dialog_ex, "Now the SD card\ncan be removed.", 64, 32, AlignCenter, AlignCenter); + notification_message(app->notification, &sequence_blink_green_100); + } else { + dialog_ex_set_header( + dialog_ex, "Cannot unmount SD Card", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text( + dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter); + notification_message(app->notification, &sequence_blink_red_100); + } + + dialog_ex_set_context(dialog_ex, app); + dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_unmounted_dialog_callback); + + view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); +} + +bool storage_settings_scene_unmounted_on_event(void* context, SceneManagerEvent event) { + StorageSettings* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case DialogExResultLeft: + consumed = + scene_manager_search_previous_scene(app->scene_manager, StorageSettingsStart); + break; + } + } else if(event.type == SceneManagerEventTypeNavigation) { + consumed = scene_manager_search_previous_scene(app->scene_manager, StorageSettingsStart); + } + + return consumed; +} + +void storage_settings_scene_unmounted_on_exit(void* context) { + StorageSettings* app = context; + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); +} diff --git a/applications/storage-settings/scenes/storage-settings-scene-format-confirm.c b/applications/storage-settings/scenes/storage-settings-scene-format-confirm.c new file mode 100644 index 00000000..92a8d532 --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-scene-format-confirm.c @@ -0,0 +1,67 @@ +#include "../storage-settings.h" + +static void + storage_settings_scene_format_confirm_dialog_callback(DialogExResult result, void* context) { + StorageSettings* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, result); +} + +void storage_settings_scene_format_confirm_on_enter(void* context) { + StorageSettings* app = context; + FS_Error sd_status = storage_sd_status(app->fs_api); + DialogEx* dialog_ex = app->dialog_ex; + dialog_ex_set_left_button_text(dialog_ex, "Back"); + + if(sd_status == FSE_NOT_READY) { + dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text( + dialog_ex, + "If an SD card is inserted,\r\npull it out and reinsert it", + 64, + 32, + AlignCenter, + AlignCenter); + } else { + dialog_ex_set_right_button_text(dialog_ex, "Format"); + dialog_ex_set_header(dialog_ex, "Format SD card?", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, "All data will be lost", 64, 32, AlignCenter, AlignCenter); + } + + dialog_ex_set_context(dialog_ex, app); + dialog_ex_set_result_callback( + dialog_ex, storage_settings_scene_format_confirm_dialog_callback); + + view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); +} + +bool storage_settings_scene_format_confirm_on_event(void* context, SceneManagerEvent event) { + StorageSettings* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case DialogExResultLeft: + consumed = scene_manager_previous_scene(app->scene_manager); + break; + case DialogExResultRight: + scene_manager_next_scene(app->scene_manager, StorageSettingsFormatting); + consumed = true; + break; + } + } + return consumed; +} + +void storage_settings_scene_format_confirm_on_exit(void* context) { + StorageSettings* app = context; + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); +} diff --git a/applications/storage-settings/scenes/storage-settings-scene-formatting.c b/applications/storage-settings/scenes/storage-settings-scene-formatting.c new file mode 100644 index 00000000..02a44947 --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-scene-formatting.c @@ -0,0 +1,85 @@ +#include "../storage-settings.h" + +static const NotificationMessage message_green_165 = { + .type = NotificationMessageTypeLedGreen, + .data.led.value = 165, +}; + +static const NotificationSequence sequence_set_formatting_leds = { + &message_red_255, + &message_green_165, + &message_blue_0, + &message_do_not_reset, + NULL, +}; + +static const NotificationSequence sequence_reset_formatting_leds = { + &message_red_0, + &message_green_0, + NULL, +}; + +static void + storage_settings_scene_formatting_dialog_callback(DialogExResult result, void* context) { + StorageSettings* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, result); +} + +void storage_settings_scene_formatting_on_enter(void* context) { + StorageSettings* app = context; + FS_Error error; + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_header(dialog_ex, "Formatting...", 64, 32, AlignCenter, AlignCenter); + view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); + + notification_message_block(app->notification, &sequence_set_formatting_leds); + error = storage_sd_format(app->fs_api); + notification_message(app->notification, &sequence_reset_formatting_leds); + notification_message(app->notification, &sequence_blink_green_100); + + if(error != FSE_OK) { + dialog_ex_set_header(dialog_ex, "Cannot format SD Card", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text( + dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter); + } else { + dialog_ex_set_header(dialog_ex, "SD card formatted", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, "Press back to return", 64, 32, AlignCenter, AlignCenter); + } + + dialog_ex_set_context(dialog_ex, app); + dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_formatting_dialog_callback); + dialog_ex_set_left_button_text(dialog_ex, "Back"); +} + +bool storage_settings_scene_formatting_on_event(void* context, SceneManagerEvent event) { + StorageSettings* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case DialogExResultLeft: + consumed = + scene_manager_search_previous_scene(app->scene_manager, StorageSettingsStart); + break; + } + } else if(event.type == SceneManagerEventTypeNavigation) { + consumed = scene_manager_search_previous_scene(app->scene_manager, StorageSettingsStart); + } + + return consumed; +} + +void storage_settings_scene_formatting_on_exit(void* context) { + StorageSettings* app = context; + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); +} diff --git a/applications/storage-settings/scenes/storage-settings-scene-internal-info.c b/applications/storage-settings/scenes/storage-settings-scene-internal-info.c new file mode 100644 index 00000000..5dff893a --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-scene-internal-info.c @@ -0,0 +1,68 @@ +#include "../storage-settings.h" +#include + +static void + storage_settings_scene_internal_info_dialog_callback(DialogExResult result, void* context) { + StorageSettings* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, result); +} + +void storage_settings_scene_internal_info_on_enter(void* context) { + StorageSettings* app = context; + uint64_t total_space; + uint64_t free_space; + FS_Error error = storage_common_fs_info(app->fs_api, "/int", &total_space, &free_space); + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_context(dialog_ex, app); + dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_internal_info_dialog_callback); + + dialog_ex_set_left_button_text(dialog_ex, "Back"); + if(error != FSE_OK) { + dialog_ex_set_header( + dialog_ex, "Internal storage error", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text( + dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter); + } else { + string_printf( + app->text_string, + "Label: %s\nType: LittleFS\n%lu KB total\n%lu KB free", + api_hal_version_get_name_ptr(), + (uint32_t)(total_space / 1024), + (uint32_t)(free_space / 1024)); + dialog_ex_set_text( + dialog_ex, string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop); + } + + view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); +} + +bool storage_settings_scene_internal_info_on_event(void* context, SceneManagerEvent event) { + StorageSettings* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case DialogExResultLeft: + consumed = scene_manager_previous_scene(app->scene_manager); + break; + } + } + return consumed; +} + +void storage_settings_scene_internal_info_on_exit(void* context) { + StorageSettings* app = context; + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); + + string_clean(app->text_string); +} diff --git a/applications/storage-settings/scenes/storage-settings-scene-sd-info.c b/applications/storage-settings/scenes/storage-settings-scene-sd-info.c new file mode 100644 index 00000000..617b2281 --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-scene-sd-info.c @@ -0,0 +1,74 @@ +#include "../storage-settings.h" + +static void storage_settings_scene_sd_info_dialog_callback(DialogExResult result, void* context) { + StorageSettings* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, result); +} + +void storage_settings_scene_sd_info_on_enter(void* context) { + StorageSettings* app = context; + SDInfo sd_info; + FS_Error sd_status = storage_sd_info(app->fs_api, &sd_info); + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_context(dialog_ex, app); + dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_sd_info_dialog_callback); + + dialog_ex_set_left_button_text(dialog_ex, "Back"); + if(sd_status != FSE_OK) { + dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_text( + dialog_ex, + "If an SD card is inserted,\r\npull it out and reinsert it", + 64, + 32, + AlignCenter, + AlignCenter); + } else { + string_printf( + app->text_string, + "Label: %s\nType: %s\n%lu KB total\n%lu KB free", + sd_info.label, + sd_api_get_fs_type_text(sd_info.fs_type), + sd_info.kb_total, + sd_info.kb_free); + dialog_ex_set_text( + dialog_ex, string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop); + } + + view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); +} + +bool storage_settings_scene_sd_info_on_event(void* context, SceneManagerEvent event) { + StorageSettings* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case DialogExResultLeft: + consumed = scene_manager_previous_scene(app->scene_manager); + break; + case DialogExResultRight: + scene_manager_next_scene(app->scene_manager, StorageSettingsUnmounted); + consumed = true; + break; + } + } + return consumed; +} + +void storage_settings_scene_sd_info_on_exit(void* context) { + StorageSettings* app = context; + DialogEx* dialog_ex = app->dialog_ex; + + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); + + string_clean(app->text_string); +} diff --git a/applications/storage-settings/scenes/storage-settings-scene-start.c b/applications/storage-settings/scenes/storage-settings-scene-start.c new file mode 100644 index 00000000..f3c42b08 --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-scene-start.c @@ -0,0 +1,104 @@ +#include "../storage-settings.h" + +enum StorageSettingsStartSubmenuIndex { + StorageSettingsStartSubmenuIndexInternalInfo, + StorageSettingsStartSubmenuIndexSDInfo, + StorageSettingsStartSubmenuIndexUnmount, + StorageSettingsStartSubmenuIndexFormat, + StorageSettingsStartSubmenuIndexBenchy, +}; + +static void storage_settings_scene_start_submenu_callback(void* context, uint32_t index) { + StorageSettings* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void storage_settings_scene_start_on_enter(void* context) { + StorageSettings* app = context; + Submenu* submenu = app->submenu; + + submenu_add_item( + submenu, + "About internal storage", + StorageSettingsStartSubmenuIndexInternalInfo, + storage_settings_scene_start_submenu_callback, + app); + submenu_add_item( + submenu, + "About SD Card", + StorageSettingsStartSubmenuIndexSDInfo, + storage_settings_scene_start_submenu_callback, + app); + submenu_add_item( + submenu, + "Unmount SD Card", + StorageSettingsStartSubmenuIndexUnmount, + storage_settings_scene_start_submenu_callback, + app); + submenu_add_item( + submenu, + "Format SD Card", + StorageSettingsStartSubmenuIndexFormat, + storage_settings_scene_start_submenu_callback, + app); + submenu_add_item( + submenu, + "Benchmark SD Card", + StorageSettingsStartSubmenuIndexBenchy, + storage_settings_scene_start_submenu_callback, + app); + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, StorageSettingsStart)); + + view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewSubmenu); +} + +bool storage_settings_scene_start_on_event(void* context, SceneManagerEvent event) { + StorageSettings* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case StorageSettingsStartSubmenuIndexSDInfo: + scene_manager_set_scene_state( + app->scene_manager, StorageSettingsStart, StorageSettingsStartSubmenuIndexSDInfo); + scene_manager_next_scene(app->scene_manager, StorageSettingsSDInfo); + consumed = true; + break; + case StorageSettingsStartSubmenuIndexInternalInfo: + scene_manager_set_scene_state( + app->scene_manager, + StorageSettingsStart, + StorageSettingsStartSubmenuIndexInternalInfo); + scene_manager_next_scene(app->scene_manager, StorageSettingsInternalInfo); + consumed = true; + break; + case StorageSettingsStartSubmenuIndexUnmount: + scene_manager_set_scene_state( + app->scene_manager, StorageSettingsStart, StorageSettingsStartSubmenuIndexUnmount); + scene_manager_next_scene(app->scene_manager, StorageSettingsUnmountConfirm); + consumed = true; + break; + case StorageSettingsStartSubmenuIndexFormat: + scene_manager_set_scene_state( + app->scene_manager, StorageSettingsStart, StorageSettingsStartSubmenuIndexFormat); + scene_manager_next_scene(app->scene_manager, StorageSettingsFormatConfirm); + consumed = true; + break; + case StorageSettingsStartSubmenuIndexBenchy: + scene_manager_set_scene_state( + app->scene_manager, StorageSettingsStart, StorageSettingsStartSubmenuIndexBenchy); + scene_manager_next_scene(app->scene_manager, StorageSettingsBenchmark); + consumed = true; + break; + } + } + return consumed; +} + +void storage_settings_scene_start_on_exit(void* context) { + StorageSettings* app = context; + submenu_clean(app->submenu); +} diff --git a/applications/storage-settings/scenes/storage-settings-scene.c b/applications/storage-settings/scenes/storage-settings-scene.c new file mode 100644 index 00000000..ea4c3f00 --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-scene.c @@ -0,0 +1,30 @@ +#include "storage-settings-scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const storage_settings_on_enter_handlers[])(void*) = { +#include "storage-settings-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 storage_settings_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "storage-settings-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 storage_settings_on_exit_handlers[])(void* context) = { +#include "storage-settings-scene-config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers storage_settings_scene_handlers = { + .on_enter_handlers = storage_settings_on_enter_handlers, + .on_event_handlers = storage_settings_on_event_handlers, + .on_exit_handlers = storage_settings_on_exit_handlers, + .scene_num = StorageSettingsSceneNum, +}; diff --git a/applications/storage-settings/scenes/storage-settings-scene.h b/applications/storage-settings/scenes/storage-settings-scene.h new file mode 100644 index 00000000..86ade12d --- /dev/null +++ b/applications/storage-settings/scenes/storage-settings-scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) StorageSettings##id, +typedef enum { +#include "storage-settings-scene-config.h" + StorageSettingsSceneNum, +} StorageSettingsScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers storage_settings_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "storage-settings-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 "storage-settings-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 "storage-settings-scene-config.h" +#undef ADD_SCENE diff --git a/applications/storage-settings/storage-settings.c b/applications/storage-settings/storage-settings.c new file mode 100644 index 00000000..19213e19 --- /dev/null +++ b/applications/storage-settings/storage-settings.c @@ -0,0 +1,75 @@ +#include "storage-settings.h" + +static bool storage_settings_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + StorageSettings* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool storage_settings_navigation_event_callback(void* context) { + furi_assert(context); + StorageSettings* app = context; + return scene_manager_handle_navigation_event(app->scene_manager); +} + +static StorageSettings* storage_settings_alloc() { + StorageSettings* app = malloc(sizeof(StorageSettings)); + + app->gui = furi_record_open("gui"); + app->fs_api = furi_record_open("storage"); + app->notification = furi_record_open("notification"); + + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&storage_settings_scene_handlers, app); + string_init(app->text_string); + + 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, storage_settings_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, storage_settings_navigation_event_callback); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + app->submenu = submenu_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, StorageSettingsViewSubmenu, submenu_get_view(app->submenu)); + + app->dialog_ex = dialog_ex_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, StorageSettingsViewDialogEx, dialog_ex_get_view(app->dialog_ex)); + + scene_manager_next_scene(app->scene_manager, StorageSettingsStart); + + return app; +} + +static void storage_settings_free(StorageSettings* app) { + view_dispatcher_remove_view(app->view_dispatcher, StorageSettingsViewSubmenu); + submenu_free(app->submenu); + + view_dispatcher_remove_view(app->view_dispatcher, StorageSettingsViewDialogEx); + dialog_ex_free(app->dialog_ex); + + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + + furi_record_close("gui"); + furi_record_close("storage"); + furi_record_close("notification"); + + string_clear(app->text_string); + + free(app); +} + +int32_t storage_settings(void* p) { + StorageSettings* app = storage_settings_alloc(); + + view_dispatcher_run(app->view_dispatcher); + + storage_settings_free(app); + return 0; +} \ No newline at end of file diff --git a/applications/storage-settings/storage-settings.h b/applications/storage-settings/storage-settings.h new file mode 100644 index 00000000..f79066c7 --- /dev/null +++ b/applications/storage-settings/storage-settings.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "scenes/storage-settings-scene.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + // records + Gui* gui; + NotificationApp* notification; + Storage* fs_api; + + // view managment + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + + // view modules + Submenu* submenu; + DialogEx* dialog_ex; + + // text + string_t text_string; +} StorageSettings; + +typedef enum { + StorageSettingsViewSubmenu, + StorageSettingsViewDialogEx, +} StorageSettingsView; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/filesystem-api-defines.h b/applications/storage/filesystem-api-defines.h new file mode 100644 index 00000000..dc6d0679 --- /dev/null +++ b/applications/storage/filesystem-api-defines.h @@ -0,0 +1,59 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Access mode flags */ +typedef enum { + FSAM_READ = (1 << 0), /**< Read access */ + FSAM_WRITE = (1 << 1), /**< Write access */ +} FS_AccessMode; + +/** Open mode flags */ +typedef enum { + FSOM_OPEN_EXISTING = 1, /**< Open file, fail if file doesn't exist */ + FSOM_OPEN_ALWAYS = 2, /**< Open file. Create new file if not exist */ + FSOM_OPEN_APPEND = 4, /**< Open file. Create new file if not exist. Set R/W pointer to EOF */ + FSOM_CREATE_NEW = 8, /**< Creates a new file. Fails if the file is exist */ + FSOM_CREATE_ALWAYS = 16, /**< Creates a new file. If file exist, truncate to zero size */ +} FS_OpenMode; + +/** API errors enumeration */ +typedef enum { + FSE_OK, /**< No error */ + FSE_NOT_READY, /**< FS not ready */ + FSE_EXIST, /**< File/Dir alrady exist */ + FSE_NOT_EXIST, /**< File/Dir does not exist */ + FSE_INVALID_PARAMETER, /**< Invalid API parameter */ + FSE_DENIED, /**< Access denied */ + FSE_INVALID_NAME, /**< Invalid name/path */ + FSE_INTERNAL, /**< Internal error */ + FSE_NOT_IMPLEMENTED, /**< Functon not implemented */ + FSE_ALREADY_OPEN, /**< File/Dir already opened */ +} FS_Error; + +/** FileInfo flags */ +typedef enum { + FSF_DIRECTORY = (1 << 0), /**< Directory */ +} FS_Flags; + +/** Structure that hold file index and returned api errors */ +typedef struct File File; + +/** Structure that hold file info */ +typedef struct { + uint8_t flags; /**< flags from FS_Flags enum */ + uint64_t size; /**< file size */ +} FileInfo; + +/** Gets the error text from FS_Error + * @param error_id error id + * @return const char* error text + */ +const char* filesystem_api_error_get_desc(FS_Error error_id); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/filesystem-api-internal.h b/applications/storage/filesystem-api-internal.h new file mode 100644 index 00000000..44f38d00 --- /dev/null +++ b/applications/storage/filesystem-api-internal.h @@ -0,0 +1,192 @@ +#pragma once +#include +#include "filesystem-api-defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Structure that hold file index and returned api errors */ +struct File { + uint32_t file_id; /**< File ID for internal references */ + FS_Error error_id; /**< Standart API error from FS_Error enum */ + int32_t internal_error_id; /**< Internal API error value */ + void* storage; +}; + +/** File api structure + * @var FS_File_Api::open + * @brief Open file + * @param file pointer to file object, filled by api + * @param path path to file + * @param access_mode access mode from FS_AccessMode + * @param open_mode open mode from FS_OpenMode + * @return success flag + * + * @var FS_File_Api::close + * @brief Close file + * @param file pointer to file object + * @return success flag + * + * @var FS_File_Api::read + * @brief Read bytes from file to buffer + * @param file pointer to file object + * @param buff pointer to buffer for reading + * @param bytes_to_read how many bytes to read, must be smaller or equal to buffer size + * @return how many bytes actually has been readed + * + * @var FS_File_Api::write + * @brief Write bytes from buffer to file + * @param file pointer to file object + * @param buff pointer to buffer for writing + * @param bytes_to_read how many bytes to write, must be smaller or equal to buffer size + * @return how many bytes actually has been writed + * + * @var FS_File_Api::seek + * @brief Move r/w pointer + * @param file pointer to file object + * @param offset offset to move r/w pointer + * @param from_start set offset from start, or from current position + * @return success flag + * + * @var FS_File_Api::tell + * @brief Get r/w pointer position + * @param file pointer to file object + * @return current r/w pointer position + * + * @var FS_File_Api::truncate + * @brief Truncate file size to current r/w pointer position + * @param file pointer to file object + * @return success flag + * + * @var FS_File_Api::size + * @brief Fet file size + * @param file pointer to file object + * @return file size + * + * @var FS_File_Api::sync + * @brief Write file cache to storage + * @param file pointer to file object + * @return success flag + * + * @var FS_File_Api::eof + * @brief Checks that the r/w pointer is at the end of the file + * @param file pointer to file object + * @return end of file flag + */ +typedef struct { + bool (*open)( + void* context, + File* file, + const char* path, + FS_AccessMode access_mode, + FS_OpenMode open_mode); + bool (*close)(void* context, File* file); + uint16_t (*read)(void* context, File* file, void* buff, uint16_t bytes_to_read); + uint16_t (*write)(void* context, File* file, const void* buff, uint16_t bytes_to_write); + bool (*seek)(void* context, File* file, uint32_t offset, bool from_start); + uint64_t (*tell)(void* context, File* file); + bool (*truncate)(void* context, File* file); + uint64_t (*size)(void* context, File* file); + bool (*sync)(void* context, File* file); + bool (*eof)(void* context, File* file); +} FS_File_Api; + +/** Dir api structure + * @var FS_Dir_Api::open + * @brief Open directory to get objects from + * @param file pointer to file object, filled by api + * @param path path to directory + * @return success flag + * + * @var FS_Dir_Api::close + * @brief Close directory + * @param file pointer to file object + * @return success flag + * + * @var FS_Dir_Api::read + * @brief Read next object info in directory + * @param file pointer to file object + * @param fileinfo pointer to readed FileInfo, can be NULL + * @param name pointer to name buffer, can be NULL + * @param name_length name buffer length + * @return success flag (if next object not exist also returns false and set error_id to FSE_NOT_EXIST) + * + * @var FS_Dir_Api::rewind + * @brief Rewind to first object info in directory + * @param file pointer to file object + * @return success flag + */ +typedef struct { + bool (*open)(void* context, File* file, const char* path); + bool (*close)(void* context, File* file); + bool (*read)(void* context, File* file, FileInfo* fileinfo, char* name, uint16_t name_length); + bool (*rewind)(void* context, File* file); +} FS_Dir_Api; + +/** Common api structure + * @var FS_Common_Api::stat + * @brief Open directory to get objects from + * @param path path to file/directory + * @param fileinfo pointer to readed FileInfo, can be NULL + * @param name pointer to name buffer, can be NULL + * @param name_length name buffer length + * @return FS_Error error info + * + * @var FS_Common_Api::remove + * @brief Remove file/directory from storage, + * directory must be empty, + * file/directory must not be opened, + * file/directory must not have FSF_READ_ONLY flag + * @param path path to file/directory + * @return FS_Error error info + * + * @var FS_Common_Api::rename + * @brief Rename file/directory, + * file/directory must not be opened + * @param path path to file/directory + * @return FS_Error error info + * + * @var FS_Common_Api::mkdir + * @brief Create new directory + * @param path path to new directory + * @return FS_Error error info + * + * @var FS_Common_Api::fs_info + * @brief Get total and free space storage values + * @param fs_path path of fs + * @param total_space pointer to total space value + * @param free_space pointer to free space value + * @return FS_Error error info + */ +typedef struct { + FS_Error (*stat)(void* context, const char* path, FileInfo* fileinfo); + FS_Error (*remove)(void* context, const char* path); + FS_Error (*rename)(void* context, const char* old_path, const char* new_path); + FS_Error (*mkdir)(void* context, const char* path); + FS_Error ( + *fs_info)(void* context, const char* fs_path, uint64_t* total_space, uint64_t* free_space); +} FS_Common_Api; + +/** Errors api structure + * @var FS_Error_Api::get_desc + * @brief Get error description text + * @param error_id FS_Error error id (for fire/dir functions result can be obtained from File.error_id) + * @return pointer to description text + */ +typedef struct { + const char* (*get_desc)(void* context, FS_Error error_id); +} FS_Error_Api; + +/** Full filesystem api structure */ +typedef struct { + FS_File_Api file; + FS_Dir_Api dir; + FS_Common_Api common; + FS_Error_Api error; + void* context; +} FS_Api; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/filesystem-api.c b/applications/storage/filesystem-api.c new file mode 100644 index 00000000..e5736bae --- /dev/null +++ b/applications/storage/filesystem-api.c @@ -0,0 +1,38 @@ +#include "filesystem-api-defines.h" + +const char* filesystem_api_error_get_desc(FS_Error error_id) { + const char* result = "unknown error"; + switch(error_id) { + case(FSE_OK): + result = "OK"; + break; + case(FSE_NOT_READY): + result = "filesystem not ready"; + break; + case(FSE_EXIST): + result = "file/dir already exist"; + break; + case(FSE_NOT_EXIST): + result = "file/dir not exist"; + break; + case(FSE_INVALID_PARAMETER): + result = "invalid parameter"; + break; + case(FSE_DENIED): + result = "access denied"; + break; + case(FSE_INVALID_NAME): + result = "invalid name/path"; + break; + case(FSE_INTERNAL): + result = "internal error"; + break; + case(FSE_NOT_IMPLEMENTED): + result = "function not implemented"; + break; + case(FSE_ALREADY_OPEN): + result = "file is already open"; + break; + } + return result; +} \ No newline at end of file diff --git a/applications/storage/storage-cli.c b/applications/storage/storage-cli.c new file mode 100644 index 00000000..bf49faa2 --- /dev/null +++ b/applications/storage/storage-cli.c @@ -0,0 +1,350 @@ +#include +#include +#include +#include +#include +#include + +#define MAX_NAME_LENGTH 255 + +void storage_cli(Cli* cli, string_t args, void* context); + +// app cli function +void storage_cli_init() { + Cli* cli = furi_record_open("cli"); + cli_add_command(cli, "storage", CliCommandFlagDefault, storage_cli, NULL); + furi_record_close("cli"); +} + +void storage_cli_print_usage() { + printf("Usage:\r\n"); + printf("storage \r\n"); + printf("The path must start with /int or /ext\r\n"); + printf("Cmd list:\r\n"); + printf("\tinfo\t - get FS info\r\n"); + printf("\tformat\t - format filesystem\r\n"); + printf("\tlist\t - list files and dirs\r\n"); + printf("\tremove\t - delete the file or directory\r\n"); + printf("\tread\t - read data from file and print file size and content to cli\r\n"); + printf( + "\twrite\t - read data from cli and append it to file, should contain how many bytes you want to write\r\n"); + printf("\tcopy\t - copy file to new file, must contain new path\r\n"); + printf("\trename\t - move file to new file, must contain new path\r\n"); +}; + +void storage_cli_print_error(FS_Error error) { + printf("Storage error: %s\r\n", storage_error_get_desc(error)); +} + +void storage_cli_print_path_error(string_t path, FS_Error error) { + printf( + "Storage error for path \"%s\": %s\r\n", + string_get_cstr(path), + storage_error_get_desc(error)); +} + +void storage_cli_print_file_error(string_t path, File* file) { + printf( + "Storage error for path \"%s\": %s\r\n", + string_get_cstr(path), + storage_file_get_error_desc(file)); +} + +void storage_cli_info(Cli* cli, string_t path) { + Storage* api = furi_record_open("storage"); + + if(string_cmp_str(path, "/int") == 0) { + uint64_t total_space; + uint64_t free_space; + FS_Error error = storage_common_fs_info(api, "/int", &total_space, &free_space); + + if(error != FSE_OK) { + storage_cli_print_path_error(path, error); + } else { + printf( + "Label: %s\r\nType: LittleFS\r\n%lu KB total\r\n%lu KB free\r\n", + api_hal_version_get_name_ptr(), + (uint32_t)(total_space / 1024), + (uint32_t)(free_space / 1024)); + } + } else if(string_cmp_str(path, "/ext") == 0) { + SDInfo sd_info; + FS_Error error = storage_sd_info(api, &sd_info); + + if(error != FSE_OK) { + storage_cli_print_path_error(path, error); + } else { + printf( + "Label: %s\r\nType: %s\r\n%lu KB total\r\n%lu KB free\r\n", + sd_info.label, + sd_api_get_fs_type_text(sd_info.fs_type), + sd_info.kb_total, + sd_info.kb_free); + } + } else { + storage_cli_print_usage(); + } + + furi_record_close("storage"); +}; + +void storage_cli_format(Cli* cli, string_t path) { + if(string_cmp_str(path, "/int") == 0) { + storage_cli_print_path_error(path, FSE_NOT_IMPLEMENTED); + } else if(string_cmp_str(path, "/ext") == 0) { + printf("Formatting SD card, all data will be lost. Are you sure (y/n)?\r\n"); + char answer = cli_getc(cli); + if(answer == 'y' || answer == 'Y') { + Storage* api = furi_record_open("storage"); + printf("Formatting, please wait...\r\n"); + + FS_Error error = storage_sd_format(api); + + if(error != FSE_OK) { + storage_cli_print_path_error(path, error); + } else { + printf("SD card was successfully formatted.\r\n"); + } + furi_record_close("storage"); + } else { + printf("Cancelled.\r\n"); + } + } else { + storage_cli_print_usage(); + } +}; + +void storage_cli_list(Cli* cli, string_t path) { + if(string_cmp_str(path, "/") == 0) { + printf("\t[D] int\r\n"); + printf("\t[D] ext\r\n"); + printf("\t[D] any\r\n"); + } else { + Storage* api = furi_record_open("storage"); + File* file = storage_file_alloc(api); + + if(storage_dir_open(file, string_get_cstr(path))) { + FileInfo fileinfo; + char name[MAX_NAME_LENGTH]; + bool readed = false; + + while(storage_dir_read(file, &fileinfo, name, MAX_NAME_LENGTH)) { + readed = true; + if(fileinfo.flags & FSF_DIRECTORY) { + printf("\t[D] %s\r\n", name); + } else { + printf("\t[F] %s %lub\r\n", name, (uint32_t)(fileinfo.size)); + } + } + + if(!readed) { + printf("\tEmpty\r\n"); + } + } else { + storage_cli_print_file_error(path, file); + } + + storage_dir_close(file); + storage_file_free(file); + furi_record_close("storage"); + } +} + +void storage_cli_read(Cli* cli, string_t path) { + Storage* api = furi_record_open("storage"); + File* file = storage_file_alloc(api); + + if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + const uint16_t read_size = 128; + uint16_t readed_size = 0; + uint8_t* data = furi_alloc(read_size); + + printf("Size: %lu\r\n", (uint32_t)storage_file_size(file)); + + do { + readed_size = storage_file_read(file, data, read_size); + for(uint16_t i = 0; i < readed_size; i++) { + printf("%c", data[i]); + } + } while(readed_size > 0); + printf("\r\n"); + + free(data); + } else { + storage_cli_print_file_error(path, file); + } + + storage_file_close(file); + storage_file_free(file); + + furi_record_close("storage"); +} + +void storage_cli_write(Cli* cli, string_t path, string_t args) { + Storage* api = furi_record_open("storage"); + File* file = storage_file_alloc(api); + + uint32_t size; + int parsed_count = sscanf(string_get_cstr(args), "%lu", &size); + + if(parsed_count == EOF || parsed_count != 1) { + storage_cli_print_usage(); + } else { + if(storage_file_open(file, string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) { + const uint16_t write_size = 8; + uint32_t readed_index = 0; + uint8_t* data = furi_alloc(write_size); + + while(true) { + data[readed_index % write_size] = cli_getc(cli); + printf("%c", data[readed_index % write_size]); + fflush(stdout); + readed_index++; + + if(((readed_index % write_size) == 0)) { + uint16_t writed_size = storage_file_write(file, data, write_size); + + if(writed_size != write_size) { + storage_cli_print_file_error(path, file); + break; + } + } else if(readed_index == size) { + uint16_t writed_size = storage_file_write(file, data, size % write_size); + + if(writed_size != (size % write_size)) { + storage_cli_print_file_error(path, file); + break; + } + } + + if(readed_index == size) { + break; + } + } + printf("\r\n"); + + free(data); + } else { + storage_cli_print_file_error(path, file); + } + storage_file_close(file); + } + + storage_file_free(file); + furi_record_close("storage"); +} + +void storage_cli_copy(Cli* cli, string_t old_path, string_t args) { + Storage* api = furi_record_open("storage"); + string_t new_path; + string_init(new_path); + + if(!args_read_probably_quoted_string_and_trim(args, new_path)) { + storage_cli_print_usage(); + } else { + FS_Error error = + storage_common_copy(api, string_get_cstr(old_path), string_get_cstr(new_path)); + + if(error != FSE_OK) { + storage_cli_print_error(error); + } + } + + string_clear(new_path); + furi_record_close("storage"); +} + +void storage_cli_remove(Cli* cli, string_t path) { + Storage* api = furi_record_open("storage"); + FS_Error error = storage_common_remove(api, string_get_cstr(path)); + + if(error != FSE_OK) { + storage_cli_print_error(error); + } + + furi_record_close("storage"); +} + +void storage_cli_rename(Cli* cli, string_t old_path, string_t args) { + Storage* api = furi_record_open("storage"); + string_t new_path; + string_init(new_path); + + if(!args_read_probably_quoted_string_and_trim(args, new_path)) { + storage_cli_print_usage(); + } else { + FS_Error error = + storage_common_rename(api, string_get_cstr(old_path), string_get_cstr(new_path)); + + if(error != FSE_OK) { + storage_cli_print_error(error); + } + } + + string_clear(new_path); + furi_record_close("storage"); +} + +void storage_cli(Cli* cli, string_t args, void* context) { + string_t cmd; + string_t path; + string_init(cmd); + string_init(path); + + do { + if(!args_read_string_and_trim(args, cmd)) { + storage_cli_print_usage(); + break; + } + + if(!args_read_probably_quoted_string_and_trim(args, path)) { + storage_cli_print_usage(); + break; + } + + if(string_cmp_str(cmd, "info") == 0) { + storage_cli_info(cli, path); + break; + } + + if(string_cmp_str(cmd, "format") == 0) { + storage_cli_format(cli, path); + break; + } + + if(string_cmp_str(cmd, "list") == 0) { + storage_cli_list(cli, path); + break; + } + + if(string_cmp_str(cmd, "read") == 0) { + storage_cli_read(cli, path); + break; + } + + if(string_cmp_str(cmd, "write") == 0) { + storage_cli_write(cli, path, args); + break; + } + + if(string_cmp_str(cmd, "copy") == 0) { + storage_cli_copy(cli, path, args); + break; + } + + if(string_cmp_str(cmd, "remove") == 0) { + storage_cli_remove(cli, path); + break; + } + + if(string_cmp_str(cmd, "rename") == 0) { + storage_cli_rename(cli, path, args); + break; + } + + storage_cli_print_usage(); + } while(false); + + string_clear(path); + string_clear(cmd); +} \ No newline at end of file diff --git a/applications/storage/storage-external-api.c b/applications/storage/storage-external-api.c new file mode 100644 index 00000000..7063d182 --- /dev/null +++ b/applications/storage/storage-external-api.c @@ -0,0 +1,383 @@ +#include "storage.h" +#include "storage-i.h" +#include "storage-message.h" + +#define S_API_PROLOGUE \ + osSemaphoreId_t semaphore = osSemaphoreNew(1, 0, NULL); \ + furi_check(semaphore != NULL); + +#define S_FILE_API_PROLOGUE \ + Storage* storage = file->storage; \ + furi_assert(storage); + +#define S_API_EPILOGUE \ + furi_check(osMessageQueuePut(storage->message_queue, &message, 0, osWaitForever) == osOK); \ + osSemaphoreAcquire(semaphore, osWaitForever); \ + osSemaphoreDelete(semaphore); + +#define S_API_MESSAGE(_command) \ + SAReturn return_data; \ + StorageMessage message = { \ + .semaphore = semaphore, \ + .command = _command, \ + .data = &data, \ + .return_data = &return_data, \ + }; + +#define S_API_DATA_FILE \ + SAData data = { \ + .file = { \ + .file = file, \ + }}; + +#define S_API_DATA_PATH \ + SAData data = { \ + .path = { \ + .path = path, \ + }}; + +#define S_RETURN_BOOL (return_data.bool_value); +#define S_RETURN_UINT16 (return_data.uint16_value); +#define S_RETURN_UINT64 (return_data.uint64_value); +#define S_RETURN_ERROR (return_data.error_value); +#define S_RETURN_CSTRING (return_data.cstring_value); + +#define FILE_OPENED 1 +#define FILE_CLOSED 0 + +/****************** FILE ******************/ + +bool storage_file_open( + File* file, + const char* path, + FS_AccessMode access_mode, + FS_OpenMode open_mode) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + + SAData data = { + .fopen = { + .file = file, + .path = path, + .access_mode = access_mode, + .open_mode = open_mode, + }}; + + file->file_id = FILE_OPENED; + + S_API_MESSAGE(StorageCommandFileOpen); + S_API_EPILOGUE; + + return S_RETURN_BOOL; +} + +bool storage_file_close(File* file) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + + S_API_DATA_FILE; + S_API_MESSAGE(StorageCommandFileClose); + S_API_EPILOGUE; + + file->file_id = FILE_CLOSED; + + return S_RETURN_BOOL; +} + +uint16_t storage_file_read(File* file, void* buff, uint16_t bytes_to_read) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + + SAData data = { + .fread = { + .file = file, + .buff = buff, + .bytes_to_read = bytes_to_read, + }}; + + S_API_MESSAGE(StorageCommandFileRead); + S_API_EPILOGUE; + return S_RETURN_UINT16; +} + +uint16_t storage_file_write(File* file, const void* buff, uint16_t bytes_to_write) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + + SAData data = { + .fwrite = { + .file = file, + .buff = buff, + .bytes_to_write = bytes_to_write, + }}; + + S_API_MESSAGE(StorageCommandFileWrite); + S_API_EPILOGUE; + return S_RETURN_UINT16; +} + +bool storage_file_seek(File* file, uint32_t offset, bool from_start) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + + SAData data = { + .fseek = { + .file = file, + .offset = offset, + .from_start = from_start, + }}; + + S_API_MESSAGE(StorageCommandFileSeek); + S_API_EPILOGUE; + return S_RETURN_BOOL; +} + +uint64_t storage_file_tell(File* file) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + S_API_DATA_FILE; + S_API_MESSAGE(StorageCommandFileTell); + S_API_EPILOGUE; + return S_RETURN_UINT64; +} + +bool storage_file_truncate(File* file) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + S_API_DATA_FILE; + S_API_MESSAGE(StorageCommandFileTruncate); + S_API_EPILOGUE; + return S_RETURN_BOOL; +} + +uint64_t storage_file_size(File* file) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + S_API_DATA_FILE; + S_API_MESSAGE(StorageCommandFileSize); + S_API_EPILOGUE; + return S_RETURN_UINT64; +} + +bool storage_file_sync(File* file) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + S_API_DATA_FILE; + S_API_MESSAGE(StorageCommandFileSync); + S_API_EPILOGUE; + return S_RETURN_BOOL; +} + +bool storage_file_eof(File* file) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + S_API_DATA_FILE; + S_API_MESSAGE(StorageCommandFileEof); + S_API_EPILOGUE; + return S_RETURN_BOOL; +} + +/****************** DIR ******************/ + +bool storage_dir_open(File* file, const char* path) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + + SAData data = { + .dopen = { + .file = file, + .path = path, + }}; + + file->file_id = FILE_OPENED; + + S_API_MESSAGE(StorageCommandDirOpen); + S_API_EPILOGUE; + return S_RETURN_BOOL; +} + +bool storage_dir_close(File* file) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + S_API_DATA_FILE; + S_API_MESSAGE(StorageCommandDirClose); + S_API_EPILOGUE; + + file->file_id = FILE_CLOSED; + + return S_RETURN_BOOL; +} + +bool storage_dir_read(File* file, FileInfo* fileinfo, char* name, uint16_t name_length) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + + SAData data = { + .dread = { + .file = file, + .fileinfo = fileinfo, + .name = name, + .name_length = name_length, + }}; + + S_API_MESSAGE(StorageCommandDirRead); + S_API_EPILOGUE; + return S_RETURN_BOOL; +} + +bool storage_dir_rewind(File* file) { + S_FILE_API_PROLOGUE; + S_API_PROLOGUE; + S_API_DATA_FILE; + S_API_MESSAGE(StorageCommandDirRewind); + S_API_EPILOGUE; + return S_RETURN_BOOL; +} + +/****************** COMMON ******************/ + +FS_Error storage_common_stat(Storage* storage, const char* path, FileInfo* fileinfo) { + S_API_PROLOGUE; + + SAData data = {.cstat = {.path = path, .fileinfo = fileinfo}}; + + S_API_MESSAGE(StorageCommandCommonStat); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + +FS_Error storage_common_remove(Storage* storage, const char* path) { + S_API_PROLOGUE; + S_API_DATA_PATH; + S_API_MESSAGE(StorageCommandCommonRemove); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + +FS_Error storage_common_rename(Storage* storage, const char* old_path, const char* new_path) { + S_API_PROLOGUE; + + SAData data = { + .cpaths = { + .old = old_path, + .new = new_path, + }}; + + S_API_MESSAGE(StorageCommandCommonRename); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + +FS_Error storage_common_copy(Storage* storage, const char* old_path, const char* new_path) { + S_API_PROLOGUE; + + SAData data = { + .cpaths = { + .old = old_path, + .new = new_path, + }}; + + S_API_MESSAGE(StorageCommandCommonCopy); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + +FS_Error storage_common_mkdir(Storage* storage, const char* path) { + S_API_PROLOGUE; + S_API_DATA_PATH; + S_API_MESSAGE(StorageCommandCommonMkDir); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + +FS_Error storage_common_fs_info( + Storage* storage, + const char* fs_path, + uint64_t* total_space, + uint64_t* free_space) { + S_API_PROLOGUE; + + SAData data = { + .cfsinfo = { + .fs_path = fs_path, + .total_space = total_space, + .free_space = free_space, + }}; + + S_API_MESSAGE(StorageCommandCommonFSInfo); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + +/****************** ERROR ******************/ + +const char* storage_error_get_desc(FS_Error error_id) { + return filesystem_api_error_get_desc(error_id); +} + +FS_Error storage_file_get_error(File* file) { + furi_check(file != NULL); + return file->error_id; +} + +const char* storage_file_get_error_desc(File* file) { + furi_check(file != NULL); + return filesystem_api_error_get_desc(file->error_id); +} + +/****************** Raw SD API ******************/ + +FS_Error storage_sd_format(Storage* storage) { + S_API_PROLOGUE; + SAData data = {}; + S_API_MESSAGE(StorageCommandSDFormat); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + +FS_Error storage_sd_unmount(Storage* storage) { + S_API_PROLOGUE; + SAData data = {}; + S_API_MESSAGE(StorageCommandSDUnmount); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + +FS_Error storage_sd_info(Storage* storage, SDInfo* info) { + S_API_PROLOGUE; + SAData data = { + .sdinfo = { + .info = info, + }}; + S_API_MESSAGE(StorageCommandSDInfo); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + +FS_Error storage_sd_status(Storage* storage) { + S_API_PROLOGUE; + SAData data = {}; + S_API_MESSAGE(StorageCommandSDStatus); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + +File* storage_file_alloc(Storage* storage) { + File* file = furi_alloc(sizeof(File)); + file->file_id = FILE_CLOSED; + file->storage = storage; + + return file; +} + +bool storage_file_is_open(File* file) { + return (file->file_id != FILE_CLOSED); +} + +void storage_file_free(File* file) { + if(storage_file_is_open(file)) { + storage_file_close(file); + } + + free(file); +} \ No newline at end of file diff --git a/applications/storage/storage-glue.c b/applications/storage/storage-glue.c new file mode 100644 index 00000000..9477712d --- /dev/null +++ b/applications/storage/storage-glue.c @@ -0,0 +1,212 @@ +#include "storage-glue.h" +#include + +/****************** storage file ******************/ + +void storage_file_init(StorageFile* obj) { + obj->file = NULL; + obj->type = ST_ERROR; + obj->file_data = NULL; + string_init(obj->path); +} + +void storage_file_init_set(StorageFile* obj, const StorageFile* src) { + obj->file = src->file; + obj->type = src->type; + obj->file_data = src->file_data; + string_init_set(obj->path, src->path); +} + +void storage_file_set(StorageFile* obj, const StorageFile* src) { + obj->file = src->file; + obj->type = src->type; + obj->file_data = src->file_data; + string_set(obj->path, src->path); +} + +void storage_file_clear(StorageFile* obj) { + string_clear(obj->path); +} + +/****************** storage data ******************/ + +void storage_data_init(StorageData* storage) { + storage->mutex = osMutexNew(NULL); + furi_check(storage->mutex != NULL); + storage->data = NULL; + storage->status = StorageStatusNotReady; + StorageFileList_init(storage->files); +} + +bool storage_data_lock(StorageData* storage) { + api_hal_power_insomnia_enter(); + return (osMutexAcquire(storage->mutex, osWaitForever) == osOK); +} + +bool storage_data_unlock(StorageData* storage) { + api_hal_power_insomnia_exit(); + return (osMutexRelease(storage->mutex) == osOK); +} + +StorageStatus storage_data_status(StorageData* storage) { + StorageStatus status; + + storage_data_lock(storage); + status = storage->status; + storage_data_unlock(storage); + + return status; +} + +const char* storage_data_status_text(StorageData* storage) { + const char* result = "unknown"; + switch(storage->status) { + case StorageStatusOK: + result = "ok"; + break; + case StorageStatusNotReady: + result = "not ready"; + break; + case StorageStatusNotMounted: + result = "not mounted"; + break; + case StorageStatusNoFS: + result = "no filesystem"; + break; + case StorageStatusNotAccessible: + result = "not accessible"; + break; + case StorageStatusErrorInternal: + result = "internal"; + break; + } + + return result; +} + +/****************** storage glue ******************/ + +bool storage_has_file(const File* file, StorageData* storage_data) { + bool result = false; + + StorageFileList_it_t it; + for(StorageFileList_it(it, storage_data->files); !StorageFileList_end_p(it); + StorageFileList_next(it)) { + const StorageFile* storage_file = StorageFileList_cref(it); + + if(storage_file->file->file_id == file->file_id) { + result = true; + break; + } + } + + return result; +} + +StorageType storage_get_type_by_path(const char* path) { + StorageType type = ST_ERROR; + + const char* ext_path = "/ext"; + const char* int_path = "/int"; + const char* any_path = "/any"; + + if(strlen(path) >= strlen(ext_path) && memcmp(path, ext_path, strlen(ext_path)) == 0) { + type = ST_EXT; + } else if(strlen(path) >= strlen(int_path) && memcmp(path, int_path, strlen(int_path)) == 0) { + type = ST_INT; + } else if(strlen(path) >= strlen(any_path) && memcmp(path, any_path, strlen(any_path)) == 0) { + type = ST_ANY; + } + + return type; +} + +bool storage_path_already_open(const char* path, StorageFileList_t array) { + bool open = false; + + StorageFileList_it_t it; + + for(StorageFileList_it(it, array); !StorageFileList_end_p(it); StorageFileList_next(it)) { + const StorageFile* storage_file = StorageFileList_cref(it); + + if(string_cmp(storage_file->path, path) == 0) { + open = true; + break; + } + } + + return open; +} + +void storage_set_storage_file_data(const File* file, void* file_data, StorageData* storage) { + StorageFile* founded_file = NULL; + + StorageFileList_it_t it; + + for(StorageFileList_it(it, storage->files); !StorageFileList_end_p(it); + StorageFileList_next(it)) { + StorageFile* storage_file = StorageFileList_ref(it); + + if(storage_file->file->file_id == file->file_id) { + founded_file = storage_file; + break; + } + } + + furi_check(founded_file != NULL); + + founded_file->file_data = file_data; +} + +void* storage_get_storage_file_data(const File* file, StorageData* storage) { + const StorageFile* founded_file = NULL; + + StorageFileList_it_t it; + + for(StorageFileList_it(it, storage->files); !StorageFileList_end_p(it); + StorageFileList_next(it)) { + const StorageFile* storage_file = StorageFileList_cref(it); + + if(storage_file->file->file_id == file->file_id) { + founded_file = storage_file; + break; + } + } + + furi_check(founded_file != NULL); + + return founded_file->file_data; +} + +void storage_push_storage_file( + File* file, + const char* path, + StorageType type, + StorageData* storage) { + StorageFile* storage_file = StorageFileList_push_new(storage->files); + furi_check(storage_file != NULL); + + file->file_id = (uint32_t)storage_file; + storage_file->file = file; + storage_file->type = type; + string_set(storage_file->path, path); +} + +bool storage_pop_storage_file(File* file, StorageData* storage) { + StorageFileList_it_t it; + bool result = false; + + for(StorageFileList_it(it, storage->files); !StorageFileList_end_p(it); + StorageFileList_next(it)) { + if(StorageFileList_cref(it)->file->file_id == file->file_id) { + result = true; + break; + } + } + + if(result) { + StorageFileList_remove(storage->files, it); + } + + return result; +} diff --git a/applications/storage/storage-glue.h b/applications/storage/storage-glue.h new file mode 100644 index 00000000..775742cc --- /dev/null +++ b/applications/storage/storage-glue.h @@ -0,0 +1,79 @@ +#pragma once +#include +#include "filesystem-api-internal.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { ST_EXT = 0, ST_INT = 1, ST_ANY, ST_ERROR } StorageType; + +typedef struct StorageData StorageData; + +typedef struct { + void (*tick)(StorageData* storage); +} StorageApi; + +typedef struct { + File* file; + StorageType type; + void* file_data; + string_t path; +} StorageFile; + +typedef enum { + StorageStatusOK, /**< storage ok */ + StorageStatusNotReady, /**< storage not ready (not initialized or waiting for data storage to appear) */ + StorageStatusNotMounted, /**< datastore appeared, but we cannot mount it */ + StorageStatusNoFS, /**< datastore appeared and mounted, but does not have a file system */ + StorageStatusNotAccessible, /**< datastore appeared and mounted, but not available */ + StorageStatusErrorInternal, /**< any other internal error */ +} StorageStatus; + +void storage_file_init(StorageFile* obj); +void storage_file_init_set(StorageFile* obj, const StorageFile* src); +void storage_file_set(StorageFile* obj, const StorageFile* src); +void storage_file_clear(StorageFile* obj); + +void storage_data_init(StorageData* storage); +bool storage_data_lock(StorageData* storage); +bool storage_data_unlock(StorageData* storage); +StorageStatus storage_data_status(StorageData* storage); +const char* storage_data_status_text(StorageData* storage); + +LIST_DEF( + StorageFileList, + StorageFile, + (INIT(API_2(storage_file_init)), + SET(API_6(storage_file_init_set)), + INIT_SET(API_6(storage_file_set)), + CLEAR(API_2(storage_file_clear)))) + +struct StorageData { + FS_Api fs_api; + StorageApi api; + void* data; + osMutexId_t mutex; + StorageStatus status; + StorageFileList_t files; +}; + +bool storage_has_file(const File* file, StorageData* storage_data); +StorageType storage_get_type_by_path(const char* path); +bool storage_path_already_open(const char* path, StorageFileList_t files); + +void storage_set_storage_file_data(const File* file, void* file_data, StorageData* storage); +void* storage_get_storage_file_data(const File* file, StorageData* storage); + +void storage_push_storage_file( + File* file, + const char* path, + StorageType type, + StorageData* storage); +bool storage_pop_storage_file(File* file, StorageData* storage); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/storage-i.h b/applications/storage/storage-i.h new file mode 100644 index 00000000..9ce3dc03 --- /dev/null +++ b/applications/storage/storage-i.h @@ -0,0 +1,27 @@ +#pragma once +#include +#include +#include "storage-glue.h" +#include "storage-sd-api.h" +#include "filesystem-api-internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define STORAGE_COUNT (ST_INT + 1) + +typedef struct { + ViewPort* view_port; + bool enabled; +} StorageSDGui; + +struct Storage { + osMessageQueueId_t message_queue; + StorageData storage[STORAGE_COUNT]; + StorageSDGui sd_gui; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/storage-message.h b/applications/storage/storage-message.h new file mode 100644 index 00000000..0d409587 --- /dev/null +++ b/applications/storage/storage-message.h @@ -0,0 +1,142 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + File* file; + const char* path; + FS_AccessMode access_mode; + FS_OpenMode open_mode; +} SADataFOpen; + +typedef struct { + File* file; + void* buff; + uint16_t bytes_to_read; +} SADataFRead; + +typedef struct { + File* file; + const void* buff; + uint16_t bytes_to_write; +} SADataFWrite; + +typedef struct { + File* file; + uint32_t offset; + bool from_start; +} SADataFSeek; + +typedef struct { + File* file; + const char* path; +} SADataDOpen; + +typedef struct { + File* file; + FileInfo* fileinfo; + char* name; + uint16_t name_length; +} SADataDRead; + +typedef struct { + const char* path; + FileInfo* fileinfo; +} SADataCStat; + +typedef struct { + const char* old; + const char* new; +} SADataCPaths; + +typedef struct { + const char* fs_path; + uint64_t* total_space; + uint64_t* free_space; +} SADataCFSInfo; + +typedef struct { + uint32_t id; +} SADataError; + +typedef struct { + const char* path; +} SADataPath; + +typedef struct { + File* file; +} SADataFile; + +typedef struct { + SDInfo* info; +} SAInfo; + +typedef union { + SADataFOpen fopen; + SADataFRead fread; + SADataFWrite fwrite; + SADataFSeek fseek; + + SADataDOpen dopen; + SADataDRead dread; + + SADataCStat cstat; + SADataCPaths cpaths; + SADataCFSInfo cfsinfo; + + SADataError error; + + SADataFile file; + SADataPath path; + + SAInfo sdinfo; +} SAData; + +typedef union { + bool bool_value; + uint16_t uint16_value; + uint64_t uint64_value; + FS_Error error_value; + const char* cstring_value; +} SAReturn; + +typedef enum { + StorageCommandFileOpen, + StorageCommandFileClose, + StorageCommandFileRead, + StorageCommandFileWrite, + StorageCommandFileSeek, + StorageCommandFileTell, + StorageCommandFileTruncate, + StorageCommandFileSize, + StorageCommandFileSync, + StorageCommandFileEof, + StorageCommandDirOpen, + StorageCommandDirClose, + StorageCommandDirRead, + StorageCommandDirRewind, + StorageCommandCommonStat, + StorageCommandCommonRemove, + StorageCommandCommonRename, + StorageCommandCommonCopy, + StorageCommandCommonMkDir, + StorageCommandCommonFSInfo, + StorageCommandSDFormat, + StorageCommandSDUnmount, + StorageCommandSDInfo, + StorageCommandSDStatus, +} StorageCommand; + +typedef struct { + osSemaphoreId_t semaphore; + StorageCommand command; + SAData* data; + SAReturn* return_data; +} StorageMessage; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/storage-processing.c b/applications/storage/storage-processing.c new file mode 100644 index 00000000..fd4cc08c --- /dev/null +++ b/applications/storage/storage-processing.c @@ -0,0 +1,584 @@ +#include "storage-processing.h" + +#define FS_CALL(_storage, _fn) \ + storage_data_lock(_storage); \ + ret = _storage->fs_api._fn; \ + storage_data_unlock(_storage); + +#define ST_CALL(_storage, _fn) \ + storage_data_lock(_storage); \ + ret = _storage->api._fn; \ + storage_data_unlock(_storage); + +static StorageData* storage_get_storage_by_type(Storage* app, StorageType type) { + StorageData* storage; + + if(type == ST_ANY) { + type = ST_INT; + StorageData* ext_storage = &app->storage[ST_EXT]; + + if(storage_data_status(ext_storage) == StorageStatusOK) { + type = ST_EXT; + } + } + storage = &app->storage[type]; + + return storage; +} + +static bool storage_type_is_not_valid(StorageType type) { + return type >= ST_ERROR; +} + +static StorageData* get_storage_by_file(File* file, StorageData* storages) { + StorageData* storage_data = NULL; + + for(uint8_t i = 0; i < STORAGE_COUNT; i++) { + if(storage_has_file(file, &storages[i])) { + storage_data = &storages[i]; + } + } + + return storage_data; +} + +const char* remove_vfs(const char* path) { + return path + MIN(4, strlen(path)); +} + +/******************* File Functions *******************/ + +bool storage_process_file_open( + Storage* app, + File* file, + const char* path, + FS_AccessMode access_mode, + FS_OpenMode open_mode) { + bool ret = false; + StorageType type = storage_get_type_by_path(path); + StorageData* storage; + file->error_id = FSE_OK; + + if(storage_type_is_not_valid(type)) { + file->error_id = FSE_INVALID_NAME; + } else { + storage = storage_get_storage_by_type(app, type); + if(storage_path_already_open(path, storage->files)) { + file->error_id = FSE_ALREADY_OPEN; + } else { + storage_push_storage_file(file, path, type, storage); + FS_CALL(storage, file.open(storage, file, remove_vfs(path), access_mode, open_mode)); + } + } + + return ret; +} + +bool storage_process_file_close(Storage* app, File* file) { + bool ret = false; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, file.close(storage, file)); + storage_pop_storage_file(file, storage); + } + + return ret; +} + +static uint16_t + storage_process_file_read(Storage* app, File* file, void* buff, uint16_t const bytes_to_read) { + uint16_t ret = 0; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, file.read(storage, file, buff, bytes_to_read)); + } + + return ret; +} + +static uint16_t storage_process_file_write( + Storage* app, + File* file, + const void* buff, + uint16_t const bytes_to_write) { + uint16_t ret = 0; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, file.write(storage, file, buff, bytes_to_write)); + } + + return ret; +} + +static bool storage_process_file_seek( + Storage* app, + File* file, + const uint32_t offset, + const bool from_start) { + bool ret = false; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, file.seek(storage, file, offset, from_start)); + } + + return ret; +} + +static uint64_t storage_process_file_tell(Storage* app, File* file) { + uint64_t ret = 0; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, file.tell(storage, file)); + } + + return ret; +} + +static bool storage_process_file_truncate(Storage* app, File* file) { + bool ret = false; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, file.truncate(storage, file)); + } + + return ret; +} + +static bool storage_process_file_sync(Storage* app, File* file) { + bool ret = false; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, file.sync(storage, file)); + } + + return ret; +} + +static uint64_t storage_process_file_size(Storage* app, File* file) { + uint64_t ret = 0; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, file.size(storage, file)); + } + + return ret; +} + +static bool storage_process_file_eof(Storage* app, File* file) { + bool ret = false; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, file.eof(storage, file)); + } + + return ret; +} + +/******************* Dir Functions *******************/ + +bool storage_process_dir_open(Storage* app, File* file, const char* path) { + bool ret = false; + StorageType type = storage_get_type_by_path(path); + StorageData* storage; + file->error_id = FSE_OK; + + if(storage_type_is_not_valid(type)) { + file->error_id = FSE_INVALID_NAME; + } else { + storage = storage_get_storage_by_type(app, type); + if(storage_path_already_open(path, storage->files)) { + file->error_id = FSE_ALREADY_OPEN; + } else { + storage_push_storage_file(file, path, type, storage); + FS_CALL(storage, dir.open(storage, file, remove_vfs(path))); + } + } + + return ret; +} + +bool storage_process_dir_close(Storage* app, File* file) { + bool ret = false; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, dir.close(storage, file)); + storage_pop_storage_file(file, storage); + } + + return ret; +} + +bool storage_process_dir_read( + Storage* app, + File* file, + FileInfo* fileinfo, + char* name, + const uint16_t name_length) { + bool ret = false; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, dir.read(storage, file, fileinfo, name, name_length)); + } + + return ret; +} + +bool storage_process_dir_rewind(Storage* app, File* file) { + bool ret = false; + StorageData* storage = get_storage_by_file(file, app->storage); + + if(storage == NULL) { + file->error_id = FSE_INVALID_PARAMETER; + } else { + FS_CALL(storage, dir.rewind(storage, file)); + } + + return ret; +} + +/******************* Common FS Functions *******************/ + +static FS_Error storage_process_common_stat(Storage* app, const char* path, FileInfo* fileinfo) { + FS_Error ret = FSE_OK; + StorageType type = storage_get_type_by_path(path); + + if(storage_type_is_not_valid(type)) { + ret = FSE_INVALID_NAME; + } else { + StorageData* storage = storage_get_storage_by_type(app, type); + FS_CALL(storage, common.stat(storage, remove_vfs(path), fileinfo)); + } + + return ret; +} + +static FS_Error storage_process_common_remove(Storage* app, const char* path) { + FS_Error ret = FSE_OK; + StorageType type = storage_get_type_by_path(path); + + do { + if(storage_type_is_not_valid(type)) { + ret = FSE_INVALID_NAME; + break; + } + + StorageData* storage = storage_get_storage_by_type(app, type); + if(storage_path_already_open(path, storage->files)) { + ret = FSE_ALREADY_OPEN; + break; + } + + FS_CALL(storage, common.remove(storage, remove_vfs(path))); + } while(false); + + return ret; +} + +static FS_Error storage_process_common_copy(Storage* app, const char* old, const char* new) { + FS_Error ret = FSE_INTERNAL; + File file_old; + File file_new; + + do { + if(!storage_process_file_open(app, &file_old, old, FSAM_READ, FSOM_OPEN_EXISTING)) { + ret = storage_file_get_error(&file_old); + storage_process_file_close(app, &file_old); + break; + } + + if(!storage_process_file_open(app, &file_new, new, FSAM_WRITE, FSOM_CREATE_NEW)) { + ret = storage_file_get_error(&file_new); + storage_process_file_close(app, &file_new); + break; + } + + const uint16_t buffer_size = 64; + uint8_t* buffer = malloc(buffer_size); + uint16_t readed_size = 0; + uint16_t writed_size = 0; + + while(true) { + readed_size = storage_process_file_read(app, &file_old, buffer, buffer_size); + ret = storage_file_get_error(&file_old); + if(readed_size == 0) break; + + writed_size = storage_process_file_write(app, &file_new, buffer, readed_size); + ret = storage_file_get_error(&file_new); + if(writed_size < readed_size) break; + } + + free(buffer); + storage_process_file_close(app, &file_old); + storage_process_file_close(app, &file_new); + } while(false); + + return ret; +} + +static FS_Error storage_process_common_rename(Storage* app, const char* old, const char* new) { + FS_Error ret = FSE_INTERNAL; + StorageType type_old = storage_get_type_by_path(old); + StorageType type_new = storage_get_type_by_path(new); + + if(storage_type_is_not_valid(type_old) || storage_type_is_not_valid(type_old)) { + ret = FSE_INVALID_NAME; + } else { + if(type_old != type_new) { + ret = storage_process_common_copy(app, old, new); + if(ret == FSE_OK) { + ret = storage_process_common_remove(app, old); + } + } else { + StorageData* storage = storage_get_storage_by_type(app, type_old); + FS_CALL(storage, common.rename(storage, remove_vfs(old), remove_vfs(new))); + } + } + + return ret; +} + +static FS_Error storage_process_common_mkdir(Storage* app, const char* path) { + FS_Error ret = FSE_OK; + StorageType type = storage_get_type_by_path(path); + + if(storage_type_is_not_valid(type)) { + ret = FSE_INVALID_NAME; + } else { + StorageData* storage = storage_get_storage_by_type(app, type); + FS_CALL(storage, common.mkdir(storage, remove_vfs(path))); + } + + return ret; +} + +static FS_Error storage_process_common_fs_info( + Storage* app, + const char* fs_path, + uint64_t* total_space, + uint64_t* free_space) { + FS_Error ret = FSE_OK; + StorageType type = storage_get_type_by_path(fs_path); + + if(storage_type_is_not_valid(type)) { + ret = FSE_INVALID_NAME; + } else { + StorageData* storage = storage_get_storage_by_type(app, type); + FS_CALL(storage, common.fs_info(storage, remove_vfs(fs_path), total_space, free_space)); + } + + return ret; +} + +/****************** Raw SD API ******************/ +// TODO think about implementing a custom storage API to split that kind of api linkage +#include "storages/storage-ext.h" + +static FS_Error storage_process_sd_format(Storage* app) { + FS_Error ret = FSE_OK; + + if(storage_data_status(&app->storage[ST_EXT]) == StorageStatusNotReady) { + ret = FSE_NOT_READY; + } else { + ret = sd_format_card(&app->storage[ST_EXT]); + } + + return ret; +} + +static FS_Error storage_process_sd_unmount(Storage* app) { + FS_Error ret = FSE_OK; + + if(storage_data_status(&app->storage[ST_EXT]) == StorageStatusNotReady) { + ret = FSE_NOT_READY; + } else { + sd_unmount_card(&app->storage[ST_EXT]); + } + + return ret; +} + +static FS_Error storage_process_sd_info(Storage* app, SDInfo* info) { + FS_Error ret = FSE_OK; + + if(storage_data_status(&app->storage[ST_EXT]) == StorageStatusNotReady) { + ret = FSE_NOT_READY; + } else { + ret = sd_card_info(&app->storage[ST_EXT], info); + } + + return ret; +} + +static FS_Error storage_process_sd_status(Storage* app) { + FS_Error ret; + StorageStatus status = storage_data_status(&app->storage[ST_EXT]); + + switch(status) { + case StorageStatusOK: + ret = FSE_OK; + break; + case StorageStatusNotReady: + ret = FSE_NOT_READY; + break; + default: + ret = FSE_INTERNAL; + break; + } + + return ret; +} + +/****************** API calls processing ******************/ + +void storage_process_message(Storage* app, StorageMessage* message) { + switch(message->command) { + case StorageCommandFileOpen: + message->return_data->bool_value = storage_process_file_open( + app, + message->data->fopen.file, + message->data->fopen.path, + message->data->fopen.access_mode, + message->data->fopen.open_mode); + break; + case StorageCommandFileClose: + message->return_data->bool_value = + storage_process_file_close(app, message->data->fopen.file); + break; + case StorageCommandFileRead: + message->return_data->uint16_value = storage_process_file_read( + app, + message->data->fread.file, + message->data->fread.buff, + message->data->fread.bytes_to_read); + break; + case StorageCommandFileWrite: + message->return_data->uint16_value = storage_process_file_write( + app, + message->data->fwrite.file, + message->data->fwrite.buff, + message->data->fwrite.bytes_to_write); + break; + case StorageCommandFileSeek: + message->return_data->bool_value = storage_process_file_seek( + app, + message->data->fseek.file, + message->data->fseek.offset, + message->data->fseek.from_start); + break; + case StorageCommandFileTell: + message->return_data->uint64_value = + storage_process_file_tell(app, message->data->file.file); + break; + case StorageCommandFileTruncate: + message->return_data->bool_value = + storage_process_file_truncate(app, message->data->file.file); + break; + case StorageCommandFileSync: + message->return_data->bool_value = + storage_process_file_sync(app, message->data->file.file); + break; + case StorageCommandFileSize: + message->return_data->uint64_value = + storage_process_file_size(app, message->data->file.file); + break; + case StorageCommandFileEof: + message->return_data->bool_value = storage_process_file_eof(app, message->data->file.file); + break; + + case StorageCommandDirOpen: + message->return_data->bool_value = + storage_process_dir_open(app, message->data->dopen.file, message->data->dopen.path); + break; + case StorageCommandDirClose: + message->return_data->bool_value = + storage_process_dir_close(app, message->data->file.file); + break; + case StorageCommandDirRead: + message->return_data->bool_value = storage_process_dir_read( + app, + message->data->dread.file, + message->data->dread.fileinfo, + message->data->dread.name, + message->data->dread.name_length); + break; + case StorageCommandDirRewind: + message->return_data->bool_value = + storage_process_dir_rewind(app, message->data->file.file); + break; + case StorageCommandCommonStat: + message->return_data->error_value = storage_process_common_stat( + app, message->data->cstat.path, message->data->cstat.fileinfo); + break; + case StorageCommandCommonRemove: + message->return_data->error_value = + storage_process_common_remove(app, message->data->path.path); + break; + case StorageCommandCommonRename: + message->return_data->error_value = storage_process_common_rename( + app, message->data->cpaths.old, message->data->cpaths.new); + break; + case StorageCommandCommonCopy: + message->return_data->error_value = + storage_process_common_copy(app, message->data->cpaths.old, message->data->cpaths.new); + break; + case StorageCommandCommonMkDir: + message->return_data->error_value = + storage_process_common_mkdir(app, message->data->path.path); + break; + case StorageCommandCommonFSInfo: + message->return_data->error_value = storage_process_common_fs_info( + app, + message->data->cfsinfo.fs_path, + message->data->cfsinfo.total_space, + message->data->cfsinfo.free_space); + break; + case StorageCommandSDFormat: + message->return_data->error_value = storage_process_sd_format(app); + break; + case StorageCommandSDUnmount: + message->return_data->error_value = storage_process_sd_unmount(app); + break; + case StorageCommandSDInfo: + message->return_data->error_value = + storage_process_sd_info(app, message->data->sdinfo.info); + break; + case StorageCommandSDStatus: + message->return_data->error_value = storage_process_sd_status(app); + break; + } + + osSemaphoreRelease(message->semaphore); +} diff --git a/applications/storage/storage-processing.h b/applications/storage/storage-processing.h new file mode 100644 index 00000000..806eb196 --- /dev/null +++ b/applications/storage/storage-processing.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "storage.h" +#include "storage-i.h" +#include "storage-message.h" +#include "storage-glue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void storage_process_message(Storage* app, StorageMessage* message); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/storage-sd-api.c b/applications/storage/storage-sd-api.c new file mode 100644 index 00000000..83fc7a76 --- /dev/null +++ b/applications/storage/storage-sd-api.c @@ -0,0 +1,21 @@ +#include "storage-sd-api.h" + +const char* sd_api_get_fs_type_text(SDFsType fs_type) { + switch(fs_type) { + case(FST_FAT12): + return "FAT12"; + break; + case(FST_FAT16): + return "FAT16"; + break; + case(FST_FAT32): + return "FAT32"; + break; + case(FST_EXFAT): + return "EXFAT"; + break; + default: + return "UNKNOWN"; + break; + } +} \ No newline at end of file diff --git a/applications/storage/storage-sd-api.h b/applications/storage/storage-sd-api.h new file mode 100644 index 00000000..44ae772c --- /dev/null +++ b/applications/storage/storage-sd-api.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include "filesystem-api-defines.h" +#include +#include "storage-glue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_LABEL_LENGTH 34 + +typedef enum { + FST_FAT12 = FS_FAT12, + FST_FAT16 = FS_FAT16, + FST_FAT32 = FS_FAT32, + FST_EXFAT = FS_EXFAT, +} SDFsType; + +typedef struct { + SDFsType fs_type; + uint32_t kb_total; + uint32_t kb_free; + uint16_t cluster_size; + uint16_t sector_size; + char label[SD_LABEL_LENGTH]; + FS_Error error; +} SDInfo; + +const char* sd_api_get_fs_type_text(SDFsType fs_type); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/storage-test-app.c b/applications/storage/storage-test-app.c new file mode 100644 index 00000000..bfc8216f --- /dev/null +++ b/applications/storage/storage-test-app.c @@ -0,0 +1,341 @@ +#include +#include +#include + +#define TAG "storage-test" +#define BYTES_COUNT 16 +#define TEST_STRING "TestDataStringProvidedByDiceRoll" +#define SEEK_OFFSET_FROM_START 10 +#define SEEK_OFFSET_INCREASE 12 +#define SEEK_OFFSET_SUM (SEEK_OFFSET_FROM_START + SEEK_OFFSET_INCREASE) + +static void do_file_test(Storage* api, const char* path) { + File* file = storage_file_alloc(api); + bool result; + uint8_t bytes[BYTES_COUNT + 1]; + uint8_t bytes_count; + uint64_t position; + uint64_t size; + + FURI_LOG_I(TAG, "--------- FILE \"%s\" ---------", path); + + // open + result = storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS); + if(result) { + FURI_LOG_I(TAG, "open"); + } else { + FURI_LOG_E(TAG, "open, %s", storage_file_get_error_desc(file)); + } + + // write + bytes_count = storage_file_write(file, TEST_STRING, strlen(TEST_STRING)); + if(bytes_count == 0) { + FURI_LOG_E(TAG, "write, %s", storage_file_get_error_desc(file)); + } else { + FURI_LOG_I(TAG, "write"); + } + + // sync + result = storage_file_sync(file); + if(result) { + FURI_LOG_I(TAG, "sync"); + } else { + FURI_LOG_E(TAG, "sync, %s", storage_file_get_error_desc(file)); + } + + // eof #1 + result = storage_file_eof(file); + if(result) { + FURI_LOG_I(TAG, "eof #1"); + } else { + FURI_LOG_E(TAG, "eof #1, %s", storage_file_get_error_desc(file)); + } + + // seek from start and tell + result = storage_file_seek(file, SEEK_OFFSET_FROM_START, true); + if(result) { + FURI_LOG_I(TAG, "seek #1"); + } else { + FURI_LOG_E(TAG, "seek #1, %s", storage_file_get_error_desc(file)); + } + position = storage_file_tell(file); + if(position != SEEK_OFFSET_FROM_START) { + FURI_LOG_E(TAG, "tell #1, %s", storage_file_get_error_desc(file)); + } else { + FURI_LOG_I(TAG, "tell #1"); + } + + // size + size = storage_file_size(file); + if(size != strlen(TEST_STRING)) { + FURI_LOG_E(TAG, "size #1, %s", storage_file_get_error_desc(file)); + } else { + FURI_LOG_I(TAG, "size #1"); + } + + // seek and tell + result = storage_file_seek(file, SEEK_OFFSET_INCREASE, false); + if(result) { + FURI_LOG_I(TAG, "seek #2"); + } else { + FURI_LOG_E(TAG, "seek #2, %s", storage_file_get_error_desc(file)); + } + position = storage_file_tell(file); + if(position != SEEK_OFFSET_SUM) { + FURI_LOG_E(TAG, "tell #2, %s", storage_file_get_error_desc(file)); + } else { + FURI_LOG_I(TAG, "tell #2"); + } + + // eof #2 + result = storage_file_eof(file); + if(!result) { + FURI_LOG_I(TAG, "eof #2"); + } else { + FURI_LOG_E(TAG, "eof #2, %s", storage_file_get_error_desc(file)); + } + + // truncate + result = storage_file_truncate(file); + if(result) { + FURI_LOG_I(TAG, "truncate"); + } else { + FURI_LOG_E(TAG, "truncate, %s", storage_file_get_error_desc(file)); + } + size = storage_file_size(file); + if(size != SEEK_OFFSET_SUM) { + FURI_LOG_E(TAG, "size #2, %s", storage_file_get_error_desc(file)); + } else { + FURI_LOG_I(TAG, "size #2"); + } + + // close + result = storage_file_close(file); + if(result) { + FURI_LOG_I(TAG, "close"); + } else { + FURI_LOG_E(TAG, "close, error"); + } + + // open + result = storage_file_open(file, path, FSAM_READ, FSOM_OPEN_EXISTING); + if(result) { + FURI_LOG_I(TAG, "open"); + } else { + FURI_LOG_E(TAG, "open, %s", storage_file_get_error_desc(file)); + } + + // read + memset(bytes, 0, BYTES_COUNT + 1); + bytes_count = storage_file_read(file, bytes, BYTES_COUNT); + if(bytes_count == 0) { + FURI_LOG_E(TAG, "read, %s", storage_file_get_error_desc(file)); + } else { + if(memcmp(TEST_STRING, bytes, bytes_count) == 0) { + FURI_LOG_I(TAG, "read"); + } else { + FURI_LOG_E(TAG, "read, garbage"); + } + } + + // close + result = storage_file_close(file); + if(result) { + FURI_LOG_I(TAG, "close"); + } else { + FURI_LOG_E(TAG, "close, error"); + } + + storage_file_free(file); +} + +static void do_dir_test(Storage* api, const char* path) { + File* file = storage_file_alloc(api); + bool result; + + FURI_LOG_I(TAG, "--------- DIR \"%s\" ---------", path); + + // open + result = storage_dir_open(file, path); + if(result) { + FURI_LOG_I(TAG, "open"); + } else { + FURI_LOG_E(TAG, "open, %s", storage_file_get_error_desc(file)); + } + + // read + const uint8_t filename_size = 100; + char* filename = malloc(filename_size); + FileInfo fileinfo; + + do { + result = storage_dir_read(file, &fileinfo, filename, filename_size); + if(result) { + if(strlen(filename)) { + FURI_LOG_I( + TAG, + "read #1, [%s]%s", + ((fileinfo.flags & FSF_DIRECTORY) ? "D" : "F"), + filename); + } + } else if(storage_file_get_error(file) != FSE_NOT_EXIST) { + FURI_LOG_E(TAG, "read #1, %s", storage_file_get_error_desc(file)); + break; + } + + } while(result); + + // rewind + result = storage_dir_rewind(file); + if(result) { + FURI_LOG_I(TAG, "rewind"); + } else { + FURI_LOG_E(TAG, "rewind, %s", storage_file_get_error_desc(file)); + } + + // read + do { + result = storage_dir_read(file, &fileinfo, filename, filename_size); + if(result) { + if(strlen(filename)) { + FURI_LOG_I( + TAG, + "read #2, [%s]%s", + ((fileinfo.flags & FSF_DIRECTORY) ? "D" : "F"), + filename); + } + } else if(storage_file_get_error(file) != FSE_NOT_EXIST) { + FURI_LOG_E(TAG, "read #2, %s", storage_file_get_error_desc(file)); + break; + } + + } while((strlen(filename))); + + // close + result = storage_dir_close(file); + if(result) { + FURI_LOG_I(TAG, "close"); + } else { + FURI_LOG_E(TAG, "close, error"); + } + + storage_file_free(file); + free(filename); +} + +static void do_test_start(Storage* api, const char* path) { + string_t str_path; + string_init_printf(str_path, "%s/test-folder", path); + + FURI_LOG_I(TAG, "--------- START \"%s\" ---------", path); + + // mkdir + FS_Error result = storage_common_mkdir(api, string_get_cstr(str_path)); + + if(result == FSE_OK) { + FURI_LOG_I(TAG, "mkdir ok"); + } else { + FURI_LOG_E(TAG, "mkdir, %s", storage_error_get_desc(result)); + } + + // stat + FileInfo fileinfo; + result = storage_common_stat(api, string_get_cstr(str_path), &fileinfo); + + if(result == FSE_OK) { + if(fileinfo.flags & FSF_DIRECTORY) { + FURI_LOG_I(TAG, "stat #1 ok"); + } else { + FURI_LOG_E(TAG, "stat #1, %s", storage_error_get_desc(result)); + } + } else { + FURI_LOG_E(TAG, "stat #1, %s", storage_error_get_desc(result)); + } + + string_clear(str_path); +} + +static void do_test_end(Storage* api, const char* path) { + uint64_t total_space; + uint64_t free_space; + string_t str_path_1; + string_t str_path_2; + string_init_printf(str_path_1, "%s/test-folder", path); + string_init_printf(str_path_2, "%s/test-folder2", path); + + FURI_LOG_I(TAG, "--------- END \"%s\" ---------", path); + + // fs stat + FS_Error result = storage_common_fs_info(api, path, &total_space, &free_space); + + if(result == FSE_OK) { + uint32_t total_kb = total_space / 1024; + uint32_t free_kb = free_space / 1024; + FURI_LOG_I(TAG, "fs_info: total %luk, free %luk", total_kb, free_kb); + } else { + FURI_LOG_E(TAG, "fs_info, %s", storage_error_get_desc(result)); + } + + // rename #1 + result = storage_common_rename(api, string_get_cstr(str_path_1), string_get_cstr(str_path_2)); + if(result == FSE_OK) { + FURI_LOG_I(TAG, "rename #1 ok"); + } else { + FURI_LOG_E(TAG, "rename #1, %s", storage_error_get_desc(result)); + } + + // remove #1 + result = storage_common_remove(api, string_get_cstr(str_path_2)); + if(result == FSE_OK) { + FURI_LOG_I(TAG, "remove #1 ok"); + } else { + FURI_LOG_E(TAG, "remove #1, %s", storage_error_get_desc(result)); + } + + // rename #2 + string_printf(str_path_1, "%s/test.txt", path); + string_printf(str_path_2, "%s/test2.txt", path); + + result = storage_common_rename(api, string_get_cstr(str_path_1), string_get_cstr(str_path_2)); + if(result == FSE_OK) { + FURI_LOG_I(TAG, "rename #2 ok"); + } else { + FURI_LOG_E(TAG, "rename #2, %s", storage_error_get_desc(result)); + } + + // remove #2 + result = storage_common_remove(api, string_get_cstr(str_path_2)); + if(result == FSE_OK) { + FURI_LOG_I(TAG, "remove #2 ok"); + } else { + FURI_LOG_E(TAG, "remove #2, %s", storage_error_get_desc(result)); + } + + string_clear(str_path_1); + string_clear(str_path_2); +} + +int32_t storage_app_test(void* p) { + Storage* api = furi_record_open("storage"); + do_test_start(api, "/int"); + do_test_start(api, "/any"); + do_test_start(api, "/ext"); + + do_file_test(api, "/int/test.txt"); + do_file_test(api, "/any/test.txt"); + do_file_test(api, "/ext/test.txt"); + + do_dir_test(api, "/int"); + do_dir_test(api, "/any"); + do_dir_test(api, "/ext"); + + do_test_end(api, "/int"); + do_test_end(api, "/any"); + do_test_end(api, "/ext"); + + while(true) { + delay(1000); + } + + return 0; +} \ No newline at end of file diff --git a/applications/storage/storage.c b/applications/storage/storage.c new file mode 100644 index 00000000..601ac441 --- /dev/null +++ b/applications/storage/storage.c @@ -0,0 +1,96 @@ +#include "storage.h" +#include "storage-i.h" +#include "storage-message.h" +#include "storage-processing.h" +#include "storages/storage-int.h" +#include "storages/storage-ext.h" + +#define STORAGE_TICK 1000 + +#define ICON_SD_MOUNTED &I_SDcardMounted_11x8 +#define ICON_SD_ERROR &I_SDcardFail_11x8 + +static void storage_app_sd_icon_draw_callback(Canvas* canvas, void* context) { + furi_assert(canvas); + furi_assert(context); + Storage* app = context; + + // here we don't care about thread race when reading / writing status + switch(app->storage[ST_EXT].status) { + case StorageStatusNotReady: + break; + case StorageStatusOK: + canvas_draw_icon(canvas, 0, 0, ICON_SD_MOUNTED); + break; + default: + canvas_draw_icon(canvas, 0, 0, ICON_SD_ERROR); + break; + } +} + +Storage* storage_app_alloc() { + Storage* app = malloc(sizeof(Storage)); + app->message_queue = osMessageQueueNew(8, sizeof(StorageMessage), NULL); + + for(uint8_t i = 0; i < STORAGE_COUNT; i++) { + storage_data_init(&app->storage[i]); + } + + storage_int_init(&app->storage[ST_INT]); + storage_ext_init(&app->storage[ST_EXT]); + + // sd icon gui + app->sd_gui.enabled = false; + app->sd_gui.view_port = view_port_alloc(); + view_port_set_width(app->sd_gui.view_port, icon_get_width(ICON_SD_MOUNTED)); + view_port_draw_callback_set(app->sd_gui.view_port, storage_app_sd_icon_draw_callback, app); + view_port_enabled_set(app->sd_gui.view_port, false); + + Gui* gui = furi_record_open("gui"); + gui_add_view_port(gui, app->sd_gui.view_port, GuiLayerStatusBarLeft); + furi_record_close("gui"); + + return app; +} + +void storage_tick(Storage* app) { + for(uint8_t i = 0; i < STORAGE_COUNT; i++) { + StorageApi api = app->storage[i].api; + if(api.tick != NULL) { + api.tick(&app->storage[i]); + } + } + + // storage not enabled but was enabled (sd card unmount) + if(app->storage[ST_EXT].status == StorageStatusNotReady && app->sd_gui.enabled == true) { + app->sd_gui.enabled = false; + view_port_enabled_set(app->sd_gui.view_port, false); + } + + // storage enabled (or in error state) but was not enabled (sd card mount) + if((app->storage[ST_EXT].status == StorageStatusOK || + app->storage[ST_EXT].status == StorageStatusNotMounted || + app->storage[ST_EXT].status == StorageStatusNoFS || + app->storage[ST_EXT].status == StorageStatusNotAccessible || + app->storage[ST_EXT].status == StorageStatusErrorInternal) && + app->sd_gui.enabled == false) { + app->sd_gui.enabled = true; + view_port_enabled_set(app->sd_gui.view_port, true); + } +} + +int32_t storage_app(void* p) { + Storage* app = storage_app_alloc(); + furi_record_create("storage", app); + + StorageMessage message; + while(1) { + if(osMessageQueueGet(app->message_queue, &message, NULL, STORAGE_TICK) == osOK) { + storage_process_message(app, &message); + } else { + storage_tick(app); + } + } + + return 0; +} \ No newline at end of file diff --git a/applications/storage/storage.h b/applications/storage/storage.h new file mode 100644 index 00000000..50e70b84 --- /dev/null +++ b/applications/storage/storage.h @@ -0,0 +1,235 @@ +#pragma once +#include +#include "filesystem-api-defines.h" +#include "storage-sd-api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Storage Storage; + +/** Allocates and initializes a file descriptor + * @return File* + */ +File* storage_file_alloc(Storage* storage); + +/** Frees the file descriptor. Closes the file if it was open. + */ +void storage_file_free(File* file); + +/******************* File Functions *******************/ + +/** Opens an existing file or create a new one. + * @param file pointer to file object. + * @param path path to file + * @param access_mode access mode from FS_AccessMode + * @param open_mode open mode from FS_OpenMode + * @return success flag. You need to close the file even if the open operation failed. + */ +bool storage_file_open( + File* file, + const char* path, + FS_AccessMode access_mode, + FS_OpenMode open_mode); + +/** Close the file. + * @param file pointer to a file object, the file object will be freed. + * @return success flag + */ +bool storage_file_close(File* file); + +/** Tells if the file is open + * @param file pointer to a file object + * @return bool true if file is open + */ +bool storage_file_is_open(File* file); + +/** Reads bytes from a file into a buffer + * @param file pointer to file object. + * @param buff pointer to a buffer, for reading + * @param bytes_to_read how many bytes to read. Must be less than or equal to the size of the buffer. + * @return uint16_t how many bytes were actually readed + */ +uint16_t storage_file_read(File* file, void* buff, uint16_t bytes_to_read); + +/** Writes bytes from a buffer to a file + * @param file pointer to file object. + * @param buff pointer to buffer, for writing + * @param bytes_to_write how many bytes to write. Must be less than or equal to the size of the buffer. + * @return uint16_t how many bytes were actually written + */ +uint16_t storage_file_write(File* file, const void* buff, uint16_t bytes_to_write); + +/** Moves the r/w pointer + * @param file pointer to file object. + * @param offset offset to move the r/w pointer + * @param from_start set an offset from the start or from the current position + * @return success flag + */ +bool storage_file_seek(File* file, uint32_t offset, bool from_start); + +/** Gets the position of the r/w pointer + * @param file pointer to file object. + * @return uint64_t position of the r/w pointer + */ +uint64_t storage_file_tell(File* file); + +/** Truncates the file size to the current position of the r/w pointer + * @param file pointer to file object. + * @return bool success flag + */ +bool storage_file_truncate(File* file); + +/** Gets the size of the file + * @param file pointer to file object. + * @return uint64_t size of the file + */ +uint64_t storage_file_size(File* file); + +/** Writes file cache to storage + * @param file pointer to file object. + * @return bool success flag + */ +bool storage_file_sync(File* file); + +/** Checks that the r/w pointer is at the end of the file + * @param file pointer to file object. + * @return bool success flag + */ +bool storage_file_eof(File* file); + +/******************* Dir Functions *******************/ + +/** Opens a directory to get objects from it + * @param app pointer to the api + * @param file pointer to file object. + * @param path path to directory + * @return bool success flag. You need to close the directory even if the open operation failed. + */ +bool storage_dir_open(File* file, const char* path); + +/** Close the directory. Also free file handle structure and point it to the NULL. + * @param file pointer to a file object. + * @return bool success flag + */ +bool storage_dir_close(File* file); + +/** Reads the next object in the directory + * @param file pointer to file object. + * @param fileinfo pointer to the readed FileInfo, may be NULL + * @param name pointer to name buffer, may be NULL + * @param name_length name buffer length + * @return success flag (if the next object does not exist, it also returns false and sets the file error id to FSE_NOT_EXIST) + */ +bool storage_dir_read(File* file, FileInfo* fileinfo, char* name, uint16_t name_length); + +/** Rewinds the read pointer to first item in the directory + * @param file pointer to file object. + * @return bool success flag + */ +bool storage_dir_rewind(File* file); + +/******************* Common Functions *******************/ + +/** Retrieves information about a file/directory + * @param app pointer to the api + * @param path path to file/directory + * @param fileinfo pointer to the readed FileInfo, may be NULL + * @return FS_Error operation result + */ +FS_Error storage_common_stat(Storage* storage, const char* path, FileInfo* fileinfo); + +/** Removes a file/directory from the repository, the directory must be empty and the file/directory must not be open + * @param app pointer to the api + * @param path + * @return FS_Error operation result + */ +FS_Error storage_common_remove(Storage* storage, const char* path); + +/** Renames file/directory, file/directory must not be open + * @param app pointer to the api + * @param old_path old path + * @param new_path new path + * @return FS_Error operation result + */ +FS_Error storage_common_rename(Storage* storage, const char* old_path, const char* new_path); + +/** Copy file, file must not be open + * @param app pointer to the api + * @param old_path old path + * @param new_path new path + * @return FS_Error operation result + */ +FS_Error storage_common_copy(Storage* storage, const char* old_path, const char* new_path); + +/** Creates a directory + * @param app pointer to the api + * @param path directory path + * @return FS_Error operation result + */ +FS_Error storage_common_mkdir(Storage* storage, const char* path); + +/** Gets general information about the storage + * @param app pointer to the api + * @param fs_path the path to the storage of interest + * @param total_space pointer to total space record, will be filled + * @param free_space pointer to free space record, will be filled + * @return FS_Error operation result + */ +FS_Error storage_common_fs_info( + Storage* storage, + const char* fs_path, + uint64_t* total_space, + uint64_t* free_space); + +/******************* Error Functions *******************/ + +/** Retrieves the error text from the error id + * @param error_id error id + * @return const char* error text + */ +const char* storage_error_get_desc(FS_Error error_id); + +/** Retrieves the error id from the file object + * @param file pointer to file object. Pointer must not point to NULL. YOU CANNOT RETREIVE THE ERROR ID IF THE FILE HAS BEEN CLOSED + * @return FS_Error error id + */ +FS_Error storage_file_get_error(File* file); + +/** Retrieves the error text from the file object + * @param file pointer to file object. Pointer must not point to NULL. YOU CANNOT RETREIVE THE ERROR TEXT IF THE FILE HAS BEEN CLOSED + * @return const char* error text + */ +const char* storage_file_get_error_desc(File* file); + +/******************* SD Card Functions *******************/ + +/** Formats SD Card + * @param api pointer to the api + * @return FS_Error operation result + */ +FS_Error storage_sd_format(Storage* api); + +/** Will unmount the SD card + * @param api pointer to the api + * @return FS_Error operation result + */ +FS_Error storage_sd_unmount(Storage* api); + +/** Retrieves SD card information + * @param api pointer to the api + * @param info pointer to the info + * @return FS_Error operation result + */ +FS_Error storage_sd_info(Storage* api, SDInfo* info); + +/** Retrieves SD card status + * @param api pointer to the api + * @return FS_Error operation result + */ +FS_Error storage_sd_status(Storage* api); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/storages/sd-notify.c b/applications/storage/storages/sd-notify.c new file mode 100644 index 00000000..d068f2e6 --- /dev/null +++ b/applications/storage/storages/sd-notify.c @@ -0,0 +1,82 @@ +#include "sd-notify.h" + +static const NotificationSequence sd_sequence_success = { + &message_green_255, + &message_delay_50, + &message_green_0, + &message_delay_50, + &message_green_255, + &message_delay_50, + &message_green_0, + &message_delay_50, + &message_green_255, + &message_delay_50, + &message_green_0, + &message_delay_50, + NULL, +}; + +static const NotificationSequence sd_sequence_error = { + &message_red_255, + &message_delay_50, + &message_red_0, + &message_delay_50, + &message_red_255, + &message_delay_50, + &message_red_0, + &message_delay_50, + &message_red_255, + &message_delay_50, + &message_red_0, + &message_delay_50, + NULL, +}; + +static const NotificationSequence sd_sequence_eject = { + &message_blue_255, + &message_delay_50, + &message_blue_0, + &message_delay_50, + &message_blue_255, + &message_delay_50, + &message_blue_0, + &message_delay_50, + &message_blue_255, + &message_delay_50, + &message_blue_0, + &message_delay_50, + NULL, +}; + +static const NotificationSequence sd_sequence_wait = { + &message_red_255, + &message_blue_255, + &message_do_not_reset, + NULL, +}; + +static const NotificationSequence sd_sequence_wait_off = { + &message_red_0, + &message_blue_0, + NULL, +}; + +void sd_notify_wait(NotificationApp* notifications) { + notification_message(notifications, &sd_sequence_wait); +} + +void sd_notify_wait_off(NotificationApp* notifications) { + notification_message(notifications, &sd_sequence_wait_off); +} + +void sd_notify_success(NotificationApp* notifications) { + notification_message(notifications, &sd_sequence_success); +} + +void sd_notify_eject(NotificationApp* notifications) { + notification_message(notifications, &sd_sequence_eject); +} + +void sd_notify_error(NotificationApp* notifications) { + notification_message(notifications, &sd_sequence_error); +} \ No newline at end of file diff --git a/applications/storage/storages/sd-notify.h b/applications/storage/storages/sd-notify.h new file mode 100644 index 00000000..dd8e5468 --- /dev/null +++ b/applications/storage/storages/sd-notify.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void sd_notify_wait(NotificationApp* notifications); +void sd_notify_wait_off(NotificationApp* notifications); +void sd_notify_success(NotificationApp* notifications); +void sd_notify_eject(NotificationApp* notifications); +void sd_notify_error(NotificationApp* notifications); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/storages/storage-ext.c b/applications/storage/storages/storage-ext.c new file mode 100644 index 00000000..6d0f7b68 --- /dev/null +++ b/applications/storage/storages/storage-ext.c @@ -0,0 +1,547 @@ +#include "fatfs.h" +#include "../filesystem-api-internal.h" +#include "storage-ext.h" +#include +#include "sd-notify.h" +#include + +typedef FIL SDFile; +typedef DIR SDDir; +typedef FILINFO SDFileInfo; +typedef FRESULT SDError; + +#define TAG "storage-ext" +#define STORAGE_PATH "/ext" +/********************* Definitions ********************/ + +typedef struct { + FATFS* fs; + const char* path; + bool sd_was_present; +} SDData; + +static FS_Error storage_ext_parse_error(SDError error); + +/******************* Core Functions *******************/ + +static bool sd_mount_card(StorageData* storage, bool notify) { + bool result = false; + const uint8_t max_init_counts = 10; + uint8_t counter = max_init_counts; + uint8_t bsp_result; + SDData* sd_data = storage->data; + + storage_data_lock(storage); + + while(result == false && counter > 0 && hal_sd_detect()) { + if(notify) { + NotificationApp* notification = furi_record_open("notification"); + sd_notify_wait(notification); + furi_record_close("notification"); + } + + if((counter % 2) == 0) { + // power reset sd card + bsp_result = BSP_SD_Init(true); + } else { + bsp_result = BSP_SD_Init(false); + } + + if(bsp_result) { + // bsp error + storage->status = StorageStatusErrorInternal; + } else { + SDError status = f_mount(sd_data->fs, sd_data->path, 1); + + if(status == FR_OK || status == FR_NO_FILESYSTEM) { + FATFS* fs; + uint32_t free_clusters; + + status = f_getfree(sd_data->path, &free_clusters, &fs); + + if(status == FR_OK || status == FR_NO_FILESYSTEM) { + result = true; + } + + if(status == FR_OK) { + storage->status = StorageStatusOK; + } else if(status == FR_NO_FILESYSTEM) { + storage->status = StorageStatusNoFS; + } else { + storage->status = StorageStatusNotAccessible; + } + } else { + storage->status = StorageStatusNotMounted; + } + } + + if(notify) { + NotificationApp* notification = furi_record_open("notification"); + sd_notify_wait_off(notification); + furi_record_close("notification"); + } + + if(!result) { + delay(1000); + FURI_LOG_E( + TAG, "init cycle %d, error: %s", counter, storage_data_status_text(storage)); + counter--; + } + } + + storage_data_unlock(storage); + + return result; +} + +FS_Error sd_unmount_card(StorageData* storage) { + SDData* sd_data = storage->data; + SDError error; + + storage_data_lock(storage); + error = storage->status = StorageStatusNotReady; + + // TODO do i need to close the files? + + f_mount(0, sd_data->path, 0); + storage_data_unlock(storage); + return storage_ext_parse_error(error); +} + +FS_Error sd_format_card(StorageData* storage) { + uint8_t* work_area; + SDData* sd_data = storage->data; + SDError error; + + storage_data_lock(storage); + + work_area = malloc(_MAX_SS); + error = f_mkfs(sd_data->path, FM_ANY, 0, work_area, _MAX_SS); + free(work_area); + + do { + storage->status = StorageStatusNotAccessible; + if(error != FR_OK) break; + storage->status = StorageStatusNoFS; + error = f_setlabel("Flipper SD"); + if(error != FR_OK) break; + storage->status = StorageStatusNotMounted; + error = f_mount(sd_data->fs, sd_data->path, 1); + if(error != FR_OK) break; + storage->status = StorageStatusOK; + } while(false); + + storage_data_unlock(storage); + + return storage_ext_parse_error(error); +} + +FS_Error sd_card_info(StorageData* storage, SDInfo* sd_info) { + uint32_t free_clusters, free_sectors, total_sectors; + FATFS* fs; + SDData* sd_data = storage->data; + SDError error; + + // clean data + memset(sd_info, 0, sizeof(SDInfo)); + + // get fs info + storage_data_lock(storage); + error = f_getlabel(sd_data->path, sd_info->label, NULL); + if(error == FR_OK) { + error = f_getfree(sd_data->path, &free_clusters, &fs); + } + storage_data_unlock(storage); + + if(error == FR_OK) { + // calculate size + total_sectors = (fs->n_fatent - 2) * fs->csize; + free_sectors = free_clusters * fs->csize; + + uint16_t sector_size = _MAX_SS; +#if _MAX_SS != _MIN_SS + sector_size = fs->ssize; +#endif + + sd_info->fs_type = fs->fs_type; + + sd_info->kb_total = total_sectors / 1024 * sector_size; + sd_info->kb_free = free_sectors / 1024 * sector_size; + sd_info->cluster_size = fs->csize; + sd_info->sector_size = sector_size; + } + + return storage_ext_parse_error(error); +} + +static void storage_ext_tick_internal(StorageData* storage, bool notify) { + SDData* sd_data = storage->data; + + if(sd_data->sd_was_present) { + if(hal_sd_detect()) { + FURI_LOG_I(TAG, "card detected"); + sd_mount_card(storage, notify); + + if(storage->status != StorageStatusOK) { + FURI_LOG_E(TAG, "sd init error: %s", storage_data_status_text(storage)); + if(notify) { + NotificationApp* notification = furi_record_open("notification"); + sd_notify_error(notification); + furi_record_close("notification"); + } + } else { + FURI_LOG_I(TAG, "card mounted"); + if(notify) { + NotificationApp* notification = furi_record_open("notification"); + sd_notify_success(notification); + furi_record_close("notification"); + } + } + + sd_data->sd_was_present = false; + + if(!hal_sd_detect()) { + FURI_LOG_I(TAG, "card removed while mounting"); + sd_unmount_card(storage); + sd_data->sd_was_present = true; + } + } + } else { + if(!hal_sd_detect()) { + FURI_LOG_I(TAG, "card removed"); + sd_data->sd_was_present = true; + + sd_unmount_card(storage); + if(notify) { + NotificationApp* notification = furi_record_open("notification"); + sd_notify_eject(notification); + furi_record_close("notification"); + } + } + } +} + +static void storage_ext_tick(StorageData* storage) { + storage_ext_tick_internal(storage, true); +} + +/****************** Common Functions ******************/ + +static FS_Error storage_ext_parse_error(SDError error) { + FS_Error result; + switch(error) { + case FR_OK: + result = FSE_OK; + break; + case FR_NOT_READY: + result = FSE_NOT_READY; + break; + case FR_NO_FILE: + case FR_NO_PATH: + case FR_NO_FILESYSTEM: + result = FSE_NOT_EXIST; + break; + case FR_EXIST: + result = FSE_EXIST; + break; + case FR_INVALID_NAME: + result = FSE_INVALID_NAME; + break; + case FR_INVALID_OBJECT: + case FR_INVALID_PARAMETER: + result = FSE_INVALID_PARAMETER; + break; + case FR_DENIED: + result = FSE_DENIED; + break; + default: + result = FSE_INTERNAL; + break; + } + + return result; +} + +/******************* File Functions *******************/ + +static bool storage_ext_file_open( + void* ctx, + File* file, + const char* path, + FS_AccessMode access_mode, + FS_OpenMode open_mode) { + StorageData* storage = ctx; + uint8_t _mode = 0; + + if(access_mode & FSAM_READ) _mode |= FA_READ; + if(access_mode & FSAM_WRITE) _mode |= FA_WRITE; + if(open_mode & FSOM_OPEN_EXISTING) _mode |= FA_OPEN_EXISTING; + if(open_mode & FSOM_OPEN_ALWAYS) _mode |= FA_OPEN_ALWAYS; + if(open_mode & FSOM_OPEN_APPEND) _mode |= FA_OPEN_APPEND; + if(open_mode & FSOM_CREATE_NEW) _mode |= FA_CREATE_NEW; + if(open_mode & FSOM_CREATE_ALWAYS) _mode |= FA_CREATE_ALWAYS; + + SDFile* file_data = malloc(sizeof(SDFile)); + storage_set_storage_file_data(file, file_data, storage); + + file->internal_error_id = f_open(file_data, path, _mode); + file->error_id = storage_ext_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} + +static bool storage_ext_file_close(void* ctx, File* file) { + StorageData* storage = ctx; + SDFile* file_data = storage_get_storage_file_data(file, storage); + file->internal_error_id = f_close(file_data); + file->error_id = storage_ext_parse_error(file->internal_error_id); + free(file_data); + return (file->error_id == FSE_OK); +} + +static uint16_t + storage_ext_file_read(void* ctx, File* file, void* buff, uint16_t const bytes_to_read) { + StorageData* storage = ctx; + SDFile* file_data = storage_get_storage_file_data(file, storage); + uint16_t bytes_readed = 0; + file->internal_error_id = f_read(file_data, buff, bytes_to_read, &bytes_readed); + file->error_id = storage_ext_parse_error(file->internal_error_id); + return bytes_readed; +} + +static uint16_t + storage_ext_file_write(void* ctx, File* file, const void* buff, uint16_t const bytes_to_write) { + StorageData* storage = ctx; + SDFile* file_data = storage_get_storage_file_data(file, storage); + uint16_t bytes_written = 0; + file->internal_error_id = f_write(file_data, buff, bytes_to_write, &bytes_written); + file->error_id = storage_ext_parse_error(file->internal_error_id); + return bytes_written; +} + +static bool + storage_ext_file_seek(void* ctx, File* file, const uint32_t offset, const bool from_start) { + StorageData* storage = ctx; + SDFile* file_data = storage_get_storage_file_data(file, storage); + + if(from_start) { + file->internal_error_id = f_lseek(file_data, offset); + } else { + uint64_t position = f_tell(file_data); + position += offset; + file->internal_error_id = f_lseek(file_data, position); + } + + file->error_id = storage_ext_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} + +static uint64_t storage_ext_file_tell(void* ctx, File* file) { + StorageData* storage = ctx; + SDFile* file_data = storage_get_storage_file_data(file, storage); + + uint64_t position = 0; + position = f_tell(file_data); + file->error_id = FSE_OK; + return position; +} + +static bool storage_ext_file_truncate(void* ctx, File* file) { + StorageData* storage = ctx; + SDFile* file_data = storage_get_storage_file_data(file, storage); + + file->internal_error_id = f_truncate(file_data); + file->error_id = storage_ext_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} + +static bool storage_ext_file_sync(void* ctx, File* file) { + StorageData* storage = ctx; + SDFile* file_data = storage_get_storage_file_data(file, storage); + + file->internal_error_id = f_sync(file_data); + file->error_id = storage_ext_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} + +static uint64_t storage_ext_file_size(void* ctx, File* file) { + StorageData* storage = ctx; + SDFile* file_data = storage_get_storage_file_data(file, storage); + + uint64_t size = 0; + size = f_size(file_data); + file->error_id = FSE_OK; + return size; +} + +static bool storage_ext_file_eof(void* ctx, File* file) { + StorageData* storage = ctx; + SDFile* file_data = storage_get_storage_file_data(file, storage); + + bool eof = f_eof(file_data); + file->internal_error_id = 0; + file->error_id = FSE_OK; + return eof; +} + +/******************* Dir Functions *******************/ + +static bool storage_ext_dir_open(void* ctx, File* file, const char* path) { + StorageData* storage = ctx; + + SDDir* file_data = malloc(sizeof(SDDir)); + storage_set_storage_file_data(file, file_data, storage); + file->internal_error_id = f_opendir(file_data, path); + file->error_id = storage_ext_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} + +static bool storage_ext_dir_close(void* ctx, File* file) { + StorageData* storage = ctx; + SDDir* file_data = storage_get_storage_file_data(file, storage); + + file->internal_error_id = f_closedir(file_data); + file->error_id = storage_ext_parse_error(file->internal_error_id); + free(file_data); + return (file->error_id == FSE_OK); +} + +static bool storage_ext_dir_read( + void* ctx, + File* file, + FileInfo* fileinfo, + char* name, + const uint16_t name_length) { + StorageData* storage = ctx; + SDDir* file_data = storage_get_storage_file_data(file, storage); + + SDFileInfo _fileinfo; + file->internal_error_id = f_readdir(file_data, &_fileinfo); + file->error_id = storage_ext_parse_error(file->internal_error_id); + + if(fileinfo != NULL) { + fileinfo->size = _fileinfo.fsize; + fileinfo->flags = 0; + + if(_fileinfo.fattrib & AM_DIR) fileinfo->flags |= FSF_DIRECTORY; + } + + if(name != NULL) { + snprintf(name, name_length, "%s", _fileinfo.fname); + } + + if(_fileinfo.fname[0] == 0) { + file->error_id = FSE_NOT_EXIST; + } + + return (file->error_id == FSE_OK); +} + +static bool storage_ext_dir_rewind(void* ctx, File* file) { + StorageData* storage = ctx; + SDDir* file_data = storage_get_storage_file_data(file, storage); + + file->internal_error_id = f_readdir(file_data, NULL); + file->error_id = storage_ext_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} +/******************* Common FS Functions *******************/ + +static FS_Error storage_ext_common_stat(void* ctx, const char* path, FileInfo* fileinfo) { + SDFileInfo _fileinfo; + SDError result = f_stat(path, &_fileinfo); + + if(fileinfo != NULL) { + fileinfo->size = _fileinfo.fsize; + fileinfo->flags = 0; + + if(_fileinfo.fattrib & AM_DIR) fileinfo->flags |= FSF_DIRECTORY; + } + + return storage_ext_parse_error(result); +} + +static FS_Error storage_ext_common_remove(void* ctx, const char* path) { + SDError result = f_unlink(path); + return storage_ext_parse_error(result); +} + +static FS_Error storage_ext_common_rename(void* ctx, const char* old_path, const char* new_path) { + SDError result = f_rename(old_path, new_path); + return storage_ext_parse_error(result); +} + +static FS_Error storage_ext_common_mkdir(void* ctx, const char* path) { + SDError result = f_mkdir(path); + return storage_ext_parse_error(result); +} + +static FS_Error storage_ext_common_fs_info( + void* ctx, + const char* fs_path, + uint64_t* total_space, + uint64_t* free_space) { + StorageData* storage = ctx; + SDData* sd_data = storage->data; + + DWORD free_clusters; + FATFS* fs; + + SDError fresult = f_getfree(sd_data->path, &free_clusters, &fs); + if((FRESULT)fresult == FR_OK) { + uint32_t total_sectors = (fs->n_fatent - 2) * fs->csize; + uint32_t free_sectors = free_clusters * fs->csize; + + uint16_t sector_size = _MAX_SS; +#if _MAX_SS != _MIN_SS + sector_size = fs->ssize; +#endif + + if(total_space != NULL) { + *total_space = (uint64_t)total_sectors * (uint64_t)sector_size; + } + + if(free_space != NULL) { + *free_space = (uint64_t)free_sectors * (uint64_t)sector_size; + } + } + + return storage_ext_parse_error(fresult); +} + +/******************* Init Storage *******************/ + +void storage_ext_init(StorageData* storage) { + SDData* sd_data = malloc(sizeof(SDData)); + sd_data->fs = &USERFatFS; + sd_data->path = "0:/"; + sd_data->sd_was_present = true; + + storage->data = sd_data; + storage->api.tick = storage_ext_tick; + storage->fs_api.file.open = storage_ext_file_open; + storage->fs_api.file.close = storage_ext_file_close; + storage->fs_api.file.read = storage_ext_file_read; + storage->fs_api.file.write = storage_ext_file_write; + storage->fs_api.file.seek = storage_ext_file_seek; + storage->fs_api.file.tell = storage_ext_file_tell; + storage->fs_api.file.truncate = storage_ext_file_truncate; + storage->fs_api.file.size = storage_ext_file_size; + storage->fs_api.file.sync = storage_ext_file_sync; + storage->fs_api.file.eof = storage_ext_file_eof; + + storage->fs_api.dir.open = storage_ext_dir_open; + storage->fs_api.dir.close = storage_ext_dir_close; + storage->fs_api.dir.read = storage_ext_dir_read; + storage->fs_api.dir.rewind = storage_ext_dir_rewind; + + storage->fs_api.common.stat = storage_ext_common_stat; + storage->fs_api.common.mkdir = storage_ext_common_mkdir; + storage->fs_api.common.rename = storage_ext_common_rename; + storage->fs_api.common.remove = storage_ext_common_remove; + storage->fs_api.common.fs_info = storage_ext_common_fs_info; + + hal_sd_detect_init(); + + // do not notify on first launch, notifications app is waiting for our thread to read settings + storage_ext_tick_internal(storage, false); +} diff --git a/applications/storage/storages/storage-ext.h b/applications/storage/storages/storage-ext.h new file mode 100644 index 00000000..a2daaa56 --- /dev/null +++ b/applications/storage/storages/storage-ext.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "../storage-glue.h" +#include "../storage-sd-api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void storage_ext_init(StorageData* storage); +FS_Error sd_unmount_card(StorageData* storage); +FS_Error sd_format_card(StorageData* storage); +FS_Error sd_card_info(StorageData* storage, SDInfo* sd_info); +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/storage/storages/storage-int.c b/applications/storage/storages/storage-int.c new file mode 100644 index 00000000..625ded6d --- /dev/null +++ b/applications/storage/storages/storage-int.c @@ -0,0 +1,690 @@ +#include "storage-int.h" +#include +#include + +#define TAG "storage-int" +#define STORAGE_PATH "/int" + +typedef struct { + const size_t start_address; + const size_t start_page; + struct lfs_config config; + lfs_t lfs; +} LFSData; + +typedef struct { + void* data; + bool open; +} LFSHandle; + +static LFSHandle* lfs_handle_alloc_file() { + LFSHandle* handle = furi_alloc(sizeof(LFSHandle)); + handle->data = furi_alloc(sizeof(lfs_file_t)); + return handle; +} + +static LFSHandle* lfs_handle_alloc_dir() { + LFSHandle* handle = furi_alloc(sizeof(LFSHandle)); + handle->data = furi_alloc(sizeof(lfs_dir_t)); + return handle; +} + +/* INTERNALS */ + +static lfs_dir_t* lfs_handle_get_dir(LFSHandle* handle) { + return handle->data; +} + +static lfs_file_t* lfs_handle_get_file(LFSHandle* handle) { + return handle->data; +} + +static void lfs_handle_free(LFSHandle* handle) { + free(handle->data); + free(handle); +} + +static void lfs_handle_set_open(LFSHandle* handle) { + handle->open = true; +} + +static bool lfs_handle_is_open(LFSHandle* handle) { + return handle->open; +} + +static lfs_t* lfs_get_from_storage(StorageData* storage) { + return &((LFSData*)storage->data)->lfs; +} + +static LFSData* lfs_data_get_from_storage(StorageData* storage) { + return (LFSData*)storage->data; +} + +static int storage_int_device_read( + const struct lfs_config* c, + lfs_block_t block, + lfs_off_t off, + void* buffer, + lfs_size_t size) { + LFSData* lfs_data = c->context; + size_t address = lfs_data->start_address + block * c->block_size + off; + + FURI_LOG_D( + TAG, + "Device read: block %d, off %d, buffer: %p, size %d, translated address: %p", + block, + off, + buffer, + size, + address); + + memcpy(buffer, (void*)address, size); + + return 0; +} + +static int storage_int_device_prog( + const struct lfs_config* c, + lfs_block_t block, + lfs_off_t off, + const void* buffer, + lfs_size_t size) { + LFSData* lfs_data = c->context; + size_t address = lfs_data->start_address + block * c->block_size + off; + + FURI_LOG_D( + TAG, + "Device prog: block %d, off %d, buffer: %p, size %d, translated address: %p", + block, + off, + buffer, + size, + address); + + int ret = 0; + while(size > 0) { + if(!api_hal_flash_write_dword(address, *(uint64_t*)buffer)) { + ret = -1; + break; + } + address += c->prog_size; + buffer += c->prog_size; + size -= c->prog_size; + } + + return ret; +} + +static int storage_int_device_erase(const struct lfs_config* c, lfs_block_t block) { + LFSData* lfs_data = c->context; + size_t page = lfs_data->start_page + block; + + FURI_LOG_D(TAG, "Device erase: page %d, translated page: %d", block, page); + + if(api_hal_flash_erase(page, 1)) { + return 0; + } else { + return -1; + } +} + +static int storage_int_device_sync(const struct lfs_config* c) { + FURI_LOG_D(TAG, "Device sync: skipping, cause "); + return 0; +} + +static LFSData* storage_int_lfs_data_alloc() { + LFSData* lfs_data = furi_alloc(sizeof(LFSData)); + + // Internal storage start address + *(size_t*)(&lfs_data->start_address) = api_hal_flash_get_free_page_start_address(); + *(size_t*)(&lfs_data->start_page) = + (lfs_data->start_address - api_hal_flash_get_base()) / api_hal_flash_get_page_size(); + + // LFS configuration + // Glue and context + lfs_data->config.context = lfs_data; + lfs_data->config.read = storage_int_device_read; + lfs_data->config.prog = storage_int_device_prog; + lfs_data->config.erase = storage_int_device_erase; + lfs_data->config.sync = storage_int_device_sync; + + // Block device description + lfs_data->config.read_size = api_hal_flash_get_read_block_size(); + lfs_data->config.prog_size = api_hal_flash_get_write_block_size(); + lfs_data->config.block_size = api_hal_flash_get_page_size(); + lfs_data->config.block_count = api_hal_flash_get_free_page_count(); + lfs_data->config.block_cycles = api_hal_flash_get_cycles_count(); + lfs_data->config.cache_size = 16; + lfs_data->config.lookahead_size = 16; + + return lfs_data; +}; + +static void storage_int_lfs_mount(LFSData* lfs_data, StorageData* storage) { + int err; + ApiHalBootFlag boot_flags = api_hal_boot_get_flags(); + lfs_t* lfs = &lfs_data->lfs; + + if(boot_flags & ApiHalBootFlagFactoryReset) { + // Factory reset + err = lfs_format(lfs, &lfs_data->config); + if(err == 0) { + FURI_LOG_I(TAG, "Factory reset: Format successful, trying to mount"); + api_hal_boot_set_flags(boot_flags & ~ApiHalBootFlagFactoryReset); + err = lfs_mount(lfs, &lfs_data->config); + if(err == 0) { + FURI_LOG_I(TAG, "Factory reset: Mounted"); + storage->status = StorageStatusOK; + } else { + FURI_LOG_E(TAG, "Factory reset: Mount after format failed"); + storage->status = StorageStatusNotMounted; + } + } else { + FURI_LOG_E(TAG, "Factory reset: Format failed"); + storage->status = StorageStatusNoFS; + } + } else { + // Normal + err = lfs_mount(lfs, &lfs_data->config); + if(err == 0) { + FURI_LOG_I(TAG, "Mounted"); + storage->status = StorageStatusOK; + } else { + FURI_LOG_E(TAG, "Mount failed, formatting"); + err = lfs_format(lfs, &lfs_data->config); + if(err == 0) { + FURI_LOG_I(TAG, "Format successful, trying to mount"); + err = lfs_mount(lfs, &lfs_data->config); + if(err == 0) { + FURI_LOG_I(TAG, "Mounted"); + storage->status = StorageStatusOK; + } else { + FURI_LOG_E(TAG, "Mount after format failed"); + storage->status = StorageStatusNotMounted; + } + } else { + FURI_LOG_E(TAG, "Format failed"); + storage->status = StorageStatusNoFS; + } + } + } +} + +/****************** Common Functions ******************/ + +static FS_Error storage_int_parse_error(int error) { + FS_Error result = FSE_INTERNAL; + + if(error >= LFS_ERR_OK) { + result = FSE_OK; + } else { + switch(error) { + case LFS_ERR_IO: + result = FSE_INTERNAL; + break; + case LFS_ERR_CORRUPT: + result = FSE_INTERNAL; + break; + case LFS_ERR_NOENT: + result = FSE_NOT_EXIST; + break; + case LFS_ERR_EXIST: + result = FSE_EXIST; + break; + case LFS_ERR_NOTDIR: + result = FSE_INVALID_NAME; + break; + case LFS_ERR_ISDIR: + result = FSE_INVALID_NAME; + break; + case LFS_ERR_NOTEMPTY: + result = FSE_DENIED; + break; + case LFS_ERR_BADF: + result = FSE_INVALID_NAME; + break; + case LFS_ERR_FBIG: + result = FSE_INTERNAL; + break; + case LFS_ERR_INVAL: + result = FSE_INVALID_PARAMETER; + break; + case LFS_ERR_NOSPC: + result = FSE_INTERNAL; + break; + case LFS_ERR_NOMEM: + result = FSE_INTERNAL; + break; + case LFS_ERR_NOATTR: + result = FSE_INVALID_PARAMETER; + break; + case LFS_ERR_NAMETOOLONG: + result = FSE_INVALID_NAME; + break; + default: + break; + } + } + + return result; +} + +/******************* File Functions *******************/ + +static bool storage_int_file_open( + void* ctx, + File* file, + const char* path, + FS_AccessMode access_mode, + FS_OpenMode open_mode) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + + int flags = 0; + + if(access_mode & FSAM_READ) flags |= LFS_O_RDONLY; + if(access_mode & FSAM_WRITE) flags |= LFS_O_WRONLY; + + if(open_mode & FSOM_OPEN_EXISTING) flags = flags; + if(open_mode & FSOM_OPEN_ALWAYS) flags |= LFS_O_CREAT; + if(open_mode & FSOM_OPEN_APPEND) flags |= LFS_O_CREAT | LFS_O_APPEND; + if(open_mode & FSOM_CREATE_NEW) flags |= LFS_O_CREAT | LFS_O_EXCL; + if(open_mode & FSOM_CREATE_ALWAYS) flags |= LFS_O_CREAT | LFS_O_TRUNC; + + LFSHandle* handle = lfs_handle_alloc_file(); + storage_set_storage_file_data(file, handle, storage); + file->internal_error_id = lfs_file_open(lfs, lfs_handle_get_file(handle), path, flags); + + if(file->internal_error_id >= LFS_ERR_OK) { + lfs_handle_set_open(handle); + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} + +static bool storage_int_file_close(void* ctx, File* file) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + if(lfs_handle_is_open(handle)) { + file->internal_error_id = lfs_file_close(lfs, lfs_handle_get_file(handle)); + } else { + file->internal_error_id = LFS_ERR_BADF; + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + lfs_handle_free(handle); + return (file->error_id == FSE_OK); +} + +static uint16_t + storage_int_file_read(void* ctx, File* file, void* buff, uint16_t const bytes_to_read) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + uint16_t bytes_readed = 0; + + if(lfs_handle_is_open(handle)) { + file->internal_error_id = + lfs_file_read(lfs, lfs_handle_get_file(handle), buff, bytes_to_read); + } else { + file->internal_error_id = LFS_ERR_BADF; + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + + if(file->error_id == FSE_OK) { + bytes_readed = file->internal_error_id; + file->internal_error_id = 0; + } + return bytes_readed; +} + +static uint16_t + storage_int_file_write(void* ctx, File* file, const void* buff, uint16_t const bytes_to_write) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + uint16_t bytes_written = 0; + + if(lfs_handle_is_open(handle)) { + file->internal_error_id = + lfs_file_write(lfs, lfs_handle_get_file(handle), buff, bytes_to_write); + } else { + file->internal_error_id = LFS_ERR_BADF; + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + + if(file->error_id == FSE_OK) { + bytes_written = file->internal_error_id; + file->internal_error_id = 0; + } + return bytes_written; +} + +static bool + storage_int_file_seek(void* ctx, File* file, const uint32_t offset, const bool from_start) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + if(lfs_handle_is_open(handle)) { + if(from_start) { + file->internal_error_id = + lfs_file_seek(lfs, lfs_handle_get_file(handle), offset, LFS_SEEK_SET); + } else { + file->internal_error_id = + lfs_file_seek(lfs, lfs_handle_get_file(handle), offset, LFS_SEEK_CUR); + } + } else { + file->internal_error_id = LFS_ERR_BADF; + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} + +static uint64_t storage_int_file_tell(void* ctx, File* file) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + if(lfs_handle_is_open(handle)) { + file->internal_error_id = lfs_file_tell(lfs, lfs_handle_get_file(handle)); + } else { + file->internal_error_id = LFS_ERR_BADF; + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + + int32_t position = 0; + if(file->error_id == FSE_OK) { + position = file->internal_error_id; + file->internal_error_id = 0; + } + + return position; +} + +static bool storage_int_file_truncate(void* ctx, File* file) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + if(lfs_handle_is_open(handle)) { + file->internal_error_id = lfs_file_tell(lfs, lfs_handle_get_file(handle)); + file->error_id = storage_int_parse_error(file->internal_error_id); + + if(file->error_id == FSE_OK) { + uint32_t position = file->internal_error_id; + file->internal_error_id = + lfs_file_truncate(lfs, lfs_handle_get_file(handle), position); + file->error_id = storage_int_parse_error(file->internal_error_id); + } + } else { + file->internal_error_id = LFS_ERR_BADF; + file->error_id = storage_int_parse_error(file->internal_error_id); + } + + return (file->error_id == FSE_OK); +} + +static bool storage_int_file_sync(void* ctx, File* file) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + if(lfs_handle_is_open(handle)) { + file->internal_error_id = lfs_file_sync(lfs, lfs_handle_get_file(handle)); + } else { + file->internal_error_id = LFS_ERR_BADF; + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} + +static uint64_t storage_int_file_size(void* ctx, File* file) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + if(lfs_handle_is_open(handle)) { + file->internal_error_id = lfs_file_size(lfs, lfs_handle_get_file(handle)); + } else { + file->internal_error_id = LFS_ERR_BADF; + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + + uint32_t size = 0; + if(file->error_id == FSE_OK) { + size = file->internal_error_id; + file->internal_error_id = 0; + } + + return size; +} + +static bool storage_int_file_eof(void* ctx, File* file) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + bool eof = true; + + if(lfs_handle_is_open(handle)) { + int32_t position = lfs_file_tell(lfs, lfs_handle_get_file(handle)); + int32_t size = lfs_file_size(lfs, lfs_handle_get_file(handle)); + + if(position < 0) { + file->internal_error_id = position; + } else if(size < 0) { + file->internal_error_id = size; + } else { + file->internal_error_id = LFS_ERR_OK; + eof = (position >= size); + } + } else { + file->internal_error_id = LFS_ERR_BADF; + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + return eof; +} + +/******************* Dir Functions *******************/ + +static bool storage_int_dir_open(void* ctx, File* file, const char* path) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + + LFSHandle* handle = lfs_handle_alloc_dir(); + storage_set_storage_file_data(file, handle, storage); + + file->internal_error_id = lfs_dir_open(lfs, lfs_handle_get_dir(handle), path); + if(file->internal_error_id >= LFS_ERR_OK) { + lfs_handle_set_open(handle); + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} + +static bool storage_int_dir_close(void* ctx, File* file) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + if(lfs_handle_is_open(handle)) { + file->internal_error_id = lfs_dir_close(lfs, lfs_handle_get_dir(handle)); + } else { + file->internal_error_id = LFS_ERR_BADF; + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + lfs_handle_free(handle); + return (file->error_id == FSE_OK); +} + +static bool storage_int_dir_read( + void* ctx, + File* file, + FileInfo* fileinfo, + char* name, + const uint16_t name_length) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + if(lfs_handle_is_open(handle)) { + struct lfs_info _fileinfo; + + // LFS returns virtual directories "." and "..", so we read until we get something meaningful or an empty string + do { + file->internal_error_id = lfs_dir_read(lfs, lfs_handle_get_dir(handle), &_fileinfo); + file->error_id = storage_int_parse_error(file->internal_error_id); + } while(strcmp(_fileinfo.name, ".") == 0 || strcmp(_fileinfo.name, "..") == 0); + + if(fileinfo != NULL) { + fileinfo->size = _fileinfo.size; + fileinfo->flags = 0; + if(_fileinfo.type & LFS_TYPE_DIR) fileinfo->flags |= FSF_DIRECTORY; + } + + if(name != NULL) { + snprintf(name, name_length, "%s", _fileinfo.name); + } + + // set FSE_NOT_EXIST error on end of directory + if(file->internal_error_id == 0) { + file->error_id = FSE_NOT_EXIST; + } + } else { + file->internal_error_id = LFS_ERR_BADF; + file->error_id = storage_int_parse_error(file->internal_error_id); + } + + return (file->error_id == FSE_OK); +} + +static bool storage_int_dir_rewind(void* ctx, File* file) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + LFSHandle* handle = storage_get_storage_file_data(file, storage); + + if(lfs_handle_is_open(handle)) { + file->internal_error_id = lfs_dir_rewind(lfs, lfs_handle_get_dir(handle)); + } else { + file->internal_error_id = LFS_ERR_BADF; + } + + file->error_id = storage_int_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); +} + +/******************* Common FS Functions *******************/ + +static FS_Error storage_int_common_stat(void* ctx, const char* path, FileInfo* fileinfo) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + struct lfs_info _fileinfo; + int result = lfs_stat(lfs, path, &_fileinfo); + + if(fileinfo != NULL) { + fileinfo->size = _fileinfo.size; + fileinfo->flags = 0; + if(_fileinfo.type & LFS_TYPE_DIR) fileinfo->flags |= FSF_DIRECTORY; + } + + return storage_int_parse_error(result); +} + +static FS_Error storage_int_common_remove(void* ctx, const char* path) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + int result = lfs_remove(lfs, path); + return storage_int_parse_error(result); +} + +static FS_Error storage_int_common_rename(void* ctx, const char* old_path, const char* new_path) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + int result = lfs_rename(lfs, old_path, new_path); + return storage_int_parse_error(result); +} + +static FS_Error storage_int_common_mkdir(void* ctx, const char* path) { + StorageData* storage = ctx; + lfs_t* lfs = lfs_get_from_storage(storage); + int result = lfs_mkdir(lfs, path); + return storage_int_parse_error(result); +} + +static FS_Error storage_int_common_fs_info( + void* ctx, + const char* fs_path, + uint64_t* total_space, + uint64_t* free_space) { + StorageData* storage = ctx; + + lfs_t* lfs = lfs_get_from_storage(storage); + LFSData* lfs_data = lfs_data_get_from_storage(storage); + + *total_space = lfs_data->config.block_size * lfs_data->config.block_count; + + lfs_ssize_t result = lfs_fs_size(lfs); + if(result >= 0) { + *free_space = *total_space - (result * lfs_data->config.block_size); + } + + return storage_int_parse_error(result); +} + +/******************* Init Storage *******************/ + +void storage_int_init(StorageData* storage) { + FURI_LOG_I(TAG, "Starting"); + LFSData* lfs_data = storage_int_lfs_data_alloc(); + FURI_LOG_I( + TAG, + "Config: start %p, read %d, write %d, page size: %d, page count: %d, cycles: %d", + lfs_data->start_address, + lfs_data->config.read_size, + lfs_data->config.prog_size, + lfs_data->config.block_size, + lfs_data->config.block_count, + lfs_data->config.block_cycles); + + storage_int_lfs_mount(lfs_data, storage); + + storage->data = lfs_data; + storage->api.tick = NULL; + storage->fs_api.file.open = storage_int_file_open; + storage->fs_api.file.close = storage_int_file_close; + storage->fs_api.file.read = storage_int_file_read; + storage->fs_api.file.write = storage_int_file_write; + storage->fs_api.file.seek = storage_int_file_seek; + storage->fs_api.file.tell = storage_int_file_tell; + storage->fs_api.file.truncate = storage_int_file_truncate; + storage->fs_api.file.size = storage_int_file_size; + storage->fs_api.file.sync = storage_int_file_sync; + storage->fs_api.file.eof = storage_int_file_eof; + + storage->fs_api.dir.open = storage_int_dir_open; + storage->fs_api.dir.close = storage_int_dir_close; + storage->fs_api.dir.read = storage_int_dir_read; + storage->fs_api.dir.rewind = storage_int_dir_rewind; + + storage->fs_api.common.stat = storage_int_common_stat; + storage->fs_api.common.mkdir = storage_int_common_mkdir; + storage->fs_api.common.rename = storage_int_common_rename; + storage->fs_api.common.remove = storage_int_common_remove; + storage->fs_api.common.fs_info = storage_int_common_fs_info; +} \ No newline at end of file diff --git a/applications/storage/storages/storage-int.h b/applications/storage/storages/storage-int.h new file mode 100644 index 00000000..2a25e02c --- /dev/null +++ b/applications/storage/storages/storage-int.h @@ -0,0 +1,13 @@ +#pragma once +#include +#include "../storage-glue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void storage_int_init(StorageData* storage); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index f9823147..a77fe3a9 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -223,8 +223,8 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { furi_check(instance->stream); SubGhzProtocol* protocol = subghz_protocol_alloc(); - subghz_protocol_load_keeloq_file(protocol, "/assets/subghz/keeloq_mfcodes"); - subghz_protocol_load_nice_flor_s_file(protocol, "/assets/subghz/nice_floor_s_rx"); + subghz_protocol_load_keeloq_file(protocol, "/ext/assets/subghz/keeloq_mfcodes"); + subghz_protocol_load_nice_flor_s_file(protocol, "/ext/assets/subghz/nice_floor_s_rx"); subghz_protocol_enable_dump_text(protocol, subghz_cli_command_rx_text_callback, instance); // Configure radio diff --git a/applications/subghz/views/subghz_capture.c b/applications/subghz/views/subghz_capture.c index bd1234df..4df825b9 100644 --- a/applications/subghz/views/subghz_capture.c +++ b/applications/subghz/views/subghz_capture.c @@ -207,9 +207,10 @@ SubghzCapture* subghz_capture_alloc() { subghz_capture->worker, (SubGhzWorkerPairCallback)subghz_protocol_parse); subghz_worker_set_context(subghz_capture->worker, subghz_capture->protocol); - subghz_protocol_load_keeloq_file(subghz_capture->protocol, "/assets/subghz/keeloq_mfcodes"); + subghz_protocol_load_keeloq_file( + subghz_capture->protocol, "/ext/assets/subghz/keeloq_mfcodes"); subghz_protocol_load_nice_flor_s_file( - subghz_capture->protocol, "/assets/subghz/nice_floor_s_rx"); + subghz_capture->protocol, "/ext/assets/subghz/nice_floor_s_rx"); subghz_protocol_enable_dump_text( subghz_capture->protocol, subghz_capture_text_callback, subghz_capture); diff --git a/assets/compiled/assets_icons.c b/assets/compiled/assets_icons.c index d8b73542..860fe5c0 100644 --- a/assets/compiled/assets_icons.c +++ b/assets/compiled/assets_icons.c @@ -56,47 +56,47 @@ const uint8_t _A_Wink_128x64_7[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 const uint8_t _A_Wink_128x64_8[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0xF0,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xBF,0x1E,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x54,0x07,0xD8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xAA,0x03,0x8E,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x55,0x03,0x13,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAA,0xC1,0x61,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD5,0x70,0x84,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0xEA,0x18,0x08,0x11,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x55,0x8C,0x10,0x38,0x1C,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x6A,0x04,0x21,0x2C,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0xFF,0x3F,0x0C,0x02,0xE6,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xC0,0x00,0x18,0x18,0x84,0x23,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x60,0xFE,0x33,0x30,0xE0,0x10,0x00,0xF8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x30,0x01,0x64,0x20,0x38,0x0C,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x90,0x00,0xC8,0xE0,0x0F,0x02,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x48,0xFC,0x91,0x00,0x00,0x01,0xE0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0xFE,0xA3,0x01,0xC0,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0xFF,0x27,0x01,0x30,0x00,0xFC,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0xFF,0x47,0x01,0x08,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0xE7,0x4F,0x01,0x06,0x80,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0xE7,0x4F,0x81,0x01,0xC0,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0xFF,0x4F,0x71,0x00,0xE0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0xFF,0x4F,0x1D,0x00,0xF0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0xFF,0x4F,0x07,0x00,0xF8,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x96,0xFF,0x7F,0x00,0x00,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x25,0xFF,0x41,0x00,0x00,0xFE,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x2A,0x7E,0x00,0x00,0x00,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x4D,0x1E,0x00,0x00,0x80,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0x9A,0x02,0x00,0x00,0xC0,0xFF,0x01,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x95,0x01,0x00,0x00,0xF0,0xFF,0xFF,0x7F,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xEA,0x00,0x00,0x00,0xF8,0x01,0x1F,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x55,0x00,0x00,0x00,0xFC,0x00,0x70,0xC0,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0x2A,0x00,0x00,0x00,0x3E,0x00,0xE0,0x39,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x15,0x00,0x60,0x80,0x1F,0x00,0x80,0x0F,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0x0A,0x00,0xC0,0xF0,0x3F,0x00,0xF0,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x05,0x00,0x00,0xFF,0xFF,0xFF,0x1F,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; const uint8_t *_A_Wink_128x64[] = {_A_Wink_128x64_0,_A_Wink_128x64_1,_A_Wink_128x64_2,_A_Wink_128x64_3,_A_Wink_128x64_4,_A_Wink_128x64_5,_A_Wink_128x64_6,_A_Wink_128x64_7,_A_Wink_128x64_8}; +const uint8_t _I_125_10px_0[] = {0xE0,0x00,0x00,0x01,0x0E,0x02,0x31,0x02,0x45,0x02,0x91,0x00,0xAA,0x00,0x92,0x00,0x44,0x00,0x38,0x00,}; +const uint8_t *_I_125_10px[] = {_I_125_10px_0}; + +const uint8_t _I_ble_10px_0[] = {0x04,0x00,0x8C,0x00,0x15,0x01,0x56,0x02,0x8C,0x02,0x8C,0x02,0x56,0x02,0x15,0x01,0x8C,0x00,0x04,0x00,}; +const uint8_t *_I_ble_10px[] = {_I_ble_10px_0}; + const uint8_t _I_dir_10px_0[] = {0x00,0x00,0x3F,0x00,0x41,0x00,0xFF,0x03,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0xFE,0x01,0x00,0x00,}; const uint8_t *_I_dir_10px[] = {_I_dir_10px_0}; +const uint8_t _I_ibutt_10px_0[] = {0x80,0x03,0x40,0x02,0x20,0x02,0x10,0x01,0x8E,0x00,0x41,0x00,0x2D,0x00,0x2D,0x00,0x21,0x00,0x1E,0x00,}; +const uint8_t *_I_ibutt_10px[] = {_I_ibutt_10px_0}; + +const uint8_t _I_ir_10px_0[] = {0xFC,0x00,0x02,0x01,0x79,0x02,0x84,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x58,0x00,0x78,0x00,0xFF,0x03,}; +const uint8_t *_I_ir_10px[] = {_I_ir_10px_0}; + const uint8_t _I_Nfc_10px_0[] = {0x80,0x00,0x00,0x01,0x22,0x02,0x43,0x02,0x45,0x02,0x49,0x02,0x31,0x02,0x22,0x02,0x00,0x01,0x80,0x00,}; const uint8_t *_I_Nfc_10px[] = {_I_Nfc_10px_0}; const uint8_t _I_sub1_10px_0[] = {0x02,0x01,0x49,0x02,0x85,0x02,0xB5,0x02,0xB5,0x02,0x01,0x02,0x32,0x01,0x30,0x00,0x30,0x00,0x30,0x00,}; const uint8_t *_I_sub1_10px[] = {_I_sub1_10px_0}; -const uint8_t _I_ir_10px_0[] = {0xFC,0x00,0x02,0x01,0x79,0x02,0x84,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x58,0x00,0x78,0x00,0xFF,0x03,}; -const uint8_t *_I_ir_10px[] = {_I_ir_10px_0}; - -const uint8_t _I_ibutt_10px_0[] = {0x80,0x03,0x40,0x02,0x20,0x02,0x10,0x01,0x8E,0x00,0x41,0x00,0x2D,0x00,0x2D,0x00,0x21,0x00,0x1E,0x00,}; -const uint8_t *_I_ibutt_10px[] = {_I_ibutt_10px_0}; - const uint8_t _I_unknown_10px_0[] = {0x78,0x00,0xCC,0x00,0x84,0x00,0xC0,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,}; const uint8_t *_I_unknown_10px[] = {_I_unknown_10px_0}; -const uint8_t _I_ble_10px_0[] = {0x04,0x00,0x8C,0x00,0x15,0x01,0x56,0x02,0x8C,0x02,0x8C,0x02,0x56,0x02,0x15,0x01,0x8C,0x00,0x04,0x00,}; -const uint8_t *_I_ble_10px[] = {_I_ble_10px_0}; - -const uint8_t _I_125_10px_0[] = {0xE0,0x00,0x00,0x01,0x0E,0x02,0x31,0x02,0x45,0x02,0x91,0x00,0xAA,0x00,0x92,0x00,0x44,0x00,0x38,0x00,}; -const uint8_t *_I_125_10px[] = {_I_125_10px_0}; - -const uint8_t _I_ButtonRightSmall_3x5_0[] = {0x01,0x03,0x07,0x03,0x01,}; -const uint8_t *_I_ButtonRightSmall_3x5[] = {_I_ButtonRightSmall_3x5_0}; - -const uint8_t _I_ButtonLeft_4x7_0[] = {0x08,0x0C,0x0E,0x0F,0x0E,0x0C,0x08,}; -const uint8_t *_I_ButtonLeft_4x7[] = {_I_ButtonLeft_4x7_0}; - -const uint8_t _I_ButtonLeftSmall_3x5_0[] = {0x04,0x06,0x07,0x06,0x04,}; -const uint8_t *_I_ButtonLeftSmall_3x5[] = {_I_ButtonLeftSmall_3x5_0}; - -const uint8_t _I_ButtonRight_4x7_0[] = {0x01,0x03,0x07,0x0F,0x07,0x03,0x01,}; -const uint8_t *_I_ButtonRight_4x7[] = {_I_ButtonRight_4x7_0}; - const uint8_t _I_ButtonCenter_7x7_0[] = {0x1C,0x22,0x5D,0x5D,0x5D,0x22,0x1C,}; const uint8_t *_I_ButtonCenter_7x7[] = {_I_ButtonCenter_7x7_0}; -const uint8_t _I_FX_SittingB_40x27_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0xFC,0x0F,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x00,0xF8,0x0F,0x00,0x00,0xE0,0xFF,0x07,0x00,0x00,0xFF,0xFF,0x03,0x00,0xE0,0xFF,0xFF,0x03,0x00,0xF8,0xFF,0xFF,0x07,0x00,0xFC,0xFF,0xFF,0x07,0x00,0xFE,0xFF,0x7F,0x07,0xFC,0x7F,0x00,0x00,0x06,0xF8,0x07,0x00,0x00,0x04,0xE0,0x03,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,}; -const uint8_t *_I_FX_SittingB_40x27[] = {_I_FX_SittingB_40x27_0}; +const uint8_t _I_ButtonLeftSmall_3x5_0[] = {0x04,0x06,0x07,0x06,0x04,}; +const uint8_t *_I_ButtonLeftSmall_3x5[] = {_I_ButtonLeftSmall_3x5_0}; + +const uint8_t _I_ButtonLeft_4x7_0[] = {0x08,0x0C,0x0E,0x0F,0x0E,0x0C,0x08,}; +const uint8_t *_I_ButtonLeft_4x7[] = {_I_ButtonLeft_4x7_0}; + +const uint8_t _I_ButtonRightSmall_3x5_0[] = {0x01,0x03,0x07,0x03,0x01,}; +const uint8_t *_I_ButtonRightSmall_3x5[] = {_I_ButtonRightSmall_3x5_0}; + +const uint8_t _I_ButtonRight_4x7_0[] = {0x01,0x03,0x07,0x0F,0x07,0x03,0x01,}; +const uint8_t *_I_ButtonRight_4x7[] = {_I_ButtonRight_4x7_0}; + +const uint8_t _I_BigBurger_24x24_0[] = {0xE0,0xFF,0x07,0x18,0x00,0x18,0x04,0x41,0x20,0x02,0x08,0x42,0x12,0x00,0x48,0x81,0x20,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0xFE,0xFF,0x7F,0xFE,0xFF,0x77,0x31,0x18,0x8C,0x87,0xC3,0xE1,0x7C,0x3C,0x3E,0x04,0x00,0x20,0xFE,0xFF,0x7F,0x01,0x00,0x80,0xFF,0x1F,0xF8,0xAA,0x6A,0x6E,0x56,0xD5,0x55,0xFE,0xFF,0x7F,0x01,0x00,0x80,0x01,0x00,0x80,0x02,0x00,0x40,0xFC,0xFF,0x3F,}; +const uint8_t *_I_BigBurger_24x24[] = {_I_BigBurger_24x24_0}; const uint8_t _I_BigGames_24x24_0[] = {0x00,0x3E,0x00,0x00,0x41,0x00,0x80,0x80,0x00,0x80,0x80,0x00,0x80,0x80,0x00,0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x41,0x00,0x00,0x3E,0x00,0x00,0x14,0x00,0x00,0x14,0x00,0x00,0x14,0x00,0xF8,0xF7,0x1F,0x08,0x14,0x10,0x84,0xF7,0x20,0xC4,0xF7,0x21,0xC2,0xFF,0x41,0x02,0x7F,0x40,0x01,0x00,0x80,0xFF,0xFF,0xFF,0x55,0x55,0xD5,0xAB,0xAA,0xAA,0x55,0x55,0xD5,0xFF,0xFF,0xFF,}; const uint8_t *_I_BigGames_24x24[] = {_I_BigGames_24x24_0}; @@ -104,47 +104,47 @@ const uint8_t *_I_BigGames_24x24[] = {_I_BigGames_24x24_0}; const uint8_t _I_BigProfile_24x24_0[] = {0x00,0x18,0x00,0x00,0x24,0x00,0x00,0x42,0x00,0x00,0x5A,0x00,0x00,0x5A,0x00,0x00,0x42,0x00,0x00,0x42,0x00,0xFE,0xFF,0x7F,0x01,0x00,0x80,0xF1,0x00,0x80,0xF9,0xF1,0xBF,0xF9,0x01,0x80,0xF9,0xF1,0xBF,0xF9,0x01,0x80,0xF1,0xB0,0x83,0x61,0x00,0x80,0x61,0xF0,0xBC,0xF1,0x00,0x80,0x09,0x01,0x80,0x05,0xF2,0xBB,0xFD,0x03,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0xFE,0xFF,0x7F,}; const uint8_t *_I_BigProfile_24x24[] = {_I_BigProfile_24x24_0}; -const uint8_t _I_DolphinOkay_41x43_0[] = {0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x1E,0xE0,0x00,0x00,0x00,0x80,0x01,0x00,0x07,0x00,0x00,0x60,0x00,0x00,0x18,0x00,0x00,0x10,0x00,0x00,0x20,0x00,0x00,0x08,0x00,0x00,0x40,0x00,0x00,0x04,0x00,0x00,0x80,0x00,0x00,0x04,0x00,0x00,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x3E,0x00,0x00,0x80,0x00,0x00,0x7D,0x00,0x00,0x80,0x00,0x80,0xFE,0x00,0x00,0x80,0x00,0x40,0xE2,0x01,0x00,0x80,0x00,0x40,0xF2,0x01,0x00,0x80,0x00,0x40,0xFE,0x01,0x00,0x80,0x00,0x40,0xFE,0x05,0x00,0x80,0x00,0x40,0x7C,0x0B,0x00,0x80,0x00,0x80,0x80,0x15,0x00,0x80,0x00,0x00,0xFD,0x0A,0x00,0x00,0x01,0x00,0x02,0x15,0x00,0x00,0x01,0x00,0x01,0x0A,0x00,0x00,0xE1,0x07,0x00,0x06,0x00,0x80,0x1F,0x00,0x00,0x02,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x20,0x00,0x00,0x08,0x00,0x00,0x20,0x00,0x00,0x04,0x00,0x00,0x10,0x00,0x00,0x02,0x00,0x00,0x08,0x00,0x00,0x01,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x80,0x03,0x00,0x00,0x01,0x00,0x70,0x00,0x00,0x00,0xF9,0x03,0x0F,0x00,0x00,0x00,0x06,0xFC,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xC0,0x01,0x00,0x08,0x00,0x00,0x78,0x00,0x00,0x30,0x00,0xF8,0xAF,0x00,0x00,0xC0,0xFF,0xFF,0x57,0x00,0x00,0x00,0xF8,0xBF,0x2A,0x00,0x00,0x00,0xF8,0x57,0x15,0x00,0x00,0x00,0xF8,0xAB,0x02,0x00,0x00,}; -const uint8_t *_I_DolphinOkay_41x43[] = {_I_DolphinOkay_41x43_0}; - -const uint8_t _I_DolphinFirstStart5_45x53_0[] = {0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x20,0x10,0x00,0x00,0xFF,0x3F,0x20,0x08,0x00,0xC0,0x00,0xC0,0x01,0x04,0x00,0x30,0x00,0x00,0x06,0x02,0x06,0x0C,0x00,0x00,0x08,0x80,0x01,0x02,0x00,0x00,0x10,0x60,0x00,0x01,0x07,0x00,0x20,0x18,0x00,0x80,0x08,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x80,0x00,0x00,0x20,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xC0,0x01,0x07,0x00,0x00,0x00,0x30,0x00,0x08,0x00,0x60,0x00,0x0C,0x00,0x10,0x00,0x70,0x00,0x03,0x00,0x10,0x00,0x7E,0xC0,0x00,0x00,0x10,0xF8,0x3F,0x20,0x00,0xFC,0x13,0xF8,0x1F,0x10,0x00,0xAF,0x16,0xF0,0x03,0x08,0xC0,0x55,0x15,0x00,0x00,0x04,0xE0,0xAA,0x0A,0xD4,0x07,0x00,0x58,0x55,0x0B,0x6A,0x00,0x00,0xAC,0xAA,0x05,0x15,0x00,0x00,0x56,0xD5,0x02,0x0A,0x00,0x00,0xFF,0xFF,0x01,0x0D,0x00,0x80,0x81,0x03,0x02,0x06,0x00,0xC0,0x70,0x00,0x04,0x04,0x01,0x70,0x0F,0x00,0x04,0x04,0x02,0xFF,0x00,0x00,0x04,0x00,0xFC,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x01,0x00,0x00,0x00,0x0C,0x00,0x02,0x00,0x00,0x00,0x0B,0x00,0x01,0x00,0x00,0xC0,0x08,0x00,0x02,0x00,0x00,0x00,0x10,0x00,0x05,0x00,0x00,0x00,0x10,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x15,0xFE,0x1F,0x00,0x20,0x00,0xAA,0x01,0xE0,0x00,0x40,0x00,0x75,0x00,0x00,0x03,0x40,0x00,0x1A,0x00,0x00,0x04,0x80,0x00,0x05,0x00,0x00,0x08,0x80,0x00,0x02,0x00,0x00,0x08,0x00,0x01,0x01,0x00,0x00,0x04,0x00,0x01,0x00,0x00,0xE0,0x0B,0x00,0x02,0x00,0x00,0x5C,0x05,0x00,0x04,0x00,0x00,0xAB,0x02,0x00,0x08,}; -const uint8_t *_I_DolphinFirstStart5_45x53[] = {_I_DolphinFirstStart5_45x53_0}; - -const uint8_t _I_DolphinFirstStart4_67x53_0[] = {0x00,0x00,0x00,0xF0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x40,0x00,0x00,0x00,0x30,0x00,0x02,0x00,0x00,0xC0,0x00,0x00,0x00,0x30,0x00,0x02,0x00,0x00,0x40,0x01,0x00,0x00,0x30,0x00,0x04,0x00,0x00,0xC0,0x00,0x00,0x00,0xB8,0x02,0x04,0x00,0x00,0x40,0x01,0x00,0x00,0x7C,0x05,0x08,0x00,0x00,0xC0,0x00,0x00,0xF0,0xBF,0x02,0x08,0x00,0x00,0x40,0x01,0x00,0xF0,0x5F,0x05,0x08,0x00,0x00,0xC0,0x02,0x00,0xC0,0xE7,0x03,0x10,0x00,0x00,0x80,0x01,0x00,0x00,0x10,0x02,0x10,0x00,0x00,0x80,0x02,0x00,0x00,0x08,0x04,0x10,0x00,0x00,0x80,0x05,0x00,0x00,0x00,0x04,0x20,0x00,0x00,0x80,0x0A,0x08,0x00,0x80,0x00,0x20,0x00,0x00,0x00,0x1F,0x03,0x00,0x80,0x00,0x20,0x00,0x00,0x00,0x6F,0x00,0x00,0x80,0x00,0x40,0x00,0x00,0x00,0x1E,0x00,0x00,0x80,0x00,0x40,0x00,0x00,0x00,0x0E,0x00,0x00,0x40,0x00,0x40,0x00,0x00,0x0F,0x04,0x00,0x00,0x20,0x00,0xC0,0x00,0x80,0x10,0x04,0x00,0x00,0x18,0x00,0x80,0x00,0x40,0x10,0x02,0x00,0x00,0x06,0x00,0xC0,0x00,0x20,0x10,0x02,0x00,0x80,0x01,0x00,0x80,0x01,0x10,0x08,0x01,0x00,0x60,0x00,0x00,0x00,0x01,0x08,0x08,0x01,0x00,0x10,0x00,0x00,0x80,0x01,0x08,0x88,0x00,0x00,0x08,0x00,0x00,0x00,0x03,0x04,0x88,0x00,0x00,0x04,0x00,0x00,0x80,0x02,0x04,0x88,0x00,0x00,0x02,0x00,0xFC,0x03,0x03,0x02,0x88,0x00,0x00,0x81,0x80,0x03,0x9C,0x06,0x02,0x88,0x00,0xC0,0x60,0x70,0x00,0x60,0x05,0x02,0x88,0x00,0x30,0x30,0x0C,0x00,0x80,0x02,0x01,0x88,0x00,0x0C,0x1C,0x03,0x00,0x00,0x05,0x01,0x88,0x81,0x03,0xAB,0x00,0x00,0x00,0x02,0x01,0x10,0x7F,0xE0,0x75,0x00,0x00,0x00,0x04,0x01,0x10,0x02,0xBC,0x0A,0x00,0x00,0x00,0x00,0x01,0x20,0xFC,0x57,0x0D,0x00,0x00,0x00,0x00,0x01,0x20,0x80,0xAA,0x1A,0x00,0x00,0x00,0x00,0x01,0x40,0x80,0x55,0x75,0xE0,0x3F,0x00,0x00,0x01,0x80,0x80,0xAA,0xAA,0xBF,0xEA,0x00,0x00,0x01,0x00,0x81,0x55,0x55,0x55,0x55,0x01,0x00,}; -const uint8_t *_I_DolphinFirstStart4_67x53[] = {_I_DolphinFirstStart4_67x53_0}; - -const uint8_t _I_DolphinFirstStart2_59x51_0[] = {0x00,0x00,0x00,0x00,0xFF,0x03,0x00,0x00,0x00,0x00,0xF8,0xFF,0x00,0x1C,0x00,0x00,0x00,0x80,0x57,0x0F,0x00,0x60,0x00,0x00,0x00,0xF8,0xAA,0x01,0x00,0x80,0x00,0x00,0x00,0x56,0x65,0x00,0x00,0x00,0x01,0x00,0x80,0xAB,0x1A,0x00,0x00,0x00,0x02,0x00,0x60,0x55,0x07,0x00,0x00,0x00,0x04,0x00,0xB0,0xAA,0x01,0x00,0x00,0x00,0x08,0x00,0x58,0x55,0x00,0x00,0x00,0x00,0x10,0x00,0xAC,0x2A,0x00,0x00,0x00,0x00,0x20,0x00,0x56,0x15,0x00,0x00,0x00,0x00,0x20,0x00,0xAA,0x0A,0x00,0x00,0x00,0x00,0x40,0x00,0x5C,0x05,0x00,0x00,0x00,0x00,0x40,0x00,0xE0,0x02,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x80,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x60,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0xA0,0x00,0x00,0xA0,0x02,0x00,0x80,0x00,0x50,0x00,0x00,0x40,0x01,0x00,0x80,0x00,0xB0,0x00,0x00,0x80,0x06,0x00,0x40,0x00,0x58,0x00,0x00,0x60,0x07,0x00,0x40,0x00,0xA8,0x01,0x00,0x80,0x06,0x00,0x40,0x00,0x54,0x01,0x00,0x00,0x0F,0x00,0x20,0x00,0xAC,0x01,0x00,0x00,0x1D,0x00,0x30,0x00,0xD4,0x00,0x00,0x00,0xF8,0x00,0x18,0x00,0xAA,0x00,0x10,0x00,0x70,0x00,0x14,0x00,0xD6,0x00,0x10,0x10,0x00,0xA0,0x0A,0x00,0xAA,0x00,0x08,0x10,0x00,0x50,0x05,0x00,0xD6,0x00,0x08,0x20,0x00,0xAC,0x82,0x03,0xAB,0x00,0x08,0x40,0x00,0xE0,0xF1,0x06,0xD5,0x00,0x08,0x00,0x00,0x80,0x5F,0x05,0xAB,0x01,0x10,0x80,0x00,0x80,0xAA,0x02,0x55,0x01,0x20,0x40,0x03,0x80,0x55,0x03,0xAB,0x01,0xC0,0x80,0x06,0x80,0xAA,0x01,0x55,0x03,0x00,0x03,0x05,0x80,0xD5,0x00,0xAB,0x02,0x00,0x8C,0x0A,0x80,0x6A,0x00,0x55,0x05,0x00,0x30,0x0D,0x80,0x35,0x00,0x2B,0x0A,0x00,0xC0,0x1A,0x80,0x1A,0x00,0x15,0x34,0x00,0x80,0x1D,0x40,0x07,0x00,0x2B,0xE8,0x00,0xE0,0x36,0xC0,0x01,0x00,0x15,0x50,0x03,0x5F,0x7F,0x40,0x00,0x00,0x0B,0x80,0xFE,0xAA,0x82,0x20,0x00,0x00,0x15,0x00,0x55,0x55,0x01,0x1F,0x00,0x00,0x0B,0x00,0xA8,0xAA,0x01,0x00,0x00,0x00,0x06,0x00,0x00,0x45,0x01,0x00,0x00,0x00,0x0A,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x80,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_DolphinFirstStart2_59x51[] = {_I_DolphinFirstStart2_59x51_0}; - const uint8_t _I_DolphinFirstStart0_70x53_0[] = {0x00,0x80,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0xC0,0x3B,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x7A,0xC0,0x01,0x00,0x00,0x00,0xC0,0x00,0x50,0x1D,0x60,0x07,0x00,0x00,0x00,0x60,0x00,0xA8,0x0E,0x38,0x0E,0x00,0x00,0x00,0x10,0x00,0x54,0x0D,0x4C,0x38,0x00,0x00,0x00,0x00,0x00,0xA8,0x06,0x87,0x21,0x00,0x00,0x00,0x00,0x00,0x54,0xC3,0x11,0x62,0x00,0x00,0x00,0x02,0x00,0xA8,0x63,0x20,0x44,0x80,0x3F,0x00,0x01,0x00,0x54,0x31,0x42,0xE0,0x70,0xE0,0x01,0x00,0x00,0xA8,0x11,0x84,0xB0,0x1C,0x00,0x03,0x00,0xFE,0xFF,0x30,0x08,0x98,0x07,0x00,0x06,0x00,0x03,0x60,0x60,0x10,0x8E,0x00,0xC0,0x07,0x80,0xF9,0xCF,0xC0,0x80,0x43,0x00,0xE0,0x07,0xC0,0x04,0x90,0x81,0xE0,0x30,0x00,0xF8,0x03,0x40,0x02,0x20,0x83,0x3F,0x08,0x00,0xFE,0x01,0x20,0xF1,0x47,0x02,0x00,0x04,0x80,0xFF,0x00,0xA0,0xF8,0x8F,0x06,0x00,0x03,0xC0,0x7F,0x00,0x90,0xFC,0x9F,0x04,0xC0,0x00,0xF0,0x3F,0x00,0x50,0xFC,0x1F,0x05,0x20,0x00,0xF8,0x1F,0x00,0x50,0x9E,0x3F,0x05,0x18,0x00,0xFE,0x0F,0x00,0x50,0x9E,0x3F,0x05,0x06,0x00,0xFF,0x07,0x00,0x50,0xFE,0x3F,0xC5,0x01,0x80,0xFF,0x03,0x00,0x50,0xFE,0x3F,0x75,0x00,0xC0,0xFF,0x01,0x00,0x50,0xFE,0x3F,0x1D,0x00,0xE0,0xFF,0x00,0x00,0x5A,0xFE,0xFF,0x01,0x00,0xF0,0x7F,0x00,0x00,0x95,0xFC,0x07,0x01,0x00,0xF8,0x3F,0x00,0x00,0xAA,0xF8,0x01,0x00,0x00,0xFC,0x1F,0x00,0x00,0x35,0x79,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x6A,0x0A,0x00,0x00,0x00,0xFF,0x07,0x00,0x1E,0x55,0x06,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0x39,0xAA,0x03,0x00,0x00,0xE0,0x07,0x7C,0x00,0x24,0x55,0x01,0x00,0x00,0xF0,0x03,0xC0,0x01,0x23,0xAA,0x00,0x00,0x00,0xF8,0x00,0x80,0xE7,0x20,0x55,0x00,0x80,0x01,0x7E,0x00,0x00,0x3E,0x10,0x2A,0x00,0x00,0xC3,0xFF,0x00,0xC0,0x03,0x10,0x15,0x00,0x00,0xFC,0xFF,0xFF,0x7F,0x00,0x08,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,}; const uint8_t *_I_DolphinFirstStart0_70x53[] = {_I_DolphinFirstStart0_70x53_0}; -const uint8_t _I_DolphinFirstStart6_58x54_0[] = {0x00,0x00,0xFC,0x3F,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0xC0,0x03,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x40,0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x20,0x00,0x00,0x06,0x00,0x08,0x00,0x00,0x20,0x00,0x00,0x18,0x00,0x08,0x00,0x00,0x20,0x00,0x00,0x60,0x00,0x14,0x00,0x00,0x10,0x00,0xFE,0x3F,0x00,0xFC,0x0F,0x00,0x10,0x80,0xFF,0xFF,0x01,0xFF,0x1F,0x00,0x10,0xC0,0x81,0xFF,0x83,0x81,0x3F,0x00,0x08,0xC0,0xC1,0xFF,0xFF,0xC1,0x3F,0x00,0x08,0xC0,0xAB,0xFF,0xFF,0xA9,0x3F,0x00,0x08,0xC0,0xD5,0xFF,0xAB,0xD7,0x3F,0x00,0x04,0xC0,0xFF,0xFF,0x57,0xFF,0x1F,0x00,0x04,0xD0,0xFF,0xFF,0xAB,0xFF,0x1F,0x00,0x04,0xA0,0xFF,0xFF,0x41,0x0F,0x60,0x00,0x04,0x50,0xFF,0xFF,0xE0,0x01,0x80,0x00,0x04,0xA8,0xFF,0x57,0x1C,0x00,0x00,0x01,0x02,0x50,0xC0,0x8A,0x03,0x00,0x00,0x02,0x02,0x20,0x80,0x00,0x00,0x00,0x00,0x02,0x02,0x10,0x00,0x00,0x00,0x00,0x3E,0x02,0x02,0x10,0x00,0x00,0x00,0xC0,0xC1,0x02,0x02,0x00,0x00,0x00,0x00,0x30,0x00,0x03,0x02,0x00,0x08,0x00,0x00,0x0C,0x00,0x02,0x02,0x00,0x08,0x00,0x00,0x03,0x00,0x01,0x02,0x00,0x10,0x00,0xF0,0x00,0x00,0x01,0x02,0x00,0xE0,0x00,0x0F,0x00,0x80,0x00,0x02,0x00,0x00,0xFF,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0x00,0x0C,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x0C,0x00,0x00,0x02,0x22,0x00,0x00,0x00,0x03,0x00,0x00,0x05,0x42,0x00,0x00,0xC0,0x00,0x00,0x80,0x0A,0x41,0x00,0x00,0x38,0x00,0x00,0x00,0x15,0x81,0x07,0x00,0x30,0x00,0x00,0x80,0xAA,0x00,0x08,0x00,0x60,0x00,0x00,0x00,0x75,0x00,0x10,0x00,0xA0,0x00,0x00,0x00,0x1A,0x00,0x20,0x00,0xA0,0x00,0x00,0x00,0x07,0x00,0x20,0x00,0x20,0x01,0x00,0xC0,0x00,0x00,0x40,0x00,0x20,0x02,0x00,0x30,0x00,0x00,0x40,0x00,0x40,0x04,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x04,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x08,0x00,0x00,0x00,0x00,0xA0,0x00,0x40,0x08,0x00,0x00,0x00,0x00,0x50,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xAC,0x00,0x80,0x10,0x00,0x00,0x00,0xE0,0x53,0x01,0x80,0x20,0x00,}; -const uint8_t *_I_DolphinFirstStart6_58x54[] = {_I_DolphinFirstStart6_58x54_0}; - const uint8_t _I_DolphinFirstStart1_59x53_0[] = {0x00,0x00,0x80,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x90,0x3F,0x00,0x00,0x00,0x80,0x00,0x00,0x70,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x18,0x80,0x00,0x00,0x00,0x40,0x00,0x00,0x04,0x80,0x00,0x00,0x00,0x40,0x00,0x00,0x02,0x9E,0x00,0x00,0x00,0x20,0x00,0x0C,0x81,0xAB,0x00,0x00,0x00,0x20,0x00,0x0C,0x40,0x55,0x18,0x00,0x00,0x10,0x00,0x0E,0xA0,0x2A,0x24,0x00,0x00,0x10,0xF0,0x0F,0x50,0x15,0x24,0x00,0x00,0x10,0xF0,0x07,0xA8,0x0E,0x24,0x00,0x00,0x10,0xE8,0x03,0x54,0x07,0xC4,0x01,0x00,0x10,0x54,0x04,0xBE,0x03,0x04,0x02,0x00,0x10,0x28,0x00,0xCF,0x01,0x24,0x04,0x00,0x10,0x20,0x80,0x03,0x06,0x24,0x04,0x00,0x10,0x00,0xE1,0x03,0x18,0x24,0x04,0x00,0x30,0x00,0x9E,0x03,0x28,0xC4,0x03,0x00,0x28,0x00,0x00,0xFC,0x27,0x04,0x02,0x00,0x34,0x00,0x00,0x00,0x20,0x02,0x02,0x00,0x6A,0x00,0x00,0x00,0x10,0x02,0x02,0x00,0x56,0x00,0x00,0x00,0x0C,0x01,0x02,0x00,0x6B,0x00,0x00,0xFE,0x83,0x00,0x02,0x00,0xD5,0x03,0x00,0x80,0x60,0x00,0x01,0x80,0x3A,0x00,0x00,0x00,0x1F,0x00,0x01,0x80,0x0D,0x00,0x00,0x00,0x01,0x80,0x00,0x40,0x03,0x00,0x00,0x00,0x03,0x80,0x00,0xC0,0x00,0x00,0x00,0x00,0x06,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x0A,0x20,0x00,0x10,0x00,0x00,0x00,0x00,0x56,0x10,0x00,0x08,0x00,0x00,0x00,0x00,0xAC,0x0A,0x00,0x04,0x00,0x00,0x00,0x00,0x54,0x05,0x00,0x02,0x00,0x00,0x00,0x00,0xAC,0x03,0x00,0x01,0x80,0x01,0x00,0x00,0xD4,0x00,0x00,0x01,0x70,0x00,0x00,0x00,0x3C,0x00,0x00,0x01,0xCC,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x42,0x01,0x00,0x00,0x04,0x00,0x00,0x02,0xC4,0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x44,0x01,0x00,0x00,0x04,0x00,0x00,0x08,0xA8,0x00,0x00,0x00,0x02,0x00,0x00,0x10,0x70,0x01,0x00,0x00,0x02,0x00,0x00,0x20,0xA0,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x40,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x43,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x22,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x5C,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x2A,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x08,0x00,0x00,0x00,}; const uint8_t *_I_DolphinFirstStart1_59x53[] = {_I_DolphinFirstStart1_59x53_0}; -const uint8_t _I_DolphinFirstStart8_56x51_0[] = {0x00,0x00,0x00,0xE0,0xFF,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x06,0x00,0x00,0x00,0x00,0x0E,0x00,0x18,0x00,0x00,0x00,0x00,0x01,0x00,0x60,0x00,0x00,0x00,0xC0,0x00,0x00,0x80,0x01,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x00,0x00,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x00,0x01,0x00,0x80,0x07,0x40,0x00,0x00,0x01,0x00,0x60,0x1C,0x40,0x00,0x80,0x00,0x00,0x10,0x3F,0x80,0x00,0x80,0x00,0x00,0x88,0x7F,0x80,0xC0,0x80,0x00,0x00,0xC8,0x71,0x80,0x20,0x81,0x00,0x00,0xC4,0xF1,0x00,0x20,0x81,0x00,0x00,0xE4,0xF3,0x02,0x20,0x82,0x01,0x00,0xE4,0xFF,0x05,0x20,0x82,0x00,0x00,0xE4,0xFF,0x0A,0x20,0x84,0x01,0x00,0xC8,0x7F,0x05,0x20,0x84,0x02,0x00,0xC8,0xFF,0x02,0x20,0x88,0x05,0x00,0x90,0x03,0x05,0x10,0x88,0x02,0x00,0x60,0x01,0x02,0x10,0x90,0xC5,0x00,0x80,0x00,0x04,0x08,0x90,0x1F,0x00,0x80,0x00,0x00,0x04,0xE0,0x01,0x00,0x00,0x00,0x00,0x02,0x30,0x00,0x00,0x00,0x00,0x00,0x01,0x08,0x00,0x00,0x00,0x10,0x00,0x01,0x06,0x00,0x00,0x00,0x10,0x00,0x01,0x01,0x00,0x00,0x00,0x10,0x00,0x81,0x00,0x00,0x00,0x00,0x08,0x00,0x41,0x00,0x00,0x00,0x00,0x04,0x00,0x41,0x00,0x00,0x00,0x00,0x03,0x00,0x42,0xFE,0x00,0x00,0xE0,0x00,0x00,0x42,0x01,0x1F,0x80,0x1F,0x00,0x00,0xC2,0x00,0xE0,0x7F,0x00,0x00,0x00,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x84,0x1E,0x00,0x00,0x00,0x00,0x00,0x04,0xF5,0x1F,0xC0,0x0F,0x00,0x00,0x04,0xAA,0xEA,0xBF,0x02,0x00,0x00,0x04,0x54,0x15,0x55,0x01,0x00,0x00,0x04,0xA8,0x1A,0xAB,0x02,0x00,0x00,0x08,0x50,0x35,0x55,0x01,0x00,0x00,0x08,0x80,0x2A,0xAA,0x00,0x00,0x00,0x08,0x00,0x54,0x56,0x00,0x00,0x00,0x08,0x00,0x60,0x2A,0x00,0x00,0x00,0x08,0x00,0x40,0x04,0x00,0x00,0x00,}; -const uint8_t *_I_DolphinFirstStart8_56x51[] = {_I_DolphinFirstStart8_56x51_0}; - -const uint8_t _I_DolphinFirstStart7_61x51_0[] = {0x00,0x00,0x00,0xC0,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x30,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0xC0,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x05,0x00,0x00,0xF0,0x01,0x01,0x00,0x80,0x0A,0x00,0x00,0x78,0x02,0x02,0x00,0x80,0x1D,0x00,0x00,0xFC,0x04,0x02,0x00,0x80,0x3E,0x00,0x00,0x9E,0x05,0x02,0x00,0x80,0x77,0x00,0x00,0x9E,0x09,0x04,0x00,0x80,0x57,0x00,0x00,0xFE,0x19,0x04,0x00,0x80,0x5F,0x00,0x00,0xFE,0x29,0x04,0x00,0x80,0x5F,0x00,0x00,0xFE,0x59,0x04,0x00,0x80,0x5F,0x00,0x00,0xFC,0x29,0x04,0x00,0x80,0x5F,0x00,0x00,0xFC,0x54,0x08,0x00,0x80,0x5F,0x00,0x00,0x78,0x2F,0x08,0x00,0x80,0x2E,0x00,0x00,0xF0,0x10,0x08,0x00,0x80,0x1D,0x06,0x08,0x20,0x00,0x08,0x00,0x80,0xA2,0x00,0x10,0x20,0x00,0x08,0x00,0x80,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x80,0x22,0x00,0x00,0x00,0x02,0x08,0x0E,0x80,0x11,0x00,0x00,0x00,0x02,0x08,0x31,0x80,0x12,0x00,0x00,0x00,0x02,0x08,0xC1,0x80,0x09,0x00,0x00,0x00,0x01,0x08,0x01,0x81,0x0A,0x00,0x80,0xC7,0x00,0x08,0x01,0x82,0x09,0x00,0x60,0x38,0x00,0x08,0x02,0x84,0x0A,0x00,0x10,0x00,0x00,0x08,0x02,0x88,0x0D,0x00,0x08,0x00,0x00,0x08,0x02,0x90,0x0A,0x00,0x04,0x00,0x00,0x08,0x04,0x10,0x3D,0x00,0x03,0x00,0x00,0x10,0x04,0x20,0xDB,0xFF,0x80,0x02,0x00,0x10,0x04,0x20,0x15,0x00,0x40,0x01,0x00,0x10,0x08,0x40,0x1B,0x00,0xB0,0x00,0x00,0x10,0x08,0x40,0x35,0x00,0x58,0x00,0x00,0x10,0x08,0x80,0xEB,0x00,0x2E,0x00,0x00,0x10,0x08,0x80,0x55,0xFF,0x17,0x00,0x00,0x10,0x08,0x00,0xAB,0xAA,0x0A,0x00,0x00,0x10,0x10,0x00,0x55,0x55,0x05,0x00,0x00,0x10,0x10,0x00,0xAA,0xAA,0x02,0x00,0x00,0x00,0x10,0x00,0x06,0x54,0x00,0x00,0x00,0x00,0x10,0x00,0x0A,0x28,0x00,0x00,0x00,0x00,0x10,0x00,0x06,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_DolphinFirstStart7_61x51[] = {_I_DolphinFirstStart7_61x51_0}; - -const uint8_t _I_Flipper_young_80x60_0[] = {0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x83,0x21,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x06,0xC3,0xD8,0x01,0x00,0x00,0x00,0x00,0xE0,0x3B,0x0C,0x86,0x31,0x07,0x00,0x00,0x00,0x00,0xC0,0x21,0x10,0x0C,0x21,0x0C,0x00,0x00,0x00,0x00,0x00,0xE7,0x60,0x18,0x62,0x14,0x00,0x00,0x00,0x00,0x00,0x8C,0xC1,0x10,0x46,0x24,0x00,0x00,0x00,0x00,0x00,0x18,0xC7,0x3F,0xC4,0x4C,0x00,0x00,0x00,0x00,0x00,0x10,0xFE,0xF3,0x87,0xC8,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x9C,0x50,0x01,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0xE0,0xD0,0x02,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x80,0x93,0x02,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x9C,0x04,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x98,0x05,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x20,0x0D,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x40,0x15,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x80,0x15,0x00,0xF0,0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x35,0x00,0x1E,0x38,0x0C,0x00,0x00,0x00,0x00,0x00,0x26,0x00,0x03,0xE0,0x04,0x00,0x00,0x00,0x00,0x00,0x24,0x80,0x01,0x80,0x07,0x00,0x00,0xF0,0xFF,0x01,0x5C,0x80,0x0F,0x00,0x04,0x00,0x00,0x18,0x00,0x03,0x48,0x80,0x1F,0x00,0x08,0x00,0x00,0xCC,0x7F,0x06,0x50,0x00,0x7F,0x00,0x30,0x00,0x00,0x26,0x80,0x0C,0x60,0x00,0xFE,0x01,0x40,0x00,0x00,0x13,0x00,0x09,0x40,0x00,0xFC,0x07,0x80,0x00,0x00,0x89,0x3F,0x12,0x80,0x00,0xF8,0x0F,0x00,0x03,0x80,0xC5,0x7F,0x14,0x00,0x00,0xF0,0x3F,0x00,0x0C,0x80,0xE4,0xFF,0x24,0x00,0x00,0xE0,0x7F,0x00,0x10,0x80,0xE2,0xFF,0x28,0x00,0x00,0xC0,0xFF,0x01,0x60,0x80,0xF2,0xE7,0x29,0x00,0x00,0x80,0xFF,0x03,0x80,0x81,0xF2,0xE7,0x29,0x00,0x00,0x00,0xFF,0x07,0x00,0x8E,0xF2,0xFF,0x29,0x00,0x00,0x00,0xFE,0x0F,0x00,0xB8,0xF2,0xFE,0x29,0x00,0x00,0x00,0xFC,0x1F,0x00,0xE0,0xF2,0xFC,0x29,0x00,0x00,0x00,0xF8,0x3F,0x00,0x00,0xFE,0xF9,0x69,0x01,0x00,0x00,0xF0,0x7F,0x00,0x00,0x82,0xFF,0xA4,0x02,0x00,0x00,0xE0,0xFF,0x00,0x00,0x00,0x7E,0x54,0x05,0x00,0x00,0xC0,0xFF,0x01,0x00,0x00,0x78,0xB2,0x0A,0xE0,0x01,0x80,0xFF,0x03,0x00,0x38,0x40,0x59,0x15,0x70,0xFE,0xFF,0xFF,0x0F,0x00,0xE0,0x80,0xA9,0x0A,0x90,0x00,0xF8,0x80,0x1F,0x00,0x80,0x01,0x57,0x15,0x10,0x03,0x0E,0x00,0x3F,0x00,0x00,0x03,0xAA,0x0A,0x10,0x9C,0x07,0x00,0x7C,0x00,0x00,0x02,0x54,0x15,0x20,0xF0,0x01,0x00,0xF8,0x01,0x06,0x06,0xA8,0x0A,0x20,0x00,0x0F,0x00,0xFC,0x0F,0x03,0x00,0x50,0x15,0x40,0x00,0xF8,0xFF,0xFF,0xFF,0x00,0x00,0xA0,0x0A,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x15,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x0A,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x05,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_Flipper_young_80x60[] = {_I_Flipper_young_80x60_0}; - -const uint8_t _I_BigBurger_24x24_0[] = {0xE0,0xFF,0x07,0x18,0x00,0x18,0x04,0x41,0x20,0x02,0x08,0x42,0x12,0x00,0x48,0x81,0x20,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0xFE,0xFF,0x7F,0xFE,0xFF,0x77,0x31,0x18,0x8C,0x87,0xC3,0xE1,0x7C,0x3C,0x3E,0x04,0x00,0x20,0xFE,0xFF,0x7F,0x01,0x00,0x80,0xFF,0x1F,0xF8,0xAA,0x6A,0x6E,0x56,0xD5,0x55,0xFE,0xFF,0x7F,0x01,0x00,0x80,0x01,0x00,0x80,0x02,0x00,0x40,0xFC,0xFF,0x3F,}; -const uint8_t *_I_BigBurger_24x24[] = {_I_BigBurger_24x24_0}; - -const uint8_t _I_FX_Bang_32x6_0[] = {0x02,0x83,0xC0,0xC0,0x06,0x86,0x61,0x60,0x0C,0x86,0x61,0x30,0x18,0x0C,0x31,0x18,0x30,0x08,0x10,0x0C,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_FX_Bang_32x6[] = {_I_FX_Bang_32x6_0}; +const uint8_t _I_DolphinFirstStart2_59x51_0[] = {0x00,0x00,0x00,0x00,0xFF,0x03,0x00,0x00,0x00,0x00,0xF8,0xFF,0x00,0x1C,0x00,0x00,0x00,0x80,0x57,0x0F,0x00,0x60,0x00,0x00,0x00,0xF8,0xAA,0x01,0x00,0x80,0x00,0x00,0x00,0x56,0x65,0x00,0x00,0x00,0x01,0x00,0x80,0xAB,0x1A,0x00,0x00,0x00,0x02,0x00,0x60,0x55,0x07,0x00,0x00,0x00,0x04,0x00,0xB0,0xAA,0x01,0x00,0x00,0x00,0x08,0x00,0x58,0x55,0x00,0x00,0x00,0x00,0x10,0x00,0xAC,0x2A,0x00,0x00,0x00,0x00,0x20,0x00,0x56,0x15,0x00,0x00,0x00,0x00,0x20,0x00,0xAA,0x0A,0x00,0x00,0x00,0x00,0x40,0x00,0x5C,0x05,0x00,0x00,0x00,0x00,0x40,0x00,0xE0,0x02,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x80,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x60,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0xA0,0x00,0x00,0xA0,0x02,0x00,0x80,0x00,0x50,0x00,0x00,0x40,0x01,0x00,0x80,0x00,0xB0,0x00,0x00,0x80,0x06,0x00,0x40,0x00,0x58,0x00,0x00,0x60,0x07,0x00,0x40,0x00,0xA8,0x01,0x00,0x80,0x06,0x00,0x40,0x00,0x54,0x01,0x00,0x00,0x0F,0x00,0x20,0x00,0xAC,0x01,0x00,0x00,0x1D,0x00,0x30,0x00,0xD4,0x00,0x00,0x00,0xF8,0x00,0x18,0x00,0xAA,0x00,0x10,0x00,0x70,0x00,0x14,0x00,0xD6,0x00,0x10,0x10,0x00,0xA0,0x0A,0x00,0xAA,0x00,0x08,0x10,0x00,0x50,0x05,0x00,0xD6,0x00,0x08,0x20,0x00,0xAC,0x82,0x03,0xAB,0x00,0x08,0x40,0x00,0xE0,0xF1,0x06,0xD5,0x00,0x08,0x00,0x00,0x80,0x5F,0x05,0xAB,0x01,0x10,0x80,0x00,0x80,0xAA,0x02,0x55,0x01,0x20,0x40,0x03,0x80,0x55,0x03,0xAB,0x01,0xC0,0x80,0x06,0x80,0xAA,0x01,0x55,0x03,0x00,0x03,0x05,0x80,0xD5,0x00,0xAB,0x02,0x00,0x8C,0x0A,0x80,0x6A,0x00,0x55,0x05,0x00,0x30,0x0D,0x80,0x35,0x00,0x2B,0x0A,0x00,0xC0,0x1A,0x80,0x1A,0x00,0x15,0x34,0x00,0x80,0x1D,0x40,0x07,0x00,0x2B,0xE8,0x00,0xE0,0x36,0xC0,0x01,0x00,0x15,0x50,0x03,0x5F,0x7F,0x40,0x00,0x00,0x0B,0x80,0xFE,0xAA,0x82,0x20,0x00,0x00,0x15,0x00,0x55,0x55,0x01,0x1F,0x00,0x00,0x0B,0x00,0xA8,0xAA,0x01,0x00,0x00,0x00,0x06,0x00,0x00,0x45,0x01,0x00,0x00,0x00,0x0A,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x80,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_DolphinFirstStart2_59x51[] = {_I_DolphinFirstStart2_59x51_0}; const uint8_t _I_DolphinFirstStart3_57x48_0[] = {0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x04,0x00,0x00,0xF8,0x03,0x01,0x00,0x00,0x08,0x00,0x00,0x04,0xBC,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0xC0,0x00,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x02,0x00,0x38,0x40,0x00,0x00,0x02,0x00,0x04,0x00,0x3E,0x40,0x00,0x00,0xF4,0x03,0x08,0x80,0x07,0x80,0x00,0x00,0x5C,0x0D,0x10,0xE0,0x01,0x80,0x00,0x00,0xA8,0x3A,0x20,0xE0,0x00,0x00,0x01,0x00,0x58,0x55,0x00,0xC0,0x01,0x00,0x01,0x00,0xB0,0xAA,0x00,0x80,0x07,0x00,0x01,0x00,0x60,0x55,0x01,0x00,0x1E,0x00,0x01,0x0E,0xC0,0xAA,0x02,0xE0,0x5C,0x00,0x01,0x11,0x80,0x55,0x05,0x00,0xA9,0x00,0x01,0x21,0x00,0xAB,0x0A,0x00,0x56,0x07,0x01,0x41,0x00,0x56,0x15,0x00,0xEC,0x08,0x01,0x81,0x00,0xBF,0x2A,0x00,0x34,0x08,0x01,0x01,0xF1,0xC0,0x57,0x00,0x0C,0x08,0x01,0x02,0x0A,0x00,0xBE,0x00,0x04,0x08,0x01,0x02,0x06,0x00,0x78,0x83,0x02,0x04,0x01,0x02,0x0C,0x00,0xF0,0x7F,0x01,0x04,0x01,0x02,0xF4,0x01,0xFE,0x81,0x00,0x04,0x01,0x04,0x08,0xFF,0x6B,0x40,0x00,0x02,0x01,0x04,0x88,0x55,0x1D,0x40,0x00,0x02,0x01,0x04,0x50,0xAA,0x06,0x20,0x00,0x02,0x01,0x04,0x30,0xD4,0x01,0x20,0x00,0x01,0x01,0x04,0x10,0x68,0x00,0x10,0x00,0x01,0x01,0x04,0x18,0x18,0x00,0x10,0x00,0x01,0x01,0x08,0x18,0x06,0x80,0x10,0x00,0x01,0x01,0x08,0xE8,0x01,0x60,0x08,0x80,0x00,0x01,0x08,0x08,0x00,0x18,0x08,0x80,0x00,0x00,0x08,0x10,0x00,0x06,0x08,0x80,0x00,0x00,0x08,0x60,0xE0,0x01,0x08,0x80,0x00,0x00,0x08,0x80,0x1F,0x00,0x08,0x80,0x00,0x00,0x08,0x80,0x04,0x00,0x04,0x00,0x01,0x00,0x08,0x80,0x04,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x10,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x10,0x80,0x00,0x00,0x04,0x00,0x02,0x00,0x10,0x80,0x00,0x00,0x04,0x00,0x06,0x00,}; const uint8_t *_I_DolphinFirstStart3_57x48[] = {_I_DolphinFirstStart3_57x48_0}; -const uint8_t _I_PassportBottom_128x17_0[] = {0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0xF9,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x05,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x05,0xFA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x09,0x79,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xD5,0x80,0x55,0xD5,0x00,0xF3,0xCC,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x6A,0x00,0xAB,0x6A,0x00,0x06,0x86,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0xFE,0x3F,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_PassportBottom_128x17[] = {_I_PassportBottom_128x17_0}; +const uint8_t _I_DolphinFirstStart4_67x53_0[] = {0x00,0x00,0x00,0xF0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x40,0x00,0x00,0x00,0x30,0x00,0x02,0x00,0x00,0xC0,0x00,0x00,0x00,0x30,0x00,0x02,0x00,0x00,0x40,0x01,0x00,0x00,0x30,0x00,0x04,0x00,0x00,0xC0,0x00,0x00,0x00,0xB8,0x02,0x04,0x00,0x00,0x40,0x01,0x00,0x00,0x7C,0x05,0x08,0x00,0x00,0xC0,0x00,0x00,0xF0,0xBF,0x02,0x08,0x00,0x00,0x40,0x01,0x00,0xF0,0x5F,0x05,0x08,0x00,0x00,0xC0,0x02,0x00,0xC0,0xE7,0x03,0x10,0x00,0x00,0x80,0x01,0x00,0x00,0x10,0x02,0x10,0x00,0x00,0x80,0x02,0x00,0x00,0x08,0x04,0x10,0x00,0x00,0x80,0x05,0x00,0x00,0x00,0x04,0x20,0x00,0x00,0x80,0x0A,0x08,0x00,0x80,0x00,0x20,0x00,0x00,0x00,0x1F,0x03,0x00,0x80,0x00,0x20,0x00,0x00,0x00,0x6F,0x00,0x00,0x80,0x00,0x40,0x00,0x00,0x00,0x1E,0x00,0x00,0x80,0x00,0x40,0x00,0x00,0x00,0x0E,0x00,0x00,0x40,0x00,0x40,0x00,0x00,0x0F,0x04,0x00,0x00,0x20,0x00,0xC0,0x00,0x80,0x10,0x04,0x00,0x00,0x18,0x00,0x80,0x00,0x40,0x10,0x02,0x00,0x00,0x06,0x00,0xC0,0x00,0x20,0x10,0x02,0x00,0x80,0x01,0x00,0x80,0x01,0x10,0x08,0x01,0x00,0x60,0x00,0x00,0x00,0x01,0x08,0x08,0x01,0x00,0x10,0x00,0x00,0x80,0x01,0x08,0x88,0x00,0x00,0x08,0x00,0x00,0x00,0x03,0x04,0x88,0x00,0x00,0x04,0x00,0x00,0x80,0x02,0x04,0x88,0x00,0x00,0x02,0x00,0xFC,0x03,0x03,0x02,0x88,0x00,0x00,0x81,0x80,0x03,0x9C,0x06,0x02,0x88,0x00,0xC0,0x60,0x70,0x00,0x60,0x05,0x02,0x88,0x00,0x30,0x30,0x0C,0x00,0x80,0x02,0x01,0x88,0x00,0x0C,0x1C,0x03,0x00,0x00,0x05,0x01,0x88,0x81,0x03,0xAB,0x00,0x00,0x00,0x02,0x01,0x10,0x7F,0xE0,0x75,0x00,0x00,0x00,0x04,0x01,0x10,0x02,0xBC,0x0A,0x00,0x00,0x00,0x00,0x01,0x20,0xFC,0x57,0x0D,0x00,0x00,0x00,0x00,0x01,0x20,0x80,0xAA,0x1A,0x00,0x00,0x00,0x00,0x01,0x40,0x80,0x55,0x75,0xE0,0x3F,0x00,0x00,0x01,0x80,0x80,0xAA,0xAA,0xBF,0xEA,0x00,0x00,0x01,0x00,0x81,0x55,0x55,0x55,0x55,0x01,0x00,}; +const uint8_t *_I_DolphinFirstStart4_67x53[] = {_I_DolphinFirstStart4_67x53_0}; + +const uint8_t _I_DolphinFirstStart5_45x53_0[] = {0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x20,0x10,0x00,0x00,0xFF,0x3F,0x20,0x08,0x00,0xC0,0x00,0xC0,0x01,0x04,0x00,0x30,0x00,0x00,0x06,0x02,0x06,0x0C,0x00,0x00,0x08,0x80,0x01,0x02,0x00,0x00,0x10,0x60,0x00,0x01,0x07,0x00,0x20,0x18,0x00,0x80,0x08,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x80,0x00,0x00,0x20,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xC0,0x01,0x07,0x00,0x00,0x00,0x30,0x00,0x08,0x00,0x60,0x00,0x0C,0x00,0x10,0x00,0x70,0x00,0x03,0x00,0x10,0x00,0x7E,0xC0,0x00,0x00,0x10,0xF8,0x3F,0x20,0x00,0xFC,0x13,0xF8,0x1F,0x10,0x00,0xAF,0x16,0xF0,0x03,0x08,0xC0,0x55,0x15,0x00,0x00,0x04,0xE0,0xAA,0x0A,0xD4,0x07,0x00,0x58,0x55,0x0B,0x6A,0x00,0x00,0xAC,0xAA,0x05,0x15,0x00,0x00,0x56,0xD5,0x02,0x0A,0x00,0x00,0xFF,0xFF,0x01,0x0D,0x00,0x80,0x81,0x03,0x02,0x06,0x00,0xC0,0x70,0x00,0x04,0x04,0x01,0x70,0x0F,0x00,0x04,0x04,0x02,0xFF,0x00,0x00,0x04,0x00,0xFC,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x01,0x00,0x00,0x00,0x0C,0x00,0x02,0x00,0x00,0x00,0x0B,0x00,0x01,0x00,0x00,0xC0,0x08,0x00,0x02,0x00,0x00,0x00,0x10,0x00,0x05,0x00,0x00,0x00,0x10,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x15,0xFE,0x1F,0x00,0x20,0x00,0xAA,0x01,0xE0,0x00,0x40,0x00,0x75,0x00,0x00,0x03,0x40,0x00,0x1A,0x00,0x00,0x04,0x80,0x00,0x05,0x00,0x00,0x08,0x80,0x00,0x02,0x00,0x00,0x08,0x00,0x01,0x01,0x00,0x00,0x04,0x00,0x01,0x00,0x00,0xE0,0x0B,0x00,0x02,0x00,0x00,0x5C,0x05,0x00,0x04,0x00,0x00,0xAB,0x02,0x00,0x08,}; +const uint8_t *_I_DolphinFirstStart5_45x53[] = {_I_DolphinFirstStart5_45x53_0}; + +const uint8_t _I_DolphinFirstStart6_58x54_0[] = {0x00,0x00,0xFC,0x3F,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0xC0,0x03,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x40,0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x20,0x00,0x00,0x06,0x00,0x08,0x00,0x00,0x20,0x00,0x00,0x18,0x00,0x08,0x00,0x00,0x20,0x00,0x00,0x60,0x00,0x14,0x00,0x00,0x10,0x00,0xFE,0x3F,0x00,0xFC,0x0F,0x00,0x10,0x80,0xFF,0xFF,0x01,0xFF,0x1F,0x00,0x10,0xC0,0x81,0xFF,0x83,0x81,0x3F,0x00,0x08,0xC0,0xC1,0xFF,0xFF,0xC1,0x3F,0x00,0x08,0xC0,0xAB,0xFF,0xFF,0xA9,0x3F,0x00,0x08,0xC0,0xD5,0xFF,0xAB,0xD7,0x3F,0x00,0x04,0xC0,0xFF,0xFF,0x57,0xFF,0x1F,0x00,0x04,0xD0,0xFF,0xFF,0xAB,0xFF,0x1F,0x00,0x04,0xA0,0xFF,0xFF,0x41,0x0F,0x60,0x00,0x04,0x50,0xFF,0xFF,0xE0,0x01,0x80,0x00,0x04,0xA8,0xFF,0x57,0x1C,0x00,0x00,0x01,0x02,0x50,0xC0,0x8A,0x03,0x00,0x00,0x02,0x02,0x20,0x80,0x00,0x00,0x00,0x00,0x02,0x02,0x10,0x00,0x00,0x00,0x00,0x3E,0x02,0x02,0x10,0x00,0x00,0x00,0xC0,0xC1,0x02,0x02,0x00,0x00,0x00,0x00,0x30,0x00,0x03,0x02,0x00,0x08,0x00,0x00,0x0C,0x00,0x02,0x02,0x00,0x08,0x00,0x00,0x03,0x00,0x01,0x02,0x00,0x10,0x00,0xF0,0x00,0x00,0x01,0x02,0x00,0xE0,0x00,0x0F,0x00,0x80,0x00,0x02,0x00,0x00,0xFF,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0x00,0x0C,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x0C,0x00,0x00,0x02,0x22,0x00,0x00,0x00,0x03,0x00,0x00,0x05,0x42,0x00,0x00,0xC0,0x00,0x00,0x80,0x0A,0x41,0x00,0x00,0x38,0x00,0x00,0x00,0x15,0x81,0x07,0x00,0x30,0x00,0x00,0x80,0xAA,0x00,0x08,0x00,0x60,0x00,0x00,0x00,0x75,0x00,0x10,0x00,0xA0,0x00,0x00,0x00,0x1A,0x00,0x20,0x00,0xA0,0x00,0x00,0x00,0x07,0x00,0x20,0x00,0x20,0x01,0x00,0xC0,0x00,0x00,0x40,0x00,0x20,0x02,0x00,0x30,0x00,0x00,0x40,0x00,0x40,0x04,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x04,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x08,0x00,0x00,0x00,0x00,0xA0,0x00,0x40,0x08,0x00,0x00,0x00,0x00,0x50,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xAC,0x00,0x80,0x10,0x00,0x00,0x00,0xE0,0x53,0x01,0x80,0x20,0x00,}; +const uint8_t *_I_DolphinFirstStart6_58x54[] = {_I_DolphinFirstStart6_58x54_0}; + +const uint8_t _I_DolphinFirstStart7_61x51_0[] = {0x00,0x00,0x00,0xC0,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x30,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0xC0,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x05,0x00,0x00,0xF0,0x01,0x01,0x00,0x80,0x0A,0x00,0x00,0x78,0x02,0x02,0x00,0x80,0x1D,0x00,0x00,0xFC,0x04,0x02,0x00,0x80,0x3E,0x00,0x00,0x9E,0x05,0x02,0x00,0x80,0x77,0x00,0x00,0x9E,0x09,0x04,0x00,0x80,0x57,0x00,0x00,0xFE,0x19,0x04,0x00,0x80,0x5F,0x00,0x00,0xFE,0x29,0x04,0x00,0x80,0x5F,0x00,0x00,0xFE,0x59,0x04,0x00,0x80,0x5F,0x00,0x00,0xFC,0x29,0x04,0x00,0x80,0x5F,0x00,0x00,0xFC,0x54,0x08,0x00,0x80,0x5F,0x00,0x00,0x78,0x2F,0x08,0x00,0x80,0x2E,0x00,0x00,0xF0,0x10,0x08,0x00,0x80,0x1D,0x06,0x08,0x20,0x00,0x08,0x00,0x80,0xA2,0x00,0x10,0x20,0x00,0x08,0x00,0x80,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x80,0x22,0x00,0x00,0x00,0x02,0x08,0x0E,0x80,0x11,0x00,0x00,0x00,0x02,0x08,0x31,0x80,0x12,0x00,0x00,0x00,0x02,0x08,0xC1,0x80,0x09,0x00,0x00,0x00,0x01,0x08,0x01,0x81,0x0A,0x00,0x80,0xC7,0x00,0x08,0x01,0x82,0x09,0x00,0x60,0x38,0x00,0x08,0x02,0x84,0x0A,0x00,0x10,0x00,0x00,0x08,0x02,0x88,0x0D,0x00,0x08,0x00,0x00,0x08,0x02,0x90,0x0A,0x00,0x04,0x00,0x00,0x08,0x04,0x10,0x3D,0x00,0x03,0x00,0x00,0x10,0x04,0x20,0xDB,0xFF,0x80,0x02,0x00,0x10,0x04,0x20,0x15,0x00,0x40,0x01,0x00,0x10,0x08,0x40,0x1B,0x00,0xB0,0x00,0x00,0x10,0x08,0x40,0x35,0x00,0x58,0x00,0x00,0x10,0x08,0x80,0xEB,0x00,0x2E,0x00,0x00,0x10,0x08,0x80,0x55,0xFF,0x17,0x00,0x00,0x10,0x08,0x00,0xAB,0xAA,0x0A,0x00,0x00,0x10,0x10,0x00,0x55,0x55,0x05,0x00,0x00,0x10,0x10,0x00,0xAA,0xAA,0x02,0x00,0x00,0x00,0x10,0x00,0x06,0x54,0x00,0x00,0x00,0x00,0x10,0x00,0x0A,0x28,0x00,0x00,0x00,0x00,0x10,0x00,0x06,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_DolphinFirstStart7_61x51[] = {_I_DolphinFirstStart7_61x51_0}; + +const uint8_t _I_DolphinFirstStart8_56x51_0[] = {0x00,0x00,0x00,0xE0,0xFF,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x06,0x00,0x00,0x00,0x00,0x0E,0x00,0x18,0x00,0x00,0x00,0x00,0x01,0x00,0x60,0x00,0x00,0x00,0xC0,0x00,0x00,0x80,0x01,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x00,0x00,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x00,0x01,0x00,0x80,0x07,0x40,0x00,0x00,0x01,0x00,0x60,0x1C,0x40,0x00,0x80,0x00,0x00,0x10,0x3F,0x80,0x00,0x80,0x00,0x00,0x88,0x7F,0x80,0xC0,0x80,0x00,0x00,0xC8,0x71,0x80,0x20,0x81,0x00,0x00,0xC4,0xF1,0x00,0x20,0x81,0x00,0x00,0xE4,0xF3,0x02,0x20,0x82,0x01,0x00,0xE4,0xFF,0x05,0x20,0x82,0x00,0x00,0xE4,0xFF,0x0A,0x20,0x84,0x01,0x00,0xC8,0x7F,0x05,0x20,0x84,0x02,0x00,0xC8,0xFF,0x02,0x20,0x88,0x05,0x00,0x90,0x03,0x05,0x10,0x88,0x02,0x00,0x60,0x01,0x02,0x10,0x90,0xC5,0x00,0x80,0x00,0x04,0x08,0x90,0x1F,0x00,0x80,0x00,0x00,0x04,0xE0,0x01,0x00,0x00,0x00,0x00,0x02,0x30,0x00,0x00,0x00,0x00,0x00,0x01,0x08,0x00,0x00,0x00,0x10,0x00,0x01,0x06,0x00,0x00,0x00,0x10,0x00,0x01,0x01,0x00,0x00,0x00,0x10,0x00,0x81,0x00,0x00,0x00,0x00,0x08,0x00,0x41,0x00,0x00,0x00,0x00,0x04,0x00,0x41,0x00,0x00,0x00,0x00,0x03,0x00,0x42,0xFE,0x00,0x00,0xE0,0x00,0x00,0x42,0x01,0x1F,0x80,0x1F,0x00,0x00,0xC2,0x00,0xE0,0x7F,0x00,0x00,0x00,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x84,0x1E,0x00,0x00,0x00,0x00,0x00,0x04,0xF5,0x1F,0xC0,0x0F,0x00,0x00,0x04,0xAA,0xEA,0xBF,0x02,0x00,0x00,0x04,0x54,0x15,0x55,0x01,0x00,0x00,0x04,0xA8,0x1A,0xAB,0x02,0x00,0x00,0x08,0x50,0x35,0x55,0x01,0x00,0x00,0x08,0x80,0x2A,0xAA,0x00,0x00,0x00,0x08,0x00,0x54,0x56,0x00,0x00,0x00,0x08,0x00,0x60,0x2A,0x00,0x00,0x00,0x08,0x00,0x40,0x04,0x00,0x00,0x00,}; +const uint8_t *_I_DolphinFirstStart8_56x51[] = {_I_DolphinFirstStart8_56x51_0}; + +const uint8_t _I_DolphinOkay_41x43_0[] = {0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x1E,0xE0,0x00,0x00,0x00,0x80,0x01,0x00,0x07,0x00,0x00,0x60,0x00,0x00,0x18,0x00,0x00,0x10,0x00,0x00,0x20,0x00,0x00,0x08,0x00,0x00,0x40,0x00,0x00,0x04,0x00,0x00,0x80,0x00,0x00,0x04,0x00,0x00,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x3E,0x00,0x00,0x80,0x00,0x00,0x7D,0x00,0x00,0x80,0x00,0x80,0xFE,0x00,0x00,0x80,0x00,0x40,0xE2,0x01,0x00,0x80,0x00,0x40,0xF2,0x01,0x00,0x80,0x00,0x40,0xFE,0x01,0x00,0x80,0x00,0x40,0xFE,0x05,0x00,0x80,0x00,0x40,0x7C,0x0B,0x00,0x80,0x00,0x80,0x80,0x15,0x00,0x80,0x00,0x00,0xFD,0x0A,0x00,0x00,0x01,0x00,0x02,0x15,0x00,0x00,0x01,0x00,0x01,0x0A,0x00,0x00,0xE1,0x07,0x00,0x06,0x00,0x80,0x1F,0x00,0x00,0x02,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x20,0x00,0x00,0x08,0x00,0x00,0x20,0x00,0x00,0x04,0x00,0x00,0x10,0x00,0x00,0x02,0x00,0x00,0x08,0x00,0x00,0x01,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x80,0x03,0x00,0x00,0x01,0x00,0x70,0x00,0x00,0x00,0xF9,0x03,0x0F,0x00,0x00,0x00,0x06,0xFC,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xC0,0x01,0x00,0x08,0x00,0x00,0x78,0x00,0x00,0x30,0x00,0xF8,0xAF,0x00,0x00,0xC0,0xFF,0xFF,0x57,0x00,0x00,0x00,0xF8,0xBF,0x2A,0x00,0x00,0x00,0xF8,0x57,0x15,0x00,0x00,0x00,0xF8,0xAB,0x02,0x00,0x00,}; +const uint8_t *_I_DolphinOkay_41x43[] = {_I_DolphinOkay_41x43_0}; + +const uint8_t _I_Flipper_young_80x60_0[] = {0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x83,0x21,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x06,0xC3,0xD8,0x01,0x00,0x00,0x00,0x00,0xE0,0x3B,0x0C,0x86,0x31,0x07,0x00,0x00,0x00,0x00,0xC0,0x21,0x10,0x0C,0x21,0x0C,0x00,0x00,0x00,0x00,0x00,0xE7,0x60,0x18,0x62,0x14,0x00,0x00,0x00,0x00,0x00,0x8C,0xC1,0x10,0x46,0x24,0x00,0x00,0x00,0x00,0x00,0x18,0xC7,0x3F,0xC4,0x4C,0x00,0x00,0x00,0x00,0x00,0x10,0xFE,0xF3,0x87,0xC8,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x9C,0x50,0x01,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0xE0,0xD0,0x02,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x80,0x93,0x02,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x9C,0x04,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x98,0x05,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x20,0x0D,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x40,0x15,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x80,0x15,0x00,0xF0,0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x35,0x00,0x1E,0x38,0x0C,0x00,0x00,0x00,0x00,0x00,0x26,0x00,0x03,0xE0,0x04,0x00,0x00,0x00,0x00,0x00,0x24,0x80,0x01,0x80,0x07,0x00,0x00,0xF0,0xFF,0x01,0x5C,0x80,0x0F,0x00,0x04,0x00,0x00,0x18,0x00,0x03,0x48,0x80,0x1F,0x00,0x08,0x00,0x00,0xCC,0x7F,0x06,0x50,0x00,0x7F,0x00,0x30,0x00,0x00,0x26,0x80,0x0C,0x60,0x00,0xFE,0x01,0x40,0x00,0x00,0x13,0x00,0x09,0x40,0x00,0xFC,0x07,0x80,0x00,0x00,0x89,0x3F,0x12,0x80,0x00,0xF8,0x0F,0x00,0x03,0x80,0xC5,0x7F,0x14,0x00,0x00,0xF0,0x3F,0x00,0x0C,0x80,0xE4,0xFF,0x24,0x00,0x00,0xE0,0x7F,0x00,0x10,0x80,0xE2,0xFF,0x28,0x00,0x00,0xC0,0xFF,0x01,0x60,0x80,0xF2,0xE7,0x29,0x00,0x00,0x80,0xFF,0x03,0x80,0x81,0xF2,0xE7,0x29,0x00,0x00,0x00,0xFF,0x07,0x00,0x8E,0xF2,0xFF,0x29,0x00,0x00,0x00,0xFE,0x0F,0x00,0xB8,0xF2,0xFE,0x29,0x00,0x00,0x00,0xFC,0x1F,0x00,0xE0,0xF2,0xFC,0x29,0x00,0x00,0x00,0xF8,0x3F,0x00,0x00,0xFE,0xF9,0x69,0x01,0x00,0x00,0xF0,0x7F,0x00,0x00,0x82,0xFF,0xA4,0x02,0x00,0x00,0xE0,0xFF,0x00,0x00,0x00,0x7E,0x54,0x05,0x00,0x00,0xC0,0xFF,0x01,0x00,0x00,0x78,0xB2,0x0A,0xE0,0x01,0x80,0xFF,0x03,0x00,0x38,0x40,0x59,0x15,0x70,0xFE,0xFF,0xFF,0x0F,0x00,0xE0,0x80,0xA9,0x0A,0x90,0x00,0xF8,0x80,0x1F,0x00,0x80,0x01,0x57,0x15,0x10,0x03,0x0E,0x00,0x3F,0x00,0x00,0x03,0xAA,0x0A,0x10,0x9C,0x07,0x00,0x7C,0x00,0x00,0x02,0x54,0x15,0x20,0xF0,0x01,0x00,0xF8,0x01,0x06,0x06,0xA8,0x0A,0x20,0x00,0x0F,0x00,0xFC,0x0F,0x03,0x00,0x50,0x15,0x40,0x00,0xF8,0xFF,0xFF,0xFF,0x00,0x00,0xA0,0x0A,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x15,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x0A,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x05,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_Flipper_young_80x60[] = {_I_Flipper_young_80x60_0}; + +const uint8_t _I_FX_Bang_32x6_0[] = {0x02,0x83,0xC0,0xC0,0x06,0x86,0x61,0x60,0x0C,0x86,0x61,0x30,0x18,0x0C,0x31,0x18,0x30,0x08,0x10,0x0C,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_FX_Bang_32x6[] = {_I_FX_Bang_32x6_0}; + +const uint8_t _I_FX_SittingB_40x27_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0xFC,0x0F,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x00,0xF8,0x0F,0x00,0x00,0xE0,0xFF,0x07,0x00,0x00,0xFF,0xFF,0x03,0x00,0xE0,0xFF,0xFF,0x03,0x00,0xF8,0xFF,0xFF,0x07,0x00,0xFC,0xFF,0xFF,0x07,0x00,0xFE,0xFF,0x7F,0x07,0xFC,0x7F,0x00,0x00,0x06,0xF8,0x07,0x00,0x00,0x04,0xE0,0x03,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,}; +const uint8_t *_I_FX_SittingB_40x27[] = {_I_FX_SittingB_40x27_0}; + +const uint8_t _I_DoorLeft_70x55_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x40,0x03,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x04,0x40,0x03,0x00,0x00,0x00,0x00,0x06,0x00,0x04,0x40,0x03,0x00,0x00,0x00,0x00,0x0C,0x00,0x04,0x40,0x03,0x00,0x00,0x00,0x00,0xF8,0x00,0x04,0x00,0x03,0x00,0x00,0x00,0x00,0x30,0x01,0x04,0x40,0x03,0x00,0x00,0x00,0x00,0x18,0x02,0x04,0x40,0x03,0xFF,0xFF,0xFF,0x1F,0x18,0x02,0x04,0x40,0x03,0x00,0x00,0x00,0x30,0x30,0x41,0x06,0x00,0x03,0x00,0x00,0x00,0x60,0xE0,0x20,0x03,0x00,0x07,0x00,0x90,0x24,0xC1,0x00,0x90,0x01,0x00,0x0E,0x00,0x20,0x49,0x82,0x01,0xC0,0x00,0x00,0x1C,0x00,0x40,0x92,0x04,0x03,0x60,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x06,0x3F,0x00,0x00,0x31,0xFF,0x00,0x00,0x00,0x8C,0x01,0x00,0x00,0x32,0x80,0x01,0x00,0x00,0xC8,0x00,0x00,0x00,0x34,0x00,0x03,0xFC,0x01,0x6E,0x00,0x00,0x00,0x34,0x0F,0x06,0x04,0x81,0x39,0x00,0x00,0x00,0x34,0x10,0x0C,0xF8,0x41,0x08,0x00,0x00,0x00,0x34,0xEF,0x08,0x00,0x20,0x08,0x00,0x00,0x00,0x34,0xD0,0x08,0x00,0x20,0x08,0x00,0x00,0x00,0x34,0xB0,0x08,0x00,0x10,0x08,0x00,0x00,0x00,0x34,0x73,0x0C,0xFC,0x11,0x08,0x00,0x00,0x00,0x34,0x06,0x06,0x04,0x11,0x08,0x00,0x00,0x00,0x32,0x0C,0x03,0xF8,0x11,0x08,0x00,0x00,0x00,0x11,0x98,0x01,0x00,0x10,0x08,0x00,0x00,0x00,0x08,0xF0,0x00,0x00,0x20,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x20,0x08,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x40,0x08,0x00,0x00,0x00,0x03,0x33,0x03,0x00,0x80,0x09,0x00,0x00,0x00,0x03,0x66,0x06,0x00,0x00,0x0E,0x00,0x00,0x00,0x03,0xCC,0x0C,0x00,0x00,0x08,0x00,0x00,0x00,0x03,0x98,0x19,0x00,0x00,0x0C,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x03,0x00,0x40,0x92,0x04,0x03,0x00,0x00,0x00,0x03,0x00,0x20,0x49,0x82,0x01,0x00,0x00,0x00,0x03,0x00,0x90,0x24,0xC1,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x07,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x0E,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x31,0xFF,0xFF,0xFF,0x30,0x33,0x00,0x00,0x00,0x33,0x00,0x00,0x80,0x61,0x66,0x00,0x00,0x40,0x32,0x00,0x00,0x00,0xC3,0xCC,0x00,0x00,0xC0,0x30,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x80,0x31,0x00,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x30,}; +const uint8_t *_I_DoorLeft_70x55[] = {_I_DoorLeft_70x55_0}; const uint8_t _I_DoorLeft_8x56_0[] = {0x0C,0x0C,0x0C,0x0C,0x0D,0x0D,0x0D,0x0D,0x0C,0x0D,0x0D,0x0D,0x0C,0x1C,0x38,0x70,0xE0,0xC4,0xC8,0xD0,0xD0,0xD0,0xD0,0xD0,0xD0,0xD0,0xD0,0xC8,0x44,0x20,0x10,0x08,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1C,0x38,0x70,0xE1,0xC3,0xC6,0xCC,0xC9,0xC3,0xC6,0xCC,0xC8,0xC0,0xC0,}; const uint8_t *_I_DoorLeft_8x56[] = {_I_DoorLeft_8x56_0}; @@ -152,92 +152,92 @@ const uint8_t *_I_DoorLeft_8x56[] = {_I_DoorLeft_8x56_0}; const uint8_t _I_DoorLocked_10x56_0[] = {0x0C,0x00,0x2D,0x00,0x6D,0x00,0xCD,0x00,0x8D,0x01,0x2C,0x01,0x6D,0x00,0xCD,0x00,0x8D,0x01,0x0C,0x01,0x1C,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0xC4,0x00,0xC8,0x00,0xD0,0x00,0xD0,0x00,0xD0,0x00,0xD0,0x00,0xD0,0x00,0xD0,0x00,0xD0,0x00,0xD0,0x00,0xC8,0x00,0x44,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x2C,0x00,0x2C,0x00,0x0C,0x00,0x2C,0x00,0x2C,0x00,0x2C,0x00,0x2C,0x00,0x2C,0x00,0x2C,0x00,0x0C,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0xE1,0x00,0xC3,0x00,0xC6,0x02,0xCC,0x00,0xC9,0x02,0xC3,0x02,0xC6,0x02,0xCC,0x00,0xC8,0x02,0xC0,0x02,0xC0,0x02,0xC0,0x02,0xC0,0x00,0xC0,0x00,}; const uint8_t *_I_DoorLocked_10x56[] = {_I_DoorLocked_10x56_0}; -const uint8_t _I_DoorRight_8x56_0[] = {0x03,0x03,0x03,0x03,0x13,0x33,0x63,0xC3,0x93,0x33,0x63,0xC3,0x86,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x06,0x16,0x16,0x06,0x16,0x16,0x16,0x16,0x16,0x16,0x06,0x0C,0x18,0x30,0x30,0xB0,0x30,0xB0,0xB0,0xB0,0x30,0xB0,0xB0,0xB0,}; -const uint8_t *_I_DoorRight_8x56[] = {_I_DoorRight_8x56_0}; - -const uint8_t _I_DoorLeft_70x55_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x40,0x03,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x04,0x40,0x03,0x00,0x00,0x00,0x00,0x06,0x00,0x04,0x40,0x03,0x00,0x00,0x00,0x00,0x0C,0x00,0x04,0x40,0x03,0x00,0x00,0x00,0x00,0xF8,0x00,0x04,0x00,0x03,0x00,0x00,0x00,0x00,0x30,0x01,0x04,0x40,0x03,0x00,0x00,0x00,0x00,0x18,0x02,0x04,0x40,0x03,0xFF,0xFF,0xFF,0x1F,0x18,0x02,0x04,0x40,0x03,0x00,0x00,0x00,0x30,0x30,0x41,0x06,0x00,0x03,0x00,0x00,0x00,0x60,0xE0,0x20,0x03,0x00,0x07,0x00,0x90,0x24,0xC1,0x00,0x90,0x01,0x00,0x0E,0x00,0x20,0x49,0x82,0x01,0xC0,0x00,0x00,0x1C,0x00,0x40,0x92,0x04,0x03,0x60,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x06,0x3F,0x00,0x00,0x31,0xFF,0x00,0x00,0x00,0x8C,0x01,0x00,0x00,0x32,0x80,0x01,0x00,0x00,0xC8,0x00,0x00,0x00,0x34,0x00,0x03,0xFC,0x01,0x6E,0x00,0x00,0x00,0x34,0x0F,0x06,0x04,0x81,0x39,0x00,0x00,0x00,0x34,0x10,0x0C,0xF8,0x41,0x08,0x00,0x00,0x00,0x34,0xEF,0x08,0x00,0x20,0x08,0x00,0x00,0x00,0x34,0xD0,0x08,0x00,0x20,0x08,0x00,0x00,0x00,0x34,0xB0,0x08,0x00,0x10,0x08,0x00,0x00,0x00,0x34,0x73,0x0C,0xFC,0x11,0x08,0x00,0x00,0x00,0x34,0x06,0x06,0x04,0x11,0x08,0x00,0x00,0x00,0x32,0x0C,0x03,0xF8,0x11,0x08,0x00,0x00,0x00,0x11,0x98,0x01,0x00,0x10,0x08,0x00,0x00,0x00,0x08,0xF0,0x00,0x00,0x20,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x20,0x08,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x40,0x08,0x00,0x00,0x00,0x03,0x33,0x03,0x00,0x80,0x09,0x00,0x00,0x00,0x03,0x66,0x06,0x00,0x00,0x0E,0x00,0x00,0x00,0x03,0xCC,0x0C,0x00,0x00,0x08,0x00,0x00,0x00,0x03,0x98,0x19,0x00,0x00,0x0C,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x03,0x00,0x40,0x92,0x04,0x03,0x00,0x00,0x00,0x03,0x00,0x20,0x49,0x82,0x01,0x00,0x00,0x00,0x03,0x00,0x90,0x24,0xC1,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x07,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x0E,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x31,0xFF,0xFF,0xFF,0x30,0x33,0x00,0x00,0x00,0x33,0x00,0x00,0x80,0x61,0x66,0x00,0x00,0x40,0x32,0x00,0x00,0x00,0xC3,0xCC,0x00,0x00,0xC0,0x30,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x80,0x31,0x00,0x00,0x00,0xFC,0xFF,0xFF,0x01,0x00,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x30,}; -const uint8_t *_I_DoorLeft_70x55[] = {_I_DoorLeft_70x55_0}; - -const uint8_t _I_PassportLeft_6x47_0[] = {0x3C,0x02,0x19,0x25,0x25,0x19,0x01,0x01,0x05,0x09,0x11,0x25,0x09,0x11,0x25,0x09,0x11,0x25,0x09,0x11,0x25,0x09,0x11,0x25,0x09,0x11,0x21,0x01,0x02,0x04,0x0C,0x1C,0x3C,0x3C,0x34,0x2C,0x34,0x2C,0x34,0x2C,0x34,0x2C,0x34,0x2C,0x34,0x2C,0x34,}; -const uint8_t *_I_PassportLeft_6x47[] = {_I_PassportLeft_6x47_0}; - const uint8_t _I_DoorRight_70x55_0[] = {0x03,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x01,0x00,0x02,0x01,0x08,0x00,0x00,0x13,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0xD6,0x1C,0x00,0x00,0x00,0x5E,0x00,0x63,0x00,0x00,0x30,0x00,0x00,0x00,0x03,0x00,0xC3,0x00,0x00,0x60,0x00,0x00,0x80,0x01,0x00,0x93,0x00,0x00,0x40,0x00,0x00,0xC0,0x00,0x00,0x33,0x00,0x00,0x00,0x01,0x00,0x60,0x00,0x00,0x63,0x00,0x00,0x00,0x03,0x00,0x30,0x00,0x00,0xC3,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0x3F,0x86,0x00,0x00,0x00,0x0C,0x00,0x00,0x30,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0xF8,0x00,0x18,0x00,0x00,0x00,0x83,0x24,0x09,0xFC,0x00,0x30,0x00,0x00,0x80,0x41,0x92,0x04,0x06,0x00,0x30,0x00,0x00,0xC0,0x20,0x49,0x02,0x03,0x00,0x30,0x00,0x00,0x60,0x00,0x00,0x80,0x01,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x80,0xFF,0x00,0x30,0x00,0x00,0x18,0x00,0x00,0x80,0x00,0x00,0x30,0x00,0x00,0x78,0x00,0x00,0x80,0xAF,0x00,0x30,0x00,0x00,0xF8,0x01,0x00,0x80,0x00,0x00,0x30,0x00,0x00,0x98,0x03,0x00,0x80,0xB6,0x00,0x30,0x00,0x00,0x18,0x06,0x00,0x80,0x00,0x00,0x30,0x00,0x00,0x18,0x04,0xE0,0x80,0xFF,0x00,0x30,0x00,0x00,0x18,0x0C,0x40,0x00,0x00,0x00,0x30,0x00,0x00,0x18,0x08,0x08,0x02,0x00,0x00,0x30,0x00,0x00,0x18,0x08,0x18,0x03,0x00,0x00,0x30,0x00,0x00,0x18,0x08,0x08,0x02,0x00,0x00,0x30,0x00,0x00,0x18,0x08,0x40,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x04,0xE0,0x00,0x00,0x00,0x0C,0x00,0x00,0x18,0x04,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x18,0x02,0x00,0xC0,0x1F,0x00,0x16,0x00,0x00,0x98,0x01,0x00,0x40,0x10,0x00,0x16,0x00,0x00,0x78,0x00,0x00,0x80,0x1F,0x00,0x06,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x16,0x00,0x00,0xE0,0x20,0x49,0xC2,0x1F,0x00,0x16,0x00,0x00,0xC0,0x41,0x92,0x44,0x10,0x00,0x16,0x00,0x00,0x80,0x83,0x24,0x89,0x1F,0x00,0x16,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x18,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0x3F,0x30,0x00,0x00,0x00,0x06,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x00,0x03,0x00,0x20,0x00,0x00,0xB0,0x00,0x00,0x80,0x01,0x00,0x40,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x00,0x01,0x00,0xB0,0x00,0x38,0x57,0x00,0x00,0x00,0xFF,0x00,0xB0,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0xB0,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xB0,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xB0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; const uint8_t *_I_DoorRight_70x55[] = {_I_DoorRight_70x55_0}; +const uint8_t _I_DoorRight_8x56_0[] = {0x03,0x03,0x03,0x03,0x13,0x33,0x63,0xC3,0x93,0x33,0x63,0xC3,0x86,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x06,0x16,0x16,0x06,0x16,0x16,0x16,0x16,0x16,0x16,0x06,0x0C,0x18,0x30,0x30,0xB0,0x30,0xB0,0xB0,0xB0,0x30,0xB0,0xB0,0xB0,}; +const uint8_t *_I_DoorRight_8x56[] = {_I_DoorRight_8x56_0}; + const uint8_t _I_LockPopup_100x49_0[] = {0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x00,0x00,0x00,0x20,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x00,0xFE,0x07,0x20,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x80,0x01,0x18,0x40,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x60,0x00,0x60,0x40,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x10,0x00,0x80,0x80,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x08,0x00,0x00,0x81,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x04,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x02,0x00,0x00,0x02,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x01,0x1E,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x83,0x00,0x21,0x00,0x08,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x83,0x80,0x5E,0x00,0xC8,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x83,0x40,0xB7,0x00,0x38,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x43,0x40,0xA7,0x00,0x0C,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x43,0x40,0xBF,0x00,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x43,0x40,0xBF,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x43,0xA0,0x5E,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x23,0x50,0x3D,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x23,0xA0,0x42,0x00,0xF0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x23,0x50,0x01,0x00,0xFC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x23,0x20,0x01,0x00,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x23,0x00,0x00,0xC0,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x23,0x00,0x40,0x30,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x23,0x00,0x83,0xFF,0xFF,0x9F,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x23,0x80,0x04,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x33,0x80,0x04,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x33,0x80,0x04,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x3B,0x80,0x04,0x00,0x00,0x1C,0x20,0x00,0x80,0x00,0x00,0x02,0x0C,0x3B,0x78,0x04,0x00,0xC0,0x03,0x30,0x00,0xC0,0x00,0x00,0x03,0x0C,0x3F,0x84,0x04,0xA0,0x3E,0x00,0xF8,0x03,0xE0,0x0F,0x80,0x3F,0x0C,0x3F,0x02,0x0F,0x40,0x1F,0x00,0x30,0x04,0xC1,0x10,0x04,0x43,0x0C,0x1F,0x02,0x09,0x80,0x1A,0x00,0x20,0x88,0x83,0x20,0x0E,0x82,0x0C,0x0F,0x0A,0x09,0x00,0x15,0x00,0x00,0x08,0x01,0x20,0x04,0x80,0x0C,0x0F,0x0A,0x09,0x00,0x10,0x00,0x00,0x04,0x00,0x10,0x00,0x40,0x0C,0x07,0xF2,0x04,0x00,0x10,0x00,0xF0,0x03,0xC0,0x0F,0x00,0x3F,0x0C,0x07,0x71,0x02,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x01,0x01,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x83,0x80,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x83,0x80,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x43,0x80,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x43,0x80,0x00,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x26,0x80,0x00,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,}; const uint8_t *_I_LockPopup_100x49[] = {_I_LockPopup_100x49_0}; -const uint8_t _I_Mute_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x03,0x01,0x21,0x80,0x14,0x01,0x41,0x40,0x0C,0x01,0x81,0x20,0x04,0x01,0x01,0x1F,0x06,0x01,0x81,0x02,0x05,0x01,0x81,0x84,0x04,0x01,0x81,0x48,0x04,0x01,0x81,0x30,0x04,0x01,0x81,0x30,0x04,0x01,0x81,0x48,0x04,0x01,0x81,0x84,0x04,0x01,0x81,0x02,0x05,0x01,0x01,0x1F,0x06,0x01,0x81,0x20,0x04,0x01,0x41,0x40,0x0C,0x01,0x21,0x80,0x14,0x01,0x01,0x00,0x03,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; -const uint8_t *_I_Mute_25x27[] = {_I_Mute_25x27_0}; +const uint8_t _I_PassportBottom_128x17_0[] = {0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0xF9,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x05,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x05,0xFA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x09,0x79,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xD5,0x80,0x55,0xD5,0x00,0xF3,0xCC,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x6A,0x00,0xAB,0x6A,0x00,0x06,0x86,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0xFE,0x3F,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_PassportBottom_128x17[] = {_I_PassportBottom_128x17_0}; -const uint8_t _I_IrdaArrowUp_4x8_0[] = {0x18,0x3C,0x7E,0xFF,}; -const uint8_t *_I_IrdaArrowUp_4x8[] = {_I_IrdaArrowUp_4x8_0}; +const uint8_t _I_PassportLeft_6x47_0[] = {0x3C,0x02,0x19,0x25,0x25,0x19,0x01,0x01,0x05,0x09,0x11,0x25,0x09,0x11,0x25,0x09,0x11,0x25,0x09,0x11,0x25,0x09,0x11,0x25,0x09,0x11,0x21,0x01,0x02,0x04,0x0C,0x1C,0x3C,0x3C,0x34,0x2C,0x34,0x2C,0x34,0x2C,0x34,0x2C,0x34,0x2C,0x34,0x2C,0x34,}; +const uint8_t *_I_PassportLeft_6x47[] = {_I_PassportLeft_6x47_0}; -const uint8_t _I_Up_hvr_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0xFC,0xFF,0x7F,0x00,0xFE,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xC7,0xFF,0x01,0xFF,0x83,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x00,0xFE,0x01,0x7F,0x00,0xFC,0x01,0x3F,0x00,0xF8,0x01,0x1F,0x00,0xF0,0x01,0x0F,0x00,0xE0,0x01,0x0F,0x00,0xE0,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; -const uint8_t *_I_Up_hvr_25x27[] = {_I_Up_hvr_25x27_0}; - -const uint8_t _I_Mute_hvr_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0xFC,0xFF,0x7F,0x00,0xFE,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFC,0x01,0xDF,0x7F,0xEB,0x01,0xBF,0xBF,0xF3,0x01,0x7F,0xDF,0xFB,0x01,0xFF,0xE0,0xF9,0x01,0x7F,0xFD,0xFA,0x01,0x7F,0x7B,0xFB,0x01,0x7F,0xB7,0xFB,0x01,0x7F,0xCF,0xFB,0x01,0x7F,0xCF,0xFB,0x01,0x7F,0xB7,0xFB,0x01,0x7F,0x7B,0xFB,0x01,0x7F,0xFD,0xFA,0x01,0xFF,0xE0,0xF9,0x01,0x7F,0xDF,0xFB,0x01,0xBF,0xBF,0xF3,0x01,0xDF,0x7F,0xEB,0x01,0xFF,0xFF,0xFC,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; -const uint8_t *_I_Mute_hvr_25x27[] = {_I_Mute_hvr_25x27_0}; - -const uint8_t _I_Vol_down_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0xC1,0xFF,0x07,0x01,0xC1,0xFF,0x07,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; -const uint8_t *_I_Vol_down_25x27[] = {_I_Vol_down_25x27_0}; +const uint8_t _I_Back_15x10_0[] = {0x04,0x00,0x06,0x00,0xFF,0x0F,0x06,0x10,0x04,0x20,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x10,0xFE,0x0F,}; +const uint8_t *_I_Back_15x10[] = {_I_Back_15x10_0}; const uint8_t _I_Down_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0xF1,0xFF,0x1F,0x01,0xF1,0xFF,0x1F,0x01,0xE1,0xFF,0x0F,0x01,0xC1,0xFF,0x07,0x01,0x81,0xFF,0x03,0x01,0x01,0xFF,0x01,0x01,0x01,0xFE,0x00,0x01,0x01,0x7C,0x00,0x01,0x01,0x38,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; const uint8_t *_I_Down_25x27[] = {_I_Down_25x27_0}; -const uint8_t _I_Power_hvr_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0xFC,0xFF,0x7F,0x00,0xFE,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xC7,0xFF,0x01,0xFF,0xC7,0xFF,0x01,0x7F,0xC6,0xFC,0x01,0x3F,0xC6,0xF8,0x01,0x1F,0xC7,0xF1,0x01,0x9F,0xC7,0xF3,0x01,0x9F,0xC7,0xF3,0x01,0x9F,0xEF,0xF3,0x01,0x9F,0xFF,0xF3,0x01,0x9F,0xFF,0xF3,0x01,0x9F,0xFF,0xF3,0x01,0x1F,0xFF,0xF1,0x01,0x3F,0xFE,0xF8,0x01,0x7F,0x7C,0xFC,0x01,0xFF,0x00,0xFE,0x01,0xFF,0x83,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; -const uint8_t *_I_Power_hvr_25x27[] = {_I_Power_hvr_25x27_0}; - -const uint8_t _I_IrdaLearnShort_128x31_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xF0,0xFF,0xFF,0xFF,0xFF,0x01,0x40,0x00,0x28,0x80,0xFF,0xFF,0xFF,0x00,0x1F,0x40,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x00,0x24,0xC0,0xAA,0xAA,0xAA,0xC1,0x7F,0x80,0x04,0x00,0x00,0x00,0x60,0x04,0x08,0x01,0x12,0x40,0x55,0x55,0x55,0xE1,0xFB,0x00,0x04,0x0C,0xB0,0x6D,0x93,0x04,0x10,0x01,0x0A,0xC0,0xFE,0xAA,0xAA,0xF1,0xF1,0x01,0x04,0x0C,0xB0,0x6D,0x93,0x04,0x20,0x02,0x09,0x40,0x03,0x55,0x55,0xF1,0xFF,0x01,0x04,0x0C,0x30,0x00,0x60,0x04,0x22,0x02,0x05,0xC0,0x01,0xAA,0xAA,0xF9,0xF1,0x03,0x04,0x00,0x80,0x6D,0x03,0x1C,0x24,0x02,0x02,0xC0,0x1C,0x5E,0x55,0xB9,0xAE,0x03,0xC4,0xED,0xB0,0x6D,0x03,0x24,0x24,0x02,0x02,0x40,0x1C,0xA6,0xAA,0x99,0x2E,0x03,0xC4,0xED,0x30,0x00,0x00,0x24,0x24,0x02,0x01,0x40,0x1C,0x71,0x55,0xB9,0xAE,0x03,0x04,0x00,0xB0,0x6D,0x03,0x1C,0x24,0x82,0x00,0x40,0x00,0xB8,0xAA,0xF9,0xF1,0x63,0x04,0x0C,0x80,0x6D,0x63,0x04,0x22,0x82,0x00,0x40,0x20,0x5C,0x55,0xF1,0xFF,0xF1,0x04,0x0C,0x00,0x00,0xF0,0x04,0x20,0x42,0x00,0x40,0xC0,0xBF,0xAA,0xF1,0xF1,0xF9,0x04,0x8C,0xF7,0xDE,0xF3,0x04,0x10,0x41,0x00,0x40,0x00,0x7E,0x55,0xE1,0xFB,0xF8,0x04,0x80,0xF7,0xDE,0x63,0x04,0x08,0x41,0x00,0x40,0x00,0xB0,0xAA,0xC1,0x7F,0xF0,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x40,0x00,0x40,0x80,0x5F,0x55,0x0D,0x1F,0x60,0xF0,0xFF,0xFF,0xFF,0xFF,0x01,0x40,0x80,0x00,0x80,0xFF,0xFF,0xFF,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_IrdaLearnShort_128x31[] = {_I_IrdaLearnShort_128x31_0}; - -const uint8_t _I_IrdaArrowDown_4x8_0[] = {0xFF,0x7E,0x3C,0x18,}; -const uint8_t *_I_IrdaArrowDown_4x8[] = {_I_IrdaArrowDown_4x8_0}; - -const uint8_t _I_Vol_down_hvr_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0xFC,0xFF,0x7F,0x00,0xFE,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0x3F,0x00,0xF8,0x01,0x3F,0x00,0xF8,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; -const uint8_t *_I_Vol_down_hvr_25x27[] = {_I_Vol_down_hvr_25x27_0}; - -const uint8_t _I_IrdaLearn_128x64_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x04,0x04,0x09,0x00,0x00,0x00,0x80,0x00,0x80,0xA0,0x07,0x00,0x40,0x00,0x80,0x08,0x00,0x04,0x09,0x00,0x00,0x00,0x80,0x00,0x80,0xA0,0x08,0x00,0x40,0x00,0x80,0xC8,0x74,0x8E,0x3B,0x06,0x67,0x6E,0xCC,0x19,0xDC,0xA1,0x88,0x63,0xEE,0x00,0x80,0x27,0x95,0x04,0x49,0x09,0x91,0x92,0x92,0x24,0x92,0xA0,0x87,0x94,0x42,0x00,0x80,0x20,0x95,0x04,0x49,0x0F,0xF1,0x92,0x92,0x3C,0x92,0xA0,0x82,0x94,0x42,0x00,0x80,0x20,0x95,0x04,0x49,0x01,0x11,0x92,0x92,0x04,0x92,0xA0,0x84,0x94,0x42,0x00,0x80,0xC0,0x94,0x04,0x49,0x06,0x61,0x92,0x8C,0x18,0x9C,0xA0,0x88,0x63,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x40,0x80,0x04,0x40,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x40,0x80,0x04,0x40,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x1C,0x27,0xD9,0xC1,0x1D,0xC3,0x49,0x77,0xE6,0x00,0x00,0x00,0x00,0x00,0x80,0x94,0x12,0x29,0x45,0x82,0xA4,0x44,0x4A,0x22,0x29,0x01,0x00,0x00,0x00,0x00,0x80,0x94,0x12,0x29,0x49,0x82,0xA4,0x47,0x4A,0x22,0x29,0x01,0x00,0x00,0x00,0x00,0x80,0x94,0x12,0x29,0x51,0x82,0xA4,0x40,0x4A,0x22,0x29,0x01,0x00,0x00,0x00,0x00,0x00,0x97,0x1C,0xC7,0x4D,0x82,0x24,0xC3,0x71,0x22,0x26,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xF0,0xFF,0xFF,0xFF,0xFF,0x01,0x40,0x00,0x28,0x80,0xFF,0xFF,0xFF,0x00,0x1F,0x40,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x00,0x24,0xC0,0xAA,0xAA,0xAA,0xC1,0x7F,0x80,0x04,0x00,0x00,0x00,0x60,0x04,0x08,0x01,0x12,0x40,0x55,0x55,0x55,0xE1,0xFB,0x00,0x04,0x0C,0xB0,0x6D,0x93,0x04,0x10,0x01,0x0A,0xC0,0xFE,0xAA,0xAA,0xF1,0xF1,0x01,0x04,0x0C,0xB0,0x6D,0x93,0x04,0x20,0x02,0x09,0x40,0x03,0x55,0x55,0xF1,0xFF,0x01,0x04,0x0C,0x30,0x00,0x60,0x04,0x22,0x02,0x05,0xC0,0x01,0xAA,0xAA,0xF9,0xF1,0x03,0x04,0x00,0x80,0x6D,0x03,0x1C,0x24,0x02,0x02,0xC0,0x1C,0x5E,0x55,0xB9,0xAE,0x03,0xC4,0xED,0xB0,0x6D,0x03,0x24,0x24,0x02,0x02,0x40,0x1C,0xA6,0xAA,0x99,0x2E,0x03,0xC4,0xED,0x30,0x00,0x00,0x24,0x24,0x02,0x01,0x40,0x1C,0x71,0x55,0xB9,0xAE,0x03,0x04,0x00,0xB0,0x6D,0x03,0x1C,0x24,0x82,0x00,0x40,0x00,0xB8,0xAA,0xF9,0xF1,0x63,0x04,0x0C,0x80,0x6D,0x63,0x04,0x22,0x82,0x00,0x40,0x20,0x5C,0x55,0xF1,0xFF,0xF1,0x04,0x0C,0x00,0x00,0xF0,0x04,0x20,0x42,0x00,0x40,0xC0,0xBF,0xAA,0xF1,0xF1,0xF9,0x04,0x8C,0xF7,0xDE,0xF3,0x04,0x10,0x41,0x00,0x40,0x00,0x7E,0x55,0xE1,0xFB,0xF8,0x04,0x80,0xF7,0xDE,0x63,0x04,0x08,0x41,0x00,0x40,0x00,0xB0,0xAA,0xC1,0x7F,0xF0,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x40,0x00,0x40,0x80,0x5F,0x55,0x0D,0x1F,0x60,0xF0,0xFF,0xFF,0xFF,0xFF,0x01,0x40,0x80,0x00,0x80,0xFF,0xFF,0xFF,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_IrdaLearn_128x64[] = {_I_IrdaLearn_128x64_0}; - const uint8_t _I_Down_hvr_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0xFC,0xFF,0x7F,0x00,0xFE,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0x0F,0x00,0xE0,0x01,0x0F,0x00,0xE0,0x01,0x1F,0x00,0xF0,0x01,0x3F,0x00,0xF8,0x01,0x7F,0x00,0xFC,0x01,0xFF,0x00,0xFE,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x83,0xFF,0x01,0xFF,0xC7,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; const uint8_t *_I_Down_hvr_25x27[] = {_I_Down_hvr_25x27_0}; const uint8_t _I_Fill_marker_7x7_0[] = {0x1C,0x32,0x6F,0x5F,0x7F,0x3E,0x1C,}; const uint8_t *_I_Fill_marker_7x7[] = {_I_Fill_marker_7x7_0}; -const uint8_t _I_Power_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x38,0x00,0x01,0x01,0x38,0x00,0x01,0x81,0x39,0x03,0x01,0xC1,0x39,0x07,0x01,0xE1,0x38,0x0E,0x01,0x61,0x38,0x0C,0x01,0x61,0x38,0x0C,0x01,0x61,0x10,0x0C,0x01,0x61,0x00,0x0C,0x01,0x61,0x00,0x0C,0x01,0x61,0x00,0x0C,0x01,0xE1,0x00,0x0E,0x01,0xC1,0x01,0x07,0x01,0x81,0x83,0x03,0x01,0x01,0xFF,0x01,0x01,0x01,0x7C,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; -const uint8_t *_I_Power_25x27[] = {_I_Power_25x27_0}; +const uint8_t _I_IrdaArrowDown_4x8_0[] = {0xFF,0x7E,0x3C,0x18,}; +const uint8_t *_I_IrdaArrowDown_4x8[] = {_I_IrdaArrowDown_4x8_0}; -const uint8_t _I_Vol_up_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0xC1,0xFF,0x07,0x01,0xC1,0xFF,0x07,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; -const uint8_t *_I_Vol_up_25x27[] = {_I_Vol_up_25x27_0}; +const uint8_t _I_IrdaArrowUp_4x8_0[] = {0x18,0x3C,0x7E,0xFF,}; +const uint8_t *_I_IrdaArrowUp_4x8[] = {_I_IrdaArrowUp_4x8_0}; -const uint8_t _I_Up_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x38,0x00,0x01,0x01,0x7C,0x00,0x01,0x01,0xFE,0x00,0x01,0x01,0xFF,0x01,0x01,0x81,0xFF,0x03,0x01,0xC1,0xFF,0x07,0x01,0xE1,0xFF,0x0F,0x01,0xF1,0xFF,0x1F,0x01,0xF1,0xFF,0x1F,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; -const uint8_t *_I_Up_25x27[] = {_I_Up_25x27_0}; +const uint8_t _I_IrdaLearnShort_128x31_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xF0,0xFF,0xFF,0xFF,0xFF,0x01,0x40,0x00,0x28,0x80,0xFF,0xFF,0xFF,0x00,0x1F,0x40,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x00,0x24,0xC0,0xAA,0xAA,0xAA,0xC1,0x7F,0x80,0x04,0x00,0x00,0x00,0x60,0x04,0x08,0x01,0x12,0x40,0x55,0x55,0x55,0xE1,0xFB,0x00,0x04,0x0C,0xB0,0x6D,0x93,0x04,0x10,0x01,0x0A,0xC0,0xFE,0xAA,0xAA,0xF1,0xF1,0x01,0x04,0x0C,0xB0,0x6D,0x93,0x04,0x20,0x02,0x09,0x40,0x03,0x55,0x55,0xF1,0xFF,0x01,0x04,0x0C,0x30,0x00,0x60,0x04,0x22,0x02,0x05,0xC0,0x01,0xAA,0xAA,0xF9,0xF1,0x03,0x04,0x00,0x80,0x6D,0x03,0x1C,0x24,0x02,0x02,0xC0,0x1C,0x5E,0x55,0xB9,0xAE,0x03,0xC4,0xED,0xB0,0x6D,0x03,0x24,0x24,0x02,0x02,0x40,0x1C,0xA6,0xAA,0x99,0x2E,0x03,0xC4,0xED,0x30,0x00,0x00,0x24,0x24,0x02,0x01,0x40,0x1C,0x71,0x55,0xB9,0xAE,0x03,0x04,0x00,0xB0,0x6D,0x03,0x1C,0x24,0x82,0x00,0x40,0x00,0xB8,0xAA,0xF9,0xF1,0x63,0x04,0x0C,0x80,0x6D,0x63,0x04,0x22,0x82,0x00,0x40,0x20,0x5C,0x55,0xF1,0xFF,0xF1,0x04,0x0C,0x00,0x00,0xF0,0x04,0x20,0x42,0x00,0x40,0xC0,0xBF,0xAA,0xF1,0xF1,0xF9,0x04,0x8C,0xF7,0xDE,0xF3,0x04,0x10,0x41,0x00,0x40,0x00,0x7E,0x55,0xE1,0xFB,0xF8,0x04,0x80,0xF7,0xDE,0x63,0x04,0x08,0x41,0x00,0x40,0x00,0xB0,0xAA,0xC1,0x7F,0xF0,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x40,0x00,0x40,0x80,0x5F,0x55,0x0D,0x1F,0x60,0xF0,0xFF,0xFF,0xFF,0xFF,0x01,0x40,0x80,0x00,0x80,0xFF,0xFF,0xFF,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_IrdaLearnShort_128x31[] = {_I_IrdaLearnShort_128x31_0}; -const uint8_t _I_Back_15x10_0[] = {0x04,0x00,0x06,0x00,0xFF,0x0F,0x06,0x10,0x04,0x20,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x10,0xFE,0x0F,}; -const uint8_t *_I_Back_15x10[] = {_I_Back_15x10_0}; - -const uint8_t _I_IrdaSend_128x64_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x02,0x82,0xAF,0x00,0x00,0x00,0x10,0x08,0x00,0x00,0x04,0x00,0x00,0x00,0x40,0x04,0x00,0x82,0x20,0x00,0x00,0x00,0x10,0x08,0x00,0x00,0x04,0x00,0x00,0x00,0x40,0x64,0x3A,0x87,0xA0,0xCE,0x31,0x87,0x3B,0x9C,0x3B,0x67,0x0E,0x00,0x00,0x00,0xC0,0x93,0x4A,0x82,0xA7,0x52,0x4A,0x41,0x12,0x48,0x8A,0x94,0x04,0x00,0x00,0x00,0x40,0x90,0x4A,0x82,0xA0,0x52,0x7A,0x41,0x12,0x48,0x8A,0xF4,0x04,0x00,0x00,0x00,0x40,0x90,0x4A,0x82,0xA0,0x52,0x0A,0x41,0x12,0x48,0x8A,0x14,0x04,0x00,0x00,0x00,0x40,0x60,0x4A,0x82,0xA0,0xCE,0x31,0x81,0x13,0x88,0x0B,0x67,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x40,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x40,0x00,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3B,0x0E,0x27,0xD9,0x81,0x3C,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x4A,0x09,0x29,0x45,0x82,0x7E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x4A,0x09,0x29,0x49,0x82,0x7E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x4A,0x09,0x29,0x51,0x82,0x3C,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x4B,0x0E,0xC7,0x4D,0x02,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC4,0xFF,0xFF,0xFF,0xFF,0x3F,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0xDF,0x55,0x55,0xDD,0x3F,0x02,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0xAA,0xAA,0xAA,0xAA,0x2E,0x02,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0x7F,0x55,0x55,0xF5,0x3F,0x02,0x04,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0xAB,0x2A,0xAA,0xAA,0x3A,0x02,0x02,0x00,0x05,0xF0,0xFF,0xFF,0x1F,0xE0,0x03,0xC4,0x5F,0x55,0x55,0xDD,0x3F,0x02,0x21,0x80,0x04,0x58,0x55,0x55,0x35,0xF8,0x0F,0xC4,0xAA,0x8A,0x88,0xAA,0x2A,0x02,0x11,0x40,0x02,0xA8,0xAA,0xAA,0x2A,0x7C,0x1F,0xC4,0x77,0x55,0x55,0x75,0x3F,0x82,0x08,0x40,0x01,0xD8,0x5F,0x55,0x35,0x3E,0x3E,0xC4,0xAB,0x22,0xA2,0xAA,0x3A,0x82,0x88,0x20,0x01,0x68,0xA0,0xAA,0x2A,0xFE,0x3F,0xC4,0x5F,0x55,0x55,0xD5,0x3F,0x82,0x48,0xA0,0x00,0x38,0x40,0x55,0x35,0x3F,0x7E,0xC4,0xAA,0xAA,0xAA,0xAA,0x2A,0x82,0x48,0x40,0x00,0x98,0xC3,0xAB,0x2A,0xD7,0x75,0xC4,0x77,0x55,0x55,0x75,0x3F,0x82,0x48,0x40,0x00,0x88,0xC3,0x54,0x35,0xD3,0x65,0xC4,0xAB,0xAA,0xAA,0xAA,0x3A,0x82,0x48,0x20,0x00,0x88,0x23,0xAE,0x2A,0xD7,0x75,0xC4,0xDF,0x55,0x55,0xDD,0x3F,0x82,0x88,0x10,0x00,0x08,0x00,0x57,0x35,0x3F,0x7E,0xC4,0xAE,0xAA,0xAA,0xAA,0x2A,0x82,0x08,0x10,0x00,0x08,0x84,0xAB,0x2A,0xFE,0x3F,0xC4,0xFF,0x77,0x75,0xF7,0x3F,0x02,0x11,0x08,0x00,0x08,0xF8,0x57,0x35,0x3E,0x3E,0xC4,0xAB,0xAA,0xAA,0xAA,0x3B,0x02,0x21,0x08,0x00,0x08,0xC0,0xAF,0x2A,0x7C,0x1F,0xC4,0xFF,0xFF,0xDD,0xFD,0x3F,0x02,0x02,0x08,0x00,0x08,0x00,0x56,0x35,0xF8,0x0F,0xC4,0xEE,0xAA,0xAA,0xEA,0x2E,0x02,0x04,0x08,0x00,0x08,0xF0,0xAB,0xAA,0xE1,0x03,0xC4,0xFF,0xFF,0xFF,0xFF,0x3F,0x02,0x00,0x10,0x00,0xF0,0xFF,0xFF,0x9F,0x01,0x00,0xC4,0xFF,0xFF,0xFF,0xFF,0x3F,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x0F,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x0F,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_IrdaSend_128x64[] = {_I_IrdaSend_128x64_0}; +const uint8_t _I_IrdaLearn_128x64_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x04,0x04,0x09,0x00,0x00,0x00,0x80,0x00,0x80,0xA0,0x07,0x00,0x40,0x00,0x80,0x08,0x00,0x04,0x09,0x00,0x00,0x00,0x80,0x00,0x80,0xA0,0x08,0x00,0x40,0x00,0x80,0xC8,0x74,0x8E,0x3B,0x06,0x67,0x6E,0xCC,0x19,0xDC,0xA1,0x88,0x63,0xEE,0x00,0x80,0x27,0x95,0x04,0x49,0x09,0x91,0x92,0x92,0x24,0x92,0xA0,0x87,0x94,0x42,0x00,0x80,0x20,0x95,0x04,0x49,0x0F,0xF1,0x92,0x92,0x3C,0x92,0xA0,0x82,0x94,0x42,0x00,0x80,0x20,0x95,0x04,0x49,0x01,0x11,0x92,0x92,0x04,0x92,0xA0,0x84,0x94,0x42,0x00,0x80,0xC0,0x94,0x04,0x49,0x06,0x61,0x92,0x8C,0x18,0x9C,0xA0,0x88,0x63,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x40,0x80,0x04,0x40,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x40,0x80,0x04,0x40,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x1C,0x27,0xD9,0xC1,0x1D,0xC3,0x49,0x77,0xE6,0x00,0x00,0x00,0x00,0x00,0x80,0x94,0x12,0x29,0x45,0x82,0xA4,0x44,0x4A,0x22,0x29,0x01,0x00,0x00,0x00,0x00,0x80,0x94,0x12,0x29,0x49,0x82,0xA4,0x47,0x4A,0x22,0x29,0x01,0x00,0x00,0x00,0x00,0x80,0x94,0x12,0x29,0x51,0x82,0xA4,0x40,0x4A,0x22,0x29,0x01,0x00,0x00,0x00,0x00,0x00,0x97,0x1C,0xC7,0x4D,0x82,0x24,0xC3,0x71,0x22,0x26,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xF0,0xFF,0xFF,0xFF,0xFF,0x01,0x40,0x00,0x28,0x80,0xFF,0xFF,0xFF,0x00,0x1F,0x40,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x00,0x24,0xC0,0xAA,0xAA,0xAA,0xC1,0x7F,0x80,0x04,0x00,0x00,0x00,0x60,0x04,0x08,0x01,0x12,0x40,0x55,0x55,0x55,0xE1,0xFB,0x00,0x04,0x0C,0xB0,0x6D,0x93,0x04,0x10,0x01,0x0A,0xC0,0xFE,0xAA,0xAA,0xF1,0xF1,0x01,0x04,0x0C,0xB0,0x6D,0x93,0x04,0x20,0x02,0x09,0x40,0x03,0x55,0x55,0xF1,0xFF,0x01,0x04,0x0C,0x30,0x00,0x60,0x04,0x22,0x02,0x05,0xC0,0x01,0xAA,0xAA,0xF9,0xF1,0x03,0x04,0x00,0x80,0x6D,0x03,0x1C,0x24,0x02,0x02,0xC0,0x1C,0x5E,0x55,0xB9,0xAE,0x03,0xC4,0xED,0xB0,0x6D,0x03,0x24,0x24,0x02,0x02,0x40,0x1C,0xA6,0xAA,0x99,0x2E,0x03,0xC4,0xED,0x30,0x00,0x00,0x24,0x24,0x02,0x01,0x40,0x1C,0x71,0x55,0xB9,0xAE,0x03,0x04,0x00,0xB0,0x6D,0x03,0x1C,0x24,0x82,0x00,0x40,0x00,0xB8,0xAA,0xF9,0xF1,0x63,0x04,0x0C,0x80,0x6D,0x63,0x04,0x22,0x82,0x00,0x40,0x20,0x5C,0x55,0xF1,0xFF,0xF1,0x04,0x0C,0x00,0x00,0xF0,0x04,0x20,0x42,0x00,0x40,0xC0,0xBF,0xAA,0xF1,0xF1,0xF9,0x04,0x8C,0xF7,0xDE,0xF3,0x04,0x10,0x41,0x00,0x40,0x00,0x7E,0x55,0xE1,0xFB,0xF8,0x04,0x80,0xF7,0xDE,0x63,0x04,0x08,0x41,0x00,0x40,0x00,0xB0,0xAA,0xC1,0x7F,0xF0,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x40,0x00,0x40,0x80,0x5F,0x55,0x0D,0x1F,0x60,0xF0,0xFF,0xFF,0xFF,0xFF,0x01,0x40,0x80,0x00,0x80,0xFF,0xFF,0xFF,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_IrdaLearn_128x64[] = {_I_IrdaLearn_128x64_0}; const uint8_t _I_IrdaSendShort_128x34_0[] = {0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC4,0xFF,0xFF,0xFF,0xFF,0x3F,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0xDF,0x55,0x55,0xDD,0x3F,0x02,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0xAA,0xAA,0xAA,0xAA,0x2E,0x02,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0x7F,0x55,0x55,0xF5,0x3F,0x02,0x04,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0xAB,0x2A,0xAA,0xAA,0x3A,0x02,0x02,0x00,0x05,0xF0,0xFF,0xFF,0x1F,0xE0,0x03,0xC4,0x5F,0x55,0x55,0xDD,0x3F,0x02,0x21,0x80,0x04,0x58,0x55,0x55,0x35,0xF8,0x0F,0xC4,0xAA,0x8A,0x88,0xAA,0x2A,0x02,0x11,0x40,0x02,0xA8,0xAA,0xAA,0x2A,0x7C,0x1F,0xC4,0x77,0x55,0x55,0x75,0x3F,0x82,0x08,0x40,0x01,0xD8,0x5F,0x55,0x35,0x3E,0x3E,0xC4,0xAB,0x22,0xA2,0xAA,0x3A,0x82,0x88,0x20,0x01,0x68,0xA0,0xAA,0x2A,0xFE,0x3F,0xC4,0x5F,0x55,0x55,0xD5,0x3F,0x82,0x48,0xA0,0x00,0x38,0x40,0x55,0x35,0x3F,0x7E,0xC4,0xAA,0xAA,0xAA,0xAA,0x2A,0x82,0x48,0x40,0x00,0x98,0xC3,0xAB,0x2A,0xD7,0x75,0xC4,0x77,0x55,0x55,0x75,0x3F,0x82,0x48,0x40,0x00,0x88,0xC3,0x54,0x35,0xD3,0x65,0xC4,0xAB,0xAA,0xAA,0xAA,0x3A,0x82,0x48,0x20,0x00,0x88,0x23,0xAE,0x2A,0xD7,0x75,0xC4,0xDF,0x55,0x55,0xDD,0x3F,0x82,0x88,0x10,0x00,0x08,0x00,0x57,0x35,0x3F,0x7E,0xC4,0xAE,0xAA,0xAA,0xAA,0x2A,0x82,0x08,0x10,0x00,0x08,0x84,0xAB,0x2A,0xFE,0x3F,0xC4,0xFF,0x77,0x75,0xF7,0x3F,0x02,0x11,0x08,0x00,0x08,0xF8,0x57,0x35,0x3E,0x3E,0xC4,0xAB,0xAA,0xAA,0xAA,0x3B,0x02,0x21,0x08,0x00,0x08,0xC0,0xAF,0x2A,0x7C,0x1F,0xC4,0xFF,0xFF,0xDD,0xFD,0x3F,0x02,0x02,0x08,0x00,0x08,0x00,0x56,0x35,0xF8,0x0F,0xC4,0xEE,0xAA,0xAA,0xEA,0x2E,0x02,0x04,0x08,0x00,0x08,0xF0,0xAB,0xAA,0xE1,0x03,0xC4,0xFF,0xFF,0xFF,0xFF,0x3F,0x02,0x00,0x10,0x00,0xF0,0xFF,0xFF,0x9F,0x01,0x00,0xC4,0xFF,0xFF,0xFF,0xFF,0x3F,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x0F,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x0F,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; const uint8_t *_I_IrdaSendShort_128x34[] = {_I_IrdaSendShort_128x34_0}; +const uint8_t _I_IrdaSend_128x64_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x02,0x82,0xAF,0x00,0x00,0x00,0x10,0x08,0x00,0x00,0x04,0x00,0x00,0x00,0x40,0x04,0x00,0x82,0x20,0x00,0x00,0x00,0x10,0x08,0x00,0x00,0x04,0x00,0x00,0x00,0x40,0x64,0x3A,0x87,0xA0,0xCE,0x31,0x87,0x3B,0x9C,0x3B,0x67,0x0E,0x00,0x00,0x00,0xC0,0x93,0x4A,0x82,0xA7,0x52,0x4A,0x41,0x12,0x48,0x8A,0x94,0x04,0x00,0x00,0x00,0x40,0x90,0x4A,0x82,0xA0,0x52,0x7A,0x41,0x12,0x48,0x8A,0xF4,0x04,0x00,0x00,0x00,0x40,0x90,0x4A,0x82,0xA0,0x52,0x0A,0x41,0x12,0x48,0x8A,0x14,0x04,0x00,0x00,0x00,0x40,0x60,0x4A,0x82,0xA0,0xCE,0x31,0x81,0x13,0x88,0x0B,0x67,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x40,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x40,0x00,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3B,0x0E,0x27,0xD9,0x81,0x3C,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x4A,0x09,0x29,0x45,0x82,0x7E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x4A,0x09,0x29,0x49,0x82,0x7E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x4A,0x09,0x29,0x51,0x82,0x3C,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x4B,0x0E,0xC7,0x4D,0x02,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC4,0xFF,0xFF,0xFF,0xFF,0x3F,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0xDF,0x55,0x55,0xDD,0x3F,0x02,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0xAA,0xAA,0xAA,0xAA,0x2E,0x02,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0x7F,0x55,0x55,0xF5,0x3F,0x02,0x04,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0xAB,0x2A,0xAA,0xAA,0x3A,0x02,0x02,0x00,0x05,0xF0,0xFF,0xFF,0x1F,0xE0,0x03,0xC4,0x5F,0x55,0x55,0xDD,0x3F,0x02,0x21,0x80,0x04,0x58,0x55,0x55,0x35,0xF8,0x0F,0xC4,0xAA,0x8A,0x88,0xAA,0x2A,0x02,0x11,0x40,0x02,0xA8,0xAA,0xAA,0x2A,0x7C,0x1F,0xC4,0x77,0x55,0x55,0x75,0x3F,0x82,0x08,0x40,0x01,0xD8,0x5F,0x55,0x35,0x3E,0x3E,0xC4,0xAB,0x22,0xA2,0xAA,0x3A,0x82,0x88,0x20,0x01,0x68,0xA0,0xAA,0x2A,0xFE,0x3F,0xC4,0x5F,0x55,0x55,0xD5,0x3F,0x82,0x48,0xA0,0x00,0x38,0x40,0x55,0x35,0x3F,0x7E,0xC4,0xAA,0xAA,0xAA,0xAA,0x2A,0x82,0x48,0x40,0x00,0x98,0xC3,0xAB,0x2A,0xD7,0x75,0xC4,0x77,0x55,0x55,0x75,0x3F,0x82,0x48,0x40,0x00,0x88,0xC3,0x54,0x35,0xD3,0x65,0xC4,0xAB,0xAA,0xAA,0xAA,0x3A,0x82,0x48,0x20,0x00,0x88,0x23,0xAE,0x2A,0xD7,0x75,0xC4,0xDF,0x55,0x55,0xDD,0x3F,0x82,0x88,0x10,0x00,0x08,0x00,0x57,0x35,0x3F,0x7E,0xC4,0xAE,0xAA,0xAA,0xAA,0x2A,0x82,0x08,0x10,0x00,0x08,0x84,0xAB,0x2A,0xFE,0x3F,0xC4,0xFF,0x77,0x75,0xF7,0x3F,0x02,0x11,0x08,0x00,0x08,0xF8,0x57,0x35,0x3E,0x3E,0xC4,0xAB,0xAA,0xAA,0xAA,0x3B,0x02,0x21,0x08,0x00,0x08,0xC0,0xAF,0x2A,0x7C,0x1F,0xC4,0xFF,0xFF,0xDD,0xFD,0x3F,0x02,0x02,0x08,0x00,0x08,0x00,0x56,0x35,0xF8,0x0F,0xC4,0xEE,0xAA,0xAA,0xEA,0x2E,0x02,0x04,0x08,0x00,0x08,0xF0,0xAB,0xAA,0xE1,0x03,0xC4,0xFF,0xFF,0xFF,0xFF,0x3F,0x02,0x00,0x10,0x00,0xF0,0xFF,0xFF,0x9F,0x01,0x00,0xC4,0xFF,0xFF,0xFF,0xFF,0x3F,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x0F,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x0F,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_IrdaSend_128x64[] = {_I_IrdaSend_128x64_0}; + +const uint8_t _I_Mute_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x03,0x01,0x21,0x80,0x14,0x01,0x41,0x40,0x0C,0x01,0x81,0x20,0x04,0x01,0x01,0x1F,0x06,0x01,0x81,0x02,0x05,0x01,0x81,0x84,0x04,0x01,0x81,0x48,0x04,0x01,0x81,0x30,0x04,0x01,0x81,0x30,0x04,0x01,0x81,0x48,0x04,0x01,0x81,0x84,0x04,0x01,0x81,0x02,0x05,0x01,0x01,0x1F,0x06,0x01,0x81,0x20,0x04,0x01,0x41,0x40,0x0C,0x01,0x21,0x80,0x14,0x01,0x01,0x00,0x03,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; +const uint8_t *_I_Mute_25x27[] = {_I_Mute_25x27_0}; + +const uint8_t _I_Mute_hvr_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0xFC,0xFF,0x7F,0x00,0xFE,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFC,0x01,0xDF,0x7F,0xEB,0x01,0xBF,0xBF,0xF3,0x01,0x7F,0xDF,0xFB,0x01,0xFF,0xE0,0xF9,0x01,0x7F,0xFD,0xFA,0x01,0x7F,0x7B,0xFB,0x01,0x7F,0xB7,0xFB,0x01,0x7F,0xCF,0xFB,0x01,0x7F,0xCF,0xFB,0x01,0x7F,0xB7,0xFB,0x01,0x7F,0x7B,0xFB,0x01,0x7F,0xFD,0xFA,0x01,0xFF,0xE0,0xF9,0x01,0x7F,0xDF,0xFB,0x01,0xBF,0xBF,0xF3,0x01,0xDF,0x7F,0xEB,0x01,0xFF,0xFF,0xFC,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; +const uint8_t *_I_Mute_hvr_25x27[] = {_I_Mute_hvr_25x27_0}; + +const uint8_t _I_Power_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x38,0x00,0x01,0x01,0x38,0x00,0x01,0x81,0x39,0x03,0x01,0xC1,0x39,0x07,0x01,0xE1,0x38,0x0E,0x01,0x61,0x38,0x0C,0x01,0x61,0x38,0x0C,0x01,0x61,0x10,0x0C,0x01,0x61,0x00,0x0C,0x01,0x61,0x00,0x0C,0x01,0x61,0x00,0x0C,0x01,0xE1,0x00,0x0E,0x01,0xC1,0x01,0x07,0x01,0x81,0x83,0x03,0x01,0x01,0xFF,0x01,0x01,0x01,0x7C,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; +const uint8_t *_I_Power_25x27[] = {_I_Power_25x27_0}; + +const uint8_t _I_Power_hvr_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0xFC,0xFF,0x7F,0x00,0xFE,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xC7,0xFF,0x01,0xFF,0xC7,0xFF,0x01,0x7F,0xC6,0xFC,0x01,0x3F,0xC6,0xF8,0x01,0x1F,0xC7,0xF1,0x01,0x9F,0xC7,0xF3,0x01,0x9F,0xC7,0xF3,0x01,0x9F,0xEF,0xF3,0x01,0x9F,0xFF,0xF3,0x01,0x9F,0xFF,0xF3,0x01,0x9F,0xFF,0xF3,0x01,0x1F,0xFF,0xF1,0x01,0x3F,0xFE,0xF8,0x01,0x7F,0x7C,0xFC,0x01,0xFF,0x00,0xFE,0x01,0xFF,0x83,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; +const uint8_t *_I_Power_hvr_25x27[] = {_I_Power_hvr_25x27_0}; + +const uint8_t _I_Up_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x38,0x00,0x01,0x01,0x7C,0x00,0x01,0x01,0xFE,0x00,0x01,0x01,0xFF,0x01,0x01,0x81,0xFF,0x03,0x01,0xC1,0xFF,0x07,0x01,0xE1,0xFF,0x0F,0x01,0xF1,0xFF,0x1F,0x01,0xF1,0xFF,0x1F,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; +const uint8_t *_I_Up_25x27[] = {_I_Up_25x27_0}; + +const uint8_t _I_Up_hvr_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0xFC,0xFF,0x7F,0x00,0xFE,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xC7,0xFF,0x01,0xFF,0x83,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x00,0xFE,0x01,0x7F,0x00,0xFC,0x01,0x3F,0x00,0xF8,0x01,0x1F,0x00,0xF0,0x01,0x0F,0x00,0xE0,0x01,0x0F,0x00,0xE0,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; +const uint8_t *_I_Up_hvr_25x27[] = {_I_Up_hvr_25x27_0}; + +const uint8_t _I_Vol_down_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0xC1,0xFF,0x07,0x01,0xC1,0xFF,0x07,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; +const uint8_t *_I_Vol_down_25x27[] = {_I_Vol_down_25x27_0}; + +const uint8_t _I_Vol_down_hvr_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0xFC,0xFF,0x7F,0x00,0xFE,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0x3F,0x00,0xF8,0x01,0x3F,0x00,0xF8,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; +const uint8_t *_I_Vol_down_hvr_25x27[] = {_I_Vol_down_hvr_25x27_0}; + +const uint8_t _I_Vol_up_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0x04,0x00,0x40,0x00,0x02,0x00,0x80,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0xC1,0xFF,0x07,0x01,0xC1,0xFF,0x07,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x10,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x03,0x00,0x80,0x01,0x06,0x00,0xC0,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; +const uint8_t *_I_Vol_up_25x27[] = {_I_Vol_up_25x27_0}; + const uint8_t _I_Vol_up_hvr_25x27_0[] = {0xF8,0xFF,0x3F,0x00,0xFC,0xFF,0x7F,0x00,0xFE,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0x3F,0x00,0xF8,0x01,0x3F,0x00,0xF8,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xEF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFF,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0xFF,0x3F,0x00,}; const uint8_t *_I_Vol_up_hvr_25x27[] = {_I_Vol_up_hvr_25x27_0}; -const uint8_t _I_KeySave_24x11_0[] = {0xFE,0xFF,0xFF,0x01,0x00,0x80,0x01,0x00,0x80,0x31,0x97,0x8C,0x89,0x94,0x92,0x91,0x94,0x9E,0xA1,0x94,0x82,0x19,0x67,0x8C,0x01,0x00,0x80,0x01,0x00,0x80,0xFE,0xFF,0x7F,}; -const uint8_t *_I_KeySave_24x11[] = {_I_KeySave_24x11_0}; - const uint8_t _I_KeyBackspaceSelected_16x9_0[] = {0xFE,0x7F,0xFF,0xFF,0xEF,0xFF,0xE7,0xFF,0x03,0xC0,0xE7,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0x7F,}; const uint8_t *_I_KeyBackspaceSelected_16x9[] = {_I_KeyBackspaceSelected_16x9_0}; +const uint8_t _I_KeyBackspace_16x9_0[] = {0xFE,0x7F,0x01,0x80,0x11,0x80,0x19,0x80,0xFD,0xBF,0x19,0x80,0x11,0x80,0x01,0x80,0xFE,0x7F,}; +const uint8_t *_I_KeyBackspace_16x9[] = {_I_KeyBackspace_16x9_0}; + const uint8_t _I_KeySaveSelected_24x11_0[] = {0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCF,0x68,0xF3,0x77,0x6B,0xED,0x6F,0x6B,0xE1,0x5F,0x6B,0xFD,0xE7,0x98,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x7F,}; const uint8_t *_I_KeySaveSelected_24x11[] = {_I_KeySaveSelected_24x11_0}; -const uint8_t _I_KeyBackspace_16x9_0[] = {0xFE,0x7F,0x01,0x80,0x11,0x80,0x19,0x80,0xFD,0xBF,0x19,0x80,0x11,0x80,0x01,0x80,0xFE,0x7F,}; -const uint8_t *_I_KeyBackspace_16x9[] = {_I_KeyBackspace_16x9_0}; +const uint8_t _I_KeySave_24x11_0[] = {0xFE,0xFF,0xFF,0x01,0x00,0x80,0x01,0x00,0x80,0x31,0x97,0x8C,0x89,0x94,0x92,0x91,0x94,0x9E,0xA1,0x94,0x82,0x19,0x67,0x8C,0x01,0x00,0x80,0x01,0x00,0x80,0xFE,0xFF,0x7F,}; +const uint8_t *_I_KeySave_24x11[] = {_I_KeySave_24x11_0}; const uint8_t _A_125khz_14_0[] = {0x80,0x07,0x00,0x08,0x00,0x13,0x00,0x24,0x0E,0x28,0x71,0x28,0x85,0x21,0x01,0x02,0x62,0x02,0x92,0x02,0x92,0x02,0x64,0x02,0x04,0x01,0xF8,0x00,}; const uint8_t _A_125khz_14_1[] = {0x80,0x07,0x00,0x08,0x00,0x10,0x00,0x20,0x0E,0x20,0x71,0x20,0x85,0x21,0x01,0x02,0x62,0x02,0x92,0x02,0x92,0x02,0x64,0x02,0x04,0x01,0xF8,0x00,}; @@ -369,53 +369,50 @@ const uint8_t _A_iButton_14_5[] = {0x00,0x00,0x00,0x38,0x00,0x24,0x00,0x22,0x80, const uint8_t _A_iButton_14_6[] = {0x00,0x00,0x00,0x38,0x00,0x24,0x00,0x23,0x80,0x20,0xF0,0x10,0x0C,0x0D,0xE2,0x02,0x91,0x01,0x69,0x01,0x15,0x01,0x8D,0x00,0x4D,0x00,0x3E,0x00,}; const uint8_t *_A_iButton_14[] = {_A_iButton_14_0,_A_iButton_14_1,_A_iButton_14_2,_A_iButton_14_3,_A_iButton_14_4,_A_iButton_14_5,_A_iButton_14_6}; -const uint8_t _I_Medium_chip_22x21_0[] = {0xFC,0xFF,0x0F,0x02,0x00,0x10,0xF9,0xFF,0x27,0x85,0x52,0x28,0xC5,0xFF,0x28,0x25,0x00,0x29,0x95,0x67,0x2A,0x5D,0x60,0x2E,0x55,0x00,0x2A,0x1D,0x80,0x2E,0x55,0x80,0x2A,0x1D,0x80,0x2E,0x55,0x80,0x2A,0x5D,0x80,0x2E,0x95,0x7D,0x2A,0x25,0x00,0x29,0xC5,0xFF,0x28,0x85,0x52,0x28,0xF9,0xFF,0x27,0x02,0x00,0x10,0xFC,0xFF,0x0F,}; -const uint8_t *_I_Medium_chip_22x21[] = {_I_Medium_chip_22x21_0}; - const uint8_t _I_EMV_Chip_14x11_0[] = {0xFC,0x0F,0x02,0x10,0xC9,0x24,0x2F,0x3C,0x11,0x22,0x11,0x22,0x11,0x22,0x2F,0x3D,0xC9,0x24,0x02,0x10,0xFC,0x0F,}; const uint8_t *_I_EMV_Chip_14x11[] = {_I_EMV_Chip_14x11_0}; -const uint8_t _I_passport_happy1_43x45_0[] = {0x00,0xF8,0x3F,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x80,0x00,0x00,0x03,0x00,0x00,0x40,0x00,0x00,0x04,0x00,0x00,0x20,0x00,0x00,0x08,0x70,0x00,0x10,0x00,0x00,0x10,0x8E,0x01,0x08,0x00,0x00,0xA0,0x01,0x02,0x08,0x00,0x00,0x60,0x00,0x02,0x04,0x00,0x00,0x30,0xC0,0x03,0x04,0x00,0x00,0x0C,0x10,0x02,0x02,0x70,0x00,0x06,0x0C,0x01,0x02,0xFC,0x01,0x01,0x02,0x01,0x02,0xFE,0x01,0x80,0x80,0x00,0x01,0xFF,0x03,0x40,0x40,0x00,0x01,0x2F,0x00,0x60,0x60,0x00,0x81,0x17,0x00,0xB0,0x20,0x00,0x41,0x0F,0x00,0x58,0x11,0x00,0x81,0x0A,0x00,0xAC,0x08,0x00,0x41,0x0D,0x00,0x56,0x05,0x00,0x81,0x8A,0x00,0xBF,0x06,0x00,0x40,0x85,0x80,0xFF,0x07,0x00,0x80,0x02,0xE3,0xC3,0x1F,0x00,0x00,0x00,0xFC,0x01,0x7F,0x00,0x00,0x00,0xF0,0x03,0xFC,0x03,0x00,0x00,0x80,0x3F,0xF0,0x07,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x8E,0x03,0x00,0x00,0x04,0x00,0xD3,0x04,0x00,0x00,0x07,0x80,0x71,0x04,0x00,0xF0,0x01,0x80,0x61,0x44,0xFD,0x1F,0x00,0x80,0x61,0x88,0xAA,0x02,0x00,0x80,0x61,0x08,0x54,0x01,0x00,0xC0,0xC0,0x10,0xA8,0x01,0x00,0xC0,0xC0,0x10,0x40,0x01,0x00,0xC0,0xC0,0x20,0x00,0x02,0x00,0x60,0xC0,0x20,0x00,0x02,0x00,0x60,0xC0,0x40,0x00,0x02,0x00,0x30,0xC0,0x80,0x00,0x02,0x00,0x38,0xC0,0x80,0x00,0x04,0x00,0x1C,0xC0,0x00,0x01,0x04,0x00,0x0E,0xC0,0x00,0x02,0x08,0x00,0x06,0xE0,0x01,0x0C,0x08,0x00,0x03,0xE0,0x01,0x70,0x10,0x00,0x01,0xF0,0x03,0x80,0x33,0x00,}; -const uint8_t *_I_passport_happy1_43x45[] = {_I_passport_happy1_43x45_0}; - -const uint8_t _I_passport_bad3_43x45_0[] = {0x00,0xC0,0xFF,0x01,0x00,0x00,0x00,0x30,0x00,0x02,0x00,0x00,0x00,0x0C,0x00,0x07,0x00,0x00,0x00,0x02,0xC0,0x18,0x00,0x00,0x00,0x01,0x20,0x20,0x00,0x00,0x80,0x01,0x10,0x40,0x00,0x00,0x40,0x01,0x08,0x80,0x00,0x00,0x20,0x01,0x08,0x80,0x00,0x00,0x10,0x01,0x08,0x00,0x01,0x00,0x10,0x01,0x04,0x50,0x01,0x00,0x08,0x02,0x04,0xAA,0x06,0x00,0x08,0xE2,0x07,0xD5,0x0F,0x00,0x04,0x14,0x88,0x3A,0x12,0x00,0x04,0xEC,0x50,0x07,0x12,0x00,0x04,0xF6,0xA1,0x04,0x14,0x00,0x02,0x8C,0x63,0x08,0x14,0x00,0x02,0x8E,0x26,0x08,0x14,0x00,0x02,0x8D,0x2B,0x08,0x14,0x00,0x02,0x4E,0x2C,0x04,0x14,0x00,0x02,0x35,0x28,0x04,0x12,0x00,0x02,0xFA,0x17,0x04,0x12,0x00,0x02,0x84,0xF9,0xFF,0x0F,0x00,0x02,0x02,0x07,0x04,0x08,0x00,0x02,0x00,0x00,0x08,0x10,0x00,0x02,0x00,0x00,0x10,0x20,0x00,0x03,0x00,0x00,0x20,0x40,0x00,0x02,0x00,0x00,0x40,0x80,0x00,0x0C,0xC0,0x01,0x80,0x00,0x01,0x30,0x20,0x06,0x00,0x01,0x02,0xC0,0x20,0x18,0x00,0x01,0x02,0x00,0x01,0x60,0x00,0x02,0x04,0x00,0x02,0x80,0x01,0x02,0x04,0x80,0x02,0x0F,0x06,0x04,0x04,0x00,0x02,0x3A,0x38,0xFC,0x07,0x01,0x02,0xD4,0xC0,0x07,0x03,0x0E,0x02,0xA8,0x03,0x80,0x00,0x70,0x02,0x40,0x1D,0x40,0x00,0x80,0x03,0x80,0xEA,0x3F,0x00,0x00,0x0C,0x00,0x55,0x35,0x00,0x00,0x30,0x00,0xAA,0x2A,0x00,0x00,0xC0,0x00,0x54,0x35,0x00,0x00,0x00,0x01,0xA0,0x6A,0x00,0x00,0x40,0x01,0x00,0x45,0x00,0x00,0x00,0x01,0x00,0x40,0x00,0x00,0x00,0x01,0x00,0x40,0x00,}; -const uint8_t *_I_passport_bad3_43x45[] = {_I_passport_bad3_43x45_0}; - -const uint8_t _I_passport_okay2_43x45_0[] = {0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x9E,0xE3,0x00,0x00,0x00,0x80,0x61,0x00,0x07,0x00,0x00,0x60,0x10,0x00,0x18,0x00,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x08,0x04,0x00,0x40,0x00,0x00,0x04,0x04,0x00,0x80,0x00,0x00,0x04,0x02,0x00,0x80,0x00,0x00,0x02,0x03,0x00,0x00,0x01,0x00,0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x03,0x00,0x00,0x02,0x80,0x80,0x05,0xFE,0x00,0x02,0x80,0x80,0x02,0x01,0x01,0x04,0x80,0x80,0x85,0x7C,0x02,0x04,0x80,0xFF,0x4A,0xFA,0x04,0x04,0x40,0x00,0x57,0xC5,0x04,0x00,0x40,0x01,0x78,0xE5,0x05,0x00,0x20,0x21,0x40,0xFD,0x15,0x00,0x20,0x21,0x40,0xFD,0x2D,0x00,0x20,0x21,0x40,0xF9,0x55,0x00,0x20,0x42,0x80,0x82,0x2C,0x00,0x20,0x42,0x80,0xFD,0x57,0x00,0x20,0x02,0x80,0x06,0x2A,0x00,0x40,0x00,0x78,0x02,0x14,0x00,0x40,0xE0,0x07,0x02,0x04,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x20,0x00,0x00,0x08,0x00,0x00,0x20,0x00,0x00,0x04,0x00,0x00,0x10,0x00,0x00,0x02,0x00,0x00,0x08,0x00,0x00,0x01,0x00,0x00,0x06,0x00,0x00,0x01,0x00,0x80,0x01,0x00,0x00,0x01,0x00,0x70,0x00,0x00,0x00,0xF9,0x00,0x0F,0x00,0x00,0x00,0x06,0xFF,0x00,0x00,0x06,0x00,0x04,0x00,0x00,0xC0,0x0B,0x00,0x08,0x00,0x00,0x78,0x05,0x00,0x30,0x00,0xF8,0xAF,0x02,0x00,0xC0,0xFF,0xFF,0x57,0x01,0x00,0x00,0xF8,0xBF,0x2A,0x00,0x00,0x00,0xF8,0x57,0x15,0x00,0x00,0x00,0xF8,0xAB,0x02,0x00,0x00,0x00,0xF8,0x55,0x01,0x00,0x00,0x00,0xF8,0xAA,0x00,0x00,0x00,}; -const uint8_t *_I_passport_okay2_43x45[] = {_I_passport_okay2_43x45_0}; - -const uint8_t _I_passport_bad2_43x45_0[] = {0x00,0xC0,0xFF,0x01,0x00,0x00,0x00,0x70,0x00,0x06,0x00,0x00,0x00,0xFC,0x07,0x18,0x00,0x00,0x00,0x02,0x1D,0x60,0x00,0x00,0x00,0x01,0x2A,0x80,0x00,0x00,0x80,0x00,0x50,0x00,0x01,0x00,0x40,0x00,0xA0,0x00,0x02,0x00,0x20,0x00,0xC0,0x00,0x04,0x00,0x10,0x00,0xA0,0x01,0x04,0x00,0x10,0x00,0x40,0x01,0x08,0x00,0x08,0xE0,0x81,0x02,0x08,0x00,0x08,0x18,0x06,0xE3,0x0F,0x00,0x04,0x04,0x88,0x1A,0x08,0x00,0x04,0x62,0x10,0x07,0x10,0x00,0x04,0xD2,0x91,0x41,0x14,0x00,0x02,0xCA,0x93,0x40,0x14,0x00,0x02,0xCA,0x66,0x44,0x14,0x00,0x02,0xCB,0x2F,0x44,0x14,0x00,0x82,0x8A,0x2F,0x44,0x14,0x00,0x02,0x15,0x14,0x04,0x10,0x00,0x82,0xFA,0x13,0x00,0x10,0x00,0x02,0x05,0x39,0xFC,0x0F,0x00,0x01,0x02,0xC6,0x03,0x08,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x20,0x00,0x01,0x00,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x80,0x00,0x01,0xC0,0x01,0x00,0x00,0x01,0x01,0x20,0x06,0x00,0x00,0x01,0x01,0x00,0x18,0x00,0x00,0x02,0x01,0x00,0x60,0x00,0x00,0x02,0x00,0x00,0x80,0x01,0x00,0x04,0x00,0x00,0x0F,0x06,0x00,0x04,0x00,0x00,0x3A,0x38,0xF8,0x07,0x00,0x00,0xD4,0xC0,0x07,0x02,0x00,0x00,0xA8,0x03,0x00,0x02,0x00,0x00,0x40,0x1D,0x80,0x01,0x00,0x00,0x80,0xEA,0x7F,0x00,0x00,0x00,0x00,0x55,0x0D,0x00,0x00,0x00,0x00,0xAA,0x0A,0x00,0x00,0x00,0x00,0x54,0x0D,0x00,0x00,0x00,0x00,0xA0,0x0A,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x00,}; -const uint8_t *_I_passport_bad2_43x45[] = {_I_passport_bad2_43x45_0}; - -const uint8_t _I_passport_okay3_43x45_0[] = {0x00,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x28,0xE0,0x00,0x00,0x00,0x00,0x5E,0x00,0x07,0x00,0x00,0x80,0xA1,0x00,0x1A,0x00,0x00,0x60,0x40,0x01,0x26,0x00,0x00,0x10,0x80,0x02,0x4A,0x00,0x00,0x08,0x80,0x02,0x85,0x00,0x00,0x04,0x00,0x01,0x83,0x00,0x00,0x02,0x00,0x01,0x05,0x01,0x00,0x02,0x00,0x02,0x03,0x01,0x00,0x01,0x00,0x82,0x01,0x02,0x00,0x01,0x00,0xFF,0x02,0x02,0x00,0xAB,0x80,0x80,0x01,0x04,0x00,0x55,0x41,0x3E,0x01,0x04,0x80,0xFF,0x22,0x41,0x02,0x04,0x40,0x40,0xA7,0xA2,0x02,0x02,0x40,0x40,0xB8,0x9C,0x06,0x02,0x20,0x20,0xA0,0x94,0x0A,0x02,0x20,0x20,0xA0,0x9C,0x06,0x01,0x20,0x20,0xA0,0xA2,0x0B,0x01,0x20,0x20,0xE0,0xC1,0x17,0x01,0x20,0x20,0xC0,0xFF,0x8B,0x00,0x20,0x40,0x80,0x03,0x95,0x00,0x40,0x40,0x78,0x01,0x4A,0x00,0x40,0xE0,0x1F,0x01,0x46,0x00,0x80,0x1F,0x05,0x00,0x40,0x00,0xC0,0xC0,0x02,0x20,0x80,0x00,0x30,0xB0,0x01,0x20,0x00,0x07,0x08,0x68,0x00,0x10,0x00,0x00,0x04,0x14,0x00,0x10,0x00,0x00,0x02,0x14,0x00,0x08,0x00,0x04,0x01,0x0A,0x00,0x04,0x00,0x02,0x01,0x0A,0x80,0x03,0x00,0x01,0x01,0x0A,0x70,0x00,0x00,0x01,0xF9,0x0A,0x0F,0x00,0x80,0x00,0x06,0xFF,0x00,0x00,0x86,0x00,0x04,0x00,0x00,0xC0,0x4B,0x00,0x08,0x00,0x00,0x78,0xA5,0x00,0x30,0x00,0xF8,0xAF,0x22,0x01,0xC0,0xFF,0xFF,0x57,0x41,0x02,0x00,0xF8,0xBF,0x2A,0x80,0x04,0x00,0xF8,0x57,0x15,0x00,0x01,0x00,0xF8,0xAB,0x02,0x00,0x02,0x00,0xF8,0x55,0x01,0x00,0x04,0x00,0xF8,0xAA,0x00,0x00,0x00,}; -const uint8_t *_I_passport_okay3_43x45[] = {_I_passport_okay3_43x45_0}; +const uint8_t _I_Medium_chip_22x21_0[] = {0xFC,0xFF,0x0F,0x02,0x00,0x10,0xF9,0xFF,0x27,0x85,0x52,0x28,0xC5,0xFF,0x28,0x25,0x00,0x29,0x95,0x67,0x2A,0x5D,0x60,0x2E,0x55,0x00,0x2A,0x1D,0x80,0x2E,0x55,0x80,0x2A,0x1D,0x80,0x2E,0x55,0x80,0x2A,0x5D,0x80,0x2E,0x95,0x7D,0x2A,0x25,0x00,0x29,0xC5,0xFF,0x28,0x85,0x52,0x28,0xF9,0xFF,0x27,0x02,0x00,0x10,0xFC,0xFF,0x0F,}; +const uint8_t *_I_Medium_chip_22x21[] = {_I_Medium_chip_22x21_0}; const uint8_t _I_passport_bad1_43x45_0[] = {0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0x30,0x80,0x03,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x02,0x00,0x30,0x00,0x00,0x00,0x01,0x00,0x40,0x00,0x00,0x80,0x00,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x10,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x04,0x60,0x30,0x00,0x08,0x00,0x04,0xD0,0x01,0x00,0x08,0x00,0x02,0xC8,0x03,0x00,0x08,0x00,0x02,0xCA,0x06,0x00,0x08,0x00,0x02,0xCD,0x0F,0x40,0x0D,0x00,0x02,0x8A,0x0F,0xA0,0x0A,0x00,0x02,0x15,0x04,0x50,0x05,0x00,0x02,0xFA,0x03,0xA8,0x06,0x00,0x02,0x04,0x01,0xF4,0x07,0x00,0x01,0x02,0x02,0x08,0x08,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x20,0x00,0x01,0x00,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x80,0x00,0x01,0xC0,0x01,0x00,0x00,0x01,0x01,0x20,0x06,0x00,0x00,0x01,0x01,0x00,0x18,0x00,0x00,0x02,0x01,0x00,0x60,0x00,0x00,0x02,0x00,0x00,0x80,0x01,0x00,0x04,0x00,0x00,0x0F,0x06,0x00,0x04,0x00,0x00,0x3A,0x38,0xF8,0x07,0x00,0x00,0xD4,0xC0,0x07,0x02,0x00,0x00,0xA8,0x03,0x00,0x02,0x00,0x00,0x40,0x1D,0x80,0x01,0x00,0x00,0x80,0xEA,0x7F,0x00,0x00,0x00,0x00,0x55,0x0D,0x00,0x00,0x00,0x00,0xAA,0x0A,0x00,0x00,0x00,0x00,0x54,0x0D,0x00,0x00,0x00,0x00,0xA0,0x0A,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x00,}; const uint8_t *_I_passport_bad1_43x45[] = {_I_passport_bad1_43x45_0}; -const uint8_t _I_passport_happy3_43x45_0[] = {0x00,0xFE,0x3F,0x00,0x00,0x00,0x80,0x05,0xE8,0x00,0x00,0x00,0x40,0x02,0xD4,0x07,0x00,0x00,0x20,0x01,0x68,0x08,0x00,0x00,0x10,0x01,0x14,0x10,0x70,0x00,0x08,0x01,0x0A,0x20,0x8E,0x01,0x08,0x02,0x05,0xE0,0x01,0x02,0x04,0xFE,0x0A,0x60,0x00,0x02,0x04,0x01,0x13,0xF0,0xC1,0x03,0x84,0x7C,0x22,0x0C,0x12,0x02,0x46,0x82,0x42,0x02,0x0C,0x01,0x4A,0xF9,0x82,0x01,0x02,0x01,0x4E,0xFD,0x42,0x80,0x80,0x00,0x7B,0xCF,0x23,0x40,0x40,0x00,0x55,0x27,0x1C,0x60,0x60,0x00,0x6A,0x1A,0x00,0xB0,0x20,0x00,0xC1,0x0C,0x00,0x58,0x11,0x00,0x81,0x09,0x00,0xAC,0x08,0x00,0x40,0x0F,0x00,0x56,0x05,0x00,0x80,0x8A,0x00,0xBF,0x06,0x00,0x41,0x85,0x80,0xFF,0x07,0x00,0x82,0x02,0xE3,0xC3,0x1F,0x00,0x04,0x00,0xFC,0x01,0x7F,0x00,0x08,0x00,0xF0,0x03,0xFC,0x03,0x10,0x00,0x80,0x3F,0xF0,0x07,0x20,0x00,0x00,0xC0,0xFF,0x07,0x21,0x00,0x00,0x00,0x00,0x04,0x23,0x8E,0x03,0x00,0x00,0x04,0x16,0xD3,0x04,0x00,0x00,0x07,0x8C,0x71,0x04,0x00,0xF0,0x01,0x98,0x61,0x44,0xFD,0x1F,0x00,0xB0,0x61,0x88,0xAA,0x02,0x00,0xE0,0x61,0x08,0x54,0x01,0x00,0xC0,0xC0,0x10,0xA8,0x01,0x00,0xC0,0xC0,0x10,0x40,0x01,0x00,0xC0,0xC0,0x20,0x00,0x02,0x00,0x60,0xC0,0x20,0x00,0x02,0x00,0x60,0xC0,0x40,0x00,0x02,0x00,0x30,0xC0,0x80,0x00,0x02,0x00,0x38,0xC0,0x80,0x00,0x04,0x00,0x1C,0xC0,0x00,0x01,0x04,0x00,0x0E,0xC0,0x00,0x02,0x08,0x00,0x06,0xE0,0x01,0x0C,0x08,0x00,0x03,0xE0,0x01,0x70,0x10,0x00,0x01,0xF0,0x03,0x80,0x33,0x00,}; -const uint8_t *_I_passport_happy3_43x45[] = {_I_passport_happy3_43x45_0}; +const uint8_t _I_passport_bad2_43x45_0[] = {0x00,0xC0,0xFF,0x01,0x00,0x00,0x00,0x70,0x00,0x06,0x00,0x00,0x00,0xFC,0x07,0x18,0x00,0x00,0x00,0x02,0x1D,0x60,0x00,0x00,0x00,0x01,0x2A,0x80,0x00,0x00,0x80,0x00,0x50,0x00,0x01,0x00,0x40,0x00,0xA0,0x00,0x02,0x00,0x20,0x00,0xC0,0x00,0x04,0x00,0x10,0x00,0xA0,0x01,0x04,0x00,0x10,0x00,0x40,0x01,0x08,0x00,0x08,0xE0,0x81,0x02,0x08,0x00,0x08,0x18,0x06,0xE3,0x0F,0x00,0x04,0x04,0x88,0x1A,0x08,0x00,0x04,0x62,0x10,0x07,0x10,0x00,0x04,0xD2,0x91,0x41,0x14,0x00,0x02,0xCA,0x93,0x40,0x14,0x00,0x02,0xCA,0x66,0x44,0x14,0x00,0x02,0xCB,0x2F,0x44,0x14,0x00,0x82,0x8A,0x2F,0x44,0x14,0x00,0x02,0x15,0x14,0x04,0x10,0x00,0x82,0xFA,0x13,0x00,0x10,0x00,0x02,0x05,0x39,0xFC,0x0F,0x00,0x01,0x02,0xC6,0x03,0x08,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x20,0x00,0x01,0x00,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x80,0x00,0x01,0xC0,0x01,0x00,0x00,0x01,0x01,0x20,0x06,0x00,0x00,0x01,0x01,0x00,0x18,0x00,0x00,0x02,0x01,0x00,0x60,0x00,0x00,0x02,0x00,0x00,0x80,0x01,0x00,0x04,0x00,0x00,0x0F,0x06,0x00,0x04,0x00,0x00,0x3A,0x38,0xF8,0x07,0x00,0x00,0xD4,0xC0,0x07,0x02,0x00,0x00,0xA8,0x03,0x00,0x02,0x00,0x00,0x40,0x1D,0x80,0x01,0x00,0x00,0x80,0xEA,0x7F,0x00,0x00,0x00,0x00,0x55,0x0D,0x00,0x00,0x00,0x00,0xAA,0x0A,0x00,0x00,0x00,0x00,0x54,0x0D,0x00,0x00,0x00,0x00,0xA0,0x0A,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x00,}; +const uint8_t *_I_passport_bad2_43x45[] = {_I_passport_bad2_43x45_0}; + +const uint8_t _I_passport_bad3_43x45_0[] = {0x00,0xC0,0xFF,0x01,0x00,0x00,0x00,0x30,0x00,0x02,0x00,0x00,0x00,0x0C,0x00,0x07,0x00,0x00,0x00,0x02,0xC0,0x18,0x00,0x00,0x00,0x01,0x20,0x20,0x00,0x00,0x80,0x01,0x10,0x40,0x00,0x00,0x40,0x01,0x08,0x80,0x00,0x00,0x20,0x01,0x08,0x80,0x00,0x00,0x10,0x01,0x08,0x00,0x01,0x00,0x10,0x01,0x04,0x50,0x01,0x00,0x08,0x02,0x04,0xAA,0x06,0x00,0x08,0xE2,0x07,0xD5,0x0F,0x00,0x04,0x14,0x88,0x3A,0x12,0x00,0x04,0xEC,0x50,0x07,0x12,0x00,0x04,0xF6,0xA1,0x04,0x14,0x00,0x02,0x8C,0x63,0x08,0x14,0x00,0x02,0x8E,0x26,0x08,0x14,0x00,0x02,0x8D,0x2B,0x08,0x14,0x00,0x02,0x4E,0x2C,0x04,0x14,0x00,0x02,0x35,0x28,0x04,0x12,0x00,0x02,0xFA,0x17,0x04,0x12,0x00,0x02,0x84,0xF9,0xFF,0x0F,0x00,0x02,0x02,0x07,0x04,0x08,0x00,0x02,0x00,0x00,0x08,0x10,0x00,0x02,0x00,0x00,0x10,0x20,0x00,0x03,0x00,0x00,0x20,0x40,0x00,0x02,0x00,0x00,0x40,0x80,0x00,0x0C,0xC0,0x01,0x80,0x00,0x01,0x30,0x20,0x06,0x00,0x01,0x02,0xC0,0x20,0x18,0x00,0x01,0x02,0x00,0x01,0x60,0x00,0x02,0x04,0x00,0x02,0x80,0x01,0x02,0x04,0x80,0x02,0x0F,0x06,0x04,0x04,0x00,0x02,0x3A,0x38,0xFC,0x07,0x01,0x02,0xD4,0xC0,0x07,0x03,0x0E,0x02,0xA8,0x03,0x80,0x00,0x70,0x02,0x40,0x1D,0x40,0x00,0x80,0x03,0x80,0xEA,0x3F,0x00,0x00,0x0C,0x00,0x55,0x35,0x00,0x00,0x30,0x00,0xAA,0x2A,0x00,0x00,0xC0,0x00,0x54,0x35,0x00,0x00,0x00,0x01,0xA0,0x6A,0x00,0x00,0x40,0x01,0x00,0x45,0x00,0x00,0x00,0x01,0x00,0x40,0x00,0x00,0x00,0x01,0x00,0x40,0x00,}; +const uint8_t *_I_passport_bad3_43x45[] = {_I_passport_bad3_43x45_0}; + +const uint8_t _I_passport_happy1_43x45_0[] = {0x00,0xF8,0x3F,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x80,0x00,0x00,0x03,0x00,0x00,0x40,0x00,0x00,0x04,0x00,0x00,0x20,0x00,0x00,0x08,0x70,0x00,0x10,0x00,0x00,0x10,0x8E,0x01,0x08,0x00,0x00,0xA0,0x01,0x02,0x08,0x00,0x00,0x60,0x00,0x02,0x04,0x00,0x00,0x30,0xC0,0x03,0x04,0x00,0x00,0x0C,0x10,0x02,0x02,0x70,0x00,0x06,0x0C,0x01,0x02,0xFC,0x01,0x01,0x02,0x01,0x02,0xFE,0x01,0x80,0x80,0x00,0x01,0xFF,0x03,0x40,0x40,0x00,0x01,0x2F,0x00,0x60,0x60,0x00,0x81,0x17,0x00,0xB0,0x20,0x00,0x41,0x0F,0x00,0x58,0x11,0x00,0x81,0x0A,0x00,0xAC,0x08,0x00,0x41,0x0D,0x00,0x56,0x05,0x00,0x81,0x8A,0x00,0xBF,0x06,0x00,0x40,0x85,0x80,0xFF,0x07,0x00,0x80,0x02,0xE3,0xC3,0x1F,0x00,0x00,0x00,0xFC,0x01,0x7F,0x00,0x00,0x00,0xF0,0x03,0xFC,0x03,0x00,0x00,0x80,0x3F,0xF0,0x07,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x8E,0x03,0x00,0x00,0x04,0x00,0xD3,0x04,0x00,0x00,0x07,0x80,0x71,0x04,0x00,0xF0,0x01,0x80,0x61,0x44,0xFD,0x1F,0x00,0x80,0x61,0x88,0xAA,0x02,0x00,0x80,0x61,0x08,0x54,0x01,0x00,0xC0,0xC0,0x10,0xA8,0x01,0x00,0xC0,0xC0,0x10,0x40,0x01,0x00,0xC0,0xC0,0x20,0x00,0x02,0x00,0x60,0xC0,0x20,0x00,0x02,0x00,0x60,0xC0,0x40,0x00,0x02,0x00,0x30,0xC0,0x80,0x00,0x02,0x00,0x38,0xC0,0x80,0x00,0x04,0x00,0x1C,0xC0,0x00,0x01,0x04,0x00,0x0E,0xC0,0x00,0x02,0x08,0x00,0x06,0xE0,0x01,0x0C,0x08,0x00,0x03,0xE0,0x01,0x70,0x10,0x00,0x01,0xF0,0x03,0x80,0x33,0x00,}; +const uint8_t *_I_passport_happy1_43x45[] = {_I_passport_happy1_43x45_0}; const uint8_t _I_passport_happy2_43x45_0[] = {0x00,0xF8,0x3F,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x80,0x00,0x80,0x0F,0x00,0x00,0x40,0x1F,0x60,0x10,0x00,0x00,0xE0,0xEA,0x10,0x24,0x70,0x00,0x10,0x54,0x49,0x68,0x8E,0x01,0x08,0xA0,0x86,0xE8,0x01,0x02,0x08,0x78,0x05,0x61,0x00,0x02,0x04,0xC6,0x12,0x31,0xC0,0x03,0x04,0x01,0x23,0x0C,0x10,0x02,0x82,0x70,0x22,0x06,0x0C,0x01,0x82,0xFC,0x02,0x01,0x02,0x01,0x42,0xFE,0xC2,0x80,0x80,0x00,0x41,0xFF,0x23,0x40,0x40,0x00,0x41,0x2F,0x1C,0x60,0x60,0x00,0x41,0x16,0x00,0xB0,0x20,0x00,0xC1,0x08,0x00,0x58,0x11,0x00,0x81,0x0F,0x00,0xAC,0x08,0x00,0x41,0x0D,0x00,0x56,0x05,0x00,0x81,0x8A,0x00,0xBF,0x06,0x00,0x40,0x85,0x80,0xFF,0x07,0x00,0x80,0x02,0xE3,0xC3,0x1F,0x00,0x00,0x00,0xFC,0x01,0x7F,0x00,0x00,0x00,0xF0,0x03,0xFC,0x03,0x00,0x00,0x80,0x3F,0xF0,0x07,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x8E,0x03,0x00,0x00,0x04,0x00,0xD3,0x04,0x00,0x00,0x07,0x80,0x71,0x04,0x00,0xF0,0x01,0x80,0x61,0x44,0xFD,0x1F,0x00,0x80,0x61,0x88,0xAA,0x02,0x00,0x80,0x61,0x08,0x54,0x01,0x00,0xC0,0xC0,0x10,0xA8,0x01,0x00,0xC0,0xC0,0x10,0x40,0x01,0x00,0xC0,0xC0,0x20,0x00,0x02,0x00,0x60,0xC0,0x20,0x00,0x02,0x00,0x60,0xC0,0x40,0x00,0x02,0x00,0x30,0xC0,0x80,0x00,0x02,0x00,0x38,0xC0,0x80,0x00,0x04,0x00,0x1C,0xC0,0x00,0x01,0x04,0x00,0x0E,0xC0,0x00,0x02,0x08,0x00,0x06,0xE0,0x01,0x0C,0x08,0x00,0x03,0xE0,0x01,0x70,0x10,0x00,0x01,0xF0,0x03,0x80,0x33,0x00,}; const uint8_t *_I_passport_happy2_43x45[] = {_I_passport_happy2_43x45_0}; +const uint8_t _I_passport_happy3_43x45_0[] = {0x00,0xFE,0x3F,0x00,0x00,0x00,0x80,0x05,0xE8,0x00,0x00,0x00,0x40,0x02,0xD4,0x07,0x00,0x00,0x20,0x01,0x68,0x08,0x00,0x00,0x10,0x01,0x14,0x10,0x70,0x00,0x08,0x01,0x0A,0x20,0x8E,0x01,0x08,0x02,0x05,0xE0,0x01,0x02,0x04,0xFE,0x0A,0x60,0x00,0x02,0x04,0x01,0x13,0xF0,0xC1,0x03,0x84,0x7C,0x22,0x0C,0x12,0x02,0x46,0x82,0x42,0x02,0x0C,0x01,0x4A,0xF9,0x82,0x01,0x02,0x01,0x4E,0xFD,0x42,0x80,0x80,0x00,0x7B,0xCF,0x23,0x40,0x40,0x00,0x55,0x27,0x1C,0x60,0x60,0x00,0x6A,0x1A,0x00,0xB0,0x20,0x00,0xC1,0x0C,0x00,0x58,0x11,0x00,0x81,0x09,0x00,0xAC,0x08,0x00,0x40,0x0F,0x00,0x56,0x05,0x00,0x80,0x8A,0x00,0xBF,0x06,0x00,0x41,0x85,0x80,0xFF,0x07,0x00,0x82,0x02,0xE3,0xC3,0x1F,0x00,0x04,0x00,0xFC,0x01,0x7F,0x00,0x08,0x00,0xF0,0x03,0xFC,0x03,0x10,0x00,0x80,0x3F,0xF0,0x07,0x20,0x00,0x00,0xC0,0xFF,0x07,0x21,0x00,0x00,0x00,0x00,0x04,0x23,0x8E,0x03,0x00,0x00,0x04,0x16,0xD3,0x04,0x00,0x00,0x07,0x8C,0x71,0x04,0x00,0xF0,0x01,0x98,0x61,0x44,0xFD,0x1F,0x00,0xB0,0x61,0x88,0xAA,0x02,0x00,0xE0,0x61,0x08,0x54,0x01,0x00,0xC0,0xC0,0x10,0xA8,0x01,0x00,0xC0,0xC0,0x10,0x40,0x01,0x00,0xC0,0xC0,0x20,0x00,0x02,0x00,0x60,0xC0,0x20,0x00,0x02,0x00,0x60,0xC0,0x40,0x00,0x02,0x00,0x30,0xC0,0x80,0x00,0x02,0x00,0x38,0xC0,0x80,0x00,0x04,0x00,0x1C,0xC0,0x00,0x01,0x04,0x00,0x0E,0xC0,0x00,0x02,0x08,0x00,0x06,0xE0,0x01,0x0C,0x08,0x00,0x03,0xE0,0x01,0x70,0x10,0x00,0x01,0xF0,0x03,0x80,0x33,0x00,}; +const uint8_t *_I_passport_happy3_43x45[] = {_I_passport_happy3_43x45_0}; + const uint8_t _I_passport_okay1_43x45_0[] = {0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x00,0x1C,0xC0,0x01,0x00,0x00,0x00,0x03,0x00,0x06,0x00,0x00,0xC0,0x00,0x00,0x18,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0x40,0x00,0x00,0x08,0x00,0x00,0x80,0x00,0x00,0x04,0x00,0x00,0x80,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x7C,0x00,0x04,0x80,0x00,0x00,0xFA,0x00,0x04,0x80,0x00,0x00,0xFD,0x01,0x04,0x80,0x00,0x80,0xC4,0x03,0x00,0x80,0x00,0x80,0xE4,0x03,0x00,0x80,0x00,0x80,0xFC,0x03,0x00,0x80,0x00,0x80,0xFC,0x0B,0x00,0x80,0x00,0x80,0xF8,0x16,0x00,0x80,0x00,0x00,0x01,0x2B,0x00,0x80,0x00,0x00,0xFA,0x15,0x00,0x00,0x01,0x00,0x04,0x2A,0x00,0x00,0x01,0x00,0x02,0x14,0x00,0x00,0xE1,0x03,0x00,0x0C,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x20,0x00,0x00,0x18,0x00,0x00,0x20,0x00,0x00,0x04,0x00,0x00,0x10,0x00,0x00,0x02,0x00,0x00,0x08,0x00,0x00,0x02,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x80,0x03,0x00,0x00,0x01,0x00,0x70,0x00,0x00,0x00,0xF9,0x03,0x0F,0x00,0x00,0x00,0x06,0xFC,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xC0,0x01,0x00,0x08,0x00,0x00,0x78,0x00,0x00,0x30,0x00,0xF8,0xAF,0x00,0x00,0xC0,0xFF,0xFF,0x57,0x00,0x00,0x00,0xF8,0xBF,0x2A,0x00,0x00,0x00,0xF8,0x57,0x15,0x00,0x00,0x00,0xF8,0xAB,0x02,0x00,0x00,0x00,0xF8,0x55,0x01,0x00,0x00,0x00,0xF8,0xAA,0x00,0x00,0x00,}; const uint8_t *_I_passport_okay1_43x45[] = {_I_passport_okay1_43x45_0}; -const uint8_t _I_Health_16x16_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x40,0x01,0x40,0x01,0x78,0x0F,0x08,0x08,0x78,0x0F,0x40,0x01,0x40,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_Health_16x16[] = {_I_Health_16x16_0}; +const uint8_t _I_passport_okay2_43x45_0[] = {0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x9E,0xE3,0x00,0x00,0x00,0x80,0x61,0x00,0x07,0x00,0x00,0x60,0x10,0x00,0x18,0x00,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x08,0x04,0x00,0x40,0x00,0x00,0x04,0x04,0x00,0x80,0x00,0x00,0x04,0x02,0x00,0x80,0x00,0x00,0x02,0x03,0x00,0x00,0x01,0x00,0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x03,0x00,0x00,0x02,0x80,0x80,0x05,0xFE,0x00,0x02,0x80,0x80,0x02,0x01,0x01,0x04,0x80,0x80,0x85,0x7C,0x02,0x04,0x80,0xFF,0x4A,0xFA,0x04,0x04,0x40,0x00,0x57,0xC5,0x04,0x00,0x40,0x01,0x78,0xE5,0x05,0x00,0x20,0x21,0x40,0xFD,0x15,0x00,0x20,0x21,0x40,0xFD,0x2D,0x00,0x20,0x21,0x40,0xF9,0x55,0x00,0x20,0x42,0x80,0x82,0x2C,0x00,0x20,0x42,0x80,0xFD,0x57,0x00,0x20,0x02,0x80,0x06,0x2A,0x00,0x40,0x00,0x78,0x02,0x14,0x00,0x40,0xE0,0x07,0x02,0x04,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x20,0x00,0x00,0x08,0x00,0x00,0x20,0x00,0x00,0x04,0x00,0x00,0x10,0x00,0x00,0x02,0x00,0x00,0x08,0x00,0x00,0x01,0x00,0x00,0x06,0x00,0x00,0x01,0x00,0x80,0x01,0x00,0x00,0x01,0x00,0x70,0x00,0x00,0x00,0xF9,0x00,0x0F,0x00,0x00,0x00,0x06,0xFF,0x00,0x00,0x06,0x00,0x04,0x00,0x00,0xC0,0x0B,0x00,0x08,0x00,0x00,0x78,0x05,0x00,0x30,0x00,0xF8,0xAF,0x02,0x00,0xC0,0xFF,0xFF,0x57,0x01,0x00,0x00,0xF8,0xBF,0x2A,0x00,0x00,0x00,0xF8,0x57,0x15,0x00,0x00,0x00,0xF8,0xAB,0x02,0x00,0x00,0x00,0xF8,0x55,0x01,0x00,0x00,0x00,0xF8,0xAA,0x00,0x00,0x00,}; +const uint8_t *_I_passport_okay2_43x45[] = {_I_passport_okay2_43x45_0}; -const uint8_t _I_FaceCharging_29x14_0[] = {0x40,0x00,0x00,0x02,0x60,0x00,0x00,0x03,0x30,0x00,0x80,0x01,0x18,0x00,0xC0,0x00,0xFC,0x00,0xE0,0x07,0xFC,0x00,0xE0,0x07,0x60,0x00,0x00,0x03,0x30,0x00,0x80,0x01,0x18,0x00,0xC0,0x00,0x08,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x00,0x00,0x08,0x02,0x00,0x00,0xF0,0x01,0x00,}; -const uint8_t *_I_FaceCharging_29x14[] = {_I_FaceCharging_29x14_0}; +const uint8_t _I_passport_okay3_43x45_0[] = {0x00,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x28,0xE0,0x00,0x00,0x00,0x00,0x5E,0x00,0x07,0x00,0x00,0x80,0xA1,0x00,0x1A,0x00,0x00,0x60,0x40,0x01,0x26,0x00,0x00,0x10,0x80,0x02,0x4A,0x00,0x00,0x08,0x80,0x02,0x85,0x00,0x00,0x04,0x00,0x01,0x83,0x00,0x00,0x02,0x00,0x01,0x05,0x01,0x00,0x02,0x00,0x02,0x03,0x01,0x00,0x01,0x00,0x82,0x01,0x02,0x00,0x01,0x00,0xFF,0x02,0x02,0x00,0xAB,0x80,0x80,0x01,0x04,0x00,0x55,0x41,0x3E,0x01,0x04,0x80,0xFF,0x22,0x41,0x02,0x04,0x40,0x40,0xA7,0xA2,0x02,0x02,0x40,0x40,0xB8,0x9C,0x06,0x02,0x20,0x20,0xA0,0x94,0x0A,0x02,0x20,0x20,0xA0,0x9C,0x06,0x01,0x20,0x20,0xA0,0xA2,0x0B,0x01,0x20,0x20,0xE0,0xC1,0x17,0x01,0x20,0x20,0xC0,0xFF,0x8B,0x00,0x20,0x40,0x80,0x03,0x95,0x00,0x40,0x40,0x78,0x01,0x4A,0x00,0x40,0xE0,0x1F,0x01,0x46,0x00,0x80,0x1F,0x05,0x00,0x40,0x00,0xC0,0xC0,0x02,0x20,0x80,0x00,0x30,0xB0,0x01,0x20,0x00,0x07,0x08,0x68,0x00,0x10,0x00,0x00,0x04,0x14,0x00,0x10,0x00,0x00,0x02,0x14,0x00,0x08,0x00,0x04,0x01,0x0A,0x00,0x04,0x00,0x02,0x01,0x0A,0x80,0x03,0x00,0x01,0x01,0x0A,0x70,0x00,0x00,0x01,0xF9,0x0A,0x0F,0x00,0x80,0x00,0x06,0xFF,0x00,0x00,0x86,0x00,0x04,0x00,0x00,0xC0,0x4B,0x00,0x08,0x00,0x00,0x78,0xA5,0x00,0x30,0x00,0xF8,0xAF,0x22,0x01,0xC0,0xFF,0xFF,0x57,0x41,0x02,0x00,0xF8,0xBF,0x2A,0x80,0x04,0x00,0xF8,0x57,0x15,0x00,0x01,0x00,0xF8,0xAB,0x02,0x00,0x02,0x00,0xF8,0x55,0x01,0x00,0x04,0x00,0xF8,0xAA,0x00,0x00,0x00,}; +const uint8_t *_I_passport_okay3_43x45[] = {_I_passport_okay3_43x45_0}; const uint8_t _I_BatteryBody_52x28_0[] = {0xC0,0xFC,0xFF,0xFF,0xFF,0xFF,0x0F,0xC0,0x0F,0x00,0x00,0x00,0x00,0x08,0x40,0xCD,0xFF,0xE4,0xFF,0x79,0x09,0xC0,0x0A,0x00,0x00,0x00,0x00,0x08,0x40,0x0D,0x00,0x00,0x00,0x00,0x0A,0xFE,0x0A,0x00,0x00,0x00,0x00,0x0A,0x77,0x0D,0x00,0x00,0x00,0x00,0x08,0xE3,0x0A,0x00,0x00,0x00,0x00,0x08,0x77,0x0D,0x00,0x00,0x00,0x00,0x0A,0xFE,0x0A,0x00,0x00,0x00,0x00,0x0A,0x40,0x0D,0x00,0x00,0x00,0x00,0x0A,0xC0,0x0A,0x00,0x00,0x00,0x00,0x0A,0x40,0x0D,0x00,0x00,0x00,0x00,0x0A,0xC0,0x0A,0x00,0x00,0x00,0x00,0x0A,0x40,0x0D,0x00,0x00,0x00,0x00,0x0A,0xC0,0x0A,0x00,0x00,0x00,0x00,0x0A,0x40,0x0D,0x00,0x00,0x00,0x00,0x0A,0xFE,0x0A,0x00,0x00,0x00,0x00,0x0A,0x7F,0x0D,0x00,0x00,0x00,0x00,0x0A,0xE3,0x0A,0x00,0x00,0x00,0x00,0x08,0x7F,0x0D,0x00,0x00,0x00,0x00,0x08,0xFE,0x0A,0x00,0x00,0x00,0x00,0x0A,0x40,0x0D,0x00,0x00,0x00,0x00,0x0A,0xC0,0x0A,0x00,0x00,0x00,0x00,0x0A,0x40,0x0D,0x00,0x00,0x00,0x00,0x0A,0xC0,0x4A,0xF1,0xE5,0x7F,0xF6,0x08,0xC0,0x0F,0x00,0x00,0x00,0x00,0x08,0xC0,0xFC,0xFF,0xFF,0xFF,0xFF,0x0F,}; const uint8_t *_I_BatteryBody_52x28[] = {_I_BatteryBody_52x28_0}; -const uint8_t _I_Voltage_16x16_0[] = {0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x80,0x01,0xC0,0x01,0xE0,0x00,0xF0,0x07,0x80,0x03,0xC0,0x01,0xC0,0x00,0x60,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_Voltage_16x16[] = {_I_Voltage_16x16_0}; +const uint8_t _I_Battery_16x16_0[] = {0x00,0x00,0x00,0x00,0x80,0x01,0xC0,0x03,0x20,0x04,0x20,0x04,0xA0,0x05,0x20,0x04,0xA0,0x05,0x20,0x04,0xA0,0x05,0x20,0x04,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_Battery_16x16[] = {_I_Battery_16x16_0}; -const uint8_t _I_Temperature_16x16_0[] = {0x00,0x00,0x00,0x00,0x80,0x00,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x20,0x02,0xE0,0x03,0xE0,0x03,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_Temperature_16x16[] = {_I_Temperature_16x16_0}; +const uint8_t _I_FaceCharging_29x14_0[] = {0x40,0x00,0x00,0x02,0x60,0x00,0x00,0x03,0x30,0x00,0x80,0x01,0x18,0x00,0xC0,0x00,0xFC,0x00,0xE0,0x07,0xFC,0x00,0xE0,0x07,0x60,0x00,0x00,0x03,0x30,0x00,0x80,0x01,0x18,0x00,0xC0,0x00,0x08,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x00,0x00,0x08,0x02,0x00,0x00,0xF0,0x01,0x00,}; +const uint8_t *_I_FaceCharging_29x14[] = {_I_FaceCharging_29x14_0}; + +const uint8_t _I_FaceConfused_29x14_0[] = {0x80,0x00,0x80,0x0F,0x38,0x01,0x40,0x10,0x44,0x01,0x20,0x07,0x52,0x01,0xA0,0x08,0x4A,0x01,0xA0,0x0A,0x32,0x91,0x24,0x09,0x84,0x48,0x42,0x04,0x78,0x24,0x81,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0F,0x00,0x00,0xFE,0x1F,0x00,0x00,0x0E,0x18,0x00,0x00,0xFE,0x1F,0x00,}; +const uint8_t *_I_FaceConfused_29x14[] = {_I_FaceConfused_29x14_0}; const uint8_t _I_FaceNopower_29x14_0[] = {0x00,0x00,0x00,0x00,0xC0,0x00,0x60,0x00,0xC0,0x00,0x60,0x00,0xE0,0x00,0xE0,0x00,0x7E,0x00,0xC0,0x0F,0x3E,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x0C,0x06,0x00,0x00,0xFE,0x0F,0x00,0x00,0xFE,0x0F,0x00,0x00,0x0E,0x0E,0x00,0x00,0x00,0x00,0x00,}; const uint8_t *_I_FaceNopower_29x14[] = {_I_FaceNopower_29x14_0}; @@ -423,111 +420,120 @@ const uint8_t *_I_FaceNopower_29x14[] = {_I_FaceNopower_29x14_0}; const uint8_t _I_FaceNormal_29x14_0[] = {0x00,0x00,0x00,0x00,0x3C,0x00,0x80,0x07,0x5E,0x00,0xC0,0x0B,0x7E,0x00,0xC0,0x0F,0x7E,0x00,0xC0,0x0F,0x7E,0x00,0xC0,0x0F,0x3C,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x00,0x08,0x02,0x00,0x00,0x08,0x02,0x00,0x00,0x10,0x01,0x00,0x00,0xE0,0x00,0x00,}; const uint8_t *_I_FaceNormal_29x14[] = {_I_FaceNormal_29x14_0}; -const uint8_t _I_Battery_16x16_0[] = {0x00,0x00,0x00,0x00,0x80,0x01,0xC0,0x03,0x20,0x04,0x20,0x04,0xA0,0x05,0x20,0x04,0xA0,0x05,0x20,0x04,0xA0,0x05,0x20,0x04,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_Battery_16x16[] = {_I_Battery_16x16_0}; +const uint8_t _I_Health_16x16_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x40,0x01,0x40,0x01,0x78,0x0F,0x08,0x08,0x78,0x0F,0x40,0x01,0x40,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_Health_16x16[] = {_I_Health_16x16_0}; -const uint8_t _I_FaceConfused_29x14_0[] = {0x80,0x00,0x80,0x0F,0x38,0x01,0x40,0x10,0x44,0x01,0x20,0x07,0x52,0x01,0xA0,0x08,0x4A,0x01,0xA0,0x0A,0x32,0x91,0x24,0x09,0x84,0x48,0x42,0x04,0x78,0x24,0x81,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0F,0x00,0x00,0xFE,0x1F,0x00,0x00,0x0E,0x18,0x00,0x00,0xFE,0x1F,0x00,}; -const uint8_t *_I_FaceConfused_29x14[] = {_I_FaceConfused_29x14_0}; +const uint8_t _I_Temperature_16x16_0[] = {0x00,0x00,0x00,0x00,0x80,0x00,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x20,0x02,0xE0,0x03,0xE0,0x03,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_Temperature_16x16[] = {_I_Temperature_16x16_0}; -const uint8_t _I_RFIDDolphinSuccess_108x57_0[] = {0x00,0x00,0xC0,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xC0,0x07,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x30,0x1C,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x88,0x3F,0x00,0x00,0x08,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xC4,0x73,0x00,0x00,0x08,0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xE4,0x61,0x00,0x00,0xC8,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xE2,0xE1,0x00,0x00,0x38,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xF2,0xF3,0x00,0x00,0x0C,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xF2,0xFF,0x00,0x00,0x03,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x80,0xF2,0xFF,0x00,0xC0,0x00,0xC0,0x27,0x00,0x00,0x20,0x00,0x00,0x20,0x40,0xF3,0xFF,0x00,0x30,0x00,0xB0,0x2A,0x00,0x00,0x20,0x00,0x00,0x20,0xA0,0xE6,0x7F,0x00,0x00,0x00,0x58,0x15,0x00,0x00,0x04,0x02,0x00,0x20,0x40,0xE5,0x7F,0x00,0x00,0x00,0xAE,0x1A,0x00,0x00,0x24,0x02,0x00,0x10,0xA0,0xEA,0x3F,0x00,0x00,0x00,0x55,0x0D,0x00,0x40,0x00,0x20,0x00,0x10,0x40,0x1D,0x1C,0x00,0x00,0xC0,0xAA,0x0A,0x00,0x80,0x00,0x10,0x00,0x10,0xA0,0x06,0x10,0x00,0x00,0x60,0x55,0x05,0x00,0x00,0x24,0x01,0x01,0x10,0x40,0x03,0x20,0x00,0x00,0xB8,0xAA,0x02,0x00,0x18,0x24,0x05,0x00,0x10,0x00,0x02,0x20,0x00,0x00,0x54,0x55,0x01,0x00,0x00,0xFC,0xC1,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0xAB,0xAA,0x00,0x00,0x80,0x03,0x0E,0x00,0x10,0x00,0x00,0x00,0x00,0x80,0x55,0x55,0x00,0x00,0x04,0x1A,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0xE0,0xAA,0x2A,0x00,0x00,0x10,0x1A,0x02,0x00,0x10,0xE0,0x00,0x00,0x00,0x58,0x55,0x1D,0x00,0x00,0x83,0x03,0x4E,0x0E,0x10,0x10,0x03,0x02,0x00,0xFE,0xAA,0x06,0x00,0x00,0x00,0x02,0x02,0x00,0x10,0x08,0x0C,0x04,0x80,0xFF,0xD7,0x01,0x00,0x00,0x00,0x02,0x02,0x00,0x10,0x08,0x10,0x18,0xF8,0x07,0xFC,0x01,0x00,0x00,0x80,0x03,0xCE,0x00,0x10,0x08,0x20,0xE0,0xFF,0x00,0xF0,0x0F,0x00,0x00,0x30,0xFC,0x01,0x00,0x10,0x0C,0x40,0x00,0x7C,0x00,0xE0,0x3F,0x00,0x00,0x04,0x24,0x05,0x00,0x10,0x18,0x80,0x00,0xE0,0x00,0xC0,0xFF,0x00,0x00,0x80,0x24,0x01,0x01,0x10,0x14,0x80,0x00,0x00,0x07,0x80,0xFF,0x03,0x00,0x40,0x00,0x10,0x00,0x30,0x28,0x00,0x01,0x00,0x38,0x00,0xFF,0x07,0x00,0x00,0x20,0x20,0x00,0x30,0x34,0x00,0x01,0x00,0xC0,0x03,0xFE,0x0F,0x00,0x00,0x04,0x02,0x00,0x38,0x68,0x00,0x02,0x00,0x00,0xFC,0xFF,0x09,0x00,0x00,0x24,0x02,0x00,0x38,0x54,0x00,0x02,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x20,0x08,0x00,0x3C,0x6A,0x00,0x02,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x02,0x00,0x00,0x3C,0x54,0x00,0x04,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x70,0x00,0x00,0x3A,0x6A,0x00,0x04,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x88,0x00,0x00,0x3E,0x55,0x00,0x04,0x00,0x15,0x00,0x38,0x00,0x00,0x00,0x86,0x00,0x00,0xBB,0x6A,0x00,0x08,0x00,0xEA,0xFF,0x07,0x00,0x00,0x80,0x81,0x00,0x00,0x7D,0x55,0x00,0x08,0x00,0x54,0x55,0x00,0x00,0x00,0x70,0x80,0x00,0x00,0xBA,0x6A,0x00,0x08,0x00,0xA8,0xEA,0x03,0x00,0x00,0x0F,0x80,0x00,0x00,0x7D,0x55,0x00,0x10,0x00,0x40,0xD5,0x3C,0x00,0xF0,0x00,0x40,0x00,0x00,0xFA,0x2A,0x00,0x10,0x00,0x80,0xAA,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x00,0x7D,0x35,0x00,0x10,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0xFA,0x2A,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x00,0x75,0x35,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,}; -const uint8_t *_I_RFIDDolphinSuccess_108x57[] = {_I_RFIDDolphinSuccess_108x57_0}; +const uint8_t _I_Voltage_16x16_0[] = {0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x80,0x01,0xC0,0x01,0xE0,0x00,0xF0,0x07,0x80,0x03,0xC0,0x01,0xC0,0x00,0x60,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_Voltage_16x16[] = {_I_Voltage_16x16_0}; const uint8_t _I_RFIDBigChip_37x36_0[] = {0x06,0x00,0x00,0x00,0x00,0xE6,0xFF,0xFF,0xFF,0x07,0x12,0x00,0x00,0x00,0x08,0xC9,0xFF,0xFF,0xFF,0x13,0x25,0x00,0x00,0x00,0x14,0x15,0xC0,0xEA,0xFF,0x14,0x15,0x80,0x2A,0x00,0x15,0x15,0x80,0x2A,0x00,0x15,0x15,0x00,0x00,0x00,0x15,0x15,0x80,0x2A,0x00,0x15,0x15,0x80,0x2A,0x00,0x15,0x15,0xC0,0x7F,0x00,0x15,0x55,0x20,0x80,0x40,0x15,0x95,0x90,0x37,0x21,0x15,0x15,0x5D,0x30,0x17,0x15,0x55,0x50,0x00,0x41,0x15,0x95,0x1D,0x40,0x37,0x15,0x15,0x50,0x40,0x01,0x15,0x95,0x1D,0x40,0x37,0x15,0x55,0x50,0x40,0x41,0x15,0x15,0x5D,0x40,0x17,0x15,0x95,0x90,0x3E,0x21,0x15,0x55,0x20,0x80,0x40,0x15,0x15,0xC0,0x7F,0x00,0x15,0x15,0x80,0x2A,0x00,0x15,0x15,0x80,0x2A,0x00,0x15,0x15,0x00,0x00,0x00,0x15,0x15,0x80,0x2A,0x00,0x15,0x15,0x80,0x2A,0x00,0x15,0x15,0xC0,0x6A,0x00,0x15,0x15,0x00,0x00,0x00,0x15,0xE5,0xFF,0xFF,0xFF,0x14,0x05,0x00,0x00,0x00,0x14,0xF9,0xFF,0xFF,0xFF,0x13,0x02,0x00,0x00,0x00,0x08,0xFC,0xFF,0xFF,0xFF,0x07,}; const uint8_t *_I_RFIDBigChip_37x36[] = {_I_RFIDBigChip_37x36_0}; -const uint8_t _I_RFIDDolphinSend_97x61_0[] = {0x00,0x00,0xFE,0x1F,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xE0,0x01,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x06,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x18,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x00,0x00,0x01,0x01,0x00,0xA0,0x0A,0x00,0x00,0x01,0x00,0x00,0x40,0x00,0x00,0x02,0x02,0x00,0xA0,0x0A,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x02,0x02,0x00,0xF0,0x1F,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x04,0x02,0x00,0x08,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x04,0x00,0xE4,0x4D,0x00,0x20,0x00,0x00,0x00,0x3C,0x04,0x10,0x08,0x04,0x00,0x17,0xCC,0x01,0x10,0x00,0x00,0x00,0x42,0x04,0x20,0x08,0x04,0x00,0x14,0x40,0x00,0x10,0x00,0x00,0x00,0x81,0x08,0x20,0x08,0x04,0x00,0x07,0xD0,0x01,0x08,0x06,0x00,0x80,0x18,0x09,0x20,0x08,0x04,0x00,0x14,0x50,0x00,0x08,0x09,0x08,0x80,0x24,0x09,0x20,0x08,0x04,0x00,0x07,0xD0,0x01,0x84,0x10,0x08,0x80,0x24,0x11,0x20,0x08,0x04,0x00,0x14,0x50,0x00,0xC4,0x10,0x10,0x80,0x24,0x11,0x10,0x08,0x04,0x00,0x17,0xD0,0x01,0x44,0x10,0x10,0x80,0x24,0x11,0x00,0x04,0x04,0x00,0xA4,0x4F,0x00,0x46,0x20,0x20,0x80,0x24,0x11,0x00,0x04,0x02,0x00,0x08,0x20,0x00,0x2A,0x20,0x20,0x80,0x24,0x11,0x00,0x02,0x02,0x00,0xF0,0x1F,0x00,0x36,0x20,0x40,0x80,0x18,0x11,0x00,0x02,0x02,0x00,0xA0,0x0A,0x00,0x1B,0xE0,0x80,0x00,0x81,0x10,0x00,0x01,0x01,0x00,0xA0,0x0A,0x00,0x0D,0xE0,0x00,0x01,0x42,0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x07,0xE0,0x01,0x00,0x3C,0x18,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x03,0xF0,0x01,0x00,0x00,0x14,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x01,0xF0,0x03,0x00,0x00,0x0A,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0xFF,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x3C,0x00,0x1F,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x60,0x80,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x02,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x18,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x02,0x20,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xC0,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x02,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x01,0x00,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB0,0x00,0x14,0x08,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x6A,0x30,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0x00,0xD4,0x41,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x00,0xA8,0x83,0x01,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2A,0x00,0x50,0x0F,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0xA0,0x1E,0xFC,0x5F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x40,0x7D,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0xA0,0xFA,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF5,0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEA,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0x5F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x9E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_RFIDDolphinSend_97x61[] = {_I_RFIDDolphinSend_97x61_0}; - const uint8_t _I_RFIDDolphinReceive_97x61_0[] = {0x00,0x00,0xFE,0x1F,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xE0,0x01,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x06,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x18,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x00,0x40,0x40,0x00,0x00,0xA0,0x0A,0x00,0x00,0x01,0x00,0x00,0x40,0x00,0x20,0x20,0x00,0x00,0xA0,0x0A,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x20,0x20,0x00,0x00,0xF0,0x1F,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0x20,0x10,0x00,0x00,0x08,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x10,0x10,0x00,0x00,0xE4,0x4D,0x00,0x20,0x00,0x00,0x00,0x3C,0x04,0x10,0x08,0x04,0x00,0x17,0xCC,0x01,0x10,0x00,0x00,0x00,0x42,0x04,0x10,0x08,0x02,0x00,0x14,0x40,0x00,0x10,0x00,0x00,0x00,0x81,0x08,0x10,0x08,0x02,0x00,0x07,0xD0,0x01,0x08,0x06,0x00,0x80,0x18,0x09,0x10,0x08,0x02,0x00,0x14,0x50,0x00,0x08,0x09,0x08,0x80,0x24,0x09,0x10,0x08,0x02,0x00,0x07,0xD0,0x01,0x84,0x10,0x08,0x80,0x24,0x11,0x10,0x08,0x02,0x00,0x14,0x50,0x00,0xC4,0x10,0x10,0x80,0x24,0x11,0x10,0x08,0x04,0x00,0x17,0xD0,0x01,0x44,0x10,0x10,0x80,0x24,0x11,0x10,0x10,0x00,0x00,0xA4,0x4F,0x00,0x46,0x20,0x20,0x80,0x24,0x11,0x20,0x10,0x00,0x00,0x08,0x20,0x00,0x2A,0x20,0x20,0x80,0x24,0x11,0x20,0x20,0x00,0x00,0xF0,0x1F,0x00,0x36,0x20,0x40,0x80,0x18,0x11,0x20,0x20,0x00,0x00,0xA0,0x0A,0x00,0x1B,0xE0,0x80,0x00,0x81,0x10,0x40,0x40,0x00,0x00,0xA0,0x0A,0x00,0x0D,0xE0,0x00,0x01,0x42,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x01,0x00,0x3C,0x18,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xF0,0x01,0x00,0x00,0x14,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xF0,0x03,0x00,0x00,0x0A,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0xFF,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x3C,0x00,0x1F,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x60,0x80,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x02,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x18,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x02,0x20,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xC0,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x02,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x01,0x00,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB0,0x00,0x14,0x08,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x6A,0x30,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0x00,0xD4,0x41,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x00,0xA8,0x83,0x01,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2A,0x00,0x50,0x0F,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0xA0,0x1E,0xFC,0x5F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x40,0x7D,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0xA0,0xFA,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF5,0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEA,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0x5F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x9E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; const uint8_t *_I_RFIDDolphinReceive_97x61[] = {_I_RFIDDolphinReceive_97x61_0}; -const uint8_t _I_SDQuestion_35x43_0[] = {0xF0,0xFF,0xFF,0xFF,0x03,0xF8,0xFF,0xFF,0xFF,0x07,0x38,0x49,0x92,0x24,0x07,0x38,0x49,0x92,0x24,0x07,0x38,0x49,0x92,0x24,0x07,0x38,0x49,0x92,0x24,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0x80,0xFF,0x07,0xF8,0x7F,0x00,0xFF,0x07,0xF8,0x3F,0x00,0xFE,0x07,0xF4,0x1F,0x3E,0xFC,0x07,0xFA,0x0F,0x7F,0xF8,0x07,0xFD,0x8F,0xFF,0xF8,0x07,0xFF,0x8F,0xFF,0xF8,0x07,0xFF,0x8F,0xFF,0xF8,0x07,0xFF,0x8F,0xFF,0xF8,0x07,0xFF,0xDF,0x7F,0xF8,0x07,0xFF,0xFF,0x3F,0xFC,0x07,0xFC,0xFF,0x1F,0xFE,0x07,0xFC,0xFF,0x0F,0xFF,0x07,0xFC,0xFF,0x87,0xFF,0x07,0xFC,0xFF,0xC7,0xFF,0x07,0xF4,0xFF,0xE3,0xFF,0x07,0xFA,0xFF,0xE3,0xFF,0x07,0xFD,0xFF,0xE3,0xFF,0x07,0xFF,0xFF,0xE3,0xFF,0x07,0xFF,0xFF,0xF7,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xE3,0xFF,0x07,0xFF,0xFF,0xE3,0xFF,0x07,0xFF,0xFF,0xE3,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFE,0xFF,0xFF,0xFF,0x03,}; -const uint8_t *_I_SDQuestion_35x43[] = {_I_SDQuestion_35x43_0}; +const uint8_t _I_RFIDDolphinSend_97x61_0[] = {0x00,0x00,0xFE,0x1F,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xE0,0x01,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x06,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x18,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x00,0x00,0x01,0x01,0x00,0xA0,0x0A,0x00,0x00,0x01,0x00,0x00,0x40,0x00,0x00,0x02,0x02,0x00,0xA0,0x0A,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x02,0x02,0x00,0xF0,0x1F,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x04,0x02,0x00,0x08,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x04,0x00,0xE4,0x4D,0x00,0x20,0x00,0x00,0x00,0x3C,0x04,0x10,0x08,0x04,0x00,0x17,0xCC,0x01,0x10,0x00,0x00,0x00,0x42,0x04,0x20,0x08,0x04,0x00,0x14,0x40,0x00,0x10,0x00,0x00,0x00,0x81,0x08,0x20,0x08,0x04,0x00,0x07,0xD0,0x01,0x08,0x06,0x00,0x80,0x18,0x09,0x20,0x08,0x04,0x00,0x14,0x50,0x00,0x08,0x09,0x08,0x80,0x24,0x09,0x20,0x08,0x04,0x00,0x07,0xD0,0x01,0x84,0x10,0x08,0x80,0x24,0x11,0x20,0x08,0x04,0x00,0x14,0x50,0x00,0xC4,0x10,0x10,0x80,0x24,0x11,0x10,0x08,0x04,0x00,0x17,0xD0,0x01,0x44,0x10,0x10,0x80,0x24,0x11,0x00,0x04,0x04,0x00,0xA4,0x4F,0x00,0x46,0x20,0x20,0x80,0x24,0x11,0x00,0x04,0x02,0x00,0x08,0x20,0x00,0x2A,0x20,0x20,0x80,0x24,0x11,0x00,0x02,0x02,0x00,0xF0,0x1F,0x00,0x36,0x20,0x40,0x80,0x18,0x11,0x00,0x02,0x02,0x00,0xA0,0x0A,0x00,0x1B,0xE0,0x80,0x00,0x81,0x10,0x00,0x01,0x01,0x00,0xA0,0x0A,0x00,0x0D,0xE0,0x00,0x01,0x42,0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x07,0xE0,0x01,0x00,0x3C,0x18,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x03,0xF0,0x01,0x00,0x00,0x14,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x01,0xF0,0x03,0x00,0x00,0x0A,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0xFF,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x3C,0x00,0x1F,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x60,0x80,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x02,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x18,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x02,0x20,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xC0,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x02,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x01,0x00,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB0,0x00,0x14,0x08,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x6A,0x30,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0x00,0xD4,0x41,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x00,0xA8,0x83,0x01,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2A,0x00,0x50,0x0F,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0xA0,0x1E,0xFC,0x5F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x40,0x7D,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0xA0,0xFA,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF5,0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEA,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0x5F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x9E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_RFIDDolphinSend_97x61[] = {_I_RFIDDolphinSend_97x61_0}; + +const uint8_t _I_RFIDDolphinSuccess_108x57_0[] = {0x00,0x00,0xC0,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xC0,0x07,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x30,0x1C,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x88,0x3F,0x00,0x00,0x08,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xC4,0x73,0x00,0x00,0x08,0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xE4,0x61,0x00,0x00,0xC8,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xE2,0xE1,0x00,0x00,0x38,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xF2,0xF3,0x00,0x00,0x0C,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xF2,0xFF,0x00,0x00,0x03,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x80,0xF2,0xFF,0x00,0xC0,0x00,0xC0,0x27,0x00,0x00,0x20,0x00,0x00,0x20,0x40,0xF3,0xFF,0x00,0x30,0x00,0xB0,0x2A,0x00,0x00,0x20,0x00,0x00,0x20,0xA0,0xE6,0x7F,0x00,0x00,0x00,0x58,0x15,0x00,0x00,0x04,0x02,0x00,0x20,0x40,0xE5,0x7F,0x00,0x00,0x00,0xAE,0x1A,0x00,0x00,0x24,0x02,0x00,0x10,0xA0,0xEA,0x3F,0x00,0x00,0x00,0x55,0x0D,0x00,0x40,0x00,0x20,0x00,0x10,0x40,0x1D,0x1C,0x00,0x00,0xC0,0xAA,0x0A,0x00,0x80,0x00,0x10,0x00,0x10,0xA0,0x06,0x10,0x00,0x00,0x60,0x55,0x05,0x00,0x00,0x24,0x01,0x01,0x10,0x40,0x03,0x20,0x00,0x00,0xB8,0xAA,0x02,0x00,0x18,0x24,0x05,0x00,0x10,0x00,0x02,0x20,0x00,0x00,0x54,0x55,0x01,0x00,0x00,0xFC,0xC1,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0xAB,0xAA,0x00,0x00,0x80,0x03,0x0E,0x00,0x10,0x00,0x00,0x00,0x00,0x80,0x55,0x55,0x00,0x00,0x04,0x1A,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0xE0,0xAA,0x2A,0x00,0x00,0x10,0x1A,0x02,0x00,0x10,0xE0,0x00,0x00,0x00,0x58,0x55,0x1D,0x00,0x00,0x83,0x03,0x4E,0x0E,0x10,0x10,0x03,0x02,0x00,0xFE,0xAA,0x06,0x00,0x00,0x00,0x02,0x02,0x00,0x10,0x08,0x0C,0x04,0x80,0xFF,0xD7,0x01,0x00,0x00,0x00,0x02,0x02,0x00,0x10,0x08,0x10,0x18,0xF8,0x07,0xFC,0x01,0x00,0x00,0x80,0x03,0xCE,0x00,0x10,0x08,0x20,0xE0,0xFF,0x00,0xF0,0x0F,0x00,0x00,0x30,0xFC,0x01,0x00,0x10,0x0C,0x40,0x00,0x7C,0x00,0xE0,0x3F,0x00,0x00,0x04,0x24,0x05,0x00,0x10,0x18,0x80,0x00,0xE0,0x00,0xC0,0xFF,0x00,0x00,0x80,0x24,0x01,0x01,0x10,0x14,0x80,0x00,0x00,0x07,0x80,0xFF,0x03,0x00,0x40,0x00,0x10,0x00,0x30,0x28,0x00,0x01,0x00,0x38,0x00,0xFF,0x07,0x00,0x00,0x20,0x20,0x00,0x30,0x34,0x00,0x01,0x00,0xC0,0x03,0xFE,0x0F,0x00,0x00,0x04,0x02,0x00,0x38,0x68,0x00,0x02,0x00,0x00,0xFC,0xFF,0x09,0x00,0x00,0x24,0x02,0x00,0x38,0x54,0x00,0x02,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x20,0x08,0x00,0x3C,0x6A,0x00,0x02,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x02,0x00,0x00,0x3C,0x54,0x00,0x04,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x70,0x00,0x00,0x3A,0x6A,0x00,0x04,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x88,0x00,0x00,0x3E,0x55,0x00,0x04,0x00,0x15,0x00,0x38,0x00,0x00,0x00,0x86,0x00,0x00,0xBB,0x6A,0x00,0x08,0x00,0xEA,0xFF,0x07,0x00,0x00,0x80,0x81,0x00,0x00,0x7D,0x55,0x00,0x08,0x00,0x54,0x55,0x00,0x00,0x00,0x70,0x80,0x00,0x00,0xBA,0x6A,0x00,0x08,0x00,0xA8,0xEA,0x03,0x00,0x00,0x0F,0x80,0x00,0x00,0x7D,0x55,0x00,0x10,0x00,0x40,0xD5,0x3C,0x00,0xF0,0x00,0x40,0x00,0x00,0xFA,0x2A,0x00,0x10,0x00,0x80,0xAA,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x00,0x7D,0x35,0x00,0x10,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0xFA,0x2A,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x00,0x75,0x35,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,}; +const uint8_t *_I_RFIDDolphinSuccess_108x57[] = {_I_RFIDDolphinSuccess_108x57_0}; const uint8_t _I_SDError_43x35_0[] = {0xFE,0xFF,0xFF,0xFF,0xFF,0x03,0x01,0x00,0x00,0x00,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x04,0x3D,0x00,0x00,0x00,0x00,0x04,0x3D,0x00,0x00,0x00,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x04,0x3D,0x30,0x18,0x0C,0x06,0x04,0x3D,0x60,0x0C,0x18,0x03,0x04,0x01,0xC0,0x06,0xB0,0x01,0x04,0x3D,0x80,0x03,0xE0,0x00,0x04,0x3D,0x80,0x03,0xE0,0x00,0x04,0x01,0xC0,0x06,0xB0,0x01,0x04,0x3D,0x60,0x0C,0x18,0x03,0x04,0x3D,0x30,0x18,0x0C,0x06,0x04,0x01,0x00,0x00,0x00,0x00,0x04,0x3D,0x00,0x00,0x00,0x00,0x04,0x3D,0x00,0x00,0x00,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x04,0x3D,0x00,0xFC,0x3F,0x00,0x04,0x3D,0x00,0xFF,0xFF,0x00,0x04,0x01,0x80,0x1F,0xF9,0x01,0x04,0x3D,0xC0,0x2F,0xF2,0x03,0x04,0x3D,0xC0,0x5F,0xE4,0x03,0x04,0x01,0x80,0x83,0xE4,0x01,0x04,0x3D,0x08,0x80,0x20,0x10,0x04,0x3D,0x08,0x00,0x11,0x10,0x04,0x01,0x30,0x00,0x0E,0x0C,0x04,0x3D,0x00,0x00,0x00,0x00,0x04,0x3D,0x00,0x00,0x00,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x04,0xFE,0xFF,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x1F,0x00,0x04,0x00,0x00,0x82,0x20,0x00,0x04,0x00,0x00,0xFC,0xC0,0xFF,0x03,}; const uint8_t *_I_SDError_43x35[] = {_I_SDError_43x35_0}; -const uint8_t _I_WalkR2_32x32_0[] = {0x00,0x80,0x0F,0x00,0x00,0x40,0xF0,0x01,0x00,0x60,0x04,0x01,0x00,0x30,0x70,0x01,0x00,0x10,0x80,0x00,0x00,0x08,0x7E,0x00,0x00,0x08,0x17,0x00,0x00,0x04,0x15,0x00,0x00,0x84,0x22,0x00,0x00,0x42,0x25,0x00,0x00,0xAA,0x2A,0x00,0x00,0x69,0x45,0x00,0x00,0xA5,0x4A,0x00,0x00,0x65,0x55,0x00,0x00,0xA5,0x62,0x00,0x00,0x66,0x43,0x00,0x00,0xA4,0x02,0x00,0x00,0x68,0x01,0x00,0x00,0xA8,0x01,0x00,0x00,0x48,0x01,0x00,0x00,0x88,0x01,0x00,0x00,0x10,0x01,0x00,0x00,0x10,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0xA0,0x04,0x00,0x00,0x60,0x05,0x00,0x00,0x60,0x05,0x00,0x00,0x20,0x06,0x00,}; -const uint8_t *_I_WalkR2_32x32[] = {_I_WalkR2_32x32_0}; - -const uint8_t _I_WalkL2_32x32_0[] = {0x00,0xF0,0x01,0x00,0x80,0x0F,0x02,0x00,0x80,0x20,0x06,0x00,0x80,0x0E,0x0C,0x00,0x00,0x01,0x08,0x00,0x00,0x7E,0x10,0x00,0x00,0xE8,0x10,0x00,0x00,0xA8,0x20,0x00,0x00,0x44,0x21,0x00,0x00,0xA4,0x42,0x00,0x00,0x54,0x55,0x00,0x00,0xA2,0x96,0x00,0x00,0x52,0xA5,0x00,0x00,0xAA,0xA6,0x00,0x00,0x46,0xA5,0x00,0x00,0xC2,0x66,0x00,0x00,0x40,0x25,0x00,0x00,0x80,0x16,0x00,0x00,0x80,0x15,0x00,0x00,0x80,0x12,0x00,0x00,0x80,0x11,0x00,0x00,0x80,0x08,0x00,0x00,0x40,0x08,0x00,0x00,0x40,0x04,0x00,0x00,0x40,0x04,0x00,0x00,0x40,0x04,0x00,0x00,0x40,0x04,0x00,0x00,0x40,0x04,0x00,0x00,0x20,0x05,0x00,0x00,0xA0,0x06,0x00,0x00,0xA0,0x06,0x00,0x00,0x60,0x04,0x00,}; -const uint8_t *_I_WalkL2_32x32[] = {_I_WalkL2_32x32_0}; - -const uint8_t _I_WalkRB1_32x32_0[] = {0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0xE0,0xFF,0x01,0x00,0xF0,0xFF,0x01,0x00,0xF0,0xFF,0x01,0x00,0xF8,0xFF,0x00,0x00,0xF8,0x7F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFE,0x1F,0x00,0x00,0xFE,0x0F,0x00,0x00,0xFF,0x0F,0x00,0x00,0xFF,0x0F,0x00,0x00,0xFF,0x1F,0x00,0x00,0xFE,0x1F,0x00,0x00,0xFC,0x1B,0x00,0x00,0xFC,0x03,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF0,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x07,0x00,0x00,0xE0,0x07,0x00,0x00,0xF0,0x0F,0x00,0x00,0xF0,0x0F,0x00,0x00,0xF0,0x1C,0x00,0x00,0x38,0x10,0x00,0x00,0x08,0x20,0x00,}; -const uint8_t *_I_WalkRB1_32x32[] = {_I_WalkRB1_32x32_0}; +const uint8_t _I_SDQuestion_35x43_0[] = {0xF0,0xFF,0xFF,0xFF,0x03,0xF8,0xFF,0xFF,0xFF,0x07,0x38,0x49,0x92,0x24,0x07,0x38,0x49,0x92,0x24,0x07,0x38,0x49,0x92,0x24,0x07,0x38,0x49,0x92,0x24,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0xFF,0xFF,0x07,0xF8,0xFF,0x80,0xFF,0x07,0xF8,0x7F,0x00,0xFF,0x07,0xF8,0x3F,0x00,0xFE,0x07,0xF4,0x1F,0x3E,0xFC,0x07,0xFA,0x0F,0x7F,0xF8,0x07,0xFD,0x8F,0xFF,0xF8,0x07,0xFF,0x8F,0xFF,0xF8,0x07,0xFF,0x8F,0xFF,0xF8,0x07,0xFF,0x8F,0xFF,0xF8,0x07,0xFF,0xDF,0x7F,0xF8,0x07,0xFF,0xFF,0x3F,0xFC,0x07,0xFC,0xFF,0x1F,0xFE,0x07,0xFC,0xFF,0x0F,0xFF,0x07,0xFC,0xFF,0x87,0xFF,0x07,0xFC,0xFF,0xC7,0xFF,0x07,0xF4,0xFF,0xE3,0xFF,0x07,0xFA,0xFF,0xE3,0xFF,0x07,0xFD,0xFF,0xE3,0xFF,0x07,0xFF,0xFF,0xE3,0xFF,0x07,0xFF,0xFF,0xF7,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xE3,0xFF,0x07,0xFF,0xFF,0xE3,0xFF,0x07,0xFF,0xFF,0xE3,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x07,0xFE,0xFF,0xFF,0xFF,0x03,}; +const uint8_t *_I_SDQuestion_35x43[] = {_I_SDQuestion_35x43_0}; const uint8_t _I_Home_painting_17x20_0[] = {0xFC,0x7F,0x00,0x02,0x80,0x00,0xF9,0x3F,0x01,0x05,0x40,0x01,0x85,0x43,0x01,0xC5,0x47,0x01,0x65,0x4C,0x01,0x25,0x58,0x01,0x35,0x5B,0x01,0xB5,0x59,0x01,0xB5,0x58,0x01,0xB5,0x4D,0x01,0x25,0x47,0x01,0x65,0x40,0x01,0xC5,0x40,0x01,0x85,0x41,0x01,0x05,0x43,0x01,0xF9,0x3F,0x01,0x02,0x80,0x00,0xFC,0x7F,0x00,}; const uint8_t *_I_Home_painting_17x20[] = {_I_Home_painting_17x20_0}; -const uint8_t _I_WalkLB2_32x32_0[] = {0x00,0xF0,0x01,0x00,0x80,0xFF,0x03,0x00,0x80,0xFF,0x07,0x00,0x80,0xFF,0x0F,0x00,0x00,0xFF,0x0F,0x00,0x00,0xFE,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0xFC,0x3F,0x00,0x00,0xFC,0x7F,0x00,0x00,0xFC,0x7F,0x00,0x00,0xFE,0xFF,0x00,0x00,0xFE,0xFF,0x00,0x00,0xEE,0xFF,0x00,0x00,0xC6,0xFF,0x00,0x00,0xC2,0x7F,0x00,0x00,0xC0,0x3F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x0F,0x00,0x00,0xC0,0x0F,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x07,0x00,0x00,0xE0,0x07,0x00,0x00,0xE0,0x06,0x00,0x00,0xE0,0x06,0x00,0x00,0x60,0x04,0x00,}; -const uint8_t *_I_WalkLB2_32x32[] = {_I_WalkLB2_32x32_0}; +const uint8_t _I_PC_22x29_0[] = {0x80,0xFF,0x00,0x40,0x00,0x01,0xFE,0xFF,0x07,0x01,0x00,0x08,0xFF,0xFF,0x0B,0x01,0x00,0x0A,0x01,0x00,0x12,0x02,0x00,0x12,0x02,0x00,0x14,0x02,0x00,0x14,0x02,0x00,0x24,0x02,0x00,0x24,0x02,0x00,0x2C,0x04,0x00,0x28,0x04,0x00,0x38,0xFC,0xFF,0x1F,0x00,0x10,0x00,0x00,0x50,0x00,0xF0,0xFF,0x0F,0x10,0x00,0x08,0x48,0x6D,0x0D,0x88,0x00,0x05,0x24,0x24,0x04,0x34,0x33,0x07,0x04,0x00,0x06,0xFC,0xFF,0x03,0x90,0x90,0x00,0x10,0x8F,0x00,0xE0,0x7F,0x00,}; +const uint8_t *_I_PC_22x29[] = {_I_PC_22x29_0}; const uint8_t _I_Sofa_40x13_0[] = {0xC0,0xFF,0xC7,0xFF,0x03,0xE0,0xFF,0xFD,0xFF,0x05,0xF0,0xFF,0xF5,0xFF,0x0D,0xB6,0xAA,0xFA,0xAA,0x6A,0x7F,0x55,0x35,0x55,0xF5,0x9F,0xAA,0xB2,0xAA,0xF2,0x1F,0x00,0x30,0x00,0xF0,0x1B,0x00,0x10,0x00,0xB0,0xF9,0xFF,0xFF,0xFF,0x97,0xF9,0xFF,0xFF,0xFF,0x9F,0x59,0x55,0x55,0x55,0x95,0xA9,0xAA,0xAA,0xAA,0x9A,0xF7,0xFF,0xFF,0xFF,0xEF,}; const uint8_t *_I_Sofa_40x13[] = {_I_Sofa_40x13_0}; -const uint8_t _I_WalkLB1_32x32_0[] = {0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x80,0xFF,0x07,0x00,0x80,0xFF,0x0F,0x00,0x80,0xFF,0x0F,0x00,0x00,0xFF,0x1F,0x00,0x00,0xFE,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0xF8,0x3F,0x00,0x00,0xF8,0x7F,0x00,0x00,0xF0,0x7F,0x00,0x00,0xF0,0xFF,0x00,0x00,0xF0,0xFF,0x00,0x00,0xF8,0xFF,0x00,0x00,0xF8,0x7F,0x00,0x00,0xD8,0x3F,0x00,0x00,0xC0,0x3F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x0F,0x00,0x00,0xC0,0x0F,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x07,0x00,0x00,0xE0,0x07,0x00,0x00,0xE0,0x07,0x00,0x00,0xF0,0x0F,0x00,0x00,0xF0,0x0F,0x00,0x00,0x38,0x0F,0x00,0x00,0x08,0x1C,0x00,0x00,0x04,0x10,0x00,}; -const uint8_t *_I_WalkLB1_32x32[] = {_I_WalkLB1_32x32_0}; - -const uint8_t _I_PC_22x29_0[] = {0x80,0xFF,0x00,0x40,0x00,0x01,0xFE,0xFF,0x07,0x01,0x00,0x08,0xFF,0xFF,0x0B,0x01,0x00,0x0A,0x01,0x00,0x12,0x02,0x00,0x12,0x02,0x00,0x14,0x02,0x00,0x14,0x02,0x00,0x24,0x02,0x00,0x24,0x02,0x00,0x2C,0x04,0x00,0x28,0x04,0x00,0x38,0xFC,0xFF,0x1F,0x00,0x10,0x00,0x00,0x50,0x00,0xF0,0xFF,0x0F,0x10,0x00,0x08,0x48,0x6D,0x0D,0x88,0x00,0x05,0x24,0x24,0x04,0x34,0x33,0x07,0x04,0x00,0x06,0xFC,0xFF,0x03,0x90,0x90,0x00,0x10,0x8F,0x00,0xE0,0x7F,0x00,}; -const uint8_t *_I_PC_22x29[] = {_I_PC_22x29_0}; - -const uint8_t _I_WalkL1_32x32_0[] = {0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x80,0x0F,0x06,0x00,0x80,0x20,0x0E,0x00,0x80,0x0E,0x08,0x00,0x00,0x01,0x10,0x00,0x00,0x7E,0x10,0x00,0x00,0xA8,0x20,0x00,0x00,0x48,0x21,0x00,0x00,0x88,0x42,0x00,0x00,0x50,0x55,0x00,0x00,0x90,0x96,0x00,0x00,0x50,0x95,0x00,0x00,0x88,0x96,0x00,0x00,0x68,0x55,0x00,0x00,0xD8,0x36,0x00,0x00,0x40,0x25,0x00,0x00,0x80,0x16,0x00,0x00,0x80,0x15,0x00,0x00,0x80,0x12,0x00,0x00,0x80,0x11,0x00,0x00,0x80,0x08,0x00,0x00,0x40,0x08,0x00,0x00,0x40,0x04,0x00,0x00,0x40,0x04,0x00,0x00,0x20,0x04,0x00,0x00,0x20,0x04,0x00,0x00,0x10,0x09,0x00,0x00,0xD0,0x08,0x00,0x00,0x38,0x0B,0x00,0x00,0x08,0x1C,0x00,0x00,0x04,0x10,0x00,}; -const uint8_t *_I_WalkL1_32x32[] = {_I_WalkL1_32x32_0}; - const uint8_t _I_TV_20x20_0[] = {0xC0,0xFF,0x0F,0x20,0x00,0x08,0x10,0x00,0x0C,0x08,0x00,0x0E,0x04,0x00,0x0B,0x02,0x80,0x0D,0xFF,0xFF,0x0A,0xFD,0x5F,0x0D,0xFD,0xEF,0x0A,0xFB,0x77,0x0D,0xFB,0xFB,0x0A,0xFF,0x7F,0x0D,0x57,0xFD,0x0A,0xAF,0x7E,0x0D,0x57,0xFD,0x0A,0xAF,0x7E,0x0D,0x57,0xFD,0x06,0xAF,0x7E,0x03,0x57,0xFD,0x01,0xFF,0xFF,0x00,}; const uint8_t *_I_TV_20x20[] = {_I_TV_20x20_0}; -const uint8_t _I_WalkR1_32x32_0[] = {0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x60,0xF0,0x01,0x00,0x70,0x04,0x01,0x00,0x10,0x70,0x01,0x00,0x08,0x80,0x00,0x00,0x08,0x7E,0x00,0x00,0x04,0x15,0x00,0x00,0x84,0x12,0x00,0x00,0x42,0x11,0x00,0x00,0xAA,0x0A,0x00,0x00,0x69,0x09,0x00,0x00,0xA9,0x0A,0x00,0x00,0x69,0x11,0x00,0x00,0xAA,0x16,0x00,0x00,0x6C,0x1B,0x00,0x00,0xA4,0x02,0x00,0x00,0x68,0x01,0x00,0x00,0xA8,0x01,0x00,0x00,0x48,0x01,0x00,0x00,0x88,0x01,0x00,0x00,0x10,0x01,0x00,0x00,0x10,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x04,0x00,0x00,0x20,0x04,0x00,0x00,0x90,0x08,0x00,0x00,0x10,0x0B,0x00,0x00,0xD0,0x1C,0x00,0x00,0x38,0x10,0x00,0x00,0x08,0x20,0x00,}; -const uint8_t *_I_WalkR1_32x32[] = {_I_WalkR1_32x32_0}; - -const uint8_t _I_WalkRB2_32x32_0[] = {0x00,0x80,0x0F,0x00,0x00,0xC0,0xFF,0x01,0x00,0xE0,0xFF,0x01,0x00,0xF0,0xFF,0x01,0x00,0xF0,0xFF,0x00,0x00,0xF8,0x7F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x3F,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFF,0x7F,0x00,0x00,0xFF,0x7F,0x00,0x00,0xFF,0x77,0x00,0x00,0xFF,0x63,0x00,0x00,0xFE,0x43,0x00,0x00,0xFC,0x03,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF0,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x07,0x00,0x00,0x60,0x07,0x00,0x00,0x60,0x07,0x00,0x00,0x20,0x06,0x00,}; -const uint8_t *_I_WalkRB2_32x32[] = {_I_WalkRB2_32x32_0}; - const uint8_t _I_TV_20x24_0[] = {0x10,0x00,0x01,0x20,0x80,0x00,0x40,0x40,0x00,0x80,0x20,0x00,0xC0,0xFF,0x0F,0x20,0x0A,0x08,0x10,0x04,0x0C,0x08,0x00,0x0E,0x04,0x00,0x0B,0x02,0x80,0x0D,0xFF,0xFF,0x0A,0xFD,0x5F,0x0D,0xFD,0xEF,0x0A,0xFB,0x77,0x0D,0xFB,0xFB,0x0A,0xFF,0x7F,0x0D,0x57,0xFD,0x0A,0xAF,0x7E,0x0D,0x57,0xFD,0x0A,0xAF,0x7E,0x0D,0x57,0xDD,0x06,0xAF,0x6E,0x03,0x57,0xF5,0x01,0xFF,0xFF,0x00,}; const uint8_t *_I_TV_20x24[] = {_I_TV_20x24_0}; -const uint8_t _I_BadUsb_9x8_0[] = {0x01,0x01,0xBB,0x01,0xFE,0x00,0xFE,0x00,0xD6,0x00,0xD6,0x00,0x7C,0x00,0x38,0x00,}; -const uint8_t *_I_BadUsb_9x8[] = {_I_BadUsb_9x8_0}; +const uint8_t _I_WalkL1_32x32_0[] = {0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x80,0x0F,0x06,0x00,0x80,0x20,0x0E,0x00,0x80,0x0E,0x08,0x00,0x00,0x01,0x10,0x00,0x00,0x7E,0x10,0x00,0x00,0xA8,0x20,0x00,0x00,0x48,0x21,0x00,0x00,0x88,0x42,0x00,0x00,0x50,0x55,0x00,0x00,0x90,0x96,0x00,0x00,0x50,0x95,0x00,0x00,0x88,0x96,0x00,0x00,0x68,0x55,0x00,0x00,0xD8,0x36,0x00,0x00,0x40,0x25,0x00,0x00,0x80,0x16,0x00,0x00,0x80,0x15,0x00,0x00,0x80,0x12,0x00,0x00,0x80,0x11,0x00,0x00,0x80,0x08,0x00,0x00,0x40,0x08,0x00,0x00,0x40,0x04,0x00,0x00,0x40,0x04,0x00,0x00,0x20,0x04,0x00,0x00,0x20,0x04,0x00,0x00,0x10,0x09,0x00,0x00,0xD0,0x08,0x00,0x00,0x38,0x0B,0x00,0x00,0x08,0x1C,0x00,0x00,0x04,0x10,0x00,}; +const uint8_t *_I_WalkL1_32x32[] = {_I_WalkL1_32x32_0}; -const uint8_t _I_PlaceholderR_30x13_0[] = {0xFC,0xFF,0xFF,0x0F,0x02,0x00,0x00,0x10,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x03,0x00,0x00,0x30,0xFE,0xFF,0xFF,0x1F,0xFC,0xFF,0xFF,0x0F,}; -const uint8_t *_I_PlaceholderR_30x13[] = {_I_PlaceholderR_30x13_0}; +const uint8_t _I_WalkL2_32x32_0[] = {0x00,0xF0,0x01,0x00,0x80,0x0F,0x02,0x00,0x80,0x20,0x06,0x00,0x80,0x0E,0x0C,0x00,0x00,0x01,0x08,0x00,0x00,0x7E,0x10,0x00,0x00,0xE8,0x10,0x00,0x00,0xA8,0x20,0x00,0x00,0x44,0x21,0x00,0x00,0xA4,0x42,0x00,0x00,0x54,0x55,0x00,0x00,0xA2,0x96,0x00,0x00,0x52,0xA5,0x00,0x00,0xAA,0xA6,0x00,0x00,0x46,0xA5,0x00,0x00,0xC2,0x66,0x00,0x00,0x40,0x25,0x00,0x00,0x80,0x16,0x00,0x00,0x80,0x15,0x00,0x00,0x80,0x12,0x00,0x00,0x80,0x11,0x00,0x00,0x80,0x08,0x00,0x00,0x40,0x08,0x00,0x00,0x40,0x04,0x00,0x00,0x40,0x04,0x00,0x00,0x40,0x04,0x00,0x00,0x40,0x04,0x00,0x00,0x40,0x04,0x00,0x00,0x20,0x05,0x00,0x00,0xA0,0x06,0x00,0x00,0xA0,0x06,0x00,0x00,0x60,0x04,0x00,}; +const uint8_t *_I_WalkL2_32x32[] = {_I_WalkL2_32x32_0}; -const uint8_t _I_Background_128x8_0[] = {0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3D,0xFB,0xFD,0xA7,0xFD,0xEF,0xE1,0xC3,0xFD,0xF7,0x4F,0x3F,0x79,0xB7,0xFF,0x9A,0x41,0x00,0x00,0x08,0x00,0x00,0x1C,0x1C,0x00,0x00,0x10,0x80,0x02,0x00,0x00,0x84,0x9D,0xDF,0xB7,0x73,0xF7,0xFE,0xC3,0xE1,0xF6,0xAF,0xE7,0x37,0xD9,0xFB,0x67,0x9A,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,}; -const uint8_t *_I_Background_128x8[] = {_I_Background_128x8_0}; +const uint8_t _I_WalkLB1_32x32_0[] = {0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x80,0xFF,0x07,0x00,0x80,0xFF,0x0F,0x00,0x80,0xFF,0x0F,0x00,0x00,0xFF,0x1F,0x00,0x00,0xFE,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0xF8,0x3F,0x00,0x00,0xF8,0x7F,0x00,0x00,0xF0,0x7F,0x00,0x00,0xF0,0xFF,0x00,0x00,0xF0,0xFF,0x00,0x00,0xF8,0xFF,0x00,0x00,0xF8,0x7F,0x00,0x00,0xD8,0x3F,0x00,0x00,0xC0,0x3F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x0F,0x00,0x00,0xC0,0x0F,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x07,0x00,0x00,0xE0,0x07,0x00,0x00,0xE0,0x07,0x00,0x00,0xF0,0x0F,0x00,0x00,0xF0,0x0F,0x00,0x00,0x38,0x0F,0x00,0x00,0x08,0x1C,0x00,0x00,0x04,0x10,0x00,}; +const uint8_t *_I_WalkLB1_32x32[] = {_I_WalkLB1_32x32_0}; -const uint8_t _I_Lock_8x8_0[] = {0x3C,0x42,0x42,0xFF,0xFF,0xE7,0xFF,0xFF,}; -const uint8_t *_I_Lock_8x8[] = {_I_Lock_8x8_0}; +const uint8_t _I_WalkLB2_32x32_0[] = {0x00,0xF0,0x01,0x00,0x80,0xFF,0x03,0x00,0x80,0xFF,0x07,0x00,0x80,0xFF,0x0F,0x00,0x00,0xFF,0x0F,0x00,0x00,0xFE,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0xFC,0x3F,0x00,0x00,0xFC,0x7F,0x00,0x00,0xFC,0x7F,0x00,0x00,0xFE,0xFF,0x00,0x00,0xFE,0xFF,0x00,0x00,0xEE,0xFF,0x00,0x00,0xC6,0xFF,0x00,0x00,0xC2,0x7F,0x00,0x00,0xC0,0x3F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x1F,0x00,0x00,0x80,0x0F,0x00,0x00,0xC0,0x0F,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x07,0x00,0x00,0xE0,0x07,0x00,0x00,0xE0,0x06,0x00,0x00,0xE0,0x06,0x00,0x00,0x60,0x04,0x00,}; +const uint8_t *_I_WalkLB2_32x32[] = {_I_WalkLB2_32x32_0}; -const uint8_t _I_Battery_26x8_0[] = {0xFE,0xFF,0x7F,0x00,0x01,0x00,0x80,0x00,0x01,0x00,0x80,0x03,0x01,0x00,0x80,0x02,0x01,0x00,0x80,0x02,0x01,0x00,0x80,0x03,0x01,0x00,0x80,0x00,0xFE,0xFF,0x7F,0x00,}; -const uint8_t *_I_Battery_26x8[] = {_I_Battery_26x8_0}; +const uint8_t _I_WalkR1_32x32_0[] = {0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x60,0xF0,0x01,0x00,0x70,0x04,0x01,0x00,0x10,0x70,0x01,0x00,0x08,0x80,0x00,0x00,0x08,0x7E,0x00,0x00,0x04,0x15,0x00,0x00,0x84,0x12,0x00,0x00,0x42,0x11,0x00,0x00,0xAA,0x0A,0x00,0x00,0x69,0x09,0x00,0x00,0xA9,0x0A,0x00,0x00,0x69,0x11,0x00,0x00,0xAA,0x16,0x00,0x00,0x6C,0x1B,0x00,0x00,0xA4,0x02,0x00,0x00,0x68,0x01,0x00,0x00,0xA8,0x01,0x00,0x00,0x48,0x01,0x00,0x00,0x88,0x01,0x00,0x00,0x10,0x01,0x00,0x00,0x10,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x04,0x00,0x00,0x20,0x04,0x00,0x00,0x90,0x08,0x00,0x00,0x10,0x0B,0x00,0x00,0xD0,0x1C,0x00,0x00,0x38,0x10,0x00,0x00,0x08,0x20,0x00,}; +const uint8_t *_I_WalkR1_32x32[] = {_I_WalkR1_32x32_0}; -const uint8_t _I_PlaceholderL_11x13_0[] = {0xFC,0x01,0x02,0x02,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x03,0x06,0xFF,0x03,0xFE,0x01,}; -const uint8_t *_I_PlaceholderL_11x13[] = {_I_PlaceholderL_11x13_0}; +const uint8_t _I_WalkR2_32x32_0[] = {0x00,0x80,0x0F,0x00,0x00,0x40,0xF0,0x01,0x00,0x60,0x04,0x01,0x00,0x30,0x70,0x01,0x00,0x10,0x80,0x00,0x00,0x08,0x7E,0x00,0x00,0x08,0x17,0x00,0x00,0x04,0x15,0x00,0x00,0x84,0x22,0x00,0x00,0x42,0x25,0x00,0x00,0xAA,0x2A,0x00,0x00,0x69,0x45,0x00,0x00,0xA5,0x4A,0x00,0x00,0x65,0x55,0x00,0x00,0xA5,0x62,0x00,0x00,0x66,0x43,0x00,0x00,0xA4,0x02,0x00,0x00,0x68,0x01,0x00,0x00,0xA8,0x01,0x00,0x00,0x48,0x01,0x00,0x00,0x88,0x01,0x00,0x00,0x10,0x01,0x00,0x00,0x10,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0xA0,0x04,0x00,0x00,0x60,0x05,0x00,0x00,0x60,0x05,0x00,0x00,0x20,0x06,0x00,}; +const uint8_t *_I_WalkR2_32x32[] = {_I_WalkR2_32x32_0}; -const uint8_t _I_Battery_19x8_0[] = {0xFE,0xFF,0x01,0x01,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x06,0x01,0x00,0x06,0x01,0x00,0x02,0x01,0x00,0x02,0xFE,0xFF,0x01,}; -const uint8_t *_I_Battery_19x8[] = {_I_Battery_19x8_0}; +const uint8_t _I_WalkRB1_32x32_0[] = {0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0xE0,0xFF,0x01,0x00,0xF0,0xFF,0x01,0x00,0xF0,0xFF,0x01,0x00,0xF8,0xFF,0x00,0x00,0xF8,0x7F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFE,0x1F,0x00,0x00,0xFE,0x0F,0x00,0x00,0xFF,0x0F,0x00,0x00,0xFF,0x0F,0x00,0x00,0xFF,0x1F,0x00,0x00,0xFE,0x1F,0x00,0x00,0xFC,0x1B,0x00,0x00,0xFC,0x03,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF0,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x07,0x00,0x00,0xE0,0x07,0x00,0x00,0xF0,0x0F,0x00,0x00,0xF0,0x0F,0x00,0x00,0xF0,0x1C,0x00,0x00,0x38,0x10,0x00,0x00,0x08,0x20,0x00,}; +const uint8_t *_I_WalkRB1_32x32[] = {_I_WalkRB1_32x32_0}; -const uint8_t _I_SDcardMounted_11x8_0[] = {0xFF,0x07,0xFF,0x04,0xFF,0x07,0xFF,0x04,0xFF,0x07,0xFF,0x04,0xFF,0x07,0x67,0x00,}; -const uint8_t *_I_SDcardMounted_11x8[] = {_I_SDcardMounted_11x8_0}; - -const uint8_t _I_SDcardFail_11x8_0[] = {0xFF,0x07,0xB7,0x07,0xFF,0x07,0x87,0x07,0x7B,0x07,0xFF,0x07,0xFF,0x07,0x67,0x00,}; -const uint8_t *_I_SDcardFail_11x8[] = {_I_SDcardFail_11x8_0}; - -const uint8_t _I_USBConnected_15x8_0[] = {0xF0,0x07,0x08,0x7C,0x04,0x44,0x07,0x54,0x07,0x54,0x04,0x44,0x08,0x7C,0xF0,0x07,}; -const uint8_t *_I_USBConnected_15x8[] = {_I_USBConnected_15x8_0}; - -const uint8_t _I_Bluetooth_5x8_0[] = {0x04,0x0D,0x16,0x0C,0x0C,0x16,0x0D,0x04,}; -const uint8_t *_I_Bluetooth_5x8[] = {_I_Bluetooth_5x8_0}; +const uint8_t _I_WalkRB2_32x32_0[] = {0x00,0x80,0x0F,0x00,0x00,0xC0,0xFF,0x01,0x00,0xE0,0xFF,0x01,0x00,0xF0,0xFF,0x01,0x00,0xF0,0xFF,0x00,0x00,0xF8,0x7F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x3F,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFF,0x7F,0x00,0x00,0xFF,0x7F,0x00,0x00,0xFF,0x77,0x00,0x00,0xFF,0x63,0x00,0x00,0xFE,0x43,0x00,0x00,0xFC,0x03,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xF0,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x07,0x00,0x00,0x60,0x07,0x00,0x00,0x60,0x07,0x00,0x00,0x20,0x06,0x00,}; +const uint8_t *_I_WalkRB2_32x32[] = {_I_WalkRB2_32x32_0}; const uint8_t _I_Background_128x11_0[] = {0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x7D,0x06,0x00,0x00,0x00,0x00,0x00,0x18,0xFF,0xB7,0x55,0x31,0x00,0x00,0x00,0x00,0x81,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0x00,0x00,0x00,0xE2,0xFF,0xFF,0xFF,0x7F,0x3D,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0xB6,0xEA,0xFF,0x04,0x00,0x00,0x00,0x80,0x41,0xFE,0xFF,0xFF,0xAA,0xFE,0xFF,0x3F,0x01,0x00,0x00,0xF9,0xFF,0xFF,0xFF,0xAB,0x9F,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xF8,0xFF,0x7F,0x02,0x00,0x00,0x00,0x80,0x3E,0xFF,0xFF,0xFF,0xFF,0x55,0xFD,0x7F,0xFC,0xFF,0xFF,0x6C,0xFF,0xFF,0xFF,0xB5,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x80,0x01,0x00,0x00,0x00,0x80,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0x7F,}; const uint8_t *_I_Background_128x11[] = {_I_Background_128x11_0}; -const uint8_t _I_DolphinMafia_115x62_0[] = {0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2F,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x15,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAF,0x0A,0x00,0x40,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x55,0x15,0x00,0x80,0xF0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xAA,0x0A,0x00,0x80,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x15,0x00,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xAA,0x2A,0xE0,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x55,0xFC,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xAA,0xAA,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x55,0xD5,0xFF,0x7F,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xAA,0xFA,0xFF,0x2B,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x55,0xFD,0x7F,0x05,0xE8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAB,0xFE,0xAF,0x00,0xF1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xFF,0x15,0xE0,0x37,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEB,0xFF,0x0A,0xFC,0x7F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF6,0x7F,0x81,0xFF,0xEF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xFA,0xAF,0xE0,0x3F,0xEE,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xFE,0x57,0xF8,0x0F,0xCE,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xFF,0x2B,0xFC,0x1F,0x07,0x00,0x30,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0xC0,0xFF,0x15,0xFC,0xFF,0x07,0x00,0xC0,0x00,0x00,0x00,0x00,0x20,0x02,0x00,0xE0,0xBF,0x0A,0xFC,0xFF,0x03,0x00,0x00,0x01,0x00,0x00,0x00,0x18,0x01,0x00,0xF8,0x5F,0x05,0xF8,0xFF,0x03,0x00,0x00,0x02,0x00,0x00,0x60,0x86,0x00,0x00,0xFC,0xAF,0x02,0xFA,0xFF,0x01,0x00,0x00,0x02,0x00,0x30,0x1D,0x40,0x00,0x00,0xFF,0x57,0x01,0xF5,0x7F,0x00,0x00,0xC0,0x02,0x00,0x08,0x00,0x30,0x00,0x80,0xFF,0xAB,0x80,0xEA,0x1F,0x00,0x00,0xE0,0xFB,0x03,0x04,0x00,0x0E,0x00,0xC0,0xFF,0x57,0x00,0xF5,0x03,0x00,0x00,0xF8,0x02,0x00,0x04,0x60,0x01,0x00,0xE0,0xFF,0x2B,0x80,0x0A,0x04,0x00,0x00,0xC6,0xC2,0x0F,0x04,0x03,0x00,0x00,0xF0,0xFF,0x16,0x00,0x05,0x08,0x00,0x80,0x01,0x02,0x00,0xF0,0x00,0x00,0x00,0xF0,0x3F,0x0A,0x80,0x02,0x00,0x00,0x60,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x06,0x00,0x03,0x00,0x00,0x1C,0x00,0x01,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x82,0x00,0x00,0x03,0x80,0x00,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x82,0x00,0xE0,0x00,0x40,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x03,0x1E,0x00,0x30,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xFC,0x01,0x00,0x0E,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xE1,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xF8,0x10,0x03,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0xF0,0x04,0x00,0x00,0x04,0x10,0x04,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x0F,0x04,0x00,0x00,0x04,0x10,0x08,0x00,0x00,0x00,0xB0,0x01,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x04,0x10,0x08,0x00,0x00,0x00,0xD8,0xFF,0xFF,0xFF,0x3F,0x00,0x28,0x00,0x00,0x08,0x10,0x08,0x00,0x00,0x00,0xEC,0x01,0x00,0x00,0xE0,0x1F,0x28,0x00,0x00,0x10,0x10,0x08,0x00,0x00,0x00,0xD6,0x02,0x00,0x00,0x00,0x30,0x50,0x00,0x00,0x10,0x10,0x04,0x00,0x00,0x00,0xEB,0x05,0x00,0x00,0x00,0x50,0x50,0x00,0x00,0x10,0x20,0x02,0x00,0x00,0x80,0xD4,0x0A,0x00,0x00,0x00,0x90,0x50,0x00,0x00,0x08,0xC0,0x01,0x00,0x00,0x40,0xEA,0x15,0x00,0x00,0x00,0x08,0x61,0x00,0x00,0x0C,0x00,0x01,0x00,0x00,0x20,0xF4,0xFF,0xFF,0x01,0x00,0x08,0x62,0x00,0x00,0x12,0x80,0x00,0x00,0x00,0x10,0xEA,0x15,0x00,0xFE,0x00,0x08,0xE4,0x01,0x00,0x21,0x80,0x00,0x00,0x00,0x10,0xF4,0x0A,0x00,0x00,0x0F,0x04,0xA8,0x06,0xC0,0xC0,0x40,0x00,0x00,0x00,0x08,0xE8,0x05,0x00,0x00,0x30,0x04,0x50,0x19,0x38,0x01,0x47,0x00,0x00,0x00,0x04,0xF4,0x02,0x00,0x00,0xC0,0x04,0xC0,0xE2,0x07,0x06,0x38,0x00,0x00,0x00,0x04,0xF8,0x05,0x00,0x00,0x00,0x03,0x40,0x01,0x00,0x18,0x20,0x00,0x00,0x00,0x02,0xF0,0x02,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x60,0x10,0x00,0x00,0x00,0x02,0xF8,0x01,0x00,0x00,0x00,0x00,0x80,0x05,0x00,0x80,0x11,0x00,0x00,0x00,0x01,0xF0,0x02,0x00,0x00,0x00,0x00,0x80,0x0A,0x00,0x00,0x0E,0x00,0x00,0x00,}; -const uint8_t *_I_DolphinMafia_115x62[] = {_I_DolphinMafia_115x62_0}; +const uint8_t _I_Background_128x8_0[] = {0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3D,0xFB,0xFD,0xA7,0xFD,0xEF,0xE1,0xC3,0xFD,0xF7,0x4F,0x3F,0x79,0xB7,0xFF,0x9A,0x41,0x00,0x00,0x08,0x00,0x00,0x1C,0x1C,0x00,0x00,0x10,0x80,0x02,0x00,0x00,0x84,0x9D,0xDF,0xB7,0x73,0xF7,0xFE,0xC3,0xE1,0xF6,0xAF,0xE7,0x37,0xD9,0xFB,0x67,0x9A,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,}; +const uint8_t *_I_Background_128x8[] = {_I_Background_128x8_0}; + +const uint8_t _I_BadUsb_9x8_0[] = {0x01,0x01,0xBB,0x01,0xFE,0x00,0xFE,0x00,0xD6,0x00,0xD6,0x00,0x7C,0x00,0x38,0x00,}; +const uint8_t *_I_BadUsb_9x8[] = {_I_BadUsb_9x8_0}; + +const uint8_t _I_Battery_19x8_0[] = {0xFE,0xFF,0x01,0x01,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x06,0x01,0x00,0x06,0x01,0x00,0x02,0x01,0x00,0x02,0xFE,0xFF,0x01,}; +const uint8_t *_I_Battery_19x8[] = {_I_Battery_19x8_0}; + +const uint8_t _I_Battery_26x8_0[] = {0xFE,0xFF,0x7F,0x00,0x01,0x00,0x80,0x00,0x01,0x00,0x80,0x03,0x01,0x00,0x80,0x02,0x01,0x00,0x80,0x02,0x01,0x00,0x80,0x03,0x01,0x00,0x80,0x00,0xFE,0xFF,0x7F,0x00,}; +const uint8_t *_I_Battery_26x8[] = {_I_Battery_26x8_0}; + +const uint8_t _I_Bluetooth_5x8_0[] = {0x04,0x0D,0x16,0x0C,0x0C,0x16,0x0D,0x04,}; +const uint8_t *_I_Bluetooth_5x8[] = {_I_Bluetooth_5x8_0}; + +const uint8_t _I_Lock_8x8_0[] = {0x3C,0x42,0x42,0xFF,0xFF,0xE7,0xFF,0xFF,}; +const uint8_t *_I_Lock_8x8[] = {_I_Lock_8x8_0}; + +const uint8_t _I_PlaceholderL_11x13_0[] = {0xFC,0x01,0x02,0x02,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x03,0x06,0xFF,0x03,0xFE,0x01,}; +const uint8_t *_I_PlaceholderL_11x13[] = {_I_PlaceholderL_11x13_0}; + +const uint8_t _I_PlaceholderR_30x13_0[] = {0xFC,0xFF,0xFF,0x0F,0x02,0x00,0x00,0x10,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x03,0x00,0x00,0x30,0xFE,0xFF,0xFF,0x1F,0xFC,0xFF,0xFF,0x0F,}; +const uint8_t *_I_PlaceholderR_30x13[] = {_I_PlaceholderR_30x13_0}; + +const uint8_t _I_SDcardFail_11x8_0[] = {0xFF,0x07,0xB7,0x07,0xFF,0x07,0x87,0x07,0x7B,0x07,0xFF,0x07,0xFF,0x07,0x67,0x00,}; +const uint8_t *_I_SDcardFail_11x8[] = {_I_SDcardFail_11x8_0}; + +const uint8_t _I_SDcardMounted_11x8_0[] = {0xFF,0x07,0xFF,0x04,0xFF,0x07,0xFF,0x04,0xFF,0x07,0xFF,0x04,0xFF,0x07,0x67,0x00,}; +const uint8_t *_I_SDcardMounted_11x8[] = {_I_SDcardMounted_11x8_0}; + +const uint8_t _I_USBConnected_15x8_0[] = {0xF0,0x07,0x08,0x7C,0x04,0x44,0x07,0x54,0x07,0x54,0x04,0x44,0x08,0x7C,0xF0,0x07,}; +const uint8_t *_I_USBConnected_15x8[] = {_I_USBConnected_15x8_0}; const uint8_t _I_DolphinExcited_64x63_0[] = {0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x00,0x00,0x00,0xF8,0xFF,0x00,0x00,0x04,0x00,0x00,0x80,0x07,0x00,0x07,0x00,0x02,0x00,0x00,0x70,0x00,0x00,0x18,0x00,0x01,0x00,0x00,0x08,0x00,0x00,0x20,0x00,0x00,0x0E,0x00,0x04,0x00,0x00,0xC0,0x00,0xC0,0x01,0x00,0x02,0x00,0x00,0x00,0x01,0x38,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x08,0xE0,0x03,0x40,0x00,0x00,0x00,0x00,0x08,0x1C,0x0C,0x20,0x00,0x3C,0x00,0x00,0x10,0x03,0x10,0x20,0x00,0xC3,0x00,0x00,0x90,0x00,0x20,0x10,0x80,0x78,0x01,0x00,0x70,0x00,0x40,0x10,0x40,0xFE,0x03,0x00,0x18,0x00,0x40,0x08,0x40,0xCE,0x03,0x00,0x04,0x00,0x40,0x08,0x20,0x8F,0x07,0x00,0x03,0x00,0x5C,0x08,0x20,0x8F,0x07,0xC0,0x00,0x00,0x3F,0x04,0x20,0xFF,0x07,0x30,0x00,0x80,0x1F,0x04,0x20,0xFF,0x07,0x08,0x00,0xE0,0x0F,0x04,0x68,0xFE,0x03,0x00,0x00,0xF0,0x07,0x04,0x54,0xFE,0x03,0x00,0x00,0xFC,0x03,0x02,0xAA,0x78,0x01,0x00,0x00,0xFE,0x01,0x02,0x54,0xFF,0x01,0x00,0x00,0x7F,0x00,0x02,0xAA,0x06,0x06,0x00,0xC0,0x1F,0x00,0x02,0x54,0x01,0x08,0x00,0xE0,0x07,0x00,0x02,0xAA,0x00,0x00,0x00,0xF8,0x01,0x00,0x02,0x54,0x00,0x00,0x00,0x7E,0x00,0x00,0x01,0x28,0x00,0x00,0x80,0xBF,0x01,0x00,0x01,0x00,0x00,0x00,0xE0,0xE1,0x1F,0x00,0x01,0x00,0x40,0x00,0x38,0x80,0xF5,0x07,0x01,0x00,0x80,0x01,0x0F,0x00,0xAE,0x7A,0x01,0x00,0x00,0xFE,0x0F,0x00,0x58,0xD5,0x01,0x00,0x00,0x80,0xFF,0x00,0xA0,0xFA,0x01,0x00,0x00,0x00,0x00,0xFF,0xFF,0x8F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x01,0x00,0x00,0x00,0x00,0xE0,0x03,0x00,0x01,0x00,0x00,0x00,0xFF,0xDF,0x00,0x00,0x01,0x00,0x00,0x00,0xAA,0xAA,0x00,0x00,0x01,0x00,0x00,0x00,0x54,0xD5,0x00,0x00,0x01,0x00,0x00,0x00,0xA8,0xAA,0x00,0x00,0x01,0x00,0x00,0x00,0x54,0x55,0x01,0x00,0x01,0x00,0x00,0x00,0xA8,0xAA,0x01,0x00,0x01,0x00,0x00,0x00,0x50,0x55,0x01,0x00,0x02,0x00,0x00,0x00,0xA0,0xAA,0x02,0x00,0x02,0x00,0x00,0x00,0x40,0x55,0x03,0x00,0x02,0x00,0x00,0x00,0x80,0xAA,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x54,0x04,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x08,0x00,}; const uint8_t *_I_DolphinExcited_64x63[] = {_I_DolphinExcited_64x63_0}; +const uint8_t _I_DolphinMafia_115x62_0[] = {0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2F,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x15,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAF,0x0A,0x00,0x40,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x55,0x15,0x00,0x80,0xF0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xAA,0x0A,0x00,0x80,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x15,0x00,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xAA,0x2A,0xE0,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x55,0xFC,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xAA,0xAA,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x55,0xD5,0xFF,0x7F,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xAA,0xFA,0xFF,0x2B,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x55,0xFD,0x7F,0x05,0xE8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAB,0xFE,0xAF,0x00,0xF1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xFF,0x15,0xE0,0x37,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEB,0xFF,0x0A,0xFC,0x7F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF6,0x7F,0x81,0xFF,0xEF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xFA,0xAF,0xE0,0x3F,0xEE,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xFE,0x57,0xF8,0x0F,0xCE,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xFF,0x2B,0xFC,0x1F,0x07,0x00,0x30,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0xC0,0xFF,0x15,0xFC,0xFF,0x07,0x00,0xC0,0x00,0x00,0x00,0x00,0x20,0x02,0x00,0xE0,0xBF,0x0A,0xFC,0xFF,0x03,0x00,0x00,0x01,0x00,0x00,0x00,0x18,0x01,0x00,0xF8,0x5F,0x05,0xF8,0xFF,0x03,0x00,0x00,0x02,0x00,0x00,0x60,0x86,0x00,0x00,0xFC,0xAF,0x02,0xFA,0xFF,0x01,0x00,0x00,0x02,0x00,0x30,0x1D,0x40,0x00,0x00,0xFF,0x57,0x01,0xF5,0x7F,0x00,0x00,0xC0,0x02,0x00,0x08,0x00,0x30,0x00,0x80,0xFF,0xAB,0x80,0xEA,0x1F,0x00,0x00,0xE0,0xFB,0x03,0x04,0x00,0x0E,0x00,0xC0,0xFF,0x57,0x00,0xF5,0x03,0x00,0x00,0xF8,0x02,0x00,0x04,0x60,0x01,0x00,0xE0,0xFF,0x2B,0x80,0x0A,0x04,0x00,0x00,0xC6,0xC2,0x0F,0x04,0x03,0x00,0x00,0xF0,0xFF,0x16,0x00,0x05,0x08,0x00,0x80,0x01,0x02,0x00,0xF0,0x00,0x00,0x00,0xF0,0x3F,0x0A,0x80,0x02,0x00,0x00,0x60,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x06,0x00,0x03,0x00,0x00,0x1C,0x00,0x01,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x82,0x00,0x00,0x03,0x80,0x00,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x82,0x00,0xE0,0x00,0x40,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x03,0x1E,0x00,0x30,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xFC,0x01,0x00,0x0E,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xE1,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xF8,0x10,0x03,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0xF0,0x04,0x00,0x00,0x04,0x10,0x04,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x0F,0x04,0x00,0x00,0x04,0x10,0x08,0x00,0x00,0x00,0xB0,0x01,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x04,0x10,0x08,0x00,0x00,0x00,0xD8,0xFF,0xFF,0xFF,0x3F,0x00,0x28,0x00,0x00,0x08,0x10,0x08,0x00,0x00,0x00,0xEC,0x01,0x00,0x00,0xE0,0x1F,0x28,0x00,0x00,0x10,0x10,0x08,0x00,0x00,0x00,0xD6,0x02,0x00,0x00,0x00,0x30,0x50,0x00,0x00,0x10,0x10,0x04,0x00,0x00,0x00,0xEB,0x05,0x00,0x00,0x00,0x50,0x50,0x00,0x00,0x10,0x20,0x02,0x00,0x00,0x80,0xD4,0x0A,0x00,0x00,0x00,0x90,0x50,0x00,0x00,0x08,0xC0,0x01,0x00,0x00,0x40,0xEA,0x15,0x00,0x00,0x00,0x08,0x61,0x00,0x00,0x0C,0x00,0x01,0x00,0x00,0x20,0xF4,0xFF,0xFF,0x01,0x00,0x08,0x62,0x00,0x00,0x12,0x80,0x00,0x00,0x00,0x10,0xEA,0x15,0x00,0xFE,0x00,0x08,0xE4,0x01,0x00,0x21,0x80,0x00,0x00,0x00,0x10,0xF4,0x0A,0x00,0x00,0x0F,0x04,0xA8,0x06,0xC0,0xC0,0x40,0x00,0x00,0x00,0x08,0xE8,0x05,0x00,0x00,0x30,0x04,0x50,0x19,0x38,0x01,0x47,0x00,0x00,0x00,0x04,0xF4,0x02,0x00,0x00,0xC0,0x04,0xC0,0xE2,0x07,0x06,0x38,0x00,0x00,0x00,0x04,0xF8,0x05,0x00,0x00,0x00,0x03,0x40,0x01,0x00,0x18,0x20,0x00,0x00,0x00,0x02,0xF0,0x02,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x60,0x10,0x00,0x00,0x00,0x02,0xF8,0x01,0x00,0x00,0x00,0x00,0x80,0x05,0x00,0x80,0x11,0x00,0x00,0x00,0x01,0xF0,0x02,0x00,0x00,0x00,0x00,0x80,0x0A,0x00,0x00,0x0E,0x00,0x00,0x00,}; +const uint8_t *_I_DolphinMafia_115x62[] = {_I_DolphinMafia_115x62_0}; + +const uint8_t _I_DolphinNice_96x59_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x1F,0x30,0x00,0x00,0xF0,0x07,0x10,0x00,0x00,0x00,0x00,0xE0,0xE0,0x58,0x01,0x00,0x08,0x08,0x10,0x00,0x00,0x00,0x00,0x10,0x00,0xAF,0x02,0x00,0x04,0x10,0x20,0x00,0x00,0x00,0x00,0x08,0x00,0x78,0x05,0x00,0xF2,0x23,0x40,0x00,0x00,0x00,0x00,0x04,0x00,0xC0,0x03,0x00,0x3A,0x26,0x40,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x06,0x00,0x3A,0x27,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x3A,0x27,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0xFA,0x27,0x80,0x00,0x00,0x00,0x00,0xE2,0x01,0x00,0x00,0x00,0xFA,0x27,0x80,0x00,0x00,0x00,0x00,0x12,0x06,0x00,0x00,0x00,0xF4,0x53,0x80,0x00,0x00,0x00,0x00,0x0A,0x38,0x00,0x00,0x00,0xF8,0xA9,0x80,0x00,0x00,0x00,0x00,0x04,0xC0,0x01,0x00,0x00,0x04,0x56,0x81,0x00,0x00,0x00,0x00,0x04,0x00,0x06,0x00,0x00,0x00,0xA8,0x80,0x00,0x00,0x00,0x00,0x04,0x00,0x18,0x00,0x00,0x00,0x50,0x81,0x00,0x00,0x18,0x00,0x04,0x00,0x60,0x00,0x00,0x00,0xB0,0x80,0x00,0x00,0x24,0x00,0x08,0x00,0x80,0x01,0x00,0x00,0x50,0x80,0x00,0x00,0x22,0x00,0x08,0x00,0x00,0x06,0x00,0x00,0x30,0x80,0x00,0xE0,0x21,0x00,0x10,0x00,0x00,0x18,0x00,0x10,0x10,0x80,0x00,0x18,0x22,0x00,0x20,0x00,0x00,0x60,0x00,0x0C,0x00,0x80,0x00,0x04,0x24,0x00,0x40,0x00,0x00,0x80,0x81,0x03,0x00,0x80,0x00,0x02,0x24,0x00,0x80,0x02,0x00,0x00,0x7E,0x00,0x00,0x80,0x00,0x01,0x28,0x00,0x00,0x15,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x48,0x00,0x00,0x2E,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x88,0x00,0x00,0x58,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x08,0x03,0x00,0xB0,0x02,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x04,0x0C,0x00,0x40,0x15,0x00,0x00,0x00,0x00,0x80,0x01,0x02,0x02,0x30,0x00,0x80,0xAA,0x02,0x00,0x00,0x00,0xC0,0x01,0xFC,0x01,0xC0,0x00,0x80,0x55,0x55,0x00,0x00,0x00,0xC0,0x03,0x08,0x00,0x00,0x07,0x80,0xAB,0xAA,0x00,0x00,0x00,0xC0,0x07,0x10,0x00,0x00,0x38,0xF0,0x55,0x15,0x00,0x00,0x00,0xC0,0x07,0x20,0x00,0x00,0xC0,0xDF,0xAA,0x00,0x00,0x00,0x00,0xC0,0x0F,0x40,0x00,0x00,0x00,0x6A,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x80,0x00,0x00,0x80,0x54,0x00,0x00,0x00,0x00,0x00,0x40,0x1F,0x00,0x01,0x00,0x00,0x2A,0x00,0x00,0x00,0x00,0x00,0xC0,0x1E,0x00,0x02,0x00,0x00,0x35,0x00,0x00,0x00,0x00,0x00,0x40,0x3D,0x00,0x04,0x00,0x40,0x1A,0x00,0x00,0x00,0x00,0x00,0xA0,0x3A,0x00,0x08,0x00,0x00,0x15,0x00,0x00,0x00,0x00,0x00,0x60,0x7D,0x00,0x10,0x00,0x40,0x0A,0x00,0x00,0x00,0x00,0x00,0xA0,0x7A,0x00,0x20,0x00,0x00,0x0D,0x00,0x00,0x00,0x00,0x00,0x60,0xF5,0x00,0xC0,0x00,0x80,0x0A,0x00,0x00,0x00,0x00,0x00,0xA0,0xEA,0x00,0x00,0x01,0x20,0x05,0x00,0x00,0x00,0x00,0x00,0x60,0xF5,0x00,0x00,0x06,0x80,0x06,0x00,0x00,0x00,0x00,0x00,0xA0,0xEA,0x00,0x00,0x08,0x40,0x05,0x00,0x00,0x00,0x00,0x00,0x60,0xC5,0x00,0x00,0x30,0x90,0x02,0x00,0x00,0x00,0x00,0x00,0xA0,0xCA,0x00,0x00,0xC0,0x40,0x03,0x00,0x00,0x00,0x00,0x00,0x60,0x85,0x00,0x00,0x00,0x87,0x02,0x00,0x00,0x00,0x00,0x00,0xA0,0x82,0x00,0x00,0x00,0x78,0x01,0x00,0x00,0x00,0x00,0x00,0x60,0x85,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0xA0,0x02,}; +const uint8_t *_I_DolphinNice_96x59[] = {_I_DolphinNice_96x59_0}; + +const uint8_t _I_DolphinWait_61x59_0[] = {0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x01,0xF0,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x0C,0x03,0x00,0x00,0x01,0x00,0x40,0x00,0xF2,0x05,0x00,0x00,0x01,0x00,0x40,0x00,0xF9,0x0B,0x00,0x80,0x03,0x00,0x00,0x00,0x3D,0x0F,0x00,0x80,0x02,0x00,0x00,0x80,0x3C,0x17,0x00,0x80,0x07,0x00,0x10,0x80,0xFC,0x17,0x00,0x80,0x07,0x00,0x10,0x80,0xFC,0x17,0x00,0x80,0x07,0x00,0x08,0x80,0xFC,0x17,0x80,0xFF,0x7F,0x00,0x08,0x80,0xF8,0x0B,0x60,0x00,0x80,0x01,0x00,0x40,0xF3,0x09,0x1C,0x00,0x00,0x06,0x04,0xA8,0x02,0x04,0x03,0x00,0x00,0x08,0x04,0x54,0x0D,0x83,0x00,0x00,0x00,0x08,0x00,0xAA,0xFF,0x00,0x00,0x00,0x00,0x10,0x02,0xD5,0x38,0x00,0x00,0x00,0x00,0x10,0x82,0x2A,0x40,0x00,0x00,0x00,0x00,0x10,0x00,0x15,0x80,0x00,0x00,0x00,0x00,0x10,0x82,0x0A,0x00,0x00,0x00,0xF8,0x3F,0x10,0x03,0x0D,0x00,0x00,0x00,0x07,0xC0,0x17,0x81,0x0A,0x00,0x00,0xE0,0x00,0x00,0x08,0x03,0x0D,0x04,0x00,0x1C,0x00,0x00,0x08,0x81,0x1A,0x04,0x00,0x03,0x00,0x00,0x08,0x03,0x15,0x04,0xC0,0x00,0x00,0x00,0x08,0x01,0x0A,0x08,0x30,0x00,0x00,0x00,0x04,0x03,0x00,0x30,0x0C,0x00,0x00,0x00,0x02,0x01,0x00,0xC0,0x03,0x00,0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x54,0x20,0x00,0x05,0x00,0x00,0x00,0x80,0xAA,0x1A,0x00,0x02,0x00,0x00,0x00,0x50,0x55,0x07,0x00,0x05,0x00,0x00,0x00,0xAA,0xAA,0x01,0x00,0x0A,0x00,0x00,0x40,0x7D,0xD5,0x01,0x00,0x15,0xFE,0xBF,0xEA,0x83,0xBF,0x01,0x00,0xEA,0x01,0xE0,0x3F,0x00,0x58,0x01,0x00,0x3D,0x00,0x80,0x63,0x00,0xA0,0x01,0x00,0x07,0x00,0xC0,0x80,0x00,0x40,0x01,0x00,0x00,0x00,0x40,0xBC,0x01,0x80,0x01,0x00,0x00,0x00,0x70,0x84,0x03,0x00,0x02,0x00,0x00,0x00,0x4E,0xC4,0x03,0x00,0x04,0x00,0x00,0x80,0xC1,0xF1,0x07,0x00,0x08,0x00,0x01,0x78,0x00,0xFF,0x0F,0x00,0x10,0x00,0x00,0x07,0x00,0xF0,0x0F,0x00,0x10,0x00,0x81,0x00,0x00,0xE0,0x1F,0x00,0x20,0x00,0x62,0x00,0x00,0xE0,0x1F,0x00,0x40,0x00,0x75,0x00,0x00,0xC0,0xFF,0x01,0x9F,0x00,0x6A,0x00,0x00,0xC0,0x03,0xFE,0xA0,0x00,0xF5,0x00,0x00,0x70,0x01,0x00,0x40,0x01,0xEA,0x1F,0x00,0xBE,0x02,0x00,0x40,0x02,0xD5,0xFF,0xFF,0x5F,0x05,0x00,0x20,0x02,}; +const uint8_t *_I_DolphinWait_61x59[] = {_I_DolphinWait_61x59_0}; + const uint8_t _I_iButtonDolphinSuccess_109x60_0[] = {0x00,0x00,0x00,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x7F,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x80,0x80,0x01,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x40,0x7E,0x02,0x00,0x00,0xE0,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x20,0xFF,0x04,0x00,0x00,0xD0,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x20,0xE3,0x05,0x00,0x00,0xA0,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x90,0xE3,0x09,0x00,0x00,0x50,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x04,0x90,0xE3,0x0B,0x00,0x00,0xA0,0x03,0x00,0x00,0x04,0x01,0x00,0x00,0x02,0x90,0xFF,0x0B,0x00,0x00,0x40,0x03,0x00,0x00,0x08,0xF8,0x00,0x00,0x02,0x90,0xFF,0x0B,0x00,0x00,0xB0,0x03,0x00,0x00,0x10,0x06,0x03,0x18,0x02,0x90,0xFF,0x0B,0x00,0x00,0xC0,0x03,0x00,0xC0,0x80,0x01,0x0C,0x06,0x02,0x10,0xFF,0x09,0x00,0x00,0x00,0x0F,0x00,0x00,0x83,0x70,0x88,0x01,0x02,0x30,0xFE,0x05,0x00,0x00,0x00,0x30,0x00,0x00,0x4C,0x8C,0x11,0x00,0x02,0x28,0x7C,0x04,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x02,0x12,0x00,0x02,0x54,0x00,0x02,0x00,0x00,0x00,0x80,0x00,0x00,0x20,0x01,0x24,0x00,0x02,0xA8,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x20,0x01,0x24,0x00,0x02,0x54,0xFF,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0xA0,0x00,0x28,0x0F,0x02,0xEA,0xC0,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0xA7,0x00,0x28,0x00,0x02,0x34,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0xA0,0x00,0x28,0x00,0x02,0x1A,0x00,0x02,0x00,0x00,0x00,0x00,0x20,0x00,0xC0,0x00,0x14,0x00,0x02,0x14,0x00,0x02,0x00,0x00,0x00,0x00,0x40,0x00,0xC0,0x00,0x94,0x03,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x44,0x00,0x0A,0x1C,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x22,0x80,0x0D,0x00,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x78,0x70,0x03,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x84,0xF8,0x60,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x02,0x05,0x80,0x01,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x02,0x86,0x00,0x06,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x03,0x84,0x00,0x00,0x04,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x02,0x04,0x01,0x00,0x08,0x00,0x60,0x00,0xE0,0xFF,0x01,0x00,0x60,0x80,0x02,0x08,0x01,0x00,0x08,0x00,0x80,0x01,0x1E,0x00,0x7E,0x00,0x58,0x80,0x04,0x08,0x02,0x00,0x08,0x00,0x00,0xFE,0x01,0x00,0x80,0xFF,0x47,0x00,0x07,0x10,0x02,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x04,0x10,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x04,0x10,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x04,0x10,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x04,0x20,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x04,0x20,0x00,0x00,0x08,0x00,0x00,0x20,0x55,0xF0,0xFF,0xFF,0x00,0x00,0x04,0x20,0x00,0x00,0x08,0x00,0x00,0x80,0xFA,0xFF,0xFF,0xBF,0x00,0x00,0x02,0x20,0x00,0x00,0x10,0x00,0x00,0x00,0xF4,0xFF,0xFF,0x57,0x01,0x00,0x02,0x40,0x00,0x00,0x10,0x00,0x00,0x00,0xAA,0xFA,0xFF,0xAA,0x01,0x00,0x01,0x40,0x00,0x00,0x10,0x00,0x00,0x00,0x50,0x55,0x55,0x55,0x01,0x80,0x00,0x40,0x00,0x00,}; const uint8_t *_I_iButtonDolphinSuccess_109x60[] = {_I_iButtonDolphinSuccess_109x60_0}; @@ -537,12 +543,6 @@ const uint8_t *_I_iButtonDolphinVerySuccess_108x52[] = {_I_iButtonDolphinVerySuc const uint8_t _I_iButtonKey_49x44_0[] = {0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x80,0x01,0x00,0x01,0x00,0x00,0x00,0x60,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0x00,0x00,0x0C,0x00,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x00,0x00,0x00,0xC0,0x00,0x00,0x08,0x00,0x00,0x00,0x30,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0xC0,0x00,0x00,0x00,0xF0,0x0F,0x00,0x20,0x00,0x00,0x00,0x0C,0x30,0x00,0x10,0x00,0x00,0x00,0x03,0x40,0x00,0x0C,0x00,0x00,0x80,0x00,0x80,0x00,0x02,0x00,0x00,0x40,0x00,0x80,0x01,0x01,0x00,0x00,0x20,0x00,0x80,0x83,0x00,0x00,0x00,0x10,0x00,0x80,0x47,0x00,0x00,0x00,0x08,0x00,0x80,0x4F,0x00,0x00,0x00,0x04,0x00,0xC0,0x4F,0x00,0x00,0x00,0x04,0x00,0x40,0x4F,0x00,0x00,0x00,0x02,0x00,0xC0,0x4E,0x00,0x00,0x00,0x02,0x00,0x60,0x45,0x00,0x00,0x00,0x01,0x00,0xA0,0x46,0x00,0x00,0x00,0x01,0x00,0x30,0x45,0x00,0x00,0x00,0x01,0x00,0x98,0x42,0x00,0x00,0x00,0x01,0x00,0x0C,0x22,0x00,0x00,0x00,0x01,0x00,0x02,0x21,0x00,0x00,0x00,0x01,0x00,0x81,0x11,0x00,0x00,0x00,0x03,0xC0,0xC0,0x10,0x00,0x00,0x00,0x06,0x78,0x40,0x08,0x00,0x00,0x00,0xFC,0x0F,0x20,0x04,0x00,0x00,0x00,0x78,0x55,0x11,0x02,0x00,0x00,0x00,0xF0,0x0A,0x0E,0x01,0x00,0x00,0x00,0xE0,0xD5,0x83,0x00,0x00,0x00,0x00,0xC0,0x7F,0x40,0x00,0x00,0x00,0x00,0x80,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,}; const uint8_t *_I_iButtonKey_49x44[] = {_I_iButtonKey_49x44_0}; -const uint8_t _I_DolphinNice_96x59_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x1F,0x30,0x00,0x00,0xF0,0x07,0x10,0x00,0x00,0x00,0x00,0xE0,0xE0,0x58,0x01,0x00,0x08,0x08,0x10,0x00,0x00,0x00,0x00,0x10,0x00,0xAF,0x02,0x00,0x04,0x10,0x20,0x00,0x00,0x00,0x00,0x08,0x00,0x78,0x05,0x00,0xF2,0x23,0x40,0x00,0x00,0x00,0x00,0x04,0x00,0xC0,0x03,0x00,0x3A,0x26,0x40,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x06,0x00,0x3A,0x27,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x3A,0x27,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0xFA,0x27,0x80,0x00,0x00,0x00,0x00,0xE2,0x01,0x00,0x00,0x00,0xFA,0x27,0x80,0x00,0x00,0x00,0x00,0x12,0x06,0x00,0x00,0x00,0xF4,0x53,0x80,0x00,0x00,0x00,0x00,0x0A,0x38,0x00,0x00,0x00,0xF8,0xA9,0x80,0x00,0x00,0x00,0x00,0x04,0xC0,0x01,0x00,0x00,0x04,0x56,0x81,0x00,0x00,0x00,0x00,0x04,0x00,0x06,0x00,0x00,0x00,0xA8,0x80,0x00,0x00,0x00,0x00,0x04,0x00,0x18,0x00,0x00,0x00,0x50,0x81,0x00,0x00,0x18,0x00,0x04,0x00,0x60,0x00,0x00,0x00,0xB0,0x80,0x00,0x00,0x24,0x00,0x08,0x00,0x80,0x01,0x00,0x00,0x50,0x80,0x00,0x00,0x22,0x00,0x08,0x00,0x00,0x06,0x00,0x00,0x30,0x80,0x00,0xE0,0x21,0x00,0x10,0x00,0x00,0x18,0x00,0x10,0x10,0x80,0x00,0x18,0x22,0x00,0x20,0x00,0x00,0x60,0x00,0x0C,0x00,0x80,0x00,0x04,0x24,0x00,0x40,0x00,0x00,0x80,0x81,0x03,0x00,0x80,0x00,0x02,0x24,0x00,0x80,0x02,0x00,0x00,0x7E,0x00,0x00,0x80,0x00,0x01,0x28,0x00,0x00,0x15,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x48,0x00,0x00,0x2E,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x88,0x00,0x00,0x58,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x08,0x03,0x00,0xB0,0x02,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x04,0x0C,0x00,0x40,0x15,0x00,0x00,0x00,0x00,0x80,0x01,0x02,0x02,0x30,0x00,0x80,0xAA,0x02,0x00,0x00,0x00,0xC0,0x01,0xFC,0x01,0xC0,0x00,0x80,0x55,0x55,0x00,0x00,0x00,0xC0,0x03,0x08,0x00,0x00,0x07,0x80,0xAB,0xAA,0x00,0x00,0x00,0xC0,0x07,0x10,0x00,0x00,0x38,0xF0,0x55,0x15,0x00,0x00,0x00,0xC0,0x07,0x20,0x00,0x00,0xC0,0xDF,0xAA,0x00,0x00,0x00,0x00,0xC0,0x0F,0x40,0x00,0x00,0x00,0x6A,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x80,0x00,0x00,0x80,0x54,0x00,0x00,0x00,0x00,0x00,0x40,0x1F,0x00,0x01,0x00,0x00,0x2A,0x00,0x00,0x00,0x00,0x00,0xC0,0x1E,0x00,0x02,0x00,0x00,0x35,0x00,0x00,0x00,0x00,0x00,0x40,0x3D,0x00,0x04,0x00,0x40,0x1A,0x00,0x00,0x00,0x00,0x00,0xA0,0x3A,0x00,0x08,0x00,0x00,0x15,0x00,0x00,0x00,0x00,0x00,0x60,0x7D,0x00,0x10,0x00,0x40,0x0A,0x00,0x00,0x00,0x00,0x00,0xA0,0x7A,0x00,0x20,0x00,0x00,0x0D,0x00,0x00,0x00,0x00,0x00,0x60,0xF5,0x00,0xC0,0x00,0x80,0x0A,0x00,0x00,0x00,0x00,0x00,0xA0,0xEA,0x00,0x00,0x01,0x20,0x05,0x00,0x00,0x00,0x00,0x00,0x60,0xF5,0x00,0x00,0x06,0x80,0x06,0x00,0x00,0x00,0x00,0x00,0xA0,0xEA,0x00,0x00,0x08,0x40,0x05,0x00,0x00,0x00,0x00,0x00,0x60,0xC5,0x00,0x00,0x30,0x90,0x02,0x00,0x00,0x00,0x00,0x00,0xA0,0xCA,0x00,0x00,0xC0,0x40,0x03,0x00,0x00,0x00,0x00,0x00,0x60,0x85,0x00,0x00,0x00,0x87,0x02,0x00,0x00,0x00,0x00,0x00,0xA0,0x82,0x00,0x00,0x00,0x78,0x01,0x00,0x00,0x00,0x00,0x00,0x60,0x85,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0xA0,0x02,}; -const uint8_t *_I_DolphinNice_96x59[] = {_I_DolphinNice_96x59_0}; - -const uint8_t _I_DolphinWait_61x59_0[] = {0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x01,0xF0,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x0C,0x03,0x00,0x00,0x01,0x00,0x40,0x00,0xF2,0x05,0x00,0x00,0x01,0x00,0x40,0x00,0xF9,0x0B,0x00,0x80,0x03,0x00,0x00,0x00,0x3D,0x0F,0x00,0x80,0x02,0x00,0x00,0x80,0x3C,0x17,0x00,0x80,0x07,0x00,0x10,0x80,0xFC,0x17,0x00,0x80,0x07,0x00,0x10,0x80,0xFC,0x17,0x00,0x80,0x07,0x00,0x08,0x80,0xFC,0x17,0x80,0xFF,0x7F,0x00,0x08,0x80,0xF8,0x0B,0x60,0x00,0x80,0x01,0x00,0x40,0xF3,0x09,0x1C,0x00,0x00,0x06,0x04,0xA8,0x02,0x04,0x03,0x00,0x00,0x08,0x04,0x54,0x0D,0x83,0x00,0x00,0x00,0x08,0x00,0xAA,0xFF,0x00,0x00,0x00,0x00,0x10,0x02,0xD5,0x38,0x00,0x00,0x00,0x00,0x10,0x82,0x2A,0x40,0x00,0x00,0x00,0x00,0x10,0x00,0x15,0x80,0x00,0x00,0x00,0x00,0x10,0x82,0x0A,0x00,0x00,0x00,0xF8,0x3F,0x10,0x03,0x0D,0x00,0x00,0x00,0x07,0xC0,0x17,0x81,0x0A,0x00,0x00,0xE0,0x00,0x00,0x08,0x03,0x0D,0x04,0x00,0x1C,0x00,0x00,0x08,0x81,0x1A,0x04,0x00,0x03,0x00,0x00,0x08,0x03,0x15,0x04,0xC0,0x00,0x00,0x00,0x08,0x01,0x0A,0x08,0x30,0x00,0x00,0x00,0x04,0x03,0x00,0x30,0x0C,0x00,0x00,0x00,0x02,0x01,0x00,0xC0,0x03,0x00,0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x54,0x20,0x00,0x05,0x00,0x00,0x00,0x80,0xAA,0x1A,0x00,0x02,0x00,0x00,0x00,0x50,0x55,0x07,0x00,0x05,0x00,0x00,0x00,0xAA,0xAA,0x01,0x00,0x0A,0x00,0x00,0x40,0x7D,0xD5,0x01,0x00,0x15,0xFE,0xBF,0xEA,0x83,0xBF,0x01,0x00,0xEA,0x01,0xE0,0x3F,0x00,0x58,0x01,0x00,0x3D,0x00,0x80,0x63,0x00,0xA0,0x01,0x00,0x07,0x00,0xC0,0x80,0x00,0x40,0x01,0x00,0x00,0x00,0x40,0xBC,0x01,0x80,0x01,0x00,0x00,0x00,0x70,0x84,0x03,0x00,0x02,0x00,0x00,0x00,0x4E,0xC4,0x03,0x00,0x04,0x00,0x00,0x80,0xC1,0xF1,0x07,0x00,0x08,0x00,0x01,0x78,0x00,0xFF,0x0F,0x00,0x10,0x00,0x00,0x07,0x00,0xF0,0x0F,0x00,0x10,0x00,0x81,0x00,0x00,0xE0,0x1F,0x00,0x20,0x00,0x62,0x00,0x00,0xE0,0x1F,0x00,0x40,0x00,0x75,0x00,0x00,0xC0,0xFF,0x01,0x9F,0x00,0x6A,0x00,0x00,0xC0,0x03,0xFE,0xA0,0x00,0xF5,0x00,0x00,0x70,0x01,0x00,0x40,0x01,0xEA,0x1F,0x00,0xBE,0x02,0x00,0x40,0x02,0xD5,0xFF,0xFF,0x5F,0x05,0x00,0x20,0x02,}; -const uint8_t *_I_DolphinWait_61x59[] = {_I_DolphinWait_61x59_0}; - const Icon A_FX_Sitting_40x27 = {.width=40,.height=27,.frame_count=2,.frame_rate=10,.frames=_A_FX_Sitting_40x27}; const Icon A_MDIB_32x32 = {.width=32,.height=32,.frame_count=4,.frame_rate=10,.frames=_A_MDIB_32x32}; const Icon A_MDI_32x32 = {.width=32,.height=32,.frame_count=4,.frame_rate=10,.frames=_A_MDI_32x32}; @@ -552,67 +552,67 @@ const Icon A_MDWRB_32x32 = {.width=32,.height=32,.frame_count=3,.frame_rate=10,. const Icon A_MDWR_32x32 = {.width=32,.height=32,.frame_count=3,.frame_rate=10,.frames=_A_MDWR_32x32}; const Icon A_WatchingTV_128x64 = {.width=128,.height=64,.frame_count=5,.frame_rate=10,.frames=_A_WatchingTV_128x64}; const Icon A_Wink_128x64 = {.width=128,.height=64,.frame_count=9,.frame_rate=10,.frames=_A_Wink_128x64}; +const Icon I_125_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_125_10px}; +const Icon I_ble_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ble_10px}; const Icon I_dir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_dir_10px}; +const Icon I_ibutt_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ibutt_10px}; +const Icon I_ir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ir_10px}; const Icon I_Nfc_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Nfc_10px}; const Icon I_sub1_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_sub1_10px}; -const Icon I_ir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ir_10px}; -const Icon I_ibutt_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ibutt_10px}; const Icon I_unknown_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_unknown_10px}; -const Icon I_ble_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ble_10px}; -const Icon I_125_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_125_10px}; -const Icon I_ButtonRightSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRightSmall_3x5}; -const Icon I_ButtonLeft_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeft_4x7}; -const Icon I_ButtonLeftSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeftSmall_3x5}; -const Icon I_ButtonRight_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRight_4x7}; const Icon I_ButtonCenter_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonCenter_7x7}; -const Icon I_FX_SittingB_40x27 = {.width=40,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_FX_SittingB_40x27}; +const Icon I_ButtonLeftSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeftSmall_3x5}; +const Icon I_ButtonLeft_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeft_4x7}; +const Icon I_ButtonRightSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRightSmall_3x5}; +const Icon I_ButtonRight_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRight_4x7}; +const Icon I_BigBurger_24x24 = {.width=24,.height=24,.frame_count=1,.frame_rate=0,.frames=_I_BigBurger_24x24}; const Icon I_BigGames_24x24 = {.width=24,.height=24,.frame_count=1,.frame_rate=0,.frames=_I_BigGames_24x24}; const Icon I_BigProfile_24x24 = {.width=24,.height=24,.frame_count=1,.frame_rate=0,.frames=_I_BigProfile_24x24}; -const Icon I_DolphinOkay_41x43 = {.width=41,.height=43,.frame_count=1,.frame_rate=0,.frames=_I_DolphinOkay_41x43}; -const Icon I_DolphinFirstStart5_45x53 = {.width=45,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart5_45x53}; -const Icon I_DolphinFirstStart4_67x53 = {.width=67,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart4_67x53}; -const Icon I_DolphinFirstStart2_59x51 = {.width=59,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart2_59x51}; const Icon I_DolphinFirstStart0_70x53 = {.width=70,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart0_70x53}; -const Icon I_DolphinFirstStart6_58x54 = {.width=58,.height=54,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart6_58x54}; const Icon I_DolphinFirstStart1_59x53 = {.width=59,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart1_59x53}; -const Icon I_DolphinFirstStart8_56x51 = {.width=56,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart8_56x51}; -const Icon I_DolphinFirstStart7_61x51 = {.width=61,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart7_61x51}; -const Icon I_Flipper_young_80x60 = {.width=80,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_Flipper_young_80x60}; -const Icon I_BigBurger_24x24 = {.width=24,.height=24,.frame_count=1,.frame_rate=0,.frames=_I_BigBurger_24x24}; -const Icon I_FX_Bang_32x6 = {.width=32,.height=6,.frame_count=1,.frame_rate=0,.frames=_I_FX_Bang_32x6}; +const Icon I_DolphinFirstStart2_59x51 = {.width=59,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart2_59x51}; const Icon I_DolphinFirstStart3_57x48 = {.width=57,.height=48,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart3_57x48}; -const Icon I_PassportBottom_128x17 = {.width=128,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_PassportBottom_128x17}; +const Icon I_DolphinFirstStart4_67x53 = {.width=67,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart4_67x53}; +const Icon I_DolphinFirstStart5_45x53 = {.width=45,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart5_45x53}; +const Icon I_DolphinFirstStart6_58x54 = {.width=58,.height=54,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart6_58x54}; +const Icon I_DolphinFirstStart7_61x51 = {.width=61,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart7_61x51}; +const Icon I_DolphinFirstStart8_56x51 = {.width=56,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart8_56x51}; +const Icon I_DolphinOkay_41x43 = {.width=41,.height=43,.frame_count=1,.frame_rate=0,.frames=_I_DolphinOkay_41x43}; +const Icon I_Flipper_young_80x60 = {.width=80,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_Flipper_young_80x60}; +const Icon I_FX_Bang_32x6 = {.width=32,.height=6,.frame_count=1,.frame_rate=0,.frames=_I_FX_Bang_32x6}; +const Icon I_FX_SittingB_40x27 = {.width=40,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_FX_SittingB_40x27}; +const Icon I_DoorLeft_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_70x55}; const Icon I_DoorLeft_8x56 = {.width=8,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_8x56}; const Icon I_DoorLocked_10x56 = {.width=10,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLocked_10x56}; -const Icon I_DoorRight_8x56 = {.width=8,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorRight_8x56}; -const Icon I_DoorLeft_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_70x55}; -const Icon I_PassportLeft_6x47 = {.width=6,.height=47,.frame_count=1,.frame_rate=0,.frames=_I_PassportLeft_6x47}; const Icon I_DoorRight_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorRight_70x55}; +const Icon I_DoorRight_8x56 = {.width=8,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorRight_8x56}; const Icon I_LockPopup_100x49 = {.width=100,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_LockPopup_100x49}; -const Icon I_Mute_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_25x27}; -const Icon I_IrdaArrowUp_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowUp_4x8}; -const Icon I_Up_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_hvr_25x27}; -const Icon I_Mute_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_hvr_25x27}; -const Icon I_Vol_down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_25x27}; +const Icon I_PassportBottom_128x17 = {.width=128,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_PassportBottom_128x17}; +const Icon I_PassportLeft_6x47 = {.width=6,.height=47,.frame_count=1,.frame_rate=0,.frames=_I_PassportLeft_6x47}; +const Icon I_Back_15x10 = {.width=15,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Back_15x10}; const Icon I_Down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Down_25x27}; -const Icon I_Power_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_hvr_25x27}; -const Icon I_IrdaLearnShort_128x31 = {.width=128,.height=31,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearnShort_128x31}; -const Icon I_IrdaArrowDown_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowDown_4x8}; -const Icon I_Vol_down_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_hvr_25x27}; -const Icon I_IrdaLearn_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearn_128x64}; const Icon I_Down_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Down_hvr_25x27}; const Icon I_Fill_marker_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_Fill_marker_7x7}; -const Icon I_Power_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_25x27}; -const Icon I_Vol_up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_25x27}; -const Icon I_Up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_25x27}; -const Icon I_Back_15x10 = {.width=15,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Back_15x10}; -const Icon I_IrdaSend_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaSend_128x64}; +const Icon I_IrdaArrowDown_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowDown_4x8}; +const Icon I_IrdaArrowUp_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowUp_4x8}; +const Icon I_IrdaLearnShort_128x31 = {.width=128,.height=31,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearnShort_128x31}; +const Icon I_IrdaLearn_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearn_128x64}; const Icon I_IrdaSendShort_128x34 = {.width=128,.height=34,.frame_count=1,.frame_rate=0,.frames=_I_IrdaSendShort_128x34}; +const Icon I_IrdaSend_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaSend_128x64}; +const Icon I_Mute_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_25x27}; +const Icon I_Mute_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_hvr_25x27}; +const Icon I_Power_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_25x27}; +const Icon I_Power_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_hvr_25x27}; +const Icon I_Up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_25x27}; +const Icon I_Up_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_hvr_25x27}; +const Icon I_Vol_down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_25x27}; +const Icon I_Vol_down_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_hvr_25x27}; +const Icon I_Vol_up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_25x27}; const Icon I_Vol_up_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_hvr_25x27}; -const Icon I_KeySave_24x11 = {.width=24,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_KeySave_24x11}; const Icon I_KeyBackspaceSelected_16x9 = {.width=16,.height=9,.frame_count=1,.frame_rate=0,.frames=_I_KeyBackspaceSelected_16x9}; -const Icon I_KeySaveSelected_24x11 = {.width=24,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_KeySaveSelected_24x11}; const Icon I_KeyBackspace_16x9 = {.width=16,.height=9,.frame_count=1,.frame_rate=0,.frames=_I_KeyBackspace_16x9}; +const Icon I_KeySaveSelected_24x11 = {.width=24,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_KeySaveSelected_24x11}; +const Icon I_KeySave_24x11 = {.width=24,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_KeySave_24x11}; const Icon A_125khz_14 = {.width=14,.height=14,.frame_count=4,.frame_rate=3,.frames=_A_125khz_14}; const Icon A_Bluetooth_14 = {.width=14,.height=14,.frame_count=6,.frame_rate=3,.frames=_A_Bluetooth_14}; const Icon A_FileManager_14 = {.width=14,.height=14,.frame_count=10,.frame_rate=3,.frames=_A_FileManager_14}; @@ -628,62 +628,62 @@ const Icon A_Sub1ghz_14 = {.width=14,.height=14,.frame_count=6,.frame_rate=3,.fr const Icon A_Tamagotchi_14 = {.width=14,.height=14,.frame_count=6,.frame_rate=3,.frames=_A_Tamagotchi_14}; const Icon A_U2F_14 = {.width=14,.height=14,.frame_count=4,.frame_rate=3,.frames=_A_U2F_14}; const Icon A_iButton_14 = {.width=14,.height=14,.frame_count=7,.frame_rate=3,.frames=_A_iButton_14}; -const Icon I_Medium_chip_22x21 = {.width=22,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_Medium_chip_22x21}; const Icon I_EMV_Chip_14x11 = {.width=14,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_EMV_Chip_14x11}; -const Icon I_passport_happy1_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_happy1_43x45}; -const Icon I_passport_bad3_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_bad3_43x45}; -const Icon I_passport_okay2_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_okay2_43x45}; -const Icon I_passport_bad2_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_bad2_43x45}; -const Icon I_passport_okay3_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_okay3_43x45}; +const Icon I_Medium_chip_22x21 = {.width=22,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_Medium_chip_22x21}; const Icon I_passport_bad1_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_bad1_43x45}; -const Icon I_passport_happy3_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_happy3_43x45}; +const Icon I_passport_bad2_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_bad2_43x45}; +const Icon I_passport_bad3_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_bad3_43x45}; +const Icon I_passport_happy1_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_happy1_43x45}; const Icon I_passport_happy2_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_happy2_43x45}; +const Icon I_passport_happy3_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_happy3_43x45}; const Icon I_passport_okay1_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_okay1_43x45}; -const Icon I_Health_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Health_16x16}; -const Icon I_FaceCharging_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceCharging_29x14}; +const Icon I_passport_okay2_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_okay2_43x45}; +const Icon I_passport_okay3_43x45 = {.width=43,.height=45,.frame_count=1,.frame_rate=0,.frames=_I_passport_okay3_43x45}; const Icon I_BatteryBody_52x28 = {.width=52,.height=28,.frame_count=1,.frame_rate=0,.frames=_I_BatteryBody_52x28}; -const Icon I_Voltage_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Voltage_16x16}; -const Icon I_Temperature_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Temperature_16x16}; +const Icon I_Battery_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Battery_16x16}; +const Icon I_FaceCharging_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceCharging_29x14}; +const Icon I_FaceConfused_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceConfused_29x14}; const Icon I_FaceNopower_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceNopower_29x14}; const Icon I_FaceNormal_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceNormal_29x14}; -const Icon I_Battery_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Battery_16x16}; -const Icon I_FaceConfused_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceConfused_29x14}; -const Icon I_RFIDDolphinSuccess_108x57 = {.width=108,.height=57,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinSuccess_108x57}; +const Icon I_Health_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Health_16x16}; +const Icon I_Temperature_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Temperature_16x16}; +const Icon I_Voltage_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Voltage_16x16}; const Icon I_RFIDBigChip_37x36 = {.width=37,.height=36,.frame_count=1,.frame_rate=0,.frames=_I_RFIDBigChip_37x36}; -const Icon I_RFIDDolphinSend_97x61 = {.width=97,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinSend_97x61}; const Icon I_RFIDDolphinReceive_97x61 = {.width=97,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinReceive_97x61}; -const Icon I_SDQuestion_35x43 = {.width=35,.height=43,.frame_count=1,.frame_rate=0,.frames=_I_SDQuestion_35x43}; +const Icon I_RFIDDolphinSend_97x61 = {.width=97,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinSend_97x61}; +const Icon I_RFIDDolphinSuccess_108x57 = {.width=108,.height=57,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinSuccess_108x57}; const Icon I_SDError_43x35 = {.width=43,.height=35,.frame_count=1,.frame_rate=0,.frames=_I_SDError_43x35}; -const Icon I_WalkR2_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkR2_32x32}; -const Icon I_WalkL2_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkL2_32x32}; -const Icon I_WalkRB1_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkRB1_32x32}; +const Icon I_SDQuestion_35x43 = {.width=35,.height=43,.frame_count=1,.frame_rate=0,.frames=_I_SDQuestion_35x43}; const Icon I_Home_painting_17x20 = {.width=17,.height=20,.frame_count=1,.frame_rate=0,.frames=_I_Home_painting_17x20}; -const Icon I_WalkLB2_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkLB2_32x32}; -const Icon I_Sofa_40x13 = {.width=40,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_Sofa_40x13}; -const Icon I_WalkLB1_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkLB1_32x32}; const Icon I_PC_22x29 = {.width=22,.height=29,.frame_count=1,.frame_rate=0,.frames=_I_PC_22x29}; -const Icon I_WalkL1_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkL1_32x32}; +const Icon I_Sofa_40x13 = {.width=40,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_Sofa_40x13}; const Icon I_TV_20x20 = {.width=20,.height=20,.frame_count=1,.frame_rate=0,.frames=_I_TV_20x20}; -const Icon I_WalkR1_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkR1_32x32}; -const Icon I_WalkRB2_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkRB2_32x32}; const Icon I_TV_20x24 = {.width=20,.height=24,.frame_count=1,.frame_rate=0,.frames=_I_TV_20x24}; -const Icon I_BadUsb_9x8 = {.width=9,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_BadUsb_9x8}; -const Icon I_PlaceholderR_30x13 = {.width=30,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_PlaceholderR_30x13}; -const Icon I_Background_128x8 = {.width=128,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Background_128x8}; -const Icon I_Lock_8x8 = {.width=8,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Lock_8x8}; -const Icon I_Battery_26x8 = {.width=26,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_26x8}; -const Icon I_PlaceholderL_11x13 = {.width=11,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_PlaceholderL_11x13}; -const Icon I_Battery_19x8 = {.width=19,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_19x8}; -const Icon I_SDcardMounted_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardMounted_11x8}; -const Icon I_SDcardFail_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardFail_11x8}; -const Icon I_USBConnected_15x8 = {.width=15,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_USBConnected_15x8}; -const Icon I_Bluetooth_5x8 = {.width=5,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Bluetooth_5x8}; +const Icon I_WalkL1_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkL1_32x32}; +const Icon I_WalkL2_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkL2_32x32}; +const Icon I_WalkLB1_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkLB1_32x32}; +const Icon I_WalkLB2_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkLB2_32x32}; +const Icon I_WalkR1_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkR1_32x32}; +const Icon I_WalkR2_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkR2_32x32}; +const Icon I_WalkRB1_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkRB1_32x32}; +const Icon I_WalkRB2_32x32 = {.width=32,.height=32,.frame_count=1,.frame_rate=0,.frames=_I_WalkRB2_32x32}; const Icon I_Background_128x11 = {.width=128,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_Background_128x11}; -const Icon I_DolphinMafia_115x62 = {.width=115,.height=62,.frame_count=1,.frame_rate=0,.frames=_I_DolphinMafia_115x62}; +const Icon I_Background_128x8 = {.width=128,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Background_128x8}; +const Icon I_BadUsb_9x8 = {.width=9,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_BadUsb_9x8}; +const Icon I_Battery_19x8 = {.width=19,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_19x8}; +const Icon I_Battery_26x8 = {.width=26,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_26x8}; +const Icon I_Bluetooth_5x8 = {.width=5,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Bluetooth_5x8}; +const Icon I_Lock_8x8 = {.width=8,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Lock_8x8}; +const Icon I_PlaceholderL_11x13 = {.width=11,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_PlaceholderL_11x13}; +const Icon I_PlaceholderR_30x13 = {.width=30,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_PlaceholderR_30x13}; +const Icon I_SDcardFail_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardFail_11x8}; +const Icon I_SDcardMounted_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardMounted_11x8}; +const Icon I_USBConnected_15x8 = {.width=15,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_USBConnected_15x8}; const Icon I_DolphinExcited_64x63 = {.width=64,.height=63,.frame_count=1,.frame_rate=0,.frames=_I_DolphinExcited_64x63}; +const Icon I_DolphinMafia_115x62 = {.width=115,.height=62,.frame_count=1,.frame_rate=0,.frames=_I_DolphinMafia_115x62}; +const Icon I_DolphinNice_96x59 = {.width=96,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinNice_96x59}; +const Icon I_DolphinWait_61x59 = {.width=61,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinWait_61x59}; const Icon I_iButtonDolphinSuccess_109x60 = {.width=109,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_iButtonDolphinSuccess_109x60}; const Icon I_iButtonDolphinVerySuccess_108x52 = {.width=108,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_iButtonDolphinVerySuccess_108x52}; const Icon I_iButtonKey_49x44 = {.width=49,.height=44,.frame_count=1,.frame_rate=0,.frames=_I_iButtonKey_49x44}; -const Icon I_DolphinNice_96x59 = {.width=96,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinNice_96x59}; -const Icon I_DolphinWait_61x59 = {.width=61,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinWait_61x59}; diff --git a/assets/compiled/assets_icons.h b/assets/compiled/assets_icons.h index 317895e2..d61f5abf 100644 --- a/assets/compiled/assets_icons.h +++ b/assets/compiled/assets_icons.h @@ -10,67 +10,67 @@ extern const Icon A_MDWRB_32x32; extern const Icon A_MDWR_32x32; extern const Icon A_WatchingTV_128x64; extern const Icon A_Wink_128x64; +extern const Icon I_125_10px; +extern const Icon I_ble_10px; extern const Icon I_dir_10px; +extern const Icon I_ibutt_10px; +extern const Icon I_ir_10px; extern const Icon I_Nfc_10px; extern const Icon I_sub1_10px; -extern const Icon I_ir_10px; -extern const Icon I_ibutt_10px; extern const Icon I_unknown_10px; -extern const Icon I_ble_10px; -extern const Icon I_125_10px; -extern const Icon I_ButtonRightSmall_3x5; -extern const Icon I_ButtonLeft_4x7; -extern const Icon I_ButtonLeftSmall_3x5; -extern const Icon I_ButtonRight_4x7; extern const Icon I_ButtonCenter_7x7; -extern const Icon I_FX_SittingB_40x27; +extern const Icon I_ButtonLeftSmall_3x5; +extern const Icon I_ButtonLeft_4x7; +extern const Icon I_ButtonRightSmall_3x5; +extern const Icon I_ButtonRight_4x7; +extern const Icon I_BigBurger_24x24; extern const Icon I_BigGames_24x24; extern const Icon I_BigProfile_24x24; -extern const Icon I_DolphinOkay_41x43; -extern const Icon I_DolphinFirstStart5_45x53; -extern const Icon I_DolphinFirstStart4_67x53; -extern const Icon I_DolphinFirstStart2_59x51; extern const Icon I_DolphinFirstStart0_70x53; -extern const Icon I_DolphinFirstStart6_58x54; extern const Icon I_DolphinFirstStart1_59x53; -extern const Icon I_DolphinFirstStart8_56x51; -extern const Icon I_DolphinFirstStart7_61x51; -extern const Icon I_Flipper_young_80x60; -extern const Icon I_BigBurger_24x24; -extern const Icon I_FX_Bang_32x6; +extern const Icon I_DolphinFirstStart2_59x51; extern const Icon I_DolphinFirstStart3_57x48; -extern const Icon I_PassportBottom_128x17; +extern const Icon I_DolphinFirstStart4_67x53; +extern const Icon I_DolphinFirstStart5_45x53; +extern const Icon I_DolphinFirstStart6_58x54; +extern const Icon I_DolphinFirstStart7_61x51; +extern const Icon I_DolphinFirstStart8_56x51; +extern const Icon I_DolphinOkay_41x43; +extern const Icon I_Flipper_young_80x60; +extern const Icon I_FX_Bang_32x6; +extern const Icon I_FX_SittingB_40x27; +extern const Icon I_DoorLeft_70x55; extern const Icon I_DoorLeft_8x56; extern const Icon I_DoorLocked_10x56; -extern const Icon I_DoorRight_8x56; -extern const Icon I_DoorLeft_70x55; -extern const Icon I_PassportLeft_6x47; extern const Icon I_DoorRight_70x55; +extern const Icon I_DoorRight_8x56; extern const Icon I_LockPopup_100x49; -extern const Icon I_Mute_25x27; -extern const Icon I_IrdaArrowUp_4x8; -extern const Icon I_Up_hvr_25x27; -extern const Icon I_Mute_hvr_25x27; -extern const Icon I_Vol_down_25x27; +extern const Icon I_PassportBottom_128x17; +extern const Icon I_PassportLeft_6x47; +extern const Icon I_Back_15x10; extern const Icon I_Down_25x27; -extern const Icon I_Power_hvr_25x27; -extern const Icon I_IrdaLearnShort_128x31; -extern const Icon I_IrdaArrowDown_4x8; -extern const Icon I_Vol_down_hvr_25x27; -extern const Icon I_IrdaLearn_128x64; extern const Icon I_Down_hvr_25x27; extern const Icon I_Fill_marker_7x7; -extern const Icon I_Power_25x27; -extern const Icon I_Vol_up_25x27; -extern const Icon I_Up_25x27; -extern const Icon I_Back_15x10; -extern const Icon I_IrdaSend_128x64; +extern const Icon I_IrdaArrowDown_4x8; +extern const Icon I_IrdaArrowUp_4x8; +extern const Icon I_IrdaLearnShort_128x31; +extern const Icon I_IrdaLearn_128x64; extern const Icon I_IrdaSendShort_128x34; +extern const Icon I_IrdaSend_128x64; +extern const Icon I_Mute_25x27; +extern const Icon I_Mute_hvr_25x27; +extern const Icon I_Power_25x27; +extern const Icon I_Power_hvr_25x27; +extern const Icon I_Up_25x27; +extern const Icon I_Up_hvr_25x27; +extern const Icon I_Vol_down_25x27; +extern const Icon I_Vol_down_hvr_25x27; +extern const Icon I_Vol_up_25x27; extern const Icon I_Vol_up_hvr_25x27; -extern const Icon I_KeySave_24x11; extern const Icon I_KeyBackspaceSelected_16x9; -extern const Icon I_KeySaveSelected_24x11; extern const Icon I_KeyBackspace_16x9; +extern const Icon I_KeySaveSelected_24x11; +extern const Icon I_KeySave_24x11; extern const Icon A_125khz_14; extern const Icon A_Bluetooth_14; extern const Icon A_FileManager_14; @@ -86,61 +86,61 @@ extern const Icon A_Sub1ghz_14; extern const Icon A_Tamagotchi_14; extern const Icon A_U2F_14; extern const Icon A_iButton_14; -extern const Icon I_Medium_chip_22x21; extern const Icon I_EMV_Chip_14x11; -extern const Icon I_passport_happy1_43x45; -extern const Icon I_passport_bad3_43x45; -extern const Icon I_passport_okay2_43x45; -extern const Icon I_passport_bad2_43x45; -extern const Icon I_passport_okay3_43x45; +extern const Icon I_Medium_chip_22x21; extern const Icon I_passport_bad1_43x45; -extern const Icon I_passport_happy3_43x45; +extern const Icon I_passport_bad2_43x45; +extern const Icon I_passport_bad3_43x45; +extern const Icon I_passport_happy1_43x45; extern const Icon I_passport_happy2_43x45; +extern const Icon I_passport_happy3_43x45; extern const Icon I_passport_okay1_43x45; -extern const Icon I_Health_16x16; -extern const Icon I_FaceCharging_29x14; +extern const Icon I_passport_okay2_43x45; +extern const Icon I_passport_okay3_43x45; extern const Icon I_BatteryBody_52x28; -extern const Icon I_Voltage_16x16; -extern const Icon I_Temperature_16x16; +extern const Icon I_Battery_16x16; +extern const Icon I_FaceCharging_29x14; +extern const Icon I_FaceConfused_29x14; extern const Icon I_FaceNopower_29x14; extern const Icon I_FaceNormal_29x14; -extern const Icon I_Battery_16x16; -extern const Icon I_FaceConfused_29x14; -extern const Icon I_RFIDDolphinSuccess_108x57; +extern const Icon I_Health_16x16; +extern const Icon I_Temperature_16x16; +extern const Icon I_Voltage_16x16; extern const Icon I_RFIDBigChip_37x36; -extern const Icon I_RFIDDolphinSend_97x61; extern const Icon I_RFIDDolphinReceive_97x61; -extern const Icon I_SDQuestion_35x43; +extern const Icon I_RFIDDolphinSend_97x61; +extern const Icon I_RFIDDolphinSuccess_108x57; extern const Icon I_SDError_43x35; -extern const Icon I_WalkR2_32x32; -extern const Icon I_WalkL2_32x32; -extern const Icon I_WalkRB1_32x32; +extern const Icon I_SDQuestion_35x43; extern const Icon I_Home_painting_17x20; -extern const Icon I_WalkLB2_32x32; -extern const Icon I_Sofa_40x13; -extern const Icon I_WalkLB1_32x32; extern const Icon I_PC_22x29; -extern const Icon I_WalkL1_32x32; +extern const Icon I_Sofa_40x13; extern const Icon I_TV_20x20; -extern const Icon I_WalkR1_32x32; -extern const Icon I_WalkRB2_32x32; extern const Icon I_TV_20x24; -extern const Icon I_BadUsb_9x8; -extern const Icon I_PlaceholderR_30x13; -extern const Icon I_Background_128x8; -extern const Icon I_Lock_8x8; -extern const Icon I_Battery_26x8; -extern const Icon I_PlaceholderL_11x13; -extern const Icon I_Battery_19x8; -extern const Icon I_SDcardMounted_11x8; -extern const Icon I_SDcardFail_11x8; -extern const Icon I_USBConnected_15x8; -extern const Icon I_Bluetooth_5x8; +extern const Icon I_WalkL1_32x32; +extern const Icon I_WalkL2_32x32; +extern const Icon I_WalkLB1_32x32; +extern const Icon I_WalkLB2_32x32; +extern const Icon I_WalkR1_32x32; +extern const Icon I_WalkR2_32x32; +extern const Icon I_WalkRB1_32x32; +extern const Icon I_WalkRB2_32x32; extern const Icon I_Background_128x11; -extern const Icon I_DolphinMafia_115x62; +extern const Icon I_Background_128x8; +extern const Icon I_BadUsb_9x8; +extern const Icon I_Battery_19x8; +extern const Icon I_Battery_26x8; +extern const Icon I_Bluetooth_5x8; +extern const Icon I_Lock_8x8; +extern const Icon I_PlaceholderL_11x13; +extern const Icon I_PlaceholderR_30x13; +extern const Icon I_SDcardFail_11x8; +extern const Icon I_SDcardMounted_11x8; +extern const Icon I_USBConnected_15x8; extern const Icon I_DolphinExcited_64x63; +extern const Icon I_DolphinMafia_115x62; +extern const Icon I_DolphinNice_96x59; +extern const Icon I_DolphinWait_61x59; extern const Icon I_iButtonDolphinSuccess_109x60; extern const Icon I_iButtonDolphinVerySuccess_108x52; extern const Icon I_iButtonKey_49x44; -extern const Icon I_DolphinNice_96x59; -extern const Icon I_DolphinWait_61x59; diff --git a/core/furi/memmgr_heap.c b/core/furi/memmgr_heap.c index 86032b63..2ddc7a26 100644 --- a/core/furi/memmgr_heap.c +++ b/core/furi/memmgr_heap.c @@ -223,6 +223,20 @@ size_t memmgr_heap_get_max_free_block() { osKernelUnlock(); return max_free_size; } + +void memmgr_heap_printf_free_blocks() { + BlockLink_t* pxBlock; + //TODO enable when we can do printf with a locked scheduler + //osKernelLock(); + + pxBlock = xStart.pxNextFreeBlock; + while(pxBlock->pxNextFreeBlock != NULL) { + printf("A %p S %lu\r\n", (void*)pxBlock, (uint32_t)pxBlock->xBlockSize); + pxBlock = pxBlock->pxNextFreeBlock; + } + + //osKernelUnlock(); +} /*-----------------------------------------------------------*/ void* pvPortMalloc(size_t xWantedSize) { diff --git a/core/furi/memmgr_heap.h b/core/furi/memmgr_heap.h index d6a2ee90..327f8d4f 100644 --- a/core/furi/memmgr_heap.h +++ b/core/furi/memmgr_heap.h @@ -28,6 +28,11 @@ size_t memmgr_heap_get_thread_memory(osThreadId_t thread_id); */ size_t memmgr_heap_get_max_free_block(); +/** + * Print the address and size of all free blocks to stdout + */ +void memmgr_heap_printf_free_blocks(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f6/Src/fatfs/ffconf.h b/firmware/targets/f6/Src/fatfs/ffconf.h index 0662e63d..d32d49a4 100644 --- a/firmware/targets/f6/Src/fatfs/ffconf.h +++ b/firmware/targets/f6/Src/fatfs/ffconf.h @@ -68,7 +68,7 @@ #define _USE_EXPAND 0 /* This option switches f_expand function. (0:Disable or 1:Enable) */ -#define _USE_CHMOD 1 +#define _USE_CHMOD 0 /* This option switches attribute manipulation functions, f_chmod() and f_utime(). / (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */ @@ -133,7 +133,7 @@ / To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1. / This option also affects behavior of string I/O functions. */ -#define _STRF_ENCODE 3 +#define _STRF_ENCODE 0 /* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to / be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf(). / @@ -205,7 +205,7 @@ / System Configurations /----------------------------------------------------------------------------*/ -#define _FS_TINY 1 /* 0:Normal or 1:Tiny */ +#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) / At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes. / Instead of private sector buffer eliminated from the file object, common sector @@ -216,10 +216,10 @@ / When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1) / Note that enabling exFAT discards C89 compatibility. */ -#define _FS_NORTC 0 -#define _NORTC_MON 6 -#define _NORTC_MDAY 4 -#define _NORTC_YEAR 2015 +#define _FS_NORTC 1 +#define _NORTC_MON 7 +#define _NORTC_MDAY 20 +#define _NORTC_YEAR 2021 /* The option _FS_NORTC switches timestamp functiton. If the system does not have / any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable / the timestamp function. All objects modified by FatFs will have a fixed timestamp @@ -229,7 +229,7 @@ / _NORTC_MDAY and _NORTC_YEAR have no effect. / These options have no effect at read-only configuration (_FS_READONLY = 1). */ -#define _FS_LOCK 2 /* 0:Disable or >=1:Enable */ +#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */ /* The option _FS_LOCK switches file lock function to control duplicated file open / and illegal operation to open objects. This option must be 0 when _FS_READONLY / is 1. @@ -240,7 +240,7 @@ / can be opened simultaneously under file lock control. Note that the file / lock control is independent of re-entrancy. */ -#define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */ +#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ #define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ #define _SYNC_t osMutexId_t /* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs diff --git a/lib/app-scened-template/file-worker.c b/lib/app-scened-template/file-worker.c index 674ddab8..cc02d994 100644 --- a/lib/app-scened-template/file-worker.c +++ b/lib/app-scened-template/file-worker.c @@ -1,16 +1,13 @@ #include "file-worker.h" #include "m-string.h" #include -#include +#include #include struct FileWorker { - FS_Api* fs_api; - SdCard_Api* sd_ex_api; + Storage* api; bool silent; - File file; - char file_buf[48]; - size_t file_buf_cnt; + File* file; }; bool file_worker_check_common_errors(FileWorker* file_worker); @@ -26,16 +23,15 @@ bool file_worker_seek_internal(FileWorker* file_worker, uint64_t position, bool FileWorker* file_worker_alloc(bool _silent) { FileWorker* file_worker = malloc(sizeof(FileWorker)); file_worker->silent = _silent; - file_worker->fs_api = furi_record_open("sdcard"); - file_worker->sd_ex_api = furi_record_open("sdcard-ex"); - file_worker->file_buf_cnt = 0; + file_worker->api = furi_record_open("storage"); + file_worker->file = storage_file_alloc(file_worker->api); return file_worker; } void file_worker_free(FileWorker* file_worker) { - furi_record_close("sdcard"); - furi_record_close("sdcard-ex"); + storage_file_free(file_worker->file); + furi_record_close("storage"); free(file_worker); } @@ -44,8 +40,7 @@ bool file_worker_open( const char* filename, FS_AccessMode access_mode, FS_OpenMode open_mode) { - bool result = - file_worker->fs_api->file.open(&file_worker->file, filename, access_mode, open_mode); + bool result = storage_file_open(file_worker->file, filename, access_mode, open_mode); if(!result) { file_worker_show_error_internal(file_worker, "Cannot open\nfile"); @@ -56,13 +51,15 @@ bool file_worker_open( } bool file_worker_close(FileWorker* file_worker) { - file_worker->fs_api->file.close(&file_worker->file); + if(storage_file_is_open(file_worker->file)) { + storage_file_close(file_worker->file); + } return file_worker_check_common_errors(file_worker); } bool file_worker_mkdir(FileWorker* file_worker, const char* dirname) { - FS_Error fs_result = file_worker->fs_api->common.mkdir(dirname); + FS_Error fs_result = storage_common_mkdir(file_worker->api, dirname); if(fs_result != FSE_OK && fs_result != FSE_EXIST) { file_worker_show_error_internal(file_worker, "Cannot create\nfolder"); @@ -73,7 +70,7 @@ bool file_worker_mkdir(FileWorker* file_worker, const char* dirname) { } bool file_worker_remove(FileWorker* file_worker, const char* filename) { - FS_Error fs_result = file_worker->fs_api->common.remove(filename); + FS_Error fs_result = storage_common_remove(file_worker->api, filename); if(fs_result != FSE_OK && fs_result != FSE_NOT_EXIST) { file_worker_show_error_internal(file_worker, "Cannot remove\nold file"); return false; @@ -96,9 +93,8 @@ bool file_worker_read_until(FileWorker* file_worker, string_t str_result, char s uint8_t buffer[buffer_size]; do { - uint16_t read_count = - file_worker->fs_api->file.read(&file_worker->file, buffer, buffer_size); - if(file_worker->file.error_id != FSE_OK) { + uint16_t read_count = storage_file_read(file_worker->file, buffer, buffer_size); + if(storage_file_get_error(file_worker->file) != FSE_OK) { file_worker_show_error_internal(file_worker, "Cannot read\nfile"); return false; } @@ -210,7 +206,16 @@ bool file_worker_write_hex(FileWorker* file_worker, const uint8_t* buffer, uint1 } void file_worker_show_error(FileWorker* file_worker, const char* error_text) { - file_worker->sd_ex_api->show_error(file_worker->sd_ex_api->context, error_text); + DialogsApp* dialogs = furi_record_open("dialogs"); + + DialogMessage* message = dialog_message_alloc(); + dialog_message_set_text(message, error_text, 88, 32, AlignCenter, AlignCenter); + dialog_message_set_icon(message, &I_SDQuestion_35x43, 5, 6); + dialog_message_set_buttons(message, "Back", NULL, NULL); + dialog_message_show(dialogs, message); + dialog_message_free(message); + + furi_record_close("dialogs"); } bool file_worker_file_select( @@ -220,16 +225,17 @@ bool file_worker_file_select( char* result, uint8_t result_size, const char* selected_filename) { - return file_worker->sd_ex_api->file_select( - file_worker->sd_ex_api->context, path, extension, result, result_size, selected_filename); + DialogsApp* dialogs = furi_record_open("dialogs"); + bool ret = + dialog_file_select_show(dialogs, path, extension, result, result_size, selected_filename); + furi_record_close("dialogs"); + return ret; } bool file_worker_check_common_errors(FileWorker* file_worker) { + //TODO remove /* TODO: [FL-1431] Add return value to file_parser.get_sd_api().check_error() and replace get_fs_info(). */ - FS_Error fs_err = file_worker->fs_api->common.get_fs_info(NULL, NULL); - if(fs_err != FSE_OK) - file_worker->sd_ex_api->show_error(file_worker->sd_ex_api->context, "SD card not found"); - return fs_err == FSE_OK; + return true; } void file_worker_show_error_internal(FileWorker* file_worker, const char* error_text) { @@ -239,10 +245,9 @@ void file_worker_show_error_internal(FileWorker* file_worker, const char* error_ } bool file_worker_read_internal(FileWorker* file_worker, void* buffer, uint16_t bytes_to_read) { - uint16_t read_count = - file_worker->fs_api->file.read(&file_worker->file, buffer, bytes_to_read); + uint16_t read_count = storage_file_read(file_worker->file, buffer, bytes_to_read); - if(file_worker->file.error_id != FSE_OK || read_count != bytes_to_read) { + if(storage_file_get_error(file_worker->file) != FSE_OK || read_count != bytes_to_read) { file_worker_show_error_internal(file_worker, "Cannot read\nfile"); return false; } @@ -254,10 +259,9 @@ bool file_worker_write_internal( FileWorker* file_worker, const void* buffer, uint16_t bytes_to_write) { - uint16_t write_count = - file_worker->fs_api->file.write(&file_worker->file, buffer, bytes_to_write); + uint16_t write_count = storage_file_write(file_worker->file, buffer, bytes_to_write); - if(file_worker->file.error_id != FSE_OK || write_count != bytes_to_write) { + if(storage_file_get_error(file_worker->file) != FSE_OK || write_count != bytes_to_write) { file_worker_show_error_internal(file_worker, "Cannot write\nto file"); return false; } @@ -266,9 +270,9 @@ bool file_worker_write_internal( } bool file_worker_tell_internal(FileWorker* file_worker, uint64_t* position) { - *position = file_worker->fs_api->file.tell(&file_worker->file); + *position = storage_file_tell(file_worker->file); - if(file_worker->file.error_id != FSE_OK) { + if(storage_file_get_error(file_worker->file) != FSE_OK) { file_worker_show_error_internal(file_worker, "Cannot tell\nfile offset"); return false; } @@ -277,8 +281,8 @@ bool file_worker_tell_internal(FileWorker* file_worker, uint64_t* position) { } bool file_worker_seek_internal(FileWorker* file_worker, uint64_t position, bool from_start) { - file_worker->fs_api->file.seek(&file_worker->file, position, from_start); - if(file_worker->file.error_id != FSE_OK) { + storage_file_seek(file_worker->file, position, from_start); + if(storage_file_get_error(file_worker->file) != FSE_OK) { file_worker_show_error_internal(file_worker, "Cannot seek\nfile"); return false; } @@ -286,9 +290,17 @@ bool file_worker_seek_internal(FileWorker* file_worker, uint64_t position, bool return true; } -bool file_worker_read_until_buffered(FileWorker* file_worker, string_t str_result, char* file_buf, size_t* file_buf_cnt, size_t file_buf_size, char separator) { +bool file_worker_read_until_buffered( + FileWorker* file_worker, + string_t str_result, + char* file_buf, + size_t* file_buf_cnt, + size_t file_buf_size, + char separator) { furi_assert(string_capacity(str_result) > 0); - furi_assert(file_buf_size <= 512); /* fs_api->file.read now supports up to 512 bytes reading at a time */ + + // fs_api->file.read now supports up to 512 bytes reading at a time + furi_assert(file_buf_size <= 512); string_clean(str_result); size_t newline_index = 0; @@ -311,11 +323,11 @@ bool file_worker_read_until_buffered(FileWorker* file_worker, string_t str_resul furi_assert(0); } - if (max_length && (string_size(str_result) + end_index > max_length)) + if(max_length && (string_size(str_result) + end_index > max_length)) max_length_exceeded = true; - if (!max_length_exceeded) { - for (size_t i = 0; i < end_index; ++i) { + if(!max_length_exceeded) { + for(size_t i = 0; i < end_index; ++i) { string_push_back(str_result, file_buf[i]); } } @@ -325,9 +337,9 @@ bool file_worker_read_until_buffered(FileWorker* file_worker, string_t str_resul if(found_eol) break; } - *file_buf_cnt += - file_worker->fs_api->file.read(&file_worker->file, &file_buf[*file_buf_cnt], file_buf_size - *file_buf_cnt); - if(file_worker->file.error_id != FSE_OK) { + *file_buf_cnt += storage_file_read( + file_worker->file, &file_buf[*file_buf_cnt], file_buf_size - *file_buf_cnt); + if(storage_file_get_error(file_worker->file) != FSE_OK) { file_worker_show_error_internal(file_worker, "Cannot read\nfile"); string_clear(str_result); *file_buf_cnt = 0; @@ -338,14 +350,13 @@ bool file_worker_read_until_buffered(FileWorker* file_worker, string_t str_resul } } - if (max_length_exceeded) - string_clear(str_result); + if(max_length_exceeded) string_clear(str_result); return string_size(str_result) || *file_buf_cnt; } bool file_worker_rename(FileWorker* file_worker, const char* old_path, const char* new_path) { - FS_Error fs_result = file_worker->fs_api->common.rename(old_path, new_path); + FS_Error fs_result = storage_common_rename(file_worker->api, old_path, new_path); if(fs_result != FSE_OK && fs_result != FSE_EXIST) { file_worker_show_error_internal(file_worker, "Cannot rename\n file/directory"); @@ -359,16 +370,12 @@ bool file_worker_check_errors(FileWorker* file_worker) { return file_worker_check_common_errors(file_worker); } -bool file_worker_is_file_exist( - FileWorker* file_worker, - const char* filename, - bool* exist) { +bool file_worker_is_file_exist(FileWorker* file_worker, const char* filename, bool* exist) { + File* file = storage_file_alloc(file_worker->api); - File file; - *exist = file_worker->fs_api->file.open(&file, filename, FSAM_READ, FSOM_OPEN_EXISTING); - if (*exist) - file_worker->fs_api->file.close(&file); + *exist = storage_file_open(file, filename, FSAM_READ, FSOM_OPEN_EXISTING); + storage_file_close(file); + storage_file_free(file); return file_worker_check_common_errors(file_worker); } - diff --git a/lib/app-scened-template/file-worker.h b/lib/app-scened-template/file-worker.h index 48c1c483..05671301 100644 --- a/lib/app-scened-template/file-worker.h +++ b/lib/app-scened-template/file-worker.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #ifdef __cplusplus extern "C" { @@ -150,20 +150,20 @@ void file_worker_show_error(FileWorker* file_worker, const char* error_text); * @brief Show system file select widget * * @param file_worker FileWorker instance - * @param path - * @param extension - * @param result - * @param result_size - * @param selected_filename - * @return true if file was selected + * @param path path to directory + * @param extension file extension to be offered for selection + * @param selected_filename buffer where the selected filename will be saved + * @param selected_filename_size and the size of this buffer + * @param preselected_filename filename to be preselected + * @return bool whether a file was selected */ bool file_worker_file_select( FileWorker* file_worker, const char* path, const char* extension, - char* result, - uint8_t result_size, - const char* selected_filename); + char* selected_filename, + uint8_t selected_filename_size, + const char* preselected_filename); /** * @brief Reads data from a file until separator or EOF is found. @@ -177,7 +177,13 @@ bool file_worker_file_select( * @param separator * @return true on success */ -bool file_worker_read_until_buffered(FileWorker* file_worker, string_t str_result, char* file_buf, size_t* file_buf_cnt, size_t max_length, char separator); +bool file_worker_read_until_buffered( + FileWorker* file_worker, + string_t str_result, + char* file_buf, + size_t* file_buf_cnt, + size_t max_length, + char separator); /** * @brief Check whether file exist or not @@ -187,10 +193,7 @@ bool file_worker_read_until_buffered(FileWorker* file_worker, string_t str_resul * @param exist - flag to show file exist * @return true on success */ -bool file_worker_is_file_exist( - FileWorker* file_worker, - const char* filename, - bool* exist); +bool file_worker_is_file_exist(FileWorker* file_worker, const char* filename, bool* exist); /** * @brief Rename file or directory @@ -200,9 +203,7 @@ bool file_worker_is_file_exist( * @param new_filename * @return true on success */ -bool file_worker_rename(FileWorker* file_worker, - const char* old_path, - const char* new_path); +bool file_worker_rename(FileWorker* file_worker, const char* old_path, const char* new_path); /** * @brief Check errors diff --git a/lib/args/args.c b/lib/args/args.c index 462d23f4..b5f24878 100644 --- a/lib/args/args.c +++ b/lib/args/args.c @@ -28,6 +28,23 @@ bool args_read_string_and_trim(string_t args, string_t word) { return true; } +bool args_read_probably_quoted_string_and_trim(string_t args, string_t word) { + if(string_size(args) > 1 && string_get_char(args, 0) == '\"') { + size_t second_quote_pos = string_search_char(args, '\"', 1); + + if(second_quote_pos == 0) { + return false; + } + + string_set_n(word, args, 1, second_quote_pos - 1); + string_right(args, second_quote_pos + 1); + string_strim(args); + return true; + } else { + return args_read_string_and_trim(args, word); + } +} + bool args_char_to_hex(char hi_nibble, char low_nibble, uint8_t* byte) { uint8_t hi_nibble_value = 0; uint8_t low_nibble_value = 0; diff --git a/lib/args/args.h b/lib/args/args.h index 0e701ac2..4d394092 100644 --- a/lib/args/args.h +++ b/lib/args/args.h @@ -8,15 +8,25 @@ extern "C" { #endif /** - * @brief Extract first word from arguments string and trim arguments string + * @brief Extract first argument from arguments string and trim arguments string * * @param args arguments string - * @param word first word, output + * @param word first argument, output * @return true - success * @return false - arguments string does not contain anything */ bool args_read_string_and_trim(string_t args, string_t word); +/** + * @brief Extract the first quoted argument from the argument string and trim the argument string. If the argument is not quoted, calls args_read_string_and_trim. + * + * @param args arguments string + * @param word first argument, output, without quotes + * @return true - success + * @return false - arguments string does not contain anything + */ +bool args_read_probably_quoted_string_and_trim(string_t args, string_t word); + /** * @brief Convert hex ASCII values to byte array * diff --git a/lib/common-api/filesystem-api.h b/lib/common-api/filesystem-api.h deleted file mode 100644 index c63f0d0e..00000000 --- a/lib/common-api/filesystem-api.h +++ /dev/null @@ -1,329 +0,0 @@ -#pragma once -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Access mode flags - */ -typedef enum { - FSAM_READ = (1 << 0), /**< Read access */ - FSAM_WRITE = (1 << 1), /**< Write access */ -} FS_AccessMode; - -/** - * @brief Open mode flags - */ -typedef enum { - FSOM_OPEN_EXISTING = 1, /**< Open file, fail if file doesn't exist */ - FSOM_OPEN_ALWAYS = 2, /**< Open file. Create new file if not exist */ - FSOM_OPEN_APPEND = 4, /**< Open file. Create new file if not exist. Set R/W pointer to EOF */ - FSOM_CREATE_NEW = 8, /**< Creates a new file. Fails if the file is exist */ - FSOM_CREATE_ALWAYS = 16, /**< Creates a new file. If file exist, truncate to zero size */ -} FS_OpenMode; - -/** - * @brief API errors enumeration - */ -typedef enum { - FSE_OK, /**< No error */ - FSE_NOT_READY, /**< FS not ready */ - FSE_EXIST, /**< File/Dir alrady exist */ - FSE_NOT_EXIST, /**< File/Dir does not exist */ - FSE_INVALID_PARAMETER, /**< Invalid API parameter */ - FSE_DENIED, /**< Access denied */ - FSE_INVALID_NAME, /**< Invalid name/path */ - FSE_INTERNAL, /**< Internal error */ - FSE_NOT_IMPLEMENTED, /**< Functon not implemented */ -} FS_Error; - -/** - * @brief FileInfo flags - */ -typedef enum { - FSF_READ_ONLY = (1 << 0), /**< Readonly */ - FSF_HIDDEN = (1 << 1), /**< Hidden */ - FSF_SYSTEM = (1 << 2), /**< System */ - FSF_DIRECTORY = (1 << 3), /**< Directory */ - FSF_ARCHIVE = (1 << 4), /**< Archive */ -} FS_Flags; - -/** - * @brief Structure that hold file index and returned api errors - */ -typedef struct { - uint32_t file_id; /**< File ID for internal references */ - FS_Error error_id; /**< Standart API error from FS_Error enum */ - uint32_t internal_error_id; /**< Internal API error value */ -} File; - -// TODO: solve year 2107 problem -/** - * @brief Structure that hold packed date values - */ -typedef struct __attribute__((packed)) { - uint16_t month_day : 5; /**< month day */ - uint16_t month : 4; /**< month index */ - uint16_t year : 7; /**< year, year + 1980 to get actual value */ -} FileDate; - -/** - * @brief Structure that hold packed time values - */ -typedef struct __attribute__((packed)) { - uint16_t second : 5; /**< second, second * 2 to get actual value */ - uint16_t minute : 6; /**< minute */ - uint16_t hour : 5; /**< hour */ -} FileTime; - -/** - * @brief Union of simple date and real value - */ -typedef union { - FileDate simple; /**< simple access to date */ - uint16_t value; /**< real date value */ -} FileDateUnion; - -/** - * @brief Union of simple time and real value - */ -typedef union { - FileTime simple; /**< simple access to time */ - uint16_t value; /**< real time value */ -} FileTimeUnion; - -/** - * @brief Structure that hold file info - */ -typedef struct { - uint8_t flags; /**< flags from FS_Flags enum */ - uint64_t size; /**< file size */ - FileDateUnion date; /**< file date */ - FileTimeUnion time; /**< file time */ -} FileInfo; - -/** @struct FS_File_Api - * @brief File api structure - * - * @var FS_File_Api::open - * @brief Open file - * @param file pointer to file object, filled by api - * @param path path to file - * @param access_mode access mode from FS_AccessMode - * @param open_mode open mode from FS_OpenMode - * @return success flag - * - * @var FS_File_Api::close - * @brief Close file - * @param file pointer to file object - * @return success flag - * - * @var FS_File_Api::read - * @brief Read bytes from file to buffer - * @param file pointer to file object - * @param buff pointer to buffer for reading - * @param bytes_to_read how many bytes to read, must be smaller or equal to buffer size - * @return how many bytes actually has been readed - * - * @var FS_File_Api::write - * @brief Write bytes from buffer to file - * @param file pointer to file object - * @param buff pointer to buffer for writing - * @param bytes_to_read how many bytes to write, must be smaller or equal to buffer size - * @return how many bytes actually has been writed - * - * @var FS_File_Api::seek - * @brief Move r/w pointer - * @param file pointer to file object - * @param offset offset to move r/w pointer - * @param from_start set offset from start, or from current position - * @return success flag - * - * @var FS_File_Api::tell - * @brief Get r/w pointer position - * @param file pointer to file object - * @return current r/w pointer position - * - * @var FS_File_Api::truncate - * @brief Truncate file size to current r/w pointer position - * @param file pointer to file object - * @return success flag - * - * @var FS_File_Api::size - * @brief Fet file size - * @param file pointer to file object - * @return file size - * - * @var FS_File_Api::sync - * @brief Write file cache to storage - * @param file pointer to file object - * @return success flag - * - * @var FS_File_Api::eof - * @brief Checks that the r/w pointer is at the end of the file - * @param file pointer to file object - * @return end of file flag - */ - -/** - * @brief File api structure - */ -typedef struct { - bool (*open)(File* file, const char* path, FS_AccessMode access_mode, FS_OpenMode open_mode); - bool (*close)(File* file); - uint16_t (*read)(File* file, void* buff, uint16_t bytes_to_read); - uint16_t (*write)(File* file, const void* buff, uint16_t bytes_to_write); - bool (*seek)(File* file, uint32_t offset, bool from_start); - uint64_t (*tell)(File* file); - bool (*truncate)(File* file); - uint64_t (*size)(File* file); - bool (*sync)(File* file); - bool (*eof)(File* file); -} FS_File_Api; - -/** @struct FS_Dir_Api - * @brief Dir api structure - * - * @var FS_Dir_Api::open - * @brief Open directory to get objects from - * @param file pointer to file object, filled by api - * @param path path to directory - * @return success flag - * - * @var FS_Dir_Api::close - * @brief Close directory - * @param file pointer to file object - * @return success flag - * - * @var FS_Dir_Api::read - * @brief Read next object info in directory - * @param file pointer to file object - * @param fileinfo pointer to readed FileInfo, can be NULL - * @param name pointer to name buffer, can be NULL - * @param name_length name buffer length - * @return success flag (if next object not exist also returns false and set error_id to FSE_NOT_EXIST) - * - * @var FS_Dir_Api::rewind - * @brief Rewind to first object info in directory - * @param file pointer to file object - * @return success flag - */ - -/** - * @brief Dir api structure - */ -typedef struct { - bool (*open)(File* file, const char* path); - bool (*close)(File* file); - bool (*read)(File* file, FileInfo* fileinfo, char* name, uint16_t name_length); - bool (*rewind)(File* file); -} FS_Dir_Api; - -/** @struct FS_Common_Api - * @brief Common api structure - * - * @var FS_Common_Api::info - * @brief Open directory to get objects from - * @param path path to file/directory - * @param fileinfo pointer to readed FileInfo, can be NULL - * @param name pointer to name buffer, can be NULL - * @param name_length name buffer length - * @return FS_Error error info - * - * @var FS_Common_Api::remove - * @brief Remove file/directory from storage, - * directory must be empty, - * file/directory must not be opened, - * file/directory must not have FSF_READ_ONLY flag - * @param path path to file/directory - * @return FS_Error error info - * - * @var FS_Common_Api::rename - * @brief Rename file/directory, - * file/directory must not be opened - * @param path path to file/directory - * @return FS_Error error info - * - * @var FS_Common_Api::set_attr - * @brief Set attributes of file/directory, - * for example: - * @code - * set "read only" flag and remove "hidden" flag - * set_attr("file.txt", FSF_READ_ONLY, FSF_READ_ONLY | FSF_HIDDEN); - * @endcode - * @param path path to file/directory - * @param attr attribute values consist of FS_Flags - * @param mask attribute mask consist of FS_Flags - * @return FS_Error error info - * - * @var FS_Common_Api::mkdir - * @brief Create new directory - * @param path path to new directory - * @return FS_Error error info - * - * @var FS_Common_Api::set_time - * @brief Set file/directory modification time - * @param path path to file/directory - * @param date modification date - * @param time modification time - * @see FileDateUnion - * @see FileTimeUnion - * @return FS_Error error info - * - * @var FS_Common_Api::get_fs_info - * @brief Get total and free space storage values - * @param total_space pointer to total space value - * @param free_space pointer to free space value - * @return FS_Error error info - */ - -/** - * @brief Common api structure - */ -typedef struct { - FS_Error (*info)(const char* path, FileInfo* fileinfo, char* name, const uint16_t name_length); - FS_Error (*remove)(const char* path); - FS_Error (*rename)(const char* old_path, const char* new_path); - FS_Error (*set_attr)(const char* path, uint8_t attr, uint8_t mask); - FS_Error (*mkdir)(const char* path); - FS_Error (*set_time)(const char* path, FileDateUnion date, FileTimeUnion time); - FS_Error (*get_fs_info)(uint64_t* total_space, uint64_t* free_space); -} FS_Common_Api; - -/** @struct FS_Error_Api - * @brief Errors api structure - * - * @var FS_Error_Api::get_desc - * @brief Get error description text - * @param error_id FS_Error error id (for fire/dir functions result can be obtained from File.error_id) - * @return pointer to description text - * - * @var FS_Error_Api::get_internal_desc - * @brief Get internal error description text - * @param internal_error_id error id (for fire/dir functions result can be obtained from File.internal_error_id) - * @return pointer to description text - */ - -/** - * @brief Errors api structure - */ -typedef struct { - const char* (*get_desc)(FS_Error error_id); - const char* (*get_internal_desc)(uint32_t internal_error_id); -} FS_Error_Api; - -/** - * @brief Full filesystem api structure - */ -typedef struct { - FS_File_Api file; - FS_Dir_Api dir; - FS_Common_Api common; - FS_Error_Api error; -} FS_Api; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/lib/common-api/sd-card-api.h b/lib/common-api/sd-card-api.h deleted file mode 100644 index d7bd611d..00000000 --- a/lib/common-api/sd-card-api.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SdApp SdApp; - -typedef struct { - SdApp* context; - bool (*file_select)( - SdApp* context, - const char* path, - const char* extension, - char* result, - uint8_t result_size, - const char* selected_filename); - void (*check_error)(SdApp* context); - void (*show_error)(SdApp* context, const char* error_text); -} SdCard_Api; - -#ifdef __cplusplus -} -#endif diff --git a/lib/file_reader/file_reader.cpp b/lib/file_reader/file_reader.cpp deleted file mode 100644 index 3dc030e4..00000000 --- a/lib/file_reader/file_reader.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include - -std::string FileReader::getline(File* file) { - std::string str; - size_t newline_index = 0; - bool found_eol = false; - bool max_length_exceeded = false; - - while(1) { - if(file_buf_cnt > 0) { - size_t end_index = 0; - char* endline_ptr = (char*)memchr(file_buf, '\n', file_buf_cnt); - newline_index = endline_ptr - file_buf; - - if(endline_ptr == 0) { - end_index = file_buf_cnt; - } else if(newline_index < file_buf_cnt) { - end_index = newline_index + 1; - found_eol = true; - } else { - furi_assert(0); - } - - if (max_line_length && (str.size() + end_index > max_line_length)) - max_length_exceeded = true; - - if (!max_length_exceeded) - str.append(file_buf, end_index); - - memmove(file_buf, &file_buf[end_index], file_buf_cnt - end_index); - file_buf_cnt = file_buf_cnt - end_index; - if(found_eol) break; - } - - file_buf_cnt += - fs_api->file.read(file, &file_buf[file_buf_cnt], sizeof(file_buf) - file_buf_cnt); - if(file_buf_cnt == 0) { - break; // end of reading - } - } - - if (max_length_exceeded) - str.clear(); - - return str; -} - - diff --git a/lib/file_reader/file_reader.h b/lib/file_reader/file_reader.h deleted file mode 100644 index f0acc442..00000000 --- a/lib/file_reader/file_reader.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -#include -#include -#include "sd-card-api.h" -#include "filesystem-api.h" - -class FileReader { -private: - char file_buf[48]; - size_t file_buf_cnt = 0; - size_t max_line_length = 0; - SdCard_Api* sd_ex_api; - FS_Api* fs_api; - -public: - FileReader() { - sd_ex_api = static_cast(furi_record_open("sdcard-ex")); - fs_api = static_cast(furi_record_open("sdcard")); - reset(); - } - ~FileReader() { - furi_record_close("sdcard"); - furi_record_close("sdcard-ex"); - } - - std::string getline(File* file); - - void reset(void) { - file_buf_cnt = 0; - } - - SdCard_Api& get_sd_api() { - return *sd_ex_api; - } - - FS_Api& get_fs_api() { - return *fs_api; - } - - void set_max_line_length(size_t value) { - max_line_length = value; - } -}; - diff --git a/lib/subghz/subghz_keystore.c b/lib/subghz/subghz_keystore.c index 02015df6..dea11e0b 100644 --- a/lib/subghz/subghz_keystore.c +++ b/lib/subghz/subghz_keystore.c @@ -1,7 +1,7 @@ #include "subghz_keystore.h" #include -#include +#include #define FILE_BUFFER_SIZE 64 @@ -52,17 +52,15 @@ static void subghz_keystore_process_line(SubGhzKeystore* instance, string_t line } void subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { - File manufacture_keys_file; - FS_Api* fs_api = furi_record_open("sdcard"); - fs_api->file.open(&manufacture_keys_file, file_name, FSAM_READ, FSOM_OPEN_EXISTING); + File* manufacture_keys_file = storage_file_alloc(furi_record_open("storage")); string_t line; string_init(line); - if(manufacture_keys_file.error_id == FSE_OK) { + if(storage_file_open(manufacture_keys_file, file_name, FSAM_READ, FSOM_OPEN_EXISTING)) { printf("Loading manufacture keys file %s\r\n", file_name); char buffer[FILE_BUFFER_SIZE]; uint16_t ret; do { - ret = fs_api->file.read(&manufacture_keys_file, buffer, FILE_BUFFER_SIZE); + ret = storage_file_read(manufacture_keys_file, buffer, FILE_BUFFER_SIZE); for (uint16_t i=0; i < ret; i++) { if (buffer[i] == '\n' && string_size(line) > 0) { subghz_keystore_process_line(instance, line); @@ -76,8 +74,9 @@ void subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { printf("Manufacture keys file is not found: %s\r\n", file_name); } string_clear(line); - fs_api->file.close(&manufacture_keys_file); - furi_record_close("sdcard"); + storage_file_close(manufacture_keys_file); + storage_file_free(manufacture_keys_file); + furi_record_close("storage"); } SubGhzKeyArray_t* subghz_keystore_get_data(SubGhzKeystore* instance) {