Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add video game module tool #127

Merged
merged 4 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions video_game_module_tool/.catalog/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
## 1.0
- Initial release
17 changes: 17 additions & 0 deletions video_game_module_tool/.catalog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Video Game Module Tool

Standalone firmware updater/installer for the Video Game Module.

## Features

- Install the official VGM firmware directly from Flipper Zero (firmware comes bundled with the application)
- Install custom VGM firmware files in UF2 format from SD card (see limitations)

## Limitations

When creating a custom UF2 firmware image, some limitations are to keep in mind:

- Non-flash blocks are NOT supported
- Block payloads MUST be exactly 256 bytes
- Payload target addresses MUST be 256 byte-aligned with no gaps
- Features such as file containers and extension tags are NOT supported
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 115 additions & 0 deletions video_game_module_tool/app.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#include <furi.h>

#include <furi_hal_rtc.h>
#include <furi_hal_debug.h>

#include <gui/gui.h>
#include <expansion/expansion.h>

#include "app_i.h"

static bool custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
App* app = context;
return scene_manager_handle_custom_event(app->scene_manager, event);
}

static bool back_event_callback(void* context) {
furi_assert(context);
App* app = context;
return scene_manager_handle_back_event(app->scene_manager);
}

static void tick_event_callback(void* context) {
furi_assert(context);
App* app = context;
scene_manager_handle_tick_event(app->scene_manager);
}

static App* app_alloc() {
App* app = malloc(sizeof(App));

app->file_path = furi_string_alloc();

app->view_dispatcher = view_dispatcher_alloc();
app->scene_manager = scene_manager_alloc(&scene_handlers, app);

app->widget = widget_alloc();
app->submenu = submenu_alloc();
app->progress = progress_alloc();

view_dispatcher_add_view(app->view_dispatcher, ViewIdWidget, widget_get_view(app->widget));
view_dispatcher_add_view(app->view_dispatcher, ViewIdSubmenu, submenu_get_view(app->submenu));
view_dispatcher_add_view(
app->view_dispatcher, ViewIdProgress, progress_get_view(app->progress));

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, custom_event_callback);
view_dispatcher_set_navigation_event_callback(app->view_dispatcher, back_event_callback);
view_dispatcher_set_tick_event_callback(app->view_dispatcher, tick_event_callback, 500);

app->notification = furi_record_open(RECORD_NOTIFICATION);

return app;
}

static void app_free(App* app) {
furi_record_close(RECORD_NOTIFICATION);

for(uint32_t i = 0; i < ViewIdMax; ++i) {
view_dispatcher_remove_view(app->view_dispatcher, i);
}

progress_free(app->progress);
submenu_free(app->submenu);
widget_free(app->widget);

scene_manager_free(app->scene_manager);
view_dispatcher_free(app->view_dispatcher);

furi_string_free(app->file_path);

free(app);
}

void submenu_item_common_callback(void* context, uint32_t index) {
furi_assert(context);

App* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, index);
}

int32_t vgm_tool_app(void* arg) {
UNUSED(arg);

Expansion* expansion = furi_record_open(RECORD_EXPANSION);
expansion_disable(expansion);

const bool is_debug_enabled = furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug);
if(is_debug_enabled) {
furi_hal_debug_disable();
}

App* app = app_alloc();
Gui* gui = furi_record_open(RECORD_GUI);

view_dispatcher_attach_to_gui(app->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
scene_manager_next_scene(app->scene_manager, SceneProbe);

view_dispatcher_run(app->view_dispatcher);

flasher_deinit();
app_free(app);

furi_record_close(RECORD_GUI);

if(is_debug_enabled) {
furi_hal_debug_enable();
}

expansion_enable(expansion);
furi_record_close(RECORD_EXPANSION);

return 0;
}
58 changes: 58 additions & 0 deletions video_game_module_tool/app_i.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* @file app_i.h
* @brief Main application header file.
*
* Contains defines, structure definitions and function prototypes
* used throughout the whole application.
*/
#pragma once

#include <gui/scene_manager.h>
#include <gui/view_dispatcher.h>

#include <gui/modules/widget.h>
#include <gui/modules/submenu.h>

#include <storage/storage.h>

#include <notification/notification.h>

#include "scenes/scene.h"
#include "views/progress.h"
#include "flasher/flasher.h"

#define VGM_TOOL_TAG "VgmTool"

// This can be set by the build system to avoid manual code editing
#ifndef VGM_FW_VERSION
#define VGM_FW_VERSION "0.1.0"
#endif
#define VGM_FW_FILE_EXTENSION ".uf2"
#define VGM_FW_FILE_NAME "vgm-fw-" VGM_FW_VERSION VGM_FW_FILE_EXTENSION

#define VGM_DEFAULT_FW_FILE APP_ASSETS_PATH(VGM_FW_FILE_NAME)
#define VGM_FW_DEFAULT_PATH EXT_PATH("")

typedef struct {
SceneManager* scene_manager;
ViewDispatcher* view_dispatcher;

Widget* widget;
Submenu* submenu;
Progress* progress;

NotificationApp* notification;

FuriString* file_path;
FlasherError flasher_error;
} App;

typedef enum {
ViewIdWidget,
ViewIdSubmenu,
ViewIdProgress,

ViewIdMax,
} ViewId;

void submenu_item_common_callback(void* context, uint32_t index);
17 changes: 17 additions & 0 deletions video_game_module_tool/application.fam
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
App(
appid="video_game_module_tool",
name="Video Game Module Tool",
apptype=FlipperAppType.EXTERNAL,
entry_point="vgm_tool_app",
requires=[
"gui",
"dialogs",
],
stack_size=2048,
fap_description="Update Video Game Module's firmware directly from Flipper",
fap_version="1.0",
fap_icon="vgm_tool.png",
fap_category="Tools",
fap_icon_assets="icons",
fap_file_assets="files",
)
11 changes: 11 additions & 0 deletions video_game_module_tool/custom_event.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

typedef enum {
// Reserve first 100 events for submenu indexes, starting from 0
CustomEventReserved = 100,

CustomEventFileConfirmed,
CustomEventFileRejected,
CustomEventSuccessDismissed,
CustomEventRetryRequested,
} CustomEvent;
Binary file added video_game_module_tool/files/vgm-fw-0.1.0.uf2
Binary file not shown.
23 changes: 23 additions & 0 deletions video_game_module_tool/flasher/board.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "board.h"

#include <furi.h>
#include <furi_hal_resources.h>

#define BOARD_RESET_PIN (gpio_ext_pc1)

void board_init(void) {
furi_hal_gpio_write(&BOARD_RESET_PIN, false);
furi_hal_gpio_init(&BOARD_RESET_PIN, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
}

void board_deinit(void) {
furi_hal_gpio_write(&BOARD_RESET_PIN, false);
furi_hal_gpio_init_simple(&BOARD_RESET_PIN, GpioModeAnalog);
}

void board_reset(void) {
furi_hal_gpio_write(&BOARD_RESET_PIN, true);
furi_delay_ms(5);
furi_hal_gpio_write(&BOARD_RESET_PIN, false);
furi_delay_ms(5);
}
23 changes: 23 additions & 0 deletions video_game_module_tool/flasher/board.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @file board.h
* @brief Video Game Module-specific functions.
*/
#pragma once

/**
* @brief Initialise the module-specific hardware.
*/
void board_init(void);

/**
* @brief Disable the module-specific hardware.
*/
void board_deinit(void);

/**
* @brief Reset the module.
*
* Resets the Video Game Module through the dedicated
* reset pin (Pin 15)
*/
void board_reset(void);