Merge branch 'dev' into xtruan/eurocorp_menu

This commit is contained in:
Struan Clark
2023-08-15 19:08:11 -06:00
23 changed files with 791 additions and 199 deletions

View File

@@ -7,7 +7,7 @@ App(
requires=["gui"], requires=["gui"],
stack_size=4 * 1024, stack_size=4 * 1024,
order=90, order=90,
fap_icon="wifi_10px.png", fap_icon="update_10px.png",
fap_category="GPIO", fap_category="GPIO",
fap_private_libs=[ fap_private_libs=[
Lib( Lib(

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

View File

@@ -76,20 +76,30 @@ void scene_on_enter_key_menu(void* context) {
menu_add_item( menu_add_item(
state->menu, state->menu,
"No encryption", "No encryption",
NULL, &I_chat_10px,
ESubGhzChatKeyMenuItems_NoEncryption, ESubGhzChatKeyMenuItems_NoEncryption,
key_menu_cb, key_menu_cb,
state); state);
menu_add_item( menu_add_item(
state->menu, "Password", NULL, ESubGhzChatKeyMenuItems_Password, key_menu_cb, state); state->menu,
"Password",
&I_keyboard_10px,
ESubGhzChatKeyMenuItems_Password,
key_menu_cb,
state);
menu_add_item( menu_add_item(
state->menu, "Hex Key", NULL, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state); state->menu, "Hex Key", &I_hex_10px, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state);
menu_add_item( menu_add_item(
state->menu, "Generate Key", NULL, ESubGhzChatKeyMenuItems_GenKey, key_menu_cb, state); state->menu,
"Generate Key",
&I_u2f_10px,
ESubGhzChatKeyMenuItems_GenKey,
key_menu_cb,
state);
menu_add_item( menu_add_item(
state->menu, state->menu,
"Read Key from NFC", "Read Key from NFC",
NULL, &I_Nfc_10px,
ESubGhzChatKeyMenuItems_ReadKeyFromNfc, ESubGhzChatKeyMenuItems_ReadKeyFromNfc,
key_menu_cb, key_menu_cb,
state); state);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 156 B

View File

@@ -16,5 +16,6 @@ ADD_SCENE(xtreme_app, protocols_freqs_add, ProtocolsFreqsAdd)
ADD_SCENE(xtreme_app, protocols_gpio, ProtocolsGpio) ADD_SCENE(xtreme_app, protocols_gpio, ProtocolsGpio)
ADD_SCENE(xtreme_app, misc, Misc) ADD_SCENE(xtreme_app, misc, Misc)
ADD_SCENE(xtreme_app, misc_screen, MiscScreen) ADD_SCENE(xtreme_app, misc_screen, MiscScreen)
ADD_SCENE(xtreme_app, misc_screen_color, MiscScreenColor)
ADD_SCENE(xtreme_app, misc_dolphin, MiscDolphin) ADD_SCENE(xtreme_app, misc_dolphin, MiscDolphin)
ADD_SCENE(xtreme_app, misc_rename, MiscRename) ADD_SCENE(xtreme_app, misc_rename, MiscRename)

View File

@@ -27,10 +27,34 @@ static void xtreme_app_scene_interface_graphics_asset_pack_changed(VariableItem*
app->apply_pack = true; app->apply_pack = true;
} }
const char* const anim_speed_names[] = const char* const anim_speed_names[] = {
{"25%", "50%", "75%", "100%", "125%", "150%", "175%", "200%", "225%", "250%", "275%", "300%"}; "25%",
const uint32_t anim_speed_values[COUNT_OF(anim_speed_names)] = "50%",
{25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300}; "75%",
"100%",
"125%",
"150%",
"175%",
"200%",
"225%",
"250%",
"275%",
"300%",
};
const uint32_t anim_speed_values[COUNT_OF(anim_speed_names)] = {
25,
50,
75,
100,
125,
150,
175,
200,
225,
250,
275,
300,
};
static void xtreme_app_scene_interface_graphics_anim_speed_changed(VariableItem* item) { static void xtreme_app_scene_interface_graphics_anim_speed_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item); XtremeApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item); uint8_t index = variable_item_get_current_value_index(item);
@@ -52,9 +76,23 @@ const char* const cycle_anims_names[] = {
"2 H", "2 H",
"6 H", "6 H",
"12 H", "12 H",
"24 H"}; "24 H",
const int32_t cycle_anims_values[COUNT_OF(cycle_anims_names)] = };
{-1, 0, 30, 60, 300, 600, 900, 1800, 3600, 7200, 21600, 43200, 86400}; const int32_t cycle_anims_values[COUNT_OF(cycle_anims_names)] = {
-1,
0,
30,
60,
300,
600,
900,
1800,
3600,
7200,
21600,
43200,
86400,
};
static void xtreme_app_scene_interface_graphics_cycle_anims_changed(VariableItem* item) { static void xtreme_app_scene_interface_graphics_cycle_anims_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item); XtremeApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item); uint8_t index = variable_item_get_current_value_index(item);

View File

@@ -13,8 +13,15 @@ void xtreme_app_scene_interface_statusbar_var_item_list_callback(void* context,
view_dispatcher_send_custom_event(app->view_dispatcher, index); view_dispatcher_send_custom_event(app->view_dispatcher, index);
} }
const char* const battery_icon_names[BatteryIconCount] = const char* const battery_icon_names[BatteryIconCount] = {
{"OFF", "Bar", "%", "Inv. %", "Retro 3", "Retro 5", "Bar %"}; "OFF",
"Bar",
"%",
"Inv. %",
"Retro 3",
"Retro 5",
"Bar %",
};
static void xtreme_app_scene_interface_statusbar_battery_icon_changed(VariableItem* item) { static void xtreme_app_scene_interface_statusbar_battery_icon_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item); XtremeApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item); uint8_t index = variable_item_get_current_value_index(item);

View File

@@ -29,10 +29,30 @@ static void xtreme_app_scene_misc_dolphin_dolphin_angry_changed(VariableItem* it
app->save_angry = true; app->save_angry = true;
} }
const char* const butthurt_timer_names[] = const char* const butthurt_timer_names[] = {
{"OFF", "30 M", "1 H", "2 H", "4 H", "6 H", "8 H", "12 H", "24 H", "48 H"}; "OFF",
const uint32_t butthurt_timer_values[COUNT_OF(butthurt_timer_names)] = "30 M",
{0, 1800, 3600, 7200, 14400, 21600, 28800, 43200, 86400, 172800}; "1 H",
"2 H",
"4 H",
"6 H",
"8 H",
"12 H",
"24 H",
"48 H",
};
const uint32_t butthurt_timer_values[COUNT_OF(butthurt_timer_names)] = {
0,
1800,
3600,
7200,
14400,
21600,
28800,
43200,
86400,
172800,
};
static void xtreme_app_scene_misc_dolphin_butthurt_timer_changed(VariableItem* item) { static void xtreme_app_scene_misc_dolphin_butthurt_timer_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item); XtremeApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item); uint8_t index = variable_item_get_current_value_index(item);

