1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 20:49:49 +04:00

Merge branch 'ofw-dev' into dev

This commit is contained in:
MX
2023-08-02 16:09:16 +03:00
20 changed files with 372 additions and 155 deletions

View File

@@ -564,7 +564,7 @@ void subghz_device_cc1101_ext_start_async_rx(
furi_hal_bus_enable(FuriHalBusTIM17); furi_hal_bus_enable(FuriHalBusTIM17);
// Configure TIM // Configure TIM
//Set the timer resolution to 2 <EFBFBD>s //Set the timer resolution to 2 us
LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1); LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1);
LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP); LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP);
LL_TIM_SetAutoReload(TIM17, 0xFFFF); LL_TIM_SetAutoReload(TIM17, 0xFFFF);
@@ -745,7 +745,7 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb
furi_hal_bus_enable(FuriHalBusTIM17); furi_hal_bus_enable(FuriHalBusTIM17);
// Configure TIM // Configure TIM
// Set the timer resolution to 2 <EFBFBD>s // Set the timer resolution to 2 us
LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1); LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1);
LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP); LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP);
LL_TIM_SetAutoReload(TIM17, 0xFFFF); LL_TIM_SetAutoReload(TIM17, 0xFFFF);

View File

@@ -1,7 +1,6 @@
#include "hid.h" #include "hid.h"
#include "views.h" #include "views.h"
#include <notification/notification_messages.h> #include <notification/notification_messages.h>
#include <dolphin/dolphin.h>
#define TAG "HidApp" #define TAG "HidApp"
@@ -404,8 +403,6 @@ int32_t hid_usb_app(void* p) {
bt_hid_connection_status_changed_callback(BtStatusConnected, app); bt_hid_connection_status_changed_callback(BtStatusConnected, app);
dolphin_deed(DolphinDeedPluginStart);
view_dispatcher_run(app->view_dispatcher); view_dispatcher_run(app->view_dispatcher);
furi_hal_usb_set_config(usb_mode_prev, NULL); furi_hal_usb_set_config(usb_mode_prev, NULL);
@@ -444,8 +441,6 @@ int32_t hid_ble_app(void* p) {
furi_hal_bt_start_advertising(); furi_hal_bt_start_advertising();
bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app); bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app);
dolphin_deed(DolphinDeedPluginStart);
view_dispatcher_run(app->view_dispatcher); view_dispatcher_run(app->view_dispatcher);
bt_set_status_changed_callback(app->bt, NULL, NULL); bt_set_status_changed_callback(app->bt, NULL, NULL);

View File

