Merge branch 'dev' of https://github.com/ClaraCrazy/Flipper-Xtreme into fix-bad_kb_bt-flipper_app-conflict

This commit is contained in:
Willy-JL
2023-02-28 21:24:18 +00:00
226 changed files with 2963 additions and 4547 deletions
-1
View File
@@ -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);
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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) {
+35 -12
View File
@@ -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) {
+39 -36
View File
@@ -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 -13
View File
@@ -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);
-4
View File
@@ -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;
+6 -6
View File
@@ -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) {
+4 -4
View File
@@ -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
*
+1 -1
View File
@@ -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
*
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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);
}
+1 -1
View File
@@ -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
*
+4 -4
View File
@@ -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;
}
+3 -3
View File
@@ -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
}
+1 -1
View File
@@ -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) {
+2 -2
View File
@@ -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;
+2 -2
View File
@@ -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
*
+3 -3
View File
@@ -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;
}
+3 -3
View File
@@ -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
*
+11 -23
View File
@@ -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;
}
}
+1 -1
View File
@@ -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();
+1 -1
View File
@@ -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
*
-30
View File
@@ -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;
+9 -12
View File
@@ -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, \
+1 -17
View File
@@ -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);
}