View File

@@ -4,7 +4,13 @@ enum VarItemListIndex {
VarItemListIndexDarkMode, VarItemListIndexDarkMode,
VarItemListIndexLeftHanded, VarItemListIndexLeftHanded,
VarItemListIndexRgbBacklight, VarItemListIndexRgbBacklight,
VarItemListIndexLcdColor, VarItemListIndexLcdColor0,
VarItemListIndexLcdColor1,
VarItemListIndexLcdColor2,
VarItemListIndexRainbowLcd,
VarItemListIndexRainbowSpeed,
VarItemListIndexRainbowInterval,
VarItemListIndexRainbowSaturation,
}; };
void xtreme_app_scene_misc_screen_var_item_list_callback(void* context, uint32_t index) { void xtreme_app_scene_misc_screen_var_item_list_callback(void* context, uint32_t index) {
@@ -30,13 +36,117 @@ static void xtreme_app_scene_misc_screen_hand_orient_changed(VariableItem* item)
} }
} }
static void xtreme_app_scene_misc_screen_lcd_color_changed(VariableItem* item) { static const struct {
char* name;
RgbColor color;
} lcd_colors[] = {
{"Orange", {255, 69, 0}},
{"Red", {255, 0, 0}},
{"Maroon", {128, 0, 0}},
{"Yellow", {255, 255, 0}},
{"Olive", {128, 128, 0}},
{"Lime", {0, 255, 0}},
{"Green", {0, 128, 0}},
{"Aqua", {0, 255, 127}},
{"Cyan", {0, 210, 210}},
{"Azure", {0, 127, 255}},
{"Teal", {0, 128, 128}},
{"Blue", {0, 0, 255}},
{"Navy", {0, 0, 128}},
{"Purple", {128, 0, 128}},
{"Fuchsia", {255, 0, 255}},
{"Pink", {173, 31, 173}},
{"Brown", {165, 42, 42}},
{"White", {255, 192, 203}},
};
static void xtreme_app_scene_misc_screen_lcd_color_changed(VariableItem* item, uint8_t led) {
XtremeApp* app = variable_item_get_context(item); XtremeApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item); uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, rgb_backlight_get_color_text(index)); variable_item_set_current_value_text(item, lcd_colors[index].name);
rgb_backlight_set_color(index); rgb_backlight_set_color(led, lcd_colors[index].color);
app->save_backlight = true;
}
static void xtreme_app_scene_misc_screen_lcd_color_0_changed(VariableItem* item) {
xtreme_app_scene_misc_screen_lcd_color_changed(item, 0);
}
static void xtreme_app_scene_misc_screen_lcd_color_1_changed(VariableItem* item) {
xtreme_app_scene_misc_screen_lcd_color_changed(item, 1);
}
static void xtreme_app_scene_misc_screen_lcd_color_2_changed(VariableItem* item) {
xtreme_app_scene_misc_screen_lcd_color_changed(item, 2);
}
const char* const rainbow_lcd_names[RGBBacklightRainbowModeCount] = {
"OFF",
"Wave",
"Static",
};
static void xtreme_app_scene_misc_screen_rainbow_lcd_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, rainbow_lcd_names[index]);
rgb_backlight_set_rainbow_mode(index);
app->save_backlight = true;
}
static void xtreme_app_scene_misc_screen_rainbow_speed_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item) + 1;
char str[4];
snprintf(str, sizeof(str), "%d", index);
variable_item_set_current_value_text(item, str);
rgb_backlight_set_rainbow_speed(index);
app->save_backlight = true;
}
const char* const rainbow_interval_names[] = {
"0.1 S",
"0.2 S",
"0.25 S",
"0.5 S",
"0.75 S",
"1 S",
"1.25 S",
"1.5 S",
"1.75 S",
"2 S",
"2.5 S",
"3 S",
"4 S",
"5 S",
};
const uint32_t rainbow_interval_values[COUNT_OF(rainbow_interval_names)] = {
100,
200,
250,
500,
750,
1000,
1250,
1500,
1750,
2000,
2500,
3000,
4000,
5000,
};
static void xtreme_app_scene_misc_screen_rainbow_interval_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, rainbow_interval_names[index]);
rgb_backlight_set_rainbow_interval(rainbow_interval_values[index]);
app->save_backlight = true;
}
static void xtreme_app_scene_misc_screen_rainbow_saturation_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item) + 1;
char str[4];
snprintf(str, sizeof(str), "%d", index);
variable_item_set_current_value_text(item, str);
rgb_backlight_set_rainbow_saturation(index);
app->save_backlight = true; app->save_backlight = true;
notification_message(app->notification, &sequence_display_backlight_on);
} }
void xtreme_app_scene_misc_screen_on_enter(void* context) { void xtreme_app_scene_misc_screen_on_enter(void* context) {
@@ -60,15 +170,87 @@ void xtreme_app_scene_misc_screen_on_enter(void* context) {
item = variable_item_list_add(var_item_list, "RGB Backlight", 1, NULL, app); item = variable_item_list_add(var_item_list, "RGB Backlight", 1, NULL, app);
variable_item_set_current_value_text(item, xtreme_settings->rgb_backlight ? "ON" : "OFF"); variable_item_set_current_value_text(item, xtreme_settings->rgb_backlight ? "ON" : "OFF");
struct {
uint8_t led;
const char* str;
VariableItemChangeCallback cb;
} lcd_cols[] = {
{0, "LCD Left", xtreme_app_scene_misc_screen_lcd_color_0_changed},
{1, "LCD Middle", xtreme_app_scene_misc_screen_lcd_color_1_changed},
{2, "LCD Right", xtreme_app_scene_misc_screen_lcd_color_2_changed},
};
size_t lcd_sz = COUNT_OF(lcd_colors);
for(size_t i = 0; i < COUNT_OF(lcd_cols); i++) {
item = variable_item_list_add(var_item_list, lcd_cols[i].str, lcd_sz, lcd_cols[i].cb, app);
RgbColor color = rgb_backlight_get_color(lcd_cols[i].led);
bool found = false;
for(size_t i = 0; i < lcd_sz; i++) {
if(rgbcmp(&color, &lcd_colors[i].color) != 0) continue;
value_index = i;
found = true;
break;
}
variable_item_set_current_value_index(item, found ? value_index : lcd_sz);
if(found) {
variable_item_set_current_value_text(item, lcd_colors[value_index].name);
} else {
char str[7];
snprintf(str, sizeof(str), "%02X%02X%02X", color.r, color.g, color.b);
variable_item_set_current_value_text(item, str);
}
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
}
item = variable_item_list_add( item = variable_item_list_add(
var_item_list, var_item_list,
"LCD Color", "Rainbow LCD",
rgb_backlight_get_color_count(), RGBBacklightRainbowModeCount,
xtreme_app_scene_misc_screen_lcd_color_changed, xtreme_app_scene_misc_screen_rainbow_lcd_changed,
app); app);
value_index = rgb_backlight_get_settings()->display_color_index; value_index = rgb_backlight_get_rainbow_mode();
variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, rgb_backlight_get_color_text(value_index)); variable_item_set_current_value_text(item, rainbow_lcd_names[value_index]);
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
item = variable_item_list_add(
var_item_list,
"Rainbow Speed",
25,
xtreme_app_scene_misc_screen_rainbow_speed_changed,
app);
value_index = rgb_backlight_get_rainbow_speed();
variable_item_set_current_value_index(item, value_index - 1);
char speed_str[4];
snprintf(speed_str, sizeof(speed_str), "%d", value_index);
variable_item_set_current_value_text(item, speed_str);
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
item = variable_item_list_add(
var_item_list,
"Rainbow Interval",
COUNT_OF(rainbow_interval_values),
xtreme_app_scene_misc_screen_rainbow_interval_changed,
app);
value_index = value_index_uint32(
rgb_backlight_get_rainbow_interval(),
rainbow_interval_values,
COUNT_OF(rainbow_interval_values));
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, rainbow_interval_names[value_index]);
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
item = variable_item_list_add(
var_item_list,
"Rainbow Saturation",
25,
xtreme_app_scene_misc_screen_rainbow_saturation_changed,
app);
value_index = rgb_backlight_get_rainbow_saturation();
variable_item_set_current_value_index(item, value_index - 1);
char saturation_str[4];
snprintf(saturation_str, sizeof(saturation_str), "%d", value_index);
variable_item_set_current_value_text(item, saturation_str);
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!"); variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
variable_item_list_set_enter_callback( variable_item_list_set_enter_callback(
@@ -110,12 +292,23 @@ bool xtreme_app_scene_misc_screen_on_event(void* context, SceneManagerEvent even
if(change) { if(change) {
XTREME_SETTINGS()->rgb_backlight = !XTREME_SETTINGS()->rgb_backlight; XTREME_SETTINGS()->rgb_backlight = !XTREME_SETTINGS()->rgb_backlight;
app->save_settings = true; app->save_settings = true;
app->save_backlight = true;
notification_message(app->notification, &sequence_display_backlight_on); notification_message(app->notification, &sequence_display_backlight_on);
rgb_backlight_reconfigure(XTREME_SETTINGS()->rgb_backlight);
scene_manager_previous_scene(app->scene_manager); scene_manager_previous_scene(app->scene_manager);
scene_manager_next_scene(app->scene_manager, XtremeAppSceneMiscScreen); scene_manager_next_scene(app->scene_manager, XtremeAppSceneMiscScreen);
} }
break; break;
} }
case VarItemListIndexLcdColor0:
case VarItemListIndexLcdColor1:
case VarItemListIndexLcdColor2:
scene_manager_set_scene_state(
app->scene_manager,
XtremeAppSceneMiscScreenColor,
event.event - VarItemListIndexLcdColor0);
scene_manager_next_scene(app->scene_manager, XtremeAppSceneMiscScreenColor);
break;
default: default:
break; break;
} }

