diff --git a/ReadMe.md b/ReadMe.md
index b28b14c206..fdd4b3bf04 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -148,5 +148,12 @@ $ ./fbt resources icons dolphin_ext
+----
+## SAST Tools
+
+This helps us a lot, thanks for the free license for this project!
+
+[PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=github&utm_medium=organic&utm_campaign=open_source) - static analyzer for C, C++, C#, and Java code.
+
----
"What we do for ourselves dies with us. What we do for others and the world remains and is immortal.” ― Albert Pike
diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c
index 1cf7be854f..f579a2beb8 100644
--- a/applications/main/archive/helpers/archive_browser.c
+++ b/applications/main/archive/helpers/archive_browser.c
@@ -64,7 +64,13 @@ static void
archive_add_file_item(browser, is_folder, furi_string_get_cstr(item_path));
} else {
with_view_model(
- browser->view, ArchiveBrowserViewModel * model, { files_array_sort(model->files); model->list_loading = false; }, true);
+ browser->view,
+ ArchiveBrowserViewModel * model,
+ {
+ files_array_sort(model->files);
+ model->list_loading = false;
+ },
+ true);
}
}
@@ -139,7 +145,7 @@ void archive_update_focus(ArchiveBrowserView* browser, const char* target) {
archive_get_items(browser, furi_string_get_cstr(browser->path));
if(!archive_file_get_array_size(browser) && archive_is_home(browser)) {
- archive_switch_tab(browser, TAB_RIGHT);
+ archive_switch_tab(browser, TAB_LEFT);
} else {
with_view_model(
browser->view,
@@ -206,7 +212,7 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) {
false);
if((items_cnt == 0) && (archive_is_home(browser))) {
- archive_switch_tab(browser, TAB_RIGHT);
+ archive_switch_tab(browser, TAB_LEFT);
}
archive_update_offset(browser);
diff --git a/applications/main/archive/helpers/archive_browser.h b/applications/main/archive/helpers/archive_browser.h
index 09ffea1f9c..5b13e98da5 100644
--- a/applications/main/archive/helpers/archive_browser.h
+++ b/applications/main/archive/helpers/archive_browser.h
@@ -3,7 +3,7 @@
#include "../archive_i.h"
#include
-#define TAB_RIGHT InputKeyRight // Default tab switch direction
+#define TAB_LEFT InputKeyLeft // Default tab switch direction
#define TAB_DEFAULT ArchiveTabFavorites // Start tab
#define FILE_LIST_BUF_LEN 50
diff --git a/applications/main/bad_usb/scenes/bad_usb_scene_error.c b/applications/main/bad_usb/scenes/bad_usb_scene_error.c
index feff466fab..8a50a2df85 100644
--- a/applications/main/bad_usb/scenes/bad_usb_scene_error.c
+++ b/applications/main/bad_usb/scenes/bad_usb_scene_error.c
@@ -34,7 +34,7 @@ void bad_usb_scene_error_on_enter(void* context) {
app->widget, GuiButtonTypeLeft, "Back", bad_usb_scene_error_event_callback, app);
} else if(app->error == BadUsbAppErrorCloseRpc) {
widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
widget_add_string_multiline_element(
app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!");
widget_add_string_multiline_element(
@@ -45,8 +45,7 @@ void bad_usb_scene_error_on_enter(void* context) {
AlignTop,
FontSecondary,
"Disconnect from\nPC or phone to\nuse this function.");
- }
- else {
+ } else {
widget_add_string_multiline_element(
app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "I am not\na whore!");
widget_add_string_multiline_element(
diff --git a/applications/main/bad_usb/views/bad_usb_view.c b/applications/main/bad_usb/views/bad_usb_view.c
index 26b6ed27d2..b700bc0236 100644
--- a/applications/main/bad_usb/views/bad_usb_view.c
+++ b/applications/main/bad_usb/views/bad_usb_view.c
@@ -50,10 +50,9 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
if((model->state.state == BadUsbStateIdle) || (model->state.state == BadUsbStateDone) ||
(model->state.state == BadUsbStateNotConnected)) {
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
elements_button_center(canvas, "Start");
- }
- else {
+ } else {
elements_button_center(canvas, "Cum");
}
} else if((model->state.state == BadUsbStateRunning) || (model->state.state == BadUsbStateDelay)) {
@@ -70,21 +69,19 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
if(model->state.state == BadUsbStateNotConnected) {
canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18);
canvas_set_font(canvas, FontPrimary);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Connect to");
canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "a device");
- }
- else {
+ } else {
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Plug me");
canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "in, Daddy");
}
} else if(model->state.state == BadUsbStateWillRun) {
canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18);
canvas_set_font(canvas, FontPrimary);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will run");
- }
- else {
+ } else {
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will cum");
}
canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "on connect");
diff --git a/applications/main/ibutton/scenes/ibutton_scene_delete_success.c b/applications/main/ibutton/scenes/ibutton_scene_delete_success.c
index 0af4b19a61..f543ceeb2d 100644
--- a/applications/main/ibutton/scenes/ibutton_scene_delete_success.c
+++ b/applications/main/ibutton/scenes/ibutton_scene_delete_success.c
@@ -12,10 +12,9 @@ void ibutton_scene_delete_success_on_enter(void* context) {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
}
popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
diff --git a/applications/main/ibutton/scenes/ibutton_scene_read.c b/applications/main/ibutton/scenes/ibutton_scene_read.c
index b574b643bd..4dbbed3521 100644
--- a/applications/main/ibutton/scenes/ibutton_scene_read.c
+++ b/applications/main/ibutton/scenes/ibutton_scene_read.c
@@ -17,10 +17,9 @@ void ibutton_scene_read_on_enter(void* context) {
popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom);
popup_set_text(popup, "Waiting\nfor key ...", 95, 30, AlignCenter, AlignTop);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59);
}
diff --git a/applications/main/ibutton/scenes/ibutton_scene_save_success.c b/applications/main/ibutton/scenes/ibutton_scene_save_success.c
index ad673fabab..02c6abe2ba 100644
--- a/applications/main/ibutton/scenes/ibutton_scene_save_success.c
+++ b/applications/main/ibutton/scenes/ibutton_scene_save_success.c
@@ -12,10 +12,9 @@ void ibutton_scene_save_success_on_enter(void* context) {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
}
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
diff --git a/applications/main/ibutton/scenes/ibutton_scene_write_success.c b/applications/main/ibutton/scenes/ibutton_scene_write_success.c
index 291140506a..3d461018cb 100644
--- a/applications/main/ibutton/scenes/ibutton_scene_write_success.c
+++ b/applications/main/ibutton/scenes/ibutton_scene_write_success.c
@@ -13,10 +13,9 @@ void ibutton_scene_write_success_on_enter(void* context) {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 12, &I_iButtonDolphinVerySuccess_108x52_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 12, &I_iButtonDolphinVerySuccess_108x52);
}
popup_set_text(popup, "Successfully written!", 40, 12, AlignLeft, AlignBottom);
diff --git a/applications/main/infrared/scenes/infrared_scene_edit_rename_done.c b/applications/main/infrared/scenes/infrared_scene_edit_rename_done.c
index 5142a181fb..056c97db6a 100644
--- a/applications/main/infrared/scenes/infrared_scene_edit_rename_done.c
+++ b/applications/main/infrared/scenes/infrared_scene_edit_rename_done.c
@@ -7,10 +7,9 @@ void infrared_scene_edit_rename_done_on_enter(void* context) {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
}
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
diff --git a/applications/main/infrared/scenes/infrared_scene_learn_done.c b/applications/main/infrared/scenes/infrared_scene_learn_done.c
index ace9bb2503..a66445efe0 100644
--- a/applications/main/infrared/scenes/infrared_scene_learn_done.c
+++ b/applications/main/infrared/scenes/infrared_scene_learn_done.c
@@ -7,16 +7,14 @@ void infrared_scene_learn_done_on_enter(void* context) {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw);
- if (infrared->app_state.is_learning_new_remote) {
+ if(infrared->app_state.is_learning_new_remote) {
popup_set_header(popup, "New remote\ncreated!", 0, 0, AlignLeft, AlignTop);
- }
- else {
+ } else {
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
}
- }
- else {
+ } else {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
}
diff --git a/applications/main/infrared/scenes/infrared_scene_learn_success.c b/applications/main/infrared/scenes/infrared_scene_learn_success.c
index ed9d8ce6ee..82ced17c2e 100644
--- a/applications/main/infrared/scenes/infrared_scene_learn_success.c
+++ b/applications/main/infrared/scenes/infrared_scene_learn_success.c
@@ -50,10 +50,9 @@ void infrared_scene_learn_success_on_enter(void* context) {
dialog_ex_set_left_button_text(dialog_ex, "Retry");
dialog_ex_set_right_button_text(dialog_ex, "Save");
dialog_ex_set_center_button_text(dialog_ex, "Send");
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63_sfw);
- }
- else {
+ } else {
dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63);
}
dialog_ex_set_result_callback(dialog_ex, infrared_scene_learn_success_dialog_result_callback);
diff --git a/applications/main/infrared/scenes/infrared_scene_start.c b/applications/main/infrared/scenes/infrared_scene_start.c
index 79826ede9c..4d13d6e0ee 100644
--- a/applications/main/infrared/scenes/infrared_scene_start.c
+++ b/applications/main/infrared/scenes/infrared_scene_start.c
@@ -71,7 +71,6 @@ bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) {
} else if(
submenu_index == SubmenuIndexLearnNewRemote ||
submenu_index == SubmenuIndexLearnNewRemoteRaw) {
-
// enable automatic signal decoding if "Learn New Remote"
// disable automatic signal decoding if "Learn New Remote (RAW)"
infrared_worker_rx_enable_signal_decoding(
diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c b/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c
index a95eed7dbf..565655080c 100644
--- a/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c
+++ b/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c
@@ -45,10 +45,9 @@ static void lfrfid_clear_t5577_password_and_config_to_EM(LfRfid* app) {
writer_initialize(t55xxtiming);
popup_set_header(popup, "Removing\npassword", 90, 36, AlignCenter, AlignCenter);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
}
popup_set_text(popup, curr_buf, 90, 56, AlignCenter, AlignCenter);
@@ -81,10 +80,9 @@ void lfrfid_scene_clear_t5577_on_enter(void* context) {
notification_message(app->notifications, &sequence_success);
popup_set_header(popup, "Done!", 94, 10, AlignCenter, AlignTop);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 7, &I_RFIDDolphinSuccess_108x57_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 7, &I_RFIDDolphinSuccess_108x57);
}
popup_set_context(popup, app);
diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_delete_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_delete_success.c
index 9b49614b27..94e5a684ef 100644
--- a/applications/main/lfrfid/scenes/lfrfid_scene_delete_success.c
+++ b/applications/main/lfrfid/scenes/lfrfid_scene_delete_success.c
@@ -7,10 +7,9 @@ void lfrfid_scene_delete_success_on_enter(void* context) {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
}
popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c
index a0e9b86094..4bc3ceb223 100644
--- a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c
+++ b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c
@@ -19,10 +19,9 @@ void lfrfid_scene_emulate_on_enter(void* context) {
AlignCenter,
AlignTop);
}
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
}
diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c
index efa319c1e1..b1130d1915 100644
--- a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c
+++ b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c
@@ -20,7 +20,7 @@ void lfrfid_scene_extra_actions_on_enter(void* context) {
submenu_add_item(
submenu,
- "Read ASK (FDX,Regular)",
+ "Read ASK (Animal, FDX)",
SubmenuIndexASK,
lfrfid_scene_extra_actions_submenu_callback,
app);
diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c
index 1d6a63f910..b8da7e04c7 100644
--- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c
+++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c
@@ -35,10 +35,9 @@ void lfrfid_scene_raw_read_on_enter(void* context) {
LfRfidReadRawState* state = malloc(sizeof(LfRfidReadRawState));
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawRead, (uint32_t)state);
state->string_file_name = furi_string_alloc();
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
}
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c
index a7161e069e..4b0f52d499 100644
--- a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c
+++ b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c
@@ -9,10 +9,9 @@ void lfrfid_scene_rpc_on_enter(void* context) {
popup_set_header(popup, "LF RFID", 89, 42, AlignCenter, AlignBottom);
popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
}
diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c
index 4646fde491..5521bb0f75 100644
--- a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c
+++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c
@@ -9,10 +9,9 @@ void lfrfid_scene_save_success_on_enter(void* context) {
// Clear state of data enter scene
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveData, 0);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
}
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_write.c b/applications/main/lfrfid/scenes/lfrfid_scene_write.c
index f4bd8f45a5..549e2f9a30 100644
--- a/applications/main/lfrfid/scenes/lfrfid_scene_write.c
+++ b/applications/main/lfrfid/scenes/lfrfid_scene_write.c
@@ -36,10 +36,9 @@ void lfrfid_scene_write_on_enter(void* context) {
AlignCenter,
AlignTop);
}
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
}
diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c
index 6ba1388792..27552f4170 100644
--- a/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c
+++ b/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c
@@ -8,10 +8,9 @@ void lfrfid_scene_write_success_on_enter(void* context) {
DESKTOP_SETTINGS_LOAD(settings);
popup_set_header(popup, "Successfully\nwritten!", 94, 3, AlignCenter, AlignTop);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 6, &I_RFIDDolphinSuccess_108x57_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 6, &I_RFIDDolphinSuccess_108x57);
}
popup_set_context(popup, app);
diff --git a/applications/main/nfc/scenes/nfc_scene_delete_success.c b/applications/main/nfc/scenes/nfc_scene_delete_success.c
index faa7fd7bbe..5da15f91f8 100644
--- a/applications/main/nfc/scenes/nfc_scene_delete_success.c
+++ b/applications/main/nfc/scenes/nfc_scene_delete_success.c
@@ -13,10 +13,9 @@ void nfc_scene_delete_success_on_enter(void* context) {
// Setup view
Popup* popup = nfc->popup;
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
}
popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
diff --git a/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c b/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c
index e6fc60d86b..d9d3db9da4 100644
--- a/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c
+++ b/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c
@@ -1,4 +1,5 @@
#include "../nfc_i.h"
+#include "../../../settings/desktop_settings/desktop_settings_app.h"
#define NFC_SCENE_EMULATE_NFCV_LOG_SIZE_MAX (100)
@@ -37,7 +38,15 @@ static void nfc_scene_emulate_nfcv_widget_config(Nfc* nfc, bool data_received) {
FuriString* info_str;
info_str = furi_string_alloc();
- widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61);
+ DesktopSettings* settings = malloc(sizeof(DesktopSettings));
+ DESKTOP_SETTINGS_LOAD(settings);
+
+ if(settings->sfw_mode) {
+ widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61_sfw);
+ } else {
+ widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61);
+ }
+
widget_add_string_element(
widget, 89, 32, AlignCenter, AlignTop, FontPrimary, "Emulating NfcV");
if(strcmp(nfc->dev->dev_name, "")) {
@@ -55,6 +64,7 @@ static void nfc_scene_emulate_nfcv_widget_config(Nfc* nfc, bool data_received) {
widget_add_button_element(
widget, GuiButtonTypeCenter, "Log", nfc_scene_emulate_nfcv_widget_callback, nfc);
}
+ free(settings);
}
void nfc_scene_emulate_nfcv_on_enter(void* context) {
diff --git a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c
index eec43c92c9..e935ad18cf 100644
--- a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c
+++ b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c
@@ -40,10 +40,9 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw);
- }
- else {
+ } else {
widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61);
}
widget_add_string_element(widget, 57, 13, AlignLeft, AlignTop, FontPrimary, "Emulating UID");
diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c
index 0fa624ad98..3a0b597e9c 100644
--- a/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c
+++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c
@@ -26,10 +26,9 @@ void nfc_scene_mf_classic_emulate_on_enter(void* context) {
} else {
nfc_text_store_set(nfc, "MIFARE\nClassic");
}
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61);
}
popup_set_text(popup, nfc->text_store, 90, 28, AlignCenter, AlignTop);
diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c
index a76a758b68..9bd354c854 100644
--- a/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c
+++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c
@@ -16,10 +16,9 @@ void nfc_scene_mf_classic_update_success_on_enter(void* context) {
notification_message(nfc->notifications, &sequence_success);
Popup* popup = nfc->popup;
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
}
popup_set_header(popup, "Updated!", 11, 20, AlignLeft, AlignBottom);
diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c
index e425d8c3a9..25656c072a 100644
--- a/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c
+++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c
@@ -16,10 +16,9 @@ void nfc_scene_mf_classic_write_success_on_enter(void* context) {
notification_message(nfc->notifications, &sequence_success);
Popup* popup = nfc->popup;
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
}
popup_set_header(popup, "Successfully\nwritten", 13, 22, AlignLeft, AlignBottom);
diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c
index 4dc35c68da..7e8a899a46 100644
--- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c
+++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c
@@ -66,7 +66,15 @@ void nfc_scene_mf_ultralight_emulate_widget_config(Nfc* nfc, bool auth_attempted
FuriString* info_str;
info_str = furi_string_alloc();
- widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61);
+ DesktopSettings* settings = malloc(sizeof(DesktopSettings));
+ DESKTOP_SETTINGS_LOAD(settings);
+
+ if(settings->sfw_mode) {
+ widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw);
+ } else {
+ widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61);
+ }
+
if(strcmp(nfc->dev->dev_name, "")) {
furi_string_printf(info_str, "Emulating\n%s", nfc->dev->dev_name);
} else {
@@ -84,6 +92,7 @@ void nfc_scene_mf_ultralight_emulate_widget_config(Nfc* nfc, bool auth_attempted
nfc_scene_mf_ultralight_emulate_widget_callback,
nfc);
}
+ free(settings);
}
void nfc_scene_mf_ultralight_emulate_on_enter(void* context) {
@@ -114,10 +123,9 @@ void nfc_scene_mf_ultralight_emulate_on_enter(void* context) {
} else {
nfc_text_store_set(nfc, "MIFARE\nNTAG");
}
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61);
}
popup_set_text(popup, nfc->text_store, 90, 28, AlignCenter, AlignTop);
diff --git a/applications/main/nfc/scenes/nfc_scene_passport_auth.c b/applications/main/nfc/scenes/nfc_scene_passport_auth.c
index c90c38233f..7bb13e1a11 100644
--- a/applications/main/nfc/scenes/nfc_scene_passport_auth.c
+++ b/applications/main/nfc/scenes/nfc_scene_passport_auth.c
@@ -107,7 +107,7 @@ void nfc_scene_passport_auth_on_enter(void* context) {
item = variable_item_list_add(variable_item_list, "Document Nr.", 1, NULL, NULL);
strncpy(temp_str, mrtd_data->auth.doc_number, temp_str_size);
- temp_str[temp_str_size -1] = '\x00';
+ temp_str[temp_str_size - 1] = '\x00';
if(strlen(temp_str) > 8) {
temp_str[8] = '.';
temp_str[9] = '.';
diff --git a/applications/main/nfc/scenes/nfc_scene_passport_date.c b/applications/main/nfc/scenes/nfc_scene_passport_date.c
index 6655bdd59d..4594721df4 100644
--- a/applications/main/nfc/scenes/nfc_scene_passport_date.c
+++ b/applications/main/nfc/scenes/nfc_scene_passport_date.c
@@ -31,7 +31,6 @@ void nfc_scene_passport_date_on_enter(void* context) {
date_value.month = 0;
date_value.day = 0;
-
switch(date_type) {
case NFC_PASSPORT_DATE_BIRTH:
text_input_set_header_text(text_input, "Birth Date");
diff --git a/applications/main/nfc/scenes/nfc_scene_restore_original.c b/applications/main/nfc/scenes/nfc_scene_restore_original.c
index 3709008fdc..b87c2f7909 100644
--- a/applications/main/nfc/scenes/nfc_scene_restore_original.c
+++ b/applications/main/nfc/scenes/nfc_scene_restore_original.c
@@ -13,10 +13,9 @@ void nfc_scene_restore_original_on_enter(void* context) {
// Setup view
Popup* popup = nfc->popup;
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
}
popup_set_header(popup, "Original file\nrestored", 13, 22, AlignLeft, AlignBottom);
diff --git a/applications/main/nfc/scenes/nfc_scene_rpc.c b/applications/main/nfc/scenes/nfc_scene_rpc.c
index edf63faf46..9bd55577d9 100644
--- a/applications/main/nfc/scenes/nfc_scene_rpc.c
+++ b/applications/main/nfc/scenes/nfc_scene_rpc.c
@@ -10,10 +10,9 @@ void nfc_scene_rpc_on_enter(void* context) {
popup_set_header(popup, "NFC", 89, 42, AlignCenter, AlignBottom);
popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 12, &I_NFC_dolphin_emulation_47x61_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 12, &I_NFC_dolphin_emulation_47x61);
}
diff --git a/applications/main/nfc/scenes/nfc_scene_save_success.c b/applications/main/nfc/scenes/nfc_scene_save_success.c
index 67dd4a6dd5..58b7d1bf41 100644
--- a/applications/main/nfc/scenes/nfc_scene_save_success.c
+++ b/applications/main/nfc/scenes/nfc_scene_save_success.c
@@ -13,10 +13,9 @@ void nfc_scene_save_success_on_enter(void* context) {
// Setup view
Popup* popup = nfc->popup;
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
}
popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom);
diff --git a/applications/main/sub_playlist/playlist.c b/applications/main/sub_playlist/playlist.c
index b11dae31ea..7bf433d09a 100644
--- a/applications/main/sub_playlist/playlist.c
+++ b/applications/main/sub_playlist/playlist.c
@@ -683,7 +683,8 @@ int32_t playlist_app(void* p) {
dialog_file_browser_set_basic_options(&browser_options, PLAYLIST_EXT, &I_sub1_10px);
browser_options.base_path = PLAYLIST_FOLDER;
- bool res = dialog_file_browser_show(dialogs, app->file_path, app->file_path, &browser_options);
+ bool res =
+ dialog_file_browser_show(dialogs, app->file_path, app->file_path, &browser_options);
furi_record_close(RECORD_DIALOGS);
// check if a file was selected
diff --git a/applications/main/subghz/scenes/subghz_scene_delete_success.c b/applications/main/subghz/scenes/subghz_scene_delete_success.c
index e10d28a218..e30eda7853 100644
--- a/applications/main/subghz/scenes/subghz_scene_delete_success.c
+++ b/applications/main/subghz/scenes/subghz_scene_delete_success.c
@@ -15,10 +15,9 @@ void subghz_scene_delete_success_on_enter(void* context) {
// Setup view
Popup* popup = subghz->popup;
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
}
popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c
index e78e7fa716..12a5787ade 100644
--- a/applications/main/subghz/scenes/subghz_scene_rpc.c
+++ b/applications/main/subghz/scenes/subghz_scene_rpc.c
@@ -16,10 +16,9 @@ void subghz_scene_rpc_on_enter(void* context) {
popup_set_header(popup, "Sub-GHz", 89, 42, AlignCenter, AlignBottom);
popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
}
diff --git a/applications/main/subghz/scenes/subghz_scene_save_success.c b/applications/main/subghz/scenes/subghz_scene_save_success.c
index 4f36a09381..76e30d088a 100644
--- a/applications/main/subghz/scenes/subghz_scene_save_success.c
+++ b/applications/main/subghz/scenes/subghz_scene_save_success.c
@@ -14,10 +14,9 @@ void subghz_scene_save_success_on_enter(void* context) {
// Setup view
Popup* popup = subghz->popup;
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
}
popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom);
diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c
index 684733c2b5..ed16480835 100644
--- a/applications/main/subghz/subghz_cli.c
+++ b/applications/main/subghz/subghz_cli.c
@@ -387,7 +387,7 @@ void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) {
}
printf(
- "Listening at \033[0;33m%s\033[0m.\r\n\r\nPress CTRL+C to stop\r\n\r\n",
+ "Listening at %s.\r\n\r\nPress CTRL+C to stop\r\n\r\n",
furi_string_get_cstr(file_name));
LevelDuration level_duration;
@@ -521,7 +521,8 @@ static void subghz_cli_command_encrypt_raw(Cli* cli, FuriString* args) {
furi_string_free(source);
}
-static void subghz_cli_command_chat(Cli* cli, FuriString* args) {
+static void subghz_cli_command_chat(Cli* cli, FuriString* args, void* context) {
+ UNUSED(context);
uint32_t frequency = 433920000;
if(furi_string_size(args)) {
@@ -577,7 +578,7 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args) {
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
- furi_string_printf(name, "\033[0;33m%s\033[0m: ", furi_hal_version_get_name_ptr());
+ furi_string_printf(name, "%s: ", furi_hal_version_get_name_ptr());
furi_string_set(input, name);
printf("%s", furi_string_get_cstr(input));
fflush(stdout);
@@ -658,18 +659,14 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args) {
notification_message(notification, &sequence_single_vibro);
break;
case SubGhzChatEventUserEntrance:
- furi_string_printf(
- sysmsg,
- "\033[0;34m%s joined chat.\033[0m\r\n",
- furi_hal_version_get_name_ptr());
+ furi_string_printf(sysmsg, "%s joined chat.\r\n", furi_hal_version_get_name_ptr());
subghz_chat_worker_write(
subghz_chat,
(uint8_t*)furi_string_get_cstr(sysmsg),
strlen(furi_string_get_cstr(sysmsg)));
break;
case SubGhzChatEventUserExit:
- furi_string_printf(
- sysmsg, "\033[0;31m%s left chat.\033[0m\r\n", furi_hal_version_get_name_ptr());
+ furi_string_printf(sysmsg, "%s left chat.\r\n", furi_hal_version_get_name_ptr());
subghz_chat_worker_write(
subghz_chat,
(uint8_t*)furi_string_get_cstr(sysmsg),
@@ -714,7 +711,7 @@ static void subghz_cli_command(Cli* cli, FuriString* args, void* context) {
}
if(furi_string_cmp_str(cmd, "chat") == 0) {
- subghz_cli_command_chat(cli, args);
+ subghz_cli_command_chat(cli, args, NULL);
break;
}
@@ -766,9 +763,11 @@ void subghz_on_system_start() {
Cli* cli = furi_record_open(RECORD_CLI);
cli_add_command(cli, "subghz", CliCommandFlagDefault, subghz_cli_command, NULL);
+ // psst RM... i know you dont care much about errors, but if you ever see this... incompatible pointer type :3
+ cli_add_command(cli, "chat", CliCommandFlagDefault, subghz_cli_command_chat, NULL);
furi_record_close(RECORD_CLI);
#else
UNUSED(subghz_cli_command);
#endif
-}
+}
\ No newline at end of file
diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c
index 77f4d20747..637ca86328 100644
--- a/applications/main/subghz/views/receiver.c
+++ b/applications/main/subghz/views/receiver.c
@@ -234,10 +234,9 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
if(model->history_item == 0) {
if(model->mode == SubGhzViewReceiverModeLive) {
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52_sfw);
- }
- else {
+ } else {
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52);
}
canvas_set_font(canvas, FontPrimary);
@@ -245,10 +244,9 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
canvas_draw_line(canvas, 46, 51, 125, 51);
canvas_set_font(canvas, FontSecondary);
} else {
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52_sfw);
- }
- else {
+ } else {
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52);
}
canvas_set_font(canvas, FontPrimary);
diff --git a/applications/main/u2f/scenes/u2f_scene_error.c b/applications/main/u2f/scenes/u2f_scene_error.c
index 20b7be9523..a4cfd38191 100644
--- a/applications/main/u2f/scenes/u2f_scene_error.c
+++ b/applications/main/u2f/scenes/u2f_scene_error.c
@@ -29,7 +29,7 @@ void u2f_scene_error_on_enter(void* context) {
app->widget, GuiButtonTypeLeft, "Back", u2f_scene_error_event_callback, app);
} else if(app->error == U2fAppErrorCloseRpc) {
widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
widget_add_string_multiline_element(
app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!");
widget_add_string_multiline_element(
@@ -40,8 +40,7 @@ void u2f_scene_error_on_enter(void* context) {
AlignTop,
FontSecondary,
"Disconnect from\nPC or phone to\nuse this function.");
- }
- else {
+ } else {
widget_add_string_multiline_element(
app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "I am not\na whore!");
widget_add_string_multiline_element(
diff --git a/applications/main/u2f/views/u2f_view.c b/applications/main/u2f/views/u2f_view.c
index af55ea7cec..77b6a288e2 100644
--- a/applications/main/u2f/views/u2f_view.c
+++ b/applications/main/u2f/views/u2f_view.c
@@ -18,70 +18,66 @@ static void u2f_view_draw_callback(Canvas* canvas, void* _model) {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
-
canvas_draw_icon(canvas, 8, 14, &I_Drive_112x35);
canvas_set_font(canvas, FontSecondary);
- if (model->display_msg == U2fMsgNotConnected) {
- if (settings->sfw_mode) {
+ if(model->display_msg == U2fMsgNotConnected) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 22, 15, &I_Connect_me_62x31_sfw);
- canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connect to a device");
- }
- else {
+ canvas_draw_str_aligned(
+ canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connect to a device");
+ } else {
canvas_draw_icon(canvas, 22, 15, &I_Connect_me_62x31);
- canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Plug me in d-daddy");
+ canvas_draw_str_aligned(
+ canvas, 128 / 2, 3, AlignCenter, AlignTop, "Plug me in d-daddy");
}
- }
- else if (model->display_msg == U2fMsgIdle) {
- if (settings->sfw_mode) {
+ } else if(model->display_msg == U2fMsgIdle) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 22, 15, &I_Connected_62x31_sfw);
canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connected!");
- }
- else {
+ } else {
canvas_draw_icon(canvas, 22, 15, &I_Connected_62x31);
canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connected!");
}
- }
- else if (model->display_msg == U2fMsgRegister) {
- if (settings->sfw_mode) {
+ } else if(model->display_msg == U2fMsgRegister) {
+ if(settings->sfw_mode) {
elements_button_center(canvas, "OK");
canvas_draw_icon(canvas, 22, 15, &I_Auth_62x31_sfw);
- canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press OK to register");
- }
- else {
+ canvas_draw_str_aligned(
+ canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press OK to register");
+ } else {
elements_button_center(canvas, "CUM");
canvas_draw_icon(canvas, 22, 15, &I_Auth_62x31);
- canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press CUM to register");
+ canvas_draw_str_aligned(
+ canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press CUM to register");
}
- }
- else if (model->display_msg == U2fMsgAuth) {
- if (settings->sfw_mode) {
+ } else if(model->display_msg == U2fMsgAuth) {
+ if(settings->sfw_mode) {
elements_button_center(canvas, "OK");
canvas_draw_icon(canvas, 22, 15, &I_Auth_62x31_sfw);
- canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press OK to authenticate");
- }
- else {
+ canvas_draw_str_aligned(
+ canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press OK to authenticate");
+ } else {
elements_button_center(canvas, "CUM");
canvas_draw_icon(canvas, 22, 15, &I_Auth_62x31);
- canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press CUM to authenticate");
+ canvas_draw_str_aligned(
+ canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press CUM to authenticate");
}
- }
- else if (model->display_msg == U2fMsgSuccess) {
- if (settings->sfw_mode) {
+ } else if(model->display_msg == U2fMsgSuccess) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 22, 15, &I_Connected_62x31_sfw);
- canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Authentication successful!");
- }
- else {
+ canvas_draw_str_aligned(
+ canvas, 128 / 2, 3, AlignCenter, AlignTop, "Authentication successful!");
+ } else {
canvas_draw_icon(canvas, 22, 15, &I_Connected_62x31);
canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Cum released~");
}
- }
- else if (model->display_msg == U2fMsgError) {
- if (settings->sfw_mode) {
+ } else if(model->display_msg == U2fMsgError) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 22, 15, &I_Error_62x31_sfw);
- canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Certificate error");
- }
- else {
+ canvas_draw_str_aligned(
+ canvas, 128 / 2, 3, AlignCenter, AlignTop, "Certificate error");
+ } else {
canvas_draw_icon(canvas, 22, 15, &I_Error_62x31);
canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Unable to cum");
}
@@ -94,10 +90,10 @@ static bool u2f_view_input_callback(InputEvent* event, void* context) {
U2fView* u2f = context;
bool consumed = false;
- if (event->type == InputTypeShort) {
- if (event->key == InputKeyOk) {
+ if(event->type == InputTypeShort) {
+ if(event->key == InputKeyOk) {
consumed = true;
- if (u2f->callback != NULL) u2f->callback(InputTypeShort, u2f->context);
+ if(u2f->callback != NULL) u2f->callback(InputTypeShort, u2f->context);
}
}
diff --git a/applications/plugins/arkanoid/arkanoid_game.c b/applications/plugins/arkanoid/arkanoid_game.c
index 2e859afe86..af9976c98f 100644
--- a/applications/plugins/arkanoid/arkanoid_game.c
+++ b/applications/plugins/arkanoid/arkanoid_game.c
@@ -277,7 +277,7 @@ void reset_level(Canvas* canvas, ArkanoidState* arkanoid_state) {
arkanoid_state->brickCount = 0;
arkanoid_state->ball_state.released = false;
arkanoid_state->gameStarted = false;
-
+
// Reset all brick hit states
for(unsigned int row = 0; row < arkanoid_state->ROWS; row++) {
for(unsigned int column = 0; column < arkanoid_state->COLUMNS; column++) {
diff --git a/applications/plugins/asteroids/app.c b/applications/plugins/asteroids/app.c
index 1a3945fd77..07be54c3d2 100644
--- a/applications/plugins/asteroids/app.c
+++ b/applications/plugins/asteroids/app.c
@@ -32,42 +32,42 @@
/* ============================ Data structures ============================= */
typedef struct Ship {
- float x, /* Ship x position. */
- y, /* Ship y position. */
- vx, /* x velocity. */
- vy, /* y velocity. */
- rot; /* Current rotation. 2*PI full rotation. */
+ float x, /* Ship x position. */
+ y, /* Ship y position. */
+ vx, /* x velocity. */
+ vy, /* y velocity. */
+ rot; /* Current rotation. 2*PI full rotation. */
} Ship;
typedef struct Bullet {
- float x, y, vx, vy; /* Fields like in ship. */
- uint32_t ttl; /* Time to live, in ticks. */
+ float x, y, vx, vy; /* Fields like in ship. */
+ uint32_t ttl; /* Time to live, in ticks. */
} Bullet;
typedef struct Asteroid {
- float x, y, vx, vy, rot, /* Fields like ship. */
- rot_speed, /* Angular velocity (rot speed and sense). */
- size; /* Asteroid size. */
- uint8_t shape_seed; /* Seed to give random shape. */
+ float x, y, vx, vy, rot, /* Fields like ship. */
+ rot_speed, /* Angular velocity (rot speed and sense). */
+ size; /* Asteroid size. */
+ uint8_t shape_seed; /* Seed to give random shape. */
} Asteroid;
-#define MAXBUL 10 /* Max bullets on the screen. */
-#define MAXAST 32 /* Max asteroids on the screen. */
+#define MAXBUL 10 /* Max bullets on the screen. */
+#define MAXAST 32 /* Max asteroids on the screen. */
#define SHIP_HIT_ANIMATION_LEN 15
typedef struct AsteroidsApp {
/* GUI */
- Gui *gui;
- ViewPort *view_port; /* We just use a raw viewport and we render
+ Gui* gui;
+ ViewPort* view_port; /* We just use a raw viewport and we render
everything into the low level canvas. */
- FuriMessageQueue *event_queue; /* Key press events go here. */
+ FuriMessageQueue* event_queue; /* Key press events go here. */
/* Game state. */
- int running; /* Once false exists the app. */
- bool gameover; /* Game over status. */
- uint32_t ticks; /* Game ticks. Increments at each refresh. */
- uint32_t score; /* Game score. */
- uint32_t lives; /* Number of lives in the current game. */
- uint32_t ship_hit; /* When non zero, the ship was hit by an asteroid
+ int running; /* Once false exists the app. */
+ bool gameover; /* Game over status. */
+ uint32_t ticks; /* Game ticks. Increments at each refresh. */
+ uint32_t score; /* Game score. */
+ uint32_t lives; /* Number of lives in the current game. */
+ uint32_t ship_hit; /* When non zero, the ship was hit by an asteroid
and we need to show an animation as long as
its value is non-zero (and decrease it's value
at each tick of animation). */
@@ -76,26 +76,26 @@ typedef struct AsteroidsApp {
struct Ship ship;
/* Bullets state. */
- struct Bullet bullets[MAXBUL]; /* Each bullet state. */
- int bullets_num; /* Active bullets. */
- uint32_t last_bullet_tick; /* Tick the last bullet was fired. */
+ struct Bullet bullets[MAXBUL]; /* Each bullet state. */
+ int bullets_num; /* Active bullets. */
+ uint32_t last_bullet_tick; /* Tick the last bullet was fired. */
/* Asteroids state. */
- Asteroid asteroids[MAXAST]; /* Each asteroid state. */
- int asteroids_num; /* Active asteroids. */
+ Asteroid asteroids[MAXAST]; /* Each asteroid state. */
+ int asteroids_num; /* Active asteroids. */
uint32_t pressed[InputKeyMAX]; /* pressed[id] is true if pressed.
Each array item contains the time
in milliseconds the key was pressed. */
- bool fire; /* Short press detected: fire a bullet. */
+ bool fire; /* Short press detected: fire a bullet. */
} AsteroidsApp;
/* ============================== Prototypes ================================ */
// Only functions called before their definition are here.
-void restart_game_after_gameover(AsteroidsApp *app);
-uint32_t key_pressed_time(AsteroidsApp *app, InputKey key);
+void restart_game_after_gameover(AsteroidsApp* app);
+uint32_t key_pressed_time(AsteroidsApp* app, InputKey key);
/* ============================ 2D drawing ================================== */
@@ -110,29 +110,21 @@ typedef struct Poly {
} Poly;
/* Define the polygons we use. */
-Poly ShipPoly = {
- {-3, 0, 3},
- {-3, 6, -3},
- 3
-};
-
-Poly ShipFirePoly = {
- {-1.5, 0, 1.5},
- {-3, -6, -3},
- 3
-};
+Poly ShipPoly = {{-3, 0, 3}, {-3, 6, -3}, 3};
+
+Poly ShipFirePoly = {{-1.5, 0, 1.5}, {-3, -6, -3}, 3};
/* Rotate the point of the polygon 'poly' and store the new rotated
* polygon in 'rot'. The polygon is rotated by an angle 'a', with
* center at 0,0. */
-void rotate_poly(Poly *rot, Poly *poly, float a) {
+void rotate_poly(Poly* rot, Poly* poly, float a) {
/* We want to compute sin(a) and cos(a) only one time
* for every point to rotate. It's a slow operation. */
float sin_a = (float)sin(a);
float cos_a = (float)cos(a);
- for (uint32_t j = 0; j < poly->points; j++) {
- rot->x[j] = poly->x[j]*cos_a - poly->y[j]*sin_a;
- rot->y[j] = poly->y[j]*cos_a + poly->x[j]*sin_a;
+ for(uint32_t j = 0; j < poly->points; j++) {
+ rot->x[j] = poly->x[j] * cos_a - poly->y[j] * sin_a;
+ rot->y[j] = poly->y[j] * cos_a + poly->x[j] * sin_a;
}
rot->points = poly->points;
}
@@ -140,36 +132,34 @@ void rotate_poly(Poly *rot, Poly *poly, float a) {
/* This is an 8 bit LFSR we use to generate a predictable and fast
* pseudorandom sequence of numbers, to give a different shape to
* each asteroid. */
-void lfsr_next(unsigned char *prev) {
+void lfsr_next(unsigned char* prev) {
unsigned char lsb = *prev & 1;
*prev = *prev >> 1;
- if (lsb == 1) *prev ^= 0b11000111;
- *prev ^= *prev<<7; /* Mix things a bit more. */
+ if(lsb == 1) *prev ^= 0b11000111;
+ *prev ^= *prev << 7; /* Mix things a bit more. */
}
/* Render the polygon 'poly' at x,y, rotated by the specified angle. */
-void draw_poly(Canvas *const canvas, Poly *poly, uint8_t x, uint8_t y, float a)
-{
+void draw_poly(Canvas* const canvas, Poly* poly, uint8_t x, uint8_t y, float a) {
Poly rot;
- rotate_poly(&rot,poly,a);
+ rotate_poly(&rot, poly, a);
canvas_set_color(canvas, ColorBlack);
- for (uint32_t j = 0; j < rot.points; j++) {
+ for(uint32_t j = 0; j < rot.points; j++) {
uint32_t a = j;
- uint32_t b = j+1;
- if (b == rot.points) b = 0;
- canvas_draw_line(canvas,x+rot.x[a],y+rot.y[a],
- x+rot.x[b],y+rot.y[b]);
+ uint32_t b = j + 1;
+ if(b == rot.points) b = 0;
+ canvas_draw_line(canvas, x + rot.x[a], y + rot.y[a], x + rot.x[b], y + rot.y[b]);
}
}
/* A bullet is just a + pixels pattern. A single pixel is not
* visible enough. */
-void draw_bullet(Canvas *const canvas, Bullet *b) {
- canvas_draw_dot(canvas,b->x-1,b->y);
- canvas_draw_dot(canvas,b->x+1,b->y);
- canvas_draw_dot(canvas,b->x,b->y);
- canvas_draw_dot(canvas,b->x,b->y-1);
- canvas_draw_dot(canvas,b->x,b->y+1);
+void draw_bullet(Canvas* const canvas, Bullet* b) {
+ canvas_draw_dot(canvas, b->x - 1, b->y);
+ canvas_draw_dot(canvas, b->x + 1, b->y);
+ canvas_draw_dot(canvas, b->x, b->y);
+ canvas_draw_dot(canvas, b->x, b->y - 1);
+ canvas_draw_dot(canvas, b->x, b->y + 1);
}
/* Draw an asteroid. The asteroid shapes is computed on the fly and
@@ -177,15 +167,15 @@ void draw_bullet(Canvas *const canvas, Bullet *b) {
* the shape, we use an initial fixed shape that we resize according
* to the asteroid size, perturbed according to the asteroid shape
* seed, and finally draw it rotated of the right amount. */
-void draw_asteroid(Canvas *const canvas, Asteroid *ast) {
+void draw_asteroid(Canvas* const canvas, Asteroid* ast) {
Poly ap;
/* Start with what is kinda of a circle. Note that this could be
* stored into a template and copied here, to avoid computing
* sin() / cos(). But the Flipper can handle it without problems. */
uint8_t r = ast->shape_seed;
- for (int j = 0; j < 8; j++) {
- float a = (PI*2)/8*j;
+ for(int j = 0; j < 8; j++) {
+ float a = (PI * 2) / 8 * j;
/* Before generating the point, to make the shape unique generate
* a random factor between .7 and 1.3 to scale the distance from
@@ -193,75 +183,73 @@ void draw_asteroid(Canvas *const canvas, Asteroid *ast) {
* that remains always the same, so we use a predictable PRNG
* implemented by an 8 bit shift register. */
lfsr_next(&r);
- float scaling = .7+((float)r/255*.6);
+ float scaling = .7 + ((float)r / 255 * .6);
ap.x[j] = (float)sin(a) * ast->size * scaling;
ap.y[j] = (float)cos(a) * ast->size * scaling;
}
ap.points = 8;
- draw_poly(canvas,&ap,ast->x,ast->y,ast->rot);
+ draw_poly(canvas, &ap, ast->x, ast->y, ast->rot);
}
/* Draw small ships in the top-right part of the screen, one for
* each left live. */
-void draw_left_lives(Canvas *const canvas, AsteroidsApp *app) {
+void draw_left_lives(Canvas* const canvas, AsteroidsApp* app) {
int lives = app->lives;
- int x = SCREEN_XRES-5;
+ int x = SCREEN_XRES - 5;
- Poly mini_ship = {
- {-2, 0, 2},
- {-2, 4, -2},
- 3
- };
+ Poly mini_ship = {{-2, 0, 2}, {-2, 4, -2}, 3};
while(lives--) {
- draw_poly(canvas,&mini_ship,x,6,PI);
+ draw_poly(canvas, &mini_ship, x, 6, PI);
x -= 6;
}
}
/* Given the current position, update it according to the velocity and
* wrap it back to the other side if the object went over the screen. */
-void update_pos_by_velocity(float *x, float *y, float vx, float vy) {
+void update_pos_by_velocity(float* x, float* y, float vx, float vy) {
/* Return back from one side to the other of the screen. */
*x += vx;
*y += vy;
- if (*x >= SCREEN_XRES) *x = 0;
- else if (*x < 0) *x = SCREEN_XRES-1;
- if (*y >= SCREEN_YRES) *y = 0;
- else if (*y < 0) *y = SCREEN_YRES-1;
+ if(*x >= SCREEN_XRES)
+ *x = 0;
+ else if(*x < 0)
+ *x = SCREEN_XRES - 1;
+ if(*y >= SCREEN_YRES)
+ *y = 0;
+ else if(*y < 0)
+ *y = SCREEN_YRES - 1;
}
/* Render the current game screen. */
-void render_callback(Canvas *const canvas, void *ctx) {
- AsteroidsApp *app = ctx;
+void render_callback(Canvas* const canvas, void* ctx) {
+ AsteroidsApp* app = ctx;
/* Clear screen. */
canvas_set_color(canvas, ColorWhite);
- canvas_draw_box(canvas, 0, 0, SCREEN_XRES-1, SCREEN_YRES-1);
+ canvas_draw_box(canvas, 0, 0, SCREEN_XRES - 1, SCREEN_YRES - 1);
/* Draw score. */
canvas_set_color(canvas, ColorBlack);
canvas_set_font(canvas, FontSecondary);
char score[32];
- snprintf(score,sizeof(score),"%lu",app->score);
+ snprintf(score, sizeof(score), "%lu", app->score);
canvas_draw_str(canvas, 0, 8, score);
/* Draw left ships. */
- draw_left_lives(canvas,app);
+ draw_left_lives(canvas, app);
/* Draw ship, asteroids, bullets. */
- draw_poly(canvas,&ShipPoly,app->ship.x,app->ship.y,app->ship.rot);
- if (key_pressed_time(app,InputKeyOk) > SHIP_ACCELERATION_KEYPRESS_TIME)
- draw_poly(canvas,&ShipFirePoly,app->ship.x,app->ship.y,app->ship.rot);
+ draw_poly(canvas, &ShipPoly, app->ship.x, app->ship.y, app->ship.rot);
+ if(key_pressed_time(app, InputKeyOk) > SHIP_ACCELERATION_KEYPRESS_TIME)
+ draw_poly(canvas, &ShipFirePoly, app->ship.x, app->ship.y, app->ship.rot);
- for (int j = 0; j < app->bullets_num; j++)
- draw_bullet(canvas,&app->bullets[j]);
+ for(int j = 0; j < app->bullets_num; j++) draw_bullet(canvas, &app->bullets[j]);
- for (int j = 0; j < app->asteroids_num; j++)
- draw_asteroid(canvas,&app->asteroids[j]);
+ for(int j = 0; j < app->asteroids_num; j++) draw_asteroid(canvas, &app->asteroids[j]);
/* Game over text. */
- if (app->gameover) {
+ if(app->gameover) {
canvas_set_color(canvas, ColorBlack);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 28, 35, "GAME OVER");
@@ -273,9 +261,9 @@ void render_callback(Canvas *const canvas, void *ctx) {
/* ============================ Game logic ================================== */
float distance(float x1, float y1, float x2, float y2) {
- float dx = x1-x2;
- float dy = y1-y2;
- return sqrt(dx*dx+dy*dy);
+ float dx = x1 - x2;
+ float dy = y1 - y2;
+ return sqrt(dx * dx + dy * dy);
}
/* Detect a collision between the object at x1,y1 of radius r1 and
@@ -289,10 +277,7 @@ float distance(float x1, float y1, float x2, float y2) {
* spheres (this is why this function only takes the radius). This
* is, after all, kinda accurate for asteroids, for bullets, and
* even for the ship "core" itself. */
-bool objects_are_colliding(float x1, float y1, float r1,
- float x2, float y2, float r2,
- float factor)
-{
+bool objects_are_colliding(float x1, float y1, float r1, float x2, float y2, float r2, float factor) {
/* The objects are colliding if the distance between object 1 and 2
* is smaller than the sum of the two radiuses r1 and r2.
* So it would be like: sqrt((x1-x2)^2+(y1-y2)^2) < r1+r2.
@@ -301,24 +286,24 @@ bool objects_are_colliding(float x1, float y1, float r1,
* the comparison like this:
*
* (x1-x2)^2+(y1-y2)^2 < (r1+r2)^2. */
- float dx = (x1-x2)*factor;
- float dy = (y1-y2)*factor;
- float rsum = r1+r2;
- return dx*dx+dy*dy < rsum*rsum;
+ float dx = (x1 - x2) * factor;
+ float dy = (y1 - y2) * factor;
+ float rsum = r1 + r2;
+ return dx * dx + dy * dy < rsum * rsum;
}
/* Create a new bullet headed in the same direction of the ship. */
-void ship_fire_bullet(AsteroidsApp *app) {
- if (app->bullets_num == MAXBUL) return;
- Bullet *b = &app->bullets[app->bullets_num];
+void ship_fire_bullet(AsteroidsApp* app) {
+ if(app->bullets_num == MAXBUL) return;
+ Bullet* b = &app->bullets[app->bullets_num];
b->x = app->ship.x;
b->y = app->ship.y;
b->vx = -sin(app->ship.rot);
b->vy = cos(app->ship.rot);
/* Ship should fire from its head, not in the middle. */
- b->x += b->vx*5;
- b->y += b->vy*5;
+ b->x += b->vx * 5;
+ b->y += b->vy * 5;
/* Give the bullet some velocity (for now the vector is just
* normalized to 1). */
@@ -336,68 +321,68 @@ void ship_fire_bullet(AsteroidsApp *app) {
}
/* Remove the specified bullet by id (index in the array). */
-void remove_bullet(AsteroidsApp *app, int bid) {
+void remove_bullet(AsteroidsApp* app, int bid) {
/* Replace the top bullet with the empty space left
* by the removal of this bullet. This way we always take the
* array dense, which is an advantage when looping. */
int n = --app->bullets_num;
- if (n && bid != n) app->bullets[bid] = app->bullets[n];
+ if(n && bid != n) app->bullets[bid] = app->bullets[n];
}
/* Create a new asteroid, away from the ship. Return the
* pointer to the asteroid object, so that the caller can change
* certain things of the asteroid if needed. */
-Asteroid *add_asteroid(AsteroidsApp *app) {
- if (app->asteroids_num == MAXAST) return NULL;
- float size = 4+rand()%15;
+Asteroid* add_asteroid(AsteroidsApp* app) {
+ if(app->asteroids_num == MAXAST) return NULL;
+ float size = 4 + rand() % 15;
float min_distance = 20;
- float x,y;
+ float x, y;
do {
x = rand() % SCREEN_XRES;
y = rand() % SCREEN_YRES;
- } while(distance(app->ship.x,app->ship.y,x,y) < min_distance+size);
- Asteroid *a = &app->asteroids[app->asteroids_num++];
+ } while(distance(app->ship.x, app->ship.y, x, y) < min_distance + size);
+ Asteroid* a = &app->asteroids[app->asteroids_num++];
a->x = x;
a->y = y;
- a->vx = 2*(-.5 + ((float)rand()/RAND_MAX));
- a->vy = 2*(-.5 + ((float)rand()/RAND_MAX));
+ a->vx = 2 * (-.5 + ((float)rand() / RAND_MAX));
+ a->vy = 2 * (-.5 + ((float)rand() / RAND_MAX));
a->size = size;
a->rot = 0;
- a->rot_speed = ((float)rand()/RAND_MAX)/10;
- if (app->ticks & 1) a->rot_speed = -(a->rot_speed);
+ a->rot_speed = ((float)rand() / RAND_MAX) / 10;
+ if(app->ticks & 1) a->rot_speed = -(a->rot_speed);
a->shape_seed = rand() & 255;
return a;
}
/* Remove the specified asteroid by id (index in the array). */
-void remove_asteroid(AsteroidsApp *app, int id) {
+void remove_asteroid(AsteroidsApp* app, int id) {
/* Replace the top asteroid with the empty space left
* by the removal of this one. This way we always take the
* array dense, which is an advantage when looping. */
int n = --app->asteroids_num;
- if (n && id != n) app->asteroids[id] = app->asteroids[n];
+ if(n && id != n) app->asteroids[id] = app->asteroids[n];
}
/* Called when an asteroid was reached by a bullet. The asteroid
* hit is the one with the specified 'id'. */
-void asteroid_was_hit(AsteroidsApp *app, int id) {
+void asteroid_was_hit(AsteroidsApp* app, int id) {
float sizelimit = 6; // Smaller than that, they disappear in one shot.
- Asteroid *a = &app->asteroids[id];
+ Asteroid* a = &app->asteroids[id];
/* Asteroid is large enough to break into fragments. */
float size = a->size;
float x = a->x, y = a->y;
- remove_asteroid(app,id);
- if (size > sizelimit) {
+ remove_asteroid(app, id);
+ if(size > sizelimit) {
int max_fragments = size / sizelimit;
- int fragments = 2+rand()%max_fragments;
- float newsize = size/fragments;
- if (newsize < 2) newsize = 2;
- for (int j = 0; j < fragments; j++) {
+ int fragments = 2 + rand() % max_fragments;
+ float newsize = size / fragments;
+ if(newsize < 2) newsize = 2;
+ for(int j = 0; j < fragments; j++) {
a = add_asteroid(app);
- if (a == NULL) break; // Too many asteroids on screen.
- a->x = x + -(size/2) + rand() % (int)newsize;
- a->y = y + -(size/2) + rand() % (int)newsize;
+ if(a == NULL) break; // Too many asteroids on screen.
+ a->x = x + -(size / 2) + rand() % (int)newsize;
+ a->y = y + -(size / 2) + rand() % (int)newsize;
a->size = newsize;
}
} else {
@@ -407,18 +392,19 @@ void asteroid_was_hit(AsteroidsApp *app, int id) {
/* Set game over state. When in game-over mode, the game displays a
* game over text with a background of many asteroids floating around. */
-void game_over(AsteroidsApp *app) {
+void game_over(AsteroidsApp* app) {
restart_game_after_gameover(app);
app->gameover = true;
int asteroids = 8;
- while(asteroids-- && add_asteroid(app) != NULL);
+ while(asteroids-- && add_asteroid(app) != NULL)
+ ;
}
/* Function called when a collision between the asteroid and the
* ship is detected. */
-void ship_was_hit(AsteroidsApp *app) {
+void ship_was_hit(AsteroidsApp* app) {
app->ship_hit = SHIP_HIT_ANIMATION_LEN;
- if (app->lives) {
+ if(app->lives) {
app->lives--;
} else {
game_over(app);
@@ -427,10 +413,10 @@ void ship_was_hit(AsteroidsApp *app) {
/* Restart game after the ship is hit. Will reset the ship position, bullets
* and asteroids to restart the game. */
-void restart_game(AsteroidsApp *app) {
+void restart_game(AsteroidsApp* app) {
app->ship.x = SCREEN_XRES / 2;
app->ship.y = SCREEN_YRES / 2;
- app->ship.rot = PI; /* Start headed towards top. */
+ app->ship.rot = PI; /* Start headed towards top. */
app->ship.vx = 0;
app->ship.vy = 0;
app->bullets_num = 0;
@@ -440,22 +426,22 @@ void restart_game(AsteroidsApp *app) {
/* Called after game over to restart the game. This function
* also calls restart_game(). */
-void restart_game_after_gameover(AsteroidsApp *app) {
+void restart_game_after_gameover(AsteroidsApp* app) {
app->gameover = false;
app->ticks = 0;
app->score = 0;
app->ship_hit = 0;
- app->lives = GAME_START_LIVES-1; /* -1 to account for current one. */
+ app->lives = GAME_START_LIVES - 1; /* -1 to account for current one. */
restart_game(app);
}
/* Move bullets. */
-void update_bullets_position(AsteroidsApp *app) {
- for (int j = 0; j < app->bullets_num; j++) {
- update_pos_by_velocity(&app->bullets[j].x,&app->bullets[j].y,
- app->bullets[j].vx,app->bullets[j].vy);
- if (--app->bullets[j].ttl == 0) {
- remove_bullet(app,j);
+void update_bullets_position(AsteroidsApp* app) {
+ for(int j = 0; j < app->bullets_num; j++) {
+ update_pos_by_velocity(
+ &app->bullets[j].x, &app->bullets[j].y, app->bullets[j].vx, app->bullets[j].vy);
+ if(--app->bullets[j].ttl == 0) {
+ remove_bullet(app, j);
j--; /* Process this bullet index again: the removal will
fill it with the top bullet to take the array dense. */
}
@@ -463,28 +449,28 @@ void update_bullets_position(AsteroidsApp *app) {
}
/* Move asteroids. */
-void update_asteroids_position(AsteroidsApp *app) {
- for (int j = 0; j < app->asteroids_num; j++) {
- update_pos_by_velocity(&app->asteroids[j].x,&app->asteroids[j].y,
- app->asteroids[j].vx,app->asteroids[j].vy);
+void update_asteroids_position(AsteroidsApp* app) {
+ for(int j = 0; j < app->asteroids_num; j++) {
+ update_pos_by_velocity(
+ &app->asteroids[j].x, &app->asteroids[j].y, app->asteroids[j].vx, app->asteroids[j].vy);
app->asteroids[j].rot += app->asteroids[j].rot_speed;
- if (app->asteroids[j].rot < 0) app->asteroids[j].rot = 2*PI;
- else if (app->asteroids[j].rot > 2*PI) app->asteroids[j].rot = 0;
+ if(app->asteroids[j].rot < 0)
+ app->asteroids[j].rot = 2 * PI;
+ else if(app->asteroids[j].rot > 2 * PI)
+ app->asteroids[j].rot = 0;
}
}
/* Collision detection and game state update based on collisions. */
-void detect_collisions(AsteroidsApp *app) {
+void detect_collisions(AsteroidsApp* app) {
/* Detect collision between bullet and asteroid. */
- for (int j = 0; j < app->bullets_num; j++) {
- Bullet *b = &app->bullets[j];
- for (int i = 0; i < app->asteroids_num; i++) {
- Asteroid *a = &app->asteroids[i];
- if (objects_are_colliding(a->x, a->y, a->size,
- b->x, b->y, 1.5, 1))
- {
- asteroid_was_hit(app,i);
- remove_bullet(app,j);
+ for(int j = 0; j < app->bullets_num; j++) {
+ Bullet* b = &app->bullets[j];
+ for(int i = 0; i < app->asteroids_num; i++) {
+ Asteroid* a = &app->asteroids[i];
+ if(objects_are_colliding(a->x, a->y, a->size, b->x, b->y, 1.5, 1)) {
+ asteroid_was_hit(app, i);
+ remove_bullet(app, j);
/* The bullet no longer exist. Break the loop.
* However we want to start processing from the
* same bullet index, since now it is used by
@@ -496,11 +482,9 @@ void detect_collisions(AsteroidsApp *app) {
}
/* Detect collision between ship and asteroid. */
- for (int j = 0; j < app->asteroids_num; j++) {
- Asteroid *a = &app->asteroids[j];
- if (objects_are_colliding(a->x, a->y, a->size,
- app->ship.x, app->ship.y, 4, 1))
- {
+ for(int j = 0; j < app->asteroids_num; j++) {
+ Asteroid* a = &app->asteroids[j];
+ if(objects_are_colliding(a->x, a->y, a->size, app->ship.x, app->ship.y, 4, 1)) {
ship_was_hit(app);
break;
}
@@ -513,26 +497,26 @@ void detect_collisions(AsteroidsApp *app) {
* on velocity. Detect collisions. Update the score and so forth.
*
* Each time this function is called, app->tick is incremented. */
-void game_tick(void *ctx) {
- AsteroidsApp *app = ctx;
+void game_tick(void* ctx) {
+ AsteroidsApp* app = ctx;
/* There are two special screens:
*
* 1. Ship was hit, we frozen the game as long as ship_hit isn't zero
* again, and show an animation of a rotating ship. */
- if (app->ship_hit) {
+ if(app->ship_hit) {
app->ship.rot += 0.5;
app->ship_hit--;
view_port_update(app->view_port);
- if (app->ship_hit == 0) {
+ if(app->ship_hit == 0) {
restart_game(app);
}
return;
- } else if (app->gameover) {
- /* 2. Game over. We need to update only background asteroids. In this
+ } else if(app->gameover) {
+ /* 2. Game over. We need to update only background asteroids. In this
* state the game just displays a GAME OVER text with the floating
* asteroids in background. */
- if (key_pressed_time(app,InputKeyOk) > 100) {
+ if(key_pressed_time(app, InputKeyOk) > 100) {
restart_game_after_gameover(app);
}
update_asteroids_position(app);
@@ -541,12 +525,12 @@ void game_tick(void *ctx) {
}
/* Handle key presses. */
- if (app->pressed[InputKeyLeft]) app->ship.rot -= .35;
- if (app->pressed[InputKeyRight]) app->ship.rot += .35;
- if (key_pressed_time(app,InputKeyOk) > SHIP_ACCELERATION_KEYPRESS_TIME) {
- app->ship.vx -= 0.5*(float)sin(app->ship.rot);
- app->ship.vy += 0.5*(float)cos(app->ship.rot);
- } else if (app->pressed[InputKeyDown]) {
+ if(app->pressed[InputKeyLeft]) app->ship.rot -= .35;
+ if(app->pressed[InputKeyRight]) app->ship.rot += .35;
+ if(key_pressed_time(app, InputKeyOk) > SHIP_ACCELERATION_KEYPRESS_TIME) {
+ app->ship.vx -= 0.5 * (float)sin(app->ship.rot);
+ app->ship.vy += 0.5 * (float)cos(app->ship.rot);
+ } else if(app->pressed[InputKeyDown]) {
app->ship.vx *= 0.75;
app->ship.vy *= 0.75;
}
@@ -554,10 +538,10 @@ void game_tick(void *ctx) {
/* Fire a bullet if needed. app->fire is set in
* asteroids_update_keypress_state() since depends on exact
* pressure timing. */
- if (app->fire) {
+ if(app->fire) {
uint32_t bullet_min_period = 200; // In milliseconds
uint32_t now = furi_get_tick();
- if (now - app->last_bullet_tick >= bullet_min_period) {
+ if(now - app->last_bullet_tick >= bullet_min_period) {
ship_fire_bullet(app);
app->last_bullet_tick = now;
}
@@ -565,7 +549,7 @@ void game_tick(void *ctx) {
}
/* Update positions and detect collisions. */
- update_pos_by_velocity(&app->ship.x,&app->ship.y,app->ship.vx,app->ship.vy);
+ update_pos_by_velocity(&app->ship.x, &app->ship.y, app->ship.vx, app->ship.vy);
update_bullets_position(app);
update_asteroids_position(app);
detect_collisions(app);
@@ -573,9 +557,7 @@ void game_tick(void *ctx) {
/* From time to time, create a new asteroid. The more asteroids
* already on the screen, the smaller probability of creating
* a new one. */
- if (app->asteroids_num == 0 ||
- (random() % 5000) < (30/(1+app->asteroids_num)))
- {
+ if(app->asteroids_num == 0 || (random() % 5000) < (30 / (1 + app->asteroids_num))) {
add_asteroid(app);
}
@@ -587,16 +569,15 @@ void game_tick(void *ctx) {
/* Here all we do is putting the events into the queue that will be handled
* in the while() loop of the app entry point function. */
-void input_callback(InputEvent* input_event, void* ctx)
-{
- AsteroidsApp *app = ctx;
- furi_message_queue_put(app->event_queue,input_event,FuriWaitForever);
+void input_callback(InputEvent* input_event, void* ctx) {
+ AsteroidsApp* app = ctx;
+ furi_message_queue_put(app->event_queue, input_event, FuriWaitForever);
}
/* Allocate the application state and initialize a number of stuff.
* This is called in the entry point to create the application state. */
AsteroidsApp* asteroids_app_alloc() {
- AsteroidsApp *app = malloc(sizeof(AsteroidsApp));
+ AsteroidsApp* app = malloc(sizeof(AsteroidsApp));
app->gui = furi_record_open(RECORD_GUI);
app->view_port = view_port_alloc();
@@ -605,16 +586,16 @@ AsteroidsApp* asteroids_app_alloc() {
gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen);
app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
- app->running = 1; /* Turns 0 when back is pressed. */
+ app->running = 1; /* Turns 0 when back is pressed. */
restart_game_after_gameover(app);
- memset(app->pressed,0,sizeof(app->pressed));
+ memset(app->pressed, 0, sizeof(app->pressed));
return app;
}
/* Free what the application allocated. It is not clear to me if the
* Flipper OS, once the application exits, will be able to reclaim space
* even if we forget to free something here. */
-void asteroids_app_free(AsteroidsApp *app) {
+void asteroids_app_free(AsteroidsApp* app) {
furi_assert(app);
// View related.
@@ -630,28 +611,27 @@ void asteroids_app_free(AsteroidsApp *app) {
/* Return the time in milliseconds the specified key is continuously
* pressed. Or 0 if it is not pressed. */
-uint32_t key_pressed_time(AsteroidsApp *app, InputKey key) {
- return app->pressed[key] == 0 ? 0 :
- furi_get_tick() - app->pressed[key];
+uint32_t key_pressed_time(AsteroidsApp* app, InputKey key) {
+ return app->pressed[key] == 0 ? 0 : furi_get_tick() - app->pressed[key];
}
/* Handle keys interaction. */
-void asteroids_update_keypress_state(AsteroidsApp *app, InputEvent input) {
- if (input.type == InputTypePress) {
+void asteroids_update_keypress_state(AsteroidsApp* app, InputEvent input) {
+ if(input.type == InputTypePress) {
app->pressed[input.key] = furi_get_tick();
- } else if (input.type == InputTypeRelease) {
- uint32_t dur = key_pressed_time(app,input.key);
+ } else if(input.type == InputTypeRelease) {
+ uint32_t dur = key_pressed_time(app, input.key);
app->pressed[input.key] = 0;
- if (dur < 200 && input.key == InputKeyOk) app->fire = true;
+ if(dur < 200 && input.key == InputKeyOk) app->fire = true;
}
}
int32_t asteroids_app_entry(void* p) {
UNUSED(p);
- AsteroidsApp *app = asteroids_app_alloc();
+ AsteroidsApp* app = asteroids_app_alloc();
/* Create a timer. We do data analysis in the callback. */
- FuriTimer *timer = furi_timer_alloc(game_tick, FuriTimerTypePeriodic, app);
+ FuriTimer* timer = furi_timer_alloc(game_tick, FuriTimerTypePeriodic, app);
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10);
/* This is the main event loop: here we get the events that are pushed
@@ -660,25 +640,24 @@ int32_t asteroids_app_entry(void* p) {
InputEvent input;
while(app->running) {
FuriStatus qstat = furi_message_queue_get(app->event_queue, &input, 100);
- if (qstat == FuriStatusOk) {
- if (DEBUG_MSG) FURI_LOG_E(TAG, "Main Loop - Input: type %d key %u",
- input.type, input.key);
+ if(qstat == FuriStatusOk) {
+ if(DEBUG_MSG)
+ FURI_LOG_E(TAG, "Main Loop - Input: type %d key %u", input.type, input.key);
/* Handle navigation here. Then handle view-specific inputs
* in the view specific handling function. */
- if (input.type == InputTypeShort &&
- input.key == InputKeyBack)
- {
+ if(input.type == InputTypeShort && input.key == InputKeyBack) {
app->running = 0;
} else {
- asteroids_update_keypress_state(app,input);
+ asteroids_update_keypress_state(app, input);
}
} else {
/* Useful to understand if the app is still alive when it
* does not respond because of bugs. */
- if (DEBUG_MSG) {
- static int c = 0; c++;
- if (!(c % 20)) FURI_LOG_E(TAG, "Loop timeout");
+ if(DEBUG_MSG) {
+ static int c = 0;
+ c++;
+ if(!(c % 20)) FURI_LOG_E(TAG, "Loop timeout");
}
}
}
diff --git a/applications/plugins/cli_bridge/application.fam b/applications/plugins/cli_bridge/application.fam
index c9baa52543..60cd9648d3 100644
--- a/applications/plugins/cli_bridge/application.fam
+++ b/applications/plugins/cli_bridge/application.fam
@@ -1,6 +1,6 @@
App(
appid="cli_gui",
- name="CLI-GUI Bridge",
+ name="CLI (subghz chat)",
apptype=FlipperAppType.EXTERNAL,
entry_point="cligui_main",
requires=["gui","cli"],
diff --git a/applications/plugins/cli_bridge/cligui_main.c b/applications/plugins/cli_bridge/cligui_main.c
index afda14683d..137b4a08be 100644
--- a/applications/plugins/cli_bridge/cligui_main.c
+++ b/applications/plugins/cli_bridge/cligui_main.c
@@ -24,14 +24,14 @@ static void cligui_tick_event_cb(void* context) {
furi_string_push_back(app->text_box_store, c);
}
}
- if (available > 0) {
+ if(available > 0) {
text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
}
// Set input header stuff
size_t len = furi_string_size(app->text_box_store);
size_t idx = len - 2;
- while (idx > 0) {
- if (furi_string_get_char(app->text_box_store, idx) == '\n') {
+ while(idx > 0) {
+ if(furi_string_get_char(app->text_box_store, idx) == '\n') {
idx++;
break;
}
diff --git a/applications/plugins/cli_bridge/console_output.c b/applications/plugins/cli_bridge/console_output.c
index 933ee8431b..71603ec13b 100644
--- a/applications/plugins/cli_bridge/console_output.c
+++ b/applications/plugins/cli_bridge/console_output.c
@@ -9,5 +9,4 @@ void console_output_input_handler(CliguiApp* app, InputEvent* event) {
char eot = 0x03;
furi_stream_buffer_send(app->data->streams.app_tx, &eot, 1, FuriWaitForever);
}
-
}
\ No newline at end of file
diff --git a/applications/plugins/cli_bridge/internal_defs.h b/applications/plugins/cli_bridge/internal_defs.h
index cdb5f2fa98..9840d008b1 100644
--- a/applications/plugins/cli_bridge/internal_defs.h
+++ b/applications/plugins/cli_bridge/internal_defs.h
@@ -88,7 +88,6 @@ typedef struct {
void* pubsub;
} Loader_internal;
-
typedef struct {
CliCallback callback;
void* context;
diff --git a/applications/plugins/dap_link/dap_link.c b/applications/plugins/dap_link/dap_link.c
index 5105405889..15f3ce7715 100644
--- a/applications/plugins/dap_link/dap_link.c
+++ b/applications/plugins/dap_link/dap_link.c
@@ -490,8 +490,9 @@ int32_t dap_link_app(void* p) {
if(furi_hal_usb_is_locked()) {
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
DialogMessage* message = dialog_message_alloc();
- if (settings->sfw_mode) {
- dialog_message_set_header(message, "Connection\nis active!", 3, 2, AlignLeft, AlignTop);
+ if(settings->sfw_mode) {
+ dialog_message_set_header(
+ message, "Connection\nis active!", 3, 2, AlignLeft, AlignTop);
dialog_message_set_text(
message,
"Disconnect from\nPC or phone to\nuse this function.",
@@ -499,8 +500,7 @@ int32_t dap_link_app(void* p) {
30,
AlignLeft,
AlignTop);
- }
- else {
+ } else {
dialog_message_set_header(message, "I am not\na whore!", 3, 2, AlignLeft, AlignTop);
dialog_message_set_text(
message,
diff --git a/applications/plugins/pocsag_pager/views/pocsag_pager_receiver.c b/applications/plugins/pocsag_pager/views/pocsag_pager_receiver.c
index 760fcd0fcd..c452e5fe9f 100644
--- a/applications/plugins/pocsag_pager/views/pocsag_pager_receiver.c
+++ b/applications/plugins/pocsag_pager/views/pocsag_pager_receiver.c
@@ -209,10 +209,9 @@ void pcsg_view_receiver_draw(Canvas* canvas, PCSGReceiverModel* model) {
canvas_set_color(canvas, ColorBlack);
if(model->history_item == 0) {
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52_sfw);
- }
- else {
+ } else {
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52);
}
canvas_set_font(canvas, FontPrimary);
@@ -236,10 +235,9 @@ void pcsg_view_receiver_draw(Canvas* canvas, PCSGReceiverModel* model) {
canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8);
canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8);
canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42_sfw);
- }
- else {
+ } else {
canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42);
}
canvas_draw_dot(canvas, 17, 61);
diff --git a/applications/plugins/pong/flipper_pong.c b/applications/plugins/pong/flipper_pong.c
index 2af3e6df43..0e80e6ff3b 100644
--- a/applications/plugins/pong/flipper_pong.c
+++ b/applications/plugins/pong/flipper_pong.c
@@ -28,34 +28,39 @@ typedef struct {
InputEvent input;
} EventApp;
-typedef struct Players
-{
- uint8_t player1_X,player1_Y,player2_X,player2_Y;
- uint16_t player1_score,player2_score;
- uint8_t ball_X,ball_Y,ball_X_speed,ball_Y_speed,ball_X_direction,ball_Y_direction;
+typedef struct Players {
+ uint8_t player1_X, player1_Y, player2_X, player2_Y;
+ uint16_t player1_score, player2_score;
+ uint8_t ball_X, ball_Y, ball_X_speed, ball_Y_speed, ball_X_direction, ball_Y_direction;
} Players;
-static void draw_callback(Canvas* canvas, void* ctx)
-{
+static void draw_callback(Canvas* canvas, void* ctx) {
UNUSED(ctx);
Players* playersMutex = (Players*)acquire_mutex_block((ValueMutex*)ctx);
canvas_draw_frame(canvas, 0, 0, 128, 64);
- canvas_draw_box(canvas, playersMutex->player1_X, playersMutex->player1_Y, PAD_SIZE_X, PAD_SIZE_Y);
- canvas_draw_box(canvas, playersMutex->player2_X, playersMutex->player2_Y, PAD_SIZE_X, PAD_SIZE_Y);
+ canvas_draw_box(
+ canvas, playersMutex->player1_X, playersMutex->player1_Y, PAD_SIZE_X, PAD_SIZE_Y);
+ canvas_draw_box(
+ canvas, playersMutex->player2_X, playersMutex->player2_Y, PAD_SIZE_X, PAD_SIZE_Y);
canvas_draw_box(canvas, playersMutex->ball_X, playersMutex->ball_Y, BALL_SIZE, BALL_SIZE);
canvas_set_font(canvas, FontPrimary);
canvas_set_font_direction(canvas, CanvasDirectionBottomToTop);
char buffer[16];
- snprintf(buffer, sizeof(buffer), "%u - %u", playersMutex->player1_score, playersMutex->player2_score);
- canvas_draw_str_aligned(canvas, SCREEN_SIZE_X/2+15, SCREEN_SIZE_Y/2+2, AlignCenter, AlignTop, buffer);
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "%u - %u",
+ playersMutex->player1_score,
+ playersMutex->player2_score);
+ canvas_draw_str_aligned(
+ canvas, SCREEN_SIZE_X / 2 + 15, SCREEN_SIZE_Y / 2 + 2, AlignCenter, AlignTop, buffer);
release_mutex((ValueMutex*)ctx, playersMutex);
}
-static void input_callback(InputEvent* input_event, void* ctx)
-{
+static void input_callback(InputEvent* input_event, void* ctx) {
furi_assert(ctx);
FuriMessageQueue* event_queue = ctx;
EventApp event = {.type = EventTypeInput, .input = *input_event};
@@ -69,48 +74,44 @@ static void clock_tick(void* ctx) {
furi_message_queue_put(queue, &event, 0);
}
-bool insidePad(uint8_t x, uint8_t y, uint8_t playerX, uint8_t playerY)
-{
- if (x >= playerX && x <= playerX+PAD_SIZE_X && y >= playerY && y <= playerY+PAD_SIZE_Y) return true;
+bool insidePad(uint8_t x, uint8_t y, uint8_t playerX, uint8_t playerY) {
+ if(x >= playerX && x <= playerX + PAD_SIZE_X && y >= playerY && y <= playerY + PAD_SIZE_Y)
+ return true;
return false;
}
-uint8_t changeSpeed()
-{
+uint8_t changeSpeed() {
uint8_t randomuint8[1];
- while(1)
- {
- furi_hal_random_fill_buf(randomuint8,1);
- randomuint8[0] &= 0b00000011;
- if (randomuint8[0] >= 1) break;
+ while(1) {
+ furi_hal_random_fill_buf(randomuint8, 1);
+ randomuint8[0] &= 0b00000011;
+ if(randomuint8[0] >= 1) break;
}
return randomuint8[0];
}
-uint8_t changeDirection()
-{
+uint8_t changeDirection() {
uint8_t randomuint8[1];
- furi_hal_random_fill_buf(randomuint8,1);
+ furi_hal_random_fill_buf(randomuint8, 1);
randomuint8[0] &= 0b1;
- return randomuint8[0];
+ return randomuint8[0];
}
-int32_t flipper_pong_app()
-{
+int32_t flipper_pong_app() {
EventApp event;
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(EventApp));
Players players;
- players.player1_X = SCREEN_SIZE_X-PAD_SIZE_X-1;
- players.player1_Y = SCREEN_SIZE_Y/2 - PAD_SIZE_Y/2;
+ players.player1_X = SCREEN_SIZE_X - PAD_SIZE_X - 1;
+ players.player1_Y = SCREEN_SIZE_Y / 2 - PAD_SIZE_Y / 2;
players.player1_score = 0;
players.player2_X = 1;
- players.player2_Y = SCREEN_SIZE_Y/2 - PAD_SIZE_Y/2;
+ players.player2_Y = SCREEN_SIZE_Y / 2 - PAD_SIZE_Y / 2;
players.player2_score = 0;
- players.ball_X = SCREEN_SIZE_X/2 - BALL_SIZE/2;
- players.ball_Y = SCREEN_SIZE_Y/2 - BALL_SIZE/2;
+ players.ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2;
+ players.ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2;
players.ball_X_speed = 1;
players.ball_Y_speed = 1;
players.ball_X_direction = changeDirection();
@@ -127,112 +128,110 @@ int32_t flipper_pong_app()
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
FuriTimer* timer = furi_timer_alloc(clock_tick, FuriTimerTypePeriodic, event_queue);
- furi_timer_start(timer, 1000/FPS);
+ furi_timer_start(timer, 1000 / FPS);
- while(1)
- {
+ while(1) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever);
Players* playersMutex = (Players*)acquire_mutex_block(&state_mutex);
- if (event_status == FuriStatusOk)
- {
- if(event.type == EventTypeInput)
- {
- if(event.input.key == InputKeyBack)
- {
+ if(event_status == FuriStatusOk) {
+ if(event.type == EventTypeInput) {
+ if(event.input.key == InputKeyBack) {
release_mutex(&state_mutex, playersMutex);
break;
+ } else if(event.input.key == InputKeyUp) {
+ if(playersMutex->player1_Y >= 1 + PLAYER1_PAD_SPEED)
+ playersMutex->player1_Y -= PLAYER1_PAD_SPEED;
+ else
+ playersMutex->player1_Y = 1;
+ } else if(event.input.key == InputKeyDown) {
+ if(playersMutex->player1_Y <=
+ SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER1_PAD_SPEED - 1)
+ playersMutex->player1_Y += PLAYER1_PAD_SPEED;
+ else
+ playersMutex->player1_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1;
}
- else if(event.input.key == InputKeyUp)
- {
- if (playersMutex->player1_Y >= 1+PLAYER1_PAD_SPEED) playersMutex->player1_Y -= PLAYER1_PAD_SPEED;
- else playersMutex->player1_Y = 1;
- }
- else if(event.input.key == InputKeyDown)
- {
- if (playersMutex->player1_Y <= SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER1_PAD_SPEED -1) playersMutex->player1_Y += PLAYER1_PAD_SPEED;
- else playersMutex->player1_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1;
- }
- }
- else if (event.type == ClockEventTypeTick)
- {
-
- if (playersMutex->ball_X + BALL_SIZE/2 <= SCREEN_SIZE_X*0.35 && playersMutex->ball_X_direction == 0)
- {
- if (playersMutex->ball_Y + BALL_SIZE/2 < playersMutex->player2_Y + PAD_SIZE_Y/2)
- {
- if (playersMutex->player2_Y >= 1+PLAYER2_PAD_SPEED) playersMutex->player2_Y -= PLAYER2_PAD_SPEED;
- else playersMutex->player2_Y= 1;
- }
- else if (playersMutex->ball_Y + BALL_SIZE/2 > playersMutex->player2_Y + PAD_SIZE_Y/2)
- {
- if (playersMutex->player2_Y <= SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER2_PAD_SPEED -1) playersMutex->player2_Y += PLAYER2_PAD_SPEED;
- else playersMutex->player2_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1;
+ } else if(event.type == ClockEventTypeTick) {
+ if(playersMutex->ball_X + BALL_SIZE / 2 <= SCREEN_SIZE_X * 0.35 &&
+ playersMutex->ball_X_direction == 0) {
+ if(playersMutex->ball_Y + BALL_SIZE / 2 <
+ playersMutex->player2_Y + PAD_SIZE_Y / 2) {
+ if(playersMutex->player2_Y >= 1 + PLAYER2_PAD_SPEED)
+ playersMutex->player2_Y -= PLAYER2_PAD_SPEED;
+ else
+ playersMutex->player2_Y = 1;
+ } else if(
+ playersMutex->ball_Y + BALL_SIZE / 2 >
+ playersMutex->player2_Y + PAD_SIZE_Y / 2) {
+ if(playersMutex->player2_Y <=
+ SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER2_PAD_SPEED - 1)
+ playersMutex->player2_Y += PLAYER2_PAD_SPEED;
+ else
+ playersMutex->player2_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1;
}
}
- uint8_t ball_corner_X[4] = {playersMutex->ball_X, playersMutex->ball_X + BALL_SIZE, playersMutex->ball_X + BALL_SIZE, playersMutex->ball_X};
- uint8_t ball_corner_Y[4] = {playersMutex->ball_Y, playersMutex->ball_Y, playersMutex->ball_Y + BALL_SIZE, playersMutex->ball_Y + BALL_SIZE};
+ uint8_t ball_corner_X[4] = {
+ playersMutex->ball_X,
+ playersMutex->ball_X + BALL_SIZE,
+ playersMutex->ball_X + BALL_SIZE,
+ playersMutex->ball_X};
+ uint8_t ball_corner_Y[4] = {
+ playersMutex->ball_Y,
+ playersMutex->ball_Y,
+ playersMutex->ball_Y + BALL_SIZE,
+ playersMutex->ball_Y + BALL_SIZE};
bool insidePlayer1 = false, insidePlayer2 = false;
- for (int i=0;i<4;i++)
- {
- if (insidePad(ball_corner_X[i], ball_corner_Y[i], playersMutex->player1_X, playersMutex->player1_Y) == true)
- {
+ for(int i = 0; i < 4; i++) {
+ if(insidePad(
+ ball_corner_X[i],
+ ball_corner_Y[i],
+ playersMutex->player1_X,
+ playersMutex->player1_Y) == true) {
insidePlayer1 = true;
break;
}
- if (insidePad(ball_corner_X[i], ball_corner_Y[i], playersMutex->player2_X, playersMutex->player2_Y) == true)
- {
+ if(insidePad(
+ ball_corner_X[i],
+ ball_corner_Y[i],
+ playersMutex->player2_X,
+ playersMutex->player2_Y) == true) {
insidePlayer2 = true;
break;
}
}
- if (insidePlayer1 == true)
- {
+ if(insidePlayer1 == true) {
playersMutex->ball_X_direction = 0;
playersMutex->ball_X -= playersMutex->ball_X_speed;
playersMutex->ball_X_speed = changeSpeed();
playersMutex->ball_Y_speed = changeSpeed();
- }
- else if (insidePlayer2 == true)
- {
+ } else if(insidePlayer2 == true) {
playersMutex->ball_X_direction = 1;
playersMutex->ball_X += playersMutex->ball_X_speed;
playersMutex->ball_X_speed = changeSpeed();
playersMutex->ball_Y_speed = changeSpeed();
- }
- else
- {
- if (playersMutex->ball_X_direction == 1)
- {
-
- if (playersMutex->ball_X <= SCREEN_SIZE_X - BALL_SIZE - 1 - playersMutex->ball_X_speed)
- {
+ } else {
+ if(playersMutex->ball_X_direction == 1) {
+ if(playersMutex->ball_X <=
+ SCREEN_SIZE_X - BALL_SIZE - 1 - playersMutex->ball_X_speed) {
playersMutex->ball_X += playersMutex->ball_X_speed;
- }
- else
- {
- playersMutex->ball_X = SCREEN_SIZE_X/2 - BALL_SIZE/2;
- playersMutex->ball_Y = SCREEN_SIZE_Y/2 - BALL_SIZE/2;
+ } else {
+ playersMutex->ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2;
+ playersMutex->ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2;
playersMutex->ball_X_speed = 1;
playersMutex->ball_Y_speed = 1;
playersMutex->ball_X_direction = 0;
playersMutex->player2_score++;
}
- }
- else
- {
- if (playersMutex->ball_X >= 1 + playersMutex->ball_X_speed)
- {
+ } else {
+ if(playersMutex->ball_X >= 1 + playersMutex->ball_X_speed) {
playersMutex->ball_X -= playersMutex->ball_X_speed;
- }
- else
- {
- playersMutex->ball_X = SCREEN_SIZE_X/2 - BALL_SIZE/2;
- playersMutex->ball_Y = SCREEN_SIZE_Y/2 - BALL_SIZE/2;
+ } else {
+ playersMutex->ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2;
+ playersMutex->ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2;
playersMutex->ball_X_speed = 1;
playersMutex->ball_Y_speed = 1;
playersMutex->ball_X_direction = 1;
@@ -241,28 +240,20 @@ int32_t flipper_pong_app()
}
}
- if (playersMutex->ball_Y_direction == 1)
- {
- if (playersMutex->ball_Y <= SCREEN_SIZE_Y - BALL_SIZE - 1 - playersMutex->ball_Y_speed)
- {
+ if(playersMutex->ball_Y_direction == 1) {
+ if(playersMutex->ball_Y <=
+ SCREEN_SIZE_Y - BALL_SIZE - 1 - playersMutex->ball_Y_speed) {
playersMutex->ball_Y += playersMutex->ball_Y_speed;
- }
- else
- {
+ } else {
playersMutex->ball_Y = SCREEN_SIZE_Y - BALL_SIZE - 1;
playersMutex->ball_X_speed = changeSpeed();
playersMutex->ball_Y_speed = changeSpeed();
playersMutex->ball_Y_direction = 0;
}
- }
- else
- {
- if (playersMutex->ball_Y >= 1 + playersMutex->ball_Y_speed)
- {
+ } else {
+ if(playersMutex->ball_Y >= 1 + playersMutex->ball_Y_speed) {
playersMutex->ball_Y -= playersMutex->ball_Y_speed;
- }
- else
- {
+ } else {
playersMutex->ball_Y = 1;
playersMutex->ball_X_speed = changeSpeed();
playersMutex->ball_Y_speed = changeSpeed();
diff --git a/applications/plugins/protoview/README.md b/applications/plugins/protoview/README.md
index 4b8a3c3a0e..a12aec979b 100644
--- a/applications/plugins/protoview/README.md
+++ b/applications/plugins/protoview/README.md
@@ -6,11 +6,25 @@ the car keys), the curious person is left wondering what the device is
sending at all. Using ProtoView she or he can visualize the high and low pulses
like in the example image below (showing a Volkswagen key in 2FSK):
-![ProtoView screenshot](/images/ProtoViewSignal.jpg)
+![ProtoView screenshot raw signal](/images/protoview_1.jpg)
This is often enough to make an initial idea about the encoding used
and if the selected modulation is correct.
+Other than that, ProtoView is able to decode a few interesting protocols:
+
+* TPMS sensors: Renault, Toyota, Schrader, Citroen, Ford.
+* Microchip HSC200/300/301 Keeloq protocol.
+* Oregon thermometer protocol 2.
+* PT2262, SC5262 based remotes.
+* ... more will be implemented soon, hopefully. Send PRs :)
+
+![ProtoView screenshot Renault TPMS data](/images/protoview_2.jpg)
+
+The app implements a framework that makes adding and experimenting with new
+protocols very simple. Check the `protocols` directory to see how the
+API works.
+
The secondary goal of ProtoView is to provide a somewhat-documented application
for the Flipper (even if ProtoView is a pretty atypical application: doesn't make use of the standard widgets and other abstractions provded by the framework).
Many apps dealing with the *subghz subsystem* (the Flipper
@@ -40,7 +54,7 @@ encodings are somewhat self-clocked, so they tend to have just two or
three classes of pulse lengths.
However often pulses of the same theoretical
-length have slightly different lenghts in the case of high and low level
+length have slightly different lengths in the case of high and low level
(RF on or off), so we classify them separately for robustness.
# Usage
@@ -55,6 +69,10 @@ Under the detected sequence, you will see a small triangle marking a
specific sample. This mark means that the sequence looked coherent up
to that point, and starting from there it could be just noise.
+If the protocol is decoded, the bottom-left corner of the screen
+will show the name of the protocol, and going in the next screen
+with the right arrow will show information about the decoded signal.
+
In the bottom-right corner the application displays an amount of time
in microseconds. This is the average length of the shortest pulse length
detected among the three classes. Usually the *data rate* of the protocol
@@ -67,7 +85,8 @@ Things to investigate:
* Many cheap remotes (gate openers, remotes, ...) are on the 433.92Mhz or nearby and use OOK modulation.
* Weather stations are often too in the 433.92Mhz OOK.
-* For car keys, try 443.92 OOK650 and 868.35 Mhz in OOK or 2FSK.
+* For car keys, try 433.92 OOK650 and 868.35 Mhz in OOK or 2FSK.
+* For TPMS try 433.92 in TPMS modulation (FSK optimized for these signals).
# Installing the app from source
@@ -101,3 +120,11 @@ The code is released under the BSD license.
# Disclaimer
This application is only provided as an educational tool. The author is not liable in case the application is used to reverse engineer protocols protected by IP or for any other illegal purpose.
+
+# Credits
+
+A big thank you to the RTL433 author, [Benjamin Larsson](https://github.com/merbanan). I used the code and tools he developed in many ways:
+* To capture TPMS data with rtl433 and save to a file, to later play the IQ files and speedup the development.
+* As a sourve of documentation for protocols.
+* As an awesome way to visualize and understand protocols, via [these great web tools](https://triq.org/).
+* To have tons of fun with RTLSDR in general, now and in the past.
diff --git a/applications/plugins/protoview/TODO b/applications/plugins/protoview/TODO
index 0003ccd385..feb7b0743e 100644
--- a/applications/plugins/protoview/TODO
+++ b/applications/plugins/protoview/TODO
@@ -1,20 +1,14 @@
Core improvements
=================
-- Detection of non Manchester and non RZ encoded signals. Not sure if there are any signals that are not self clocked widely used in RF. Note that the current approach already detects encodings using short high + long low and long high + short low to encode 0 and 1. In addition to the current classifier, it is possible to add one that checks for a sequence of pulses that are all multiples of some base length. This should detect, for instance, even NRZ encodings where 1 and 0 are just clocked as they are.
-
-- Views on-enter on-exit.
-
-Features
-========
-
-- Help screen (with press ok for next page).
-- Detect the line code used and try to decode the message as hex dump.
-- Pressing right/left you browse different modes:
- * Current best signal pulse classes.
- * Raw square wave display. Central button freezes and resumes (toggle). When frozen we display "paused" (inverted) on the low part of the screen.
-
-Screens sequence (user can navigate with <- and ->):
-
- (default)
-[settings] <> [freq] <> [pulses view] <> [raw square view] <> [signal info]
+- Decoders should declare the short pulse duration range, so that
+ only matching decoders will be called. This may also be useful for
+ modulations. If a signal is only OOK, does not make much sense to
+ call it for samples obtained in FSK.
+- More protocols, especially TPMS and other stuff not supported right now
+ by the Flipper.
+- CC1101 synchronous mode with protocol hopping?
+- Protocols decoded can register actions, for instance to generate
+ sub files with modified signal and so forth.
+- Optimize memory usage storing raw samples in a bitfield: 15 bits
+ duration, 1 bit level.
diff --git a/applications/plugins/protoview/app.c b/applications/plugins/protoview/app.c
index 4e6b2ff3e9..ea4e366b8d 100644
--- a/applications/plugins/protoview/app.c
+++ b/applications/plugins/protoview/app.c
@@ -89,6 +89,12 @@ static void app_switch_view(ProtoViewApp *app, SwitchViewDirection dir) {
/* Call the enter/exit view callbacks if needed. */
if (old == ViewDirectSampling) view_exit_direct_sampling(app);
if (new == ViewDirectSampling) view_enter_direct_sampling(app);
+ /* The frequency/modulation settings are actually a single view:
+ * as long as the user stays between the two modes of this view we
+ * don't need to call the exit-view callback. */
+ if ((old == ViewFrequencySettings && new != ViewModulationSettings) ||
+ (old == ViewModulationSettings && new != ViewFrequencySettings))
+ view_exit_settings(app);
}
/* Allocate the application state and initialize a number of stuff.
@@ -112,9 +118,11 @@ ProtoViewApp* protoview_app_alloc() {
gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen);
app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
app->current_view = ViewRawPulses;
+ app->direct_sampling_enabled = false;
// Signal found and visualization defaults
app->signal_bestlen = 0;
+ app->signal_last_scan_idx = 0;
app->signal_decoded = false;
app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE;
app->signal_offset = 0;
@@ -123,20 +131,24 @@ ProtoViewApp* protoview_app_alloc() {
app->txrx = malloc(sizeof(ProtoViewTxRx));
/* Setup rx worker and environment. */
+ app->txrx->freq_mod_changed = false;
+ app->txrx->debug_timer_sampling = false;
+ app->txrx->last_g0_change_time = DWT->CYCCNT;
+ app->txrx->last_g0_value = false;
app->txrx->worker = subghz_worker_alloc();
-
#ifdef PROTOVIEW_DISABLE_SUBGHZ_FILTER
app->txrx->worker->filter_running = 0;
#endif
-
app->txrx->environment = subghz_environment_alloc();
subghz_environment_set_protocol_registry(
app->txrx->environment, (void*)&protoview_protocol_registry);
- app->txrx->receiver = subghz_receiver_alloc_init(app->txrx->environment);
-
- subghz_receiver_set_filter(app->txrx->receiver, SubGhzProtocolFlag_Decodable);
+ app->txrx->receiver =
+ subghz_receiver_alloc_init(app->txrx->environment);
+ subghz_receiver_set_filter(app->txrx->receiver,
+ SubGhzProtocolFlag_Decodable);
subghz_worker_set_overrun_callback(
- app->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset);
+ app->txrx->worker,
+ (SubGhzWorkerOverrunCallback)subghz_receiver_reset);
subghz_worker_set_pair_callback(
app->txrx->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode);
subghz_worker_set_context(app->txrx->worker, app->txrx->receiver);
@@ -171,9 +183,11 @@ void protoview_app_free(ProtoViewApp *app) {
subghz_setting_free(app->setting);
// Worker stuff.
- subghz_receiver_free(app->txrx->receiver);
- subghz_environment_free(app->txrx->environment);
- subghz_worker_free(app->txrx->worker);
+ if (!app->txrx->debug_timer_sampling) {
+ subghz_receiver_free(app->txrx->receiver);
+ subghz_environment_free(app->txrx->environment);
+ subghz_worker_free(app->txrx->worker);
+ }
free(app->txrx);
// Raw samples buffers.
@@ -189,6 +203,20 @@ void protoview_app_free(ProtoViewApp *app) {
* function is to scan for signals and set DetectedSamples. */
static void timer_callback(void *ctx) {
ProtoViewApp *app = ctx;
+ uint32_t delta, lastidx = app->signal_last_scan_idx;
+
+ /* scan_for_signal(), called by this function, deals with a
+ * circular buffer. To never miss anything, even if a signal spawns
+ * cross-boundaries, it is enough if we scan each time the buffer fills
+ * for 50% more compared to the last scan. Thanks to this check we
+ * can avoid scanning too many times to just find the same data. */
+ if (lastidx < RawSamples->idx) {
+ delta = RawSamples->idx - lastidx;
+ } else {
+ delta = RawSamples->total - lastidx + RawSamples->idx;
+ }
+ if (delta < RawSamples->total/2) return;
+ app->signal_last_scan_idx = RawSamples->idx;
scan_for_signal(app);
}
@@ -198,7 +226,7 @@ int32_t protoview_app_entry(void* p) {
/* Create a timer. We do data analysis in the callback. */
FuriTimer *timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, app);
- furi_timer_start(timer, furi_kernel_get_tick_frequency() / 4);
+ furi_timer_start(timer, furi_kernel_get_tick_frequency() / 8);
/* Start listening to signals immediately. */
radio_begin(app);
diff --git a/applications/plugins/protoview/app.h b/applications/plugins/protoview/app.h
index 4ad0a9196d..52b0bff5b6 100644
--- a/applications/plugins/protoview/app.h
+++ b/applications/plugins/protoview/app.h
@@ -65,10 +65,21 @@ extern ProtoViewModulation ProtoViewModulations[]; /* In app_subghz.c */
* It receives data and we get our protocol "feed" callback called
* with the level (1 or 0) and duration. */
struct ProtoViewTxRx {
+ bool freq_mod_changed; /* The user changed frequency and/or modulation
+ from the interface. There is to restart the
+ radio with the right parameters. */
SubGhzWorker* worker; /* Our background worker. */
SubGhzEnvironment* environment;
SubGhzReceiver* receiver;
TxRxState txrx_state; /* Receiving, idle or sleeping? */
+
+ /* Timer sampling mode state. */
+ bool debug_timer_sampling; /* Read data from GDO0 in a busy loop. Only
+ for testing. */
+ uint32_t last_g0_change_time; /* Last high->low (or reverse) switch. */
+ bool last_g0_value; /* Current value (high or low): we are
+ checking the duration in the timer
+ handler. */
};
typedef struct ProtoViewTxRx ProtoViewTxRx;
@@ -85,6 +96,7 @@ typedef struct ProtoViewMsgInfo {
char info1[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 1. */
char info2[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 2. */
char info3[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 3. */
+ char info4[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 4. */
uint64_t len; /* Bits consumed from the stream. */
} ProtoViewMsgInfo;
@@ -103,8 +115,12 @@ struct ProtoViewApp {
/* Generic app state. */
int running; /* Once false exists the app. */
uint32_t signal_bestlen; /* Longest coherent signal observed so far. */
+ uint32_t signal_last_scan_idx; /* Index of the buffer last time we
+ performed the scan. */
bool signal_decoded; /* Was the current signal decoded? */
ProtoViewMsgInfo signal_info; /* Decoded message, if signal_decoded true. */
+ bool direct_sampling_enabled; /* This special view needs an explicit
+ acknowledge to work. */
/* Raw view apps state. */
uint32_t us_scale; /* microseconds per pixel. */
@@ -136,6 +152,8 @@ uint32_t radio_rx(ProtoViewApp* app);
void radio_idle(ProtoViewApp* app);
void radio_rx_end(ProtoViewApp* app);
void radio_sleep(ProtoViewApp* app);
+void raw_sampling_worker_start(ProtoViewApp *app);
+void raw_sampling_worker_stop(ProtoViewApp *app);
/* signal.c */
uint32_t duration_delta(uint32_t a, uint32_t b);
@@ -144,10 +162,11 @@ void scan_for_signal(ProtoViewApp *app);
bool bitmap_get(uint8_t *b, uint32_t blen, uint32_t bitpos);
void bitmap_set(uint8_t *b, uint32_t blen, uint32_t bitpos, bool val);
void bitmap_set_pattern(uint8_t *b, uint32_t blen, const char *pat);
-void bitmap_invert_bytes_bits(uint8_t *p, uint32_t len);
+void bitmap_reverse_bytes(uint8_t *p, uint32_t len);
bool bitmap_match_bits(uint8_t *b, uint32_t blen, uint32_t bitpos, const char *bits);
uint32_t bitmap_seek_bits(uint8_t *b, uint32_t blen, uint32_t startpos, uint32_t maxbits, const char *bits);
uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t offset, const char *zero_pattern, const char *one_pattern);
+uint32_t convert_from_diff_manchester(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, bool previous);
/* view_*.c */
void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app);
@@ -160,6 +179,10 @@ void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app);
void process_input_direct_sampling(ProtoViewApp *app, InputEvent input);
void view_enter_direct_sampling(ProtoViewApp *app);
void view_exit_direct_sampling(ProtoViewApp *app);
+void view_exit_settings(ProtoViewApp *app);
/* ui.c */
void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color);
+
+/* crc.c */
+uint8_t crc8(const uint8_t *data, size_t len, uint8_t init, uint8_t poly);
diff --git a/applications/plugins/protoview/app_buffer.c b/applications/plugins/protoview/app_buffer.c
index df2e7074e9..7c069fd91f 100644
--- a/applications/plugins/protoview/app_buffer.c
+++ b/applications/plugins/protoview/app_buffer.c
@@ -29,8 +29,7 @@ void raw_samples_reset(RawSamplesBuffer *s) {
s->total = RAW_SAMPLES_NUM;
s->idx = 0;
s->short_pulse_dur = 0;
- memset(s->level,0,sizeof(s->level));
- memset(s->dur,0,sizeof(s->dur));
+ memset(s->samples,0,sizeof(s->samples));
furi_mutex_release(s->mutex);
}
@@ -43,8 +42,8 @@ void raw_samples_center(RawSamplesBuffer *s, uint32_t offset) {
/* Add the specified sample in the circular buffer. */
void raw_samples_add(RawSamplesBuffer *s, bool level, uint32_t dur) {
furi_mutex_acquire(s->mutex,FuriWaitForever);
- s->level[s->idx] = level;
- s->dur[s->idx] = dur;
+ s->samples[s->idx].level = level;
+ s->samples[s->idx].dur = dur;
s->idx = (s->idx+1) % RAW_SAMPLES_NUM;
furi_mutex_release(s->mutex);
}
@@ -55,8 +54,8 @@ void raw_samples_get(RawSamplesBuffer *s, uint32_t idx, bool *level, uint32_t *d
{
furi_mutex_acquire(s->mutex,FuriWaitForever);
idx = (s->idx + idx) % RAW_SAMPLES_NUM;
- *level = s->level[idx];
- *dur = s->dur[idx];
+ *level = s->samples[idx].level;
+ *dur = s->samples[idx].dur;
furi_mutex_release(s->mutex);
}
@@ -66,8 +65,7 @@ void raw_samples_copy(RawSamplesBuffer *dst, RawSamplesBuffer *src) {
furi_mutex_acquire(dst->mutex,FuriWaitForever);
dst->idx = src->idx;
dst->short_pulse_dur = src->short_pulse_dur;
- memcpy(dst->level,src->level,sizeof(dst->level));
- memcpy(dst->dur,src->dur,sizeof(dst->dur));
+ memcpy(dst->samples,src->samples,sizeof(dst->samples));
furi_mutex_release(src->mutex);
furi_mutex_release(dst->mutex);
}
diff --git a/applications/plugins/protoview/app_buffer.h b/applications/plugins/protoview/app_buffer.h
index 5d997d02eb..3a34d50f8d 100644
--- a/applications/plugins/protoview/app_buffer.h
+++ b/applications/plugins/protoview/app_buffer.h
@@ -7,11 +7,12 @@
#define RAW_SAMPLES_NUM 2048 /* Use a power of two: we take the modulo
of the index quite often to normalize inside
the range, and division is slow. */
-
typedef struct RawSamplesBuffer {
FuriMutex *mutex;
- uint8_t level[RAW_SAMPLES_NUM];
- uint32_t dur[RAW_SAMPLES_NUM];
+ struct {
+ uint16_t level:1;
+ uint16_t dur:15;
+ } samples[RAW_SAMPLES_NUM];
uint32_t idx; /* Current idx (next to write). */
uint32_t total; /* Total samples: same as RAW_SAMPLES_NUM, we provide
this field for a cleaner interface with the user, but
diff --git a/applications/plugins/protoview/app_subghz.c b/applications/plugins/protoview/app_subghz.c
index 2bb87af7ad..ec7724b137 100644
--- a/applications/plugins/protoview/app_subghz.c
+++ b/applications/plugins/protoview/app_subghz.c
@@ -5,6 +5,12 @@
#include "custom_presets.h"
#include
+#include
+#include
+#include
+
+void raw_sampling_worker_start(ProtoViewApp *app);
+void raw_sampling_worker_stop(ProtoViewApp *app);
ProtoViewModulation ProtoViewModulations[] = {
{"OOK 650Khz", FuriHalSubGhzPresetOok650Async, NULL},
@@ -13,8 +19,10 @@ ProtoViewModulation ProtoViewModulations[] = {
{"2FSK 47.6Khz", FuriHalSubGhzPreset2FSKDev476Async, NULL},
{"MSK", FuriHalSubGhzPresetMSK99_97KbAsync, NULL},
{"GFSK", FuriHalSubGhzPresetGFSK9_99KbAsync, NULL},
- {"TPMS 1 (FSK)", 0, (uint8_t*)protoview_subghz_tpms1_async_regs},
- {"TPMS 2 (FSK)", 0, (uint8_t*)protoview_subghz_tpms2_async_regs},
+ {"TPMS 1 (FSK)", 0, (uint8_t*)protoview_subghz_tpms1_fsk_async_regs},
+ {"TPMS 2 (OOK)", 0, (uint8_t*)protoview_subghz_tpms2_ook_async_regs},
+ {"TPMS 3 (FSK)", 0, (uint8_t*)protoview_subghz_tpms3_fsk_async_regs},
+ {"TPMS 4 (FSK)", 0, (uint8_t*)protoview_subghz_tpms4_fsk_async_regs},
{NULL, 0, NULL} /* End of list sentinel. */
};
@@ -53,9 +61,14 @@ uint32_t radio_rx(ProtoViewApp* app) {
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
furi_hal_subghz_flush_rx();
furi_hal_subghz_rx();
+ if (!app->txrx->debug_timer_sampling) {
- furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, app->txrx->worker);
- subghz_worker_start(app->txrx->worker);
+ furi_hal_subghz_start_async_rx(subghz_worker_rx_callback,
+ app->txrx->worker);
+ subghz_worker_start(app->txrx->worker);
+ } else {
+ raw_sampling_worker_start(app);
+ }
app->txrx->txrx_state = TxRxStateRx;
return value;
}
@@ -64,9 +77,13 @@ uint32_t radio_rx(ProtoViewApp* app) {
void radio_rx_end(ProtoViewApp* app) {
furi_assert(app);
if (app->txrx->txrx_state == TxRxStateRx) {
- if(subghz_worker_is_running(app->txrx->worker)) {
- subghz_worker_stop(app->txrx->worker);
- furi_hal_subghz_stop_async_rx();
+ if (!app->txrx->debug_timer_sampling) {
+ if(subghz_worker_is_running(app->txrx->worker)) {
+ subghz_worker_stop(app->txrx->worker);
+ furi_hal_subghz_stop_async_rx();
+ }
+ } else {
+ raw_sampling_worker_stop(app);
}
}
furi_hal_subghz_idle();
@@ -84,3 +101,55 @@ void radio_sleep(ProtoViewApp* app) {
furi_hal_subghz_sleep();
app->txrx->txrx_state = TxRxStateSleep;
}
+
+/* ============================= Raw sampling mode =============================
+ * This is a special mode that uses a high frequency timer to sample the
+ * CC1101 pin directly. It's useful for debugging purposes when we want
+ * to get the raw data from the chip and completely bypass the subghz
+ * Flipper system.
+ * ===========================================================================*/
+
+void protoview_timer_isr(void *ctx) {
+ ProtoViewApp *app = ctx;
+
+ bool level = furi_hal_gpio_read(&gpio_cc1101_g0);
+ if (app->txrx->last_g0_value != level) {
+ uint32_t now = DWT->CYCCNT;
+ uint32_t dur = now - app->txrx->last_g0_change_time;
+ dur /= furi_hal_cortex_instructions_per_microsecond();
+ if (dur > 15000) dur = 15000;
+ raw_samples_add(RawSamples, app->txrx->last_g0_value, dur);
+ app->txrx->last_g0_value = level;
+ app->txrx->last_g0_change_time = now;
+ }
+ LL_TIM_ClearFlag_UPDATE(TIM2);
+}
+
+void raw_sampling_worker_start(ProtoViewApp *app) {
+ UNUSED(app);
+
+ LL_TIM_InitTypeDef tim_init = {
+ .Prescaler = 63, /* CPU frequency is ~64Mhz. */
+ .CounterMode = LL_TIM_COUNTERMODE_UP,
+ .Autoreload = 5, /* Sample every 5 us */
+ };
+
+ LL_TIM_Init(TIM2, &tim_init);
+ LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL);
+ LL_TIM_DisableCounter(TIM2);
+ LL_TIM_SetCounter(TIM2, 0);
+ furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, protoview_timer_isr, app);
+ LL_TIM_EnableIT_UPDATE(TIM2);
+ LL_TIM_EnableCounter(TIM2);
+ FURI_LOG_E(TAG, "Timer enabled");
+}
+
+void raw_sampling_worker_stop(ProtoViewApp *app) {
+ UNUSED(app);
+ FURI_CRITICAL_ENTER();
+ LL_TIM_DisableCounter(TIM2);
+ LL_TIM_DisableIT_UPDATE(TIM2);
+ furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
+ LL_TIM_DeInit(TIM2);
+ FURI_CRITICAL_EXIT();
+}
diff --git a/applications/plugins/protoview/application.fam b/applications/plugins/protoview/application.fam
index df2a772612..6cd31372e2 100644
--- a/applications/plugins/protoview/application.fam
+++ b/applications/plugins/protoview/application.fam
@@ -1,6 +1,6 @@
App(
appid="protoview",
- name="Protocols visualizer",
+ name="ProtoView",
apptype=FlipperAppType.EXTERNAL,
entry_point="protoview_app_entry",
cdefines=["APP_PROTOVIEW"],
diff --git a/applications/plugins/protoview/binaries/protoview.fap b/applications/plugins/protoview/binaries/protoview.fap
index f5a03056e1..696dc523ef 100644
Binary files a/applications/plugins/protoview/binaries/protoview.fap and b/applications/plugins/protoview/binaries/protoview.fap differ
diff --git a/applications/plugins/protoview/binaries/update.sh b/applications/plugins/protoview/binaries/update.sh
new file mode 100644
index 0000000000..5a4ea0b4ea
--- /dev/null
+++ b/applications/plugins/protoview/binaries/update.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+BINPATH="/Users/antirez/hack/flipper/official/build/f7-firmware-D/.extapps/protoview.fap"
+cp $BINPATH .
+git commit -a -m 'Binary file updated.'
diff --git a/applications/plugins/protoview/crc.c b/applications/plugins/protoview/crc.c
new file mode 100644
index 0000000000..38a809e103
--- /dev/null
+++ b/applications/plugins/protoview/crc.c
@@ -0,0 +1,20 @@
+#include
+#include
+
+/* CRC8 with the specified initialization value 'init' and
+ * polynomial 'poly'. */
+uint8_t crc8(const uint8_t *data, size_t len, uint8_t init, uint8_t poly)
+{
+ uint8_t crc = init;
+ size_t i, j;
+ for (i = 0; i < len; i++) {
+ crc ^= data[i];
+ for (j = 0; j < 8; j++) {
+ if ((crc & 0x80) != 0)
+ crc = (uint8_t)((crc << 1) ^ poly);
+ else
+ crc <<= 1;
+ }
+ }
+ return crc;
+}
diff --git a/applications/plugins/protoview/custom_presets.h b/applications/plugins/protoview/custom_presets.h
index d34446f483..713827d228 100644
--- a/applications/plugins/protoview/custom_presets.h
+++ b/applications/plugins/protoview/custom_presets.h
@@ -1,8 +1,8 @@
#include
-/* This is how to configure registers MDMCFG3 and MDMCFG4.
+/* ========================== DATA RATE SETTINGS ===============================
*
- * Data rate kBaud setting:
+ * This is how to configure registers MDMCFG3 and MDMCFG4.
*
* MDMCFG3 is the data rate mantissa, the exponent is in MDMCFG4,
* last 4 bits of the register.
@@ -11,10 +11,12 @@
*
* ((256+MDMCFG3)*(2^MDMCFG4:0..3bits)) / 2^28 * 26000000.
*
- * For instance for the default values of MDMCFG3 (34) and MDMCFG4 (12):
+ * For instance for the default values of MDMCFG3[0..3] (34) and MDMCFG4 (12):
*
* ((256+34)*(2^12))/(2^28)*26000000 = 115051.2688000000, that is 115KBaud
*
+ * ============================ BANDWIDTH FILTER ===============================
+ *
* Bandwidth filter setting:
*
* BW filter as just 16 possibilities depending on how the first nibble
@@ -38,10 +40,29 @@
* d 82 khz
* e 68 khz
* f 58 khz
+ *
+ * ============================== FSK DEVIATION ================================
+ *
+ * FSK deviation is controlled by the DEVIATION register. In Ruby:
+ *
+ * dev = (26000000.0/2**17)*(8+(deviation&7))*(2**(deviation>>4&7))
+ *
+ * deviation&7 (last three bits) is the deviation mantissa, while
+ * deviation>>4&7 (bits 6,5,4) are the exponent.
+ *
+ * Deviations values according to certain configuration of DEVIATION:
+ *
+ * 0x04 -> 2.380371 kHz
+ * 0x24 -> 9.521484 kHz
+ * 0x34 -> 19.042969 Khz
+ * 0x40 -> 25.390625 Khz
+ * 0x43 -> 34.912109 Khz
+ * 0x45 -> 41.259765 Khz
+ * 0x47 -> 47.607422 kHz
*/
/* 20 KBaud, 2FSK, 28.56 kHz deviation, 325 Khz bandwidth filter. */
-static uint8_t protoview_subghz_tpms1_async_regs[][2] = {
+static uint8_t protoview_subghz_tpms1_fsk_async_regs[][2] = {
/* GPIO GD0 */
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
@@ -85,8 +106,55 @@ static uint8_t protoview_subghz_tpms1_async_regs[][2] = {
{0, 0},
};
-/* 40 KBaud, 2FSK, 19 kHz deviation, 102 Khz bandwidth filter. */
-static uint8_t protoview_subghz_tpms2_async_regs[][2] = {
+/* This is like the default Flipper OOK 640Khz bandwidth preset, but
+ * the bandwidth is changed to 10kBaud to accomodate TPMS frequency. */
+static const uint8_t protoview_subghz_tpms2_ook_async_regs[][2] = {
+ /* GPIO GD0 */
+ {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
+
+ /* FIFO and internals */
+ {CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION
+
+ /* Packet engine */
+ {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
+
+ /* Frequency Synthesizer Control */
+ {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
+
+ // Modem Configuration
+ {CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz
+ {CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz
+ {CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync
+ {CC1101_MDMCFG3, 0x93}, // Data rate is 10kBaud
+ {CC1101_MDMCFG4, 0x18}, // Rx BW filter is 650.000kHz
+
+ /* Main Radio Control State Machine */
+ {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
+
+ /* Frequency Offset Compensation Configuration */
+ {CC1101_FOCCFG,
+ 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
+
+ /* Automatic Gain Control */
+ {CC1101_AGCCTRL0,
+ 0x91}, // 10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
+ {CC1101_AGCCTRL1,
+ 0x0}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
+ {CC1101_AGCCTRL2, 0x07}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB
+
+ /* Wake on radio and timeouts control */
+ {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
+
+ /* Frontend configuration */
+ {CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1]
+ {CC1101_FREND1, 0xB6}, //
+
+ /* End */
+ {0, 0},
+};
+
+/* 40 KBaud, 2FSK, 28 kHz deviation, 270 Khz bandwidth filter. */
+static uint8_t protoview_subghz_tpms3_fsk_async_regs[][2] = {
/* GPIO GD0 */
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
@@ -103,7 +171,7 @@ static uint8_t protoview_subghz_tpms2_async_regs[][2] = {
{CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized). Other code reading TPMS uses GFSK, but should be the same when in RX mode.
{CC1101_MDMCFG3, 0x93}, // Data rate is 40kBaud
{CC1101_MDMCFG4, 0x6A}, // 6 = BW filter 270kHz, A = Data rate exp
- {CC1101_DEVIATN, 0x41}, // Deviation 19.042 kHz
+ {CC1101_DEVIATN, 0x41}, // Deviation 28kHz
/* Main Radio Control State Machine */
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
@@ -130,3 +198,47 @@ static uint8_t protoview_subghz_tpms2_async_regs[][2] = {
{0, 0},
};
+/* FSK 19k dev, 325 Khz filter, 20kBaud. Works well with Toyota. */
+static uint8_t protoview_subghz_tpms4_fsk_async_regs[][2] = {
+ /* GPIO GD0 */
+ {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
+
+ /* Frequency Synthesizer Control */
+ {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
+
+ /* Packet engine */
+ {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
+ {CC1101_PKTCTRL1, 0x04},
+
+ // // Modem Configuration
+ {CC1101_MDMCFG0, 0x00},
+ {CC1101_MDMCFG1, 0x02}, // 2 is the channel spacing exponet: not used
+ {CC1101_MDMCFG2, 0x10}, // GFSK without any other check
+ {CC1101_MDMCFG3, 0x93}, // Data rate is 20kBaud
+ {CC1101_MDMCFG4, 0x59}, // Rx bandwidth filter is 325 kHz
+ {CC1101_DEVIATN, 0x34}, // Deviation 19.04 Khz.
+
+ /* Main Radio Control State Machine */
+ {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
+
+ /* Frequency Offset Compensation Configuration */
+ {CC1101_FOCCFG,
+ 0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
+
+ /* Automatic Gain Control */
+ {CC1101_AGCCTRL0, 0x80},
+ {CC1101_AGCCTRL1, 0x58},
+ {CC1101_AGCCTRL2, 0x87},
+
+ /* Wake on radio and timeouts control */
+ {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
+
+ /* Frontend configuration */
+ {CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer
+ {CC1101_FREND1, 0x56},
+
+ /* End */
+ {0, 0},
+};
+
+
diff --git a/applications/plugins/protoview/proto.c b/applications/plugins/protoview/data_feed.c
similarity index 100%
rename from applications/plugins/protoview/proto.c
rename to applications/plugins/protoview/data_feed.c
diff --git a/applications/plugins/protoview/images/protoview_1.jpg b/applications/plugins/protoview/images/protoview_1.jpg
new file mode 100644
index 0000000000..10d9d6ec55
Binary files /dev/null and b/applications/plugins/protoview/images/protoview_1.jpg differ
diff --git a/applications/plugins/protoview/images/protoview_2.jpg b/applications/plugins/protoview/images/protoview_2.jpg
new file mode 100644
index 0000000000..2560297707
Binary files /dev/null and b/applications/plugins/protoview/images/protoview_2.jpg differ
diff --git a/applications/plugins/protoview/protocols/b4b1.c b/applications/plugins/protoview/protocols/b4b1.c
index 6977c0eb35..2bed2ac32f 100644
--- a/applications/plugins/protoview/protocols/b4b1.c
+++ b/applications/plugins/protoview/protocols/b4b1.c
@@ -1,7 +1,7 @@
/* PT/SC remotes. Usually 443.92 Mhz OOK.
*
* This line code is used in many remotes such as Princeton chips
- * named PT, Silian Microelectronics SC5262 and others.
+ * named PT2262, Silian Microelectronics SC5262 and others.
* Basically every 4 pulsee represent a bit, where 1000 means 0, and
* 1110 means 1. Usually we can read 24 bits of data.
* In this specific implementation we check for a prelude that is
diff --git a/applications/plugins/protoview/protocols/keeloq.c b/applications/plugins/protoview/protocols/keeloq.c
new file mode 100644
index 0000000000..cf0b7682f5
--- /dev/null
+++ b/applications/plugins/protoview/protocols/keeloq.c
@@ -0,0 +1,87 @@
+/* Microchip HCS200/HCS300/HSC301 KeeLoq, rolling code remotes.
+ *
+ * Usually 443.92 Mhz OOK, ~200us or ~400us pulse len, depending
+ * on the configuration.
+ *
+ * Preamble: 12 pairs of alternating pulse/gap.
+ * Sync: long gap of around 10 times the duration of the short-pulse.
+ * Data: pulse width encoded data. Each bit takes three cycles:
+ *
+ * 0 = 110
+ * 1 = 100
+ *
+ * There are a total of 66 bits transmitted.
+ * 0..31: 32 bits of encrypted rolling code.
+ * 32..59: Remote ID, 28 bits
+ * 60..63: Buttons pressed
+ * 64..64: Low battery if set
+ * 65..65: Always set to 1
+ *
+ * Bits in bytes are inverted: least significant bit is first.
+ * For some reason there is no checksum whatsoever, so we only decode
+ * if we find everything well formed.
+ */
+
+#include "../app.h"
+
+static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
+
+ /* In the sync pattern, we require the 12 high/low pulses and at least
+ * half the gap we expect (5 pulses times, one is the final zero in the
+ * 24 symbols high/low sequence, then other 4). */
+ const char *sync_pattern = "101010101010101010101010" "0000";
+ uint8_t sync_len = 24+4;
+ if (numbits-sync_len+sync_len < 3*66) return false;
+ uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
+ if (off == BITMAP_SEEK_NOT_FOUND) return false;
+ off += sync_len;
+
+ /* Now there is half the gap left, but we allow from 3 to 7, instead of 5
+ * symbols of gap, to avoid missing the signal for a matter of wrong
+ * timing. */
+ uint8_t gap_len = 0;
+ while(gap_len <= 7 && bitmap_get(bits,numbytes,off+gap_len) == 0)
+ gap_len++;
+ if (gap_len < 3 || gap_len > 7) return false;
+
+ off += gap_len;
+ FURI_LOG_E(TAG, "Keeloq preamble+sync found");
+
+ uint8_t raw[9] = {0};
+ uint32_t decoded =
+ convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
+ "110","100"); /* Pulse width modulation. */
+ FURI_LOG_E(TAG, "Keeloq decoded bits: %lu", decoded);
+
+ if (decoded < 66) return false; /* Require the full 66 bits. */
+ bitmap_reverse_bytes(raw,sizeof(raw)); /* Keeloq is LSB first. */
+
+ int buttons = raw[7]>>4;
+ int s3 = (buttons&1) != 0;
+ int s0 = (buttons&2) != 0;
+ int s1 = (buttons&4) != 0;
+ int s2 = (buttons&8) != 0;
+
+ int remote_id = ((raw[7]&0x0f) << 24) |
+ (raw[6] << 16) |
+ (raw[5] << 8) |
+ (raw[4] << 0);
+ int lowbat = raw[8]&0x80;
+
+ snprintf(info->name,sizeof(info->name),"%s","Keeloq remote");
+ snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
+ raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
+ raw[6],raw[7],raw[8]);
+ snprintf(info->info1,sizeof(info->info1),"Encrpyted %02X%02X%02X%02X",
+ raw[3],raw[2],raw[1],raw[0]);
+ snprintf(info->info2,sizeof(info->info2),"ID %08X", remote_id);
+ snprintf(info->info3,sizeof(info->info3),"s0-s3: %d%d%d%d",
+ s0,s1,s2,s3);
+ snprintf(info->info4,sizeof(info->info4),"Low battery? %s",
+ lowbat ? "yes" : "no");
+ return true;
+}
+
+ProtoViewDecoder KeeloqDecoder = {
+ "Keeloq", decode
+};
diff --git a/applications/plugins/protoview/protocols/oregon2.txt b/applications/plugins/protoview/protocols/oregon2.txt
deleted file mode 100644
index 3626314311..0000000000
--- a/applications/plugins/protoview/protocols/oregon2.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-11001100110011001100110011001100110011001100110011001100110 (Preamble)
-10 01 01 10 10 01 01 10 (Sync)
-01 10 10 01 10 01 10 01 01 10 10 01 01 10 01 10 10 01 01 10 10 01 10 01 10 01 10 01 10 01 10 01 01 10 10 01 10 01 10 01 01 10 01 10 01 10 01 10 01 10 01 10 10 01 01 10 01 10 10 01 10 01 10 01 10 01 10 01 01 10 10 01 10 01 01 10 01 10 10 01 01 10 10 01 10 01 10 01 10 01 10 01 10 01 11 0
-
-We need to seek the following bytes: 01100110 01100110 10010110 10010110
- 0x66 0x66 96 96
diff --git a/applications/plugins/protoview/protocols/tpms/citroen.c b/applications/plugins/protoview/protocols/tpms/citroen.c
new file mode 100644
index 0000000000..809dc0a252
--- /dev/null
+++ b/applications/plugins/protoview/protocols/tpms/citroen.c
@@ -0,0 +1,60 @@
+/* Citroen TPMS. Usually 443.92 Mhz FSK.
+ *
+ * Preamble of ~14 high/low 52 us pulses
+ * Sync of high 100us pulse then 50us low
+ * Then Manchester bits, 10 bytes total.
+ * Simple XOR checksum. */
+
+#include "../../app.h"
+
+static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
+
+ /* We consider a preamble of 17 symbols. They are more, but the decoding
+ * is more likely to happen if we don't pretend to receive from the
+ * very start of the message. */
+ uint32_t sync_len = 17;
+ const char *sync_pattern = "10101010101010110";
+ if (numbits-sync_len < 8*10) return false; /* Expect 10 bytes. */
+
+ uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
+ if (off == BITMAP_SEEK_NOT_FOUND) return false;
+ FURI_LOG_E(TAG, "Renault TPMS preamble+sync found");
+
+ off += sync_len; /* Skip preamble + sync. */
+
+ uint8_t raw[10];
+ uint32_t decoded =
+ convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
+ "01","10"); /* Manchester. */
+ FURI_LOG_E(TAG, "Citroen TPMS decoded bits: %lu", decoded);
+
+ if (decoded < 8*10) return false; /* Require the full 10 bytes. */
+
+ /* Check the CRC. It's a simple XOR of bytes 1-9, the first byte
+ * is not included. The meaning of the first byte is unknown and
+ * we don't display it. */
+ uint8_t crc = 0;
+ for (int j = 1; j < 10; j++) crc ^= raw[j];
+ if (crc != 0) return false; /* Require sane checksum. */
+
+ int repeat = raw[5] & 0xf;
+ float kpa = (float)raw[6]*1.364;
+ int temp = raw[7]-50;
+ int battery = raw[8]; /* This may be the battery. It's not clear. */
+
+ snprintf(info->name,sizeof(info->name),"%s","Citroen TPMS");
+ snprintf(info->raw,sizeof(info->raw),
+ "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
+ raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
+ raw[6],raw[7],raw[8],raw[9]);
+ snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X",
+ raw[1],raw[2],raw[3],raw[4]);
+ snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
+ snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
+ snprintf(info->info4,sizeof(info->info4),"Repeat %d, Bat %d", repeat, battery);
+ return true;
+}
+
+ProtoViewDecoder CitroenTPMSDecoder = {
+ "Citroen TPMS", decode
+};
diff --git a/applications/plugins/protoview/protocols/tpms/ford.c b/applications/plugins/protoview/protocols/tpms/ford.c
new file mode 100644
index 0000000000..a9c687075d
--- /dev/null
+++ b/applications/plugins/protoview/protocols/tpms/ford.c
@@ -0,0 +1,64 @@
+/* Ford tires TPMS. Usually 443.92 Mhz FSK (in Europe).
+ *
+ * 52 us short pules
+ * Preamble: 0101010101010101010101010101
+ * Sync: 0110 (that is 52 us gap + 104 us pulse + 52 us gap)
+ * Data: 8 bytes Manchester encoded
+ * 01 = zero
+ * 10 = one
+ */
+
+#include "../../app.h"
+
+static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
+
+ const char *sync_pattern = "010101010101" "0110";
+ uint8_t sync_len = 12+4; /* We just use 12 preamble symbols + sync. */
+ if (numbits-sync_len < 8*8) return false;
+
+ uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
+ if (off == BITMAP_SEEK_NOT_FOUND) return false;
+ FURI_LOG_E(TAG, "Fort TPMS preamble+sync found");
+
+ off += sync_len; /* Skip preamble and sync. */
+
+ uint8_t raw[8];
+ uint32_t decoded =
+ convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
+ "01","10"); /* Manchester. */
+ FURI_LOG_E(TAG, "Ford TPMS decoded bits: %lu", decoded);
+
+ if (decoded < 8*8) return false; /* Require the full 8 bytes. */
+
+ /* CRC is just the sum of the first 7 bytes MOD 256. */
+ uint8_t crc = 0;
+ for (int j = 0; j < 7; j++) crc += raw[j];
+ if (crc != raw[7]) return false; /* Require sane CRC. */
+
+ float psi = 0.25 * (((raw[6]&0x20)<<3)|raw[4]);
+
+ /* Temperature apperas to be valid only if the most significant
+ * bit of the value is not set. Otherwise its meaning is unknown.
+ * Likely useful to alternatively send temperature or other info. */
+ int temp = raw[5] & 0x80 ? 0 : raw[5]-56;
+ int flags = raw[5] & 0x7f;
+ int car_moving = (raw[6] & 0x44) == 0x44;
+
+ snprintf(info->name,sizeof(info->name),"%s","Ford TPMS");
+ snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X",
+ raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
+ raw[6],raw[7]);
+ snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X",
+ raw[0],raw[1],raw[2],raw[3]);
+ snprintf(info->info2,sizeof(info->info2),"Pressure %.2f psi", (double)psi);
+ if (temp)
+ snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
+ else
+ snprintf(info->info3,sizeof(info->info3),"Flags %d", flags);
+ snprintf(info->info4,sizeof(info->info4),"Moving %s", car_moving ? "yes" : "no");
+ return true;
+}
+
+ProtoViewDecoder FordTPMSDecoder = {
+ "Ford TPMS", decode
+};
diff --git a/applications/plugins/protoview/protocols/renault_tpms.c b/applications/plugins/protoview/protocols/tpms/renault.c
similarity index 69%
rename from applications/plugins/protoview/protocols/renault_tpms.c
rename to applications/plugins/protoview/protocols/tpms/renault.c
index 3022a5d4e3..4bbe55e42a 100644
--- a/applications/plugins/protoview/protocols/renault_tpms.c
+++ b/applications/plugins/protoview/protocols/tpms/renault.c
@@ -1,16 +1,16 @@
/* Renault tires TPMS. Usually 443.92 Mhz FSK.
*
- * Preamble + marshal-encoded bits. 9 Bytes in total if we don't
- * count the preamble. */
+ * Preamble + sync + Manchester bits. ~48us short pulse.
+ * 9 Bytes in total not counting the preamble. */
-#include "../app.h"
+#include "../../app.h"
#define USE_TEST_VECTOR 0
static const char *test_vector =
- "10101010" "10101010" "10101010" "10101001" // Preamble + sync.
+ "...01010101010101010110" // Preamble + sync
- /* The following is marshal encoded, so each two characters are
- * actaully one bit. 01 = 1, 10 = 0. */
+ /* The following is Marshal encoded, so each two characters are
+ * actaully one bit. 01 = 0, 10 = 1. */
"010110010110" // Flags.
"10011001101010011001" // Pressure, multiply by 0.75 to obtain kpa.
// 244 kpa here.
@@ -29,22 +29,23 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
numbits = strlen(test_vector);
}
- if (numbits < 13*8) return false;
+ if (numbits-12 < 9*8) return false;
- const char *sync_pattern = "10101010" "10101010" "10101010" "10101001";
+ const char *sync_pattern = "01010101010101010110";
uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
if (off == BITMAP_SEEK_NOT_FOUND) return false;
FURI_LOG_E(TAG, "Renault TPMS preamble+sync found");
- off += 32; /* Skip preamble. */
+ off += 20; /* Skip preamble. */
uint8_t raw[9];
uint32_t decoded =
convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
- "10","01"); /* Manchester. */
+ "01","10"); /* Manchester. */
FURI_LOG_E(TAG, "Renault TPMS decoded bits: %lu", decoded);
if (decoded < 8*9) return false; /* Require the full 9 bytes. */
+ if (crc8(raw,8,0,7) != raw[8]) return false; /* Require sane CRC. */
float kpa = 0.75 *((uint32_t)((raw[0]&3)<<8) | raw[1]);
int temp = raw[2]-30;
@@ -53,8 +54,10 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
raw[6],raw[7],raw[8]);
- snprintf(info->info1,sizeof(info->info1),"Pressure %.2f kpa", (double)kpa);
- snprintf(info->info2,sizeof(info->info2),"Temperature %d C", temp);
+ snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X",
+ raw[3],raw[4],raw[5]);
+ snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
+ snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
return true;
}
diff --git a/applications/plugins/protoview/protocols/tpms/schrader.c b/applications/plugins/protoview/protocols/tpms/schrader.c
new file mode 100644
index 0000000000..ab65a92d39
--- /dev/null
+++ b/applications/plugins/protoview/protocols/tpms/schrader.c
@@ -0,0 +1,65 @@
+/* Schrader TPMS. Usually 443.92 Mhz OOK, 120us pulse len.
+ *
+ * 500us high pulse + Preamble + Manchester coded bits where:
+ * 1 = 10
+ * 0 = 01
+ *
+ * 60 bits of data total (first 4 nibbles is the preamble, 0xF).
+ *
+ * Used in FIAT-Chrysler, Mercedes, ... */
+
+#include "../../app.h"
+
+#define USE_TEST_VECTOR 0
+static const char *test_vector = "000000111101010101011010010110010110101001010110100110011001100101010101011010100110100110011010101010101010101010101010101010101010101010101010";
+
+static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
+
+ if (USE_TEST_VECTOR) { /* Test vector to check that decoding works. */
+ bitmap_set_pattern(bits,numbytes,test_vector);
+ numbits = strlen(test_vector);
+ }
+
+ if (numbits < 64) return false; /* Preamble + data. */
+
+ const char *sync_pattern = "1111010101" "01011010";
+ uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
+ if (off == BITMAP_SEEK_NOT_FOUND) return false;
+ FURI_LOG_E(TAG, "Schrader TPMS gap+preamble found");
+
+ off += 10; /* Skip just the long pulse and the first 3 bits of sync, so
+ that we have the first byte of data with the sync nibble
+ 0011 = 0x3. */
+
+ uint8_t raw[8];
+ uint32_t decoded =
+ convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
+ "01","10"); /* Manchester code. */
+ FURI_LOG_E(TAG, "Schrader TPMS decoded bits: %lu", decoded);
+
+ if (decoded < 64) return false; /* Require the full 8 bytes. */
+
+ raw[0] |= 0xf0; // Fix the preamble nibble for checksum computation.
+ uint8_t cksum = crc8(raw,sizeof(raw)-1,0xf0,0x7);
+ if (cksum != raw[7]) {
+ FURI_LOG_E(TAG, "Schrader TPMS checksum mismatch");
+ return false;
+ }
+
+ float kpa = (float)raw[5]*2.5;
+ int temp = raw[6]-50;
+
+ snprintf(info->name,sizeof(info->name),"%s","Schrader TPMS");
+ snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X",
+ raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
+ raw[6],raw[7]);
+ snprintf(info->info1,sizeof(info->info1),"Tire ID %01X%02X%02X%02X",
+ raw[1]&7,raw[2],raw[3],raw[4]); /* Only 28 bits of ID, not 32. */
+ snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
+ snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
+ return true;
+}
+
+ProtoViewDecoder SchraderTPMSDecoder = {
+ "Schrader TPMS", decode
+};
diff --git a/applications/plugins/protoview/protocols/tpms/schrader_eg53ma4.c b/applications/plugins/protoview/protocols/tpms/schrader_eg53ma4.c
new file mode 100644
index 0000000000..6fce40d64e
--- /dev/null
+++ b/applications/plugins/protoview/protocols/tpms/schrader_eg53ma4.c
@@ -0,0 +1,63 @@
+/* Schrader variant EG53MA4 TPMS.
+ * Usually 443.92 Mhz OOK, 100us pulse len.
+ *
+ * Preamble: alternating pulse/gap, 100us.
+ * Sync (as pulses and gaps): "01100101", already part of the data stream
+ * (first nibble) corresponding to 0x4
+ *
+ * A total of 10 bytes payload, Manchester encoded.
+ *
+ * 0 = 01
+ * 1 = 10
+ *
+ * Used in certain Open cars and others.
+ */
+
+#include "../../app.h"
+
+static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
+
+ const char *sync_pattern = "010101010101" "01100101";
+ uint8_t sync_len = 12+8; /* We just use 12 preamble symbols + sync. */
+ if (numbits-sync_len+8 < 8*10) return false;
+
+ uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
+ if (off == BITMAP_SEEK_NOT_FOUND) return false;
+ FURI_LOG_E(TAG, "Schrader EG53MA4 TPMS preamble+sync found");
+
+ off += sync_len-8; /* Skip preamble, not sync that is part of the data. */
+
+ uint8_t raw[10];
+ uint32_t decoded =
+ convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
+ "01","10"); /* Manchester code. */
+ FURI_LOG_E(TAG, "Schrader EG53MA4 TPMS decoded bits: %lu", decoded);
+
+ if (decoded < 10*8) return false; /* Require the full 10 bytes. */
+
+ /* CRC is just all bytes added mod 256. */
+ uint8_t crc = 0;
+ for (int j = 0; j < 9; j++) crc += raw[j];
+ if (crc != raw[9]) return false; /* Require sane CRC. */
+
+ /* To convert the raw pressure to kPa, RTL433 uses 2.5, but is likely
+ * wrong. Searching on Google for users experimenting with the value
+ * reported, the value appears to be 2.75. */
+ float kpa = (float)raw[7]*2.75;
+ int temp_f = raw[8];
+ int temp_c = (temp_f-32)*5/9; /* Convert Fahrenheit to Celsius. */
+
+ snprintf(info->name,sizeof(info->name),"%s","Schrader EG53MA4 TPMS");
+ snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
+ raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
+ raw[6],raw[7],raw[8],raw[9]);
+ snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X",
+ raw[4],raw[5],raw[6]); /* Only 28 bits of ID, not 32. */
+ snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
+ snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp_c);
+ return true;
+}
+
+ProtoViewDecoder SchraderEG53MA4TPMSDecoder = {
+ "Schrader EG53MA4 TPMS", decode
+};
diff --git a/applications/plugins/protoview/protocols/tpms/toyota.c b/applications/plugins/protoview/protocols/tpms/toyota.c
new file mode 100644
index 0000000000..b273537395
--- /dev/null
+++ b/applications/plugins/protoview/protocols/tpms/toyota.c
@@ -0,0 +1,77 @@
+/* Toyota tires TPMS. Usually 443.92 Mhz FSK (In Europe).
+ *
+ * Preamble + sync + 64 bits of data. ~48us short pulse length.
+ *
+ * The preamble + sync is something like:
+ *
+ * 10101010101 (preamble) + 001111[1] (sync)
+ *
+ * Note: the final [1] means that sometimes it is four 1s, sometimes
+ * five, depending on the short pulse length detection and the exact
+ * duration of the high long pulse. After the sync, a differential
+ * Manchester encoded payload follows. However the Flipper's CC1101
+ * often can't decode correctly the initial alternating pattern 101010101,
+ * so what we do is to seek just the sync, that is "001111" or "0011111",
+ * however we now that it must be followed by one differenitally encoded
+ * bit, so we can use also the first symbol of data to force a more robust
+ * detection, and look for one of the following:
+ *
+ * [001111]00
+ * [0011111]00
+ * [001111]01
+ * [0011111]01
+ */
+
+#include "../../app.h"
+
+static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
+
+ if (numbits-6 < 64*2) return false; /* Ask for 64 bit of data (each bit
+ is two symbols in the bitmap). */
+
+ char *sync[] = {
+ "00111100",
+ "001111100",
+ "00111101",
+ "001111101",
+ NULL
+ };
+
+ int j;
+ uint32_t off = 0;
+ for (j = 0; sync[j]; j++) {
+ off = bitmap_seek_bits(bits,numbytes,0,numbits,sync[j]);
+ if (off != BITMAP_SEEK_NOT_FOUND) {
+ off += strlen(sync[j])-2;
+ break;
+ }
+ }
+ if (off == BITMAP_SEEK_NOT_FOUND) return false;
+
+ FURI_LOG_E(TAG, "Toyota TPMS sync[%s] found", sync[j]);
+
+ uint8_t raw[9];
+ uint32_t decoded =
+ convert_from_diff_manchester(raw,sizeof(raw),bits,numbytes,off,true);
+ FURI_LOG_E(TAG, "Toyota TPMS decoded bits: %lu", decoded);
+
+ if (decoded < 8*9) return false; /* Require the full 8 bytes. */
+ if (crc8(raw,8,0x80,7) != raw[8]) return false; /* Require sane CRC. */
+
+ float kpa = (float)((raw[4]&0x7f)<<1 | raw[5]>>7) * 0.25 - 7;
+ int temp = ((raw[5]&0x7f)<<1 | raw[6]>>7) - 40;
+
+ snprintf(info->name,sizeof(info->name),"%s","Toyota TPMS");
+ snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
+ raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
+ raw[6],raw[7],raw[8]);
+ snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X",
+ raw[0],raw[1],raw[2],raw[3]);
+ snprintf(info->info1,sizeof(info->info1),"Pressure %.2f psi", (double)kpa);
+ snprintf(info->info2,sizeof(info->info2),"Temperature %d C", temp);
+ return true;
+}
+
+ProtoViewDecoder ToyotaTPMSDecoder = {
+ "Toyota TPMS", decode
+};
diff --git a/applications/plugins/protoview/signal.c b/applications/plugins/protoview/signal.c
index 2ff632811b..06e2197c24 100644
--- a/applications/plugins/protoview/signal.c
+++ b/applications/plugins/protoview/signal.c
@@ -53,6 +53,7 @@ uint32_t search_coherent_signal(RawSamplesBuffer *s, uint32_t idx) {
bool level;
uint32_t dur;
raw_samples_get(s, j, &level, &dur);
+
if (dur < minlen || dur > maxlen) break; /* return. */
/* Let's see if it matches a class we already have or if we
@@ -70,7 +71,7 @@ uint32_t search_coherent_signal(RawSamplesBuffer *s, uint32_t idx) {
/* Is the difference in duration between this signal and
* the class we are inspecting less than a given percentage?
* If so, accept this signal. */
- if (delta < classavg/8) { /* 100%/8 = 12%. */
+ if (delta < classavg/5) { /* 100%/5 = 20%. */
/* It is useful to compute the average of the class
* we are observing. We know how many samples we got so
* far, so we can recompute the average easily.
@@ -130,9 +131,9 @@ void scan_for_signal(ProtoViewApp *app) {
/* Try to seek on data that looks to have a regular high low high low
* pattern. */
- uint32_t minlen = 13; /* Min run of coherent samples. Up to
- 12 samples it's very easy to mistake
- noise for signal. */
+ uint32_t minlen = 18; /* Min run of coherent samples. With less
+ than a few samples it's very easy to
+ mistake noise for signal. */
ProtoViewMsgInfo *info = malloc(sizeof(ProtoViewMsgInfo));
uint32_t i = 0;
@@ -152,18 +153,25 @@ void scan_for_signal(ProtoViewApp *app) {
the signal in the loop. */
/* Accept this signal as the new signal if either it's longer
- * than the previous one, or the previous one was unknown and
- * this is decoded. */
- if (thislen > app->signal_bestlen ||
- (app->signal_decoded == false && decoded))
+ * than the previous undecoded one, or the previous one was
+ * unknown and this is decoded. */
+ if ((thislen > app->signal_bestlen && app->signal_decoded == false)
+ || (app->signal_decoded == false && decoded))
{
app->signal_info = *info;
app->signal_bestlen = thislen;
app->signal_decoded = decoded;
raw_samples_copy(DetectedSamples,copy);
raw_samples_center(DetectedSamples,i);
- FURI_LOG_E(TAG, "Displayed sample updated (%d samples %lu us)",
+ FURI_LOG_E(TAG, "===> Displayed sample updated (%d samples %lu us)",
(int)thislen, DetectedSamples->short_pulse_dur);
+
+ /* Adjust raw view scale if the signal has an high
+ * data rate. */
+ if (DetectedSamples->short_pulse_dur < 75)
+ app->us_scale = 10;
+ else if (DetectedSamples->short_pulse_dur < 145)
+ app->us_scale = 30;
}
}
i += thislen ? thislen : 1;
@@ -207,14 +215,19 @@ bool bitmap_get(uint8_t *b, uint32_t blen, uint32_t bitpos) {
return (b[byte] & (1< 56781234 */
+ b = (b&0xf0)>>4 | (b&0x0f)<<4;
+ /* Step 2: swap adjacent pairs : 56781234 -> 78563412 */
+ b = (b&0xcc)>>2 | (b&0x33)<<2;
+ /* Step 3: swap adjacent bits : 78563412 -> 87654321 */
+ b = (b&0xaa)>>1 | (b&0x55)<<1;
+ p[j] = b;
}
}
@@ -317,11 +330,9 @@ uint32_t convert_signal_to_bits(uint8_t *b, uint32_t blen, RawSamplesBuffer *s,
/* This function converts the line code used to the final data representation.
* The representation is put inside 'buf', for up to 'buflen' bytes of total
- * data. For instance in order to convert manchester I can use "10" and "01"
- * as zero and one patterns. It is possible to use "?" inside patterns in
- * order to skip certain bits. For instance certain devices encode data twice,
- * with each bit encoded in manchester encoding and then in its reversed
- * representation. In such a case I could use "10??" and "01??".
+ * data. For instance in order to convert manchester you can use "10" and "01"
+ * as zero and one patterns. However this function does not handle differential
+ * encodings. See below for convert_from_diff_manchester().
*
* The function returns the number of bits converted. It will stop as soon
* as it finds a pattern that does not match zero or one patterns, or when
@@ -350,17 +361,50 @@ uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, ui
return decoded;
}
+/* Convert the differential Manchester code to bits. This is similar to
+ * convert_from_line_code() but specific for Manchester. The user must
+ * supply the value of the previous symbol before this stream, since
+ * in differential codings the next bits depend on the previous one.
+ *
+ * Parameters and return values are like convert_from_line_code(). */
+uint32_t convert_from_diff_manchester(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, bool previous)
+{
+ uint32_t decoded = 0;
+ len *= 8; /* Conver to bits. */
+ for (uint32_t j = off; j < len; j += 2) {
+ bool b0 = bitmap_get(bits,len,j);
+ bool b1 = bitmap_get(bits,len,j+1);
+ if (b0 == previous) break; /* Each new bit must switch value. */
+ bitmap_set(buf,buflen,decoded++,b0 == b1);
+ previous = b1;
+ if (decoded/8 == buflen) break; /* No space left on target buffer. */
+ }
+ return decoded;
+}
+
/* Supported protocols go here, with the relevant implementation inside
* protocols/.c */
extern ProtoViewDecoder Oregon2Decoder;
extern ProtoViewDecoder B4B1Decoder;
extern ProtoViewDecoder RenaultTPMSDecoder;
+extern ProtoViewDecoder ToyotaTPMSDecoder;
+extern ProtoViewDecoder SchraderTPMSDecoder;
+extern ProtoViewDecoder SchraderEG53MA4TPMSDecoder;
+extern ProtoViewDecoder CitroenTPMSDecoder;
+extern ProtoViewDecoder FordTPMSDecoder;
+extern ProtoViewDecoder KeeloqDecoder;
ProtoViewDecoder *Decoders[] = {
- &Oregon2Decoder, /* Oregon sensors v2.1 protocol. */
- &B4B1Decoder, /* PT, SC, ... 24 bits remotes. */
- &RenaultTPMSDecoder, /* Renault TPMS. */
+ &Oregon2Decoder, /* Oregon sensors v2.1 protocol. */
+ &B4B1Decoder, /* PT, SC, ... 24 bits remotes. */
+ &RenaultTPMSDecoder, /* Renault TPMS. */
+ &ToyotaTPMSDecoder, /* Toyota TPMS. */
+ &SchraderTPMSDecoder, /* Schrader TPMS. */
+ &SchraderEG53MA4TPMSDecoder, /* Schrader EG53MA4 TPMS. */
+ &CitroenTPMSDecoder, /* Citroen TPMS. */
+ &FordTPMSDecoder, /* Ford TPMS. */
+ &KeeloqDecoder, /* Keeloq remote. */
NULL
};
@@ -378,12 +422,13 @@ bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info) {
uint32_t bitmap_bits_size = 4096*8;
uint32_t bitmap_size = bitmap_bits_size/8;
- /* We call the decoders with an offset a few bits before the actual
+ /* We call the decoders with an offset a few samples before the actual
* signal detected and for a len of a few bits after its end. */
- uint32_t before_after_bits = 2;
+ uint32_t before_samples = 20;
+ uint32_t after_samples = 100;
uint8_t *bitmap = malloc(bitmap_size);
- uint32_t bits = convert_signal_to_bits(bitmap,bitmap_size,s,-before_after_bits,len+before_after_bits*2,s->short_pulse_dur);
+ uint32_t bits = convert_signal_to_bits(bitmap,bitmap_size,s,-before_samples,len+before_samples+after_samples,s->short_pulse_dur);
if (DEBUG_MSG) { /* Useful for debugging purposes. Don't remove. */
char *str = malloc(1024);
@@ -413,7 +458,7 @@ bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info) {
if (!decoded) {
FURI_LOG_E(TAG, "No decoding possible");
} else {
- FURI_LOG_E(TAG, "Decoded %s, raw=%s info=[%s,%s,%s]", info->name, info->raw, info->info1, info->info2, info->info3);
+ FURI_LOG_E(TAG, "Decoded %s, raw=%s info=[%s,%s,%s,%s]", info->name, info->raw, info->info1, info->info2, info->info3, info->info4);
}
free(bitmap);
return decoded;
diff --git a/applications/plugins/protoview/view_direct_sampling.c b/applications/plugins/protoview/view_direct_sampling.c
index a287dc14a2..251a289b8e 100644
--- a/applications/plugins/protoview/view_direct_sampling.c
+++ b/applications/plugins/protoview/view_direct_sampling.c
@@ -8,7 +8,18 @@
/* Read directly from the G0 CC1101 pin, and draw a black or white
* dot depending on the level. */
void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app) {
- UNUSED(app);
+ if (!app->direct_sampling_enabled) {
+ canvas_set_font(canvas, FontSecondary);
+ canvas_draw_str(canvas,2,9,"Direct sampling is a special");
+ canvas_draw_str(canvas,2,18,"mode that displays the signal");
+ canvas_draw_str(canvas,2,27,"captured in real time. Like in");
+ canvas_draw_str(canvas,2,36,"a old CRT TV. It's very slow.");
+ canvas_draw_str(canvas,2,45,"Can crash your Flipper.");
+ canvas_set_font(canvas, FontPrimary);
+ canvas_draw_str(canvas,14,60,"To enable press OK");
+ return;
+ }
+
for (int y = 0; y < 64; y++) {
for (int x = 0; x < 128; x++) {
bool level = furi_hal_gpio_read(&gpio_cc1101_g0);
@@ -16,31 +27,41 @@ void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app) {
/* Busy loop: this is a terrible approach as it blocks
* everything else, but for now it's the best we can do
* to obtain direct data with some spacing. */
- uint32_t x = 500; while(x--);
+ uint32_t x = 250; while(x--);
}
}
canvas_set_font(canvas, FontSecondary);
- canvas_draw_str_with_border(canvas,40,60,"Direct sampling",
+ canvas_draw_str_with_border(canvas,36,60,"Direct sampling",
ColorWhite,ColorBlack);
}
/* Handle input */
void process_input_direct_sampling(ProtoViewApp *app, InputEvent input) {
- UNUSED(app);
- UNUSED(input);
+ if (input.type == InputTypePress && input.key == InputKeyOk) {
+ app->direct_sampling_enabled = !app->direct_sampling_enabled;
+ }
}
/* Enter view. Stop the subghz thread to prevent access as we read
* the CC1101 data directly. */
void view_enter_direct_sampling(ProtoViewApp *app) {
- if (app->txrx->txrx_state == TxRxStateRx) {
+ if (app->txrx->txrx_state == TxRxStateRx &&
+ !app->txrx->debug_timer_sampling)
+ {
subghz_worker_stop(app->txrx->worker);
+ } else {
+ raw_sampling_worker_stop(app);
}
}
/* Exit view. Restore the subghz thread. */
void view_exit_direct_sampling(ProtoViewApp *app) {
- if (app->txrx->txrx_state == TxRxStateRx) {
+ if (app->txrx->txrx_state == TxRxStateRx &&
+ !app->txrx->debug_timer_sampling)
+ {
subghz_worker_start(app->txrx->worker);
+ } else {
+ raw_sampling_worker_start(app);
}
+ app->direct_sampling_enabled = false;
}
diff --git a/applications/plugins/protoview/view_info.c b/applications/plugins/protoview/view_info.c
index fff9c836ee..775c8abc2b 100644
--- a/applications/plugins/protoview/view_info.c
+++ b/applications/plugins/protoview/view_info.c
@@ -25,17 +25,18 @@ void render_view_info(Canvas *const canvas, ProtoViewApp *app) {
canvas_draw_str(canvas, 0, y, buf);
y += lineheight;
}
- canvas_draw_str(canvas, 0, y, app->signal_info.info1);
- y += lineheight;
- canvas_draw_str(canvas, 0, y, app->signal_info.info2);
- y += lineheight;
- canvas_draw_str(canvas, 0, y, app->signal_info.info3);
- y += lineheight;
+ canvas_draw_str(canvas, 0, y, app->signal_info.info1); y += lineheight;
+ canvas_draw_str(canvas, 0, y, app->signal_info.info2); y += lineheight;
+ canvas_draw_str(canvas, 0, y, app->signal_info.info3); y += lineheight;
+ canvas_draw_str(canvas, 0, y, app->signal_info.info4); y += lineheight;
}
-/* Handle input for the settings view. */
+/* Handle input for the info view. */
void process_input_info(ProtoViewApp *app, InputEvent input) {
- UNUSED(app);
- UNUSED(input);
- return;
+ if (input.type == InputTypeShort) {
+ if (input.key == InputKeyOk) {
+ /* Reset the current sample to capture the next. */
+ reset_current_signal(app);
+ }
+ }
}
diff --git a/applications/plugins/protoview/view_settings.c b/applications/plugins/protoview/view_settings.c
index 22ac5ef0f9..1e2dce226f 100644
--- a/applications/plugins/protoview/view_settings.c
+++ b/applications/plugins/protoview/view_settings.c
@@ -20,6 +20,9 @@ void render_view_settings(Canvas *const canvas, ProtoViewApp *app) {
canvas_set_font(canvas, FontSecondary);
canvas_draw_str(canvas,10,61,"Use up and down to modify");
+ if (app->txrx->debug_timer_sampling)
+ canvas_draw_str(canvas,3,52,"(DEBUG timer sampling is ON)");
+
/* Show frequency. We can use big numbers font since it's just a number. */
if (app->current_view == ViewFrequencySettings) {
char buf[16];
@@ -40,6 +43,18 @@ void process_input_settings(ProtoViewApp *app, InputEvent input) {
* modulation. */
app->frequency = subghz_setting_get_default_frequency(app->setting);
app->modulation = 0;
+ } else if (0 && input.type == InputTypeLong && input.key == InputKeyDown) {
+ /* Long pressing to down switches between normal and debug
+ * timer sampling mode. NOTE: this feature is disabled for users,
+ * only useful for devs (if useful at all). */
+
+ /* We have to stop the previous sampling system. */
+ radio_rx_end(app);
+
+ /* Then switch mode and start the new one. */
+ app->txrx->debug_timer_sampling = !app->txrx->debug_timer_sampling;
+ radio_begin(app);
+ radio_rx(app);
} else if (input.type == InputTypePress &&
(input.key != InputKeyDown || input.key != InputKeyUp))
{
@@ -85,9 +100,18 @@ void process_input_settings(ProtoViewApp *app, InputEvent input) {
return;
}
- /* Apply changes. */
- FURI_LOG_E(TAG, "Setting view, setting frequency/modulation to %lu %s", app->frequency, ProtoViewModulations[app->modulation].name);
- radio_rx_end(app);
- radio_begin(app);
- radio_rx(app);
+ /* Apply changes when switching to other views. */
+ app->txrx->freq_mod_changed = true;
+}
+
+/* When the user switches to some other view, if they changed the parameters
+ * we need to restart the radio with the right frequency and modulation. */
+void view_exit_settings(ProtoViewApp *app) {
+ if (app->txrx->freq_mod_changed) {
+ FURI_LOG_E(TAG, "Setting view, setting frequency/modulation to %lu %s", app->frequency, ProtoViewModulations[app->modulation].name);
+ radio_rx_end(app);
+ radio_begin(app);
+ radio_rx(app);
+ app->txrx->freq_mod_changed = false;
+ }
}
diff --git a/applications/plugins/qrcode/qrcode.c b/applications/plugins/qrcode/qrcode.c
index c36285a17a..aed1869cf2 100644
--- a/applications/plugins/qrcode/qrcode.c
+++ b/applications/plugins/qrcode/qrcode.c
@@ -42,40 +42,84 @@
static const uint16_t NUM_ERROR_CORRECTION_CODEWORDS[4][40] = {
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
- { 10, 16, 26, 36, 48, 64, 72, 88, 110, 130, 150, 176, 198, 216, 240, 280, 308, 338, 364, 416, 442, 476, 504, 560, 588, 644, 700, 728, 784, 812, 868, 924, 980, 1036, 1064, 1120, 1204, 1260, 1316, 1372}, // Medium
- { 7, 10, 15, 20, 26, 36, 40, 48, 60, 72, 80, 96, 104, 120, 132, 144, 168, 180, 196, 224, 224, 252, 270, 300, 312, 336, 360, 390, 420, 450, 480, 510, 540, 570, 570, 600, 630, 660, 720, 750}, // Low
- { 17, 28, 44, 64, 88, 112, 130, 156, 192, 224, 264, 308, 352, 384, 432, 480, 532, 588, 650, 700, 750, 816, 900, 960, 1050, 1110, 1200, 1260, 1350, 1440, 1530, 1620, 1710, 1800, 1890, 1980, 2100, 2220, 2310, 2430}, // High
- { 13, 22, 36, 52, 72, 96, 108, 132, 160, 192, 224, 260, 288, 320, 360, 408, 448, 504, 546, 600, 644, 690, 750, 810, 870, 952, 1020, 1050, 1140, 1200, 1290, 1350, 1440, 1530, 1590, 1680, 1770, 1860, 1950, 2040}, // Quartile
+ {10, 16, 26, 36, 48, 64, 72, 88, 110, 130, 150, 176, 198, 216,
+ 240, 280, 308, 338, 364, 416, 442, 476, 504, 560, 588, 644, 700, 728,
+ 784, 812, 868, 924, 980, 1036, 1064, 1120, 1204, 1260, 1316, 1372}, // Medium
+ {7, 10, 15, 20, 26, 36, 40, 48, 60, 72, 80, 96, 104, 120,
+ 132, 144, 168, 180, 196, 224, 224, 252, 270, 300, 312, 336, 360, 390,
+ 420, 450, 480, 510, 540, 570, 570, 600, 630, 660, 720, 750}, // Low
+ {17, 28, 44, 64, 88, 112, 130, 156, 192, 224, 264, 308, 352, 384,
+ 432, 480, 532, 588, 650, 700, 750, 816, 900, 960, 1050, 1110, 1200, 1260,
+ 1350, 1440, 1530, 1620, 1710, 1800, 1890, 1980, 2100, 2220, 2310, 2430}, // High
+ {13, 22, 36, 52, 72, 96, 108, 132, 160, 192, 224, 260, 288, 320,
+ 360, 408, 448, 504, 546, 600, 644, 690, 750, 810, 870, 952, 1020, 1050,
+ 1140, 1200, 1290, 1350, 1440, 1530, 1590, 1680, 1770, 1860, 1950, 2040}, // Quartile
};
static const uint8_t NUM_ERROR_CORRECTION_BLOCKS[4][40] = {
// Version: (note that index 0 is for padding, and is set to an illegal value)
// 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
- { 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium
- { 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low
- { 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High
- { 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile
+ {1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16,
+ 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium
+ {1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8,
+ 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low
+ {1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25,
+ 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High
+ {1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20,
+ 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile
};
static const uint16_t NUM_RAW_DATA_MODULES[40] = {
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 208, 359, 567, 807, 1079, 1383, 1568, 1936, 2336, 2768, 3232, 3728, 4256, 4651, 5243, 5867, 6523,
+ 208,
+ 359,
+ 567,
+ 807,
+ 1079,
+ 1383,
+ 1568,
+ 1936,
+ 2336,
+ 2768,
+ 3232,
+ 3728,
+ 4256,
+ 4651,
+ 5243,
+ 5867,
+ 6523,
// 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 7211, 7931, 8683, 9252, 10068, 10916, 11796, 12708, 13652, 14628, 15371, 16411, 17483, 18587,
+ 7211,
+ 7931,
+ 8683,
+ 9252,
+ 10068,
+ 10916,
+ 11796,
+ 12708,
+ 13652,
+ 14628,
+ 15371,
+ 16411,
+ 17483,
+ 18587,
// 32, 33, 34, 35, 36, 37, 38, 39, 40
- 19723, 20891, 22091, 23008, 24272, 25568, 26896, 28256, 29648
-};
+ 19723,
+ 20891,
+ 22091,
+ 23008,
+ 24272,
+ 25568,
+ 26896,
+ 28256,
+ 29648};
// @TODO: Put other LOCK_VERSIONS here
#elif LOCK_VERSION == 3
-static const int16_t NUM_ERROR_CORRECTION_CODEWORDS[4] = {
- 26, 15, 44, 36
-};
+static const int16_t NUM_ERROR_CORRECTION_CODEWORDS[4] = {26, 15, 44, 36};
-static const int8_t NUM_ERROR_CORRECTION_BLOCKS[4] = {
- 1, 1, 2, 2
-};
+static const int8_t NUM_ERROR_CORRECTION_BLOCKS[4] = {1, 1, 2, 2};
static const uint16_t NUM_RAW_DATA_MODULES = 567;
@@ -85,9 +129,10 @@ static const uint16_t NUM_RAW_DATA_MODULES = 567;
#endif
-
static int max(int a, int b) {
- if (a > b) { return a; }
+ if(a > b) {
+ return a;
+ }
return b;
}
@@ -98,44 +143,57 @@ static int abs(int value) {
}
*/
-
static int8_t getAlphanumeric(char c) {
-
- if (c >= '0' && c <= '9') { return (c - '0'); }
- if (c >= 'A' && c <= 'Z') { return (c - 'A' + 10); }
-
- switch (c) {
- case ' ': return 36;
- case '$': return 37;
- case '%': return 38;
- case '*': return 39;
- case '+': return 40;
- case '-': return 41;
- case '.': return 42;
- case '/': return 43;
- case ':': return 44;
+ if(c >= '0' && c <= '9') {
+ return (c - '0');
+ }
+ if(c >= 'A' && c <= 'Z') {
+ return (c - 'A' + 10);
+ }
+
+ switch(c) {
+ case ' ':
+ return 36;
+ case '$':
+ return 37;
+ case '%':
+ return 38;
+ case '*':
+ return 39;
+ case '+':
+ return 40;
+ case '-':
+ return 41;
+ case '.':
+ return 42;
+ case '/':
+ return 43;
+ case ':':
+ return 44;
}
-
+
return -1;
}
-static bool isAlphanumeric(const char *text, uint16_t length) {
- while (length != 0) {
- if (getAlphanumeric(text[--length]) == -1) { return false; }
+static bool isAlphanumeric(const char* text, uint16_t length) {
+ while(length != 0) {
+ if(getAlphanumeric(text[--length]) == -1) {
+ return false;
+ }
}
return true;
}
-
-static bool isNumeric(const char *text, uint16_t length) {
- while (length != 0) {
+static bool isNumeric(const char* text, uint16_t length) {
+ while(length != 0) {
char c = text[--length];
- if (c < '0' || c > '9') { return false; }
+ if(c < '0' || c > '9') {
+ return false;
+ }
}
return true;
}
-
// We store the following tightly packed (less 8) in modeInfo
// <=9 <=26 <= 40
// NUMERIC ( 10, 12, 14);
@@ -145,26 +203,31 @@ static char getModeBits(uint8_t version, uint8_t mode) {
// Note: We use 15 instead of 16; since 15 doesn't exist and we cannot store 16 (8 + 8) in 3 bits
// hex(int("".join(reversed([('00' + bin(x - 8)[2:])[-3:] for x in [10, 9, 8, 12, 11, 15, 14, 13, 15]])), 2))
unsigned int modeInfo = 0x7bbb80a;
-
+
#if LOCK_VERSION == 0 || LOCK_VERSION > 9
- if (version > 9) { modeInfo >>= 9; }
+ if(version > 9) {
+ modeInfo >>= 9;
+ }
#endif
-
+
#if LOCK_VERSION == 0 || LOCK_VERSION > 26
- if (version > 26) { modeInfo >>= 9; }
+ if(version > 26) {
+ modeInfo >>= 9;
+ }
#endif
-
+
char result = 8 + ((modeInfo >> (3 * mode)) & 0x07);
- if (result == 15) { result = 16; }
-
+ if(result == 15) {
+ result = 16;
+ }
+
return result;
}
-
typedef struct BitBucket {
uint32_t bitOffsetOrWidth;
uint16_t capacityBytes;
- uint8_t *data;
+ uint8_t* data;
} BitBucket;
/*
@@ -186,15 +249,15 @@ static uint16_t bb_getBufferSizeBytes(uint32_t bits) {
return ((bits + 7) / 8);
}
-static void bb_initBuffer(BitBucket *bitBuffer, uint8_t *data, int32_t capacityBytes) {
+static void bb_initBuffer(BitBucket* bitBuffer, uint8_t* data, int32_t capacityBytes) {
bitBuffer->bitOffsetOrWidth = 0;
bitBuffer->capacityBytes = capacityBytes;
bitBuffer->data = data;
-
+
memset(data, 0, bitBuffer->capacityBytes);
}
-static void bb_initGrid(BitBucket *bitGrid, uint8_t *data, uint8_t size) {
+static void bb_initGrid(BitBucket* bitGrid, uint8_t* data, uint8_t size) {
bitGrid->bitOffsetOrWidth = size;
bitGrid->capacityBytes = bb_getGridSizeBytes(size);
bitGrid->data = data;
@@ -202,9 +265,9 @@ static void bb_initGrid(BitBucket *bitGrid, uint8_t *data, uint8_t size) {
memset(data, 0, bitGrid->capacityBytes);
}
-static void bb_appendBits(BitBucket *bitBuffer, uint32_t val, uint8_t length) {
+static void bb_appendBits(BitBucket* bitBuffer, uint32_t val, uint8_t length) {
uint32_t offset = bitBuffer->bitOffsetOrWidth;
- for (int8_t i = length - 1; i >= 0; i--, offset++) {
+ for(int8_t i = length - 1; i >= 0; i--, offset++) {
bitBuffer->data[offset >> 3] |= ((val >> i) & 1) << (7 - (offset & 7));
}
bitBuffer->bitOffsetOrWidth = offset;
@@ -216,74 +279,92 @@ void bb_setBits(BitBucket *bitBuffer, uint32_t val, int offset, uint8_t length)
}
}
*/
-static void bb_setBit(BitBucket *bitGrid, uint8_t x, uint8_t y, bool on) {
+static void bb_setBit(BitBucket* bitGrid, uint8_t x, uint8_t y, bool on) {
uint32_t offset = y * bitGrid->bitOffsetOrWidth + x;
uint8_t mask = 1 << (7 - (offset & 0x07));
- if (on) {
+ if(on) {
bitGrid->data[offset >> 3] |= mask;
} else {
bitGrid->data[offset >> 3] &= ~mask;
}
}
-static void bb_invertBit(BitBucket *bitGrid, uint8_t x, uint8_t y, bool invert) {
+static void bb_invertBit(BitBucket* bitGrid, uint8_t x, uint8_t y, bool invert) {
uint32_t offset = y * bitGrid->bitOffsetOrWidth + x;
uint8_t mask = 1 << (7 - (offset & 0x07));
bool on = ((bitGrid->data[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0);
- if (on ^ invert) {
+ if(on ^ invert) {
bitGrid->data[offset >> 3] |= mask;
} else {
bitGrid->data[offset >> 3] &= ~mask;
}
}
-static bool bb_getBit(BitBucket *bitGrid, uint8_t x, uint8_t y) {
+static bool bb_getBit(BitBucket* bitGrid, uint8_t x, uint8_t y) {
uint32_t offset = y * bitGrid->bitOffsetOrWidth + x;
return (bitGrid->data[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0;
}
-
// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
// properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
// This means it is possible to apply a mask, undo it, and try another mask. Note that a final
// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.).
-static void applyMask(BitBucket *modules, BitBucket *isFunction, uint8_t mask) {
+static void applyMask(BitBucket* modules, BitBucket* isFunction, uint8_t mask) {
uint8_t size = modules->bitOffsetOrWidth;
-
- for (uint8_t y = 0; y < size; y++) {
- for (uint8_t x = 0; x < size; x++) {
- if (bb_getBit(isFunction, x, y)) { continue; }
-
+
+ for(uint8_t y = 0; y < size; y++) {
+ for(uint8_t x = 0; x < size; x++) {
+ if(bb_getBit(isFunction, x, y)) {
+ continue;
+ }
+
bool invert = 0;
- switch (mask) {
- case 0: invert = (x + y) % 2 == 0; break;
- case 1: invert = y % 2 == 0; break;
- case 2: invert = x % 3 == 0; break;
- case 3: invert = (x + y) % 3 == 0; break;
- case 4: invert = (x / 3 + y / 2) % 2 == 0; break;
- case 5: invert = x * y % 2 + x * y % 3 == 0; break;
- case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break;
- case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break;
+ switch(mask) {
+ case 0:
+ invert = (x + y) % 2 == 0;
+ break;
+ case 1:
+ invert = y % 2 == 0;
+ break;
+ case 2:
+ invert = x % 3 == 0;
+ break;
+ case 3:
+ invert = (x + y) % 3 == 0;
+ break;
+ case 4:
+ invert = (x / 3 + y / 2) % 2 == 0;
+ break;
+ case 5:
+ invert = x * y % 2 + x * y % 3 == 0;
+ break;
+ case 6:
+ invert = (x * y % 2 + x * y % 3) % 2 == 0;
+ break;
+ case 7:
+ invert = ((x + y) % 2 + x * y % 3) % 2 == 0;
+ break;
}
bb_invertBit(modules, x, y, invert);
}
}
}
-static void setFunctionModule(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y, bool on) {
+static void
+ setFunctionModule(BitBucket* modules, BitBucket* isFunction, uint8_t x, uint8_t y, bool on) {
bb_setBit(modules, x, y, on);
bb_setBit(isFunction, x, y, true);
}
// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y).
-static void drawFinderPattern(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y) {
+static void drawFinderPattern(BitBucket* modules, BitBucket* isFunction, uint8_t x, uint8_t y) {
uint8_t size = modules->bitOffsetOrWidth;
- for (int8_t i = -4; i <= 4; i++) {
- for (int8_t j = -4; j <= 4; j++) {
- uint8_t dist = max(abs(i), abs(j)); // Chebyshev/infinity norm
+ for(int8_t i = -4; i <= 4; i++) {
+ for(int8_t j = -4; j <= 4; j++) {
+ uint8_t dist = max(abs(i), abs(j)); // Chebyshev/infinity norm
int16_t xx = x + j, yy = y + i;
- if (0 <= xx && xx < size && 0 <= yy && yy < size) {
+ if(0 <= xx && xx < size && 0 <= yy && yy < size) {
setFunctionModule(modules, isFunction, xx, yy, dist != 2 && dist != 4);
}
}
@@ -291,9 +372,9 @@ static void drawFinderPattern(BitBucket *modules, BitBucket *isFunction, uint8_t
}
// Draws a 5*5 alignment pattern, with the center module at (x, y).
-static void drawAlignmentPattern(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y) {
- for (int8_t i = -2; i <= 2; i++) {
- for (int8_t j = -2; j <= 2; j++) {
+static void drawAlignmentPattern(BitBucket* modules, BitBucket* isFunction, uint8_t x, uint8_t y) {
+ for(int8_t i = -2; i <= 2; i++) {
+ for(int8_t j = -2; j <= 2; j++) {
setFunctionModule(modules, isFunction, x + j, y + i, max(abs(i), abs(j)) != 1);
}
}
@@ -301,157 +382,159 @@ static void drawAlignmentPattern(BitBucket *modules, BitBucket *isFunction, uint
// Draws two copies of the format bits (with its own error correction code)
// based on the given mask and this object's error correction level field.
-static void drawFormatBits(BitBucket *modules, BitBucket *isFunction, uint8_t ecc, uint8_t mask) {
-
+static void drawFormatBits(BitBucket* modules, BitBucket* isFunction, uint8_t ecc, uint8_t mask) {
uint8_t size = modules->bitOffsetOrWidth;
// Calculate error correction code and pack bits
- uint32_t data = ecc << 3 | mask; // errCorrLvl is uint2, mask is uint3
+ uint32_t data = ecc << 3 | mask; // errCorrLvl is uint2, mask is uint3
uint32_t rem = data;
- for (int i = 0; i < 10; i++) {
+ for(int i = 0; i < 10; i++) {
rem = (rem << 1) ^ ((rem >> 9) * 0x537);
}
-
+
data = data << 10 | rem;
- data ^= 0x5412; // uint15
-
+ data ^= 0x5412; // uint15
+
// Draw first copy
- for (uint8_t i = 0; i <= 5; i++) {
+ for(uint8_t i = 0; i <= 5; i++) {
setFunctionModule(modules, isFunction, 8, i, ((data >> i) & 1) != 0);
}
-
+
setFunctionModule(modules, isFunction, 8, 7, ((data >> 6) & 1) != 0);
setFunctionModule(modules, isFunction, 8, 8, ((data >> 7) & 1) != 0);
setFunctionModule(modules, isFunction, 7, 8, ((data >> 8) & 1) != 0);
-
- for (int8_t i = 9; i < 15; i++) {
+
+ for(int8_t i = 9; i < 15; i++) {
setFunctionModule(modules, isFunction, 14 - i, 8, ((data >> i) & 1) != 0);
}
-
+
// Draw second copy
- for (int8_t i = 0; i <= 7; i++) {
+ for(int8_t i = 0; i <= 7; i++) {
setFunctionModule(modules, isFunction, size - 1 - i, 8, ((data >> i) & 1) != 0);
}
-
- for (int8_t i = 8; i < 15; i++) {
+
+ for(int8_t i = 8; i < 15; i++) {
setFunctionModule(modules, isFunction, 8, size - 15 + i, ((data >> i) & 1) != 0);
}
-
+
setFunctionModule(modules, isFunction, 8, size - 8, true);
}
-
// Draws two copies of the version bits (with its own error correction code),
// based on this object's version field (which only has an effect for 7 <= version <= 40).
-static void drawVersion(BitBucket *modules, BitBucket *isFunction, uint8_t version) {
-
+static void drawVersion(BitBucket* modules, BitBucket* isFunction, uint8_t version) {
int8_t size = modules->bitOffsetOrWidth;
#if LOCK_VERSION != 0 && LOCK_VERSION < 7
return;
-
+
#else
- if (version < 7) { return; }
-
+ if(version < 7) {
+ return;
+ }
+
// Calculate error correction code and pack bits
- uint32_t rem = version; // version is uint6, in the range [7, 40]
- for (uint8_t i = 0; i < 12; i++) {
+ uint32_t rem = version; // version is uint6, in the range [7, 40]
+ for(uint8_t i = 0; i < 12; i++) {
rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
}
-
- uint32_t data = version << 12 | rem; // uint18
-
+
+ uint32_t data = version << 12 | rem; // uint18
+
// Draw two copies
- for (uint8_t i = 0; i < 18; i++) {
+ for(uint8_t i = 0; i < 18; i++) {
bool bit = ((data >> i) & 1) != 0;
uint8_t a = size - 11 + i % 3, b = i / 3;
setFunctionModule(modules, isFunction, a, b, bit);
setFunctionModule(modules, isFunction, b, a, bit);
}
-
+
#endif
}
-static void drawFunctionPatterns(BitBucket *modules, BitBucket *isFunction, uint8_t version, uint8_t ecc) {
-
+static void
+ drawFunctionPatterns(BitBucket* modules, BitBucket* isFunction, uint8_t version, uint8_t ecc) {
uint8_t size = modules->bitOffsetOrWidth;
// Draw the horizontal and vertical timing patterns
- for (uint8_t i = 0; i < size; i++) {
+ for(uint8_t i = 0; i < size; i++) {
setFunctionModule(modules, isFunction, 6, i, i % 2 == 0);
setFunctionModule(modules, isFunction, i, 6, i % 2 == 0);
}
-
+
// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
drawFinderPattern(modules, isFunction, 3, 3);
drawFinderPattern(modules, isFunction, size - 4, 3);
drawFinderPattern(modules, isFunction, 3, size - 4);
-
-#if LOCK_VERSION == 0 || LOCK_VERSION > 1
- if (version > 1) {
+#if LOCK_VERSION == 0 || LOCK_VERSION > 1
+ if(version > 1) {
// Draw the numerous alignment patterns
-
+
uint8_t alignCount = version / 7 + 2;
uint8_t step;
- if (version != 32) {
- step = (version * 4 + alignCount * 2 + 1) / (2 * alignCount - 2) * 2; // ceil((size - 13) / (2*numAlign - 2)) * 2
+ if(version != 32) {
+ step = (version * 4 + alignCount * 2 + 1) / (2 * alignCount - 2) *
+ 2; // ceil((size - 13) / (2*numAlign - 2)) * 2
} else { // C-C-C-Combo breaker!
step = 26;
}
-
+
uint8_t alignPositionIndex = alignCount - 1;
uint8_t alignPosition[alignCount];
-
+
alignPosition[0] = 6;
-
+
uint8_t size = version * 4 + 17;
- for (uint8_t i = 0, pos = size - 7; i < alignCount - 1; i++, pos -= step) {
+ for(uint8_t i = 0, pos = size - 7; i < alignCount - 1; i++, pos -= step) {
alignPosition[alignPositionIndex--] = pos;
}
-
- for (uint8_t i = 0; i < alignCount; i++) {
- for (uint8_t j = 0; j < alignCount; j++) {
- if ((i == 0 && j == 0) || (i == 0 && j == alignCount - 1) || (i == alignCount - 1 && j == 0)) {
- continue; // Skip the three finder corners
+
+ for(uint8_t i = 0; i < alignCount; i++) {
+ for(uint8_t j = 0; j < alignCount; j++) {
+ if((i == 0 && j == 0) || (i == 0 && j == alignCount - 1) ||
+ (i == alignCount - 1 && j == 0)) {
+ continue; // Skip the three finder corners
} else {
drawAlignmentPattern(modules, isFunction, alignPosition[i], alignPosition[j]);
}
}
}
}
-
+
#endif
-
+
// Draw configuration data
- drawFormatBits(modules, isFunction, ecc, 0); // Dummy mask value; overwritten later in the constructor
+ drawFormatBits(
+ modules, isFunction, ecc, 0); // Dummy mask value; overwritten later in the constructor
drawVersion(modules, isFunction, version);
}
-
// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
// data area of this QR Code symbol. Function modules need to be marked off before this is called.
-static void drawCodewords(BitBucket *modules, BitBucket *isFunction, BitBucket *codewords) {
-
+static void drawCodewords(BitBucket* modules, BitBucket* isFunction, BitBucket* codewords) {
uint32_t bitLength = codewords->bitOffsetOrWidth;
- uint8_t *data = codewords->data;
-
+ uint8_t* data = codewords->data;
+
uint8_t size = modules->bitOffsetOrWidth;
-
+
// Bit index into the data
uint32_t i = 0;
-
+
// Do the funny zigzag scan
- for (int16_t right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair
- if (right == 6) { right = 5; }
-
- for (uint8_t vert = 0; vert < size; vert++) { // Vertical counter
- for (int j = 0; j < 2; j++) {
- uint8_t x = right - j; // Actual x coordinate
+ for(int16_t right = size - 1; right >= 1;
+ right -= 2) { // Index of right column in each column pair
+ if(right == 6) {
+ right = 5;
+ }
+
+ for(uint8_t vert = 0; vert < size; vert++) { // Vertical counter
+ for(int j = 0; j < 2; j++) {
+ uint8_t x = right - j; // Actual x coordinate
bool upwards = ((right & 2) == 0) ^ (x < 6);
- uint8_t y = upwards ? size - 1 - vert : vert; // Actual y coordinate
- if (!bb_getBit(isFunction, x, y) && i < bitLength) {
+ uint8_t y = upwards ? size - 1 - vert : vert; // Actual y coordinate
+ if(!bb_getBit(isFunction, x, y) && i < bitLength) {
bb_setBit(modules, x, y, ((data[i >> 3] >> (7 - (i & 7))) & 1) != 0);
i++;
}
@@ -462,73 +545,70 @@ static void drawCodewords(BitBucket *modules, BitBucket *isFunction, BitBucket *
}
}
-
-
-#define PENALTY_N1 3
-#define PENALTY_N2 3
-#define PENALTY_N3 40
-#define PENALTY_N4 10
+#define PENALTY_N1 3
+#define PENALTY_N2 3
+#define PENALTY_N3 40
+#define PENALTY_N4 10
// Calculates and returns the penalty score based on state of this QR Code's current modules.
// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
// @TODO: This can be optimized by working with the bytes instead of bits.
-static uint32_t getPenaltyScore(BitBucket *modules) {
+static uint32_t getPenaltyScore(BitBucket* modules) {
uint32_t result = 0;
-
+
uint8_t size = modules->bitOffsetOrWidth;
-
+
// Adjacent modules in row having same color
- for (uint8_t y = 0; y < size; y++) {
-
+ for(uint8_t y = 0; y < size; y++) {
bool colorX = bb_getBit(modules, 0, y);
- for (uint8_t x = 1, runX = 1; x < size; x++) {
+ for(uint8_t x = 1, runX = 1; x < size; x++) {
bool cx = bb_getBit(modules, x, y);
- if (cx != colorX) {
+ if(cx != colorX) {
colorX = cx;
runX = 1;
-
+
} else {
runX++;
- if (runX == 5) {
+ if(runX == 5) {
result += PENALTY_N1;
- } else if (runX > 5) {
+ } else if(runX > 5) {
result++;
}
}
}
}
-
+
// Adjacent modules in column having same color
- for (uint8_t x = 0; x < size; x++) {
+ for(uint8_t x = 0; x < size; x++) {
bool colorY = bb_getBit(modules, x, 0);
- for (uint8_t y = 1, runY = 1; y < size; y++) {
+ for(uint8_t y = 1, runY = 1; y < size; y++) {
bool cy = bb_getBit(modules, x, y);
- if (cy != colorY) {
+ if(cy != colorY) {
colorY = cy;
runY = 1;
} else {
runY++;
- if (runY == 5) {
+ if(runY == 5) {
result += PENALTY_N1;
- } else if (runY > 5) {
+ } else if(runY > 5) {
result++;
}
}
}
}
-
+
uint16_t black = 0;
- for (uint8_t y = 0; y < size; y++) {
+ for(uint8_t y = 0; y < size; y++) {
uint16_t bitsRow = 0, bitsCol = 0;
- for (uint8_t x = 0; x < size; x++) {
+ for(uint8_t x = 0; x < size; x++) {
bool color = bb_getBit(modules, x, y);
// 2*2 blocks of modules having same color
- if (x > 0 && y > 0) {
+ if(x > 0 && y > 0) {
bool colorUL = bb_getBit(modules, x - 1, y - 1);
bool colorUR = bb_getBit(modules, x, y - 1);
bool colorL = bb_getBit(modules, x - 1, y);
- if (color == colorUL && color == colorUR && color == colorL) {
+ if(color == colorUL && color == colorUR && color == colorL) {
result += PENALTY_N2;
}
}
@@ -538,146 +618,154 @@ static uint32_t getPenaltyScore(BitBucket *modules) {
bitsCol = ((bitsCol << 1) & 0x7FF) | bb_getBit(modules, y, x);
// Needs 11 bits accumulated
- if (x >= 10) {
- if (bitsRow == 0x05D || bitsRow == 0x5D0) {
+ if(x >= 10) {
+ if(bitsRow == 0x05D || bitsRow == 0x5D0) {
result += PENALTY_N3;
}
- if (bitsCol == 0x05D || bitsCol == 0x5D0) {
+ if(bitsCol == 0x05D || bitsCol == 0x5D0) {
result += PENALTY_N3;
}
}
// Balance of black and white modules
- if (color) { black++; }
+ if(color) {
+ black++;
+ }
}
}
// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
uint16_t total = size * size;
- for (uint16_t k = 0; black * 20 < (9 - k) * total || black * 20 > (11 + k) * total; k++) {
+ for(uint16_t k = 0; black * 20 < (9 - k) * total || black * 20 > (11 + k) * total; k++) {
result += PENALTY_N4;
}
-
+
return result;
}
-
static uint8_t rs_multiply(uint8_t x, uint8_t y) {
// Russian peasant multiplication
// See: https://en.wikipedia.org/wiki/Ancient_Egyptian_multiplication
uint16_t z = 0;
- for (int8_t i = 7; i >= 0; i--) {
+ for(int8_t i = 7; i >= 0; i--) {
z = (z << 1) ^ ((z >> 7) * 0x11D);
z ^= ((y >> i) & 1) * x;
}
return z;
}
-static void rs_init(uint8_t degree, uint8_t *coeff) {
+static void rs_init(uint8_t degree, uint8_t* coeff) {
memset(coeff, 0, degree);
coeff[degree - 1] = 1;
-
+
// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
// drop the highest term, and store the rest of the coefficients in order of descending powers.
// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
uint16_t root = 1;
- for (uint8_t i = 0; i < degree; i++) {
+ for(uint8_t i = 0; i < degree; i++) {
// Multiply the current product by (x - r^i)
- for (uint8_t j = 0; j < degree; j++) {
+ for(uint8_t j = 0; j < degree; j++) {
coeff[j] = rs_multiply(coeff[j], root);
- if (j + 1 < degree) {
+ if(j + 1 < degree) {
coeff[j] ^= coeff[j + 1];
}
}
- root = (root << 1) ^ ((root >> 7) * 0x11D); // Multiply by 0x02 mod GF(2^8/0x11D)
+ root = (root << 1) ^ ((root >> 7) * 0x11D); // Multiply by 0x02 mod GF(2^8/0x11D)
}
}
-static void rs_getRemainder(uint8_t degree, uint8_t *coeff, uint8_t *data, uint8_t length, uint8_t *result, uint8_t stride) {
+static void rs_getRemainder(
+ uint8_t degree,
+ uint8_t* coeff,
+ uint8_t* data,
+ uint8_t length,
+ uint8_t* result,
+ uint8_t stride) {
// Compute the remainder by performing polynomial division
-
+
//for (uint8_t i = 0; i < degree; i++) { result[] = 0; }
//memset(result, 0, degree);
-
- for (uint8_t i = 0; i < length; i++) {
+
+ for(uint8_t i = 0; i < length; i++) {
uint8_t factor = data[i] ^ result[0];
- for (uint8_t j = 1; j < degree; j++) {
+ for(uint8_t j = 1; j < degree; j++) {
result[(j - 1) * stride] = result[j * stride];
}
result[(degree - 1) * stride] = 0;
-
- for (uint8_t j = 0; j < degree; j++) {
+
+ for(uint8_t j = 0; j < degree; j++) {
result[j * stride] ^= rs_multiply(coeff[j], factor);
}
}
}
-
-
-static int8_t encodeDataCodewords(BitBucket *dataCodewords, const uint8_t *text, uint16_t length, uint8_t version) {
+static int8_t encodeDataCodewords(
+ BitBucket* dataCodewords,
+ const uint8_t* text,
+ uint16_t length,
+ uint8_t version) {
int8_t mode = MODE_BYTE;
-
- if (isNumeric((char*)text, length)) {
+
+ if(isNumeric((char*)text, length)) {
mode = MODE_NUMERIC;
bb_appendBits(dataCodewords, 1 << MODE_NUMERIC, 4);
bb_appendBits(dataCodewords, length, getModeBits(version, MODE_NUMERIC));
uint16_t accumData = 0;
uint8_t accumCount = 0;
- for (uint16_t i = 0; i < length; i++) {
+ for(uint16_t i = 0; i < length; i++) {
accumData = accumData * 10 + ((char)(text[i]) - '0');
accumCount++;
- if (accumCount == 3) {
+ if(accumCount == 3) {
bb_appendBits(dataCodewords, accumData, 10);
accumData = 0;
accumCount = 0;
}
}
-
+
// 1 or 2 digits remaining
- if (accumCount > 0) {
+ if(accumCount > 0) {
bb_appendBits(dataCodewords, accumData, accumCount * 3 + 1);
}
-
- } else if (isAlphanumeric((char*)text, length)) {
+
+ } else if(isAlphanumeric((char*)text, length)) {
mode = MODE_ALPHANUMERIC;
bb_appendBits(dataCodewords, 1 << MODE_ALPHANUMERIC, 4);
bb_appendBits(dataCodewords, length, getModeBits(version, MODE_ALPHANUMERIC));
uint16_t accumData = 0;
uint8_t accumCount = 0;
- for (uint16_t i = 0; i < length; i++) {
+ for(uint16_t i = 0; i < length; i++) {
accumData = accumData * 45 + getAlphanumeric((char)(text[i]));
accumCount++;
- if (accumCount == 2) {
+ if(accumCount == 2) {
bb_appendBits(dataCodewords, accumData, 11);
accumData = 0;
accumCount = 0;
}
}
-
+
// 1 character remaining
- if (accumCount > 0) {
+ if(accumCount > 0) {
bb_appendBits(dataCodewords, accumData, 6);
}
-
+
} else {
bb_appendBits(dataCodewords, 1 << MODE_BYTE, 4);
bb_appendBits(dataCodewords, length, getModeBits(version, MODE_BYTE));
- for (uint16_t i = 0; i < length; i++) {
+ for(uint16_t i = 0; i < length; i++) {
bb_appendBits(dataCodewords, (char)(text[i]), 8);
}
}
-
+
//bb_setBits(dataCodewords, length, 4, getModeBits(version, mode));
-
+
return mode;
}
-static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket *data) {
-
+static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket* data) {
// See: http://www.thonky.com/qr-code-tutorial/structure-final-message
-
+
#if LOCK_VERSION == 0
uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc][version - 1];
uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc][version - 1];
@@ -687,63 +775,68 @@ static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket *data
uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc];
uint16_t moduleCount = NUM_RAW_DATA_MODULES;
#endif
-
+
uint8_t blockEccLen = totalEcc / numBlocks;
uint8_t numShortBlocks = numBlocks - moduleCount / 8 % numBlocks;
uint8_t shortBlockLen = moduleCount / 8 / numBlocks;
-
+
uint8_t shortDataBlockLen = shortBlockLen - blockEccLen;
-
+
uint8_t result[data->capacityBytes];
memset(result, 0, sizeof(result));
-
+
uint8_t coeff[blockEccLen];
rs_init(blockEccLen, coeff);
-
+
uint16_t offset = 0;
- uint8_t *dataBytes = data->data;
-
-
+ uint8_t* dataBytes = data->data;
+
// Interleave all short blocks
- for (uint8_t i = 0; i < shortDataBlockLen; i++) {
+ for(uint8_t i = 0; i < shortDataBlockLen; i++) {
uint16_t index = i;
uint8_t stride = shortDataBlockLen;
- for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) {
+ for(uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) {
result[offset++] = dataBytes[index];
-
+
#if LOCK_VERSION == 0 || LOCK_VERSION >= 5
- if (blockNum == numShortBlocks) { stride++; }
+ if(blockNum == numShortBlocks) {
+ stride++;
+ }
#endif
index += stride;
}
}
-
+
// Version less than 5 only have short blocks
#if LOCK_VERSION == 0 || LOCK_VERSION >= 5
{
// Interleave long blocks
uint16_t index = shortDataBlockLen * (numShortBlocks + 1);
uint8_t stride = shortDataBlockLen;
- for (uint8_t blockNum = 0; blockNum < numBlocks - numShortBlocks; blockNum++) {
+ for(uint8_t blockNum = 0; blockNum < numBlocks - numShortBlocks; blockNum++) {
result[offset++] = dataBytes[index];
-
- if (blockNum == 0) { stride++; }
+
+ if(blockNum == 0) {
+ stride++;
+ }
index += stride;
}
}
#endif
-
+
// Add all ecc blocks, interleaved
uint8_t blockSize = shortDataBlockLen;
- for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) {
-
+ for(uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) {
#if LOCK_VERSION == 0 || LOCK_VERSION >= 5
- if (blockNum == numShortBlocks) { blockSize++; }
+ if(blockNum == numShortBlocks) {
+ blockSize++;
+ }
#endif
- rs_getRemainder(blockEccLen, coeff, dataBytes, blockSize, &result[offset + blockNum], numBlocks);
+ rs_getRemainder(
+ blockEccLen, coeff, dataBytes, blockSize, &result[offset + blockNum], numBlocks);
dataBytes += blockSize;
}
-
+
memcpy(data->data, result, data->capacityBytes);
data->bitOffsetOrWidth = moduleCount;
}
@@ -752,94 +845,110 @@ static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket *data
// The format bits can be determined by ECC_FORMAT_BITS >> (2 * ecc)
static const uint8_t ECC_FORMAT_BITS = (0x02 << 6) | (0x03 << 4) | (0x00 << 2) | (0x01 << 0);
-
uint16_t qrcode_getBufferSize(uint8_t version) {
return bb_getGridSizeBytes(4 * version + 17);
}
// @TODO: Return error if data is too big.
-int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length) {
+int8_t qrcode_initBytes(
+ QRCode* qrcode,
+ uint8_t* modules,
+ uint8_t version,
+ uint8_t ecc,
+ uint8_t* data,
+ uint16_t length) {
uint8_t size = version * 4 + 17;
qrcode->version = version;
qrcode->size = size;
qrcode->ecc = ecc;
qrcode->modules = modules;
-
+
uint8_t eccFormatBits = (ECC_FORMAT_BITS >> (2 * ecc)) & 0x03;
-
+
#if LOCK_VERSION == 0
uint16_t moduleCount = NUM_RAW_DATA_MODULES[version - 1];
- uint16_t dataCapacity = moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits][version - 1];
+ uint16_t dataCapacity =
+ moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits][version - 1];
#else
version = LOCK_VERSION;
uint16_t moduleCount = NUM_RAW_DATA_MODULES;
uint16_t dataCapacity = moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits];
#endif
-
+
struct BitBucket codewords;
uint8_t codewordBytes[bb_getBufferSizeBytes(moduleCount)];
bb_initBuffer(&codewords, codewordBytes, (int32_t)sizeof(codewordBytes));
-
+
// Place the data code words into the buffer
int8_t mode = encodeDataCodewords(&codewords, data, length, version);
-
- if (mode < 0) { return -1; }
+
+ if(mode < 0) {
+ return -1;
+ }
qrcode->mode = mode;
-
+
// Add terminator and pad up to a byte if applicable
uint32_t padding = (dataCapacity * 8) - codewords.bitOffsetOrWidth;
- if (padding > 4) { padding = 4; }
+ if(padding > 4) {
+ padding = 4;
+ }
bb_appendBits(&codewords, 0, padding);
bb_appendBits(&codewords, 0, (8 - codewords.bitOffsetOrWidth % 8) % 8);
// Pad with alternate bytes until data capacity is reached
- for (uint8_t padByte = 0xEC; codewords.bitOffsetOrWidth < (dataCapacity * 8); padByte ^= 0xEC ^ 0x11) {
+ for(uint8_t padByte = 0xEC; codewords.bitOffsetOrWidth < (dataCapacity * 8);
+ padByte ^= 0xEC ^ 0x11) {
bb_appendBits(&codewords, padByte, 8);
}
BitBucket modulesGrid;
bb_initGrid(&modulesGrid, modules, size);
-
+
BitBucket isFunctionGrid;
uint8_t isFunctionGridBytes[bb_getGridSizeBytes(size)];
bb_initGrid(&isFunctionGrid, isFunctionGridBytes, size);
-
+
// Draw function patterns, draw all codewords, do masking
drawFunctionPatterns(&modulesGrid, &isFunctionGrid, version, eccFormatBits);
performErrorCorrection(version, eccFormatBits, &codewords);
drawCodewords(&modulesGrid, &isFunctionGrid, &codewords);
-
+
// Find the best (lowest penalty) mask
uint8_t mask = 0;
int32_t minPenalty = INT32_MAX;
- for (uint8_t i = 0; i < 8; i++) {
+ for(uint8_t i = 0; i < 8; i++) {
drawFormatBits(&modulesGrid, &isFunctionGrid, eccFormatBits, i);
applyMask(&modulesGrid, &isFunctionGrid, i);
int penalty = getPenaltyScore(&modulesGrid);
- if (penalty < minPenalty) {
+ if(penalty < minPenalty) {
mask = i;
minPenalty = penalty;
}
- applyMask(&modulesGrid, &isFunctionGrid, i); // Undoes the mask due to XOR
+ applyMask(&modulesGrid, &isFunctionGrid, i); // Undoes the mask due to XOR
}
-
+
qrcode->mask = mask;
-
+
// Overwrite old format bits
drawFormatBits(&modulesGrid, &isFunctionGrid, eccFormatBits, mask);
-
+
// Apply the final choice of mask
applyMask(&modulesGrid, &isFunctionGrid, mask);
return 0;
}
-int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data) {
+int8_t qrcode_initText(
+ QRCode* qrcode,
+ uint8_t* modules,
+ uint8_t version,
+ uint8_t ecc,
+ const char* data) {
return qrcode_initBytes(qrcode, modules, version, ecc, (uint8_t*)data, strlen(data));
}
-bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y) {
- if (x >= qrcode->size || y >= qrcode->size) {
+bool qrcode_getModule(QRCode* qrcode, uint8_t x, uint8_t y) {
+ if(x >= qrcode->size || y >= qrcode->size) {
return false;
}
diff --git a/applications/plugins/qrcode/qrcode.h b/applications/plugins/qrcode/qrcode.h
index 6e8bf1c364..12f2d9ab3a 100644
--- a/applications/plugins/qrcode/qrcode.h
+++ b/applications/plugins/qrcode/qrcode.h
@@ -33,7 +33,6 @@
* See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp
*/
-
#ifndef __QRCODE_H_
#define __QRCODE_H_
@@ -46,55 +45,56 @@
#include
#include
-
// QR Code Format Encoding
-#define MODE_NUMERIC 0
-#define MODE_ALPHANUMERIC 1
-#define MODE_BYTE 2
-
+#define MODE_NUMERIC 0
+#define MODE_ALPHANUMERIC 1
+#define MODE_BYTE 2
// Error Correction Code Levels
-#define ECC_LOW 0
-#define ECC_MEDIUM 1
-#define ECC_QUARTILE 2
-#define ECC_HIGH 3
-
+#define ECC_LOW 0
+#define ECC_MEDIUM 1
+#define ECC_QUARTILE 2
+#define ECC_HIGH 3
// If set to non-zero, this library can ONLY produce QR codes at that version
// This saves a lot of dynamic memory, as the codeword tables are skipped
#ifndef LOCK_VERSION
-#define LOCK_VERSION 0
+#define LOCK_VERSION 0
#endif
-
typedef struct QRCode {
uint8_t version;
uint8_t size;
uint8_t ecc;
uint8_t mode;
uint8_t mask;
- uint8_t *modules;
+ uint8_t* modules;
} QRCode;
-
#ifdef __cplusplus
-extern "C"{
-#endif /* __cplusplus */
-
-
+extern "C" {
+#endif /* __cplusplus */
uint16_t qrcode_getBufferSize(uint8_t version);
-int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data);
-int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length);
-
-bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y);
-
-
+int8_t qrcode_initText(
+ QRCode* qrcode,
+ uint8_t* modules,
+ uint8_t version,
+ uint8_t ecc,
+ const char* data);
+int8_t qrcode_initBytes(
+ QRCode* qrcode,
+ uint8_t* modules,
+ uint8_t version,
+ uint8_t ecc,
+ uint8_t* data,
+ uint16_t length);
+
+bool qrcode_getModule(QRCode* qrcode, uint8_t x, uint8_t y);
#ifdef __cplusplus
}
-#endif /* __cplusplus */
-
+#endif /* __cplusplus */
-#endif /* __QRCODE_H_ */
+#endif /* __QRCODE_H_ */
diff --git a/applications/plugins/qrcode/qrcode_app.c b/applications/plugins/qrcode/qrcode_app.c
index 8a4d367831..056f04eb98 100644
--- a/applications/plugins/qrcode/qrcode_app.c
+++ b/applications/plugins/qrcode/qrcode_app.c
@@ -28,22 +28,22 @@ static const uint16_t MAX_LENGTH[3][4][MAX_QRCODE_VERSION] = {
// Numeric
{41, 77, 127, 187, 255, 322, 370, 461, 552, 652, 772}, // Low
{34, 63, 101, 149, 202, 255, 293, 365, 432, 513, 604}, // Medium
- {27, 48, 77, 111, 144, 178, 207, 259, 312, 364, 427}, // Quartile
- {17, 34, 58, 82, 106, 139, 154, 202, 235, 288, 331}, // High
+ {27, 48, 77, 111, 144, 178, 207, 259, 312, 364, 427}, // Quartile
+ {17, 34, 58, 82, 106, 139, 154, 202, 235, 288, 331}, // High
},
{
// Alphanumeric
{25, 47, 77, 114, 154, 195, 224, 279, 335, 395, 468}, // Low
- {20, 38, 61, 90, 122, 154, 178, 221, 262, 311, 366}, // Medium
- {16, 29, 47, 67, 87, 108, 125, 157, 189, 221, 259}, // Quartile
- {10, 20, 35, 50, 64, 84, 93, 122, 143, 174, 200}, // High
+ {20, 38, 61, 90, 122, 154, 178, 221, 262, 311, 366}, // Medium
+ {16, 29, 47, 67, 87, 108, 125, 157, 189, 221, 259}, // Quartile
+ {10, 20, 35, 50, 64, 84, 93, 122, 143, 174, 200}, // High
},
{
// Binary
{17, 32, 53, 78, 106, 134, 154, 192, 230, 271, 321}, // Low
- {14, 26, 42, 62, 84, 106, 122, 152, 180, 213, 251}, // Medium
- {11, 20, 32, 46, 60, 74, 86, 108, 130, 151, 177}, // Quartile
- {7, 14, 24, 34, 44, 58, 64, 84, 98, 119, 137}, // High
+ {14, 26, 42, 62, 84, 106, 122, 152, 180, 213, 251}, // Medium
+ {11, 20, 32, 46, 60, 74, 86, 108, 130, 151, 177}, // Quartile
+ {7, 14, 24, 34, 44, 58, 64, 84, 98, 119, 137}, // High
},
};
@@ -72,12 +72,17 @@ typedef struct {
* @returns a character corresponding to the ecc level
*/
static char get_ecc_char(uint8_t ecc) {
- switch (ecc) {
- case 0: return 'L';
- case 1: return 'M';
- case 2: return 'Q';
- case 3: return 'H';
- default: return '?';
+ switch(ecc) {
+ case 0:
+ return 'L';
+ case 1:
+ return 'M';
+ case 2:
+ return 'Q';
+ case 3:
+ return 'H';
+ default:
+ return '?';
}
}
@@ -86,12 +91,17 @@ static char get_ecc_char(uint8_t ecc) {
* @returns a character corresponding to the mode
*/
static char get_mode_char(uint8_t mode) {
- switch (mode) {
- case 0: return 'N';
- case 1: return 'A';
- case 2: return 'B';
- case 3: return 'K';
- default: return '?';
+ switch(mode) {
+ case 0:
+ return 'N';
+ case 1:
+ return 'A';
+ case 2:
+ return 'B';
+ case 3:
+ return 'K';
+ default:
+ return '?';
}
}
@@ -114,68 +124,108 @@ static void render_callback(Canvas* canvas, void* ctx) {
uint8_t font_height = canvas_current_font_height(canvas);
uint8_t width = canvas_width(canvas);
uint8_t height = canvas_height(canvas);
- if (instance->loading) {
- canvas_draw_str_aligned(canvas, width / 2, height / 2, AlignCenter, AlignCenter, "Loading...");
- } else if (instance->qrcode) {
+ if(instance->loading) {
+ canvas_draw_str_aligned(
+ canvas, width / 2, height / 2, AlignCenter, AlignCenter, "Loading...");
+ } else if(instance->qrcode) {
uint8_t size = instance->qrcode->size;
uint8_t pixel_size = height / size;
uint8_t top = (height - pixel_size * size) / 2;
uint8_t left = ((instance->show_stats ? 65 : width) - pixel_size * size) / 2;
- for (uint8_t y = 0; y < size; y++) {
- for (uint8_t x = 0; x < size; x++) {
- if (qrcode_getModule(instance->qrcode, x, y)) {
- if (pixel_size == 1) {
+ for(uint8_t y = 0; y < size; y++) {
+ for(uint8_t x = 0; x < size; x++) {
+ if(qrcode_getModule(instance->qrcode, x, y)) {
+ if(pixel_size == 1) {
canvas_draw_dot(canvas, left + x * pixel_size, top + y * pixel_size);
} else {
- canvas_draw_box(canvas, left + x * pixel_size, top + y * pixel_size, pixel_size, pixel_size);
+ canvas_draw_box(
+ canvas,
+ left + x * pixel_size,
+ top + y * pixel_size,
+ pixel_size,
+ pixel_size);
}
}
}
}
- if (instance->show_stats) {
+ if(instance->show_stats) {
top = 10;
left = 66;
FuriString* str = furi_string_alloc();
- if (!instance->edit || instance->selected_idx == 0) {
+ if(!instance->edit || instance->selected_idx == 0) {
furi_string_printf(str, "Ver: %i", instance->set_version);
canvas_draw_str(canvas, left + 5, top + font_height, furi_string_get_cstr(str));
- if (instance->selected_idx == 0) {
- canvas_draw_triangle(canvas, left, top + font_height / 2, font_height - 4, 4, CanvasDirectionLeftToRight);
+ if(instance->selected_idx == 0) {
+ canvas_draw_triangle(
+ canvas,
+ left,
+ top + font_height / 2,
+ font_height - 4,
+ 4,
+ CanvasDirectionLeftToRight);
}
- if (instance->edit) {
+ if(instance->edit) {
uint8_t arrow_left = left + 5 + canvas_string_width(canvas, "Ver: 8") / 2;
- canvas_draw_triangle(canvas, arrow_left, top, font_height - 4, 4, CanvasDirectionBottomToTop);
- canvas_draw_triangle(canvas, arrow_left, top + font_height + 1, font_height - 4, 4, CanvasDirectionTopToBottom);
+ canvas_draw_triangle(
+ canvas, arrow_left, top, font_height - 4, 4, CanvasDirectionBottomToTop);
+ canvas_draw_triangle(
+ canvas,
+ arrow_left,
+ top + font_height + 1,
+ font_height - 4,
+ 4,
+ CanvasDirectionTopToBottom);
}
}
- if (!instance->edit || instance->selected_idx == 1) {
+ if(!instance->edit || instance->selected_idx == 1) {
furi_string_printf(str, "ECC: %c", get_ecc_char(instance->set_ecc));
- canvas_draw_str(canvas, left + 5, 2 * font_height + top + 2, furi_string_get_cstr(str));
- if (instance->selected_idx == 1) {
- canvas_draw_triangle(canvas, left, 3 * font_height / 2 + top + 2, font_height - 4, 4, CanvasDirectionLeftToRight);
+ canvas_draw_str(
+ canvas, left + 5, 2 * font_height + top + 2, furi_string_get_cstr(str));
+ if(instance->selected_idx == 1) {
+ canvas_draw_triangle(
+ canvas,
+ left,
+ 3 * font_height / 2 + top + 2,
+ font_height - 4,
+ 4,
+ CanvasDirectionLeftToRight);
}
- if (instance->edit) {
+ if(instance->edit) {
uint8_t arrow_left = left + 5 + canvas_string_width(canvas, "ECC: H") / 2;
- canvas_draw_triangle(canvas, arrow_left, font_height + top + 2, font_height - 4, 4, CanvasDirectionBottomToTop);
- canvas_draw_triangle(canvas, arrow_left, 2 * font_height + top + 3, font_height - 4, 4, CanvasDirectionTopToBottom);
+ canvas_draw_triangle(
+ canvas,
+ arrow_left,
+ font_height + top + 2,
+ font_height - 4,
+ 4,
+ CanvasDirectionBottomToTop);
+ canvas_draw_triangle(
+ canvas,
+ arrow_left,
+ 2 * font_height + top + 3,
+ font_height - 4,
+ 4,
+ CanvasDirectionTopToBottom);
}
}
- if (!instance->edit) {
+ if(!instance->edit) {
furi_string_printf(str, "Mod: %c", get_mode_char(instance->qrcode->mode));
- canvas_draw_str(canvas, left + 5, 3 * font_height + top + 4, furi_string_get_cstr(str));
+ canvas_draw_str(
+ canvas, left + 5, 3 * font_height + top + 4, furi_string_get_cstr(str));
}
furi_string_free(str);
}
} else {
uint8_t margin = (height - font_height * 2) / 3;
- canvas_draw_str_aligned(canvas, width / 2, margin, AlignCenter, AlignTop, "Could not load qrcode.");
- if (instance->too_long) {
+ canvas_draw_str_aligned(
+ canvas, width / 2, margin, AlignCenter, AlignTop, "Could not load qrcode.");
+ if(instance->too_long) {
canvas_set_font(canvas, FontSecondary);
canvas_draw_str(canvas, width / 2, margin * 2 + font_height, "Message is too long.");
}
@@ -192,7 +242,7 @@ static void render_callback(Canvas* canvas, void* ctx) {
static void input_callback(InputEvent* input_event, void* ctx) {
furi_assert(input_event);
furi_assert(ctx);
- if (input_event->type == InputTypeShort) {
+ if(input_event->type == InputTypeShort) {
QRCodeApp* instance = ctx;
furi_message_queue_put(instance->input_queue, input_event, 0);
}
@@ -205,9 +255,9 @@ static void input_callback(InputEvent* input_event, void* ctx) {
*/
static bool is_numeric(const char* str, uint16_t len) {
furi_assert(str);
- while (len > 0) {
+ while(len > 0) {
char c = str[--len];
- if (c < '0' || c > '9') return false;
+ if(c < '0' || c > '9') return false;
}
return true;
}
@@ -219,19 +269,12 @@ static bool is_numeric(const char* str, uint16_t len) {
*/
static bool is_alphanumeric(const char* str, uint16_t len) {
furi_assert(str);
- while (len > 0) {
+ while(len > 0) {
char c = str[--len];
- if (c >= '0' && c <= '9') continue;
- if (c >= 'A' && c <= 'Z') continue;
- if (c == ' '
- || c == '$'
- || c == '%'
- || c == '*'
- || c == '+'
- || c == '-'
- || c == '.'
- || c == '/'
- || c == ':')
+ if(c >= '0' && c <= '9') continue;
+ if(c >= 'A' && c <= 'Z') continue;
+ if(c == ' ' || c == '$' || c == '%' || c == '*' || c == '+' || c == '-' || c == '.' ||
+ c == '/' || c == ':')
continue;
return false;
}
@@ -277,8 +320,9 @@ static bool rebuild_qrcode(QRCodeApp* instance, uint8_t version, uint8_t ecc) {
uint16_t len = strlen(cstr);
instance->qrcode = qrcode_alloc(version);
- int8_t res = qrcode_initBytes(instance->qrcode, instance->qrcode->modules, version, ecc, (uint8_t*)cstr, len);
- if (res != 0) {
+ int8_t res = qrcode_initBytes(
+ instance->qrcode, instance->qrcode->modules, version, ecc, (uint8_t*)cstr, len);
+ if(res != 0) {
FURI_LOG_E(TAG, "Could not create qrcode");
qrcode_free(instance->qrcode);
@@ -300,11 +344,11 @@ static bool qrcode_load_string(QRCodeApp* instance, FuriString* str) {
furi_assert(str);
furi_check(furi_mutex_acquire(instance->mutex, FuriWaitForever) == FuriStatusOk);
- if (instance->message) {
+ if(instance->message) {
furi_string_free(instance->message);
instance->message = NULL;
}
- if (instance->qrcode) {
+ if(instance->qrcode) {
qrcode_free(instance->qrcode);
instance->qrcode = NULL;
}
@@ -319,15 +363,17 @@ static bool qrcode_load_string(QRCodeApp* instance, FuriString* str) {
uint16_t len = strlen(cstr);
instance->message = furi_string_alloc_set(str);
- if (!instance->message) {
+ if(!instance->message) {
FURI_LOG_E(TAG, "Could not allocate message");
break;
}
// figure out the qrcode "mode"
uint8_t mode = MODE_BYTE;
- if (is_numeric(cstr, len)) mode = MODE_NUMERIC;
- else if (is_alphanumeric(cstr, len)) mode = MODE_ALPHANUMERIC;
+ if(is_numeric(cstr, len))
+ mode = MODE_NUMERIC;
+ else if(is_alphanumeric(cstr, len))
+ mode = MODE_ALPHANUMERIC;
// Figure out the smallest qrcode version that'll fit all of the data -
// we prefer the smallest version to maximize the pixel size of each
@@ -336,11 +382,11 @@ static bool qrcode_load_string(QRCodeApp* instance, FuriString* str) {
// number, so we'll add one later.
uint8_t ecc = ECC_LOW;
uint8_t version = 0;
- while (version < MAX_QRCODE_VERSION && MAX_LENGTH[mode][ecc][version] < len) {
+ while(version < MAX_QRCODE_VERSION && MAX_LENGTH[mode][ecc][version] < len) {
version++;
}
- if (version == MAX_QRCODE_VERSION) {
+ if(version == MAX_QRCODE_VERSION) {
instance->too_long = true;
break;
}
@@ -350,13 +396,13 @@ static bool qrcode_load_string(QRCodeApp* instance, FuriString* str) {
// above that ECC_LOW (0) works... don't forget to add one to that
// version number...
ecc = ECC_HIGH;
- while (MAX_LENGTH[mode][ecc][version] < len) {
+ while(MAX_LENGTH[mode][ecc][version] < len) {
ecc--;
}
version++;
// Build the qrcode
- if (!rebuild_qrcode(instance, version, ecc)) {
+ if(!rebuild_qrcode(instance, version, ecc)) {
furi_string_free(instance->message);
instance->message = NULL;
break;
@@ -365,7 +411,7 @@ static bool qrcode_load_string(QRCodeApp* instance, FuriString* str) {
instance->min_version = instance->set_version = version;
instance->max_ecc_at_min_version = instance->set_ecc = ecc;
result = true;
- } while (false);
+ } while(false);
instance->loading = false;
@@ -391,27 +437,26 @@ static bool qrcode_load_file(QRCodeApp* instance, const char* file_path) {
FlipperFormat* file = flipper_format_file_alloc(storage);
do {
- if (!flipper_format_file_open_existing(file, file_path)) break;
+ if(!flipper_format_file_open_existing(file, file_path)) break;
uint32_t version = 0;
- if (!flipper_format_read_header(file, temp_str, &version)) break;
- if (furi_string_cmp_str(temp_str, QRCODE_FILETYPE)
- || version != QRCODE_FILE_VERSION) {
+ if(!flipper_format_read_header(file, temp_str, &version)) break;
+ if(furi_string_cmp_str(temp_str, QRCODE_FILETYPE) || version != QRCODE_FILE_VERSION) {
FURI_LOG_E(TAG, "Incorrect file format or version");
break;
}
- if (!flipper_format_read_string(file, "Message", temp_str)) {
+ if(!flipper_format_read_string(file, "Message", temp_str)) {
FURI_LOG_E(TAG, "Message is missing");
break;
}
- if (!qrcode_load_string(instance, temp_str)) {
+ if(!qrcode_load_string(instance, temp_str)) {
break;
}
result = true;
- } while (false);
+ } while(false);
furi_record_close(RECORD_STORAGE);
flipper_format_free(file);
@@ -454,8 +499,8 @@ static QRCodeApp* qrcode_app_alloc() {
* @param qrcode_app The app to free
*/
static void qrcode_app_free(QRCodeApp* instance) {
- if (instance->message) furi_string_free(instance->message);
- if (instance->qrcode) qrcode_free(instance->qrcode);
+ if(instance->message) furi_string_free(instance->message);
+ if(instance->qrcode) qrcode_free(instance->qrcode);
gui_remove_view_port(instance->gui, instance->view_port);
furi_record_close(RECORD_GUI);
@@ -475,14 +520,14 @@ int32_t qrcode_app(void* p) {
FuriString* file_path = furi_string_alloc();
do {
- if (p && strlen(p)) {
+ if(p && strlen(p)) {
furi_string_set(file_path, (const char*)p);
} else {
furi_string_set(file_path, QRCODE_FOLDER);
DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(
- &browser_options, QRCODE_EXTENSION, &I_qrcode_10px);
+ &browser_options, QRCODE_EXTENSION, &I_qrcode_10px);
browser_options.hide_ext = true;
browser_options.base_path = QRCODE_FOLDER;
@@ -490,26 +535,27 @@ int32_t qrcode_app(void* p) {
bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options);
furi_record_close(RECORD_DIALOGS);
- if (!res) {
+ if(!res) {
FURI_LOG_E(TAG, "No file selected");
break;
}
}
- if (!qrcode_load_file(instance, furi_string_get_cstr(file_path))) {
+ if(!qrcode_load_file(instance, furi_string_get_cstr(file_path))) {
FURI_LOG_E(TAG, "Unable to load file");
}
InputEvent input;
- while (furi_message_queue_get(instance->input_queue, &input, FuriWaitForever) == FuriStatusOk) {
+ while(furi_message_queue_get(instance->input_queue, &input, FuriWaitForever) ==
+ FuriStatusOk) {
furi_check(furi_mutex_acquire(instance->mutex, FuriWaitForever) == FuriStatusOk);
- if (input.key == InputKeyBack) {
- if (instance->message) {
+ if(input.key == InputKeyBack) {
+ if(instance->message) {
furi_string_free(instance->message);
instance->message = NULL;
}
- if (instance->qrcode) {
+ if(instance->qrcode) {
qrcode_free(instance->qrcode);
instance->qrcode = NULL;
}
@@ -517,43 +563,49 @@ int32_t qrcode_app(void* p) {
instance->edit = false;
furi_mutex_release(instance->mutex);
break;
- } else if (input.key == InputKeyRight) {
+ } else if(input.key == InputKeyRight) {
instance->show_stats = true;
- } else if (input.key == InputKeyLeft) {
+ } else if(input.key == InputKeyLeft) {
instance->show_stats = false;
- } else if (instance->show_stats && !instance->loading && instance->qrcode) {
- if (input.key == InputKeyUp) {
- if (!instance->edit) {
+ } else if(instance->show_stats && !instance->loading && instance->qrcode) {
+ if(input.key == InputKeyUp) {
+ if(!instance->edit) {
instance->selected_idx = MAX(0, instance->selected_idx - 1);
} else {
- if (instance->selected_idx == 0 && instance->set_version < MAX_QRCODE_VERSION) {
+ if(instance->selected_idx == 0 &&
+ instance->set_version < MAX_QRCODE_VERSION) {
instance->set_version++;
- } else if (instance->selected_idx == 1) {
- uint8_t max_ecc = instance->set_version == instance->min_version ? instance->max_ecc_at_min_version : ECC_HIGH;
- if (instance->set_ecc < max_ecc) {
+ } else if(instance->selected_idx == 1) {
+ uint8_t max_ecc = instance->set_version == instance->min_version ?
+ instance->max_ecc_at_min_version :
+ ECC_HIGH;
+ if(instance->set_ecc < max_ecc) {
instance->set_ecc++;
}
}
}
- } else if (input.key == InputKeyDown) {
- if (!instance->edit) {
+ } else if(input.key == InputKeyDown) {
+ if(!instance->edit) {
instance->selected_idx = MIN(1, instance->selected_idx + 1);
} else {
- if (instance->selected_idx == 0 && instance->set_version > instance->min_version) {
+ if(instance->selected_idx == 0 &&
+ instance->set_version > instance->min_version) {
instance->set_version--;
- if (instance->set_version == instance->min_version) {
- instance->set_ecc = MAX(instance->set_ecc, instance->max_ecc_at_min_version);
+ if(instance->set_version == instance->min_version) {
+ instance->set_ecc =
+ MAX(instance->set_ecc, instance->max_ecc_at_min_version);
}
- } else if (instance->selected_idx == 1 && instance->set_ecc > 0) {
+ } else if(instance->selected_idx == 1 && instance->set_ecc > 0) {
instance->set_ecc--;
}
}
- } else if (input.key == InputKeyOk) {
- if (instance->edit && (instance->set_version != instance->qrcode->version || instance->set_ecc != instance->qrcode->ecc)) {
+ } else if(input.key == InputKeyOk) {
+ if(instance->edit && (instance->set_version != instance->qrcode->version ||
+ instance->set_ecc != instance->qrcode->ecc)) {
QRCode* qrcode = instance->qrcode;
instance->loading = true;
- if (rebuild_qrcode(instance, instance->set_version, instance->set_ecc)) {
+ if(rebuild_qrcode(instance, instance->set_version, instance->set_ecc)) {
qrcode_free(qrcode);
} else {
FURI_LOG_E(TAG, "Could not rebuild qrcode");
@@ -572,12 +624,12 @@ int32_t qrcode_app(void* p) {
view_port_update(instance->view_port);
}
- if (p && strlen(p)) {
+ if(p && strlen(p)) {
// if started with an arg, exit instead
// of looping back to the browser
break;
}
- } while (true);
+ } while(true);
furi_string_free(file_path);
qrcode_app_free(instance);
diff --git a/applications/plugins/solitaire/solitaire.c b/applications/plugins/solitaire/solitaire.c
index b099e77a13..8893b39863 100644
--- a/applications/plugins/solitaire/solitaire.c
+++ b/applications/plugins/solitaire/solitaire.c
@@ -255,8 +255,7 @@ bool place_on_top(Card* where, Card what) {
int8_t b_letter = (int8_t)what.character;
if(a_letter == 12) a_letter = -1;
if(b_letter == 12) b_letter = -1;
- if(where->disabled && b_letter!=-1)
- return false;
+ if(where->disabled && b_letter != -1) return false;
if((a_letter + 1) == b_letter) {
where->disabled = what.disabled;
where->pip = what.pip;
diff --git a/applications/plugins/totp/cli/cli.c b/applications/plugins/totp/cli/cli.c
index e61c672069..8f4708f4db 100644
--- a/applications/plugins/totp/cli/cli.c
+++ b/applications/plugins/totp/cli/cli.c
@@ -11,6 +11,7 @@
#include "commands/move/move.h"
#include "commands/pin/pin.h"
#include "commands/notification/notification.h"
+#include "commands/reset/reset.h"
static void totp_cli_print_unknown_command(const FuriString* unknown_command) {
TOTP_CLI_PRINTF(
@@ -20,7 +21,8 @@ static void totp_cli_print_unknown_command(const FuriString* unknown_command) {
}
static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
- PluginState* plugin_state = (PluginState*)context;
+ TotpCliContext* cli_context = context;
+ PluginState* plugin_state = cli_context->plugin_state;
FuriString* cmd = furi_string_alloc();
@@ -55,6 +57,8 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
totp_cli_command_pin_handle(plugin_state, args, cli);
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_NOTIFICATION) == 0) {
totp_cli_command_notification_handle(plugin_state, args, cli);
+ } else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_RESET) == 0) {
+ totp_cli_command_reset_handle(cli, cli_context->event_queue);
} else {
totp_cli_print_unknown_command(cmd);
}
@@ -62,15 +66,22 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
furi_string_free(cmd);
}
-void totp_cli_register_command_handler(PluginState* plugin_state) {
+TotpCliContext*
+ totp_cli_register_command_handler(PluginState* plugin_state, FuriMessageQueue* event_queue) {
Cli* cli = furi_record_open(RECORD_CLI);
+ TotpCliContext* context = malloc(sizeof(TotpCliContext));
+ furi_check(context != NULL);
+ context->plugin_state = plugin_state;
+ context->event_queue = event_queue;
cli_add_command(
- cli, TOTP_CLI_COMMAND_NAME, CliCommandFlagParallelSafe, totp_cli_handler, plugin_state);
+ cli, TOTP_CLI_COMMAND_NAME, CliCommandFlagParallelSafe, totp_cli_handler, context);
furi_record_close(RECORD_CLI);
+ return context;
}
-void totp_cli_unregister_command_handler() {
+void totp_cli_unregister_command_handler(TotpCliContext* context) {
Cli* cli = furi_record_open(RECORD_CLI);
cli_delete_command(cli, TOTP_CLI_COMMAND_NAME);
furi_record_close(RECORD_CLI);
+ free(context);
}
\ No newline at end of file
diff --git a/applications/plugins/totp/cli/cli.h b/applications/plugins/totp/cli/cli.h
index 3eb18172cf..2e4b92db89 100644
--- a/applications/plugins/totp/cli/cli.h
+++ b/applications/plugins/totp/cli/cli.h
@@ -3,5 +3,11 @@
#include
#include "../types/plugin_state.h"
-void totp_cli_register_command_handler(PluginState* plugin_state);
-void totp_cli_unregister_command_handler();
\ No newline at end of file
+typedef struct {
+ PluginState* plugin_state;
+ FuriMessageQueue* event_queue;
+} TotpCliContext;
+
+TotpCliContext*
+ totp_cli_register_command_handler(PluginState* plugin_state, FuriMessageQueue* event_queue);
+void totp_cli_unregister_command_handler(TotpCliContext* context);
\ No newline at end of file
diff --git a/applications/plugins/totp/cli/cli_helpers.c b/applications/plugins/totp/cli/cli_helpers.c
index 0bea6fd906..9846371646 100644
--- a/applications/plugins/totp/cli/cli_helpers.c
+++ b/applications/plugins/totp/cli/cli_helpers.c
@@ -1,5 +1,6 @@
#include "cli_helpers.h"
#include
+#include "../types/plugin_event.h"
bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli) {
if(plugin_state->current_scene == TotpSceneAuthentication) {
@@ -17,5 +18,45 @@ bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli) {
}
}
+ return true;
+}
+
+void totp_cli_force_close_app(FuriMessageQueue* event_queue) {
+ PluginEvent event = {.type = EventForceCloseApp};
+ furi_message_queue_put(event_queue, &event, FuriWaitForever);
+}
+
+bool totp_cli_read_line(Cli* cli, FuriString* out_str, bool mask_user_input) {
+ uint8_t c;
+ while(cli_read(cli, &c, 1) == 1) {
+ if(c == CliSymbolAsciiEsc) {
+ // Some keys generating escape-sequences
+ // We need to ignore them as we care about alpha-numerics only
+ uint8_t c2;
+ cli_read_timeout(cli, &c2, 1, 0);
+ cli_read_timeout(cli, &c2, 1, 0);
+ } else if(c == CliSymbolAsciiETX) {
+ cli_nl();
+ return false;
+ } else if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ if(mask_user_input) {
+ putc('*', stdout);
+ } else {
+ putc(c, stdout);
+ }
+ fflush(stdout);
+ furi_string_push_back(out_str, c);
+ } else if(c == CliSymbolAsciiBackspace || c == CliSymbolAsciiDel) {
+ size_t out_str_size = furi_string_size(out_str);
+ if(out_str_size > 0) {
+ TOTP_CLI_DELETE_LAST_CHAR();
+ furi_string_left(out_str, out_str_size - 1);
+ }
+ } else if(c == CliSymbolAsciiCR) {
+ cli_nl();
+ break;
+ }
+ }
+
return true;
}
\ No newline at end of file
diff --git a/applications/plugins/totp/cli/cli_helpers.h b/applications/plugins/totp/cli/cli_helpers.h
index ae6fe6e0cb..5027d7027f 100644
--- a/applications/plugins/totp/cli/cli_helpers.h
+++ b/applications/plugins/totp/cli/cli_helpers.h
@@ -45,7 +45,22 @@
* @brief Checks whether user is authenticated and entered correct PIN.
* If user is not authenticated it prompts user to enter correct PIN to authenticate.
* @param plugin_state application state
- * @param cli reference to the firmware CLI subsystem
+ * @param cli pointer to the firmware CLI subsystem
* @return \c true if user is already authenticated or successfully authenticated; \c false otherwise
*/
bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli);
+
+/**
+ * @brief Forces application to be instantly closed
+ * @param event_queue main app queue
+ */
+void totp_cli_force_close_app(FuriMessageQueue* event_queue);
+
+/**
+ * @brief Reads line of characters from console
+ * @param cli pointer to the firmware CLI subsystem
+ * @param out_str pointer to an output string to put read line to
+ * @param mask_user_input whether to mask input characters in console or not
+ * @return \c true if line successfully read and confirmed; \c false otherwise
+ */
+bool totp_cli_read_line(Cli* cli, FuriString* out_str, bool mask_user_input);
diff --git a/applications/plugins/totp/cli/commands/add/add.c b/applications/plugins/totp/cli/commands/add/add.c
index e037546e27..ba36a973ab 100644
--- a/applications/plugins/totp/cli/commands/add/add.c
+++ b/applications/plugins/totp/cli/commands/add/add.c
@@ -76,43 +76,6 @@ static void furi_string_secure_free(FuriString* str) {
furi_string_free(str);
}
-static bool totp_cli_read_secret(Cli* cli, FuriString* out_str, bool mask_user_input) {
- uint8_t c;
- while(cli_read(cli, &c, 1) == 1) {
- if(c == CliSymbolAsciiEsc) {
- // Some keys generating escape-sequences
- // We need to ignore them as we care about alpha-numerics only
- uint8_t c2;
- cli_read_timeout(cli, &c2, 1, 0);
- cli_read_timeout(cli, &c2, 1, 0);
- } else if(c == CliSymbolAsciiETX) {
- TOTP_CLI_DELETE_CURRENT_LINE();
- TOTP_CLI_PRINTF("Cancelled by user\r\n");
- return false;
- } else if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
- if(mask_user_input) {
- putc('*', stdout);
- } else {
- putc(c, stdout);
- }
- fflush(stdout);
- furi_string_push_back(out_str, c);
- } else if(c == CliSymbolAsciiBackspace || c == CliSymbolAsciiDel) {
- size_t out_str_size = furi_string_size(out_str);
- if(out_str_size > 0) {
- TOTP_CLI_DELETE_LAST_CHAR();
- furi_string_left(out_str, out_str_size - 1);
- }
- } else if(c == CliSymbolAsciiCR) {
- cli_nl();
- break;
- }
- }
-
- TOTP_CLI_DELETE_LAST_LINE();
- return true;
-}
-
void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
FuriString* temp_str = furi_string_alloc();
TokenInfo* token_info = token_info_alloc();
@@ -178,13 +141,17 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
// Reading token secret
furi_string_reset(temp_str);
TOTP_CLI_PRINTF("Enter token secret and confirm with [ENTER]\r\n");
- if(!totp_cli_read_secret(cli, temp_str, mask_user_input) ||
+ if(!totp_cli_read_line(cli, temp_str, mask_user_input) ||
!totp_cli_ensure_authenticated(plugin_state, cli)) {
+ TOTP_CLI_DELETE_LAST_LINE();
+ TOTP_CLI_PRINTF("Cancelled by user\r\n");
furi_string_secure_free(temp_str);
token_info_free(token_info);
return;
}
+ TOTP_CLI_DELETE_LAST_LINE();
+
if(!token_info_set_secret(
token_info,
furi_string_get_cstr(temp_str),
diff --git a/applications/plugins/totp/cli/commands/help/help.c b/applications/plugins/totp/cli/commands/help/help.c
index 4199648809..104b39e473 100644
--- a/applications/plugins/totp/cli/commands/help/help.c
+++ b/applications/plugins/totp/cli/commands/help/help.c
@@ -7,6 +7,7 @@
#include "../move/move.h"
#include "../pin/pin.h"
#include "../notification/notification.h"
+#include "../reset/reset.h"
void totp_cli_command_help_docopt_commands() {
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_HELP ", " TOTP_CLI_COMMAND_HELP_ALT
@@ -29,6 +30,7 @@ void totp_cli_command_help_handle() {
totp_cli_command_move_docopt_usage();
totp_cli_command_pin_docopt_usage();
totp_cli_command_notification_docopt_usage();
+ totp_cli_command_reset_docopt_usage();
cli_nl();
TOTP_CLI_PRINTF("Commands:\r\n");
totp_cli_command_help_docopt_commands();
@@ -39,6 +41,7 @@ void totp_cli_command_help_handle() {
totp_cli_command_move_docopt_commands();
totp_cli_command_pin_docopt_commands();
totp_cli_command_notification_docopt_commands();
+ totp_cli_command_reset_docopt_commands();
cli_nl();
TOTP_CLI_PRINTF("Arguments:\r\n");
totp_cli_command_add_docopt_arguments();
diff --git a/applications/plugins/totp/cli/commands/reset/reset.c b/applications/plugins/totp/cli/commands/reset/reset.c
new file mode 100644
index 0000000000..3f20dc8adf
--- /dev/null
+++ b/applications/plugins/totp/cli/commands/reset/reset.c
@@ -0,0 +1,37 @@
+#include "reset.h"
+
+#include
+#include
+#include "../../cli_helpers.h"
+#include "../../../services/config/config.h"
+
+#define TOTP_CLI_RESET_CONFIRMATION_KEYWORD "YES"
+
+void totp_cli_command_reset_docopt_commands() {
+ TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_RESET
+ " Reset application to default settings\r\n");
+}
+
+void totp_cli_command_reset_docopt_usage() {
+ TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NAME " " TOTP_CLI_COMMAND_RESET "\r\n");
+}
+
+void totp_cli_command_reset_handle(Cli* cli, FuriMessageQueue* event_queue) {
+ TOTP_CLI_PRINTF(
+ "As a result of reset all the settings and tokens will be permanently lost.\r\n");
+ TOTP_CLI_PRINTF("Do you really want to reset application?\r\n");
+ TOTP_CLI_PRINTF("Type \"" TOTP_CLI_RESET_CONFIRMATION_KEYWORD
+ "\" and hit to confirm:\r\n");
+ FuriString* temp_str = furi_string_alloc();
+ bool is_confirmed = totp_cli_read_line(cli, temp_str, false) &&
+ furi_string_cmpi_str(temp_str, TOTP_CLI_RESET_CONFIRMATION_KEYWORD) == 0;
+ furi_string_free(temp_str);
+ if(is_confirmed) {
+ totp_config_file_reset();
+ TOTP_CLI_PRINTF("Application has been successfully reset to default.\r\n");
+ TOTP_CLI_PRINTF("Now application will be closed to apply all the changes.\r\n");
+ totp_cli_force_close_app(event_queue);
+ } else {
+ TOTP_CLI_PRINTF("Action was not confirmed by user\r\n");
+ }
+}
\ No newline at end of file
diff --git a/applications/plugins/totp/cli/commands/reset/reset.h b/applications/plugins/totp/cli/commands/reset/reset.h
new file mode 100644
index 0000000000..7c879e13e0
--- /dev/null
+++ b/applications/plugins/totp/cli/commands/reset/reset.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include
+#include "../../../types/plugin_state.h"
+
+#define TOTP_CLI_COMMAND_RESET "reset"
+
+void totp_cli_command_reset_handle(Cli* cli, FuriMessageQueue* event_queue);
+void totp_cli_command_reset_docopt_commands();
+void totp_cli_command_reset_docopt_usage();
\ No newline at end of file
diff --git a/applications/plugins/totp/services/config/config.c b/applications/plugins/totp/services/config/config.c
index 799db79b82..4b2090d55c 100644
--- a/applications/plugins/totp/services/config/config.c
+++ b/applications/plugins/totp/services/config/config.c
@@ -730,4 +730,10 @@ TotpConfigFileUpdateResult
totp_close_storage();
return update_result;
-}
\ No newline at end of file
+}
+
+void totp_config_file_reset() {
+ Storage* storage = totp_open_storage();
+ storage_simply_remove(storage, CONFIG_FILE_PATH);
+ totp_close_storage();
+}
diff --git a/applications/plugins/totp/services/config/config.h b/applications/plugins/totp/services/config/config.h
index bb48105f75..c630810a65 100644
--- a/applications/plugins/totp/services/config/config.h
+++ b/applications/plugins/totp/services/config/config.h
@@ -116,4 +116,9 @@ TotpConfigFileUpdateResult totp_config_file_update_user_settings(const PluginSta
* @return Config file update result
*/
TotpConfigFileUpdateResult
- totp_config_file_update_crypto_signatures(const PluginState* plugin_state);
\ No newline at end of file
+ totp_config_file_update_crypto_signatures(const PluginState* plugin_state);
+
+/**
+ * @brief Reset all the settings to default
+ */
+void totp_config_file_reset();
\ No newline at end of file
diff --git a/applications/plugins/totp/totp_app.c b/applications/plugins/totp/totp_app.c
index 93acf8e4d1..f108378147 100644
--- a/applications/plugins/totp/totp_app.c
+++ b/applications/plugins/totp/totp_app.c
@@ -143,7 +143,7 @@ int32_t totp_app() {
return 255;
}
- totp_cli_register_command_handler(plugin_state);
+ TotpCliContext* cli_context = totp_cli_register_command_handler(plugin_state, event_queue);
totp_scene_director_init_scenes(plugin_state);
if(!totp_activate_initial_scene(plugin_state)) {
FURI_LOG_E(LOGGING_TAG, "An error ocurred during activating initial scene\r\n");
@@ -172,7 +172,11 @@ int32_t totp_app() {
last_user_interaction_time = furi_get_tick();
}
- processing = totp_scene_director_handle_event(&event, plugin_state_m);
+ if(event.type == EventForceCloseApp) {
+ processing = false;
+ } else {
+ processing = totp_scene_director_handle_event(&event, plugin_state_m);
+ }
} else if(
plugin_state_m->pin_set && plugin_state_m->current_scene != TotpSceneAuthentication &&
furi_get_tick() - last_user_interaction_time > IDLE_TIMEOUT) {
@@ -183,7 +187,7 @@ int32_t totp_app() {
release_mutex(&state_mutex, plugin_state_m);
}
- totp_cli_unregister_command_handler();
+ totp_cli_unregister_command_handler(cli_context);
totp_scene_director_deactivate_active_scene(plugin_state);
totp_scene_director_dispose(plugin_state);
diff --git a/applications/plugins/totp/types/event_type.h b/applications/plugins/totp/types/event_type.h
index 4fe9168724..7bdf6981f1 100644
--- a/applications/plugins/totp/types/event_type.h
+++ b/applications/plugins/totp/types/event_type.h
@@ -3,7 +3,4 @@
typedef uint8_t EventType;
-enum EventTypes {
- EventTypeTick,
- EventTypeKey,
-};
+enum EventTypes { EventTypeTick, EventTypeKey, EventForceCloseApp };
diff --git a/applications/plugins/totp/types/token_info.c b/applications/plugins/totp/types/token_info.c
index a5e12ac4cb..b432937887 100644
--- a/applications/plugins/totp/types/token_info.c
+++ b/applications/plugins/totp/types/token_info.c
@@ -28,7 +28,7 @@ bool token_info_set_secret(
size_t token_secret_length,
const uint8_t* iv) {
if(token_secret_length == 0) return false;
-
+
uint8_t* plain_secret = malloc(token_secret_length);
furi_check(plain_secret != NULL);
int plain_secret_length =
diff --git a/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c b/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c
index 5ff6b4cd7c..fa4ba54119 100644
--- a/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c
+++ b/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c
@@ -247,4 +247,4 @@ void totp_scene_app_settings_deactivate(PluginState* plugin_state) {
void totp_scene_app_settings_free(const PluginState* plugin_state) {
UNUSED(plugin_state);
-}
\ No newline at end of file
+}
diff --git a/applications/plugins/unitemp/views/General_view.c b/applications/plugins/unitemp/views/General_view.c
index b48349bdd7..02e416fb2f 100644
--- a/applications/plugins/unitemp/views/General_view.c
+++ b/applications/plugins/unitemp/views/General_view.c
@@ -172,10 +172,9 @@ static void _draw_singleSensor(Canvas* canvas, Sensor* sensor, const uint8_t pos
static void _draw_view_noSensors(Canvas* canvas) {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 7, 17, &I_sherlok_53x45_sfw);
- }
- else {
+ } else {
canvas_draw_icon(canvas, 7, 17, &I_sherlok_53x45);
}
//Рисование рамки
diff --git a/applications/plugins/usb_hid_autofire/tools.c b/applications/plugins/usb_hid_autofire/tools.c
index 2b452b55b1..566d005648 100644
--- a/applications/plugins/usb_hid_autofire/tools.c
+++ b/applications/plugins/usb_hid_autofire/tools.c
@@ -5,8 +5,7 @@
void strrev(char* arr, int start, int end) {
char temp;
- if (start >= end)
- return;
+ if(start >= end) return;
temp = *(arr + start);
*(arr + start) = *(arr + end);
@@ -17,33 +16,28 @@ void strrev(char* arr, int start, int end) {
strrev(arr, start, end);
}
-char *itoa(int number, char *arr, int base)
-{
+char* itoa(int number, char* arr, int base) {
int i = 0, r, negative = 0;
- if (number == 0)
- {
+ if(number == 0) {
arr[i] = '0';
arr[i + 1] = '\0';
return arr;
}
- if (number < 0 && base == 10)
- {
+ if(number < 0 && base == 10) {
number *= -1;
negative = 1;
}
- while (number != 0)
- {
+ while(number != 0) {
r = number % base;
arr[i] = (r > 9) ? (r - 10) + 'a' : r + '0';
i++;
number /= base;
}
- if (negative)
- {
+ if(negative) {
arr[i] = '-';
i++;
}
diff --git a/applications/plugins/usb_hid_autofire/tools.h b/applications/plugins/usb_hid_autofire/tools.h
index 9c71ea6ca7..7e5226514f 100644
--- a/applications/plugins/usb_hid_autofire/tools.h
+++ b/applications/plugins/usb_hid_autofire/tools.h
@@ -1,7 +1,7 @@
#ifndef FLIPPERZERO_FIRMWARE_TOOLS_H
#define FLIPPERZERO_FIRMWARE_TOOLS_H
-void strrev(char *arr, int start, int end);
-char *itoa(int number, char *arr, int base);
+void strrev(char* arr, int start, int end);
+char* itoa(int number, char* arr, int base);
#endif //FLIPPERZERO_FIRMWARE_TOOLS_H
diff --git a/applications/plugins/usb_hid_autofire/usb_hid_autofire.c b/applications/plugins/usb_hid_autofire/usb_hid_autofire.c
index 1333ba94ab..cf8077ae78 100644
--- a/applications/plugins/usb_hid_autofire/usb_hid_autofire.c
+++ b/applications/plugins/usb_hid_autofire/usb_hid_autofire.c
@@ -88,19 +88,19 @@ int32_t usb_hid_autofire_app(void* p) {
}
switch(event.input.key) {
- case InputKeyOk:
- btn_left_autofire = !btn_left_autofire;
- break;
- case InputKeyLeft:
- if(autofire_delay > 0) {
- autofire_delay -= 10;
- }
- break;
- case InputKeyRight:
- autofire_delay += 10;
- break;
- default:
- break;
+ case InputKeyOk:
+ btn_left_autofire = !btn_left_autofire;
+ break;
+ case InputKeyLeft:
+ if(autofire_delay > 0) {
+ autofire_delay -= 10;
+ }
+ break;
+ case InputKeyRight:
+ autofire_delay += 10;
+ break;
+ default:
+ break;
}
}
}
diff --git a/applications/plugins/weather_station/views/weather_station_receiver.c b/applications/plugins/weather_station/views/weather_station_receiver.c
index 89dbc7a0a4..cfcdac9fba 100644
--- a/applications/plugins/weather_station/views/weather_station_receiver.c
+++ b/applications/plugins/weather_station/views/weather_station_receiver.c
@@ -205,10 +205,9 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) {
canvas_set_color(canvas, ColorBlack);
if(model->history_item == 0) {
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52_sfw);
- }
- else {
+ } else {
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52);
}
canvas_set_font(canvas, FontPrimary);
@@ -232,10 +231,9 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) {
canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8);
canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8);
canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42_sfw);
- }
- else {
+ } else {
canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42);
}
canvas_draw_dot(canvas, 17, 61);
diff --git a/applications/plugins/wii_ec_anal/_image_tool/_convert.c b/applications/plugins/wii_ec_anal/_image_tool/_convert.c
index 267985e8d2..57deeb083d 100644
--- a/applications/plugins/wii_ec_anal/_image_tool/_convert.c
+++ b/applications/plugins/wii_ec_anal/_image_tool/_convert.c
@@ -3,136 +3,146 @@
#include
#include
-int main (int argc, char* argv[])
-{
- const unsigned char* pp = NULL;
- uint32_t pix = 0;
- int bit = 0;
-
- uint8_t b = 0;
- uint8_t bcnt = 0;
-
- unsigned int lcnt = 0;
- static const int lmax = 16; // max hex values per line
-
- uint8_t* buf = NULL;
- uint8_t* bp = NULL;
- unsigned int blen = 0;
-
- uint8_t* cmp = NULL;
- uint8_t* cp = NULL;
- unsigned int clen = 0;
- uint8_t ctag = 0xFF;
- uint32_t tag[256] = {0};
- uint32_t tmax = UINT32_MAX;
-
- unsigned int x, y, z;
-
- const char* name = argv[1];
- FILE* fh = fopen(argv[2], "wb");
-
- uint32_t white = 0xFF;
-
- int rv = 0; // assume success
-
- // allocate buffers
- blen = ((img.w * img.h) +0x7) >>3;
- bp = (buf = calloc(blen +1, 1));
- cp = (cmp = calloc(blen +4, 1));
-
- // sanity check
- if (!fh || !buf || !cmp) {
- printf("! fopen() or malloc() fail.\n");
- rv = 255;
- goto bail;
- }
-
- // Find white value
- for (x = 1; x < img.bpp; x++)
- white = (white << 8) | 0xFF ;
-
- // build bit pattern
- // create the comment as we go
- for (pp = img.b, y = 0; y < img.h; y++) {
- fprintf(fh, "// ");
- for (x = 0; x < img.w; x++) {
- // read pixel
- for (pix = 0, z = 0; z < img.bpp; pix = (pix << 8) | *pp++, z++) ;
- // get bit and draw
- if (pix < white) {
- b = (b << 1) | 1;
- fprintf(fh, "##");
- } else {
- b <<= 1;
- fprintf(fh, "..");
- }
- // got byte
- if ((++bcnt) == 8) {
- *bp++ = b;
- tag[b]++;
- bcnt = (b = 0);
- }
- }
- fprintf(fh, "\n");
- }
- fprintf(fh, "\n");
- // padding
- if (bcnt) {
- b <<= (bcnt = 8 - bcnt);
- *bp++ = b;
- tag[b]++;
- }
- // Kill the compression
- *bp = ~bp[-1]; // https://youtube.com/clip/Ugkx-JZIr16hETy7hz_H6yIdKPtxVe8C5w_V
-
- // Byte run length compression
- // Find a good tag
- for (x = 0; tmax && (x < 256); x++) {
- if (tag[x] < tmax) {
- tmax = tag[x];
- ctag = x;
- }
- }
-
- // compress the data
- for (bp = buf, x = 0; (clen < blen) && (x < blen); x++) {
- // need at least 4 the same to be worth it
- // must compress tag (if it occurs)
- if ((bp[x] == bp[x+1]) && (bp[x] == bp[x+2]) && (bp[x] == bp[x+3]) || (bp[x] == ctag)) {
- for (y = 1; (y < 255) && (bp[x] == bp[x+y]); y++) ;
- *cp++ = ctag; // tag
- *cp++ = y; // length
- *cp++ = bp[x]; // byte
- x += y -1;
- clen += 3;
- } else {
- *cp++ = bp[x];
- clen++;
- }
- }
-
- // create struct
- fprintf(fh, "#include \"images.h\"\n\n");
- fprintf(fh, "const image_t img_%s = { %d, %d, ", name, img.w, img.h);
-
- if (clen < blen) { // dump compressed?
- fprintf(fh, "true, %d, 0x%02X, { // orig:%d, comp:%.2f%%\n\t",
- clen, ctag, blen, 100.0-((clen*100.0)/blen));
- for (x = 0; x < clen; x++)
- if (x == clen -1) fprintf(fh, "0x%02X\n}};\n", cmp[x]) ;
- else fprintf(fh, "0x%02X%s", cmp[x], (!((x+1)%16)) ? ",\n\t" : ", ") ;
-
- } else { // dump UNcompressed
- fprintf(fh, "false, %d, 0, {\n\t", blen);
- for (x = 0; x < blen; x++)
- if (x == blen -1) fprintf(fh, "0x%02X\n}};\n", buf[x]) ;
- else fprintf(fh, "0x%02X%s", buf[x], (!((x+1)%16)) ? ",\n\t" : ", ") ;
- }
+int main(int argc, char* argv[]) {
+ const unsigned char* pp = NULL;
+ uint32_t pix = 0;
+ int bit = 0;
+
+ uint8_t b = 0;
+ uint8_t bcnt = 0;
+
+ unsigned int lcnt = 0;
+ static const int lmax = 16; // max hex values per line
+
+ uint8_t* buf = NULL;
+ uint8_t* bp = NULL;
+ unsigned int blen = 0;
+
+ uint8_t* cmp = NULL;
+ uint8_t* cp = NULL;
+ unsigned int clen = 0;
+ uint8_t ctag = 0xFF;
+ uint32_t tag[256] = {0};
+ uint32_t tmax = UINT32_MAX;
+
+ unsigned int x, y, z;
+
+ const char* name = argv[1];
+ FILE* fh = fopen(argv[2], "wb");
+
+ uint32_t white = 0xFF;
+
+ int rv = 0; // assume success
+
+ // allocate buffers
+ blen = ((img.w * img.h) + 0x7) >> 3;
+ bp = (buf = calloc(blen + 1, 1));
+ cp = (cmp = calloc(blen + 4, 1));
+
+ // sanity check
+ if(!fh || !buf || !cmp) {
+ printf("! fopen() or malloc() fail.\n");
+ rv = 255;
+ goto bail;
+ }
+
+ // Find white value
+ for(x = 1; x < img.bpp; x++) white = (white << 8) | 0xFF;
+
+ // build bit pattern
+ // create the comment as we go
+ for(pp = img.b, y = 0; y < img.h; y++) {
+ fprintf(fh, "// ");
+ for(x = 0; x < img.w; x++) {
+ // read pixel
+ for(pix = 0, z = 0; z < img.bpp; pix = (pix << 8) | *pp++, z++)
+ ;
+ // get bit and draw
+ if(pix < white) {
+ b = (b << 1) | 1;
+ fprintf(fh, "##");
+ } else {
+ b <<= 1;
+ fprintf(fh, "..");
+ }
+ // got byte
+ if((++bcnt) == 8) {
+ *bp++ = b;
+ tag[b]++;
+ bcnt = (b = 0);
+ }
+ }
+ fprintf(fh, "\n");
+ }
+ fprintf(fh, "\n");
+ // padding
+ if(bcnt) {
+ b <<= (bcnt = 8 - bcnt);
+ *bp++ = b;
+ tag[b]++;
+ }
+ // Kill the compression
+ *bp = ~bp[-1]; // https://youtube.com/clip/Ugkx-JZIr16hETy7hz_H6yIdKPtxVe8C5w_V
+
+ // Byte run length compression
+ // Find a good tag
+ for(x = 0; tmax && (x < 256); x++) {
+ if(tag[x] < tmax) {
+ tmax = tag[x];
+ ctag = x;
+ }
+ }
+
+ // compress the data
+ for(bp = buf, x = 0; (clen < blen) && (x < blen); x++) {
+ // need at least 4 the same to be worth it
+ // must compress tag (if it occurs)
+ if((bp[x] == bp[x + 1]) && (bp[x] == bp[x + 2]) && (bp[x] == bp[x + 3]) ||
+ (bp[x] == ctag)) {
+ for(y = 1; (y < 255) && (bp[x] == bp[x + y]); y++)
+ ;
+ *cp++ = ctag; // tag
+ *cp++ = y; // length
+ *cp++ = bp[x]; // byte
+ x += y - 1;
+ clen += 3;
+ } else {
+ *cp++ = bp[x];
+ clen++;
+ }
+ }
+
+ // create struct
+ fprintf(fh, "#include \"images.h\"\n\n");
+ fprintf(fh, "const image_t img_%s = { %d, %d, ", name, img.w, img.h);
+
+ if(clen < blen) { // dump compressed?
+ fprintf(
+ fh,
+ "true, %d, 0x%02X, { // orig:%d, comp:%.2f%%\n\t",
+ clen,
+ ctag,
+ blen,
+ 100.0 - ((clen * 100.0) / blen));
+ for(x = 0; x < clen; x++)
+ if(x == clen - 1)
+ fprintf(fh, "0x%02X\n}};\n", cmp[x]);
+ else
+ fprintf(fh, "0x%02X%s", cmp[x], (!((x + 1) % 16)) ? ",\n\t" : ", ");
+
+ } else { // dump UNcompressed
+ fprintf(fh, "false, %d, 0, {\n\t", blen);
+ for(x = 0; x < blen; x++)
+ if(x == blen - 1)
+ fprintf(fh, "0x%02X\n}};\n", buf[x]);
+ else
+ fprintf(fh, "0x%02X%s", buf[x], (!((x + 1) % 16)) ? ",\n\t" : ", ");
+ }
bail:
- if (fh) fclose(fh) ;
- if (buf) free(buf) ;
- if (cmp) free(cmp) ;
+ if(fh) fclose(fh);
+ if(buf) free(buf);
+ if(cmp) free(cmp);
- return rv;
+ return rv;
}
diff --git a/applications/plugins/wii_ec_anal/_image_tool/_convert_images.c b/applications/plugins/wii_ec_anal/_image_tool/_convert_images.c
index 57046e9a34..e8ab899f75 100644
--- a/applications/plugins/wii_ec_anal/_image_tool/_convert_images.c
+++ b/applications/plugins/wii_ec_anal/_image_tool/_convert_images.c
@@ -1,55 +1,49 @@
-#include // GUI (screen/keyboard) API
+#include // GUI (screen/keyboard) API
-#include "images.h"
+#include "images.h"
//----------------------------------------------------------------------------- ----------------------------------------
-static Canvas* _canvas;
-static uint8_t _tlx;
-static uint8_t _tly;
+static Canvas* _canvas;
+static uint8_t _tlx;
+static uint8_t _tly;
-static uint8_t _x;
-static uint8_t _y;
+static uint8_t _x;
+static uint8_t _y;
-static const image_t* _img;
+static const image_t* _img;
-static bool _blk;
-static Color _set;
-static Color _clr;
+static bool _blk;
+static Color _set;
+static Color _clr;
//+============================================================================
-static
-void _showByteSet (const uint8_t b)
-{
- for (uint8_t m = 0x80; m; m >>= 1) {
- if (b & m) // plot only SET bits
- canvas_draw_dot(_canvas, (_tlx +_x), (_tly +_y)) ;
- if ( ((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h) ) break ;
- }
+static void _showByteSet(const uint8_t b) {
+ for(uint8_t m = 0x80; m; m >>= 1) {
+ if(b & m) // plot only SET bits
+ canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y));
+ if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break;
+ }
}
//+============================================================================
-static
-void _showByteClr (const uint8_t b)
-{
- for (uint8_t m = 0x80; m; m >>= 1) {
- if (!(b & m)) // plot only CLR bits
- canvas_draw_dot(_canvas, (_tlx +_x), (_tly +_y)) ;
- if ( ((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h) ) break ;
- }
+static void _showByteClr(const uint8_t b) {
+ for(uint8_t m = 0x80; m; m >>= 1) {
+ if(!(b & m)) // plot only CLR bits
+ canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y));
+ if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break;
+ }
}
//+============================================================================
-static
-void _showByteAll (const uint8_t b)
-{
- for (uint8_t m = 0x80; m; m >>= 1) {
- if ((!!(b & m)) ^ _blk) { // Change colour only when required
- canvas_set_color(_canvas, ((b & m) ? _set : _clr));
- _blk = !_blk;
- }
- canvas_draw_dot(_canvas, (_tlx +_x), (_tly +_y)) ;
- if ( ((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h) ) break ;
- }
+static void _showByteAll(const uint8_t b) {
+ for(uint8_t m = 0x80; m; m >>= 1) {
+ if((!!(b & m)) ^ _blk) { // Change colour only when required
+ canvas_set_color(_canvas, ((b & m) ? _set : _clr));
+ _blk = !_blk;
+ }
+ canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y));
+ if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break;
+ }
}
//+============================================================================
@@ -61,81 +55,83 @@ void _showByteAll (const uint8_t b)
// SHOW_ALL - plot all images pixels as they are
// SHOW_ALL_INV - plot all images pixels inverted
//
-void show (Canvas* const canvas, const uint8_t tlx, const uint8_t tly,
- const image_t* img, const showMode_t mode)
-{
- void(*fnShow)(const uint8_t) = NULL;
-
- const uint8_t* bp = img->data;
-
- // code size optimisation
- switch (mode & SHOW_INV_) {
- case SHOW_NRM_:
- _set = ColorBlack;
- _clr = ColorWhite;
- break;
-
- case SHOW_INV_:
- _set = ColorWhite;
- _clr = ColorBlack;
- break;
-
- case SHOW_BLK_:
- canvas_set_color(canvas, ColorBlack);
- break;
-
- case SHOW_WHT_:
- canvas_set_color(canvas, ColorWhite);
- break;
-
- }
- switch (mode & SHOW_INV_) {
- case SHOW_NRM_:
- case SHOW_INV_:
- fnShow = _showByteAll;
- canvas_set_color(canvas, ColorWhite);
- _blk = 0;
- break;
-
- case SHOW_BLK_:
- case SHOW_WHT_:
- switch (mode & SHOW_ALL_) {
- case SHOW_SET_:
- fnShow = _showByteSet;
- break;
- case SHOW_CLR_:
- fnShow = _showByteClr;
- break;
- }
- break;
- }
- furi_check(fnShow);
-
- // I want nested functions!
- _canvas = canvas;
- _img = img;
- _tlx = tlx;
- _tly = tly;
- _x = 0;
- _y = 0;
-
- // Compressed
- if (img->c) {
- for (unsigned int i = 0; i < img->len; i++, bp++) {
- // Compressed data? {tag, length, value}
- if (*bp == img->tag) {
- for (uint16_t c = 0; c < bp[1]; c++) fnShow(bp[2]) ;
- bp += 3 -1;
- i += 3 -1;
-
- // Uncompressed byte
- } else {
- fnShow(*bp);
- }
- }
-
- // Not compressed
- } else {
- for (unsigned int i = 0; i < img->len; i++, bp++) fnShow(*bp) ;
- }
+void show(
+ Canvas* const canvas,
+ const uint8_t tlx,
+ const uint8_t tly,
+ const image_t* img,
+ const showMode_t mode) {
+ void (*fnShow)(const uint8_t) = NULL;
+
+ const uint8_t* bp = img->data;
+
+ // code size optimisation
+ switch(mode & SHOW_INV_) {
+ case SHOW_NRM_:
+ _set = ColorBlack;
+ _clr = ColorWhite;
+ break;
+
+ case SHOW_INV_:
+ _set = ColorWhite;
+ _clr = ColorBlack;
+ break;
+
+ case SHOW_BLK_:
+ canvas_set_color(canvas, ColorBlack);
+ break;
+
+ case SHOW_WHT_:
+ canvas_set_color(canvas, ColorWhite);
+ break;
+ }
+ switch(mode & SHOW_INV_) {
+ case SHOW_NRM_:
+ case SHOW_INV_:
+ fnShow = _showByteAll;
+ canvas_set_color(canvas, ColorWhite);
+ _blk = 0;
+ break;
+
+ case SHOW_BLK_:
+ case SHOW_WHT_:
+ switch(mode & SHOW_ALL_) {
+ case SHOW_SET_:
+ fnShow = _showByteSet;
+ break;
+ case SHOW_CLR_:
+ fnShow = _showByteClr;
+ break;
+ }
+ break;
+ }
+ furi_check(fnShow);
+
+ // I want nested functions!
+ _canvas = canvas;
+ _img = img;
+ _tlx = tlx;
+ _tly = tly;
+ _x = 0;
+ _y = 0;
+
+ // Compressed
+ if(img->c) {
+ for(unsigned int i = 0; i < img->len; i++, bp++) {
+ // Compressed data? {tag, length, value}
+ if(*bp == img->tag) {
+ for(uint16_t c = 0; c < bp[1]; c++) fnShow(bp[2]);
+ bp += 3 - 1;
+ i += 3 - 1;
+
+ // Uncompressed byte
+ } else {
+ fnShow(*bp);
+ }
+ }
+
+ // Not compressed
+ } else {
+ for(unsigned int i = 0; i < img->len; i++, bp++) fnShow(*bp);
+ }
}
diff --git a/applications/plugins/wii_ec_anal/_image_tool/_convert_images.h b/applications/plugins/wii_ec_anal/_image_tool/_convert_images.h
index bfc44568ec..1743cb4094 100644
--- a/applications/plugins/wii_ec_anal/_image_tool/_convert_images.h
+++ b/applications/plugins/wii_ec_anal/_image_tool/_convert_images.h
@@ -1,53 +1,53 @@
-#ifndef IMAGES_H_
-#define IMAGES_H_
+#ifndef IMAGES_H_
+#define IMAGES_H_
#include
#include
//----------------------------------------------------------------------------- ----------------------------------------
-typedef
- enum showMode {
- // {INV:--:WHT:BLK::--:--:CLR:SET}
- SHOW_SET_ = 0x01,
- SHOW_CLR_ = 0x02,
- SHOW_ALL_ = SHOW_SET_ | SHOW_CLR_,
+typedef enum showMode {
+ // {INV:--:WHT:BLK::--:--:CLR:SET}
+ SHOW_SET_ = 0x01,
+ SHOW_CLR_ = 0x02,
+ SHOW_ALL_ = SHOW_SET_ | SHOW_CLR_,
- SHOW_BLK_ = 0x10,
- SHOW_WHT_ = 0x20,
- SHOW_NRM_ = 0x00,
- SHOW_INV_ = SHOW_BLK_ | SHOW_WHT_,
+ SHOW_BLK_ = 0x10,
+ SHOW_WHT_ = 0x20,
+ SHOW_NRM_ = 0x00,
+ SHOW_INV_ = SHOW_BLK_ | SHOW_WHT_,
- SHOW_SET_BLK = SHOW_SET_ | SHOW_BLK_,
- SHOW_SET_WHT = SHOW_SET_ | SHOW_WHT_,
+ SHOW_SET_BLK = SHOW_SET_ | SHOW_BLK_,
+ SHOW_SET_WHT = SHOW_SET_ | SHOW_WHT_,
- SHOW_CLR_BLK = SHOW_CLR_ | SHOW_BLK_,
- SHOW_CLR_WHT = SHOW_CLR_ | SHOW_WHT_,
+ SHOW_CLR_BLK = SHOW_CLR_ | SHOW_BLK_,
+ SHOW_CLR_WHT = SHOW_CLR_ | SHOW_WHT_,
- SHOW_ALL = SHOW_ALL_ | SHOW_NRM_,
- SHOW_ALL_INV = SHOW_ALL_ | SHOW_INV_,
- }
-showMode_t;
+ SHOW_ALL = SHOW_ALL_ | SHOW_NRM_,
+ SHOW_ALL_INV = SHOW_ALL_ | SHOW_INV_,
+} showMode_t;
//----------------------------------------------------------------------------- ----------------------------------------
-typedef
- struct image {
- uint8_t w; // width
- uint8_t h; // height
- bool c; // compressed?
- uint16_t len; // image data length
- uint8_t tag; // rle tag
- uint8_t data[]; // image data
- }
-image_t;
+typedef struct image {
+ uint8_t w; // width
+ uint8_t h; // height
+ bool c; // compressed?
+ uint16_t len; // image data length
+ uint8_t tag; // rle tag
+ uint8_t data[]; // image data
+} image_t;
//----------------------------------------------------------------------------- ----------------------------------------
//[TAG]
//----------------------------------------------------------------------------- ----------------------------------------
#ifndef IMGTEST
-# include
- void show (Canvas* const canvas, const uint8_t tlx, const uint8_t tly,
- const image_t* img, const showMode_t mode) ;
+#include
+void show(
+ Canvas* const canvas,
+ const uint8_t tlx,
+ const uint8_t tly,
+ const image_t* img,
+ const showMode_t mode);
#endif
#endif //IMAGES_H_
diff --git a/applications/plugins/wii_ec_anal/_image_tool/_convert_test.c b/applications/plugins/wii_ec_anal/_image_tool/_convert_test.c
index 4bdb531d58..fdc2ee9466 100644
--- a/applications/plugins/wii_ec_anal/_image_tool/_convert_test.c
+++ b/applications/plugins/wii_ec_anal/_image_tool/_convert_test.c
@@ -1,59 +1,59 @@
-#include
-#include
+#include
+#include
-#include "images.h"
+#include "images.h"
//-----------------------------------------------------------------------------
// This will be the plot function out of your graphics library
//
-#define PLOT(x,y,c) do { \
- printf("%s", (c ? "#" : ".")); \
- if (x == img->w -1) printf("\n") ; \
-}while(0)
+#define PLOT(x, y, c) \
+ do { \
+ printf("%s", (c ? "#" : ".")); \
+ if(x == img->w - 1) printf("\n"); \
+ } while(0)
//+============================================================================
// The pain we endure to avoid code duplication cleanly
//
-#define PLOTBYTE(b) do { \
- for (uint8_t m = 0x80; m; m>>=1) { \
- PLOT(x,y, (b & m)); \
- if ( ((++x) == img->w) && !(x = 0) && ((++y) == img->h) ) break ; \
- } \
-}while(0)
-
-void show (const image_t* img)
-{
- // Some variables
- const uint8_t* bp = img->data;
- unsigned int x = 0;
- unsigned int y = 0;
-
- // Compressed
- if (img->c) {
- for (unsigned int i = 0; i < img->len; i++, bp++) {
- // Compressed data? {tag, length, value}
- if (*bp == img->tag) {
- for (uint16_t c = 0; c < bp[1]; c++) PLOTBYTE(bp[2]) ;
- bp += 3 -1;
- i += 3 -1;
-
- // Uncompressed byte
- } else {
- PLOTBYTE(*bp);
- }
- }
-
- // Not compressed
- } else {
- for (unsigned int i = 0; i < img->len; i++, bp++) PLOTBYTE(*bp) ;
- }
+#define PLOTBYTE(b) \
+ do { \
+ for(uint8_t m = 0x80; m; m >>= 1) { \
+ PLOT(x, y, (b & m)); \
+ if(((++x) == img->w) && !(x = 0) && ((++y) == img->h)) break; \
+ } \
+ } while(0)
+
+void show(const image_t* img) {
+ // Some variables
+ const uint8_t* bp = img->data;
+ unsigned int x = 0;
+ unsigned int y = 0;
+
+ // Compressed
+ if(img->c) {
+ for(unsigned int i = 0; i < img->len; i++, bp++) {
+ // Compressed data? {tag, length, value}
+ if(*bp == img->tag) {
+ for(uint16_t c = 0; c < bp[1]; c++) PLOTBYTE(bp[2]);
+ bp += 3 - 1;
+ i += 3 - 1;
+
+ // Uncompressed byte
+ } else {
+ PLOTBYTE(*bp);
+ }
+ }
+
+ // Not compressed
+ } else {
+ for(unsigned int i = 0; i < img->len; i++, bp++) PLOTBYTE(*bp);
+ }
}
-#undef PLOTBYTE
+#undef PLOTBYTE
//+============================================================================
-int main (void)
-{
- show(&img_zzz);
- return 0;
+int main(void) {
+ show(&img_zzz);
+ return 0;
}
diff --git a/applications/plugins/wii_ec_anal/bc_logging.h b/applications/plugins/wii_ec_anal/bc_logging.h
index d9bb48c923..73dda80bd0 100644
--- a/applications/plugins/wii_ec_anal/bc_logging.h
+++ b/applications/plugins/wii_ec_anal/bc_logging.h
@@ -1,13 +1,13 @@
-#ifndef BC_LOGGING_H_
-#define BC_LOGGING_H_
+#ifndef BC_LOGGING_H_
+#define BC_LOGGING_H_
#include
-#include "err.h" // appName
+#include "err.h" // appName
//! WARNING: There is a bug in Furi such that if you crank LOG_LEVEL up to 6=TRACE
//! AND you have menu->settings->system->logLevel = trace
//! THEN this program will cause the FZ to crash when the plugin exits!
-#define LOG_LEVEL 4
+#define LOG_LEVEL 4
//----------------------------------------------------------------------------- ----------------------------------------
// The FlipperZero Settings->System menu allows you to set the logging level at RUN-time
@@ -27,44 +27,44 @@
// The FlipperZero Settings->System menu allows you to set the logging level at RUN-time
// This lets you limit it at COMPILE-time
#ifndef LOG_LEVEL
-# define LOG_LEVEL 6 // default = full logging
+#define LOG_LEVEL 6 // default = full logging
#endif
-#if (LOG_LEVEL < 2)
-# undef FURI_LOG_E
-# define FURI_LOG_E(tag, fmt, ...)
+#if(LOG_LEVEL < 2)
+#undef FURI_LOG_E
+#define FURI_LOG_E(tag, fmt, ...)
#endif
-#if (LOG_LEVEL < 3)
-# undef FURI_LOG_W
-# define FURI_LOG_W(tag, fmt, ...)
+#if(LOG_LEVEL < 3)
+#undef FURI_LOG_W
+#define FURI_LOG_W(tag, fmt, ...)
#endif
-#if (LOG_LEVEL < 4)
-# undef FURI_LOG_I
-# define FURI_LOG_I(tag, fmt, ...)
+#if(LOG_LEVEL < 4)
+#undef FURI_LOG_I
+#define FURI_LOG_I(tag, fmt, ...)
#endif
-#if (LOG_LEVEL < 5)
-# undef FURI_LOG_D
-# define FURI_LOG_D(tag, fmt, ...)
+#if(LOG_LEVEL < 5)
+#undef FURI_LOG_D
+#define FURI_LOG_D(tag, fmt, ...)
#endif
-#if (LOG_LEVEL < 6)
-# undef FURI_LOG_T
-# define FURI_LOG_T(tag, fmt, ...)
+#if(LOG_LEVEL < 6)
+#undef FURI_LOG_T
+#define FURI_LOG_T(tag, fmt, ...)
#endif
//----------------------------------------------------------
// Logging helper macros
//
-#define ERROR(fmt, ...) FURI_LOG_E(appName, fmt __VA_OPT__(,) __VA_ARGS__)
-#define WARN(fmt, ...) FURI_LOG_W(appName, fmt __VA_OPT__(,) __VA_ARGS__)
-#define INFO(fmt, ...) FURI_LOG_I(appName, fmt __VA_OPT__(,) __VA_ARGS__)
-#define DEBUG(fmt, ...) FURI_LOG_D(appName, fmt __VA_OPT__(,) __VA_ARGS__)
-#define TRACE(fmt, ...) FURI_LOG_T(appName, fmt __VA_OPT__(,) __VA_ARGS__)
+#define ERROR(fmt, ...) FURI_LOG_E(appName, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define WARN(fmt, ...) FURI_LOG_W(appName, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define INFO(fmt, ...) FURI_LOG_I(appName, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define DEBUG(fmt, ...) FURI_LOG_D(appName, fmt __VA_OPT__(, ) __VA_ARGS__)
+#define TRACE(fmt, ...) FURI_LOG_T(appName, fmt __VA_OPT__(, ) __VA_ARGS__)
-#define ENTER TRACE("(+) %s", __func__)
-#define LEAVE TRACE("(-) %s", __func__)
+#define ENTER TRACE("(+) %s", __func__)
+#define LEAVE TRACE("(-) %s", __func__)
#endif //BC_LOGGING_H_
diff --git a/applications/plugins/wii_ec_anal/err.h b/applications/plugins/wii_ec_anal/err.h
index 9398a3fb85..5a25c93f80 100644
--- a/applications/plugins/wii_ec_anal/err.h
+++ b/applications/plugins/wii_ec_anal/err.h
@@ -1,11 +1,11 @@
// Avoid circular/nested/mulitple inclusion
-#ifndef ERR_H_
-#define ERR_H_
+#ifndef ERR_H_
+#define ERR_H_
//----------------------------------------------------------------------------- ----------------------------------------
// Application name
//
-static const char* const appName = "Wii_i2c"; //$ Name used in log files
+static const char* const appName = "Wii_i2c"; //$ Name used in log files
//----------------------------------------------------------------------------- ----------------------------------------
// Error codes and messages
@@ -13,57 +13,60 @@ static const char* const appName = "Wii_i2c"; //$ Name used in log files
// You should only ever (need to) edit this list
// ...Watch out for extraneous whitespace after the terminating backslashes
-#define FOREACH_ES(esPrial) \
- /* The first line MUST define 'ERR_OK = 0' */ \
- esPrial( 0, ERR_OK , "OK (no error)") \
-\
- esPrial( 1, ERR_MALLOC_QUEUE , "malloc() fail - queue") \
- esPrial( 2, ERR_MALLOC_STATE , "malloc() fail - state") \
- esPrial( 3, ERR_MALLOC_TEXT , "malloc() fail - text") \
- esPrial( 4, ERR_MALLOC_VIEW , "malloc() fail - viewport") \
- esPrial( 5, ERR_NO_MUTEX , "Cannot create mutex") \
- esPrial( 6, ERR_NO_GUI , "Cannot open GUI") \
- esPrial( 7, ERR_NO_TIMER , "Cannot create timer") \
- esPrial( 8, ERR_NO_NOTIFY , "Cannot acquire notifications handle") \
-\
- esPrial(10, ERR_MUTEX_BLOCK , "Mutex block failed") \
- esPrial(11, ERR_MUTEX_RELEASE , "Mutex release failed") \
-\
- esPrial(20, ERR_QUEUE_RTOS , "queue - Undefined RTOS error") \
- esPrial(21, DEBUG_QUEUE_TIMEOUT, "queue - Timeout") \
- esPrial(22, ERR_QUEUE_RESOURCE , "queue - Resource not available") \
- esPrial(23, ERR_QUEUE_BADPRM , "queue - Bad parameter") \
- esPrial(24, ERR_QUEUE_NOMEM , "queue - Out of memory") \
- esPrial(25, ERR_QUEUE_ISR , "queue - Banned in ISR") \
- esPrial(26, ERR_QUEUE_UNK , "queue - Unknown") \
-\
- esPrial(30, WARN_SCAN_START , "Scan - Already started") \
- esPrial(31, WARN_SCAN_STOP , "Scan - Already stopped") \
- esPrial(32, ERR_TIMER_START , "Scan - Cannot start timer") \
- esPrial(33, ERR_TIMER_STOP , "Scan - Cannot stop timer") \
-//[EOT]
+#define FOREACH_ES(esPrial) \
+ /* The first line MUST define 'ERR_OK = 0' */ \
+ esPrial(0, ERR_OK, "OK (no error)") \
+ \
+ esPrial(1, ERR_MALLOC_QUEUE, "malloc() fail - queue") esPrial( \
+ 2, \
+ ERR_MALLOC_STATE, \
+ "malloc() fail - state") esPrial(3, ERR_MALLOC_TEXT, "malloc() fail - text") \
+ esPrial(4, ERR_MALLOC_VIEW, "malloc() fail - viewport") esPrial( \
+ 5, ERR_NO_MUTEX, "Cannot create mutex") esPrial(6, ERR_NO_GUI, "Cannot open GUI") \
+ esPrial(7, ERR_NO_TIMER, "Cannot create timer") esPrial( \
+ 8, ERR_NO_NOTIFY, "Cannot acquire notifications handle") \
+ \
+ esPrial(10, ERR_MUTEX_BLOCK, "Mutex block failed") esPrial( \
+ 11, ERR_MUTEX_RELEASE, "Mutex release failed") \
+ \
+ esPrial(20, ERR_QUEUE_RTOS, "queue - Undefined RTOS error") \
+ esPrial(21, DEBUG_QUEUE_TIMEOUT, "queue - Timeout") esPrial( \
+ 22, ERR_QUEUE_RESOURCE, "queue - Resource not available") \
+ esPrial(23, ERR_QUEUE_BADPRM, "queue - Bad parameter") esPrial( \
+ 24, ERR_QUEUE_NOMEM, "queue - Out of memory") \
+ esPrial(25, ERR_QUEUE_ISR, "queue - Banned in ISR") esPrial( \
+ 26, ERR_QUEUE_UNK, "queue - Unknown") \
+ \
+ esPrial(30, WARN_SCAN_START, "Scan - Already started") \
+ esPrial(31, WARN_SCAN_STOP, "Scan - Already stopped") \
+ esPrial( \
+ 32, \
+ ERR_TIMER_START, \
+ "Scan - Cannot start timer") \
+ esPrial( \
+ 33, \
+ ERR_TIMER_STOP, \
+ "Scan - Cannot stop timer") //[EOT]
// Declare list extraction macros
-#define ES_ENUM(num, ename, string) ename = num,
-#define ES_STRING(num, ename, string) string"\r\n",
+#define ES_ENUM(num, ename, string) ename = num,
+#define ES_STRING(num, ename, string) string "\r\n",
// Build the enum
-typedef
- enum err { FOREACH_ES(ES_ENUM) }
-err_t ;
+typedef enum err { FOREACH_ES(ES_ENUM) } err_t;
// You need to '#define ERR_C_' in precisely ONE source file
#ifdef ERR_C_
- // Build the string list
- const char* const wii_errs[] = { FOREACH_ES(ES_STRING) };
+// Build the string list
+const char* const wii_errs[] = {FOREACH_ES(ES_STRING)};
#else
- // Give access to string list
- extern const char* const wii_errs[];
+// Give access to string list
+extern const char* const wii_errs[];
#endif
// This is a header file, clean up
-#undef ES_ENUM
-#undef ES_STRING
-#undef FOREACH_ES
+#undef ES_ENUM
+#undef ES_STRING
+#undef FOREACH_ES
#endif // ERR_H_
diff --git a/applications/plugins/wii_ec_anal/gfx/images.c b/applications/plugins/wii_ec_anal/gfx/images.c
index 57046e9a34..e8ab899f75 100644
--- a/applications/plugins/wii_ec_anal/gfx/images.c
+++ b/applications/plugins/wii_ec_anal/gfx/images.c
@@ -1,55 +1,49 @@
-#include // GUI (screen/keyboard) API
+#include // GUI (screen/keyboard) API
-#include "images.h"
+#include "images.h"
//----------------------------------------------------------------------------- ----------------------------------------
-static Canvas* _canvas;
-static uint8_t _tlx;
-static uint8_t _tly;
+static Canvas* _canvas;
+static uint8_t _tlx;
+static uint8_t _tly;
-static uint8_t _x;
-static uint8_t _y;
+static uint8_t _x;
+static uint8_t _y;
-static const image_t* _img;
+static const image_t* _img;
-static bool _blk;
-static Color _set;
-static Color _clr;
+static bool _blk;
+static Color _set;
+static Color _clr;
//+============================================================================
-static
-void _showByteSet (const uint8_t b)
-{
- for (uint8_t m = 0x80; m; m >>= 1) {
- if (b & m) // plot only SET bits
- canvas_draw_dot(_canvas, (_tlx +_x), (_tly +_y)) ;
- if ( ((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h) ) break ;
- }
+static void _showByteSet(const uint8_t b) {
+ for(uint8_t m = 0x80; m; m >>= 1) {
+ if(b & m) // plot only SET bits
+ canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y));
+ if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break;
+ }
}
//+============================================================================
-static
-void _showByteClr (const uint8_t b)
-{
- for (uint8_t m = 0x80; m; m >>= 1) {
- if (!(b & m)) // plot only CLR bits
- canvas_draw_dot(_canvas, (_tlx +_x), (_tly +_y)) ;
- if ( ((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h) ) break ;
- }
+static void _showByteClr(const uint8_t b) {
+ for(uint8_t m = 0x80; m; m >>= 1) {
+ if(!(b & m)) // plot only CLR bits
+ canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y));
+ if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break;
+ }
}
//+============================================================================
-static
-void _showByteAll (const uint8_t b)
-{
- for (uint8_t m = 0x80; m; m >>= 1) {
- if ((!!(b & m)) ^ _blk) { // Change colour only when required
- canvas_set_color(_canvas, ((b & m) ? _set : _clr));
- _blk = !_blk;
- }
- canvas_draw_dot(_canvas, (_tlx +_x), (_tly +_y)) ;
- if ( ((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h) ) break ;
- }
+static void _showByteAll(const uint8_t b) {
+ for(uint8_t m = 0x80; m; m >>= 1) {
+ if((!!(b & m)) ^ _blk) { // Change colour only when required
+ canvas_set_color(_canvas, ((b & m) ? _set : _clr));
+ _blk = !_blk;
+ }
+ canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y));
+ if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break;
+ }
}
//+============================================================================
@@ -61,81 +55,83 @@ void _showByteAll (const uint8_t b)
// SHOW_ALL - plot all images pixels as they are
// SHOW_ALL_INV - plot all images pixels inverted
//
-void show (Canvas* const canvas, const uint8_t tlx, const uint8_t tly,
- const image_t* img, const showMode_t mode)
-{
- void(*fnShow)(const uint8_t) = NULL;
-
- const uint8_t* bp = img->data;
-
- // code size optimisation
- switch (mode & SHOW_INV_) {
- case SHOW_NRM_:
- _set = ColorBlack;
- _clr = ColorWhite;
- break;
-
- case SHOW_INV_:
- _set = ColorWhite;
- _clr = ColorBlack;
- break;
-
- case SHOW_BLK_:
- canvas_set_color(canvas, ColorBlack);
- break;
-
- case SHOW_WHT_:
- canvas_set_color(canvas, ColorWhite);
- break;
-
- }
- switch (mode & SHOW_INV_) {
- case SHOW_NRM_:
- case SHOW_INV_:
- fnShow = _showByteAll;
- canvas_set_color(canvas, ColorWhite);
- _blk = 0;
- break;
-
- case SHOW_BLK_:
- case SHOW_WHT_:
- switch (mode & SHOW_ALL_) {
- case SHOW_SET_:
- fnShow = _showByteSet;
- break;
- case SHOW_CLR_:
- fnShow = _showByteClr;
- break;
- }
- break;
- }
- furi_check(fnShow);
-
- // I want nested functions!
- _canvas = canvas;
- _img = img;
- _tlx = tlx;
- _tly = tly;
- _x = 0;
- _y = 0;
-
- // Compressed
- if (img->c) {
- for (unsigned int i = 0; i < img->len; i++, bp++) {
- // Compressed data? {tag, length, value}
- if (*bp == img->tag) {
- for (uint16_t c = 0; c < bp[1]; c++) fnShow(bp[2]) ;
- bp += 3 -1;
- i += 3 -1;
-
- // Uncompressed byte
- } else {
- fnShow(*bp);
- }
- }
-
- // Not compressed
- } else {
- for (unsigned int i = 0; i < img->len; i++, bp++) fnShow(*bp) ;
- }
+void show(
+ Canvas* const canvas,
+ const uint8_t tlx,
+ const uint8_t tly,
+ const image_t* img,
+ const showMode_t mode) {
+ void (*fnShow)(const uint8_t) = NULL;
+
+ const uint8_t* bp = img->data;
+
+ // code size optimisation
+ switch(mode & SHOW_INV_) {
+ case SHOW_NRM_:
+ _set = ColorBlack;
+ _clr = ColorWhite;
+ break;
+
+ case SHOW_INV_:
+ _set = ColorWhite;
+ _clr = ColorBlack;
+ break;
+
+ case SHOW_BLK_:
+ canvas_set_color(canvas, ColorBlack);
+ break;
+
+ case SHOW_WHT_:
+ canvas_set_color(canvas, ColorWhite);
+ break;
+ }
+ switch(mode & SHOW_INV_) {
+ case SHOW_NRM_:
+ case SHOW_INV_:
+ fnShow = _showByteAll;
+ canvas_set_color(canvas, ColorWhite);
+ _blk = 0;
+ break;
+
+ case SHOW_BLK_:
+ case SHOW_WHT_:
+ switch(mode & SHOW_ALL_) {
+ case SHOW_SET_:
+ fnShow = _showByteSet;
+ break;
+ case SHOW_CLR_:
+ fnShow = _showByteClr;
+ break;
+ }
+ break;
+ }
+ furi_check(fnShow);
+
+ // I want nested functions!
+ _canvas = canvas;
+ _img = img;
+ _tlx = tlx;
+ _tly = tly;
+ _x = 0;
+ _y = 0;
+
+ // Compressed
+ if(img->c) {
+ for(unsigned int i = 0; i < img->len; i++, bp++) {
+ // Compressed data? {tag, length, value}
+ if(*bp == img->tag) {
+ for(uint16_t c = 0; c < bp[1]; c++) fnShow(bp[2]);
+ bp += 3 - 1;
+ i += 3 - 1;
+
+ // Uncompressed byte
+ } else {
+ fnShow(*bp);
+ }
+ }
+
+ // Not compressed
+ } else {
+ for(unsigned int i = 0; i < img->len; i++, bp++) fnShow(*bp);
+ }
}
diff --git a/applications/plugins/wii_ec_anal/gfx/images.h b/applications/plugins/wii_ec_anal/gfx/images.h
index 87f2b89b7c..d21909176c 100644
--- a/applications/plugins/wii_ec_anal/gfx/images.h
+++ b/applications/plugins/wii_ec_anal/gfx/images.h
@@ -1,134 +1,134 @@
-#ifndef IMAGES_H_
-#define IMAGES_H_
+#ifndef IMAGES_H_
+#define IMAGES_H_
#include
#include
//----------------------------------------------------------------------------- ----------------------------------------
-typedef
- enum showMode {
- // {INV:--:WHT:BLK::--:--:CLR:SET}
- SHOW_SET_ = 0x01,
- SHOW_CLR_ = 0x02,
- SHOW_ALL_ = SHOW_SET_ | SHOW_CLR_,
+typedef enum showMode {
+ // {INV:--:WHT:BLK::--:--:CLR:SET}
+ SHOW_SET_ = 0x01,
+ SHOW_CLR_ = 0x02,
+ SHOW_ALL_ = SHOW_SET_ | SHOW_CLR_,
- SHOW_BLK_ = 0x10,
- SHOW_WHT_ = 0x20,
- SHOW_NRM_ = 0x00,
- SHOW_INV_ = SHOW_BLK_ | SHOW_WHT_,
+ SHOW_BLK_ = 0x10,
+ SHOW_WHT_ = 0x20,
+ SHOW_NRM_ = 0x00,
+ SHOW_INV_ = SHOW_BLK_ | SHOW_WHT_,
- SHOW_SET_BLK = SHOW_SET_ | SHOW_BLK_,
- SHOW_SET_WHT = SHOW_SET_ | SHOW_WHT_,
+ SHOW_SET_BLK = SHOW_SET_ | SHOW_BLK_,
+ SHOW_SET_WHT = SHOW_SET_ | SHOW_WHT_,
- SHOW_CLR_BLK = SHOW_CLR_ | SHOW_BLK_,
- SHOW_CLR_WHT = SHOW_CLR_ | SHOW_WHT_,
+ SHOW_CLR_BLK = SHOW_CLR_ | SHOW_BLK_,
+ SHOW_CLR_WHT = SHOW_CLR_ | SHOW_WHT_,
- SHOW_ALL = SHOW_ALL_ | SHOW_NRM_,
- SHOW_ALL_INV = SHOW_ALL_ | SHOW_INV_,
- }
-showMode_t;
+ SHOW_ALL = SHOW_ALL_ | SHOW_NRM_,
+ SHOW_ALL_INV = SHOW_ALL_ | SHOW_INV_,
+} showMode_t;
//----------------------------------------------------------------------------- ----------------------------------------
-typedef
- struct image {
- uint8_t w; // width
- uint8_t h; // height
- bool c; // compressed?
- uint16_t len; // image data length
- uint8_t tag; // rle tag
- uint8_t data[]; // image data
- }
-image_t;
+typedef struct image {
+ uint8_t w; // width
+ uint8_t h; // height
+ bool c; // compressed?
+ uint16_t len; // image data length
+ uint8_t tag; // rle tag
+ uint8_t data[]; // image data
+} image_t;
//----------------------------------------------------------------------------- ----------------------------------------
//[TAG]
-extern const image_t img_csLogo_Small;
-extern const image_t img_3x5_v;
-extern const image_t img_3x5_9;
-extern const image_t img_3x5_8;
-extern const image_t img_3x5_7;
-extern const image_t img_3x5_6;
-extern const image_t img_3x5_5;
-extern const image_t img_3x5_4;
-extern const image_t img_3x5_3;
-extern const image_t img_3x5_2;
-extern const image_t img_3x5_1;
-extern const image_t img_3x5_0;
-extern const image_t img_key_Ui;
-extern const image_t img_key_OKi;
-extern const image_t img_RIP;
-extern const image_t img_cc_trg_R4;
-extern const image_t img_cc_trg_R3;
-extern const image_t img_cc_trg_R2;
-extern const image_t img_cc_trg_R1;
-extern const image_t img_cc_trg_L4;
-extern const image_t img_cc_trg_L3;
-extern const image_t img_cc_trg_L2;
-extern const image_t img_cc_trg_L1;
-extern const image_t img_cc_Joy;
-extern const image_t img_cc_Main;
-extern const image_t img_cc_Cable;
-extern const image_t img_key_Back;
-extern const image_t img_key_OK;
-extern const image_t img_6x8_Z;
-extern const image_t img_6x8_Y;
-extern const image_t img_6x8_X;
-extern const image_t img_key_U;
-extern const image_t img_key_D;
-extern const image_t img_csLogo_FULL;
-extern const image_t img_6x8_7;
-extern const image_t img_key_R;
-extern const image_t img_key_L;
-extern const image_t img_5x7_7;
-extern const image_t img_5x7_F;
-extern const image_t img_5x7_E;
-extern const image_t img_5x7_D;
-extern const image_t img_5x7_C;
-extern const image_t img_5x7_B;
-extern const image_t img_5x7_A;
-extern const image_t img_5x7_9;
-extern const image_t img_5x7_8;
-extern const image_t img_5x7_6;
-extern const image_t img_5x7_5;
-extern const image_t img_5x7_4;
-extern const image_t img_5x7_3;
-extern const image_t img_5x7_2;
-extern const image_t img_5x7_1;
-extern const image_t img_5x7_0;
-extern const image_t img_6x8_v;
-extern const image_t img_6x8_n;
-extern const image_t img_6x8_G;
-extern const image_t img_6x8_F;
-extern const image_t img_6x8_E;
-extern const image_t img_6x8_d;
-extern const image_t img_6x8_C;
-extern const image_t img_6x8_B;
-extern const image_t img_6x8_A;
-extern const image_t img_6x8_9;
-extern const image_t img_6x8_8;
-extern const image_t img_6x8_6;
-extern const image_t img_6x8_5;
-extern const image_t img_6x8_4;
-extern const image_t img_6x8_3;
-extern const image_t img_6x8_2;
-extern const image_t img_6x8_1;
-extern const image_t img_6x8_0;
-extern const image_t img_ecp_SDA;
-extern const image_t img_ecp_SCL;
-extern const image_t img_ecp_port;
-extern const image_t img_cc_pad_UD1;
-extern const image_t img_cc_pad_LR1;
-extern const image_t img_cc_btn_Y1;
-extern const image_t img_cc_btn_X1;
-extern const image_t img_cc_btn_B1;
-extern const image_t img_cc_btn_A1;
-extern const image_t img_6x8_D;
+extern const image_t img_csLogo_Small;
+extern const image_t img_3x5_v;
+extern const image_t img_3x5_9;
+extern const image_t img_3x5_8;
+extern const image_t img_3x5_7;
+extern const image_t img_3x5_6;
+extern const image_t img_3x5_5;
+extern const image_t img_3x5_4;
+extern const image_t img_3x5_3;
+extern const image_t img_3x5_2;
+extern const image_t img_3x5_1;
+extern const image_t img_3x5_0;
+extern const image_t img_key_Ui;
+extern const image_t img_key_OKi;
+extern const image_t img_RIP;
+extern const image_t img_cc_trg_R4;
+extern const image_t img_cc_trg_R3;
+extern const image_t img_cc_trg_R2;
+extern const image_t img_cc_trg_R1;
+extern const image_t img_cc_trg_L4;
+extern const image_t img_cc_trg_L3;
+extern const image_t img_cc_trg_L2;
+extern const image_t img_cc_trg_L1;
+extern const image_t img_cc_Joy;
+extern const image_t img_cc_Main;
+extern const image_t img_cc_Cable;
+extern const image_t img_key_Back;
+extern const image_t img_key_OK;
+extern const image_t img_6x8_Z;
+extern const image_t img_6x8_Y;
+extern const image_t img_6x8_X;
+extern const image_t img_key_U;
+extern const image_t img_key_D;
+extern const image_t img_csLogo_FULL;
+extern const image_t img_6x8_7;
+extern const image_t img_key_R;
+extern const image_t img_key_L;
+extern const image_t img_5x7_7;
+extern const image_t img_5x7_F;
+extern const image_t img_5x7_E;
+extern const image_t img_5x7_D;
+extern const image_t img_5x7_C;
+extern const image_t img_5x7_B;
+extern const image_t img_5x7_A;
+extern const image_t img_5x7_9;
+extern const image_t img_5x7_8;
+extern const image_t img_5x7_6;
+extern const image_t img_5x7_5;
+extern const image_t img_5x7_4;
+extern const image_t img_5x7_3;
+extern const image_t img_5x7_2;
+extern const image_t img_5x7_1;
+extern const image_t img_5x7_0;
+extern const image_t img_6x8_v;
+extern const image_t img_6x8_n;
+extern const image_t img_6x8_G;
+extern const image_t img_6x8_F;
+extern const image_t img_6x8_E;
+extern const image_t img_6x8_d;
+extern const image_t img_6x8_C;
+extern const image_t img_6x8_B;
+extern const image_t img_6x8_A;
+extern const image_t img_6x8_9;
+extern const image_t img_6x8_8;
+extern const image_t img_6x8_6;
+extern const image_t img_6x8_5;
+extern const image_t img_6x8_4;
+extern const image_t img_6x8_3;
+extern const image_t img_6x8_2;
+extern const image_t img_6x8_1;
+extern const image_t img_6x8_0;
+extern const image_t img_ecp_SDA;
+extern const image_t img_ecp_SCL;
+extern const image_t img_ecp_port;
+extern const image_t img_cc_pad_UD1;
+extern const image_t img_cc_pad_LR1;
+extern const image_t img_cc_btn_Y1;
+extern const image_t img_cc_btn_X1;
+extern const image_t img_cc_btn_B1;
+extern const image_t img_cc_btn_A1;
+extern const image_t img_6x8_D;
//----------------------------------------------------------------------------- ----------------------------------------
#ifndef IMGTEST
-# include
- void show (Canvas* const canvas, const uint8_t tlx, const uint8_t tly,
- const image_t* img, const showMode_t mode) ;
+#include
+void show(
+ Canvas* const canvas,
+ const uint8_t tlx,
+ const uint8_t tly,
+ const image_t* img,
+ const showMode_t mode);
#endif
#endif //IMAGES_H_
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_0.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_0.c
index 975d98d35d..8fc8e0e146 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_0.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_0.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_0 = { 3, 5, false, 2, 0, {
- 0xF6, 0xDE
-}};
+const image_t img_3x5_0 = {3, 5, false, 2, 0, {0xF6, 0xDE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_1.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_1.c
index 0d9dc3fe41..8b7d4cf807 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_1.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_1 = { 3, 5, false, 2, 0, {
- 0xC9, 0x2E
-}};
+const image_t img_3x5_1 = {3, 5, false, 2, 0, {0xC9, 0x2E}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_2.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_2.c
index d98bf4e936..89a81c75ea 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_2.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_2.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_2 = { 3, 5, false, 2, 0, {
- 0xE7, 0xCE
-}};
+const image_t img_3x5_2 = {3, 5, false, 2, 0, {0xE7, 0xCE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_3.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_3.c
index 8d08ed1b61..97ff0478ac 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_3.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_3.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_3 = { 3, 5, false, 2, 0, {
- 0xE5, 0x9E
-}};
+const image_t img_3x5_3 = {3, 5, false, 2, 0, {0xE5, 0x9E}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_4.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_4.c
index 795e9b76f3..2bbd9ef428 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_4.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_4.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_4 = { 3, 5, false, 2, 0, {
- 0x97, 0x92
-}};
+const image_t img_3x5_4 = {3, 5, false, 2, 0, {0x97, 0x92}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_5.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_5.c
index 3778535073..e0466f37ab 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_5.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_5.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_5 = { 3, 5, false, 2, 0, {
- 0xF3, 0x9E
-}};
+const image_t img_3x5_5 = {3, 5, false, 2, 0, {0xF3, 0x9E}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_6.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_6.c
index d3af640711..1b62caf725 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_6.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_6.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_6 = { 3, 5, false, 2, 0, {
- 0xD3, 0xDE
-}};
+const image_t img_3x5_6 = {3, 5, false, 2, 0, {0xD3, 0xDE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_7.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_7.c
index 2c3b1e0b91..acfe57cf8a 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_7.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_7.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_7 = { 3, 5, false, 2, 0, {
- 0xE5, 0x24
-}};
+const image_t img_3x5_7 = {3, 5, false, 2, 0, {0xE5, 0x24}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_8.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_8.c
index 5cb6d33548..31f32af52d 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_8.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_8.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_8 = { 3, 5, false, 2, 0, {
- 0xF7, 0xDE
-}};
+const image_t img_3x5_8 = {3, 5, false, 2, 0, {0xF7, 0xDE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_9.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_9.c
index ee5e82b878..4b1ba1e09e 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_9.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_9.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_9 = { 3, 5, false, 2, 0, {
- 0xF7, 0x96
-}};
+const image_t img_3x5_9 = {3, 5, false, 2, 0, {0xF7, 0x96}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_3x5_v.c b/applications/plugins/wii_ec_anal/gfx/img_3x5_v.c
index dcf3f631df..2282e16978 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_3x5_v.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_3x5_v.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_3x5_v = { 3, 5, false, 2, 0, {
- 0x02, 0xD4
-}};
+const image_t img_3x5_v = {3, 5, false, 2, 0, {0x02, 0xD4}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_0.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_0.c
index c59852f192..7ae2186b37 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_0.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_0.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_0 = { 5, 7, false, 5, 0, {
- 0x74, 0x67, 0x5C, 0xC5, 0xC0
-}};
+const image_t img_5x7_0 = {5, 7, false, 5, 0, {0x74, 0x67, 0x5C, 0xC5, 0xC0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_1.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_1.c
index 4bd08f89c9..c1a9cec746 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_1.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_1 = { 5, 7, false, 5, 0, {
- 0x65, 0x08, 0x42, 0x13, 0xE0
-}};
+const image_t img_5x7_1 = {5, 7, false, 5, 0, {0x65, 0x08, 0x42, 0x13, 0xE0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_2.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_2.c
index 1270393f7d..7fab900107 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_2.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_2.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_2 = { 5, 7, false, 5, 0, {
- 0x74, 0x42, 0x22, 0x23, 0xE0
-}};
+const image_t img_5x7_2 = {5, 7, false, 5, 0, {0x74, 0x42, 0x22, 0x23, 0xE0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_3.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_3.c
index e26bac523b..2099bf795d 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_3.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_3.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_3 = { 5, 7, false, 5, 0, {
- 0x74, 0x42, 0x60, 0xC5, 0xC0
-}};
+const image_t img_5x7_3 = {5, 7, false, 5, 0, {0x74, 0x42, 0x60, 0xC5, 0xC0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_4.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_4.c
index e0dc5687f9..1eee4f07d5 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_4.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_4.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_4 = { 5, 7, false, 5, 0, {
- 0x84, 0x25, 0x2F, 0x88, 0x40
-}};
+const image_t img_5x7_4 = {5, 7, false, 5, 0, {0x84, 0x25, 0x2F, 0x88, 0x40}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_5.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_5.c
index 81747376fe..be1e54681e 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_5.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_5.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_5 = { 5, 7, false, 5, 0, {
- 0xFC, 0x21, 0xE0, 0x87, 0xC0
-}};
+const image_t img_5x7_5 = {5, 7, false, 5, 0, {0xFC, 0x21, 0xE0, 0x87, 0xC0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_6.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_6.c
index 455c874dc6..da155c1b54 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_6.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_6.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_6 = { 5, 7, false, 5, 0, {
- 0x74, 0x21, 0xE8, 0xC5, 0xC0
-}};
+const image_t img_5x7_6 = {5, 7, false, 5, 0, {0x74, 0x21, 0xE8, 0xC5, 0xC0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_7.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_7.c
index 73e813a218..fde7e8ea2a 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_7.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_7.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_7 = { 5, 7, false, 5, 0, {
- 0xF8, 0x44, 0x22, 0x10, 0x80
-}};
+const image_t img_5x7_7 = {5, 7, false, 5, 0, {0xF8, 0x44, 0x22, 0x10, 0x80}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_8.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_8.c
index 0f04a48bff..aff1782827 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_8.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_8.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_8 = { 5, 7, false, 5, 0, {
- 0x74, 0x62, 0xE8, 0xC5, 0xC0
-}};
+const image_t img_5x7_8 = {5, 7, false, 5, 0, {0x74, 0x62, 0xE8, 0xC5, 0xC0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_9.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_9.c
index 2b1e978c6c..2417c57e87 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_9.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_9.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_9 = { 5, 7, false, 5, 0, {
- 0x74, 0x62, 0xF0, 0x85, 0xC0
-}};
+const image_t img_5x7_9 = {5, 7, false, 5, 0, {0x74, 0x62, 0xF0, 0x85, 0xC0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_A.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_A.c
index a6b049f013..910c034a2d 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_A.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_A.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_A = { 5, 7, false, 5, 0, {
- 0x74, 0x63, 0xF8, 0xC6, 0x20
-}};
+const image_t img_5x7_A = {5, 7, false, 5, 0, {0x74, 0x63, 0xF8, 0xC6, 0x20}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_B.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_B.c
index 06b36599c5..93808fee27 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_B.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_B.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_B = { 5, 7, false, 5, 0, {
- 0xF4, 0x63, 0x68, 0xC7, 0xC0
-}};
+const image_t img_5x7_B = {5, 7, false, 5, 0, {0xF4, 0x63, 0x68, 0xC7, 0xC0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_C.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_C.c
index c058d09a9b..1438eaf446 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_C.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_C.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_C = { 5, 7, false, 5, 0, {
- 0x74, 0x61, 0x08, 0x45, 0xC0
-}};
+const image_t img_5x7_C = {5, 7, false, 5, 0, {0x74, 0x61, 0x08, 0x45, 0xC0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_D.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_D.c
index 3425e36482..9c6b590eed 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_D.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_D.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_D = { 5, 7, false, 5, 0, {
- 0x75, 0x4A, 0x52, 0xD5, 0xC0
-}};
+const image_t img_5x7_D = {5, 7, false, 5, 0, {0x75, 0x4A, 0x52, 0xD5, 0xC0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_E.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_E.c
index c7bbc301ae..bc15fb240d 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_E.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_E.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_E = { 5, 7, false, 5, 0, {
- 0xFC, 0x21, 0xC8, 0x43, 0xE0
-}};
+const image_t img_5x7_E = {5, 7, false, 5, 0, {0xFC, 0x21, 0xC8, 0x43, 0xE0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_5x7_F.c b/applications/plugins/wii_ec_anal/gfx/img_5x7_F.c
index 440c37eae8..e4ad0db69e 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_5x7_F.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_5x7_F.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_5x7_F = { 5, 7, false, 5, 0, {
- 0xFC, 0x21, 0xC8, 0x42, 0x00
-}};
+const image_t img_5x7_F = {5, 7, false, 5, 0, {0xFC, 0x21, 0xC8, 0x42, 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_0.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_0.c
index b8b4c7d9ac..952cf34d85 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_0.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_0.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_0 = { 6, 8, false, 6, 0, {
- 0x7B, 0xFC, 0xF3, 0xCF, 0x3F, 0xDE
-}};
+const image_t img_6x8_0 = {6, 8, false, 6, 0, {0x7B, 0xFC, 0xF3, 0xCF, 0x3F, 0xDE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_1.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_1.c
index 91e2b2cfab..846a6876c2 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_1.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_1 = { 6, 8, false, 6, 0, {
- 0x73, 0xC3, 0x0C, 0x30, 0xCF, 0xFF
-}};
+const image_t img_6x8_1 = {6, 8, false, 6, 0, {0x73, 0xC3, 0x0C, 0x30, 0xCF, 0xFF}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_2.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_2.c
index 7d24c64d64..4534bb67c3 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_2.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_2.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_2 = { 6, 8, false, 6, 0, {
- 0x7B, 0xF0, 0xC7, 0x31, 0x8F, 0xFF
-}};
+const image_t img_6x8_2 = {6, 8, false, 6, 0, {0x7B, 0xF0, 0xC7, 0x31, 0x8F, 0xFF}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_3.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_3.c
index 3a8f9f2110..7e79eb03a4 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_3.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_3.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_3 = { 6, 8, false, 6, 0, {
- 0x7B, 0xF0, 0xCF, 0x3C, 0x3F, 0xDE
-}};
+const image_t img_6x8_3 = {6, 8, false, 6, 0, {0x7B, 0xF0, 0xCF, 0x3C, 0x3F, 0xDE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_4.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_4.c
index c5ae9efef0..324b036ce6 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_4.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_4.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_4 = { 6, 8, false, 6, 0, {
- 0xC3, 0x0D, 0xB6, 0xFF, 0xF1, 0x86
-}};
+const image_t img_6x8_4 = {6, 8, false, 6, 0, {0xC3, 0x0D, 0xB6, 0xFF, 0xF1, 0x86}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_5.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_5.c
index 787e39ea6d..cdfda5f2b3 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_5.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_5.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_5 = { 6, 8, false, 6, 0, {
- 0xFF, 0xFC, 0x3E, 0xFC, 0x3F, 0xFE
-}};
+const image_t img_6x8_5 = {6, 8, false, 6, 0, {0xFF, 0xFC, 0x3E, 0xFC, 0x3F, 0xFE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_6.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_6.c
index 8f07f1bfc4..781a060f1b 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_6.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_6.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_6 = { 6, 8, false, 6, 0, {
- 0x7B, 0xEC, 0x3E, 0xFF, 0x3F, 0xDE
-}};
+const image_t img_6x8_6 = {6, 8, false, 6, 0, {0x7B, 0xEC, 0x3E, 0xFF, 0x3F, 0xDE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_7.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_7.c
index cad50c65d4..fec5f4bf4a 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_7.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_7.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_7 = { 6, 8, false, 6, 0, {
- 0xFF, 0xF0, 0xC6, 0x18, 0xC3, 0x0C
-}};
+const image_t img_6x8_7 = {6, 8, false, 6, 0, {0xFF, 0xF0, 0xC6, 0x18, 0xC3, 0x0C}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_8.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_8.c
index a38b2110d5..a5b21c3753 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_8.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_8.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_8 = { 6, 8, false, 6, 0, {
- 0x7B, 0xFC, 0xDE, 0xFF, 0x3F, 0xDE
-}};
+const image_t img_6x8_8 = {6, 8, false, 6, 0, {0x7B, 0xFC, 0xDE, 0xFF, 0x3F, 0xDE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_9.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_9.c
index b740c7f90a..f7707c0df1 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_9.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_9.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_9 = { 6, 8, false, 6, 0, {
- 0x7B, 0xFC, 0xFF, 0x7C, 0x37, 0xDE
-}};
+const image_t img_6x8_9 = {6, 8, false, 6, 0, {0x7B, 0xFC, 0xFF, 0x7C, 0x37, 0xDE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_A.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_A.c
index fa3aed598f..1bb65c9021 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_A.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_A.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_A = { 6, 8, false, 6, 0, {
- 0x7B, 0xFC, 0xF3, 0xFF, 0xFC, 0xF3
-}};
+const image_t img_6x8_A = {6, 8, false, 6, 0, {0x7B, 0xFC, 0xF3, 0xFF, 0xFC, 0xF3}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_B.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_B.c
index 14c1e28c6c..00e012d53f 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_B.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_B.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_B = { 6, 8, false, 6, 0, {
- 0xFB, 0xFC, 0xFE, 0xFB, 0x3F, 0xFE
-}};
+const image_t img_6x8_B = {6, 8, false, 6, 0, {0xFB, 0xFC, 0xFE, 0xFB, 0x3F, 0xFE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_C.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_C.c
index 6d8f7aa325..6949010098 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_C.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_C.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_C = { 6, 8, false, 6, 0, {
- 0x7F, 0xFC, 0x30, 0xC3, 0x0F, 0xDF
-}};
+const image_t img_6x8_C = {6, 8, false, 6, 0, {0x7F, 0xFC, 0x30, 0xC3, 0x0F, 0xDF}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_D.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_D.c
index 474e4a2354..a95e760eb3 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_D.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_D.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_D = { 6, 8, false, 6, 0, {
- 0xFB, 0xF6, 0xDB, 0x6D, 0xBF, 0xFE
-}};
+const image_t img_6x8_D = {6, 8, false, 6, 0, {0xFB, 0xF6, 0xDB, 0x6D, 0xBF, 0xFE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_E.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_E.c
index 00f2cb5596..f49503f000 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_E.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_E.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_E = { 6, 8, false, 6, 0, {
- 0xFF, 0xFC, 0x3C, 0xF3, 0x0F, 0xFF
-}};
+const image_t img_6x8_E = {6, 8, false, 6, 0, {0xFF, 0xFC, 0x3C, 0xF3, 0x0F, 0xFF}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_F.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_F.c
index 8958a04193..0037b25441 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_F.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_F.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_F = { 6, 8, false, 6, 0, {
- 0xFF, 0xFC, 0x3C, 0xF3, 0x0C, 0x30
-}};
+const image_t img_6x8_F = {6, 8, false, 6, 0, {0xFF, 0xFC, 0x3C, 0xF3, 0x0C, 0x30}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_G.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_G.c
index f5e8f03f40..f30bc99526 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_G.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_G.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_G = { 6, 8, false, 6, 0, {
- 0x7F, 0xFC, 0x30, 0xDF, 0x3F, 0xDF
-}};
+const image_t img_6x8_G = {6, 8, false, 6, 0, {0x7F, 0xFC, 0x30, 0xDF, 0x3F, 0xDF}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_X.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_X.c
index 7b162baf30..4735e82a19 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_X.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_X.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_X = { 6, 8, false, 6, 0, {
- 0xCF, 0x36, 0x8E, 0x71, 0x6C, 0xF3
-}};
+const image_t img_6x8_X = {6, 8, false, 6, 0, {0xCF, 0x36, 0x8E, 0x71, 0x6C, 0xF3}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_Y.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_Y.c
index b393929486..508e786bde 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_Y.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_Y.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_Y = { 6, 8, false, 6, 0, {
- 0xCF, 0x3C, 0xF3, 0x78, 0xC3, 0x0C
-}};
+const image_t img_6x8_Y = {6, 8, false, 6, 0, {0xCF, 0x3C, 0xF3, 0x78, 0xC3, 0x0C}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_Z.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_Z.c
index 9904d08b4b..c42d560acd 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_Z.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_Z.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_Z = { 6, 8, false, 6, 0, {
- 0xFF, 0xF0, 0xC6, 0x31, 0x8F, 0xFF
-}};
+const image_t img_6x8_Z = {6, 8, false, 6, 0, {0xFF, 0xF0, 0xC6, 0x31, 0x8F, 0xFF}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_d_.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_d_.c
index 2a00713fd0..1f8123a6cf 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_d_.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_d_.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_d = { 6, 8, false, 6, 0, {
- 0x0C, 0x30, 0xDF, 0xFF, 0x3F, 0xDF
-}};
+const image_t img_6x8_d = {6, 8, false, 6, 0, {0x0C, 0x30, 0xDF, 0xFF, 0x3F, 0xDF}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_n_.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_n_.c
index 086bdd2dea..15d403d288 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_n_.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_n_.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_n = { 6, 8, false, 6, 0, {
- 0x00, 0x07, 0xBF, 0xCF, 0x3C, 0xF3
-}};
+const image_t img_6x8_n = {6, 8, false, 6, 0, {0x00, 0x07, 0xBF, 0xCF, 0x3C, 0xF3}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_6x8_v_.c b/applications/plugins/wii_ec_anal/gfx/img_6x8_v_.c
index c897aadffd..1229701a13 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_6x8_v_.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_6x8_v_.c
@@ -9,6 +9,4 @@
#include "images.h"
-const image_t img_6x8_v = { 6, 8, false, 6, 0, {
- 0x00, 0x08, 0x73, 0xCF, 0xF7, 0x8C
-}};
+const image_t img_6x8_v = {6, 8, false, 6, 0, {0x00, 0x08, 0x73, 0xCF, 0xF7, 0x8C}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_RIP.c b/applications/plugins/wii_ec_anal/gfx/img_RIP.c
index 55cb7bfc28..c20877ef08 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_RIP.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_RIP.c
@@ -65,58 +65,66 @@
#include "images.h"
-const image_t img_RIP = { 128, 64, true, 837, 0x06, { // orig:1024, comp:18.26%
- 0x06, 0x20, 0xFF, 0xC0, 0x06, 0x0E, 0x00, 0x03, 0xD4, 0x06, 0x0E, 0x00, 0x2B, 0xC8, 0x01, 0xFC,
- 0x1E, 0x1F, 0xF0, 0x00, 0xFE, 0x20, 0x8F, 0xE3, 0xF8, 0xFE, 0x3F, 0x80, 0x13, 0xD4, 0x01, 0xFC,
- 0x0E, 0x0F, 0xF0, 0x00, 0xFE, 0x71, 0xCF, 0xE3, 0xF8, 0xFE, 0x3F, 0x80, 0x2B, 0xC0, 0x00, 0x0E,
- 0x0A, 0x00, 0x38, 0x01, 0x87, 0x71, 0xD8, 0x77, 0x1C, 0x07, 0x71, 0xC0, 0x03, 0xC0, 0x03, 0x8E,
- 0x0A, 0x0E, 0x28, 0x01, 0xC5, 0x51, 0x5C, 0x77, 0x1D, 0xC7, 0x71, 0x40, 0x03, 0xC0, 0x03, 0x8A,
- 0x0A, 0x0E, 0x28, 0x01, 0x47, 0x51, 0x5C, 0x55, 0x15, 0xC5, 0x51, 0x40, 0x03, 0xC0, 0x02, 0x8A,
- 0x0A, 0x0A, 0x28, 0x01, 0x40, 0x51, 0x54, 0x55, 0x15, 0x45, 0x51, 0x40, 0x03, 0xC0, 0x02, 0x8A,
- 0x0A, 0x0A, 0x28, 0x01, 0x40, 0x51, 0x54, 0x55, 0x15, 0x45, 0x51, 0xC0, 0x03, 0xC0, 0x02, 0x8E,
- 0x0A, 0x0A, 0x38, 0x01, 0x40, 0x51, 0x54, 0x75, 0x55, 0x47, 0x50, 0x00, 0x03, 0xC0, 0x02, 0xF8,
- 0x0A, 0x0B, 0xE0, 0x01, 0x40, 0x71, 0xD7, 0xC5, 0x15, 0x7C, 0x50, 0x00, 0x03, 0xC0, 0x02, 0xF8,
- 0x0A, 0x0B, 0xE0, 0x01, 0x40, 0x3F, 0x97, 0xC5, 0x15, 0x7C, 0x57, 0x80, 0x03, 0xC0, 0x02, 0x9C,
- 0x0A, 0x0A, 0x00, 0x01, 0x40, 0x1B, 0x14, 0x75, 0x55, 0x4E, 0x57, 0xC0, 0x03, 0xC0, 0x02, 0x94,
- 0x0A, 0x0A, 0x00, 0x01, 0x40, 0x0A, 0x14, 0x55, 0x15, 0x4A, 0x51, 0x40, 0x03, 0xC0, 0x02, 0x94,
- 0x0A, 0x0A, 0x00, 0x01, 0x40, 0x0A, 0x14, 0x55, 0x15, 0x4A, 0x51, 0x40, 0x03, 0xC0, 0x02, 0x94,
- 0x0A, 0x0A, 0x00, 0x01, 0xC7, 0x0A, 0x14, 0x55, 0x15, 0x4A, 0x71, 0x40, 0x03, 0xC0, 0x02, 0x94,
- 0x0A, 0x0A, 0x00, 0x01, 0xC5, 0x0A, 0x1C, 0x77, 0x1D, 0x4A, 0x71, 0x40, 0x03, 0xC0, 0x02, 0x94,
- 0x0A, 0x0A, 0x00, 0x01, 0x87, 0x0E, 0x1C, 0x77, 0x1D, 0x4A, 0x61, 0xC0, 0x03, 0xC0, 0x03, 0x9C,
- 0xCE, 0xCE, 0xC0, 0x00, 0xFE, 0x0E, 0x0F, 0xE3, 0xF9, 0xCE, 0x3F, 0x80, 0x03, 0xC0, 0x03, 0x8E,
- 0xDE, 0xDE, 0xC0, 0x00, 0xFE, 0x1F, 0x0F, 0xE3, 0xF9, 0xC7, 0x3F, 0x80, 0x03, 0xC0, 0x06, 0x0E,
- 0x00, 0x03, 0xC0, 0x06, 0x0E, 0x00, 0x03, 0xC0, 0x06, 0x0A, 0x00, 0x01, 0x8C, 0x07, 0xF0, 0x03,
- 0xC0, 0x06, 0x07, 0x00, 0x04, 0x00, 0x00, 0x02, 0x52, 0x18, 0x0C, 0x03, 0xC1, 0xD5, 0xC7, 0x57,
- 0x77, 0x6D, 0xC4, 0x5D, 0x2B, 0x8E, 0xE0, 0x03, 0x5A, 0x20, 0x02, 0x03, 0xC0, 0x95, 0x04, 0x54,
- 0x24, 0x55, 0x04, 0x55, 0xA1, 0x0A, 0x80, 0x01, 0x8C, 0x47, 0xC1, 0x03, 0xC0, 0x9D, 0x87, 0x27,
- 0x26, 0x55, 0xC5, 0x55, 0x61, 0x0C, 0xC0, 0x00, 0x50, 0x88, 0x21, 0x03, 0xC0, 0x95, 0x01, 0x21,
- 0x24, 0x44, 0x45, 0x55, 0x21, 0x0A, 0x80, 0x00, 0x20, 0x90, 0x11, 0x03, 0xC0, 0x95, 0xC7, 0x27,
- 0x27, 0x45, 0xC6, 0xDD, 0x21, 0x0E, 0xE0, 0x00, 0x70, 0x91, 0x91, 0x03, 0xC0, 0x06, 0x0B, 0x00,
- 0x88, 0x92, 0x51, 0x03, 0xC0, 0x06, 0x0A, 0x00, 0x01, 0x08, 0x92, 0x91, 0x03, 0xC0, 0x06, 0x0A,
- 0x00, 0x01, 0x08, 0x92, 0x11, 0x03, 0xC1, 0xD5, 0xC7, 0x76, 0xDC, 0x45, 0xDD, 0x5D, 0x5C, 0x57,
- 0x50, 0x00, 0x87, 0x11, 0xE2, 0x03, 0xC0, 0x95, 0x04, 0x55, 0x50, 0x44, 0x89, 0x55, 0x48, 0x55,
- 0x50, 0x00, 0x80, 0x88, 0x03, 0x03, 0xC0, 0x9D, 0x87, 0x75, 0x58, 0x54, 0x89, 0xD5, 0x48, 0x25,
- 0x50, 0x00, 0x40, 0x7C, 0x04, 0x83, 0xC0, 0x95, 0x01, 0x54, 0x50, 0x54, 0x89, 0x55, 0x48, 0x25,
- 0x50, 0x00, 0x40, 0x07, 0xF8, 0x43, 0xC0, 0x95, 0xC7, 0x54, 0x5C, 0x6D, 0xC9, 0x5D, 0xC8, 0x27,
- 0x70, 0x00, 0x30, 0x00, 0x00, 0x43, 0xC0, 0x06, 0x0B, 0x00, 0x0F, 0xFF, 0xFF, 0x83, 0xC0, 0x06,
- 0x0E, 0x00, 0x03, 0xC0, 0x06, 0x0E, 0x00, 0x03, 0xC0, 0x00, 0x07, 0xC7, 0xF1, 0xFC, 0x7F, 0x00,
- 0x03, 0xF8, 0xFE, 0x3F, 0x8F, 0xE0, 0x00, 0x03, 0xC0, 0x00, 0x07, 0xC7, 0xF1, 0xFC, 0x7F, 0x00,
- 0x03, 0xF8, 0xFE, 0x3F, 0x8F, 0xE0, 0x00, 0x03, 0xC0, 0x00, 0x05, 0x4E, 0x3B, 0x8E, 0xE3, 0x80,
- 0x07, 0x1D, 0xC7, 0x71, 0xDC, 0x70, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x4E, 0x3A, 0x8E, 0xE3, 0x80,
- 0x05, 0x15, 0xC7, 0x51, 0x54, 0x50, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x4A, 0x2B, 0x8A, 0xA2, 0x80,
- 0x07, 0x15, 0x45, 0x71, 0x5C, 0x50, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x4A, 0x28, 0x0A, 0xA2, 0x80,
- 0x00, 0x15, 0x45, 0x01, 0x40, 0x50, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x4A, 0x28, 0x0A, 0xA6, 0x80,
- 0x00, 0x15, 0x4D, 0x01, 0x40, 0x50, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x4E, 0x28, 0x0E, 0xA6, 0x80,
- 0x00, 0x1D, 0x4D, 0x01, 0xC0, 0x70, 0x00, 0x03, 0xC0, 0x00, 0x01, 0xC3, 0xE8, 0x0E, 0xAA, 0x9F,
- 0xE1, 0xF9, 0x55, 0x1F, 0x87, 0xE0, 0x00, 0x03, 0xC0, 0x00, 0x01, 0xC3, 0xE8, 0x38, 0xAA, 0x90,
- 0x23, 0xF1, 0x55, 0x3F, 0x0F, 0xC0, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x28, 0x38, 0xB2, 0x9F,
- 0xE7, 0x01, 0x65, 0x70, 0x1C, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x28, 0x28, 0xB2, 0x80,
- 0x05, 0x01, 0x65, 0x50, 0x14, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x28, 0x28, 0xA2, 0x80,
- 0x05, 0x01, 0x45, 0x50, 0x14, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x28, 0x28, 0xA2, 0x80,
- 0x05, 0x01, 0x45, 0x50, 0x14, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x38, 0x28, 0xE3, 0x80,
- 0x05, 0x01, 0xC7, 0x50, 0x14, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x38, 0x28, 0xE3, 0x80,
- 0x05, 0x0D, 0xC7, 0x50, 0xD4, 0x30, 0x00, 0x03, 0xD4, 0x00, 0x07, 0xF3, 0xF0, 0x38, 0x7F, 0x00,
- 0x07, 0xFC, 0xFE, 0x7F, 0xDF, 0xF0, 0x00, 0x2B, 0xC8, 0x00, 0x0F, 0xFB, 0xF0, 0x38, 0x7F, 0x00,
- 0x07, 0xFC, 0xFE, 0x7F, 0xDF, 0xF0, 0x00, 0x13, 0xD4, 0x06, 0x0E, 0x00, 0x2B, 0xC0, 0x06, 0x0E,
- 0x00, 0x03, 0x06, 0x20, 0xFF
-}};
+const image_t img_RIP = {
+ 128,
+ 64,
+ true,
+ 837,
+ 0x06,
+ {// orig:1024, comp:18.26%
+ 0x06, 0x20, 0xFF, 0xC0, 0x06, 0x0E, 0x00, 0x03, 0xD4, 0x06, 0x0E, 0x00, 0x2B, 0xC8, 0x01,
+ 0xFC, 0x1E, 0x1F, 0xF0, 0x00, 0xFE, 0x20, 0x8F, 0xE3, 0xF8, 0xFE, 0x3F, 0x80, 0x13, 0xD4,
+ 0x01, 0xFC, 0x0E, 0x0F, 0xF0, 0x00, 0xFE, 0x71, 0xCF, 0xE3, 0xF8, 0xFE, 0x3F, 0x80, 0x2B,
+ 0xC0, 0x00, 0x0E, 0x0A, 0x00, 0x38, 0x01, 0x87, 0x71, 0xD8, 0x77, 0x1C, 0x07, 0x71, 0xC0,
+ 0x03, 0xC0, 0x03, 0x8E, 0x0A, 0x0E, 0x28, 0x01, 0xC5, 0x51, 0x5C, 0x77, 0x1D, 0xC7, 0x71,
+ 0x40, 0x03, 0xC0, 0x03, 0x8A, 0x0A, 0x0E, 0x28, 0x01, 0x47, 0x51, 0x5C, 0x55, 0x15, 0xC5,
+ 0x51, 0x40, 0x03, 0xC0, 0x02, 0x8A, 0x0A, 0x0A, 0x28, 0x01, 0x40, 0x51, 0x54, 0x55, 0x15,
+ 0x45, 0x51, 0x40, 0x03, 0xC0, 0x02, 0x8A, 0x0A, 0x0A, 0x28, 0x01, 0x40, 0x51, 0x54, 0x55,
+ 0x15, 0x45, 0x51, 0xC0, 0x03, 0xC0, 0x02, 0x8E, 0x0A, 0x0A, 0x38, 0x01, 0x40, 0x51, 0x54,
+ 0x75, 0x55, 0x47, 0x50, 0x00, 0x03, 0xC0, 0x02, 0xF8, 0x0A, 0x0B, 0xE0, 0x01, 0x40, 0x71,
+ 0xD7, 0xC5, 0x15, 0x7C, 0x50, 0x00, 0x03, 0xC0, 0x02, 0xF8, 0x0A, 0x0B, 0xE0, 0x01, 0x40,
+ 0x3F, 0x97, 0xC5, 0x15, 0x7C, 0x57, 0x80, 0x03, 0xC0, 0x02, 0x9C, 0x0A, 0x0A, 0x00, 0x01,
+ 0x40, 0x1B, 0x14, 0x75, 0x55, 0x4E, 0x57, 0xC0, 0x03, 0xC0, 0x02, 0x94, 0x0A, 0x0A, 0x00,
+ 0x01, 0x40, 0x0A, 0x14, 0x55, 0x15, 0x4A, 0x51, 0x40, 0x03, 0xC0, 0x02, 0x94, 0x0A, 0x0A,
+ 0x00, 0x01, 0x40, 0x0A, 0x14, 0x55, 0x15, 0x4A, 0x51, 0x40, 0x03, 0xC0, 0x02, 0x94, 0x0A,
+ 0x0A, 0x00, 0x01, 0xC7, 0x0A, 0x14, 0x55, 0x15, 0x4A, 0x71, 0x40, 0x03, 0xC0, 0x02, 0x94,
+ 0x0A, 0x0A, 0x00, 0x01, 0xC5, 0x0A, 0x1C, 0x77, 0x1D, 0x4A, 0x71, 0x40, 0x03, 0xC0, 0x02,
+ 0x94, 0x0A, 0x0A, 0x00, 0x01, 0x87, 0x0E, 0x1C, 0x77, 0x1D, 0x4A, 0x61, 0xC0, 0x03, 0xC0,
+ 0x03, 0x9C, 0xCE, 0xCE, 0xC0, 0x00, 0xFE, 0x0E, 0x0F, 0xE3, 0xF9, 0xCE, 0x3F, 0x80, 0x03,
+ 0xC0, 0x03, 0x8E, 0xDE, 0xDE, 0xC0, 0x00, 0xFE, 0x1F, 0x0F, 0xE3, 0xF9, 0xC7, 0x3F, 0x80,
+ 0x03, 0xC0, 0x06, 0x0E, 0x00, 0x03, 0xC0, 0x06, 0x0E, 0x00, 0x03, 0xC0, 0x06, 0x0A, 0x00,
+ 0x01, 0x8C, 0x07, 0xF0, 0x03, 0xC0, 0x06, 0x07, 0x00, 0x04, 0x00, 0x00, 0x02, 0x52, 0x18,
+ 0x0C, 0x03, 0xC1, 0xD5, 0xC7, 0x57, 0x77, 0x6D, 0xC4, 0x5D, 0x2B, 0x8E, 0xE0, 0x03, 0x5A,
+ 0x20, 0x02, 0x03, 0xC0, 0x95, 0x04, 0x54, 0x24, 0x55, 0x04, 0x55, 0xA1, 0x0A, 0x80, 0x01,
+ 0x8C, 0x47, 0xC1, 0x03, 0xC0, 0x9D, 0x87, 0x27, 0x26, 0x55, 0xC5, 0x55, 0x61, 0x0C, 0xC0,
+ 0x00, 0x50, 0x88, 0x21, 0x03, 0xC0, 0x95, 0x01, 0x21, 0x24, 0x44, 0x45, 0x55, 0x21, 0x0A,
+ 0x80, 0x00, 0x20, 0x90, 0x11, 0x03, 0xC0, 0x95, 0xC7, 0x27, 0x27, 0x45, 0xC6, 0xDD, 0x21,
+ 0x0E, 0xE0, 0x00, 0x70, 0x91, 0x91, 0x03, 0xC0, 0x06, 0x0B, 0x00, 0x88, 0x92, 0x51, 0x03,
+ 0xC0, 0x06, 0x0A, 0x00, 0x01, 0x08, 0x92, 0x91, 0x03, 0xC0, 0x06, 0x0A, 0x00, 0x01, 0x08,
+ 0x92, 0x11, 0x03, 0xC1, 0xD5, 0xC7, 0x76, 0xDC, 0x45, 0xDD, 0x5D, 0x5C, 0x57, 0x50, 0x00,
+ 0x87, 0x11, 0xE2, 0x03, 0xC0, 0x95, 0x04, 0x55, 0x50, 0x44, 0x89, 0x55, 0x48, 0x55, 0x50,
+ 0x00, 0x80, 0x88, 0x03, 0x03, 0xC0, 0x9D, 0x87, 0x75, 0x58, 0x54, 0x89, 0xD5, 0x48, 0x25,
+ 0x50, 0x00, 0x40, 0x7C, 0x04, 0x83, 0xC0, 0x95, 0x01, 0x54, 0x50, 0x54, 0x89, 0x55, 0x48,
+ 0x25, 0x50, 0x00, 0x40, 0x07, 0xF8, 0x43, 0xC0, 0x95, 0xC7, 0x54, 0x5C, 0x6D, 0xC9, 0x5D,
+ 0xC8, 0x27, 0x70, 0x00, 0x30, 0x00, 0x00, 0x43, 0xC0, 0x06, 0x0B, 0x00, 0x0F, 0xFF, 0xFF,
+ 0x83, 0xC0, 0x06, 0x0E, 0x00, 0x03, 0xC0, 0x06, 0x0E, 0x00, 0x03, 0xC0, 0x00, 0x07, 0xC7,
+ 0xF1, 0xFC, 0x7F, 0x00, 0x03, 0xF8, 0xFE, 0x3F, 0x8F, 0xE0, 0x00, 0x03, 0xC0, 0x00, 0x07,
+ 0xC7, 0xF1, 0xFC, 0x7F, 0x00, 0x03, 0xF8, 0xFE, 0x3F, 0x8F, 0xE0, 0x00, 0x03, 0xC0, 0x00,
+ 0x05, 0x4E, 0x3B, 0x8E, 0xE3, 0x80, 0x07, 0x1D, 0xC7, 0x71, 0xDC, 0x70, 0x00, 0x03, 0xC0,
+ 0x00, 0x01, 0x4E, 0x3A, 0x8E, 0xE3, 0x80, 0x05, 0x15, 0xC7, 0x51, 0x54, 0x50, 0x00, 0x03,
+ 0xC0, 0x00, 0x01, 0x4A, 0x2B, 0x8A, 0xA2, 0x80, 0x07, 0x15, 0x45, 0x71, 0x5C, 0x50, 0x00,
+ 0x03, 0xC0, 0x00, 0x01, 0x4A, 0x28, 0x0A, 0xA2, 0x80, 0x00, 0x15, 0x45, 0x01, 0x40, 0x50,
+ 0x00, 0x03, 0xC0, 0x00, 0x01, 0x4A, 0x28, 0x0A, 0xA6, 0x80, 0x00, 0x15, 0x4D, 0x01, 0x40,
+ 0x50, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x4E, 0x28, 0x0E, 0xA6, 0x80, 0x00, 0x1D, 0x4D, 0x01,
+ 0xC0, 0x70, 0x00, 0x03, 0xC0, 0x00, 0x01, 0xC3, 0xE8, 0x0E, 0xAA, 0x9F, 0xE1, 0xF9, 0x55,
+ 0x1F, 0x87, 0xE0, 0x00, 0x03, 0xC0, 0x00, 0x01, 0xC3, 0xE8, 0x38, 0xAA, 0x90, 0x23, 0xF1,
+ 0x55, 0x3F, 0x0F, 0xC0, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x28, 0x38, 0xB2, 0x9F, 0xE7,
+ 0x01, 0x65, 0x70, 0x1C, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x28, 0x28, 0xB2, 0x80,
+ 0x05, 0x01, 0x65, 0x50, 0x14, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x28, 0x28, 0xA2,
+ 0x80, 0x05, 0x01, 0x45, 0x50, 0x14, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x28, 0x28,
+ 0xA2, 0x80, 0x05, 0x01, 0x45, 0x50, 0x14, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40, 0x38,
+ 0x28, 0xE3, 0x80, 0x05, 0x01, 0xC7, 0x50, 0x14, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x40,
+ 0x38, 0x28, 0xE3, 0x80, 0x05, 0x0D, 0xC7, 0x50, 0xD4, 0x30, 0x00, 0x03, 0xD4, 0x00, 0x07,
+ 0xF3, 0xF0, 0x38, 0x7F, 0x00, 0x07, 0xFC, 0xFE, 0x7F, 0xDF, 0xF0, 0x00, 0x2B, 0xC8, 0x00,
+ 0x0F, 0xFB, 0xF0, 0x38, 0x7F, 0x00, 0x07, 0xFC, 0xFE, 0x7F, 0xDF, 0xF0, 0x00, 0x13, 0xD4,
+ 0x06, 0x0E, 0x00, 0x2B, 0xC0, 0x06, 0x0E, 0x00, 0x03, 0x06, 0x20, 0xFF}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_Cable.c b/applications/plugins/wii_ec_anal/gfx/img_cc_Cable.c
index 2fc6b5f238..f4ac261730 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_Cable.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_Cable.c
@@ -12,6 +12,14 @@
#include "images.h"
-const image_t img_cc_Cable = { 4, 11, true, 4, 0x00, { // orig:6, comp:33.33%
- 0x00, 0x05, 0xDB, 0xD0
-}};
+const image_t img_cc_Cable = {
+ 4,
+ 11,
+ true,
+ 4,
+ 0x00,
+ {// orig:6, comp:33.33%
+ 0x00,
+ 0x05,
+ 0xDB,
+ 0xD0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_Joy.c b/applications/plugins/wii_ec_anal/gfx/img_cc_Joy.c
index dd189cb7e3..5054103b3f 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_Joy.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_Joy.c
@@ -18,8 +18,8 @@
#include "images.h"
-const image_t img_cc_Joy = { 17, 17, false, 37, 0, {
- 0x00, 0x80, 0x01, 0xF0, 0x0F, 0xDF, 0x87, 0x01, 0xC3, 0x00, 0x61, 0x00, 0x11, 0x80, 0x0C, 0xC0,
- 0x06, 0xC0, 0x01, 0xB0, 0x01, 0x98, 0x00, 0xC4, 0x00, 0x43, 0x00, 0x61, 0xC0, 0x70, 0xFD, 0xF8,
- 0x07, 0xC0, 0x00, 0x80, 0x00
-}};
+const image_t img_cc_Joy = {17, 17, false, 37, 0, {0x00, 0x80, 0x01, 0xF0, 0x0F, 0xDF, 0x87, 0x01,
+ 0xC3, 0x00, 0x61, 0x00, 0x11, 0x80, 0x0C, 0xC0,
+ 0x06, 0xC0, 0x01, 0xB0, 0x01, 0x98, 0x00, 0xC4,
+ 0x00, 0x43, 0x00, 0x61, 0xC0, 0x70, 0xFD, 0xF8,
+ 0x07, 0xC0, 0x00, 0x80, 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_Main.c b/applications/plugins/wii_ec_anal/gfx/img_cc_Main.c
index 8e7bd5ed9d..b29a9ab57e 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_Main.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_Main.c
@@ -54,39 +54,47 @@
#include "images.h"
-const image_t img_cc_Main = { 116, 53, true, 542, 0x05, { // orig:769, comp:29.52%
- 0x00, 0x00, 0x00, 0x7F, 0xC0, 0x05, 0x05, 0x00, 0x3F, 0xE0, 0x05, 0x04, 0x00, 0x01, 0xF8, 0x04,
- 0x0F, 0x80, 0x00, 0x00, 0x1F, 0x02, 0x01, 0xF8, 0x05, 0x04, 0x00, 0x60, 0x00, 0x41, 0x04, 0x00,
- 0x60, 0x02, 0x08, 0x20, 0x00, 0x60, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0xF0, 0x7F, 0xFF, 0xFF,
- 0xE0, 0xFE, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x41, 0x04, 0x00, 0x60, 0x02, 0x08,
- 0x20, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x50, 0x03, 0xFC, 0x10, 0x40, 0x06, 0x00, 0x20, 0x83, 0xFC,
- 0x00, 0xA0, 0x00, 0x00, 0x09, 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x3F, 0x09,
- 0x00, 0x00, 0x01, 0x1F, 0x05, 0x09, 0x00, 0x0F, 0x88, 0x00, 0x00, 0x20, 0x05, 0x0A, 0xFF, 0xF0,
- 0x40, 0x00, 0x04, 0x78, 0x05, 0x09, 0x00, 0x01, 0xE2, 0x00, 0x00, 0x9C, 0x05, 0x0A, 0x00, 0x03,
- 0x90, 0x00, 0x13, 0x05, 0x0B, 0x00, 0x0C, 0x80, 0x03, 0xE0, 0x05, 0x0B, 0x00, 0x7C, 0x00, 0x38,
- 0x05, 0x05, 0x00, 0xC6, 0xD8, 0x05, 0x04, 0x00, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0xF0, 0x00, 0x00,
- 0x0D, 0x60, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x60, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xD6,
- 0xD8, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x60, 0x0C, 0x00, 0x18, 0x30, 0x00, 0x00, 0x0D, 0x6D, 0x80,
- 0x00, 0x00, 0x31, 0x80, 0x03, 0x01, 0xC0, 0x01, 0x83, 0x00, 0x00, 0x00, 0x6C, 0xD8, 0x00, 0x00,
- 0x06, 0x0C, 0x00, 0x38, 0x18, 0x00, 0x19, 0x30, 0x05, 0x07, 0x00, 0xCA, 0x60, 0x01, 0x81, 0x00,
- 0x01, 0x93, 0x05, 0x07, 0x00, 0x0C, 0x46, 0x00, 0x0C, 0x30, 0x00, 0x19, 0x30, 0x05, 0x07, 0x00,
- 0xCA, 0x60, 0x00, 0xC2, 0x00, 0xFF, 0x83, 0xFE, 0x05, 0x05, 0x00, 0x07, 0x06, 0x0C, 0x1C, 0x04,
- 0x60, 0x0F, 0xF8, 0x3F, 0xE0, 0x05, 0x05, 0x00, 0xF8, 0x31, 0x83, 0xE0, 0x64, 0x00, 0xC0, 0x00,
- 0x06, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x18, 0xC1, 0xF0, 0x63, 0x02, 0x40, 0x0C, 0x00, 0x00, 0x60,
- 0x01, 0x99, 0x99, 0x98, 0x03, 0x06, 0x0E, 0x0C, 0x98, 0x2C, 0x00, 0xCE, 0x00, 0xE6, 0x00, 0x10,
- 0x90, 0x90, 0x80, 0x65, 0x30, 0x01, 0x94, 0xC3, 0x80, 0x0C, 0x00, 0x00, 0x60, 0x01, 0x09, 0x09,
- 0x08, 0x06, 0x73, 0x00, 0x19, 0xCC, 0x18, 0x00, 0xC0, 0x00, 0x06, 0x00, 0x19, 0x99, 0x99, 0x80,
- 0x61, 0x30, 0x01, 0x94, 0xC1, 0x80, 0x0F, 0xF8, 0x3F, 0xE0, 0x00, 0xF0, 0xF0, 0xF0, 0x03, 0x26,
- 0x0E, 0x0C, 0x18, 0x18, 0x00, 0xFF, 0x83, 0xFE, 0x05, 0x05, 0x00, 0x18, 0xC1, 0xF0, 0x63, 0x01,
- 0x80, 0x00, 0x19, 0x30, 0x05, 0x06, 0x00, 0xF8, 0x31, 0x83, 0xE0, 0x18, 0x00, 0x01, 0x93, 0x05,
- 0x06, 0x00, 0x07, 0x06, 0x8C, 0x1C, 0x01, 0x80, 0x00, 0x19, 0x30, 0x05, 0x07, 0x00, 0xC8, 0x60,
- 0x00, 0x18, 0x00, 0x01, 0x83, 0x05, 0x07, 0x00, 0x0C, 0xC6, 0x00, 0x01, 0x80, 0x00, 0x18, 0x30,
- 0x05, 0x07, 0x00, 0xCA, 0x60, 0x00, 0x1C, 0x00, 0x01, 0xFF, 0x05, 0x07, 0x00, 0x06, 0x6C, 0x00,
- 0x03, 0x40, 0x00, 0x1F, 0xF0, 0x05, 0x07, 0x00, 0x31, 0x80, 0x00, 0x24, 0x05, 0x0A, 0x00, 0x01,
- 0xF0, 0x00, 0x02, 0x60, 0x05, 0x0A, 0x00, 0x0E, 0x00, 0x00, 0x62, 0x05, 0x0D, 0x00, 0x04, 0x20,
- 0x05, 0x0D, 0x00, 0x43, 0x05, 0x0D, 0x00, 0x0C, 0x10, 0x05, 0x0D, 0x00, 0x81, 0x80, 0x05, 0x0C,
- 0x00, 0x18, 0x0C, 0x05, 0x0C, 0x00, 0x03, 0x00, 0x60, 0x05, 0x0C, 0x00, 0x60, 0x03, 0x05, 0x0C,
- 0x00, 0x0C, 0x00, 0x18, 0x05, 0x0B, 0x00, 0x01, 0x80, 0x00, 0xE0, 0x05, 0x0B, 0x00, 0x70, 0x00,
- 0x03, 0x05, 0x0B, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x05, 0x0A, 0x00, 0x03, 0x80, 0x00, 0x00, 0x78,
- 0x05, 0x09, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x05, 0x0A, 0xFF, 0xF0, 0x00, 0x00
-}};
+const image_t img_cc_Main = {
+ 116,
+ 53,
+ true,
+ 542,
+ 0x05,
+ {// orig:769, comp:29.52%
+ 0x00, 0x00, 0x00, 0x7F, 0xC0, 0x05, 0x05, 0x00, 0x3F, 0xE0, 0x05, 0x04, 0x00, 0x01, 0xF8,
+ 0x04, 0x0F, 0x80, 0x00, 0x00, 0x1F, 0x02, 0x01, 0xF8, 0x05, 0x04, 0x00, 0x60, 0x00, 0x41,
+ 0x04, 0x00, 0x60, 0x02, 0x08, 0x20, 0x00, 0x60, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0xF0,
+ 0x7F, 0xFF, 0xFF, 0xE0, 0xFE, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x41, 0x04,
+ 0x00, 0x60, 0x02, 0x08, 0x20, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x50, 0x03, 0xFC, 0x10, 0x40,
+ 0x06, 0x00, 0x20, 0x83, 0xFC, 0x00, 0xA0, 0x00, 0x00, 0x09, 0x0F, 0xC0, 0x00, 0xF8, 0x00,
+ 0x00, 0x01, 0xF0, 0x00, 0x3F, 0x09, 0x00, 0x00, 0x01, 0x1F, 0x05, 0x09, 0x00, 0x0F, 0x88,
+ 0x00, 0x00, 0x20, 0x05, 0x0A, 0xFF, 0xF0, 0x40, 0x00, 0x04, 0x78, 0x05, 0x09, 0x00, 0x01,
+ 0xE2, 0x00, 0x00, 0x9C, 0x05, 0x0A, 0x00, 0x03, 0x90, 0x00, 0x13, 0x05, 0x0B, 0x00, 0x0C,
+ 0x80, 0x03, 0xE0, 0x05, 0x0B, 0x00, 0x7C, 0x00, 0x38, 0x05, 0x05, 0x00, 0xC6, 0xD8, 0x05,
+ 0x04, 0x00, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x0D, 0x60, 0x00, 0x00, 0x00,
+ 0x0E, 0x00, 0x0E, 0x00, 0x60, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xD6, 0xD8, 0x00, 0x00, 0x01,
+ 0xF0, 0x00, 0x60, 0x0C, 0x00, 0x18, 0x30, 0x00, 0x00, 0x0D, 0x6D, 0x80, 0x00, 0x00, 0x31,
+ 0x80, 0x03, 0x01, 0xC0, 0x01, 0x83, 0x00, 0x00, 0x00, 0x6C, 0xD8, 0x00, 0x00, 0x06, 0x0C,
+ 0x00, 0x38, 0x18, 0x00, 0x19, 0x30, 0x05, 0x07, 0x00, 0xCA, 0x60, 0x01, 0x81, 0x00, 0x01,
+ 0x93, 0x05, 0x07, 0x00, 0x0C, 0x46, 0x00, 0x0C, 0x30, 0x00, 0x19, 0x30, 0x05, 0x07, 0x00,
+ 0xCA, 0x60, 0x00, 0xC2, 0x00, 0xFF, 0x83, 0xFE, 0x05, 0x05, 0x00, 0x07, 0x06, 0x0C, 0x1C,
+ 0x04, 0x60, 0x0F, 0xF8, 0x3F, 0xE0, 0x05, 0x05, 0x00, 0xF8, 0x31, 0x83, 0xE0, 0x64, 0x00,
+ 0xC0, 0x00, 0x06, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x18, 0xC1, 0xF0, 0x63, 0x02, 0x40, 0x0C,
+ 0x00, 0x00, 0x60, 0x01, 0x99, 0x99, 0x98, 0x03, 0x06, 0x0E, 0x0C, 0x98, 0x2C, 0x00, 0xCE,
+ 0x00, 0xE6, 0x00, 0x10, 0x90, 0x90, 0x80, 0x65, 0x30, 0x01, 0x94, 0xC3, 0x80, 0x0C, 0x00,
+ 0x00, 0x60, 0x01, 0x09, 0x09, 0x08, 0x06, 0x73, 0x00, 0x19, 0xCC, 0x18, 0x00, 0xC0, 0x00,
+ 0x06, 0x00, 0x19, 0x99, 0x99, 0x80, 0x61, 0x30, 0x01, 0x94, 0xC1, 0x80, 0x0F, 0xF8, 0x3F,
+ 0xE0, 0x00, 0xF0, 0xF0, 0xF0, 0x03, 0x26, 0x0E, 0x0C, 0x18, 0x18, 0x00, 0xFF, 0x83, 0xFE,
+ 0x05, 0x05, 0x00, 0x18, 0xC1, 0xF0, 0x63, 0x01, 0x80, 0x00, 0x19, 0x30, 0x05, 0x06, 0x00,
+ 0xF8, 0x31, 0x83, 0xE0, 0x18, 0x00, 0x01, 0x93, 0x05, 0x06, 0x00, 0x07, 0x06, 0x8C, 0x1C,
+ 0x01, 0x80, 0x00, 0x19, 0x30, 0x05, 0x07, 0x00, 0xC8, 0x60, 0x00, 0x18, 0x00, 0x01, 0x83,
+ 0x05, 0x07, 0x00, 0x0C, 0xC6, 0x00, 0x01, 0x80, 0x00, 0x18, 0x30, 0x05, 0x07, 0x00, 0xCA,
+ 0x60, 0x00, 0x1C, 0x00, 0x01, 0xFF, 0x05, 0x07, 0x00, 0x06, 0x6C, 0x00, 0x03, 0x40, 0x00,
+ 0x1F, 0xF0, 0x05, 0x07, 0x00, 0x31, 0x80, 0x00, 0x24, 0x05, 0x0A, 0x00, 0x01, 0xF0, 0x00,
+ 0x02, 0x60, 0x05, 0x0A, 0x00, 0x0E, 0x00, 0x00, 0x62, 0x05, 0x0D, 0x00, 0x04, 0x20, 0x05,
+ 0x0D, 0x00, 0x43, 0x05, 0x0D, 0x00, 0x0C, 0x10, 0x05, 0x0D, 0x00, 0x81, 0x80, 0x05, 0x0C,
+ 0x00, 0x18, 0x0C, 0x05, 0x0C, 0x00, 0x03, 0x00, 0x60, 0x05, 0x0C, 0x00, 0x60, 0x03, 0x05,
+ 0x0C, 0x00, 0x0C, 0x00, 0x18, 0x05, 0x0B, 0x00, 0x01, 0x80, 0x00, 0xE0, 0x05, 0x0B, 0x00,
+ 0x70, 0x00, 0x03, 0x05, 0x0B, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x05, 0x0A, 0x00, 0x03, 0x80,
+ 0x00, 0x00, 0x78, 0x05, 0x09, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x05, 0x0A, 0xFF, 0xF0,
+ 0x00, 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_btn_A1.c b/applications/plugins/wii_ec_anal/gfx/img_cc_btn_A1.c
index 4d54cbf22b..0889b2a08b 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_btn_A1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_btn_A1.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_cc_btn_A1 = { 7, 7, false, 7, 0, {
- 0xFF, 0xDF, 0x5E, 0x3D, 0x7F, 0xFF, 0x80
-}};
+const image_t img_cc_btn_A1 = {7, 7, false, 7, 0, {0xFF, 0xDF, 0x5E, 0x3D, 0x7F, 0xFF, 0x80}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_btn_B1.c b/applications/plugins/wii_ec_anal/gfx/img_cc_btn_B1.c
index 89d3572823..bbf5fba1a4 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_btn_B1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_btn_B1.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_cc_btn_B1 = { 7, 7, false, 7, 0, {
- 0xFF, 0xBF, 0x7E, 0x7D, 0x7C, 0xFF, 0x80
-}};
+const image_t img_cc_btn_B1 = {7, 7, false, 7, 0, {0xFF, 0xBF, 0x7E, 0x7D, 0x7C, 0xFF, 0x80}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_btn_X1.c b/applications/plugins/wii_ec_anal/gfx/img_cc_btn_X1.c
index a1e7f28766..2352ba695b 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_btn_X1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_btn_X1.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_cc_btn_X1 = { 7, 7, false, 7, 0, {
- 0xFF, 0xFF, 0x5F, 0x7D, 0x7F, 0xFF, 0x80
-}};
+const image_t img_cc_btn_X1 = {7, 7, false, 7, 0, {0xFF, 0xFF, 0x5F, 0x7D, 0x7F, 0xFF, 0x80}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_btn_Y1.c b/applications/plugins/wii_ec_anal/gfx/img_cc_btn_Y1.c
index 01f66b4c7e..d7192e3e72 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_btn_Y1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_btn_Y1.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_cc_btn_Y1 = { 7, 7, false, 7, 0, {
- 0xFF, 0xFF, 0x5E, 0x3F, 0x7D, 0xFF, 0x80
-}};
+const image_t img_cc_btn_Y1 = {7, 7, false, 7, 0, {0xFF, 0xFF, 0x5E, 0x3F, 0x7D, 0xFF, 0x80}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_pad_LR1.c b/applications/plugins/wii_ec_anal/gfx/img_cc_pad_LR1.c
index 698fcfdd6d..300ed5eee9 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_pad_LR1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_pad_LR1.c
@@ -6,6 +6,4 @@
#include "images.h"
-const image_t img_cc_pad_LR1 = { 7, 5, false, 5, 0, {
- 0xFF, 0xFF, 0x1F, 0xFF, 0xE0
-}};
+const image_t img_cc_pad_LR1 = {7, 5, false, 5, 0, {0xFF, 0xFF, 0x1F, 0xFF, 0xE0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_pad_UD1.c b/applications/plugins/wii_ec_anal/gfx/img_cc_pad_UD1.c
index b7d104ee42..feb32d2831 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_pad_UD1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_pad_UD1.c
@@ -8,6 +8,4 @@
#include "images.h"
-const image_t img_cc_pad_UD1 = { 5, 7, false, 5, 0, {
- 0xFF, 0xF7, 0xBD, 0xFF, 0xE0
-}};
+const image_t img_cc_pad_UD1 = {5, 7, false, 5, 0, {0xFF, 0xF7, 0xBD, 0xFF, 0xE0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L1.c b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L1.c
index cf4d7159b7..c70e353347 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L1.c
@@ -7,6 +7,10 @@
#include "images.h"
-const image_t img_cc_trg_L1 = { 17, 6, false, 13, 0, {
- 0x1F, 0xC9, 0x34, 0x92, 0x64, 0x92, 0x54, 0x92, 0x44, 0x93, 0xFC, 0xFE, 0x00
-}};
+const image_t img_cc_trg_L1 = {
+ 17,
+ 6,
+ false,
+ 13,
+ 0,
+ {0x1F, 0xC9, 0x34, 0x92, 0x64, 0x92, 0x54, 0x92, 0x44, 0x93, 0xFC, 0xFE, 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L2.c b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L2.c
index 9e61a64cc8..47561ab98b 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L2.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L2.c
@@ -7,6 +7,22 @@
#include "images.h"
-const image_t img_cc_trg_L2 = { 17, 6, true, 12, 0x01, { // orig:13, comp:7.69%
- 0x1F, 0xD5, 0x35, 0x55, 0x75, 0x01, 0x04, 0x55, 0x57, 0xFD, 0x7E, 0x00
-}};
+const image_t img_cc_trg_L2 = {
+ 17,
+ 6,
+ true,
+ 12,
+ 0x01,
+ {// orig:13, comp:7.69%
+ 0x1F,
+ 0xD5,
+ 0x35,
+ 0x55,
+ 0x75,
+ 0x01,
+ 0x04,
+ 0x55,
+ 0x57,
+ 0xFD,
+ 0x7E,
+ 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L3.c b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L3.c
index 1b06de5eef..0b51bed353 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L3.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L3.c
@@ -7,6 +7,10 @@
#include "images.h"
-const image_t img_cc_trg_L3 = { 17, 6, false, 13, 0, {
- 0x1F, 0xB6, 0xBB, 0x6D, 0xBB, 0x6D, 0xBB, 0x6D, 0xBB, 0x6F, 0xFB, 0x7E, 0x00
-}};
+const image_t img_cc_trg_L3 = {
+ 17,
+ 6,
+ false,
+ 13,
+ 0,
+ {0x1F, 0xB6, 0xBB, 0x6D, 0xBB, 0x6D, 0xBB, 0x6D, 0xBB, 0x6F, 0xFB, 0x7E, 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L4.c b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L4.c
index 12f877ab1b..062caca77d 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L4.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_L4.c
@@ -7,6 +7,18 @@
#include "images.h"
-const image_t img_cc_trg_L4 = { 17, 6, true, 8, 0x01, { // orig:13, comp:38.46%
- 0x1F, 0xFF, 0xBF, 0x01, 0x08, 0xFF, 0xFE, 0x00
-}};
+const image_t img_cc_trg_L4 = {
+ 17,
+ 6,
+ true,
+ 8,
+ 0x01,
+ {// orig:13, comp:38.46%
+ 0x1F,
+ 0xFF,
+ 0xBF,
+ 0x01,
+ 0x08,
+ 0xFF,
+ 0xFE,
+ 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R1.c b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R1.c
index a196c0fe14..6f08886d38 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R1.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R1.c
@@ -7,6 +7,10 @@
#include "images.h"
-const image_t img_cc_trg_R1 = { 17, 6, false, 13, 0, {
- 0x49, 0xFC, 0x49, 0x25, 0x92, 0x49, 0x24, 0x92, 0x5F, 0xE4, 0x90, 0x0F, 0xE4
-}};
+const image_t img_cc_trg_R1 = {
+ 17,
+ 6,
+ false,
+ 13,
+ 0,
+ {0x49, 0xFC, 0x49, 0x25, 0x92, 0x49, 0x24, 0x92, 0x5F, 0xE4, 0x90, 0x0F, 0xE4}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R2.c b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R2.c
index ea5458f391..d85e457618 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R2.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R2.c
@@ -7,6 +7,10 @@
#include "images.h"
-const image_t img_cc_trg_R2 = { 17, 6, false, 13, 0, {
- 0x55, 0xFC, 0x55, 0x55, 0x95, 0x55, 0x75, 0x55, 0x5F, 0xF5, 0x50, 0x0F, 0xD4
-}};
+const image_t img_cc_trg_R2 = {
+ 17,
+ 6,
+ false,
+ 13,
+ 0,
+ {0x55, 0xFC, 0x55, 0x55, 0x95, 0x55, 0x75, 0x55, 0x5F, 0xF5, 0x50, 0x0F, 0xD4}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R3.c b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R3.c
index 94cf02bf05..082d160e23 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R3.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R3.c
@@ -7,6 +7,10 @@
#include "images.h"
-const image_t img_cc_trg_R3 = { 17, 6, false, 13, 0, {
- 0xB6, 0xFC, 0x36, 0xDB, 0xAD, 0xB6, 0xFB, 0x6D, 0xBF, 0xFB, 0x68, 0x0F, 0xD8
-}};
+const image_t img_cc_trg_R3 = {
+ 17,
+ 6,
+ false,
+ 13,
+ 0,
+ {0xB6, 0xFC, 0x36, 0xDB, 0xAD, 0xB6, 0xFB, 0x6D, 0xBF, 0xFB, 0x68, 0x0F, 0xD8}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R4.c b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R4.c
index c90fbe20b6..0395058b83 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R4.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_cc_trg_R4.c
@@ -7,6 +7,21 @@
#include "images.h"
-const image_t img_cc_trg_R4 = { 17, 6, true, 11, 0x00, { // orig:13, comp:15.38%
- 0xFF, 0xFC, 0x7F, 0xFF, 0xBF, 0x00, 0x05, 0xFF, 0xF8, 0x0F, 0xFC
-}};
+const image_t img_cc_trg_R4 = {
+ 17,
+ 6,
+ true,
+ 11,
+ 0x00,
+ {// orig:13, comp:15.38%
+ 0xFF,
+ 0xFC,
+ 0x7F,
+ 0xFF,
+ 0xBF,
+ 0x00,
+ 0x05,
+ 0xFF,
+ 0xF8,
+ 0x0F,
+ 0xFC}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_csLogo_FULL.c b/applications/plugins/wii_ec_anal/gfx/img_csLogo_FULL.c
index 97f09ac17a..a8c030fa22 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_csLogo_FULL.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_csLogo_FULL.c
@@ -41,41 +41,49 @@
#include "images.h"
-const image_t img_csLogo_FULL = { 124, 40, true, 571, 0x0B, { // orig:620, comp:7.90%
- 0x3F, 0xFF, 0xFE, 0x10, 0x43, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x0B, 0x05, 0x00, 0x03, 0xFF, 0xFF,
- 0xE3, 0x8E, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xC0, 0x0B, 0x05, 0x00, 0xFC, 0x00, 0x07, 0x38, 0xE6,
- 0x1C, 0xE3, 0x80, 0x73, 0x8E, 0x03, 0xBB, 0x80, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x52, 0x8A, 0x71,
- 0xCE, 0x39, 0xC7, 0x38, 0xA0, 0x22, 0x10, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x05, 0x28, 0xA7, 0x14,
- 0xA2, 0x9C, 0x52, 0x8A, 0x03, 0x39, 0x00, 0x00, 0x00, 0x0C, 0xC0, 0x00, 0x52, 0x8A, 0x51, 0x4A,
- 0x29, 0x45, 0x28, 0xA0, 0x20, 0x90, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x07, 0x28, 0xA5, 0x14, 0xA2,
- 0x94, 0x52, 0x8E, 0x03, 0xB9, 0x40, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x02, 0x8A, 0x51, 0xCA, 0xA9,
- 0x47, 0x28, 0x0B, 0x06, 0x00, 0xCC, 0x00, 0x00, 0x38, 0xE5, 0xF0, 0xA2, 0x97, 0xC2, 0x80, 0x06,
- 0xEE, 0x80, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x01, 0xFC, 0x5F, 0x0A, 0x29, 0x7C, 0x2B, 0xC0, 0x2A,
- 0xAA, 0x00, 0x00, 0x00, 0xDC, 0x30, 0x00, 0x0D, 0x85, 0x1C, 0xAA, 0x94, 0xE2, 0xBE, 0x02, 0xEE,
- 0xE0, 0x00, 0x00, 0x0E, 0xC0, 0x30, 0x00, 0x50, 0x51, 0x4A, 0x29, 0x4A, 0x28, 0xA0, 0x22, 0xA2,
- 0x00, 0x00, 0x00, 0xDC, 0x04, 0x80, 0x05, 0x05, 0x14, 0xA2, 0x94, 0xA2, 0x8A, 0x07, 0x2E, 0x20,
- 0x00, 0x08, 0x0E, 0xC0, 0x48, 0x00, 0x50, 0x51, 0x4A, 0x29, 0x4A, 0x38, 0xA0, 0x00, 0x00, 0x00,
- 0x01, 0x40, 0xDC, 0x03, 0x00, 0x05, 0x07, 0x1C, 0xE3, 0x94, 0xA3, 0x8A, 0x0B, 0x04, 0x00, 0xE2,
- 0x0C, 0xC0, 0x00, 0x00, 0x70, 0x71, 0xCE, 0x39, 0x4A, 0x30, 0xE0, 0x00, 0x00, 0x00, 0x0C, 0x90,
- 0xCC, 0x00, 0x00, 0x07, 0x03, 0xF8, 0x7F, 0x1C, 0xE1, 0xFC, 0x0B, 0x04, 0x00, 0x94, 0x8C, 0xC0,
- 0x00, 0x00, 0xF8, 0x3F, 0x87, 0xF1, 0xC7, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x72, 0x24, 0xCC, 0x0B,
- 0x0C, 0x00, 0x06, 0x15, 0x2C, 0xC0, 0x0B, 0x0C, 0x00, 0x48, 0x89, 0xCC, 0x00, 0xFE, 0x10, 0x43,
- 0xF8, 0xFF, 0x8F, 0xE1, 0xFC, 0x3F, 0x80, 0x00, 0x39, 0x05, 0x3C, 0xC0, 0x0F, 0xE3, 0x8E, 0x3F,
- 0x8F, 0xF8, 0xFE, 0x1F, 0xC3, 0xF8, 0x00, 0x03, 0x22, 0x27, 0xDC, 0x01, 0x87, 0x38, 0xE6, 0x1C,
- 0xDD, 0x99, 0xF3, 0xFE, 0x61, 0xC0, 0x00, 0x21, 0x50, 0xFE, 0xC0, 0x1C, 0x52, 0x8A, 0x71, 0x41,
- 0x41, 0xC0, 0x3A, 0xE7, 0x14, 0x00, 0x1C, 0x88, 0x9E, 0xDC, 0x01, 0x45, 0x28, 0xA5, 0x14, 0x14,
- 0x14, 0x02, 0xAA, 0x51, 0x40, 0x01, 0x94, 0x13, 0xEE, 0xC0, 0x14, 0x52, 0x8A, 0x51, 0x41, 0x41,
- 0x40, 0x2A, 0xA5, 0x14, 0x00, 0x12, 0x22, 0x7F, 0xDC, 0x01, 0x47, 0x28, 0xA5, 0x1C, 0x14, 0x14,
- 0x02, 0xAA, 0x51, 0xC0, 0x0E, 0x05, 0x0F, 0x3E, 0xC0, 0x1C, 0x02, 0x8A, 0x70, 0x01, 0x41, 0x4E,
- 0x2A, 0xA7, 0x00, 0x00, 0xC0, 0x09, 0xF0, 0xCC, 0x00, 0xFC, 0x38, 0xE3, 0xF0, 0x14, 0x17, 0x82,
- 0xAA, 0x3F, 0x00, 0x09, 0x01, 0x3F, 0x8F, 0xC0, 0x03, 0xE1, 0xFC, 0x0F, 0x81, 0x41, 0x78, 0x2A,
- 0xA0, 0xF8, 0x01, 0x28, 0x27, 0x98, 0xFC, 0x00, 0x07, 0x0D, 0x80, 0x1C, 0x14, 0x14, 0xE2, 0xAA,
- 0x01, 0xC0, 0x28, 0x40, 0xF8, 0x0C, 0xC0, 0x1C, 0x50, 0x50, 0x71, 0x41, 0x41, 0x40, 0x28, 0xA7,
- 0x14, 0x03, 0x02, 0x9F, 0xC0, 0xFC, 0x01, 0x45, 0x05, 0x05, 0x14, 0x14, 0x14, 0x02, 0xAA, 0x51,
- 0x40, 0x32, 0x13, 0xCC, 0x0F, 0xC1, 0x94, 0x50, 0x50, 0x51, 0x41, 0x41, 0x40, 0x28, 0xA5, 0x14,
- 0x01, 0xF2, 0x7C, 0x00, 0xFC, 0x19, 0x47, 0x05, 0x05, 0x1C, 0x14, 0x1C, 0x02, 0x8A, 0x51, 0xC0,
- 0x0E, 0x0F, 0xE0, 0x0F, 0xC1, 0x9C, 0x30, 0x70, 0x70, 0xC1, 0x41, 0x9F, 0x28, 0xA7, 0x0C, 0x00,
- 0x61, 0xE6, 0x00, 0x3F, 0xF8, 0xFE, 0x07, 0x03, 0xF8, 0x1C, 0x0F, 0xE3, 0x8E, 0x3F, 0x80, 0x03,
- 0xBE, 0x00, 0x03, 0xFF, 0x8F, 0xE0, 0xF8, 0x3F, 0x81, 0xC0, 0xFE, 0x38, 0xE3, 0xF8, 0x00, 0x1F,
- 0xF0, 0x0B, 0x0E, 0x00, 0xF3, 0x0B, 0x0E, 0x00, 0x06, 0x00, 0x00
-}};
+const image_t img_csLogo_FULL = {
+ 124,
+ 40,
+ true,
+ 571,
+ 0x0B,
+ {// orig:620, comp:7.90%
+ 0x3F, 0xFF, 0xFE, 0x10, 0x43, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x0B, 0x05, 0x00, 0x03, 0xFF,
+ 0xFF, 0xE3, 0x8E, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xC0, 0x0B, 0x05, 0x00, 0xFC, 0x00, 0x07,
+ 0x38, 0xE6, 0x1C, 0xE3, 0x80, 0x73, 0x8E, 0x03, 0xBB, 0x80, 0x00, 0x00, 0x0F, 0xC0, 0x00,
+ 0x52, 0x8A, 0x71, 0xCE, 0x39, 0xC7, 0x38, 0xA0, 0x22, 0x10, 0x00, 0x00, 0x00, 0xFC, 0x00,
+ 0x05, 0x28, 0xA7, 0x14, 0xA2, 0x9C, 0x52, 0x8A, 0x03, 0x39, 0x00, 0x00, 0x00, 0x0C, 0xC0,
+ 0x00, 0x52, 0x8A, 0x51, 0x4A, 0x29, 0x45, 0x28, 0xA0, 0x20, 0x90, 0x00, 0x00, 0x00, 0xFC,
+ 0x00, 0x07, 0x28, 0xA5, 0x14, 0xA2, 0x94, 0x52, 0x8E, 0x03, 0xB9, 0x40, 0x00, 0x00, 0x0F,
+ 0xC0, 0x00, 0x02, 0x8A, 0x51, 0xCA, 0xA9, 0x47, 0x28, 0x0B, 0x06, 0x00, 0xCC, 0x00, 0x00,
+ 0x38, 0xE5, 0xF0, 0xA2, 0x97, 0xC2, 0x80, 0x06, 0xEE, 0x80, 0x00, 0x00, 0x0E, 0xC3, 0x00,
+ 0x01, 0xFC, 0x5F, 0x0A, 0x29, 0x7C, 0x2B, 0xC0, 0x2A, 0xAA, 0x00, 0x00, 0x00, 0xDC, 0x30,
+ 0x00, 0x0D, 0x85, 0x1C, 0xAA, 0x94, 0xE2, 0xBE, 0x02, 0xEE, 0xE0, 0x00, 0x00, 0x0E, 0xC0,
+ 0x30, 0x00, 0x50, 0x51, 0x4A, 0x29, 0x4A, 0x28, 0xA0, 0x22, 0xA2, 0x00, 0x00, 0x00, 0xDC,
+ 0x04, 0x80, 0x05, 0x05, 0x14, 0xA2, 0x94, 0xA2, 0x8A, 0x07, 0x2E, 0x20, 0x00, 0x08, 0x0E,
+ 0xC0, 0x48, 0x00, 0x50, 0x51, 0x4A, 0x29, 0x4A, 0x38, 0xA0, 0x00, 0x00, 0x00, 0x01, 0x40,
+ 0xDC, 0x03, 0x00, 0x05, 0x07, 0x1C, 0xE3, 0x94, 0xA3, 0x8A, 0x0B, 0x04, 0x00, 0xE2, 0x0C,
+ 0xC0, 0x00, 0x00, 0x70, 0x71, 0xCE, 0x39, 0x4A, 0x30, 0xE0, 0x00, 0x00, 0x00, 0x0C, 0x90,
+ 0xCC, 0x00, 0x00, 0x07, 0x03, 0xF8, 0x7F, 0x1C, 0xE1, 0xFC, 0x0B, 0x04, 0x00, 0x94, 0x8C,
+ 0xC0, 0x00, 0x00, 0xF8, 0x3F, 0x87, 0xF1, 0xC7, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x72, 0x24,
+ 0xCC, 0x0B, 0x0C, 0x00, 0x06, 0x15, 0x2C, 0xC0, 0x0B, 0x0C, 0x00, 0x48, 0x89, 0xCC, 0x00,
+ 0xFE, 0x10, 0x43, 0xF8, 0xFF, 0x8F, 0xE1, 0xFC, 0x3F, 0x80, 0x00, 0x39, 0x05, 0x3C, 0xC0,
+ 0x0F, 0xE3, 0x8E, 0x3F, 0x8F, 0xF8, 0xFE, 0x1F, 0xC3, 0xF8, 0x00, 0x03, 0x22, 0x27, 0xDC,
+ 0x01, 0x87, 0x38, 0xE6, 0x1C, 0xDD, 0x99, 0xF3, 0xFE, 0x61, 0xC0, 0x00, 0x21, 0x50, 0xFE,
+ 0xC0, 0x1C, 0x52, 0x8A, 0x71, 0x41, 0x41, 0xC0, 0x3A, 0xE7, 0x14, 0x00, 0x1C, 0x88, 0x9E,
+ 0xDC, 0x01, 0x45, 0x28, 0xA5, 0x14, 0x14, 0x14, 0x02, 0xAA, 0x51, 0x40, 0x01, 0x94, 0x13,
+ 0xEE, 0xC0, 0x14, 0x52, 0x8A, 0x51, 0x41, 0x41, 0x40, 0x2A, 0xA5, 0x14, 0x00, 0x12, 0x22,
+ 0x7F, 0xDC, 0x01, 0x47, 0x28, 0xA5, 0x1C, 0x14, 0x14, 0x02, 0xAA, 0x51, 0xC0, 0x0E, 0x05,
+ 0x0F, 0x3E, 0xC0, 0x1C, 0x02, 0x8A, 0x70, 0x01, 0x41, 0x4E, 0x2A, 0xA7, 0x00, 0x00, 0xC0,
+ 0x09, 0xF0, 0xCC, 0x00, 0xFC, 0x38, 0xE3, 0xF0, 0x14, 0x17, 0x82, 0xAA, 0x3F, 0x00, 0x09,
+ 0x01, 0x3F, 0x8F, 0xC0, 0x03, 0xE1, 0xFC, 0x0F, 0x81, 0x41, 0x78, 0x2A, 0xA0, 0xF8, 0x01,
+ 0x28, 0x27, 0x98, 0xFC, 0x00, 0x07, 0x0D, 0x80, 0x1C, 0x14, 0x14, 0xE2, 0xAA, 0x01, 0xC0,
+ 0x28, 0x40, 0xF8, 0x0C, 0xC0, 0x1C, 0x50, 0x50, 0x71, 0x41, 0x41, 0x40, 0x28, 0xA7, 0x14,
+ 0x03, 0x02, 0x9F, 0xC0, 0xFC, 0x01, 0x45, 0x05, 0x05, 0x14, 0x14, 0x14, 0x02, 0xAA, 0x51,
+ 0x40, 0x32, 0x13, 0xCC, 0x0F, 0xC1, 0x94, 0x50, 0x50, 0x51, 0x41, 0x41, 0x40, 0x28, 0xA5,
+ 0x14, 0x01, 0xF2, 0x7C, 0x00, 0xFC, 0x19, 0x47, 0x05, 0x05, 0x1C, 0x14, 0x1C, 0x02, 0x8A,
+ 0x51, 0xC0, 0x0E, 0x0F, 0xE0, 0x0F, 0xC1, 0x9C, 0x30, 0x70, 0x70, 0xC1, 0x41, 0x9F, 0x28,
+ 0xA7, 0x0C, 0x00, 0x61, 0xE6, 0x00, 0x3F, 0xF8, 0xFE, 0x07, 0x03, 0xF8, 0x1C, 0x0F, 0xE3,
+ 0x8E, 0x3F, 0x80, 0x03, 0xBE, 0x00, 0x03, 0xFF, 0x8F, 0xE0, 0xF8, 0x3F, 0x81, 0xC0, 0xFE,
+ 0x38, 0xE3, 0xF8, 0x00, 0x1F, 0xF0, 0x0B, 0x0E, 0x00, 0xF3, 0x0B, 0x0E, 0x00, 0x06, 0x00,
+ 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_csLogo_Small.c b/applications/plugins/wii_ec_anal/gfx/img_csLogo_Small.c
index 5cd2f613f6..71debc2ff5 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_csLogo_Small.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_csLogo_Small.c
@@ -13,6 +13,10 @@
#include "images.h"
-const image_t img_csLogo_Small = { 9, 12, false, 14, 0, {
- 0xFF, 0xFF, 0xF0, 0x78, 0x3D, 0x06, 0x3F, 0x13, 0x88, 0xC7, 0xE0, 0x7D, 0x3E, 0xF0
-}};
+const image_t img_csLogo_Small = {
+ 9,
+ 12,
+ false,
+ 14,
+ 0,
+ {0xFF, 0xFF, 0xF0, 0x78, 0x3D, 0x06, 0x3F, 0x13, 0x88, 0xC7, 0xE0, 0x7D, 0x3E, 0xF0}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_ecp_SCL.c b/applications/plugins/wii_ec_anal/gfx/img_ecp_SCL.c
index 533b79c7b9..e3622a6266 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_ecp_SCL.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_ecp_SCL.c
@@ -8,6 +8,10 @@
#include "images.h"
-const image_t img_ecp_SCL = { 16, 7, false, 14, 0, {
- 0x3F, 0x8F, 0x3F, 0x8F, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0xF1, 0xFC, 0xF1, 0xFC
-}};
+const image_t img_ecp_SCL = {
+ 16,
+ 7,
+ false,
+ 14,
+ 0,
+ {0x3F, 0x8F, 0x3F, 0x8F, 0x31, 0x8C, 0x31, 0x8C, 0x31, 0x8C, 0xF1, 0xFC, 0xF1, 0xFC}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_ecp_SDA.c b/applications/plugins/wii_ec_anal/gfx/img_ecp_SDA.c
index 7384fc87cc..5ce0cbec4c 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_ecp_SDA.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_ecp_SDA.c
@@ -13,7 +13,7 @@
#include "images.h"
-const image_t img_ecp_SDA = { 17, 12, false, 26, 0, {
- 0x10, 0x00, 0x18, 0x00, 0x18, 0x00, 0x1F, 0xFC, 0x0F, 0xFE, 0x43, 0x00, 0x30, 0xC0, 0x0C, 0x27,
- 0xFF, 0x03, 0xFF, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x80
-}};
+const image_t img_ecp_SDA = {17, 12, false, 26, 0, {0x10, 0x00, 0x18, 0x00, 0x18, 0x00, 0x1F,
+ 0xFC, 0x0F, 0xFE, 0x43, 0x00, 0x30, 0xC0,
+ 0x0C, 0x27, 0xFF, 0x03, 0xFF, 0x80, 0x01,
+ 0x80, 0x01, 0x80, 0x00, 0x80}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_ecp_port.c b/applications/plugins/wii_ec_anal/gfx/img_ecp_port.c
index 942f0c5934..60f535458d 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_ecp_port.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_ecp_port.c
@@ -43,24 +43,30 @@
#include "images.h"
-const image_t img_ecp_port = { 69, 42, true, 290, 0x04, { // orig:363, comp:20.11%
- 0x00, 0x2A, 0x04, 0x06, 0xAA, 0xA8, 0x02, 0x04, 0x07, 0xAA, 0x80, 0x2A, 0x04, 0x07, 0xAA, 0x02,
- 0x04, 0x07, 0xAA, 0xA0, 0x2A, 0x04, 0x07, 0xAA, 0x82, 0x04, 0x07, 0xAA, 0xA8, 0x2A, 0x04, 0x07,
- 0xAA, 0xA3, 0x04, 0x07, 0xFF, 0xAA, 0x1F, 0x04, 0x06, 0xFF, 0xFE, 0xA8, 0xC0, 0x04, 0x06, 0x00,
- 0x6A, 0x86, 0x04, 0x06, 0x00, 0x03, 0xAA, 0x30, 0x04, 0x06, 0x00, 0x1A, 0xA1, 0x80, 0x04, 0x06,
- 0x00, 0xEA, 0x8C, 0x04, 0x06, 0x00, 0x06, 0xA8, 0x61, 0x04, 0x05, 0xFF, 0xFC, 0x3A, 0xA3, 0x0F,
- 0x04, 0x05, 0xFF, 0xE1, 0xAA, 0x18, 0x61, 0x83, 0x0C, 0x18, 0x60, 0xC3, 0x0E, 0xA8, 0xC3, 0x0C,
- 0x18, 0x60, 0xC3, 0x06, 0x18, 0x6A, 0x86, 0x18, 0x7F, 0xC3, 0xFE, 0x1F, 0xF0, 0xC3, 0xAA, 0x30,
- 0xC3, 0xFE, 0x1F, 0xF0, 0xFF, 0x86, 0x1A, 0xA1, 0x86, 0x04, 0x05, 0x00, 0x30, 0xEA, 0xBC, 0x30,
- 0x04, 0x04, 0x00, 0x01, 0x86, 0xFB, 0xE1, 0x80, 0x04, 0x04, 0x00, 0x0C, 0x3F, 0xFF, 0x0C, 0x04,
- 0x05, 0x00, 0x61, 0xBE, 0x78, 0x60, 0x04, 0x04, 0x00, 0x03, 0x0F, 0xF8, 0xC3, 0x0F, 0xF8, 0x00,
- 0x03, 0xFE, 0x18, 0x6A, 0x86, 0x18, 0x7F, 0xC0, 0x00, 0x1F, 0xF0, 0xC3, 0xAA, 0x30, 0xC3, 0x06,
- 0x1F, 0xF0, 0xC1, 0x86, 0x1A, 0xA1, 0x86, 0x18, 0x30, 0x80, 0x86, 0x0C, 0x30, 0xEA, 0x8C, 0x3F,
- 0x04, 0x05, 0xFF, 0x86, 0xA8, 0x61, 0x04, 0x05, 0xFF, 0xFC, 0x3A, 0xA3, 0x04, 0x06, 0x00, 0x01,
- 0xAA, 0x18, 0x04, 0x06, 0x00, 0x0E, 0xA8, 0xC0, 0x04, 0x06, 0x00, 0x6A, 0x86, 0x00, 0x00, 0x7F,
- 0xFF, 0xF0, 0x00, 0x03, 0xAA, 0x30, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x1A, 0xA1, 0x80, 0x00,
- 0x1A, 0xA0, 0x0C, 0x00, 0x00, 0xEA, 0x0C, 0x00, 0x00, 0xEA, 0x00, 0x60, 0x00, 0x06, 0xA0, 0x60,
- 0x00, 0x06, 0xA0, 0x03, 0x00, 0x00, 0x3A, 0x03, 0x00, 0x00, 0x3A, 0x00, 0x18, 0x00, 0x01, 0xA0,
- 0x1F, 0xFF, 0xFF, 0xA0, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF,
- 0xE0, 0x00
-}};
+const image_t img_ecp_port = {
+ 69,
+ 42,
+ true,
+ 290,
+ 0x04,
+ {// orig:363, comp:20.11%
+ 0x00, 0x2A, 0x04, 0x06, 0xAA, 0xA8, 0x02, 0x04, 0x07, 0xAA, 0x80, 0x2A, 0x04, 0x07, 0xAA,
+ 0x02, 0x04, 0x07, 0xAA, 0xA0, 0x2A, 0x04, 0x07, 0xAA, 0x82, 0x04, 0x07, 0xAA, 0xA8, 0x2A,
+ 0x04, 0x07, 0xAA, 0xA3, 0x04, 0x07, 0xFF, 0xAA, 0x1F, 0x04, 0x06, 0xFF, 0xFE, 0xA8, 0xC0,
+ 0x04, 0x06, 0x00, 0x6A, 0x86, 0x04, 0x06, 0x00, 0x03, 0xAA, 0x30, 0x04, 0x06, 0x00, 0x1A,
+ 0xA1, 0x80, 0x04, 0x06, 0x00, 0xEA, 0x8C, 0x04, 0x06, 0x00, 0x06, 0xA8, 0x61, 0x04, 0x05,
+ 0xFF, 0xFC, 0x3A, 0xA3, 0x0F, 0x04, 0x05, 0xFF, 0xE1, 0xAA, 0x18, 0x61, 0x83, 0x0C, 0x18,
+ 0x60, 0xC3, 0x0E, 0xA8, 0xC3, 0x0C, 0x18, 0x60, 0xC3, 0x06, 0x18, 0x6A, 0x86, 0x18, 0x7F,
+ 0xC3, 0xFE, 0x1F, 0xF0, 0xC3, 0xAA, 0x30, 0xC3, 0xFE, 0x1F, 0xF0, 0xFF, 0x86, 0x1A, 0xA1,
+ 0x86, 0x04, 0x05, 0x00, 0x30, 0xEA, 0xBC, 0x30, 0x04, 0x04, 0x00, 0x01, 0x86, 0xFB, 0xE1,
+ 0x80, 0x04, 0x04, 0x00, 0x0C, 0x3F, 0xFF, 0x0C, 0x04, 0x05, 0x00, 0x61, 0xBE, 0x78, 0x60,
+ 0x04, 0x04, 0x00, 0x03, 0x0F, 0xF8, 0xC3, 0x0F, 0xF8, 0x00, 0x03, 0xFE, 0x18, 0x6A, 0x86,
+ 0x18, 0x7F, 0xC0, 0x00, 0x1F, 0xF0, 0xC3, 0xAA, 0x30, 0xC3, 0x06, 0x1F, 0xF0, 0xC1, 0x86,
+ 0x1A, 0xA1, 0x86, 0x18, 0x30, 0x80, 0x86, 0x0C, 0x30, 0xEA, 0x8C, 0x3F, 0x04, 0x05, 0xFF,
+ 0x86, 0xA8, 0x61, 0x04, 0x05, 0xFF, 0xFC, 0x3A, 0xA3, 0x04, 0x06, 0x00, 0x01, 0xAA, 0x18,
+ 0x04, 0x06, 0x00, 0x0E, 0xA8, 0xC0, 0x04, 0x06, 0x00, 0x6A, 0x86, 0x00, 0x00, 0x7F, 0xFF,
+ 0xF0, 0x00, 0x03, 0xAA, 0x30, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x1A, 0xA1, 0x80, 0x00,
+ 0x1A, 0xA0, 0x0C, 0x00, 0x00, 0xEA, 0x0C, 0x00, 0x00, 0xEA, 0x00, 0x60, 0x00, 0x06, 0xA0,
+ 0x60, 0x00, 0x06, 0xA0, 0x03, 0x00, 0x00, 0x3A, 0x03, 0x00, 0x00, 0x3A, 0x00, 0x18, 0x00,
+ 0x01, 0xA0, 0x1F, 0xFF, 0xFF, 0xA0, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFE, 0x00,
+ 0x07, 0xFF, 0xFF, 0xE0, 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_key_Back.c b/applications/plugins/wii_ec_anal/gfx/img_key_Back.c
index d13bcf7f2d..23c17fe2ba 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_key_Back.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_key_Back.c
@@ -10,6 +10,5 @@
#include "images.h"
-const image_t img_key_Back = { 9, 9, false, 11, 0, {
- 0x7F, 0x7F, 0xFB, 0xF8, 0x7E, 0xDF, 0xEF, 0xCF, 0xFF, 0x3F, 0x00
-}};
+const image_t img_key_Back =
+ {9, 9, false, 11, 0, {0x7F, 0x7F, 0xFB, 0xF8, 0x7E, 0xDF, 0xEF, 0xCF, 0xFF, 0x3F, 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_key_D.c b/applications/plugins/wii_ec_anal/gfx/img_key_D.c
index 8d182427c4..689b9148c4 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_key_D.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_key_D.c
@@ -9,6 +9,5 @@
#include "images.h"
-const image_t img_key_D = { 9, 8, false, 9, 0, {
- 0x7F, 0x7F, 0xFF, 0xF8, 0x3E, 0x3F, 0xBF, 0xFE, 0xFE
-}};
+const image_t img_key_D =
+ {9, 8, false, 9, 0, {0x7F, 0x7F, 0xFF, 0xF8, 0x3E, 0x3F, 0xBF, 0xFE, 0xFE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_key_L.c b/applications/plugins/wii_ec_anal/gfx/img_key_L.c
index 1fc5556b1d..a5fca1a21f 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_key_L.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_key_L.c
@@ -10,6 +10,5 @@
#include "images.h"
-const image_t img_key_L = { 8, 9, false, 9, 0, {
- 0x7E, 0xFF, 0xF7, 0xE7, 0xC7, 0xE7, 0xF7, 0xFF, 0x7E
-}};
+const image_t img_key_L =
+ {8, 9, false, 9, 0, {0x7E, 0xFF, 0xF7, 0xE7, 0xC7, 0xE7, 0xF7, 0xFF, 0x7E}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_key_OK.c b/applications/plugins/wii_ec_anal/gfx/img_key_OK.c
index ef64128f85..926d91c2e1 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_key_OK.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_key_OK.c
@@ -10,6 +10,5 @@
#include "images.h"
-const image_t img_key_OK = { 9, 9, false, 11, 0, {
- 0x7F, 0x7F, 0xF8, 0xF8, 0x3C, 0x1E, 0x0F, 0x8F, 0xFF, 0x3F, 0x00
-}};
+const image_t img_key_OK =
+ {9, 9, false, 11, 0, {0x7F, 0x7F, 0xF8, 0xF8, 0x3C, 0x1E, 0x0F, 0x8F, 0xFF, 0x3F, 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_key_OKi.c b/applications/plugins/wii_ec_anal/gfx/img_key_OKi.c
index 595f2f4317..aa6f9e6921 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_key_OKi.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_key_OKi.c
@@ -10,6 +10,5 @@
#include "images.h"
-const image_t img_key_OKi = { 9, 9, false, 11, 0, {
- 0x7F, 0x60, 0xE7, 0x37, 0xDB, 0xED, 0xF6, 0x73, 0x83, 0x7F, 0x00
-}};
+const image_t img_key_OKi =
+ {9, 9, false, 11, 0, {0x7F, 0x60, 0xE7, 0x37, 0xDB, 0xED, 0xF6, 0x73, 0x83, 0x7F, 0x00}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_key_R.c b/applications/plugins/wii_ec_anal/gfx/img_key_R.c
index 87cc385bc6..8b97c7b483 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_key_R.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_key_R.c
@@ -10,6 +10,5 @@
#include "images.h"
-const image_t img_key_R = { 8, 9, false, 9, 0, {
- 0x7E, 0xFF, 0xEF, 0xE7, 0xE3, 0xE7, 0xEF, 0xFF, 0x7E
-}};
+const image_t img_key_R =
+ {8, 9, false, 9, 0, {0x7E, 0xFF, 0xEF, 0xE7, 0xE3, 0xE7, 0xEF, 0xFF, 0x7E}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_key_U.c b/applications/plugins/wii_ec_anal/gfx/img_key_U.c
index aca5bb62a7..65f4cd9e0e 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_key_U.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_key_U.c
@@ -9,6 +9,5 @@
#include "images.h"
-const image_t img_key_U = { 9, 8, false, 9, 0, {
- 0x7F, 0x7F, 0xFD, 0xFC, 0x7C, 0x1F, 0xFF, 0xFE, 0xFE
-}};
+const image_t img_key_U =
+ {9, 8, false, 9, 0, {0x7F, 0x7F, 0xFD, 0xFC, 0x7C, 0x1F, 0xFF, 0xFE, 0xFE}};
diff --git a/applications/plugins/wii_ec_anal/gfx/img_key_Ui.c b/applications/plugins/wii_ec_anal/gfx/img_key_Ui.c
index b740780adf..30c60c66e4 100644
--- a/applications/plugins/wii_ec_anal/gfx/img_key_Ui.c
+++ b/applications/plugins/wii_ec_anal/gfx/img_key_Ui.c
@@ -9,6 +9,5 @@
#include "images.h"
-const image_t img_key_Ui = { 9, 8, false, 9, 0, {
- 0x7F, 0x60, 0xE2, 0x33, 0x9B, 0xEC, 0x07, 0x06, 0xFE
-}};
+const image_t img_key_Ui =
+ {9, 8, false, 9, 0, {0x7F, 0x60, 0xE2, 0x33, 0x9B, 0xEC, 0x07, 0x06, 0xFE}};
diff --git a/applications/plugins/wii_ec_anal/i2c_workaround.h b/applications/plugins/wii_ec_anal/i2c_workaround.h
index de1dbba540..b24efaf484 100644
--- a/applications/plugins/wii_ec_anal/i2c_workaround.h
+++ b/applications/plugins/wii_ec_anal/i2c_workaround.h
@@ -40,62 +40,70 @@ void furi_hal_i2c_release (FuriHalI2cBusHandle* handle)
*/
-#ifndef I2C_WORKAROUND_H_
-#define I2C_WORKAROUND_H_
+#ifndef I2C_WORKAROUND_H_
+#define I2C_WORKAROUND_H_
-#include
+#include
#define ENABLE_WORKAROUND 1
#if ENABLE_WORKAROUND == 1
- //+============================================================================ ========================================
- static inline
- bool furi_hal_Wi2c_is_device_ready (FuriHalI2cBusHandle* const bus, const uint8_t addr, const uint32_t tmo)
- {
- furi_hal_i2c_acquire(bus);
- bool rv = furi_hal_i2c_is_device_ready(bus, addr, tmo);
- furi_hal_i2c_release(bus);
- return rv;
- }
-
- //+============================================================================
- static inline
- bool furi_hal_Wi2c_tx ( FuriHalI2cBusHandle* const bus, const uint8_t addr,
- const void* buf, const size_t len, const uint32_t tmo )
- {
- furi_hal_i2c_acquire(bus);
- bool rv = furi_hal_i2c_tx(bus, addr, buf, len, tmo);
- furi_hal_i2c_release(bus);
- return rv;
- }
-
- //+============================================================================
- static inline
- bool furi_hal_Wi2c_rx ( FuriHalI2cBusHandle* const bus, const uint8_t addr,
- void* buf, const size_t len, const uint32_t tmo )
- {
- furi_hal_i2c_acquire(bus);
- bool rv = furi_hal_i2c_rx(bus, addr, buf, len, tmo);
- furi_hal_i2c_release(bus);
- return rv;
- }
-
- //+============================================================================
- static inline
- bool furi_hal_Wi2c_trx ( FuriHalI2cBusHandle* const bus, const uint8_t addr,
- const void* tx, const size_t txlen,
- void* rx, const size_t rxlen, const uint32_t tmo )
- {
- bool rv = furi_hal_Wi2c_tx(bus, addr, tx, txlen, tmo);
- if (rv) rv = furi_hal_Wi2c_rx(bus, addr, rx, rxlen, tmo);
- return rv;
- }
-
- //----------------------------------------------------------------------------- ----------------------------------------
-# define furi_hal_i2c_is_device_ready(...) furi_hal_Wi2c_is_device_ready(__VA_ARGS__)
-# define furi_hal_i2c_tx(...) furi_hal_Wi2c_tx(__VA_ARGS__)
-# define furi_hal_i2c_rx(...) furi_hal_Wi2c_rx(__VA_ARGS__)
-# define furi_hal_i2c_trx(...) furi_hal_Wi2c_trx(__VA_ARGS__)
+//+============================================================================ ========================================
+static inline bool furi_hal_Wi2c_is_device_ready(
+ FuriHalI2cBusHandle* const bus,
+ const uint8_t addr,
+ const uint32_t tmo) {
+ furi_hal_i2c_acquire(bus);
+ bool rv = furi_hal_i2c_is_device_ready(bus, addr, tmo);
+ furi_hal_i2c_release(bus);
+ return rv;
+}
+
+//+============================================================================
+static inline bool furi_hal_Wi2c_tx(
+ FuriHalI2cBusHandle* const bus,
+ const uint8_t addr,
+ const void* buf,
+ const size_t len,
+ const uint32_t tmo) {
+ furi_hal_i2c_acquire(bus);
+ bool rv = furi_hal_i2c_tx(bus, addr, buf, len, tmo);
+ furi_hal_i2c_release(bus);
+ return rv;
+}
+
+//+============================================================================
+static inline bool furi_hal_Wi2c_rx(
+ FuriHalI2cBusHandle* const bus,
+ const uint8_t addr,
+ void* buf,
+ const size_t len,
+ const uint32_t tmo) {
+ furi_hal_i2c_acquire(bus);
+ bool rv = furi_hal_i2c_rx(bus, addr, buf, len, tmo);
+ furi_hal_i2c_release(bus);
+ return rv;
+}
+
+//+============================================================================
+static inline bool furi_hal_Wi2c_trx(
+ FuriHalI2cBusHandle* const bus,
+ const uint8_t addr,
+ const void* tx,
+ const size_t txlen,
+ void* rx,
+ const size_t rxlen,
+ const uint32_t tmo) {
+ bool rv = furi_hal_Wi2c_tx(bus, addr, tx, txlen, tmo);
+ if(rv) rv = furi_hal_Wi2c_rx(bus, addr, rx, rxlen, tmo);
+ return rv;
+}
+
+//----------------------------------------------------------------------------- ----------------------------------------
+#define furi_hal_i2c_is_device_ready(...) furi_hal_Wi2c_is_device_ready(__VA_ARGS__)
+#define furi_hal_i2c_tx(...) furi_hal_Wi2c_tx(__VA_ARGS__)
+#define furi_hal_i2c_rx(...) furi_hal_Wi2c_rx(__VA_ARGS__)
+#define furi_hal_i2c_trx(...) furi_hal_Wi2c_trx(__VA_ARGS__)
#endif //ENABLE_WORKAROUND
@@ -103,17 +111,21 @@ void furi_hal_i2c_release (FuriHalI2cBusHandle* handle)
// Some devices take a moment to respond to read requests
// The puts a delay between the address being set and the data being read
//
-static inline
-bool furi_hal_i2c_trxd ( FuriHalI2cBusHandle* const bus, const uint8_t addr,
- const void* tx, const size_t txlen,
- void* rx, const size_t rxlen, const uint32_t tmo, const uint32_t us )
-{
- bool rv = furi_hal_i2c_tx(bus, addr, tx, txlen, tmo);
- if (rv) {
- furi_delay_us(us);
- rv = furi_hal_i2c_rx(bus, addr, rx, rxlen, tmo);
- }
- return rv;
+static inline bool furi_hal_i2c_trxd(
+ FuriHalI2cBusHandle* const bus,
+ const uint8_t addr,
+ const void* tx,
+ const size_t txlen,
+ void* rx,
+ const size_t rxlen,
+ const uint32_t tmo,
+ const uint32_t us) {
+ bool rv = furi_hal_i2c_tx(bus, addr, tx, txlen, tmo);
+ if(rv) {
+ furi_delay_us(us);
+ rv = furi_hal_i2c_rx(bus, addr, rx, rxlen, tmo);
+ }
+ return rv;
}
#endif //I2C_WORKAROUND_H_
diff --git a/applications/plugins/wii_ec_anal/wii_anal.c b/applications/plugins/wii_ec_anal/wii_anal.c
index fdf718b634..f0af1c9c5a 100644
--- a/applications/plugins/wii_ec_anal/wii_anal.c
+++ b/applications/plugins/wii_ec_anal/wii_anal.c
@@ -3,34 +3,34 @@
//
// System libs
-#include // malloc
-#include // uint32_t
-#include // __VA_ARGS__
-#include
-#include
+#include // malloc
+#include // uint32_t
+#include // __VA_ARGS__
+#include
+#include
// FlipperZero libs
-#include // Core API
-#include // GUI (screen/keyboard) API
-#include // GUI Input extensions
-#include
+#include // Core API
+#include // GUI (screen/keyboard) API
+#include // GUI Input extensions
+#include
// Do this first!
#define ERR_C_ // Do this in precisely ONE file
-#include "err.h" // Error numbers & messages
+#include "err.h" // Error numbers & messages
-#include "bc_logging.h"
+#include "bc_logging.h"
// Local headers
-#include "wii_anal.h" // Various enums and struct declarations
-#include "wii_i2c.h" // Wii i2c functions
-#include "wii_ec.h" // Wii Extension Controller functions (eg. draw)
-#include "wii_anal_keys.h" // key mappings
-#include "gfx/images.h" // Images
-#include "wii_anal_lcd.h" // Drawing functions
-#include "wii_anal_ec.h" // Wii controller events
+#include "wii_anal.h" // Various enums and struct declarations
+#include "wii_i2c.h" // Wii i2c functions
+#include "wii_ec.h" // Wii Extension Controller functions (eg. draw)
+#include "wii_anal_keys.h" // key mappings
+#include "gfx/images.h" // Images
+#include "wii_anal_lcd.h" // Drawing functions
+#include "wii_anal_ec.h" // Wii controller events
-#include "wii_anal_ver.h" // Version number
+#include "wii_anal_ver.h" // Version number
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OOOOO // SSSSS CCCCC AAA L L BBBB AAA CCCC K K SSSSS
@@ -44,48 +44,42 @@
// OS Callback : Timer tick
// We register this function to be called when the OS signals a timer 'tick' event
//
-static
-void cbTimer (FuriMessageQueue* queue)
-{
- ENTER;
- furi_assert(queue);
+static void cbTimer(FuriMessageQueue* queue) {
+ ENTER;
+ furi_assert(queue);
- eventMsg_t message = {.id = EVID_TICK};
- furi_message_queue_put(queue, &message, 0);
+ eventMsg_t message = {.id = EVID_TICK};
+ furi_message_queue_put(queue, &message, 0);
- LEAVE;
- return;
+ LEAVE;
+ return;
}
//+============================================================================ ========================================
// OS Callback : Keypress
// We register this function to be called when the OS detects a keypress
//
-static
-void cbInput (InputEvent* event, FuriMessageQueue* queue)
-{
- ENTER;
- furi_assert(queue);
- furi_assert(event);
-
- // Put an "input" event message on the message queue
- eventMsg_t message = {.id = EVID_KEY, .input = *event};
- furi_message_queue_put(queue, &message, FuriWaitForever);
-
- LEAVE;
- return;
+static void cbInput(InputEvent* event, FuriMessageQueue* queue) {
+ ENTER;
+ furi_assert(queue);
+ furi_assert(event);
+
+ // Put an "input" event message on the message queue
+ eventMsg_t message = {.id = EVID_KEY, .input = *event};
+ furi_message_queue_put(queue, &message, FuriWaitForever);
+
+ LEAVE;
+ return;
}
//+============================================================================
// Show version number
//
-static
-void showVer (Canvas* const canvas)
-{
- show(canvas, 0,59, &img_3x5_v, SHOW_SET_BLK);
- show(canvas, 4,59, VER_MAJ, SHOW_SET_BLK);
- canvas_draw_frame(canvas, 8,62, 2,2);
- show(canvas, 11,59, VER_MIN, SHOW_SET_BLK);
+static void showVer(Canvas* const canvas) {
+ show(canvas, 0, 59, &img_3x5_v, SHOW_SET_BLK);
+ show(canvas, 4, 59, VER_MAJ, SHOW_SET_BLK);
+ canvas_draw_frame(canvas, 8, 62, 2, 2);
+ show(canvas, 11, 59, VER_MIN, SHOW_SET_BLK);
}
//+============================================================================
@@ -95,105 +89,103 @@ void showVer (Canvas* const canvas)
// We actually instruct the OS to perform this request, after we update the interface
// I guess it's possible that this instruction may able be issued by other threads !?
//
-static
-void cbDraw (Canvas* const canvas, void* ctx)
-{
- ENTER;
- furi_assert(canvas);
- furi_assert(ctx);
+static void cbDraw(Canvas* const canvas, void* ctx) {
+ ENTER;
+ furi_assert(canvas);
+ furi_assert(ctx);
- state_t* state = NULL;
+ state_t* state = NULL;
- // Try to acquire the mutex for the plugin state variables, timeout = 25mS
- if ( !(state = (state_t*)acquire_mutex((ValueMutex*)ctx, 25)) ) return ;
+ // Try to acquire the mutex for the plugin state variables, timeout = 25mS
+ if(!(state = (state_t*)acquire_mutex((ValueMutex*)ctx, 25))) return;
- switch (state->scene) {
- //---------------------------------------------------------------------
- case SCENE_SPLASH:
- show(canvas, 2,0, &img_csLogo_FULL, SHOW_SET_BLK);
+ switch(state->scene) {
+ //---------------------------------------------------------------------
+ case SCENE_SPLASH:
+ show(canvas, 2, 0, &img_csLogo_FULL, SHOW_SET_BLK);
- canvas_set_font(canvas, FontSecondary);
- canvas_draw_str_aligned(canvas, 64,43, AlignCenter, AlignTop, "Wii Extension Controller");
- canvas_draw_str_aligned(canvas, 64,55, AlignCenter, AlignTop, "Protocol Analyser");
+ canvas_set_font(canvas, FontSecondary);
+ canvas_draw_str_aligned(canvas, 64, 43, AlignCenter, AlignTop, "Wii Extension Controller");
+ canvas_draw_str_aligned(canvas, 64, 55, AlignCenter, AlignTop, "Protocol Analyser");
- showVer(canvas);
+ showVer(canvas);
- break;
+ break;
- //---------------------------------------------------------------------
- case SCENE_RIP:
- show(canvas, 0,0, &img_RIP, SHOW_SET_BLK);
- break;
+ //---------------------------------------------------------------------
+ case SCENE_RIP:
+ show(canvas, 0, 0, &img_RIP, SHOW_SET_BLK);
+ break;
- //---------------------------------------------------------------------
- case SCENE_WAIT:
-# define xo 2
+ //---------------------------------------------------------------------
+ case SCENE_WAIT:
+#define xo 2
- show(canvas, 3+xo,10, &img_ecp_port, SHOW_SET_BLK);
+ show(canvas, 3 + xo, 10, &img_ecp_port, SHOW_SET_BLK);
- BOX_TL(22+xo, 6, 82+xo,23); // 3v3
- BOX_TL(48+xo,21, 82+xo,23); // C1
- BOX_BL(22+xo,41, 82+xo,58); // C0
- BOX_BL(48+xo,41, 82+xo,44); // Gnd
+ BOX_TL(22 + xo, 6, 82 + xo, 23); // 3v3
+ BOX_TL(48 + xo, 21, 82 + xo, 23); // C1
+ BOX_BL(22 + xo, 41, 82 + xo, 58); // C0
+ BOX_BL(48 + xo, 41, 82 + xo, 44); // Gnd
- show(canvas, 90+xo, 3, &img_6x8_3, SHOW_SET_BLK); // 3v3
- show(canvas, 97+xo, 3, &img_6x8_v, SHOW_SET_BLK);
- show(canvas, 104+xo, 3, &img_6x8_3, SHOW_SET_BLK);
+ show(canvas, 90 + xo, 3, &img_6x8_3, SHOW_SET_BLK); // 3v3
+ show(canvas, 97 + xo, 3, &img_6x8_v, SHOW_SET_BLK);
+ show(canvas, 104 + xo, 3, &img_6x8_3, SHOW_SET_BLK);
- show(canvas, 90+xo,18, &img_6x8_C, SHOW_SET_BLK); // C1 <->
- show(canvas, 98+xo,18, &img_6x8_1, SHOW_SET_BLK);
- show(canvas, 107+xo,16, &img_ecp_SDA, SHOW_SET_BLK);
+ show(canvas, 90 + xo, 18, &img_6x8_C, SHOW_SET_BLK); // C1 <->
+ show(canvas, 98 + xo, 18, &img_6x8_1, SHOW_SET_BLK);
+ show(canvas, 107 + xo, 16, &img_ecp_SDA, SHOW_SET_BLK);
- show(canvas, 90+xo,40, &img_6x8_G, SHOW_SET_BLK); // Gnd
- show(canvas, 97+xo,40, &img_6x8_n, SHOW_SET_BLK);
- show(canvas, 104+xo,40, &img_6x8_d, SHOW_SET_BLK);
+ show(canvas, 90 + xo, 40, &img_6x8_G, SHOW_SET_BLK); // Gnd
+ show(canvas, 97 + xo, 40, &img_6x8_n, SHOW_SET_BLK);
+ show(canvas, 104 + xo, 40, &img_6x8_d, SHOW_SET_BLK);
- show(canvas, 90+xo,54, &img_6x8_C, SHOW_SET_BLK); // C0 _-_-
- show(canvas, 98+xo,54, &img_6x8_0, SHOW_SET_BLK);
- show(canvas, 108+xo,54, &img_ecp_SCL, SHOW_SET_BLK);
+ show(canvas, 90 + xo, 54, &img_6x8_C, SHOW_SET_BLK); // C0 _-_-
+ show(canvas, 98 + xo, 54, &img_6x8_0, SHOW_SET_BLK);
+ show(canvas, 108 + xo, 54, &img_ecp_SCL, SHOW_SET_BLK);
- show(canvas, 0,0, &img_csLogo_Small, SHOW_SET_BLK);
- showVer(canvas);
+ show(canvas, 0, 0, &img_csLogo_Small, SHOW_SET_BLK);
+ showVer(canvas);
-# undef xo
- break;
+#undef xo
+ break;
- //---------------------------------------------------------------------
- case SCENE_DEBUG:
- canvas_set_font(canvas, FontSecondary);
+ //---------------------------------------------------------------------
+ case SCENE_DEBUG:
+ canvas_set_font(canvas, FontSecondary);
- show(canvas, 0,0, &img_key_U, SHOW_SET_BLK);
- canvas_draw_str_aligned(canvas, 11, 0, AlignLeft, AlignTop, "Initialise Perhipheral");
+ show(canvas, 0, 0, &img_key_U, SHOW_SET_BLK);
+ canvas_draw_str_aligned(canvas, 11, 0, AlignLeft, AlignTop, "Initialise Perhipheral");
- show(canvas, 0,11, &img_key_OK, SHOW_SET_BLK);
- canvas_draw_str_aligned(canvas, 11,11, AlignLeft, AlignTop, "Read values [see log]");
+ show(canvas, 0, 11, &img_key_OK, SHOW_SET_BLK);
+ canvas_draw_str_aligned(canvas, 11, 11, AlignLeft, AlignTop, "Read values [see log]");
- show(canvas, 0,23, &img_key_D, SHOW_SET_BLK);
- canvas_draw_str_aligned(canvas, 11,22, AlignLeft, AlignTop, "Restart Scanner");
+ show(canvas, 0, 23, &img_key_D, SHOW_SET_BLK);
+ canvas_draw_str_aligned(canvas, 11, 22, AlignLeft, AlignTop, "Restart Scanner");
- show(canvas, 0,33, &img_key_Back, SHOW_SET_BLK);
- canvas_draw_str_aligned(canvas, 11,33, AlignLeft, AlignTop, "Exit");
+ show(canvas, 0, 33, &img_key_Back, SHOW_SET_BLK);
+ canvas_draw_str_aligned(canvas, 11, 33, AlignLeft, AlignTop, "Exit");
- break ;
+ break;
- //---------------------------------------------------------------------
- default:
- if (state->ec.pidx >= PID_ERROR) {
- ERROR("%s : bad PID = %d", __func__, state->ec.pidx);
- } else {
- if ((state->scene == SCENE_DUMP) || !ecId[state->ec.pidx].show)
- ecId[PID_UNKNOWN].show(canvas, state);
- else
- ecId[state->ec.pidx].show(canvas, state);
- }
- break;
- }
+ //---------------------------------------------------------------------
+ default:
+ if(state->ec.pidx >= PID_ERROR) {
+ ERROR("%s : bad PID = %d", __func__, state->ec.pidx);
+ } else {
+ if((state->scene == SCENE_DUMP) || !ecId[state->ec.pidx].show)
+ ecId[PID_UNKNOWN].show(canvas, state);
+ else
+ ecId[state->ec.pidx].show(canvas, state);
+ }
+ break;
+ }
- // Release the mutex
- release_mutex((ValueMutex*)ctx, state);
+ // Release the mutex
+ release_mutex((ValueMutex*)ctx, state);
- LEAVE;
- return;
+ LEAVE;
+ return;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -207,56 +199,54 @@ void cbDraw (Canvas* const canvas, void* ctx)
//+============================================================================ ========================================
// Initialise plugin state variables
//
-static inline
-bool stateInit (state_t* const state)
-{
- ENTER;
- furi_assert(state);
-
- bool rv = true; // assume success
-
- // Enable the main loop
- state->run = true;
-
- // Timer
- state->timerEn = false;
- state->timer = NULL;
- state->timerHz = furi_kernel_get_tick_frequency();
- state->fps = 30;
-
- // Scene
- state->scene = SCENE_SPLASH;
- state->scenePrev = SCENE_NONE;
- state->scenePegg = SCENE_NONE;
-
- state->hold = 0; // show hold meters (-1=lowest, 0=current, +1=highest}
- state->calib = CAL_TRACK;
- state->pause = false; // animation running
- state->apause = false; // auto-pause animation
-
- // Notifications
- state->notify = NULL;
-
- // Perhipheral
- state->ec.init = false;
- state->ec.pidx = PID_UNKNOWN;
- state->ec.sid = ecId[state->ec.pidx].name;
-
- // Controller data
- memset(state->ec.pid, 0xC5, PID_LEN); // Cyborg 5ystems
- memset(state->ec.calF, 0xC5, CAL_LEN);
- memset(state->ec.joy, 0xC5, JOY_LEN);
-
- // Encryption details
- state->ec.encrypt = false;
- memset(state->ec.encKey, 0x00, ENC_LEN);
-
- // Seed the PRNG
- // CYCCNT --> lib/STM32CubeWB/Drivers/CMSIS/Include/core_cm7.h
-// srand(DWT->CYCCNT);
-
- LEAVE;
- return rv;
+static inline bool stateInit(state_t* const state) {
+ ENTER;
+ furi_assert(state);
+
+ bool rv = true; // assume success
+
+ // Enable the main loop
+ state->run = true;
+
+ // Timer
+ state->timerEn = false;
+ state->timer = NULL;
+ state->timerHz = furi_kernel_get_tick_frequency();
+ state->fps = 30;
+
+ // Scene
+ state->scene = SCENE_SPLASH;
+ state->scenePrev = SCENE_NONE;
+ state->scenePegg = SCENE_NONE;
+
+ state->hold = 0; // show hold meters (-1=lowest, 0=current, +1=highest}
+ state->calib = CAL_TRACK;
+ state->pause = false; // animation running
+ state->apause = false; // auto-pause animation
+
+ // Notifications
+ state->notify = NULL;
+
+ // Perhipheral
+ state->ec.init = false;
+ state->ec.pidx = PID_UNKNOWN;
+ state->ec.sid = ecId[state->ec.pidx].name;
+
+ // Controller data
+ memset(state->ec.pid, 0xC5, PID_LEN); // Cyborg 5ystems
+ memset(state->ec.calF, 0xC5, CAL_LEN);
+ memset(state->ec.joy, 0xC5, JOY_LEN);
+
+ // Encryption details
+ state->ec.encrypt = false;
+ memset(state->ec.encKey, 0x00, ENC_LEN);
+
+ // Seed the PRNG
+ // CYCCNT --> lib/STM32CubeWB/Drivers/CMSIS/Include/core_cm7.h
+ // srand(DWT->CYCCNT);
+
+ LEAVE;
+ return rv;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -270,271 +260,284 @@ bool stateInit (state_t* const state)
//+============================================================================ ========================================
// Enable/Disable scanning
//
-void timerEn (state_t* state, bool on)
-{
- ENTER;
- furi_assert(state);
-
- // ENable scanning
- if (on) {
- if (state->timerEn) {
- WARN(wii_errs[WARN_SCAN_START]);
- } else {
- // Set the timer to fire at 'fps' times/second
- if (furi_timer_start(state->timer, state->timerHz/state->fps) == FuriStatusOk) {
- state->timerEn = true;
- INFO("%s : monitor started", __func__);
- } else {
- ERROR(wii_errs[ERR_TIMER_START]);
- }
- }
-
- // DISable scanning
- } else {
- if (!state->timerEn) {
- WARN(wii_errs[WARN_SCAN_STOP]);
- } else {
- // Stop the timer
- if (furi_timer_stop(state->timer) == FuriStatusOk) {
- state->timerEn = false;
- INFO("%s : monitor stopped", __func__);
- } else {
- ERROR(wii_errs[ERR_TIMER_STOP]);
- }
- }
- }
-
- LEAVE;
- return;
+void timerEn(state_t* state, bool on) {
+ ENTER;
+ furi_assert(state);
+
+ // ENable scanning
+ if(on) {
+ if(state->timerEn) {
+ WARN(wii_errs[WARN_SCAN_START]);
+ } else {
+ // Set the timer to fire at 'fps' times/second
+ if(furi_timer_start(state->timer, state->timerHz / state->fps) == FuriStatusOk) {
+ state->timerEn = true;
+ INFO("%s : monitor started", __func__);
+ } else {
+ ERROR(wii_errs[ERR_TIMER_START]);
+ }
+ }
+
+ // DISable scanning
+ } else {
+ if(!state->timerEn) {
+ WARN(wii_errs[WARN_SCAN_STOP]);
+ } else {
+ // Stop the timer
+ if(furi_timer_stop(state->timer) == FuriStatusOk) {
+ state->timerEn = false;
+ INFO("%s : monitor stopped", __func__);
+ } else {
+ ERROR(wii_errs[ERR_TIMER_STOP]);
+ }
+ }
+ }
+
+ LEAVE;
+ return;
}
//+============================================================================ ========================================
// Plugin entry point
//
-int32_t wii_ec_anal (void)
-{
- ENTER;
-
- // ===== Variables =====
- err_t error = 0; // assume success
- Gui* gui = NULL;
- ViewPort* vpp = NULL;
- state_t* state = NULL;
- ValueMutex mutex = {0};
- FuriMessageQueue* queue = NULL;
- const uint32_t queueSz = 20; // maximum messages in queue
- uint32_t tmo = (3.5f *1000); // timeout splash screen after N seconds
-
- // The queue will contain plugin event-messages
- // --> local
- eventMsg_t msg = {0};
-
- INFO("BEGIN");
-
- // ===== Message queue =====
- // 1. Create a message queue (for up to 8 (keyboard) event messages)
- if ( !(queue = furi_message_queue_alloc(queueSz, sizeof(msg))) ) {
- ERROR(wii_errs[(error = ERR_MALLOC_QUEUE)]);
- goto bail;
- }
-
- // ===== Create GUI Interface =====
- // 2. Create a GUI interface
- if ( !(gui = furi_record_open("gui")) ) {
- ERROR(wii_errs[(error = ERR_NO_GUI)]);
- goto bail;
- }
-
- // ===== Plugin state variables =====
- // 3. Allocate space on the heap for the plugin state variables
- if ( !(state = malloc(sizeof(state_t))) ) {
- ERROR(wii_errs[(error = ERR_MALLOC_STATE)]);
- goto bail;
- }
- // 4. Initialise the plugin state variables
- if (!stateInit(state)) {
- // error message(s) is/are output by stateInit()
- error = 15;
- goto bail;
- }
- // 5. Create a mutex for (reading/writing) the plugin state variables
- if (!init_mutex(&mutex, state, sizeof(state))) {
- ERROR(wii_errs[(error = ERR_NO_MUTEX)]);
- goto bail;
- }
-
- // ===== Viewport =====
- // 6. Allocate space on the heap for the viewport
- if ( !(vpp = view_port_alloc()) ) {
- ERROR(wii_errs[(error = ERR_MALLOC_VIEW)]);
- goto bail;
- }
- // 7a. Register a callback for input events
- view_port_input_callback_set(vpp, cbInput, queue);
- // 7b. Register a callback for draw events
- view_port_draw_callback_set(vpp, cbDraw, &mutex);
-
- // ===== Start GUI Interface =====
- // 8. Attach the viewport to the GUI
- gui_add_view_port(gui, vpp, GuiLayerFullscreen);
-
- // ===== Timer =====
- // 9. Allocate a timer
- if ( !(state->timer = furi_timer_alloc(cbTimer, FuriTimerTypePeriodic, queue)) ) {
- ERROR(wii_errs[(error = ERR_NO_TIMER)]);
- goto bail;
- }
-
- // === System Notifications ===
- // 10. Acquire a handle for the system notification queue
- if ( !(state->notify = furi_record_open(RECORD_NOTIFICATION)) ) {
- ERROR(wii_errs[(error = ERR_NO_NOTIFY)]);
- goto bail;
- }
- patBacklight(state); // Turn on the backlight [qv. remote FAP launch]
-
- INFO("INITIALISED");
-
- // ==================== Main event loop ====================
-
- if (state->run) do {
- bool redraw = false;
- FuriStatus status = FuriStatusErrorTimeout;
-
- // Wait for a message
-// while ((status = furi_message_queue_get(queue, &msg, tmo)) == FuriStatusErrorTimeout) ;
- status = furi_message_queue_get(queue, &msg, tmo);
-
- // Clear splash screen
- if ( (state->scene == SCENE_SPLASH) && (state->scenePrev == SCENE_NONE) && // Initial splash
- ( (status == FuriStatusErrorTimeout) || // timeout
- ((msg.id == EVID_KEY) && (msg.input.type == InputTypeShort)) ) // or key-short
- ) {
- tmo = 60 *1000; // increase message-wait timeout to 60secs
- timerEn(state, true); // start scanning the i2c bus
- status = FuriStatusOk; // pass status check
- msg.id = EVID_NONE; // valid msg ID
- sceneSet(state, SCENE_WAIT); // move to wait screen
- }
-
- // Check for queue errors
- if (status != FuriStatusOk) {
- switch (status) {
- case FuriStatusErrorTimeout: DEBUG(wii_errs[DEBUG_QUEUE_TIMEOUT]); continue ;
- case FuriStatusError: ERROR(wii_errs[(error = ERR_QUEUE_RTOS)]); goto bail ;
- case FuriStatusErrorResource: ERROR(wii_errs[(error = ERR_QUEUE_RESOURCE)]); goto bail ;
- case FuriStatusErrorParameter: ERROR(wii_errs[(error = ERR_QUEUE_BADPRM)]); goto bail ;
- case FuriStatusErrorNoMemory: ERROR(wii_errs[(error = ERR_QUEUE_NOMEM)]); goto bail ;
- case FuriStatusErrorISR: ERROR(wii_errs[(error = ERR_QUEUE_ISR)]); goto bail ;
- default: ERROR(wii_errs[(error = ERR_QUEUE_UNK)]); goto bail ;
- }
- }
- // Read successful
-
- // *** Try to lock the plugin state variables ***
- if ( !(state = (state_t*)acquire_mutex_block(&mutex)) ) {
- ERROR(wii_errs[(error = ERR_MUTEX_BLOCK)]);
- goto bail;
- }
-
- // *** Handle events ***
- switch (msg.id) {
- //---------------------------------------------
- case EVID_TICK: // Timer events
- //! I would prefer to have ecPoll() called by cbTimer()
- //! ...but how does cbTimer() get the required access to the state variables? Namely: 'state->ec'
- //! So, for now, the timer pushes a message to call ecPoll()
- //! which, in turn, will push WIIEC event meesages!
- ecPoll(&state->ec, queue);
- break;
-
- //---------------------------------------------
- case EVID_WIIEC: // WiiMote Perhipheral
- if (evWiiEC(&msg, state)) redraw = true ;
- break;
-
- //---------------------------------------------
- case EVID_KEY: // Key events
- patBacklight(state);
- if (evKey(&msg, state)) redraw = true;
- break;
-
- //---------------------------------------------
- case EVID_NONE:
- break;
-
- //---------------------------------------------
- default: // Unknown event
- WARN("Unknown message.ID [%d]", msg.id);
- break;
- }
-
- // *** Update the GUI screen via the viewport ***
- if (redraw) view_port_update(vpp) ;
-
- // *** Try to release the plugin state variables ***
- if ( !release_mutex(&mutex, state) ) {
- ERROR(wii_errs[(error = ERR_MUTEX_RELEASE)]);
- goto bail;
- }
- } while (state->run);
-
- // ===== Game Over =====
- INFO("USER EXIT");
+int32_t wii_ec_anal(void) {
+ ENTER;
+
+ // ===== Variables =====
+ err_t error = 0; // assume success
+ Gui* gui = NULL;
+ ViewPort* vpp = NULL;
+ state_t* state = NULL;
+ ValueMutex mutex = {0};
+ FuriMessageQueue* queue = NULL;
+ const uint32_t queueSz = 20; // maximum messages in queue
+ uint32_t tmo = (3.5f * 1000); // timeout splash screen after N seconds
+
+ // The queue will contain plugin event-messages
+ // --> local
+ eventMsg_t msg = {0};
+
+ INFO("BEGIN");
+
+ // ===== Message queue =====
+ // 1. Create a message queue (for up to 8 (keyboard) event messages)
+ if(!(queue = furi_message_queue_alloc(queueSz, sizeof(msg)))) {
+ ERROR(wii_errs[(error = ERR_MALLOC_QUEUE)]);
+ goto bail;
+ }
+
+ // ===== Create GUI Interface =====
+ // 2. Create a GUI interface
+ if(!(gui = furi_record_open("gui"))) {
+ ERROR(wii_errs[(error = ERR_NO_GUI)]);
+ goto bail;
+ }
+
+ // ===== Plugin state variables =====
+ // 3. Allocate space on the heap for the plugin state variables
+ if(!(state = malloc(sizeof(state_t)))) {
+ ERROR(wii_errs[(error = ERR_MALLOC_STATE)]);
+ goto bail;
+ }
+ // 4. Initialise the plugin state variables
+ if(!stateInit(state)) {
+ // error message(s) is/are output by stateInit()
+ error = 15;
+ goto bail;
+ }
+ // 5. Create a mutex for (reading/writing) the plugin state variables
+ if(!init_mutex(&mutex, state, sizeof(state))) {
+ ERROR(wii_errs[(error = ERR_NO_MUTEX)]);
+ goto bail;
+ }
+
+ // ===== Viewport =====
+ // 6. Allocate space on the heap for the viewport
+ if(!(vpp = view_port_alloc())) {
+ ERROR(wii_errs[(error = ERR_MALLOC_VIEW)]);
+ goto bail;
+ }
+ // 7a. Register a callback for input events
+ view_port_input_callback_set(vpp, cbInput, queue);
+ // 7b. Register a callback for draw events
+ view_port_draw_callback_set(vpp, cbDraw, &mutex);
+
+ // ===== Start GUI Interface =====
+ // 8. Attach the viewport to the GUI
+ gui_add_view_port(gui, vpp, GuiLayerFullscreen);
+
+ // ===== Timer =====
+ // 9. Allocate a timer
+ if(!(state->timer = furi_timer_alloc(cbTimer, FuriTimerTypePeriodic, queue))) {
+ ERROR(wii_errs[(error = ERR_NO_TIMER)]);
+ goto bail;
+ }
+
+ // === System Notifications ===
+ // 10. Acquire a handle for the system notification queue
+ if(!(state->notify = furi_record_open(RECORD_NOTIFICATION))) {
+ ERROR(wii_errs[(error = ERR_NO_NOTIFY)]);
+ goto bail;
+ }
+ patBacklight(state); // Turn on the backlight [qv. remote FAP launch]
+
+ INFO("INITIALISED");
+
+ // ==================== Main event loop ====================
+
+ if(state->run) do {
+ bool redraw = false;
+ FuriStatus status = FuriStatusErrorTimeout;
+
+ // Wait for a message
+ // while ((status = furi_message_queue_get(queue, &msg, tmo)) == FuriStatusErrorTimeout) ;
+ status = furi_message_queue_get(queue, &msg, tmo);
+
+ // Clear splash screen
+ if((state->scene == SCENE_SPLASH) &&
+ (state->scenePrev == SCENE_NONE) && // Initial splash
+ ((status == FuriStatusErrorTimeout) || // timeout
+ ((msg.id == EVID_KEY) && (msg.input.type == InputTypeShort))) // or key-short
+ ) {
+ tmo = 60 * 1000; // increase message-wait timeout to 60secs
+ timerEn(state, true); // start scanning the i2c bus
+ status = FuriStatusOk; // pass status check
+ msg.id = EVID_NONE; // valid msg ID
+ sceneSet(state, SCENE_WAIT); // move to wait screen
+ }
+
+ // Check for queue errors
+ if(status != FuriStatusOk) {
+ switch(status) {
+ case FuriStatusErrorTimeout:
+ DEBUG(wii_errs[DEBUG_QUEUE_TIMEOUT]);
+ continue;
+ case FuriStatusError:
+ ERROR(wii_errs[(error = ERR_QUEUE_RTOS)]);
+ goto bail;
+ case FuriStatusErrorResource:
+ ERROR(wii_errs[(error = ERR_QUEUE_RESOURCE)]);
+ goto bail;
+ case FuriStatusErrorParameter:
+ ERROR(wii_errs[(error = ERR_QUEUE_BADPRM)]);
+ goto bail;
+ case FuriStatusErrorNoMemory:
+ ERROR(wii_errs[(error = ERR_QUEUE_NOMEM)]);
+ goto bail;
+ case FuriStatusErrorISR:
+ ERROR(wii_errs[(error = ERR_QUEUE_ISR)]);
+ goto bail;
+ default:
+ ERROR(wii_errs[(error = ERR_QUEUE_UNK)]);
+ goto bail;
+ }
+ }
+ // Read successful
+
+ // *** Try to lock the plugin state variables ***
+ if(!(state = (state_t*)acquire_mutex_block(&mutex))) {
+ ERROR(wii_errs[(error = ERR_MUTEX_BLOCK)]);
+ goto bail;
+ }
+
+ // *** Handle events ***
+ switch(msg.id) {
+ //---------------------------------------------
+ case EVID_TICK: // Timer events
+ //! I would prefer to have ecPoll() called by cbTimer()
+ //! ...but how does cbTimer() get the required access to the state variables? Namely: 'state->ec'
+ //! So, for now, the timer pushes a message to call ecPoll()
+ //! which, in turn, will push WIIEC event meesages!
+ ecPoll(&state->ec, queue);
+ break;
+
+ //---------------------------------------------
+ case EVID_WIIEC: // WiiMote Perhipheral
+ if(evWiiEC(&msg, state)) redraw = true;
+ break;
+
+ //---------------------------------------------
+ case EVID_KEY: // Key events
+ patBacklight(state);
+ if(evKey(&msg, state)) redraw = true;
+ break;
+
+ //---------------------------------------------
+ case EVID_NONE:
+ break;
+
+ //---------------------------------------------
+ default: // Unknown event
+ WARN("Unknown message.ID [%d]", msg.id);
+ break;
+ }
+
+ // *** Update the GUI screen via the viewport ***
+ if(redraw) view_port_update(vpp);
+
+ // *** Try to release the plugin state variables ***
+ if(!release_mutex(&mutex, state)) {
+ ERROR(wii_errs[(error = ERR_MUTEX_RELEASE)]);
+ goto bail;
+ }
+ } while(state->run);
+
+ // ===== Game Over =====
+ INFO("USER EXIT");
bail:
- // 10. Release system notification queue
- if (state->notify) {
- furi_record_close(RECORD_NOTIFICATION);
- state->notify = NULL;
- }
-
- // 9. Stop the timer
- if (state->timer) {
- (void)furi_timer_stop(state->timer);
- furi_timer_free(state->timer);
- state->timer = NULL;
- state->timerEn = false;
- }
-
- // 8. Detach the viewport
- gui_remove_view_port(gui, vpp);
-
- // 7. No need to unreqgister the callbacks
- // ...they will go when the viewport is destroyed
-
- // 6. Destroy the viewport
- if (vpp) {
- view_port_enabled_set(vpp, false);
- view_port_free(vpp);
- vpp = NULL;
- }
-
- // 5. Free the mutex
- if (mutex.mutex) {
- delete_mutex(&mutex);
- mutex.mutex = NULL;
- }
-
- // 4. Free up state pointer(s)
- // none
-
- // 3. Free the plugin state variables
- if (state) {
- free(state);
- state = NULL;
- }
-
- // 2. Close the GUI
- furi_record_close("gui");
-
- // 1. Destroy the message queue
- if (queue) {
- furi_message_queue_free(queue);
- queue = NULL;
- }
-
- INFO("CLEAN EXIT ... Exit code: %d", error);
- LEAVE;
- return (int32_t)error;
+ // 10. Release system notification queue
+ if(state->notify) {
+ furi_record_close(RECORD_NOTIFICATION);
+ state->notify = NULL;
+ }
+
+ // 9. Stop the timer
+ if(state->timer) {
+ (void)furi_timer_stop(state->timer);
+ furi_timer_free(state->timer);
+ state->timer = NULL;
+ state->timerEn = false;
+ }
+
+ // 8. Detach the viewport
+ gui_remove_view_port(gui, vpp);
+
+ // 7. No need to unreqgister the callbacks
+ // ...they will go when the viewport is destroyed
+
+ // 6. Destroy the viewport
+ if(vpp) {
+ view_port_enabled_set(vpp, false);
+ view_port_free(vpp);
+ vpp = NULL;
+ }
+
+ // 5. Free the mutex
+ if(mutex.mutex) {
+ delete_mutex(&mutex);
+ mutex.mutex = NULL;
+ }
+
+ // 4. Free up state pointer(s)
+ // none
+
+ // 3. Free the plugin state variables
+ if(state) {
+ free(state);
+ state = NULL;
+ }
+
+ // 2. Close the GUI
+ furi_record_close("gui");
+
+ // 1. Destroy the message queue
+ if(queue) {
+ furi_message_queue_free(queue);
+ queue = NULL;
+ }
+
+ INFO("CLEAN EXIT ... Exit code: %d", error);
+ LEAVE;
+ return (int32_t)error;
}
diff --git a/applications/plugins/wii_ec_anal/wii_anal.h b/applications/plugins/wii_ec_anal/wii_anal.h
index ac7ffddb18..3aae61fdc9 100644
--- a/applications/plugins/wii_ec_anal/wii_anal.h
+++ b/applications/plugins/wii_ec_anal/wii_anal.h
@@ -1,97 +1,89 @@
-#ifndef WII_ANAL_H_
-#define WII_ANAL_H_
+#ifndef WII_ANAL_H_
+#define WII_ANAL_H_
-#include // Core API
-#include // GUI Input extensions
-#include
+#include // Core API
+#include // GUI Input extensions
+#include
//----------------------------------------------------------------------------- ----------------------------------------
// GUI scenes
//
-typedef
- enum scene {
- SCENE_NONE = 0,
- SCENE_SPLASH = 1,
- SCENE_RIP = 2,
- SCENE_WAIT = 3,
- SCENE_DEBUG = 4,
- SCENE_DUMP = 5,
- SCENE_CLASSIC = 6,
- SCENE_CLASSIC_N = 7,
- SCENE_NUNCHUCK = 8,
- SCENE_NUNCHUCK_ACC = 9,
- }
-scene_t;
+typedef enum scene {
+ SCENE_NONE = 0,
+ SCENE_SPLASH = 1,
+ SCENE_RIP = 2,
+ SCENE_WAIT = 3,
+ SCENE_DEBUG = 4,
+ SCENE_DUMP = 5,
+ SCENE_CLASSIC = 6,
+ SCENE_CLASSIC_N = 7,
+ SCENE_NUNCHUCK = 8,
+ SCENE_NUNCHUCK_ACC = 9,
+} scene_t;
//----------------------------------------------------------------------------- ----------------------------------------
-#include "wii_i2c.h"
-#include "wii_ec.h"
+#include "wii_i2c.h"
+#include "wii_ec.h"
//----------------------------------------------------------------------------- ----------------------------------------
// A list of event IDs handled by this plugin
//
-typedef
- enum eventID {
- EVID_NONE,
- EVID_UNKNOWN,
+typedef enum eventID {
+ EVID_NONE,
+ EVID_UNKNOWN,
- // A full list of events can be found with: `grep -r --color "void.*set_.*_callback" applications/gui/*`
- // ...A free gift to you from the makers of well written code that conforms to a good coding standard
- EVID_KEY, // keypad
- EVID_TICK, // tick
- EVID_WIIEC, // wii extension controller
- }
-eventID_t;
+ // A full list of events can be found with: `grep -r --color "void.*set_.*_callback" applications/gui/*`
+ // ...A free gift to you from the makers of well written code that conforms to a good coding standard
+ EVID_KEY, // keypad
+ EVID_TICK, // tick
+ EVID_WIIEC, // wii extension controller
+} eventID_t;
//----------------------------------------------------------------------------- ----------------------------------------
// An item in the event message-queue
//
-typedef
- struct eventMsg {
- eventID_t id;
- union {
- InputEvent input; // --> applications/input/input.h
- wiiEcEvent_t wiiEc; // --> local
- };
- }
-eventMsg_t;
+typedef struct eventMsg {
+ eventID_t id;
+ union {
+ InputEvent input; // --> applications/input/input.h
+ wiiEcEvent_t wiiEc; // --> local
+ };
+} eventMsg_t;
//----------------------------------------------------------------------------- ----------------------------------------
// State variables for this plugin
// An instance of this is allocated on the heap, and the pointer is passed back to the OS
// Access to this memory is controlled by mutex
//
-typedef
- struct state {
- bool run; // true : plugin is running
+typedef struct state {
+ bool run; // true : plugin is running
- bool timerEn; // controller scanning enabled
- FuriTimer* timer; // the timer
- uint32_t timerHz; // system ticks per second
- int fps; // poll/refresh [frames]-per-second
+ bool timerEn; // controller scanning enabled
+ FuriTimer* timer; // the timer
+ uint32_t timerHz; // system ticks per second
+ int fps; // poll/refresh [frames]-per-second
- int cnvW; // canvas width
- int cnvH; // canvas height
- scene_t scene; // current scene
- scene_t scenePrev; // previous scene
- scene_t scenePegg; // previous scene for easter eggs
- int flash; // flash counter (flashing icons)
+ int cnvW; // canvas width
+ int cnvH; // canvas height
+ scene_t scene; // current scene
+ scene_t scenePrev; // previous scene
+ scene_t scenePegg; // previous scene for easter eggs
+ int flash; // flash counter (flashing icons)
- int hold; // hold type: {-1=tough-peak, 0=none, +1=peak-hold}
- ecCalib_t calib; // Software calibration mode
+ int hold; // hold type: {-1=tough-peak, 0=none, +1=peak-hold}
+ ecCalib_t calib; // Software calibration mode
- bool pause; // Accelerometer animation pause
- bool apause; // Accelerometer animation auto-pause
+ bool pause; // Accelerometer animation pause
+ bool apause; // Accelerometer animation auto-pause
- NotificationApp* notify; // OS nitifcation queue (for patting the backlight watchdog timer)
+ NotificationApp* notify; // OS nitifcation queue (for patting the backlight watchdog timer)
- wiiEC_t ec; // Extension Controller details
- }
-state_t;
+ wiiEC_t ec; // Extension Controller details
+} state_t;
//============================================================================= ========================================
// Function prototypes
//
-void timerEn (state_t* state, bool on) ;
+void timerEn(state_t* state, bool on);
#endif //WII_ANAL_H_
diff --git a/applications/plugins/wii_ec_anal/wii_anal_ec.c b/applications/plugins/wii_ec_anal/wii_anal_ec.c
index 0bfa473628..dab167bc0e 100644
--- a/applications/plugins/wii_ec_anal/wii_anal_ec.c
+++ b/applications/plugins/wii_ec_anal/wii_anal_ec.c
@@ -1,97 +1,115 @@
-#include
-#include
+#include
+#include
-#include "wii_anal.h"
-#include "wii_anal_lcd.h"
-#include "wii_anal_keys.h"
+#include "wii_anal.h"
+#include "wii_anal_lcd.h"
+#include "wii_anal_keys.h"
//+============================================================================ ========================================
// Handle Wii Extension Controller events
//
-bool evWiiEC (const eventMsg_t* const msg, state_t* const state)
-{
- bool redraw = false;
+bool evWiiEC(const eventMsg_t* const msg, state_t* const state) {
+ bool redraw = false;
-# if LOG_LEVEL >= 4
- {
- const char* s = NULL;
- switch (msg->wiiEc.type) {
- case WIIEC_NONE: s = "Error"; break ;
- case WIIEC_CONN: s = "Connect"; break ;
- case WIIEC_DISCONN: s = "Disconnect"; break ;
- case WIIEC_PRESS: s = "Press"; break ;
- case WIIEC_RELEASE: s = "Release"; break ;
- case WIIEC_ANALOG: s = "Analog"; break ;
- case WIIEC_ACCEL: s = "Accel"; break ;
- default: s = "Bug"; break ;
- }
- INFO("WIIP : %s '%c' = %d", s, (isprint((int)msg->wiiEc.in) ? msg->wiiEc.in : '_'), msg->wiiEc.val);
- if ((msg->wiiEc.type == WIIEC_CONN) || (msg->wiiEc.type == WIIEC_DISCONN))
- INFO("...%d=\"%s\"", msg->wiiEc.val, ecId[msg->wiiEc.val].name);
- }
-# endif
+#if LOG_LEVEL >= 4
+ {
+ const char* s = NULL;
+ switch(msg->wiiEc.type) {
+ case WIIEC_NONE:
+ s = "Error";
+ break;
+ case WIIEC_CONN:
+ s = "Connect";
+ break;
+ case WIIEC_DISCONN:
+ s = "Disconnect";
+ break;
+ case WIIEC_PRESS:
+ s = "Press";
+ break;
+ case WIIEC_RELEASE:
+ s = "Release";
+ break;
+ case WIIEC_ANALOG:
+ s = "Analog";
+ break;
+ case WIIEC_ACCEL:
+ s = "Accel";
+ break;
+ default:
+ s = "Bug";
+ break;
+ }
+ INFO(
+ "WIIP : %s '%c' = %d",
+ s,
+ (isprint((int)msg->wiiEc.in) ? msg->wiiEc.in : '_'),
+ msg->wiiEc.val);
+ if((msg->wiiEc.type == WIIEC_CONN) || (msg->wiiEc.type == WIIEC_DISCONN))
+ INFO("...%d=\"%s\"", msg->wiiEc.val, ecId[msg->wiiEc.val].name);
+ }
+#endif
- switch (msg->wiiEc.type) {
- case WIIEC_CONN:
- patBacklight(state);
- state->hold = 0;
- state->calib = CAL_TRACK;
- sceneSet(state, ecId[msg->wiiEc.val].scene);
- redraw = true ;
+ switch(msg->wiiEc.type) {
+ case WIIEC_CONN:
+ patBacklight(state);
+ state->hold = 0;
+ state->calib = CAL_TRACK;
+ sceneSet(state, ecId[msg->wiiEc.val].scene);
+ redraw = true;
-#if 1 // Workaround for Classic Controller Pro, which shows 00's for Factory Calibration Data!?
- if (state->ec.pidx == PID_CLASSIC_PRO) {
- // Simulate a Long-OK keypress, to start Software Calibration mode
- eventMsg_t msg = {
-// .id = EVID_KEY,
- .input.type = InputTypeLong,
- .input.key = InputKeyOk
- };
- key_calib(&msg, state);
- }
+#if 1 // Workaround for Classic Controller Pro, which shows 00's for Factory Calibration Data!?
+ if(state->ec.pidx == PID_CLASSIC_PRO) {
+ // Simulate a Long-OK keypress, to start Software Calibration mode
+ eventMsg_t msg = {// .id = EVID_KEY,
+ .input.type = InputTypeLong,
+ .input.key = InputKeyOk};
+ key_calib(&msg, state);
+ }
#endif
- break;
+ break;
- case WIIEC_DISCONN:
- patBacklight(state);
- sceneSet(state, SCENE_WAIT);
- redraw = true;
- break;
+ case WIIEC_DISCONN:
+ patBacklight(state);
+ sceneSet(state, SCENE_WAIT);
+ redraw = true;
+ break;
- case WIIEC_PRESS:
- if (state->scene == SCENE_NUNCHUCK_ACC) switch (msg->wiiEc.in) {
- case 'z': // un-pause
- state->pause = !state->pause;
- break;
- case 'c': // toggle auto-pause
- state->pause = false;
- state->apause = !state->apause;
- break;
- default: break ;
- }
+ case WIIEC_PRESS:
+ if(state->scene == SCENE_NUNCHUCK_ACC) switch(msg->wiiEc.in) {
+ case 'z': // un-pause
+ state->pause = !state->pause;
+ break;
+ case 'c': // toggle auto-pause
+ state->pause = false;
+ state->apause = !state->apause;
+ break;
+ default:
+ break;
+ }
-#if 1 //! factory calibration method not known for classic triggers - this will set the digital switch point
- if ((state->ec.pidx == PID_CLASSIC) || (state->ec.pidx == PID_CLASSIC_PRO)) {
- if (msg->wiiEc.in == 'l') state->ec.calS.classic[2].trgZL = msg->wiiEc.val ;
- if (msg->wiiEc.in == 'r') state->ec.calS.classic[2].trgZR = msg->wiiEc.val ;
- }
+#if 1 //! factory calibration method not known for classic triggers - this will set the digital switch point
+ if((state->ec.pidx == PID_CLASSIC) || (state->ec.pidx == PID_CLASSIC_PRO)) {
+ if(msg->wiiEc.in == 'l') state->ec.calS.classic[2].trgZL = msg->wiiEc.val;
+ if(msg->wiiEc.in == 'r') state->ec.calS.classic[2].trgZR = msg->wiiEc.val;
+ }
#endif
- __attribute__ ((fallthrough));
+ __attribute__((fallthrough));
- case WIIEC_RELEASE:
- patBacklight(state);
- redraw = true;
- break;
+ case WIIEC_RELEASE:
+ patBacklight(state);
+ redraw = true;
+ break;
- case WIIEC_ANALOG:
- case WIIEC_ACCEL:
- ecCalibrate(&state->ec, state->calib);
- redraw = true;
- break;
+ case WIIEC_ANALOG:
+ case WIIEC_ACCEL:
+ ecCalibrate(&state->ec, state->calib);
+ redraw = true;
+ break;
- default:
- break;
- }
+ default:
+ break;
+ }
- return redraw;
+ return redraw;
}
diff --git a/applications/plugins/wii_ec_anal/wii_anal_ec.h b/applications/plugins/wii_ec_anal/wii_anal_ec.h
index 886b602815..eec6b523cb 100644
--- a/applications/plugins/wii_ec_anal/wii_anal_ec.h
+++ b/applications/plugins/wii_ec_anal/wii_anal_ec.h
@@ -1,14 +1,14 @@
-#ifndef WII_ANAL_EC_H_
-#define WII_ANAL_EC_H_
+#ifndef WII_ANAL_EC_H_
+#define WII_ANAL_EC_H_
-#include
+#include
//============================================================================= ========================================
// Function prototypes
//
-typedef struct eventMsg eventMsg_t ;
-typedef struct state state_t ;
+typedef struct eventMsg eventMsg_t;
+typedef struct state state_t;
-bool evWiiEC (const eventMsg_t* const msg, state_t* const state) ;
+bool evWiiEC(const eventMsg_t* const msg, state_t* const state);
#endif //WII_ANAL_EC_H_
diff --git a/applications/plugins/wii_ec_anal/wii_anal_keys.c b/applications/plugins/wii_ec_anal/wii_anal_keys.c
index 3d2fae14a3..2a446efb69 100644
--- a/applications/plugins/wii_ec_anal/wii_anal_keys.c
+++ b/applications/plugins/wii_ec_anal/wii_anal_keys.c
@@ -1,40 +1,35 @@
-#include
+#include
-#include "bc_logging.h"
+#include "bc_logging.h"
-#include "wii_anal.h"
+#include "wii_anal.h"
//+============================================================================ ========================================
// Stop Calibration mode
//
-static
-void calStop (state_t* const state)
-{
- state->hold = 0; // stop calibration mode
- state->calib &= ~(CAL_RANGE | CAL_NOTJOY); // ...
+static void calStop(state_t* const state) {
+ state->hold = 0; // stop calibration mode
+ state->calib &= ~(CAL_RANGE | CAL_NOTJOY); // ...
}
//+============================================================================ ========================================
// Change to another scene
//
-void sceneSet (state_t* const state, const scene_t scene)
-{
- calStop(state); // Stop software calibration
- state->scenePrev = state->scene; // Remember where we came from
- state->scene = scene; // Go to new scene
- INFO("Scene : %d -> %d", state->scenePrev, state->scene);
+void sceneSet(state_t* const state, const scene_t scene) {
+ calStop(state); // Stop software calibration
+ state->scenePrev = state->scene; // Remember where we came from
+ state->scene = scene; // Go to new scene
+ INFO("Scene : %d -> %d", state->scenePrev, state->scene);
}
//+============================================================================ ========================================
// Change to an easter egg scene
//
-static
-void sceneSetEgg (state_t* const state, const scene_t scene)
-{
- calStop(state); // Stop software calibration
- state->scenePegg = state->scene; // Remember where we came from
- state->scene = scene; // Go to new scene
- INFO("Scene* : %d => %d", state->scenePegg, state->scene);
+static void sceneSetEgg(state_t* const state, const scene_t scene) {
+ calStop(state); // Stop software calibration
+ state->scenePegg = state->scene; // Remember where we came from
+ state->scene = scene; // Go to new scene
+ INFO("Scene* : %d => %d", state->scenePegg, state->scene);
}
//+============================================================================ ========================================
@@ -42,256 +37,265 @@ void sceneSetEgg (state_t* const state, const scene_t scene)
// Enabling peak-hold on screen with no peak meters will have no effect
// So, to avoid code duplication...
//
-bool key_calib (const eventMsg_t* const msg, state_t* const state)
-{
- int used = false; // assume key is NOT-handled
-
- switch (msg->input.type) {
- case InputTypeShort: //# input.key) {
- case InputKeyUp: //# hold = (state->hold == +1) ? 0 : +1 ; // toggle peak hold
- used = true;
- break;
-
- case InputKeyDown: //# hold = (state->hold == -1) ? 0 : -1 ; // toggle trough hold
- used = true;
- break;
-
- case InputKeyOk: //# calib & CAL_RANGE) calStop(state) ; // STOP softare calibration
- else ecCalibrate(&state->ec, CAL_CENTRE) ; // perform centre calibration
- used = true;
- break;
-
- default: break ;
- }
- break;
-
- case InputTypeLong: //# >! After INPUT_LONG_PRESS interval, asynch to InputTypeRelease
- switch (msg->input.key) {
- case InputKeyOk: //# >O [ LONG-OK ]
- ecCalibrate(&state->ec, CAL_RESET | CAL_CENTRE); // START software calibration
- state->hold = 0;
- state->calib |= CAL_RANGE;
- state->flash = 8; // start with flash ON
- used = true;
- break;
-
- default: break ;
- }
- break;
-
- default: break ;
- }
-
- return used;
+bool key_calib(const eventMsg_t* const msg, state_t* const state) {
+ int used = false; // assume key is NOT-handled
+
+ switch(msg->input.type) {
+ case InputTypeShort: //# input.key) {
+ case InputKeyUp: //# hold = (state->hold == +1) ? 0 : +1; // toggle peak hold
+ used = true;
+ break;
+
+ case InputKeyDown: //# hold = (state->hold == -1) ? 0 : -1; // toggle trough hold
+ used = true;
+ break;
+
+ case InputKeyOk: //# calib & CAL_RANGE)
+ calStop(state); // STOP softare calibration
+ else
+ ecCalibrate(&state->ec, CAL_CENTRE); // perform centre calibration
+ used = true;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case InputTypeLong: //# >! After INPUT_LONG_PRESS interval, asynch to InputTypeRelease
+ switch(msg->input.key) {
+ case InputKeyOk: //# >O [ LONG-OK ]
+ ecCalibrate(&state->ec, CAL_RESET | CAL_CENTRE); // START software calibration
+ state->hold = 0;
+ state->calib |= CAL_RANGE;
+ state->flash = 8; // start with flash ON
+ used = true;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return used;
}
//+============================================================================ ========================================
// WAIT screen
//
-static inline
-bool wait_key (const eventMsg_t* const msg, state_t* const state)
-{
- int used = false; // assume key is NOT-handled
-
- if (msg->input.type == InputTypeShort) {
- switch (msg->input.key) {
- case InputKeyLeft: //# run = false;
- used = true;
- break;
-
- default: break ;
- }
- }
-
- return used;
+static inline bool wait_key(const eventMsg_t* const msg, state_t* const state) {
+ int used = false; // assume key is NOT-handled
+
+ if(msg->input.type == InputTypeShort) {
+ switch(msg->input.key) {
+ case InputKeyLeft: //# run = false;
+ used = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return used;
}
//+============================================================================ ========================================
// DEBUG screen
//
-static inline
-bool debug_key (const eventMsg_t* const msg, state_t* const state)
-{
- int used = false; // assume key is NOT-handled
-
- switch (msg->input.type) {
- case InputTypeShort: //# input.key) {
- case InputKeyUp: { //# ec, NULL); // Initialise the controller //! NULL = no encryption
- (void)init; // in case INFO is optimised out
- INFO("%s : %s", __func__, (init ? "init OK" : "init fail"));
- used = true;
- break;
- }
-
- case InputKeyOk: //# ec) == 0) { // Read the controller
- INFO( "%s : joy: {%02X,%02X,%02X,%02X,%02X,%02X}", __func__,
- state->ec.joy[0], state->ec.joy[1], state->ec.joy[2],
- state->ec.joy[3], state->ec.joy[4], state->ec.joy[5] );
- }
- used = true;
- break;
-
- case InputKeyDown: //# scenePrev);
- used = true;
- break;
-
- case InputKeyBack: //# run = false;
- used = true;
- break;
-
- default: break ; //#
- }
- break;
-
- default: break ;
- }
-
- return used;
+static inline bool debug_key(const eventMsg_t* const msg, state_t* const state) {
+ int used = false; // assume key is NOT-handled
+
+ switch(msg->input.type) {
+ case InputTypeShort: //# input.key) {
+ case InputKeyUp: { //# ec, NULL); // Initialise the controller //! NULL = no encryption
+ (void)init; // in case INFO is optimised out
+ INFO("%s : %s", __func__, (init ? "init OK" : "init fail"));
+ used = true;
+ break;
+ }
+
+ case InputKeyOk: //# ec) == 0) { // Read the controller
+ INFO(
+ "%s : joy: {%02X,%02X,%02X,%02X,%02X,%02X}",
+ __func__,
+ state->ec.joy[0],
+ state->ec.joy[1],
+ state->ec.joy[2],
+ state->ec.joy[3],
+ state->ec.joy[4],
+ state->ec.joy[5]);
+ }
+ used = true;
+ break;
+
+ case InputKeyDown: //# scenePrev);
+ used = true;
+ break;
+
+ case InputKeyBack: //# run = false;
+ used = true;
+ break;
+
+ default:
+ break; //#
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return used;
}
//+============================================================================ ========================================
// SPLASH and RIP screen
//
-static inline
-bool splash_key (const eventMsg_t* const msg, state_t* const state)
-{
- // Back key on the initial SPLASH screen (this will catch the InputKeyPress)
- if ((msg->input.key == InputKeyBack) && (state->scenePrev == SCENE_NONE)) state->run = false ;
-
- // ANY-other-KEY press
- if (msg->input.type == InputTypeShort) {
- timerEn(state, true); // Restart the timer
- state->scene = state->scenePegg;
- }
-
- return true;
-}
+static inline bool splash_key(const eventMsg_t* const msg, state_t* const state) {
+ // Back key on the initial SPLASH screen (this will catch the InputKeyPress)
+ if((msg->input.key == InputKeyBack) && (state->scenePrev == SCENE_NONE)) state->run = false;
+
+ // ANY-other-KEY press
+ if(msg->input.type == InputTypeShort) {
+ timerEn(state, true); // Restart the timer
+ state->scene = state->scenePegg;
+ }
+ return true;
+}
//+============================================================================ ========================================
// "_pre" allows the plugin to use the key before the active scene gets a chance
//
-static inline
-bool key_pre (const eventMsg_t* const msg, state_t* const state)
-{
- (void)msg;
- (void)state;
+static inline bool key_pre(const eventMsg_t* const msg, state_t* const state) {
+ (void)msg;
+ (void)state;
- return false;
+ return false;
}
//+============================================================================ ========================================
// "_post" allows the plugin to use a key if it was not used by the active scene
//
-static inline
-bool key_post (const eventMsg_t* const msg, state_t* const state)
-{
- int used = false; // assume key is NOT-handled
-
- if (msg->input.key == InputKeyBack) {
- if (msg->input.type == InputTypeShort) { //# ec.init = false; // reset/disconnect the controller
- sceneSet(state, SCENE_WAIT);
- used = true;
-
- } else if (msg->input.type == InputTypeLong) { //# >B [LONG-BACK]
- state->run = false; // Signal the plugin to exit
- used = true;
- }
- }
-
- // Easter eggs
- switch (state->scene) {
- case SCENE_SPLASH: // Scenes that do NOT offer Easter eggs
- case SCENE_RIP:
- case SCENE_DEBUG:
- break;
- default:
- if (msg->input.type == InputTypeLong) {
- switch (msg->input.key) {
- case InputKeyDown: //# >D [LONG-DOWN]
- timerEn(state, false); // Stop the timer
- sceneSetEgg(state, SCENE_DEBUG);
- used = true;
- break;
-
- case InputKeyLeft: //# >L [ LONG-LEFT ]
- timerEn(state, false); // Stop the timer
- sceneSetEgg(state, SCENE_SPLASH);
- used = true;
- break;
-
- case InputKeyUp: //# >U [ LONG-UP ]
- timerEn(state, false); // Stop the timer
- sceneSetEgg(state, SCENE_RIP);
- used = true;
- break;
-
- default: break ;
- }
- }
- break;
- }
-
- return used;
+static inline bool key_post(const eventMsg_t* const msg, state_t* const state) {
+ int used = false; // assume key is NOT-handled
+
+ if(msg->input.key == InputKeyBack) {
+ if(msg->input.type == InputTypeShort) { //# ec.init = false; // reset/disconnect the controller
+ sceneSet(state, SCENE_WAIT);
+ used = true;
+
+ } else if(msg->input.type == InputTypeLong) { //# >B [LONG-BACK]
+ state->run = false; // Signal the plugin to exit
+ used = true;
+ }
+ }
+
+ // Easter eggs
+ switch(state->scene) {
+ case SCENE_SPLASH: // Scenes that do NOT offer Easter eggs
+ case SCENE_RIP:
+ case SCENE_DEBUG:
+ break;
+ default:
+ if(msg->input.type == InputTypeLong) {
+ switch(msg->input.key) {
+ case InputKeyDown: //# >D [LONG-DOWN]
+ timerEn(state, false); // Stop the timer
+ sceneSetEgg(state, SCENE_DEBUG);
+ used = true;
+ break;
+
+ case InputKeyLeft: //# >L [ LONG-LEFT ]
+ timerEn(state, false); // Stop the timer
+ sceneSetEgg(state, SCENE_SPLASH);
+ used = true;
+ break;
+
+ case InputKeyUp: //# >U [ LONG-UP ]
+ timerEn(state, false); // Stop the timer
+ sceneSetEgg(state, SCENE_RIP);
+ used = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+ }
+
+ return used;
}
//+============================================================================ ========================================
// Handle a key press event
//
-bool evKey (const eventMsg_t* const msg, state_t* const state)
-{
- furi_assert(msg);
- furi_assert(state);
-
- bool used = key_pre(msg, state);
-
- if (!used) switch (state->scene) {
- case SCENE_SPLASH: //...
- case SCENE_RIP: used = splash_key(msg, state); break ;
-
- case SCENE_WAIT: used = wait_key(msg, state); break ;
- case SCENE_DEBUG: used = debug_key(msg, state); break ;
-
- default:
- if (state->ec.pidx >= PID_ERROR) {
- ERROR("%s : bad PID = %d", __func__, state->ec.pidx);
- } else {
- if ((state->scene == SCENE_DUMP) || !ecId[state->ec.pidx].keys)
- ecId[PID_UNKNOWN].keys(msg, state);
- else
- ecId[state->ec.pidx].keys(msg, state);
- }
- break;
-
- case SCENE_NONE: break;
- }
-
- if (!used) used = key_post(msg, state) ;
-
- return used;
+bool evKey(const eventMsg_t* const msg, state_t* const state) {
+ furi_assert(msg);
+ furi_assert(state);
+
+ bool used = key_pre(msg, state);
+
+ if(!used) switch(state->scene) {
+ case SCENE_SPLASH: //...
+ case SCENE_RIP:
+ used = splash_key(msg, state);
+ break;
+
+ case SCENE_WAIT:
+ used = wait_key(msg, state);
+ break;
+ case SCENE_DEBUG:
+ used = debug_key(msg, state);
+ break;
+
+ default:
+ if(state->ec.pidx >= PID_ERROR) {
+ ERROR("%s : bad PID = %d", __func__, state->ec.pidx);
+ } else {
+ if((state->scene == SCENE_DUMP) || !ecId[state->ec.pidx].keys)
+ ecId[PID_UNKNOWN].keys(msg, state);
+ else
+ ecId[state->ec.pidx].keys(msg, state);
+ }
+ break;
+
+ case SCENE_NONE:
+ break;
+ }
+
+ if(!used) used = key_post(msg, state);
+
+ return used;
}
-
diff --git a/applications/plugins/wii_ec_anal/wii_anal_keys.h b/applications/plugins/wii_ec_anal/wii_anal_keys.h
index 0ebbd5e8e4..c10fcd1ef7 100644
--- a/applications/plugins/wii_ec_anal/wii_anal_keys.h
+++ b/applications/plugins/wii_ec_anal/wii_anal_keys.h
@@ -1,16 +1,16 @@
-#ifndef WII_ANAL_KEYS_H_
-#define WII_ANAL_KEYS_H_
+#ifndef WII_ANAL_KEYS_H_
+#define WII_ANAL_KEYS_H_
//============================================================================= ========================================
// Function prototypes
//
-#include // bool
-typedef struct eventMsg eventMsg_t ;
-typedef struct state state_t ;
-typedef enum scene scene_t ;
+#include // bool
+typedef struct eventMsg eventMsg_t;
+typedef struct state state_t;
+typedef enum scene scene_t;
-void sceneSet (state_t* const state, const scene_t scene) ;
-bool key_calib (const eventMsg_t* const msg, state_t* const state) ;
-bool evKey (const eventMsg_t* const msg, state_t* const state) ;
+void sceneSet(state_t* const state, const scene_t scene);
+bool key_calib(const eventMsg_t* const msg, state_t* const state);
+bool evKey(const eventMsg_t* const msg, state_t* const state);
#endif //WII_ANAL_KEYS_H_
diff --git a/applications/plugins/wii_ec_anal/wii_anal_lcd.c b/applications/plugins/wii_ec_anal/wii_anal_lcd.c
index d031bc1203..921a3708e9 100644
--- a/applications/plugins/wii_ec_anal/wii_anal_lcd.c
+++ b/applications/plugins/wii_ec_anal/wii_anal_lcd.c
@@ -1,17 +1,45 @@
-#include "wii_anal.h"
-#include "gfx/images.h" // Images
+#include "wii_anal.h"
+#include "gfx/images.h" // Images
//----------------------------------------------------------------------------- ----------------------------------------
// A couple of monospaced hex fonts
//
-const image_t* img_6x8[16] = {
- &img_6x8_0, &img_6x8_1, &img_6x8_2, &img_6x8_3, &img_6x8_4, &img_6x8_5, &img_6x8_6, &img_6x8_7,
- &img_6x8_8, &img_6x8_9, &img_6x8_A, &img_6x8_B, &img_6x8_C, &img_6x8_D, &img_6x8_E, &img_6x8_F,
+const image_t* img_6x8[16] = {
+ &img_6x8_0,
+ &img_6x8_1,
+ &img_6x8_2,
+ &img_6x8_3,
+ &img_6x8_4,
+ &img_6x8_5,
+ &img_6x8_6,
+ &img_6x8_7,
+ &img_6x8_8,
+ &img_6x8_9,
+ &img_6x8_A,
+ &img_6x8_B,
+ &img_6x8_C,
+ &img_6x8_D,
+ &img_6x8_E,
+ &img_6x8_F,
};
-const image_t* img_5x7[16] = {
- &img_5x7_0, &img_5x7_1, &img_5x7_2, &img_5x7_3, &img_5x7_4, &img_5x7_5, &img_5x7_6, &img_5x7_7,
- &img_5x7_8, &img_5x7_9, &img_5x7_A, &img_5x7_B, &img_5x7_C, &img_5x7_D, &img_5x7_E, &img_5x7_F,
+const image_t* img_5x7[16] = {
+ &img_5x7_0,
+ &img_5x7_1,
+ &img_5x7_2,
+ &img_5x7_3,
+ &img_5x7_4,
+ &img_5x7_5,
+ &img_5x7_6,
+ &img_5x7_7,
+ &img_5x7_8,
+ &img_5x7_9,
+ &img_5x7_A,
+ &img_5x7_B,
+ &img_5x7_C,
+ &img_5x7_D,
+ &img_5x7_E,
+ &img_5x7_F,
};
//+============================================================================ ========================================
@@ -30,66 +58,71 @@ const image_t* img_5x7[16] = {
// // Do this ONCE ... at plugin quit
// furi_record_close(RECORD_NOTIFICATION);
// }
-void patBacklight (state_t* state)
-{
- notification_message(state->notify, &sequence_display_backlight_on);
+void patBacklight(state_t* state) {
+ notification_message(state->notify, &sequence_display_backlight_on);
}
//============================================================================= ========================================
// Show a hex number in an inverted box (for ananlogue readings)
//
-void showHex ( Canvas* const canvas, uint8_t x, uint8_t y,
- const uint32_t val, const uint8_t cnt, const int b )
-{
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_box(canvas, x++,y++, 1 +(cnt *(6 +1)), 10);
+void showHex(
+ Canvas* const canvas,
+ uint8_t x,
+ uint8_t y,
+ const uint32_t val,
+ const uint8_t cnt,
+ const int b) {
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_box(canvas, x++, y++, 1 + (cnt * (6 + 1)), 10);
- // thicken border
- if (b == 2) canvas_draw_frame(canvas, x-2,y-2, 1 +(cnt *(6 +1))+2, 10+2);
+ // thicken border
+ if(b == 2) canvas_draw_frame(canvas, x - 2, y - 2, 1 + (cnt * (6 + 1)) + 2, 10 + 2);
- for (int i = (cnt -1) *4; i >= 0; i -= 4, x += 6+1)
- show(canvas, x,y, img_6x8[(val >>i) &0xF], SHOW_SET_WHT) ;
+ for(int i = (cnt - 1) * 4; i >= 0; i -= 4, x += 6 + 1)
+ show(canvas, x, y, img_6x8[(val >> i) & 0xF], SHOW_SET_WHT);
}
//============================================================================= ========================================
// Show the up/down "peak hold" controls in the bottom right
//
-void showPeakHold (state_t* const state, Canvas* const canvas, const int hold)
-{
- switch (hold) {
- case 0:
- show(canvas, 119,51, &img_key_U, SHOW_CLR_BLK);
- show(canvas, 119,56, &img_key_D, SHOW_CLR_BLK);
- break;
- case +1:
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_box(canvas, 120,52, 7,6);
- show(canvas, 119,51, &img_key_U, SHOW_CLR_WHT);
- show(canvas, 119,56, &img_key_D, SHOW_CLR_BLK);
- break;
- case -1:
- show(canvas, 119,51, &img_key_U, SHOW_CLR_BLK);
- canvas_draw_box(canvas, 120,57, 7,6);
- show(canvas, 119,56, &img_key_D, SHOW_CLR_WHT);
- break;
- default:
- break;
- }
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_frame(canvas, 119,51, 9,13);
-
- // calibration indicator
- show( canvas, 108,55,
- ((state->calib & CAL_RANGE) && (++state->flash &8)) ? &img_key_OKi : &img_key_OK,
- SHOW_SET_BLK );
+void showPeakHold(state_t* const state, Canvas* const canvas, const int hold) {
+ switch(hold) {
+ case 0:
+ show(canvas, 119, 51, &img_key_U, SHOW_CLR_BLK);
+ show(canvas, 119, 56, &img_key_D, SHOW_CLR_BLK);
+ break;
+ case +1:
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_box(canvas, 120, 52, 7, 6);
+ show(canvas, 119, 51, &img_key_U, SHOW_CLR_WHT);
+ show(canvas, 119, 56, &img_key_D, SHOW_CLR_BLK);
+ break;
+ case -1:
+ show(canvas, 119, 51, &img_key_U, SHOW_CLR_BLK);
+ canvas_draw_box(canvas, 120, 57, 7, 6);
+ show(canvas, 119, 56, &img_key_D, SHOW_CLR_WHT);
+ break;
+ default:
+ break;
+ }
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_frame(canvas, 119, 51, 9, 13);
+
+ // calibration indicator
+ show(
+ canvas,
+ 108,
+ 55,
+ ((state->calib & CAL_RANGE) && (++state->flash & 8)) ? &img_key_OKi : &img_key_OK,
+ SHOW_SET_BLK);
}
//============================================================================= ========================================
-// This code performs a FULL calibration on the device EVERY time it draws a joystick
+// This code performs a FULL calibration on the device EVERY time it draws a joystick
//...This is NOT a good way forward for anything other than a test tool.
//
// Realistically you would do all the maths when the controller is connected
-// or, if you prefer (and it IS a good thing), have a "calibrate controller" menu option
+// or, if you prefer (and it IS a good thing), have a "calibrate controller" menu option
// ...and then just use a lookup table, or trivial formual
//
// THIS algorithm chops the joystick in to one of 9 zones
@@ -97,12 +130,12 @@ void showPeakHold (state_t* const state, Canvas* const canvas, const int hold
// FullLeft and FullRight have a deadzone of N [qv. xDead] ..a total of N+1 positions
// Middle has a deadzone of N EACH WAY ...a total of 2N+1 positions
//
-// If the remaining range does not divide evenly in to three zones,
+// If the remaining range does not divide evenly in to three zones,
// the first remainder is added to zone3,
// and the second remainder (if there is one) is added to zone2
// ...giving finer control near the centre of the joystick
//
-// The value of the deadzone is based on the number of bits in the
+// The value of the deadzone is based on the number of bits in the
// joystcik {x,y} values - the larger the range, the larger the deadzone.
//
// 03 15 29
@@ -118,106 +151,132 @@ void showPeakHold (state_t* const state, Canvas* const canvas, const int hold
// Turn and object - this is probably good enough
// Start slowly & pick up speed - how about a log or sine curve?
//
-void showJoy ( Canvas* const canvas, const uint8_t x, const uint8_t y, // x,y is the CENTRE of the Joystick
- const uint8_t xMin, const uint8_t xMid, const uint8_t xMax,
- const uint8_t yMin, const uint8_t yMid, const uint8_t yMax,
- const uint8_t xPos, const uint8_t yPos, const uint8_t bits )
-{
- int xOff = 0; // final offset of joystick hat image
- int yOff = 0;
-
- int xDead = (bits < 7) ? (1<<0) : (1<<3); // dead zone (centre & limits)
- int yDead = xDead;
-
- // This code is NOT optimised ...and it's still barely readable!
- if ((xPos >= (xMid -xDead)) && (xPos <= (xMid +xDead))) xOff = 0 ; // centre [most likely]
- else if (xPos <= (xMin +xDead)) xOff = -4 ; // full left
- else if (xPos >= (xMax -xDead)) xOff = +4 ; // full right
- else if (xPos < (xMid -xDead)) { // part left
- // very much hard-coded for 3 interim positions
- int lo = (xMin +xDead) +1; // lowest position
- int hi = (xMid -xDead) -1; // highest position
-
- // this is the only duplicated bit of code
- int range = (hi -lo) +1; // range covered
- int div = range /3; // each division (base amount, eg. 17/3==5)
- int rem = range -(div *3); // remainder (ie. range%3)
-
-// int hi1 = hi; // lowest value for zone #-1
-// int lo1 = hi1 -div +1; // highest value for zone #-1
-// int hi2 = lo1 -1; // lowest value for zone #-2
-// int lo2 = hi2 -div +1 -(rem==2); // highest value for zone #-2 expand out remainder
-// int hi3 = lo2 -1; // lowest value for zone #-3
-// int lo3 = hi3 -div +1 -(rem>=1); // highest value for zone #-3 expand out remainder
-
- int lo1 = hi -div +1; // (in brevity)
- int hi3 = hi -div -div -(rem==2); // ...
-
- if (xPos <= hi3) xOff = -3 ; // zone #-3
- else if (xPos >= lo1) xOff = -1 ; // zone #-1
- else xOff = -2 ; // zone #-2
-
- } else /*if (xPos > (xMid +xDead))*/ { // part right
- // very much hard-coded for 3 interim positions
- int lo = (xMid +xDead) +1; // lowest position
- int hi = (xMax -xDead) -1; // highest position
-
- int range = (hi -lo) +1; // range covered
- int div = range /3; // each division (base amount, eg. 17/3==5)
- int rem = range -(div *3); // remainder (ie. range%3)
-
-// int lo1 = lo; // lowest value for zone #+1
-// int hi1 = lo +div -1; // highest value for zone #+1
-// int lo2 = hi1 +1; // lowest value for zone #+2
-// int hi2 = lo2 +div -1 +(rem==2); // highest value for zone #+2 expand out remainder
-// int lo3 = hi2 +1; // lowest value for zone #+3
-// int hi3 = lo3 +div -1 +(rem>=1); // highest value for zone #+3 expand out remainder
-
- int hi1 = lo +div -1; // (in brevity)
- int lo3 = lo +div +div +(rem==2); // ...
-
- if (xPos <= hi1) xOff = 1 ; // zone #1
- else if (xPos >= lo3) xOff = 3 ; // zone #3
- else xOff = 2 ; // zone #2
- }
-
- // All this to print a 3x3 square (in the right place) - LOL!
- if ((yPos >= (yMid -yDead)) && (yPos <= (yMid +yDead))) yOff = 0 ; // centre [most likely]
- else if (yPos <= (yMin +yDead)) yOff = +4 ; // full down
- else if (yPos >= (yMax -yDead)) yOff = -4 ; // full up
- else if (yPos < (yMid -yDead)) { // part down
- int lo = (yMin +yDead) +1; // lowest position
- int hi = (yMid -yDead) -1; // highest position
-
- int range = (hi -lo) +1; // range covered
- int div = range /3; // each division (base amount, eg. 17/3==5)
- int rem = range -(div *3); // remainder (ie. range%3)
-
- int lo1 = hi -div +1; // (in brevity)
- int hi3 = hi -div -div -(rem==2); // ...
-
- if (yPos <= hi3) yOff = +3 ; // zone #3
- else if (yPos >= lo1) yOff = +1 ; // zone #1
- else yOff = +2 ; // zone #2
-
- } else /*if (yPos > (yMid +yDead))*/ { // part up
- int lo = (yMid +yDead) +1; // lowest position
- int hi = (yMax -yDead) -1; // highest position
-
- int range = (hi -lo) +1; // range covered
- int div = range /3; // each division (base amount, eg. 17/3==5)
- int rem = range -(div *3); // remainder (ie. range%3)
-
- int hi1 = lo +div -1; // (in brevity)
- int lo3 = lo +div +div +(rem==2); // ...
-
- if (yPos <= hi1) yOff = -1 ; // zone #-1
- else if (yPos >= lo3) yOff = -3 ; // zone #-3
- else yOff = -2 ; // zone #-2
- }
-
- show(canvas, x-(img_cc_Joy.w/2),y-(img_cc_Joy.h/2), &img_cc_Joy, SHOW_SET_BLK);
-
- // All ^that^ for v-this-v - LOL!!
- canvas_draw_box(canvas, (x-1)+xOff,(y-1)+yOff, 3,3);
+void showJoy(
+ Canvas* const canvas,
+ const uint8_t x,
+ const uint8_t y, // x,y is the CENTRE of the Joystick
+ const uint8_t xMin,
+ const uint8_t xMid,
+ const uint8_t xMax,
+ const uint8_t yMin,
+ const uint8_t yMid,
+ const uint8_t yMax,
+ const uint8_t xPos,
+ const uint8_t yPos,
+ const uint8_t bits) {
+ int xOff = 0; // final offset of joystick hat image
+ int yOff = 0;
+
+ int xDead = (bits < 7) ? (1 << 0) : (1 << 3); // dead zone (centre & limits)
+ int yDead = xDead;
+
+ // This code is NOT optimised ...and it's still barely readable!
+ if((xPos >= (xMid - xDead)) && (xPos <= (xMid + xDead)))
+ xOff = 0; // centre [most likely]
+ else if(xPos <= (xMin + xDead))
+ xOff = -4; // full left
+ else if(xPos >= (xMax - xDead))
+ xOff = +4; // full right
+ else if(xPos < (xMid - xDead)) { // part left
+ // very much hard-coded for 3 interim positions
+ int lo = (xMin + xDead) + 1; // lowest position
+ int hi = (xMid - xDead) - 1; // highest position
+
+ // this is the only duplicated bit of code
+ int range = (hi - lo) + 1; // range covered
+ int div = range / 3; // each division (base amount, eg. 17/3==5)
+ int rem = range - (div * 3); // remainder (ie. range%3)
+
+ // int hi1 = hi; // lowest value for zone #-1
+ // int lo1 = hi1 -div +1; // highest value for zone #-1
+ // int hi2 = lo1 -1; // lowest value for zone #-2
+ // int lo2 = hi2 -div +1 -(rem==2); // highest value for zone #-2 expand out remainder
+ // int hi3 = lo2 -1; // lowest value for zone #-3
+ // int lo3 = hi3 -div +1 -(rem>=1); // highest value for zone #-3 expand out remainder
+
+ int lo1 = hi - div + 1; // (in brevity)
+ int hi3 = hi - div - div - (rem == 2); // ...
+
+ if(xPos <= hi3)
+ xOff = -3; // zone #-3
+ else if(xPos >= lo1)
+ xOff = -1; // zone #-1
+ else
+ xOff = -2; // zone #-2
+
+ } else /*if (xPos > (xMid +xDead))*/ { // part right
+ // very much hard-coded for 3 interim positions
+ int lo = (xMid + xDead) + 1; // lowest position
+ int hi = (xMax - xDead) - 1; // highest position
+
+ int range = (hi - lo) + 1; // range covered
+ int div = range / 3; // each division (base amount, eg. 17/3==5)
+ int rem = range - (div * 3); // remainder (ie. range%3)
+
+ // int lo1 = lo; // lowest value for zone #+1
+ // int hi1 = lo +div -1; // highest value for zone #+1
+ // int lo2 = hi1 +1; // lowest value for zone #+2
+ // int hi2 = lo2 +div -1 +(rem==2); // highest value for zone #+2 expand out remainder
+ // int lo3 = hi2 +1; // lowest value for zone #+3
+ // int hi3 = lo3 +div -1 +(rem>=1); // highest value for zone #+3 expand out remainder
+
+ int hi1 = lo + div - 1; // (in brevity)
+ int lo3 = lo + div + div + (rem == 2); // ...
+
+ if(xPos <= hi1)
+ xOff = 1; // zone #1
+ else if(xPos >= lo3)
+ xOff = 3; // zone #3
+ else
+ xOff = 2; // zone #2
+ }
+
+ // All this to print a 3x3 square (in the right place) - LOL!
+ if((yPos >= (yMid - yDead)) && (yPos <= (yMid + yDead)))
+ yOff = 0; // centre [most likely]
+ else if(yPos <= (yMin + yDead))
+ yOff = +4; // full down
+ else if(yPos >= (yMax - yDead))
+ yOff = -4; // full up
+ else if(yPos < (yMid - yDead)) { // part down
+ int lo = (yMin + yDead) + 1; // lowest position
+ int hi = (yMid - yDead) - 1; // highest position
+
+ int range = (hi - lo) + 1; // range covered
+ int div = range / 3; // each division (base amount, eg. 17/3==5)
+ int rem = range - (div * 3); // remainder (ie. range%3)
+
+ int lo1 = hi - div + 1; // (in brevity)
+ int hi3 = hi - div - div - (rem == 2); // ...
+
+ if(yPos <= hi3)
+ yOff = +3; // zone #3
+ else if(yPos >= lo1)
+ yOff = +1; // zone #1
+ else
+ yOff = +2; // zone #2
+
+ } else /*if (yPos > (yMid +yDead))*/ { // part up
+ int lo = (yMid + yDead) + 1; // lowest position
+ int hi = (yMax - yDead) - 1; // highest position
+
+ int range = (hi - lo) + 1; // range covered
+ int div = range / 3; // each division (base amount, eg. 17/3==5)
+ int rem = range - (div * 3); // remainder (ie. range%3)
+
+ int hi1 = lo + div - 1; // (in brevity)
+ int lo3 = lo + div + div + (rem == 2); // ...
+
+ if(yPos <= hi1)
+ yOff = -1; // zone #-1
+ else if(yPos >= lo3)
+ yOff = -3; // zone #-3
+ else
+ yOff = -2; // zone #-2
+ }
+
+ show(canvas, x - (img_cc_Joy.w / 2), y - (img_cc_Joy.h / 2), &img_cc_Joy, SHOW_SET_BLK);
+
+ // All ^that^ for v-this-v - LOL!!
+ canvas_draw_box(canvas, (x - 1) + xOff, (y - 1) + yOff, 3, 3);
}
diff --git a/applications/plugins/wii_ec_anal/wii_anal_lcd.h b/applications/plugins/wii_ec_anal/wii_anal_lcd.h
index 5258c4de1f..e52a3adc67 100644
--- a/applications/plugins/wii_ec_anal/wii_anal_lcd.h
+++ b/applications/plugins/wii_ec_anal/wii_anal_lcd.h
@@ -1,43 +1,57 @@
-#ifndef WII_ANAL_LCD_H_
-#define WII_ANAL_LCD_H_
+#ifndef WII_ANAL_LCD_H_
+#define WII_ANAL_LCD_H_
//----------------------------------------------------------------------------- ----------------------------------------
// A couple of monospaced hex fonts
//
#include "gfx/images.h"
-extern const image_t* img_6x8[];
-extern const image_t* img_5x7[];
+extern const image_t* img_6x8[];
+extern const image_t* img_5x7[];
//============================================================================= ========================================
// macros to draw only two sides of a box
// these are used for drawing the wires on the WAIT screen
//
-#define BOX_TL(x1,y1,x2,y2) do { \
- canvas_draw_frame(canvas, x1,y1, x2-x1+1,2); \
- canvas_draw_frame(canvas, x1,y1+2, 2,y2-y1+1-2); \
-}while(0)
-
-#define BOX_BL(x1,y1,x2,y2) do { \
- canvas_draw_frame(canvas, x1,y2-1, x2-x1+1,2); \
- canvas_draw_frame(canvas, x1,y1, 2,y2-y1+1-2); \
-}while(0)
-
+#define BOX_TL(x1, y1, x2, y2) \
+ do { \
+ canvas_draw_frame(canvas, x1, y1, x2 - x1 + 1, 2); \
+ canvas_draw_frame(canvas, x1, y1 + 2, 2, y2 - y1 + 1 - 2); \
+ } while(0)
+
+#define BOX_BL(x1, y1, x2, y2) \
+ do { \
+ canvas_draw_frame(canvas, x1, y2 - 1, x2 - x1 + 1, 2); \
+ canvas_draw_frame(canvas, x1, y1, 2, y2 - y1 + 1 - 2); \
+ } while(0)
//============================================================================= ========================================
// Function prototypes
//
-void patBacklight (state_t* state) ;
-
-void showHex ( Canvas* const canvas, uint8_t x, uint8_t y,
- const uint32_t val, const uint8_t cnt, const int b ) ;
-
-void showPeakHold (state_t* const state, Canvas* const canvas, const int hold) ;
-
-void showJoy ( Canvas* const canvas, const uint8_t x, const uint8_t y, // x,y is the CENTRE of the Joystick
- const uint8_t xMin, const uint8_t xMid, const uint8_t xMax,
- const uint8_t yMin, const uint8_t yMid, const uint8_t yMax,
- const uint8_t xPos, const uint8_t yPos, const uint8_t bits ) ;
-
+void patBacklight(state_t* state);
+
+void showHex(
+ Canvas* const canvas,
+ uint8_t x,
+ uint8_t y,
+ const uint32_t val,
+ const uint8_t cnt,
+ const int b);
+
+void showPeakHold(state_t* const state, Canvas* const canvas, const int hold);
+
+void showJoy(
+ Canvas* const canvas,
+ const uint8_t x,
+ const uint8_t y, // x,y is the CENTRE of the Joystick
+ const uint8_t xMin,
+ const uint8_t xMid,
+ const uint8_t xMax,
+ const uint8_t yMin,
+ const uint8_t yMid,
+ const uint8_t yMax,
+ const uint8_t xPos,
+ const uint8_t yPos,
+ const uint8_t bits);
#endif //WII_ANAL_LCD_H_
diff --git a/applications/plugins/wii_ec_anal/wii_anal_ver.h b/applications/plugins/wii_ec_anal/wii_anal_ver.h
index 88ed17d194..3f2c8c0e6d 100644
--- a/applications/plugins/wii_ec_anal/wii_anal_ver.h
+++ b/applications/plugins/wii_ec_anal/wii_anal_ver.h
@@ -1,9 +1,9 @@
-#ifndef WII_ANAL_VER_H_
-#define WII_ANAL_VER_H_
+#ifndef WII_ANAL_VER_H_
+#define WII_ANAL_VER_H_
-#include "gfx/images.h"
+#include "gfx/images.h"
-#define VER_MAJ &img_3x5_1
-#define VER_MIN &img_3x5_0
+#define VER_MAJ &img_3x5_1
+#define VER_MIN &img_3x5_0
#endif //WII_ANAL_VER_H_
diff --git a/applications/plugins/wii_ec_anal/wii_ec.c b/applications/plugins/wii_ec_anal/wii_ec.c
index 93b17c67cd..00dcbf9222 100644
--- a/applications/plugins/wii_ec_anal/wii_ec.c
+++ b/applications/plugins/wii_ec_anal/wii_ec.c
@@ -1,220 +1,298 @@
-#include
-#include // Core API
+#include
+#include // Core API
-#include "wii_anal.h"
-#include "wii_i2c.h"
-#include "wii_ec.h"
-#include "bc_logging.h"
+#include "wii_anal.h"
+#include "wii_i2c.h"
+#include "wii_ec.h"
+#include "bc_logging.h"
-#include "gfx/images.h" // Images
-#include "wii_anal_lcd.h" // Drawing functions
-#include "wii_anal_keys.h" // key mappings
+#include "gfx/images.h" // Images
+#include "wii_anal_lcd.h" // Drawing functions
+#include "wii_anal_keys.h" // key mappings
//----------------------------------------------------------------------------- ----------------------------------------
// List of known perhipherals
//
// More perhipheral ID codes here: https://wiibrew.org/wiki/Wiimote/Extension_Controllers#The_New_Way
//
-const ecId_t ecId[PID_CNT] = {
- [PID_UNKNOWN ] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "Unknown Perhipheral", SCENE_DUMP,
- NULL, NULL, NULL, NULL, ec_show, ec_key},
-
- // If you're wise, ONLY edit this bit
- [PID_NUNCHUCK ] = { {0x00, 0x00, 0xA4, 0x20, 0x00, 0x00}, "Nunchuck", SCENE_NUNCHUCK,
- NULL, nunchuck_decode, nunchuck_msg, nunchuck_calib, nunchuck_show, nunchuck_key },
-
- [PID_NUNCHUCK_R2] = { {0xFF, 0x00, 0xA4, 0x20, 0x00, 0x00}, "Nunchuck (rev2)", SCENE_NUNCHUCK,
- NULL, nunchuck_decode, nunchuck_msg, nunchuck_calib, nunchuck_show, nunchuck_key },
-
- [PID_CLASSIC ] = { {0x00, 0x00, 0xA4, 0x20, 0x01, 0x01}, "Classic Controller", SCENE_CLASSIC,
- NULL, classic_decode, classic_msg, classic_calib, classic_show, classic_key },
-
- [PID_CLASSIC_PRO] = { {0x01, 0x00, 0xA4, 0x20, 0x01, 0x01}, "Classic Controller Pro", SCENE_CLASSIC,
- NULL, classic_decode, classic_msg, classic_calib, classic_show, classic_key },
-
- [PID_BALANCE ] = { {0x00, 0x00, 0xA4, 0x20, 0x04, 0x02}, "Balance Board", SCENE_DUMP,
- NULL, NULL, NULL, NULL, NULL, NULL },
-
- [PID_GH_GUITAR ] = { {0x00, 0x00, 0xA4, 0x20, 0x01, 0x03}, "Guitar Hero Guitar", SCENE_DUMP,
- NULL, NULL, NULL, NULL, NULL, NULL },
-
- [PID_GH_DRUMS ] = { {0x01, 0x00, 0xA4, 0x20, 0x01, 0x03}, "Guitar Hero World Tour Drums", SCENE_DUMP,
- NULL, NULL, NULL, NULL, NULL, NULL },
-
- [PID_TURNTABLE ] = { {0x03, 0x00, 0xA4, 0x20, 0x01, 0x03}, "DJ Hero Turntable", SCENE_DUMP,
- NULL, NULL, NULL, NULL, NULL, NULL },
-
- [PID_TAIKO_DRUMS] = { {0x00, 0x00, 0xA4, 0x20, 0x01, 0x11}, "Taiko Drum Controller)", SCENE_DUMP,
- NULL, NULL, NULL, NULL, NULL, NULL }, // Taiko no Tatsujin TaTaCon (Drum controller)
-
- [PID_UDRAW ] = { {0xFF, 0x00, 0xA4, 0x20, 0x00, 0x13}, "uDraw Tablet", SCENE_DUMP,
- udraw_init, NULL, NULL, NULL, NULL, NULL }, //! same as drawsome?
- // -----
-
- [PID_ERROR ] = { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, "Read Error", SCENE_NONE,
- NULL, NULL, NULL, NULL, NULL, NULL },
-
- [PID_NULL ] = { {0}, NULL, SCENE_NONE, NULL, NULL, NULL, NULL, NULL, NULL } // last entry
+const ecId_t ecId[PID_CNT] = {
+ [PID_UNKNOWN] =
+ {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ "Unknown Perhipheral",
+ SCENE_DUMP,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ ec_show,
+ ec_key},
+
+ // If you're wise, ONLY edit this bit
+ [PID_NUNCHUCK] =
+ {{0x00, 0x00, 0xA4, 0x20, 0x00, 0x00},
+ "Nunchuck",
+ SCENE_NUNCHUCK,
+ NULL,
+ nunchuck_decode,
+ nunchuck_msg,
+ nunchuck_calib,
+ nunchuck_show,
+ nunchuck_key},
+
+ [PID_NUNCHUCK_R2] =
+ {{0xFF, 0x00, 0xA4, 0x20, 0x00, 0x00},
+ "Nunchuck (rev2)",
+ SCENE_NUNCHUCK,
+ NULL,
+ nunchuck_decode,
+ nunchuck_msg,
+ nunchuck_calib,
+ nunchuck_show,
+ nunchuck_key},
+
+ [PID_CLASSIC] =
+ {{0x00, 0x00, 0xA4, 0x20, 0x01, 0x01},
+ "Classic Controller",
+ SCENE_CLASSIC,
+ NULL,
+ classic_decode,
+ classic_msg,
+ classic_calib,
+ classic_show,
+ classic_key},
+
+ [PID_CLASSIC_PRO] =
+ {{0x01, 0x00, 0xA4, 0x20, 0x01, 0x01},
+ "Classic Controller Pro",
+ SCENE_CLASSIC,
+ NULL,
+ classic_decode,
+ classic_msg,
+ classic_calib,
+ classic_show,
+ classic_key},
+
+ [PID_BALANCE] =
+ {{0x00, 0x00, 0xA4, 0x20, 0x04, 0x02},
+ "Balance Board",
+ SCENE_DUMP,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ [PID_GH_GUITAR] =
+ {{0x00, 0x00, 0xA4, 0x20, 0x01, 0x03},
+ "Guitar Hero Guitar",
+ SCENE_DUMP,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ [PID_GH_DRUMS] =
+ {{0x01, 0x00, 0xA4, 0x20, 0x01, 0x03},
+ "Guitar Hero World Tour Drums",
+ SCENE_DUMP,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ [PID_TURNTABLE] =
+ {{0x03, 0x00, 0xA4, 0x20, 0x01, 0x03},
+ "DJ Hero Turntable",
+ SCENE_DUMP,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ [PID_TAIKO_DRUMS] =
+ {{0x00, 0x00, 0xA4, 0x20, 0x01, 0x11},
+ "Taiko Drum Controller)",
+ SCENE_DUMP,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL}, // Taiko no Tatsujin TaTaCon (Drum controller)
+
+ [PID_UDRAW] =
+ {{0xFF, 0x00, 0xA4, 0x20, 0x00, 0x13},
+ "uDraw Tablet",
+ SCENE_DUMP,
+ udraw_init,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL}, //! same as drawsome?
+ // -----
+
+ [PID_ERROR] =
+ {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ "Read Error",
+ SCENE_NONE,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ [PID_NULL] = {{0}, NULL, SCENE_NONE, NULL, NULL, NULL, NULL, NULL, NULL} // last entry
};
//+============================================================================ ========================================
-void ecDecode (wiiEC_t* pec)
-{
- if (ecId[pec->pidx].decode) ecId[pec->pidx].decode(pec) ;
+void ecDecode(wiiEC_t* pec) {
+ if(ecId[pec->pidx].decode) ecId[pec->pidx].decode(pec);
}
//+============================================================================ ========================================
-void ecCalibrate (wiiEC_t* const pec, ecCalib_t c)
-{
- if (ecId[pec->pidx].calib) ecId[pec->pidx].calib(pec, c) ;
+void ecCalibrate(wiiEC_t* const pec, ecCalib_t c) {
+ if(ecId[pec->pidx].calib) ecId[pec->pidx].calib(pec, c);
}
//+============================================================================ ========================================
-void ecPoll (wiiEC_t* const pec, FuriMessageQueue* const queue)
-{
- ENTER;
- furi_assert(queue);
-
- if (!pec->init) {
- // Attempt to initialise
- if (ecInit(pec, NULL)) { //! need a way to auto-start with encryption enabled
- eventMsg_t msg = {
- .id = EVID_WIIEC,
- .wiiEc = {
- .type = WIIEC_CONN,
- .in = '<',
- .val = pec->pidx
- }
- };
- furi_message_queue_put(queue, &msg, 0);
- }
-
- } else {
- // Attempt to read
- switch (ecRead(pec)) {
- case 2: { // device gone
- eventMsg_t msg = {
- .id = EVID_WIIEC,
- .wiiEc = {
- .type = WIIEC_DISCONN,
- .in = '>',
- .val = pec->pidx
- }
- };
- furi_message_queue_put(queue, &msg, 0);
- break;
- }
-
- case 0: { // read OK
- void (*fn)(wiiEC_t*, FuriMessageQueue*) = ecId[pec->pidx].check;
- if (fn) fn(pec, queue);
- break;
- }
-
- case 3: // read fail
- // this is probably temporary just ignore it
- break;
-
- default: // bug: unknown
- case 1: // bug: not initialised - should never happen
- ERROR("%s : read bug", __func__);
- break;
- }
- }
-
- LEAVE;
- return;
+void ecPoll(wiiEC_t* const pec, FuriMessageQueue* const queue) {
+ ENTER;
+ furi_assert(queue);
+
+ if(!pec->init) {
+ // Attempt to initialise
+ if(ecInit(pec, NULL)) { //! need a way to auto-start with encryption enabled
+ eventMsg_t msg = {
+ .id = EVID_WIIEC, .wiiEc = {.type = WIIEC_CONN, .in = '<', .val = pec->pidx}};
+ furi_message_queue_put(queue, &msg, 0);
+ }
+
+ } else {
+ // Attempt to read
+ switch(ecRead(pec)) {
+ case 2: { // device gone
+ eventMsg_t msg = {
+ .id = EVID_WIIEC, .wiiEc = {.type = WIIEC_DISCONN, .in = '>', .val = pec->pidx}};
+ furi_message_queue_put(queue, &msg, 0);
+ break;
+ }
+
+ case 0: { // read OK
+ void (*fn)(wiiEC_t*, FuriMessageQueue*) = ecId[pec->pidx].check;
+ if(fn) fn(pec, queue);
+ break;
+ }
+
+ case 3: // read fail
+ // this is probably temporary just ignore it
+ break;
+
+ default: // bug: unknown
+ case 1: // bug: not initialised - should never happen
+ ERROR("%s : read bug", __func__);
+ break;
+ }
+ }
+
+ LEAVE;
+ return;
}
//+============================================================================ ========================================
// This is the screen drawn for an unknown controller
// It is also available by pressing LEFT (at least once) on a "known controller" screen
//
-void ec_show (Canvas* const canvas, state_t* const state)
-{
- wiiEC_t* pec = &state->ec;
- int h = 11; // line height
- int x = 1; // (initial) offset for bits
- int y = -h; // previous y value
- int yb = 0; // y for bit patterns
- int c2 = 17; // column 2
-
- // Headings
- canvas_set_font(canvas, FontSecondary);
- canvas_set_color(canvas, ColorBlack);
-
- canvas_draw_str_aligned(canvas, 0 ,0, AlignLeft, AlignTop, "SID:");
- canvas_draw_str_aligned(canvas, c2,0, AlignLeft, AlignTop, pec->sid);
-
- canvas_draw_str_aligned(canvas, 0 ,11, AlignLeft, AlignTop, "PID:");
- canvas_draw_str_aligned(canvas, 0 ,22, AlignLeft, AlignTop, "Cal:");
-
- // PID
- x = c2;
- for (int i = 0; i < 6; i++) {
- show(canvas, x,11, img_5x7[pec->pid[i]>>4], SHOW_SET_BLK);
- x += 5+1;
- show(canvas, x,11, img_5x7[pec->pid[i]&0xF], SHOW_SET_BLK);
- x += 5+1+2;
- }
-
- // Calibrations data
- y = 11;
- for (int j = 0; j <= 8; j += 8) {
- x = c2;
- y += 11;
- for (int i = 0; i < 8; i++) {
- show(canvas, x,y, img_5x7[pec->calF[i+j]>>4], SHOW_SET_BLK);
- x += 5+1;
- show(canvas, x,y, img_5x7[pec->calF[i+j]&0xF], SHOW_SET_BLK);
- x += 5+1+2;
- }
- }
-
- // Reading
- x = 1;
- y++;
- yb = (y+=h) +h +2;
-
- canvas_draw_line(canvas, x,y-1, x,yb+4);
- x += 2;
-
- for (int i = 0; i < JOY_LEN; i++) {
- show(canvas, x+ 1,y, img_6x8[pec->joy[i]>>4], SHOW_SET_BLK);
- show(canvas, x+11,y, img_6x8[pec->joy[i]&0xF], SHOW_SET_BLK);
-
- // bits
- for (int m = 0x80; m; m >>= 1) {
- x += 2 * !!(m & 0x08) ; // nybble step
- canvas_draw_box(canvas, x,yb +(2*!(pec->joy[i] & m)), 2,2) ;
- x += 2; // bit step
- }
-
- // byte step
- x += 1;
- canvas_draw_line(canvas, x,y-1, x,yb+4);
- x += 2;
- }
-
- // Scene navigation
- if (state->scenePrev != SCENE_WAIT)
- show(canvas, 120,0, &img_key_R, SHOW_SET_BLK);
+void ec_show(Canvas* const canvas, state_t* const state) {
+ wiiEC_t* pec = &state->ec;
+ int h = 11; // line height
+ int x = 1; // (initial) offset for bits
+ int y = -h; // previous y value
+ int yb = 0; // y for bit patterns
+ int c2 = 17; // column 2
+
+ // Headings
+ canvas_set_font(canvas, FontSecondary);
+ canvas_set_color(canvas, ColorBlack);
+
+ canvas_draw_str_aligned(canvas, 0, 0, AlignLeft, AlignTop, "SID:");
+ canvas_draw_str_aligned(canvas, c2, 0, AlignLeft, AlignTop, pec->sid);
+
+ canvas_draw_str_aligned(canvas, 0, 11, AlignLeft, AlignTop, "PID:");
+ canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, "Cal:");
+
+ // PID
+ x = c2;
+ for(int i = 0; i < 6; i++) {
+ show(canvas, x, 11, img_5x7[pec->pid[i] >> 4], SHOW_SET_BLK);
+ x += 5 + 1;
+ show(canvas, x, 11, img_5x7[pec->pid[i] & 0xF], SHOW_SET_BLK);
+ x += 5 + 1 + 2;
+ }
+
+ // Calibrations data
+ y = 11;
+ for(int j = 0; j <= 8; j += 8) {
+ x = c2;
+ y += 11;
+ for(int i = 0; i < 8; i++) {
+ show(canvas, x, y, img_5x7[pec->calF[i + j] >> 4], SHOW_SET_BLK);
+ x += 5 + 1;
+ show(canvas, x, y, img_5x7[pec->calF[i + j] & 0xF], SHOW_SET_BLK);
+ x += 5 + 1 + 2;
+ }
+ }
+
+ // Reading
+ x = 1;
+ y++;
+ yb = (y += h) + h + 2;
+
+ canvas_draw_line(canvas, x, y - 1, x, yb + 4);
+ x += 2;
+
+ for(int i = 0; i < JOY_LEN; i++) {
+ show(canvas, x + 1, y, img_6x8[pec->joy[i] >> 4], SHOW_SET_BLK);
+ show(canvas, x + 11, y, img_6x8[pec->joy[i] & 0xF], SHOW_SET_BLK);
+
+ // bits
+ for(int m = 0x80; m; m >>= 1) {
+ x += 2 * !!(m & 0x08); // nybble step
+ canvas_draw_box(canvas, x, yb + (2 * !(pec->joy[i] & m)), 2, 2);
+ x += 2; // bit step
+ }
+
+ // byte step
+ x += 1;
+ canvas_draw_line(canvas, x, y - 1, x, yb + 4);
+ x += 2;
+ }
+
+ // Scene navigation
+ if(state->scenePrev != SCENE_WAIT) show(canvas, 120, 0, &img_key_R, SHOW_SET_BLK);
}
//+============================================================================ ========================================
-// The DUMP screen is
+// The DUMP screen is
//
-bool ec_key (const eventMsg_t* const msg, state_t* const state)
-{
- int used = false; // assume key is NOT-handled
-
- if (state->scenePrev != SCENE_WAIT) {
- //# input.type == InputTypeShort) && (msg->input.key == InputKeyRight)) {
- sceneSet(state, state->scenePrev);
- used = true;
- }
- }
-
- return used;
+bool ec_key(const eventMsg_t* const msg, state_t* const state) {
+ int used = false; // assume key is NOT-handled
+
+ if(state->scenePrev != SCENE_WAIT) {
+ //# input.type == InputTypeShort) && (msg->input.key == InputKeyRight)) {
+ sceneSet(state, state->scenePrev);
+ used = true;
+ }
+ }
+
+ return used;
}
diff --git a/applications/plugins/wii_ec_anal/wii_ec.h b/applications/plugins/wii_ec_anal/wii_ec.h
index e8745ba13d..a284537405 100644
--- a/applications/plugins/wii_ec_anal/wii_ec.h
+++ b/applications/plugins/wii_ec_anal/wii_ec.h
@@ -1,158 +1,142 @@
-#ifndef WII_EC_H_
-#define WII_EC_H_
+#ifndef WII_EC_H_
+#define WII_EC_H_
-#include
+#include
-#include
+#include
-#include "wii_ec_nunchuck.h"
-#include "wii_ec_classic.h"
-#include "wii_ec_udraw.h"
+#include "wii_ec_nunchuck.h"
+#include "wii_ec_classic.h"
+#include "wii_ec_udraw.h"
//----------------------------------------------------------------------------- ----------------------------------------
// Crypto key (PSK), base register : {0x40..0x4F}[2][8]
-#define ENC_LEN (2*8)
+#define ENC_LEN (2 * 8)
// Controller State data, base register : {0x00..0x05}[6]
-#define JOY_LEN (6)
+#define JOY_LEN (6)
// Calibration data, base register : {0x20..0x2F}[16]
-#define CAL_LEN (16)
+#define CAL_LEN (16)
// Controller ID, base register : {0xFA..0xFF}[6]
-#define PID_LEN (6)
+#define PID_LEN (6)
//----------------------------------------------------------------------------- ----------------------------------------
// Perhipheral specific parameters union
//
-typedef
- union ecDec {
- ecDecNunchuck_t nunchuck;
- ecDecClassic_t classic;
- }
-ecDec_t;
+typedef union ecDec {
+ ecDecNunchuck_t nunchuck;
+ ecDecClassic_t classic;
+} ecDec_t;
//-----------------------------------------------------------------------------
-typedef
- union ecCal {
- // 0=lowest seen ; 1=min ; 2=mid ; 3=max ; 4=highest seen
- ecCalNunchuck_t nunchuck[5];
- ecCalClassic_t classic[5];
- }
-ecCal_t;
+typedef union ecCal {
+ // 0=lowest seen ; 1=min ; 2=mid ; 3=max ; 4=highest seen
+ ecCalNunchuck_t nunchuck[5];
+ ecCalClassic_t classic[5];
+} ecCal_t;
//----------------------------------------------------------------------------- ----------------------------------------
// Wii Extension Controller events
//
-typedef
- enum wiiEcEventType {
- WIIEC_NONE,
- WIIEC_CONN, // Connect
- WIIEC_DISCONN, // Disconnect
- WIIEC_PRESS, // Press button
- WIIEC_RELEASE, // Release button
- WIIEC_ANALOG, // Analogue change (Joystick/Trigger)
- WIIEC_ACCEL, // Accelerometer change
- }
-wiiEcEventType_t;
+typedef enum wiiEcEventType {
+ WIIEC_NONE,
+ WIIEC_CONN, // Connect
+ WIIEC_DISCONN, // Disconnect
+ WIIEC_PRESS, // Press button
+ WIIEC_RELEASE, // Release button
+ WIIEC_ANALOG, // Analogue change (Joystick/Trigger)
+ WIIEC_ACCEL, // Accelerometer change
+} wiiEcEventType_t;
//-----------------------------------------------------------------------------
-typedef
- struct wiiEcEvent {
- wiiEcEventType_t type; // event type
- char in; // input (see device specific options)
- uint32_t val; // new value - meaningless for digital button presses
- }
-wiiEcEvent_t;
+typedef struct wiiEcEvent {
+ wiiEcEventType_t type; // event type
+ char in; // input (see device specific options)
+ uint32_t val; // new value - meaningless for digital button presses
+} wiiEcEvent_t;
//----------------------------------------------------------------------------- ----------------------------------------
// Known perhipheral types
//
-typedef
- enum ecPid {
- PID_UNKNOWN = 0,
- PID_FIRST = 1,
- PID_NUNCHUCK = PID_FIRST,
-
- // If you're wise, ONLY edit this section
- PID_NUNCHUCK_R2,
- PID_CLASSIC,
- PID_CLASSIC_PRO,
- PID_BALANCE,
- PID_GH_GUITAR,
- PID_GH_DRUMS,
- PID_TURNTABLE,
- PID_TAIKO_DRUMS,
- PID_UDRAW, //! same as drawsome?
- // -----
-
- PID_ERROR,
- PID_NULL,
- PID_CNT,
- }
-ecPid_t;
+typedef enum ecPid {
+ PID_UNKNOWN = 0,
+ PID_FIRST = 1,
+ PID_NUNCHUCK = PID_FIRST,
+
+ // If you're wise, ONLY edit this section
+ PID_NUNCHUCK_R2,
+ PID_CLASSIC,
+ PID_CLASSIC_PRO,
+ PID_BALANCE,
+ PID_GH_GUITAR,
+ PID_GH_DRUMS,
+ PID_TURNTABLE,
+ PID_TAIKO_DRUMS,
+ PID_UDRAW, //! same as drawsome?
+ // -----
+
+ PID_ERROR,
+ PID_NULL,
+ PID_CNT,
+} ecPid_t;
//-----------------------------------------------------------------------------
// Calibration strategies
//
-typedef
- enum ecCalib {
- CAL_FACTORY = 0x01, // (re)set to factory defaults
- CAL_TRACK = 0x02, // track maximum and minimum values seen
- CAL_RESET = 0x04, // initialise ready for software calibration
- CAL_RANGE = 0x08, // perform software calibration step
- CAL_CENTRE = 0x10, // reset centre point of joystick
- CAL_NOTJOY = 0x20, // do NOT calibrate the joystick
- }
-ecCalib_t;
+typedef enum ecCalib {
+ CAL_FACTORY = 0x01, // (re)set to factory defaults
+ CAL_TRACK = 0x02, // track maximum and minimum values seen
+ CAL_RESET = 0x04, // initialise ready for software calibration
+ CAL_RANGE = 0x08, // perform software calibration step
+ CAL_CENTRE = 0x10, // reset centre point of joystick
+ CAL_NOTJOY = 0x20, // do NOT calibrate the joystick
+} ecCalib_t;
//-----------------------------------------------------------------------------
// ecId table entry
//
-typedef
- struct ecId {
- uint8_t id[6]; // 6 byte ID string returned by Extension Controller
- char* name; // Friendly name
- scene_t scene; // Default scene
- bool (*init)(wiiEC_t*); // Additional initialisation code
- void (*decode)(wiiEC_t*); // Decode function
- void (*check)(wiiEC_t*, FuriMessageQueue*); // check (for action) function
- void (*calib)(wiiEC_t*, ecCalib_t); // calibrate analogue controllers [SOFTWARE]
- void (*show)(Canvas* const, state_t* const); // Draw scene
- bool (*keys)(const eventMsg_t* const, state_t* const); // Interpret keys
- }
-ecId_t;
+typedef struct ecId {
+ uint8_t id[6]; // 6 byte ID string returned by Extension Controller
+ char* name; // Friendly name
+ scene_t scene; // Default scene
+ bool (*init)(wiiEC_t*); // Additional initialisation code
+ void (*decode)(wiiEC_t*); // Decode function
+ void (*check)(wiiEC_t*, FuriMessageQueue*); // check (for action) function
+ void (*calib)(wiiEC_t*, ecCalib_t); // calibrate analogue controllers [SOFTWARE]
+ void (*show)(Canvas* const, state_t* const); // Draw scene
+ bool (*keys)(const eventMsg_t* const, state_t* const); // Interpret keys
+} ecId_t;
//-----------------------------------------------------------------------------
// List of known perhipherals
//
// More perhipheral ID codes here: https://wiibrew.org/wiki/Wiimote/Extension_Controllers#The_New_Way
//
-extern const ecId_t ecId[PID_CNT] ;
+extern const ecId_t ecId[PID_CNT];
//----------------------------------------------------------------------------- ----------------------------------------
// Data pertaining to a single Perhipheral instance
//
-typedef
- struct wiiEC {
- // Perhipheral state
- bool init; // Initialised?
+typedef struct wiiEC {
+ // Perhipheral state
+ bool init; // Initialised?
- uint8_t pid[PID_LEN]; // PID string - eg. {0x00, 0x00, 0xA4, 0x20, 0x00, 0x00}
- ecPid_t pidx; // Index in to ecId table
- const char* sid; // just for convenience
+ uint8_t pid[PID_LEN]; // PID string - eg. {0x00, 0x00, 0xA4, 0x20, 0x00, 0x00}
+ ecPid_t pidx; // Index in to ecId table
+ const char* sid; // just for convenience
- bool encrypt; // encryption enabled?
- uint8_t encKey[ENC_LEN]; // encryption key
+ bool encrypt; // encryption enabled?
+ uint8_t encKey[ENC_LEN]; // encryption key
- uint8_t calF[CAL_LEN]; // factory calibration data (not software)
- uint8_t joy[JOY_LEN]; // Perhipheral raw data
+ uint8_t calF[CAL_LEN]; // factory calibration data (not software)
+ uint8_t joy[JOY_LEN]; // Perhipheral raw data
- ecDec_t dec[2]; // device specific decode (two, so we can spot changes)
- int decN; // which decode set is most recent {0, 1}
- ecCal_t calS; // software calibration data
- }
-wiiEC_t;
+ ecDec_t dec[2]; // device specific decode (two, so we can spot changes)
+ int decN; // which decode set is most recent {0, 1}
+ ecCal_t calS; // software calibration data
+} wiiEC_t;
//----------------------------------------------------------------------------- ----------------------------------------
// Function prototypes
@@ -161,17 +145,17 @@ wiiEC_t;
// top level check() function will handle connect/disconnect messages
//
-#include // Canvas
-typedef struct wiiEC wiiEC_t ;
-typedef enum ecCalib ecCalib_t ;
-typedef struct state state_t ;
-typedef struct eventMsg eventMsg_t ;
+#include // Canvas
+typedef struct wiiEC wiiEC_t;
+typedef enum ecCalib ecCalib_t;
+typedef struct state state_t;
+typedef struct eventMsg eventMsg_t;
-void ecDecode (wiiEC_t* const pec) ;
-void ecPoll (wiiEC_t* const pec, FuriMessageQueue* const queue) ;
-void ecCalibrate (wiiEC_t* const pec, ecCalib_t c) ;
+void ecDecode(wiiEC_t* const pec);
+void ecPoll(wiiEC_t* const pec, FuriMessageQueue* const queue);
+void ecCalibrate(wiiEC_t* const pec, ecCalib_t c);
-void ec_show ( Canvas* const canvas, state_t* const state) ;
-bool ec_key (const eventMsg_t* const msg, state_t* const state) ;
+void ec_show(Canvas* const canvas, state_t* const state);
+bool ec_key(const eventMsg_t* const msg, state_t* const state);
#endif //WII_EC_H_
diff --git a/applications/plugins/wii_ec_anal/wii_ec_classic.c b/applications/plugins/wii_ec_anal/wii_ec_classic.c
index 91393ba075..5bd3398ca1 100644
--- a/applications/plugins/wii_ec_anal/wii_ec_classic.c
+++ b/applications/plugins/wii_ec_anal/wii_ec_classic.c
@@ -1,17 +1,17 @@
-#include
-#include // Core API
+#include
+#include // Core API
-#include "wii_anal.h"
-#include "wii_ec.h"
-#include "bc_logging.h"
+#include "wii_anal.h"
+#include "wii_ec.h"
+#include "bc_logging.h"
//#include "gfx/images.h" // Images
-#include "wii_anal_lcd.h" // Drawing functions
-#include "wii_anal_keys.h" // key mappings
+#include "wii_anal_lcd.h" // Drawing functions
+#include "wii_anal_keys.h" // key mappings
// ** If you want to see what this source code looks like with all the MACROs expanded
// ** grep -v '#include ' wii_i2c_classic.c | gcc -E -o /dev/stdout -xc -
-# include "wii_ec_macros.h"
+#include "wii_ec_macros.h"
//----------------------------------------------------------------------------- ----------------------------------------
// Classic Controller ... Classic Controller Pro is electronically the same
@@ -36,102 +36,115 @@
// ...And yes, the left-joystick has an extra 'bit' of precision!
// ...Also: trgZ{L|R} WILL continue to increase after btnZ{L|R} has gone active
//
-void classic_decode (wiiEC_t* const pec)
-{
- ecDecClassic_t* p = &pec->dec[(pec->decN = !pec->decN)].classic;
- uint8_t* joy = pec->joy;
-
- p->trgZL = ((joy[2] >>2) &0x18) | ((joy[3] >>5) &0x07); // {5}
- p->btnZL = !(joy[4] & 0x20); // !{1}
-
- p->trgZR = joy[3] & 0x1F; // {5}
- p->btnZR = !(joy[4] & 0x02); // !{1}
-
- p->btnL = !(joy[5] & 0x80); // !{1}
- p->btnR = !(joy[5] & 0x04); // !{1}
-
- p->padU = !(joy[5] & 0x01); // !{1}
- p->padD = !(joy[4] & 0x40); // !{1}
- p->padL = !(joy[5] & 0x02); // !{1}
- p->padR = !(joy[4] & 0x80); // !{1}
-
- p->btnM = !(joy[4] & 0x10); // !{1}
- p->btnH = !(joy[4] & 0x08); // !{1}
- p->btnP = !(joy[4] & 0x04); // !{1}
-
- p->btnX = !(joy[5] & 0x08); // !{1}
- p->btnY = !(joy[5] & 0x20); // !{1}
-
- p->btnA = !(joy[5] & 0x10); // !{1}
- p->btnB = !(joy[5] & 0x40); // !{1}
-
- p->joyLX = joy[0] & 0x3F; // {6}
- p->joyLY = joy[1] & 0x3F; // {6}
-
- p->joyRX = ((joy[0] >>3) &0x18) | ((joy[1] >>5) &0x06) | ((joy[2] >>7) &0x01); // {5}
- p->joyRY = joy[2] & 0x1F; // {5}
-
- DEBUG( ">%d> ZL{%02X}%c, L:%c, R:%c, ZR{%02X}%c", pec->decN,
- p->trgZL, (p->btnZL ? '#' : '.'),
- (p->btnL ? '#' : '.'),
- (p->btnR ? '#' : '.'),
- p->trgZR, (p->btnZR ? '#' : '.')
- );
- DEBUG( ">%d> D:{%c,%c,%c,%c}, H:{%c,%c,%c}, B:{%c,%c,%c,%c}", pec->decN,
- (p->padU ? 'U' : '.'), (p->padD ? 'D' : '.'), (p->padL ? 'L' : '.'), (p->padR ? 'R' : '.'),
- (p->btnM ? '-' : '.'), (p->btnH ? 'H' : '.'), (p->btnP ? '+' : '.'),
- (p->btnX ? 'X' : '.'), (p->btnY ? 'Y' : '.'), (p->btnA ? 'A' : '.'), (p->btnB ? 'B' : '.')
- );
- DEBUG( ">%d> JoyL{x:%02X, y:%02X}, JoyR{x:%02X, y:%02X}", pec->decN,
- p->joyLX, p->joyLY, p->joyRX, p->joyRY
- );
+void classic_decode(wiiEC_t* const pec) {
+ ecDecClassic_t* p = &pec->dec[(pec->decN = !pec->decN)].classic;
+ uint8_t* joy = pec->joy;
+
+ p->trgZL = ((joy[2] >> 2) & 0x18) | ((joy[3] >> 5) & 0x07); // {5}
+ p->btnZL = !(joy[4] & 0x20); // !{1}
+
+ p->trgZR = joy[3] & 0x1F; // {5}
+ p->btnZR = !(joy[4] & 0x02); // !{1}
+
+ p->btnL = !(joy[5] & 0x80); // !{1}
+ p->btnR = !(joy[5] & 0x04); // !{1}
+
+ p->padU = !(joy[5] & 0x01); // !{1}
+ p->padD = !(joy[4] & 0x40); // !{1}
+ p->padL = !(joy[5] & 0x02); // !{1}
+ p->padR = !(joy[4] & 0x80); // !{1}
+
+ p->btnM = !(joy[4] & 0x10); // !{1}
+ p->btnH = !(joy[4] & 0x08); // !{1}
+ p->btnP = !(joy[4] & 0x04); // !{1}
+
+ p->btnX = !(joy[5] & 0x08); // !{1}
+ p->btnY = !(joy[5] & 0x20); // !{1}
+
+ p->btnA = !(joy[5] & 0x10); // !{1}
+ p->btnB = !(joy[5] & 0x40); // !{1}
+
+ p->joyLX = joy[0] & 0x3F; // {6}
+ p->joyLY = joy[1] & 0x3F; // {6}
+
+ p->joyRX = ((joy[0] >> 3) & 0x18) | ((joy[1] >> 5) & 0x06) | ((joy[2] >> 7) & 0x01); // {5}
+ p->joyRY = joy[2] & 0x1F; // {5}
+
+ DEBUG(
+ ">%d> ZL{%02X}%c, L:%c, R:%c, ZR{%02X}%c",
+ pec->decN,
+ p->trgZL,
+ (p->btnZL ? '#' : '.'),
+ (p->btnL ? '#' : '.'),
+ (p->btnR ? '#' : '.'),
+ p->trgZR,
+ (p->btnZR ? '#' : '.'));
+ DEBUG(
+ ">%d> D:{%c,%c,%c,%c}, H:{%c,%c,%c}, B:{%c,%c,%c,%c}",
+ pec->decN,
+ (p->padU ? 'U' : '.'),
+ (p->padD ? 'D' : '.'),
+ (p->padL ? 'L' : '.'),
+ (p->padR ? 'R' : '.'),
+ (p->btnM ? '-' : '.'),
+ (p->btnH ? 'H' : '.'),
+ (p->btnP ? '+' : '.'),
+ (p->btnX ? 'X' : '.'),
+ (p->btnY ? 'Y' : '.'),
+ (p->btnA ? 'A' : '.'),
+ (p->btnB ? 'B' : '.'));
+ DEBUG(
+ ">%d> JoyL{x:%02X, y:%02X}, JoyR{x:%02X, y:%02X}",
+ pec->decN,
+ p->joyLX,
+ p->joyLY,
+ p->joyRX,
+ p->joyRY);
}
//+============================================================================ ========================================
// Give each button a unique character identifier
//
-void classic_msg (wiiEC_t* const pec, FuriMessageQueue* const queue)
-{
- ecDecClassic_t* new = &pec->dec[pec->decN].classic;
- ecDecClassic_t* old = &pec->dec[!pec->decN].classic;
-
- eventMsg_t msg = {
- .id = EVID_WIIEC,
- .wiiEc = {
- .type = WIIEC_NONE,
- .in = ' ',
- .val = 0,
- }
- };
-
- ANALOG(trgZL, 'l'); // FIVE bit value
- ANABTN(btnZL, trgZL, 'l');
-
- BUTTON(btnL, 'L');
- BUTTON(btnR, 'R');
-
- ANALOG(trgZR, 'r'); // FIVE bit value
- ANABTN(btnZR, trgZR, 'r');
-
- BUTTON(padU, 'W');
- BUTTON(padL, 'A');
- BUTTON(padD, 'S');
- BUTTON(padR, 'D');
-
- BUTTON(btnM, '-');
- BUTTON(btnH, 'h');
- BUTTON(btnP, '+');
-
- BUTTON(btnX, 'x');
- BUTTON(btnY, 'y');
- BUTTON(btnA, 'a');
- BUTTON(btnB, 'b');
-
- ANALOG(joyLX, 'x'); // SIX bit values
- ANALOG(joyLY, 'y');
-
- ANALOG(joyRX, 'X'); // FIVE bit values
- ANALOG(joyRY, 'Y');
+void classic_msg(wiiEC_t* const pec, FuriMessageQueue* const queue) {
+ ecDecClassic_t* new = &pec->dec[pec->decN].classic;
+ ecDecClassic_t* old = &pec->dec[!pec->decN].classic;
+
+ eventMsg_t msg = {
+ .id = EVID_WIIEC,
+ .wiiEc = {
+ .type = WIIEC_NONE,
+ .in = ' ',
+ .val = 0,
+ }};
+
+ ANALOG(trgZL, 'l'); // FIVE bit value
+ ANABTN(btnZL, trgZL, 'l');
+
+ BUTTON(btnL, 'L');
+ BUTTON(btnR, 'R');
+
+ ANALOG(trgZR, 'r'); // FIVE bit value
+ ANABTN(btnZR, trgZR, 'r');
+
+ BUTTON(padU, 'W');
+ BUTTON(padL, 'A');
+ BUTTON(padD, 'S');
+ BUTTON(padR, 'D');
+
+ BUTTON(btnM, '-');
+ BUTTON(btnH, 'h');
+ BUTTON(btnP, '+');
+
+ BUTTON(btnX, 'x');
+ BUTTON(btnY, 'y');
+ BUTTON(btnA, 'a');
+ BUTTON(btnB, 'b');
+
+ ANALOG(joyLX, 'x'); // SIX bit values
+ ANALOG(joyLY, 'y');
+
+ ANALOG(joyRX, 'X'); // FIVE bit values
+ ANALOG(joyRY, 'Y');
}
//+============================================================================ ========================================
@@ -144,255 +157,283 @@ void classic_msg (wiiEC_t* const pec, FuriMessageQueue* const queue)
// 9..11 right analog stick Y axis {maximum, minimum, center} ... JoyR is 5bits, so >>3 to compare to readings
// 12..15 somehow describe the shoulder {5bit} button values!?
//
-void classic_calib (wiiEC_t* const pec, ecCalib_t c)
-{
- ecDecClassic_t* src = &pec->dec[pec->decN].classic; // from input
- ecCalClassic_t* dst = pec->calS.classic; // to calibration data
-
- if (c & CAL_RESET) { // initialise ready for software calibration
- // LO is set to the MAXIMUM value (so it can be reduced)
- // HI is set to ZERO (so it can be increased)
- RESET_LO_HI(trgZL, 5); // 5bit value
- RESET_LO_HI(trgZR, 5); // 5bit value
-
- RESET_LO_MID_HI(joyLX, 6); // 6bit value
- RESET_LO_MID_HI(joyLY, 6); // 6bit value
-
- RESET_LO_MID_HI(joyRX, 5); // 5bit value
- RESET_LO_MID_HI(joyRY, 5); // 5bit value
- }
- if (c & CAL_FACTORY) { // (re)set to factory defaults
-//! strategy for factory calibration for classic controller [pro] triggers is (currently) unknown
-//! FACTORY_LO( trgZL, pec->calF[12..15]);
-//! FACTORY_MID(trgZL, pec->calF[12..15]);
-//! FACTORY_HI( trgZL, pec->calF[12..15]);
-
-//! FACTORY_LO( trgZR, pec->calF[12..15]);
-//! FACTORY_MID(trgZR, pec->calF[12..15]);
-//! FACTORY_HI( trgZR, pec->calF[12..15]);
+void classic_calib(wiiEC_t* const pec, ecCalib_t c) {
+ ecDecClassic_t* src = &pec->dec[pec->decN].classic; // from input
+ ecCalClassic_t* dst = pec->calS.classic; // to calibration data
+
+ if(c & CAL_RESET) { // initialise ready for software calibration
+ // LO is set to the MAXIMUM value (so it can be reduced)
+ // HI is set to ZERO (so it can be increased)
+ RESET_LO_HI(trgZL, 5); // 5bit value
+ RESET_LO_HI(trgZR, 5); // 5bit value
+
+ RESET_LO_MID_HI(joyLX, 6); // 6bit value
+ RESET_LO_MID_HI(joyLY, 6); // 6bit value
+
+ RESET_LO_MID_HI(joyRX, 5); // 5bit value
+ RESET_LO_MID_HI(joyRY, 5); // 5bit value
+ }
+ if(c & CAL_FACTORY) { // (re)set to factory defaults
+ //! strategy for factory calibration for classic controller [pro] triggers is (currently) unknown
+ //! FACTORY_LO( trgZL, pec->calF[12..15]);
+ //! FACTORY_MID(trgZL, pec->calF[12..15]);
+ //! FACTORY_HI( trgZL, pec->calF[12..15]);
+
+ //! FACTORY_LO( trgZR, pec->calF[12..15]);
+ //! FACTORY_MID(trgZR, pec->calF[12..15]);
+ //! FACTORY_HI( trgZR, pec->calF[12..15]);
#if 1
- FACTORY_LO(trgZL, 0x03);
- FACTORY_LO(trgZR, 0x03);
+ FACTORY_LO(trgZL, 0x03);
+ FACTORY_LO(trgZR, 0x03);
- FACTORY_MID(trgZL, 0x1B); //! these will be set every time the digital switch changes to ON
- FACTORY_MID(trgZR, 0x1B);
+ FACTORY_MID(trgZL, 0x1B); //! these will be set every time the digital switch changes to ON
+ FACTORY_MID(trgZR, 0x1B);
#endif
- FACTORY_LO( joyLX, pec->calF[ 1] >>2);
- FACTORY_MID(joyLX, pec->calF[ 2] >>2);
- FACTORY_HI( joyLX, pec->calF[ 0] >>2);
-
- FACTORY_LO( joyLY, pec->calF[ 4] >>2);
- FACTORY_MID(joyLY, pec->calF[ 5] >>2);
- FACTORY_HI( joyLY, pec->calF[ 3] >>2);
-
- FACTORY_LO( joyRX, pec->calF[ 7] >>3);
- FACTORY_MID(joyRX, pec->calF[ 8] >>3);
- FACTORY_HI( joyRX, pec->calF[ 6] >>3);
-
- FACTORY_LO( joyRY, pec->calF[10] >>3);
- FACTORY_MID(joyRY, pec->calF[11] >>3);
- FACTORY_HI( joyRY, pec->calF[ 9] >>3);
- }
- if (c & CAL_TRACK) { // track maximum and minimum values seen
- TRACK_LO_HI(trgZL);
- TRACK_LO_HI(trgZR);
-
- TRACK_LO_HI(joyLX);
- TRACK_LO_HI(joyLY);
-
- TRACK_LO_HI(joyRX);
- TRACK_LO_HI(joyRY);
- }
- if (c & CAL_RANGE) { // perform software calibration step
- RANGE_LO_HI(trgZL);
- RANGE_LO_HI(trgZR);
-
- RANGE_LO_HI(joyLX);
- RANGE_LO_HI(joyLY);
-
- RANGE_LO_HI(joyRX);
- RANGE_LO_HI(joyRY);
- }
- if (c & CAL_CENTRE) { // reset centre point of joystick
- CENTRE(joyLX);
- CENTRE(joyLY);
-
- CENTRE(joyRX);
- CENTRE(joyRY);
- }
+ FACTORY_LO(joyLX, pec->calF[1] >> 2);
+ FACTORY_MID(joyLX, pec->calF[2] >> 2);
+ FACTORY_HI(joyLX, pec->calF[0] >> 2);
+
+ FACTORY_LO(joyLY, pec->calF[4] >> 2);
+ FACTORY_MID(joyLY, pec->calF[5] >> 2);
+ FACTORY_HI(joyLY, pec->calF[3] >> 2);
+
+ FACTORY_LO(joyRX, pec->calF[7] >> 3);
+ FACTORY_MID(joyRX, pec->calF[8] >> 3);
+ FACTORY_HI(joyRX, pec->calF[6] >> 3);
+
+ FACTORY_LO(joyRY, pec->calF[10] >> 3);
+ FACTORY_MID(joyRY, pec->calF[11] >> 3);
+ FACTORY_HI(joyRY, pec->calF[9] >> 3);
+ }
+ if(c & CAL_TRACK) { // track maximum and minimum values seen
+ TRACK_LO_HI(trgZL);
+ TRACK_LO_HI(trgZR);
+
+ TRACK_LO_HI(joyLX);
+ TRACK_LO_HI(joyLY);
+
+ TRACK_LO_HI(joyRX);
+ TRACK_LO_HI(joyRY);
+ }
+ if(c & CAL_RANGE) { // perform software calibration step
+ RANGE_LO_HI(trgZL);
+ RANGE_LO_HI(trgZR);
+
+ RANGE_LO_HI(joyLX);
+ RANGE_LO_HI(joyLY);
+
+ RANGE_LO_HI(joyRX);
+ RANGE_LO_HI(joyRY);
+ }
+ if(c & CAL_CENTRE) { // reset centre point of joystick
+ CENTRE(joyLX);
+ CENTRE(joyLY);
+
+ CENTRE(joyRX);
+ CENTRE(joyRY);
+ }
}
//+============================================================================ ========================================
// bits that are common to both screens
//
-static
-void classic_show_ (Canvas* const canvas, state_t* const state)
-{
- ecDecClassic_t* d = &state->ec.dec[state->ec.decN].classic;
- ecCalClassic_t* js = state->ec.calS.classic;
-
- static const int dead = 1; // trigger deadzone
- const image_t* img = NULL; // trigger image
-
- show(canvas, 6, 0, &img_cc_Main , SHOW_SET_BLK);
- show(canvas, 62,53, &img_cc_Cable, SHOW_SET_BLK);
-
- // classic triggers
- if (d->trgZL >= js[2].trgZL ) img = &img_cc_trg_L4;
- else if (d->trgZL <= js[1].trgZL +dead) img = NULL;
- else {
- // copied from the joystick calibration code
- int lo = js[1].trgZL +dead +1;
- int hi = js[2].trgZL -1;
- int range = hi -lo +1;
- int div = range /3; // each division (base amount, eg. 17/3==5)
- int rem = range -(div *3); // remainder (ie. range%3)
- int hi1 = lo +div -1; // (in brevity)
- int lo3 = lo +div +div +(rem==2); // ...
-
- if (d->trgZL <= hi1) img = &img_cc_trg_L1 ; // zone #1
- else if (d->trgZL >= lo3) img = &img_cc_trg_L3 ; // zone #3
- else img = &img_cc_trg_L2 ; // zone #2
- }
- if (img) show(canvas, 22,1, img, SHOW_SET_BLK) ;
-
- if (d->trgZR >= js[2].trgZR ) img = &img_cc_trg_R4;
- else if (d->trgZR <= js[1].trgZR +dead) img = NULL;
- else {
- // copied from the joystick calibration code
- int lo = js[1].trgZR +dead +1;
- int hi = js[2].trgZR -1;
- int range = hi -lo +1;
- int div = range /3; // each division (base amount, eg. 17/3==5)
- int rem = range -(div *3); // remainder (ie. range%3)
- int hi1 = lo +div -1; // (in brevity)
- int lo3 = lo +div +div +(rem==2); // ...
-
- if (d->trgZR <= hi1) img = &img_cc_trg_R1 ; // zone #1
- else if (d->trgZR >= lo3) img = &img_cc_trg_R3 ; // zone #3
- else img = &img_cc_trg_R2 ; // zone #2
- }
- if (img) show(canvas, 89,1, img, SHOW_SET_BLK) ;
-
- if (d->padU ) show(canvas, 27,16, &img_cc_pad_UD1, SHOW_ALL) ;
- if (d->padL ) show(canvas, 20,23, &img_cc_pad_LR1, SHOW_ALL) ;
- if (d->padD ) show(canvas, 27,28, &img_cc_pad_UD1, SHOW_ALL) ;
- if (d->padR ) show(canvas, 32,23, &img_cc_pad_LR1, SHOW_ALL) ;
-
- if (d->btnX ) show(canvas, 96,16, &img_cc_btn_X1, SHOW_ALL) ;
- if (d->btnY ) show(canvas, 85,23, &img_cc_btn_Y1, SHOW_ALL) ;
- if (d->btnA ) show(canvas, 107,23, &img_cc_btn_A1, SHOW_ALL) ;
- if (d->btnB ) show(canvas, 96,30, &img_cc_btn_B1, SHOW_ALL) ;
-
- canvas_set_color(canvas, ColorBlack);
- if (d->btnL ) canvas_draw_box(canvas, 46,2, 5,4) ;
- if (d->btnR ) canvas_draw_box(canvas, 77,2, 5,4) ;
-
- if (d->btnM ) canvas_draw_box(canvas, 54,24, 4,4) ;
- if (d->btnH ) canvas_draw_box(canvas, 62,24, 4,4) ;
- if (d->btnP ) canvas_draw_box(canvas, 70,24, 4,4) ;
-
- // Show joysticks
- showJoy(canvas, 48,42, js[1].joyLX,js[2].joyLX, js[3].joyLX,
- js[1].joyLY,js[2].joyLY, js[3].joyLY, d->joyLX,d->joyLY, 6);
- showJoy(canvas, 78,42, js[1].joyRX,js[2].joyRX, js[3].joyRX,
- js[1].joyRY,js[2].joyRY, js[3].joyRY, d->joyRX,d->joyRY, 5);
-
- show(canvas, 0,55, &img_key_L, SHOW_SET_BLK);
+static void classic_show_(Canvas* const canvas, state_t* const state) {
+ ecDecClassic_t* d = &state->ec.dec[state->ec.decN].classic;
+ ecCalClassic_t* js = state->ec.calS.classic;
+
+ static const int dead = 1; // trigger deadzone
+ const image_t* img = NULL; // trigger image
+
+ show(canvas, 6, 0, &img_cc_Main, SHOW_SET_BLK);
+ show(canvas, 62, 53, &img_cc_Cable, SHOW_SET_BLK);
+
+ // classic triggers
+ if(d->trgZL >= js[2].trgZL)
+ img = &img_cc_trg_L4;
+ else if(d->trgZL <= js[1].trgZL + dead)
+ img = NULL;
+ else {
+ // copied from the joystick calibration code
+ int lo = js[1].trgZL + dead + 1;
+ int hi = js[2].trgZL - 1;
+ int range = hi - lo + 1;
+ int div = range / 3; // each division (base amount, eg. 17/3==5)
+ int rem = range - (div * 3); // remainder (ie. range%3)
+ int hi1 = lo + div - 1; // (in brevity)
+ int lo3 = lo + div + div + (rem == 2); // ...
+
+ if(d->trgZL <= hi1)
+ img = &img_cc_trg_L1; // zone #1
+ else if(d->trgZL >= lo3)
+ img = &img_cc_trg_L3; // zone #3
+ else
+ img = &img_cc_trg_L2; // zone #2
+ }
+ if(img) show(canvas, 22, 1, img, SHOW_SET_BLK);
+
+ if(d->trgZR >= js[2].trgZR)
+ img = &img_cc_trg_R4;
+ else if(d->trgZR <= js[1].trgZR + dead)
+ img = NULL;
+ else {
+ // copied from the joystick calibration code
+ int lo = js[1].trgZR + dead + 1;
+ int hi = js[2].trgZR - 1;
+ int range = hi - lo + 1;
+ int div = range / 3; // each division (base amount, eg. 17/3==5)
+ int rem = range - (div * 3); // remainder (ie. range%3)
+ int hi1 = lo + div - 1; // (in brevity)
+ int lo3 = lo + div + div + (rem == 2); // ...
+
+ if(d->trgZR <= hi1)
+ img = &img_cc_trg_R1; // zone #1
+ else if(d->trgZR >= lo3)
+ img = &img_cc_trg_R3; // zone #3
+ else
+ img = &img_cc_trg_R2; // zone #2
+ }
+ if(img) show(canvas, 89, 1, img, SHOW_SET_BLK);
+
+ if(d->padU) show(canvas, 27, 16, &img_cc_pad_UD1, SHOW_ALL);
+ if(d->padL) show(canvas, 20, 23, &img_cc_pad_LR1, SHOW_ALL);
+ if(d->padD) show(canvas, 27, 28, &img_cc_pad_UD1, SHOW_ALL);
+ if(d->padR) show(canvas, 32, 23, &img_cc_pad_LR1, SHOW_ALL);
+
+ if(d->btnX) show(canvas, 96, 16, &img_cc_btn_X1, SHOW_ALL);
+ if(d->btnY) show(canvas, 85, 23, &img_cc_btn_Y1, SHOW_ALL);
+ if(d->btnA) show(canvas, 107, 23, &img_cc_btn_A1, SHOW_ALL);
+ if(d->btnB) show(canvas, 96, 30, &img_cc_btn_B1, SHOW_ALL);
+
+ canvas_set_color(canvas, ColorBlack);
+ if(d->btnL) canvas_draw_box(canvas, 46, 2, 5, 4);
+ if(d->btnR) canvas_draw_box(canvas, 77, 2, 5, 4);
+
+ if(d->btnM) canvas_draw_box(canvas, 54, 24, 4, 4);
+ if(d->btnH) canvas_draw_box(canvas, 62, 24, 4, 4);
+ if(d->btnP) canvas_draw_box(canvas, 70, 24, 4, 4);
+
+ // Show joysticks
+ showJoy(
+ canvas,
+ 48,
+ 42,
+ js[1].joyLX,
+ js[2].joyLX,
+ js[3].joyLX,
+ js[1].joyLY,
+ js[2].joyLY,
+ js[3].joyLY,
+ d->joyLX,
+ d->joyLY,
+ 6);
+ showJoy(
+ canvas,
+ 78,
+ 42,
+ js[1].joyRX,
+ js[2].joyRX,
+ js[3].joyRX,
+ js[1].joyRY,
+ js[2].joyRY,
+ js[3].joyRY,
+ d->joyRX,
+ d->joyRY,
+ 5);
+
+ show(canvas, 0, 55, &img_key_L, SHOW_SET_BLK);
}
//+============================================================================ ========================================
-static
-void classic_showN (Canvas* const canvas, state_t* const state)
-{
- ecCalClassic_t* c = (state->hold) ? &state->ec.calS.classic[(state->hold < 0) ? 0 : 4]
- : (ecCalClassic_t*)(&state->ec.dec[state->ec.decN].classic) ; //! danger
+static void classic_showN(Canvas* const canvas, state_t* const state) {
+ ecCalClassic_t* c = (state->hold) ?
+ &state->ec.calS.classic[(state->hold < 0) ? 0 : 4] :
+ (ecCalClassic_t*)(&state->ec.dec[state->ec.decN].classic); //! danger
- classic_show_(canvas, state);
+ classic_show_(canvas, state);
- showHex(canvas, 0, 0, c->trgZL, 2,1); // 5bits
- showHex(canvas, 113, 0, c->trgZR, 2,1); // 5bits
+ showHex(canvas, 0, 0, c->trgZL, 2, 1); // 5bits
+ showHex(canvas, 113, 0, c->trgZR, 2, 1); // 5bits
- showHex(canvas, 24,41, c->joyLX, 2,1); // 6bits
- showHex(canvas, 41,54, c->joyLY, 2,1); // 6bits
+ showHex(canvas, 24, 41, c->joyLX, 2, 1); // 6bits
+ showHex(canvas, 41, 54, c->joyLY, 2, 1); // 6bits
- showHex(canvas, 88,41, c->joyRX, 2,1); // 5bits
- showHex(canvas, 71,54, c->joyRY, 2,1); // 5bits
+ showHex(canvas, 88, 41, c->joyRX, 2, 1); // 5bits
+ showHex(canvas, 71, 54, c->joyRY, 2, 1); // 5bits
- showPeakHold(state, canvas, state->hold); // peak keys
+ showPeakHold(state, canvas, state->hold); // peak keys
}
//+============================================================================ ========================================
-void classic_show (Canvas* const canvas, state_t* const state)
-{
- // Classic controllers have TWO scenes
- if (state->scene == SCENE_CLASSIC_N) return classic_showN(canvas, state) ;
-
- // Default scene
- classic_show_(canvas, state);
- show(canvas, 9,55, &img_key_R, SHOW_SET_BLK);
-
- show( canvas, 119,55,
- ((state->calib & CAL_RANGE) && (++state->flash &8)) ? &img_key_OKi : &img_key_OK,
- SHOW_SET_BLK );
+void classic_show(Canvas* const canvas, state_t* const state) {
+ // Classic controllers have TWO scenes
+ if(state->scene == SCENE_CLASSIC_N) return classic_showN(canvas, state);
+
+ // Default scene
+ classic_show_(canvas, state);
+ show(canvas, 9, 55, &img_key_R, SHOW_SET_BLK);
+
+ show(
+ canvas,
+ 119,
+ 55,
+ ((state->calib & CAL_RANGE) && (++state->flash & 8)) ? &img_key_OKi : &img_key_OK,
+ SHOW_SET_BLK);
}
//+============================================================================ ========================================
-static
-bool classic_keyN (const eventMsg_t* const msg, state_t* const state)
-{
- int used = false; // assume key is NOT-handled
+static bool classic_keyN(const eventMsg_t* const msg, state_t* const state) {
+ int used = false; // assume key is NOT-handled
- if ((msg->input.type == InputTypeShort) && (msg->input.key == InputKeyLeft)) {
- sceneSet(state, SCENE_CLASSIC);
- used = true;
- }
+ if((msg->input.type == InputTypeShort) && (msg->input.key == InputKeyLeft)) {
+ sceneSet(state, SCENE_CLASSIC);
+ used = true;
+ }
- // Calibration keys
- if (!used) used = key_calib(msg, state) ;
+ // Calibration keys
+ if(!used) used = key_calib(msg, state);
- return used;
+ return used;
}
//+============================================================================ ========================================
-bool classic_key (const eventMsg_t* const msg, state_t* const state)
-{
- // Classic controllers have TWO scenes
- if (state->scene == SCENE_CLASSIC_N) return classic_keyN(msg, state) ;
-
- // Default scene
- int used = false; // assume key is NOT-handled
-
- switch (msg->input.type) {
- case InputTypeShort: //# input.key) {
- case InputKeyUp: //# scene == SCENE_CLASSIC_N) return classic_keyN(msg, state);
+
+ // Default scene
+ int used = false; // assume key is NOT-handled
+
+ switch(msg->input.type) {
+ case InputTypeShort: //# input.key) {
+ case InputKeyUp: //#
-#include
+#include
+#include
//----------------------------------------------------------------------------- ----------------------------------------
// Classic Controller ... Classic Controller Pro is electronically the same
@@ -25,60 +25,55 @@
//----------------------------------------------------------------------------- ----------------------------------------
// Controllers which have calibration must have their calibratable controls here
//! Is there a better way to get the start of the decode struct to match the calibration struct ?
-#define CLASSIC_ANALOGUE \
- uint8_t trgZL, trgZR; /* ANA{l, l} lowercase=trigger 5bit values {5} */ \
- uint8_t joyLX, joyLY; /* ANA{x, y} left=lowercase 6bit values {6}<-- */ \
- uint8_t joyRX, joyRY; /* ANA{X, Y} 5bit values {5} */
+#define CLASSIC_ANALOGUE \
+ uint8_t trgZL, trgZR; /* ANA{l, l} lowercase=trigger 5bit values {5} */ \
+ uint8_t joyLX, joyLY; /* ANA{x, y} left=lowercase 6bit values {6}<-- */ \
+ uint8_t joyRX, joyRY; /* ANA{X, Y} 5bit values {5} */
//-----------------------------------------------------------------------------
// Calibratable controls
//
-typedef
- struct ecCalClassic
- {
- CLASSIC_ANALOGUE
- }
-ecCalClassic_t;
+typedef struct ecCalClassic {
+ CLASSIC_ANALOGUE
+} ecCalClassic_t;
//-----------------------------------------------------------------------------
// All controls
//
-typedef
- struct ecDecClassic
- {
- CLASSIC_ANALOGUE // MUST be first
+typedef struct ecDecClassic {
+ CLASSIC_ANALOGUE // MUST be first
- // Digital controls
- bool btnZL, btnZR; // BTN{l, l}
+ // Digital controls
+ bool btnZL,
+ btnZR; // BTN{l, l}
- bool btnL, btnR; // BTN{L, R} upperrcase=shoulder
+ bool btnL, btnR; // BTN{L, R} upperrcase=shoulder
- bool padU, padL, padD, padR; // BTN{W, A, S, D}
+ bool padU, padL, padD, padR; // BTN{W, A, S, D}
- bool btnM, btnH, btnP; // BTN{-, h, +}
+ bool btnM, btnH, btnP; // BTN{-, h, +}
- bool btnX, btnY; // BTN{x, y}
- bool btnA, btnB; // BTN{a, b}
+ bool btnX, btnY; // BTN{x, y}
+ bool btnA, btnB; // BTN{a, b}
- }
-ecDecClassic_t;
+} ecDecClassic_t;
#undef CLASSIC_ANALOGUE
//============================================================================= ========================================
// Function prototypes
//
-#include // Canvas
-typedef struct wiiEC wiiEC_t ;
-typedef enum ecCalib ecCalib_t ;
-typedef struct state state_t ;
-typedef struct eventMsg eventMsg_t ;
-
-void classic_decode (wiiEC_t* const pec) ;
-void classic_msg (wiiEC_t* const pec, FuriMessageQueue* const queue) ;
-void classic_calib (wiiEC_t* const pec, ecCalib_t c) ;
-
-void classic_show (Canvas* const canvas, state_t* const state) ;
-bool classic_key (const eventMsg_t* const msg, state_t* const state) ;
+#include // Canvas
+typedef struct wiiEC wiiEC_t;
+typedef enum ecCalib ecCalib_t;
+typedef struct state state_t;
+typedef struct eventMsg eventMsg_t;
+
+void classic_decode(wiiEC_t* const pec);
+void classic_msg(wiiEC_t* const pec, FuriMessageQueue* const queue);
+void classic_calib(wiiEC_t* const pec, ecCalib_t c);
+
+void classic_show(Canvas* const canvas, state_t* const state);
+bool classic_key(const eventMsg_t* const msg, state_t* const state);
#endif //WII_EC_CLASSIC_H_
diff --git a/applications/plugins/wii_ec_anal/wii_ec_macros.h b/applications/plugins/wii_ec_anal/wii_ec_macros.h
index 33daf944d6..00ab9825b7 100644
--- a/applications/plugins/wii_ec_anal/wii_ec_macros.h
+++ b/applications/plugins/wii_ec_anal/wii_ec_macros.h
@@ -9,49 +9,53 @@
//
//if (furi_message_queue_get_count(queue) > 18) WARN("queue high %d", furi_message_queue_get_count(queue));
-#define MSGQ(lbl) do { \
- msg.wiiEc.in = lbl; \
- furi_message_queue_put(queue, &msg, 0); \
-}while(0)
-
+#define MSGQ(lbl) \
+ do { \
+ msg.wiiEc.in = lbl; \
+ furi_message_queue_put(queue, &msg, 0); \
+ } while(0)
// A 'standard' "button" is an independent SPST switch
// Eg. Nunchuck 'Z' button
// The "value" will always be 0
-#define BUTTON(btn,lbl) do { \
- if (new->btn != old->btn) { \
- msg.wiiEc.type = (new->btn) ? WIIEC_PRESS : WIIEC_RELEASE; \
- msg.wiiEc.val = 0; \
- MSGQ(lbl); \
- } \
-}while(0)
+#define BUTTON(btn, lbl) \
+ do { \
+ if(new->btn != old->btn) { \
+ msg.wiiEc.type = (new->btn) ? WIIEC_PRESS : WIIEC_RELEASE; \
+ msg.wiiEc.val = 0; \
+ MSGQ(lbl); \
+ } \
+ } while(0)
// An "analogue button" is an SPST coupled with an ananlogue 'switch'
// Eg. The "bottom out" switches on the triggers of the classic controller
// The "value" will be the value of the associated analogue controller
-#define ANABTN(btn,ana,lbl) do { \
- if (new->btn != old->btn) { \
- msg.wiiEc.type = (new->btn) ? WIIEC_PRESS : WIIEC_RELEASE; \
- msg.wiiEc.val = new->ana; \
- MSGQ(lbl); \
- } \
-}while(0)
+#define ANABTN(btn, ana, lbl) \
+ do { \
+ if(new->btn != old->btn) { \
+ msg.wiiEc.type = (new->btn) ? WIIEC_PRESS : WIIEC_RELEASE; \
+ msg.wiiEc.val = new->ana; \
+ MSGQ(lbl); \
+ } \
+ } while(0)
-#define ANALOG(ana,lbl) do { \
- if (new->ana != old->ana) { \
- msg.wiiEc.type = WIIEC_ANALOG; \
- msg.wiiEc.val = new->ana; \
- MSGQ(lbl); \
- } \
-}while(0)
+#define ANALOG(ana, lbl) \
+ do { \
+ if(new->ana != old->ana) { \
+ msg.wiiEc.type = WIIEC_ANALOG; \
+ msg.wiiEc.val = new->ana; \
+ MSGQ(lbl); \
+ } \
+ } while(0)
-#define ACCEL(acc,lbl) do { \
- if (new->acc != old->acc) { \
- msg.wiiEc.type = WIIEC_ACCEL; \
- msg.wiiEc.val = new->acc; \
- MSGQ(lbl); \
- } \
-}while(0)
+#define ACCEL(acc, lbl) \
+ do { \
+ if(new->acc != old->acc) { \
+ msg.wiiEc.type = WIIEC_ACCEL; \
+ msg.wiiEc.val = new->acc; \
+ MSGQ(lbl); \
+ } \
+ } while(0)
//----------------------------------------------------------------------------- ----------------------------------------
// CALIBRATION MACROS
@@ -61,24 +65,74 @@
//
// ... v=variable, n=number
//
-#define FACTORY_LO(v,n) do{ (dst[1]. v) = n; }while(0)
-#define FACTORY_MID(v,n) do{ (dst[2]. v) = n; }while(0)
-#define FACTORY_HI(v,n) do{ (dst[3]. v) = n; }while(0)
+#define FACTORY_LO(v, n) \
+ do { \
+ (dst[1].v) = n; \
+ } while(0)
+#define FACTORY_MID(v, n) \
+ do { \
+ (dst[2].v) = n; \
+ } while(0)
+#define FACTORY_HI(v, n) \
+ do { \
+ (dst[3].v) = n; \
+ } while(0)
-#define TRACK_LO(v) do{ if ((src-> v) < (dst[0]. v)) (dst[0]. v) = (src-> v); }while(0)
-#define TRACK_HI(v) do{ if ((src-> v) > (dst[4]. v)) (dst[4]. v) = (src-> v); }while(0)
-#define TRACK_LO_HI(v) do{ TRACK_LO(v); TRACK_HI(v); }while(0)
+#define TRACK_LO(v) \
+ do { \
+ if((src->v) < (dst[0].v)) (dst[0].v) = (src->v); \
+ } while(0)
+#define TRACK_HI(v) \
+ do { \
+ if((src->v) > (dst[4].v)) (dst[4].v) = (src->v); \
+ } while(0)
+#define TRACK_LO_HI(v) \
+ do { \
+ TRACK_LO(v); \
+ TRACK_HI(v); \
+ } while(0)
-#define RESET_LO(v,b) do{ (dst[0]. v) = (dst[1]. v) = ((1<<(b))-1); }while(0)
-#define RESET_HI(v) do{ (dst[4]. v) = (dst[3]. v) = 0; }while(0)
-#define RESET_MID(v) do{ (dst[2]. v) = (src-> v); }while(0)
-#define RESET_LO_HI(v,b) do{ RESET_LO(v,b); RESET_HI(v); }while(0)
-#define RESET_LO_MID_HI(v,b) do{ RESET_LO(v,b); RESET_MID(v); RESET_HI(v); }while(0)
+#define RESET_LO(v, b) \
+ do { \
+ (dst[0].v) = (dst[1].v) = ((1 << (b)) - 1); \
+ } while(0)
+#define RESET_HI(v) \
+ do { \
+ (dst[4].v) = (dst[3].v) = 0; \
+ } while(0)
+#define RESET_MID(v) \
+ do { \
+ (dst[2].v) = (src->v); \
+ } while(0)
+#define RESET_LO_HI(v, b) \
+ do { \
+ RESET_LO(v, b); \
+ RESET_HI(v); \
+ } while(0)
+#define RESET_LO_MID_HI(v, b) \
+ do { \
+ RESET_LO(v, b); \
+ RESET_MID(v); \
+ RESET_HI(v); \
+ } while(0)
-#define RANGE_LO(v) do{ if ((src-> v) < (dst[1]. v)) (dst[1]. v) = (src-> v); }while(0)
-#define RANGE_HI(v) do{ if ((src-> v) > (dst[3]. v)) (dst[3]. v) = (src-> v); }while(0)
-#define RANGE_LO_HI(v) do{ RANGE_LO(v); RANGE_HI(v); }while(0)
+#define RANGE_LO(v) \
+ do { \
+ if((src->v) < (dst[1].v)) (dst[1].v) = (src->v); \
+ } while(0)
+#define RANGE_HI(v) \
+ do { \
+ if((src->v) > (dst[3].v)) (dst[3].v) = (src->v); \
+ } while(0)
+#define RANGE_LO_HI(v) \
+ do { \
+ RANGE_LO(v); \
+ RANGE_HI(v); \
+ } while(0)
-#define CENTRE(v) do{ (dst[2]. v) = (src-> v); } while(0)
+#define CENTRE(v) \
+ do { \
+ (dst[2].v) = (src->v); \
+ } while(0)
#endif //WII_EC_MACROS_H_
diff --git a/applications/plugins/wii_ec_anal/wii_ec_nunchuck.c b/applications/plugins/wii_ec_anal/wii_ec_nunchuck.c
index 81c32a243c..d88d535b68 100644
--- a/applications/plugins/wii_ec_anal/wii_ec_nunchuck.c
+++ b/applications/plugins/wii_ec_anal/wii_ec_nunchuck.c
@@ -1,142 +1,144 @@
-#include
-#include // Core API
+#include
+#include // Core API
-#include "wii_anal.h"
-#include "wii_i2c.h"
-#include "bc_logging.h"
+#include "wii_anal.h"
+#include "wii_i2c.h"
+#include "bc_logging.h"
-#include "gfx/images.h" // Images
-#include "wii_anal_lcd.h" // Drawing functions
-#include "wii_anal_keys.h" // key mappings
+#include "gfx/images.h" // Images
+#include "wii_anal_lcd.h" // Drawing functions
+#include "wii_anal_keys.h" // key mappings
// ** If you want to see what this source code looks like with all the MACROs expanded
// ** grep -v '#include ' wii_ec_nunchuck.c | gcc -E -o /dev/stdout -xc -
-# include "wii_ec_macros.h"
+#include "wii_ec_macros.h"
//+============================================================================ ========================================
// Standard Nunchuck : 2 buttons, 1 analogue joystick, 1 3-axis accelerometer
-//
-void nunchuck_decode (wiiEC_t* const pec)
-{
- ecDecNunchuck_t* p = &pec->dec[(pec->decN = !pec->decN)].nunchuck;
- uint8_t* joy = pec->joy;
-
- p->btnC = !(joy[5] & 0x02); // !{1}
- p->btnZ = !(joy[5] & 0x01); // !{1}
-
- p->joyX = joy[0]; // {8}
- p->joyY = joy[1]; // {8}
-
- p->accX = ((uint16_t)joy[2] << 2) | ((joy[5] >>2) & 0x03); // {10}
- p->accY = ((uint16_t)joy[3] << 2) | ((joy[5] >>4) & 0x03); // {10}
- p->accZ = ((uint16_t)joy[4] << 2) | ((joy[5] >>6) & 0x03); // {10}
-
- DEBUG(">%d> C:%c, Z:%c, Joy{x:%02X, y:%02X}, Acc{x:%03X, y:%03X, z:%03X}", pec->decN,
- (p->btnC ? '#' : '.'), (p->btnZ ? '#' : '.'),
- p->joyX, p->joyY, p->accX, p->accY, p->accZ
- );
+//
+void nunchuck_decode(wiiEC_t* const pec) {
+ ecDecNunchuck_t* p = &pec->dec[(pec->decN = !pec->decN)].nunchuck;
+ uint8_t* joy = pec->joy;
+
+ p->btnC = !(joy[5] & 0x02); // !{1}
+ p->btnZ = !(joy[5] & 0x01); // !{1}
+
+ p->joyX = joy[0]; // {8}
+ p->joyY = joy[1]; // {8}
+
+ p->accX = ((uint16_t)joy[2] << 2) | ((joy[5] >> 2) & 0x03); // {10}
+ p->accY = ((uint16_t)joy[3] << 2) | ((joy[5] >> 4) & 0x03); // {10}
+ p->accZ = ((uint16_t)joy[4] << 2) | ((joy[5] >> 6) & 0x03); // {10}
+
+ DEBUG(
+ ">%d> C:%c, Z:%c, Joy{x:%02X, y:%02X}, Acc{x:%03X, y:%03X, z:%03X}",
+ pec->decN,
+ (p->btnC ? '#' : '.'),
+ (p->btnZ ? '#' : '.'),
+ p->joyX,
+ p->joyY,
+ p->accX,
+ p->accY,
+ p->accZ);
}
//+============================================================================ ========================================
// Give each button a unique character identifier
//
-void nunchuck_msg (wiiEC_t* const pec, FuriMessageQueue* const queue)
-{
- ecDecNunchuck_t* new = &pec->dec[pec->decN].nunchuck;
- ecDecNunchuck_t* old = &pec->dec[!pec->decN].nunchuck;
-
- eventMsg_t msg = {
- .id = EVID_WIIEC,
- .wiiEc = {
- .type = WIIEC_NONE,
- .in = ' ',
- .val = 0,
- }
- };
-
- BUTTON(btnC, 'c');
- BUTTON(btnZ, 'z');
-
- ANALOG(joyX, 'x');
- ANALOG(joyY, 'y');
-
- ACCEL(accX, 'x');
- ACCEL(accY, 'y');
- ACCEL(accZ, 'z');
+void nunchuck_msg(wiiEC_t* const pec, FuriMessageQueue* const queue) {
+ ecDecNunchuck_t* new = &pec->dec[pec->decN].nunchuck;
+ ecDecNunchuck_t* old = &pec->dec[!pec->decN].nunchuck;
+
+ eventMsg_t msg = {
+ .id = EVID_WIIEC,
+ .wiiEc = {
+ .type = WIIEC_NONE,
+ .in = ' ',
+ .val = 0,
+ }};
+
+ BUTTON(btnC, 'c');
+ BUTTON(btnZ, 'z');
+
+ ANALOG(joyX, 'x');
+ ANALOG(joyY, 'y');
+
+ ACCEL(accX, 'x');
+ ACCEL(accY, 'y');
+ ACCEL(accZ, 'z');
}
//+============================================================================ ========================================
// https://www.hackster.io/infusion/using-a-wii-nunchuk-with-arduino-597254#toc-5--read-actual-calibration-data-from-the-device-14
//
-void nunchuck_calib (wiiEC_t* const pec, ecCalib_t c)
-{
- ecDecNunchuck_t* src = &pec->dec[pec->decN].nunchuck; // from input
- ecCalNunchuck_t* dst = pec->calS.nunchuck; // to calibration data
-
- if (c & CAL_RESET) { // initialise ready for software calibration
- // LO is set to the MAXIMUM value (so it can be reduced)
- // HI is set to ZERO (so it can be increased)
- RESET_LO_HI(accX, 10); // 10bit value
- RESET_LO_HI(accY, 10); // 10bit value
- RESET_LO_HI(accZ, 10); // 10bit value
-
- RESET_LO_HI(joyX, 8); // 8bit value
- RESET_LO_HI(joyY, 8); // 8bit value
- }
- if (c & CAL_FACTORY) { // (re)set to factory defaults
- //! "[4] LSB of Zero value of X,Y,Z axes" ...helpful!
- //! ...Well, my test nunchuck has bits set in the bottom 6 bits, so let's guess ;)
-
- // No value available - annecdotal tests suggest 8 is reasonable
- FACTORY_LO( accX, 8);
- FACTORY_LO( accY, 8);
- FACTORY_LO( accZ, 8);
-
- // @ 0G
- FACTORY_MID( accX, ((pec->calF[0] <<2) | ((pec->calF[3] >>4) &0x3)) ) ;
- FACTORY_MID( accY, ((pec->calF[1] <<2) | ((pec->calF[3] >>2) &0x3)) ) ;
- FACTORY_MID( accZ, ((pec->calF[2] <<2) | ((pec->calF[3] ) &0x3)) ) ;
-
- // @ 1G
- FACTORY_HI( accX, ((pec->calF[4] <<2) | ((pec->calF[7] >>4) &0x3)) ) ;
- FACTORY_HI( accY, ((pec->calF[5] <<2) | ((pec->calF[7] >>2) &0x3)) ) ;
- FACTORY_HI( accZ, ((pec->calF[6] <<2) | ((pec->calF[7] ) &0x3)) ) ;
-
- // Joysticks
- FACTORY_LO( joyX, pec->calF[ 9] ) ;
- FACTORY_MID(joyX, pec->calF[10] ) ;
- FACTORY_HI( joyX, pec->calF[ 8] ) ;
-
- FACTORY_LO( joyY, pec->calF[12] ) ;
- FACTORY_MID(joyY, pec->calF[13] ) ;
- FACTORY_HI( joyY, pec->calF[11] ) ;
- }
- if (c & CAL_TRACK) { // track maximum and minimum values seen
- TRACK_LO_HI(accX);
- TRACK_LO_HI(accY);
- TRACK_LO_HI(accZ);
-
- TRACK_LO_HI(joyX);
- TRACK_LO_HI(joyY);
- }
- if (c & CAL_RANGE) { // perform software calibration step
- RANGE_LO_HI(accX);
- RANGE_LO_HI(accY);
- RANGE_LO_HI(accZ);
-
- if (!(c & CAL_NOTJOY)) { // double negative!
- RANGE_LO_HI(joyX);
- RANGE_LO_HI(joyY);
- }
- }
- if (c & CAL_CENTRE) { // reset centre point of joystick
- CENTRE(accX);
- CENTRE(accY);
- CENTRE(accZ);
-
- CENTRE(joyX);
- CENTRE(joyY);
- }
+void nunchuck_calib(wiiEC_t* const pec, ecCalib_t c) {
+ ecDecNunchuck_t* src = &pec->dec[pec->decN].nunchuck; // from input
+ ecCalNunchuck_t* dst = pec->calS.nunchuck; // to calibration data
+
+ if(c & CAL_RESET) { // initialise ready for software calibration
+ // LO is set to the MAXIMUM value (so it can be reduced)
+ // HI is set to ZERO (so it can be increased)
+ RESET_LO_HI(accX, 10); // 10bit value
+ RESET_LO_HI(accY, 10); // 10bit value
+ RESET_LO_HI(accZ, 10); // 10bit value
+
+ RESET_LO_HI(joyX, 8); // 8bit value
+ RESET_LO_HI(joyY, 8); // 8bit value
+ }
+ if(c & CAL_FACTORY) { // (re)set to factory defaults
+ //! "[4] LSB of Zero value of X,Y,Z axes" ...helpful!
+ //! ...Well, my test nunchuck has bits set in the bottom 6 bits, so let's guess ;)
+
+ // No value available - annecdotal tests suggest 8 is reasonable
+ FACTORY_LO(accX, 8);
+ FACTORY_LO(accY, 8);
+ FACTORY_LO(accZ, 8);
+
+ // @ 0G
+ FACTORY_MID(accX, ((pec->calF[0] << 2) | ((pec->calF[3] >> 4) & 0x3)));
+ FACTORY_MID(accY, ((pec->calF[1] << 2) | ((pec->calF[3] >> 2) & 0x3)));
+ FACTORY_MID(accZ, ((pec->calF[2] << 2) | ((pec->calF[3]) & 0x3)));
+
+ // @ 1G
+ FACTORY_HI(accX, ((pec->calF[4] << 2) | ((pec->calF[7] >> 4) & 0x3)));
+ FACTORY_HI(accY, ((pec->calF[5] << 2) | ((pec->calF[7] >> 2) & 0x3)));
+ FACTORY_HI(accZ, ((pec->calF[6] << 2) | ((pec->calF[7]) & 0x3)));
+
+ // Joysticks
+ FACTORY_LO(joyX, pec->calF[9]);
+ FACTORY_MID(joyX, pec->calF[10]);
+ FACTORY_HI(joyX, pec->calF[8]);
+
+ FACTORY_LO(joyY, pec->calF[12]);
+ FACTORY_MID(joyY, pec->calF[13]);
+ FACTORY_HI(joyY, pec->calF[11]);
+ }
+ if(c & CAL_TRACK) { // track maximum and minimum values seen
+ TRACK_LO_HI(accX);
+ TRACK_LO_HI(accY);
+ TRACK_LO_HI(accZ);
+
+ TRACK_LO_HI(joyX);
+ TRACK_LO_HI(joyY);
+ }
+ if(c & CAL_RANGE) { // perform software calibration step
+ RANGE_LO_HI(accX);
+ RANGE_LO_HI(accY);
+ RANGE_LO_HI(accZ);
+
+ if(!(c & CAL_NOTJOY)) { // double negative!
+ RANGE_LO_HI(joyX);
+ RANGE_LO_HI(joyY);
+ }
+ }
+ if(c & CAL_CENTRE) { // reset centre point of joystick
+ CENTRE(accX);
+ CENTRE(accY);
+ CENTRE(accZ);
+
+ CENTRE(joyX);
+ CENTRE(joyY);
+ }
}
//============================================================================= ========================================
@@ -152,308 +154,323 @@ void nunchuck_calib (wiiEC_t* const pec, ecCalib_t c)
//
// EG. Move left will effect X ; turn left will effect Y & Z
//
-#define aw 110 // axis width
-#define ah 15 // height {0......7......14}
-#define am 7 // midpoint { 7 }
-#define ar 7 // range {1234567 1234567}
+#define aw 110 // axis width
+#define ah 15 // height {0......7......14}
+#define am 7 // midpoint { 7 }
+#define ar 7 // range {1234567 1234567}
enum {
- ACC_X = 0,
- ACC_Y = 1,
- ACC_Z = 2,
- ACC_CNT = 3,
- ACC_1 = ACC_X, // first
- ACC_N = ACC_Z, // last
+ ACC_X = 0,
+ ACC_Y = 1,
+ ACC_Z = 2,
+ ACC_CNT = 3,
+ ACC_1 = ACC_X, // first
+ ACC_N = ACC_Z, // last
};
//+============================================================================
-static
-void nunchuck_showAcc (Canvas* const canvas, state_t* const state)
-{
- ecDecNunchuck_t* d = &state->ec.dec[state->ec.decN].nunchuck;
- ecCalNunchuck_t* lo = &state->ec.calS.nunchuck[1];
- ecCalNunchuck_t* mid = &state->ec.calS.nunchuck[2];
- ecCalNunchuck_t* hi = &state->ec.calS.nunchuck[3];
-
- int y[ACC_CNT] = {0, 0+(ah+4), 0+((ah+4)*2)};
- int x = 10;
-
- static uint16_t v[ACC_CNT][aw] = {0};
-// static uint16_t tv[ACC_CNT][aw] = {0};
-
- static uint16_t idx = 0;
- static uint16_t cnt = aw -1;
-
- // Only record when scanner NOT-paused
- if (!state->pause) {
- uint16_t dead = (1<<5);
-
- // Find axes y-offsets
- for (int a = ACC_1; a <= ACC_N; a++) {
- uint16_t* dp = NULL; // data value (current reading)
- uint16_t* lp = NULL; // lo value
- uint16_t* mp = NULL; // mid value
- uint16_t* hp = NULL; // hi value
- uint16_t* vp = NULL; // value (result)
-
- switch (a) {
- case ACC_X:
- dp = & d->accX; // data (input)
- lp = & lo->accX; // low \.
- mp = &mid->accX; // mid > calibration
- hp = & hi->accX; // high /
- vp = &v[ ACC_X][idx]; // value (where to store the result)
- break;
- case ACC_Y:
- dp = & d->accY;
- lp = & lo->accY;
- mp = &mid->accY;
- hp = & hi->accY;
- vp = &v[ ACC_Y][idx];
- break;
- case ACC_Z:
- dp = & d->accZ;
- lp = & lo->accZ;
- mp = &mid->accZ;
- hp = & hi->accZ;
- vp = &v[ ACC_Z][idx];
- break;
- default: break ;
- }
-
- // Again - qv. the joysick calibration:
- // This is not the "right way" to do this, it is just "one way" to do it
- // ...mid point and extreme zones have a deadzone
- // ...the rest is evenly divided by the amount of space on the graph
- if ((*dp >= (*mp -dead)) && (*dp <= (*mp +dead))) *vp = ar ;
- else if (*dp >= (*hp -dead)) *vp = ah-1 ;
- else if (*dp <= (*lp +dead)) *vp = 0 ;
- else if (*dp < *mp) {
- uint16_t min = ((*lp +dead) +1);
- uint16_t max = ((*mp -dead) -1);
- float range = (max -min) +1;
- float m = range /(ar-1); // 6 evenly(/fairly) divided zones
- *vp = ((int)((*dp -min) /m)) +1;
-
- } else {//if (*dp > *mp)
- uint16_t min = ((*mp +dead) +1);
- uint16_t max = ((*hp -dead) -1);
- float range = (max -min) +1;
- float m = range /(ar-1); // 6 evenly(/fairly) divided zones
- *vp = ((int)((*dp -min) /m)) +1 +ar;
- }
- }
-
-//! If we decide to offer "export to CSV"
-//! I suggest we keep a second array of true-values, rather than do all the maths every time
-//! Also - the data will need to me moved to the 'state' table - so a.n.other function can save it off
-// tv[ACC_X][idx] = d->accX;
-// tv[ACC_Y][idx] = d->accY;
-// tv[ACC_Z][idx] = d->accZ;
-
- // Prepare for the next datapoint
- if (++idx >= aw) idx = 0 ;
- if (cnt) cnt-- ;
- }
-
- // Auto-pause
- if (state->apause && !idx) state->pause = true ;
-
- // *** Draw axes ***
- show(canvas, 0,y[ACC_X] +((ah -img_6x8_X.h) /2), &img_6x8_X, SHOW_SET_BLK);
- show(canvas, 0,y[ACC_Y] +((ah -img_6x8_Y.h) /2), &img_6x8_Y, SHOW_SET_BLK);
- show(canvas, 0,y[ACC_Z] +((ah -img_6x8_Z.h) /2), &img_6x8_Z, SHOW_SET_BLK);
-
- canvas_set_color(canvas, ColorBlack);
- for (int a = ACC_1; a <= ACC_N; a++) {
- canvas_draw_line(canvas, x-1,y[a] , x -1,y[a]+ah);
- canvas_draw_line(canvas, x ,y[a]+ah, x+aw-1,y[a]+ah);
-
- // Mid & Peak lines
- for (int i = 1; i < aw; i += 3) {
- canvas_draw_dot(canvas, x+i,y[a]);
- canvas_draw_dot(canvas, x+i,y[a] +(ah /2));
- }
- }
-
- // Data (wiper display - see notes.txt for scrolling algorithm)
- int end = idx ? idx : aw;
- for (int a = ACC_1; a <= ACC_N; a++) {
- canvas_draw_dot(canvas, x,y[a]+v[a][idx]);
- for (int i = 1; i < end; i++)
- canvas_draw_line(canvas, x+i,y[a]+v[a][i-1] , x+i,y[a]+v[a][i]);
- if (!state->apause)
- for (int i = end+10; i < aw -cnt; i++)
- canvas_draw_line(canvas, x+i,y[a]+v[a][i-1] , x+i,y[a]+v[a][i]);
- }
- // Wipe bar
- if (end < aw) canvas_draw_line(canvas, x+end,y[0], x+end,y[2]+ah-1);
- if (++end < aw) canvas_draw_line(canvas, x+end,y[0], x+end,y[2]+ah-1);
- if (++end < aw) canvas_draw_line(canvas, x+end,y[0], x+end,y[2]+ah-1);
-
- // *** Mode buttons ***
- show(canvas, 0,55, &img_key_L, SHOW_SET_BLK); // mode key
-
- if ((state->calib & CAL_RANGE) || state->pause) state->flash++ ;
-
- // -pause- ...yeah, this got a little out of hand! LOL!
- if (state->pause || state->apause) {
- if (state->pause && state->apause && !idx) {
- if (state->flash &8) {
- show(canvas, 108,56, &img_key_U, SHOW_SET_BLK);
- } else {
- show(canvas, 108,56, &img_key_Ui, SHOW_SET_BLK);
- canvas_draw_line(canvas, x+aw,y[0], x+aw,y[2]+ah-1);
- }
- } else {
- show(canvas, 108,56, &img_key_Ui, SHOW_SET_BLK);
- }
- } else {
- show(canvas, 108,56, &img_key_U, SHOW_SET_BLK); // pause
- }
-
- // -calibration-
- if (state->calib & CAL_RANGE) {
- show(canvas, 119,55, (state->flash &8) ? &img_key_OKi : &img_key_OK, SHOW_SET_BLK);
- } else {
- show(canvas, 119,55, &img_key_OK, SHOW_SET_BLK);
- }
+static void nunchuck_showAcc(Canvas* const canvas, state_t* const state) {
+ ecDecNunchuck_t* d = &state->ec.dec[state->ec.decN].nunchuck;
+ ecCalNunchuck_t* lo = &state->ec.calS.nunchuck[1];
+ ecCalNunchuck_t* mid = &state->ec.calS.nunchuck[2];
+ ecCalNunchuck_t* hi = &state->ec.calS.nunchuck[3];
+
+ int y[ACC_CNT] = {0, 0 + (ah + 4), 0 + ((ah + 4) * 2)};
+ int x = 10;
+
+ static uint16_t v[ACC_CNT][aw] = {0};
+ // static uint16_t tv[ACC_CNT][aw] = {0};
+
+ static uint16_t idx = 0;
+ static uint16_t cnt = aw - 1;
+
+ // Only record when scanner NOT-paused
+ if(!state->pause) {
+ uint16_t dead = (1 << 5);
+
+ // Find axes y-offsets
+ for(int a = ACC_1; a <= ACC_N; a++) {
+ uint16_t* dp = NULL; // data value (current reading)
+ uint16_t* lp = NULL; // lo value
+ uint16_t* mp = NULL; // mid value
+ uint16_t* hp = NULL; // hi value
+ uint16_t* vp = NULL; // value (result)
+
+ switch(a) {
+ case ACC_X:
+ dp = &d->accX; // data (input)
+ lp = &lo->accX; // low \.
+ mp = &mid->accX; // mid > calibration
+ hp = &hi->accX; // high /
+ vp = &v[ACC_X][idx]; // value (where to store the result)
+ break;
+ case ACC_Y:
+ dp = &d->accY;
+ lp = &lo->accY;
+ mp = &mid->accY;
+ hp = &hi->accY;
+ vp = &v[ACC_Y][idx];
+ break;
+ case ACC_Z:
+ dp = &d->accZ;
+ lp = &lo->accZ;
+ mp = &mid->accZ;
+ hp = &hi->accZ;
+ vp = &v[ACC_Z][idx];
+ break;
+ default:
+ break;
+ }
+
+ // Again - qv. the joysick calibration:
+ // This is not the "right way" to do this, it is just "one way" to do it
+ // ...mid point and extreme zones have a deadzone
+ // ...the rest is evenly divided by the amount of space on the graph
+ if((*dp >= (*mp - dead)) && (*dp <= (*mp + dead)))
+ *vp = ar;
+ else if(*dp >= (*hp - dead))
+ *vp = ah - 1;
+ else if(*dp <= (*lp + dead))
+ *vp = 0;
+ else if(*dp < *mp) {
+ uint16_t min = ((*lp + dead) + 1);
+ uint16_t max = ((*mp - dead) - 1);
+ float range = (max - min) + 1;
+ float m = range / (ar - 1); // 6 evenly(/fairly) divided zones
+ *vp = ((int)((*dp - min) / m)) + 1;
+
+ } else { //if (*dp > *mp)
+ uint16_t min = ((*mp + dead) + 1);
+ uint16_t max = ((*hp - dead) - 1);
+ float range = (max - min) + 1;
+ float m = range / (ar - 1); // 6 evenly(/fairly) divided zones
+ *vp = ((int)((*dp - min) / m)) + 1 + ar;
+ }
+ }
+
+ //! If we decide to offer "export to CSV"
+ //! I suggest we keep a second array of true-values, rather than do all the maths every time
+ //! Also - the data will need to me moved to the 'state' table - so a.n.other function can save it off
+ // tv[ACC_X][idx] = d->accX;
+ // tv[ACC_Y][idx] = d->accY;
+ // tv[ACC_Z][idx] = d->accZ;
+
+ // Prepare for the next datapoint
+ if(++idx >= aw) idx = 0;
+ if(cnt) cnt--;
+ }
+
+ // Auto-pause
+ if(state->apause && !idx) state->pause = true;
+
+ // *** Draw axes ***
+ show(canvas, 0, y[ACC_X] + ((ah - img_6x8_X.h) / 2), &img_6x8_X, SHOW_SET_BLK);
+ show(canvas, 0, y[ACC_Y] + ((ah - img_6x8_Y.h) / 2), &img_6x8_Y, SHOW_SET_BLK);
+ show(canvas, 0, y[ACC_Z] + ((ah - img_6x8_Z.h) / 2), &img_6x8_Z, SHOW_SET_BLK);
+
+ canvas_set_color(canvas, ColorBlack);
+ for(int a = ACC_1; a <= ACC_N; a++) {
+ canvas_draw_line(canvas, x - 1, y[a], x - 1, y[a] + ah);
+ canvas_draw_line(canvas, x, y[a] + ah, x + aw - 1, y[a] + ah);
+
+ // Mid & Peak lines
+ for(int i = 1; i < aw; i += 3) {
+ canvas_draw_dot(canvas, x + i, y[a]);
+ canvas_draw_dot(canvas, x + i, y[a] + (ah / 2));
+ }
+ }
+
+ // Data (wiper display - see notes.txt for scrolling algorithm)
+ int end = idx ? idx : aw;
+ for(int a = ACC_1; a <= ACC_N; a++) {
+ canvas_draw_dot(canvas, x, y[a] + v[a][idx]);
+ for(int i = 1; i < end; i++)
+ canvas_draw_line(canvas, x + i, y[a] + v[a][i - 1], x + i, y[a] + v[a][i]);
+ if(!state->apause)
+ for(int i = end + 10; i < aw - cnt; i++)
+ canvas_draw_line(canvas, x + i, y[a] + v[a][i - 1], x + i, y[a] + v[a][i]);
+ }
+ // Wipe bar
+ if(end < aw) canvas_draw_line(canvas, x + end, y[0], x + end, y[2] + ah - 1);
+ if(++end < aw) canvas_draw_line(canvas, x + end, y[0], x + end, y[2] + ah - 1);
+ if(++end < aw) canvas_draw_line(canvas, x + end, y[0], x + end, y[2] + ah - 1);
+
+ // *** Mode buttons ***
+ show(canvas, 0, 55, &img_key_L, SHOW_SET_BLK); // mode key
+
+ if((state->calib & CAL_RANGE) || state->pause) state->flash++;
+
+ // -pause- ...yeah, this got a little out of hand! LOL!
+ if(state->pause || state->apause) {
+ if(state->pause && state->apause && !idx) {
+ if(state->flash & 8) {
+ show(canvas, 108, 56, &img_key_U, SHOW_SET_BLK);
+ } else {
+ show(canvas, 108, 56, &img_key_Ui, SHOW_SET_BLK);
+ canvas_draw_line(canvas, x + aw, y[0], x + aw, y[2] + ah - 1);
+ }
+ } else {
+ show(canvas, 108, 56, &img_key_Ui, SHOW_SET_BLK);
+ }
+ } else {
+ show(canvas, 108, 56, &img_key_U, SHOW_SET_BLK); // pause
+ }
+
+ // -calibration-
+ if(state->calib & CAL_RANGE) {
+ show(canvas, 119, 55, (state->flash & 8) ? &img_key_OKi : &img_key_OK, SHOW_SET_BLK);
+ } else {
+ show(canvas, 119, 55, &img_key_OK, SHOW_SET_BLK);
+ }
}
-# undef aw
-# undef ah
-# undef am
-# undef ar
+#undef aw
+#undef ah
+#undef am
+#undef ar
//+============================================================================ ========================================
// Default nunchuck screen
//
-void nunchuck_show (Canvas* const canvas, state_t* const state)
-{
- // Nunchucks have TWO scenes
- if (state->scene == SCENE_NUNCHUCK_ACC) return nunchuck_showAcc(canvas, state) ;
-
- // Default scene
- ecDecNunchuck_t* d = &state->ec.dec[state->ec.decN].nunchuck;
- ecCalNunchuck_t* c = (state->hold) ? &state->ec.calS.nunchuck[(state->hold < 0) ? 0 : 4]
- : (ecCalNunchuck_t*)d ; //! danger will robinson!
- ecCalNunchuck_t* js = state->ec.calS.nunchuck;
-
- // X, Y, Z
- show(canvas, 42,0, &img_6x8_X, SHOW_SET_BLK);
- show(canvas, 73,0, &img_6x8_Y, SHOW_SET_BLK);
- show(canvas, 104,0, &img_6x8_Z, SHOW_SET_BLK);
-
- canvas_draw_str_aligned(canvas, 0,14, AlignLeft, AlignTop, "Accel");
- canvas_draw_str_aligned(canvas, 0,28, AlignLeft, AlignTop, "Joy");
-
- // accel values
- showHex(canvas, 34,12, c->accX, 3,2);
- showHex(canvas, 65,12, c->accY, 3,2);
- showHex(canvas, 96,12, c->accZ, 3,2);
- // Joy values
- showHex(canvas, 38,27, c->joyX, 2,2);
- showHex(canvas, 69,27, c->joyY, 2,2);
-
- showJoy(canvas, 103,32, js[1].joyX, js[2].joyX, js[3].joyX,
- js[1].joyY, js[2].joyY, js[3].joyY, d->joyX,d->joyY, 8);
-
- // buttons
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_str_aligned(canvas, 0,44, AlignLeft, AlignTop, "Button");
-
- if (!d->btnC) {
- canvas_draw_rframe(canvas, 36,42, 18,12, 6);
- show(canvas, 42,44, &img_6x8_C, SHOW_SET_BLK);
- } else {
- canvas_draw_rbox(canvas, 36,42, 18,12, 6);
- show(canvas, 42,44, &img_6x8_C, SHOW_SET_WHT);
- canvas_set_color(canvas, ColorBlack);
- }
-
- if (!d->btnZ) {
- canvas_draw_rframe(canvas, 64,40, 24,16, 2);
- show(canvas, 73,44, &img_6x8_Z, SHOW_SET_BLK);
- } else {
- canvas_draw_rbox(canvas, 64,40, 24,16, 2);
- show(canvas, 73,44, &img_6x8_Z, SHOW_SET_WHT);
- }
-
- // Navigation
- showPeakHold(state, canvas, state->hold); // peak keys
- show(canvas, 0,55, &img_key_L, SHOW_SET_BLK); // mode keys
- show(canvas, 9,55, &img_key_R, SHOW_SET_BLK);
+void nunchuck_show(Canvas* const canvas, state_t* const state) {
+ // Nunchucks have TWO scenes
+ if(state->scene == SCENE_NUNCHUCK_ACC) return nunchuck_showAcc(canvas, state);
+
+ // Default scene
+ ecDecNunchuck_t* d = &state->ec.dec[state->ec.decN].nunchuck;
+ ecCalNunchuck_t* c = (state->hold) ? &state->ec.calS.nunchuck[(state->hold < 0) ? 0 : 4] :
+ (ecCalNunchuck_t*)d; //! danger will robinson!
+ ecCalNunchuck_t* js = state->ec.calS.nunchuck;
+
+ // X, Y, Z
+ show(canvas, 42, 0, &img_6x8_X, SHOW_SET_BLK);
+ show(canvas, 73, 0, &img_6x8_Y, SHOW_SET_BLK);
+ show(canvas, 104, 0, &img_6x8_Z, SHOW_SET_BLK);
+
+ canvas_draw_str_aligned(canvas, 0, 14, AlignLeft, AlignTop, "Accel");
+ canvas_draw_str_aligned(canvas, 0, 28, AlignLeft, AlignTop, "Joy");
+
+ // accel values
+ showHex(canvas, 34, 12, c->accX, 3, 2);
+ showHex(canvas, 65, 12, c->accY, 3, 2);
+ showHex(canvas, 96, 12, c->accZ, 3, 2);
+ // Joy values
+ showHex(canvas, 38, 27, c->joyX, 2, 2);
+ showHex(canvas, 69, 27, c->joyY, 2, 2);
+
+ showJoy(
+ canvas,
+ 103,
+ 32,
+ js[1].joyX,
+ js[2].joyX,
+ js[3].joyX,
+ js[1].joyY,
+ js[2].joyY,
+ js[3].joyY,
+ d->joyX,
+ d->joyY,
+ 8);
+
+ // buttons
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_str_aligned(canvas, 0, 44, AlignLeft, AlignTop, "Button");
+
+ if(!d->btnC) {
+ canvas_draw_rframe(canvas, 36, 42, 18, 12, 6);
+ show(canvas, 42, 44, &img_6x8_C, SHOW_SET_BLK);
+ } else {
+ canvas_draw_rbox(canvas, 36, 42, 18, 12, 6);
+ show(canvas, 42, 44, &img_6x8_C, SHOW_SET_WHT);
+ canvas_set_color(canvas, ColorBlack);
+ }
+
+ if(!d->btnZ) {
+ canvas_draw_rframe(canvas, 64, 40, 24, 16, 2);
+ show(canvas, 73, 44, &img_6x8_Z, SHOW_SET_BLK);
+ } else {
+ canvas_draw_rbox(canvas, 64, 40, 24, 16, 2);
+ show(canvas, 73, 44, &img_6x8_Z, SHOW_SET_WHT);
+ }
+
+ // Navigation
+ showPeakHold(state, canvas, state->hold); // peak keys
+ show(canvas, 0, 55, &img_key_L, SHOW_SET_BLK); // mode keys
+ show(canvas, 9, 55, &img_key_R, SHOW_SET_BLK);
}
//+============================================================================ ========================================
-static
-bool nunchuck_keyAcc (const eventMsg_t* const msg, state_t* const state)
-{
- int used = false; // assume key is NOT-handled
-
- switch (msg->input.type) {
- case InputTypeShort: //# input.key) {
- case InputKeyDown: //# pause) state->pause = false ; // Paused? Restart
- else state->apause = !state->apause ; // No? toggle auto-pause
- used = true;
- break;
-
- case InputKeyLeft: //# calib &= ~CAL_NOTJOY; // DO calibrate joystick in NUNCHUCK mode
- used = true;
- break;
-
- default: break ; //#
- }
- break;
-
- default: break ;
- }
-
- // Calibration keys
- if (!used) used = key_calib(msg, state) ;
-
- return used;
+static bool nunchuck_keyAcc(const eventMsg_t* const msg, state_t* const state) {
+ int used = false; // assume key is NOT-handled
+
+ switch(msg->input.type) {
+ case InputTypeShort: //# input.key) {
+ case InputKeyDown: //# pause)
+ state->pause = false; // Paused? Restart
+ else
+ state->apause = !state->apause; // No? toggle auto-pause
+ used = true;
+ break;
+
+ case InputKeyLeft: //# calib &= ~CAL_NOTJOY; // DO calibrate joystick in NUNCHUCK mode
+ used = true;
+ break;
+
+ default:
+ break; //#
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Calibration keys
+ if(!used) used = key_calib(msg, state);
+
+ return used;
}
//+============================================================================ ========================================
-bool nunchuck_key (const eventMsg_t* const msg, state_t* const state)
-{
- // Nunchucks have TWO scenes
- if (state->scene == SCENE_NUNCHUCK_ACC) return nunchuck_keyAcc(msg, state) ;
-
- // Default scene
- int used = false; // assume key is NOT-handled
-
- switch (msg->input.type) {
- case InputTypeShort: //# input.key) {
- case InputKeyLeft: //# calib |= CAL_NOTJOY; // do NOT calibrate joystick in _ACC mode
- used = true;
- break;
- default: break ; //#
- }
- break;
-
- default: break ;
- }
-
- // Calibration keys
- if (!used) used = key_calib(msg, state) ;
-
- return used;
+bool nunchuck_key(const eventMsg_t* const msg, state_t* const state) {
+ // Nunchucks have TWO scenes
+ if(state->scene == SCENE_NUNCHUCK_ACC) return nunchuck_keyAcc(msg, state);
+
+ // Default scene
+ int used = false; // assume key is NOT-handled
+
+ switch(msg->input.type) {
+ case InputTypeShort: //# input.key) {
+ case InputKeyLeft: //# calib |= CAL_NOTJOY; // do NOT calibrate joystick in _ACC mode
+ used = true;
+ break;
+ default:
+ break; //#
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Calibration keys
+ if(!used) used = key_calib(msg, state);
+
+ return used;
}
diff --git a/applications/plugins/wii_ec_anal/wii_ec_nunchuck.h b/applications/plugins/wii_ec_anal/wii_ec_nunchuck.h
index 020ecd5559..e202cc7f1e 100644
--- a/applications/plugins/wii_ec_anal/wii_ec_nunchuck.h
+++ b/applications/plugins/wii_ec_anal/wii_ec_nunchuck.h
@@ -1,53 +1,50 @@
-#ifndef WII_EC_NUNCHUCK_H_
-#define WII_EC_NUNCHUCK_H_
+#ifndef WII_EC_NUNCHUCK_H_
+#define WII_EC_NUNCHUCK_H_
-#include
-#include
+#include
+#include
//-----------------------------------------------------------------------------
// Controllers which have calibration must have their calibratable controls here
//! Is there a better way to get the start of the decode struct to match the calibration struct ?
#define NUNCHUCK_ANALOGUE \
- uint8_t joyX, joyY; \
- uint16_t accX, accY, accZ;
+ uint8_t joyX, joyY; \
+ uint16_t accX, accY, accZ;
//-----------------------------------------------------------------------------
// Calibratable controls
//
-typedef
- struct ecCalNunchuck {
- NUNCHUCK_ANALOGUE
- }
-ecCalNunchuck_t;
+typedef struct ecCalNunchuck {
+ NUNCHUCK_ANALOGUE
+} ecCalNunchuck_t;
//-----------------------------------------------------------------------------
// All controls
//
-typedef
- struct ecDecNunchuck {
- NUNCHUCK_ANALOGUE // MUST be first
+typedef struct ecDecNunchuck {
+ NUNCHUCK_ANALOGUE // MUST be first
- // Digital controls
- bool btnC, btnZ; // BTN{c, z}
- }
-ecDecNunchuck_t;
+ // Digital controls
+ bool btnC,
+ btnZ; // BTN{c, z}
+} ecDecNunchuck_t;
#undef NUNCHUCK_ANALOGUE
//=============================================================================
// Function prototypes
//
-#include // Canvas
-typedef struct wiiEC wiiEC_t ;
-typedef enum ecCalib ecCalib_t ;
-typedef struct state state_t ;
-typedef struct eventMsg eventMsg_t ;
-
-void nunchuck_decode (wiiEC_t* const pec) ;
-void nunchuck_msg (wiiEC_t* const pec, FuriMessageQueue* const queue) ;
-void nunchuck_calib (wiiEC_t* const pec, ecCalib_t c) ;
-
-void nunchuck_show (Canvas* const canvas, state_t* const state) ;
-bool nunchuck_key (const eventMsg_t* const msg, state_t* const state) ;
+#include // Canvas
+typedef struct wiiEC wiiEC_t;
+typedef enum ecCalib ecCalib_t;
+typedef struct state state_t;
+typedef struct eventMsg eventMsg_t;
+
+void nunchuck_decode(wiiEC_t* const pec);
+void nunchuck_msg(wiiEC_t* const pec, FuriMessageQueue* const queue);
+void nunchuck_calib(wiiEC_t* const pec, ecCalib_t c);
+
+void nunchuck_show(Canvas* const canvas, state_t* const state);
+bool nunchuck_key(const eventMsg_t* const msg, state_t* const state);
#endif //WII_EC_NUNCHUCK_H_
diff --git a/applications/plugins/wii_ec_anal/wii_ec_udraw.c b/applications/plugins/wii_ec_anal/wii_ec_udraw.c
index babbc92abf..82987b205e 100644
--- a/applications/plugins/wii_ec_anal/wii_ec_udraw.c
+++ b/applications/plugins/wii_ec_anal/wii_ec_udraw.c
@@ -1,16 +1,16 @@
//! udraw support is NOT written - this is just notes about the init function
-#include
-#include // Core API
+#include
+#include // Core API
-#include "wii_anal.h"
-#include "wii_ec.h"
-#include "bc_logging.h"
+#include "wii_anal.h"
+#include "wii_ec.h"
+#include "bc_logging.h"
-#include "i2c_workaround.h" //! temporary workaround for a bug in furi i2c [see header]
+#include "i2c_workaround.h" //! temporary workaround for a bug in furi i2c [see header]
// ** If you want to see what this source code looks like with all the MACROs expanded
// ** grep -v '#include ' wii_ec_udraw.c | gcc -E -o /dev/stdout -xc -
-# include "wii_ec_macros.h"
+#include "wii_ec_macros.h"
//+============================================================================ ========================================
// https://github.com/madhephaestus/WiiChuck/blob/master/src/Drawsome.cpp#L3
@@ -27,13 +27,12 @@
// read 6 bytes starting from 0x00 (#3)
// read 6 bytes starting from 0x00 (#4)
//
-bool udraw_init (wiiEC_t* const pec)
-{
- ENTER;
- bool rv = true;
+bool udraw_init(wiiEC_t* const pec) {
+ ENTER;
+ bool rv = true;
-(void)pec;
-/*
+ (void)pec;
+ /*
//! this is the Drawsome code, NOT the uDraw code !!
static const uint8_t reg[9] = {0x20, 0x28, 0x30, 0x38, 0x00, 0x00, 0xFB, 0x00, 0x00}; // 0..8
const uint8_t* p = reg;
@@ -72,74 +71,79 @@ bool udraw_init (wiiEC_t* const pec)
done:
*/
- LEAVE;
- return rv;
+ LEAVE;
+ return rv;
}
//+============================================================================ ========================================
-bool udraw_key (const eventMsg_t* const msg, state_t* const state)
-{
-(void)state;
- bool run = true;
-
- switch (msg->input.type) {
- case InputTypeShort: //# input.key) {
- case InputKeyUp: //# ! After INPUT_LONG_PRESS interval, asynch to InputTypeRelease
- switch (msg->input.key) {
- case InputKeyUp: //# >U [ LONG-UP ]
- case InputKeyDown: //# >D [ LONG-DOWN ]
- case InputKeyLeft: //# >L [ LONG-LEFT ]
- case InputKeyRight: //# >R [ LONG-RIGHT ]
- case InputKeyOk: //# >O [ LONG-OK ]
- case InputKeyBack: //# >B [ LONG-BACK ]
- default: break ; //# >?
- }
- break;
- case InputTypePress: //# +! After debounce
- switch (msg->input.key) {
- case InputKeyUp: //# +U [ SHORT-UP ]
- case InputKeyDown: //# +D [ SHORT-DOWN ]
- case InputKeyLeft: //# +L [ SHORT-LEFT ]
- case InputKeyRight: //# +R [ SHORT-RIGHT ]
- case InputKeyOk: //# +O [ SHORT-OK ]
- case InputKeyBack: //# +B [ SHORT-BACK ]
- default: break ; //# +?
- }
- break;
- case InputTypeRepeat: //# *! With INPUT_REPEATE_PRESS period after InputTypeLong event
- switch (msg->input.key) {
- case InputKeyUp: //# *U [ REPEAT-UP ]
- case InputKeyDown: //# *D [ REPEAT-DOWN ]
- case InputKeyLeft: //# *L [ REPEAT-LEFT ]
- case InputKeyRight: //# *R [ REPEAT-RIGHT ]
- case InputKeyOk: //# *O [ REPEAT-OK ]
- case InputKeyBack: //# *B [ REPEAT-BACK ]
- default: break ; //# *?
- }
- break;
- case InputTypeRelease: //# -! After debounce
- switch (msg->input.key) {
- case InputKeyUp: //# -U [ RELEASE-UP ]
- case InputKeyDown: //# -D [ RELEASE-DOWN ]
- case InputKeyLeft: //# -L [ RELEASE-LEFT ]
- case InputKeyRight: //# -R [ RELEASE-RIGHT ]
- case InputKeyOk: //# -O [ RELEASE-OK ]
- case InputKeyBack: //# -B [ RELEASE-BACK ]
- default: break ; //# -?
- }
- break;
- default: return true ;
- }
-
- return run;
+bool udraw_key(const eventMsg_t* const msg, state_t* const state) {
+ (void)state;
+ bool run = true;
+
+ switch(msg->input.type) {
+ case InputTypeShort: //# input.key) {
+ case InputKeyUp: //# ! After INPUT_LONG_PRESS interval, asynch to InputTypeRelease
+ switch(msg->input.key) {
+ case InputKeyUp: //# >U [ LONG-UP ]
+ case InputKeyDown: //# >D [ LONG-DOWN ]
+ case InputKeyLeft: //# >L [ LONG-LEFT ]
+ case InputKeyRight: //# >R [ LONG-RIGHT ]
+ case InputKeyOk: //# >O [ LONG-OK ]
+ case InputKeyBack: //# >B [ LONG-BACK ]
+ default:
+ break; //# >?
+ }
+ break;
+ case InputTypePress: //# +! After debounce
+ switch(msg->input.key) {
+ case InputKeyUp: //# +U [ SHORT-UP ]
+ case InputKeyDown: //# +D [ SHORT-DOWN ]
+ case InputKeyLeft: //# +L [ SHORT-LEFT ]
+ case InputKeyRight: //# +R [ SHORT-RIGHT ]
+ case InputKeyOk: //# +O [ SHORT-OK ]
+ case InputKeyBack: //# +B [ SHORT-BACK ]
+ default:
+ break; //# +?
+ }
+ break;
+ case InputTypeRepeat: //# *! With INPUT_REPEATE_PRESS period after InputTypeLong event
+ switch(msg->input.key) {
+ case InputKeyUp: //# *U [ REPEAT-UP ]
+ case InputKeyDown: //# *D [ REPEAT-DOWN ]
+ case InputKeyLeft: //# *L [ REPEAT-LEFT ]
+ case InputKeyRight: //# *R [ REPEAT-RIGHT ]
+ case InputKeyOk: //# *O [ REPEAT-OK ]
+ case InputKeyBack: //# *B [ REPEAT-BACK ]
+ default:
+ break; //# *?
+ }
+ break;
+ case InputTypeRelease: //# -! After debounce
+ switch(msg->input.key) {
+ case InputKeyUp: //# -U [ RELEASE-UP ]
+ case InputKeyDown: //# -D [ RELEASE-DOWN ]
+ case InputKeyLeft: //# -L [ RELEASE-LEFT ]
+ case InputKeyRight: //# -R [ RELEASE-RIGHT ]
+ case InputKeyOk: //# -O [ RELEASE-OK ]
+ case InputKeyBack: //# -B [ RELEASE-BACK ]
+ default:
+ break; //# -?
+ }
+ break;
+ default:
+ return true;
+ }
+
+ return run;
}
diff --git a/applications/plugins/wii_ec_anal/wii_ec_udraw.h b/applications/plugins/wii_ec_anal/wii_ec_udraw.h
index 1721894e58..9283fd95d9 100644
--- a/applications/plugins/wii_ec_anal/wii_ec_udraw.h
+++ b/applications/plugins/wii_ec_anal/wii_ec_udraw.h
@@ -1,18 +1,18 @@
-#ifndef WII_EC_UDRAW_H_
-#define WII_EC_UDRAW_H_
+#ifndef WII_EC_UDRAW_H_
+#define WII_EC_UDRAW_H_
-#include
-#include
+#include
+#include
//============================================================================= =======================================
// Function prototypes
//
-typedef struct wiiEC wiiEC_t ;
-typedef enum ecCalib ecCalib_t ;
-typedef struct eventMsg eventMsg_t ;
-typedef struct state state_t ;
+typedef struct wiiEC wiiEC_t;
+typedef enum ecCalib ecCalib_t;
+typedef struct eventMsg eventMsg_t;
+typedef struct state state_t;
-bool udraw_init (wiiEC_t* const pec) ;
-bool udraw_key (const eventMsg_t* const msg, state_t* const state) ;
+bool udraw_init(wiiEC_t* const pec);
+bool udraw_key(const eventMsg_t* const msg, state_t* const state);
#endif //WII_EC_UDRAW_H_
diff --git a/applications/plugins/wii_ec_anal/wii_i2c.c b/applications/plugins/wii_ec_anal/wii_i2c.c
index 90fe221634..f5d6840d9d 100644
--- a/applications/plugins/wii_ec_anal/wii_i2c.c
+++ b/applications/plugins/wii_ec_anal/wii_i2c.c
@@ -17,103 +17,98 @@
// 0xFA..0xFF ( 6 bytes) ... [r] Perhipheral ID
//----------------------------------------------------------------------------- ----------------------------------------
-#include
-#include
-#include
+#include
+#include
+#include
-#include
-#include
-#include
+#include
+#include
+#include
-#include "i2c_workaround.h" //! temporary workaround for a bug in furi i2c [see header]
+#include "i2c_workaround.h" //! temporary workaround for a bug in furi i2c [see header]
-#include "wii_anal.h"
-#include "wii_i2c.h"
-#include "wii_ec.h"
+#include "wii_anal.h"
+#include "wii_i2c.h"
+#include "wii_ec.h"
-#include "bc_logging.h"
+#include "bc_logging.h"
//----------------------------------------------------------------------------- ----------------------------------------
// Wii Extension Controller i2c Bus address
-static const uint8_t ec_i2cAddr = 0x52;
+static const uint8_t ec_i2cAddr = 0x52;
// Initialise for UNencrypted comms
-static const uint8_t regInit1 = 0xF0;
-static const uint8_t regInit2 = 0xFB;
-static const uint8_t cmdInit1[] = {regInit1, 0x55};
-static const uint8_t cmdInit2[] = {regInit2, 0x00};
+static const uint8_t regInit1 = 0xF0;
+static const uint8_t regInit2 = 0xFB;
+static const uint8_t cmdInit1[] = {regInit1, 0x55};
+static const uint8_t cmdInit2[] = {regInit2, 0x00};
// Initialise for ENcrypted comms
-static const uint8_t regInitEnc = 0x40;
-static const uint8_t cmdInitEnc[] = {regInitEnc, 0x00};
+static const uint8_t regInitEnc = 0x40;
+static const uint8_t cmdInitEnc[] = {regInitEnc, 0x00};
// Crypto key (PSK), base register : {0x40..0x4F}[2][8]
-static const uint8_t regEnc = 0x40; // ENC_LEN
+static const uint8_t regEnc = 0x40; // ENC_LEN
// Controller State data, base register : {0x00..0x05}[6]
-static const uint8_t regJoy = 0x00; // JOY_LEN
+static const uint8_t regJoy = 0x00; // JOY_LEN
// Calibration data, base register : {0x20..0x2F}[16]
-static const uint8_t regCal = 0x20; // CAL_LEN
+static const uint8_t regCal = 0x20; // CAL_LEN
// Controller ID, base register : {0xFA..0xFF}[6]
-static const uint8_t regPid = 0xFA; // PID_LEN
+static const uint8_t regPid = 0xFA; // PID_LEN
//+============================================================================ ========================================
// Hexdump a buffer to the logfile
//
#if LOG_LEVEL >= 4 // INFO
-static
-void dump (const uint8_t* buf, const unsigned int len, const char* id)
-{
- // snprintf() would be useful!
- char s[128] = {0};
- char* p = NULL;
-
- strcpy(s, id);
- p = s +strlen(s);
- *p++ = ':';
- *p++ = ' ';
- *p++ = '{';
-
- for (unsigned int i = 0; i < len; i++) {
- uint8_t hi = (buf[i] &0xF0) >>4;
- uint8_t lo = (buf[i] &0x0F);
-
- hi = hi + ((hi > 9) ? ('A' -10) : '0');
- lo = lo + ((lo > 9) ? ('A' -10) : '0');
-
- *p++ = (char)hi;
- *p++ = (char)lo;
- *p++ = ',';
- }
- *p = '\0';
- *--p = '}';
- INFO(s);
+static void dump(const uint8_t* buf, const unsigned int len, const char* id) {
+ // snprintf() would be useful!
+ char s[128] = {0};
+ char* p = NULL;
+
+ strcpy(s, id);
+ p = s + strlen(s);
+ *p++ = ':';
+ *p++ = ' ';
+ *p++ = '{';
+
+ for(unsigned int i = 0; i < len; i++) {
+ uint8_t hi = (buf[i] & 0xF0) >> 4;
+ uint8_t lo = (buf[i] & 0x0F);
+
+ hi = hi + ((hi > 9) ? ('A' - 10) : '0');
+ lo = lo + ((lo > 9) ? ('A' - 10) : '0');
+
+ *p++ = (char)hi;
+ *p++ = (char)lo;
+ *p++ = ',';
+ }
+ *p = '\0';
+ *--p = '}';
+ INFO(s);
}
#else
-# define dump(...)
+#define dump(...)
#endif
//+============================================================================ ========================================
//
//! -W-A-R-N-I-N-G- : THIS ENCRYPTION CODE SHOULD NEVER BE REQUIRED ... AS SUCH, I'VE NEVER TESTED IT
//
-static
-void decrypt (uint8_t* buf, const uint8_t* encKey, const uint8_t reg, unsigned int len)
-{
-#if 1 // Use standard algorithm
- // decrypted_byte = (encrypted_byte XOR encKey[1][address%8]) + encKey[2][address%8]
- for (uint8_t* p = buf; p < buf+len; p++)
- *p = (*p ^ encKey[(reg +(p -buf)) %8]) + encKey[8 +((reg +(p -buf)) %8)];
-
-#else //! This is (I think) a shortcut for an all-zero key [not tested]
- (void)encKey;
- (void)reg;
- for (uint8_t* p = buf; p < buf+len; p++)
- *p = (*p ^ 0x17) + 0x17;
+static void decrypt(uint8_t* buf, const uint8_t* encKey, const uint8_t reg, unsigned int len) {
+#if 1 // Use standard algorithm
+ // decrypted_byte = (encrypted_byte XOR encKey[1][address%8]) + encKey[2][address%8]
+ for(uint8_t* p = buf; p < buf + len; p++)
+ *p = (*p ^ encKey[(reg + (p - buf)) % 8]) + encKey[8 + ((reg + (p - buf)) % 8)];
+
+#else //! This is (I think) a shortcut for an all-zero key [not tested]
+ (void)encKey;
+ (void)reg;
+ for(uint8_t* p = buf; p < buf + len; p++) *p = (*p ^ 0x17) + 0x17;
#endif
}
@@ -123,38 +118,38 @@ void decrypt (uint8_t* buf, const uint8_t* encKey, const uint8_t reg, unsign
//
// Returns: {0:OK, >0:Error}
//
-int ecRead (wiiEC_t* pec)
-{
- ENTER;
- int rv = 0; // assume success
-
- if (!pec->init) {
- WARN("%s : device not initialised", __func__);
- rv = 1;
- goto bail;
- }
-
- if (!furi_hal_i2c_is_device_ready(i2cBus,i2cAddr, i2cTimeout)) {
- INFO("%s : device disconnected", __func__);
- pec->init = false;
- rv = 2;
- goto bail;
- }
-
- if (!furi_hal_i2c_trxd(i2cBus,i2cAddr, ®Joy,1, pec->joy,JOY_LEN, i2cTimeout,i2cReadWait)) {
- ERROR("%s : trxd fail", __func__);
- rv = 3;
- goto bail;
- }
-
- if (pec->encrypt) decrypt(pec->joy, pec->encKey, regJoy, JOY_LEN) ;
-
- // Decode the readings (according to Controller type)
- ecDecode(pec);
+int ecRead(wiiEC_t* pec) {
+ ENTER;
+ int rv = 0; // assume success
+
+ if(!pec->init) {
+ WARN("%s : device not initialised", __func__);
+ rv = 1;
+ goto bail;
+ }
+
+ if(!furi_hal_i2c_is_device_ready(i2cBus, i2cAddr, i2cTimeout)) {
+ INFO("%s : device disconnected", __func__);
+ pec->init = false;
+ rv = 2;
+ goto bail;
+ }
+
+ if(!furi_hal_i2c_trxd(
+ i2cBus, i2cAddr, ®Joy, 1, pec->joy, JOY_LEN, i2cTimeout, i2cReadWait)) {
+ ERROR("%s : trxd fail", __func__);
+ rv = 3;
+ goto bail;
+ }
+
+ if(pec->encrypt) decrypt(pec->joy, pec->encKey, regJoy, JOY_LEN);
+
+ // Decode the readings (according to Controller type)
+ ecDecode(pec);
bail:
- LEAVE;
- return rv;
+ LEAVE;
+ return rv;
}
//+============================================================================ ========================================
@@ -162,148 +157,145 @@ int ecRead (wiiEC_t* pec)
//
//! To disable encryption, pass a NULL encryption key <-- this is currently ALWAYS the case
//
-bool ecInit (wiiEC_t* pec, const uint8_t* encKey)
-{
- ENTER;
+bool ecInit(wiiEC_t* pec, const uint8_t* encKey) {
+ ENTER;
- bool rv = false; // assume failure
+ bool rv = false; // assume failure
-#if 0 //! i2c workaround
+#if 0 //! i2c workaround
//! I think this is done during OS startup - long before the plugin starts
furi_hal_i2c_init();
#endif
-#if 0 //! i2c workaround
+#if 0 //! i2c workaround
// May become relevant when the i2c issues are resolved
// Take control of the i2c bus [which returns void !?]
// --> firmware/targets/f7/furi_hal/furi_hal_i2c.c
furi_hal_i2c_acquire(i2cBus);
#endif
- pec->init = false; // assume failure
-
- // === See if the device is alive ===
- if (!furi_hal_i2c_is_device_ready(i2cBus,i2cAddr, i2cTimeout)) {
- TRACE("%s : waiting for device", __func__);
- goto bail;
- }
- INFO("%s : device connected", __func__);
-
- // === Initialise the device ===
- pec->init = false; // This goes true AFTER the (optional) controller-specific init code
-
- // === Start the Extension Controller ===
- if (encKey) { //! start in encrypted mode
-
- //! todo - should this happen here, or AFTER we've got the ID ?
-
- } else {
-
- if ( !furi_hal_i2c_tx(i2cBus,i2cAddr, cmdInit1,sizeof(cmdInit1), i2cTimeout) ) {
- ERROR("%s : init fail (dec1)", __func__);
- goto bail;
- }
- TRACE("%s : init OK1", __func__);
-
- if ( !furi_hal_i2c_tx(i2cBus,i2cAddr, cmdInit2,sizeof(cmdInit2), i2cTimeout) ) {
- ERROR("%s : init fail (dec2)", __func__);
- goto bail;
- }
- TRACE("%s : init OK2", __func__);
- }
-
- // === Retrieve the Extension Controller ID ===
- if (!furi_hal_i2c_trx(i2cBus,i2cAddr, ®Pid,1, pec->pid,PID_LEN, i2cTimeout)) {
- ERROR("%s : T(R)x fail (pid)", __func__);
- goto bail;
- }
- if (pec->encrypt) decrypt(pec->joy, pec->encKey, regJoy, JOY_LEN);
- dump(pec->pid, PID_LEN, "pid"); // debug INFO
-
- // Find the StringID in the lookup table
- for (pec->pidx = PID_FIRST; pec->pidx < PID_ERROR; pec->pidx++)
- if (memcmp(pec->pid, ecId[pec->pidx].id, PID_LEN) == 0) break ;
- if (pec->pidx == PID_ERROR) pec->pidx = PID_UNKNOWN ;
- pec->sid = ecId[pec->pidx].name;
- INFO("sid: %s", pec->sid);
-
- // === (optionally) Enable encryption ===
- if (!encKey) {
- pec->encrypt = false;
-
- } else { // Controller WILL encrypt ALL tranmissions
-//! this encryption code fails - should it be done earlier?
-//! as it is probably never of any use, I'm kinda loathed to spend time on it
-//! https://github.com/madhephaestus/WiiChuck/blob/master/src/Accessory.cpp#L138
- uint8_t encTx[1+ENC_LEN] = {0};
- uint8_t* ep = encTx;
-
- pec->encrypt = true;
-
- // ** Start the Controller in ENcrytped mode
- if ( !furi_hal_i2c_tx(i2cBus,i2cAddr, cmdInitEnc,sizeof(cmdInitEnc), i2cTimeout) ) {
- ERROR("%s : init fail (enc)", __func__);
- goto bail;
- }
-
- // Copy the (symmetric) encryption key to the controller state table
- if (pec->encKey != encKey)
- memcpy(pec->encKey, encKey, ENC_LEN);
-
- // Build the encryption key packet
- *ep++ = regEnc;
- memcpy(ep, pec->encKey, ENC_LEN);
-
- // ** Send encryption key (PSK)
- if ( !furi_hal_i2c_tx(i2cBus,i2cAddr, encTx,(1+ENC_LEN), i2cTimeout) ) {
- ERROR("%s : key fail", __func__);
- goto bail;
- }
-
- TRACE("%s : init OK (enc)", __func__);
- }
-
- // === Some devices [eg. Drawsome/uDraw] require additional init code ===
- if ( ecId[pec->init].init && (ecId[pec->init].init(pec) == false) ) goto bail ;
- pec->init = true;
-
- // === Read calibration data ===
- if (!furi_hal_i2c_trx(i2cBus,i2cAddr, ®Cal,1, pec->calF,CAL_LEN, i2cTimeout)) {
- ERROR("%s : trx fail (cal)", __func__);
- goto bail;
- }
- if (pec->encrypt) decrypt(pec->joy, pec->encKey, regJoy, JOY_LEN);
- dump(pec->calF, CAL_LEN, "cal");
-
- ecCalibrate(pec, CAL_RESET | CAL_FACTORY); // Load factory default calibration
-
- // === Initialise decode buffers ===
- pec->decN = 0; // read in to decode[1] (yes, N=0 -> read in to dec[1])
- switch (ecRead(pec)) {
- case 0: // read OK
- memcpy(&pec->dec[0], &pec->dec[1], sizeof(pec->dec[0]));
- dump(pec->joy, JOY_LEN, "joy");
- break;
-
- default: // bug: unknown
- case 1: // bug: not initialised - should never happen
- ERROR("%s : read bug", __func__);
- break;
-
- case 2: // device gone
- case 3: // read fail
- // Logging done by ecRead()
- pec->init = false;
- goto bail;
- }
-
- rv = true; // yay :)
+ pec->init = false; // assume failure
+
+ // === See if the device is alive ===
+ if(!furi_hal_i2c_is_device_ready(i2cBus, i2cAddr, i2cTimeout)) {
+ TRACE("%s : waiting for device", __func__);
+ goto bail;
+ }
+ INFO("%s : device connected", __func__);
+
+ // === Initialise the device ===
+ pec->init = false; // This goes true AFTER the (optional) controller-specific init code
+
+ // === Start the Extension Controller ===
+ if(encKey) { //! start in encrypted mode
+
+ //! todo - should this happen here, or AFTER we've got the ID ?
+
+ } else {
+ if(!furi_hal_i2c_tx(i2cBus, i2cAddr, cmdInit1, sizeof(cmdInit1), i2cTimeout)) {
+ ERROR("%s : init fail (dec1)", __func__);
+ goto bail;
+ }
+ TRACE("%s : init OK1", __func__);
+
+ if(!furi_hal_i2c_tx(i2cBus, i2cAddr, cmdInit2, sizeof(cmdInit2), i2cTimeout)) {
+ ERROR("%s : init fail (dec2)", __func__);
+ goto bail;
+ }
+ TRACE("%s : init OK2", __func__);
+ }
+
+ // === Retrieve the Extension Controller ID ===
+ if(!furi_hal_i2c_trx(i2cBus, i2cAddr, ®Pid, 1, pec->pid, PID_LEN, i2cTimeout)) {
+ ERROR("%s : T(R)x fail (pid)", __func__);
+ goto bail;
+ }
+ if(pec->encrypt) decrypt(pec->joy, pec->encKey, regJoy, JOY_LEN);
+ dump(pec->pid, PID_LEN, "pid"); // debug INFO
+
+ // Find the StringID in the lookup table
+ for(pec->pidx = PID_FIRST; pec->pidx < PID_ERROR; pec->pidx++)
+ if(memcmp(pec->pid, ecId[pec->pidx].id, PID_LEN) == 0) break;
+ if(pec->pidx == PID_ERROR) pec->pidx = PID_UNKNOWN;
+ pec->sid = ecId[pec->pidx].name;
+ INFO("sid: %s", pec->sid);
+
+ // === (optionally) Enable encryption ===
+ if(!encKey) {
+ pec->encrypt = false;
+
+ } else { // Controller WILL encrypt ALL tranmissions
+ //! this encryption code fails - should it be done earlier?
+ //! as it is probably never of any use, I'm kinda loathed to spend time on it
+ //! https://github.com/madhephaestus/WiiChuck/blob/master/src/Accessory.cpp#L138
+ uint8_t encTx[1 + ENC_LEN] = {0};
+ uint8_t* ep = encTx;
+
+ pec->encrypt = true;
+
+ // ** Start the Controller in ENcrytped mode
+ if(!furi_hal_i2c_tx(i2cBus, i2cAddr, cmdInitEnc, sizeof(cmdInitEnc), i2cTimeout)) {
+ ERROR("%s : init fail (enc)", __func__);
+ goto bail;
+ }
+
+ // Copy the (symmetric) encryption key to the controller state table
+ if(pec->encKey != encKey) memcpy(pec->encKey, encKey, ENC_LEN);
+
+ // Build the encryption key packet
+ *ep++ = regEnc;
+ memcpy(ep, pec->encKey, ENC_LEN);
+
+ // ** Send encryption key (PSK)
+ if(!furi_hal_i2c_tx(i2cBus, i2cAddr, encTx, (1 + ENC_LEN), i2cTimeout)) {
+ ERROR("%s : key fail", __func__);
+ goto bail;
+ }
+
+ TRACE("%s : init OK (enc)", __func__);
+ }
+
+ // === Some devices [eg. Drawsome/uDraw] require additional init code ===
+ if(ecId[pec->init].init && (ecId[pec->init].init(pec) == false)) goto bail;
+ pec->init = true;
+
+ // === Read calibration data ===
+ if(!furi_hal_i2c_trx(i2cBus, i2cAddr, ®Cal, 1, pec->calF, CAL_LEN, i2cTimeout)) {
+ ERROR("%s : trx fail (cal)", __func__);
+ goto bail;
+ }
+ if(pec->encrypt) decrypt(pec->joy, pec->encKey, regJoy, JOY_LEN);
+ dump(pec->calF, CAL_LEN, "cal");
+
+ ecCalibrate(pec, CAL_RESET | CAL_FACTORY); // Load factory default calibration
+
+ // === Initialise decode buffers ===
+ pec->decN = 0; // read in to decode[1] (yes, N=0 -> read in to dec[1])
+ switch(ecRead(pec)) {
+ case 0: // read OK
+ memcpy(&pec->dec[0], &pec->dec[1], sizeof(pec->dec[0]));
+ dump(pec->joy, JOY_LEN, "joy");
+ break;
+
+ default: // bug: unknown
+ case 1: // bug: not initialised - should never happen
+ ERROR("%s : read bug", __func__);
+ break;
+
+ case 2: // device gone
+ case 3: // read fail
+ // Logging done by ecRead()
+ pec->init = false;
+ goto bail;
+ }
+
+ rv = true; // yay :)
bail:
#if 0 //! i2c workaround
furi_hal_i2c_release(i2cBus);
#endif
- LEAVE;
- return rv;
+ LEAVE;
+ return rv;
}
diff --git a/applications/plugins/wii_ec_anal/wii_i2c.h b/applications/plugins/wii_ec_anal/wii_i2c.h
index 18cb5ee9b4..efebefcf9f 100644
--- a/applications/plugins/wii_ec_anal/wii_i2c.h
+++ b/applications/plugins/wii_ec_anal/wii_i2c.h
@@ -1,7 +1,7 @@
-#ifndef WII_I2C_H_
-#define WII_I2C_H_
+#ifndef WII_I2C_H_
+#define WII_I2C_H_
-#include
+#include
//#include "wii_ec.h"
@@ -14,11 +14,11 @@
//
// After the (special) START "bit"...
// the first 8bits (byte) of i2c data are the 7bit i2c Address,
-// FOLLOWED by 1bit to signify a READ or WRITE {0=write, 1=read}
+// FOLLOWED by 1bit to signify a READ or WRITE {0=write, 1=read}
// The data is transmitted BIG-Endian, IE. MSb first [human readable]
// So the address actually lives in the TOP (MSb's) of the first "byte", (with bit0 being used as the read/write flag)
//
-// The read() and write() functions on the FZ will set the LSb appropriately,
+// The read() and write() functions on the FZ will set the LSb appropriately,
// BUT they do NOT shift the address left to make room for it!
// So the address you give to read/write() MUST be given as (7bitAddress << 1)
//
@@ -26,17 +26,17 @@
//
// firmware/targets/f7/furi_hal/furi_hal_i2c_types.h
-#define i2cBus (&furi_hal_i2c_handle_external) // FZ external i2c bus
-#define i2cAddr (ec_i2cAddr << 1)
-#define i2cTimeout (3) // in mS
-#define i2cReadWait (300) //! 300uS: how low can we take this?
+#define i2cBus (&furi_hal_i2c_handle_external) // FZ external i2c bus
+#define i2cAddr (ec_i2cAddr << 1)
+#define i2cTimeout (3) // in mS
+#define i2cReadWait (300) //! 300uS: how low can we take this?
//----------------------------------------------------------------------------- ----------------------------------------
// public functions
//
-typedef struct wiiEC wiiEC_t ;
+typedef struct wiiEC wiiEC_t;
-bool ecInit (wiiEC_t* const pec, const uint8_t* encKey) ;
-int ecRead (wiiEC_t* const pec) ;
+bool ecInit(wiiEC_t* const pec, const uint8_t* encKey);
+int ecRead(wiiEC_t* const pec);
#endif //WII_I2C_H_
diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c
index b1be442143..e341544b32 100644
--- a/applications/services/bt/bt_service/bt.c
+++ b/applications/services/bt/bt_service/bt.c
@@ -38,10 +38,9 @@ static void bt_pin_code_view_port_draw_callback(Canvas* canvas, void* context) {
char pin_code_info[24];
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 0, 0, &I_BLE_Pairing_128x64_sfw);
- }
- else {
+ } else {
canvas_draw_icon(canvas, 0, 0, &I_BLE_Pairing_128x64);
}
snprintf(pin_code_info, sizeof(pin_code_info), "Pairing code\n%06lu", bt->pin_code);
@@ -89,10 +88,9 @@ static bool bt_pin_code_verify_event_handler(Bt* bt, uint32_t pin) {
notification_message(bt->notification, &sequence_display_backlight_on);
FuriString* pin_str;
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
dialog_message_set_icon(bt->dialog_message, &I_BLE_Pairing_128x64_sfw, 0, 0);
- }
- else {
+ } else {
dialog_message_set_icon(bt->dialog_message, &I_BLE_Pairing_128x64, 0, 0);
}
pin_str = furi_string_alloc_printf("Verify code\n%06lu", pin);
diff --git a/applications/services/desktop/animations/animation_manager.c b/applications/services/desktop/animations/animation_manager.c
index 041ef2d115..d3d85be43d 100644
--- a/applications/services/desktop/animations/animation_manager.c
+++ b/applications/services/desktop/animations/animation_manager.c
@@ -200,7 +200,11 @@ static void animation_manager_start_new_idle(AnimationManager* animation_manager
const BubbleAnimation* bubble_animation =
animation_storage_get_bubble_animation(animation_manager->current_animation);
animation_manager->state = AnimationManagerStateIdle;
- furi_timer_start(animation_manager->idle_animation_timer, bubble_animation->duration * 1000);
+ DesktopSettings* settings = malloc(sizeof(DesktopSettings));
+ DESKTOP_SETTINGS_LOAD(settings);
+ int32_t duration_s = settings->cycle_animation_s == -1 ? bubble_animation->duration : (settings->cycle_animation_s - 1);
+ furi_timer_start(animation_manager->idle_animation_timer, duration_s * 1000);
+ free(settings);
}
static bool animation_manager_check_blocking(AnimationManager* animation_manager) {
@@ -365,7 +369,7 @@ static bool animation_manager_is_valid_idle_animation(
static StorageAnimation*
animation_manager_select_idle_animation(AnimationManager* animation_manager) {
UNUSED(animation_manager);
-
+
StorageAnimationList_t animation_list;
StorageAnimationList_init(animation_list);
animation_storage_fill_animation_list(&animation_list);
@@ -510,8 +514,12 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m
} else {
const BubbleAnimation* animation = animation_storage_get_bubble_animation(
animation_manager->current_animation);
+ DesktopSettings* settings = malloc(sizeof(DesktopSettings));
+ DESKTOP_SETTINGS_LOAD(settings);
+ int32_t duration_s = settings->cycle_animation_s == -1 ? animation->duration : (settings->cycle_animation_s - 1);
furi_timer_start(
- animation_manager->idle_animation_timer, animation->duration * 1000);
+ animation_manager->idle_animation_timer, duration_s * 1000);
+ free(settings);
}
}
} else {
@@ -556,18 +564,18 @@ static void animation_manager_switch_to_one_shot_view(AnimationManager* animatio
View* next_view = one_shot_view_get_view(animation_manager->one_shot_view);
view_stack_remove_view(animation_manager->view_stack, prev_view);
view_stack_add_view(animation_manager->view_stack, next_view);
- if (settings->sfw_mode) {
- one_shot_view_start_animation(animation_manager->one_shot_view, &A_Levelup1_128x64);
- }else {
- if (stats.level <= 20) {
- one_shot_view_start_animation(animation_manager->one_shot_view, &A_Levelup1_128x64_sfw);
- }
- else if (stats.level >= 21) {
- one_shot_view_start_animation(animation_manager->one_shot_view, &A_Levelup2_128x64_sfw);
- }
- else {
+ if(settings->sfw_mode) {
+ if(stats.level <= 20) {
+ one_shot_view_start_animation(
+ animation_manager->one_shot_view, &A_Levelup1_128x64_sfw);
+ } else if(stats.level >= 21) {
+ one_shot_view_start_animation(
+ animation_manager->one_shot_view, &A_Levelup2_128x64_sfw);
+ } else {
furi_assert(0);
}
+ } else {
+ one_shot_view_start_animation(animation_manager->one_shot_view, &A_Levelup1_128x64);
}
free(settings);
}
diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c
index 410da12903..c1dcdffc34 100644
--- a/applications/services/desktop/animations/animation_storage.c
+++ b/applications/services/desktop/animations/animation_storage.c
@@ -27,20 +27,18 @@ static void animation_storage_free_frames(BubbleAnimation* animation);
static void animation_storage_free_animation(BubbleAnimation** storage_animation);
static BubbleAnimation* animation_storage_load_animation(const char* name);
-void animation_handler_beta()
-{
+void animation_handler_beta() {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
- snprintf(ANIMATION_MANIFEST_FILE, sizeof(ANIMATION_DIR), "%s", ANIMATION_DIR);
+ if(settings->sfw_mode) {
+ snprintf(ANIMATION_MANIFEST_FILE, sizeof(ANIMATION_DIR), "%s", ANIMATION_DIR);
FURI_LOG_I(TAG, "SFW Manifest selected");
- strcat(ANIMATION_MANIFEST_FILE,"/sfw/manifest.txt");
- }
- else {
- snprintf(ANIMATION_MANIFEST_FILE, sizeof(ANIMATION_DIR), "%s", ANIMATION_DIR);
+ strcat(ANIMATION_MANIFEST_FILE, "/sfw/manifest.txt");
+ } else {
+ snprintf(ANIMATION_MANIFEST_FILE, sizeof(ANIMATION_DIR), "%s", ANIMATION_DIR);
FURI_LOG_I(TAG, "NSFW Manifest selected");
- strcat(ANIMATION_MANIFEST_FILE,"/nsfw/manifest.txt");
+ strcat(ANIMATION_MANIFEST_FILE, "/nsfw/manifest.txt");
}
free(settings);
}
diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c
index 5575537de3..78ff9bdab5 100644
--- a/applications/services/desktop/desktop.c
+++ b/applications/services/desktop/desktop.c
@@ -26,10 +26,9 @@ static void desktop_loader_callback(const void* message, void* context) {
Desktop* desktop = context;
const LoaderEvent* event = message;
- if (event->type == LoaderEventTypeApplicationStarted) {
+ if(event->type == LoaderEventTypeApplicationStarted) {
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalBeforeAppStarted);
- }
- else if (event->type == LoaderEventTypeApplicationStopped) {
+ } else if(event->type == LoaderEventTypeApplicationStopped) {
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalAfterAppFinished);
}
}
@@ -39,17 +38,11 @@ static void desktop_lock_icon_draw_callback(Canvas* canvas, void* context) {
canvas_draw_icon(canvas, 0, 0, &I_Lock_8x8);
}
-static void desktop_sfw_mode_icon_draw_callback(Canvas* canvas, void* context) {
- UNUSED(context);
- furi_assert(canvas);
- canvas_draw_icon(canvas, 0, 0, &I_GameMode_11x8);
-}
-
static bool desktop_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
Desktop* desktop = (Desktop*)context;
- switch (event) {
+ switch(event) {
case DesktopGlobalBeforeAppStarted:
animation_manager_unload_and_stall_animation(desktop->animation_manager);
desktop_auto_lock_inhibit(desktop);
@@ -62,12 +55,11 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) {
desktop_auto_lock_arm(desktop);
return true;
case DesktopGlobalAutoLock:
- if (!loader_is_locked(desktop->loader)) {
- if (desktop->settings.pin_code.length > 0) {
+ if(!loader_is_locked(desktop->loader)) {
+ if(desktop->settings.pin_code.length > 0) {
desktop_pin_lock(&desktop->settings);
desktop_lock(desktop);
- }
- else {
+ } else {
desktop_lock(desktop);
}
}
@@ -94,7 +86,7 @@ static void desktop_input_event_callback(const void* value, void* context) {
furi_assert(context);
const InputEvent* event = value;
Desktop* desktop = context;
- if (event->type == InputTypePress) {
+ if(event->type == InputTypePress) {
desktop_start_auto_lock_timer(desktop);
}
}
@@ -115,7 +107,7 @@ static void desktop_stop_auto_lock_timer(Desktop* desktop) {
}
static void desktop_auto_lock_arm(Desktop* desktop) {
- if (desktop->settings.auto_lock_delay_ms) {
+ if(desktop->settings.auto_lock_delay_ms) {
desktop->input_events_subscription = furi_pubsub_subscribe(
desktop->input_events_pubsub, desktop_input_event_callback, desktop);
desktop_start_auto_lock_timer(desktop);
@@ -124,7 +116,7 @@ static void desktop_auto_lock_arm(Desktop* desktop) {
static void desktop_auto_lock_inhibit(Desktop* desktop) {
desktop_stop_auto_lock_timer(desktop);
- if (desktop->input_events_subscription) {
+ if(desktop->input_events_subscription) {
furi_pubsub_unsubscribe(desktop->input_events_pubsub, desktop->input_events_subscription);
desktop->input_events_subscription = NULL;
}
@@ -149,7 +141,6 @@ void desktop_unlock(Desktop* desktop) {
}
void desktop_set_sfw_mode_state(Desktop* desktop, bool enabled) {
- view_port_enabled_set(desktop->sfw_mode_icon_viewport, enabled);
desktop->settings.sfw_mode = enabled;
DESKTOP_SETTINGS_SAVE(&desktop->settings);
animation_manager_new_idle_process(desktop->animation_manager);
@@ -238,18 +229,10 @@ Desktop* desktop_alloc() {
view_port_enabled_set(desktop->lock_icon_viewport, false);
gui_add_view_port(desktop->gui, desktop->lock_icon_viewport, GuiLayerStatusBarLeft);
- // Dummy mode icon
- desktop->sfw_mode_icon_viewport = view_port_alloc();
- view_port_set_width(desktop->sfw_mode_icon_viewport, icon_get_width(&I_GameMode_11x8));
- view_port_draw_callback_set(
- desktop->sfw_mode_icon_viewport, desktop_sfw_mode_icon_draw_callback, desktop);
- view_port_enabled_set(desktop->sfw_mode_icon_viewport, false);
- gui_add_view_port(desktop->gui, desktop->sfw_mode_icon_viewport, GuiLayerStatusBarLeft);
-
// Special case: autostart application is already running
desktop->loader = furi_record_open(RECORD_LOADER);
- if (loader_is_locked(desktop->loader) &&
- animation_manager_is_animation_loaded(desktop->animation_manager)) {
+ if(loader_is_locked(desktop->loader) &&
+ animation_manager_is_animation_loaded(desktop->animation_manager)) {
animation_manager_unload_and_stall_animation(desktop->animation_manager);
}
@@ -272,7 +255,7 @@ void desktop_free(Desktop* desktop) {
furi_pubsub_unsubscribe(
loader_get_pubsub(desktop->loader), desktop->app_start_stop_subscription);
- if (desktop->input_events_subscription) {
+ if(desktop->input_events_subscription) {
furi_pubsub_unsubscribe(desktop->input_events_pubsub, desktop->input_events_subscription);
desktop->input_events_subscription = NULL;
}
@@ -328,45 +311,45 @@ static bool desktop_check_file_flag(const char* flag_path) {
int32_t desktop_srv(void* p) {
UNUSED(p);
- if (furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal)
- {
+ if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
FURI_LOG_W("Desktop", "Desktop load skipped. Device is in special startup mode.");
- }
- else
- {
+ } else {
Desktop* desktop = desktop_alloc();
bool loaded = DESKTOP_SETTINGS_LOAD(&desktop->settings);
- if (!loaded) {
+ if(!loaded) {
memset(&desktop->settings, 0, sizeof(desktop->settings));
DESKTOP_SETTINGS_SAVE(&desktop->settings);
}
- view_port_enabled_set(desktop->sfw_mode_icon_viewport, desktop->settings.sfw_mode);
+ if(!desktop->settings.cycle_animation_s) {
+ desktop->settings.cycle_animation_s = -1;
+ DESKTOP_SETTINGS_SAVE(&desktop->settings);
+ }
+
desktop_main_set_sfw_mode_state(desktop->main_view, desktop->settings.sfw_mode);
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)) {
+ if(!desktop_pin_lock_is_locked()) {
+ if(!loader_is_locked(desktop->loader)) {
desktop_auto_lock_arm(desktop);
}
- }
- else {
+ } else {
desktop_lock(desktop);
}
- if (desktop_check_file_flag(SLIDESHOW_FS_PATH)) {
+ if(desktop_check_file_flag(SLIDESHOW_FS_PATH)) {
scene_manager_next_scene(desktop->scene_manager, DesktopSceneSlideshow);
}
- if (!furi_hal_version_do_i_belong_here()) {
+ if(!furi_hal_version_do_i_belong_here()) {
scene_manager_next_scene(desktop->scene_manager, DesktopSceneHwMismatch);
}
- if (furi_hal_rtc_get_fault_data()) {
+ if(furi_hal_rtc_get_fault_data()) {
scene_manager_next_scene(desktop->scene_manager, DesktopSceneFault);
}
diff --git a/applications/services/desktop/desktop_i.h b/applications/services/desktop/desktop_i.h
index b6de6bfd57..007c50f364 100644
--- a/applications/services/desktop/desktop_i.h
+++ b/applications/services/desktop/desktop_i.h
@@ -58,7 +58,6 @@ struct Desktop {
DesktopViewPinInput* pin_input_view;
ViewPort* lock_icon_viewport;
- ViewPort* sfw_mode_icon_viewport;
AnimationManager* animation_manager;
diff --git a/applications/services/desktop/desktop_settings.h b/applications/services/desktop/desktop_settings.h
index 55d8640f54..5e97f76476 100644
--- a/applications/services/desktop/desktop_settings.h
+++ b/applications/services/desktop/desktop_settings.h
@@ -64,4 +64,5 @@ typedef struct {
uint8_t displayBatteryPercentage;
bool is_sfwmode;
uint8_t sfw_mode;
+ int32_t cycle_animation_s;
} DesktopSettings;
diff --git a/applications/services/desktop/scenes/desktop_scene_fault.c b/applications/services/desktop/scenes/desktop_scene_fault.c
index 38151e6b9d..79dedbe59f 100644
--- a/applications/services/desktop/scenes/desktop_scene_fault.c
+++ b/applications/services/desktop/scenes/desktop_scene_fault.c
@@ -18,7 +18,7 @@ void desktop_scene_fault_on_enter(void* context) {
Popup* popup = desktop->hw_mismatch_popup;
popup_set_context(popup, desktop);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_header(
popup,
"Flipper crashed\n but has been rebooted",
@@ -26,8 +26,7 @@ void desktop_scene_fault_on_enter(void* context) {
14 + STATUS_BAR_Y_SHIFT,
AlignCenter,
AlignCenter);
- }
- else {
+ } else {
popup_set_header(
popup,
"Slut passed out\n but is now back",
@@ -37,7 +36,6 @@ void desktop_scene_fault_on_enter(void* context) {
AlignCenter);
}
-
char* message = (char*)furi_hal_rtc_get_fault_data();
popup_set_text(popup, message, 60, 37 + STATUS_BAR_Y_SHIFT, AlignCenter, AlignCenter);
popup_set_callback(popup, desktop_scene_fault_callback);
diff --git a/applications/services/desktop/views/desktop_view_lock_menu.c b/applications/services/desktop/views/desktop_view_lock_menu.c
index 77eedcb8c5..698c265057 100644
--- a/applications/services/desktop/views/desktop_view_lock_menu.c
+++ b/applications/services/desktop/views/desktop_view_lock_menu.c
@@ -38,10 +38,7 @@ void desktop_lock_menu_set_pin_state(DesktopLockMenuView* lock_menu, bool pin_is
void desktop_lock_menu_set_sfw_mode_state(DesktopLockMenuView* lock_menu, bool sfw_mode) {
with_view_model(
- lock_menu->view,
- DesktopLockMenuViewModel * model,
- { model->sfw_mode = sfw_mode; },
- true);
+ lock_menu->view, DesktopLockMenuViewModel * model, { model->sfw_mode = sfw_mode; }, true);
}
void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx) {
diff --git a/applications/services/dolphin/helpers/dolphin_state.c b/applications/services/dolphin/helpers/dolphin_state.c
index eb34e87ea4..e0e5dbe60f 100644
--- a/applications/services/dolphin/helpers/dolphin_state.c
+++ b/applications/services/dolphin/helpers/dolphin_state.c
@@ -82,8 +82,8 @@ uint64_t dolphin_state_timestamp() {
}
bool dolphin_state_is_levelup(int icounter) {
- for (int i = 0; i<30; ++i) {
- if ((icounter == level_array[i])) {
+ for(int i = 0; i < 30; ++i) {
+ if((icounter == level_array[i])) {
return true;
}
};
@@ -91,20 +91,18 @@ bool dolphin_state_is_levelup(int icounter) {
}
uint8_t dolphin_get_level(int icounter) {
-for (int i = 0; i < 29; ++i) {
- if (icounter <= level_array[i]) {
- return i + 1;
+ for(int i = 0; i < 29; ++i) {
+ if(icounter <= level_array[i]) {
+ return i + 1;
+ }
}
-}
-return 30;
+ return 30;
}
uint32_t dolphin_state_xp_above_last_levelup(int icounter) {
- if(level_array[0] > icounter) {
- for(int i = 1; i < 29; ++i) {
- if(icounter <= level_array[i]) {
- return level_array[i] - icounter + 1;
- }
+ for(int i = 1; i < 29; ++i) {
+ if(icounter <= level_array[i]) {
+ return icounter - level_array[i - 1];
}
}
return icounter;
diff --git a/applications/services/gui/gui.c b/applications/services/gui/gui.c
index 060fa844ba..e1b5f02000 100644
--- a/applications/services/gui/gui.c
+++ b/applications/services/gui/gui.c
@@ -86,9 +86,9 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) {
GUI_STATUS_BAR_Y + 1,
width + 2,
GUI_STATUS_BAR_WORKAREA_HEIGHT + 2);
- canvas_set_color(gui->canvas, ColorWhite);
- canvas_draw_box(
- gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas));
+ // canvas_set_color(gui->canvas, ColorWhite);
+ // canvas_draw_box(
+ // gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas));
canvas_set_color(gui->canvas, ColorBlack);
// ViewPort draw
canvas_frame_set(
@@ -105,52 +105,17 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) {
GUI_STATUS_BAR_Y,
right_used + 2,
GUI_STATUS_BAR_HEIGHT);
- canvas_set_color(gui->canvas, ColorBlack);
- canvas_draw_rframe(
- gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas) - 1, 1);
- canvas_draw_line(
- gui->canvas,
- canvas_width(gui->canvas) - 1,
- 2,
- canvas_width(gui->canvas) - 1,
- canvas_height(gui->canvas) - 4);
+ // canvas_set_color(gui->canvas, ColorBlack);
+ // canvas_draw_rframe(
+ // gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas) - 1, 1);
+ // canvas_draw_line(
+ // gui->canvas,
+ // canvas_width(gui->canvas) - 1,
+ // 2,
+ // canvas_width(gui->canvas) - 1,
+ // canvas_height(gui->canvas) - 4);
}
- // Left side
- x = 2;
- ViewPortArray_it(it, gui->layers[GuiLayerStatusBarLeft]);
- while(!ViewPortArray_end_p(it) && (right_used + left_used) < GUI_STATUS_BAR_WIDTH) {
- ViewPort* view_port = *ViewPortArray_ref(it);
- if(view_port_is_enabled(view_port)) {
- width = view_port_get_width(view_port);
- if(!width) width = 8;
- // Prepare work area background
- canvas_frame_set(
- gui->canvas,
- x - 1,
- // SASQUACH SAYS : This is the white box behind the left bar, move it 64 to hide it
- GUI_STATUS_BAR_Y + 64,
- width + 2,
- GUI_STATUS_BAR_WORKAREA_HEIGHT + 2);
- canvas_set_color(gui->canvas, ColorWhite);
- canvas_draw_box(
- gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas));
- canvas_set_color(gui->canvas, ColorBlack);
- // ViewPort draw
- canvas_frame_set(
- // SASQUACH SAYS : This is where you move the Icons for the left bar, 64 to hide it
- gui->canvas,
- x,
- GUI_STATUS_BAR_Y + 64,
- width,
- GUI_STATUS_BAR_WORKAREA_HEIGHT);
- view_port_draw(view_port, gui->canvas);
- // Recalculate next position
- left_used += (width + 2);
- x += (width + 2);
- }
- ViewPortArray_next(it);
- }
// Extra notification
if(need_attention) {
width = icon_get_width(&I_Hidden_window_9x8);
@@ -172,7 +137,6 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) {
left_used += (width + 2);
x += (width + 2);
}
- // Draw frame around icons on the left
}
static bool gui_redraw_window(Gui* gui) {
diff --git a/applications/services/gui/modules/button_menu.c b/applications/services/gui/modules/button_menu.c
index 60bd160c5b..427a3e1aea 100644
--- a/applications/services/gui/modules/button_menu.c
+++ b/applications/services/gui/modules/button_menu.c
@@ -178,6 +178,47 @@ static void button_menu_process_down(ButtonMenu* button_menu) {
true);
}
+static void button_menu_process_right(ButtonMenu* button_menu) {
+ furi_assert(button_menu);
+
+ with_view_model(
+ button_menu->view,
+ ButtonMenuModel * model,
+ {
+ if(ButtonMenuItemArray_size(model->items) > BUTTONS_PER_SCREEN) {
+ size_t position_candidate = model->position + BUTTONS_PER_SCREEN;
+ position_candidate -= position_candidate % BUTTONS_PER_SCREEN;
+ if(position_candidate < (ButtonMenuItemArray_size(model->items))) {
+ model->position = position_candidate;
+ } else {
+ model->position = 0;
+ }
+ }
+ },
+ true);
+}
+
+static void button_menu_process_left(ButtonMenu* button_menu) {
+ furi_assert(button_menu);
+
+ with_view_model(
+ button_menu->view,
+ ButtonMenuModel * model,
+ {
+ if(ButtonMenuItemArray_size(model->items) > BUTTONS_PER_SCREEN) {
+ size_t position_candidate;
+ if(model->position < BUTTONS_PER_SCREEN) {
+ position_candidate = (ButtonMenuItemArray_size(model->items) - 1);
+ } else {
+ position_candidate = model->position - BUTTONS_PER_SCREEN;
+ };
+ position_candidate -= position_candidate % BUTTONS_PER_SCREEN;
+ model->position = position_candidate;
+ }
+ },
+ true);
+}
+
static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) {
furi_assert(button_menu);
@@ -239,6 +280,14 @@ static bool button_menu_view_input_callback(InputEvent* event, void* context) {
consumed = true;
button_menu_process_down(button_menu);
break;
+ case InputKeyRight:
+ consumed = true;
+ button_menu_process_right(button_menu);
+ break;
+ case InputKeyLeft:
+ consumed = true;
+ button_menu_process_left(button_menu);
+ break;
default:
break;
}
diff --git a/applications/services/gui/modules/submenu.c b/applications/services/gui/modules/submenu.c
index 72626c587d..88c1c55d43 100644
--- a/applications/services/gui/modules/submenu.c
+++ b/applications/services/gui/modules/submenu.c
@@ -1,4 +1,5 @@
#include "submenu.h"
+#include
#include
#include
@@ -63,7 +64,12 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
SubmenuModel* model = _model;
const uint8_t item_height = 16;
- const uint8_t item_width = 123;
+ uint8_t item_width = 123;
+
+ if(canvas->orientation == CanvasOrientationVertical ||
+ canvas->orientation == CanvasOrientationVerticalFlip) {
+ item_width = 60;
+ }
canvas_clear(canvas);
diff --git a/applications/services/gui/modules/text_input.c b/applications/services/gui/modules/text_input.c
index 32607e8842..9004304cb2 100644
--- a/applications/services/gui/modules/text_input.c
+++ b/applications/services/gui/modules/text_input.c
@@ -138,7 +138,7 @@ static bool char_is_lowercase(char letter) {
static char char_to_uppercase(const char letter) {
if(letter == '_') {
return 0x20;
- } else if(islower(letter)) {
+ } else if(isalpha(letter)) {
return (letter - 0x20);
} else {
return letter;
@@ -309,9 +309,7 @@ static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, b
char selected = get_selected_char(model);
size_t text_length = strlen(model->text_buffer);
- bool toogle_case = text_length == 0;
- if(shift) toogle_case = !toogle_case;
- if(toogle_case) {
+ if(shift) {
selected = char_to_uppercase(selected);
}
@@ -331,6 +329,9 @@ static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, b
text_length = 0;
}
if(text_length < (model->text_buffer_size - 1)) {
+ if(text_length == 0 && char_is_lowercase(selected)) {
+ selected = char_to_uppercase(selected);
+ }
model->text_buffer[text_length] = selected;
model->text_buffer[text_length + 1] = 0;
}
@@ -567,4 +568,4 @@ void* text_input_get_validator_callback_context(TextInput* text_input) {
void text_input_set_header_text(TextInput* text_input, const char* text) {
with_view_model(
text_input->view, TextInputModel * model, { model->header = text; }, true);
-}
+}
\ No newline at end of file
diff --git a/applications/services/namechangersrv/namechangersrv.c b/applications/services/namechangersrv/namechangersrv.c
index 3e63c91209..e62b39c013 100644
--- a/applications/services/namechangersrv/namechangersrv.c
+++ b/applications/services/namechangersrv/namechangersrv.c
@@ -4,12 +4,9 @@
#include
void namechanger_on_system_start() {
- if (furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal)
- {
+ if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
FURI_LOG_W(TAG, "NameChangerSRV load skipped. Device is in special startup mode.");
- }
- else
- {
+ } else {
Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* file = flipper_format_file_alloc(storage);
@@ -25,36 +22,36 @@ void namechanger_on_system_start() {
data = furi_string_alloc();
do {
- if (!flipper_format_file_open_existing(file, furi_string_get_cstr(filepath))) {
+ if(!flipper_format_file_open_existing(file, furi_string_get_cstr(filepath))) {
break;
}
// header
uint32_t version;
- if (!flipper_format_read_header(file, data, &version)) {
+ if(!flipper_format_read_header(file, data, &version)) {
break;
}
- if (furi_string_cmp_str(data, furi_string_get_cstr(NAMEHEADER)) != 0) {
+ if(furi_string_cmp_str(data, furi_string_get_cstr(NAMEHEADER)) != 0) {
break;
}
- if (version != 1) {
+ if(version != 1) {
break;
}
// get Name
- if (!flipper_format_read_string(file, "Name", data)) {
+ if(!flipper_format_read_string(file, "Name", data)) {
break;
}
result = true;
- } while (false);
+ } while(false);
flipper_format_free(file);
- if (!result) {
+ if(!result) {
//file not good - write new one
FlipperFormat* file = flipper_format_file_alloc(storage);
@@ -62,49 +59,49 @@ void namechanger_on_system_start() {
do {
// Open file for write
- if (!flipper_format_file_open_always(file, furi_string_get_cstr(filepath))) {
+ if(!flipper_format_file_open_always(file, furi_string_get_cstr(filepath))) {
break;
}
// Write header
- if (!flipper_format_write_header_cstr(file, furi_string_get_cstr(NAMEHEADER), 1)) {
+ if(!flipper_format_write_header_cstr(file, furi_string_get_cstr(NAMEHEADER), 1)) {
break;
}
// Write comments
- if (!flipper_format_write_comment_cstr(
- file,
- "Changing the value below will change your FlipperZero device name.")) {
+ if(!flipper_format_write_comment_cstr(
+ file,
+ "Changing the value below will change your FlipperZero device name.")) {
break;
}
- if (!flipper_format_write_comment_cstr(
- file,
- "Note: This is limited to 8 characters using the following: a-z, A-Z, 0-9, and _")) {
+ if(!flipper_format_write_comment_cstr(
+ file,
+ "Note: This is limited to 8 characters using the following: a-z, A-Z, 0-9, and _")) {
break;
}
- if (!flipper_format_write_comment_cstr(
- file, "It can contain other characters but use at your own risk.")) {
+ if(!flipper_format_write_comment_cstr(
+ file, "It can contain other characters but use at your own risk.")) {
break;
}
//Write name
- if (!flipper_format_write_string_cstr(file, "Name", furi_hal_version_get_name_ptr())) {
+ if(!flipper_format_write_string_cstr(
+ file, "Name", furi_hal_version_get_name_ptr())) {
break;
}
res = true;
- } while (false);
+ } while(false);
flipper_format_free(file);
- if (!res) {
+ if(!res) {
FURI_LOG_E(TAG, "Save failed.");
}
- }
- else {
- if (!furi_string_size(data)) {
+ } else {
+ if(!furi_string_size(data)) {
//Empty file - get default name and write to file.
FlipperFormat* file = flipper_format_file_alloc(storage);
@@ -112,50 +109,49 @@ void namechanger_on_system_start() {
do {
// Open file for write
- if (!flipper_format_file_open_always(file, furi_string_get_cstr(filepath))) {
+ if(!flipper_format_file_open_always(file, furi_string_get_cstr(filepath))) {
break;
}
// Write header
- if (!flipper_format_write_header_cstr(
- file, furi_string_get_cstr(NAMEHEADER), 1)) {
+ if(!flipper_format_write_header_cstr(
+ file, furi_string_get_cstr(NAMEHEADER), 1)) {
break;
}
// Write comments
- if (!flipper_format_write_comment_cstr(
- file,
- "Changing the value below will change your FlipperZero device name.")) {
+ if(!flipper_format_write_comment_cstr(
+ file,
+ "Changing the value below will change your FlipperZero device name.")) {
break;
}
- if (!flipper_format_write_comment_cstr(
- file,
- "Note: This is limited to 8 characters using the following: a-z, A-Z, 0-9, and _")) {
+ if(!flipper_format_write_comment_cstr(
+ file,
+ "Note: This is limited to 8 characters using the following: a-z, A-Z, 0-9, and _")) {
break;
}
- if (!flipper_format_write_comment_cstr(
- file, "It cannot contain any other characters.")) {
+ if(!flipper_format_write_comment_cstr(
+ file, "It cannot contain any other characters.")) {
break;
}
//Write name
- if (!flipper_format_write_string_cstr(
- file, "Name", furi_hal_version_get_name_ptr())) {
+ if(!flipper_format_write_string_cstr(
+ file, "Name", furi_hal_version_get_name_ptr())) {
break;
}
res = true;
- } while (false);
+ } while(false);
flipper_format_free(file);
- if (!res) {
+ if(!res) {
FURI_LOG_E(TAG, "Save failed.");
}
- }
- else {
+ } else {
char newdata[9];
snprintf(newdata, 9, "%s", furi_string_get_cstr(data));
//set name from file
diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c
index d891968c7f..76be018063 100644
--- a/applications/services/power/power_service/power.c
+++ b/applications/services/power/power_service/power.c
@@ -9,7 +9,14 @@
void power_draw_battery_callback(Canvas* canvas, void* context) {
furi_assert(context);
Power* power = context;
- canvas_draw_icon(canvas, 0, 0, &I_Battery_26x8);
+ canvas_draw_icon(canvas, 0, 0, &I_Battery_25x8);
+ canvas_set_color(canvas, ColorWhite);
+ canvas_draw_box(canvas, -1, 0, 1, 8);
+ canvas_draw_box(canvas, 0, -1, 24, 1);
+ canvas_draw_box(canvas, 0, 8, 24, 1);
+ canvas_draw_box(canvas, 25, 1, 2, 6);
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_box(canvas, 25, 2, 1, 4);
if(power->info.gauge_is_ok) {
char batteryPercentile[4];
@@ -62,8 +69,9 @@ void power_draw_battery_callback(Canvas* canvas, void* context) {
} else if(
(power->displayBatteryPercentage == DISPLAY_BATTERY_BAR_PERCENT) &&
(power->state != PowerStateCharging) && // Default bar display with percentage
- (power->info.voltage_battery_charging >= 4.2)) { // not looking nice with low voltage indicator
- canvas_set_font(canvas, FontBatteryPercent);
+ (power->info.voltage_battery_charging >=
+ 4.2)) { // not looking nice with low voltage indicator
+ canvas_set_font(canvas, FontBatteryPercent);
// align charge dispaly value with digits to draw
uint8_t bar_charge = power->info.charge;
@@ -167,7 +175,7 @@ void power_draw_battery_callback(Canvas* canvas, void* context) {
static ViewPort* power_battery_view_port_alloc(Power* power) {
ViewPort* battery_view_port = view_port_alloc();
- view_port_set_width(battery_view_port, icon_get_width(&I_Battery_26x8));
+ view_port_set_width(battery_view_port, icon_get_width(&I_Battery_25x8));
view_port_draw_callback_set(battery_view_port, power_draw_battery_callback, power);
gui_add_view_port(power->gui, battery_view_port, GuiLayerStatusBarRight);
return battery_view_port;
diff --git a/applications/settings/about/about.c b/applications/settings/about/about.c
index 25e8b8fdb7..17c734a208 100644
--- a/applications/settings/about/about.c
+++ b/applications/settings/about/about.c
@@ -136,7 +136,13 @@ static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage*
}
dialog_message_set_header(message, "Firmware Info:", 0, 0, AlignLeft, AlignTop);
- dialog_message_set_text(message, "XFW - Xtreme Firmware\nGithub.com/ClaraCrazy/Flipper-Xtreme", 0, 13, AlignLeft, AlignTop);
+ dialog_message_set_text(
+ message,
+ "XFW - Xtreme Firmware\nGithub.com/ClaraCrazy/Flipper-Xtreme",
+ 0,
+ 13,
+ AlignLeft,
+ AlignTop);
result = dialog_message_show(dialogs, message);
dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop);
dialog_message_set_header(message, NULL, 0, 0, AlignLeft, AlignTop);
@@ -154,7 +160,6 @@ const AboutDialogScreen about_screens[] = {
compliance_screen,
address_screen};
-
const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScreen);
int32_t about_settings_app(void* p) {
diff --git a/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_success.c b/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_success.c
index 1a3914f3c6..79651a9766 100644
--- a/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_success.c
+++ b/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_success.c
@@ -13,10 +13,9 @@ void bt_settings_scene_forget_dev_success_on_enter(void* context) {
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw);
- }
- else {
+ } else {
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
}
popup_set_header(popup, "Done", 14, 15, AlignLeft, AlignTop);
diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c
index c8a383acd5..4b183251bb 100644
--- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c
+++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c
@@ -26,10 +26,9 @@ void desktop_settings_scene_pin_disable_on_enter(void* context) {
popup_set_context(app->popup, app);
popup_set_callback(app->popup, pin_disable_back_callback);
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
popup_set_icon(app->popup, 0, 2, &I_DolphinMafia_115x62_sfw);
- }
- else {
+ } else {
popup_set_icon(app->popup, 0, 2, &I_DolphinMafia_115x62);
}
popup_set_header(app->popup, "PIN\nDeleted!", 95, 9, AlignCenter, AlignCenter);
diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c
index da4140aa1e..b97c2a4a28 100644
--- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c
+++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c
@@ -27,25 +27,38 @@ const uint32_t auto_lock_delay_value[AUTO_LOCK_DELAY_COUNT] =
{0, 10000, 15000, 30000, 60000, 90000, 120000, 300000, 600000};
#define BATTERY_VIEW_COUNT 6
-const char* const battery_view_count_text[BATTERY_VIEW_COUNT] = {
- "Bar",
- "%",
- "Inv. %",
- "Retro 3",
- "Retro 5",
- "Bar %"
-};
+const char* const battery_view_count_text[BATTERY_VIEW_COUNT] =
+ {"Bar", "%", "Inv. %", "Retro 3", "Retro 5", "Bar %"};
const uint32_t displayBatteryPercentage_value[BATTERY_VIEW_COUNT] = {
DISPLAY_BATTERY_BAR,
DISPLAY_BATTERY_PERCENT,
DISPLAY_BATTERY_INVERTED_PERCENT,
DISPLAY_BATTERY_RETRO_3,
DISPLAY_BATTERY_RETRO_5,
- DISPLAY_BATTERY_BAR_PERCENT
-};
+ DISPLAY_BATTERY_BAR_PERCENT};
uint8_t origBattDisp_value = 0;
+#define CYCLE_ANIMATION_COUNT 13
+const char* const cycle_animation_text[CYCLE_ANIMATION_COUNT] = {
+ "OFF",
+ "Manifest",
+ "30 S",
+ "1 M",
+ "5 M",
+ "10 M",
+ "15 M",
+ "30 M",
+ "1 H",
+ "2 H",
+ "6 H",
+ "12 H",
+ "24 H",
+};
+// Values are offset by 1 so that 0 is not a valid value and desktop.c can detect this to set a default value (3601 / 1 H)
+const int32_t cycle_animation_value[CYCLE_ANIMATION_COUNT] =
+ {1, -1, 31, 61, 301, 601, 901, 1801, 3601, 7201, 21601, 43201, 86401};
+
static void desktop_settings_scene_start_var_list_enter_callback(void* context, uint32_t index) {
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, index);
@@ -67,6 +80,14 @@ static void desktop_settings_scene_start_battery_view_changed(VariableItem* item
app->settings.displayBatteryPercentage = index;
}
+static void desktop_settings_scene_start_cycle_animation_changed(VariableItem* item) {
+ DesktopSettingsApp* app = variable_item_get_context(item);
+ uint8_t index = variable_item_get_current_value_index(item);
+
+ variable_item_set_current_value_text(item, cycle_animation_text[index]);
+ app->settings.cycle_animation_s = cycle_animation_value[index];
+}
+
void desktop_settings_scene_start_on_enter(void* context) {
DesktopSettingsApp* app = context;
VariableItemList* variable_item_list = app->variable_item_list;
@@ -109,6 +130,18 @@ void desktop_settings_scene_start_on_enter(void* context) {
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, battery_view_count_text[value_index]);
+ item = variable_item_list_add(
+ variable_item_list,
+ "Cycle Animation",
+ CYCLE_ANIMATION_COUNT,
+ desktop_settings_scene_start_cycle_animation_changed,
+ app);
+
+ value_index = value_index_int32(
+ app->settings.cycle_animation_s, cycle_animation_value, CYCLE_ANIMATION_COUNT);
+ variable_item_set_current_value_index(item, value_index);
+ variable_item_set_current_value_text(item, cycle_animation_text[value_index]);
+
variable_item_list_set_enter_callback(
variable_item_list, desktop_settings_scene_start_var_list_enter_callback, app);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewVarItemList);
diff --git a/applications/settings/dolphin_passport/passport.c b/applications/settings/dolphin_passport/passport.c
index f8be24397c..b6c94d2c15 100644
--- a/applications/settings/dolphin_passport/passport.c
+++ b/applications/settings/dolphin_passport/passport.c
@@ -12,28 +12,53 @@
#define MOODS_TOTAL 3
#define BUTTHURT_MAX 3
-static const Icon* const portrait_happy_sfw[BUTTHURT_MAX] = {&I_passport_happy1_46x49_sfw, &I_passport_happy2_46x49_sfw, &I_passport_happy3_46x49_sfw};
-static const Icon* const portrait_ok_sfw[BUTTHURT_MAX] = {&I_passport_okay1_46x49_sfw, &I_passport_okay2_46x49_sfw, &I_passport_okay3_46x49_sfw};
-static const Icon* const portrait_bad_sfw[BUTTHURT_MAX] = {&I_passport_bad1_46x49_sfw, &I_passport_bad2_46x49_sfw, &I_passport_bad3_46x49_sfw};
+static const Icon* const portrait_happy_sfw[BUTTHURT_MAX] = {
+ &I_passport_happy1_46x49_sfw,
+ &I_passport_happy2_46x49_sfw,
+ &I_passport_happy3_46x49_sfw};
+static const Icon* const portrait_ok_sfw[BUTTHURT_MAX] = {
+ &I_passport_okay1_46x49_sfw,
+ &I_passport_okay2_46x49_sfw,
+ &I_passport_okay3_46x49_sfw};
+static const Icon* const portrait_bad_sfw[BUTTHURT_MAX] = {
+ &I_passport_bad1_46x49_sfw,
+ &I_passport_bad2_46x49_sfw,
+ &I_passport_bad3_46x49_sfw};
static const Icon* const portrait_happy[BUTTHURT_MAX] = {&I_flipper};
static const Icon* const portrait_ok[BUTTHURT_MAX] = {&I_flipper};
static const Icon* const portrait_bad[BUTTHURT_MAX] = {&I_flipper};
-static const Icon* const* portraits_sfw[MOODS_TOTAL] = {portrait_happy_sfw, portrait_ok_sfw, portrait_bad_sfw};
+static const Icon* const* portraits_sfw[MOODS_TOTAL] = {
+ portrait_happy_sfw,
+ portrait_ok_sfw,
+ portrait_bad_sfw};
static const Icon* const* portraits[MOODS_TOTAL] = {portrait_happy, portrait_ok, portrait_bad};
// static const Icon* const* portraits[MOODS_TOTAL] = {portrait_happy};
-static void input_callback(InputEvent* input, void* ctx) {
- FuriSemaphore* semaphore = ctx;
+typedef struct {
+ FuriSemaphore* semaphore;
+ DolphinStats* stats;
+ ViewPort* view_port;
+ bool progress_total;
+} PassportContext;
+
+static void input_callback(InputEvent* input, void* _ctx) {
+ PassportContext* ctx = _ctx;
+
+ if((input->type == InputTypeShort) && (input->key == InputKeyOk)) {
+ ctx->progress_total = !ctx->progress_total;
+ view_port_update(ctx->view_port);
+ }
if((input->type == InputTypeShort) && (input->key == InputKeyBack)) {
- furi_semaphore_release(semaphore);
+ furi_semaphore_release(ctx->semaphore);
}
}
-static void render_callback(Canvas* canvas, void* ctx) {
- DolphinStats* stats = ctx;
+static void render_callback(Canvas* canvas, void* _ctx) {
+ PassportContext* ctx = _ctx;
+ DolphinStats* stats = ctx->stats;
DesktopSettings* settings = malloc(sizeof(DesktopSettings));
DESKTOP_SETTINGS_LOAD(settings);
@@ -65,40 +90,43 @@ static void render_callback(Canvas* canvas, void* ctx) {
mood = 2;
snprintf(mood_str, 20, "Status: Desperate");
}
-
}
uint32_t xp_progress = 0;
- uint32_t xp_to_levelup = dolphin_state_xp_to_levelup(stats->icounter);
+ uint32_t xp_need = dolphin_state_xp_to_levelup(stats->icounter);
uint32_t xp_above_last_levelup = dolphin_state_xp_above_last_levelup(stats->icounter);
- uint32_t xp_for_current_level = xp_to_levelup + xp_above_last_levelup;
+ uint32_t xp_levelup = 0;
+ if (ctx->progress_total) {
+ xp_levelup = xp_need + stats->icounter;
+ } else {
+ xp_levelup = xp_need + xp_above_last_levelup;
+ }
+ uint32_t xp_have = xp_levelup - xp_need;
if(stats->level == 30) {
xp_progress = 0;
} else {
- xp_progress = xp_to_levelup * 64 / xp_for_current_level;
+ xp_progress = xp_need * 64 / xp_levelup;
}
// multipass
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 0, 0, &I_passport_DB_sfw);
- }
- else {
+ } else {
canvas_draw_icon(canvas, 0, 0, &I_passport_DB);
}
// portrait
furi_assert((stats->level > 0) && (stats->level <= 30));
uint16_t tmpLvl = 0;
- if (settings->sfw_mode) {
+ if(settings->sfw_mode) {
canvas_draw_icon(canvas, 11, 2, portraits_sfw[mood][tmpLvl]);
- }
- else {
+ } else {
canvas_draw_icon(canvas, 11, 2, portraits[mood][tmpLvl]);
}
const char* my_name = furi_hal_version_get_name_ptr();
snprintf(level_str, 12, "Level: %hu", stats->level);
- snprintf(xp_str, 12, "%lu/%lu", xp_above_last_levelup, xp_for_current_level);
+ snprintf(xp_str, 12, "%lu/%lu", xp_have, xp_levelup);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str(canvas, 58, 10, my_name ? my_name : "Unknown");
canvas_draw_str(canvas, 58, 22, mood_str);
@@ -112,6 +140,11 @@ static void render_callback(Canvas* canvas, void* ctx) {
canvas_set_color(canvas, ColorWhite);
canvas_draw_box(canvas, 123 - xp_progress, 45, xp_progress + 1, 5);
canvas_set_color(canvas, ColorBlack);
+
+ canvas_draw_icon(canvas, 52, 51, &I_Ok_btn_9x9);
+ canvas_draw_str(
+ canvas, ctx->progress_total ? 37 : 36, 59, ctx->progress_total ? "Lvl" : "Tot");
+
free(settings);
}
@@ -124,9 +157,14 @@ int32_t passport_app(void* p) {
Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN);
DolphinStats stats = dolphin_stats(dolphin);
+ PassportContext* ctx = malloc(sizeof(PassportContext));
+ ctx->stats = &stats;
+ ctx->view_port = view_port;
+ ctx->semaphore = semaphore;
+ ctx->progress_total = false;
furi_record_close(RECORD_DOLPHIN);
- view_port_draw_callback_set(view_port, render_callback, &stats);
- view_port_input_callback_set(view_port, input_callback, semaphore);
+ view_port_draw_callback_set(view_port, render_callback, ctx);
+ view_port_input_callback_set(view_port, input_callback, ctx);
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
view_port_update(view_port);
@@ -137,6 +175,7 @@ int32_t passport_app(void* p) {
view_port_free(view_port);
furi_record_close(RECORD_GUI);
furi_semaphore_free(semaphore);
+ free(ctx);
return 0;
}
diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c
index f20f1a5bf8..43d429692c 100644
--- a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c
+++ b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c
@@ -15,14 +15,15 @@ void power_settings_scene_power_off_on_enter(void* context) {
DESKTOP_SETTINGS_LOAD(settings);
dialog_ex_set_header(dialog, "Turn Off Device?", 64, 2, AlignCenter, AlignTop);
- if (settings->sfw_mode) {
- dialog_ex_set_text(dialog, " I will be\nwaiting for\n you here", 78, 16, AlignLeft, AlignTop);
+ if(settings->sfw_mode) {
+ dialog_ex_set_text(
+ dialog, " I will be\nwaiting for\n you here", 78, 16, AlignLeft, AlignTop);
dialog_ex_set_icon(dialog, 21, 13, &I_Cry_dolph_55x52_sfw);
- }
- else {
- dialog_ex_set_text(dialog, " I will be\nwaiting for\n you master", 78, 16, AlignLeft, AlignTop);
+ } else {
+ dialog_ex_set_text(
+ dialog, " I will be\nwaiting for\n you master", 78, 16, AlignLeft, AlignTop);
dialog_ex_set_icon(dialog, 21, 13, &I_Cry_dolph_55x52);
- }
+ }
dialog_ex_set_left_button_text(dialog, "Back");
dialog_ex_set_right_button_text(dialog, "OFF");
dialog_ex_set_result_callback(dialog, power_settings_scene_power_off_dialog_callback);
diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c b/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c
index 486f07603a..4d8f81f9ea 100644
--- a/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c
+++ b/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c
@@ -1,4 +1,5 @@
#include "../storage_settings.h"
+#include "../../desktop_settings/desktop_settings_app.h"
static void
storage_settings_scene_unmounted_dialog_callback(DialogExResult result, void* context) {
@@ -11,9 +12,15 @@ void storage_settings_scene_unmounted_on_enter(void* context) {
StorageSettings* app = context;
FS_Error error = storage_sd_unmount(app->fs_api);
DialogEx* dialog_ex = app->dialog_ex;
+ DesktopSettings* settings = malloc(sizeof(DesktopSettings));
+ DESKTOP_SETTINGS_LOAD(settings);
dialog_ex_set_center_button_text(dialog_ex, "OK");
- dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48);
+ if(settings->sfw_mode) {
+ dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48_sfw);
+ } else {
+ dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48);
+ }
if(error == FSE_OK) {
dialog_ex_set_header(dialog_ex, "SD Card Unmounted", 64, 3, AlignCenter, AlignTop);
@@ -29,6 +36,7 @@ void storage_settings_scene_unmounted_on_enter(void* context) {
dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_unmounted_dialog_callback);
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx);
+ free(settings);
}
bool storage_settings_scene_unmounted_on_event(void* context, SceneManagerEvent event) {
diff --git a/assets/dolphin/external/sfw/L1_Boxing_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Boxing_128x64/meta.txt
index c66998e7d8..ec5127b8ae 100644
--- a/assets/dolphin/external/sfw/L1_Boxing_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Boxing_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 7
Frames order: 0 1 2 1 3 1 2 3 1 4 5 6 5 6 5 4
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 2
diff --git a/assets/dolphin/external/sfw/L1_Cry_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Cry_128x64/meta.txt
index e96c8d7c61..ea0bf89d02 100644
--- a/assets/dolphin/external/sfw/L1_Cry_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Cry_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 4
Frames order: 0 1 2 3 4 2 3 4 5 6 7 6
Active cycles: 2
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 2
diff --git a/assets/dolphin/external/sfw/L1_Furippa1_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Furippa1_128x64/meta.txt
index c21027e49c..8b01676f5a 100644
--- a/assets/dolphin/external/sfw/L1_Furippa1_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Furippa1_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 11
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
diff --git a/assets/dolphin/external/sfw/L1_Happy_holidays_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Happy_holidays_128x64/meta.txt
index a2c7333972..ad883525e1 100644
--- a/assets/dolphin/external/sfw/L1_Happy_holidays_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Happy_holidays_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 18
Frames order: 0 1 2 1 0 1 2 1 0 1 2 3 4 5 6 5 4 7 2 8 9 10 11 10 9 10 11 12
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/dolphin/external/sfw/L1_Laptop_128x51/meta.txt b/assets/dolphin/external/sfw/L1_Laptop_128x51/meta.txt
index 90cdc5ce9d..0c3edb0574 100644
--- a/assets/dolphin/external/sfw/L1_Laptop_128x51/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Laptop_128x51/meta.txt
@@ -8,7 +8,7 @@ Active frames: 2
Frames order: 0 1 2 3 4 5 6 7
Active cycles: 4
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/dolphin/external/sfw/L1_Leaving_sad_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Leaving_sad_128x64/meta.txt
index 8760030795..fbf7c67fc7 100644
--- a/assets/dolphin/external/sfw/L1_Leaving_sad_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Leaving_sad_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 42
Frames order: 0 1 2 1 3 4 5 6 7 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 11 12 4 3
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/dolphin/external/sfw/L1_Mad_fist_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Mad_fist_128x64/meta.txt
index 93e59e49b4..56f3807479 100644
--- a/assets/dolphin/external/sfw/L1_Mad_fist_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Mad_fist_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 13
Frames order: 0 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 12 13 12 13
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/dolphin/external/sfw/L1_Mods_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Mods_128x64/meta.txt
index 0225c7e559..255fda7386 100644
--- a/assets/dolphin/external/sfw/L1_Mods_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Mods_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 18
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
\ No newline at end of file
diff --git a/assets/dolphin/external/sfw/L1_Painting_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Painting_128x64/meta.txt
index 6964b479bd..3676efdfec 100644
--- a/assets/dolphin/external/sfw/L1_Painting_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Painting_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 13
Frames order: 0 1 2 3 4 5 2 3 4 10 6 7 8 7 8 7 8 7 8 9 10 11
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/dolphin/external/sfw/L1_Read_books_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Read_books_128x64/meta.txt
index 7432507ce2..750c043d03 100644
--- a/assets/dolphin/external/sfw/L1_Read_books_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Read_books_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 2
Frames order: 0 1 0 2 3 3 4 0 1 5 6 1 1 7 8
Active cycles: 2
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 5
Bubble slots: 1
diff --git a/assets/dolphin/external/sfw/L1_Recording_128x51/meta.txt b/assets/dolphin/external/sfw/L1_Recording_128x51/meta.txt
index de37d5b2e4..dc79b1645c 100644
--- a/assets/dolphin/external/sfw/L1_Recording_128x51/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Recording_128x51/meta.txt
@@ -8,7 +8,7 @@ Active frames: 6
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 5
Bubble slots: 0
diff --git a/assets/dolphin/external/sfw/L1_Sleep_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Sleep_128x64/meta.txt
index 7960b06532..eea23b69c6 100644
--- a/assets/dolphin/external/sfw/L1_Sleep_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Sleep_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 4
Frames order: 0 1 2 3 2 3
Active cycles: 2
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 5
Bubble slots: 2
diff --git a/assets/dolphin/external/sfw/L1_Sleigh_ride_128x64/meta.txt b/assets/dolphin/external/sfw/L1_Sleigh_ride_128x64/meta.txt
index 3e31e1d692..eed81079d7 100644
--- a/assets/dolphin/external/sfw/L1_Sleigh_ride_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Sleigh_ride_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 19
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/dolphin/external/sfw/L1_Waves_128x50/meta.txt b/assets/dolphin/external/sfw/L1_Waves_128x50/meta.txt
index c2f63b4c71..f865796340 100644
--- a/assets/dolphin/external/sfw/L1_Waves_128x50/meta.txt
+++ b/assets/dolphin/external/sfw/L1_Waves_128x50/meta.txt
@@ -8,7 +8,7 @@ Active frames: 4
Frames order: 0 1 2 3 2 3
Active cycles: 2
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 5
Bubble slots: 3
diff --git a/assets/dolphin/external/sfw/L2_Furippa2_128x64/meta.txt b/assets/dolphin/external/sfw/L2_Furippa2_128x64/meta.txt
index c21027e49c..8b01676f5a 100644
--- a/assets/dolphin/external/sfw/L2_Furippa2_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L2_Furippa2_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 11
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
diff --git a/assets/dolphin/external/sfw/L2_Hacking_pc_128x64/meta.txt b/assets/dolphin/external/sfw/L2_Hacking_pc_128x64/meta.txt
index 8ad8d42a34..a47eae2a95 100644
--- a/assets/dolphin/external/sfw/L2_Hacking_pc_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L2_Hacking_pc_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 2
Frames order: 0 1 2 3 4
Active cycles: 4
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/dolphin/external/sfw/L2_Soldering_128x64/meta.txt b/assets/dolphin/external/sfw/L2_Soldering_128x64/meta.txt
index b705bf6236..f47cfe0478 100644
--- a/assets/dolphin/external/sfw/L2_Soldering_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L2_Soldering_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 5
Frames order: 0 1 2 3 4 5 6 7 8 9 10 9 10 9
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/dolphin/external/sfw/L2_Wake_up_128x64/meta.txt b/assets/dolphin/external/sfw/L2_Wake_up_128x64/meta.txt
index 06c710f039..c91bda1fc4 100644
--- a/assets/dolphin/external/sfw/L2_Wake_up_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L2_Wake_up_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 18
Frames order: 0 1 0 1 0 1 0 2 3 4 0 5 6 7 8 9 10 11 10 12 13 14 15 16 17 18 19 20
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
\ No newline at end of file
diff --git a/assets/dolphin/external/sfw/L3_Furippa3_128x64/meta.txt b/assets/dolphin/external/sfw/L3_Furippa3_128x64/meta.txt
index c21027e49c..8b01676f5a 100644
--- a/assets/dolphin/external/sfw/L3_Furippa3_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L3_Furippa3_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 11
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
diff --git a/assets/dolphin/external/sfw/L3_Hijack_radio_128x64/meta.txt b/assets/dolphin/external/sfw/L3_Hijack_radio_128x64/meta.txt
index 1d415b4b85..8af34cdc5c 100644
--- a/assets/dolphin/external/sfw/L3_Hijack_radio_128x64/meta.txt
+++ b/assets/dolphin/external/sfw/L3_Hijack_radio_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 8
Frames order: 0 1 2 3 4 5 4 6 7 8 9 10 11 12 11 13
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
diff --git a/assets/dolphin/external/sfw/L3_Lab_research_128x54/meta.txt b/assets/dolphin/external/sfw/L3_Lab_research_128x54/meta.txt
index e83a8b4368..efb2f9cd5d 100644
--- a/assets/dolphin/external/sfw/L3_Lab_research_128x54/meta.txt
+++ b/assets/dolphin/external/sfw/L3_Lab_research_128x54/meta.txt
@@ -8,7 +8,7 @@ Active frames: 8
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/icons/Dolphin/DolphinCommon_56x48_sfw.png b/assets/icons/Dolphin/DolphinCommon_56x48_sfw.png
new file mode 100644
index 0000000000..089aaed835
Binary files /dev/null and b/assets/icons/Dolphin/DolphinCommon_56x48_sfw.png differ
diff --git a/assets/icons/StatusBar/Battery_25x8.png b/assets/icons/StatusBar/Battery_25x8.png
new file mode 100644
index 0000000000..03187dc1f3
Binary files /dev/null and b/assets/icons/StatusBar/Battery_25x8.png differ
diff --git a/assets/icons/StatusBar/Battery_26x8.png b/assets/icons/StatusBar/Battery_26x8.png
deleted file mode 100644
index 5fc1b0cd6d..0000000000
Binary files a/assets/icons/StatusBar/Battery_26x8.png and /dev/null differ
diff --git a/assets/resources/dolphin/sfw/L1_Boxing_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Boxing_128x64/meta.txt
index c66998e7d8..ec5127b8ae 100644
--- a/assets/resources/dolphin/sfw/L1_Boxing_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Boxing_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 7
Frames order: 0 1 2 1 3 1 2 3 1 4 5 6 5 6 5 4
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 2
diff --git a/assets/resources/dolphin/sfw/L1_Cry_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Cry_128x64/meta.txt
index 1b7d13dd88..43b4603d47 100644
--- a/assets/resources/dolphin/sfw/L1_Cry_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Cry_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 4
Frames order: 0 1 2 3 4 2 3 4 5 6 7 6
Active cycles: 2
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 2
diff --git a/assets/resources/dolphin/sfw/L1_Furippa1_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Furippa1_128x64/meta.txt
index c21027e49c..8b01676f5a 100644
--- a/assets/resources/dolphin/sfw/L1_Furippa1_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Furippa1_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 11
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
diff --git a/assets/resources/dolphin/sfw/L1_Happy_holidays_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Happy_holidays_128x64/meta.txt
index 6c50a40ed3..d99fe14b97 100644
--- a/assets/resources/dolphin/sfw/L1_Happy_holidays_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Happy_holidays_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 18
Frames order: 0 1 2 1 0 1 2 1 0 1 2 3 4 5 6 5 4 7 2 8 9 10 11 10 9 10 11 12
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/resources/dolphin/sfw/L1_Laptop_128x51/meta.txt b/assets/resources/dolphin/sfw/L1_Laptop_128x51/meta.txt
index 90cdc5ce9d..0c3edb0574 100644
--- a/assets/resources/dolphin/sfw/L1_Laptop_128x51/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Laptop_128x51/meta.txt
@@ -8,7 +8,7 @@ Active frames: 2
Frames order: 0 1 2 3 4 5 6 7
Active cycles: 4
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/resources/dolphin/sfw/L1_Leaving_sad_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Leaving_sad_128x64/meta.txt
index 8760030795..fbf7c67fc7 100644
--- a/assets/resources/dolphin/sfw/L1_Leaving_sad_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Leaving_sad_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 42
Frames order: 0 1 2 1 3 4 5 6 7 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 11 12 4 3
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/resources/dolphin/sfw/L1_Mad_fist_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Mad_fist_128x64/meta.txt
index 93e59e49b4..56f3807479 100644
--- a/assets/resources/dolphin/sfw/L1_Mad_fist_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Mad_fist_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 13
Frames order: 0 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 12 13 12 13
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/resources/dolphin/sfw/L1_Mods_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Mods_128x64/meta.txt
index c9c35ee412..40dc021bf8 100644
--- a/assets/resources/dolphin/sfw/L1_Mods_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Mods_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 18
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
diff --git a/assets/resources/dolphin/sfw/L1_Painting_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Painting_128x64/meta.txt
index e5f5fc0a64..b0b88fbbd7 100644
--- a/assets/resources/dolphin/sfw/L1_Painting_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Painting_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 13
Frames order: 0 1 2 3 4 5 2 3 4 10 6 7 8 7 8 7 8 7 8 9 10 11
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/resources/dolphin/sfw/L1_Read_books_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Read_books_128x64/meta.txt
index 7432507ce2..750c043d03 100644
--- a/assets/resources/dolphin/sfw/L1_Read_books_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Read_books_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 2
Frames order: 0 1 0 2 3 3 4 0 1 5 6 1 1 7 8
Active cycles: 2
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 5
Bubble slots: 1
diff --git a/assets/resources/dolphin/sfw/L1_Recording_128x51/meta.txt b/assets/resources/dolphin/sfw/L1_Recording_128x51/meta.txt
index de37d5b2e4..dc79b1645c 100644
--- a/assets/resources/dolphin/sfw/L1_Recording_128x51/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Recording_128x51/meta.txt
@@ -8,7 +8,7 @@ Active frames: 6
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 5
Bubble slots: 0
diff --git a/assets/resources/dolphin/sfw/L1_Sleep_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Sleep_128x64/meta.txt
index ffd845e8ce..589f462946 100644
--- a/assets/resources/dolphin/sfw/L1_Sleep_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Sleep_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 4
Frames order: 0 1 2 3 2 3
Active cycles: 2
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 5
Bubble slots: 2
diff --git a/assets/resources/dolphin/sfw/L1_Sleigh_ride_128x64/meta.txt b/assets/resources/dolphin/sfw/L1_Sleigh_ride_128x64/meta.txt
index 3e31e1d692..eed81079d7 100644
--- a/assets/resources/dolphin/sfw/L1_Sleigh_ride_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Sleigh_ride_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 19
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/resources/dolphin/sfw/L1_Waves_128x50/meta.txt b/assets/resources/dolphin/sfw/L1_Waves_128x50/meta.txt
index 376447af78..edc7ebe990 100644
--- a/assets/resources/dolphin/sfw/L1_Waves_128x50/meta.txt
+++ b/assets/resources/dolphin/sfw/L1_Waves_128x50/meta.txt
@@ -8,7 +8,7 @@ Active frames: 4
Frames order: 0 1 2 3 2 3
Active cycles: 2
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 5
Bubble slots: 3
diff --git a/assets/resources/dolphin/sfw/L2_Furippa2_128x64/meta.txt b/assets/resources/dolphin/sfw/L2_Furippa2_128x64/meta.txt
index c21027e49c..8b01676f5a 100644
--- a/assets/resources/dolphin/sfw/L2_Furippa2_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L2_Furippa2_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 11
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
diff --git a/assets/resources/dolphin/sfw/L2_Hacking_pc_128x64/meta.txt b/assets/resources/dolphin/sfw/L2_Hacking_pc_128x64/meta.txt
index 8ad8d42a34..a47eae2a95 100644
--- a/assets/resources/dolphin/sfw/L2_Hacking_pc_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L2_Hacking_pc_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 2
Frames order: 0 1 2 3 4
Active cycles: 4
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/resources/dolphin/sfw/L2_Soldering_128x64/meta.txt b/assets/resources/dolphin/sfw/L2_Soldering_128x64/meta.txt
index b705bf6236..f47cfe0478 100644
--- a/assets/resources/dolphin/sfw/L2_Soldering_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L2_Soldering_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 5
Frames order: 0 1 2 3 4 5 6 7 8 9 10 9 10 9
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/resources/dolphin/sfw/L2_Wake_up_128x64/meta.txt b/assets/resources/dolphin/sfw/L2_Wake_up_128x64/meta.txt
index 8ae3b093d0..08de0bbc09 100644
--- a/assets/resources/dolphin/sfw/L2_Wake_up_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L2_Wake_up_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 18
Frames order: 0 1 0 1 0 1 0 2 3 4 0 5 6 7 8 9 10 11 10 12 13 14 15 16 17 18 19 20
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
diff --git a/assets/resources/dolphin/sfw/L3_Furippa3_128x64/meta.txt b/assets/resources/dolphin/sfw/L3_Furippa3_128x64/meta.txt
index c21027e49c..8b01676f5a 100644
--- a/assets/resources/dolphin/sfw/L3_Furippa3_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L3_Furippa3_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 11
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
diff --git a/assets/resources/dolphin/sfw/L3_Hijack_radio_128x64/meta.txt b/assets/resources/dolphin/sfw/L3_Hijack_radio_128x64/meta.txt
index 1d415b4b85..8af34cdc5c 100644
--- a/assets/resources/dolphin/sfw/L3_Hijack_radio_128x64/meta.txt
+++ b/assets/resources/dolphin/sfw/L3_Hijack_radio_128x64/meta.txt
@@ -8,7 +8,7 @@ Active frames: 8
Frames order: 0 1 2 3 4 5 4 6 7 8 9 10 11 12 11 13
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 0
diff --git a/assets/resources/dolphin/sfw/L3_Lab_research_128x54/meta.txt b/assets/resources/dolphin/sfw/L3_Lab_research_128x54/meta.txt
index e83a8b4368..efb2f9cd5d 100644
--- a/assets/resources/dolphin/sfw/L3_Lab_research_128x54/meta.txt
+++ b/assets/resources/dolphin/sfw/L3_Lab_research_128x54/meta.txt
@@ -8,7 +8,7 @@ Active frames: 8
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
Active cycles: 1
Frame rate: 2
-Duration: 3600
+Duration: 360
Active cooldown: 7
Bubble slots: 1
diff --git a/assets/resources/infrared/assets/ac.ir b/assets/resources/infrared/assets/ac.ir
index bce1031d69..20a72e0ca3 100644
--- a/assets/resources/infrared/assets/ac.ir
+++ b/assets/resources/infrared/assets/ac.ir
@@ -1,7 +1,37 @@
Filetype: IR library file
Version: 1
-# Last Updated 20th Dec, 2022
-# Last Checked 21th Dec, 2022
+# Last Updated 13th Jan, 2023
+# Last Checked 13th Jan, 2023
+#
+name: POWER
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 8714 4338 579 538 551 540 549 542 557 1613 555 1615 553 538 551 540 549 1619 549 1620 558 1612 556 1614 554 1617 551 540 559 1611 557 1612 556 531 558 1613 555 536 553 538 551 1620 558 1612 556 535 554 537 552 535 554 537 552 1618 550 1620 558 533 556 536 553 1617 551 1617 551 1608 549
+#
+name: MODE
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 8710 4341 576 541 558 533 556 535 554 1616 552 1618 550 542 557 533 556 1612 556 1614 554 1616 552 1618 550 1621 557 534 555 1615 553 1616 552 536 553 538 551 541 558 533 556 1613 555 537 552 539 550 541 558 528 550 1619 559 1610 557 1612 556 536 553 1616 552 1618 550 1619 559 1598 559
+#
+name: TIMER
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 8717 4334 583 534 555 537 552 539 550 1620 558 1611 557 535 554 536 553 1615 553 1617 551 1619 559 1611 557 1613 555 537 552 1617 551 1619 559 528 550 541 558 1612 556 535 554 1616 552 1619 549 543 556 534 555 532 557 1614 554 537 552 1619 559 533 556 535 554 1616 552 1617 551 1608 549
+#
+name: TEMP+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 8714 4337 580 538 551 540 559 533 556 1613 555 1615 553 539 550 541 558 1608 560 1611 557 1587 581 1590 578 1593 575 542 557 1613 555 1614 554 534 555 1615 553 539 550 1620 558 534 555 536 553 539 550 541 558 529 549 541 558 1612 556 536 553 1617 551 1619 559 1611 557 1613 555 1603 554
+#
+name: TEMP-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 8711 4341 576 541 558 534 555 536 553 1616 552 1618 549 542 557 533 556 1611 557 1613 555 1614 554 1616 552 1619 559 532 557 1613 555 1614 554 533 556 1614 554 538 551 541 558 1611 557 535 554 537 552 539 550 537 552 540 549 1620 558 1612 556 536 553 1617 550 1619 559 1610 558 1601 556
#
# POWER_ON
name: POWER
@@ -112,7 +142,7 @@ type: raw
frequency: 38000
duty_cycle: 0.330000
data: 473 397 473 397 473 397 472 371 472 397 473 25350 3523 1697 449 1292 449 422 474 397 473 397 473 1267 473 372 470 401 468 402 468 402 441 1300 441 402 468 1272 469 1272 469 402 468 1273 468 1273 468 1272 469 1273 468 1273 468 403 440 402 468 1273 468 402 468 402 468 375 468 402 468 402 468 402 441 402 468 402 468 402 468 376 467 1273 468 402 468 1273 468 402 468 402 441 402 468 1273 468 1273 468 402 468 403 467 376 467 403 467 403 467 376 467 403 467 403 467 403 440 403 467 403 467 403 467 376 467 403 467 403 467 403 440 1302 439 1302 439 1302 439 404 466 1274 467 403 467 1274 467 1275 466 34905 3520 1705 469 1273 468 402 441 402 468 402 468 1273 468 402 468 376 467 402 468 402 468 1273 468 402 441 1300 441 1300 441 403 467 1273 468 1273 468 1273 468 1273 468 1273 468 403 467 402 468 1273 468 376 467 402 468 402 468 402 441 403 467 403 468 402 441 403 467 403 467 403 467 376 467 1274 467 403 467 403 467 403 440 403 467 1274 467 403 467 403 467 376 467 1274 467 1274 467 1274 467 1274 467 403 467 404 466 1274 467 1274 467 404 439 1302 439 1302 439 404 466 404 466 404 439 1302 439 1302 439 404 466 1275 466 404 466 1275 466 404 466 1275 466 34906 3519 1705 468 1273 468 376 467 402 468 402 468 1273 468 402 441 402 468 402 468 402 468 1273 468 376 467 1273 468 1273 468 402 468 1273 468 1273 468 1273 468 1273 468 1273 468 402 468 376 467 1273 468 402 468 402 468 403 440 403 467 403 467 403 467 376 467 403 467 403 467 403 440 403 467 403 468 402 468 376 467 403 467 403 467 403 440 403 467 403 467 403 440 403 467 1274 467 1274 467 1274 467 403 467 404 466 376 467 1274 467 1275 466 404 466 1275 466 1275 466 404 466 404 439 404 466 404 467 404 466 377 466 404 466 404 466 404 439 404 466 404 466 405 438 405 465 404 466 405 465 1276 465 1299 442 378 465 406 464 405 465 406 437 405 465 428 442 428 442 401 442 428 442 428 442 428 415 429 441 428 442 429 414 429 441 429 441 428 442 401 442 1300 441 1299 442 429 441 429 441 429 414 429 441 429 441 429 441 402 441 429 441 429 441 429 414 1327 414 1327 414 429 441 429 441 429 441 402 441 429 441 429 441 402 441 429 441 429 441 429 414 429 441 429 441 429 441 402 441 429 441 429 441 429 414 1328 413 430 441 429 441 429 441 402 441 429 441 1300 441 1301 440 429 441 402 441 430 440 430 440 430 413 430 441 429 441 1301 440 430 440 403 440 430 440 430 440 430 413 430 440 430 440 430 440 1301 440 1301 440 1301 440 403 440 430 440 430 440 403 440 1301 440
-#
+#
name: TEMP-
type: raw
frequency: 38000
@@ -1440,115 +1470,75 @@ type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3821 1901 456 507 456 1424 430 490 484 1425 429 475 488 1420 434 471 482 1427 437 467 486 1420 434 486 457 1416 459 1432 432 487 456 1436 439 480 483 1425 439 1425 460 1420 455 1419 435 485 457 472 491 1417 458 1407 437 483 459 487 456 474 458 487 466 1432 432 471 461 485 457 472 491 1415 460 1378 466 480 483 1424 430 474 458 487 466 1424 461 1419 456 1426 438 465 457 489 464 466 456 489 464 1426 438 481 461 484 437 493 460 1429 435 482 460 485 458 1440 435 484 458 1438 437 467 465 480 462 467 465 481 461 468 464 481 461 469 463 481 461 468 485 1424 430 1434 462 1418 457 1425 439 465 457 489 464 465 457 489 464 466 456 490 463 467 465 480 463 467 465 480 463 467 486 1422 432 471 461 485 457 472 460 485 457 472 460 485 457 472 460 486 456 488 434 497 456 473 459 486 456 488 465 1414 461 1393 482 1423 462 1419 435 469 463 482 460 469 463 482 460 1436 439 1425 439 480 483
-#
-# Model: Sharp AH-X9VEW. Doesn't have heat function.
-name: Dh
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 307 125509 3831 1867 489 482 491 1392 461 468 485 1397 456 489 464 1411 463 466 487 1397 456 488 465 1390 463 482 481 1402 462 1402 483 471 461 1412 462 468 485 1400 464 1401 484 1397 488 1395 458 471 461 485 457 1408 487 1393 460 485 457 473 459 486 456 474 489 1394 459 471 461 485 457 473 459 488 465 466 455 490 463 467 465 480 462 468 464 482 460 470 483 1399 465 464 457 488 465 465 488 1393 460 484 458 471 461 485 457 1415 459 1405 511 408 482 489 464 466 487 1377 456 489 464 481 461 469 463 482 460 470 462 483 459 470 462 484 458 472 460 485 457 473 459 487 455 474 489 1395 458 471 461 485 457 472 460 486 456 473 459 486 456 474 458 487 455 474 458 488 465 466 487 1396 457 487 434 496 457 488 433 496 457 489 432 497 466 479 432 498 465 480 431 499 464 482 439 490 463 482 460 1394 491 1389 485 1395 490 1392 461 468 464 482 460 469 484 1399 465 1399 465 480 462 483 491 77962 300
#
-name: Cool_hi
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 345 2685 478 1170 176 29680 3832 1891 465 481 482 1400 464 465 488 1395 458 470 483 1396 457 487 466 1406 458 471 492 1389 464 481 461 1411 463 1408 456 489 464 1407 457 473 490 1392 482 1383 481 1399 486 1396 458 462 459 497 456 1409 486 1394 459 459 483 473 459 487 455 474 489 1392 461 468 464 481 461 469 463 483 459 471 482 1398 487 1379 464 481 461 485 457 1416 458 487 466 1407 457 472 460 460 482 474 489 1393 460 469 463 483 459 471 461 485 457 1408 456 488 465 481 461 469 484 1381 462 483 459 486 456 473 459 487 455 474 458 487 455 475 457 489 464 467 465 481 461 1410 485 1380 484 1397 488 1392 461 483 459 471 461 485 457 473 459 486 456 474 458 488 454 476 456 490 463 467 465 481 461 1411 464 481 440 491 462 484 437 492 461 485 436 494 459 487 434 495 458 488 433 497 456 489 432 498 486 450 482 1408 467 1389 485 1394 480 1384 459 486 456 489 464 466 487 1393 460 485 457 1415 459 1406 510
-#
-name: Cool_lo
+name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 181 11813 3819 1899 457 488 486 1421 433 472 491 1416 438 481 461 1417 437 482 492 1416 437 467 486 1419 435 485 457 1439 435 1403 461 483 480 1408 435 484 490 1416 438 1401 484 1395 490 1392 461 467 465 480 462 1427 458 1396 457 486 456 473 459 486 456 472 481 1426 438 466 466 480 462 467 465 480 462 467 465 479 463 1426 438 481 461 484 458 1438 436 1409 486 1378 465 480 462 483 459 471 482 1425 428 475 457 487 455 474 458 487 455 1434 430 489 464 481 461 468 485 1404 439 480 462 483 459 470 462 483 459 469 463 482 460 470 462 483 459 470 462 483 459 1437 458 1381 483 1395 490 1390 463 481 461 469 463 482 460 468 464 481 461 468 464 481 461 469 463 482 460 469 463 481 461 1434 430 474 458 486 456 473 459 486 456 473 459 486 456 473 459 486 456 473 459 485 457 472 460 485 489 449 462 1434 461 1378 486 1393 481 1397 519 400 479 476 456 489 464 1431 433 486 435 495 458 487 487
+data: 6149 7347 601 535 573 560 602 505 602 480 597 509 600 534 599 487 593 541 591 568 569 539 568 490 594 539 570 513 568 540 570 566 570 540 568 543 594 540 569 566 543 515 594 540 569 514 567 542 570 514 568 543 594 540 569 490 592 542 570 514 568 541 570 541 542 541 569 567 570 515 567 542 570 515 567 542 570 568 568 516 570 568 570 542 568 542 570 515 569 542 570 568 568 517 569 541 569 517 569 568 570 515 568 570 569 569 543 542 569 569 569 516 569 542 570 543 568 1640 570 516 568 543 570 569 543 1613 569 516 568 1613 570 569 543 570 569 542 543 543 569 543 542 544 569 516 569 544 570 543 570 570 570 543 543 544 569 1615 569 571 569 570 568 519 569 1615 569 544 569 1615 568 572 569 571 542 1642 569 571 568 1617 569 1642 542 1642 569 1589 568 545 569 1590 569 518 568 1617 569 545 568 7372 568
#
-name: Off
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3826 1866 490 481 482 1382 461 484 490 1392 461 467 486 1396 457 471 482 1400 464 479 463 1390 463 481 482 1399 465 1398 518 401 510 1379 464 480 483 1398 456 1408 487 1392 482 1399 517 386 483 487 466 1399 486 1392 461 483 459 470 462 482 460 469 484 1397 456 473 459 459 483 472 460 484 458 471 461 483 459 1411 463 480 462 467 486 1377 487 1392 482 1396 457 486 456 472 460 486 456 473 480 1400 464 465 456 488 454 475 488 1393 460 468 464 480 462 467 486 1395 458 470 462 483 459 485 436 493 460 469 463 481 461 486 435 500 463 463 458 486 456 1397 488 1390 484 1394 480 1400 464 465 456 488 465 464 457 487 455 474 458 487 455 473 459 485 457 472 460 485 457 472 481 1399 517 401 458 497 456 473 459 485 457 487 434 495 458 471 461 484 458 488 433 502 430 507 435 500 432 498 455 1409 486 1392 482 1399 454 1409 455 488 465 480 462 467 465 480 462 1408 456 473 459 486 488
-#
-# Model: Electrolux ESV09CRO-B21. Doesn't have heat function.
-name: Dh
+name: MODE
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 3092 3057 3092 4438 579 1675 545 534 576 1650 571 535 575 531 569 1656 575 1652 579 527 573 533 577 1648 572 1655 576 1651 580 526 573 532 578 1647 573 532 578 1647 573 1654 577 529 571 535 575 530 570 535 575 529 571 534 576 529 571 534 576 528 571 534 576 528 572 533 577 528 572 533 577 527 573 1651 580 526 573 532 578 527 572 532 568 537 573 531 568 536 574 1650 571 535 575 531 569 536 574 530 569 535 575 529 571 534 576 529 571 533 577 528 572 533 577 527 572 532 568 536 574 531 569 1655 576 530 570 535 575 530 570 535 575 529 571 534 576 528 572 533 577 527 573 532 578 527 572 531 569 536 574 531 569 535 575 530 570 534 576 529 571 534 576 528 571 533 577 527 573 532 567 537 573 531 569 536 574 530 570 535 575 529 571 534 576 528 571 533 577 527 572 532 578 526 573 531 569 536 574 530 570 535 575 529 571 534 576 528 572 533 577 1646 574 532 578 1646 574 1652 579 527 572 533 577 1647 573 1653 578 1675 545 534 576 1649 571
-#
-name: Cool_hi
+data: 6145 7375 572 534 598 535 574 532 576 507 598 507 601 508 599 484 595 565 569 567 568 541 566 541 567 543 567 513 569 540 569 568 568 513 569 567 569 541 568 513 568 568 569 542 568 540 568 543 568 569 567 541 568 543 568 542 541 541 569 542 567 515 569 542 568 514 568 572 567 570 567 515 569 571 567 514 569 544 567 569 568 542 568 1641 566 543 541 595 568 546 567 515 568 573 566 571 566 517 568 572 567 515 568 571 542 543 568 571 567 569 541 519 568 569 516 570 569 1639 541 518 568 570 515 544 568 1666 542 518 568 1666 542 543 568 571 542 516 568 571 542 517 567 598 542 517 568 572 542 544 567 572 542 517 569 571 542 1615 568 1669 542 544 568 572 542 1615 568 599 542 1615 567 572 542 518 569 1642 515 571 542 1615 569 598 542 518 569 598 543 1670 514 1644 542 1616 567 1670 542 545 568 7374 567
+# High
+name: TEMP+
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 315 101050 3094 3056 3093 4437 580 1648 572 534 576 1649 582 525 574 530 580 1646 574 1653 578 529 570 534 576 529 571 534 576 529 570 1655 576 1651 580 527 572 532 578 1647 573 1654 577 1651 580 526 573 531 579 526 573 531 579 526 573 531 579 526 573 531 579 526 573 531 579 525 574 531 579 525 574 531 579 1646 574 532 578 526 573 531 579 526 573 531 579 526 573 1652 579 527 572 1653 578 528 571 534 576 528 571 533 577 528 571 533 577 528 572 533 577 528 572 532 578 527 572 532 578 527 572 532 578 526 573 1652 579 527 572 532 578 527 572 532 578 527 572 532 578 526 573 531 579 526 573 531 579 526 573 531 579 525 574 530 580 525 574 530 580 525 574 530 580 524 575 529 581 524 575 529 571 534 576 528 571 533 577 528 571 533 577 528 571 533 577 527 572 532 578 527 572 532 578 526 573 531 579 526 573 531 579 525 574 531 579 525 574 530 580 525 574 1650 581 525 574 1651 580 1647 573 533 577 527 572 1653 578 528 572 1654 577 1650 581 1646 574 71637 254
-#
-name: Cool_lo
+data: 6143 7350 600 533 572 507 573 532 575 508 597 507 600 535 572 510 569 539 569 593 542 541 566 540 568 569 541 513 569 540 568 542 567 513 568 570 567 594 542 569 540 541 568 567 542 513 568 571 567 544 564 542 567 569 542 514 569 568 568 568 542 514 567 570 542 514 568 569 569 568 542 514 570 568 542 514 568 570 542 595 515 542 568 1664 542 514 568 1639 542 595 515 569 542 595 543 542 568 597 542 596 542 542 568 597 543 596 540 518 569 596 542 542 568 571 542 1612 568 1640 541 516 568 571 542 596 515 1640 542 516 568 1641 542 596 516 570 542 516 569 571 542 517 568 571 542 516 569 598 543 597 515 571 542 517 568 571 543 1614 568 1642 542 517 569 571 542 1615 569 598 542 1615 568 571 542 544 569 1669 542 518 568 1668 542 1619 565 571 540 1643 543 1668 516 1643 541 1616 567 1670 542 545 568 7371 568
+# Low
+name: TEMP-
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 284 19161 3098 3053 3096 4435 572 1656 575 532 578 1648 572 534 576 530 570 1682 549 1652 579 527 572 534 576 1649 571 1656 575 1652 579 1649 571 1656 575 531 579 527 572 1653 578 1649 571 1656 575 531 579 527 572 532 578 527 572 533 577 527 572 533 577 527 573 532 578 527 572 532 578 527 573 532 578 527 572 1652 579 527 572 533 577 528 571 533 577 528 571 533 577 1648 572 533 577 1649 571 535 575 530 569 536 574 531 569 536 574 530 569 536 574 530 570 535 575 530 570 535 575 530 569 535 575 530 569 535 575 1649 571 535 575 531 568 536 574 531 568 536 574 531 568 536 574 531 569 536 574 530 569 536 574 530 569 535 575 530 569 535 575 530 569 535 575 530 570 535 575 529 570 534 576 529 570 534 576 529 570 534 576 528 571 534 576 528 571 534 576 528 571 534 576 528 571 534 576 528 571 533 577 528 571 533 577 528 572 533 577 528 571 533 577 528 572 1652 579 527 572 1653 578 529 570 534 576 529 570 535 575 529 570 1654 577 1677 554 1673 547
+data: 6144 7375 572 534 572 533 574 559 575 507 598 507 600 508 598 484 595 539 568 567 568 513 568 540 568 541 567 513 567 542 568 541 541 540 568 568 568 514 593 515 569 541 568 540 568 543 567 542 567 515 568 569 567 514 569 567 569 542 568 514 568 569 569 542 567 515 569 569 568 515 567 543 567 542 567 516 569 543 567 515 568 543 568 1610 568 569 542 1612 540 542 568 544 566 516 568 596 542 516 567 572 567 596 541 517 568 569 542 543 567 597 542 597 540 518 568 1667 541 1587 567 570 541 544 567 598 541 1587 567 1641 540 1614 567 598 540 598 541 519 566 571 541 519 567 598 541 518 567 572 541 545 566 573 541 519 566 573 541 1617 565 1670 541 545 541 572 541 1642 541 599 541 1642 540 600 541 571 542 1671 539 545 541 1671 540 1617 566 600 540 1642 541 1643 541 1642 540 1644 540 545 541 1643 514 7370 566
#
-name: Off
+name: TIMER
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 3093 3058 3090 4441 576 1652 579 528 571 1654 577 531 579 526 573 1652 579 1649 582 525 574 1652 579 528 571 1654 577 1651 580 527 572 533 577 528 571 533 577 1649 582 1646 574 1653 578 529 581 525 574 530 580 525 574 530 580 525 574 531 579 526 573 531 579 526 573 531 579 526 573 531 579 526 573 531 579 526 573 531 579 526 573 531 579 526 573 532 578 1647 573 533 577 1648 572 535 575 530 569 535 575 530 580 525 574 531 579 525 574 531 579 526 573 531 579 526 573 531 579 526 573 531 579 526 573 1651 580 527 572 533 577 528 571 533 577 528 571 533 577 528 571 533 577 528 571 534 576 528 571 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 529 570 534 576 1649 582 525 574 1650 581 1647 573 1654 577 1651 580 1647 573 1654 577 531 579 1646 574 1653 578
+data: 6199 7295 628 530 604 504 601 480 573 534 600 482 596 537 570 538 595 541 593 540 568 541 569 567 568 566 568 518 590 1636 569 540 568 1582 566 569 569 540 568 514 569 541 569 567 542 541 569 567 570 514 567 569 568 541 568 515 568 541 569 1610 568 541 569 541 568 516 568 1636 569 515 567 542 569 515 568 542 569 541 568 516 569 541 570 1611 567 543 569 568 568 517 569 1637 569 516 568 542 569 542 568 569 570 569 569 542 568 543 570 516 567 544 569 543 568 543 570 1639 542 1639 568 542 568 518 568 542 569 1588 569 1639 543 1613 569 570 568 517 569 543 543 543 569 570 569 544 569 543 570 517 569 570 569 517 568 572 569 544 568 1642 569 1615 567 571 569 517 569 1642 569 518 567 1616 569 517 569 544 569 1616 568 571 569 1616 568 571 569 1616 568 571 569 1616 568 1642 569 1616 568 1642 568 545 569 7371 568
#
-# Model: Daikin FTE35KV1. Doesn't have heat function.
-name: Dh
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 5045 2158 335 1768 358 690 357 723 335 716 331 1771 355 694 364 686 361 720 327 723 335 1767 359 690 357 1775 362 1770 356 692 366 1767 359 1772 354 1777 360 1771 355 1776 361 687 360 690 357 1776 361 687 360 690 357 693 365 716 331 719 328 692 366 1767 359 1772 354 1777 360 1771 355 1776 361 687 360 1773 364 1767 360 689 358 692 366 685 362 688 359 721 326 724 334 717 330 720 327 723 335 715 332 718 329 721 326 1777 360 1771 355 1776 361 1770 356 692 366 715 332 718 329 721 326 29460 5042 2161 332 1770 356 692 366 685 362 688 359 1774 363 685 362 688 359 721 326 694 364 1769 357 691 367 1767 360 1771 355 693 365 1769 358 1773 364 1768 359 1772 365 1766 361 688 359 691 367 1767 360 689 358 692 366 684 363 717 330 720 327 693 365 686 361 689 358 722 336 684 363 1770 357 1774 363 686 361 689 358 1774 363 686 361 1771 356 1776 361 1770 357 692 366 685 362 688 359 690 357 1776 361 687 360 690 357 1776 361 688 359 691 356 694 364 716 331 689 358 1775 362 686 361 689 358 692 366 685 362 688 359 691 356 724 334 716 331 689 358 722 336 685 362 688 359 721 326 693 365 716 331 689 358 692 366 684 363 718 329 690 357 693 365 716 331 689 358 722 336 1767 360 689 358 1774 363 686 361 1771 356 693 365 686 361 689 358 722 336 684 363 717 330 720 327 1776 361 687 360 690 357 693 365 716 331 1771 355 693 365 686 361 1772 355 1776 361 688 359 1773 364 1768 359
-#
-name: Cool_hi
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 5038 2165 328 1772 365 686 361 689 358 692 366 1765 362 719 328 692 366 684 363 717 330 1771 366 684 363 1768 359 1774 363 686 361 1771 355 1776 361 1770 357 1775 362 1769 358 691 356 694 364 1767 360 691 356 694 364 686 361 689 358 692 366 685 362 1769 358 1775 362 1769 358 1774 363 1768 359 690 357 1776 361 1770 357 692 366 684 363 687 360 690 357 693 365 686 361 689 358 692 366 684 363 687 360 690 357 693 365 1766 361 1773 364 1767 360 1772 355 694 364 686 361 689 358 692 366 25151 319 3980 5041 2131 362 1769 358 693 365 686 361 689 358 1772 365 686 361 689 358 692 366 684 363 1768 359 692 366 1765 361 1772 354 694 364 1769 358 1774 363 1768 359 1773 364 1767 359 719 328 692 366 1796 331 719 328 692 366 685 362 688 359 691 356 694 364 686 361 689 358 692 366 685 362 1768 359 1775 362 686 361 689 358 1773 364 686 361 1770 357 1777 360 1771 355 693 365 686 361 689 358 1772 365 1769 358 690 357 694 364 1767 360 691 356 694 364 686 361 689 358 723 335 1766 361 690 357 693 365 685 362 688 359 691 356 694 364 687 360 690 357 693 365 685 362 688 359 691 356 694 364 687 360 690 357 693 365 685 362 688 359 691 367 684 363 687 360 1771 366 684 363 687 360 690 357 693 365 1767 360 690 357 1804 333 687 360 690 357 693 365 686 361 689 358 692 366 685 362 1768 359 692 366 685 362 688 359 690 357 1774 363 688 359 691 356 1774 363 1770 356 1775 362 1769 358 691 356
-#
-name: Cool_lo
+name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 301 132136 5036 2167 337 1766 361 689 358 692 366 684 363 1770 357 692 366 684 363 718 329 690 357 1776 361 687 360 1773 364 1767 360 689 358 1775 362 1769 357 1774 363 1768 359 1773 364 684 363 718 329 1773 364 684 363 718 329 691 356 694 364 716 331 719 328 1775 362 1769 358 1774 363 1768 359 1772 365 714 333 1770 357 1774 363 716 331 719 328 722 336 715 332 718 329 721 326 724 334 716 331 719 328 722 336 715 332 718 329 1773 364 1767 360 1772 354 1777 360 719 328 721 326 725 333 717 330 29455 5036 2139 354 1777 360 688 359 691 367 714 333 1770 356 692 366 684 363 687 360 690 357 1776 361 688 359 1773 364 1768 359 689 358 1775 362 1769 357 1774 363 1768 359 1773 364 684 363 687 360 1773 364 685 362 688 359 691 356 694 364 686 361 689 358 692 366 685 362 688 359 691 356 1777 360 1771 355 693 365 685 362 1771 355 693 365 1768 359 1773 364 1767 360 689 358 692 366 685 362 1771 355 1775 362 687 360 690 357 1775 362 687 360 690 357 693 365 716 331 689 358 1774 363 686 361 689 358 692 366 685 362 688 359 691 356 694 364 686 361 689 358 692 366 685 362 688 359 691 356 694 364 686 361 689 358 692 366 685 362 1771 355 693 365 1768 358 1773 364 684 363 687 360 690 357 693 365 1768 359 690 357 1776 361 688 359 691 356 694 364 686 361 689 358 692 366 685 362 1770 356 693 365 685 362 688 359 691 356 1777 360 1771 355 693 365 686 361 689 358 692 366 685 362 1770 356
+data: 1299 412 1270 412 426 1225 1299 412 1244 438 399 1279 400 1254 451 1253 426 1253 426 1253 426 1254 1268 7130 1266 416 1266 416 421 1258 1267 416 1267 416 422 1258 421 1258 422 1258 421 1259 421 1258 422 1258 1266 7132 1266 417 1266 417 421 1259 1266 417 1266 417 421 1259 421 1259 421 1259 421 1259 421 1259 421 1259 1266 7133 1265 417 1266 417 421 1259 1266 418 1266 417 422 1259 421 1260 420 1259 421 1259 421 1259 420 1259 1266 7133 1265 418 1266 418 421 1260 1265 418 1266 418 421 1260 420 1260 420 1260 420 1260 420 1260 420 1260 1266 7135 1265 418 1266 419 420 1260 1266 419 1266 419 420 1261 420 1261 420 1261 420 1261 420 1261 420 1261 1265 7137 1264 420 1265 420 419 1262 1266 420 1265 420 420 1262 420 1262 419 1262 420 1262 419 1262 419 1262 1265 7139 1264 421 1265 421 419 1263 1265 421 1265 421 418 1264 418 1264 418 1263 419 1264 417 1264 418 1264 1264 7142 1263 423 1263 422 418 1288 1241 446 1240 446 394 1288 394 1289 393 1288 394 1288 394 1288 394 1288 1241 7168 1240 446 1241 446 394 1289 1241 447 1241 447 394 1289 394 1289 394 1289 394 1289 394 1289 394 1289 1241 7171 1239 447 1240 447 393 1290 1240 447 1241 447 393 1290 393 1290 393 1290 393 1290 393 1290 393 1290 1241 7174 1239 447 1241 448 392 1291 1240 448 1241 448 393 1291 393 1292 392 1292 392 1291 393 1292 392 1291 1240 7177 1239 449 1240 449 392 1292 1240 449 1240 449 392 1293 392 1293 392 1292 392 1293 391 1293 392 1293 1239 7179 1239 450 1239 450 391 1294 1239 450 1240 451 391 1294 391 1294 391 1295 390 1294 391 1295 390 1294 1239 7184 1237 452 1238 475 367 1319 1215 476 1215 476 366 1320 366 1320 366 1320 365 1320 365 1320 366 1320 1215 7211 1213 476 1190 501 366 1321 1215 477 1214 477 365 1322 364 1321 365 1322 364 1321 365 1321 365 1322 1213 7214 1213 478 1213 478 364 1322 1189 503 1189 503 364 1323 339 1348 338 1348 364 1323 363 1324 362 1323 1213 7218 1187 528 1164 529 313 1374 1163 529 1164 529 313 1375 313 1375 312 1375 312 1374 313 1374 313 1375 1163 7271 1162 530 1163 530 312 1376 1163 531 1162 530 312 1377 311 1378 310 1402 285 1378 310 1402 285 1403 1136 7300 1136 557 1136 557 285 1404 1136 558 1136 559 283 1404 285 1431 257 1405 284 1431 257 1431 257 1431 1109 7330 1108 585 1109 586 256 1432 1109 586 1109 638 177 1486 222 1468 221 1468 221 1468 221 1467 221 1495 1055 7413 1028 666 1029 2500 885
#
-name: Off
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 5043 2132 361 1770 356 723 335 715 332 718 329 1774 363 715 332 719 328 722 336 714 333 1770 356 722 336 1767 360 1772 354 724 334 1769 357 1774 363 1768 358 1773 364 1767 359 720 327 723 335 1768 359 720 327 723 335 716 331 719 328 722 336 714 333 1770 356 1774 363 1769 357 1773 364 1767 360 720 327 1775 362 1769 357 721 326 725 333 717 330 720 327 723 335 716 331 719 328 722 336 714 333 717 330 720 327 723 335 1768 359 1773 364 1767 360 1772 354 724 334 717 330 720 327 723 335 29451 5041 2134 359 1772 354 724 334 717 330 720 327 1775 362 717 330 720 327 723 335 715 332 1771 355 723 335 1768 358 1773 364 715 332 1770 357 1775 362 1769 357 1774 363 1768 359 720 327 723 335 1768 359 720 327 724 334 716 331 719 328 722 336 715 332 718 329 720 327 723 335 716 331 1771 355 1776 361 718 329 721 326 1776 361 718 329 1773 364 1767 360 720 327 723 335 715 332 718 329 1774 363 1768 359 720 327 723 335 1768 358 721 326 724 334 716 331 719 328 722 336 1767 360 719 328 722 336 715 332 718 329 721 326 724 334 717 330 720 327 723 335 715 332 719 328 722 325 725 333 717 330 720 327 723 335 716 331 719 328 1774 363 716 331 1771 355 1776 361 718 329 721 326 724 334 717 330 1772 365 714 333 1770 356 722 336 715 332 718 329 721 326 724 334 717 330 719 328 1775 362 717 330 720 327 723 335 715 332 718 329 1774 363 715 332 718 329 721 326 725 333 717 330 1772 365
-#
-# Model: Dyson Purifier Hot+Cool
-name: Off
+name: SWING
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 2309 665 781 672 803 672 803 695 832 643 833 1355 804 694 836 640 781 695 804 1409 778 697 777 702 797 678 798 677 799 678 799 701 803 674 802 1412 801 674 801 674 801 674 802 674 801 51317 2284 670 775 1413 802 51252 2283 670 801 1412 775 51275 2258 673 798 1414 802 51248 2284 670 802 1412 774 51246 2259 695 775 1413 801
+data: 1333 359 1331 358 482 1200 1279 411 1279 411 430 1255 430 1256 1279 411 430 1257 428 1257 428 1258 452 7993 1276 390 1300 415 402 1285 1276 415 1276 416 425 1262 425 1262 1275 417 425 1262 425 1262 425 1262 424 8000 1274 417 1275 417 425 1262 1276 417 1276 417 425 1263 424 1263 1275 417 425 1263 424 1263 425 1263 424 8003 1274 417 1276 417 425 1263 1275 418 1276 417 425 1263 425 1263 1276 417 425 1263 425 1263 425 1263 425 8006 1275 418 1276 418 425 1264 1276 418 1276 418 425 1264 425 1264 1276 418 425 1264 425 1264 425 1264 424 8009 1276 418 1276 418 425 1265 1276 418 1277 419 424 1265 425 1265 1276 419 424 1265 424 1265 425 1265 424 8013 1275 419 1277 419 424 1266 1276 419 1277 419 425 1266 424 1266 1276 419 424 1266 424 1266 424 1266 424 8016 1276 419 1277 420 424 1267 1276 420 1277 420 424 1267 424 1267 1276 420 424 1267 424 1267 424 1267 424 8019 1276 420 1277 420 424 1267 1277 420 1277 421 423 1268 423 1268 1277 421 423 1268 424 1268 423 1268 423 8023 1275 421 1276 421 423 1268 1277 421 1277 421 424 1269 423 1269 1277 422 423 1269 423 1269 423 1269 423 8025 1276 422 1276 422 423 1270 1276 422 1277 422 423 1270 422 1270 1277 422 423 1271 422 1271 421 1271 422 8029 1275 423 1276 423 422 1271 1276 423 1276 447 398 1273 421 1273 1275 424 421 1296 397 1296 397 1296 397 8056 1252 447 1253 447 398 1296 1252 448 1253 448 398 1296 398 1296 1252 448 398 1297 397 1296 398 1296 398 8059 1252 448 1253 448 398 1297 1252 448 1253 448 398 1297 397 1297 1252 449 397 1298 397 1297 397 1297 397 8062 1252 449 1253 449 397 1298 1252 449 1253 449 397 1298 397 1298 1253 450 396 1298 397 1298 397 1298 397 8065 1252 449 1252 450 397 1299 1252 450 1253 450 396 1299 397 1299 1253 450 396 1299 397 1299 396 1299 396 8069 1251 450 1253 450 396 1300 1252 450 1253 451 396 1300 396 1300 1253 451 396 1301 396 1300 396 1301 395 8072 1251 451 1253 451 396 1301 1252 452 1252 452 395 1302 395 1302 1227 477 395 1302 395 1302 394 1302 395 8076 1251 452 1227 478 394 1302 1252 453 1227 478 370 1328 369 1328 1251 454 394 1304 369 1329 369 1329 369 8129 1201 503 1202 503 344 1353 1202 503 1203 503 345 1354 344 1354 1202 504 344 1354 345 1354 344 1354 344 8132 1201 503 1202 504 344 1354 1202 504 1202 504 344 1355 344 1355 1202 504 344 1355 344 1355 344 1355 344 8135 1201 504 1202 505 343 1355 1202 505 1202 505 343 1357 343 1357 1201 506 343 1358 342 1383 316 1383 316 8166 1173 533 1174 559 288 1412 1147 560 1148 561 287 1439 261 1440 1120 588 260 1441 259 1467 227 1474 225
#
-name: Heat_hi
+name: TIMER
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 2316 610 806 671 781 695 806 695 781 695 782 1405 782 694 808 694 780 693 808 1381 779 697 802 1412 776 1438 800 1437 776 1438 775 700 775 1412 776 700 801 701 775 700 776 1438 776 700 776 51695 2258 695 776 1437 776 51248 2258 672 798 1439 776 51240 2258 670 801 1436 776
+data: 1275 413 1305 384 457 1226 1308 385 1329 385 430 1228 457 1228 457 1229 1304 411 429 1257 428 1258 427 7993 1275 416 1275 416 425 1262 1274 416 1275 417 425 1262 425 1262 425 1261 1276 416 426 1262 424 1262 425 7999 1274 417 1275 417 425 1262 1276 417 1276 417 425 1263 424 1262 425 1262 1276 417 425 1263 425 1263 424 8003 1274 417 1276 417 425 1263 1275 417 1277 417 425 1263 425 1263 425 1263 1276 418 425 1264 424 1263 425 8006 1276 418 1276 418 425 1263 1277 418 1277 418 425 1264 425 1264 425 1264 1276 418 425 1264 425 1264 425 8010 1276 418 1276 418 425 1264 1277 418 1277 418 425 1265 425 1265 424 1265 1276 418 425 1265 425 1265 425 8012 1276 418 1277 418 425 1265 1277 419 1277 419 425 1266 424 1266 424 1266 1277 419 425 1266 424 1266 424 8016 1276 419 1277 419 425 1266 1277 419 1278 419 425 1267 424 1266 425 1267 1277 420 424 1267 424 1267 424 8020 1275 420 1277 420 424 1267 1277 420 1277 420 424 1268 424 1268 423 1267 1277 420 424 1268 424 1268 424 8023 1276 420 1277 421 424 1268 1277 421 1277 421 424 1269 423 1269 423 1268 1278 421 423 1269 424 1269 423 8026 1276 421 1277 422 423 1269 1277 422 1277 422 423 1270 423 1270 423 1270 1276 422 423 1270 423 1271 422 8029 1276 423 1276 447 398 1272 1276 446 1254 447 399 1295 398 1272 422 1295 1252 447 398 1295 398 1295 398 8056 1252 447 1252 447 398 1296 1252 447 1253 447 399 1296 398 1296 398 1296 1253 448 398 1296 398 1296 398 8059 1252 447 1253 447 399 1296 1253 448 1253 448 398 1297 397 1297 398 1297 1253 448 398 1297 398 1297 397 8062 1252 448 1253 448 398 1297 1253 448 1254 448 398 1298 397 1298 397 1298 1253 449 397 1298 397 1298 397 8065 1252 449 1253 449 397 1298 1253 449 1254 449 398 1299 397 1299 397 1299 1253 449 398 1299 397 1299 397 8069 1252 450 1252 450 397 1299 1253 450 1254 450 397 1300 396 1300 396 1300 1252 450 397 1300 397 1300 396 8072 1252 450 1253 451 396 1300 1253 451 1253 451 396 1301 396 1301 396 1301 1253 451 396 1301 396 1301 396 8075 1251 452 1252 452 396 1301 1253 452 1253 452 395 1303 395 1303 394 1302 1254 453 395 1303 395 1303 395 8081 1250 477 1228 455 393 1304 1252 478 1227 478 370 1329 369 1329 369 1328 1228 478 370 1329 369 1329 369 8107 1227 478 1227 478 370 1329 1227 479 1227 479 369 1329 370 1329 370 1329 1227 479 369 1330 369 1330 369 8111 1225 479 1227 479 369 1330 1227 479 1228 480 368 1331 368 1331 368 1331 1227 480 368 1332 367 1332 367 8114 1225 480 1227 481 367 1332 1226 506 1201 507 342 1358 317 1383 342 1358 1200 507 317 1384 316 1384 316 8168 1174 532 1175 532 316 1384 1175 533 1175 533 315 1385 315 1385 315 1384 1175 533 315 1386 315 1385 315 8171 1174 534 1174 559 289 1387 1174 559 1149 560 289 1413 288 1412 289 1413 1148 560 289 1413 288 1413 288 8203 1147 561 1148 562 287 1414 1148 562 1147 588 260 1416 286 1441 260 1440 1122 588 260 1442 260 1442 260 8232 1120 589 1120 615 228 1474 1095 616 1094 642 182 1494 226 1476 226 1503 1067 643 181 3224 182 8314 1066 671 1039 2427 986
#
-name: Heat_lo
+name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 2342 612 781 695 805 668 810 666 810 665 811 1402 811 666 811 692 781 670 781 1432 781 696 778 1436 802 1412 802 1412 802 1413 801 1412 802 1412 801 1412 777 1411 776 1463 776 1412 800 1414 801 51041 2257 697 802 1411 777 51240 2283 671 776 1437 801 51209 2255 672 799 1412 801
+data: 3110 1566 525 1084 497 356 471 1085 497 356 472 356 471 1085 497 356 470 357 474 1084 498 356 471 356 471 356 471 356 471 356 496 357 470 357 473 1061 520 357 470 1063 519 357 470 1064 518 1064 518 357 470 357 471
#
-name: Cool_hi
+name: TIMER
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 2317 637 832 644 830 669 805 670 805 672 803 1411 803 673 802 674 802 673 803 1411 803 674 801 1411 802 675 775 1415 800 701 774 1440 801 1412 775 702 799 1414 774 1413 801 701 801 675 800 51681 2257 695 803 1411 801 51226 2283 671 799 1412 803 51246 2257 696 803 1411 775 51255 2282 668 803 1410 802 51243 2258 695 802 1387 798
+data: 3128 1546 549 1032 549 356 471 1033 549 357 470 356 445 1085 496 356 471 357 498 1059 523 1059 522 1059 522 1061 520 356 470 357 470 357 470 357 474 1064 518 1065 517 357 470 357 471 357 470 357 470 1064 517 357 471
#
-name: Cool_lo
+name: TEMP+
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 2315 618 853 643 832 644 834 641 833 643 833 1356 805 695 835 640 808 667 809 1404 808 668 806 1409 803 674 801 1412 802 1388 799 677 799 701 775 701 801 1389 799 677 799 676 800 1439 802 51426 2283 671 800 1412 802 51251 2258 697 801 1387 800 51248 2283 669 802 1411 802 51230 2258 696 799 1387 801 51225 2283 670 801 1411 801 51200 2280 695 775 1411 802 51227 2258 696 802 1411 775 51204 2281 669 801 1411 800
+data: 3107 1568 549 1034 524 356 471 1056 549 357 471 357 471 1031 525 356 471 358 473 1083 498 356 471 1083 498 356 494 357 471 357 469 357 470 358 472 1063 518 357 470 357 470 1064 518 1063 519 1064 517 357 470 357 471
#
-name: Dh
+name: TEMP-
type: raw
frequency: 38000
duty_cycle: 0.330000
-data: 2320 634 837 637 838 637 838 640 835 642 832 1378 836 645 826 670 809 667 808 1406 806 672 803 674 802 1412 802 1412 800 676 801 675 802 1412 802 674 802 1413 801 1412 801 1413 802 1412 802 50937 2285 671 801 1411 802 51225 2280 696 775 1412 801 51212 2283 671 775 1412 802
+data: 3110 1567 551 1031 550 356 471 1032 550 356 471 356 445 1084 497 355 472 357 497 356 472 1058 523 1058 523 356 471 356 470 357 469 357 470 357 474 357 470 1063 519 357 470 1063 518 1063 519 1063 518 357 470 357 471
diff --git a/assets/resources/infrared/assets/audio.ir b/assets/resources/infrared/assets/audio.ir
index f39a8c3b4b..5a0b186588 100644
--- a/assets/resources/infrared/assets/audio.ir
+++ b/assets/resources/infrared/assets/audio.ir
@@ -1,309 +1,176 @@
Filetype: IR library file
Version: 1
-# Last Checked 20th Dec, 2022
-# Model: NoName Unknown Audio remote
-name: Play
+# Last Updated 13th Jan, 2023
+# Last Checked 13th Jan, 2023
+#
+name: POWER
type: parsed
protocol: NEC
-address: 00 00 00 00
-command: 43 00 00 00
-#
-name: Vol_up
+address: 77 00 00 00
+command: F1 00 00 00
+#
+name: MUTE
type: parsed
protocol: NEC
-address: 00 00 00 00
-command: 15 00 00 00
-#
-name: Vol_dn
+address: 77 00 00 00
+command: F3 00 00 00
+#
+name: VOL+
type: parsed
protocol: NEC
-address: 00 00 00 00
-command: 07 00 00 00
-#
-name: Next
+address: 77 00 00 00
+command: FB 00 00 00
+#
+name: VOL-
type: parsed
protocol: NEC
-address: 00 00 00 00
-command: 40 00 00 00
-#
-name: Prev
+address: 77 00 00 00
+command: FC 00 00 00
+#
+name: POWER
type: parsed
protocol: NEC
-address: 00 00 00 00
-command: 44 00 00 00
-#
-# Model: Western Digital Unknown
-name: Power
-type: parsed
-protocol: NECext
-address: 84 79 00 00
-command: 12 ED 00 00
-#
-name: Play
+address: 80 00 00 00
+command: 1A 00 00 00
+#
+name: POWER
type: parsed
protocol: NECext
-address: 84 79 00 00
-command: 0A F5 00 00
-#
-name: Vol_up
+address: 10 E7 00 00
+command: 46 B9 00 00
+#
+name: VOL+
type: parsed
protocol: NECext
-address: 84 79 00 00
-command: 05 FA 00 00
-#
-name: Vol_dn
+address: 10 E7 00 00
+command: 06 F9 00 00
+#
+name: VOL-
type: parsed
protocol: NECext
-address: 84 79 00 00
-command: 00 FF 00 00
-#
-name: Next
+address: 10 E7 00 00
+command: 47 B8 00 00
+#
+name: MUTE
type: parsed
protocol: NECext
-address: 84 79 00 00
-command: 01 FE 00 00
-#
-name: Prev
+address: 10 E7 00 00
+command: 41 BE 00 00
+#
+name: POWER
type: parsed
-protocol: NECext
-address: 84 79 00 00
-command: 02 FD 00 00
-#
-# Model: Yamaha RAV15
-name: Play
+protocol: RC5
+address: 10 00 00 00
+command: 0C 00 00 00
+#
+name: MUTE
type: parsed
-protocol: NEC
-address: 00 00 00 00
-command: 43 00 00 00
-#
-name: Vol_up
+protocol: RC5
+address: 10 00 00 00
+command: 0D 00 00 00
+#
+name: VOL+
type: parsed
-protocol: NEC
-address: 00 00 00 00
-command: 15 00 00 00
-#
-name: Vol_dn
+protocol: RC5
+address: 10 00 00 00
+command: 10 00 00 00
+#
+name: VOL-
type: parsed
-protocol: NEC
-address: 00 00 00 00
-command: 07 00 00 00
-#
-name: Next
+protocol: RC5
+address: 10 00 00 00
+command: 11 00 00 00
+#
+name: POWER
type: parsed
protocol: NEC
address: 00 00 00 00
command: 40 00 00 00
-#
-name: Prev
+#
+name: VOL+
type: parsed
protocol: NEC
address: 00 00 00 00
-command: 44 00 00 00
-#
-# Model: Yamaha RX-V375
-name: Power
-type: parsed
-protocol: NEC
-address: 7E 00 00 00
-command: 2A 00 00 00
-#
-name: Vol_up
-type: parsed
-protocol: NEC
-address: 7A 00 00 00
-command: 1A 00 00 00
-#
-name: Mute
-type: parsed
-protocol: NEC
-address: 7A 00 00 00
-command: 1C 00 00 00
-#
-name: Vol_dn
-type: parsed
-protocol: NEC
-address: 7A 00 00 00
-command: 1B 00 00 00
-#
-# Model: SVEN HT-415
-name: Power
-type: parsed
-protocol: NEC
-address: 41 00 00 00
-command: 42 00 00 00
-#
-name: Vol_up
-type: parsed
-protocol: NEC
-address: 41 00 00 00
-command: 0B 00 00 00
-#
-name: Vol_dn
-type: parsed
-protocol: NEC
-address: 41 00 00 00
-command: 1B 00 00 00
-#
-name: Mute
-type: parsed
-protocol: NEC
-address: 41 00 00 00
-command: 56 00 00 00
-#
-# Model: HUAYU AKB74475490
-name: Power
-type: parsed
-protocol: NEC
-address: 04 00 00 00
-command: 08 00 00 00
-#
-name: Play
-type: parsed
-protocol: NEC
-address: 04 00 00 00
-command: B0 00 00 00
-#
-name: Pause
-type: parsed
-protocol: NEC
-address: 04 00 00 00
-command: BA 00 00 00
-#
-name: Vol_up
-type: parsed
-protocol: NEC
-address: 04 00 00 00
-command: 02 00 00 00
-#
-name: Vol_dn
-type: parsed
-protocol: NEC
-address: 04 00 00 00
-command: 03 00 00 00
-#
-name: Prev
-type: parsed
-protocol: NEC
-address: 04 00 00 00
-command: 8F 00 00 00
-#
-name: Next
+command: 41 00 00 00
+#
+name: VOL-
type: parsed
protocol: NEC
-address: 04 00 00 00
-command: 8E 00 00 00
-#
-name: Mute
+address: 00 00 00 00
+command: 45 00 00 00
+#
+name: MUTE
type: parsed
protocol: NEC
-address: 04 00 00 00
-command: 09 00 00 00
-#
-# Model: Samsung HW-K450 Soundbar
-#
-name: Power
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 4637 4376 612 419 584 420 584 420 583 421 582 1427 531 1477 531 472 532 472 557 1452 556 1451 557 1451 557 1452 556 447 557 448 556 449 555 449 555 4453 554 450 554 450 554 451 553 450 554 451 553 451 553 451 553 450 554 1455 553 1454 554 1454 554 451 553 1454 554 1454 554 1455 553 1454 554 451 553 450 554 450 554 1455 553 55439 4554 4458 555 449 555 449 555 450 554 450 554 1455 553 1454 554 451 553 450 554 1454 554 1454 554 1454 554 1455 553 450 554 451 553 451 553 451 553 4453 554 451 553 451 552 451 553 451 553 451 553 451 553 451 553 451 553 1455 553 1455 553 1455 553 451 553 1455 553 1455 553 1455 553 1455 553 451 553 451 552 451 553 1455 553
-#
-name: Play
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 4636 4380 612 392 612 394 610 394 610 419 583 1399 557 1452 556 473 556 448 556 1428 581 1453 555 1453 555 1453 555 449 555 450 554 451 553 452 552 4457 551 452 552 452 552 452 552 452 552 452 552 1457 551 452 552 1457 551 452 552 452 552 453 551 1457 552 1457 551 452 552 1457 551 452 552 1457 551 1457 551 1457 552 452 552 55450 4551 4461 553 451 553 452 552 452 552 452 552 1456 552 1456 552 452 552 452 552 1456 552 1456 552 1456 552 1456 552 452 552 452 552 453 551 453 551 4456 551 453 551 453 551 453 551 453 551 453 551 1457 551 453 551 1457 552 453 551 454 550 454 550 1457 552 1457 551 454 550 1457 551 454 550 1458 551 1457 551 1458 550 454 550
-#
-name: Vol_up
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 4640 4405 583 420 583 421 582 421 583 422 581 1427 531 1478 530 473 531 472 557 1452 557 1452 556 1452 556 1452 556 448 556 448 556 449 555 450 554 4454 554 451 553 451 553 451 553 451 553 1455 554 1455 553 1455 553 451 553 1455 553 1456 553 1456 553 451 553 451 553 451 553 451 554 1455 554 451 553 452 553 451 553 1456 553 55447 4556 4458 555 449 555 450 554 450 554 450 554 1455 553 1455 553 451 553 451 553 1455 553 1455 553 1455 553 1455 553 451 553 451 553 451 553 451 553 4454 553 451 553 450 554 451 553 450 554 1455 553 1455 553 1455 553 451 553 1455 553 1455 553 1455 553 451 553 451 553 451 553 450 554 1455 553 451 553 451 553 451 553 1455 553
-#
-name: Vol_dn
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 4636 4378 613 393 611 392 612 393 611 393 557 1451 558 1450 610 420 583 421 557 1427 581 1452 556 1452 556 1452 556 448 555 449 555 450 554 450 554 4455 553 451 553 451 553 451 553 451 553 451 553 451 553 452 552 1456 553 1456 552 1456 553 1456 552 451 553 1456 553 1456 552 1456 553 451 553 451 553 452 552 451 553 1456 552 55452 4553 4461 553 450 554 451 553 451 553 451 553 1456 553 1456 552 451 553 451 553 1456 552 1455 553 1455 553 1455 553 451 553 451 553 451 553 451 553 4456 552 451 553 451 553 451 553 451 553 451 553 451 553 451 553 1456 552 1455 553 1455 553 1455 553 451 553 1455 553 1456 552 1456 552 451 553 451 553 451 553 451 553 1456 552
-#
-name: Prev
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 255 113623 4638 4378 613 391 612 392 559 446 558 446 558 1477 531 1477 532 472 532 472 532 1476 532 1476 532 1476 532 1477 531 473 555 449 555 449 555 450 554 4455 554 450 554 450 554 450 554 450 554 1455 554 1455 554 450 554 1455 554 450 555 450 554 450 554 1455 554 451 553 451 553 1455 554 450 554 1455 554 1456 553 1455 554 450 554
-#
-name: Next
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 4557 4430 611 392 610 394 559 445 559 446 558 1451 558 1477 531 448 556 472 532 1476 532 1477 532 1477 531 1477 531 473 556 449 555 449 555 450 554 4454 554 450 554 450 554 450 554 450 555 450 554 450 554 1455 554 1455 554 450 554 450 554 450 554 1455 554 1455 554 1455 553 451 553 450 554 1455 554 1455 554 1455 554 450 554 55458 4555 4459 554 450 554 450 554 450 554 450 554 1455 553 1455 553 450 554 450 554 1455 553 1455 553 1455 553 1455 553 450 554 450 554 450 554 450 554 4454 554 450 554 450 554 450 554 451 553 450 554 450 554 1455 553 1455 553 451 553 450 554 450 554 1455 553 1455 553 1455 553 450 554 451 553 1455 554 1455 553 1455 553 450 554
+address: 00 00 00 00
+command: 48 00 00 00
#
-name: Mute
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 4639 4406 586 418 585 393 559 447 557 447 557 1477 532 1477 532 472 532 472 532 1476 533 1476 532 1476 532 1476 532 473 555 449 555 449 555 449 555 4455 554 450 554 450 554 450 554 450 554 1455 554 450 554 450 554 450 554 1455 554 1455 553 1455 553 450 554 450 554 1455 554 1455 554 1455 554 450 554 450 554 450 554 1455 554 55454 4557 4458 555 449 555 449 555 450 554 450 554 1455 554 1455 553 450 554 450 554 1455 554 1455 554 1454 554 1455 554 450 554 450 554 450 555 450 554 4455 553 450 554 450 554 450 554 450 554 1455 554 450 554 450 554 450 554 1455 554 1455 554 1455 553 450 554 450 554 1455 554 1455 553 1455 554 450 554 450 554 450 554 1455 554
-#
-# Model: Edifier R1850DB
-name: Power
+name: POWER
type: parsed
protocol: NECext
-address: 10 E7 00 00
-command: 46 B9 00 00
-#
-name: Play
+address: 2D D3 00 00
+command: 12 ED 00 00
+#
+name: VOL+
type: parsed
protocol: NECext
-address: 10 E7 00 00
-command: 5E A1 00 00
-#
-name: Vol_up
+address: 2D D3 00 00
+command: 11 EE 00 00
+#
+name: VOL-
type: parsed
protocol: NECext
-address: 10 E7 00 00
-command: 05 FA 00 00
-#
-name: Vol_dn
+address: 2D D3 00 00
+command: 10 EF 00 00
+#
+name: MUTE
type: parsed
protocol: NECext
-address: 10 E7 00 00
-command: 49 B6 00 00
-#
-name: Next
+address: 2D D3 00 00
+command: 13 EC 00 00
+#
+name: POWER
type: parsed
-protocol: NECext
-address: 10 E7 00 00
-command: 02 FD 00 00
-#
-name: Prev
+protocol: SIRC15
+address: 44 00 00 00
+command: 15 00 00 00
+#
+name: VOL+
type: parsed
-protocol: NECext
-address: 10 E7 00 00
-command: 1E E1 00 00
-#
-name: Mute
+protocol: SIRC15
+address: 44 00 00 00
+command: 12 00 00 00
+#
+name: VOL-
type: parsed
-protocol: NECext
-address: 10 E7 00 00
-command: 41 BE 00 00
-#
+protocol: SIRC15
+address: 44 00 00 00
+command: 13 00 00 00
+#
+name: MUTE
+type: parsed
+protocol: SIRC15
+address: 44 00 00 00
+command: 14 00 00 00
+#
name: POWER
type: parsed
protocol: NECext
address: 02 A0 00 00
command: 80 7F 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 02 A0 00 00
command: AA 55 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 02 A0 00 00
command: 6A 95 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
@@ -333,7 +200,7 @@ type: parsed
protocol: NEC
address: 04 00 00 00
command: 06 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
@@ -357,25 +224,25 @@ type: parsed
protocol: NECext
address: 29 A1 00 00
command: 9F 60 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 7A 00 00 00
command: 1F 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 00 00 00 00
command: 1C 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 00 00 00 00
command: 0B 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
@@ -387,49 +254,49 @@ type: parsed
protocol: NEC
address: 00 00 00 00
command: 05 00 00 00
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4617 4406 584 448 557 448 557 449 556 449 555 1430 580 1432 577 452 552 454 550 1460 549 1462 548 1462 549 1462 548 457 548 457 548 457 548 457 548 4463 548 457 548 457 548 457 548 458 548 1462 548 1462 548 1462 548 457 548 1463 547 1462 548 1462 548 458 547 458 548 458 548 458 547 1463 547 458 547 458 547 458 548 1463 547 55451 4606 4440 549 457 548 457 548 457 548 457 548 1462 548 1462 548 457 548 457 548 1462 548 1461 549 1462 548 1462 548 457 548 457 548 457 548 457 548 4462 548 457 548 457 548 457 548 457 548 1462 548 1462 548 1462 548 457 548 1462 548 1462 548 1462 547 457 548 458 547 458 547 458 547 1462 548 458 547 458 547 458 547 1462 548
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4614 4408 583 449 555 450 555 451 553 451 554 1432 577 1434 576 453 551 454 550 1460 549 1461 549 1461 549 1461 549 457 548 457 548 457 548 457 548 4461 548 457 548 457 548 457 548 457 548 457 548 457 548 457 548 1462 548 1461 549 1461 549 1461 548 457 548 1462 549 1461 549 1461 548 457 548 457 548 457 548 458 547 1462 548 55443 4606 4440 549 456 549 456 549 456 549 456 549 1461 549 1461 549 457 548 457 548 1461 549 1461 549 1461 549 1461 549 456 549 457 548 457 548 457 548 4461 549 456 549 457 548 457 548 457 548 457 548 457 548 457 548 1462 548 1461 549 1461 549 1461 548 457 548 1461 549 1461 549 1461 549 457 548 457 548 458 547 457 548 1462 548
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4588 4435 556 477 556 449 555 450 555 451 554 1428 582 1429 581 451 553 452 552 1457 552 1458 551 1461 548 1463 547 458 547 458 547 458 547 458 547 4464 547 458 547 458 547 458 547 458 548 458 547 458 547 458 548 458 547 1463 547 1463 547 1464 546 459 547 1464 546 1464 546 1463 547 1464 546 459 546 459 546 459 546 1464 547 55456 4581 4468 546 458 547 458 547 458 547 458 547 1463 547 1463 547 458 547 459 547 1463 547 1464 546 1464 546 1464 547 459 546 459 546 459 546 459 547 4465 546 459 546 459 546 459 546 459 546 459 547 459 546 459 546 459 546 1464 546 1464 546 1465 546 460 545 1465 545 1465 545 1465 546 1465 546 460 545 460 546 460 545 1466 544
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 3F 5C 00 00
command: 18 E7 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 3F 5C 00 00
command: 55 AA 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 3F 5C 00 00
command: 59 A6 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 3F 5C 00 00
command: 15 EA 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
@@ -453,25 +320,25 @@ type: parsed
protocol: NECext
address: 00 FB 00 00
command: 0A F5 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 80 D9 00 00
command: 8A 75 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 80 D9 00 00
command: 88 77 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 80 D9 00 00
command: 8C 73 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
@@ -495,13 +362,13 @@ type: parsed
protocol: NECext
address: 78 0E 00 00
command: 18 E7 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 20 00 00 00
command: 14 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
@@ -514,1579 +381,1501 @@ type: parsed
protocol: RC5
address: 10 00 00 00
command: 0E 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 10 E7 00 00
command: 0C F3 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 10 E7 00 00
command: 09 F6 00 00
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3309 1906 410 1178 411 1177 412 416 435 445 406 448 414 440 411 1150 439 415 436 1178 411 1177 412 442 409 444 407 1181 408 419 432 1182 407 420 442 1146 433 448 414 440 411 442 409 444 407 446 416 438 413 441 410 443 408 419 432 1182 407 446 405 422 440 414 437 416 435 445 406 1181 408 446 405 448 414 440 411 442 409 418 433 446 416 438 413 1175 414 413 438 1176 413 414 437 443 408 419 432 421 441 413 438 42493 3308 3343 355 43011 3309 3316 382 43009 3310 3314 384 43007 3303 3347 361
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3307 1879 437 1177 412 1176 413 415 436 417 434 446 405 448 414 1174 415 412 439 1149 440 1147 442 438 413 440 411 1177 412 441 410 1178 411 442 409 1179 410 417 434 419 432 448 414 440 411 442 409 444 407 446 416 438 413 441 410 1151 438 415 436 444 407 446 416 412 439 414 437 1177 412 1176 413 414 437 416 435 1152 437 1177 412 416 435 444 407 446 416 1146 433 421 441 1173 406 422 440 413 438 442 409 444 407 40133 3308 3341 357 42862 3301 3347 361 42859 3304 3319 379
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3310 1876 440 1174 415 1173 405 422 440 414 437 443 408 445 406 1182 407 420 442 1173 406 1182 407 420 442 412 439 1175 414 440 411 1150 439 415 436 1152 437 416 435 419 432 447 415 440 411 442 409 418 433 420 442 438 413 440 411 1177 412 415 436 418 433 420 442 438 413 441 410 1151 438 1150 439 415 436 1178 411 1150 439 1149 440 414 437 417 434 445 406 1155 434 420 442 438 413 1175 414 413 438 442 409 444 407 39503 3303 3320 388 42857 3304 3319 379 42867 3305 3317 381
-#
+#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3305 1907 409 1178 411 1177 412 442 409 418 433 447 415 439 412 1176 413 441 410 1177 412 1176 413 441 410 443 408 1180 409 445 406 1181 408 446 416 1172 406 448 413 440 411 442 409 445 406 447 414 439 412 442 409 444 407 447 414 1173 405 449 413 441 410 443 408 446 405 448 413 1174 415 440 411 442 409 1178 411 1177 412 1177 412 442 409 444 407 447 415 439 412 441 410 444 407 1180 409 445 406 448 414 440 411 41125 3303 3347 360 42906 3308 3315 382
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: BA A0 00 00
command: 01 FE 00 00
-#
+#
name: POWER
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3469 1719 450 447 423 1293 447 451 419 452 418 454 416 455 425 446 424 447 423 449 421 450 420 451 419 452 418 454 416 1300 450 447 423 449 421 450 420 451 419 453 417 454 416 455 425 1291 449 449 421 1295 445 452 418 454 416 1300 450 1292 448 1295 445 453 417 454 426 445 425 1291 449 449 421 1295 445 1297 453 1289 451 1292 448 450 420 452 418 1298 452 445 425 446 424 448 422 449 420 450 420 452 418 1298 452 74868 3471 1717 453 445 425 1291 449 449 421 451 419 452 418 453 417 455 425 446 424 447 423 448 422 449 421 451 419 452 418 1298 452 445 425 447 423 448 422 449 421 451 419 452 418 454 416 1300 450 447 423 1293 447 451 419 453 417 1299 451 1291 449 1293 447 451 419 453 417 454 426 1290 450 447 423 1293 447 1296 444 1299 451 1291 449 449 421 450 420 1296 444 454 426 445 425 446 424 448 422 449 421 450 420 1296 444 74877 3472 1716 443 455 425 1291 449 448 422 450 420 451 419 453 417 454 426 445 425 446 424 447 423 449 421 450 420 451 419 1298 452 445 425 446 424 448 422 449 421 450 420 452 418 453 417 1299 451 447 423 1293 447 451 419 452 418 1298 452 1290 450 1293 447 451 419 452 418 454 416 1300 450 447 423 1293 447 1296 444 1299 451 1291 449 449 421 450 420 1296 444 454 426 445 425 446 424 447 423 449 421 450 420 1296 444
-#
+type: parsed
+protocol: Kaseikyo
+address: AC 02 20 00
+command: D1 03 00 00
+#
name: VOL+
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3472 1743 416 455 425 1317 422 449 420 451 418 453 416 454 426 445 424 447 422 448 421 450 419 452 417 453 416 455 425 1317 422 449 420 450 419 452 417 454 415 455 425 446 423 448 421 1320 419 452 417 1325 425 447 422 448 421 450 419 452 417 453 416 455 425 446 423 448 421 449 420 451 418 452 417 454 415 456 424 1317 422 449 420 451 418 453 416 455 425 446 423 447 422 449 420 450 419 452 417 1324 426 74911 3469 1746 423 448 421 1321 418 453 416 455 425 446 423 447 422 449 420 450 419 452 417 454 415 455 425 446 423 448 421 1320 419 452 417 454 426 445 424 447 422 448 421 450 419 452 417 1324 426 446 423 1291 448 450 419 452 417 454 415 455 425 446 423 448 421 450 419 451 418 453 416 454 426 446 423 447 422 449 420 1294 445 453 416 455 425 446 423 448 421 449 420 451 418 453 416 454 426 445 424 1290 449
-#
+type: parsed
+protocol: Kaseikyo
+address: A0 02 20 00
+command: 00 02 00 00
+#
name: VOL-
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3473 1742 417 454 426 1317 422 448 421 450 419 452 417 453 416 455 425 446 423 447 422 449 420 451 418 452 417 454 415 1326 424 448 421 449 420 451 418 453 416 454 426 445 425 447 422 1320 419 452 417 1324 426 446 423 447 422 449 420 450 419 452 417 454 415 455 425 446 423 1319 420 451 418 453 416 454 426 445 424 1318 421 450 419 452 417 1324 426 446 423 447 422 449 420 451 418 452 417 454 415 1326 424 74913 3467 1748 421 450 419 1323 416 455 425 446 423 447 422 449 420 451 418 452 417 454 415 455 425 446 423 448 421 449 420 1322 417 454 426 445 424 447 422 448 421 450 419 452 417 453 416 1326 424 447 422 1320 419 452 417 454 415 455 425 446 423 448 421 450 419 451 418 453 416 1325 425 447 422 448 421 450 419 452 417 1324 426 446 423 447 422 1320 419 452 417 454 415 455 425 446 423 448 421 450 419 1322 417
-#
+type: parsed
+protocol: Kaseikyo
+address: A0 02 20 00
+command: 10 02 00 00
+#
name: MUTE
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3473 1716 453 445 425 1291 448 422 447 424 446 453 416 427 453 446 423 420 449 449 420 423 446 425 444 454 426 418 451 1291 448 423 446 452 417 454 415 428 452 446 423 421 448 422 447 1296 443 455 425 1290 449 449 420 423 446 425 444 427 453 445 424 420 449 449 420 423 446 425 444 1298 452 419 450 448 421 1294 445 1298 452 446 423 448 421 449 420 1296 443 427 453 445 424 1292 447 423 446 452 417 1299 451 74922 3472 1717 452 446 423 1292 447 451 418 452 417 454 426 445 424 447 423 449 420 450 419 452 417 454 415 455 425 446 424 1293 446 451 418 453 416 455 425 446 423 447 422 449 420 451 418 1297 453 445 424 1292 447 450 419 452 417 454 415 455 425 446 423 448 421 450 419 451 418 453 416 1300 450 448 421 449 420 1296 443 1299 451 447 422 449 420 450 419 1297 442 455 425 447 422 1293 446 451 418 453 416 1300 450
-#
+type: parsed
+protocol: Kaseikyo
+address: A0 02 20 00
+command: 20 03 00 00
+#
name: POWER
type: parsed
protocol: NEC
address: 01 00 00 00
command: 02 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 01 00 00 00
command: 01 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 01 00 00 00
command: 0B 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 01 00 00 00
command: 06 00 00 00
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 9150 4435 643 1608 643 468 644 469 642 364 749 468 643 447 665 449 663 469 643 452 660 470 642 450 662 442 670 449 662 469 643 1579 672 1608 642 1580 671 1609 641 1607 643 1578 672 1607 643 1608 642 1606 644 1606 644 1606 644 1607 643 1576 675 1579 671 1605 674 438 645 466 673 438 646 466 674 437 673 439 672 439 673 438 646 1604 673 1577 673 1578 673 1577 674 1577 673 23799 9095 4485 616
-#
+#
name: VOL+
type: parsed
protocol: NEC42
address: 01 00 00 00
command: 0C 00 00 00
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 9151 4434 644 1608 643 376 737 379 733 446 666 449 663 468 644 469 643 468 644 468 644 468 644 447 665 448 664 468 644 450 662 1608 643 1607 644 1576 676 1607 644 1608 643 1578 674 1608 643 1577 674 1579 672 1607 643 1608 643 1607 644 1607 644 1608 643 448 664 1608 643 448 664 468 644 469 643 380 732 468 644 469 643 1607 644 468 644 1608 643 1608 644 1609 643 1608 643 23837 9152 4434 642
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 8968 4344 670 460 670 460 670 1566 669 462 668 486 643 487 642 489 641 1595 640 490 640 491 640 1596 640 491 640 1596 640 1596 640 1596 640 491 640 1596 640 1596 640 1596 640 1596 640 1596 640 1596 640 1596 640 1622 640 491 640 491 640 491 640 491 640 491 640 491 640 491 640 491 639
-#
+#
name: POWER
type: parsed
protocol: SIRC
address: 10 00 00 00
command: 2E 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 00 FD 00 00
command: 01 FE 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 00 FD 00 00
command: 03 FC 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 00 FD 00 00
command: 09 F6 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 00 FD 00 00
command: 07 F8 00 00
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1042 1461 540 1460 541 1460 541 1460 541 1459 542 1459 542 454 536 460 540 456 544 452 538 458 542 454 546 450 540 456 544 1457 544 1456 545 1448 542 50531 1041 1462 539 1462 539 1461 540 1461 540 1460 541 1460 541 455 545 451 539 457 543 480 510 459 541 481 519 451 539 457 543 1457 543 1457 544 1449 541 50515 1037 1467 544 1456 545 1456 545 1455 546 1455 535 1465 536 486 514 483 517 479 511 485 515 481 509 487 513 483 517 478 512 1462 539 1462 539 1454 536 50537 1035 1467 544 1457 544 1457 544 1456 545 1456 544 1456 545 477 513 483 517 479 511 486 514 481 519 477 513 484 516 479 511 1464 536 1463 538 1455 546
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1010 1491 509 1490 510 1488 512 487 513 487 513 1486 514 1485 515 484 516 1483 517 482 518 482 518 1481 509 1489 511 488 512 487 513 1486 514 484 516 50963 1011 1489 511 1488 512 1487 513 485 515 486 514 1485 515 1484 516 484 516 1483 517 482 518 482 518 1481 509 1489 511 489 511 489 511 1487 513 486 514 50986 1008 1492 518 1480 510 1488 512 487 513 487 513 1486 514 1484 516 484 516 1483 517 482 518 481 519 1480 510 1488 512 487 513 487 513 1486 514 484 516 50972 1012 1488 512 1486 514 1484 516 483 517 483 517 1482 518 1480 510 489 511 1487 513 486 514 486 514 1485 515 1483 517 483 517 483 517 1481 509 490 510 50976 1008 1491 509 1489 511 1487 513 485 515 485 515 1484 516 1481 509 491 509 1489 511 488 512 488 512 1487 513 1485 515 484 516 484 516 1483 517 481 509
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1011 1479 517 477 516 481 512 1480 516 1473 513 482 511 485 518 1473 513 482 511 1481 515 1474 512 482 511 485 518 1473 513 1477 509 486 517 1473 513 50728 1014 1475 511 484 509 487 516 1475 511 1479 517 477 516 480 513 1478 508 487 516 1475 511 1479 517 478 514 480 513 1479 517 1473 513 508 484 1479 517 50725 1016 1473 513 481 512 484 519 1473 513 1477 509 485 518 478 515 1476 510 485 518 1473 513 1477 509 486 517 478 515 1476 510 1480 516 479 514 1476 510 50735 1069 1421 513 481 512 484 509 1483 513 1477 509 486 517 479 514 1477 509 486 517 1474 512 1479 507 488 515 480 513 1479 507 1483 513 482 511 1479 517 50733 1011 1478 508 513 490 506 486 1478 508 1483 513 508 485 511 482 1482 514 508 485 1480 516 1473 513 508 485 511 482 1483 513 1477 509 512 491 1473 513 50735 1008 1480 516 479 514 508 485 1480 516 1474 512 509 484 486 517 1472 514 508 485 1480 516 1474 512 509 484 512 481 1482 514 1477 509 512 491 1472 514 50738 1006 1509 487 508 485 486 507 1509 487 1503 483 513 490 505 488 1502 484 512 491 1473 513 1503 483 512 491 505 488 1476 510 1507 489 506 487 1503 483
-#
+#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1010 1479 517 1474 512 509 484 512 491 505 488 507 486 510 483 512 491 505 488 508 485 1505 491 1474 512 1478 508 1483 513 1477 509 1482 514 1475 511 50713 1005 1483 513 1475 511 511 482 513 490 505 488 507 486 483 510 511 482 487 516 505 488 1501 485 1478 508 1483 513 1476 510 1479 507 1483 513 1474 512 50707 1012 1501 485 1479 506 513 490 505 488 507 486 509 484 511 482 487 516 505 488 508 485 1504 482 1482 514 1476 592 1396 590 1400 513 1476 510 1478 508 50715 1015 1473 513 1476 510 484 508 513 490 504 489 480 513 508 485 483 510 511 482 488 515 1473 513 1477 509 1480 516 1474 512 1477 591 1397 516 1472 514
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1041 1462 538 1462 538 485 515 481 519 478 512 484 516 1458 542 1458 542 1459 541 481 519 1481 519 1455 545 1482 518 1456 544 479 511 486 514 474 516 50532 1039 1464 536 1490 510 487 513 483 517 480 510 486 514 1460 540 1486 514 1460 540 483 517 1457 543 1484 516 1458 542 1458 542 481 519 477 513 476 513 50534 1036 1467 543 1457 543 480 509 460 540 483 517 479 511 1463 537 1463 537 1464 536 486 514 1487 513 1461 539 1461 539 1462 538 484 516 481 519 469 510
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1042 1461 539 457 543 1458 542 1458 542 1458 542 1458 542 454 536 461 539 457 543 1457 543 453 537 460 540 456 544 452 538 1463 537 1463 537 1456 544 50530 1065 1438 572 424 566 1434 566 1435 565 1435 565 1436 544 452 537 459 572 424 545 1456 544 451 539 458 542 454 536 460 540 1461 539 1461 539 1454 536 50538 1036 1467 543 452 537 1464 536 1464 536 1464 536 1465 545 450 540 456 544 452 537 1464 536 460 540 455 545 452 538 458 542 1459 541 1460 540 1452 538
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1044 1456 544 455 545 455 534 1464 536 1462 538 1460 540 1458 542 1456 544 1455 545 1453 537 1461 539 460 540 459 541 459 561 437 542 457 543 456 544 50915 1016 1483 517 482 518 482 518 1481 509 1489 511 1487 513 1486 514 1485 515 1483 517 1482 508 1490 510 489 511 488 512 487 513 487 513 486 514 485 515 50956 1047 1452 538 462 538 462 538 1461 539 1460 540 1458 542 1457 543 1456 544 1454 546 1453 547 1451 539 461 539 460 540 460 540 459 541 459 541 457 543
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1017 1484 516 1482 518 481 519 1480 510 1489 511 1487 513 1486 514 1485 515 1483 517 482 518 1480 510 490 510 489 511 489 511 488 512 488 512 486 514 50956 1015 1486 514 1484 516 484 516 1483 517 1482 518 1480 510 1489 511 1488 512 1486 514 486 514 1485 515 484 516 484 516 483 517 483 517 482 518 481 509 50960 1011 1488 512 1486 514 486 514 1485 515 1483 517 1482 518 1480 510 1488 512 1486 514 486 514 1484 516 483 517 483 517 482 518 481 519 481 508 489 511 50961 1040 1461 539 1459 541 459 541 1458 542 1456 544 1455 545 1454 546 1452 538 1460 540 460 540 1458 542 457 543 456 544 456 544 455 545 455 545 453 547
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1006 1485 511 1479 517 1473 513 509 484 511 482 514 489 506 487 508 485 511 482 513 490 505 488 1477 509 1481 515 1475 511 1480 516 1474 512 1477 509 50734 1007 1483 513 1477 509 1482 514 507 486 509 484 511 492 503 490 506 487 508 485 510 483 513 490 1474 512 1479 517 1473 513 1477 509 1481 515 1474 512 50729 1012 1477 509 1481 515 1474 512 509 484 512 491 504 489 506 487 508 485 511 482 513 490 506 487 1477 509 1481 515 1475 511 1479 517 1473 513 1476 510
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1012 1503 483 514 489 1475 511 483 510 486 517 478 515 481 512 483 510 486 517 1473 513 508 485 1480 516 1475 511 1479 507 1483 513 1477 509 1480 588 50646 1012 1476 510 512 491 1473 513 508 485 485 508 488 515 480 513 482 511 512 481 1482 514 482 511 1480 516 1473 513 1478 508 1482 514 1476 510 1479 590 50651 1007 1507 489 507 485 1478 508 514 489 506 487 509 484 485 508 488 515 506 487 1503 483 513 490 1474 512 1478 508 1483 513 1477 509 1481 515 1473 513 50721 1009 1505 491 478 515 1475 511 510 483 486 517 478 515 507 486 483 510 512 491 1472 514 508 485 1505 491 1473 513 1477 509 1481 587 1403 510 1478 508 50733 1008 1506 490 479 514 1477 509 512 481 514 489 506 487 508 485 484 509 513 490 1473 513 509 483 1481 515 1474 512 1479 507 1482 514 1476 510 1478 590 50642 1006 1508 488 508 485 1478 508 487 516 479 514 481 512 510 483 486 517 504 489 1474 512 510 483 1482 514 1475 511 1479 507 1483 513 1477 509 1480 516
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 20 00 00 00
command: 09 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 20 00 00 00
command: 1F 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 20 00 00 00
command: 0E 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 20 00 00 00
command: 1A 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 20 00 00 00
command: 02 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 20 00 00 00
command: 05 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 20 00 00 00
command: 0C 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 20 00 00 00
command: 08 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 00 00 00 00
command: 12 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 00 00 00 00
command: 1E 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 00 00 00 00
command: 03 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 00 00 00 00
command: 01 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 00 00 00 00
command: 1F 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 00 00 00 00
command: 09 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 10 E7 00 00
command: 01 FE 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 10 E7 00 00
command: 00 FF 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 10 E7 00 00
command: 2B D4 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 78 0E 00 00
command: 09 F6 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 78 0E 00 00
command: 01 FE 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 78 0E 00 00
command: 02 FD 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 00 00 00 00
command: 06 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 02 00 00 00
command: 0A 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 02 00 00 00
command: 0D 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 02 00 00 00
command: 1C 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 02 00 00 00
command: 07 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 00 00 00 00
command: 14 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 00 00 00 00
command: 08 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 86 FF 00 00
command: 14 EB 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 86 FF 00 00
command: 13 EC 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 86 FF 00 00
command: 1B E4 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 86 FF 00 00
command: 2A D5 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 00 00 00 00
command: 07 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 00 00 00 00
command: 00 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 40 AF 00 00
command: 19 E6 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 02 BD 00 00
command: 26 D9 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 02 BD 00 00
command: 28 D7 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 02 BD 00 00
command: 53 AC 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 02 BD 00 00
command: AD 52 00 00
-#
+#
name: POWER
type: parsed
protocol: SIRC
address: 10 00 00 00
command: 2F 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: SIRC
address: 10 00 00 00
command: 12 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: SIRC
address: 10 00 00 00
command: 13 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 85 23 00 00
command: 99 66 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 85 23 00 00
command: 97 68 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 85 23 00 00
command: 57 A8 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 85 23 00 00
command: 47 B8 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 08 00 00 00
command: 10 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 08 00 00 00
command: 16 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 86 FF 00 00
command: 21 DE 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 86 FF 00 00
command: 2B D4 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: BA 4B 00 00
command: 03 FC 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: BA 4B 00 00
command: 02 FD 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: BA A0 00 00
command: 03 FC 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: BA A0 00 00
command: 02 FD 00 00
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1014 1477 517 478 514 509 483 487 515 480 512 484 508 488 514 1479 515 1476 508 1483 511 1481 513 1478 516 1475 509 1482 512 1479 515 480 512 483 509 50775 1014 1477 517 504 488 508 484 513 489 506 486 510 482 514 488 1478 516 1475 509 1483 511 1480 514 1477 517 1474 510 1482 512 1478 516 505 487 509 483 50770 1009 1481 513 508 484 512 490 506 486 510 482 514 488 508 484 1481 513 1478 516 1475 509 1483 511 1480 514 1477 517 1475 509 1482 512 509 483 513 489
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1010 1508 486 509 483 513 489 507 485 512 490 505 487 510 482 1509 485 511 491 1501 483 1509 485 1507 487 1504 490 1502 482 1509 485 511 491 1500 484 50779 1010 1506 488 508 484 512 490 505 487 509 483 513 489 506 486 1506 488 507 485 1506 488 1503 481 1510 484 1508 486 1505 489 1503 481 514 488 1503 491
-#
+#
name: POWER
type: parsed
protocol: NECext
address: BA A0 00 00
command: 4C B3 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: BA A0 00 00
command: 01 FD 00 00
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1004 1513 481 515 487 1478 516 505 487 510 482 1484 510 1481 513 508 484 512 490 1475 509 513 489 1477 507 1484 510 511 481 515 487 1479 515 1474 510 50774 1005 1484 510 513 489 1476 508 513 489 508 484 1482 512 1479 515 506 486 511 481 1483 511 512 490 1475 509 1483 511 510 482 515 487 1504 490 1475 509 50777 1013 1503 491 506 486 1505 489 507 485 512 490 1501 483 1508 486 510 482 514 488 1503 481 515 487 1504 490 1500 484 512 490 506 486 1506 488 1502 482
-#
+#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1014 1477 507 514 488 508 484 512 490 505 487 509 483 513 489 507 485 1480 514 1477 517 1475 509 1483 511 1480 514 1477 517 1475 509 1482 512 508 484 50774 1004 1486 508 513 489 507 485 511 491 504 488 508 484 513 489 505 487 1479 515 1476 508 1484 510 1481 513 1478 516 1475 509 1482 512 1480 514 507 485 50771 1007 1507 487 509 483 513 489 507 485 511 481 515 487 508 484 513 489 1502 482 1483 511 1481 513 1479 515 1476 508 1484 510 1481 513 1478 516 506 486
-#
+#
name: POWER
type: parsed
protocol: NECext
address: BA 4B 00 00
command: 4C B3 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: BA 4B 00 00
command: 01 FE 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 83 22 00 00
command: 0A F5 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 83 22 00 00
command: 01 FE 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 35 00 00 00
command: 45 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 35 00 00 00
command: 1B 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 35 00 00 00
command: 09 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 35 00 00 00
command: 51 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 83 22 00 00
command: 08 F7 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 0A 1D 00 00
command: 08 F7 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 0A 1D 00 00
command: 0A F5 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 0A 1D 00 00
command: 03 FC 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 0A 1D 00 00
command: 01 FE 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 20 00 00 00
command: 06 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 20 00 00 00
command: 07 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 20 00 00 00
command: 1E 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 80 00 00 00
command: 01 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 80 00 00 00
command: 03 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 80 00 00 00
command: 06 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: Samsung32
address: 2C 00 00 00
command: 17 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: Samsung32
address: 2C 00 00 00
command: 16 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 83 22 00 00
command: 16 E9 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 83 22 00 00
command: 0F F0 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 83 22 00 00
command: 0C F3 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 83 22 00 00
command: 15 EA 00 00
-#
-name: VOL+
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3492 1750 416 454 425 1313 424 446 422 447 421 448 420 450 418 451 417 452 416 453 415 455 424 445 423 446 422 447 421 1290 447 450 418 451 417 452 416 453 415 455 424 445 423 447 421 1290 447 422 446 1319 418 452 416 426 442 454 425 445 423 446 422 447 421 421 447 449 419 450 418 451 417 452 416 453 415 454 425 1314 423 446 422 447 421 448 420 449 419 450 418 451 417 452 416 454 425 444 424 1315 422 74926 3488 1754 422 447 421 1317 420 422 446 451 417 452 416 453 415 454 425 444 424 445 423 446 422 447 421 448 420 449 419 1292 445 452 416 453 415 454 425 445 423 446 422 447 421 448 420 1318 419 450 418 1293 444 453 415 454 425 445 423 446 422 447 421 448 420 449 419 450 418 451 417 452 416 453 415 455 424 445 423 1315 422 448 420 449 419 450 418 424 444 452 416 453 415 454 425 445 423 446 422 1289 448
-#
-name: VOL-
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3486 1756 420 449 419 1291 446 424 444 452 416 453 415 454 425 444 424 445 423 446 422 446 422 447 421 448 420 449 419 1319 418 452 416 453 415 426 453 444 424 445 423 446 422 447 421 1290 447 422 446 1319 418 451 417 452 416 454 425 444 424 445 423 446 422 447 421 420 448 1317 420 449 419 450 418 452 416 453 415 1322 425 417 451 445 423 1315 422 447 421 448 420 449 419 450 418 451 417 452 416 1322 415 74922 3492 1722 444 452 416 1321 416 426 453 444 424 445 423 446 422 447 421 447 421 448 420 449 419 450 418 451 417 452 416 1294 443 453 415 454 425 445 423 445 423 446 422 447 421 448 420 1317 420 450 418 1319 418 451 417 425 443 453 415 454 425 444 424 418 450 446 422 447 421 1317 420 449 419 450 418 451 417 452 416 1322 425 444 424 445 423 1315 422 420 448 448 420 448 420 422 446 450 418 451 417 1321 416
-#
+#
name: POWER
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3491 1751 415 454 425 1314 423 446 422 448 420 449 419 450 418 451 417 452 416 453 415 454 425 445 423 446 422 447 421 1317 420 449 419 451 417 452 416 453 415 454 425 444 424 445 423 1316 421 448 420 1318 419 451 417 452 416 453 415 454 425 445 423 446 422 447 421 448 420 1318 419 451 417 1321 416 1322 425 1313 424 1314 423 419 449 447 421 1290 447 450 418 1320 417 1321 416 1322 425 444 424 445 423 1288 449 74914 3491 1751 415 427 452 1314 423 446 422 447 421 448 420 449 419 450 418 451 417 452 416 453 415 454 425 445 423 446 422 1316 421 449 419 450 418 451 417 452 416 453 415 454 425 445 423 1315 422 448 420 1318 419 451 417 452 416 453 415 454 425 445 423 446 422 447 421 448 420 1318 419 451 417 1321 416 1322 415 1295 452 1286 451 446 422 447 421 1317 420 450 418 1320 417 1321 416 1295 442 454 425 445 423 1315 422 74905 3491 1752 424 445 423 1315 422 447 421 448 420 422 446 451 417 452 416 453 415 454 425 445 423 446 422 447 421 448 420 1318 419 451 417 452 416 453 415 454 425 445 423 446 422 447 421 1317 420 450 418 1293 444 452 416 454 425 444 424 446 422 447 421 448 420 449 419 450 418 1320 417 453 415 1323 424 1314 423 1315 422 1288 449 448 420 450 418 1293 444 453 415 1323 424 1313 424 1314 423 447 421 448 420 1318 419
-#
-name: MUTE
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3486 1728 448 448 420 1318 419 423 445 451 417 452 416 454 425 444 424 445 423 446 422 447 421 448 420 421 447 449 419 1319 418 451 417 453 415 453 426 444 424 445 423 446 422 447 421 1317 420 449 419 1319 418 451 417 452 416 453 415 454 425 445 423 446 422 447 421 447 421 421 447 1291 446 423 445 425 443 1322 415 1322 425 444 424 445 423 446 422 1289 448 448 420 422 446 1292 445 451 417 452 416 1322 415 74924 3486 1755 421 447 421 1317 420 449 419 450 418 451 417 452 416 453 415 454 425 417 451 445 423 446 422 420 448 448 420 1317 420 450 418 451 417 452 416 426 442 427 452 444 424 445 423 1315 422 447 421 1317 420 449 419 450 418 451 417 425 443 453 415 454 425 444 424 418 450 446 422 1315 422 448 420 421 447 1291 446 1319 418 451 417 452 416 454 414 1323 424 445 423 419 449 1316 421 422 446 450 418 1293 444 74912 3487 1755 421 448 420 1290 447 423 445 451 417 452 416 453 415 454 425 445 423 446 422 446 422 447 421 421 447 449 419 1319 418 452 416 426 442 454 425 444 424 445 423 446 422 447 421 1290 447 449 419 1319 418 452 416 452 416 453 415 427 451 445 423 446 422 447 421 448 420 449 419 1319 418 424 444 452 416 1322 415 1323 424 444 424 445 423 446 422 1317 420 449 419 423 445 1320 417 453 415 427 452 1313 424
-#
+type: parsed
+protocol: Kaseikyo
+address: A0 02 20 00
+command: D0 03 00 00
+#
name: POWER
type: parsed
protocol: NECext
address: C8 91 00 00
command: 00 FF 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: C8 91 00 00
command: 20 DF 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: C8 91 00 00
command: 1E E1 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: C8 91 00 00
command: 1F E0 00 00
-#
+#
name: VOL+
type: parsed
protocol: RC6
address: 10 00 00 00
command: 10 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: RC6
address: 10 00 00 00
command: 11 00 00 00
-#
+#
name: POWER
type: parsed
protocol: RC6
address: 10 00 00 00
command: 0C 00 00 00
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4559 4461 546 490 515 495 521 490 515 495 489 1484 516 1482 550 486 519 491 493 1480 520 1478 522 1477 523 1475 546 490 515 495 521 490 515 495 489 4493 545 491 525 486 519 491 514 496 488 1484 516 1483 517 1481 551 486 488 1485 515 1483 517 1482 550 486 519 491 525 486 519 491 493 1479 542 494 522 489 516 467 517 1482 550
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4550 4469 548 462 543 467 549 461 544 466 518 1481 520 1479 542 468 548 462 522 1477 523 1476 514 1485 515 1483 549 461 544 466 550 461 544 466 518 4491 547 463 542 468 548 462 543 467 549 462 543 467 549 461 523 1476 514 1485 515 1484 516 1482 550 461 513 1486 514 1485 515 1483 549 461 544 466 550 461 544 493 491 1481 540
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4496 4442 513 503 488 502 489 501 490 500 491 1505 487 1508 484 505 486 504 487 1508 484 1511 492 1503 489 1499 514 484 486 504 487 502 489 501 490 4449 517 499 492 499 492 497 483 507 484 1511 492 1504 488 1499 514 483 487 1509 483 1512 491 1504 488 503 488 501 490 500 491 499 492 1504 488 501 490 500 491 492 509 1494 488 55126 4496 4446 541 482 488 502 489 501 490 500 491 1505 487 1508 484 505 486 504 487 1508 484 1503 510 1493 489 1480 512 504 487 503 488 502 489 500 491 4449 517 498 493 497 483 507 484 505 486 1502 511 1492 490 1504 488 502 489 1507 485 1509 483 1512 491 473 518 498 493 496 484 505 486 1510 483 499 512 484 486 504 487 1508 484
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4492 4434 510 505 486 505 486 504 487 503 488 1481 511 1484 518 499 492 498 493 1476 516 1479 513 1483 519 1469 596 402 516 500 491 499 492 498 493 4447 518 498 493 497 483 507 484 506 485 504 487 503 488 494 517 1485 486 1483 519 1476 516 1480 512 504 486 1508 484 1486 517 1479 565 425 513 502 488 501 490 492 509 1467 515
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4500 4436 516 504 486 510 490 505 485 510 490 1500 491 1474 517 505 485 484 516 1501 490 1501 490 1501 490 1501 490 505 485 511 489 506 484 485 515 4449 513 482 508 513 487 508 482 514 486 1504 487 1504 487 1504 487 482 508 1509 482 1509 492 1499 492 504 486 509 491 504 486 509 491 1500 491 504 486 510 490 478 512 1505 486 55017 4492 4444 508 512 488 508 482 513 487 508 482 1508 483 1482 509 513 487 508 482 1509 482 1509 482 1483 508 1483 508 513 487 508 482 514 486 509 481 4457 515 506 484 511 489 506 484 511 489 1501 490 1475 516 1501 490 506 484 1480 511 1507 484 1480 511 511 489 506 484 512 488 507 483 1507 484 512 488 507 483 512 488 1503 488
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4493 4443 509 512 488 507 483 512 488 507 483 1482 509 1482 509 512 488 507 483 1482 509 1482 509 1482 509 1482 509 512 488 507 483 513 487 508 482 4457 516 505 485 510 490 505 485 510 490 505 485 511 489 505 485 1480 511 1480 511 1480 511 1481 510 484 516 1476 515 1476 515 1476 515 481 509 486 514 481 509 486 514 1476 515 55014 4498 4438 514 482 508 487 513 482 508 488 512 1477 514 1477 514 482 508 487 513 1477 514 1477 514 1477 514 1477 514 482 518 477 513 482 518 477 513 4451 511 485 515 479 511 485 515 480 510 485 515 480 510 485 515 1475 516 1475 516 1476 515 1476 515 480 510 1481 510 1481 510 1481 510 486 514 481 509 486 514 481 509 1482 509
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4524 4473 512 516 491 511 486 516 491 511 496 1482 522 1482 522 506 491 512 495 1483 521 1483 521 1483 521 1483 521 506 491 512 495 507 490 512 495 4475 521 507 490 513 494 508 489 513 494 1484 520 1484 520 1483 521 507 490 1488 516 1488 516 1488 516 511 496 506 491 511 496 506 491 1488 516 511 496 506 491 512 495 1483 521 55356 4533 4463 512 516 491 511 486 516 491 511 496 1507 487 1492 512 515 492 510 487 1492 512 1492 512 1491 513 1491 513 515 492 510 487 515 492 510 487 4484 512 516 491 511 496 506 491 512 495 1483 521 1482 522 1482 522 506 491 1488 516 1487 517 1487 517 511 496 506 491 512 495 506 491 1488 516 512 495 507 490 512 495 1483 521
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4533 4464 521 507 490 512 495 507 490 513 494 1484 520 1484 520 508 489 513 494 1484 520 1484 520 1483 521 1483 521 506 491 511 496 506 491 512 495 4475 521 507 490 512 495 507 490 513 494 508 489 513 494 508 489 1490 514 1490 514 1490 514 1490 514 514 493 1485 519 1485 519 1485 519 509 488 515 492 510 487 516 491 1487 517 55369 4531 4465 520 508 489 514 493 509 488 515 492 1486 518 1486 518 509 488 514 493 1486 518 1485 519 1485 519 1485 519 509 488 514 493 509 488 515 492 4478 518 511 486 516 491 511 496 506 491 512 495 507 490 512 495 1483 521 1483 521 1483 521 1483 521 507 490 1488 516 1488 516 1488 516 512 495 507 490 513 494 508 489 1490 514
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4530 4465 521 507 490 513 494 507 490 513 494 1509 496 1483 521 506 491 512 495 1508 486 1492 512 1492 513 1491 513 514 493 509 488 514 493 509 488 4483 513 514 493 509 488 515 492 510 487 515 492 510 487 515 492 510 487 1517 488 1491 513 1490 515 513 494 1510 494 1484 520 1483 521 1483 521 506 491 512 495 506 491 1487 517 55357 4528 4468 518 510 487 515 492 510 487 515 492 1512 493 1485 519 509 488 514 493 1510 494 1483 522 1483 521 1482 512 516 491 511 486 516 491 511 486 4484 512 516 491 511 486 516 491 511 486 516 491 511 486 516 491 511 496 1507 487 1491 513 1491 514 514 493 1510 495 1484 521 1483 522 1483 522 506 491 511 486 516 491 1513 491
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4495 4440 512 509 491 504 486 509 491 504 486 1478 513 1479 512 509 491 504 486 1478 513 1479 512 1479 512 1479 512 509 491 504 486 509 491 504 486 4452 511 511 489 506 484 511 489 506 484 511 489 506 484 511 489 506 484 1480 511 1480 511 1480 511 510 491 1500 491 1475 516 1475 516 1475 516 504 486 510 490 505 485 1479 512 55017 4497 4439 513 507 483 513 487 507 483 513 487 1476 515 1477 514 507 483 513 487 1476 515 1476 515 1477 514 1477 514 481 509 512 488 507 483 512 488 4451 512 509 491 504 486 509 491 504 486 483 517 504 486 509 492 504 486 1504 487 1504 487 1478 513 508 482 1509 482 1509 482 1509 482 1483 508 513 487 508 482 513 487 1504 487
-#
+#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4501 4435 517 504 486 510 490 505 485 510 490 1475 516 1475 516 506 484 511 489 1476 515 1476 515 1476 515 1477 514 507 483 512 488 507 483 513 487 4451 511 510 490 479 511 484 516 506 484 1481 510 511 489 506 484 511 489 1476 515 1476 515 1477 514 507 483 512 488 1477 514 1477 514 1478 513 508 482 513 487 508 482 1484 517 55011 4496 4440 512 509 491 478 512 483 517 504 486 1480 511 1480 511 484 516 505 485 1480 511 1480 511 1481 510 1481 510 484 516 506 484 511 489 506 484 4455 517 504 486 509 491 504 486 483 517 1474 517 505 485 510 490 505 485 1480 511 1480 511 1481 510 511 489 480 510 1481 510 1481 510 1482 509 485 515 507 483 512 488 1477 514
-#
+#
name: POWER
type: parsed
protocol: Samsung32
address: 2C 00 00 00
command: 1E 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: Samsung32
address: 2C 00 00 00
command: 1F 00 00 00
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4504 4432 511 509 492 504 486 509 492 504 486 1478 514 1477 515 507 484 512 489 1476 516 1475 517 1475 517 1474 518 503 487 509 492 503 487 508 493 4446 508 513 488 507 483 512 489 507 483 512 489 506 484 511 490 506 484 1481 511 1480 512 1479 513 509 492 1473 519 1473 519 1472 509 1482 510 511 490 506 484 511 490 1475 517 54985 4498 4437 517 504 486 509 492 504 486 509 492 1473 519 1472 509 512 489 506 484 1481 511 1480 512 1480 512 1479 513 508 493 502 488 507 483 512 489 4449 516 506 485 511 490 505 485 510 491 505 485 510 491 504 486 509 492 1473 519 1473 508 1483 561 434 515 1476 516 1475 517 1474 518 1473 519 502 488 507 483 512 489 1476 516
-#
+#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4531 4406 516 478 512 484 538 457 544 452 538 1453 518 1473 519 476 546 450 540 1451 509 1482 510 1481 511 1480 512 483 539 457 544 452 538 457 544 4420 513 482 540 456 545 450 540 455 546 1445 547 449 541 454 536 458 543 1449 543 1449 543 1448 544 451 539 456 545 1445 547 1445 547 1444 537 458 543 453 537 457 544 1448 544 54957 4495 4440 514 481 520 477 513 482 519 476 514 1476 516 1475 517 478 512 484 517 1474 518 1473 519 1472 520 1471 521 474 516 479 511 484 517 479 511 4452 512 509 492 503 487 508 493 503 487 1477 515 507 483 512 489 506 484 1481 511 1481 511 1480 512 509 492 503 487 1478 514 1478 514 1477 515 506 484 511 490 505 485 1480 512
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4551 4468 549 461 544 493 523 460 545 466 518 1480 520 1479 542 468 548 489 495 1477 523 1475 515 1484 516 1483 549 461 544 493 523 487 518 466 518 4490 548 462 543 493 523 488 517 466 550 461 544 466 550 460 545 465 519 1480 520 1478 522 1477 544 465 519 1480 520 1479 521 1477 523 1476 545 464 541 496 520 490 494 1479 542 55901 4554 4465 542 494 522 489 516 494 522 488 496 1477 523 1476 545 490 515 495 489 1484 516 1483 517 1481 519 1479 542 494 522 489 516 494 522 488 496 4487 541 495 521 490 515 495 521 489 516 494 522 488 517 493 523 488 496 1476 525 1475 515 1483 549 488 496 1476 524 1475 515 1484 516 1482 550 486 519 491 525 486 488 1485 547 55897 4548 4470 548 462 543 468 548 462 543 467 517 1482 518 1480 541 469 547 490 494 1478 575 1423 515 1485 515 1483 549 461 544 466 550 461 544 466 518 4491 547 462 543 467 549 462 543 467 549 461 544 466 539 497 519 492 492 1480 520 1478 522 1477 544 465 519 1480 520 1479 521 1477 513 1486 546 464 541 469 547 464 520 1478 543
-#
+#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4553 4467 550 459 546 464 541 469 547 464 520 1479 521 1477 544 492 524 486 498 1475 515 1484 516 1482 518 1481 540 496 520 490 515 495 521 490 494 4488 550 486 519 491 525 486 519 491 493 1479 542 494 522 489 516 494 490 1482 518 1481 519 1480 541 494 522 489 495 1478 522 1476 514 1485 547 489 516 494 522 489 495 1477 544
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4555 4483 516 516 488 519 495 512 492 515 489 1525 493 1519 489 518 496 511 493 1521 487 1525 493 1520 488 1524 494 513 491 517 487 520 494 514 490 4501 519 513 491 516 488 520 494 513 491 517 487 521 493 514 490 518 486 1527 491 1522 496 1517 491 516 488 1525 493 1520 488 1525 493 1520 488 519 495 512 492 516 488 1525 493
-#
+#
name: VOL+
type: parsed
protocol: RC5
address: 13 00 00 00
command: 0D 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: RC5
address: 13 00 00 00
command: 0E 00 00 00
-#
+#
name: POWER
type: parsed
protocol: RC5
address: 13 00 00 00
command: 0B 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: RC5
address: 13 00 00 00
command: 0C 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: SIRC
address: 01 00 00 00
command: 12 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: SIRC
address: 01 00 00 00
command: 13 00 00 00
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4552 4468 574 436 566 444 568 442 570 441 540 1458 546 1453 572 439 573 437 544 1455 539 1460 544 1456 548 1450 575 436 566 444 568 442 570 440 541 4468 594 416 565 445 567 443 569 441 540 1459 545 1453 541 1459 566 444 547 1452 542 1457 547 1452 593 417 564 446 566 444 568 442 539 1460 565 446 566 444 568 442 539 1460 565 55957 4581 4437 543 467 545 466 546 464 538 472 519 1480 514 1485 540 471 541 469 512 1486 518 1481 513 1486 518 1481 575 436 566 444 568 442 570 440 541 4468 543 468 544 465 547 464 538 472 519 1480 514 1485 519 1479 546 465 516 1483 511 1488 516 1483 542 468 544 466 546 464 538 473 519 1480 545 466 546 464 538 472 519 1480 545
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4546 4473 538 473 539 470 542 469 543 467 514 1484 520 1479 545 465 547 463 518 1481 513 1486 518 1481 513 1487 538 472 540 470 542 469 543 466 515 4495 546 463 539 472 540 470 542 468 544 466 546 491 521 462 519 1480 513 1485 519 1480 514 1486 539 472 519 1479 515 1484 520 1479 546 464 548 463 539 471 541 469 512 1487 548
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4549 4469 542 468 544 467 545 465 537 473 519 1481 513 1485 540 471 541 469 512 1487 517 1482 512 1487 517 1482 543 467 545 465 547 463 539 472 519 4489 543 468 544 466 546 464 538 473 539 470 542 468 544 466 546 465 516 1482 512 1487 517 1482 543 468 513 1485 519 1480 514 1485 519 1480 545 465 547 463 539 472 520 1479 546 55899 4549 4470 541 469 574 436 566 445 546 463 549 1450 513 1486 539 471 572 438 543 1456 548 1451 543 1456 548 1451 574 436 566 445 567 443 569 441 540 4469 573 437 575 435 567 443 569 441 571 439 573 437 565 445 567 443 549 1451 543 1456 548 1451 574 436 545 1454 540 1459 545 1454 540 1459 566 444 568 442 570 440 541 1458 567 55878 4580 4439 572 439 573 437 565 445 567 443 548 1451 543 1456 569 441 571 439 542 1457 547 1452 542 1457 547 1452 573 437 575 435 567 443 569 442 539 4469 573 438 574 436 566 444 568 442 570 440 572 438 574 436 566 444 547 1452 542 1457 547 1452 573 437 544 1455 539 1460 544 1455 539 1460 575 435 567 444 568 442 539 1459 566 55879 4578 4442 569 441 571 439 573 437 575 435 546 1453 541 1458 567 444 568 441 540 1459 545 1454 540 1459 545 1454 571 439 573 437 575 435 567 444 548 4461 571 440 572 438 574 436 566 444 568 442 570 440 572 438 574 436 545 1454 540 1459 545 1454 571 439 542 1457 547 1452 542 1457 547 1452 573 437 575 435 567 444 547 1451 574 55871 4554 4465 546 464 538 473 539 471 541 469 512 1487 517 1481 544 467 545 465 516 1483 511 1488 516 1483 511 1488 547 463 539 472 540 470 542 468 513 4496 546 464 538 472 540 470 542 468 544 466 546 464 538 473 539 471 510 1488 516 1483 511 1488 547 463 518 1481 513 1486 518 1481 513 1486 539 472 540 470 542 467 514 1485 540
-#
+#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 4555 4465 546 464 538 472 540 470 542 468 513 1486 518 1481 544 467 545 465 516 1483 511 1488 516 1483 511 1488 537 473 539 472 540 470 542 468 513 4496 546 464 538 473 539 471 541 469 512 1487 538 472 540 470 542 469 512 1486 518 1481 544 1455 570 441 571 439 542 1457 547 1452 542 1457 568 442 570 440 572 438 543 1456 569 55920 4555 4464 547 464 538 472 540 470 542 468 513 1486 518 1481 544 466 546 464 517 1482 512 1487 517 1482 512 1487 538 473 539 471 541 469 543 467 514 4495 547 463 539 472 540 470 542 468 513 1486 539 471 541 469 543 467 514 1485 519 1479 515 1485 540 470 542 468 513 1486 518 1481 513 1486 539 471 541 469 543 467 514 1485 540
-#
+#
name: POWER
type: parsed
protocol: SIRC15
address: 10 00 00 00
command: 15 00 00 00
-#
+#
name: POWER
type: parsed
protocol: SIRC
address: 01 00 00 00
command: 15 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: SIRC
address: 01 00 00 00
command: 14 00 00 00
-#
+#
name: POWER
type: parsed
protocol: SIRC
address: 10 00 00 00
command: 15 00 00 00
-#
+#
name: POWER
type: parsed
protocol: SIRC15
address: 30 00 00 00
command: 15 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: SIRC15
address: 30 00 00 00
command: 14 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 86 FF 00 00
command: 1C E3 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 86 FF 00 00
command: 1D E2 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 80 00 00 00
command: 0D 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 80 00 00 00
command: 08 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 80 00 00 00
command: 12 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 80 00 00 00
command: 1E 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: EF 01 00 00
command: 25 DA 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: EF 01 00 00
command: 14 EB 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: EF 01 00 00
command: 13 EC 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: EF 01 00 00
command: 28 D7 00 00
-#
-name: POWER
-type: parsed
-protocol: NEC
-address: 00 00 00 00
-command: 40 00 00 00
-#
-name: VOL+
-type: parsed
-protocol: NEC
-address: 00 00 00 00
-command: 41 00 00 00
-#
-name: VOL-
-type: parsed
-protocol: NEC
-address: 00 00 00 00
-command: 45 00 00 00
-#
-name: MUTE
-type: parsed
-protocol: NEC
-address: 00 00 00 00
-command: 48 00 00 00
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1048 580 597 1165 596 582 595 1167 594 875 599 578 599 1455 593 585 592 1171 600 577 600 576 601 13191 1042 586 591 1170 601 576 601 1161 600 869 595 582 595 1459 599 578 599 1163 598 580 597 579 598 13195 1048 580 597 1165 596 581 596 1167 594 875 599 578 599 1456 592 585 592 1171 600 577 600 577 600 13192 1052 576 601 1162 599 578 599 1163 598 871 593 584 593 1462 596 581 596 1166 595 582 595 582 595
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1048 553 624 1138 623 554 623 1139 622 848 626 551 626 1427 621 556 652 1403 655 522 655 814 650 12579 1050 552 656 1106 624 553 624 1138 623 847 627 550 627 1427 621 556 621 1434 624 553 624 845 619 12612 1079 523 623 1139 622 555 622 1139 622 848 626 550 627 1427 621 556 621 1434 624 553 624 845 619 12613 1047 556 621 1141 620 556 621 1141 620 850 624 552 625 1429 619 558 619 1435 623 554 623 846 628 12600 1050 552 625 1137 624 553 624 1137 624 846 618 558 619 1435 623 554 623 1431 627 550 627 842 622 12609 1051 551 626 1136 625 551 626 1136 625 844 620 557 620 1434 624 554 623 1431 627 550 627 843 621
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1073 528 649 1114 647 530 647 1116 645 825 649 527 650 1405 653 1402 625 552 646 1409 649 1113 648 11417 1077 524 653 1110 651 526 651 1112 649 820 654 523 654 1400 648 1407 651 526 651 1404 654 1109 652 11414 1079 523 654 1109 652 524 653 1111 650 819 624 554 654 1401 647 1408 650 529 648 1406 652 1111 650 11416 1077 525 652 1110 651 526 651 1112 649 820 654 523 654 1401 647 1408 650 528 649 1405 622 1141 651 11414 1080 521 646 1116 624 553 645 1117 654 816 648 529 648 1406 652 1403 655 523 644 1410 648 1114 647 11418 1075 526 651 1111 650 527 650 1112 649 820 623 554 654 1400 648 1407 651 526 651 1403 655 1107 654
-#
+#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1051 550 627 1135 626 551 626 1136 625 845 619 850 624 553 675 794 629 842 622 555 622 555 622 13780 1047 555 622 1140 621 557 620 1141 620 850 624 845 619 558 619 850 624 846 618 559 618 559 618 13782 1045 558 619 1143 618 559 618 1144 627 842 622 847 627 550 627 842 622 848 626 551 626 551 626 13774 1053 549 618 1144 627 550 627 1135 626 843 621 849 625 551 626 844 620 850 624 553 624 552 625 13776 1051 551 626 1137 624 553 624 1138 623 846 618 851 623 554 623 846 628 841 623 554 623 554 623 13776 1051 551 626 1136 625 552 625 1137 624 845 619 850 624 553 624 846 618 852 622 555 622 554 623 13778 1049 554 623 1139 622 555 622 1140 621 849 625 844 620 557 620 850 624 846 618 559 618 558 619
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 78 00 00 00
command: CC 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 78 00 00 00
command: 9C 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 7E 00 00 00
command: 2A 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 7A 00 00 00
command: 1C 00 00 00
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 274 789 254 1792 275 814 250 787 246 816 248 1798 279 784 249 813 251 785 248 788 245 1827 281 1791 275 1825 272 790 253 783 250 43886 277 786 278 1795 272 791 252 783 281 782 251 785 269 1804 273 1800 277 1822 275 1798 279 783 270 766 277 759 274 1825 272 1800 277 43886 277 759 274 1825 272 764 279 756 277 786 278 1795 282 781 272 763 280 755 278 785 279 1794 273 1827 270 1802 275 761 272 791 273 43888 276 761 272 1800 277 786 278 758 275 760 273 790 274 1799 278 1821 276 1796 281 1792 275 788 276 760 273 789 275 1798 279 1794 273 43889 278 785 248 1825 272 790 253 782 272 764 279 1793 274 790 274 761 282 781 273 763 280 1793 273 1825 272 1800 277 813 220 789 275
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 270 793 250 1795 272 818 246 791 252 809 244 766 277 1795 282 781 272 790 253 809 224 1822 275 1797 280 1820 277 785 248 788 245 43889 273 790 274 1799 278 785 248 788 276 787 246 1826 271 792 251 1794 273 1827 270 1802 275 788 245 791 273 790 253 1819 278 1794 273 43889 274 789 254 1818 269 767 276 786 247 789 275 788 245 1827 270 792 251 785 248 814 250 1796 281 1819 248 1825 272 790 253 783 271 43889 245 791 273 1799 278 786 278 784 249 787 246 1827 281 781 252 1821 276 1796 281 1792 274 814 250 786 247 789 244 1829 279 1793 274 43888 275 815 218 1828 280 783 250 786 278 785 248 788 245 1827 280 782 251 785 268 794 249 1797 280 1819 278 1794 272 791 252 810 254
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 277 759 274 1799 278 784 280 783 250 812 242 1804 273 816 227 808 246 791 252 1819 248 1825 273 1826 251 1822 276 786 247 789 244 43888 274 815 249 1797 280 783 250 812 252 784 249 813 241 1805 272 1827 250 1822 275 787 246 816 217 819 255 807 226 1820 278 1795 272 43888 273 789 254 1817 270 793 251 785 248 814 250 1795 282 807 247 790 253 783 250 1822 276 1796 281 1818 249 1824 274 814 229 807 247
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 275 762 271 1800 277 786 278 784 249 813 241 795 248 1824 253 784 270 792 251 1821 246 1826 272 1801 276 1823 275 762 271 790 243 43889 274 789 275 1797 280 783 250 812 252 784 249 1823 275 762 271 1827 250 1822 276 787 246 816 217 818 246 790 253 1819 268 1804 273 43886 277 786 247 1825 273 764 280 783 250 811 253 784 249 1822 276 761 272 816 228 1819 279 1794 273 1826 251 1821 277 786 247 815 249
-#
+#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 275 762 271 1800 277 786 278 784 249 813 241 795 248 814 219 817 247 789 254 1818 249 1824 274 1798 279 1820 278 759 274 788 245 43887 274 789 275 1798 279 783 250 812 252 784 249 1823 274 1798 279 1820 247 1826 271 765 278 809 224 812 252 784 249 1823 275 1798 279 43880 281 782 251 1821 277 760 273 789 244 818 246 790 253 808 246 791 252 809 224 1822 275 1797 280 1819 248 1825 273 790 253 808 246
-#
+#
name: POWER
-type: raw
-frequency: 39105
-duty_cycle: 0.330000
-data: 5396 53113 8899 4450 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 1662 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 563 563 563 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 1662 563 1662 563 1662 563 1662 563 563 563 38358 8899 2225 563 95052
-#
+type: parsed
+protocol: NECext
+address: 87 7C 00 00
+command: 80 7F 00 00
+#
name: VOL+
-type: raw
-frequency: 39105
-duty_cycle: 0.330000
-data: 5472 53216 8899 4450 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 1662 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 1662 563 563 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 563 563 1662 563 1662 563 1662 563 563 563 38358 8899 2199 563 95052
-#
+type: parsed
+protocol: NECext
+address: 87 7C 00 00
+command: 88 77 00 00
+#
name: VOL-
-type: raw
-frequency: 39105
-duty_cycle: 0.330000
-data: 5472 53344 8899 4424 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 1662 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 1662 563 1662 563 563 563 563 563 563 563 1662 563 1662 563 1662 563 563 563 563 563 1662 563 1662 563 1662 563 563 563 38358 8899 2225 563 95052
-#
+type: parsed
+protocol: NECext
+address: 87 7C 00 00
+command: 8C 73 00 00
+#
name: MUTE
-type: raw
-frequency: 39105
-duty_cycle: 0.330000
-data: 5498 53523 8899 4450 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 1662 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 1662 563 563 563 1662 563 563 563 563 563 1662 563 1662 563 1662 563 563 563 1662 563 563 563 1662 563 1662 563 563 563 38358 8899 2199 563 95052
-#
+type: parsed
+protocol: NECext
+address: 87 7C 00 00
+command: 94 6B 00 00
+#
name: POWER
type: parsed
protocol: NECext
address: D2 6C 00 00
command: CB 34 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: D2 6D 00 00
command: 02 FD 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: D2 6D 00 00
command: 03 FC 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: D2 6D 00 00
command: 05 FA 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: D2 03 00 00
command: 04 FB 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: D2 03 00 00
command: 02 FD 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: D2 03 00 00
command: 03 FC 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: D2 03 00 00
command: 05 FA 00 00
-#
+#
name: POWER
type: parsed
protocol: RC5
address: 14 00 00 00
command: 0C 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: RC5
address: 14 00 00 00
command: 11 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: RC5
address: 14 00 00 00
command: 10 00 00 00
-#
-name: MUTE
-type: parsed
-protocol: RC5
-address: 10 00 00 00
-command: 0D 00 00 00
-#
-name: VOL+
-type: parsed
-protocol: RC5
-address: 10 00 00 00
-command: 10 00 00 00
-#
-name: VOL-
-type: parsed
-protocol: RC5
-address: 10 00 00 00
-command: 11 00 00 00
-#
+#
name: POWER
type: parsed
protocol: SIRC15
address: 10 00 00 00
command: 60 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: SIRC15
address: 30 00 00 00
command: 12 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: SIRC15
address: 30 00 00 00
command: 13 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: SIRC15
address: 10 00 00 00
command: 12 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: SIRC15
address: 10 00 00 00
command: 13 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 7E 81 00 00
command: 2A D4 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 7A 85 00 00
command: 1C E2 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 78 00 00 00
command: 0F 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 78 00 00 00
command: 4F 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 7A 00 00 00
command: 1A 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 7A 00 00 00
command: 1B 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 7A 85 00 00
command: 1A E4 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 7A 85 00 00
command: 1B E5 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 78 00 00 00
command: 1E 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 78 00 00 00
command: 1F 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: RC5X
address: 0A 00 00 00
command: 2F 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 00 00 00 00
command: 15 00 00 00
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 8437 4188 538 1565 539 1565 539 513 544 508 538 513 544 1559 545 507 539 1564 540 1564 540 1563 541 1563 541 511 546 1557 547 505 542 511 546 505 542 20497 597 1507 545 1559 545 507 539 512 545 507 539 1564 540 512 545 1558 546 1558 546 1558 546 1557 547 505 542 1562 542 510 547 505 542 510 547 20492 540 1564 540 1564 540 512 545 506 540 511 546 1558 546 505 542 1562 542 1562 542 1562 542 1561 543 509 548 1555 538 514 543 509 537 514 543 20495 547 1558 546 1557 547 505 541 511 546 505 542 1562 542 510 547 1556 548 1556 548 1556 548 1556 537 514 543 1560 544 508 538 514 543 508 538 20501 541 1562 542 1562 542 510 547 505 541 510 547 1556 548 504 543 1561 543 1561 543 1560 544 1560 544 508 538 1565 539 513 544 507 539 513 544 20494 548 1556 548 1556 548 504 543 509 548 504 543 1560 544 508 539 1565 539 1565 539 1564 540 1564 540 512 545 1559 545 506 540 512 545 506 540 20499 543 1560 544 1560 544 508 539 513 544 508 538 1564 540 512 545 1559 545 1558 546 1558 546 1558 546 506 541 1563 541 510 547 505 542 510 547
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 8430 4194 542 1562 542 1562 542 510 547 505 541 510 547 1556 548 504 542 1561 543 509 548 1556 548 1556 548 1556 548 1556 548 504 542 509 537 514 543 20496 545 1559 545 1559 545 507 539 512 545 507 539 1564 540 512 545 1559 545 507 539 1564 540 1564 540 1563 541 1563 541 511 546 506 540 511 546 20494 546 1557 547 1557 547 505 541 510 547 505 541 1562 542 510 547 1556 548 505 541 1562 542 1562 542 1561 543 1561 543 509 548 504 542 509 537 20501 540 1565 539 1565 539 512 545 507 539 512 545 1559 545 507 539 1564 540 512 545 1559 545 1558 546 1558 546 1558 546 506 540 511 546 506 540 20498 543 1562 542 1562 542 510 547 505 541 510 547 1557 547 505 541 1562 542 509 548 1556 548 1556 548 1556 548 1556 548 504 542 509 548 504 542 20497 543 1560 544 1560 544 508 538 513 544 508 538 1565 539 513 544 1560 544 508 538 1565 539 1565 539 1565 539 1564 540 513 544 507 539 512 545 20495 545 1558 546 1558 546 506 540 511 546 506 540 1563 541 511 546 1558 546 506 540 1563 541 1563 541 1563 541 1562 542 510 547 505 541 510 547 20493 548 1556 548 1556 548 504 542 509 548 504 542 1561 543 509 537 1566 538 514 543 1560 544 1560 544 1560 544 1560 544 508 538 513 544 508 538 20501 539 1564 540 1564 540 512 545 507 539 512 545 1559 545 507 539 1564 540 512 545 1559 545 1558 546 1558 546 1558 546 506 540 511 546 506 540
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 8434 4191 545 1559 545 1559 545 534 512 513 544 507 539 1564 540 538 519 1559 545 1558 546 1558 546 1558 546 1558 546 1558 546 533 513 511 546 506 540 19446 547 1557 547 1557 547 532 514 511 546 532 514 1562 593 459 546 1557 547 1557 547 1557 547 1557 547 1557 547 1557 547 531 515 510 547 505 541 19446 548 1556 548 1556 548 530 516 509 548 504 543 1561 543 535 512 1566 538 1565 539 1565 539 1565 539 1565 539 1565 539 540 517 509 537 514 543 19444 539 1565 539 1565 539 513 544 508 538 513 544 1559 545 534 512 1564 540 1564 540 1564 540 1564 540 1564 540 1564 540 539 518 507 539 513 544 19442 541 1563 541 1563 541 538 519 507 539 512 545 1558 546 506 540 1563 541 1563 541 1563 541 1563 541 1563 541 1562 542 537 520 505 541 511 546 19440 595 1509 543 1561 543 536 521 504 542 509 548 1555 538 540 517 1560 544 1560 544 1560 544 1560 544 1560 544 1560 544 534 512 513 544 508 538 19448 546 1559 545 1559 545 533 513 512 545 507 539 1563 541 538 519 1558 546 1558 546 1558 546 1557 547 1558 546 1558 546 533 513 512 545 506 540 19447 546 1557 547 1557 547 532 514 511 546 506 540 1562 542 537 520 1557 547 1557 547 1557 547 1557 547 1557 547 1557 547 505 542 510 547 505 541 19445 548 1556 548 1556 548 531 515 510 547 504 542 1561 543 536 521 1555 538 1566 538 1566 538 1566 538 1566 538 1565 539 514 543 509 537 514 543
-#
+#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 8435 4189 547 1557 547 1557 547 505 541 510 547 505 541 1562 542 510 547 1557 547 505 541 510 547 1557 546 1557 547 1557 547 505 541 510 547 505 541 21550 547 1558 545 1558 546 506 540 511 546 506 540 1563 541 511 546 1558 545 506 540 511 546 1558 546 1558 546 1558 546 506 540 511 546 506 540 21551 546 1558 546 1558 546 506 540 512 545 506 540 1563 540 512 545 1558 546 506 540 512 545 1558 546 1558 546 1558 546 506 540 512 545 506 540 21551 546 1559 545 1559 545 507 539 512 545 507 539 1564 539 512 545 1559 545 507 539 512 545 1559 545 1559 545 1559 545 507 539 512 545 507 539 21552 545 1559 545 1559 545 507 539 513 544 507 539 1564 540 512 545 1559 545 507 539 512 545 1559 545 1559 545 1559 545 507 539 512 545 507 539 21552 545 1559 545 1559 545 507 539 513 544 507 539 1565 538 513 544 1559 545 507 539 513 544 1559 545 1559 544 1559 545 534 512 513 544 507 539 21553 544 1560 544 1560 544 534 512 513 544 508 538 1565 539 539 518 1560 544 534 512 513 544 1560 544 1560 544 1560 544 534 512 513 544 508 538
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 20 00 00 00
command: 41 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 20 00 00 00
command: 42 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 20 00 00 00
command: 43 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 20 00 00 00
command: 1B 00 00 00
-#
+#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 8498 4205 651 1471 576 530 550 1572 547 535 545 536 544 1578 541 540 550 1572 547 535 545 1576 543 539 541 1580 549 1572 547 534 546 1576 543 539 541 540 550 1571 548 533 547 1574 545 537 543 539 541 541 549 532 548 1574 545 536 544 1578 541 540 550 1571 548 1572 547 1574 545 1576 543 26533 8497 4203 653 1468 569 538 542 1579 550 531 549 533 547 1573 546 535 545 1576 543 538 542 1579 550 531 549 1571 548 1573 546 536 544 1576 543 539 541 540 550 1571 548 533 547 1574 545 536 544 538 542 540 550 530 550 1572 547 534 546 1575 544 537 543 1578 541 1579 550 1570 549 1572 547 26524 8496 4207 576 1570 549 533 547 1574 545 537 543 539 541 1580 549 532 548 1573 546 536 544 1577 542 539 551 1570 549 1572 547 534 546 1575 544 538 542 540 550 1571 548 534 546 1575 544 538 542 540 550 531 549 533 547 1575 544 537 543 1579 550 531 549 1571 548 1572 547 1574 545 1576 543 26529 8491 4211 573 1573 546 535 545 1576 543 539 551 530 550 1571 548 533 547 1574 545 536 544 1578 541 540 550 1570 549 1572 547 534 546 1575 544 538 542 539 541 1580 549 532 548 1572 547 535 545 537 543 539 541 540 550 1571 548 533 547 1574 545 537 543 1578 541 1579 550 1571 548 1574 545 26522 8498 4202 571 1574 545 537 543 1578 541 541 549 532 548 1573 546 534 546 1575 544 537 543 1577 542 540 550 1570 549 1571 548 533 547 1574 545 537 543 538 542 1579 550 531 549 1572 547 534 546 536 544 537 543 538 542 1579 550 531 549 1572 547 535 545 1575 544 1577 542 1579 550 1571 548 26522 8498 4203 570 1575 544 537 543 1578 541 541 549 532 548 1573 546 535 545 1575 544 538 542 1579 550 531 549 1571 548 1572 547 535 545 1575 544 538 542 539 541 1580 549 532 548 1572 547 534 546 536 544 537 543 539 541 1579 550 531 549 1571 548 533 547 1573 546 1574 545 1575 544 1577 542
-#
+#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 8490 4211 573 1573 546 535 545 1576 543 539 541 540 550 1571 548 532 548 1573 546 535 545 1576 543 539 541 1579 550 1571 548 533 547 1574 545 536 544 1576 543 1578 541 540 550 1570 549 533 547 534 546 536 544 537 543 539 541 540 550 1570 549 532 548 1572 547 1573 546 1574 545 1576 543 26528 8492 4208 648 1475 572 534 546 1575 544 537 543 539 541 1580 549 532 548 1573 546 535 545 1576 543 538 542 1579 550 1571 548 533 547 1575 544 537 543 1577 542 1579 550 532 548 1573 546 535 545 537 543 539 541 541 549 532 548 533 547 1575 544 537 543 1578 541 1579 550 1571 548 1573 546 26523 8496 4203 622 1499 569 537 543 1578 541 541 549 532 548 1572 547 534 546 1574 545 537 543 1578 541 540 550 1570 549 1571 548 534 546 1575 544 538 542 1578 541 1580 549 532 548 1573 546 536 544 538 542 540 550 532 548 533 547 535 545 1576 543 539 541 1579 550 1571 548 1573 546 1574 545 26521 8498 4201 572 1573 546 536 544 1577 542 540 550 531 549 1571 548 533 547 1573 546 536 544 1576 543 539 541 1579 550 1570 549 532 548 1573 546 535 545 1576 543 1578 541 540 550 1571 548 533 547 535 545 537 543 538 542 540 550 531 549 1572 547 534 546 1575 544 1576 543 1577 542 1579 550 26522 8498 4203 570 1575 544 538 542 1579 550 532 548 533 547 1575 544 537 543 1578 541 540 550 1570 549 533 547 1573 546 1575 544 537 543 1578 541 540 550 1571 548 1573 546 536 544 1578 551 531 549 533 547 535 545 537 543 539 541 540 550 1571 548 533 547 1575 544 1576 543 1578 541 1580 549 26521 8498 4203 570 1576 543 538 542 1580 549 532 548 533 547 1574 545 536 544 1577 542 540 550 1570 549 533 547 1573 546 1575 544 538 542 1579 550 531 549 1571 548 1573 546 536 544 1576 543 539 551 531 549 532 548 534 546 536 544 538 542 1579 550 531 549 1572 547 1573 546 1574 545 1576 543
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 8500 4203 653 1468 569 538 542 1579 550 532 548 534 546 1575 544 536 544 1578 541 540 550 1572 547 534 546 1575 544 1577 542 539 541 1580 550 532 548 534 546 535 545 1576 543 1577 542 1579 551 532 548 534 546 536 544 1577 542 1578 552 531 549 533 547 534 546 1574 545 1575 544 1577 542 26533 8492 4211 573 1573 546 535 545 1576 543 539 551 530 550 1571 548 533 547 1574 545 536 544 1577 542 540 550 1570 549 1572 547 534 546 1576 543 539 541 541 549 532 548 1573 546 1574 545 1576 543 539 551 531 549 533 547 1573 546 1576 543 539 541 541 549 532 548 1573 546 1574 545 1576 543 26532 8493 4209 575 1571 548 533 547 1575 544 537 543 539 541 1580 550 531 549 1572 547 534 546 1576 543 538 542 1579 551 1570 549 532 548 1574 545 537 543 538 542 540 550 1570 549 1572 547 1575 544 537 543 539 541 540 550 1571 548 1573 546 536 544 538 542 539 551 1570 549 1572 547 1574 545 26530 8496 4207 567 1579 551 531 549 1572 547 535 545 536 544 1576 543 538 542 1579 551 530 550 1571 548 534 546 1574 545 1576 543 538 542 1579 551 532 548 533 547 534 546 1576 543 1577 542 1579 551 532 548 534 546 535 545 1576 543 1578 541 540 550 532 548 533 547 1574 545 1575 544 1577 542 26531 8495 4210 574 1571 548 534 546 1575 544 538 542 539 551 1569 550 531 549 1572 547 535 545 1576 543 539 541 1579 550 1571 548 534 546 1575 544 538 542 540 550 531 549 1572 547 1549 570 1551 568 539 551 531 549 532 548 1573 546 1550 569 538 542 540 550 531 549 1571 548 1548 571 1550 569
-#
+#
name: POWER
type: parsed
protocol: NECext
address: 00 EF 00 00
command: 1C E3 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 00 EF 00 00
command: 00 FF 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 00 EF 00 00
command: 04 FB 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC42
address: 6E 00 00 00
command: 00 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC42
address: 6E 00 00 00
command: 4D 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC42
address: 6E 00 00 00
command: 4E 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC42
address: 6E 00 00 00
command: 0E 00 00 00
-#
+#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 8441 4184 542 1562 541 1562 542 511 546 506 540 511 546 1557 546 506 540 1563 541 1563 540 1563 541 512 545 507 539 512 545 507 539 512 545 507 539 22605 538 1565 539 1565 538 514 543 509 537 514 543 1560 543 509 548 1555 548 1556 548 1556 547 504 542 510 547 505 541 510 547 505 541 510 547 22597 546 1559 544 1559 545 507 539 513 544 507 539 1564 539 513 544 1559 544 1559 545 545 508 549 513 508 538 513 544 508 538 513 544 22601 542 1562 542 1561 543 510 547 505 541 510 547 1557 547 505 541 1562 542 1562 542 1562 542 510 547 505 541 510 547 505 541 511 546 505 541 22603 540 1564 539 1565 538 513 544 508 538 513 544 1560 544 508 538 1565 538 1565 538 1566 537 514 543 509 548 504 542 509 548 504 542 509 548 22597 546 1558 546 1558 546 506 540 512 545 507 539 1564 540 512 545 1559 545 1559 544 1559 544 507 539 513 544 508 538 513 544 508 538 513 544 22600 543 1561 542 1562 542 510 547 505 541 510 547 1557 547 505 541 1562 541 1563 540 1563 541 511 546 506 540 511 546 506 540 511 546 506 540 22604 539 1565 538 1566 537 514 543 509 548 504 542 1561 543 509 548 1556 548 1556 548 1556 547 504 542 510 547 505 541 510 547 505 541 510 547 22598 545 1559 544 1559 545 507 539 512 545 507 539 1564 540 512 545 1559 544 1559 545 1559 545 508 538 513 544 508 538 513 544 508 538 513 544 22601 542 1562 542 1562 542 511 546 505 541 511 546 1557 546 506 540 1563 541 1563 540 1563 541 511 546 506 540 511 546 506 540 512 545 506 540 22604 539 1565 538 1566 537 514 543 509 548 504 542 1561 543 509 548 1556 547 1556 547 1556 548 504 542 510 547 505 541 510 547 505 541 510 547
-#
+#
name: POWER
type: parsed
protocol: SIRC
address: 10 00 00 00
command: 60 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 08 00 00 00
command: 0E 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 08 00 00 00
command: 1A 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 00 00 00 00
command: 57 00 00 00
-#
-name: VOL+
-type: parsed
-protocol: NECext
-address: 10 E7 00 00
-command: 06 F9 00 00
-#
-name: VOL-
-type: parsed
-protocol: NECext
-address: 10 E7 00 00
-command: 47 B8 00 00
-#
-name: MUTE
-type: parsed
-protocol: NECext
-address: 10 E7 00 00
-command: 41 BE 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 4D 00 00 00
command: 04 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 4D 00 00 00
command: 05 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 4D 00 00 00
command: 02 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 4D 00 00 00
command: 03 00 00 00
-#
+#
name: POWER
type: parsed
protocol: NEC
address: 4D 00 00 00
command: 00 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NEC
address: 00 00 00 00
command: 19 00 00 00
-#
+#
name: VOL-
type: parsed
protocol: NEC
address: 00 00 00 00
command: 16 00 00 00
-#
+#
name: MUTE
type: parsed
protocol: NEC
address: 00 00 00 00
command: 44 00 00 00
-#
+#
name: VOL+
type: parsed
protocol: NECext
address: 12 36 00 00
command: 0A F5 00 00
-#
+#
name: VOL-
type: parsed
protocol: NECext
address: 12 36 00 00
command: 0B F4 00 00
-#
+#
name: MUTE
type: parsed
protocol: NECext
address: 12 36 00 00
command: 09 F6 00 00
-#
+#
name: POWER
type: parsed
protocol: NECext
@@ -2099,4 +1888,117 @@ type: parsed
protocol: RC5
address: 10 00 00 00
command: 0F 00 00 00
-#
+#
+name: POWER
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 02 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 0A 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 0E 00 00 00
+#
+name: POWER
+type: parsed
+protocol: SIRC
+address: 0F 00 00 00
+command: 15 00 00 00
+#
+name: Power
+type: parsed
+protocol: Samsung32
+address: 10 00 00 00
+command: 1E 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: Samsung32
+address: 10 00 00 00
+command: 17 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: Samsung32
+address: 10 00 00 00
+command: 16 00 00 00
+#
+name: MUTE
+type: parsed
+protocol: Samsung32
+address: 10 00 00 00
+command: 1F 00 00 00
+#
+name: POWER
+type: parsed
+protocol: Kaseikyo
+address: 51 54 32 01
+command: 03 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: Kaseikyo
+address: 51 54 32 01
+command: 04 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: Kaseikyo
+address: 51 54 32 01
+command: 05 00 00 00
+#
+name: MUTE
+type: parsed
+protocol: Kaseikyo
+address: 51 54 32 01
+command: 06 00 00 00
+#
+name: POWER
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4567 4454 549 481 522 481 523 480 498 506 498 1509 499 1509 523 480 499 505 523 1484 523 1484 523 1485 521 1487 520 484 519 485 519 485 519 471 519 4488 518 485 519 485 518 485 519 485 518 485 519 485 519 485 519 485 519 1489 519 1489 518 1489 518 485 519 1489 518 1490 518 1490 517 1490 518 486 518 486 518 486 518 1490 518
+#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4571 4453 552 478 525 478 526 478 500 504 500 1507 501 1506 526 478 525 477 526 1481 526 1481 526 1482 524 1483 523 481 522 482 521 481 522 468 522 4484 521 482 521 482 521 482 522 481 522 1486 521 1486 521 1486 521 482 521 1486 522 1486 522 1486 522 482 522 482 522 482 522 482 522 1486 522 483 521 482 521 483 521 1487 521 55474 4547 4477 524 479 524 480 524 480 523 480 523 1485 523 1484 524 481 523 481 523 1485 523 1485 522 1485 523 1485 523 480 524 480 524 481 523 467 524 4484 523 481 523 481 523 481 523 481 523 1485 523 1485 523 1485 523 481 523 1485 523 1485 523 1485 523 481 523 481 523 481 523 481 523 1485 523 481 523 481 523 481 523 1486 522
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4572 4453 552 456 548 479 524 479 500 504 500 1482 526 1482 551 478 526 478 525 1483 524 1484 523 1486 521 1487 521 483 521 483 521 483 521 470 520 4487 521 483 521 483 521 483 521 483 521 483 521 483 521 483 521 1488 520 1488 520 1488 520 1488 520 483 521 1488 520 1488 520 1488 520 483 521 483 521 483 521 483 521 1488 520 55457 4565 4483 521 483 521 483 521 483 521 483 520 1488 520 1487 521 483 521 483 520 1488 520 1488 520 1488 520 1488 520 483 520 484 520 484 520 470 521 4487 520 484 520 483 520 484 520 484 520 484 520 484 519 484 520 1488 520 1488 520 1488 519 1488 520 484 520 1488 520 1488 520 1488 520 484 520 484 520 484 520 484 520 1489 519
+#
+name: MUTE
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4573 4451 552 477 527 478 526 477 526 478 501 1507 501 1506 502 502 527 477 526 1481 527 1481 527 1481 526 1482 525 479 524 480 523 481 523 468 523 4485 522 481 522 482 522 482 522 482 522 1486 522 482 521 482 522 482 522 1486 522 1486 522 1486 522 482 522 482 521 1487 521 1487 521 1487 521 482 521 483 521 483 521 1487 521 55462 4547 4474 524 478 525 479 524 480 523 480 523 1484 523 1484 523 480 523 480 523 1484 523 1484 524 1484 523 1485 522 480 523 480 524 480 523 467 523 4484 522 480 524 481 523 481 523 481 523 1485 523 481 522 481 523 481 523 1485 522 1485 523 1485 523 481 523 481 522 1485 522 1485 522 1485 523 481 522 481 522 481 523 1485 523
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 10 E7 00 00
+command: 49 B6 00 00
+#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 10 E7 00 00
+command: 05 FA 00 00
+#
+name: MUTE
+type: parsed
+protocol: NEC
+address: 20 00 00 00
+command: 50 00 00 00
diff --git a/assets/resources/infrared/assets/fans.ir b/assets/resources/infrared/assets/fans.ir
index 8b3310fb69..b2c683cba8 100644
--- a/assets/resources/infrared/assets/fans.ir
+++ b/assets/resources/infrared/assets/fans.ir
@@ -1,7 +1,7 @@
Filetype: IR library file
Version: 1
-# Last Updated 21th Dec, 2022
-# Last Checked 26th Dec, 2022
+# Last Updated 13th Jan, 2023
+# Last Checked 13th Jan, 2023
#
name: POWER
type: raw
@@ -1203,4 +1203,87 @@ type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1366 388 1295 387 446 1164 1368 387 1296 387 448 1164 518 1164 493 1189 517 1165 492 1189 493 1189 493 7851 1365 387 1270 388 446 1190 1365 387 1295 387 447 1192 490 1193 489 1193 489 1194 488 1194 488 1193 489 7855 1337 386 1296 386 448 1193 1338 386 1296 386 448 1193 489 1193 489 1193 489 1193 489 1193 489 1193 489 7855 1337 386 1297 386 448 1194 1337 386 1296 386 448 1194 488 1194 488 1194 488 1194 488 1194 488 1194 488 8160 1336 387 1296 387 447 1194 1337 387 1296 386 448 1194 488 1194 488 1194 488 1194 488 1194 488 1194 488 7855 1336 386 1297 387 447 1195 1336 386 1297 386 448 1195 486 1195 487 1195 487 1195 487 1196 486 1196 486 7881 1310 387 1272 397 436 1245 1286 397 1285 397 436 1246 436 1246 436 1247 435 1247 435 1248 434 1248 434 7934 1259 424 1259 424 408 1274 1258 424 1259 424 408 1274 408 1274 408 1274 408 1274 408 1274 408 1274 408 8239 1258 425 1258 424 408 1274 1258 424 1258 425 407 1273 408 1273 409 1273 408 1273 408 1274 408 1273 408 7907 1283 424 1258 424 409 1248 1283 399 1283 400 433 1247 434 1247 434 1247 434 1247 434 1247 434 1247 434 7905 1282 424 1258 425 407 1273 1257 425 1257 425 407 1273 407 1274 407 1274 407 1274 407 1275 406 1275 406 7958 1230 478 1204 478 353 1328 1204 478 1204 453 378 1327 353 1328 353 1302 379 1301 380 1301 380 1300 381
+#
+name: POWER
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1341 337 1339 338 496 1178 1395 305 1316 337 1339 338 496 1178 526 1151 526 1151 1366 335 1341 335 498 7888 1338 338 1337 339 495 1182 1336 340 1336 340 1336 340 494 1182 494 1182 494 1183 1336 340 1336 340 494 7892 1336 340 1336 340 494 1183 1336 340 1336 340 1336 340 494 1183 494 1183 494 1183 1335 341 1335 340 494 7893 1335 341 1335 341 493 1183 1336 341 1335 341 1335 341 493 1183 493 1183 494 1183 1335 341 1335 341 493 7893 1335 341 1335 341 493 1184 1334 341 1335 341 1335 341 493 1184 493 1184 493 1184 1335 341 1335 342 492 7894 1334 342 1334 342 492 1184 1334 342 1334 341 1335 342 492 1184 493 1184 492 1185 1334 342 1334 342 492 7894 1334 342 1334 342 492 1185 1333 343 1333 342 1334 342 492 1185 492 1185 492 1185 1333 343 1333 343 491 7895 1333 343 1333 343 491 1185 1333 343 1333 344 1332 344 490 1186 490 1186 491 1186 1333 344 1332 344 490 7897 1331 368 1308 368 466 1211 1308 368 1308 368 1308 368 466 1211 465 1211 466 1211 1307 368 1308 369 465 7921 1307 368 1308 368 466 1211 1308 368 1308 369 1307 368 466 1211 466 1211 465 1211 1308 369 1307 369 465 7921 1307 369 1307 369 465 1212 1307 369 1307 369 1307 369 465 1212 465 1212 465 1212 1307 369 1307 369 465 7922 1306 370 1306 370 464 1212 1307 370 1306 370 1306 370 464 1212 464 1213 464 1212 1306 370 1306 370 464 7922 1306 370 1306 371 463 1213 1306 370 1306 371 1305 371 463 1213 439 1238 439 1238 1305 371 1305 371 462 7924 1280 396 1280 396 438 1238 1281 396 1280 396 1280 396 438 1239 437 1239 438 1239 1280 396 1280 397 437 7949 1279 397 1279 397 437 1240 1279 398 1278 422 1254 422 412 1265 411 1265 412 1265 1254 422 1254 422 412 7974 1254 422 1254 422 412 1265 1254 423 1253 423 1253 449 384 1293 383 1293 383 1294 1225 451 1225 452 382 8056 1171 505 1171 532 188 1463 1169
+#
+name: MODE
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1349 364 1321 363 490 1219 1324 364 1294 389 463 1245 1324 363 462 1219 491 1221 462 1223 461 1226 484 8019 1292 393 1292 420 433 1252 1292 393 1292 420 433 1252 1292 393 460 1252 433 1252 460 1226 459 1252 433 8021 1317 393 1292 394 459 1226 1318 393 1292 394 458 1226 1318 394 432 1253 459 1226 459 1253 432 1253 459
+#
+name: TEMP+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1355 364 1348 363 462 1189 1355 363 1322 389 436 1245 492 1192 1351 389 436 1221 490 1197 487 1249 434 8019 1319 393 1292 393 459 1252 1292 393 1292 393 459 1252 432 1252 1292 393 459 1252 433 1252 433 1252 460 8020 1291 393 1292 420 432 1252 1292 393 1292 420 432 1253 459 1226 1291 420 432 1253 459 1226 459 1252 432
+#
+name: TEMP-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1354 363 1322 363 489 1219 1325 364 1295 389 463 1245 464 1219 466 1219 1324 416 435 1223 461 1249 461 8019 1292 393 1318 393 432 1252 1292 393 1318 393 433 1252 460 1225 460 1252 1292 393 460 1225 459 1252 433 8020 1318 393 1292 393 459 1253 1291 393 1291 394 459 1253 431 1253 432 1253 1291 420 432 1253 432 1253 458
+#
+name: TIMER
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1376 337 1348 363 462 1219 1325 390 1295 388 1322 363 490 1218 466 1219 465 1220 490 1222 1319 369 1316 7187 1292 393 1292 393 460 1252 1292 370 1315 393 1292 420 433 1252 433 1252 460 1252 433 1252 1292 393 1292 7188 1291 393 1318 393 433 1252 1292 393 1319 393 1291 393 460 1226 459 1252 432 1253 459 1225 1319 393 1292
#
+name: POWER
+type: parsed
+protocol: NECext
+address: 00 F3 00 00
+command: 91 6E 00 00
+#
+name: TIMER
+type: parsed
+protocol: NECext
+address: 00 F3 00 00
+command: 96 69 00 00
+#
+name: POWER
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 9253 4427 684 486 656 486 656 486 682 461 681 1573 680 1575 678 464 677 491 651 1604 650 1604 650 1604 650 1604 650 491 651 491 651 1604 650 1604 651 491 651 491 651 1604 650 1604 650 491 651 491 651 491 652 1604 650 1604 651 1604 650 491 651 491 652 1604 650 1604 650 1604 651 491 651 39948 9250 2183 651
+#
+name: SPEED+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 9226 4450 657 484 657 484 658 484 657 485 657 1596 658 1597 681 487 653 488 653 1602 652 1602 652 1602 652 1602 652 490 652 490 652 1602 652 1602 652 490 652 490 652 490 652 1603 652 490 652 490 652 490 652 1602 652 1602 652 1602 653 1602 652 490 652 1602 652 1602 652 1602 653 489 653 39949 9250 2179 653
+# OSC
+name: ROTATE
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 9231 4449 657 484 658 483 659 483 659 483 659 1595 659 1595 659 485 681 461 680 1601 652 1602 653 1601 653 1601 653 488 654 488 654 1602 653 1601 653 488 654 488 654 1602 653 1602 652 1602 652 488 654 488 654 1602 653 1601 653 1602 652 488 654 488 654 488 654 1602 652 1602 653 488 654 39978 9229 2174 654 96468 9259 2146 679
+#
+name: TIMER
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 9384 4452 658 485 657 484 658 484 659 485 657 1597 658 1597 682 487 655 488 654 1603 652 1603 653 1603 653 1604 653 491 653 491 653 1603 653 1603 653 1603 653 491 653 1604 652 490 654 1603 652 490 653 490 653 1603 652 490 653 1603 652 490 653 1603 652 490 653 1603 652 1603 652 490 653 39953 9263 2181 652
+#
+name: POWER
+type: parsed
+protocol: NEC
+address: 01 00 00 00
+command: 83 00 00 00
+#
+name: SPEED+
+type: parsed
+protocol: NEC
+address: 01 00 00 00
+command: 87 00 00 00
+#
+name: TIMER
+type: parsed
+protocol: NEC
+address: 01 00 00 00
+command: 8B 00 00 00
diff --git a/assets/resources/infrared/assets/projectors.ir b/assets/resources/infrared/assets/projectors.ir
index f30ee402a2..db90997a73 100644
--- a/assets/resources/infrared/assets/projectors.ir
+++ b/assets/resources/infrared/assets/projectors.ir
@@ -1,7 +1,7 @@
Filetype: IR library file
Version: 1
-# Last Updated 26th Dec, 2022
-# Last Checked 26th Dec, 2022
+# Last Updated 13th Jan, 2023
+# Last Checked 13th Jan, 2023
#
# ON
name: POWER
@@ -10,7 +10,7 @@ frequency: 38000
duty_cycle: 0.330000
data: 310 27591 171 27662 241 27731 307 27575 107 27749 306 27551 130 55520 243 27614 217 55584 129 27743 119 27756 115 27747 163 27712 308 27502 243 27650 217 27732 175 27693 167 27698 166 27689 171 27622 215 27712 133 27658 216 27716 129 27732 162 27698 305 27571 131 27753 310 27570 170 27707 162 27707 175 10960 9194 4518 618 542 618 543 725 434 672 1623 671 1647 646 514 592 568 592 568 592 1702 592 568 592 567 593 1702 592 568 618 1676 618 1676 618 1676 618 543 617 543 617 543 617 1677 617 544 616 544 616 544 616 544 616 1678 616 1678 616 1678 616 544 616 1678 616 1679 615 1678 616 1678 616 40239 9196 2250 617
#
-name: VOL +
+name: VOL+
type: parsed
protocol: NEC
address: 08 00 00 00
@@ -592,7 +592,7 @@ type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3523 1701 472 426 444 1269 472 426 444 426 442 429 443 427 443 426 444 426 444 426 443 427 442 429 440 430 439 432 438 1304 437 433 437 432 438 432 438 433 437 433 437 433 437 433 437 433 437 433 437 1304 437 433 437 433 437 433 437 1304 437 433 437 433 437 1304 437 433 437 434 436 433 437 434 436 434 436 434 436 433 437 433 437 434 436 1304 437 1305 436 1305 436 1305 436 1305 436 1305 436 434 436 434 436 1305 436 1305 436 1305 436 434 436 1305 436 1305 436 1306 435 1306 435 74393 3515 1736 437 433 437 1304 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 434 436 433 437 434 436 434 436 1304 437 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 1305 436 434 436 434 436 1306 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 436 434 435 435 1307 434 1331 410 1307 434 1307 434 1330 411 1307 434 460 410 460 410 1331 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 74393 3515 1736 437 433 437 1304 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 434 436 434 436 433 437 433 437 1304 437 434 436 434 436 434 437 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 1305 436 435 435 434 436 1305 436 434 436 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 1307 434 1306 435 1307 434 1307 434 1307 434 1331 410 460 410 460 410 1331 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 74393 3515 1736 437 433 437 1304 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 434 436 433 437 1304 437 433 437 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 437 1305 436 434 436 434 436 434 436 1305 436 434 436 434 436 1306 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 1307 434 1330 411 1330 411 1330 411 1330 411 1330 411 460 410 460 410 1331 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410
-# Standby/Off
+# OFF
name: POWER
type: raw
frequency: 38000
@@ -641,3 +641,140 @@ protocol: NEC
address: 02 00 00 00
command: 18 00 00 00
#
+name: POWER
+type: parsed
+protocol: NECext
+address: B8 57 00 00
+command: 0C F3 00 00
+#
+name: MUTE
+type: parsed
+protocol: NECext
+address: B8 57 00 00
+command: 0D F2 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: B8 57 00 00
+command: 1E E1 00 00
+#
+name: VOL+
+type: parsed
+protocol: NECext
+address: B8 57 00 00
+command: 1F E0 00 00
+#
+name: POWER
+type: parsed
+protocol: NEC
+address: 32 00 00 00
+command: 81 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 32 00 00 00
+command: 8F 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 32 00 00 00
+command: 8C 00 00 00
+#
+name: MUTE
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 9066 4428 608 507 609 1622 609 507 609 507 609 1623 608 1623 609 507 609 506 610 1623 609 507 609 1622 610 1623 608 507 609 506 610 1622 609 1623 609 506 610 1622 610 506 610 1623 637 478 690 425 638 478 637 1594 637 1594 664 451 636 1594 610 506 610 1621 611 1621 610 1621 610 505 611 40183 9065 2156 637 95953 9037 2185 608
+#
+name: POWER
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: A8 00 00 00
+#
+name: MUTE
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 88 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 9C 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 8C 00 00 00
+#
+name: POWER
+type: parsed
+protocol: NECext
+address: 87 45 00 00
+command: 17 E8 00 00
+#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 9064 4354 666 1559 666 1562 662 1586 638 475 636 477 635 477 635 478 635 1590 635 1591 634 478 635 1591 634 478 634 478 635 478 634 1591 635 478 634 1591 634 478 635 478 634 478 635 1591 634 478 634 1591 635 478 634 478 634 1591 634 1591 635 1591 634 478 635 1591 634 478 634 1591 635 40957 9035 2144 634 95483 9047 2155 632 95484 9048 2153 633
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 87 45 00 00
+command: 50 AF 00 00
+#
+name: MUTE
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 9034 4385 638 1587 664 1562 663 1587 637 476 635 478 634 478 635 478 635 1591 634 1591 634 478 635 1591 635 478 634 478 635 478 635 1591 635 478 634 478 634 1591 634 478 635 479 634 1591 635 478 634 1591 635 478 634 1592 634 478 634 1591 635 1591 635 478 634 1592 634 478 634 1591 634 40958 9033 2144 635
+#
+name: POWER
+type: parsed
+protocol: NECext
+address: FF FF 00 00
+command: E8 17 00 00
+#
+name: VOL+
+type: parsed
+protocol: NECext
+address: FF FF 00 00
+command: BD 42 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: FF FF 00 00
+command: F2 0D 00 00
+#
+name: POWER
+type: parsed
+protocol: Kaseikyo
+address: 41 54 32 00
+command: 05 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: Kaseikyo
+address: 41 54 32 00
+command: 70 01 00 00
+#
+name: VOL-
+type: parsed
+protocol: Kaseikyo
+address: 41 54 32 00
+command: 71 01 00 00
+#
+name: POWER
+type: parsed
+protocol: NEC
+address: 31 00 00 00
+command: 81 00 00 00
diff --git a/assets/resources/infrared/assets/tv.ir b/assets/resources/infrared/assets/tv.ir
index a4df4d4c47..6126a6239e 100644
--- a/assets/resources/infrared/assets/tv.ir
+++ b/assets/resources/infrared/assets/tv.ir
@@ -1,7 +1,115 @@
Filetype: IR library file
Version: 1
-# Last Updated 20th Dec, 2022
-# Last Checked 26th Dec, 2022
+# Last Updated 13th Jan, 2023
+# Last Checked 13th Jan, 2023
+#
+name: POWER
+type: parsed
+protocol: SIRC
+address: 01 00 00 00
+command: 15 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: SIRC
+address: 01 00 00 00
+command: 12 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: SIRC
+address: 01 00 00 00
+command: 13 00 00 00
+#
+name: CH+
+type: parsed
+protocol: SIRC
+address: 01 00 00 00
+command: 10 00 00 00
+#
+name: CH-
+type: parsed
+protocol: SIRC
+address: 01 00 00 00
+command: 11 00 00 00
+#
+name: MUTE
+type: parsed
+protocol: SIRC
+address: 01 00 00 00
+command: 14 00 00 00
+#
+name: POWER
+type: parsed
+protocol: NEC
+address: 40 00 00 00
+command: 0B 00 00 00
+#
+name: CH+
+type: parsed
+protocol: NEC
+address: 40 00 00 00
+command: 11 00 00 00
+#
+name: CH-
+type: parsed
+protocol: NEC
+address: 40 00 00 00
+command: 10 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 40 00 00 00
+command: 13 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 40 00 00 00
+command: 12 00 00 00
+#
+name: MUTE
+type: parsed
+protocol: NEC
+address: 40 00 00 00
+command: 14 00 00 00
+#
+name: POWER
+type: parsed
+protocol: Kaseikyo
+address: 80 02 20 00
+command: D0 03 00 00
+#
+name: VOL+
+type: parsed
+protocol: Kaseikyo
+address: 80 02 20 00
+command: 00 02 00 00
+#
+name: VOL-
+type: parsed
+protocol: Kaseikyo
+address: 80 02 20 00
+command: 10 02 00 00
+#
+name: MUTE
+type: parsed
+protocol: Kaseikyo
+address: 80 02 20 00
+command: 20 03 00 00
+#
+name: CH+
+type: parsed
+protocol: Kaseikyo
+address: 80 02 20 00
+command: 40 03 00 00
+#
+name: CH-
+type: parsed
+protocol: Kaseikyo
+address: 80 02 20 00
+command: 50 03 00 00
#
name: POWER
type: parsed
@@ -51,42 +159,6 @@ protocol: NECext
address: 00 7F 00 00
command: 18 E7 00 00
#
-name: POWER
-type: parsed
-protocol: Kaseikyo
-address: 80 02 20 00
-command: D0 03 00 00
-#
-name: MUTE
-type: parsed
-protocol: Kaseikyo
-address: 80 02 20 00
-command: 20 03 00 00
-#
-name: VOL+
-type: parsed
-protocol: Kaseikyo
-address: 80 02 20 00
-command: 00 02 00 00
-#
-name: VOL-
-type: parsed
-protocol: Kaseikyo
-address: 80 02 20 00
-command: 10 02 00 00
-#
-name: CH+
-type: parsed
-protocol: Kaseikyo
-address: 80 02 20 00
-command: 40 03 00 00
-#
-name: CH-
-type: parsed
-protocol: Kaseikyo
-address: 80 02 20 00
-command: 50 03 00 00
-#
name: MUTE
type: parsed
protocol: NECext
@@ -283,12 +355,6 @@ command: E9 16 00 00
name: POWER
type: parsed
protocol: SIRC
-address: 01 00 00 00
-command: 15 00 00 00
-#
-name: POWER
-type: parsed
-protocol: SIRC
address: 10 00 00 00
command: 15 00 00 00
#
@@ -420,12 +486,6 @@ command: 17 00 00 00
#
name: POWER
type: parsed
-protocol: NEC
-address: 40 00 00 00
-command: 12 00 00 00
-#
-name: POWER
-type: parsed
protocol: NECext
address: 31 49 00 00
command: 63 00 00 00
@@ -1083,61 +1143,19 @@ type: parsed
protocol: RC6
address: 00 00 00 00
command: 0D 00 00 00
-#
+# Samsung Standby
name: POWER
type: parsed
protocol: Samsung32
address: 07 00 00 00
command: E0 00 00 00
-#
-name: VOL-
-type: parsed
-protocol: Samsung32
-address: 07 00 00 00
-command: 23 00 00 00
-#
-name: CH-
-type: parsed
-protocol: Samsung32
-address: 07 00 00 00
-command: 13 00 00 00
-#
+# Samsung Power Off
name: POWER
type: parsed
protocol: Samsung32
address: 07 00 00 00
command: 98 00 00 00
#
-name: VOL+
-type: parsed
-protocol: SIRC
-address: 01 00 00 00
-command: 12 00 00 00
-#
-name: VOL-
-type: parsed
-protocol: SIRC
-address: 01 00 00 00
-command: 13 00 00 00
-#
-name: CH+
-type: parsed
-protocol: SIRC
-address: 01 00 00 00
-command: 10 00 00 00
-#
-name: CH-
-type: parsed
-protocol: SIRC
-address: 01 00 00 00
-command: 11 00 00 00
-#
-name: MUTE
-type: parsed
-protocol: SIRC
-address: 01 00 00 00
-command: 14 00 00 00
-#
name: POWER
type: parsed
protocol: SIRC
@@ -1192,12 +1210,6 @@ protocol: NEC
address: 40 00 00 00
command: 1E 00 00 00
#
-name: MUTE
-type: parsed
-protocol: NEC
-address: 40 00 00 00
-command: 10 00 00 00
-#
name: CH+
type: parsed
protocol: NEC
@@ -1773,4 +1785,39 @@ type: parsed
protocol: NEC
address: 00 00 00 00
command: 33 00 00 00
+#
+name: POWER
+type: parsed
+protocol: NEC
+address: 28 00 00 00
+command: 0B 00 00 00
+#
+name: CH+
+type: parsed
+protocol: NEC
+address: 28 00 00 00
+command: 0C 00 00 00
+#
+name: CH-
+type: parsed
+protocol: NEC
+address: 28 00 00 00
+command: 0D 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 28 00 00 00
+command: 0E 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 28 00 00 00
+command: 0F 00 00 00
#
+name: MUTE
+type: parsed
+protocol: NEC
+address: 28 00 00 00
+command: 10 00 00 00
diff --git a/assets/resources/infrared/ir_remote/Roku.txt b/assets/resources/infrared/ir_remote/Roku.txt
deleted file mode 100644
index d9778d3ec0..0000000000
--- a/assets/resources/infrared/ir_remote/Roku.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-REMOTE: /ext/infrared/Roku.ir
-UP: Up
-DOWN: Down
-LEFT: Left
-RIGHT: Right
-OK: Ok
-BACK: Back
-UPHOLD: V_up
-DOWNHOLD: V_down
-LEFTHOLD: Play
-RIGHTHOLD: Home
-OKHOLD: Power
\ No newline at end of file
diff --git a/assets/resources/subghz/assets/setting_user.txt b/assets/resources/subghz/assets/setting_user.txt
index 0926f6bd71..06a699a6c0 100644
--- a/assets/resources/subghz/assets/setting_user.txt
+++ b/assets/resources/subghz/assets/setting_user.txt
@@ -49,6 +49,7 @@ Frequency: 434620000
Frequency: 434775000
Frequency: 438900000
Frequency: 440175000
+Frequency: 446000000
Frequency: 464000000
Frequency: 779000000
Frequency: 868350000
diff --git a/fbt_options.py b/fbt_options.py
index a54f2595fb..0458ea03bc 100644
--- a/fbt_options.py
+++ b/fbt_options.py
@@ -14,7 +14,7 @@
# Suffix to add to files when building distribution
# If OS environment has DIST_SUFFIX set, it will be used instead
-DIST_SUFFIX = "XFW-0037_01072023"
+DIST_SUFFIX = "XFW-0039_01172023"
# Coprocessor firmware
COPRO_OB_DATA = "scripts/ob.data"
diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv
index 9e38f6970d..42ea150dfe 100644
--- a/firmware/targets/f7/api_symbols.csv
+++ b/firmware/targets/f7/api_symbols.csv
@@ -1,5 +1,5 @@
entry,status,name,type,params
-Version,+,12.0,,
+Version,+,12.3,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
@@ -1659,6 +1659,7 @@ Function,+,infrared_get_protocol_by_name,InfraredProtocol,const char*
Function,+,infrared_get_protocol_command_length,uint8_t,InfraredProtocol
Function,+,infrared_get_protocol_duty_cycle,float,InfraredProtocol
Function,+,infrared_get_protocol_frequency,uint32_t,InfraredProtocol
+Function,+,infrared_get_protocol_min_repeat_count,size_t,InfraredProtocol
Function,+,infrared_get_protocol_name,const char*,InfraredProtocol
Function,+,infrared_is_protocol_valid,_Bool,InfraredProtocol
Function,+,infrared_reset_decoder,void,InfraredDecoderHandler*
@@ -1912,7 +1913,7 @@ Function,-,mf_classic_dict_is_key_present,_Bool,"MfClassicDict*, uint8_t*"
Function,-,mf_classic_dict_is_key_present_str,_Bool,"MfClassicDict*, FuriString*"
Function,-,mf_classic_dict_rewind,_Bool,MfClassicDict*
Function,-,mf_classic_emulator,_Bool,"MfClassicEmulator*, FuriHalNfcTxRxContext*"
-Function,-,mf_classic_get_classic_type,MfClassicType,"int8_t, uint8_t, uint8_t"
+Function,-,mf_classic_get_classic_type,MfClassicType,"uint8_t, uint8_t, uint8_t"
Function,-,mf_classic_get_read_sectors_and_keys,void,"MfClassicData*, uint8_t*, uint8_t*"
Function,-,mf_classic_get_sector_by_block,uint8_t,uint8_t
Function,-,mf_classic_get_sector_trailer_block_num_by_sector,uint8_t,uint8_t
@@ -3189,6 +3190,7 @@ Function,+,subghz_worker_free,void,SubGhzWorker*
Function,+,subghz_worker_is_running,_Bool,SubGhzWorker*
Function,+,subghz_worker_rx_callback,void,"_Bool, uint32_t, void*"
Function,+,subghz_worker_set_context,void,"SubGhzWorker*, void*"
+Function,+,subghz_worker_set_filter,void,"SubGhzWorker*, uint16_t"
Function,+,subghz_worker_set_overrun_callback,void,"SubGhzWorker*, SubGhzWorkerOverrunCallback"
Function,+,subghz_worker_set_pair_callback,void,"SubGhzWorker*, SubGhzWorkerPairCallback"
Function,+,subghz_worker_start,void,SubGhzWorker*
@@ -4408,6 +4410,7 @@ Function,+,validator_is_file_callback,_Bool,"const char*, FuriString*, void*"
Function,+,validator_is_file_free,void,ValidatorIsFile*
Function,+,value_index_bool,uint8_t,"const _Bool, const _Bool[], uint8_t"
Function,+,value_index_float,uint8_t,"const float, const float[], uint8_t"
+Function,+,value_index_int32,uint8_t,"const int32_t, const int32_t[], uint8_t"
Function,+,value_index_uint32,uint8_t,"const uint32_t, const uint32_t[], uint8_t"
Function,+,variable_item_get_context,void*,VariableItem*
Function,+,variable_item_get_current_value_index,uint8_t,VariableItem*
diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c
index 0857fe4ee5..4e10b90d7b 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_bt.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c
@@ -218,8 +218,8 @@ bool furi_hal_bt_start_app(FuriHalBtProfile profile, GapEventCallback event_cb,
} else if(profile == FuriHalBtProfileHidKeyboard) {
// Change MAC address for HID profile
config->mac_address[2]++;
- // Change name Flipper -> Control
- const char* clicker_str = "Control";
+ // Change name Flipper -> Flipper Remote
+ const char* clicker_str = "Flipper Remote";
memcpy(&config->adv_name[1], clicker_str, strlen(clicker_str));
}
if(!gap_init(config, event_cb, context)) {
diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c
index 74f9d334f0..fdeb5c7427 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c
@@ -354,7 +354,7 @@ bool furi_hal_subghz_is_tx_allowed(uint32_t value) {
!(value >= 915000000 && value <= 928000000)) {
} else {
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
- if((value >= 304100000 && value <= 321950000) &&
+ if(value <= 321950000 &&
((furi_hal_subghz.preset == FuriHalSubGhzPresetOok270Async) ||
(furi_hal_subghz.preset == FuriHalSubGhzPresetOok650Async))) {
furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable_au);
diff --git a/firmware/targets/f7/furi_hal/furi_hal_version.c b/firmware/targets/f7/furi_hal/furi_hal_version.c
index e59cbd0407..418dda10a7 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_version.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_version.c
@@ -94,7 +94,10 @@ void furi_hal_version_set_custom_name(const char* name) {
if((name != NULL) && ((strlen(name) >= 1) && (strlen(name) <= 8))) {
strlcpy(furi_hal_version.name, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH);
snprintf(
- furi_hal_version.device_name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH, "xFlipper %s", name);
+ furi_hal_version.device_name,
+ FURI_HAL_VERSION_DEVICE_NAME_LENGTH,
+ "x%s", // Someone tell me why that X is needed
+ name);
furi_hal_version.device_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME;
}
@@ -106,7 +109,7 @@ static void furi_hal_version_set_name(const char* name) {
snprintf(
furi_hal_version.device_name,
FURI_HAL_VERSION_DEVICE_NAME_LENGTH,
- "xFlipper %s",
+ "x%s", // Someone tell me why that X is needed
furi_hal_version.name);
} else {
snprintf(furi_hal_version.device_name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH, "xFlipper");
diff --git a/lib/flipper_application/elf/elf_file.c b/lib/flipper_application/elf/elf_file.c
index bf98650a25..64d5755efa 100644
--- a/lib/flipper_application/elf/elf_file.c
+++ b/lib/flipper_application/elf/elf_file.c
@@ -315,6 +315,7 @@ static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf3
FURI_LOG_D(TAG, " R_ARM_ABS32 relocated is 0x%08X", (unsigned int)*((uint32_t*)relAddr));
break;
case R_ARM_THM_PC22:
+ case R_ARM_CALL:
case R_ARM_THM_JUMP24:
elf_relocate_jmp_call(elf, relAddr, type, symAddr);
FURI_LOG_D(
diff --git a/lib/infrared/encoder_decoder/common/infrared_common_decoder.c b/lib/infrared/encoder_decoder/common/infrared_common_decoder.c
index 8acb6751ba..d67b204f52 100644
--- a/lib/infrared/encoder_decoder/common/infrared_common_decoder.c
+++ b/lib/infrared/encoder_decoder/common/infrared_common_decoder.c
@@ -1,11 +1,8 @@
+#include "infrared_common_i.h"
+
+#include
#include
#include
-#include "infrared.h"
-#include "infrared_common_i.h"
-#include
-#include
-#include "infrared_i.h"
-#include
static void infrared_common_decoder_reset_state(InfraredCommonDecoder* decoder);
diff --git a/lib/infrared/encoder_decoder/common/infrared_common_encoder.c b/lib/infrared/encoder_decoder/common/infrared_common_encoder.c
index 9c774617e9..f145a585a9 100644
--- a/lib/infrared/encoder_decoder/common/infrared_common_encoder.c
+++ b/lib/infrared/encoder_decoder/common/infrared_common_encoder.c
@@ -1,10 +1,9 @@
-#include
-#include "infrared.h"
#include "infrared_common_i.h"
-#include
-#include
-#include "infrared_i.h"
-#include
+
+#include
+#include
+#include
+#include
static InfraredStatus
infrared_common_encode_bits(InfraredCommonEncoder* encoder, uint32_t* duration, bool* level) {
diff --git a/lib/infrared/encoder_decoder/common/infrared_common_protocol_defs.c b/lib/infrared/encoder_decoder/common/infrared_common_protocol_defs.c
deleted file mode 100644
index 3dd26e9d87..0000000000
--- a/lib/infrared/encoder_decoder/common/infrared_common_protocol_defs.c
+++ /dev/null
@@ -1,140 +0,0 @@
-#include "infrared_common_i.h"
-#include "infrared_protocol_defs_i.h"
-
-const InfraredCommonProtocolSpec protocol_nec = {
- .timings =
- {
- .preamble_mark = INFRARED_NEC_PREAMBLE_MARK,
- .preamble_space = INFRARED_NEC_PREAMBLE_SPACE,
- .bit1_mark = INFRARED_NEC_BIT1_MARK,
- .bit1_space = INFRARED_NEC_BIT1_SPACE,
- .bit0_mark = INFRARED_NEC_BIT0_MARK,
- .bit0_space = INFRARED_NEC_BIT0_SPACE,
- .preamble_tolerance = INFRARED_NEC_PREAMBLE_TOLERANCE,
- .bit_tolerance = INFRARED_NEC_BIT_TOLERANCE,
- .silence_time = INFRARED_NEC_SILENCE,
- .min_split_time = INFRARED_NEC_MIN_SPLIT_TIME,
- },
- .databit_len[0] = 42,
- .databit_len[1] = 32,
- .no_stop_bit = false,
- .decode = infrared_common_decode_pdwm,
- .encode = infrared_common_encode_pdwm,
- .interpret = infrared_decoder_nec_interpret,
- .decode_repeat = infrared_decoder_nec_decode_repeat,
- .encode_repeat = infrared_encoder_nec_encode_repeat,
-};
-
-const InfraredCommonProtocolSpec protocol_samsung32 = {
- .timings =
- {
- .preamble_mark = INFRARED_SAMSUNG_PREAMBLE_MARK,
- .preamble_space = INFRARED_SAMSUNG_PREAMBLE_SPACE,
- .bit1_mark = INFRARED_SAMSUNG_BIT1_MARK,
- .bit1_space = INFRARED_SAMSUNG_BIT1_SPACE,
- .bit0_mark = INFRARED_SAMSUNG_BIT0_MARK,
- .bit0_space = INFRARED_SAMSUNG_BIT0_SPACE,
- .preamble_tolerance = INFRARED_SAMSUNG_PREAMBLE_TOLERANCE,
- .bit_tolerance = INFRARED_SAMSUNG_BIT_TOLERANCE,
- .silence_time = INFRARED_SAMSUNG_SILENCE,
- .min_split_time = INFRARED_SAMSUNG_MIN_SPLIT_TIME,
- },
- .databit_len[0] = 32,
- .no_stop_bit = false,
- .decode = infrared_common_decode_pdwm,
- .encode = infrared_common_encode_pdwm,
- .interpret = infrared_decoder_samsung32_interpret,
- .decode_repeat = infrared_decoder_samsung32_decode_repeat,
- .encode_repeat = infrared_encoder_samsung32_encode_repeat,
-};
-
-const InfraredCommonProtocolSpec protocol_rc6 = {
- .timings =
- {
- .preamble_mark = INFRARED_RC6_PREAMBLE_MARK,
- .preamble_space = INFRARED_RC6_PREAMBLE_SPACE,
- .bit1_mark = INFRARED_RC6_BIT,
- .preamble_tolerance = INFRARED_RC6_PREAMBLE_TOLERANCE,
- .bit_tolerance = INFRARED_RC6_BIT_TOLERANCE,
- .silence_time = INFRARED_RC6_SILENCE,
- .min_split_time = INFRARED_RC6_MIN_SPLIT_TIME,
- },
- .databit_len[0] =
- 1 + 3 + 1 + 8 +
- 8, // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command
- .manchester_start_from_space = false,
- .decode = infrared_decoder_rc6_decode_manchester,
- .encode = infrared_encoder_rc6_encode_manchester,
- .interpret = infrared_decoder_rc6_interpret,
- .decode_repeat = NULL,
- .encode_repeat = NULL,
-};
-
-const InfraredCommonProtocolSpec protocol_rc5 = {
- .timings =
- {
- .preamble_mark = 0,
- .preamble_space = 0,
- .bit1_mark = INFRARED_RC5_BIT,
- .preamble_tolerance = 0,
- .bit_tolerance = INFRARED_RC5_BIT_TOLERANCE,
- .silence_time = INFRARED_RC5_SILENCE,
- .min_split_time = INFRARED_RC5_MIN_SPLIT_TIME,
- },
- .databit_len[0] = 1 + 1 + 1 + 5 +
- 6, // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command
- .manchester_start_from_space = true,
- .decode = infrared_common_decode_manchester,
- .encode = infrared_common_encode_manchester,
- .interpret = infrared_decoder_rc5_interpret,
- .decode_repeat = NULL,
- .encode_repeat = NULL,
-};
-
-const InfraredCommonProtocolSpec protocol_sirc = {
- .timings =
- {
- .preamble_mark = INFRARED_SIRC_PREAMBLE_MARK,
- .preamble_space = INFRARED_SIRC_PREAMBLE_SPACE,
- .bit1_mark = INFRARED_SIRC_BIT1_MARK,
- .bit1_space = INFRARED_SIRC_BIT1_SPACE,
- .bit0_mark = INFRARED_SIRC_BIT0_MARK,
- .bit0_space = INFRARED_SIRC_BIT0_SPACE,
- .preamble_tolerance = INFRARED_SIRC_PREAMBLE_TOLERANCE,
- .bit_tolerance = INFRARED_SIRC_BIT_TOLERANCE,
- .silence_time = INFRARED_SIRC_SILENCE,
- .min_split_time = INFRARED_SIRC_MIN_SPLIT_TIME,
- },
- .databit_len[0] = 20,
- .databit_len[1] = 15,
- .databit_len[2] = 12,
- .no_stop_bit = true,
- .decode = infrared_common_decode_pdwm,
- .encode = infrared_common_encode_pdwm,
- .interpret = infrared_decoder_sirc_interpret,
- .decode_repeat = NULL,
- .encode_repeat = infrared_encoder_sirc_encode_repeat,
-};
-
-const InfraredCommonProtocolSpec protocol_kaseikyo = {
- .timings =
- {
- .preamble_mark = INFRARED_KASEIKYO_PREAMBLE_MARK,
- .preamble_space = INFRARED_KASEIKYO_PREAMBLE_SPACE,
- .bit1_mark = INFRARED_KASEIKYO_BIT1_MARK,
- .bit1_space = INFRARED_KASEIKYO_BIT1_SPACE,
- .bit0_mark = INFRARED_KASEIKYO_BIT0_MARK,
- .bit0_space = INFRARED_KASEIKYO_BIT0_SPACE,
- .preamble_tolerance = INFRARED_KASEIKYO_PREAMBLE_TOLERANCE,
- .bit_tolerance = INFRARED_KASEIKYO_BIT_TOLERANCE,
- .silence_time = INFRARED_KASEIKYO_SILENCE,
- .min_split_time = INFRARED_KASEIKYO_MIN_SPLIT_TIME,
- },
- .databit_len[0] = 48,
- .no_stop_bit = false,
- .decode = infrared_common_decode_pdwm,
- .encode = infrared_common_encode_pdwm,
- .interpret = infrared_decoder_kaseikyo_interpret,
- .decode_repeat = NULL,
- .encode_repeat = NULL,
-};
diff --git a/lib/infrared/encoder_decoder/infrared.c b/lib/infrared/encoder_decoder/infrared.c
index 2c5ef0fffd..fcfc5da2b2 100644
--- a/lib/infrared/encoder_decoder/infrared.c
+++ b/lib/infrared/encoder_decoder/infrared.c
@@ -1,13 +1,16 @@
#include "infrared.h"
-#include
-#include "common/infrared_common_i.h"
-#include "infrared_protocol_defs_i.h"
-#include
-#include
+
#include
-#include
-#include "infrared_i.h"
-#include
+#include
+#include
+#include
+
+#include "nec/infrared_protocol_nec.h"
+#include "samsung/infrared_protocol_samsung.h"
+#include "rc5/infrared_protocol_rc5.h"
+#include "rc6/infrared_protocol_rc6.h"
+#include "sirc/infrared_protocol_sirc.h"
+#include "kaseikyo/infrared_protocol_kaseikyo.h"
typedef struct {
InfraredAlloc alloc;
@@ -36,7 +39,7 @@ struct InfraredEncoderHandler {
typedef struct {
InfraredEncoders encoder;
InfraredDecoders decoder;
- InfraredGetProtocolSpec get_protocol_spec;
+ InfraredGetProtocolVariant get_protocol_variant;
} InfraredEncoderDecoder;
static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
@@ -52,7 +55,7 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
.encode = infrared_encoder_nec_encode,
.reset = infrared_encoder_nec_reset,
.free = infrared_encoder_nec_free},
- .get_protocol_spec = infrared_nec_get_spec,
+ .get_protocol_variant = infrared_protocol_nec_get_variant,
},
{
.decoder =
@@ -66,7 +69,7 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
.encode = infrared_encoder_samsung32_encode,
.reset = infrared_encoder_samsung32_reset,
.free = infrared_encoder_samsung32_free},
- .get_protocol_spec = infrared_samsung32_get_spec,
+ .get_protocol_variant = infrared_protocol_samsung32_get_variant,
},
{
.decoder =
@@ -80,7 +83,7 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
.encode = infrared_encoder_rc5_encode,
.reset = infrared_encoder_rc5_reset,
.free = infrared_encoder_rc5_free},
- .get_protocol_spec = infrared_rc5_get_spec,
+ .get_protocol_variant = infrared_protocol_rc5_get_variant,
},
{
.decoder =
@@ -94,7 +97,7 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
.encode = infrared_encoder_rc6_encode,
.reset = infrared_encoder_rc6_reset,
.free = infrared_encoder_rc6_free},
- .get_protocol_spec = infrared_rc6_get_spec,
+ .get_protocol_variant = infrared_protocol_rc6_get_variant,
},
{
.decoder =
@@ -108,7 +111,7 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
.encode = infrared_encoder_sirc_encode,
.reset = infrared_encoder_sirc_reset,
.free = infrared_encoder_sirc_free},
- .get_protocol_spec = infrared_sirc_get_spec,
+ .get_protocol_variant = infrared_protocol_sirc_get_variant,
},
{
.decoder =
@@ -122,13 +125,12 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
.encode = infrared_encoder_kaseikyo_encode,
.reset = infrared_encoder_kaseikyo_reset,
.free = infrared_encoder_kaseikyo_free},
- .get_protocol_spec = infrared_kaseikyo_get_spec,
+ .get_protocol_variant = infrared_protocol_kaseikyo_get_variant,
},
};
static int infrared_find_index_by_protocol(InfraredProtocol protocol);
-static const InfraredProtocolSpecification*
- infrared_get_spec_by_protocol(InfraredProtocol protocol);
+static const InfraredProtocolVariant* infrared_get_variant_by_protocol(InfraredProtocol protocol);
const InfraredMessage*
infrared_decode(InfraredDecoderHandler* handler, bool level, uint32_t duration) {
@@ -224,7 +226,7 @@ void infrared_free_encoder(InfraredEncoderHandler* handler) {
static int infrared_find_index_by_protocol(InfraredProtocol protocol) {
for(size_t i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) {
- if(infrared_encoder_decoder[i].get_protocol_spec(protocol)) {
+ if(infrared_encoder_decoder[i].get_protocol_variant(protocol)) {
return i;
}
}
@@ -282,34 +284,37 @@ InfraredProtocol infrared_get_protocol_by_name(const char* protocol_name) {
return InfraredProtocolUnknown;
}
-static const InfraredProtocolSpecification*
- infrared_get_spec_by_protocol(InfraredProtocol protocol) {
+static const InfraredProtocolVariant* infrared_get_variant_by_protocol(InfraredProtocol protocol) {
int index = infrared_find_index_by_protocol(protocol);
- const InfraredProtocolSpecification* spec = NULL;
+ const InfraredProtocolVariant* variant = NULL;
if(index >= 0) {
- spec = infrared_encoder_decoder[index].get_protocol_spec(protocol);
+ variant = infrared_encoder_decoder[index].get_protocol_variant(protocol);
}
- furi_assert(spec);
- return spec;
+ furi_assert(variant);
+ return variant;
}
const char* infrared_get_protocol_name(InfraredProtocol protocol) {
- return infrared_get_spec_by_protocol(protocol)->name;
+ return infrared_get_variant_by_protocol(protocol)->name;
}
uint8_t infrared_get_protocol_address_length(InfraredProtocol protocol) {
- return infrared_get_spec_by_protocol(protocol)->address_length;
+ return infrared_get_variant_by_protocol(protocol)->address_length;
}
uint8_t infrared_get_protocol_command_length(InfraredProtocol protocol) {
- return infrared_get_spec_by_protocol(protocol)->command_length;
+ return infrared_get_variant_by_protocol(protocol)->command_length;
}
uint32_t infrared_get_protocol_frequency(InfraredProtocol protocol) {
- return infrared_get_spec_by_protocol(protocol)->frequency;
+ return infrared_get_variant_by_protocol(protocol)->frequency;
}
float infrared_get_protocol_duty_cycle(InfraredProtocol protocol) {
- return infrared_get_spec_by_protocol(protocol)->duty_cycle;
+ return infrared_get_variant_by_protocol(protocol)->duty_cycle;
+}
+
+size_t infrared_get_protocol_min_repeat_count(InfraredProtocol protocol) {
+ return infrared_get_variant_by_protocol(protocol)->repeat_count;
}
diff --git a/lib/infrared/encoder_decoder/infrared.h b/lib/infrared/encoder_decoder/infrared.h
index 2c76645fff..3ab46cbbf5 100644
--- a/lib/infrared/encoder_decoder/infrared.h
+++ b/lib/infrared/encoder_decoder/infrared.h
@@ -1,6 +1,7 @@
#pragma once
#include
+#include
#include
#ifdef __cplusplus
@@ -201,6 +202,15 @@ uint32_t infrared_get_protocol_frequency(InfraredProtocol protocol);
*/
float infrared_get_protocol_duty_cycle(InfraredProtocol protocol);
+/**
+ * Get the minimum count of signal repeats for the selected protocol
+ *
+ * \param[in] protocol - protocol to get the repeat count from
+ *
+ * \return repeat count
+ */
+size_t infrared_get_protocol_min_repeat_count(InfraredProtocol protocol);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/infrared/encoder_decoder/infrared_i.h b/lib/infrared/encoder_decoder/infrared_i.h
index 3a645cede8..3efc41cd67 100644
--- a/lib/infrared/encoder_decoder/infrared_i.h
+++ b/lib/infrared/encoder_decoder/infrared_i.h
@@ -22,9 +22,10 @@ typedef struct {
uint8_t command_length;
uint32_t frequency;
float duty_cycle;
-} InfraredProtocolSpecification;
+ size_t repeat_count;
+} InfraredProtocolVariant;
-typedef const InfraredProtocolSpecification* (*InfraredGetProtocolSpec)(InfraredProtocol protocol);
+typedef const InfraredProtocolVariant* (*InfraredGetProtocolVariant)(InfraredProtocol protocol);
typedef void* (*InfraredAlloc)(void);
typedef void (*InfraredFree)(void*);
diff --git a/lib/infrared/encoder_decoder/infrared_protocol_defs_i.h b/lib/infrared/encoder_decoder/infrared_protocol_defs_i.h
deleted file mode 100644
index 6146f7b4e2..0000000000
--- a/lib/infrared/encoder_decoder/infrared_protocol_defs_i.h
+++ /dev/null
@@ -1,320 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-#include "infrared.h"
-#include "common/infrared_common_i.h"
-
-/***************************************************************************************************
-* NEC protocol description
-* https://radioparty.ru/manuals/encyclopedia/213-ircontrol?start=1
-****************************************************************************************************
-* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble Stop
-* mark space Modulation up to period repeat repeat bit
-* mark space
-*
-* 9000 4500 32 bit + stop bit ...110000 9000 2250
-* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ ___________ _
-* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ________________ ____________ ___
-*
-***************************************************************************************************/
-
-#define INFRARED_NEC_PREAMBLE_MARK 9000
-#define INFRARED_NEC_PREAMBLE_SPACE 4500
-#define INFRARED_NEC_BIT1_MARK 560
-#define INFRARED_NEC_BIT1_SPACE 1690
-#define INFRARED_NEC_BIT0_MARK 560
-#define INFRARED_NEC_BIT0_SPACE 560
-#define INFRARED_NEC_REPEAT_PERIOD 110000
-#define INFRARED_NEC_SILENCE INFRARED_NEC_REPEAT_PERIOD
-#define INFRARED_NEC_MIN_SPLIT_TIME INFRARED_NEC_REPEAT_PAUSE_MIN
-#define INFRARED_NEC_REPEAT_PAUSE_MIN 4000
-#define INFRARED_NEC_REPEAT_PAUSE_MAX 150000
-#define INFRARED_NEC_REPEAT_MARK 9000
-#define INFRARED_NEC_REPEAT_SPACE 2250
-#define INFRARED_NEC_PREAMBLE_TOLERANCE 200 // us
-#define INFRARED_NEC_BIT_TOLERANCE 120 // us
-
-void* infrared_decoder_nec_alloc(void);
-void infrared_decoder_nec_reset(void* decoder);
-void infrared_decoder_nec_free(void* decoder);
-InfraredMessage* infrared_decoder_nec_check_ready(void* decoder);
-InfraredMessage* infrared_decoder_nec_decode(void* decoder, bool level, uint32_t duration);
-void* infrared_encoder_nec_alloc(void);
-InfraredStatus infrared_encoder_nec_encode(void* encoder_ptr, uint32_t* duration, bool* level);
-void infrared_encoder_nec_reset(void* encoder_ptr, const InfraredMessage* message);
-void infrared_encoder_nec_free(void* encoder_ptr);
-bool infrared_decoder_nec_interpret(InfraredCommonDecoder* decoder);
-InfraredStatus infrared_decoder_nec_decode_repeat(InfraredCommonDecoder* decoder);
-InfraredStatus infrared_encoder_nec_encode_repeat(
- InfraredCommonEncoder* encoder,
- uint32_t* duration,
- bool* level);
-const InfraredProtocolSpecification* infrared_nec_get_spec(InfraredProtocol protocol);
-
-extern const InfraredCommonProtocolSpec protocol_nec;
-
-/***************************************************************************************************
-* SAMSUNG32 protocol description
-* https://www.mikrocontroller.net/articles/IRMP_-_english#SAMSUNG
-****************************************************************************************************
-* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble Bit1 Stop
-* mark space Modulation repeat repeat bit
-* mark space
-*
-* 4500 4500 32 bit + stop bit 40000/100000 4500 4500
-* __________ _ _ _ _ _ _ _ _ _ _ _ ___________ _ _
-* _ __________ __ _ __ __ __ _ _ __ __ _ ________________ ____________ ____ ___
-*
-***************************************************************************************************/
-
-#define INFRARED_SAMSUNG_PREAMBLE_MARK 4500
-#define INFRARED_SAMSUNG_PREAMBLE_SPACE 4500
-#define INFRARED_SAMSUNG_BIT1_MARK 550
-#define INFRARED_SAMSUNG_BIT1_SPACE 1650
-#define INFRARED_SAMSUNG_BIT0_MARK 550
-#define INFRARED_SAMSUNG_BIT0_SPACE 550
-#define INFRARED_SAMSUNG_REPEAT_PAUSE_MIN 30000
-#define INFRARED_SAMSUNG_REPEAT_PAUSE1 46000
-#define INFRARED_SAMSUNG_REPEAT_PAUSE2 97000
-/* Samsung silence have to be greater than REPEAT MAX
- * otherwise there can be problems during unit tests parsing
- * of some data. Real tolerances we don't know, but in real life
- * silence time should be greater than max repeat time. This is
- * because of similar preambule timings for repeat and first messages. */
-#define INFRARED_SAMSUNG_MIN_SPLIT_TIME 5000
-#define INFRARED_SAMSUNG_SILENCE 145000
-#define INFRARED_SAMSUNG_REPEAT_PAUSE_MAX 140000
-#define INFRARED_SAMSUNG_REPEAT_MARK 4500
-#define INFRARED_SAMSUNG_REPEAT_SPACE 4500
-#define INFRARED_SAMSUNG_PREAMBLE_TOLERANCE 200 // us
-#define INFRARED_SAMSUNG_BIT_TOLERANCE 120 // us
-
-void* infrared_decoder_samsung32_alloc(void);
-void infrared_decoder_samsung32_reset(void* decoder);
-void infrared_decoder_samsung32_free(void* decoder);
-InfraredMessage* infrared_decoder_samsung32_check_ready(void* ctx);
-InfraredMessage* infrared_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration);
-InfraredStatus
- infrared_encoder_samsung32_encode(void* encoder_ptr, uint32_t* duration, bool* level);
-void infrared_encoder_samsung32_reset(void* encoder_ptr, const InfraredMessage* message);
-void* infrared_encoder_samsung32_alloc(void);
-void infrared_encoder_samsung32_free(void* encoder_ptr);
-bool infrared_decoder_samsung32_interpret(InfraredCommonDecoder* decoder);
-InfraredStatus infrared_decoder_samsung32_decode_repeat(InfraredCommonDecoder* decoder);
-InfraredStatus infrared_encoder_samsung32_encode_repeat(
- InfraredCommonEncoder* encoder,
- uint32_t* duration,
- bool* level);
-const InfraredProtocolSpecification* infrared_samsung32_get_spec(InfraredProtocol protocol);
-
-extern const InfraredCommonProtocolSpec protocol_samsung32;
-
-/***************************************************************************************************
-* RC6 protocol description
-* https://www.mikrocontroller.net/articles/IRMP_-_english#RC6_.2B_RC6A
-****************************************************************************************************
-* Preamble Manchester/biphase Silence
-* mark/space Modulation
-*
-* 2666 889 444/888 - bit (x2 for toggle bit) 2666
-*
-* ________ __ __ __ __ ____ __ __ __ __ __ __ __ __
-* _ _________ ____ __ __ ____ __ __ __ __ __ __ __ __ _______________
-* | 1 | 0 | 0 | 0 | 0 | ... | ... | |
-* s m2 m1 m0 T address (MSB) command (MSB)
-*
-* s - start bit (always 1)
-* m0-2 - mode (000 for RC6)
-* T - toggle bit, twice longer
-* address - 8 bit
-* command - 8 bit
-***************************************************************************************************/
-
-#define INFRARED_RC6_CARRIER_FREQUENCY 36000
-#define INFRARED_RC6_DUTY_CYCLE 0.33
-
-#define INFRARED_RC6_PREAMBLE_MARK 2666
-#define INFRARED_RC6_PREAMBLE_SPACE 889
-#define INFRARED_RC6_BIT 444 // half of time-quant for 1 bit
-#define INFRARED_RC6_PREAMBLE_TOLERANCE 200 // us
-#define INFRARED_RC6_BIT_TOLERANCE 120 // us
-/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */
-#define INFRARED_RC6_SILENCE (2700 * 10)
-#define INFRARED_RC6_MIN_SPLIT_TIME 2700
-
-void* infrared_decoder_rc6_alloc(void);
-void infrared_decoder_rc6_reset(void* decoder);
-void infrared_decoder_rc6_free(void* decoder);
-InfraredMessage* infrared_decoder_rc6_check_ready(void* ctx);
-InfraredMessage* infrared_decoder_rc6_decode(void* decoder, bool level, uint32_t duration);
-void* infrared_encoder_rc6_alloc(void);
-void infrared_encoder_rc6_reset(void* encoder_ptr, const InfraredMessage* message);
-void infrared_encoder_rc6_free(void* decoder);
-InfraredStatus infrared_encoder_rc6_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
-bool infrared_decoder_rc6_interpret(InfraredCommonDecoder* decoder);
-InfraredStatus infrared_decoder_rc6_decode_manchester(
- InfraredCommonDecoder* decoder,
- bool level,
- uint32_t timing);
-InfraredStatus infrared_encoder_rc6_encode_manchester(
- InfraredCommonEncoder* encoder_ptr,
- uint32_t* duration,
- bool* polarity);
-const InfraredProtocolSpecification* infrared_rc6_get_spec(InfraredProtocol protocol);
-
-extern const InfraredCommonProtocolSpec protocol_rc6;
-
-/***************************************************************************************************
-* RC5 protocol description
-* https://www.mikrocontroller.net/articles/IRMP_-_english#RC5_.2B_RC5X
-****************************************************************************************************
-* Manchester/biphase
-* Modulation
-*
-* 888/1776 - bit (x2 for toggle bit)
-*
-* __ ____ __ __ __ __ __ __ __ __
-* __ __ ____ __ __ __ __ __ __ __ _
-* | 1 | 1 | 0 | ... | ... |
-* s si T address (MSB) command (MSB)
-*
-* Note: manchester starts from space timing, so it have to be handled properly
-* s - start bit (always 1)
-* si - RC5: start bit (always 1), RC5X - 7-th bit of address (in our case always 0)
-* T - toggle bit, change it's value every button press
-* address - 5 bit
-* command - 6/7 bit
-***************************************************************************************************/
-
-#define INFRARED_RC5_CARRIER_FREQUENCY 36000
-#define INFRARED_RC5_DUTY_CYCLE 0.33
-
-#define INFRARED_RC5_PREAMBLE_MARK 0
-#define INFRARED_RC5_PREAMBLE_SPACE 0
-#define INFRARED_RC5_BIT 888 // half of time-quant for 1 bit
-#define INFRARED_RC5_PREAMBLE_TOLERANCE 200 // us
-#define INFRARED_RC5_BIT_TOLERANCE 120 // us
-/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */
-#define INFRARED_RC5_SILENCE (2700 * 10)
-#define INFRARED_RC5_MIN_SPLIT_TIME 2700
-
-void* infrared_decoder_rc5_alloc(void);
-void infrared_decoder_rc5_reset(void* decoder);
-void infrared_decoder_rc5_free(void* decoder);
-InfraredMessage* infrared_decoder_rc5_check_ready(void* ctx);
-InfraredMessage* infrared_decoder_rc5_decode(void* decoder, bool level, uint32_t duration);
-void* infrared_encoder_rc5_alloc(void);
-void infrared_encoder_rc5_reset(void* encoder_ptr, const InfraredMessage* message);
-void infrared_encoder_rc5_free(void* decoder);
-InfraredStatus infrared_encoder_rc5_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
-bool infrared_decoder_rc5_interpret(InfraredCommonDecoder* decoder);
-const InfraredProtocolSpecification* infrared_rc5_get_spec(InfraredProtocol protocol);
-
-extern const InfraredCommonProtocolSpec protocol_rc5;
-
-/***************************************************************************************************
-* Sony SIRC protocol description
-* https://www.sbprojects.net/knowledge/ir/sirc.php
-* http://picprojects.org.uk/
-****************************************************************************************************
-* Preamble Preamble Pulse Width Modulation Pause Entirely repeat
-* mark space up to period message..
-*
-* 2400 600 12/15/20 bits (600,1200) ...45000 2400 600
-* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ __________ _ _
-* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ____________________ __________ _
-* | command | address |
-* SIRC | 7b LSB | 5b LSB |
-* SIRC15 | 7b LSB | 8b LSB |
-* SIRC20 | 7b LSB | 13b LSB |
-*
-* No way to determine either next message is repeat or not,
-* so recognize only fact message received. Sony remotes always send at least 3 messages.
-* Assume 8 last extended bits for SIRC20 are address bits.
-***************************************************************************************************/
-
-#define INFRARED_SIRC_CARRIER_FREQUENCY 40000
-#define INFRARED_SIRC_DUTY_CYCLE 0.33
-#define INFRARED_SIRC_PREAMBLE_MARK 2400
-#define INFRARED_SIRC_PREAMBLE_SPACE 600
-#define INFRARED_SIRC_BIT1_MARK 1200
-#define INFRARED_SIRC_BIT1_SPACE 600
-#define INFRARED_SIRC_BIT0_MARK 600
-#define INFRARED_SIRC_BIT0_SPACE 600
-#define INFRARED_SIRC_PREAMBLE_TOLERANCE 200 // us
-#define INFRARED_SIRC_BIT_TOLERANCE 120 // us
-#define INFRARED_SIRC_SILENCE 10000
-#define INFRARED_SIRC_MIN_SPLIT_TIME (INFRARED_SIRC_SILENCE - 1000)
-#define INFRARED_SIRC_REPEAT_PERIOD 45000
-
-void* infrared_decoder_sirc_alloc(void);
-void infrared_decoder_sirc_reset(void* decoder);
-InfraredMessage* infrared_decoder_sirc_check_ready(void* decoder);
-uint32_t infrared_decoder_sirc_get_timeout(void* decoder);
-void infrared_decoder_sirc_free(void* decoder);
-InfraredMessage* infrared_decoder_sirc_decode(void* decoder, bool level, uint32_t duration);
-void* infrared_encoder_sirc_alloc(void);
-void infrared_encoder_sirc_reset(void* encoder_ptr, const InfraredMessage* message);
-void infrared_encoder_sirc_free(void* decoder);
-InfraredStatus infrared_encoder_sirc_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
-bool infrared_decoder_sirc_interpret(InfraredCommonDecoder* decoder);
-const InfraredProtocolSpecification* infrared_sirc_get_spec(InfraredProtocol protocol);
-InfraredStatus infrared_encoder_sirc_encode_repeat(
- InfraredCommonEncoder* encoder,
- uint32_t* duration,
- bool* level);
-
-extern const InfraredCommonProtocolSpec protocol_sirc;
-
-/***************************************************************************************************
-* Kaseikyo protocol description
-* https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/ir_Kaseikyo.hpp
-****************************************************************************************************
-* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble
-* mark space Modulation up to period repeat repeat
-* mark space
-*
-* 3360 1665 48 bit ...130000 3456 1728
-* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ ___________
-* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ________________ ___________
-*
-***************************************************************************************************/
-
-#define INFRARED_KASEIKYO_UNIT 432
-#define INFRARED_KASEIKYO_PREAMBLE_MARK (8 * INFRARED_KASEIKYO_UNIT)
-#define INFRARED_KASEIKYO_PREAMBLE_SPACE (4 * INFRARED_KASEIKYO_UNIT)
-#define INFRARED_KASEIKYO_BIT1_MARK INFRARED_KASEIKYO_UNIT
-#define INFRARED_KASEIKYO_BIT1_SPACE (3 * INFRARED_KASEIKYO_UNIT)
-#define INFRARED_KASEIKYO_BIT0_MARK INFRARED_KASEIKYO_UNIT
-#define INFRARED_KASEIKYO_BIT0_SPACE INFRARED_KASEIKYO_UNIT
-#define INFRARED_KASEIKYO_REPEAT_PERIOD 130000
-#define INFRARED_KASEIKYO_SILENCE INFRARED_KASEIKYO_REPEAT_PERIOD
-#define INFRARED_KASEIKYO_MIN_SPLIT_TIME INFRARED_KASEIKYO_REPEAT_PAUSE_MIN
-#define INFRARED_KASEIKYO_REPEAT_PAUSE_MIN 4000
-#define INFRARED_KASEIKYO_REPEAT_PAUSE_MAX 150000
-#define INFRARED_KASEIKYO_REPEAT_MARK INFRARED_KASEIKYO_PREAMBLE_MARK
-#define INFRARED_KASEIKYO_REPEAT_SPACE (INFRARED_KASEIKYO_REPEAT_PERIOD - 56000)
-#define INFRARED_KASEIKYO_PREAMBLE_TOLERANCE 200 // us
-#define INFRARED_KASEIKYO_BIT_TOLERANCE 120 // us
-
-void* infrared_decoder_kaseikyo_alloc(void);
-void infrared_decoder_kaseikyo_reset(void* decoder);
-void infrared_decoder_kaseikyo_free(void* decoder);
-InfraredMessage* infrared_decoder_kaseikyo_check_ready(void* decoder);
-InfraredMessage* infrared_decoder_kaseikyo_decode(void* decoder, bool level, uint32_t duration);
-void* infrared_encoder_kaseikyo_alloc(void);
-InfraredStatus
- infrared_encoder_kaseikyo_encode(void* encoder_ptr, uint32_t* duration, bool* level);
-void infrared_encoder_kaseikyo_reset(void* encoder_ptr, const InfraredMessage* message);
-void infrared_encoder_kaseikyo_free(void* encoder_ptr);
-bool infrared_decoder_kaseikyo_interpret(InfraredCommonDecoder* decoder);
-InfraredStatus infrared_decoder_kaseikyo_decode_repeat(InfraredCommonDecoder* decoder);
-InfraredStatus infrared_encoder_kaseikyo_encode_repeat(
- InfraredCommonEncoder* encoder,
- uint32_t* duration,
- bool* level);
-const InfraredProtocolSpecification* infrared_kaseikyo_get_spec(InfraredProtocol protocol);
-
-extern const InfraredCommonProtocolSpec protocol_kaseikyo;
diff --git a/lib/infrared/encoder_decoder/kaseikyo/infrared_decoder_kaseikyo.c b/lib/infrared/encoder_decoder/kaseikyo/infrared_decoder_kaseikyo.c
index b8db81d7ef..e85a896525 100644
--- a/lib/infrared/encoder_decoder/kaseikyo/infrared_decoder_kaseikyo.c
+++ b/lib/infrared/encoder_decoder/kaseikyo/infrared_decoder_kaseikyo.c
@@ -1,9 +1,5 @@
-#include "infrared.h"
-#include "infrared_protocol_defs_i.h"
-#include
-#include
-#include
-#include "../infrared_i.h"
+#include "infrared_protocol_kaseikyo_i.h"
+#include
InfraredMessage* infrared_decoder_kaseikyo_check_ready(void* ctx) {
return infrared_common_decoder_check_ready(ctx);
@@ -38,7 +34,7 @@ bool infrared_decoder_kaseikyo_interpret(InfraredCommonDecoder* decoder) {
}
void* infrared_decoder_kaseikyo_alloc(void) {
- return infrared_common_decoder_alloc(&protocol_kaseikyo);
+ return infrared_common_decoder_alloc(&infrared_protocol_kaseikyo);
}
InfraredMessage* infrared_decoder_kaseikyo_decode(void* decoder, bool level, uint32_t duration) {
diff --git a/lib/infrared/encoder_decoder/kaseikyo/infrared_encoder_kaseikyo.c b/lib/infrared/encoder_decoder/kaseikyo/infrared_encoder_kaseikyo.c
index 5814c72557..618fc3babd 100644
--- a/lib/infrared/encoder_decoder/kaseikyo/infrared_encoder_kaseikyo.c
+++ b/lib/infrared/encoder_decoder/kaseikyo/infrared_encoder_kaseikyo.c
@@ -1,9 +1,5 @@
+#include "infrared_protocol_kaseikyo_i.h"
#include
-#include "common/infrared_common_i.h"
-#include
-#include "../infrared_i.h"
-#include "infrared_protocol_defs_i.h"
-#include
void infrared_encoder_kaseikyo_reset(void* encoder_ptr, const InfraredMessage* message) {
furi_assert(encoder_ptr);
@@ -32,7 +28,7 @@ void infrared_encoder_kaseikyo_reset(void* encoder_ptr, const InfraredMessage* m
}
void* infrared_encoder_kaseikyo_alloc(void) {
- return infrared_common_encoder_alloc(&protocol_kaseikyo);
+ return infrared_common_encoder_alloc(&infrared_protocol_kaseikyo);
}
void infrared_encoder_kaseikyo_free(void* encoder_ptr) {
diff --git a/lib/infrared/encoder_decoder/kaseikyo/infrared_kaseikyo_spec.c b/lib/infrared/encoder_decoder/kaseikyo/infrared_kaseikyo_spec.c
deleted file mode 100644
index 87c86c7b3d..0000000000
--- a/lib/infrared/encoder_decoder/kaseikyo/infrared_kaseikyo_spec.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "../infrared_i.h"
-#include "infrared_protocol_defs_i.h"
-
-static const InfraredProtocolSpecification infrared_kaseikyo_protocol_specification = {
- .name = "Kaseikyo",
- .address_length = 26,
- .command_length = 10,
- .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
-};
-
-const InfraredProtocolSpecification* infrared_kaseikyo_get_spec(InfraredProtocol protocol) {
- if(protocol == InfraredProtocolKaseikyo)
- return &infrared_kaseikyo_protocol_specification;
- else
- return NULL;
-}
diff --git a/lib/infrared/encoder_decoder/kaseikyo/infrared_protocol_kaseikyo.c b/lib/infrared/encoder_decoder/kaseikyo/infrared_protocol_kaseikyo.c
new file mode 100644
index 0000000000..0c61be3bf8
--- /dev/null
+++ b/lib/infrared/encoder_decoder/kaseikyo/infrared_protocol_kaseikyo.c
@@ -0,0 +1,40 @@
+#include "infrared_protocol_kaseikyo_i.h"
+
+const InfraredCommonProtocolSpec infrared_protocol_kaseikyo = {
+ .timings =
+ {
+ .preamble_mark = INFRARED_KASEIKYO_PREAMBLE_MARK,
+ .preamble_space = INFRARED_KASEIKYO_PREAMBLE_SPACE,
+ .bit1_mark = INFRARED_KASEIKYO_BIT1_MARK,
+ .bit1_space = INFRARED_KASEIKYO_BIT1_SPACE,
+ .bit0_mark = INFRARED_KASEIKYO_BIT0_MARK,
+ .bit0_space = INFRARED_KASEIKYO_BIT0_SPACE,
+ .preamble_tolerance = INFRARED_KASEIKYO_PREAMBLE_TOLERANCE,
+ .bit_tolerance = INFRARED_KASEIKYO_BIT_TOLERANCE,
+ .silence_time = INFRARED_KASEIKYO_SILENCE,
+ .min_split_time = INFRARED_KASEIKYO_MIN_SPLIT_TIME,
+ },
+ .databit_len[0] = 48,
+ .no_stop_bit = false,
+ .decode = infrared_common_decode_pdwm,
+ .encode = infrared_common_encode_pdwm,
+ .interpret = infrared_decoder_kaseikyo_interpret,
+ .decode_repeat = NULL,
+ .encode_repeat = NULL,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_kaseikyo = {
+ .name = "Kaseikyo",
+ .address_length = 26,
+ .command_length = 10,
+ .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
+ .repeat_count = INFRARED_KASEIKYO_REPEAT_COUNT_MIN,
+};
+
+const InfraredProtocolVariant* infrared_protocol_kaseikyo_get_variant(InfraredProtocol protocol) {
+ if(protocol == InfraredProtocolKaseikyo)
+ return &infrared_protocol_variant_kaseikyo;
+ else
+ return NULL;
+}
diff --git a/lib/infrared/encoder_decoder/kaseikyo/infrared_protocol_kaseikyo.h b/lib/infrared/encoder_decoder/kaseikyo/infrared_protocol_kaseikyo.h
new file mode 100644
index 0000000000..61ff0ca1cf
--- /dev/null
+++ b/lib/infrared/encoder_decoder/kaseikyo/infrared_protocol_kaseikyo.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "../infrared_i.h"
+
+/***************************************************************************************************
+* Kaseikyo protocol description
+* https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/ir_Kaseikyo.hpp
+****************************************************************************************************
+* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble
+* mark space Modulation up to period repeat repeat
+* mark space
+*
+* 3360 1665 48 bit ...130000 3456 1728
+* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ ___________
+* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ________________ ___________
+*
+***************************************************************************************************/
+
+void* infrared_decoder_kaseikyo_alloc(void);
+void infrared_decoder_kaseikyo_reset(void* decoder);
+void infrared_decoder_kaseikyo_free(void* decoder);
+InfraredMessage* infrared_decoder_kaseikyo_check_ready(void* decoder);
+InfraredMessage* infrared_decoder_kaseikyo_decode(void* decoder, bool level, uint32_t duration);
+
+void* infrared_encoder_kaseikyo_alloc(void);
+InfraredStatus
+ infrared_encoder_kaseikyo_encode(void* encoder_ptr, uint32_t* duration, bool* level);
+void infrared_encoder_kaseikyo_reset(void* encoder_ptr, const InfraredMessage* message);
+void infrared_encoder_kaseikyo_free(void* encoder_ptr);
+
+const InfraredProtocolVariant* infrared_protocol_kaseikyo_get_variant(InfraredProtocol protocol);
diff --git a/lib/infrared/encoder_decoder/kaseikyo/infrared_protocol_kaseikyo_i.h b/lib/infrared/encoder_decoder/kaseikyo/infrared_protocol_kaseikyo_i.h
new file mode 100644
index 0000000000..bee116c4d1
--- /dev/null
+++ b/lib/infrared/encoder_decoder/kaseikyo/infrared_protocol_kaseikyo_i.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "../common/infrared_common_i.h"
+
+#define INFRARED_KASEIKYO_UNIT 432
+#define INFRARED_KASEIKYO_PREAMBLE_MARK (8 * INFRARED_KASEIKYO_UNIT)
+#define INFRARED_KASEIKYO_PREAMBLE_SPACE (4 * INFRARED_KASEIKYO_UNIT)
+#define INFRARED_KASEIKYO_BIT1_MARK INFRARED_KASEIKYO_UNIT
+#define INFRARED_KASEIKYO_BIT1_SPACE (3 * INFRARED_KASEIKYO_UNIT)
+#define INFRARED_KASEIKYO_BIT0_MARK INFRARED_KASEIKYO_UNIT
+#define INFRARED_KASEIKYO_BIT0_SPACE INFRARED_KASEIKYO_UNIT
+#define INFRARED_KASEIKYO_REPEAT_PERIOD 130000
+#define INFRARED_KASEIKYO_SILENCE INFRARED_KASEIKYO_REPEAT_PERIOD
+#define INFRARED_KASEIKYO_MIN_SPLIT_TIME INFRARED_KASEIKYO_REPEAT_PAUSE_MIN
+#define INFRARED_KASEIKYO_REPEAT_PAUSE_MIN 4000
+#define INFRARED_KASEIKYO_REPEAT_PAUSE_MAX 150000
+#define INFRARED_KASEIKYO_REPEAT_COUNT_MIN 1
+#define INFRARED_KASEIKYO_REPEAT_MARK INFRARED_KASEIKYO_PREAMBLE_MARK
+#define INFRARED_KASEIKYO_REPEAT_SPACE (INFRARED_KASEIKYO_REPEAT_PERIOD - 56000)
+#define INFRARED_KASEIKYO_PREAMBLE_TOLERANCE 200 // us
+#define INFRARED_KASEIKYO_BIT_TOLERANCE 120 // us
+
+extern const InfraredCommonProtocolSpec infrared_protocol_kaseikyo;
+
+bool infrared_decoder_kaseikyo_interpret(InfraredCommonDecoder* decoder);
+InfraredStatus infrared_decoder_kaseikyo_decode_repeat(InfraredCommonDecoder* decoder);
+InfraredStatus infrared_encoder_kaseikyo_encode_repeat(
+ InfraredCommonEncoder* encoder,
+ uint32_t* duration,
+ bool* level);
diff --git a/lib/infrared/encoder_decoder/nec/infrared_decoder_nec.c b/lib/infrared/encoder_decoder/nec/infrared_decoder_nec.c
index 3ad14a7ab1..91384d702a 100644
--- a/lib/infrared/encoder_decoder/nec/infrared_decoder_nec.c
+++ b/lib/infrared/encoder_decoder/nec/infrared_decoder_nec.c
@@ -1,10 +1,5 @@
-#include "common/infrared_common_i.h"
-#include "infrared.h"
-#include "infrared_protocol_defs_i.h"
-#include
-#include
-#include
-#include "../infrared_i.h"
+#include "infrared_protocol_nec_i.h"
+#include
InfraredMessage* infrared_decoder_nec_check_ready(void* ctx) {
return infrared_common_decoder_check_ready(ctx);
@@ -86,7 +81,7 @@ InfraredStatus infrared_decoder_nec_decode_repeat(InfraredCommonDecoder* decoder
}
void* infrared_decoder_nec_alloc(void) {
- return infrared_common_decoder_alloc(&protocol_nec);
+ return infrared_common_decoder_alloc(&infrared_protocol_nec);
}
InfraredMessage* infrared_decoder_nec_decode(void* decoder, bool level, uint32_t duration) {
diff --git a/lib/infrared/encoder_decoder/nec/infrared_encoder_nec.c b/lib/infrared/encoder_decoder/nec/infrared_encoder_nec.c
index d0039c330b..87f815142a 100644
--- a/lib/infrared/encoder_decoder/nec/infrared_encoder_nec.c
+++ b/lib/infrared/encoder_decoder/nec/infrared_encoder_nec.c
@@ -1,10 +1,7 @@
+#include "infrared_protocol_nec_i.h"
+
+#include
#include
-#include "infrared.h"
-#include "common/infrared_common_i.h"
-#include
-#include "../infrared_i.h"
-#include "infrared_protocol_defs_i.h"
-#include
static const uint32_t repeat_timings[] = {
INFRARED_NEC_REPEAT_PERIOD - INFRARED_NEC_REPEAT_MARK - INFRARED_NEC_REPEAT_SPACE -
@@ -81,7 +78,7 @@ InfraredStatus infrared_encoder_nec_encode_repeat(
}
void* infrared_encoder_nec_alloc(void) {
- return infrared_common_encoder_alloc(&protocol_nec);
+ return infrared_common_encoder_alloc(&infrared_protocol_nec);
}
void infrared_encoder_nec_free(void* encoder_ptr) {
diff --git a/lib/infrared/encoder_decoder/nec/infrared_nec_spec.c b/lib/infrared/encoder_decoder/nec/infrared_nec_spec.c
deleted file mode 100644
index 16cab8b5f5..0000000000
--- a/lib/infrared/encoder_decoder/nec/infrared_nec_spec.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "../infrared_i.h"
-#include "infrared_protocol_defs_i.h"
-
-static const InfraredProtocolSpecification infrared_nec_protocol_specification = {
- .name = "NEC",
- .address_length = 8,
- .command_length = 8,
- .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
-};
-
-static const InfraredProtocolSpecification infrared_necext_protocol_specification = {
- .name = "NECext",
- .address_length = 16,
- .command_length = 16,
- .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
-};
-
-static const InfraredProtocolSpecification infrared_nec42_protocol_specification = {
- .name = "NEC42",
- .address_length = 13,
- .command_length = 8,
- .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
-};
-
-static const InfraredProtocolSpecification infrared_nec42ext_protocol_specification = {
- .name = "NEC42ext",
- .address_length = 26,
- .command_length = 16,
- .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
-};
-
-const InfraredProtocolSpecification* infrared_nec_get_spec(InfraredProtocol protocol) {
- if(protocol == InfraredProtocolNEC)
- return &infrared_nec_protocol_specification;
- else if(protocol == InfraredProtocolNECext)
- return &infrared_necext_protocol_specification;
- else if(protocol == InfraredProtocolNEC42)
- return &infrared_nec42_protocol_specification;
- else if(protocol == InfraredProtocolNEC42ext)
- return &infrared_nec42ext_protocol_specification;
- else
- return NULL;
-}
diff --git a/lib/infrared/encoder_decoder/nec/infrared_protocol_nec.c b/lib/infrared/encoder_decoder/nec/infrared_protocol_nec.c
new file mode 100644
index 0000000000..3444f78b61
--- /dev/null
+++ b/lib/infrared/encoder_decoder/nec/infrared_protocol_nec.c
@@ -0,0 +1,74 @@
+#include "infrared_protocol_nec_i.h"
+
+const InfraredCommonProtocolSpec infrared_protocol_nec = {
+ .timings =
+ {
+ .preamble_mark = INFRARED_NEC_PREAMBLE_MARK,
+ .preamble_space = INFRARED_NEC_PREAMBLE_SPACE,
+ .bit1_mark = INFRARED_NEC_BIT1_MARK,
+ .bit1_space = INFRARED_NEC_BIT1_SPACE,
+ .bit0_mark = INFRARED_NEC_BIT0_MARK,
+ .bit0_space = INFRARED_NEC_BIT0_SPACE,
+ .preamble_tolerance = INFRARED_NEC_PREAMBLE_TOLERANCE,
+ .bit_tolerance = INFRARED_NEC_BIT_TOLERANCE,
+ .silence_time = INFRARED_NEC_SILENCE,
+ .min_split_time = INFRARED_NEC_MIN_SPLIT_TIME,
+ },
+ .databit_len[0] = 42,
+ .databit_len[1] = 32,
+ .no_stop_bit = false,
+ .decode = infrared_common_decode_pdwm,
+ .encode = infrared_common_encode_pdwm,
+ .interpret = infrared_decoder_nec_interpret,
+ .decode_repeat = infrared_decoder_nec_decode_repeat,
+ .encode_repeat = infrared_encoder_nec_encode_repeat,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_nec = {
+ .name = "NEC",
+ .address_length = 8,
+ .command_length = 8,
+ .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
+ .repeat_count = INFRARED_NEC_REPEAT_COUNT_MIN,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_necext = {
+ .name = "NECext",
+ .address_length = 16,
+ .command_length = 16,
+ .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
+ .repeat_count = INFRARED_NEC_REPEAT_COUNT_MIN,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_nec42 = {
+ .name = "NEC42",
+ .address_length = 13,
+ .command_length = 8,
+ .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
+ .repeat_count = INFRARED_NEC_REPEAT_COUNT_MIN,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_nec42ext = {
+ .name = "NEC42ext",
+ .address_length = 26,
+ .command_length = 16,
+ .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
+ .repeat_count = INFRARED_NEC_REPEAT_COUNT_MIN,
+};
+
+const InfraredProtocolVariant* infrared_protocol_nec_get_variant(InfraredProtocol protocol) {
+ if(protocol == InfraredProtocolNEC)
+ return &infrared_protocol_variant_nec;
+ else if(protocol == InfraredProtocolNECext)
+ return &infrared_protocol_variant_necext;
+ else if(protocol == InfraredProtocolNEC42)
+ return &infrared_protocol_variant_nec42;
+ else if(protocol == InfraredProtocolNEC42ext)
+ return &infrared_protocol_variant_nec42ext;
+ else
+ return NULL;
+}
diff --git a/lib/infrared/encoder_decoder/nec/infrared_protocol_nec.h b/lib/infrared/encoder_decoder/nec/infrared_protocol_nec.h
new file mode 100644
index 0000000000..559e31fda1
--- /dev/null
+++ b/lib/infrared/encoder_decoder/nec/infrared_protocol_nec.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "../infrared_i.h"
+
+/***************************************************************************************************
+* NEC protocol description
+* https://radioparty.ru/manuals/encyclopedia/213-ircontrol?start=1
+****************************************************************************************************
+* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble Stop
+* mark space Modulation up to period repeat repeat bit
+* mark space
+*
+* 9000 4500 32 bit + stop bit ...110000 9000 2250
+* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ ___________ _
+* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ________________ ____________ ___
+*
+***************************************************************************************************/
+
+void* infrared_decoder_nec_alloc(void);
+void infrared_decoder_nec_reset(void* decoder);
+void infrared_decoder_nec_free(void* decoder);
+InfraredMessage* infrared_decoder_nec_check_ready(void* decoder);
+InfraredMessage* infrared_decoder_nec_decode(void* decoder, bool level, uint32_t duration);
+
+void* infrared_encoder_nec_alloc(void);
+InfraredStatus infrared_encoder_nec_encode(void* encoder_ptr, uint32_t* duration, bool* level);
+void infrared_encoder_nec_reset(void* encoder_ptr, const InfraredMessage* message);
+void infrared_encoder_nec_free(void* encoder_ptr);
+
+const InfraredProtocolVariant* infrared_protocol_nec_get_variant(InfraredProtocol protocol);
diff --git a/lib/infrared/encoder_decoder/nec/infrared_protocol_nec_i.h b/lib/infrared/encoder_decoder/nec/infrared_protocol_nec_i.h
new file mode 100644
index 0000000000..05df1f474e
--- /dev/null
+++ b/lib/infrared/encoder_decoder/nec/infrared_protocol_nec_i.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "../common/infrared_common_i.h"
+
+#define INFRARED_NEC_PREAMBLE_MARK 9000
+#define INFRARED_NEC_PREAMBLE_SPACE 4500
+#define INFRARED_NEC_BIT1_MARK 560
+#define INFRARED_NEC_BIT1_SPACE 1690
+#define INFRARED_NEC_BIT0_MARK 560
+#define INFRARED_NEC_BIT0_SPACE 560
+#define INFRARED_NEC_REPEAT_PERIOD 110000
+#define INFRARED_NEC_SILENCE INFRARED_NEC_REPEAT_PERIOD
+#define INFRARED_NEC_MIN_SPLIT_TIME INFRARED_NEC_REPEAT_PAUSE_MIN
+#define INFRARED_NEC_REPEAT_PAUSE_MIN 4000
+#define INFRARED_NEC_REPEAT_PAUSE_MAX 150000
+#define INFRARED_NEC_REPEAT_COUNT_MIN 1
+#define INFRARED_NEC_REPEAT_MARK 9000
+#define INFRARED_NEC_REPEAT_SPACE 2250
+#define INFRARED_NEC_PREAMBLE_TOLERANCE 200 // us
+#define INFRARED_NEC_BIT_TOLERANCE 120 // us
+
+extern const InfraredCommonProtocolSpec infrared_protocol_nec;
+
+bool infrared_decoder_nec_interpret(InfraredCommonDecoder* decoder);
+InfraredStatus infrared_decoder_nec_decode_repeat(InfraredCommonDecoder* decoder);
+InfraredStatus infrared_encoder_nec_encode_repeat(
+ InfraredCommonEncoder* encoder,
+ uint32_t* duration,
+ bool* level);
diff --git a/lib/infrared/encoder_decoder/rc5/infrared_decoder_rc5.c b/lib/infrared/encoder_decoder/rc5/infrared_decoder_rc5.c
index 6b4a7c2e35..1b2f2f3019 100644
--- a/lib/infrared/encoder_decoder/rc5/infrared_decoder_rc5.c
+++ b/lib/infrared/encoder_decoder/rc5/infrared_decoder_rc5.c
@@ -1,10 +1,7 @@
-#include "infrared.h"
-#include
-#include
-#include
-#include
-#include "../infrared_i.h"
-#include "../infrared_protocol_defs_i.h"
+#include "infrared_protocol_rc5_i.h"
+
+#include
+#include
typedef struct {
InfraredCommonDecoder* common_decoder;
@@ -60,7 +57,7 @@ bool infrared_decoder_rc5_interpret(InfraredCommonDecoder* decoder) {
void* infrared_decoder_rc5_alloc(void) {
InfraredRc5Decoder* decoder = malloc(sizeof(InfraredRc5Decoder));
decoder->toggle = false;
- decoder->common_decoder = infrared_common_decoder_alloc(&protocol_rc5);
+ decoder->common_decoder = infrared_common_decoder_alloc(&infrared_protocol_rc5);
decoder->common_decoder->context = decoder;
return decoder;
}
diff --git a/lib/infrared/encoder_decoder/rc5/infrared_encoder_rc5.c b/lib/infrared/encoder_decoder/rc5/infrared_encoder_rc5.c
index 7b55cdc447..df47fb7c43 100644
--- a/lib/infrared/encoder_decoder/rc5/infrared_encoder_rc5.c
+++ b/lib/infrared/encoder_decoder/rc5/infrared_encoder_rc5.c
@@ -1,9 +1,7 @@
-#include
-#include "infrared.h"
-#include "common/infrared_common_i.h"
-#include "infrared_protocol_defs_i.h"
-#include
-#include "../infrared_i.h"
+#include "infrared_protocol_rc5_i.h"
+
+#include
+#include
typedef struct InfraredEncoderRC5 {
InfraredCommonEncoder* common_encoder;
@@ -41,7 +39,7 @@ InfraredStatus infrared_encoder_rc5_encode(void* encoder_ptr, uint32_t* duration
void* infrared_encoder_rc5_alloc(void) {
InfraredEncoderRC5* encoder = malloc(sizeof(InfraredEncoderRC5));
- encoder->common_encoder = infrared_common_encoder_alloc(&protocol_rc5);
+ encoder->common_encoder = infrared_common_encoder_alloc(&infrared_protocol_rc5);
encoder->toggle_bit = false;
return encoder;
}
diff --git a/lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5.c b/lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5.c
new file mode 100644
index 0000000000..bc7e299fda
--- /dev/null
+++ b/lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5.c
@@ -0,0 +1,49 @@
+#include "infrared_protocol_rc5_i.h"
+
+const InfraredCommonProtocolSpec infrared_protocol_rc5 = {
+ .timings =
+ {
+ .preamble_mark = 0,
+ .preamble_space = 0,
+ .bit1_mark = INFRARED_RC5_BIT,
+ .preamble_tolerance = 0,
+ .bit_tolerance = INFRARED_RC5_BIT_TOLERANCE,
+ .silence_time = INFRARED_RC5_SILENCE,
+ .min_split_time = INFRARED_RC5_MIN_SPLIT_TIME,
+ },
+ .databit_len[0] = 1 + 1 + 1 + 5 +
+ 6, // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command
+ .manchester_start_from_space = true,
+ .decode = infrared_common_decode_manchester,
+ .encode = infrared_common_encode_manchester,
+ .interpret = infrared_decoder_rc5_interpret,
+ .decode_repeat = NULL,
+ .encode_repeat = NULL,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_rc5 = {
+ .name = "RC5",
+ .address_length = 5,
+ .command_length = 6,
+ .frequency = INFRARED_RC5_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_RC5_DUTY_CYCLE,
+ .repeat_count = INFRARED_RC5_REPEAT_COUNT_MIN,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_rc5x = {
+ .name = "RC5X",
+ .address_length = 5,
+ .command_length = 7,
+ .frequency = INFRARED_RC5_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_RC5_DUTY_CYCLE,
+ .repeat_count = INFRARED_RC5_REPEAT_COUNT_MIN,
+};
+
+const InfraredProtocolVariant* infrared_protocol_rc5_get_variant(InfraredProtocol protocol) {
+ if(protocol == InfraredProtocolRC5)
+ return &infrared_protocol_variant_rc5;
+ else if(protocol == InfraredProtocolRC5X)
+ return &infrared_protocol_variant_rc5x;
+ else
+ return NULL;
+}
diff --git a/lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5.h b/lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5.h
new file mode 100644
index 0000000000..9dd5802a93
--- /dev/null
+++ b/lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "../infrared_i.h"
+
+/***************************************************************************************************
+* RC5 protocol description
+* https://www.mikrocontroller.net/articles/IRMP_-_english#RC5_.2B_RC5X
+****************************************************************************************************
+* Manchester/biphase
+* Modulation
+*
+* 888/1776 - bit (x2 for toggle bit)
+*
+* __ ____ __ __ __ __ __ __ __ __
+* __ __ ____ __ __ __ __ __ __ __ _
+* | 1 | 1 | 0 | ... | ... |
+* s si T address (MSB) command (MSB)
+*
+* Note: manchester starts from space timing, so it have to be handled properly
+* s - start bit (always 1)
+* si - RC5: start bit (always 1), RC5X - 7-th bit of address (in our case always 0)
+* T - toggle bit, change it's value every button press
+* address - 5 bit
+* command - 6/7 bit
+***************************************************************************************************/
+
+void* infrared_decoder_rc5_alloc(void);
+void infrared_decoder_rc5_reset(void* decoder);
+void infrared_decoder_rc5_free(void* decoder);
+InfraredMessage* infrared_decoder_rc5_check_ready(void* ctx);
+InfraredMessage* infrared_decoder_rc5_decode(void* decoder, bool level, uint32_t duration);
+
+void* infrared_encoder_rc5_alloc(void);
+void infrared_encoder_rc5_reset(void* encoder_ptr, const InfraredMessage* message);
+void infrared_encoder_rc5_free(void* decoder);
+InfraredStatus infrared_encoder_rc5_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
+
+const InfraredProtocolVariant* infrared_protocol_rc5_get_variant(InfraredProtocol protocol);
diff --git a/lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5_i.h b/lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5_i.h
new file mode 100644
index 0000000000..b906c369e0
--- /dev/null
+++ b/lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5_i.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "../common/infrared_common_i.h"
+
+#define INFRARED_RC5_CARRIER_FREQUENCY 36000
+#define INFRARED_RC5_DUTY_CYCLE 0.33
+
+#define INFRARED_RC5_PREAMBLE_MARK 0
+#define INFRARED_RC5_PREAMBLE_SPACE 0
+#define INFRARED_RC5_BIT 888 // half of time-quant for 1 bit
+#define INFRARED_RC5_PREAMBLE_TOLERANCE 200 // us
+#define INFRARED_RC5_BIT_TOLERANCE 120 // us
+/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */
+#define INFRARED_RC5_SILENCE (2700 * 10)
+#define INFRARED_RC5_MIN_SPLIT_TIME 2700
+#define INFRARED_RC5_REPEAT_COUNT_MIN 1
+
+extern const InfraredCommonProtocolSpec infrared_protocol_rc5;
+
+bool infrared_decoder_rc5_interpret(InfraredCommonDecoder* decoder);
diff --git a/lib/infrared/encoder_decoder/rc5/infrared_rc5_spec.c b/lib/infrared/encoder_decoder/rc5/infrared_rc5_spec.c
deleted file mode 100644
index 25ea230ef3..0000000000
--- a/lib/infrared/encoder_decoder/rc5/infrared_rc5_spec.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "../infrared_i.h"
-#include "infrared_protocol_defs_i.h"
-
-static const InfraredProtocolSpecification infrared_rc5_protocol_specification = {
- .name = "RC5",
- .address_length = 5,
- .command_length = 6,
- .frequency = INFRARED_RC5_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_RC5_DUTY_CYCLE,
-};
-
-static const InfraredProtocolSpecification infrared_rc5x_protocol_specification = {
- .name = "RC5X",
- .address_length = 5,
- .command_length = 7,
- .frequency = INFRARED_RC5_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_RC5_DUTY_CYCLE,
-};
-
-const InfraredProtocolSpecification* infrared_rc5_get_spec(InfraredProtocol protocol) {
- if(protocol == InfraredProtocolRC5)
- return &infrared_rc5_protocol_specification;
- else if(protocol == InfraredProtocolRC5X)
- return &infrared_rc5x_protocol_specification;
- else
- return NULL;
-}
diff --git a/lib/infrared/encoder_decoder/rc6/infrared_decoder_rc6.c b/lib/infrared/encoder_decoder/rc6/infrared_decoder_rc6.c
index 13d3e5364d..b70f7ceb85 100644
--- a/lib/infrared/encoder_decoder/rc6/infrared_decoder_rc6.c
+++ b/lib/infrared/encoder_decoder/rc6/infrared_decoder_rc6.c
@@ -1,10 +1,7 @@
-#include "infrared.h"
-#include
-#include
-#include
-#include
-#include "../infrared_i.h"
-#include "../infrared_protocol_defs_i.h"
+#include "infrared_protocol_rc6_i.h"
+
+#include
+#include
typedef struct {
InfraredCommonDecoder* common_decoder;
@@ -93,7 +90,7 @@ InfraredStatus infrared_decoder_rc6_decode_manchester(
void* infrared_decoder_rc6_alloc(void) {
InfraredRc6Decoder* decoder = malloc(sizeof(InfraredRc6Decoder));
decoder->toggle = false;
- decoder->common_decoder = infrared_common_decoder_alloc(&protocol_rc6);
+ decoder->common_decoder = infrared_common_decoder_alloc(&infrared_protocol_rc6);
decoder->common_decoder->context = decoder;
return decoder;
}
diff --git a/lib/infrared/encoder_decoder/rc6/infrared_encoder_rc6.c b/lib/infrared/encoder_decoder/rc6/infrared_encoder_rc6.c
index f1240b17a7..d13a204ea0 100644
--- a/lib/infrared/encoder_decoder/rc6/infrared_encoder_rc6.c
+++ b/lib/infrared/encoder_decoder/rc6/infrared_encoder_rc6.c
@@ -1,9 +1,7 @@
-#include
-#include "infrared.h"
-#include "common/infrared_common_i.h"
-#include "infrared_protocol_defs_i.h"
-#include
-#include "../infrared_i.h"
+#include "infrared_protocol_rc6_i.h"
+
+#include
+#include
typedef struct InfraredEncoderRC6 {
InfraredCommonEncoder* common_encoder;
@@ -35,7 +33,7 @@ InfraredStatus infrared_encoder_rc6_encode(void* encoder_ptr, uint32_t* duration
void* infrared_encoder_rc6_alloc(void) {
InfraredEncoderRC6* encoder = malloc(sizeof(InfraredEncoderRC6));
- encoder->common_encoder = infrared_common_encoder_alloc(&protocol_rc6);
+ encoder->common_encoder = infrared_common_encoder_alloc(&infrared_protocol_rc6);
encoder->toggle_bit = false;
return encoder;
}
diff --git a/lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6.c b/lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6.c
new file mode 100644
index 0000000000..40a187d85c
--- /dev/null
+++ b/lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6.c
@@ -0,0 +1,39 @@
+#include "infrared_protocol_rc6_i.h"
+
+const InfraredCommonProtocolSpec infrared_protocol_rc6 = {
+ .timings =
+ {
+ .preamble_mark = INFRARED_RC6_PREAMBLE_MARK,
+ .preamble_space = INFRARED_RC6_PREAMBLE_SPACE,
+ .bit1_mark = INFRARED_RC6_BIT,
+ .preamble_tolerance = INFRARED_RC6_PREAMBLE_TOLERANCE,
+ .bit_tolerance = INFRARED_RC6_BIT_TOLERANCE,
+ .silence_time = INFRARED_RC6_SILENCE,
+ .min_split_time = INFRARED_RC6_MIN_SPLIT_TIME,
+ },
+ .databit_len[0] =
+ 1 + 3 + 1 + 8 +
+ 8, // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command
+ .manchester_start_from_space = false,
+ .decode = infrared_decoder_rc6_decode_manchester,
+ .encode = infrared_encoder_rc6_encode_manchester,
+ .interpret = infrared_decoder_rc6_interpret,
+ .decode_repeat = NULL,
+ .encode_repeat = NULL,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_rc6 = {
+ .name = "RC6",
+ .address_length = 8,
+ .command_length = 8,
+ .frequency = INFRARED_RC6_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_RC6_DUTY_CYCLE,
+ .repeat_count = INFRARED_RC6_REPEAT_COUNT_MIN,
+};
+
+const InfraredProtocolVariant* infrared_protocol_rc6_get_variant(InfraredProtocol protocol) {
+ if(protocol == InfraredProtocolRC6)
+ return &infrared_protocol_variant_rc6;
+ else
+ return NULL;
+}
diff --git a/lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6.h b/lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6.h
new file mode 100644
index 0000000000..f0b1634111
--- /dev/null
+++ b/lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "../infrared_i.h"
+
+/***************************************************************************************************
+* RC6 protocol description
+* https://www.mikrocontroller.net/articles/IRMP_-_english#RC6_.2B_RC6A
+****************************************************************************************************
+* Preamble Manchester/biphase Silence
+* mark/space Modulation
+*
+* 2666 889 444/888 - bit (x2 for toggle bit) 2666
+*
+* ________ __ __ __ __ ____ __ __ __ __ __ __ __ __
+* _ _________ ____ __ __ ____ __ __ __ __ __ __ __ __ _______________
+* | 1 | 0 | 0 | 0 | 0 | ... | ... | |
+* s m2 m1 m0 T address (MSB) command (MSB)
+*
+* s - start bit (always 1)
+* m0-2 - mode (000 for RC6)
+* T - toggle bit, twice longer
+* address - 8 bit
+* command - 8 bit
+***************************************************************************************************/
+
+void* infrared_decoder_rc6_alloc(void);
+void infrared_decoder_rc6_reset(void* decoder);
+void infrared_decoder_rc6_free(void* decoder);
+InfraredMessage* infrared_decoder_rc6_check_ready(void* ctx);
+InfraredMessage* infrared_decoder_rc6_decode(void* decoder, bool level, uint32_t duration);
+
+void* infrared_encoder_rc6_alloc(void);
+void infrared_encoder_rc6_reset(void* encoder_ptr, const InfraredMessage* message);
+void infrared_encoder_rc6_free(void* decoder);
+InfraredStatus infrared_encoder_rc6_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
+
+const InfraredProtocolVariant* infrared_protocol_rc6_get_variant(InfraredProtocol protocol);
diff --git a/lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6_i.h b/lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6_i.h
new file mode 100644
index 0000000000..06aa2a6a51
--- /dev/null
+++ b/lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6_i.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "../common/infrared_common_i.h"
+
+#define INFRARED_RC6_CARRIER_FREQUENCY 36000
+#define INFRARED_RC6_DUTY_CYCLE 0.33
+
+#define INFRARED_RC6_PREAMBLE_MARK 2666
+#define INFRARED_RC6_PREAMBLE_SPACE 889
+#define INFRARED_RC6_BIT 444 // half of time-quant for 1 bit
+#define INFRARED_RC6_PREAMBLE_TOLERANCE 200 // us
+#define INFRARED_RC6_BIT_TOLERANCE 120 // us
+/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */
+#define INFRARED_RC6_SILENCE (2700 * 10)
+#define INFRARED_RC6_MIN_SPLIT_TIME 2700
+#define INFRARED_RC6_REPEAT_COUNT_MIN 1
+
+extern const InfraredCommonProtocolSpec infrared_protocol_rc6;
+
+bool infrared_decoder_rc6_interpret(InfraredCommonDecoder* decoder);
+InfraredStatus infrared_decoder_rc6_decode_manchester(
+ InfraredCommonDecoder* decoder,
+ bool level,
+ uint32_t timing);
+InfraredStatus infrared_encoder_rc6_encode_manchester(
+ InfraredCommonEncoder* encoder_ptr,
+ uint32_t* duration,
+ bool* polarity);
diff --git a/lib/infrared/encoder_decoder/rc6/infrared_rc6_spec.c b/lib/infrared/encoder_decoder/rc6/infrared_rc6_spec.c
deleted file mode 100644
index 9e0ba74625..0000000000
--- a/lib/infrared/encoder_decoder/rc6/infrared_rc6_spec.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "../infrared_i.h"
-#include "infrared_protocol_defs_i.h"
-
-static const InfraredProtocolSpecification infrared_rc6_protocol_specification = {
- .name = "RC6",
- .address_length = 8,
- .command_length = 8,
- .frequency = INFRARED_RC6_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_RC6_DUTY_CYCLE,
-};
-
-const InfraredProtocolSpecification* infrared_rc6_get_spec(InfraredProtocol protocol) {
- if(protocol == InfraredProtocolRC6)
- return &infrared_rc6_protocol_specification;
- else
- return NULL;
-}
diff --git a/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c b/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c
index e8cd3b05cb..32881d3c95 100644
--- a/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c
+++ b/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c
@@ -1,9 +1,5 @@
-#include "infrared.h"
-#include "infrared_protocol_defs_i.h"
-#include
-#include
-#include
-#include "../infrared_i.h"
+#include "infrared_protocol_samsung_i.h"
+#include
InfraredMessage* infrared_decoder_samsung32_check_ready(void* ctx) {
return infrared_common_decoder_check_ready(ctx);
@@ -57,7 +53,7 @@ InfraredStatus infrared_decoder_samsung32_decode_repeat(InfraredCommonDecoder* d
}
void* infrared_decoder_samsung32_alloc(void) {
- return infrared_common_decoder_alloc(&protocol_samsung32);
+ return infrared_common_decoder_alloc(&infrared_protocol_samsung32);
}
InfraredMessage* infrared_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration) {
diff --git a/lib/infrared/encoder_decoder/samsung/infrared_encoder_samsung.c b/lib/infrared/encoder_decoder/samsung/infrared_encoder_samsung.c
index 75b037f007..3aed50656e 100644
--- a/lib/infrared/encoder_decoder/samsung/infrared_encoder_samsung.c
+++ b/lib/infrared/encoder_decoder/samsung/infrared_encoder_samsung.c
@@ -1,9 +1,7 @@
+#include "infrared_protocol_samsung_i.h"
+
#include
-#include "common/infrared_common_i.h"
-#include
-#include "../infrared_i.h"
-#include "infrared_protocol_defs_i.h"
-#include
+#include
static const uint32_t repeat_timings[] = {
INFRARED_SAMSUNG_REPEAT_PAUSE2,
@@ -58,7 +56,7 @@ InfraredStatus infrared_encoder_samsung32_encode_repeat(
}
void* infrared_encoder_samsung32_alloc(void) {
- return infrared_common_encoder_alloc(&protocol_samsung32);
+ return infrared_common_encoder_alloc(&infrared_protocol_samsung32);
}
void infrared_encoder_samsung32_free(void* encoder_ptr) {
diff --git a/lib/infrared/encoder_decoder/samsung/infrared_protocol_samsung.c b/lib/infrared/encoder_decoder/samsung/infrared_protocol_samsung.c
new file mode 100644
index 0000000000..ca78726acf
--- /dev/null
+++ b/lib/infrared/encoder_decoder/samsung/infrared_protocol_samsung.c
@@ -0,0 +1,40 @@
+#include "infrared_protocol_samsung_i.h"
+
+const InfraredCommonProtocolSpec infrared_protocol_samsung32 = {
+ .timings =
+ {
+ .preamble_mark = INFRARED_SAMSUNG_PREAMBLE_MARK,
+ .preamble_space = INFRARED_SAMSUNG_PREAMBLE_SPACE,
+ .bit1_mark = INFRARED_SAMSUNG_BIT1_MARK,
+ .bit1_space = INFRARED_SAMSUNG_BIT1_SPACE,
+ .bit0_mark = INFRARED_SAMSUNG_BIT0_MARK,
+ .bit0_space = INFRARED_SAMSUNG_BIT0_SPACE,
+ .preamble_tolerance = INFRARED_SAMSUNG_PREAMBLE_TOLERANCE,
+ .bit_tolerance = INFRARED_SAMSUNG_BIT_TOLERANCE,
+ .silence_time = INFRARED_SAMSUNG_SILENCE,
+ .min_split_time = INFRARED_SAMSUNG_MIN_SPLIT_TIME,
+ },
+ .databit_len[0] = 32,
+ .no_stop_bit = false,
+ .decode = infrared_common_decode_pdwm,
+ .encode = infrared_common_encode_pdwm,
+ .interpret = infrared_decoder_samsung32_interpret,
+ .decode_repeat = infrared_decoder_samsung32_decode_repeat,
+ .encode_repeat = infrared_encoder_samsung32_encode_repeat,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_samsung32 = {
+ .name = "Samsung32",
+ .address_length = 8,
+ .command_length = 8,
+ .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
+ .repeat_count = INFRARED_SAMSUNG_REPEAT_COUNT_MIN,
+};
+
+const InfraredProtocolVariant* infrared_protocol_samsung32_get_variant(InfraredProtocol protocol) {
+ if(protocol == InfraredProtocolSamsung32)
+ return &infrared_protocol_variant_samsung32;
+ else
+ return NULL;
+}
diff --git a/lib/infrared/encoder_decoder/samsung/infrared_protocol_samsung.h b/lib/infrared/encoder_decoder/samsung/infrared_protocol_samsung.h
new file mode 100644
index 0000000000..9abcb2e3e6
--- /dev/null
+++ b/lib/infrared/encoder_decoder/samsung/infrared_protocol_samsung.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "../infrared_i.h"
+
+/***************************************************************************************************
+* SAMSUNG32 protocol description
+* https://www.mikrocontroller.net/articles/IRMP_-_english#SAMSUNG
+****************************************************************************************************
+* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble Bit1 Stop
+* mark space Modulation repeat repeat bit
+* mark space
+*
+* 4500 4500 32 bit + stop bit 40000/100000 4500 4500
+* __________ _ _ _ _ _ _ _ _ _ _ _ ___________ _ _
+* _ __________ __ _ __ __ __ _ _ __ __ _ ________________ ____________ ____ ___
+*
+***************************************************************************************************/
+
+void* infrared_decoder_samsung32_alloc(void);
+void infrared_decoder_samsung32_reset(void* decoder);
+void infrared_decoder_samsung32_free(void* decoder);
+InfraredMessage* infrared_decoder_samsung32_check_ready(void* ctx);
+InfraredMessage* infrared_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration);
+
+InfraredStatus
+ infrared_encoder_samsung32_encode(void* encoder_ptr, uint32_t* duration, bool* level);
+void infrared_encoder_samsung32_reset(void* encoder_ptr, const InfraredMessage* message);
+void* infrared_encoder_samsung32_alloc(void);
+void infrared_encoder_samsung32_free(void* encoder_ptr);
+
+const InfraredProtocolVariant* infrared_protocol_samsung32_get_variant(InfraredProtocol protocol);
diff --git a/lib/infrared/encoder_decoder/samsung/infrared_protocol_samsung_i.h b/lib/infrared/encoder_decoder/samsung/infrared_protocol_samsung_i.h
new file mode 100644
index 0000000000..b853849429
--- /dev/null
+++ b/lib/infrared/encoder_decoder/samsung/infrared_protocol_samsung_i.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "../common/infrared_common_i.h"
+
+#define INFRARED_SAMSUNG_PREAMBLE_MARK 4500
+#define INFRARED_SAMSUNG_PREAMBLE_SPACE 4500
+#define INFRARED_SAMSUNG_BIT1_MARK 550
+#define INFRARED_SAMSUNG_BIT1_SPACE 1650
+#define INFRARED_SAMSUNG_BIT0_MARK 550
+#define INFRARED_SAMSUNG_BIT0_SPACE 550
+#define INFRARED_SAMSUNG_REPEAT_PAUSE_MIN 30000
+#define INFRARED_SAMSUNG_REPEAT_PAUSE_MAX 140000
+#define INFRARED_SAMSUNG_REPEAT_PAUSE1 46000
+#define INFRARED_SAMSUNG_REPEAT_PAUSE2 97000
+#define INFRARED_SAMSUNG_REPEAT_COUNT_MIN 1
+/* Samsung silence have to be greater than REPEAT MAX
+ * otherwise there can be problems during unit tests parsing
+ * of some data. Real tolerances we don't know, but in real life
+ * silence time should be greater than max repeat time. This is
+ * because of similar preambule timings for repeat and first messages. */
+#define INFRARED_SAMSUNG_MIN_SPLIT_TIME 5000
+#define INFRARED_SAMSUNG_SILENCE 145000
+#define INFRARED_SAMSUNG_REPEAT_MARK 4500
+#define INFRARED_SAMSUNG_REPEAT_SPACE 4500
+#define INFRARED_SAMSUNG_PREAMBLE_TOLERANCE 200 // us
+#define INFRARED_SAMSUNG_BIT_TOLERANCE 120 // us
+
+bool infrared_decoder_samsung32_interpret(InfraredCommonDecoder* decoder);
+InfraredStatus infrared_decoder_samsung32_decode_repeat(InfraredCommonDecoder* decoder);
+InfraredStatus infrared_encoder_samsung32_encode_repeat(
+ InfraredCommonEncoder* encoder,
+ uint32_t* duration,
+ bool* level);
+
+extern const InfraredCommonProtocolSpec infrared_protocol_samsung32;
diff --git a/lib/infrared/encoder_decoder/samsung/infrared_samsung_spec.c b/lib/infrared/encoder_decoder/samsung/infrared_samsung_spec.c
deleted file mode 100644
index f4cbf699ec..0000000000
--- a/lib/infrared/encoder_decoder/samsung/infrared_samsung_spec.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "../infrared_i.h"
-#include "infrared_protocol_defs_i.h"
-
-static const InfraredProtocolSpecification infrared_samsung32_protocol_specification = {
- .name = "Samsung32",
- .address_length = 8,
- .command_length = 8,
- .frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
-};
-
-const InfraredProtocolSpecification* infrared_samsung32_get_spec(InfraredProtocol protocol) {
- if(protocol == InfraredProtocolSamsung32)
- return &infrared_samsung32_protocol_specification;
- else
- return NULL;
-}
diff --git a/lib/infrared/encoder_decoder/sirc/infrared_decoder_sirc.c b/lib/infrared/encoder_decoder/sirc/infrared_decoder_sirc.c
index 45f06c9422..fc18a183ca 100644
--- a/lib/infrared/encoder_decoder/sirc/infrared_decoder_sirc.c
+++ b/lib/infrared/encoder_decoder/sirc/infrared_decoder_sirc.c
@@ -1,10 +1,5 @@
-#include "common/infrared_common_i.h"
-#include "infrared.h"
-#include "infrared_protocol_defs_i.h"
-#include
-#include
-#include
-#include "../infrared_i.h"
+#include "infrared_protocol_sirc_i.h"
+#include
InfraredMessage* infrared_decoder_sirc_check_ready(void* ctx) {
return infrared_common_decoder_check_ready(ctx);
@@ -44,7 +39,7 @@ bool infrared_decoder_sirc_interpret(InfraredCommonDecoder* decoder) {
}
void* infrared_decoder_sirc_alloc(void) {
- return infrared_common_decoder_alloc(&protocol_sirc);
+ return infrared_common_decoder_alloc(&infrared_protocol_sirc);
}
InfraredMessage* infrared_decoder_sirc_decode(void* decoder, bool level, uint32_t duration) {
diff --git a/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c b/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c
index 2c2bda1afd..6adf2235ce 100644
--- a/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c
+++ b/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c
@@ -1,10 +1,5 @@
+#include "infrared_protocol_sirc_i.h"
#include
-#include "infrared.h"
-#include "common/infrared_common_i.h"
-#include
-#include "../infrared_i.h"
-#include "infrared_protocol_defs_i.h"
-#include
void infrared_encoder_sirc_reset(void* encoder_ptr, const InfraredMessage* message) {
furi_assert(encoder_ptr);
@@ -53,7 +48,7 @@ InfraredStatus infrared_encoder_sirc_encode_repeat(
}
void* infrared_encoder_sirc_alloc(void) {
- return infrared_common_encoder_alloc(&protocol_sirc);
+ return infrared_common_encoder_alloc(&infrared_protocol_sirc);
}
void infrared_encoder_sirc_free(void* encoder_ptr) {
diff --git a/lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc.c b/lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc.c
new file mode 100644
index 0000000000..b527fba980
--- /dev/null
+++ b/lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc.c
@@ -0,0 +1,64 @@
+#include "infrared_protocol_sirc_i.h"
+
+const InfraredCommonProtocolSpec infrared_protocol_sirc = {
+ .timings =
+ {
+ .preamble_mark = INFRARED_SIRC_PREAMBLE_MARK,
+ .preamble_space = INFRARED_SIRC_PREAMBLE_SPACE,
+ .bit1_mark = INFRARED_SIRC_BIT1_MARK,
+ .bit1_space = INFRARED_SIRC_BIT1_SPACE,
+ .bit0_mark = INFRARED_SIRC_BIT0_MARK,
+ .bit0_space = INFRARED_SIRC_BIT0_SPACE,
+ .preamble_tolerance = INFRARED_SIRC_PREAMBLE_TOLERANCE,
+ .bit_tolerance = INFRARED_SIRC_BIT_TOLERANCE,
+ .silence_time = INFRARED_SIRC_SILENCE,
+ .min_split_time = INFRARED_SIRC_MIN_SPLIT_TIME,
+ },
+ .databit_len[0] = 20,
+ .databit_len[1] = 15,
+ .databit_len[2] = 12,
+ .no_stop_bit = true,
+ .decode = infrared_common_decode_pdwm,
+ .encode = infrared_common_encode_pdwm,
+ .interpret = infrared_decoder_sirc_interpret,
+ .decode_repeat = NULL,
+ .encode_repeat = infrared_encoder_sirc_encode_repeat,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_sirc = {
+ .name = "SIRC",
+ .address_length = 5,
+ .command_length = 7,
+ .frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
+ .repeat_count = INFRARED_SIRC_REPEAT_COUNT_MIN,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_sirc15 = {
+ .name = "SIRC15",
+ .address_length = 8,
+ .command_length = 7,
+ .frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
+ .repeat_count = INFRARED_SIRC_REPEAT_COUNT_MIN,
+};
+
+static const InfraredProtocolVariant infrared_protocol_variant_sirc20 = {
+ .name = "SIRC20",
+ .address_length = 13,
+ .command_length = 7,
+ .frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
+ .duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
+ .repeat_count = INFRARED_SIRC_REPEAT_COUNT_MIN,
+};
+
+const InfraredProtocolVariant* infrared_protocol_sirc_get_variant(InfraredProtocol protocol) {
+ if(protocol == InfraredProtocolSIRC)
+ return &infrared_protocol_variant_sirc;
+ else if(protocol == InfraredProtocolSIRC15)
+ return &infrared_protocol_variant_sirc15;
+ else if(protocol == InfraredProtocolSIRC20)
+ return &infrared_protocol_variant_sirc20;
+ else
+ return NULL;
+}
diff --git a/lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc.h b/lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc.h
new file mode 100644
index 0000000000..0c3bcd8a2a
--- /dev/null
+++ b/lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "../infrared_i.h"
+
+/***************************************************************************************************
+* Sony SIRC protocol description
+* https://www.sbprojects.net/knowledge/ir/sirc.php
+* http://picprojects.org.uk/
+****************************************************************************************************
+* Preamble Preamble Pulse Width Modulation Pause Entirely repeat
+* mark space up to period message..
+*
+* 2400 600 12/15/20 bits (600,1200) ...45000 2400 600
+* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ __________ _ _
+* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ____________________ __________ _
+* | command | address |
+* SIRC | 7b LSB | 5b LSB |
+* SIRC15 | 7b LSB | 8b LSB |
+* SIRC20 | 7b LSB | 13b LSB |
+*
+* No way to determine either next message is repeat or not,
+* so recognize only fact message received. Sony remotes always send at least 3 messages.
+* Assume 8 last extended bits for SIRC20 are address bits.
+***************************************************************************************************/
+
+void* infrared_decoder_sirc_alloc(void);
+void infrared_decoder_sirc_reset(void* decoder);
+InfraredMessage* infrared_decoder_sirc_check_ready(void* decoder);
+void infrared_decoder_sirc_free(void* decoder);
+InfraredMessage* infrared_decoder_sirc_decode(void* decoder, bool level, uint32_t duration);
+
+void* infrared_encoder_sirc_alloc(void);
+void infrared_encoder_sirc_reset(void* encoder_ptr, const InfraredMessage* message);
+void infrared_encoder_sirc_free(void* decoder);
+InfraredStatus infrared_encoder_sirc_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
+
+const InfraredProtocolVariant* infrared_protocol_sirc_get_variant(InfraredProtocol protocol);
diff --git a/lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc_i.h b/lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc_i.h
new file mode 100644
index 0000000000..e38be9bc86
--- /dev/null
+++ b/lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc_i.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "../common/infrared_common_i.h"
+
+#define INFRARED_SIRC_CARRIER_FREQUENCY 40000
+#define INFRARED_SIRC_DUTY_CYCLE 0.33
+#define INFRARED_SIRC_PREAMBLE_MARK 2400
+#define INFRARED_SIRC_PREAMBLE_SPACE 600
+#define INFRARED_SIRC_BIT1_MARK 1200
+#define INFRARED_SIRC_BIT1_SPACE 600
+#define INFRARED_SIRC_BIT0_MARK 600
+#define INFRARED_SIRC_BIT0_SPACE 600
+#define INFRARED_SIRC_PREAMBLE_TOLERANCE 200 // us
+#define INFRARED_SIRC_BIT_TOLERANCE 120 // us
+#define INFRARED_SIRC_SILENCE 10000
+#define INFRARED_SIRC_MIN_SPLIT_TIME (INFRARED_SIRC_SILENCE - 1000)
+#define INFRARED_SIRC_REPEAT_PERIOD 45000
+#define INFRARED_SIRC_REPEAT_COUNT_MIN 3
+
+extern const InfraredCommonProtocolSpec infrared_protocol_sirc;
+
+bool infrared_decoder_sirc_interpret(InfraredCommonDecoder* decoder);
+InfraredStatus infrared_encoder_sirc_encode_repeat(
+ InfraredCommonEncoder* encoder,
+ uint32_t* duration,
+ bool* level);
diff --git a/lib/infrared/encoder_decoder/sirc/infrared_sirc_spec.c b/lib/infrared/encoder_decoder/sirc/infrared_sirc_spec.c
deleted file mode 100644
index 9bf35908e9..0000000000
--- a/lib/infrared/encoder_decoder/sirc/infrared_sirc_spec.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "../infrared_i.h"
-#include "infrared_protocol_defs_i.h"
-
-static const InfraredProtocolSpecification infrared_sirc_protocol_specification = {
- .name = "SIRC",
- .address_length = 5,
- .command_length = 7,
- .frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
-};
-
-static const InfraredProtocolSpecification infrared_sirc15_protocol_specification = {
- .name = "SIRC15",
- .address_length = 8,
- .command_length = 7,
- .frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
-};
-
-static const InfraredProtocolSpecification infrared_sirc20_protocol_specification = {
- .name = "SIRC20",
- .address_length = 13,
- .command_length = 7,
- .frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
- .duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
-};
-
-const InfraredProtocolSpecification* infrared_sirc_get_spec(InfraredProtocol protocol) {
- if(protocol == InfraredProtocolSIRC)
- return &infrared_sirc_protocol_specification;
- else if(protocol == InfraredProtocolSIRC15)
- return &infrared_sirc15_protocol_specification;
- else if(protocol == InfraredProtocolSIRC20)
- return &infrared_sirc20_protocol_specification;
- else
- return NULL;
-}
diff --git a/lib/infrared/worker/infrared_transmit.c b/lib/infrared/worker/infrared_transmit.c
index 1a50830191..113fb63244 100644
--- a/lib/infrared/worker/infrared_transmit.c
+++ b/lib/infrared/worker/infrared_transmit.c
@@ -101,7 +101,8 @@ void infrared_send(const InfraredMessage* message, int times) {
InfraredEncoderHandler* handler = infrared_alloc_encoder();
infrared_reset_encoder(handler, message);
- infrared_tx_number_of_transmissions = times;
+ infrared_tx_number_of_transmissions =
+ MAX((int)infrared_get_protocol_min_repeat_count(message->protocol), times);
uint32_t frequency = infrared_get_protocol_frequency(message->protocol);
float duty_cycle = infrared_get_protocol_duty_cycle(message->protocol);
diff --git a/lib/infrared/worker/infrared_worker.c b/lib/infrared/worker/infrared_worker.c
index 033dba5259..5add1413e9 100644
--- a/lib/infrared/worker/infrared_worker.c
+++ b/lib/infrared/worker/infrared_worker.c
@@ -1,14 +1,11 @@
-#include
-#include
-#include "sys/_stdint.h"
#include "infrared_worker.h"
-#include
+
#include
-#include
-#include
-#include
#include
+#include
+#include
+
#include
#define INFRARED_WORKER_RX_TIMEOUT INFRARED_RAW_RX_TIMING_DELAY_US
@@ -471,18 +468,23 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
furi_assert(instance->state == InfraredWorkerStateStartTx);
furi_assert(thread_context);
+ size_t repeats_left =
+ instance->signal.decoded ?
+ infrared_get_protocol_min_repeat_count(instance->signal.message.protocol) :
+ 1;
uint32_t events = 0;
- bool new_data_available = true;
- bool exit = false;
- exit = !infrared_get_new_signal(instance);
- furi_assert(!exit);
+ bool exit_pending = false;
- while(!exit) {
+ bool running = infrared_get_new_signal(instance);
+ furi_assert(running);
+
+ while(running) {
switch(instance->state) {
case InfraredWorkerStateStartTx:
+ --repeats_left; /* The first message does not result in TX_MESSAGE_SENT event for some reason */
instance->tx.need_reinitialization = false;
- new_data_available = infrared_worker_tx_fill_buffer(instance);
+ const bool new_data_available = infrared_worker_tx_fill_buffer(instance);
furi_hal_infrared_async_tx_start(instance->tx.frequency, instance->tx.duty_cycle);
if(!new_data_available) {
@@ -496,7 +498,7 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
break;
case InfraredWorkerStateStopTx:
furi_hal_infrared_async_tx_stop();
- exit = true;
+ running = false;
break;
case InfraredWorkerStateWaitTxEnd:
furi_hal_infrared_async_tx_wait_termination();
@@ -504,18 +506,18 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
events = furi_thread_flags_get();
if(events & INFRARED_WORKER_EXIT) {
- exit = true;
+ running = false;
break;
}
break;
case InfraredWorkerStateRunTx:
- events = furi_thread_flags_wait(INFRARED_WORKER_ALL_TX_EVENTS, 0, FuriWaitForever);
+ events = furi_thread_flags_wait(
+ INFRARED_WORKER_ALL_TX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
furi_check(events & INFRARED_WORKER_ALL_TX_EVENTS); /* at least one caught */
if(events & INFRARED_WORKER_EXIT) {
- instance->state = InfraredWorkerStateStopTx;
- break;
+ exit_pending = true;
}
if(events & INFRARED_WORKER_TX_FILL_BUFFER) {
@@ -527,9 +529,19 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
}
if(events & INFRARED_WORKER_TX_MESSAGE_SENT) {
- if(instance->tx.message_sent_callback)
+ if(repeats_left > 0) {
+ --repeats_left;
+ }
+
+ if(instance->tx.message_sent_callback) {
instance->tx.message_sent_callback(instance->tx.message_sent_context);
+ }
}
+
+ if(exit_pending && repeats_left == 0) {
+ instance->state = InfraredWorkerStateStopTx;
+ }
+
break;
default:
furi_assert(0);
diff --git a/lib/lfrfid/protocols/protocol_paradox.c b/lib/lfrfid/protocols/protocol_paradox.c
index 7e029f1de2..26c9b55dcd 100644
--- a/lib/lfrfid/protocols/protocol_paradox.c
+++ b/lib/lfrfid/protocols/protocol_paradox.c
@@ -136,17 +136,45 @@ LevelDuration protocol_paradox_encoder_yield(ProtocolParadox* protocol) {
return level_duration_make(level, duration);
};
+static uint8_t protocol_paradox_calculate_checksum(uint8_t fc, uint16_t card_id) {
+ uint8_t card_hi = (card_id >> 8) & 0xff;
+ uint8_t card_lo = card_id & 0xff;
+
+ uint8_t arr[5] = {0, 0, fc, card_hi, card_lo};
+
+ uint8_t manchester[9];
+
+ bit_lib_push_bit(manchester, 9, false);
+ bit_lib_push_bit(manchester, 9, false);
+ bit_lib_push_bit(manchester, 9, false);
+ bit_lib_push_bit(manchester, 9, false);
+
+ for(uint8_t i = 6; i < 40; i += 1) {
+ if(bit_lib_get_bit(arr, i) == 0b1) {
+ bit_lib_push_bit(manchester, 9, true);
+ bit_lib_push_bit(manchester, 9, false);
+ } else {
+ bit_lib_push_bit(manchester, 9, false);
+ bit_lib_push_bit(manchester, 9, true);
+ }
+ }
+
+ uint8_t output = bit_lib_crc8(manchester, 9, 0x31, 0x00, true, true, 0x06);
+
+ return output;
+}
+
void protocol_paradox_render_data(ProtocolParadox* protocol, FuriString* result) {
uint8_t* decoded_data = protocol->data;
uint8_t fc = bit_lib_get_bits(decoded_data, 10, 8);
uint16_t card_id = bit_lib_get_bits_16(decoded_data, 18, 16);
+ uint8_t card_crc = bit_lib_get_bits_16(decoded_data, 34, 8);
+ uint8_t calc_crc = protocol_paradox_calculate_checksum(fc, card_id);
furi_string_cat_printf(result, "Facility: %u\r\n", fc);
furi_string_cat_printf(result, "Card: %u\r\n", card_id);
- furi_string_cat_printf(result, "Data: ");
- for(size_t i = 0; i < PARADOX_DECODED_DATA_SIZE; i++) {
- furi_string_cat_printf(result, "%02X", decoded_data[i]);
- }
+ furi_string_cat_printf(result, "CRC: %u Calc CRC: %u\r\n", card_crc, calc_crc);
+ if(card_crc != calc_crc) furi_string_cat_printf(result, "CRC Mismatch, Invalid Card!\r\n");
};
void protocol_paradox_render_brief_data(ProtocolParadox* protocol, FuriString* result) {
@@ -154,8 +182,15 @@ void protocol_paradox_render_brief_data(ProtocolParadox* protocol, FuriString* r
uint8_t fc = bit_lib_get_bits(decoded_data, 10, 8);
uint16_t card_id = bit_lib_get_bits_16(decoded_data, 18, 16);
-
- furi_string_cat_printf(result, "FC: %03u, Card: %05u", fc, card_id);
+ uint8_t card_crc = bit_lib_get_bits_16(decoded_data, 34, 8);
+ uint8_t calc_crc = protocol_paradox_calculate_checksum(fc, card_id);
+
+ furi_string_cat_printf(result, "FC: %03u, Card: %05u\r\n", fc, card_id);
+ if(calc_crc == card_crc) {
+ furi_string_cat_printf(result, "CRC : %03u", card_crc);
+ } else {
+ furi_string_cat_printf(result, "Card is Invalid!");
+ }
};
bool protocol_paradox_write_data(ProtocolParadox* protocol, void* data) {
diff --git a/lib/nfc/helpers/nfc_generators.c b/lib/nfc/helpers/nfc_generators.c
index 769b9c7b6b..590ff4d50b 100644
--- a/lib/nfc/helpers/nfc_generators.c
+++ b/lib/nfc/helpers/nfc_generators.c
@@ -352,11 +352,27 @@ void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType
}
// Set SAK to 08
data->nfc_data.sak = 0x08;
+ } else if(type == MfClassicTypeMini) {
+ // Set every block to 0xFF
+ for(uint16_t i = 1; i < MF_MINI_TOTAL_SECTORS_NUM * 4; i += 1) {
+ if(mf_classic_is_sector_trailer(i)) {
+ nfc_generate_mf_classic_sector_trailer(mfc, i);
+ } else {
+ memset(&mfc->block[i].value, 0xFF, 16);
+ }
+ mf_classic_set_block_read(mfc, i, &mfc->block[i]);
+ }
+ // Set SAK to 09
+ data->nfc_data.sak = 0x09;
}
mfc->type = type;
}
+static void nfc_generate_mf_mini(NfcDeviceData* data) {
+ nfc_generate_mf_classic(data, 4, MfClassicTypeMini);
+}
+
static void nfc_generate_mf_classic_1k_4b_uid(NfcDeviceData* data) {
nfc_generate_mf_classic(data, 4, MfClassicType1k);
}
@@ -438,6 +454,11 @@ static const NfcGenerator ntag_i2c_plus_2k_generator = {
.generator_func = nfc_generate_ntag_i2c_plus_2k,
};
+static const NfcGenerator mifare_mini_generator = {
+ .name = "Mifare Mini",
+ .generator_func = nfc_generate_mf_mini,
+};
+
static const NfcGenerator mifare_classic_1k_4b_uid_generator = {
.name = "Mifare Classic 1k 4byte UID",
.generator_func = nfc_generate_mf_classic_1k_4b_uid,
@@ -472,6 +493,7 @@ const NfcGenerator* const nfc_generators[] = {
&ntag_i2c_2k_generator,
&ntag_i2c_plus_1k_generator,
&ntag_i2c_plus_2k_generator,
+ &mifare_mini_generator,
&mifare_classic_1k_4b_uid_generator,
&mifare_classic_1k_7b_uid_generator,
&mifare_classic_4k_4b_uid_generator,
diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c
index 2a47ba1fde..df7688ed15 100644
--- a/lib/nfc/nfc_device.c
+++ b/lib/nfc/nfc_device.c
@@ -1055,7 +1055,10 @@ static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice*
do {
if(!flipper_format_write_comment_cstr(file, "Mifare Classic specific data")) break;
- if(data->type == MfClassicType1k) {
+ if(data->type == MfClassicTypeMini) {
+ if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "MINI")) break;
+ blocks = 20;
+ } else if(data->type == MfClassicType1k) {
if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "1K")) break;
blocks = 64;
} else if(data->type == MfClassicType4k) {
@@ -1153,7 +1156,10 @@ static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice*
do {
// Read Mifare Classic type
if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break;
- if(!furi_string_cmp(temp_str, "1K")) {
+ if(!furi_string_cmp(temp_str, "MINI")) {
+ data->type = MfClassicTypeMini;
+ data_blocks = 20;
+ } else if(!furi_string_cmp(temp_str, "1K")) {
data->type = MfClassicType1k;
data_blocks = 64;
} else if(!furi_string_cmp(temp_str, "4K")) {
@@ -1228,7 +1234,9 @@ static bool nfc_device_save_mifare_classic_keys(NfcDevice* dev) {
if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break;
if(!flipper_format_write_header_cstr(file, nfc_keys_file_header, nfc_keys_file_version))
break;
- if(data->type == MfClassicType1k) {
+ if(data->type == MfClassicTypeMini) {
+ if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "MINI")) break;
+ } else if(data->type == MfClassicType1k) {
if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "1K")) break;
} else if(data->type == MfClassicType4k) {
if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "4K")) break;
@@ -1278,7 +1286,9 @@ bool nfc_device_load_key_cache(NfcDevice* dev) {
if(furi_string_cmp_str(temp_str, nfc_keys_file_header)) break;
if(version != nfc_keys_file_version) break;
if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break;
- if(!furi_string_cmp(temp_str, "1K")) {
+ if(!furi_string_cmp(temp_str, "MINI")) {
+ data->type = MfClassicTypeMini;
+ } else if(!furi_string_cmp(temp_str, "1K")) {
data->type = MfClassicType1k;
} else if(!furi_string_cmp(temp_str, "4K")) {
data->type = MfClassicType4k;
diff --git a/lib/nfc/nfc_types.c b/lib/nfc/nfc_types.c
index 4276287699..02ca85580d 100644
--- a/lib/nfc/nfc_types.c
+++ b/lib/nfc/nfc_types.c
@@ -55,7 +55,9 @@ const char* nfc_mf_ul_type(MfUltralightType type, bool full_name) {
}
const char* nfc_mf_classic_type(MfClassicType type) {
- if(type == MfClassicType1k) {
+ if(type == MfClassicTypeMini) {
+ return "Mifare Mini 0.3K";
+ } else if(type == MfClassicType1k) {
return "Mifare Classic 1K";
} else if(type == MfClassicType4k) {
return "Mifare Classic 4K";
diff --git a/lib/nfc/protocols/mifare_classic.c b/lib/nfc/protocols/mifare_classic.c
index a22617ef70..5fda122ab7 100644
--- a/lib/nfc/protocols/mifare_classic.c
+++ b/lib/nfc/protocols/mifare_classic.c
@@ -13,7 +13,9 @@
#define MF_CLASSIC_WRITE_BLOCK_CMD (0xA0)
const char* mf_classic_get_type_str(MfClassicType type) {
- if(type == MfClassicType1k) {
+ if(type == MfClassicTypeMini) {
+ return "MIFARE Mini 0.3K";
+ } else if(type == MfClassicType1k) {
return "MIFARE Classic 1K";
} else if(type == MfClassicType4k) {
return "MIFARE Classic 4K";
@@ -73,7 +75,9 @@ MfClassicSectorTrailer*
}
uint8_t mf_classic_get_total_sectors_num(MfClassicType type) {
- if(type == MfClassicType1k) {
+ if(type == MfClassicTypeMini) {
+ return MF_MINI_TOTAL_SECTORS_NUM;
+ } else if(type == MfClassicType1k) {
return MF_CLASSIC_1K_TOTAL_SECTORS_NUM;
} else if(type == MfClassicType4k) {
return MF_CLASSIC_4K_TOTAL_SECTORS_NUM;
@@ -83,7 +87,9 @@ uint8_t mf_classic_get_total_sectors_num(MfClassicType type) {
}
uint16_t mf_classic_get_total_block_num(MfClassicType type) {
- if(type == MfClassicType1k) {
+ if(type == MfClassicTypeMini) {
+ return 20;
+ } else if(type == MfClassicType1k) {
return 64;
} else if(type == MfClassicType4k) {
return 256;
@@ -361,10 +367,14 @@ bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
}
}
-MfClassicType mf_classic_get_classic_type(int8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
+MfClassicType mf_classic_get_classic_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
UNUSED(ATQA1);
- if((ATQA0 == 0x44 || ATQA0 == 0x04) && (SAK == 0x08 || SAK == 0x88 || SAK == 0x09)) {
- return MfClassicType1k;
+ if((ATQA0 == 0x44 || ATQA0 == 0x04)) {
+ if((SAK == 0x08 || SAK == 0x88)) {
+ return MfClassicType1k;
+ } else if(SAK == 0x09) {
+ return MfClassicTypeMini;
+ }
} else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) {
//skylanders support
return MfClassicType1k;
@@ -589,13 +599,14 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u
if(!key_a_found) break;
FURI_LOG_D(TAG, "Try to read blocks with key A");
key = nfc_util_bytes2num(sec_tr->key_a, sizeof(sec_tr->key_a));
- if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyA, &crypto, false, 0)) break;
for(size_t i = start_block; i < start_block + total_blocks; i++) {
if(!mf_classic_is_block_read(data, i)) {
+ if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyA, &crypto, false, 0)) continue;
if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
mf_classic_set_block_read(data, i, &block_tmp);
blocks_read++;
}
+ furi_hal_nfc_sleep();
} else {
blocks_read++;
}
@@ -607,14 +618,14 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u
if(!key_b_found) break;
FURI_LOG_D(TAG, "Try to read blocks with key B");
key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b));
- furi_hal_nfc_sleep();
- if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto, false, 0)) break;
for(size_t i = start_block; i < start_block + total_blocks; i++) {
if(!mf_classic_is_block_read(data, i)) {
+ if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyB, &crypto, false, 0)) continue;
if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
mf_classic_set_block_read(data, i, &block_tmp);
blocks_read++;
}
+ furi_hal_nfc_sleep();
} else {
blocks_read++;
}
diff --git a/lib/nfc/protocols/mifare_classic.h b/lib/nfc/protocols/mifare_classic.h
index 74beceb625..ac5701ecf7 100644
--- a/lib/nfc/protocols/mifare_classic.h
+++ b/lib/nfc/protocols/mifare_classic.h
@@ -8,6 +8,7 @@
#define MF_CLASSIC_TOTAL_BLOCKS_MAX (256)
#define MF_CLASSIC_1K_TOTAL_SECTORS_NUM (16)
#define MF_CLASSIC_4K_TOTAL_SECTORS_NUM (40)
+#define MF_MINI_TOTAL_SECTORS_NUM (5)
#define MF_CLASSIC_SECTORS_MAX (40)
#define MF_CLASSIC_BLOCKS_IN_SECTOR_MAX (16)
@@ -18,6 +19,7 @@
#define MF_CLASSIC_ACCESS_BYTES_SIZE (4)
typedef enum {
+ MfClassicTypeMini,
MfClassicType1k,
MfClassicType4k,
} MfClassicType;
@@ -94,7 +96,7 @@ const char* mf_classic_get_type_str(MfClassicType type);
bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK);
-MfClassicType mf_classic_get_classic_type(int8_t ATQA0, uint8_t ATQA1, uint8_t SAK);
+MfClassicType mf_classic_get_classic_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK);
uint8_t mf_classic_get_total_sectors_num(MfClassicType type);
diff --git a/lib/subghz/protocols/protocol_items.c b/lib/subghz/protocols/protocol_items.c
index 5d708c4681..5f733d6bdf 100644
--- a/lib/subghz/protocols/protocol_items.c
+++ b/lib/subghz/protocols/protocol_items.c
@@ -1,18 +1,18 @@
#include "protocol_items.h"
const SubGhzProtocol* subghz_protocol_registry_items[] = {
- &subghz_protocol_gate_tx, &subghz_protocol_keeloq, &subghz_protocol_star_line,
- &subghz_protocol_nice_flo, &subghz_protocol_came, &subghz_protocol_faac_slh,
- &subghz_protocol_nice_flor_s, &subghz_protocol_came_twee, &subghz_protocol_came_atomo,
- &subghz_protocol_nero_sketch, &subghz_protocol_ido, &subghz_protocol_kia,
- &subghz_protocol_hormann, &subghz_protocol_nero_radio, &subghz_protocol_somfy_telis,
- &subghz_protocol_somfy_keytis, &subghz_protocol_scher_khan, &subghz_protocol_princeton,
- &subghz_protocol_raw, &subghz_protocol_linear, &subghz_protocol_secplus_v2,
- &subghz_protocol_secplus_v1, &subghz_protocol_megacode, &subghz_protocol_holtek,
- &subghz_protocol_chamb_code, &subghz_protocol_power_smart, &subghz_protocol_marantec,
- &subghz_protocol_bett, &subghz_protocol_doitrand, &subghz_protocol_phoenix_v2,
- &subghz_protocol_honeywell_wdb, &subghz_protocol_magellan, &subghz_protocol_intertechno_v3,
- &subghz_protocol_clemsa, &subghz_protocol_ansonic, &subghz_protocol_pocsag,
+ &subghz_protocol_gate_tx, &subghz_protocol_keeloq, &subghz_protocol_star_line,
+ &subghz_protocol_nice_flo, &subghz_protocol_came, &subghz_protocol_faac_slh,
+ &subghz_protocol_nice_flor_s, &subghz_protocol_came_twee, &subghz_protocol_came_atomo,
+ &subghz_protocol_nero_sketch, &subghz_protocol_ido, &subghz_protocol_kia,
+ &subghz_protocol_hormann, &subghz_protocol_nero_radio, &subghz_protocol_somfy_telis,
+ &subghz_protocol_somfy_keytis, &subghz_protocol_scher_khan, &subghz_protocol_princeton,
+ &subghz_protocol_raw, &subghz_protocol_linear, &subghz_protocol_secplus_v2,
+ &subghz_protocol_secplus_v1, &subghz_protocol_megacode, &subghz_protocol_holtek,
+ &subghz_protocol_chamb_code, &subghz_protocol_power_smart, &subghz_protocol_marantec,
+ &subghz_protocol_bett, &subghz_protocol_doitrand, &subghz_protocol_phoenix_v2,
+ &subghz_protocol_honeywell_wdb, &subghz_protocol_magellan, &subghz_protocol_intertechno_v3,
+ &subghz_protocol_clemsa, &subghz_protocol_ansonic, &subghz_protocol_pocsag,
&subghz_protocol_smc5326, &subghz_protocol_holtek_th12x,
};
diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c
index 61a7442aa0..393d7f360f 100644
--- a/lib/subghz/protocols/raw.c
+++ b/lib/subghz/protocols/raw.c
@@ -170,6 +170,7 @@ bool subghz_protocol_raw_save_to_file_init(
instance->upload_raw = malloc(SUBGHZ_DOWNLOAD_MAX_SIZE * sizeof(int32_t));
instance->file_is_open = RAWFileIsOpenWrite;
instance->sample_write = 0;
+ instance->last_level = false;
instance->pause = false;
init = true;
} while(0);
diff --git a/lib/subghz/subghz_worker.c b/lib/subghz/subghz_worker.c
index 35e3998858..50b5aba511 100644
--- a/lib/subghz/subghz_worker.c
+++ b/lib/subghz/subghz_worker.c
@@ -12,7 +12,6 @@ struct SubGhzWorker {
volatile bool overrun;
LevelDuration filter_level_duration;
- bool filter_running;
uint16_t filter_duration;
SubGhzWorkerOverrunCallback overrun_callback;
@@ -59,24 +58,19 @@ static int32_t subghz_worker_thread_callback(void* context) {
bool level = level_duration_get_level(level_duration);
uint32_t duration = level_duration_get_duration(level_duration);
- if(instance->filter_running) {
- if((duration < instance->filter_duration) ||
- (instance->filter_level_duration.level == level)) {
- instance->filter_level_duration.duration += duration;
-
- } else if(instance->filter_level_duration.level != level) {
- if(instance->pair_callback)
- instance->pair_callback(
- instance->context,
- instance->filter_level_duration.level,
- instance->filter_level_duration.duration);
-
- instance->filter_level_duration.duration = duration;
- instance->filter_level_duration.level = level;
- }
- } else {
+ if((duration < instance->filter_duration) ||
+ (instance->filter_level_duration.level == level)) {
+ instance->filter_level_duration.duration += duration;
+
+ } else if(instance->filter_level_duration.level != level) {
if(instance->pair_callback)
- instance->pair_callback(instance->context, level, duration);
+ instance->pair_callback(
+ instance->context,
+ instance->filter_level_duration.level,
+ instance->filter_level_duration.duration);
+
+ instance->filter_level_duration.duration = duration;
+ instance->filter_level_duration.level = level;
}
}
}
@@ -94,8 +88,7 @@ SubGhzWorker* subghz_worker_alloc() {
instance->stream =
furi_stream_buffer_alloc(sizeof(LevelDuration) * 4096, sizeof(LevelDuration));
- //setting filter
- instance->filter_running = true;
+ //setting default filter in us
instance->filter_duration = 30;
return instance;
@@ -149,3 +142,8 @@ bool subghz_worker_is_running(SubGhzWorker* instance) {
furi_assert(instance);
return instance->running;
}
+
+void subghz_worker_set_filter(SubGhzWorker* instance, uint16_t timeout) {
+ furi_assert(instance);
+ instance->filter_duration = timeout;
+}
\ No newline at end of file
diff --git a/lib/subghz/subghz_worker.h b/lib/subghz/subghz_worker.h
index f85b1fdc7a..657278f505 100644
--- a/lib/subghz/subghz_worker.h
+++ b/lib/subghz/subghz_worker.h
@@ -67,6 +67,14 @@ void subghz_worker_stop(SubGhzWorker* instance);
*/
bool subghz_worker_is_running(SubGhzWorker* instance);
+/**
+ * Short duration filter setting.
+ * glues short durations into 1. The default setting is 30 us, if set to 0 the filter will be disabled
+ * @param instance Pointer to a SubGhzWorker instance
+ * @param timeout time in us
+ */
+void subghz_worker_set_filter(SubGhzWorker* instance, uint16_t timeout);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/toolbox/value_index.c b/lib/toolbox/value_index.c
index e0745e4341..87bf990f37 100644
--- a/lib/toolbox/value_index.c
+++ b/lib/toolbox/value_index.c
@@ -1,5 +1,16 @@
#include "value_index.h"
+uint8_t value_index_int32(const int32_t value, const int32_t values[], uint8_t values_count) {
+ uint8_t index = 0;
+ for(uint8_t i = 0; i < values_count; i++) {
+ if(value == values[i]) {
+ index = i;
+ break;
+ }
+ }
+ return index;
+}
+
uint8_t value_index_uint32(const uint32_t value, const uint32_t values[], uint8_t values_count) {
int64_t last_value = INT64_MIN;
uint8_t index = 0;
diff --git a/lib/toolbox/value_index.h b/lib/toolbox/value_index.h
index 9459292a75..23d53ca215 100644
--- a/lib/toolbox/value_index.h
+++ b/lib/toolbox/value_index.h
@@ -7,6 +7,19 @@
extern "C" {
#endif
+/** Get the index of a int32_t array element which is equal to the given value.
+ *
+ * Returned index corresponds to the first element found.
+ * If no suitable elements were found, the function returns 0.
+ *
+ * @param value value to be searched.
+ * @param values pointer to the array to perform the search in.
+ * @param values_count array size.
+ *
+ * @return value's index.
+ */
+uint8_t value_index_int32(const int32_t value, const int32_t values[], uint8_t values_count);
+
/** Get the index of a uint32_t array element which is closest to the given value.
*
* Returned index corresponds to the first element found.
diff --git a/scripts/FlipperPlaylist.py b/scripts/FlipperPlaylist.py
new file mode 100644
index 0000000000..4a688f2fbb
--- /dev/null
+++ b/scripts/FlipperPlaylist.py
@@ -0,0 +1,27 @@
+# Flipper Zero SUB-GHZ Playlist Generator
+import os
+import pip
+try:
+ from easygui import diropenbox
+except ImportError:
+ pip.main(['Install'], "easygui")
+ from easygui import diropenbox
+
+def main():
+ folder_path = diropenbox("Select the folder with Subghz files", "Subghz selector")
+ output_path = diropenbox("Select your output location", "Output location")
+ playlist_name = str(input("Enter a name for the playlist: "))
+ playlist_file = open((output_path + playlist_name.lower() + ".txt"), "w")
+ playlist_file.write("# " + playlist_name + "\n")
+ for root, dirs, files in os.walk(folder_path, topdown=True):
+ for file in files:
+ if file.endswith(".sub"):
+ file_path = os.path.join(root, file)
+ file_path = file_path.replace("\\", "/")
+ file_path = file_path.replace(f"{folder_path.split(':')[0]}:", "ext")
+ playlist_file.write(f"sub: {file_path}\n")
+ playlist_file.close()
+ print("Done!")
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/scripts/assets.py b/scripts/assets.py
index 7f086afd7c..9307831417 100755
--- a/scripts/assets.py
+++ b/scripts/assets.py
@@ -4,8 +4,8 @@
from flipper.assets.icon import file2image
import os
-import sys
import shutil
+import pathlib
ICONS_SUPPORTED_FORMATS = ["png"]
@@ -27,13 +27,13 @@
valid_dirs = list()
# This will not stay, dont worry! This is temp code until we got time to rewrite this all
-we_are_here = "\\".join(os.path.abspath(__file__).split("\\")[:-2])
-dolphin_external = os.path.join(we_are_here, r"assets\dolphin\external/")
-potential_directories = [d for d in os.listdir(dolphin_external) if os.path.isdir(os.path.join(dolphin_external, d))] # Get all animation directories
+root_dir = pathlib.Path(__file__).absolute().parent.parent
+dolphin_external = root_dir / "assets/dolphin/external/"
+potential_directories = [item for item in dolphin_external.iterdir() if item.is_dir()] # Get all animation directories
-for i in potential_directories: # loop through all of them
- if os.path.exists(os.path.join(dolphin_external, f"{i}\manifest.txt")): # check if they contain a manifest.txt TODO: This code should be moved to wherever manifest.txt files are validated!
- valid_dirs.append(os.path.join(dolphin_external, f"{i}")) # append valid directory to list
+for directory in potential_directories: # loop through all of them
+ if (directory / "manifest.txt").exists(): # check if they contain a manifest.txt TODO: This code should be moved to wherever manifest.txt files are validated!
+ valid_dirs.append(directory) # append valid directory to list
class Main(App):
def init(self):
@@ -259,10 +259,9 @@ def manifest(self):
# This will not stay, dont worry! This is temp code until we got time to rewrite this all
global valid_dirs # access our global variable
- for i in valid_dirs: # We can copy the manifest for all of the valid dirs!
- i = i.split("/")[-1]
- shutil.copyfile(fr"assets\dolphin\external\{i}\manifest.txt", fr"assets\resources\dolphin\{i}\manifest.txt")
- os.remove(r"assets\resources\dolphin\manifest.txt")
+ for valid_dir in valid_dirs: # We can copy the manifest for all of the valid dirs!
+ shutil.copyfile(valid_dir / "manifest.txt", root_dir / f"assets/resources/dolphin/{valid_dir.name}/manifest.txt")
+ (root_dir / "assets/resources/dolphin/manifest.txt").unlink()
self.logger.info(f"Complete")
@@ -292,7 +291,7 @@ def dolphin(self):
self.logger.info(f"Processing Dolphin sources")
dolphin = Dolphin()
self.logger.info(f"Loading data")
- if not "dolphin\external" in str(self.args.input_directory): # AHEM... oopsie. This script apparently just loads all assets, not only external assets, lol.
+ if not f"dolphin{os.sep}external" in str(self.args.input_directory): # AHEM... oopsie. This script apparently just loads all assets, not only external assets, lol.
dolphin.load([self.args.input_directory])
else:
dolphin.load(valid_dirs)
diff --git a/scripts/version.py b/scripts/version.py
index 74c2f4a042..8f3ff0cf57 100644
--- a/scripts/version.py
+++ b/scripts/version.py
@@ -14,7 +14,7 @@ def __init__(self, source_dir):
self.gitlist = [("commit", "rev-parse --short HEAD"), ("branch", "rev-parse --abbrev-ref") , ("branch_num", "rev-list -count HEAD")]
def get_version_info(self):
- commit = branch = branch_num = "XFW-0037"
+ commit = branch = branch_num = "XFW-0039"
# We dont use an `or` in commands that we expect to fail. It will serve no function.
# We also dont try;exept an entire block of code. This is bad practise. We only try the single part that we expect to fail!
@@ -40,7 +40,15 @@ def get_version_info(self):
os.environ.get("CUSTOM_FLIPPER_NAME", None)
or ""
)
-
+
+ force_no_dirty = (
+ os.environ.get("FORCE_NO_DIRTY", None)
+ or ""
+ )
+
+ if (force_no_dirty != ""):
+ dirty = False
+
if (custom_fz_name != "") and (len(custom_fz_name) <= 8) and (custom_fz_name.isalnum()) and (custom_fz_name.isascii()):
return {
"GIT_COMMIT": commit,
diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons
index 3e6859b4e3..00781db314 100644
--- a/site_scons/commandline.scons
+++ b/site_scons/commandline.scons
@@ -106,6 +106,11 @@ vars.AddVariables(
"Replaces OTP flipper name with custom string of 8 chars",
"",
),
+ (
+ "FORCE_NO_DIRTY",
+ "Force disable dirty status of the build",
+ "",
+ ),
(
"COPRO_CUBE_VERSION",
"Cube version",
@@ -242,4 +247,4 @@ vars.AddVariables(
),
)
-Return("vars")
+Return("vars")
\ No newline at end of file
diff --git a/site_scons/environ.scons b/site_scons/environ.scons
index 128a667f15..ab60d4e71b 100644
--- a/site_scons/environ.scons
+++ b/site_scons/environ.scons
@@ -21,6 +21,7 @@ variables_to_forward = [
"WORKFLOW_BRANCH_OR_TAG",
"DIST_SUFFIX",
"CUSTOM_FLIPPER_NAME",
+ "FORCE_NO_DIRTY",
# Python & other tools
"HOME",
"APPDATA",
@@ -87,4 +88,4 @@ SetOption("max_drift", 1)
wrap_tempfile(coreenv, "LINKCOM")
wrap_tempfile(coreenv, "ARCOM")
-Return("coreenv")
+Return("coreenv")
\ No newline at end of file
diff --git a/site_scons/extapps.scons b/site_scons/extapps.scons
index 5f6b1393fb..6b67357058 100644
--- a/site_scons/extapps.scons
+++ b/site_scons/extapps.scons
@@ -1,4 +1,3 @@
-import os
from dataclasses import dataclass, field
from SCons.Node import NodeList
from SCons.Warnings import warn, WarningOnByDefault
@@ -110,25 +109,12 @@ if appsrc := appenv.subst("$APPSRC"):
app_artifacts = appenv.GetExtAppFromPath(appsrc)
appenv.PhonyTarget(
"launch_app",
- '${PYTHON3} "${APP_RUN_SCRIPT}" --launch "${SOURCE}" --fap_dst_dir "/ext/apps/${FAP_CATEGORY}"',
+ '${PYTHON3} "${APP_RUN_SCRIPT}" "${SOURCE}" --fap_dst_dir "/ext/apps/${FAP_CATEGORY}"',
source=app_artifacts.compact,
FAP_CATEGORY=app_artifacts.app.fap_category,
)
appenv.Alias("launch_app", app_artifacts.validator)
-appenv.PhonyTarget(
- "faps_copy",
- os.linesep.join(
- [
- '${PYTHON3} "${APP_RUN_SCRIPT}"'
- f' "{app_artifact.compact[0].rstr()}"'
- f' --fap_dst_dir "/ext/apps/{app_artifact.app.fap_category}"'
- for app_artifact in appenv["EXT_APPS"].values()
- ]
- ),
- source=["faps"],
-)
-
# SDK management
sdk_origin_path = "${BUILD_DIR}/sdk_origin"