mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-30 02:18:11 -07:00
Merge branch 'dev' of https://github.com/ClaraCrazy/Flipper-Xtreme into fix-bad_kb_bt-flipper_app-conflict
This commit is contained in:
@@ -14,7 +14,6 @@ typedef struct {
|
||||
const size_t stack_size;
|
||||
const Icon* icon;
|
||||
const FlipperApplicationFlag flags;
|
||||
const char* link;
|
||||
} FlipperApplication;
|
||||
|
||||
typedef void (*FlipperOnStartHook)(void);
|
||||
|
||||
@@ -463,7 +463,7 @@ int32_t bt_srv(void* p) {
|
||||
Bt* bt = bt_alloc();
|
||||
|
||||
if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
|
||||
FURI_LOG_W(TAG, "Skipped BT init: device in special startup mode");
|
||||
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||
ble_glue_wait_for_c2_start(FURI_HAL_BT_C2_START_TIMEOUT);
|
||||
furi_record_create(RECORD_BT, bt);
|
||||
return 0;
|
||||
|
||||
@@ -461,7 +461,7 @@ int32_t cli_srv(void* p) {
|
||||
if(furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModeNormal) {
|
||||
cli_session_open(cli, &cli_vcp);
|
||||
} else {
|
||||
FURI_LOG_W(TAG, "Skipped CLI session open: device in special startup mode");
|
||||
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||
}
|
||||
|
||||
while(1) {
|
||||
|
||||
@@ -12,26 +12,48 @@
|
||||
// Close to ISO, `date +'%Y-%m-%d %H:%M:%S %u'`
|
||||
#define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d"
|
||||
|
||||
void cli_command_device_info_callback(const char* key, const char* value, bool last, void* context) {
|
||||
UNUSED(context);
|
||||
void cli_command_info_callback(const char* key, const char* value, bool last, void* context) {
|
||||
UNUSED(last);
|
||||
UNUSED(context);
|
||||
printf("%-30s: %s\r\n", key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Device Info Command
|
||||
/** Info Command
|
||||
*
|
||||
* This command is intended to be used by humans
|
||||
*
|
||||
* Arguments:
|
||||
* - device - print device info
|
||||
* - power - print power info
|
||||
* - power_debug - print power debug info
|
||||
*
|
||||
* @param cli The cli instance
|
||||
* @param args The arguments
|
||||
* @param context The context
|
||||
*/
|
||||
void cli_command_device_info(Cli* cli, FuriString* args, void* context) {
|
||||
void cli_command_info(Cli* cli, FuriString* args, void* context) {
|
||||
UNUSED(cli);
|
||||
UNUSED(args);
|
||||
furi_hal_info_get(cli_command_device_info_callback, '_', context);
|
||||
|
||||
if(context) {
|
||||
furi_hal_info_get(cli_command_info_callback, '_', NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!furi_string_cmp(args, "device")) {
|
||||
furi_hal_info_get(cli_command_info_callback, '.', NULL);
|
||||
} else if(!furi_string_cmp(args, "power")) {
|
||||
furi_hal_power_info_get(cli_command_info_callback, '.', NULL);
|
||||
} else if(!furi_string_cmp(args, "power_debug")) {
|
||||
furi_hal_power_debug_get(cli_command_info_callback, NULL);
|
||||
} else {
|
||||
cli_print_usage("info", "<device|power|power_debug>", furi_string_get_cstr(args));
|
||||
}
|
||||
}
|
||||
|
||||
void cli_command_help(Cli* cli, FuriString* args, void* context) {
|
||||
UNUSED(args);
|
||||
UNUSED(context);
|
||||
printf("Commands we have:");
|
||||
printf("Commands available:");
|
||||
|
||||
// Command count
|
||||
const size_t commands_count = CliCommandTree_size(cli->commands);
|
||||
@@ -61,9 +83,9 @@ void cli_command_help(Cli* cli, FuriString* args, void* context) {
|
||||
|
||||
if(furi_string_size(args) > 0) {
|
||||
cli_nl();
|
||||
printf("Also I have no clue what '");
|
||||
printf("`");
|
||||
printf("%s", furi_string_get_cstr(args));
|
||||
printf("' is.");
|
||||
printf("` command not found");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,8 +442,9 @@ void cli_command_i2c(Cli* cli, FuriString* args, void* context) {
|
||||
}
|
||||
|
||||
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);
|
||||
cli_add_command(cli, "!", CliCommandFlagParallelSafe, cli_command_info, (void*)true);
|
||||
cli_add_command(cli, "info", CliCommandFlagParallelSafe, cli_command_info, NULL);
|
||||
cli_add_command(cli, "device_info", CliCommandFlagParallelSafe, cli_command_info, (void*)true);
|
||||
cli_add_command(cli, "src", CliCommandFlagParallelSafe, cli_command_src, NULL);
|
||||
cli_add_command(cli, "source", CliCommandFlagParallelSafe, cli_command_src, NULL);
|
||||
|
||||
|
||||
@@ -415,7 +415,7 @@ static StorageAnimation*
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lucky_number = furi_hal_random_get() % (whole_weight != 0 ? whole_weight : 1);
|
||||
uint32_t lucky_number = furi_hal_random_get() % whole_weight;
|
||||
uint32_t weight = 0;
|
||||
|
||||
StorageAnimation* selected = NULL;
|
||||
|
||||
@@ -156,4 +156,4 @@ void animation_manager_unload_and_stall_animation(AnimationManager* animation_ma
|
||||
*
|
||||
* @animation_manager instance
|
||||
*/
|
||||
void animation_manager_load_and_continue_animation(AnimationManager* animation_manager);
|
||||
void animation_manager_load_and_continue_animation(AnimationManager* animation_manager);
|
||||
|
||||
@@ -325,7 +325,7 @@ static bool animation_storage_load_frames(
|
||||
FURI_CONST_ASSIGN(icon->width, width);
|
||||
icon->frames = malloc(sizeof(const uint8_t*) * icon->frame_count);
|
||||
|
||||
bool frames_ok = true;
|
||||
bool frames_ok = false;
|
||||
File* file = storage_file_alloc(storage);
|
||||
FileInfo file_info;
|
||||
FuriString* filename;
|
||||
@@ -333,41 +333,34 @@ static bool animation_storage_load_frames(
|
||||
size_t max_filesize = ROUND_UP_TO(width, 8) * height + 2;
|
||||
|
||||
for(int i = 0; i < icon->frame_count; ++i) {
|
||||
FURI_CONST_ASSIGN_PTR(icon->frames[i], 0);
|
||||
if(frames_ok) {
|
||||
frames_ok = false;
|
||||
furi_string_printf(filename, "%s/%s/frame_%d.bm", ANIMATION_DIR, name, i);
|
||||
do {
|
||||
if(storage_common_stat(storage, furi_string_get_cstr(filename), &file_info) !=
|
||||
FSE_OK)
|
||||
break;
|
||||
if(file_info.size > max_filesize) {
|
||||
FURI_LOG_E(
|
||||
TAG,
|
||||
"Filesize %lld, max: %d (width %d, height %d)",
|
||||
file_info.size,
|
||||
max_filesize,
|
||||
width,
|
||||
height);
|
||||
break;
|
||||
}
|
||||
if(!storage_file_open(
|
||||
file, furi_string_get_cstr(filename), FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
FURI_LOG_E(TAG, "Can't open file \'%s\'", furi_string_get_cstr(filename));
|
||||
break;
|
||||
}
|
||||
frames_ok = false;
|
||||
furi_string_printf(filename, "%s/%s/frame_%d.bm", ANIMATION_DIR, name, i);
|
||||
|
||||
FURI_CONST_ASSIGN_PTR(icon->frames[i], malloc(file_info.size));
|
||||
if(storage_file_read(file, (void*)icon->frames[i], file_info.size) !=
|
||||
file_info.size) {
|
||||
FURI_LOG_E(TAG, "Read failed: \'%s\'", furi_string_get_cstr(filename));
|
||||
break;
|
||||
} else {
|
||||
frames_ok = true;
|
||||
}
|
||||
storage_file_close(file);
|
||||
} while(0);
|
||||
if(storage_common_stat(storage, furi_string_get_cstr(filename), &file_info) != FSE_OK)
|
||||
break;
|
||||
if(file_info.size > max_filesize) {
|
||||
FURI_LOG_E(
|
||||
TAG,
|
||||
"Filesize %lld, max: %d (width %d, height %d)",
|
||||
file_info.size,
|
||||
max_filesize,
|
||||
width,
|
||||
height);
|
||||
break;
|
||||
}
|
||||
if(!storage_file_open(
|
||||
file, furi_string_get_cstr(filename), FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
FURI_LOG_E(TAG, "Can't open file \'%s\'", furi_string_get_cstr(filename));
|
||||
break;
|
||||
}
|
||||
|
||||
FURI_CONST_ASSIGN_PTR(icon->frames[i], malloc(file_info.size));
|
||||
if(storage_file_read(file, (void*)icon->frames[i], file_info.size) != file_info.size) {
|
||||
FURI_LOG_E(TAG, "Read failed: \'%s\'", furi_string_get_cstr(filename));
|
||||
break;
|
||||
}
|
||||
storage_file_close(file);
|
||||
frames_ok = true;
|
||||
}
|
||||
|
||||
if(!frames_ok) {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "helpers/pin_lock.h"
|
||||
#include "helpers/slideshow_filename.h"
|
||||
|
||||
#define TAG "Desktop"
|
||||
|
||||
static void desktop_auto_lock_arm(Desktop*);
|
||||
static void desktop_auto_lock_inhibit(Desktop*);
|
||||
static void desktop_start_auto_lock_timer(Desktop*);
|
||||
@@ -304,43 +306,44 @@ int32_t desktop_srv(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
|
||||
FURI_LOG_W("Desktop", "Desktop load skipped. Device is in special startup mode.");
|
||||
} else {
|
||||
Desktop* desktop = desktop_alloc();
|
||||
|
||||
bool loaded = DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
if(!loaded) {
|
||||
memset(&desktop->settings, 0, sizeof(desktop->settings));
|
||||
DESKTOP_SETTINGS_SAVE(&desktop->settings);
|
||||
}
|
||||
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain);
|
||||
|
||||
desktop_pin_lock_init(&desktop->settings);
|
||||
|
||||
if(!desktop_pin_lock_is_locked()) {
|
||||
if(!loader_is_locked(desktop->loader)) {
|
||||
desktop_auto_lock_arm(desktop);
|
||||
}
|
||||
} else {
|
||||
desktop_lock(desktop);
|
||||
}
|
||||
|
||||
if(desktop_check_file_flag(SLIDESHOW_FS_PATH)) {
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneSlideshow);
|
||||
}
|
||||
|
||||
if(!furi_hal_version_do_i_belong_here()) {
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneHwMismatch);
|
||||
}
|
||||
|
||||
if(furi_hal_rtc_get_fault_data()) {
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneFault);
|
||||
}
|
||||
|
||||
view_dispatcher_run(desktop->view_dispatcher);
|
||||
desktop_free(desktop);
|
||||
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Desktop* desktop = desktop_alloc();
|
||||
|
||||
bool loaded = DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||
if(!loaded) {
|
||||
memset(&desktop->settings, 0, sizeof(desktop->settings));
|
||||
DESKTOP_SETTINGS_SAVE(&desktop->settings);
|
||||
}
|
||||
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain);
|
||||
|
||||
desktop_pin_lock_init(&desktop->settings);
|
||||
|
||||
if(!desktop_pin_lock_is_locked()) {
|
||||
if(!loader_is_locked(desktop->loader)) {
|
||||
desktop_auto_lock_arm(desktop);
|
||||
}
|
||||
} else {
|
||||
desktop_lock(desktop);
|
||||
}
|
||||
|
||||
if(desktop_check_file_flag(SLIDESHOW_FS_PATH)) {
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneSlideshow);
|
||||
}
|
||||
|
||||
if(!furi_hal_version_do_i_belong_here()) {
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneHwMismatch);
|
||||
}
|
||||
|
||||
if(furi_hal_rtc_get_fault_data()) {
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneFault);
|
||||
}
|
||||
|
||||
view_dispatcher_run(desktop->view_dispatcher);
|
||||
desktop_free(desktop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "applications/services/applications.h"
|
||||
#include <applications.h>
|
||||
#include <assets_icons.h>
|
||||
#include <loader/loader.h>
|
||||
|
||||
|
||||
@@ -75,7 +75,8 @@ void desktop_debug_render(Canvas* canvas, void* model) {
|
||||
c2_ver ? c2_ver->StackTypeString : "<none>");
|
||||
canvas_draw_str(canvas, 0, 40 + STATUS_BAR_Y_SHIFT, buffer);
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "[%d] %s", version_get_target(ver), "dev");
|
||||
snprintf(
|
||||
buffer, sizeof(buffer), "[%d] %s", version_get_target(ver), version_get_gitbranch(ver));
|
||||
canvas_draw_str(canvas, 0, 50 + STATUS_BAR_Y_SHIFT, buffer);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
#include <furi.h>
|
||||
#include <gui/elements.h>
|
||||
#include <dolphin/dolphin.h>
|
||||
#include <assets_icons.h>
|
||||
|
||||
#include "../desktop_i.h"
|
||||
#include "desktop_view_lock_menu.h"
|
||||
#include "xtreme/settings.h"
|
||||
|
||||
#define LOCK_MENU_ITEMS_NB 5
|
||||
|
||||
typedef enum {
|
||||
DesktopLockMenuIndexLock,
|
||||
|
||||
@@ -85,7 +85,6 @@ DesktopMainView* desktop_main_alloc() {
|
||||
DesktopMainView* main_view = malloc(sizeof(DesktopMainView));
|
||||
|
||||
main_view->view = view_alloc();
|
||||
view_allocate_model(main_view->view, ViewModelTypeLockFree, 1);
|
||||
view_set_context(main_view->view, main_view);
|
||||
view_set_input_callback(main_view->view, desktop_main_input_callback);
|
||||
|
||||
|
||||
@@ -61,9 +61,9 @@ static bool desktop_view_slideshow_input(InputEvent* event, void* context) {
|
||||
furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_SHORT);
|
||||
} else if(event->type == InputTypeRelease) {
|
||||
furi_timer_stop(instance->timer);
|
||||
// if(!slideshow_is_one_page(model->slideshow)) {
|
||||
// furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG);
|
||||
// }
|
||||
/*if(!slideshow_is_one_page(model->slideshow)) {
|
||||
furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
view_commit_model(instance->view, update_view);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <furi_hal.h>
|
||||
#include <stdint.h>
|
||||
#include <furi.h>
|
||||
#include "furi_hal_random.h"
|
||||
#include <xtreme/settings.h>
|
||||
#define DOLPHIN_LOCK_EVENT_FLAG (0x1)
|
||||
|
||||
@@ -23,18 +22,6 @@ void dolphin_deed(Dolphin* dolphin, DolphinDeed deed) {
|
||||
dolphin_event_send_async(dolphin, &event);
|
||||
}
|
||||
|
||||
DolphinDeed getRandomDeed() {
|
||||
DolphinDeed returnGrp[14] = {1, 5, 8, 10, 12, 15, 17, 20, 21, 25, 26, 28, 29, 32};
|
||||
static bool rand_generator_inited = false;
|
||||
if(!rand_generator_inited) {
|
||||
srand(furi_get_tick());
|
||||
rand_generator_inited = true;
|
||||
}
|
||||
uint8_t diceRoll = (rand() % COUNT_OF(returnGrp)); // JUST TO GET IT GOING? AND FIX BUG
|
||||
diceRoll = (rand() % COUNT_OF(returnGrp));
|
||||
return returnGrp[diceRoll];
|
||||
}
|
||||
|
||||
DolphinStats dolphin_stats(Dolphin* dolphin) {
|
||||
furi_assert(dolphin);
|
||||
|
||||
@@ -173,6 +160,12 @@ static void dolphin_update_clear_limits_timer_period(Dolphin* dolphin) {
|
||||
|
||||
int32_t dolphin_srv(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
|
||||
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Dolphin* dolphin = dolphin_alloc();
|
||||
furi_record_create(RECORD_DOLPHIN, dolphin);
|
||||
|
||||
|
||||
@@ -44,10 +44,6 @@ void dolphin_deed(Dolphin* dolphin, DolphinDeed deed);
|
||||
*/
|
||||
DolphinStats dolphin_stats(Dolphin* dolphin);
|
||||
|
||||
/** GET RANDOM 3PT DEED
|
||||
*/
|
||||
DolphinDeed getRandomDeed();
|
||||
|
||||
/** Flush dolphin queue and save state
|
||||
* Thread safe, blocking
|
||||
*/
|
||||
|
||||
@@ -170,7 +170,7 @@ void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) {
|
||||
int32_t new_butthurt = ((int32_t)dolphin_state->data.butthurt) -
|
||||
(butthurt_icounter_level_old != butthurt_icounter_level_new);
|
||||
new_butthurt = CLAMP(new_butthurt, BUTTHURT_MAX, BUTTHURT_MIN);
|
||||
if(new_butthurt >= 7) new_butthurt = BUTTHURT_MIN; // FLIPPER STAYS HAPPY
|
||||
|
||||
dolphin_state->data.butthurt = new_butthurt;
|
||||
dolphin_state->data.timestamp = dolphin_state_timestamp();
|
||||
dolphin_state->dirty = true;
|
||||
|
||||
@@ -59,7 +59,7 @@ uint8_t* canvas_get_buffer(Canvas* canvas) {
|
||||
return u8g2_GetBufferPtr(&canvas->fb);
|
||||
}
|
||||
|
||||
size_t canvas_get_buffer_size(Canvas* canvas) {
|
||||
size_t canvas_get_buffer_size(const Canvas* canvas) {
|
||||
furi_assert(canvas);
|
||||
return u8g2_GetBufferTileWidth(&canvas->fb) * u8g2_GetBufferTileHeight(&canvas->fb) * 8;
|
||||
}
|
||||
@@ -77,17 +77,17 @@ void canvas_frame_set(
|
||||
canvas->height = height;
|
||||
}
|
||||
|
||||
uint8_t canvas_width(Canvas* canvas) {
|
||||
uint8_t canvas_width(const Canvas* canvas) {
|
||||
furi_assert(canvas);
|
||||
return canvas->width;
|
||||
}
|
||||
|
||||
uint8_t canvas_height(Canvas* canvas) {
|
||||
uint8_t canvas_height(const Canvas* canvas) {
|
||||
furi_assert(canvas);
|
||||
return canvas->height;
|
||||
}
|
||||
|
||||
uint8_t canvas_current_font_height(Canvas* canvas) {
|
||||
uint8_t canvas_current_font_height(const Canvas* canvas) {
|
||||
furi_assert(canvas);
|
||||
uint8_t font_height = u8g2_GetMaxCharHeight(&canvas->fb);
|
||||
|
||||
@@ -98,10 +98,10 @@ uint8_t canvas_current_font_height(Canvas* canvas) {
|
||||
return font_height;
|
||||
}
|
||||
|
||||
CanvasFontParameters* canvas_get_font_params(Canvas* canvas, Font font) {
|
||||
const CanvasFontParameters* canvas_get_font_params(const Canvas* canvas, Font font) {
|
||||
furi_assert(canvas);
|
||||
furi_assert(font < FontTotalNumber);
|
||||
return (CanvasFontParameters*)&canvas_font_params[font];
|
||||
return &canvas_font_params[font];
|
||||
}
|
||||
|
||||
void canvas_clear(Canvas* canvas) {
|
||||
|
||||
@@ -86,7 +86,7 @@ void canvas_commit(Canvas* canvas);
|
||||
*
|
||||
* @return width in pixels.
|
||||
*/
|
||||
uint8_t canvas_width(Canvas* canvas);
|
||||
uint8_t canvas_width(const Canvas* canvas);
|
||||
|
||||
/** Get Canvas height
|
||||
*
|
||||
@@ -94,7 +94,7 @@ uint8_t canvas_width(Canvas* canvas);
|
||||
*
|
||||
* @return height in pixels.
|
||||
*/
|
||||
uint8_t canvas_height(Canvas* canvas);
|
||||
uint8_t canvas_height(const Canvas* canvas);
|
||||
|
||||
/** Get current font height
|
||||
*
|
||||
@@ -102,7 +102,7 @@ uint8_t canvas_height(Canvas* canvas);
|
||||
*
|
||||
* @return height in pixels.
|
||||
*/
|
||||
uint8_t canvas_current_font_height(Canvas* canvas);
|
||||
uint8_t canvas_current_font_height(const Canvas* canvas);
|
||||
|
||||
/** Get font parameters
|
||||
*
|
||||
@@ -111,7 +111,7 @@ uint8_t canvas_current_font_height(Canvas* canvas);
|
||||
*
|
||||
* @return pointer to CanvasFontParameters structure
|
||||
*/
|
||||
CanvasFontParameters* canvas_get_font_params(Canvas* canvas, Font font);
|
||||
const CanvasFontParameters* canvas_get_font_params(const Canvas* canvas, Font font);
|
||||
|
||||
/** Clear canvas
|
||||
*
|
||||
|
||||
@@ -49,7 +49,7 @@ uint8_t* canvas_get_buffer(Canvas* canvas);
|
||||
*
|
||||
* @return size of canvas in bytes
|
||||
*/
|
||||
size_t canvas_get_buffer_size(Canvas* canvas);
|
||||
size_t canvas_get_buffer_size(const Canvas* canvas);
|
||||
|
||||
/** Set drawing region relative to real screen buffer
|
||||
*
|
||||
|
||||
@@ -639,7 +639,7 @@ void elements_text_box(
|
||||
bool inverse_present = false;
|
||||
Font current_font = FontSecondary;
|
||||
Font prev_font = FontSecondary;
|
||||
CanvasFontParameters* font_params = canvas_get_font_params(canvas, current_font);
|
||||
const CanvasFontParameters* font_params = canvas_get_font_params(canvas, current_font);
|
||||
|
||||
// Fill line parameters
|
||||
uint8_t line_leading_min = font_params->leading_min;
|
||||
|
||||
@@ -501,7 +501,7 @@ void gui_remove_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback,
|
||||
gui_unlock(gui);
|
||||
}
|
||||
|
||||
size_t gui_get_framebuffer_size(Gui* gui) {
|
||||
size_t gui_get_framebuffer_size(const Gui* gui) {
|
||||
furi_assert(gui);
|
||||
return canvas_get_buffer_size(gui->canvas);
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ void gui_remove_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback,
|
||||
* @param gui Gui instance
|
||||
* @return size_t size of frame buffer in bytes
|
||||
*/
|
||||
size_t gui_get_framebuffer_size(Gui* gui);
|
||||
size_t gui_get_framebuffer_size(const Gui* gui);
|
||||
|
||||
/** Set lockdown mode
|
||||
*
|
||||
|
||||
@@ -29,7 +29,7 @@ void icon_animation_set_update_callback(
|
||||
instance->callback_context = context;
|
||||
}
|
||||
|
||||
const uint8_t* icon_animation_get_data(IconAnimation* instance) {
|
||||
const uint8_t* icon_animation_get_data(const IconAnimation* instance) {
|
||||
return instance->icon->frames[instance->frame];
|
||||
}
|
||||
|
||||
@@ -51,12 +51,12 @@ void icon_animation_timer_callback(void* context) {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t icon_animation_get_width(IconAnimation* instance) {
|
||||
uint8_t icon_animation_get_width(const IconAnimation* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->icon->width;
|
||||
}
|
||||
|
||||
uint8_t icon_animation_get_height(IconAnimation* instance) {
|
||||
uint8_t icon_animation_get_height(const IconAnimation* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->icon->height;
|
||||
}
|
||||
@@ -83,7 +83,7 @@ void icon_animation_stop(IconAnimation* instance) {
|
||||
}
|
||||
}
|
||||
|
||||
bool icon_animation_is_last_frame(IconAnimation* instance) {
|
||||
bool icon_animation_is_last_frame(const IconAnimation* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->icon->frame_count - instance->frame <= 1;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ void icon_animation_set_update_callback(
|
||||
*
|
||||
* @return width in pixels
|
||||
*/
|
||||
uint8_t icon_animation_get_width(IconAnimation* instance);
|
||||
uint8_t icon_animation_get_width(const IconAnimation* instance);
|
||||
|
||||
/** Get icon animation height
|
||||
*
|
||||
@@ -63,7 +63,7 @@ uint8_t icon_animation_get_width(IconAnimation* instance);
|
||||
*
|
||||
* @return height in pixels
|
||||
*/
|
||||
uint8_t icon_animation_get_height(IconAnimation* instance);
|
||||
uint8_t icon_animation_get_height(const IconAnimation* instance);
|
||||
|
||||
/** Start icon animation
|
||||
*
|
||||
@@ -83,7 +83,7 @@ void icon_animation_stop(IconAnimation* instance);
|
||||
*
|
||||
* @return true if last frame
|
||||
*/
|
||||
bool icon_animation_is_last_frame(IconAnimation* instance);
|
||||
bool icon_animation_is_last_frame(const IconAnimation* instance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ struct IconAnimation {
|
||||
*
|
||||
* @return pointer to current frame XBM bitmap data
|
||||
*/
|
||||
const uint8_t* icon_animation_get_data(IconAnimation* instance);
|
||||
const uint8_t* icon_animation_get_data(const IconAnimation* instance);
|
||||
|
||||
/** Advance to next frame
|
||||
*
|
||||
|
||||
@@ -74,7 +74,7 @@ static void widget_element_text_scroll_fill_lines(Canvas* canvas, WidgetElement*
|
||||
}
|
||||
// Set canvas font
|
||||
canvas_set_font(canvas, line_tmp.font);
|
||||
CanvasFontParameters* params = canvas_get_font_params(canvas, line_tmp.font);
|
||||
const CanvasFontParameters* params = canvas_get_font_params(canvas, line_tmp.font);
|
||||
total_height += params->height;
|
||||
if(total_height > model->height) {
|
||||
model->scroll_pos_total++;
|
||||
@@ -138,7 +138,7 @@ static void widget_element_text_scroll_draw(Canvas* canvas, WidgetElement* eleme
|
||||
TextScrollLineArray_next(it), curr_line++) {
|
||||
if(curr_line < model->scroll_pos_current) continue;
|
||||
TextScrollLineArray* line = TextScrollLineArray_ref(it);
|
||||
CanvasFontParameters* params = canvas_get_font_params(canvas, line->font);
|
||||
const CanvasFontParameters* params = canvas_get_font_params(canvas, line->font);
|
||||
if(y + params->descender > model->y + model->height) break;
|
||||
canvas_set_font(canvas, line->font);
|
||||
if(line->horizontal == AlignLeft) {
|
||||
|
||||
@@ -34,7 +34,7 @@ void scene_manager_set_scene_state(SceneManager* scene_manager, uint32_t scene_i
|
||||
scene_manager->scene[scene_id].state = state;
|
||||
}
|
||||
|
||||
uint32_t scene_manager_get_scene_state(SceneManager* scene_manager, uint32_t scene_id) {
|
||||
uint32_t scene_manager_get_scene_state(const SceneManager* scene_manager, uint32_t scene_id) {
|
||||
furi_assert(scene_manager);
|
||||
furi_assert(scene_id < scene_manager->scene_handlers->scene_num);
|
||||
|
||||
@@ -184,7 +184,7 @@ bool scene_manager_search_and_switch_to_previous_scene_one_of(
|
||||
return scene_found;
|
||||
}
|
||||
|
||||
bool scene_manager_has_previous_scene(SceneManager* scene_manager, uint32_t scene_id) {
|
||||
bool scene_manager_has_previous_scene(const SceneManager* scene_manager, uint32_t scene_id) {
|
||||
furi_assert(scene_manager);
|
||||
bool scene_found = false;
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ void scene_manager_set_scene_state(SceneManager* scene_manager, uint32_t scene_i
|
||||
*
|
||||
* @return Scene state
|
||||
*/
|
||||
uint32_t scene_manager_get_scene_state(SceneManager* scene_manager, uint32_t scene_id);
|
||||
uint32_t scene_manager_get_scene_state(const SceneManager* scene_manager, uint32_t scene_id);
|
||||
|
||||
/** Scene Manager allocation and configuration
|
||||
*
|
||||
@@ -134,7 +134,7 @@ bool scene_manager_previous_scene(SceneManager* scene_manager);
|
||||
*
|
||||
* @return true if previous scene was found, false otherwise
|
||||
*/
|
||||
bool scene_manager_has_previous_scene(SceneManager* scene_manager, uint32_t scene_id);
|
||||
bool scene_manager_has_previous_scene(const SceneManager* scene_manager, uint32_t scene_id);
|
||||
|
||||
/** Search and switch to previous Scene
|
||||
*
|
||||
|
||||
@@ -89,7 +89,7 @@ void view_port_set_width(ViewPort* view_port, uint8_t width) {
|
||||
view_port->width = width;
|
||||
}
|
||||
|
||||
uint8_t view_port_get_width(ViewPort* view_port) {
|
||||
uint8_t view_port_get_width(const ViewPort* view_port) {
|
||||
furi_assert(view_port);
|
||||
return view_port->width;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ void view_port_set_height(ViewPort* view_port, uint8_t height) {
|
||||
view_port->height = height;
|
||||
}
|
||||
|
||||
uint8_t view_port_get_height(ViewPort* view_port) {
|
||||
uint8_t view_port_get_height(const ViewPort* view_port) {
|
||||
furi_assert(view_port);
|
||||
return view_port->height;
|
||||
}
|
||||
@@ -112,7 +112,7 @@ void view_port_enabled_set(ViewPort* view_port, bool enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
bool view_port_is_enabled(ViewPort* view_port) {
|
||||
bool view_port_is_enabled(const ViewPort* view_port) {
|
||||
furi_assert(view_port);
|
||||
return view_port->is_enabled;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ void view_port_free(ViewPort* view_port);
|
||||
* @param width wanted width, 0 - auto.
|
||||
*/
|
||||
void view_port_set_width(ViewPort* view_port, uint8_t width);
|
||||
uint8_t view_port_get_width(ViewPort* view_port);
|
||||
uint8_t view_port_get_width(const ViewPort* view_port);
|
||||
|
||||
/** Set view_port height.
|
||||
*
|
||||
@@ -66,7 +66,7 @@ uint8_t view_port_get_width(ViewPort* view_port);
|
||||
* @param height wanted height, 0 - auto.
|
||||
*/
|
||||
void view_port_set_height(ViewPort* view_port, uint8_t height);
|
||||
uint8_t view_port_get_height(ViewPort* view_port);
|
||||
uint8_t view_port_get_height(const ViewPort* view_port);
|
||||
|
||||
/** Enable or disable view_port rendering.
|
||||
*
|
||||
@@ -75,7 +75,7 @@ uint8_t view_port_get_height(ViewPort* view_port);
|
||||
* @warning automatically dispatches update event
|
||||
*/
|
||||
void view_port_enabled_set(ViewPort* view_port, bool enabled);
|
||||
bool view_port_is_enabled(ViewPort* view_port);
|
||||
bool view_port_is_enabled(const ViewPort* view_port);
|
||||
|
||||
/** ViewPort event callbacks
|
||||
*
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <furi.h>
|
||||
#include "loader/loader.h"
|
||||
#include "loader_i.h"
|
||||
#include "applications/services/desktop/desktop_i.h"
|
||||
|
||||
#define TAG "LoaderSrv"
|
||||
|
||||
@@ -48,18 +47,13 @@ static void loader_menu_callback(void* _ctx, uint32_t index) {
|
||||
|
||||
furi_assert(application->app);
|
||||
furi_assert(application->name);
|
||||
furi_assert(application->link);
|
||||
|
||||
if(strcmp(application->link, "NULL") != 0) {
|
||||
loader_start(NULL, "Applications", application->link);
|
||||
} else {
|
||||
if(!loader_lock(loader_instance)) {
|
||||
FURI_LOG_E(TAG, "Loader is locked");
|
||||
return;
|
||||
}
|
||||
|
||||
loader_start_application(application, NULL);
|
||||
if(!loader_lock(loader_instance)) {
|
||||
FURI_LOG_E(TAG, "Loader is locked");
|
||||
return;
|
||||
}
|
||||
|
||||
loader_start_application(application, NULL);
|
||||
}
|
||||
|
||||
static void loader_submenu_callback(void* context, uint32_t index) {
|
||||
@@ -162,12 +156,7 @@ static void loader_cli_list(Cli* cli, FuriString* args, Loader* instance) {
|
||||
UNUSED(instance);
|
||||
printf("Applications:\r\n");
|
||||
for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) {
|
||||
if(strcmp(FLIPPER_APPS[i].link, "NULL") != 0) {
|
||||
printf(
|
||||
"\tFor %s, Use: Applications %s\r\n", FLIPPER_APPS[i].name, FLIPPER_APPS[i].link);
|
||||
} else {
|
||||
printf("\t%s\r\n", FLIPPER_APPS[i].name);
|
||||
}
|
||||
printf("\t%s\r\n", FLIPPER_APPS[i].name);
|
||||
}
|
||||
|
||||
printf("Plugins:\r\n");
|
||||
@@ -175,7 +164,7 @@ static void loader_cli_list(Cli* cli, FuriString* args, Loader* instance) {
|
||||
printf("\t%s\r\n", FLIPPER_PLUGINS[i].name);
|
||||
}
|
||||
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) && FLIPPER_DEBUG_APPS_COUNT != 0) {
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||
printf("Debug:\r\n");
|
||||
for(size_t i = 0; i < FLIPPER_DEBUG_APPS_COUNT; i++) {
|
||||
printf("\t%s\r\n", FLIPPER_DEBUG_APPS[i].name);
|
||||
@@ -273,7 +262,7 @@ void loader_unlock(Loader* instance) {
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
bool loader_is_locked(Loader* instance) {
|
||||
bool loader_is_locked(const Loader* instance) {
|
||||
return instance->lock_count > 0;
|
||||
}
|
||||
|
||||
@@ -429,7 +418,7 @@ static void loader_build_menu() {
|
||||
loader_submenu_callback,
|
||||
(void*)LoaderMenuViewPlugins);
|
||||
}
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) && FLIPPER_DEBUG_APPS_COUNT != 0) {
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) && (FLIPPER_DEBUG_APPS_COUNT > 0)) {
|
||||
menu_add_item(
|
||||
loader_instance->primary_menu,
|
||||
"Debug Tools",
|
||||
@@ -448,9 +437,8 @@ static void loader_build_menu() {
|
||||
}
|
||||
|
||||
static void loader_build_submenu() {
|
||||
size_t i;
|
||||
|
||||
FURI_LOG_I(TAG, "Building plugins menu");
|
||||
size_t i;
|
||||
for(i = 0; i < FLIPPER_PLUGINS_COUNT; i++) {
|
||||
submenu_add_item(
|
||||
loader_instance->plugins_menu,
|
||||
@@ -531,4 +519,4 @@ int32_t loader_srv(void* p) {
|
||||
|
||||
FuriPubSub* loader_get_pubsub(Loader* instance) {
|
||||
return instance->pubsub;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ bool loader_lock(Loader* instance);
|
||||
void loader_unlock(Loader* instance);
|
||||
|
||||
/** Get loader lock status */
|
||||
bool loader_is_locked(Loader* instance);
|
||||
bool loader_is_locked(const Loader* instance);
|
||||
|
||||
/** Show primary loader */
|
||||
void loader_show_menu();
|
||||
|
||||
@@ -81,7 +81,7 @@ void locale_format_time(
|
||||
*
|
||||
* @return The Locale DateFormat.
|
||||
*/
|
||||
LocaleDateFormat locale_get_date_format();
|
||||
LocaleDateFormat locale_get_date_format(void);
|
||||
|
||||
/** Set Locale DateFormat
|
||||
*
|
||||
|
||||
@@ -26,24 +26,6 @@ void power_cli_reboot2dfu(Cli* cli, FuriString* args) {
|
||||
power_reboot(PowerBootModeDfu);
|
||||
}
|
||||
|
||||
static void power_cli_callback(const char* key, const char* value, bool last, void* context) {
|
||||
UNUSED(last);
|
||||
UNUSED(context);
|
||||
printf("%-24s: %s\r\n", key, value);
|
||||
}
|
||||
|
||||
void power_cli_info(Cli* cli, FuriString* args) {
|
||||
UNUSED(cli);
|
||||
UNUSED(args);
|
||||
furi_hal_power_info_get(power_cli_callback, '_', NULL);
|
||||
}
|
||||
|
||||
void power_cli_debug(Cli* cli, FuriString* args) {
|
||||
UNUSED(cli);
|
||||
UNUSED(args);
|
||||
furi_hal_power_debug_get(power_cli_callback, NULL);
|
||||
}
|
||||
|
||||
void power_cli_5v(Cli* cli, FuriString* args) {
|
||||
UNUSED(cli);
|
||||
if(!furi_string_cmp(args, "0")) {
|
||||
@@ -74,8 +56,6 @@ static void power_cli_command_print_usage() {
|
||||
printf("\toff\t - shutdown power\r\n");
|
||||
printf("\treboot\t - reboot\r\n");
|
||||
printf("\treboot2dfu\t - reboot to dfu bootloader\r\n");
|
||||
printf("\tinfo\t - show power info\r\n");
|
||||
printf("\tdebug\t - show debug information\r\n");
|
||||
printf("\t5v <0 or 1>\t - enable or disable 5v ext\r\n");
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||
printf("\t3v3 <0 or 1>\t - enable or disable 3v3 ext\r\n");
|
||||
@@ -108,16 +88,6 @@ void power_cli(Cli* cli, FuriString* args, void* context) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(furi_string_cmp_str(cmd, "info") == 0) {
|
||||
power_cli_info(cli, args);
|
||||
break;
|
||||
}
|
||||
|
||||
if(furi_string_cmp_str(cmd, "debug") == 0) {
|
||||
power_cli_debug(cli, args);
|
||||
break;
|
||||
}
|
||||
|
||||
if(furi_string_cmp_str(cmd, "5v") == 0) {
|
||||
power_cli_5v(cli, args);
|
||||
break;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "xtreme/settings.h"
|
||||
|
||||
#define POWER_OFF_TIMEOUT 90
|
||||
#define TAG "Power"
|
||||
|
||||
void power_draw_battery_callback(Canvas* canvas, void* context) {
|
||||
furi_assert(context);
|
||||
@@ -73,7 +74,7 @@ void power_draw_battery_callback(Canvas* canvas, void* context) {
|
||||
} else if(
|
||||
(battery_icon == BatteryIconBarPercent) &&
|
||||
(power->state != PowerStateCharging) && // Default bar display with percentage
|
||||
(power->info.voltage_battery_charging >=
|
||||
(power->info.voltage_battery_charge_limit >=
|
||||
4.2)) { // not looking nice with low voltage indicator
|
||||
canvas_set_font(canvas, FontBatteryPercent);
|
||||
|
||||
@@ -117,7 +118,7 @@ void power_draw_battery_callback(Canvas* canvas, void* context) {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 15, 4, AlignCenter, AlignCenter, batteryPercentileSecondDigit);
|
||||
} else { // charge >= 62, both digits are white
|
||||
} else { // charge >= 74, both digits are white
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 11, 4, AlignCenter, AlignCenter, batteryPercentile);
|
||||
@@ -128,7 +129,7 @@ void power_draw_battery_callback(Canvas* canvas, void* context) {
|
||||
}
|
||||
|
||||
// TODO: Verify if it displays correctly with custom battery skins !!!
|
||||
if(power->info.voltage_battery_charging < 4.2) {
|
||||
if(power->info.voltage_battery_charge_limit < 4.2) {
|
||||
// Battery charging voltage is modified, indicate with cross pattern
|
||||
canvas_invert_color(canvas);
|
||||
uint8_t battery_bar_width = (power->info.charge + 4) / 5;
|
||||
@@ -442,7 +443,7 @@ static bool power_update_info(Power* power) {
|
||||
info.capacity_full = furi_hal_power_get_battery_full_capacity();
|
||||
info.current_charger = furi_hal_power_get_battery_current(FuriHalPowerICCharger);
|
||||
info.current_gauge = furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge);
|
||||
info.voltage_battery_charging = furi_hal_power_get_battery_charging_voltage();
|
||||
info.voltage_battery_charge_limit = furi_hal_power_get_battery_charge_voltage_limit();
|
||||
info.voltage_charger = furi_hal_power_get_battery_voltage(FuriHalPowerICCharger);
|
||||
info.voltage_gauge = furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge);
|
||||
info.voltage_vbus = furi_hal_power_get_usb_voltage();
|
||||
@@ -513,6 +514,12 @@ static void power_check_battery_level_change(Power* power) {
|
||||
|
||||
int32_t power_srv(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
|
||||
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Power* power = power_alloc();
|
||||
if(!LOAD_POWER_SETTINGS(&power->shutdown_idle_delay_ms)) {
|
||||
power->shutdown_idle_delay_ms = 0;
|
||||
|
||||
@@ -52,7 +52,7 @@ typedef struct {
|
||||
float current_charger;
|
||||
float current_gauge;
|
||||
|
||||
float voltage_battery_charging;
|
||||
float voltage_battery_charge_limit;
|
||||
float voltage_charger;
|
||||
float voltage_gauge;
|
||||
float voltage_vbus;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <stm32_adafruit_sd.h>
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include <lib/toolbox/args.h>
|
||||
@@ -61,28 +60,26 @@ static void storage_cli_info(Cli* cli, FuriString* path) {
|
||||
}
|
||||
} else if(furi_string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) {
|
||||
SDInfo sd_info;
|
||||
SD_CID sd_cid;
|
||||
FS_Error error = storage_sd_info(api, &sd_info);
|
||||
BSP_SD_GetCIDRegister(&sd_cid);
|
||||
|
||||
if(error != FSE_OK) {
|
||||
storage_cli_print_error(error);
|
||||
} else {
|
||||
printf(
|
||||
"Label: %s\r\nType: %s\r\n%luKiB total\r\n%luKiB free\r\n"
|
||||
"%02x%2.2s %5.5s %i.%i\r\nSN:%04lx %02i/%i\r\n",
|
||||
"%02x%s %s v%i.%i\r\nSN:%04lx %02i/%i\r\n",
|
||||
sd_info.label,
|
||||
sd_api_get_fs_type_text(sd_info.fs_type),
|
||||
sd_info.kb_total,
|
||||
sd_info.kb_free,
|
||||
sd_cid.ManufacturerID,
|
||||
sd_cid.OEM_AppliID,
|
||||
sd_cid.ProdName,
|
||||
sd_cid.ProdRev >> 4,
|
||||
sd_cid.ProdRev & 0xf,
|
||||
sd_cid.ProdSN,
|
||||
sd_cid.ManufactMonth,
|
||||
sd_cid.ManufactYear + 2000);
|
||||
sd_info.manufacturer_id,
|
||||
sd_info.oem_id,
|
||||
sd_info.product_name,
|
||||
sd_info.product_revision_major,
|
||||
sd_info.product_revision_minor,
|
||||
sd_info.product_serial_number,
|
||||
sd_info.manufacturing_month,
|
||||
sd_info.manufacturing_year);
|
||||
}
|
||||
} else {
|
||||
storage_cli_print_usage();
|
||||
|
||||
@@ -12,9 +12,7 @@
|
||||
|
||||
#define TAG "StorageAPI"
|
||||
|
||||
#define S_API_PROLOGUE \
|
||||
FuriSemaphore* semaphore = furi_semaphore_alloc(1, 0); \
|
||||
furi_check(semaphore != NULL);
|
||||
#define S_API_PROLOGUE FuriApiLock lock = api_lock_alloc_locked();
|
||||
|
||||
#define S_FILE_API_PROLOGUE \
|
||||
Storage* storage = file->storage; \
|
||||
@@ -24,13 +22,12 @@
|
||||
furi_check( \
|
||||
furi_message_queue_put(storage->message_queue, &message, FuriWaitForever) == \
|
||||
FuriStatusOk); \
|
||||
furi_semaphore_acquire(semaphore, FuriWaitForever); \
|
||||
furi_semaphore_free(semaphore);
|
||||
api_lock_wait_unlock_and_free(lock)
|
||||
|
||||
#define S_API_MESSAGE(_command) \
|
||||
SAReturn return_data; \
|
||||
StorageMessage message = { \
|
||||
.semaphore = semaphore, \
|
||||
.lock = lock, \
|
||||
.command = _command, \
|
||||
.data = &data, \
|
||||
.return_data = &return_data, \
|
||||
|
||||
@@ -31,29 +31,13 @@ void storage_file_clear(StorageFile* obj) {
|
||||
/****************** storage data ******************/
|
||||
|
||||
void storage_data_init(StorageData* storage) {
|
||||
storage->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
furi_check(storage->mutex != NULL);
|
||||
storage->data = NULL;
|
||||
storage->status = StorageStatusNotReady;
|
||||
StorageFileList_init(storage->files);
|
||||
}
|
||||
|
||||
bool storage_data_lock(StorageData* storage) {
|
||||
return (furi_mutex_acquire(storage->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
}
|
||||
|
||||
bool storage_data_unlock(StorageData* storage) {
|
||||
return (furi_mutex_release(storage->mutex) == FuriStatusOk);
|
||||
}
|
||||
|
||||
StorageStatus storage_data_status(StorageData* storage) {
|
||||
StorageStatus status;
|
||||
|
||||
storage_data_lock(storage);
|
||||
status = storage->status;
|
||||
storage_data_unlock(storage);
|
||||
|
||||
return status;
|
||||
return storage->status;
|
||||
}
|
||||
|
||||
const char* storage_data_status_text(StorageData* storage) {
|
||||
|
||||
@@ -38,8 +38,6 @@ 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);
|
||||
void storage_data_timestamp(StorageData* storage);
|
||||
@@ -57,7 +55,6 @@ struct StorageData {
|
||||
const FS_Api* fs_api;
|
||||
StorageApi api;
|
||||
void* data;
|
||||
FuriMutex* mutex;
|
||||
StorageStatus status;
|
||||
StorageFileList_t files;
|
||||
uint32_t timestamp;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <furi.h>
|
||||
#include <toolbox/api_lock.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -130,7 +131,7 @@ typedef enum {
|
||||
} StorageCommand;
|
||||
|
||||
typedef struct {
|
||||
FuriSemaphore* semaphore;
|
||||
FuriApiLock lock;
|
||||
StorageCommand command;
|
||||
SAData* data;
|
||||
SAReturn* return_data;
|
||||
|
||||
@@ -2,15 +2,7 @@
|
||||
#include <m-list.h>
|
||||
#include <m-dict.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);
|
||||
#define FS_CALL(_storage, _fn) ret = _storage->fs_api->_fn;
|
||||
|
||||
static StorageData* storage_get_storage_by_type(Storage* app, StorageType type) {
|
||||
furi_check(type == ST_EXT || type == ST_INT);
|
||||
@@ -44,16 +36,11 @@ static const char* remove_vfs(const char* path) {
|
||||
|
||||
static StorageType storage_get_type_by_path(Storage* app, const char* path) {
|
||||
StorageType type = ST_ERROR;
|
||||
if(strlen(path) >= strlen(STORAGE_EXT_PATH_PREFIX) &&
|
||||
memcmp(path, STORAGE_EXT_PATH_PREFIX, strlen(STORAGE_EXT_PATH_PREFIX)) == 0) {
|
||||
if(memcmp(path, STORAGE_EXT_PATH_PREFIX, strlen(STORAGE_EXT_PATH_PREFIX)) == 0) {
|
||||
type = ST_EXT;
|
||||
} else if(
|
||||
strlen(path) >= strlen(STORAGE_INT_PATH_PREFIX) &&
|
||||
memcmp(path, STORAGE_INT_PATH_PREFIX, strlen(STORAGE_INT_PATH_PREFIX)) == 0) {
|
||||
} else if(memcmp(path, STORAGE_INT_PATH_PREFIX, strlen(STORAGE_INT_PATH_PREFIX)) == 0) {
|
||||
type = ST_INT;
|
||||
} else if(
|
||||
strlen(path) >= strlen(STORAGE_ANY_PATH_PREFIX) &&
|
||||
memcmp(path, STORAGE_ANY_PATH_PREFIX, strlen(STORAGE_ANY_PATH_PREFIX)) == 0) {
|
||||
} else if(memcmp(path, STORAGE_ANY_PATH_PREFIX, strlen(STORAGE_ANY_PATH_PREFIX)) == 0) {
|
||||
type = ST_ANY;
|
||||
}
|
||||
|
||||
@@ -68,21 +55,15 @@ static StorageType storage_get_type_by_path(Storage* app, const char* path) {
|
||||
}
|
||||
|
||||
static void storage_path_change_to_real_storage(FuriString* path, StorageType real_storage) {
|
||||
if(memcmp(
|
||||
furi_string_get_cstr(path), STORAGE_ANY_PATH_PREFIX, strlen(STORAGE_ANY_PATH_PREFIX)) ==
|
||||
0) {
|
||||
if(furi_string_search(path, STORAGE_ANY_PATH_PREFIX) == 0) {
|
||||
switch(real_storage) {
|
||||
case ST_EXT:
|
||||
furi_string_set_char(path, 0, STORAGE_EXT_PATH_PREFIX[0]);
|
||||
furi_string_set_char(path, 1, STORAGE_EXT_PATH_PREFIX[1]);
|
||||
furi_string_set_char(path, 2, STORAGE_EXT_PATH_PREFIX[2]);
|
||||
furi_string_set_char(path, 3, STORAGE_EXT_PATH_PREFIX[3]);
|
||||
furi_string_replace_at(
|
||||
path, 0, strlen(STORAGE_EXT_PATH_PREFIX), STORAGE_EXT_PATH_PREFIX);
|
||||
break;
|
||||
case ST_INT:
|
||||
furi_string_set_char(path, 0, STORAGE_INT_PATH_PREFIX[0]);
|
||||
furi_string_set_char(path, 1, STORAGE_INT_PATH_PREFIX[1]);
|
||||
furi_string_set_char(path, 2, STORAGE_INT_PATH_PREFIX[2]);
|
||||
furi_string_set_char(path, 3, STORAGE_INT_PATH_PREFIX[3]);
|
||||
furi_string_replace_at(
|
||||
path, 0, strlen(STORAGE_INT_PATH_PREFIX), STORAGE_INT_PATH_PREFIX);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -604,7 +585,7 @@ void storage_process_message_internal(Storage* app, StorageMessage* message) {
|
||||
break;
|
||||
}
|
||||
|
||||
furi_semaphore_release(message->semaphore);
|
||||
api_lock_unlock(message->lock);
|
||||
}
|
||||
|
||||
void storage_process_message(Storage* app, StorageMessage* message) {
|
||||
|
||||
@@ -23,6 +23,16 @@ typedef struct {
|
||||
uint16_t cluster_size;
|
||||
uint16_t sector_size;
|
||||
char label[SD_LABEL_LENGTH];
|
||||
|
||||
uint8_t manufacturer_id;
|
||||
char oem_id[3];
|
||||
char product_name[6];
|
||||
uint8_t product_revision_major;
|
||||
uint8_t product_revision_minor;
|
||||
uint32_t product_serial_number;
|
||||
uint8_t manufacturing_month;
|
||||
uint16_t manufacturing_year;
|
||||
|
||||
FS_Error error;
|
||||
} SDInfo;
|
||||
|
||||
|
||||
@@ -26,12 +26,10 @@ static FS_Error storage_ext_parse_error(SDError error);
|
||||
|
||||
static bool sd_mount_card(StorageData* storage, bool notify) {
|
||||
bool result = false;
|
||||
uint8_t counter = BSP_SD_MaxMountRetryCount();
|
||||
uint8_t counter = sd_max_mount_retry_count();
|
||||
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(RECORD_NOTIFICATION);
|
||||
@@ -41,9 +39,9 @@ static bool sd_mount_card(StorageData* storage, bool notify) {
|
||||
|
||||
if((counter % 2) == 0) {
|
||||
// power reset sd card
|
||||
bsp_result = BSP_SD_Init(true);
|
||||
bsp_result = sd_init(true);
|
||||
} else {
|
||||
bsp_result = BSP_SD_Init(false);
|
||||
bsp_result = sd_init(false);
|
||||
}
|
||||
|
||||
if(bsp_result) {
|
||||
@@ -91,7 +89,6 @@ static bool sd_mount_card(StorageData* storage, bool notify) {
|
||||
}
|
||||
|
||||
storage_data_timestamp(storage);
|
||||
storage_data_unlock(storage);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -100,14 +97,12 @@ FS_Error sd_unmount_card(StorageData* storage) {
|
||||
SDData* sd_data = storage->data;
|
||||
SDError error;
|
||||
|
||||
storage_data_lock(storage);
|
||||
storage->status = StorageStatusNotReady;
|
||||
error = FR_DISK_ERR;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -120,8 +115,6 @@ FS_Error sd_format_card(StorageData* storage) {
|
||||
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);
|
||||
@@ -138,8 +131,6 @@ FS_Error sd_format_card(StorageData* storage) {
|
||||
storage->status = StorageStatusOK;
|
||||
} while(false);
|
||||
|
||||
storage_data_unlock(storage);
|
||||
|
||||
return storage_ext_parse_error(error);
|
||||
#endif
|
||||
}
|
||||
@@ -156,14 +147,12 @@ FS_Error sd_card_info(StorageData* storage, SDInfo* sd_info) {
|
||||
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) {
|
||||
#ifndef FURI_RAM_EXEC
|
||||
error = f_getfree(sd_data->path, &free_clusters, &fs);
|
||||
#endif
|
||||
}
|
||||
storage_data_unlock(storage);
|
||||
|
||||
if(error == FR_OK) {
|
||||
// calculate size
|
||||
@@ -210,6 +199,20 @@ FS_Error sd_card_info(StorageData* storage, SDInfo* sd_info) {
|
||||
#endif
|
||||
}
|
||||
|
||||
SD_CID cid;
|
||||
SdSpiStatus status = sd_get_cid(&cid);
|
||||
|
||||
if(status == SdSpiStatusOK) {
|
||||
sd_info->manufacturer_id = cid.ManufacturerID;
|
||||
memcpy(sd_info->oem_id, cid.OEM_AppliID, sizeof(cid.OEM_AppliID));
|
||||
memcpy(sd_info->product_name, cid.ProdName, sizeof(cid.ProdName));
|
||||
sd_info->product_revision_major = cid.ProdRev >> 4;
|
||||
sd_info->product_revision_minor = cid.ProdRev & 0x0F;
|
||||
sd_info->product_serial_number = cid.ProdSN;
|
||||
sd_info->manufacturing_year = 2000 + cid.ManufactYear;
|
||||
sd_info->manufacturing_month = cid.ManufactMonth;
|
||||
}
|
||||
|
||||
return storage_ext_parse_error(error);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user