View File

@@ -0,0 +1,59 @@
#include "../xtreme_app.h"
enum ByteInputResult {
ByteInputResultOk,
};
void xtreme_app_scene_misc_screen_color_byte_input_callback(void* context) {
XtremeApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, ByteInputResultOk);
}
void xtreme_app_scene_misc_screen_color_on_enter(void* context) {
XtremeApp* app = context;
ByteInput* byte_input = app->byte_input;
byte_input_set_header_text(byte_input, "Set LCD Color (#RRGGBB)");
app->lcd_color = rgb_backlight_get_color(
scene_manager_get_scene_state(app->scene_manager, XtremeAppSceneMiscScreenColor));
byte_input_set_result_callback(
byte_input,
xtreme_app_scene_misc_screen_color_byte_input_callback,
NULL,
app,
(void*)&app->lcd_color,
sizeof(app->lcd_color));
view_dispatcher_switch_to_view(app->view_dispatcher, XtremeAppViewByteInput);
}
bool xtreme_app_scene_misc_screen_color_on_event(void* context, SceneManagerEvent event) {
XtremeApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
switch(event.event) {
case ByteInputResultOk:
rgb_backlight_set_color(
scene_manager_get_scene_state(app->scene_manager, XtremeAppSceneMiscScreenColor),
app->lcd_color);
app->save_backlight = true;
scene_manager_previous_scene(app->scene_manager);
break;
default:
break;
}
}
return consumed;
}
void xtreme_app_scene_misc_screen_color_on_exit(void* context) {
XtremeApp* app = context;
byte_input_set_result_callback(app->byte_input, NULL, NULL, NULL, NULL, 0);
byte_input_set_header_text(app->byte_input, "");
}

View File

@@ -193,6 +193,10 @@ XtremeApp* xtreme_app_alloc() {
view_dispatcher_add_view( view_dispatcher_add_view(
app->view_dispatcher, XtremeAppViewTextInput, text_input_get_view(app->text_input)); app->view_dispatcher, XtremeAppViewTextInput, text_input_get_view(app->text_input));
app->byte_input = byte_input_alloc();
view_dispatcher_add_view(
app->view_dispatcher, XtremeAppViewByteInput, byte_input_get_view(app->byte_input));
app->popup = popup_alloc(); app->popup = popup_alloc();
view_dispatcher_add_view(app->view_dispatcher, XtremeAppViewPopup, popup_get_view(app->popup)); view_dispatcher_add_view(app->view_dispatcher, XtremeAppViewPopup, popup_get_view(app->popup));
@@ -315,6 +319,8 @@ void xtreme_app_free(XtremeApp* app) {
submenu_free(app->submenu); submenu_free(app->submenu);
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewTextInput); view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewTextInput);
text_input_free(app->text_input); text_input_free(app->text_input);
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewByteInput);
byte_input_free(app->byte_input);
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewPopup); view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewPopup);
popup_free(app->popup); popup_free(app->popup);
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewDialogEx); view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewDialogEx);

View File