@@ -61,6 +61,8 @@ typedef enum {
InfraredEditModeNone, InfraredEditModeNone,
InfraredEditModeRename, InfraredEditModeRename,
InfraredEditModeDelete, InfraredEditModeDelete,
InfraredEditModeMove,
InfraredEditModeMoveSelectDest
} InfraredEditMode; } InfraredEditMode;
typedef struct { typedef struct {
@@ -70,6 +72,7 @@ typedef struct {
InfraredEditTarget edit_target : 8; InfraredEditTarget edit_target : 8;
InfraredEditMode edit_mode : 8; InfraredEditMode edit_mode : 8;
int32_t current_button_index; int32_t current_button_index;
int32_t current_button_index_move_orig;
uint32_t last_transmit_time; uint32_t last_transmit_time;
} InfraredAppState; } InfraredAppState;

View File

@@ -108,6 +108,21 @@ bool infrared_remote_delete_button(InfraredRemote* remote, size_t index) {
return infrared_remote_store(remote); return infrared_remote_store(remote);
} }
bool infrared_remote_move_button(InfraredRemote* remote, size_t index_orig, size_t index_dest) {
furi_assert(index_orig < InfraredButtonArray_size(remote->buttons));
furi_assert(index_dest <= InfraredButtonArray_size(remote->buttons));
if(index_orig == index_dest) {
return true;
}
InfraredRemoteButton* button;
InfraredButtonArray_pop_at(&button, remote->buttons, index_orig);
if(index_orig > index_dest)
InfraredButtonArray_push_at(remote->buttons, index_dest, button);
else
InfraredButtonArray_push_at(remote->buttons, index_dest - 1, button);
return infrared_remote_store(remote);
}
bool infrared_remote_store(InfraredRemote* remote) { bool infrared_remote_store(InfraredRemote* remote) {
Storage* storage = furi_record_open(RECORD_STORAGE); Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* ff = flipper_format_file_alloc(storage); FlipperFormat* ff = flipper_format_file_alloc(storage);

View File

@@ -23,6 +23,7 @@ bool infrared_remote_find_button_by_name(InfraredRemote* remote, const char* nam
bool infrared_remote_add_button(InfraredRemote* remote, const char* name, InfraredSignal* signal); bool infrared_remote_add_button(InfraredRemote* remote, const char* name, InfraredSignal* signal);
bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, size_t index); bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, size_t index);
bool infrared_remote_delete_button(InfraredRemote* remote, size_t index); bool infrared_remote_delete_button(InfraredRemote* remote, size_t index);
bool infrared_remote_move_button(InfraredRemote* remote, size_t index_orig, size_t index_dest);
bool infrared_remote_store(InfraredRemote* remote); bool infrared_remote_store(InfraredRemote* remote);
bool infrared_remote_load(InfraredRemote* remote, FuriString* path); bool infrared_remote_load(InfraredRemote* remote, FuriString* path);

View File

@@ -7,6 +7,8 @@ ADD_SCENE(infrared, edit_delete_done, EditDeleteDone)
ADD_SCENE(infrared, edit_button_select, EditButtonSelect) ADD_SCENE(infrared, edit_button_select, EditButtonSelect)
ADD_SCENE(infrared, edit_rename, EditRename) ADD_SCENE(infrared, edit_rename, EditRename)
ADD_SCENE(infrared, edit_rename_done, EditRenameDone) ADD_SCENE(infrared, edit_rename_done, EditRenameDone)
ADD_SCENE(infrared, edit_move, EditMove)
ADD_SCENE(infrared, edit_move_done, EditMoveDone)
ADD_SCENE(infrared, learn, Learn) ADD_SCENE(infrared, learn, Learn)
ADD_SCENE(infrared, learn_done, LearnDone) ADD_SCENE(infrared, learn_done, LearnDone)
ADD_SCENE(infrared, learn_enter_name, LearnEnterName) ADD_SCENE(infrared, learn_enter_name, LearnEnterName)

View File

@@ -3,6 +3,7 @@
typedef enum { typedef enum {
SubmenuIndexAddButton, SubmenuIndexAddButton,
SubmenuIndexRenameButton, SubmenuIndexRenameButton,
SubmenuIndexMoveButton,
SubmenuIndexDeleteButton, SubmenuIndexDeleteButton,
SubmenuIndexRenameRemote, SubmenuIndexRenameRemote,
SubmenuIndexDeleteRemote, SubmenuIndexDeleteRemote,
@@ -30,6 +31,12 @@ void infrared_scene_edit_on_enter(void* context) {
SubmenuIndexRenameButton, SubmenuIndexRenameButton,
infrared_scene_edit_submenu_callback, infrared_scene_edit_submenu_callback,
context); context);
submenu_add_item(
submenu,
"Move Button",
SubmenuIndexMoveButton,
infrared_scene_edit_submenu_callback,
context);
submenu_add_item( submenu_add_item(
submenu, submenu,
"Delete Button", "Delete Button",
@@ -74,6 +81,11 @@ bool infrared_scene_edit_on_event(void* context, SceneManagerEvent event) {
infrared->app_state.edit_mode = InfraredEditModeRename; infrared->app_state.edit_mode = InfraredEditModeRename;
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect); scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
consumed = true; consumed = true;
} else if(submenu_index == SubmenuIndexMoveButton) {
infrared->app_state.edit_target = InfraredEditTargetButton;
infrared->app_state.edit_mode = InfraredEditModeMove;
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
consumed = true;
} else if(submenu_index == SubmenuIndexDeleteButton) { } else if(submenu_index == SubmenuIndexDeleteButton) {
infrared->app_state.edit_target = InfraredEditTargetButton; infrared->app_state.edit_target = InfraredEditTargetButton;
infrared->app_state.edit_mode = InfraredEditModeDelete; infrared->app_state.edit_mode = InfraredEditModeDelete;

View File

@@ -11,9 +11,23 @@ void infrared_scene_edit_button_select_on_enter(void* context) {
InfraredRemote* remote = infrared->remote; InfraredRemote* remote = infrared->remote;
InfraredAppState* app_state = &infrared->app_state; InfraredAppState* app_state = &infrared->app_state;
const char* header = infrared->app_state.edit_mode == InfraredEditModeRename ? const char* header = NULL;
"Rename Button:" : switch(infrared->app_state.edit_mode) {
"Delete Button:"; case InfraredEditModeRename:
header = "Rename Button:";
break;
case InfraredEditModeDelete:
header = "Delete Button:";
break;
case InfraredEditModeMove:
header = "Select Button to Move:";
break;
case InfraredEditModeMoveSelectDest:
case InfraredEditModeNone:
default:
header = "Move Button Before:";
break;
}
submenu_set_header(submenu, header); submenu_set_header(submenu, header);
const size_t button_count = infrared_remote_get_button_count(remote); const size_t button_count = infrared_remote_get_button_count(remote);
@@ -26,7 +40,14 @@ void infrared_scene_edit_button_select_on_enter(void* context) {
infrared_scene_edit_button_select_submenu_callback, infrared_scene_edit_button_select_submenu_callback,
context); context);
} }
if(infrared->app_state.edit_mode == InfraredEditModeMoveSelectDest) {
submenu_add_item(
submenu,
"-- Move to the end --",
button_count,
infrared_scene_edit_button_select_submenu_callback,
context);
}
if(button_count && app_state->current_button_index != InfraredButtonIndexNone) { if(button_count && app_state->current_button_index != InfraredButtonIndexNone) {
submenu_set_selected_item(submenu, app_state->current_button_index); submenu_set_selected_item(submenu, app_state->current_button_index);
app_state->current_button_index = InfraredButtonIndexNone; app_state->current_button_index = InfraredButtonIndexNone;
@@ -48,6 +69,12 @@ bool infrared_scene_edit_button_select_on_event(void* context, SceneManagerEvent
scene_manager_next_scene(scene_manager, InfraredSceneEditRename); scene_manager_next_scene(scene_manager, InfraredSceneEditRename);
} else if(edit_mode == InfraredEditModeDelete) { } else if(edit_mode == InfraredEditModeDelete) {
scene_manager_next_scene(scene_manager, InfraredSceneEditDelete); scene_manager_next_scene(scene_manager, InfraredSceneEditDelete);
} else if(edit_mode == InfraredEditModeMove) {
app_state->current_button_index_move_orig = event.event;
app_state->edit_mode = InfraredEditModeMoveSelectDest;
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
} else if(edit_mode == InfraredEditModeMoveSelectDest) {
scene_manager_next_scene(scene_manager, InfraredSceneEditMove);
} else { } else {
furi_assert(0); furi_assert(0);
} }

View File

@@ -0,0 +1,103 @@
#include "../infrared_i.h"
static void infrared_scene_edit_move_dialog_result_callback(DialogExResult result, void* context) {
Infrared* infrared = context;
view_dispatcher_send_custom_event(infrared->view_dispatcher, result);
}
void infrared_scene_edit_move_on_enter(void* context) {
Infrared* infrared = context;
DialogEx* dialog_ex = infrared->dialog_ex;
InfraredRemote* remote = infrared->remote;
const InfraredEditTarget edit_target = infrared->app_state.edit_target;
if(edit_target == InfraredEditTargetButton) {
int32_t current_button_index = infrared->app_state.current_button_index_move_orig;
furi_assert(current_button_index != InfraredButtonIndexNone);
dialog_ex_set_header(dialog_ex, "Move Button?", 64, 0, AlignCenter, AlignTop);
InfraredRemoteButton* current_button =
infrared_remote_get_button(remote, current_button_index);
InfraredSignal* signal = infrared_remote_button_get_signal(current_button);
if(infrared_signal_is_raw(signal)) {
const InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
infrared_text_store_set(
infrared,
0,
"%s\nRAW\n%ld samples",
infrared_remote_button_get_name(current_button),
raw->timings_size);
} else {
const InfraredMessage* message = infrared_signal_get_message(signal);
infrared_text_store_set(
infrared,
0,
"%s\n%s\nA=0x%0*lX C=0x%0*lX",
infrared_remote_button_get_name(current_button),
infrared_get_protocol_name(message->protocol),
ROUND_UP_TO(infrared_get_protocol_address_length(message->protocol), 4),
message->address,
ROUND_UP_TO(infrared_get_protocol_command_length(message->protocol), 4),
message->command);
}
} else {
furi_assert(0);
}
dialog_ex_set_text(dialog_ex, infrared->text_store[0], 64, 31, AlignCenter, AlignCenter);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, "Cancel");
dialog_ex_set_right_button_text(dialog_ex, "Move");
dialog_ex_set_result_callback(dialog_ex, infrared_scene_edit_move_dialog_result_callback);
dialog_ex_set_context(dialog_ex, context);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx);
}
bool infrared_scene_edit_move_on_event(void* context, SceneManagerEvent event) {
Infrared* infrared = context;
SceneManager* scene_manager = infrared->scene_manager;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == DialogExResultLeft) {
scene_manager_previous_scene(scene_manager);
consumed = true;
} else if(event.event == DialogExResultRight) {
bool success = false;
InfraredRemote* remote = infrared->remote;
InfraredAppState* app_state = &infrared->app_state;
const InfraredEditTarget edit_target = app_state->edit_target;
if(edit_target == InfraredEditTargetButton) {
furi_assert(app_state->current_button_index != InfraredButtonIndexNone);
success = infrared_remote_move_button(
remote,
app_state->current_button_index_move_orig,
app_state->current_button_index);
app_state->current_button_index_move_orig = InfraredButtonIndexNone;
app_state->current_button_index = InfraredButtonIndexNone;
} else {
furi_assert(0);
}
if(success) {
scene_manager_next_scene(scene_manager, InfraredSceneEditMoveDone);
} else {
const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart};
scene_manager_search_and_switch_to_previous_scene_one_of(
scene_manager, possible_scenes, COUNT_OF(possible_scenes));
}
consumed = true;
}
}
return consumed;
}
void infrared_scene_edit_move_on_exit(void* context) {
Infrared* infrared = context;
UNUSED(infrared);
}

