[FL-2744] SPI Mem Manager C port (#1860)
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
30
applications/plugins/spi_mem_manager/scenes/spi_mem_scene.c
Normal file
30
applications/plugins/spi_mem_manager/scenes/spi_mem_scene.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "spi_mem_scene.h"
|
||||
|
||||
// Generate scene on_enter handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
|
||||
void (*const spi_mem_on_enter_handlers[])(void*) = {
|
||||
#include "spi_mem_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 spi_mem_on_event_handlers[])(void* context, SceneManagerEvent event) = {
|
||||
#include "spi_mem_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 spi_mem_on_exit_handlers[])(void* context) = {
|
||||
#include "spi_mem_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Initialize scene handlers configuration structure
|
||||
const SceneManagerHandlers spi_mem_scene_handlers = {
|
||||
.on_enter_handlers = spi_mem_on_enter_handlers,
|
||||
.on_event_handlers = spi_mem_on_event_handlers,
|
||||
.on_exit_handlers = spi_mem_on_exit_handlers,
|
||||
.scene_num = SPIMemSceneNum,
|
||||
};
|
29
applications/plugins/spi_mem_manager/scenes/spi_mem_scene.h
Normal file
29
applications/plugins/spi_mem_manager/scenes/spi_mem_scene.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/scene_manager.h>
|
||||
|
||||
// Generate scene id and total number
|
||||
#define ADD_SCENE(prefix, name, id) SPIMemScene##id,
|
||||
typedef enum {
|
||||
#include "spi_mem_scene_config.h"
|
||||
SPIMemSceneNum,
|
||||
} SPIMemScene;
|
||||
#undef ADD_SCENE
|
||||
|
||||
extern const SceneManagerHandlers spi_mem_scene_handlers;
|
||||
|
||||
// Generate scene on_enter handlers declaration
|
||||
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
|
||||
#include "spi_mem_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 "spi_mem_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 "spi_mem_scene_config.h"
|
||||
#undef ADD_SCENE
|
@@ -0,0 +1,42 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include "../lib/spi/spi_mem_chip.h"
|
||||
|
||||
#define SPI_MEM_VERSION_APP "0.1.0"
|
||||
#define SPI_MEM_DEVELOPER "DrunkBatya"
|
||||
#define SPI_MEM_GITHUB "https://github.com/flipperdevices/flipperzero-firmware"
|
||||
#define SPI_MEM_NAME "\e#\e! SPI Mem Manager \e!\n"
|
||||
#define SPI_MEM_BLANK_INV "\e#\e! \e!\n"
|
||||
|
||||
void spi_mem_scene_about_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
FuriString* tmp_string = furi_string_alloc();
|
||||
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 0, 128, 14, AlignCenter, AlignBottom, SPI_MEM_BLANK_INV, false);
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 2, 128, 14, AlignCenter, AlignBottom, SPI_MEM_NAME, false);
|
||||
furi_string_printf(tmp_string, "\e#%s\n", "Information");
|
||||
furi_string_cat_printf(tmp_string, "Version: %s\n", SPI_MEM_VERSION_APP);
|
||||
furi_string_cat_printf(tmp_string, "Developed by: %s\n", SPI_MEM_DEVELOPER);
|
||||
furi_string_cat_printf(tmp_string, "Github: %s\n\n", SPI_MEM_GITHUB);
|
||||
furi_string_cat_printf(tmp_string, "\e#%s\n", "Description");
|
||||
furi_string_cat_printf(
|
||||
tmp_string,
|
||||
"SPI memory dumper\n"
|
||||
"Originally written by Hedger, ghettorce and x893 at\n"
|
||||
"Flipper Hackathon 2021\n\n");
|
||||
widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(tmp_string));
|
||||
|
||||
furi_string_free(tmp_string);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_about_on_event(void* context, SceneManagerEvent event) {
|
||||
UNUSED(context);
|
||||
UNUSED(event);
|
||||
return false;
|
||||
}
|
||||
void spi_mem_scene_about_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
|
||||
static void spi_mem_scene_chip_detect_callback(void* context, SPIMemCustomEventWorker event) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void spi_mem_scene_chip_detect_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
notification_message(app->notifications, &sequence_blink_start_yellow);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewDetect);
|
||||
spi_mem_worker_start_thread(app->worker);
|
||||
spi_mem_worker_chip_detect_start(
|
||||
app->chip_info, &app->found_chips, app->worker, spi_mem_scene_chip_detect_callback, app);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_chip_detect_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == SPIMemCustomEventWorkerChipIdentified) {
|
||||
scene_manager_set_scene_state(app->scene_manager, SPIMemSceneSelectVendor, 0);
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneSelectVendor);
|
||||
} else if(event.event == SPIMemCustomEventWorkerChipUnknown) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetectFail);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void spi_mem_scene_chip_detect_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
spi_mem_worker_stop_thread(app->worker);
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
popup_reset(app->popup);
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include "../lib/spi/spi_mem_chip.h"
|
||||
|
||||
static void spi_mem_scene_chip_detect_fail_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
SPIMemApp* app = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void spi_mem_scene_chip_detect_fail_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
FuriString* str = furi_string_alloc();
|
||||
widget_add_button_element(
|
||||
app->widget,
|
||||
GuiButtonTypeCenter,
|
||||
"Retry",
|
||||
spi_mem_scene_chip_detect_fail_widget_callback,
|
||||
app);
|
||||
widget_add_string_element(
|
||||
app->widget, 64, 9, AlignCenter, AlignBottom, FontPrimary, "Detected");
|
||||
widget_add_string_element(
|
||||
app->widget, 64, 20, AlignCenter, AlignBottom, FontPrimary, "unknown SPI chip");
|
||||
furi_string_printf(str, "Vendor\nid: 0x%02X", spi_mem_chip_get_vendor_id(app->chip_info));
|
||||
widget_add_string_multiline_element(
|
||||
app->widget, 16, 44, AlignCenter, AlignBottom, FontSecondary, furi_string_get_cstr(str));
|
||||
furi_string_printf(str, "Type\nid: 0x%02X", spi_mem_chip_get_type_id(app->chip_info));
|
||||
widget_add_string_multiline_element(
|
||||
app->widget, 64, 44, AlignCenter, AlignBottom, FontSecondary, furi_string_get_cstr(str));
|
||||
furi_string_printf(str, "Capacity\nid: 0x%02X", spi_mem_chip_get_capacity_id(app->chip_info));
|
||||
widget_add_string_multiline_element(
|
||||
app->widget, 110, 44, AlignCenter, AlignBottom, FontSecondary, furi_string_get_cstr(str));
|
||||
furi_string_free(str);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_chip_detect_fail_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
scene_manager_search_and_switch_to_previous_scene(app->scene_manager, SPIMemSceneStart);
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == GuiButtonTypeCenter) {
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_chip_detect_fail_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
|
||||
static void spi_mem_scene_chip_detected_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
SPIMemApp* app = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_mem_scene_chip_detected_print_chip_info(Widget* widget, SPIMemChip* chip_info) {
|
||||
FuriString* tmp_string = furi_string_alloc();
|
||||
widget_add_string_element(
|
||||
widget,
|
||||
40,
|
||||
12,
|
||||
AlignLeft,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
spi_mem_chip_get_vendor_name(chip_info));
|
||||
widget_add_string_element(
|
||||
widget, 40, 20, AlignLeft, AlignTop, FontSecondary, spi_mem_chip_get_model_name(chip_info));
|
||||
furi_string_printf(tmp_string, "Size: %zu KB", spi_mem_chip_get_size(chip_info) / 1024);
|
||||
widget_add_string_element(
|
||||
widget, 40, 28, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string));
|
||||
furi_string_free(tmp_string);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_chip_detect_draw_next_button(SPIMemApp* app) {
|
||||
FuriString* str = furi_string_alloc();
|
||||
if(app->mode == SPIMemModeRead) furi_string_printf(str, "%s", "Read");
|
||||
if(app->mode == SPIMemModeWrite) furi_string_printf(str, "%s", "Write");
|
||||
if(app->mode == SPIMemModeErase) furi_string_printf(str, "%s", "Erase");
|
||||
if(app->mode == SPIMemModeCompare) furi_string_printf(str, "%s", "Check");
|
||||
widget_add_button_element(
|
||||
app->widget,
|
||||
GuiButtonTypeRight,
|
||||
furi_string_get_cstr(str),
|
||||
spi_mem_scene_chip_detected_widget_callback,
|
||||
app);
|
||||
furi_string_free(str);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_chip_detected_set_previous_scene(SPIMemApp* app) {
|
||||
uint32_t scene = SPIMemSceneStart;
|
||||
if(app->mode == SPIMemModeCompare || app->mode == SPIMemModeWrite)
|
||||
scene = SPIMemSceneSavedFileMenu;
|
||||
scene_manager_search_and_switch_to_previous_scene(app->scene_manager, scene);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_chip_detected_set_next_scene(SPIMemApp* app) {
|
||||
uint32_t scene = SPIMemSceneStart;
|
||||
if(app->mode == SPIMemModeRead) scene = SPIMemSceneReadFilename;
|
||||
if(app->mode == SPIMemModeWrite) scene = SPIMemSceneErase;
|
||||
if(app->mode == SPIMemModeErase) scene = SPIMemSceneErase;
|
||||
if(app->mode == SPIMemModeCompare) scene = SPIMemSceneVerify;
|
||||
scene_manager_next_scene(app->scene_manager, scene);
|
||||
}
|
||||
|
||||
void spi_mem_scene_chip_detected_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_add_button_element(
|
||||
app->widget, GuiButtonTypeLeft, "Retry", spi_mem_scene_chip_detected_widget_callback, app);
|
||||
spi_mem_scene_chip_detect_draw_next_button(app);
|
||||
widget_add_icon_element(app->widget, 0, 12, &I_Dip8_32x36);
|
||||
widget_add_string_element(
|
||||
app->widget, 64, 9, AlignCenter, AlignBottom, FontPrimary, "Detected SPI chip");
|
||||
spi_mem_scene_chip_detected_print_chip_info(app->widget, app->chip_info);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_chip_detected_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
spi_mem_scene_chip_detected_set_previous_scene(app);
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, SPIMemSceneChipDetect);
|
||||
} else if(event.event == GuiButtonTypeRight) {
|
||||
spi_mem_scene_chip_detected_set_next_scene(app);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_chip_detected_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
|
||||
static void
|
||||
spi_mem_scene_chip_error_widget_callback(GuiButtonType result, InputType type, void* context) {
|
||||
SPIMemApp* app = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void spi_mem_scene_chip_error_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_add_button_element(
|
||||
app->widget, GuiButtonTypeLeft, "Back", spi_mem_scene_chip_error_widget_callback, app);
|
||||
widget_add_string_element(
|
||||
app->widget, 85, 15, AlignCenter, AlignBottom, FontPrimary, "SPI chip error");
|
||||
widget_add_string_multiline_element(
|
||||
app->widget,
|
||||
85,
|
||||
52,
|
||||
AlignCenter,
|
||||
AlignBottom,
|
||||
FontSecondary,
|
||||
"Error while\ncommunicating\nwith chip");
|
||||
widget_add_icon_element(app->widget, 5, 6, &I_Dip8_32x36);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_chip_error_set_previous_scene(SPIMemApp* app) {
|
||||
uint32_t scene = SPIMemSceneChipDetect;
|
||||
if(app->mode == SPIMemModeRead || app->mode == SPIMemModeErase) scene = SPIMemSceneStart;
|
||||
scene_manager_search_and_switch_to_previous_scene(app->scene_manager, scene);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_chip_error_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
spi_mem_scene_chip_error_set_previous_scene(app);
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
spi_mem_scene_chip_error_set_previous_scene(app);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_chip_error_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
ADD_SCENE(spi_mem, start, Start)
|
||||
ADD_SCENE(spi_mem, chip_detect, ChipDetect)
|
||||
ADD_SCENE(spi_mem, chip_detected, ChipDetected)
|
||||
ADD_SCENE(spi_mem, chip_detect_fail, ChipDetectFail)
|
||||
ADD_SCENE(spi_mem, select_file, SelectFile)
|
||||
ADD_SCENE(spi_mem, saved_file_menu, SavedFileMenu)
|
||||
ADD_SCENE(spi_mem, read, Read)
|
||||
ADD_SCENE(spi_mem, read_filename, ReadFilename)
|
||||
ADD_SCENE(spi_mem, delete_confirm, DeleteConfirm)
|
||||
ADD_SCENE(spi_mem, success, Success)
|
||||
ADD_SCENE(spi_mem, about, About)
|
||||
ADD_SCENE(spi_mem, verify, Verify)
|
||||
ADD_SCENE(spi_mem, file_info, FileInfo)
|
||||
ADD_SCENE(spi_mem, erase, Erase)
|
||||
ADD_SCENE(spi_mem, chip_error, ChipError)
|
||||
ADD_SCENE(spi_mem, verify_error, VerifyError)
|
||||
ADD_SCENE(spi_mem, write, Write)
|
||||
ADD_SCENE(spi_mem, storage_error, StorageError)
|
||||
ADD_SCENE(spi_mem, select_vendor, SelectVendor)
|
||||
ADD_SCENE(spi_mem, select_model, SelectModel)
|
||||
ADD_SCENE(spi_mem, wiring, Wiring)
|
@@ -0,0 +1,62 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include "../spi_mem_files.h"
|
||||
|
||||
static void spi_mem_scene_delete_confirm_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
SPIMemApp* app = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void spi_mem_scene_delete_confirm_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
FuriString* file_name = furi_string_alloc();
|
||||
FuriString* message = furi_string_alloc();
|
||||
path_extract_filename(app->file_path, file_name, true);
|
||||
furi_string_printf(message, "\e#Delete %s?\e#", furi_string_get_cstr(file_name));
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 0, 128, 27, AlignCenter, AlignCenter, furi_string_get_cstr(message), true);
|
||||
widget_add_button_element(
|
||||
app->widget,
|
||||
GuiButtonTypeLeft,
|
||||
"Cancel",
|
||||
spi_mem_scene_delete_confirm_widget_callback,
|
||||
app);
|
||||
widget_add_button_element(
|
||||
app->widget,
|
||||
GuiButtonTypeRight,
|
||||
"Delete",
|
||||
spi_mem_scene_delete_confirm_widget_callback,
|
||||
app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget);
|
||||
furi_string_free(file_name);
|
||||
furi_string_free(message);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == GuiButtonTypeRight) {
|
||||
app->mode = SPIMemModeDelete;
|
||||
if(spi_mem_file_delete(app)) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneSuccess);
|
||||
} else {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneStorageError);
|
||||
}
|
||||
} else if(event.event == GuiButtonTypeLeft) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, SPIMemSceneSavedFileMenu);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void spi_mem_scene_delete_confirm_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
|
||||
static void
|
||||
spi_mem_scene_erase_widget_callback(GuiButtonType result, InputType type, void* context) {
|
||||
SPIMemApp* app = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_mem_scene_erase_callback(void* context, SPIMemCustomEventWorker event) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void spi_mem_scene_erase_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_add_button_element(
|
||||
app->widget, GuiButtonTypeLeft, "Cancel", spi_mem_scene_erase_widget_callback, app);
|
||||
widget_add_string_element(
|
||||
app->widget, 64, 15, AlignCenter, AlignBottom, FontPrimary, "Erasing SPI chip");
|
||||
widget_add_string_element(
|
||||
app->widget, 64, 27, AlignCenter, AlignBottom, FontSecondary, "Please be patient");
|
||||
notification_message(app->notifications, &sequence_blink_start_magenta);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget);
|
||||
spi_mem_worker_start_thread(app->worker);
|
||||
spi_mem_worker_erase_start(app->chip_info, app->worker, spi_mem_scene_erase_callback, app);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_erase_set_previous_scene(SPIMemApp* app) {
|
||||
uint32_t scene = SPIMemSceneStart;
|
||||
if(app->mode == SPIMemModeWrite) scene = SPIMemSceneSavedFileMenu;
|
||||
scene_manager_search_and_switch_to_previous_scene(app->scene_manager, scene);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_erase_set_next_scene(SPIMemApp* app) {
|
||||
uint32_t scene = SPIMemSceneSuccess;
|
||||
if(app->mode == SPIMemModeWrite) scene = SPIMemSceneWrite;
|
||||
scene_manager_next_scene(app->scene_manager, scene);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_erase_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
spi_mem_scene_erase_set_previous_scene(app);
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
} else if(event.event == SPIMemCustomEventWorkerDone) {
|
||||
spi_mem_scene_erase_set_next_scene(app);
|
||||
} else if(event.event == SPIMemCustomEventWorkerChipFail) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneChipError);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_erase_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
spi_mem_worker_stop_thread(app->worker);
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include "../spi_mem_files.h"
|
||||
|
||||
void spi_mem_scene_file_info_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
FuriString* str = furi_string_alloc();
|
||||
furi_string_printf(str, "Size: %zu KB", spi_mem_file_get_size(app) / 1024);
|
||||
widget_add_string_element(
|
||||
app->widget, 64, 9, AlignCenter, AlignBottom, FontPrimary, "File info");
|
||||
widget_add_string_element(
|
||||
app->widget, 64, 20, AlignCenter, AlignBottom, FontSecondary, furi_string_get_cstr(str));
|
||||
furi_string_free(str);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_file_info_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, SPIMemSceneSavedFileMenu);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_file_info_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include "../spi_mem_files.h"
|
||||
#include "../lib/spi/spi_mem_chip.h"
|
||||
#include "../lib/spi/spi_mem_tools.h"
|
||||
|
||||
void spi_mem_scene_read_progress_view_result_callback(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, SPIMemCustomEventViewReadCancel);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_read_callback(void* context, SPIMemCustomEventWorker event) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void spi_mem_scene_read_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
spi_mem_view_progress_set_read_callback(
|
||||
app->view_progress, spi_mem_scene_read_progress_view_result_callback, app);
|
||||
notification_message(app->notifications, &sequence_blink_start_blue);
|
||||
spi_mem_view_progress_set_chip_size(app->view_progress, spi_mem_chip_get_size(app->chip_info));
|
||||
spi_mem_view_progress_set_block_size(
|
||||
app->view_progress, spi_mem_tools_get_file_max_block_size(app->chip_info));
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewProgress);
|
||||
spi_mem_worker_start_thread(app->worker);
|
||||
spi_mem_worker_read_start(app->chip_info, app->worker, spi_mem_scene_read_callback, app);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_read_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
UNUSED(app);
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == SPIMemCustomEventViewReadCancel) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, SPIMemSceneChipDetect);
|
||||
} else if(event.event == SPIMemCustomEventWorkerBlockReaded) {
|
||||
spi_mem_view_progress_inc_progress(app->view_progress);
|
||||
} else if(event.event == SPIMemCustomEventWorkerDone) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneVerify);
|
||||
} else if(event.event == SPIMemCustomEventWorkerChipFail) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneChipError);
|
||||
} else if(event.event == SPIMemCustomEventWorkerFileFail) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneStorageError);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_read_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
spi_mem_worker_stop_thread(app->worker);
|
||||
spi_mem_view_progress_reset(app->view_progress);
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include "../spi_mem_files.h"
|
||||
|
||||
void spi_mem_scene_read_filename_view_result_callback(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, SPIMemCustomEventTextEditResult);
|
||||
}
|
||||
|
||||
void spi_mem_scene_read_set_random_filename(SPIMemApp* app) {
|
||||
if(furi_string_end_with(app->file_path, SPI_MEM_FILE_EXTENSION)) {
|
||||
size_t filename_start = furi_string_search_rchar(app->file_path, '/');
|
||||
furi_string_left(app->file_path, filename_start);
|
||||
}
|
||||
set_random_name(app->text_buffer, SPI_MEM_TEXT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void spi_mem_scene_read_filename_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
spi_mem_scene_read_set_random_filename(app);
|
||||
text_input_set_header_text(app->text_input, "Name the dump");
|
||||
text_input_set_result_callback(
|
||||
app->text_input,
|
||||
spi_mem_scene_read_filename_view_result_callback,
|
||||
app,
|
||||
app->text_buffer,
|
||||
SPI_MEM_FILE_NAME_SIZE,
|
||||
true);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewTextInput);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_read_filename_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
UNUSED(app);
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == SPIMemCustomEventTextEditResult) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneRead);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_read_filename_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
text_input_reset(app->text_input);
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
|
||||
typedef enum {
|
||||
SPIMemSceneSavedFileMenuSubmenuIndexWrite,
|
||||
SPIMemSceneSavedFileMenuSubmenuIndexCompare,
|
||||
SPIMemSceneSavedFileMenuSubmenuIndexInfo,
|
||||
SPIMemSceneSavedFileMenuSubmenuIndexDelete,
|
||||
} SPIMemSceneSavedFileMenuSubmenuIndex;
|
||||
|
||||
static void spi_mem_scene_saved_file_menu_submenu_callback(void* context, uint32_t index) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void spi_mem_scene_saved_file_menu_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Write",
|
||||
SPIMemSceneSavedFileMenuSubmenuIndexWrite,
|
||||
spi_mem_scene_saved_file_menu_submenu_callback,
|
||||
app);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Compare",
|
||||
SPIMemSceneSavedFileMenuSubmenuIndexCompare,
|
||||
spi_mem_scene_saved_file_menu_submenu_callback,
|
||||
app);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Info",
|
||||
SPIMemSceneSavedFileMenuSubmenuIndexInfo,
|
||||
spi_mem_scene_saved_file_menu_submenu_callback,
|
||||
app);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Delete",
|
||||
SPIMemSceneSavedFileMenuSubmenuIndexDelete,
|
||||
spi_mem_scene_saved_file_menu_submenu_callback,
|
||||
app);
|
||||
submenu_set_selected_item(
|
||||
app->submenu, scene_manager_get_scene_state(app->scene_manager, SPIMemSceneSavedFileMenu));
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewSubmenu);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_saved_file_menu_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
scene_manager_set_scene_state(app->scene_manager, SPIMemSceneSavedFileMenu, event.event);
|
||||
if(event.event == SPIMemSceneSavedFileMenuSubmenuIndexWrite) {
|
||||
app->mode = SPIMemModeWrite;
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetect);
|
||||
success = true;
|
||||
}
|
||||
if(event.event == SPIMemSceneSavedFileMenuSubmenuIndexCompare) {
|
||||
app->mode = SPIMemModeCompare;
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetect);
|
||||
success = true;
|
||||
}
|
||||
if(event.event == SPIMemSceneSavedFileMenuSubmenuIndexDelete) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneDeleteConfirm);
|
||||
success = true;
|
||||
}
|
||||
if(event.event == SPIMemSceneSavedFileMenuSubmenuIndexInfo) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneFileInfo);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void spi_mem_scene_saved_file_menu_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
submenu_reset(app->submenu);
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include "../spi_mem_files.h"
|
||||
|
||||
void spi_mem_scene_select_file_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
if(spi_mem_file_select(app)) {
|
||||
scene_manager_set_scene_state(app->scene_manager, SPIMemSceneSavedFileMenu, 0);
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneSavedFileMenu);
|
||||
} else {
|
||||
scene_manager_search_and_switch_to_previous_scene(app->scene_manager, SPIMemSceneStart);
|
||||
}
|
||||
}
|
||||
|
||||
bool spi_mem_scene_select_file_on_event(void* context, SceneManagerEvent event) {
|
||||
UNUSED(context);
|
||||
UNUSED(event);
|
||||
return false;
|
||||
}
|
||||
|
||||
void spi_mem_scene_select_file_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
|
||||
static void spi_mem_scene_select_model_submenu_callback(void* context, uint32_t index) {
|
||||
SPIMemApp* app = context;
|
||||
spi_mem_chip_copy_chip_info(app->chip_info, *found_chips_get(app->found_chips, index));
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void spi_mem_scene_select_model_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
size_t models_on_vendor = 0;
|
||||
for(size_t index = 0; index < found_chips_size(app->found_chips); index++) {
|
||||
if(spi_mem_chip_get_vendor_enum(*found_chips_get(app->found_chips, index)) !=
|
||||
app->chip_vendor_enum)
|
||||
continue;
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
spi_mem_chip_get_model_name(*found_chips_get(app->found_chips, index)),
|
||||
index,
|
||||
spi_mem_scene_select_model_submenu_callback,
|
||||
app);
|
||||
models_on_vendor++;
|
||||
}
|
||||
if(models_on_vendor == 1) spi_mem_scene_select_model_submenu_callback(context, 0);
|
||||
submenu_set_header(app->submenu, "Choose chip model");
|
||||
submenu_set_selected_item(
|
||||
app->submenu, scene_manager_get_scene_state(app->scene_manager, SPIMemSceneSelectVendor));
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewSubmenu);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_select_model_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
scene_manager_set_scene_state(app->scene_manager, SPIMemSceneSelectVendor, event.event);
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetected);
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void spi_mem_scene_select_model_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
submenu_reset(app->submenu);
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include <m-array.h>
|
||||
#include <m-algo.h>
|
||||
|
||||
ARRAY_DEF(vendors, uint32_t)
|
||||
ALGO_DEF(vendors, ARRAY_OPLIST(vendors))
|
||||
|
||||
static void spi_mem_scene_select_vendor_submenu_callback(void* context, uint32_t index) {
|
||||
SPIMemApp* app = context;
|
||||
app->chip_vendor_enum = index;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_select_vendor_sort_vendors(SPIMemApp* app, vendors_t vendors_arr) {
|
||||
for(size_t index = 0; index < found_chips_size(app->found_chips); index++) {
|
||||
vendors_push_back(
|
||||
vendors_arr, spi_mem_chip_get_vendor_enum(*found_chips_get(app->found_chips, index)));
|
||||
}
|
||||
vendors_uniq(vendors_arr);
|
||||
}
|
||||
|
||||
void spi_mem_scene_select_vendor_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
vendors_t vendors_arr;
|
||||
vendors_init(vendors_arr);
|
||||
spi_mem_scene_select_vendor_sort_vendors(app, vendors_arr);
|
||||
size_t vendors_arr_size = vendors_size(vendors_arr);
|
||||
if(vendors_arr_size == 1)
|
||||
spi_mem_scene_select_vendor_submenu_callback(context, *vendors_get(vendors_arr, 0));
|
||||
for(size_t index = 0; index < vendors_arr_size; index++) {
|
||||
uint32_t vendor_enum = *vendors_get(vendors_arr, index);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
spi_mem_chip_get_vendor_name_by_enum(vendor_enum),
|
||||
vendor_enum,
|
||||
spi_mem_scene_select_vendor_submenu_callback,
|
||||
app);
|
||||
}
|
||||
vendors_clear(vendors_arr);
|
||||
submenu_set_header(app->submenu, "Choose chip vendor");
|
||||
submenu_set_selected_item(
|
||||
app->submenu, scene_manager_get_scene_state(app->scene_manager, SPIMemSceneSelectVendor));
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewSubmenu);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_select_vendor_set_previous_scene(SPIMemApp* app) {
|
||||
uint32_t scene = SPIMemSceneStart;
|
||||
if(app->mode == SPIMemModeCompare || app->mode == SPIMemModeWrite)
|
||||
scene = SPIMemSceneSavedFileMenu;
|
||||
scene_manager_search_and_switch_to_previous_scene(app->scene_manager, scene);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_select_vendor_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
spi_mem_scene_select_vendor_set_previous_scene(app);
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
scene_manager_set_scene_state(app->scene_manager, SPIMemSceneSelectVendor, event.event);
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneSelectModel);
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void spi_mem_scene_select_vendor_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
submenu_reset(app->submenu);
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
|
||||
typedef enum {
|
||||
SPIMemSceneStartSubmenuIndexRead,
|
||||
SPIMemSceneStartSubmenuIndexSaved,
|
||||
SPIMemSceneStartSubmenuIndexErase,
|
||||
SPIMemSceneStartSubmenuIndexWiring,
|
||||
SPIMemSceneStartSubmenuIndexAbout
|
||||
} SPIMemSceneStartSubmenuIndex;
|
||||
|
||||
static void spi_mem_scene_start_submenu_callback(void* context, uint32_t index) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void spi_mem_scene_start_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Read",
|
||||
SPIMemSceneStartSubmenuIndexRead,
|
||||
spi_mem_scene_start_submenu_callback,
|
||||
app);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Saved",
|
||||
SPIMemSceneStartSubmenuIndexSaved,
|
||||
spi_mem_scene_start_submenu_callback,
|
||||
app);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Erase",
|
||||
SPIMemSceneStartSubmenuIndexErase,
|
||||
spi_mem_scene_start_submenu_callback,
|
||||
app);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Wiring",
|
||||
SPIMemSceneStartSubmenuIndexWiring,
|
||||
spi_mem_scene_start_submenu_callback,
|
||||
app);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"About",
|
||||
SPIMemSceneStartSubmenuIndexAbout,
|
||||
spi_mem_scene_start_submenu_callback,
|
||||
app);
|
||||
submenu_set_selected_item(
|
||||
app->submenu, scene_manager_get_scene_state(app->scene_manager, SPIMemSceneStart));
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewSubmenu);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
scene_manager_set_scene_state(app->scene_manager, SPIMemSceneStart, event.event);
|
||||
if(event.event == SPIMemSceneStartSubmenuIndexRead) {
|
||||
app->mode = SPIMemModeRead;
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetect);
|
||||
success = true;
|
||||
} else if(event.event == SPIMemSceneStartSubmenuIndexSaved) {
|
||||
furi_string_set(app->file_path, SPI_MEM_FILE_FOLDER);
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneSelectFile);
|
||||
success = true;
|
||||
} else if(event.event == SPIMemSceneStartSubmenuIndexErase) {
|
||||
app->mode = SPIMemModeErase;
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetect);
|
||||
success = true;
|
||||
} else if(event.event == SPIMemSceneStartSubmenuIndexWiring) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneWiring);
|
||||
success = true;
|
||||
} else if(event.event == SPIMemSceneStartSubmenuIndexAbout) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneAbout);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void spi_mem_scene_start_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
submenu_reset(app->submenu);
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
|
||||
static void spi_mem_scene_storage_error_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
SPIMemApp* app = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void spi_mem_scene_storage_error_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_add_button_element(
|
||||
app->widget, GuiButtonTypeLeft, "Back", spi_mem_scene_storage_error_widget_callback, app);
|
||||
widget_add_string_element(
|
||||
app->widget, 85, 15, AlignCenter, AlignBottom, FontPrimary, "Storage error");
|
||||
widget_add_string_multiline_element(
|
||||
app->widget,
|
||||
85,
|
||||
52,
|
||||
AlignCenter,
|
||||
AlignBottom,
|
||||
FontSecondary,
|
||||
"Error while\nworking with\nfilesystem");
|
||||
widget_add_icon_element(app->widget, 5, 6, &I_SDQuestion_35x43);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_storage_error_set_previous_scene(SPIMemApp* app) {
|
||||
uint32_t scene = SPIMemSceneChipDetect;
|
||||
if(app->mode == SPIMemModeRead) scene = SPIMemSceneStart;
|
||||
if(app->mode == SPIMemModeErase) scene = SPIMemSceneStart;
|
||||
if(app->mode == SPIMemModeDelete) scene = SPIMemSceneStart;
|
||||
scene_manager_search_and_switch_to_previous_scene(app->scene_manager, scene);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_storage_error_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
spi_mem_scene_storage_error_set_previous_scene(app);
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
spi_mem_scene_storage_error_set_previous_scene(app);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_storage_error_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
|
||||
static void spi_mem_scene_success_popup_callback(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, SPIMemCustomEventPopupBack);
|
||||
}
|
||||
|
||||
void spi_mem_scene_success_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
popup_set_icon(app->popup, 32, 5, &I_DolphinNice_96x59);
|
||||
popup_set_header(app->popup, "Success!", 5, 7, AlignLeft, AlignTop);
|
||||
popup_set_callback(app->popup, spi_mem_scene_success_popup_callback);
|
||||
popup_set_context(app->popup, app);
|
||||
popup_set_timeout(app->popup, 1500);
|
||||
popup_enable_timeout(app->popup);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewPopup);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_success_set_previous_scene(SPIMemApp* app) {
|
||||
uint32_t scene = SPIMemSceneSelectFile;
|
||||
if(app->mode == SPIMemModeErase) scene = SPIMemSceneStart;
|
||||
scene_manager_search_and_switch_to_another_scene(app->scene_manager, scene);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_success_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == SPIMemCustomEventPopupBack) {
|
||||
spi_mem_scene_success_set_previous_scene(app);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void spi_mem_scene_success_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
popup_reset(app->popup);
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include "../spi_mem_files.h"
|
||||
#include "../lib/spi/spi_mem_chip.h"
|
||||
#include "../lib/spi/spi_mem_tools.h"
|
||||
|
||||
void spi_mem_scene_verify_view_result_callback(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, SPIMemCustomEventViewVerifySkip);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_verify_callback(void* context, SPIMemCustomEventWorker event) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void spi_mem_scene_verify_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
spi_mem_view_progress_set_verify_callback(
|
||||
app->view_progress, spi_mem_scene_verify_view_result_callback, app);
|
||||
notification_message(app->notifications, &sequence_blink_start_cyan);
|
||||
spi_mem_view_progress_set_chip_size(app->view_progress, spi_mem_chip_get_size(app->chip_info));
|
||||
spi_mem_view_progress_set_file_size(app->view_progress, spi_mem_file_get_size(app));
|
||||
spi_mem_view_progress_set_block_size(
|
||||
app->view_progress, spi_mem_tools_get_file_max_block_size(app->chip_info));
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewProgress);
|
||||
spi_mem_worker_start_thread(app->worker);
|
||||
spi_mem_worker_verify_start(app->chip_info, app->worker, spi_mem_scene_verify_callback, app);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_verify_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
UNUSED(app);
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == SPIMemCustomEventViewVerifySkip) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneSuccess);
|
||||
} else if(event.event == SPIMemCustomEventWorkerBlockReaded) {
|
||||
spi_mem_view_progress_inc_progress(app->view_progress);
|
||||
} else if(event.event == SPIMemCustomEventWorkerChipFail) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneChipError);
|
||||
} else if(event.event == SPIMemCustomEventWorkerFileFail) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneStorageError);
|
||||
} else if(event.event == SPIMemCustomEventWorkerDone) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneSuccess);
|
||||
} else if(event.event == SPIMemCustomEventWorkerVerifyFail) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneVerifyError);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_verify_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
spi_mem_worker_stop_thread(app->worker);
|
||||
spi_mem_view_progress_reset(app->view_progress);
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
|
||||
static void spi_mem_scene_verify_error_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
SPIMemApp* app = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void spi_mem_scene_verify_error_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_add_button_element(
|
||||
app->widget, GuiButtonTypeLeft, "Back", spi_mem_scene_verify_error_widget_callback, app);
|
||||
widget_add_string_element(
|
||||
app->widget, 64, 9, AlignCenter, AlignBottom, FontPrimary, "Verification error");
|
||||
widget_add_string_element(
|
||||
app->widget, 64, 21, AlignCenter, AlignBottom, FontSecondary, "Data mismatch");
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_verify_error_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, SPIMemSceneChipDetect);
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, SPIMemSceneChipDetect);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_verify_error_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include "../lib/spi/spi_mem_chip.h"
|
||||
|
||||
void spi_mem_scene_wiring_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_add_icon_element(app->widget, 0, 0, &I_Wiring_SPI_128x64);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_wiring_on_event(void* context, SceneManagerEvent event) {
|
||||
UNUSED(context);
|
||||
UNUSED(event);
|
||||
return false;
|
||||
}
|
||||
void spi_mem_scene_wiring_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
#include "../spi_mem_app_i.h"
|
||||
#include "../spi_mem_files.h"
|
||||
#include "../lib/spi/spi_mem_chip.h"
|
||||
#include "../lib/spi/spi_mem_tools.h"
|
||||
|
||||
void spi_mem_scene_write_progress_view_result_callback(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, SPIMemCustomEventViewReadCancel);
|
||||
}
|
||||
|
||||
static void spi_mem_scene_write_callback(void* context, SPIMemCustomEventWorker event) {
|
||||
SPIMemApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void spi_mem_scene_write_on_enter(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
spi_mem_view_progress_set_write_callback(
|
||||
app->view_progress, spi_mem_scene_write_progress_view_result_callback, app);
|
||||
notification_message(app->notifications, &sequence_blink_start_cyan);
|
||||
spi_mem_view_progress_set_chip_size(app->view_progress, spi_mem_chip_get_size(app->chip_info));
|
||||
spi_mem_view_progress_set_file_size(app->view_progress, spi_mem_file_get_size(app));
|
||||
spi_mem_view_progress_set_block_size(
|
||||
app->view_progress, spi_mem_tools_get_file_max_block_size(app->chip_info));
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewProgress);
|
||||
spi_mem_worker_start_thread(app->worker);
|
||||
spi_mem_worker_write_start(app->chip_info, app->worker, spi_mem_scene_write_callback, app);
|
||||
}
|
||||
|
||||
bool spi_mem_scene_write_on_event(void* context, SceneManagerEvent event) {
|
||||
SPIMemApp* app = context;
|
||||
UNUSED(app);
|
||||
bool success = false;
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
success = true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
success = true;
|
||||
if(event.event == SPIMemCustomEventViewReadCancel) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, SPIMemSceneChipDetect);
|
||||
} else if(event.event == SPIMemCustomEventWorkerBlockReaded) {
|
||||
spi_mem_view_progress_inc_progress(app->view_progress);
|
||||
} else if(event.event == SPIMemCustomEventWorkerDone) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneVerify);
|
||||
} else if(event.event == SPIMemCustomEventWorkerChipFail) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneChipError);
|
||||
} else if(event.event == SPIMemCustomEventWorkerFileFail) {
|
||||
scene_manager_next_scene(app->scene_manager, SPIMemSceneStorageError);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
void spi_mem_scene_write_on_exit(void* context) {
|
||||
SPIMemApp* app = context;
|
||||
spi_mem_worker_stop_thread(app->worker);
|
||||
spi_mem_view_progress_reset(app->view_progress);
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
}
|
Reference in New Issue
Block a user