@@ -12,6 +12,7 @@
#include <gui/modules/variable_item_list.h> #include <gui/modules/variable_item_list.h>
#include <gui/modules/submenu.h> #include <gui/modules/submenu.h>
#include <gui/modules/text_input.h> #include <gui/modules/text_input.h>
#include <gui/modules/byte_input.h>
#include <gui/modules/popup.h> #include <gui/modules/popup.h>
#include <lib/toolbox/value_index.h> #include <lib/toolbox/value_index.h>
#include <toolbox/stream/file_stream.h> #include <toolbox/stream/file_stream.h>
@@ -42,6 +43,7 @@ typedef struct {
VariableItemList* var_item_list; VariableItemList* var_item_list;
Submenu* submenu; Submenu* submenu;
TextInput* text_input; TextInput* text_input;
ByteInput* byte_input;
Popup* popup; Popup* popup;
DialogEx* dialog_ex; DialogEx* dialog_ex;
@@ -57,6 +59,7 @@ typedef struct {
uint8_t subghz_hopper_index; uint8_t subghz_hopper_index;
char subghz_freq_buffer[XTREME_SUBGHZ_FREQ_BUFFER_SIZE]; char subghz_freq_buffer[XTREME_SUBGHZ_FREQ_BUFFER_SIZE];
bool subghz_extend; bool subghz_extend;
RgbColor lcd_color;
char device_name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH]; char device_name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH];
int32_t dolphin_level; int32_t dolphin_level;
int32_t dolphin_angry; int32_t dolphin_angry;
@@ -79,6 +82,7 @@ typedef enum {
XtremeAppViewVarItemList, XtremeAppViewVarItemList,
XtremeAppViewSubmenu, XtremeAppViewSubmenu,
XtremeAppViewTextInput, XtremeAppViewTextInput,
XtremeAppViewByteInput,
XtremeAppViewPopup, XtremeAppViewPopup,
XtremeAppViewDialogEx, XtremeAppViewDialogEx,
} XtremeAppView; } XtremeAppView;

View File

@@ -1171,18 +1171,18 @@ Function,+,furi_hal_cortex_timer_is_expired,_Bool,FuriHalCortexTimer
Function,+,furi_hal_cortex_timer_wait,void,FuriHalCortexTimer Function,+,furi_hal_cortex_timer_wait,void,FuriHalCortexTimer
Function,+,furi_hal_crypto_ctr,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, uint8_t*, size_t" Function,+,furi_hal_crypto_ctr,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, uint8_t*, size_t"
Function,+,furi_hal_crypto_decrypt,_Bool,"const uint8_t*, uint8_t*, size_t" Function,+,furi_hal_crypto_decrypt,_Bool,"const uint8_t*, uint8_t*, size_t"
Function,+,furi_hal_crypto_enclave_ensure_key,_Bool,uint8_t
Function,+,furi_hal_crypto_enclave_load_key,_Bool,"uint8_t, const uint8_t*"
Function,+,furi_hal_crypto_enclave_store_key,_Bool,"FuriHalCryptoKey*, uint8_t*"
Function,+,furi_hal_crypto_enclave_unload_key,_Bool,uint8_t
Function,+,furi_hal_crypto_enclave_verify,_Bool,"uint8_t*, uint8_t*"
Function,+,furi_hal_crypto_encrypt,_Bool,"const uint8_t*, uint8_t*, size_t" Function,+,furi_hal_crypto_encrypt,_Bool,"const uint8_t*, uint8_t*, size_t"
Function,+,furi_hal_crypto_gcm,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*, _Bool" Function,+,furi_hal_crypto_gcm,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*, _Bool"
Function,+,furi_hal_crypto_gcm_decrypt_and_verify,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, const uint8_t*" Function,+,furi_hal_crypto_gcm_decrypt_and_verify,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, const uint8_t*"
Function,+,furi_hal_crypto_gcm_encrypt_and_tag,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*" Function,+,furi_hal_crypto_gcm_encrypt_and_tag,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*"
Function,-,furi_hal_crypto_init,void, Function,-,furi_hal_crypto_init,void,
Function,+,furi_hal_crypto_load_key,_Bool,"const uint8_t*, const uint8_t*" Function,+,furi_hal_crypto_load_key,_Bool,"const uint8_t*, const uint8_t*"
Function,+,furi_hal_crypto_enclave_store_key,_Bool,"FuriHalCryptoKey*, uint8_t*"
Function,+,furi_hal_crypto_enclave_load_key,_Bool,"uint8_t, const uint8_t*"
Function,+,furi_hal_crypto_enclave_unload_key,_Bool,uint8_t
Function,+,furi_hal_crypto_unload_key,_Bool, Function,+,furi_hal_crypto_unload_key,_Bool,
Function,+,furi_hal_crypto_enclave_verify,_Bool,"uint8_t*, uint8_t*"
Function,+,furi_hal_crypto_enclave_ensure_key,_Bool,uint8_t
Function,+,furi_hal_debug_disable,void, Function,+,furi_hal_debug_disable,void,
Function,+,furi_hal_debug_enable,void, Function,+,furi_hal_debug_enable,void,
Function,+,furi_hal_debug_is_gdb_session_active,_Bool, Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
@@ -1733,6 +1733,8 @@ Function,+,hex_char_to_hex_nibble,_Bool,"char, uint8_t*"
Function,+,hex_char_to_uint8,_Bool,"char, char, uint8_t*" Function,+,hex_char_to_uint8,_Bool,"char, char, uint8_t*"
Function,+,hex_chars_to_uint64,_Bool,"const char*, uint64_t*" Function,+,hex_chars_to_uint64,_Bool,"const char*, uint64_t*"
Function,+,hex_chars_to_uint8,_Bool,"const char*, uint8_t*" Function,+,hex_chars_to_uint8,_Bool,"const char*, uint8_t*"
Function,+,hsv2rgb,RgbColor,HsvColor
Function,+,hsvcmp,int,"const HsvColor*, const HsvColor*"
Function,-,hypot,double,"double, double" Function,-,hypot,double,"double, double"
Function,-,hypotf,float,"float, float" Function,-,hypotf,float,"float, float"
Function,-,hypotl,long double,"long double, long double" Function,-,hypotl,long double,"long double, long double"
@@ -2555,13 +2557,22 @@ Function,-,rfal_platform_spi_acquire,void,
Function,-,rfal_platform_spi_release,void, Function,-,rfal_platform_spi_release,void,
Function,-,rfal_set_callback_context,void,void* Function,-,rfal_set_callback_context,void,void*
Function,-,rfal_set_state_changed_callback,void,RfalStateChangedCallback Function,-,rfal_set_state_changed_callback,void,RfalStateChangedCallback
Function,+,rgb_backlight_get_color_count,uint8_t, Function,+,rgb2hsv,HsvColor,RgbColor
Function,+,rgb_backlight_get_color_text,const char*,uint8_t Function,+,rgb_backlight_get_color,RgbColor,uint8_t
Function,+,rgb_backlight_get_settings,RGBBacklightSettings*, Function,+,rgb_backlight_get_rainbow_interval,uint32_t,
Function,+,rgb_backlight_get_rainbow_mode,RGBBacklightRainbowMode,
Function,+,rgb_backlight_get_rainbow_saturation,uint8_t,
Function,+,rgb_backlight_get_rainbow_speed,uint8_t,
Function,-,rgb_backlight_load_settings,void, Function,-,rgb_backlight_load_settings,void,
Function,+,rgb_backlight_reconfigure,void,_Bool
Function,+,rgb_backlight_save_settings,void, Function,+,rgb_backlight_save_settings,void,
Function,+,rgb_backlight_set_color,void,uint8_t Function,+,rgb_backlight_set_color,void,"uint8_t, RgbColor"
Function,-,rgb_backlight_update,void,uint8_t Function,+,rgb_backlight_set_rainbow_interval,void,uint32_t
Function,+,rgb_backlight_set_rainbow_mode,void,RGBBacklightRainbowMode
Function,+,rgb_backlight_set_rainbow_saturation,void,uint8_t
Function,+,rgb_backlight_set_rainbow_speed,void,uint8_t
Function,-,rgb_backlight_update,void,"uint8_t, _Bool"
Function,+,rgbcmp,int,"const RgbColor*, const RgbColor*"
Function,-,rindex,char*,"const char*, int" Function,-,rindex,char*,"const char*, int"
Function,-,rint,double,double Function,-,rint,double,double
Function,-,rintf,float,float Function,-,rintf,float,float
1 entry status name type params
1171 Function + furi_hal_cortex_timer_wait void FuriHalCortexTimer
1172 Function + furi_hal_crypto_ctr _Bool const uint8_t*, const uint8_t*, const uint8_t*, uint8_t*, size_t
1173 Function + furi_hal_crypto_decrypt _Bool const uint8_t*, uint8_t*, size_t
1174 Function + furi_hal_crypto_enclave_ensure_key _Bool uint8_t
1175 Function + furi_hal_crypto_enclave_load_key _Bool uint8_t, const uint8_t*
1176 Function + furi_hal_crypto_enclave_store_key _Bool FuriHalCryptoKey*, uint8_t*
1177 Function + furi_hal_crypto_enclave_unload_key _Bool uint8_t
1178 Function + furi_hal_crypto_enclave_verify _Bool uint8_t*, uint8_t*
1179 Function + furi_hal_crypto_encrypt _Bool const uint8_t*, uint8_t*, size_t
1180 Function + furi_hal_crypto_gcm _Bool const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*, _Bool
1181 Function + furi_hal_crypto_gcm_decrypt_and_verify FuriHalCryptoGCMState const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, const uint8_t*
1182 Function + furi_hal_crypto_gcm_encrypt_and_tag FuriHalCryptoGCMState const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*
1183 Function - furi_hal_crypto_init void
1184 Function + furi_hal_crypto_load_key _Bool const uint8_t*, const uint8_t*
Function + furi_hal_crypto_enclave_store_key _Bool FuriHalCryptoKey*, uint8_t*
Function + furi_hal_crypto_enclave_load_key _Bool uint8_t, const uint8_t*
Function + furi_hal_crypto_enclave_unload_key _Bool uint8_t
1185 Function + furi_hal_crypto_unload_key _Bool
Function + furi_hal_crypto_enclave_verify _Bool uint8_t*, uint8_t*
Function + furi_hal_crypto_enclave_ensure_key _Bool uint8_t
1186 Function + furi_hal_debug_disable void
1187 Function + furi_hal_debug_enable void
1188 Function + furi_hal_debug_is_gdb_session_active _Bool
1733 Function + hex_char_to_uint8 _Bool char, char, uint8_t*
1734 Function + hex_chars_to_uint64 _Bool const char*, uint64_t*
1735 Function + hex_chars_to_uint8 _Bool const char*, uint8_t*
1736 Function + hsv2rgb RgbColor HsvColor
1737 Function + hsvcmp int const HsvColor*, const HsvColor*
1738 Function - hypot double double, double
1739 Function - hypotf float float, float
1740 Function - hypotl long double long double, long double
2557 Function - rfal_platform_spi_release void
2558 Function - rfal_set_callback_context void void*
2559 Function - rfal_set_state_changed_callback void RfalStateChangedCallback
2560 Function + rgb_backlight_get_color_count rgb2hsv uint8_t HsvColor RgbColor
2561 Function + rgb_backlight_get_color_text rgb_backlight_get_color const char* RgbColor uint8_t
2562 Function + rgb_backlight_get_settings rgb_backlight_get_rainbow_interval RGBBacklightSettings* uint32_t
2563 Function + rgb_backlight_get_rainbow_mode RGBBacklightRainbowMode
2564 Function + rgb_backlight_get_rainbow_saturation uint8_t
2565 Function + rgb_backlight_get_rainbow_speed uint8_t
2566 Function - rgb_backlight_load_settings void
2567 Function + rgb_backlight_reconfigure void _Bool
2568 Function + rgb_backlight_save_settings void
2569 Function + rgb_backlight_set_color void uint8_t uint8_t, RgbColor
2570 Function - + rgb_backlight_update rgb_backlight_set_rainbow_interval void uint8_t uint32_t
2571 Function + rgb_backlight_set_rainbow_mode void RGBBacklightRainbowMode
2572 Function + rgb_backlight_set_rainbow_saturation void uint8_t
2573 Function + rgb_backlight_set_rainbow_speed void uint8_t
2574 Function - rgb_backlight_update void uint8_t, _Bool
2575 Function + rgbcmp int const RgbColor*, const RgbColor*
2576 Function - rindex char* const char*, int
2577 Function - rint double double
2578 Function - rintf float float