View File

@@ -0,0 +1,48 @@
#include "../infrared_i.h"
void infrared_scene_edit_move_done_on_enter(void* context) {
Infrared* infrared = context;
Popup* popup = infrared->popup;
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
popup_set_header(popup, "Moved", 83, 19, AlignLeft, AlignBottom);
popup_set_callback(popup, infrared_popup_closed_callback);
popup_set_context(popup, context);
popup_set_timeout(popup, 1500);
popup_enable_timeout(popup);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
}
bool infrared_scene_edit_move_done_on_event(void* context, SceneManagerEvent event) {
Infrared* infrared = context;
SceneManager* scene_manager = infrared->scene_manager;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == InfraredCustomEventTypePopupClosed) {
const InfraredEditTarget edit_target = infrared->app_state.edit_target;
if(edit_target == InfraredEditTargetButton) {
scene_manager_search_and_switch_to_previous_scene(
scene_manager, InfraredSceneRemote);
} else if(edit_target == InfraredEditTargetRemote) {
const uint32_t possible_scenes[] = {InfraredSceneStart, InfraredSceneRemoteList};
if(!scene_manager_search_and_switch_to_previous_scene_one_of(
scene_manager, possible_scenes, COUNT_OF(possible_scenes))) {
view_dispatcher_stop(infrared->view_dispatcher);
}
} else {
furi_assert(0);
}
consumed = true;
}
}
return consumed;
}
void infrared_scene_edit_move_done_on_exit(void* context) {
Infrared* infrared = context;
UNUSED(infrared);
}