View File

@@ -45,7 +45,7 @@ void furi_hal_light_set(Light light, uint8_t value) {
} }
if(light & LightBacklight) { if(light & LightBacklight) {
if(XTREME_SETTINGS()->rgb_backlight) { if(XTREME_SETTINGS()->rgb_backlight) {
rgb_backlight_update(value); rgb_backlight_update(value, false);
} else { } else {
uint8_t prev = uint8_t prev =
lp5562_get_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite); lp5562_get_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite);

View File

@@ -19,9 +19,10 @@
#include "SK6805.h" #include "SK6805.h"
#include <furi_hal.h> #include <furi_hal.h>
#define TAG "SK6805"
/* Настройки */ /* Настройки */
#define SK6805_LED_COUNT 3 //Количество светодиодов на плате подсветки #define SK6805_LED_PIN &led_pin // LED connection port
#define SK6805_LED_PIN &led_pin //Порт подключения светодиодов
#ifdef FURI_DEBUG #ifdef FURI_DEBUG
#define DEBUG_PIN &gpio_ext_pa7 #define DEBUG_PIN &gpio_ext_pa7
@@ -53,17 +54,18 @@ void SK6805_set_led_color(uint8_t led_index, uint8_t r, uint8_t g, uint8_t b) {
led_buffer[led_index][0] = g; led_buffer[led_index][0] = g;
led_buffer[led_index][1] = r; led_buffer[led_index][1] = r;
led_buffer[led_index][2] = b; led_buffer[led_index][2] = b;
FURI_LOG_T(TAG, "led: %d, r: %d, g: %d, b: %d", led_index, r, g, b);
} }
void SK6805_update(void) { void SK6805_update(void) {
SK6805_init(); SK6805_init();
furi_kernel_lock(); furi_kernel_lock();
uint32_t end; uint32_t end;
/* Последовательная отправка цветов светодиодов */ // Sequential sending LEDs
for(uint8_t lednumber = 0; lednumber < SK6805_LED_COUNT; lednumber++) { for(uint8_t lednumber = 0; lednumber < SK6805_LED_COUNT; lednumber++) {
//Последовательная отправка цветов светодиода // Sequential sending colors
for(uint8_t color = 0; color < 3; color++) { for(uint8_t color = 0; color < 3; color++) {
//Последовательная отправка битов цвета // Sequentially sending color bits
uint8_t i = 0b10000000; uint8_t i = 0b10000000;
while(i != 0) { while(i != 0) {
if(led_buffer[lednumber][color] & (i)) { if(led_buffer[lednumber][color] & (i)) {

View File

@@ -21,6 +21,8 @@
#include <furi.h> #include <furi.h>
#define SK6805_LED_COUNT 3 //Количество светодиодов на плате подсветки
/** /**
* @brief Инициализация линии управления подсветкой * @brief Инициализация линии управления подсветкой
*/ */
@@ -48,4 +50,4 @@ void SK6805_set_led_color(uint8_t led_index, uint8_t r, uint8_t g, uint8_t b);
*/ */
void SK6805_update(void); void SK6805_update(void);
#endif /* SK6805_H_ */ #endif /* SK6805_H_ */

View File

@@ -1,6 +1,7 @@
/* /*
RGB backlight FlipperZero driver RGB backlight FlipperZero driver
Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n) Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
Heavily modified by Willy-JL and Z3bro
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -19,156 +20,243 @@
#include "rgb_backlight.h" #include "rgb_backlight.h"
#include <furi_hal.h> #include <furi_hal.h>
#include <storage/storage.h> #include <storage/storage.h>
#include <toolbox/saved_struct.h>
#define RGB_BACKLIGHT_SETTINGS_VERSION 5 #define RGB_BACKLIGHT_SETTINGS_MAGIC 0x15
#define RGB_BACKLIGHT_SETTINGS_VERSION 6
#define RGB_BACKLIGHT_SETTINGS_PATH CFG_PATH("rgb_backlight.settings") #define RGB_BACKLIGHT_SETTINGS_PATH CFG_PATH("rgb_backlight.settings")
#define COLOR_COUNT (sizeof(colors) / sizeof(RGBBacklightColor)) static struct {
RgbColor colors[SK6805_LED_COUNT];
#define TAG "RGB Backlight" RGBBacklightRainbowMode rainbow_mode;
uint8_t rainbow_speed;
static RGBBacklightSettings rgb_settings = { uint32_t rainbow_interval;
.version = RGB_BACKLIGHT_SETTINGS_VERSION, uint32_t rainbow_saturation;
.display_color_index = 0, } rgb_settings = {
.settings_is_loaded = false}; .colors =
{
static const RGBBacklightColor colors[] = { {255, 69, 0},
{"Orange", 255, 69, 0}, {255, 69, 0},
{"Red", 255, 0, 0}, {255, 69, 0},
{"Maroon", 128, 0, 0}, },
{"Yellow", 255, 255, 0}, .rainbow_mode = RGBBacklightRainbowModeOff,
{"Olive", 128, 128, 0}, .rainbow_speed = 5,
{"Lime", 0, 255, 0}, .rainbow_interval = 250,
{"Green", 0, 128, 0}, .rainbow_saturation = 255,
{"Aqua", 0, 255, 127},
{"Cyan", 0, 210, 210},
{"Azure", 0, 127, 255},
{"Teal", 0, 128, 128},
{"Blue", 0, 0, 255},
{"Navy", 0, 0, 128},
{"Purple", 128, 0, 128},
{"Fuchsia", 255, 0, 255},
{"Pink", 173, 31, 173},
{"Brown", 165, 42, 42},
{"White", 255, 192, 203},
}; };
uint8_t rgb_backlight_get_color_count(void) { static struct {
return COLOR_COUNT; bool settings_loaded;
bool enabled;
bool last_rainbow;
uint8_t last_brightness;
RgbColor last_colors[SK6805_LED_COUNT];
FuriTimer* rainbow_timer;
HsvColor rainbow_hsv;
} rgb_state = {
.settings_loaded = false,
.enabled = false,
.last_rainbow = true,
.last_brightness = 0,
.last_colors =
{
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
},
.rainbow_timer = NULL,
.rainbow_hsv = {0, 255, 255},
};
static void rainbow_timer(void* ctx) {
UNUSED(ctx);
rgb_backlight_update(rgb_state.last_brightness, true);
} }
const char* rgb_backlight_get_color_text(uint8_t index) { void rgb_backlight_reconfigure(bool enabled) {
return colors[index].name; if(enabled && !rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
rgb_state.enabled = enabled;
if(rgb_state.enabled && rgb_settings.rainbow_mode != RGBBacklightRainbowModeOff) {
if(rgb_state.rainbow_timer == NULL) {
rgb_state.rainbow_timer = furi_timer_alloc(rainbow_timer, FuriTimerTypePeriodic, NULL);
} else {
furi_timer_stop(rgb_state.rainbow_timer);
}
furi_timer_start(rgb_state.rainbow_timer, rgb_settings.rainbow_interval);
} else if(rgb_state.rainbow_timer != NULL) {
furi_timer_stop(rgb_state.rainbow_timer);
furi_timer_free(rgb_state.rainbow_timer);
rgb_state.rainbow_timer = NULL;
}
rgb_state.rainbow_hsv.s = rgb_settings.rainbow_saturation;
rgb_backlight_update(rgb_state.last_brightness, false);
} }
void rgb_backlight_load_settings(void) { void rgb_backlight_load_settings(void) {
//Не загружать данные из внутренней памяти при загрузке в режиме DFU // Do not load data from internal memory when booting in DFU mode
if(!furi_hal_is_normal_boot()) { if(!furi_hal_is_normal_boot() || rgb_state.settings_loaded) {
rgb_settings.settings_is_loaded = true; rgb_state.settings_loaded = true;
return; return;
} }
RGBBacklightSettings settings; saved_struct_load(
File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); RGB_BACKLIGHT_SETTINGS_PATH,
const size_t settings_size = sizeof(RGBBacklightSettings); &rgb_settings,
sizeof(rgb_settings),
RGB_BACKLIGHT_SETTINGS_MAGIC,
RGB_BACKLIGHT_SETTINGS_VERSION);
FURI_LOG_I(TAG, "loading settings from \"%s\"", RGB_BACKLIGHT_SETTINGS_PATH); rgb_state.settings_loaded = true;
bool fs_result = rgb_backlight_reconfigure(rgb_state.enabled);
storage_file_open(file, RGB_BACKLIGHT_SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
if(fs_result) {
uint16_t bytes_count = storage_file_read(file, &settings, settings_size);
if(bytes_count != settings_size) {
fs_result = false;
}
}
if(fs_result) {
FURI_LOG_I(TAG, "load success");
if(settings.version != RGB_BACKLIGHT_SETTINGS_VERSION) {
FURI_LOG_E(
TAG,
"version(%d != %d) mismatch",
settings.version,
RGB_BACKLIGHT_SETTINGS_VERSION);
} else {
memcpy(&rgb_settings, &settings, settings_size);
}
} else {
FURI_LOG_E(TAG, "load failed, %s", storage_file_get_error_desc(file));
}
storage_file_close(file);
storage_file_free(file);
furi_record_close(RECORD_STORAGE);
rgb_settings.settings_is_loaded = true;
} }
void rgb_backlight_save_settings(void) { void rgb_backlight_save_settings(void) {
RGBBacklightSettings settings; saved_struct_save(
File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); RGB_BACKLIGHT_SETTINGS_PATH,
const size_t settings_size = sizeof(RGBBacklightSettings); &rgb_settings,
sizeof(rgb_settings),
RGB_BACKLIGHT_SETTINGS_MAGIC,
RGB_BACKLIGHT_SETTINGS_VERSION);
}
FURI_LOG_I(TAG, "saving settings to \"%s\"", RGB_BACKLIGHT_SETTINGS_PATH); void rgb_backlight_set_color(uint8_t index, RgbColor color) {
if(index >= COUNT_OF(rgb_settings.colors)) return;
if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
rgb_settings.colors[index] = color;
rgb_backlight_reconfigure(rgb_state.enabled);
}
memcpy(&settings, &rgb_settings, settings_size); RgbColor rgb_backlight_get_color(uint8_t index) {
if(index >= COUNT_OF(rgb_settings.colors)) return (RgbColor){0, 0, 0};
if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
return rgb_settings.colors[index];
}
bool fs_result = void rgb_backlight_set_rainbow_mode(RGBBacklightRainbowMode rainbow_mode) {
storage_file_open(file, RGB_BACKLIGHT_SETTINGS_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS); if(rainbow_mode >= RGBBacklightRainbowModeCount) return;
if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
rgb_settings.rainbow_mode = rainbow_mode;
rgb_backlight_reconfigure(rgb_state.enabled);
}
if(fs_result) { RGBBacklightRainbowMode rgb_backlight_get_rainbow_mode() {
uint16_t bytes_count = storage_file_write(file, &settings, settings_size); if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
return rgb_settings.rainbow_mode;
}
if(bytes_count != settings_size) { void rgb_backlight_set_rainbow_speed(uint8_t rainbow_speed) {
fs_result = false; if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
rgb_settings.rainbow_speed = rainbow_speed;
}
uint8_t rgb_backlight_get_rainbow_speed() {
if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
return rgb_settings.rainbow_speed;
}
void rgb_backlight_set_rainbow_interval(uint32_t rainbow_interval) {
if(rainbow_interval < 100) return;
if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
rgb_settings.rainbow_interval = rainbow_interval;
rgb_backlight_reconfigure(rgb_state.enabled);
}
uint32_t rgb_backlight_get_rainbow_interval() {
if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
return rgb_settings.rainbow_interval;
}
void rgb_backlight_set_rainbow_saturation(uint8_t rainbow_saturation) {
if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
rgb_settings.rainbow_saturation = rainbow_saturation;
rgb_backlight_reconfigure(rgb_state.enabled);
}
uint8_t rgb_backlight_get_rainbow_saturation() {
if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
return rgb_settings.rainbow_saturation;
}
void rgb_backlight_update(uint8_t brightness, bool tick) {
if(!rgb_state.enabled) return;
if(!rgb_state.settings_loaded) {
rgb_backlight_load_settings();
}
switch(rgb_settings.rainbow_mode) {
case RGBBacklightRainbowModeOff: {
if(!rgb_state.last_rainbow && rgb_state.last_brightness == brightness &&
memcmp(rgb_state.last_colors, rgb_settings.colors, sizeof(rgb_settings.colors)) == 0) {
return;
} }
rgb_state.last_rainbow = false;
memcpy(rgb_state.last_colors, rgb_settings.colors, sizeof(rgb_settings.colors));
float bright = brightness / 255.0f;
for(uint8_t i = 0; i < SK6805_get_led_count(); i++) {
SK6805_set_led_color(
i,
rgb_settings.colors[i].r * bright,
rgb_settings.colors[i].g * bright,
rgb_settings.colors[i].b * bright);
}
break;
} }
if(fs_result) { case RGBBacklightRainbowModeWave:
FURI_LOG_I(TAG, "save success"); case RGBBacklightRainbowModeSolid: {
} else { rgb_state.last_rainbow = true;
FURI_LOG_E(TAG, "save failed, %s", storage_file_get_error_desc(file));
if(tick && brightness) {
rgb_state.rainbow_hsv.h += rgb_settings.rainbow_speed;
} else {
if(rgb_state.last_brightness == brightness && rgb_state.last_rainbow) {
return;
}
rgb_state.rainbow_hsv.v = brightness;
}
HsvColor hsv = rgb_state.rainbow_hsv;
RgbColor rgb = hsv2rgb(hsv);
for(uint8_t i = 0; i < SK6805_get_led_count(); i++) {
if(i && rgb_settings.rainbow_mode == RGBBacklightRainbowModeWave) {
hsv.h += (50 * i);
rgb = hsv2rgb(hsv);
}
SK6805_set_led_color(i, rgb.r, rgb.g, rgb.b);
}
break;
} }
storage_file_close(file); default:
storage_file_free(file);
furi_record_close(RECORD_STORAGE);
}
RGBBacklightSettings* rgb_backlight_get_settings(void) {
if(!rgb_settings.settings_is_loaded) {
rgb_backlight_load_settings();
}
return &rgb_settings;
}
void rgb_backlight_set_color(uint8_t color_index) {
if(color_index > (rgb_backlight_get_color_count() - 1)) color_index = 0;
rgb_settings.display_color_index = color_index;
}
void rgb_backlight_update(uint8_t brightness) {
if(!rgb_settings.settings_is_loaded) {
rgb_backlight_load_settings();
}
static uint8_t last_color_index = 255;
static uint8_t last_brightness = 123;
if(last_brightness == brightness && last_color_index == rgb_settings.display_color_index)
return; return;
last_brightness = brightness;
last_color_index = rgb_settings.display_color_index;
for(uint8_t i = 0; i < SK6805_get_led_count(); i++) {
uint8_t r = colors[rgb_settings.display_color_index].red * (brightness / 255.0f);
uint8_t g = colors[rgb_settings.display_color_index].green * (brightness / 255.0f);
uint8_t b = colors[rgb_settings.display_color_index].blue * (brightness / 255.0f);
SK6805_set_led_color(i, r, g, b);
} }
rgb_state.last_brightness = brightness;
SK6805_update(); SK6805_update();
} }

View File

@@ -1,6 +1,7 @@
/* /*
RGB backlight FlipperZero driver RGB backlight FlipperZero driver
Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n) Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
Heavily modified by Willy-JL and Z3bro
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -18,69 +19,89 @@
#include <furi.h> #include <furi.h>
#include "SK6805.h" #include "SK6805.h"
#include <toolbox/colors.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef struct { typedef enum {
char* name; RGBBacklightRainbowModeOff,
uint8_t red; RGBBacklightRainbowModeWave,
uint8_t green; RGBBacklightRainbowModeSolid,
uint8_t blue; RGBBacklightRainbowModeCount,
} RGBBacklightColor; } RGBBacklightRainbowMode;
typedef struct {
uint8_t version;
uint8_t display_color_index;
bool settings_is_loaded;
} RGBBacklightSettings;
/** /**
* @brief Получить текущие настройки RGB-подсветки * @brief Reconfigure rgb backlight with new settings
* *
* @return Указатель на структуру настроек * @param enabled Whether the rgb backlight is enabled
*/ */
RGBBacklightSettings* rgb_backlight_get_settings(void); void rgb_backlight_reconfigure(bool enabled);
/** /**
* @brief Загрузить настройки подсветки с SD-карты * @brief Load backlight settings from SD card
*/ */
void rgb_backlight_load_settings(void); void rgb_backlight_load_settings();
/** /**
* @brief Сохранить текущие настройки RGB-подсветки * @brief Save Current RGB Lighting Settings
*/ */
void rgb_backlight_save_settings(void); void rgb_backlight_save_settings();
/** /**
* @brief Применить текущие настройки RGB-подсветки * @brief Change the color of the backlight
* *
* @param brightness Яркость свечения (0-255) * @param index What led to set the color to (0 - SK6805_LED_COUNT-1)
* @param color RGB color to use
*/ */
void rgb_backlight_update(uint8_t brightness); void rgb_backlight_set_color(uint8_t index, RgbColor color);
RgbColor rgb_backlight_get_color(uint8_t index);
/** /**
* @brief Установить цвет RGB-подсветки * @brief Change rainbow mode
* *
* @param color_index Индекс цвета (0 - rgb_backlight_get_color_count()) * @param rainbow_mode What mode to use (0 - RGBBacklightRainbowModeCount)
*/ */
void rgb_backlight_set_color(uint8_t color_index); void rgb_backlight_set_rainbow_mode(RGBBacklightRainbowMode rainbow_mode);
RGBBacklightRainbowMode rgb_backlight_get_rainbow_mode();
/** /**
* @brief Получить количество доступных цветов * @brief Change rainbow speed
* *
* @return Число доступных вариантов цвета * @param rainbow_speed What speed to use (0 - 255)
*/ */
uint8_t rgb_backlight_get_color_count(void); void rgb_backlight_set_rainbow_speed(uint8_t rainbow_speed);
uint8_t rgb_backlight_get_rainbow_speed();
/** /**
* @brief Получить текстовое название цвета * @brief Change rainbow interval
* *
* @param index Индекс из доступных вариантов цвета * @param rainbow_interval What interval to use
* @return Указатель на строку с названием цвета
*/ */
const char* rgb_backlight_get_color_text(uint8_t index); void rgb_backlight_set_rainbow_interval(uint32_t rainbow_interval);
uint32_t rgb_backlight_get_rainbow_interval();
/**
* @brief Change rainbow saturation
*
* @param rainbow_saturation What saturation to use (0 - 255)
*/
void rgb_backlight_set_rainbow_saturation(uint8_t rainbow_saturation);
uint8_t rgb_backlight_get_rainbow_saturation();
/**
* @brief Apply current RGB lighting settings
*
* @param brightness Backlight intensity (0-255)
* @param tick Whether this update was a tick (for rainbow)
*/
void rgb_backlight_update(uint8_t brightness, bool tick);
#ifdef __cplusplus #ifdef __cplusplus
} }

95
lib/toolbox/colors.c Normal file
View File

@@ -0,0 +1,95 @@
// https://stackoverflow.com/a/14733008
#include "colors.h"
inline int rgbcmp(const RgbColor* a, const RgbColor* b) {
return memcmp(a, b, sizeof(RgbColor));
}
inline int hsvcmp(const HsvColor* a, const HsvColor* b) {
return memcmp(a, b, sizeof(HsvColor));
}
RgbColor hsv2rgb(HsvColor hsv) {
RgbColor rgb;
uint8_t region, remainder, p, q, t;
if(hsv.s == 0) {
rgb.r = hsv.v;
rgb.g = hsv.v;
rgb.b = hsv.v;
return rgb;
}
region = hsv.h / 43;
remainder = (hsv.h - (region * 43)) * 6;
p = (hsv.v * (255 - hsv.s)) >> 8;
q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;
t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;
switch(region) {
case 0:
rgb.r = hsv.v;
rgb.g = t;
rgb.b = p;
break;
case 1:
rgb.r = q;
rgb.g = hsv.v;
rgb.b = p;
break;
case 2:
rgb.r = p;
rgb.g = hsv.v;
rgb.b = t;
break;
case 3:
rgb.r = p;
rgb.g = q;
rgb.b = hsv.v;
break;
case 4:
rgb.r = t;
rgb.g = p;
rgb.b = hsv.v;
break;
default:
rgb.r = hsv.v;
rgb.g = p;
rgb.b = q;
break;
}
return rgb;
}
HsvColor rgb2hsv(RgbColor rgb) {
HsvColor hsv;
uint8_t rgbMin, rgbMax;
rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);
hsv.v = rgbMax;
if(hsv.v == 0) {
hsv.h = 0;
hsv.s = 0;
return hsv;
}
hsv.s = 255 * ((long)rgbMax - (long)rgbMin) / hsv.v;
if(hsv.s == 0) {
hsv.h = 0;
return hsv;
}
if(rgbMax == rgb.r)
hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
else if(rgbMax == rgb.g)
hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
else
hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);
return hsv;
}

32
lib/toolbox/colors.h Normal file
View File

@@ -0,0 +1,32 @@
#pragma once
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct RgbColor {
uint8_t r;
uint8_t g;
uint8_t b;
} RgbColor;
typedef struct HsvColor {
uint8_t h;
uint8_t s;
uint8_t v;
} HsvColor;
int rgbcmp(const RgbColor* a, const RgbColor* b);
int hsvcmp(const HsvColor* a, const HsvColor* b);
RgbColor hsv2rgb(HsvColor hsv);
HsvColor rgb2hsv(RgbColor rgb);
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,6 @@
#include "xtreme.h" #include "xtreme.h"
#include <furi_hal.h> #include <furi_hal.h>
#include <rgb_backlight.h>
#include <flipper_format/flipper_format.h> #include <flipper_format/flipper_format.h>
#define TAG "XtremeSettings" #define TAG "XtremeSettings"
@@ -194,6 +195,8 @@ void XTREME_SETTINGS_LOAD() {
} }
flipper_format_free(file); flipper_format_free(file);
furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_STORAGE);
rgb_backlight_reconfigure(x->rgb_backlight);
} }
void XTREME_SETTINGS_SAVE() { void XTREME_SETTINGS_SAVE() {