View File

@@ -7,7 +7,7 @@
#define TAG "U2F" #define TAG "U2F"
#define U2F_DATA_FOLDER ANY_PATH("u2f/") #define U2F_DATA_FOLDER EXT_PATH("u2f/")
#define U2F_CERT_FILE U2F_DATA_FOLDER "assets/cert.der" #define U2F_CERT_FILE U2F_DATA_FOLDER "assets/cert.der"
#define U2F_CERT_KEY_FILE U2F_DATA_FOLDER "assets/cert_key.u2f" #define U2F_CERT_KEY_FILE U2F_DATA_FOLDER "assets/cert_key.u2f"
#define U2F_KEY_FILE U2F_DATA_FOLDER "key.u2f" #define U2F_KEY_FILE U2F_DATA_FOLDER "key.u2f"

View File

@@ -39,7 +39,7 @@ static const DolphinDeedWeight dolphin_deed_weights[] = {
{1, DolphinAppPlugin}, // DolphinDeedGpioUartBridge {1, DolphinAppPlugin}, // DolphinDeedGpioUartBridge
{1, DolphinAppPlugin}, // DolphinDeedPluginStart {2, DolphinAppPlugin}, // DolphinDeedPluginStart
{1, DolphinAppPlugin}, // DolphinDeedPluginGameStart {1, DolphinAppPlugin}, // DolphinDeedPluginGameStart
{10, DolphinAppPlugin}, // DolphinDeedPluginGameWin {10, DolphinAppPlugin}, // DolphinDeedPluginGameWin
}; };

View File

@@ -4,6 +4,7 @@
#include <furi.h> #include <furi.h>
#include <assets_icons.h> #include <assets_icons.h>
/** ByteInput type */
struct ByteInput { struct ByteInput {
View* view; View* view;
}; };
@@ -61,11 +62,11 @@ static const ByteInputKey keyboard_keys_row_2[] = {
{enter_symbol, 95, 17}, {enter_symbol, 95, 17},
}; };
/** /** Get row size
* @brief Get row size
* *
* @param row_index Index of row * @param row_index Index of row
* @return uint8_t Row size *
* @return uint8_t Row size
*/ */
static uint8_t byte_input_get_row_size(uint8_t row_index) { static uint8_t byte_input_get_row_size(uint8_t row_index) {
uint8_t row_size = 0; uint8_t row_size = 0;
@@ -84,11 +85,11 @@ static uint8_t byte_input_get_row_size(uint8_t row_index) {
return row_size; return row_size;
} }
/** /** Get row pointer
* @brief Get row pointer
* *
* @param row_index Index of row * @param row_index Index of row
* @return const ByteInputKey* Row pointer *
* @return const ByteInputKey* Row pointer
*/ */
static const ByteInputKey* byte_input_get_row(uint8_t row_index) { static const ByteInputKey* byte_input_get_row(uint8_t row_index) {
const ByteInputKey* row = NULL; const ByteInputKey* row = NULL;
@@ -107,12 +108,12 @@ static const ByteInputKey* byte_input_get_row(uint8_t row_index) {
return row; return row;
} }
/** /** Get text from nibble
* @brief Get text from nibble
* *
* @param byte byte value * @param byte byte value
* @param high_nibble Get from high nibble, otherwise low nibble * @param high_nibble Get from high nibble, otherwise low nibble
* @return char nibble text *
* @return char nibble text
*/ */
static char byte_input_get_nibble_text(uint8_t byte, bool high_nibble) { static char byte_input_get_nibble_text(uint8_t byte, bool high_nibble) {
if(high_nibble) { if(high_nibble) {
@@ -151,11 +152,10 @@ static char byte_input_get_nibble_text(uint8_t byte, bool high_nibble) {
const char num_to_char[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; const char num_to_char[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
/** /** Draw input box (common view)
* @brief Draw input box (common view)
* *
* @param canvas * @param canvas The canvas
* @param model * @param model The model
*/ */
static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) { static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) {
const uint8_t text_x = 8; const uint8_t text_x = 8;
@@ -263,11 +263,10 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) {
} }
} }
/** /** Draw input box (selected view)
* @brief Draw input box (selected view)
* *
* @param canvas * @param canvas The canvas
* @param model * @param model The model
*/ */
static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model) { static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model) {
const uint8_t text_x = 7; const uint8_t text_x = 7;
@@ -324,13 +323,12 @@ static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model
canvas_invert_color(canvas); canvas_invert_color(canvas);
} }
/** /** Set nibble at position
* @brief Set nibble at position
* *
* @param data where to set nibble * @param data where to set nibble
* @param position byte position * @param position byte position
* @param value char value * @param value char value
* @param high_nibble set high nibble * @param high_nibble set high nibble
*/ */
static void byte_input_set_nibble(uint8_t* data, uint8_t position, char value, bool high_nibble) { static void byte_input_set_nibble(uint8_t* data, uint8_t position, char value, bool high_nibble) {
switch(value) { switch(value) {
@@ -368,29 +366,28 @@ static void byte_input_set_nibble(uint8_t* data, uint8_t position, char value, b
} }
} }
/** /** What currently selected
* @brief What currently selected
* *
* @return true - keyboard selected, false - input selected * @param model The model
*
* @return true - keyboard selected, false - input selected
*/ */
static bool byte_input_keyboard_selected(ByteInputModel* model) { static bool byte_input_keyboard_selected(ByteInputModel* model) {
return model->selected_row >= 0; return model->selected_row >= 0;
} }
/** /** Do transition from keyboard
* @brief Do transition from keyboard
* *
* @param model * @param model The model
*/ */
static void byte_input_transition_from_keyboard(ByteInputModel* model) { static void byte_input_transition_from_keyboard(ByteInputModel* model) {
model->selected_row += 1; model->selected_row += 1;
model->selected_high_nibble = true; model->selected_high_nibble = true;
} }
/** /** Increase selected byte position
* @brief Increase selected byte position
* *
* @param model * @param model The model
*/ */
static void byte_input_inc_selected_byte(ByteInputModel* model) { static void byte_input_inc_selected_byte(ByteInputModel* model) {
if(model->selected_byte < model->bytes_count - 1) { if(model->selected_byte < model->bytes_count - 1) {
@@ -409,18 +406,17 @@ static void byte_input_inc_selected_byte(ByteInputModel* model) {
static void byte_input_inc_selected_byte_mini(ByteInputModel* model) { static void byte_input_inc_selected_byte_mini(ByteInputModel* model) {
if((model->selected_byte < model->bytes_count - 1) || model->selected_high_nibble) { if((model->selected_byte < model->bytes_count - 1) || model->selected_high_nibble) {
if(!model->selected_high_nibble) { if(!model->selected_high_nibble) {
model->selected_high_nibble = !model->selected_high_nibble; model->selected_high_nibble = !model->selected_high_nibble; //-V547
byte_input_inc_selected_byte(model); byte_input_inc_selected_byte(model);
} else { } else {
model->selected_high_nibble = !model->selected_high_nibble; model->selected_high_nibble = !model->selected_high_nibble; //-V547
} }
} }
} }
/** /** Decrease selected byte position
* @brief Decrease selected byte position
* *
* @param model * @param model The model
*/ */
static void byte_input_dec_selected_byte(ByteInputModel* model) { static void byte_input_dec_selected_byte(ByteInputModel* model) {
if(model->selected_byte > 0) { if(model->selected_byte > 0) {
@@ -438,18 +434,17 @@ static void byte_input_dec_selected_byte(ByteInputModel* model) {
static void byte_input_dec_selected_byte_mini(ByteInputModel* model) { static void byte_input_dec_selected_byte_mini(ByteInputModel* model) {
if(model->selected_byte > 0 || !model->selected_high_nibble) { if(model->selected_byte > 0 || !model->selected_high_nibble) {
if(model->selected_high_nibble) { if(model->selected_high_nibble) {
model->selected_high_nibble = !model->selected_high_nibble; model->selected_high_nibble = !model->selected_high_nibble; //-V547
byte_input_dec_selected_byte(model); byte_input_dec_selected_byte(model);
} else { } else {
model->selected_high_nibble = !model->selected_high_nibble; model->selected_high_nibble = !model->selected_high_nibble; //-V547
} }
} }
} }
/** /** Call input callback
* @brief Call input callback
* *
* @param model * @param model The model
*/ */
static void byte_input_call_input_callback(ByteInputModel* model) { static void byte_input_call_input_callback(ByteInputModel* model) {
if(model->input_callback != NULL) { if(model->input_callback != NULL) {
@@ -457,10 +452,9 @@ static void byte_input_call_input_callback(ByteInputModel* model) {
} }
} }
/** /** Call changed callback
* @brief Call changed callback
* *
* @param model * @param model The model
*/ */
static void byte_input_call_changed_callback(ByteInputModel* model) { static void byte_input_call_changed_callback(ByteInputModel* model) {
if(model->changed_callback != NULL) { if(model->changed_callback != NULL) {
@@ -468,8 +462,9 @@ static void byte_input_call_changed_callback(ByteInputModel* model) {
} }
} }
/** /** Clear selected byte
* @brief Clear selected byte *
* @param model The model
*/ */
static void byte_input_clear_selected_byte(ByteInputModel* model) { static void byte_input_clear_selected_byte(ByteInputModel* model) {
@@ -479,10 +474,9 @@ static void byte_input_clear_selected_byte(ByteInputModel* model) {
byte_input_call_changed_callback(model); byte_input_call_changed_callback(model);
} }
/** /** Handle up button
* @brief Handle up button
* *
* @param model * @param model The model
*/ */
static void byte_input_handle_up(ByteInputModel* model) { static void byte_input_handle_up(ByteInputModel* model) {
if(model->selected_row > -2) { if(model->selected_row > -2) {
@@ -500,10 +494,9 @@ static void byte_input_handle_up(ByteInputModel* model) {
} }
} }
/** /** Handle down button
* @brief Handle down button
* *
* @param model * @param model The model
*/ */
static void byte_input_handle_down(ByteInputModel* model) { static void byte_input_handle_down(ByteInputModel* model) {
if(model->selected_row != -2) { if(model->selected_row != -2) {
@@ -527,10 +520,9 @@ static void byte_input_handle_down(ByteInputModel* model) {
} }
} }
/** /** Handle left button
* @brief Handle left button
* *
* @param model * @param model The model
*/ */
static void byte_input_handle_left(ByteInputModel* model) { // XXX static void byte_input_handle_left(ByteInputModel* model) { // XXX
if(byte_input_keyboard_selected(model)) { if(byte_input_keyboard_selected(model)) {
@@ -548,10 +540,9 @@ static void byte_input_handle_left(ByteInputModel* model) { // XXX
} }
} }
/** /** Handle right button
* @brief Handle right button
* *
* @param model * @param model The model
*/ */
static void byte_input_handle_right(ByteInputModel* model) { // XXX static void byte_input_handle_right(ByteInputModel* model) { // XXX
if(byte_input_keyboard_selected(model)) { if(byte_input_keyboard_selected(model)) {
@@ -569,10 +560,9 @@ static void byte_input_handle_right(ByteInputModel* model) { // XXX
} }
} }
/** /** Handle OK button
* @brief Handle OK button
* *
* @param model * @param model The model
*/ */
static void byte_input_handle_ok(ByteInputModel* model) { static void byte_input_handle_ok(ByteInputModel* model) {
if(byte_input_keyboard_selected(model)) { if(byte_input_keyboard_selected(model)) {
@@ -600,11 +590,10 @@ static void byte_input_handle_ok(ByteInputModel* model) {
} }
} }
/** /** Draw callback
* @brief Draw callback
* *
* @param canvas * @param canvas The canvas
* @param _model * @param _model The model
*/ */
static void byte_input_view_draw_callback(Canvas* canvas, void* _model) { static void byte_input_view_draw_callback(Canvas* canvas, void* _model) {
ByteInputModel* model = _model; ByteInputModel* model = _model;
@@ -698,13 +687,13 @@ static void byte_input_view_draw_callback(Canvas* canvas, void* _model) {
} }
} }
/** /** Input callback
* @brief Input callback
* *
* @param event * @param event The event
* @param context * @param context The context
* @return true *
* @return false * @return true
* @return false
*/ */
static bool byte_input_view_input_callback(InputEvent* event, void* context) { static bool byte_input_view_input_callback(InputEvent* event, void* context) {
ByteInput* byte_input = context; ByteInput* byte_input = context;
@@ -773,10 +762,9 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) {
return consumed; return consumed;
} }
/** /** Reset all input-related data in model
* @brief Reset all input-related data in model
* *
* @param model ByteInputModel * @param model The model
*/ */
static void byte_input_reset_model_input_data(ByteInputModel* model) { static void byte_input_reset_model_input_data(ByteInputModel* model) {
model->bytes = NULL; model->bytes = NULL;
@@ -788,11 +776,6 @@ static void byte_input_reset_model_input_data(ByteInputModel* model) {
model->first_visible_byte = 0; model->first_visible_byte = 0;
} }
/**
* @brief Allocate and initialize byte input. This byte input is used to enter bytes.
*
* @return ByteInput instance pointer
*/
ByteInput* byte_input_alloc() { ByteInput* byte_input_alloc() {
ByteInput* byte_input = malloc(sizeof(ByteInput)); ByteInput* byte_input = malloc(sizeof(ByteInput));
byte_input->view = view_alloc(); byte_input->view = view_alloc();
@@ -816,38 +799,17 @@ ByteInput* byte_input_alloc() {
return byte_input; return byte_input;
} }
/**
* @brief Deinitialize and free byte input
*
* @param byte_input Byte input instance
*/
void byte_input_free(ByteInput* byte_input) { void byte_input_free(ByteInput* byte_input) {
furi_assert(byte_input); furi_assert(byte_input);
view_free(byte_input->view); view_free(byte_input->view);
free(byte_input); free(byte_input);
} }
/**
* @brief Get byte input view
*
* @param byte_input byte input instance
* @return View instance that can be used for embedding
*/
View* byte_input_get_view(ByteInput* byte_input) { View* byte_input_get_view(ByteInput* byte_input) {
furi_assert(byte_input); furi_assert(byte_input);
return byte_input->view; return byte_input->view;
} }
/**
* @brief Deinitialize and free byte input
*
* @param byte_input byte input instance
* @param input_callback input callback fn
* @param changed_callback changed callback fn
* @param callback_context callback context
* @param bytes buffer to use
* @param bytes_count buffer length
*/
void byte_input_set_result_callback( void byte_input_set_result_callback(
ByteInput* byte_input, ByteInput* byte_input,
ByteInputCallback input_callback, ByteInputCallback input_callback,
@@ -869,12 +831,6 @@ void byte_input_set_result_callback(
true); true);
} }
/**
* @brief Set byte input header text
*
* @param byte_input byte input instance
* @param text text to be shown
*/
void byte_input_set_header_text(ByteInput* byte_input, const char* text) { void byte_input_set_header_text(ByteInput* byte_input, const char* text) {
with_view_model( with_view_model(
byte_input->view, ByteInputModel * model, { model->header = text; }, true); byte_input->view, ByteInputModel * model, { model->header = text; }, true);

View File

@@ -6,6 +6,7 @@
#include <gui/gui.h> #include <gui/gui.h>
#include <gui/view_holder.h> #include <gui/view_holder.h>
#include <gui/modules/loading.h> #include <gui/modules/loading.h>
#include <dolphin/dolphin.h>
#define TAG "LoaderApplications" #define TAG "LoaderApplications"
@@ -119,6 +120,8 @@ static void loader_pubsub_callback(const void* message, void* context) {
static void loader_applications_start_app(LoaderApplicationsApp* app) { static void loader_applications_start_app(LoaderApplicationsApp* app) {
const char* name = furi_string_get_cstr(app->fap_path); const char* name = furi_string_get_cstr(app->fap_path);
dolphin_deed(DolphinDeedPluginStart);
// load app // load app
FuriThreadId thread_id = furi_thread_get_current_id(); FuriThreadId thread_id = furi_thread_get_current_id();
FuriPubSubSubscription* subscription = FuriPubSubSubscription* subscription =

View File

@@ -5,7 +5,7 @@
#include <input/input.h> #include <input/input.h>
#include <gui/gui_i.h> #include <gui/gui_i.h>
#include <u8g2_glue.h> #include <u8g2_glue.h>
#include <lib/toolbox/float_tools.h>
#include "notification.h" #include "notification.h"
#include "notification_messages.h" #include "notification_messages.h"
#include "notification_app.h" #include "notification_app.h"
@@ -104,7 +104,10 @@ static void notification_reset_notification_led_layer(NotificationLedLayer* laye
furi_hal_light_set(layer->light, layer->value[LayerInternal]); furi_hal_light_set(layer->light, layer->value[LayerInternal]);
} }
static void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) { static void notification_reset_notification_layer(
NotificationApp* app,
uint8_t reset_mask,
float display_brightness_set) {
if(reset_mask & reset_blink_mask) { if(reset_mask & reset_blink_mask) {
furi_hal_light_blink_stop(); furi_hal_light_blink_stop();
} }
@@ -124,6 +127,9 @@ static void notification_reset_notification_layer(NotificationApp* app, uint8_t
notification_sound_off(); notification_sound_off();
} }
if(reset_mask & reset_display_mask) { if(reset_mask & reset_display_mask) {
if(!float_is_equal(display_brightness_set, app->settings.display_brightness)) {
furi_hal_light_set(LightBacklight, app->settings.display_brightness * 0xFF);
}
furi_timer_start(app->display_timer, notification_settings_display_off_delay_ticks(app)); furi_timer_start(app->display_timer, notification_settings_display_off_delay_ticks(app));
} }
} }
@@ -212,13 +218,14 @@ static void notification_process_notification_message(
notification_apply_notification_led_layer( notification_apply_notification_led_layer(
&app->display, &app->display,
notification_message->data.led.value * display_brightness_setting); notification_message->data.led.value * display_brightness_setting);
reset_mask |= reset_display_mask;
} else { } else {
reset_mask &= ~reset_display_mask;
notification_reset_notification_led_layer(&app->display); notification_reset_notification_led_layer(&app->display);
if(furi_timer_is_running(app->display_timer)) { if(furi_timer_is_running(app->display_timer)) {
furi_timer_stop(app->display_timer); furi_timer_stop(app->display_timer);
} }
} }
reset_mask |= reset_display_mask;
break; break;
case NotificationMessageTypeLedDisplayBacklightEnforceOn: case NotificationMessageTypeLedDisplayBacklightEnforceOn:
furi_assert(app->display_led_lock < UINT8_MAX); furi_assert(app->display_led_lock < UINT8_MAX);
@@ -370,7 +377,7 @@ static void notification_process_notification_message(
} }
if(reset_notifications) { if(reset_notifications) {
notification_reset_notification_layer(app, reset_mask); notification_reset_notification_layer(app, reset_mask, display_brightness_setting);
} }
} }

View File

@@ -205,8 +205,6 @@ const AboutDialogScreen about_screens[] = {
hw_version_screen, hw_version_screen,
fw_version_screen}; fw_version_screen};
const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScreen);
int32_t about_settings_app(void* p) { int32_t about_settings_app(void* p) {
UNUSED(p); UNUSED(p);
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
@@ -227,7 +225,7 @@ int32_t about_settings_app(void* p) {
view_dispatcher_switch_to_view(view_dispatcher, empty_screen_index); view_dispatcher_switch_to_view(view_dispatcher, empty_screen_index);
while(1) { while(1) {
if(screen_index >= about_screens_count - 1) { if(screen_index >= COUNT_OF(about_screens) - 1) {
dialog_message_set_buttons(message, "Back", NULL, NULL); dialog_message_set_buttons(message, "Back", NULL, NULL);
} else { } else {
dialog_message_set_buttons(message, "Back", NULL, "Next"); dialog_message_set_buttons(message, "Back", NULL, "Next");
@@ -242,7 +240,7 @@ int32_t about_settings_app(void* p) {
screen_index--; screen_index--;
} }
} else if(screen_result == DialogMessageButtonRight) { } else if(screen_result == DialogMessageButtonRight) {
if(screen_index < about_screens_count - 1) { if(screen_index < COUNT_OF(about_screens) - 1) {
screen_index++; screen_index++;
} }
} else if(screen_result == DialogMessageButtonBack) { } else if(screen_result == DialogMessageButtonBack) {

View File

@@ -24,10 +24,10 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
// Device Info version // Device Info version
if(sep == '.') { if(sep == '.') {
property_value_out(&property_context, NULL, 2, "format", "major", "3"); property_value_out(&property_context, NULL, 2, "format", "major", "3");
property_value_out(&property_context, NULL, 2, "format", "minor", "2"); property_value_out(&property_context, NULL, 2, "format", "minor", "3");
} else { } else {
property_value_out(&property_context, NULL, 3, "device", "info", "major", "2"); property_value_out(&property_context, NULL, 3, "device", "info", "major", "2");
property_value_out(&property_context, NULL, 3, "device", "info", "minor", "3"); property_value_out(&property_context, NULL, 3, "device", "info", "minor", "4");
} }
// Model name // Model name
@@ -298,6 +298,7 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
property_value_out(&property_context, NULL, 2, "radio", "alive", "false"); property_value_out(&property_context, NULL, 2, "radio", "alive", "false");
} }
// RTC flags
property_value_out( property_value_out(
&property_context, &property_context,
"%u", "%u",
@@ -305,8 +306,52 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
"system", "system",
"debug", "debug",
furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)); furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug));
property_value_out(
&property_context, "%u", 2, "system", "lock", furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock));
property_value_out(
&property_context,
"%u",
2,
"system",
"orient",
furi_hal_rtc_is_flag_set(FuriHalRtcFlagHandOrient));
property_value_out(
&property_context,
"%u",
3,
"system",
"sleep",
"legacy",
furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep));
property_value_out(
&property_context,
"%u",
2,
"system",
"stealth",
furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode));
property_value_out( property_value_out(
&property_context, "%u", 3, "system", "heap", "track", furi_hal_rtc_get_heap_track_mode()); &property_context, "%u", 3, "system", "heap", "track", furi_hal_rtc_get_heap_track_mode());
property_value_out(&property_context, "%u", 2, "system", "boot", furi_hal_rtc_get_boot_mode());
property_value_out(
&property_context,
"%u",
3,
"system",
"locale",
"time",
furi_hal_rtc_get_locale_timeformat());
property_value_out(
&property_context,
"%u",
3,
"system",
"locale",
"date",
furi_hal_rtc_get_locale_dateformat());
property_value_out(
&property_context, "%u", 3, "system", "locale", "unit", furi_hal_rtc_get_locale_units());
property_value_out( property_value_out(
&property_context, "%u", 3, "system", "log", "level", furi_hal_rtc_get_log_level()); &property_context, "%u", 3, "system", "log", "level", furi_hal_rtc_get_log_level());

View File

@@ -35,6 +35,7 @@ typedef enum {
FuriHalVersionColorUnknown = 0x00, FuriHalVersionColorUnknown = 0x00,
FuriHalVersionColorBlack = 0x01, FuriHalVersionColorBlack = 0x01,
FuriHalVersionColorWhite = 0x02, FuriHalVersionColorWhite = 0x02,
FuriHalVersionColorTransparent = 0x03,
} FuriHalVersionColor; } FuriHalVersionColor;
/** Device Regions */ /** Device Regions */

View File

@@ -28,7 +28,7 @@ typedef enum {
FuriThreadPriorityNormal = 16, /**< Normal */ FuriThreadPriorityNormal = 16, /**< Normal */
FuriThreadPriorityHigh = 17, /**< High */ FuriThreadPriorityHigh = 17, /**< High */
FuriThreadPriorityHighest = 18, /**< Highest */ FuriThreadPriorityHighest = 18, /**< Highest */
FuriThreadPriorityIsr = 32, /**< Deffered Isr (highest possible) */ FuriThreadPriorityIsr = (configMAX_PRIORITIES - 1), /**< Deferred ISR (highest possible) */
} FuriThreadPriority; } FuriThreadPriority;
/** FuriThread anonymous structure */ /** FuriThread anonymous structure */

View File

@@ -17,6 +17,7 @@ OTP_COLORS = {
"unknown": 0x00, "unknown": 0x00,
"black": 0x01, "black": 0x01,
"white": 0x02, "white": 0x02,
"transparent": 0x03,
} }
OTP_REGIONS = { OTP_REGIONS = {