mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-20 04:54:45 -07:00
Merge branch 'dev' of https://github.com/DarkFlippers/unleashed-firmware into xfw-dev
This commit is contained in:
@@ -11,6 +11,7 @@ typedef struct {
|
||||
uint16_t left;
|
||||
uint16_t right;
|
||||
uint16_t ok;
|
||||
FuriMutex* mutex;
|
||||
} KeypadTestState;
|
||||
|
||||
static void keypad_test_reset_state(KeypadTestState* state) {
|
||||
@@ -22,7 +23,8 @@ static void keypad_test_reset_state(KeypadTestState* state) {
|
||||
}
|
||||
|
||||
static void keypad_test_render_callback(Canvas* canvas, void* ctx) {
|
||||
KeypadTestState* state = (KeypadTestState*)acquire_mutex((ValueMutex*)ctx, 25);
|
||||
KeypadTestState* state = ctx;
|
||||
furi_mutex_acquire(state->mutex, FuriWaitForever);
|
||||
canvas_clear(canvas);
|
||||
char strings[5][20];
|
||||
|
||||
@@ -51,7 +53,7 @@ static void keypad_test_render_callback(Canvas* canvas, void* ctx) {
|
||||
|
||||
canvas_draw_str(canvas, 10, 63, "[back] - reset, hold to exit");
|
||||
|
||||
release_mutex((ValueMutex*)ctx, state);
|
||||
furi_mutex_release(state->mutex);
|
||||
}
|
||||
|
||||
static void keypad_test_input_callback(InputEvent* input_event, void* ctx) {
|
||||
@@ -64,17 +66,17 @@ int32_t keypad_test_app(void* p) {
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
|
||||
furi_check(event_queue);
|
||||
|
||||
KeypadTestState _state = {{false, false, false, false, false}, 0, 0, 0, 0, 0};
|
||||
KeypadTestState state = {{false, false, false, false, false}, 0, 0, 0, 0, 0, NULL};
|
||||
state.mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, &_state, sizeof(KeypadTestState))) {
|
||||
if(!state.mutex) {
|
||||
FURI_LOG_E(TAG, "cannot create mutex");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
|
||||
view_port_draw_callback_set(view_port, keypad_test_render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, keypad_test_render_callback, &state);
|
||||
view_port_input_callback_set(view_port, keypad_test_input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -83,7 +85,7 @@ int32_t keypad_test_app(void* p) {
|
||||
|
||||
InputEvent event;
|
||||
while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
|
||||
KeypadTestState* state = (KeypadTestState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(state.mutex, FuriWaitForever);
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"key: %s type: %s",
|
||||
@@ -92,54 +94,54 @@ int32_t keypad_test_app(void* p) {
|
||||
|
||||
if(event.key == InputKeyRight) {
|
||||
if(event.type == InputTypePress) {
|
||||
state->press[0] = true;
|
||||
state.press[0] = true;
|
||||
} else if(event.type == InputTypeRelease) {
|
||||
state->press[0] = false;
|
||||
state.press[0] = false;
|
||||
} else if(event.type == InputTypeShort) {
|
||||
++state->right;
|
||||
++state.right;
|
||||
}
|
||||
} else if(event.key == InputKeyLeft) {
|
||||
if(event.type == InputTypePress) {
|
||||
state->press[1] = true;
|
||||
state.press[1] = true;
|
||||
} else if(event.type == InputTypeRelease) {
|
||||
state->press[1] = false;
|
||||
state.press[1] = false;
|
||||
} else if(event.type == InputTypeShort) {
|
||||
++state->left;
|
||||
++state.left;
|
||||
}
|
||||
} else if(event.key == InputKeyUp) {
|
||||
if(event.type == InputTypePress) {
|
||||
state->press[2] = true;
|
||||
state.press[2] = true;
|
||||
} else if(event.type == InputTypeRelease) {
|
||||
state->press[2] = false;
|
||||
state.press[2] = false;
|
||||
} else if(event.type == InputTypeShort) {
|
||||
++state->up;
|
||||
++state.up;
|
||||
}
|
||||
} else if(event.key == InputKeyDown) {
|
||||
if(event.type == InputTypePress) {
|
||||
state->press[3] = true;
|
||||
state.press[3] = true;
|
||||
} else if(event.type == InputTypeRelease) {
|
||||
state->press[3] = false;
|
||||
state.press[3] = false;
|
||||
} else if(event.type == InputTypeShort) {
|
||||
++state->down;
|
||||
++state.down;
|
||||
}
|
||||
} else if(event.key == InputKeyOk) {
|
||||
if(event.type == InputTypePress) {
|
||||
state->press[4] = true;
|
||||
state.press[4] = true;
|
||||
} else if(event.type == InputTypeRelease) {
|
||||
state->press[4] = false;
|
||||
state.press[4] = false;
|
||||
} else if(event.type == InputTypeShort) {
|
||||
++state->ok;
|
||||
++state.ok;
|
||||
}
|
||||
} else if(event.key == InputKeyBack) {
|
||||
if(event.type == InputTypeLong) {
|
||||
release_mutex(&state_mutex, state);
|
||||
furi_mutex_release(state.mutex);
|
||||
break;
|
||||
} else if(event.type == InputTypeShort) {
|
||||
keypad_test_reset_state(state);
|
||||
keypad_test_reset_state(&state);
|
||||
}
|
||||
}
|
||||
|
||||
release_mutex(&state_mutex, state);
|
||||
furi_mutex_release(state.mutex);
|
||||
view_port_update(view_port);
|
||||
}
|
||||
|
||||
@@ -147,7 +149,7 @@ int32_t keypad_test_app(void* p) {
|
||||
gui_remove_view_port(gui, view_port);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(state.mutex);
|
||||
|
||||
furi_record_close(RECORD_GUI);
|
||||
|
||||
|
||||
@@ -53,15 +53,17 @@ static void (*text_box_test_render[])(Canvas* canvas) = {
|
||||
|
||||
typedef struct {
|
||||
uint32_t idx;
|
||||
FuriMutex* mutex;
|
||||
} TextBoxTestState;
|
||||
|
||||
static void text_box_test_render_callback(Canvas* canvas, void* ctx) {
|
||||
TextBoxTestState* state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
TextBoxTestState* state = ctx;
|
||||
furi_mutex_acquire(state->mutex, FuriWaitForever);
|
||||
canvas_clear(canvas);
|
||||
|
||||
text_box_test_render[state->idx](canvas);
|
||||
|
||||
release_mutex((ValueMutex*)ctx, state);
|
||||
furi_mutex_release(state->mutex);
|
||||
}
|
||||
|
||||
static void text_box_test_input_callback(InputEvent* input_event, void* ctx) {
|
||||
@@ -74,17 +76,17 @@ int32_t text_box_test_app(void* p) {
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
|
||||
furi_check(event_queue);
|
||||
|
||||
TextBoxTestState _state = {.idx = 0};
|
||||
TextBoxTestState state = {.idx = 0, .mutex = NULL};
|
||||
state.mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, &_state, sizeof(TextBoxTestState))) {
|
||||
if(!state.mutex) {
|
||||
FURI_LOG_E(TAG, "Cannot create mutex");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
|
||||
view_port_draw_callback_set(view_port, text_box_test_render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, text_box_test_render_callback, &state);
|
||||
view_port_input_callback_set(view_port, text_box_test_input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -94,24 +96,24 @@ int32_t text_box_test_app(void* p) {
|
||||
uint32_t test_renders_num = COUNT_OF(text_box_test_render);
|
||||
InputEvent event;
|
||||
while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
|
||||
TextBoxTestState* state = acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(state.mutex, FuriWaitForever);
|
||||
|
||||
if(event.type == InputTypeShort) {
|
||||
if(event.key == InputKeyRight) {
|
||||
if(state->idx < test_renders_num - 1) {
|
||||
state->idx++;
|
||||
if(state.idx < test_renders_num - 1) {
|
||||
state.idx++;
|
||||
}
|
||||
} else if(event.key == InputKeyLeft) {
|
||||
if(state->idx > 0) {
|
||||
state->idx--;
|
||||
if(state.idx > 0) {
|
||||
state.idx--;
|
||||
}
|
||||
} else if(event.key == InputKeyBack) {
|
||||
release_mutex(&state_mutex, state);
|
||||
furi_mutex_release(state.mutex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
release_mutex(&state_mutex, state);
|
||||
furi_mutex_release(state.mutex);
|
||||
view_port_update(view_port);
|
||||
}
|
||||
|
||||
@@ -119,7 +121,7 @@ int32_t text_box_test_app(void* p) {
|
||||
gui_remove_view_port(gui, view_port);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(state.mutex);
|
||||
|
||||
furi_record_close(RECORD_GUI);
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
// v2 tests
|
||||
void test_furi_create_open();
|
||||
void test_furi_valuemutex();
|
||||
void test_furi_concurrent_access();
|
||||
void test_furi_pubsub();
|
||||
|
||||
@@ -30,10 +29,6 @@ MU_TEST(mu_test_furi_create_open) {
|
||||
test_furi_create_open();
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_valuemutex) {
|
||||
test_furi_valuemutex();
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_pubsub) {
|
||||
test_furi_pubsub();
|
||||
}
|
||||
@@ -51,7 +46,6 @@ MU_TEST_SUITE(test_suite) {
|
||||
|
||||
// v2 tests
|
||||
MU_RUN_TEST(mu_test_furi_create_open);
|
||||
MU_RUN_TEST(mu_test_furi_valuemutex);
|
||||
MU_RUN_TEST(mu_test_furi_pubsub);
|
||||
MU_RUN_TEST(mu_test_furi_memmgr);
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <furi.h>
|
||||
|
||||
#include "../minunit.h"
|
||||
|
||||
void test_furi_valuemutex() {
|
||||
const int init_value = 0xdeadbeef;
|
||||
const int changed_value = 0x12345678;
|
||||
|
||||
int value = init_value;
|
||||
bool result;
|
||||
ValueMutex valuemutex;
|
||||
|
||||
// init mutex case
|
||||
result = init_mutex(&valuemutex, &value, sizeof(value));
|
||||
mu_assert(result, "init mutex failed");
|
||||
|
||||
// acquire mutex case
|
||||
int* value_pointer = acquire_mutex(&valuemutex, 100);
|
||||
mu_assert_pointers_eq(value_pointer, &value);
|
||||
|
||||
// second acquire mutex case
|
||||
int* value_pointer_second = acquire_mutex(&valuemutex, 100);
|
||||
mu_assert_pointers_eq(value_pointer_second, NULL);
|
||||
|
||||
// change value case
|
||||
*value_pointer = changed_value;
|
||||
mu_assert_int_eq(value, changed_value);
|
||||
|
||||
// release mutex case
|
||||
result = release_mutex(&valuemutex, &value);
|
||||
mu_assert(result, "release mutex failed");
|
||||
|
||||
// TODO
|
||||
//acquire mutex blocking case
|
||||
//write mutex blocking case
|
||||
//read mutex blocking case
|
||||
|
||||
mu_check(delete_mutex(&valuemutex));
|
||||
}
|
||||
@@ -19,7 +19,7 @@ void ibutton_scene_exit_confirm_on_enter(void* context) {
|
||||
widget_add_button_element(
|
||||
widget, GuiButtonTypeRight, "Stay", ibutton_scene_exit_confirm_widget_callback, ibutton);
|
||||
widget_add_string_element(
|
||||
widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton menu?");
|
||||
widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton Menu?");
|
||||
widget_add_string_element(
|
||||
widget, 64, 31, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost!");
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ void ibutton_scene_read_on_enter(void* context) {
|
||||
iButtonWorker* worker = ibutton->worker;
|
||||
|
||||
popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom);
|
||||
popup_set_text(popup, "Waiting\nfor key ...", 95, 30, AlignCenter, AlignTop);
|
||||
popup_set_text(popup, "Apply key to\nFlipper's back", 95, 30, AlignCenter, AlignTop);
|
||||
popup_set_icon(popup, 0, 5, XTREME_ASSETS()->I_DolphinWait_61x59);
|
||||
|
||||
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup);
|
||||
|
||||
@@ -19,7 +19,7 @@ void ibutton_scene_retry_confirm_on_enter(void* context) {
|
||||
widget_add_button_element(
|
||||
widget, GuiButtonTypeRight, "Stay", ibutton_scene_retry_confirm_widget_callback, ibutton);
|
||||
widget_add_string_element(
|
||||
widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Return to reading?");
|
||||
widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Retry Reading?");
|
||||
widget_add_string_element(
|
||||
widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost!");
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@ void infrared_scene_ask_back_on_enter(void* context) {
|
||||
DialogEx* dialog_ex = infrared->dialog_ex;
|
||||
|
||||
if(infrared->app_state.is_learning_new_remote) {
|
||||
dialog_ex_set_header(dialog_ex, "Exit to Infrared Menu?", 64, 0, AlignCenter, AlignTop);
|
||||
dialog_ex_set_header(dialog_ex, "Exit to Infrared Menu?", 64, 11, AlignCenter, AlignTop);
|
||||
} else {
|
||||
dialog_ex_set_header(dialog_ex, "Exit to Remote Menu?", 64, 0, AlignCenter, AlignTop);
|
||||
dialog_ex_set_header(dialog_ex, "Exit to Remote Menu?", 64, 11, AlignCenter, AlignTop);
|
||||
}
|
||||
|
||||
dialog_ex_set_text(
|
||||
dialog_ex, "All unsaved data\nwill be lost!", 64, 31, AlignCenter, AlignCenter);
|
||||
dialog_ex, "All unsaved data\nwill be lost!", 64, 25, AlignCenter, AlignTop);
|
||||
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
|
||||
dialog_ex_set_left_button_text(dialog_ex, "Exit");
|
||||
dialog_ex_set_center_button_text(dialog_ex, NULL);
|
||||
|
||||
@@ -9,9 +9,9 @@ void infrared_scene_ask_retry_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
DialogEx* dialog_ex = infrared->dialog_ex;
|
||||
|
||||
dialog_ex_set_header(dialog_ex, "Return to Reading?", 64, 0, AlignCenter, AlignTop);
|
||||
dialog_ex_set_header(dialog_ex, "Retry Reading?", 64, 11, AlignCenter, AlignTop);
|
||||
dialog_ex_set_text(
|
||||
dialog_ex, "All unsaved data\nwill be lost!", 64, 31, AlignCenter, AlignCenter);
|
||||
dialog_ex, "All unsaved data\nwill be lost!", 64, 25, AlignCenter, AlignTop);
|
||||
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
|
||||
dialog_ex_set_left_button_text(dialog_ex, "Exit");
|
||||
dialog_ex_set_center_button_text(dialog_ex, NULL);
|
||||
|
||||
@@ -7,7 +7,7 @@ void lfrfid_scene_retry_confirm_on_enter(void* context) {
|
||||
widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", lfrfid_widget_callback, app);
|
||||
widget_add_button_element(widget, GuiButtonTypeRight, "Stay", lfrfid_widget_callback, app);
|
||||
widget_add_string_element(
|
||||
widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Return to reading?");
|
||||
widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Retry Reading?");
|
||||
widget_add_string_element(
|
||||
widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost!");
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ void nfc_scene_mf_classic_menu_on_enter(void* context) {
|
||||
if(!mf_classic_is_card_read(&nfc->dev->dev_data.mf_classic_data)) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Detect reader",
|
||||
"Detect Reader",
|
||||
SubmenuIndexDetectReader,
|
||||
nfc_scene_mf_classic_menu_submenu_callback,
|
||||
nfc);
|
||||
|
||||
@@ -14,7 +14,7 @@ void nfc_scene_retry_confirm_on_enter(void* context) {
|
||||
dialog_ex_set_right_button_text(dialog_ex, "Stay");
|
||||
dialog_ex_set_header(dialog_ex, "Retry Reading?", 64, 11, AlignCenter, AlignTop);
|
||||
dialog_ex_set_text(
|
||||
dialog_ex, "All unsaved data will be\nlost!", 64, 25, AlignCenter, AlignTop);
|
||||
dialog_ex, "All unsaved data\nwill be lost!", 64, 25, AlignCenter, AlignTop);
|
||||
dialog_ex_set_context(dialog_ex, nfc);
|
||||
dialog_ex_set_result_callback(dialog_ex, nfc_scene_retry_confirm_dialog_callback);
|
||||
|
||||
|
||||
@@ -52,20 +52,20 @@ void nfc_scene_saved_menu_on_enter(void* context) {
|
||||
if(!mf_classic_is_card_read(&nfc->dev->dev_data.mf_classic_data)) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Detect reader",
|
||||
"Detect Reader",
|
||||
SubmenuIndexDetectReader,
|
||||
nfc_scene_saved_menu_submenu_callback,
|
||||
nfc);
|
||||
}
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Write To Initial Card",
|
||||
"Write to Initial Card",
|
||||
SubmenuIndexWrite,
|
||||
nfc_scene_saved_menu_submenu_callback,
|
||||
nfc);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Update From Initial Card",
|
||||
"Update from Initial Card",
|
||||
SubmenuIndexUpdate,
|
||||
nfc_scene_saved_menu_submenu_callback,
|
||||
nfc);
|
||||
@@ -76,13 +76,13 @@ void nfc_scene_saved_menu_on_enter(void* context) {
|
||||
!mf_ul_is_full_capture(&nfc->dev->dev_data.mf_ul_data)) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Unlock With Reader",
|
||||
"Unlock with Reader",
|
||||
SubmenuIndexMfUlUnlockByReader,
|
||||
nfc_scene_saved_menu_submenu_callback,
|
||||
nfc);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Unlock With Password",
|
||||
"Unlock with Password",
|
||||
SubmenuIndexMfUlUnlockByPassword,
|
||||
nfc_scene_saved_menu_submenu_callback,
|
||||
nfc);
|
||||
|
||||
@@ -146,6 +146,8 @@ bool subghz_scene_ext_module_settings_on_event(void* context, SceneManagerEvent
|
||||
// Set selected radio module
|
||||
furi_hal_subghz_set_radio_type(value_index_exm);
|
||||
|
||||
furi_hal_subghz_enable_ext_power();
|
||||
|
||||
// Check if module is present, if no -> show error
|
||||
if(!furi_hal_subghz_check_radio()) {
|
||||
value_index_exm = 0;
|
||||
|
||||
@@ -16,7 +16,7 @@ void subghz_scene_need_saving_on_enter(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
|
||||
widget_add_string_multiline_element(
|
||||
subghz->widget, 64, 13, AlignCenter, AlignCenter, FontPrimary, "Exit to Sub-GHz menu?");
|
||||
subghz->widget, 64, 13, AlignCenter, AlignCenter, FontPrimary, "Exit to Sub-GHz Menu?");
|
||||
widget_add_string_multiline_element(
|
||||
subghz->widget,
|
||||
64,
|
||||
@@ -24,7 +24,7 @@ void subghz_scene_need_saving_on_enter(void* context) {
|
||||
AlignCenter,
|
||||
AlignCenter,
|
||||
FontSecondary,
|
||||
"All unsaved will be\nlost.");
|
||||
"All unsaved data\nwill be lost!");
|
||||
|
||||
widget_add_button_element(
|
||||
subghz->widget, GuiButtonTypeRight, "Stay", subghz_scene_need_saving_callback, subghz);
|
||||
|
||||
@@ -75,43 +75,46 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexExtSettings);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneExtModuleSettings);
|
||||
return true;
|
||||
|
||||
} else if(!furi_hal_subghz_check_radio()) {
|
||||
furi_string_set(subghz->error_str, "Please connect\nexternal radio");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexReadRAW) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW);
|
||||
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexRead) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRead);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexSaved) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexSaved);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexAddManually) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexAddManually);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetType);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexFrequencyAnalyzer) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer);
|
||||
DOLPHIN_DEED(DolphinDeedSubGhzFrequencyAnalyzer);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexTest) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexTest);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTest);
|
||||
return true;
|
||||
} else {
|
||||
furi_hal_subghz_enable_ext_power();
|
||||
|
||||
if(!furi_hal_subghz_check_radio()) {
|
||||
furi_string_set(subghz->error_str, "Please connect\nexternal radio");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexReadRAW) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW);
|
||||
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexRead) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRead);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexSaved) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexSaved);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexFrequencyAnalyzer) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer);
|
||||
DOLPHIN_DEED(DolphinDeedSubGhzFrequencyAnalyzer);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexTest) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexTest);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTest);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -421,6 +421,9 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) {
|
||||
|
||||
// The rest
|
||||
free(subghz);
|
||||
|
||||
// Disable power for External CC1101 if it was enabled and module is connected
|
||||
furi_hal_subghz_disable_ext_power();
|
||||
}
|
||||
|
||||
int32_t subghz_app(void* p) {
|
||||
|
||||
@@ -37,6 +37,7 @@ typedef struct {
|
||||
} BallState;
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
BallState ball_state;
|
||||
BrickState brick_state;
|
||||
NotificationApp* notify;
|
||||
@@ -309,10 +310,9 @@ static void arkanoid_state_init(ArkanoidState* arkanoid_state) {
|
||||
}
|
||||
|
||||
static void arkanoid_draw_callback(Canvas* const canvas, void* ctx) {
|
||||
ArkanoidState* arkanoid_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(arkanoid_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
ArkanoidState* arkanoid_state = ctx;
|
||||
furi_mutex_acquire(arkanoid_state->mutex, FuriWaitForever);
|
||||
|
||||
//Initial level draw
|
||||
if(!arkanoid_state->initialDraw) {
|
||||
@@ -351,7 +351,7 @@ static void arkanoid_draw_callback(Canvas* const canvas, void* ctx) {
|
||||
arkanoid_state->score = 0;
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, arkanoid_state);
|
||||
furi_mutex_release(arkanoid_state->mutex);
|
||||
}
|
||||
|
||||
static void arkanoid_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -377,8 +377,8 @@ int32_t arkanoid_game_app(void* p) {
|
||||
ArkanoidState* arkanoid_state = malloc(sizeof(ArkanoidState));
|
||||
arkanoid_state_init(arkanoid_state);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, arkanoid_state, sizeof(ArkanoidState))) {
|
||||
arkanoid_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!arkanoid_state->mutex) {
|
||||
FURI_LOG_E(TAG, "Cannot create mutex\r\n");
|
||||
return_code = 255;
|
||||
goto free_and_exit;
|
||||
@@ -386,7 +386,7 @@ int32_t arkanoid_game_app(void* p) {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, arkanoid_draw_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, arkanoid_draw_callback, arkanoid_state);
|
||||
view_port_input_callback_set(view_port, arkanoid_input_callback, event_queue);
|
||||
|
||||
FuriTimer* timer =
|
||||
@@ -400,7 +400,7 @@ int32_t arkanoid_game_app(void* p) {
|
||||
GameEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
ArkanoidState* arkanoid_state = (ArkanoidState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(arkanoid_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// Key events
|
||||
@@ -457,7 +457,7 @@ int32_t arkanoid_game_app(void* p) {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, arkanoid_state);
|
||||
furi_mutex_release(arkanoid_state->mutex);
|
||||
}
|
||||
furi_timer_free(timer);
|
||||
view_port_enabled_set(view_port, false);
|
||||
@@ -465,7 +465,7 @@ int32_t arkanoid_game_app(void* p) {
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
view_port_free(view_port);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(arkanoid_state->mutex);
|
||||
|
||||
free_and_exit:
|
||||
free(arkanoid_state);
|
||||
|
||||
@@ -130,10 +130,9 @@ int calculate_check_digit(PluginState* plugin_state, BarcodeType* type) {
|
||||
}
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(plugin_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
PluginState* plugin_state = ctx;
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
|
||||
if(plugin_state->mode == MenuMode) {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
@@ -239,7 +238,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas_draw_box(canvas, (endSafetyPosition + 2), BARCODE_Y_START, 1, BARCODE_HEIGHT + 2);
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -387,8 +386,9 @@ int32_t barcode_generator_app(void* p) {
|
||||
|
||||
PluginState* plugin_state = malloc(sizeof(PluginState));
|
||||
barcode_generator_state_init(plugin_state);
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
|
||||
|
||||
plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!plugin_state->mutex) {
|
||||
FURI_LOG_E("barcode_generator", "cannot create mutex\r\n");
|
||||
furi_message_queue_free(event_queue);
|
||||
free(plugin_state);
|
||||
@@ -397,7 +397,7 @@ int32_t barcode_generator_app(void* p) {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, plugin_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -407,7 +407,7 @@ int32_t barcode_generator_app(void* p) {
|
||||
PluginEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
@@ -430,7 +430,7 @@ int32_t barcode_generator_app(void* p) {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
view_port_enabled_set(view_port, false);
|
||||
@@ -438,6 +438,7 @@ int32_t barcode_generator_app(void* p) {
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
furi_mutex_free(plugin_state->mutex);
|
||||
// save settings
|
||||
SAVE_BARCODE_SETTINGS(&plugin_state->barcode_state);
|
||||
free(plugin_state);
|
||||
|
||||
@@ -81,6 +81,7 @@ typedef struct {
|
||||
} BarcodeState;
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
BarcodeState barcode_state;
|
||||
int editingIndex; //The index of the editing symbol
|
||||
int menuIndex; //The index of the menu cursor
|
||||
|
||||
@@ -32,11 +32,9 @@ static void draw_ui(Canvas* const canvas, const GameState* game_state) {
|
||||
}
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
const GameState* game_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
|
||||
if(game_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const GameState* game_state = ctx;
|
||||
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
|
||||
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
@@ -59,7 +57,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
settings_page(canvas, game_state);
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, game_state);
|
||||
furi_mutex_release(game_state->mutex);
|
||||
}
|
||||
|
||||
//region card draw
|
||||
@@ -551,68 +549,65 @@ int32_t blackjack_app(void* p) {
|
||||
|
||||
game_state->state = GameStateStart;
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, game_state, sizeof(GameState))) {
|
||||
game_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!game_state->mutex) {
|
||||
FURI_LOG_E(APP_NAME, "cannot create mutex\r\n");
|
||||
return_code = 255;
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, game_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
FuriTimer* timer = furi_timer_alloc(update_timer_callback, FuriTimerTypePeriodic, event_queue);
|
||||
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 25);
|
||||
|
||||
Gui* gui = furi_record_open("gui");
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
AppEvent event;
|
||||
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
GameState* localstate = (GameState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
|
||||
if(event_status == FuriStatusOk) {
|
||||
if(event.type == EventTypeKey) {
|
||||
if(event.input.type == InputTypePress) {
|
||||
switch(event.input.key) {
|
||||
case InputKeyUp:
|
||||
localstate->selectDirection = DirectionUp;
|
||||
game_state->selectDirection = DirectionUp;
|
||||
break;
|
||||
case InputKeyDown:
|
||||
localstate->selectDirection = DirectionDown;
|
||||
game_state->selectDirection = DirectionDown;
|
||||
break;
|
||||
case InputKeyRight:
|
||||
localstate->selectDirection = DirectionRight;
|
||||
game_state->selectDirection = DirectionRight;
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
localstate->selectDirection = DirectionLeft;
|
||||
game_state->selectDirection = DirectionLeft;
|
||||
break;
|
||||
case InputKeyBack:
|
||||
if(localstate->state == GameStateSettings) {
|
||||
localstate->state = GameStateStart;
|
||||
save_settings(localstate->settings);
|
||||
if(game_state->state == GameStateSettings) {
|
||||
game_state->state = GameStateStart;
|
||||
save_settings(game_state->settings);
|
||||
} else
|
||||
processing = false;
|
||||
break;
|
||||
case InputKeyOk:
|
||||
localstate->selectDirection = Select;
|
||||
game_state->selectDirection = Select;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(event.type == EventTypeTick) {
|
||||
tick(localstate);
|
||||
processing = localstate->processing;
|
||||
tick(game_state);
|
||||
processing = game_state->processing;
|
||||
}
|
||||
} else {
|
||||
//FURI_LOG_D(APP_NAME, "osMessageQueue: event timeout");
|
||||
// event timeout
|
||||
}
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, localstate);
|
||||
furi_mutex_release(game_state->mutex);
|
||||
}
|
||||
|
||||
furi_timer_free(timer);
|
||||
@@ -620,7 +615,7 @@ int32_t blackjack_app(void* p) {
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(game_state->mutex);
|
||||
|
||||
free_and_exit:
|
||||
free(game_state->deck.cards);
|
||||
|
||||
@@ -54,6 +54,7 @@ typedef enum {
|
||||
} Direction;
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
Card player_cards[21];
|
||||
Card dealer_cards[21];
|
||||
uint8_t player_card_count;
|
||||
|
||||
@@ -37,6 +37,7 @@ typedef struct {
|
||||
} PluginEvent;
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
Player player;
|
||||
Entity entity[MAX_ENTITIES];
|
||||
StaticEntity static_entity[MAX_STATIC_ENTITIES];
|
||||
@@ -770,10 +771,9 @@ void loopIntro(Canvas* const canvas) {
|
||||
}
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(plugin_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
PluginState* plugin_state = ctx;
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
if(plugin_state->init) setupDisplay(canvas);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
@@ -797,7 +797,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
release_mutex((ValueMutex*)ctx, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -967,8 +967,8 @@ int32_t doom_app() {
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
|
||||
PluginState* plugin_state = malloc(sizeof(PluginState));
|
||||
doom_state_init(plugin_state);
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
|
||||
plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!plugin_state->mutex) {
|
||||
FURI_LOG_E("Doom_game", "cannot create mutex\r\n");
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_message_queue_free(event_queue);
|
||||
@@ -980,11 +980,11 @@ int32_t doom_app() {
|
||||
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 12);
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, plugin_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
Gui* gui = furi_record_open("gui");
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
//////////////////////////////////
|
||||
@@ -997,7 +997,7 @@ int32_t doom_app() {
|
||||
#endif
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
#ifdef SOUND
|
||||
furi_check(
|
||||
furi_mutex_acquire(plugin_state->music_instance->model_mutex, FuriWaitForever) ==
|
||||
@@ -1087,7 +1087,7 @@ int32_t doom_app() {
|
||||
furi_mutex_release(plugin_state->music_instance->model_mutex);
|
||||
#endif
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
#ifdef SOUND
|
||||
music_player_worker_free(plugin_state->music_instance->worker);
|
||||
@@ -1099,8 +1099,9 @@ int32_t doom_app() {
|
||||
furi_timer_free(timer);
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close("gui");
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
furi_mutex_free(plugin_state->mutex);
|
||||
furi_message_queue_free(event_queue);
|
||||
free(plugin_state);
|
||||
return 0;
|
||||
|
||||
@@ -59,6 +59,7 @@ typedef struct {
|
||||
PILAR pilars[FLAPPY_PILAR_MAX];
|
||||
bool debug;
|
||||
State state;
|
||||
FuriMutex* mutex;
|
||||
} GameState;
|
||||
|
||||
typedef struct {
|
||||
@@ -174,10 +175,9 @@ static void flappy_game_flap(GameState* const game_state) {
|
||||
}
|
||||
|
||||
static void flappy_game_render_callback(Canvas* const canvas, void* ctx) {
|
||||
const GameState* game_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(game_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const GameState* game_state = ctx;
|
||||
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
|
||||
|
||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
|
||||
@@ -261,7 +261,7 @@ static void flappy_game_render_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas_draw_str_aligned(canvas, 64, 41, AlignCenter, AlignBottom, buffer);
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, game_state);
|
||||
furi_mutex_release(game_state->mutex);
|
||||
}
|
||||
|
||||
static void flappy_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -287,8 +287,8 @@ int32_t flappy_game_app(void* p) {
|
||||
GameState* game_state = malloc(sizeof(GameState));
|
||||
flappy_game_state_init(game_state);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, game_state, sizeof(GameState))) {
|
||||
game_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!game_state->mutex) {
|
||||
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
||||
return_code = 255;
|
||||
goto free_and_exit;
|
||||
@@ -296,7 +296,7 @@ int32_t flappy_game_app(void* p) {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, flappy_game_render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, flappy_game_render_callback, game_state);
|
||||
view_port_input_callback_set(view_port, flappy_game_input_callback, event_queue);
|
||||
|
||||
FuriTimer* timer =
|
||||
@@ -310,7 +310,7 @@ int32_t flappy_game_app(void* p) {
|
||||
GameEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
GameState* game_state = (GameState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
@@ -352,7 +352,7 @@ int32_t flappy_game_app(void* p) {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, game_state);
|
||||
furi_mutex_release(game_state->mutex);
|
||||
}
|
||||
|
||||
furi_timer_free(timer);
|
||||
@@ -360,7 +360,7 @@ int32_t flappy_game_app(void* p) {
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(game_state->mutex);
|
||||
|
||||
free_and_exit:
|
||||
flappy_game_state_free(game_state);
|
||||
|
||||
@@ -9,11 +9,9 @@
|
||||
#define RFIDFUZZER_APP_FOLDER "/ext/lrfid/rfidfuzzer"
|
||||
|
||||
static void flipfrid_draw_callback(Canvas* const canvas, void* ctx) {
|
||||
FlipFridState* flipfrid_state = (FlipFridState*)acquire_mutex((ValueMutex*)ctx, 100);
|
||||
|
||||
if(flipfrid_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
FlipFridState* flipfrid_state = ctx;
|
||||
furi_mutex_acquire(flipfrid_state->mutex, FuriWaitForever);
|
||||
|
||||
// Draw correct Canvas
|
||||
switch(flipfrid_state->current_scene) {
|
||||
@@ -37,7 +35,7 @@ static void flipfrid_draw_callback(Canvas* const canvas, void* ctx) {
|
||||
break;
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, flipfrid_state);
|
||||
furi_mutex_release(flipfrid_state->mutex);
|
||||
}
|
||||
|
||||
void flipfrid_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -118,11 +116,9 @@ int32_t flipfrid_start(void* p) {
|
||||
FURI_LOG_I(TAG, "Initializing input");
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(FlipFridEvent));
|
||||
FlipFridState* flipfrid_state = flipfrid_alloc();
|
||||
ValueMutex flipfrid_state_mutex;
|
||||
|
||||
// Mutex
|
||||
FURI_LOG_I(TAG, "Initializing flipfrid mutex");
|
||||
if(!init_mutex(&flipfrid_state_mutex, flipfrid_state, sizeof(FlipFridState))) {
|
||||
flipfrid_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!flipfrid_state->mutex) {
|
||||
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
||||
furi_message_queue_free(event_queue);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
@@ -139,7 +135,7 @@ int32_t flipfrid_start(void* p) {
|
||||
// Configure view port
|
||||
FURI_LOG_I(TAG, "Initializing viewport");
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, flipfrid_draw_callback, &flipfrid_state_mutex);
|
||||
view_port_draw_callback_set(view_port, flipfrid_draw_callback, flipfrid_state);
|
||||
view_port_input_callback_set(view_port, flipfrid_input_callback, event_queue);
|
||||
|
||||
// Configure timer
|
||||
@@ -268,6 +264,7 @@ int32_t flipfrid_start(void* p) {
|
||||
furi_message_queue_free(event_queue);
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_mutex_free(flipfrid_state->mutex);
|
||||
flipfrid_free(flipfrid_state);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -58,6 +58,7 @@ typedef struct {
|
||||
|
||||
// STRUCTS
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
bool is_running;
|
||||
bool is_attacking;
|
||||
FlipFridScene current_scene;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "i2ctools_i.h"
|
||||
|
||||
void i2ctools_draw_callback(Canvas* canvas, void* ctx) {
|
||||
i2cTools* i2ctools = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
furi_assert(ctx);
|
||||
i2cTools* i2ctools = ctx;
|
||||
furi_mutex_acquire(i2ctools->mutex, FuriWaitForever);
|
||||
|
||||
switch(i2ctools->main_view->current_view) {
|
||||
case MAIN_VIEW:
|
||||
@@ -23,7 +25,7 @@ void i2ctools_draw_callback(Canvas* canvas, void* ctx) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
release_mutex((ValueMutex*)ctx, i2ctools);
|
||||
furi_mutex_release(i2ctools->mutex);
|
||||
}
|
||||
|
||||
void i2ctools_input_callback(InputEvent* input_event, void* ctx) {
|
||||
@@ -38,8 +40,8 @@ int32_t i2ctools_app(void* p) {
|
||||
|
||||
// Alloc i2ctools
|
||||
i2cTools* i2ctools = malloc(sizeof(i2cTools));
|
||||
ValueMutex i2ctools_mutex;
|
||||
if(!init_mutex(&i2ctools_mutex, i2ctools, sizeof(i2cTools))) {
|
||||
i2ctools->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!i2ctools->mutex) {
|
||||
FURI_LOG_E(APP_NAME, "cannot create mutex\r\n");
|
||||
free(i2ctools);
|
||||
return -1;
|
||||
@@ -47,7 +49,7 @@ int32_t i2ctools_app(void* p) {
|
||||
|
||||
// Alloc viewport
|
||||
i2ctools->view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(i2ctools->view_port, i2ctools_draw_callback, &i2ctools_mutex);
|
||||
view_port_draw_callback_set(i2ctools->view_port, i2ctools_draw_callback, i2ctools);
|
||||
view_port_input_callback_set(i2ctools->view_port, i2ctools_input_callback, event_queue);
|
||||
|
||||
// Register view port in GUI
|
||||
@@ -216,6 +218,7 @@ int32_t i2ctools_app(void* p) {
|
||||
i2c_scanner_free(i2ctools->scanner);
|
||||
i2c_sender_free(i2ctools->sender);
|
||||
i2c_main_view_free(i2ctools->main_view);
|
||||
furi_mutex_free(i2ctools->mutex);
|
||||
free(i2ctools);
|
||||
furi_record_close(RECORD_GUI);
|
||||
return 0;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
// App datas
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
ViewPort* view_port;
|
||||
i2cMainView* main_view;
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ typedef enum {
|
||||
} State;
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
State state;
|
||||
uint8_t table[CELLS_COUNT][CELLS_COUNT];
|
||||
uint32_t score;
|
||||
@@ -103,8 +104,9 @@ static void gray_canvas(Canvas* const canvas) {
|
||||
}
|
||||
|
||||
static void draw_callback(Canvas* const canvas, void* ctx) {
|
||||
const GameState* game_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(game_state == NULL) return;
|
||||
furi_assert(ctx);
|
||||
const GameState* game_state = ctx;
|
||||
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
|
||||
|
||||
canvas_clear(canvas);
|
||||
|
||||
@@ -180,7 +182,7 @@ static void draw_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas_draw_str_aligned(canvas, 64, 48, AlignCenter, AlignBottom, buf);
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, game_state);
|
||||
furi_mutex_release(game_state->mutex);
|
||||
}
|
||||
|
||||
void calculate_move_to_left(uint8_t arr[], MoveResult* const move_result) {
|
||||
@@ -380,8 +382,8 @@ int32_t game_2048_app() {
|
||||
|
||||
MoveResult* move_result = malloc(sizeof(MoveResult));
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, game_state, sizeof(GameState))) {
|
||||
game_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!game_state->mutex) {
|
||||
FURI_LOG_E("2048Game", "cannot create mutex\r\n");
|
||||
free(game_state);
|
||||
return 255;
|
||||
@@ -391,7 +393,7 @@ int32_t game_2048_app() {
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, draw_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, draw_callback, game_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
@@ -404,7 +406,7 @@ int32_t game_2048_app() {
|
||||
// handle only press event, ignore repeat/release events
|
||||
if(input.type != InputTypePress) continue;
|
||||
|
||||
GameState* game_state = (GameState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
|
||||
|
||||
switch(game_state->state) {
|
||||
case GameStateMenu:
|
||||
@@ -489,7 +491,7 @@ int32_t game_2048_app() {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, game_state);
|
||||
furi_mutex_release(game_state->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,7 +502,7 @@ int32_t game_2048_app() {
|
||||
|
||||
furi_message_queue_free(event_queue);
|
||||
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(game_state->mutex);
|
||||
|
||||
free(game_state);
|
||||
free(move_result);
|
||||
|
||||
@@ -15,10 +15,9 @@ typedef struct {
|
||||
} PluginEvent;
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* context) {
|
||||
const GpsUart* gps_uart = acquire_mutex((ValueMutex*)context, 25);
|
||||
if(gps_uart == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(context);
|
||||
const GpsUart* gps_uart = context;
|
||||
furi_mutex_acquire(gps_uart->mutex, FuriWaitForever);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 32, 8, AlignCenter, AlignBottom, "Latitude");
|
||||
@@ -57,7 +56,7 @@ static void render_callback(Canvas* const canvas, void* context) {
|
||||
gps_uart->status.time_seconds);
|
||||
canvas_draw_str_aligned(canvas, 96, 62, AlignCenter, AlignBottom, buffer);
|
||||
|
||||
release_mutex((ValueMutex*)context, gps_uart);
|
||||
furi_mutex_release(gps_uart->mutex);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -74,8 +73,8 @@ int32_t gps_app(void* p) {
|
||||
|
||||
GpsUart* gps_uart = gps_uart_enable();
|
||||
|
||||
ValueMutex gps_uart_mutex;
|
||||
if(!init_mutex(&gps_uart_mutex, gps_uart, sizeof(GpsUart))) {
|
||||
gps_uart->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!gps_uart->mutex) {
|
||||
FURI_LOG_E("GPS", "cannot create mutex\r\n");
|
||||
free(gps_uart);
|
||||
return 255;
|
||||
@@ -83,18 +82,18 @@ int32_t gps_app(void* p) {
|
||||
|
||||
// set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &gps_uart_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, gps_uart);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
// open GUI and register view_port
|
||||
Gui* gui = furi_record_open("gui");
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
PluginEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
|
||||
GpsUart* gps_uart = (GpsUart*)acquire_mutex_block(&gps_uart_mutex);
|
||||
furi_mutex_acquire(gps_uart->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
@@ -118,15 +117,15 @@ int32_t gps_app(void* p) {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&gps_uart_mutex, gps_uart);
|
||||
furi_mutex_release(gps_uart->mutex);
|
||||
}
|
||||
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close("gui");
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&gps_uart_mutex);
|
||||
furi_mutex_free(gps_uart->mutex);
|
||||
gps_uart_disable(gps_uart);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -22,6 +22,7 @@ typedef struct {
|
||||
} GpsStatus;
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
FuriThread* thread;
|
||||
FuriStreamBuffer* rx_stream;
|
||||
uint8_t rx_buf[RX_BUF_SIZE];
|
||||
|
||||
@@ -24,6 +24,7 @@ typedef struct {
|
||||
} PluginEvent;
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
NotificationApp* notification;
|
||||
bool have_5v;
|
||||
bool measurement_made;
|
||||
@@ -41,10 +42,10 @@ const NotificationSequence sequence_done = {
|
||||
};
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(plugin_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const PluginState* plugin_state = ctx;
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
|
||||
// border around the edge of the screen
|
||||
// canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
|
||||
@@ -85,7 +86,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -184,8 +185,8 @@ int32_t hc_sr04_app() {
|
||||
|
||||
furi_hal_console_disable();
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
|
||||
plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!plugin_state->mutex) {
|
||||
FURI_LOG_E("hc_sr04", "cannot create mutex\r\n");
|
||||
if(furi_hal_power_is_otg_enabled()) {
|
||||
furi_hal_power_disable_otg();
|
||||
@@ -201,7 +202,7 @@ int32_t hc_sr04_app() {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, plugin_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -212,7 +213,7 @@ int32_t hc_sr04_app() {
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
|
||||
PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
@@ -238,7 +239,7 @@ int32_t hc_sr04_app() {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
if(furi_hal_power_is_otg_enabled()) {
|
||||
@@ -267,7 +268,8 @@ int32_t hc_sr04_app() {
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(plugin_state->mutex);
|
||||
free(plugin_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ typedef struct {
|
||||
Person* person;
|
||||
Animations animation;
|
||||
GameStatuses game_status;
|
||||
FuriMutex* mutex;
|
||||
} GameState;
|
||||
|
||||
typedef Box** Field;
|
||||
@@ -432,15 +433,15 @@ static void draw_box(Canvas* canvas, Box* box, int x, int y) {
|
||||
|
||||
static void heap_defense_render_callback(Canvas* const canvas, void* mutex) {
|
||||
furi_assert(mutex);
|
||||
|
||||
const GameState* game = acquire_mutex((ValueMutex*)mutex, 25);
|
||||
const GameState* game = mutex;
|
||||
furi_mutex_acquire(game->mutex, FuriWaitForever);
|
||||
|
||||
///Draw GameOver or Pause
|
||||
if(!(game->game_status & GameStatusInProgress)) {
|
||||
FURI_LOG_W(TAG, "[DAED_DRAW]func: [%s] line: %d ", __FUNCTION__, __LINE__);
|
||||
|
||||
canvas_draw_icon_animation(canvas, 0, 0, animations[game->animation]);
|
||||
release_mutex((ValueMutex*)mutex, game);
|
||||
furi_mutex_release(game->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -480,7 +481,7 @@ static void heap_defense_render_callback(Canvas* const canvas, void* mutex) {
|
||||
}
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)mutex, game);
|
||||
furi_mutex_release(game->mutex);
|
||||
}
|
||||
|
||||
static void heap_defense_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -505,25 +506,25 @@ int32_t heap_defence_app(void* p) {
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(GameEvent));
|
||||
GameState* game = allocGameState();
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, game, sizeof(GameState))) {
|
||||
game->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!game->mutex) {
|
||||
game_destroy(game);
|
||||
return 1;
|
||||
}
|
||||
|
||||
assets_load();
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, heap_defense_render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, heap_defense_render_callback, game);
|
||||
view_port_input_callback_set(view_port, heap_defense_input_callback, event_queue);
|
||||
|
||||
FuriTimer* timer =
|
||||
furi_timer_alloc(heap_defense_timer_callback, FuriTimerTypePeriodic, event_queue);
|
||||
furi_timer_start(timer, furi_kernel_get_tick_frequency() / TIMER_UPDATE_FREQ);
|
||||
|
||||
Gui* gui = furi_record_open("gui");
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
NotificationApp* notification = furi_record_open("notification");
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
memset(game->field[Y_LAST], 128, ROW_BYTE_SIZE);
|
||||
game->person->p.y -= 2;
|
||||
@@ -536,7 +537,7 @@ int32_t heap_defence_app(void* p) {
|
||||
continue;
|
||||
}
|
||||
|
||||
game = (GameState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(game->mutex, FuriWaitForever);
|
||||
|
||||
//unset vibration
|
||||
if(game->game_status & GameStatusVibro) {
|
||||
@@ -573,7 +574,7 @@ int32_t heap_defence_app(void* p) {
|
||||
notification_message(notification, &sequence_error);
|
||||
}
|
||||
}
|
||||
release_mutex(&state_mutex, game);
|
||||
furi_mutex_release(game->mutex);
|
||||
view_port_update(view_port);
|
||||
}
|
||||
|
||||
@@ -581,11 +582,11 @@ int32_t heap_defence_app(void* p) {
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
view_port_free(view_port);
|
||||
furi_record_close("gui");
|
||||
furi_record_close("notification");
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_message_queue_free(event_queue);
|
||||
assets_clear();
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(game->mutex);
|
||||
game_destroy(game);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -9,11 +9,9 @@
|
||||
#define IBTNFUZZER_APP_FOLDER "/ext/ibtnfuzzer"
|
||||
|
||||
static void ibtnfuzzer_draw_callback(Canvas* const canvas, void* ctx) {
|
||||
iBtnFuzzerState* ibtnfuzzer_state = (iBtnFuzzerState*)acquire_mutex((ValueMutex*)ctx, 100);
|
||||
|
||||
if(ibtnfuzzer_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
iBtnFuzzerState* ibtnfuzzer_state = ctx;
|
||||
furi_mutex_acquire(ibtnfuzzer_state->mutex, FuriWaitForever);
|
||||
|
||||
// Draw correct Canvas
|
||||
switch(ibtnfuzzer_state->current_scene) {
|
||||
@@ -35,7 +33,7 @@ static void ibtnfuzzer_draw_callback(Canvas* const canvas, void* ctx) {
|
||||
break;
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, ibtnfuzzer_state);
|
||||
furi_mutex_release(ibtnfuzzer_state->mutex);
|
||||
}
|
||||
|
||||
void ibtnfuzzer_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -120,11 +118,9 @@ int32_t ibtnfuzzer_start(void* p) {
|
||||
FURI_LOG_I(TAG, "Initializing input");
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(iBtnFuzzerEvent));
|
||||
iBtnFuzzerState* ibtnfuzzer_state = ibtnfuzzer_alloc();
|
||||
ValueMutex ibtnfuzzer_state_mutex;
|
||||
|
||||
// Mutex
|
||||
FURI_LOG_I(TAG, "Initializing ibtnfuzzer mutex");
|
||||
if(!init_mutex(&ibtnfuzzer_state_mutex, ibtnfuzzer_state, sizeof(iBtnFuzzerState))) {
|
||||
ibtnfuzzer_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!ibtnfuzzer_state->mutex) {
|
||||
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
||||
furi_message_queue_free(event_queue);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
@@ -141,7 +137,7 @@ int32_t ibtnfuzzer_start(void* p) {
|
||||
// Configure view port
|
||||
FURI_LOG_I(TAG, "Initializing viewport");
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, ibtnfuzzer_draw_callback, &ibtnfuzzer_state_mutex);
|
||||
view_port_draw_callback_set(view_port, ibtnfuzzer_draw_callback, ibtnfuzzer_state);
|
||||
view_port_input_callback_set(view_port, ibtnfuzzer_input_callback, event_queue);
|
||||
|
||||
// Configure timer
|
||||
@@ -160,6 +156,7 @@ int32_t ibtnfuzzer_start(void* p) {
|
||||
while(ibtnfuzzer_state->is_running) {
|
||||
// Get next event
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 25);
|
||||
//furi_mutex_acquire(ibtnfuzzer_state->mutex, FuriWaitForever);
|
||||
if(event_status == FuriStatusOk) {
|
||||
if(event.evt_type == EventTypeKey) {
|
||||
//Handle event key
|
||||
@@ -250,6 +247,7 @@ int32_t ibtnfuzzer_start(void* p) {
|
||||
view_port_update(view_port);
|
||||
}
|
||||
}
|
||||
//furi_mutex_release(ibtnfuzzer_state->mutex);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
@@ -262,6 +260,7 @@ int32_t ibtnfuzzer_start(void* p) {
|
||||
furi_message_queue_free(event_queue);
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_mutex_free(ibtnfuzzer_state->mutex);
|
||||
ibtnfuzzer_free(ibtnfuzzer_state);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -56,6 +56,7 @@ typedef struct {
|
||||
|
||||
// STRUCTS
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
bool is_running;
|
||||
bool is_attacking;
|
||||
iBtnFuzzerScene current_scene;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
#include <m-string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gui/gui.h>
|
||||
@@ -50,31 +49,33 @@ typedef struct {
|
||||
enum OutputMode output_mode;
|
||||
FuriTimer* timer;
|
||||
NotificationApp* notifications;
|
||||
FuriMutex* mutex;
|
||||
} MetronomeState;
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
const MetronomeState* metronome_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(metronome_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const MetronomeState* metronome_state = ctx;
|
||||
furi_mutex_acquire(metronome_state->mutex, FuriWaitForever);
|
||||
|
||||
string_t tempStr;
|
||||
string_init(tempStr);
|
||||
FuriString* tempStr = furi_string_alloc();
|
||||
|
||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
|
||||
// draw bars/beat
|
||||
string_printf(tempStr, "%d/%d", metronome_state->beats_per_bar, metronome_state->note_length);
|
||||
canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, string_get_cstr(tempStr));
|
||||
string_reset(tempStr);
|
||||
furi_string_printf(
|
||||
tempStr, "%d/%d", metronome_state->beats_per_bar, metronome_state->note_length);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 8, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr));
|
||||
furi_string_reset(tempStr);
|
||||
|
||||
// draw BPM value
|
||||
string_printf(tempStr, "%.2f", metronome_state->bpm);
|
||||
furi_string_printf(tempStr, "%.2f", metronome_state->bpm);
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
canvas_draw_str_aligned(canvas, 64, 24, AlignCenter, AlignCenter, string_get_cstr(tempStr));
|
||||
string_reset(tempStr);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 24, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr));
|
||||
furi_string_reset(tempStr);
|
||||
|
||||
// draw volume indicator
|
||||
// always draw first waves
|
||||
@@ -126,8 +127,8 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas, 8, 36, 112, (float)metronome_state->current_beat / metronome_state->beats_per_bar);
|
||||
|
||||
// cleanup
|
||||
string_clear(tempStr);
|
||||
release_mutex((ValueMutex*)ctx, metronome_state);
|
||||
furi_string_free(tempStr);
|
||||
furi_mutex_release(metronome_state->mutex);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -139,7 +140,10 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
|
||||
|
||||
static void timer_callback(void* ctx) {
|
||||
// this is where we go BEEP!
|
||||
MetronomeState* metronome_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
furi_assert(ctx);
|
||||
MetronomeState* metronome_state = ctx;
|
||||
furi_mutex_acquire(metronome_state->mutex, FuriWaitForever);
|
||||
|
||||
metronome_state->current_beat++;
|
||||
if(metronome_state->current_beat > metronome_state->beats_per_bar) {
|
||||
metronome_state->current_beat = 1;
|
||||
@@ -200,7 +204,7 @@ static void timer_callback(void* ctx) {
|
||||
}
|
||||
notification_message(metronome_state->notifications, &sequence_reset_rgb);
|
||||
|
||||
release_mutex((ValueMutex*)ctx, metronome_state);
|
||||
furi_mutex_release(metronome_state->mutex);
|
||||
}
|
||||
|
||||
static uint32_t state_to_sleep_ticks(MetronomeState* metronome_state) {
|
||||
@@ -273,8 +277,8 @@ int32_t metronome_app() {
|
||||
MetronomeState* metronome_state = malloc(sizeof(MetronomeState));
|
||||
metronome_state_init(metronome_state);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, metronome_state, sizeof(MetronomeState))) {
|
||||
metronome_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!metronome_state->mutex) {
|
||||
FURI_LOG_E("Metronome", "cannot create mutex\r\n");
|
||||
free(metronome_state);
|
||||
return 255;
|
||||
@@ -282,19 +286,20 @@ int32_t metronome_app() {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, metronome_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
metronome_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, &state_mutex);
|
||||
metronome_state->timer =
|
||||
furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, metronome_state);
|
||||
|
||||
// Open GUI and register view_port
|
||||
Gui* gui = furi_record_open("gui");
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
PluginEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
|
||||
MetronomeState* metronome_state = (MetronomeState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(metronome_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
if(event.type == EventTypeKey) {
|
||||
@@ -373,21 +378,18 @@ int32_t metronome_app() {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FURI_LOG_D("Metronome", "FuriMessageQueue: event timeout");
|
||||
// event timeout
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, metronome_state);
|
||||
furi_mutex_release(metronome_state->mutex);
|
||||
}
|
||||
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close("gui");
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(metronome_state->mutex);
|
||||
furi_timer_free(metronome_state->timer);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
free(metronome_state);
|
||||
|
||||
@@ -55,6 +55,7 @@ typedef struct {
|
||||
int flags_set;
|
||||
bool game_started;
|
||||
uint32_t game_started_tick;
|
||||
FuriMutex* mutex;
|
||||
} Minesweeper;
|
||||
|
||||
static void timer_callback(void* ctx) {
|
||||
@@ -72,10 +73,10 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
|
||||
}
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
const Minesweeper* minesweeper_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(minesweeper_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const Minesweeper* minesweeper_state = ctx;
|
||||
furi_mutex_acquire(minesweeper_state->mutex, FuriWaitForever);
|
||||
|
||||
FuriString* mineStr;
|
||||
FuriString* timeStr;
|
||||
mineStr = furi_string_alloc();
|
||||
@@ -160,7 +161,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
|
||||
furi_string_free(mineStr);
|
||||
furi_string_free(timeStr);
|
||||
release_mutex((ValueMutex*)ctx, minesweeper_state);
|
||||
furi_mutex_release(minesweeper_state->mutex);
|
||||
}
|
||||
|
||||
static void setup_playfield(Minesweeper* minesweeper_state) {
|
||||
@@ -387,8 +388,8 @@ int32_t minesweeper_app(void* p) {
|
||||
// setup
|
||||
minesweeper_state_init(minesweeper_state);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, minesweeper_state, sizeof(minesweeper_state))) {
|
||||
minesweeper_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!minesweeper_state->mutex) {
|
||||
FURI_LOG_E("Minesweeper", "cannot create mutex\r\n");
|
||||
free(minesweeper_state);
|
||||
return 255;
|
||||
@@ -397,18 +398,19 @@ int32_t minesweeper_app(void* p) {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, minesweeper_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
minesweeper_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypeOnce, &state_mutex);
|
||||
minesweeper_state->timer =
|
||||
furi_timer_alloc(timer_callback, FuriTimerTypeOnce, minesweeper_state);
|
||||
|
||||
// Open GUI and register view_port
|
||||
Gui* gui = furi_record_open("gui");
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
PluginEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
Minesweeper* minesweeper_state = (Minesweeper*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(minesweeper_state->mutex, FuriWaitForever);
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
if(event.type == EventTypeKey) {
|
||||
@@ -496,19 +498,16 @@ int32_t minesweeper_app(void* p) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// event timeout
|
||||
;
|
||||
}
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, minesweeper_state);
|
||||
furi_mutex_release(minesweeper_state->mutex);
|
||||
}
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close("gui");
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(minesweeper_state->mutex);
|
||||
furi_timer_free(minesweeper_state->timer);
|
||||
free(minesweeper_state);
|
||||
|
||||
|
||||
@@ -41,10 +41,10 @@ char target_address_str[12] = "None";
|
||||
char target_text[30];
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(plugin_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const PluginState* plugin_state = ctx;
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
|
||||
// border around the edge of the screen
|
||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
|
||||
@@ -83,7 +83,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas_draw_str_aligned(canvas, 3, 30, AlignLeft, AlignBottom, "to exit");
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -291,8 +291,8 @@ int32_t mousejacker_app(void* p) {
|
||||
|
||||
PluginState* plugin_state = malloc(sizeof(PluginState));
|
||||
mousejacker_state_init(plugin_state);
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
|
||||
plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!plugin_state->mutex) {
|
||||
FURI_LOG_E("mousejacker", "cannot create mutex\r\n");
|
||||
furi_message_queue_free(event_queue);
|
||||
free(plugin_state);
|
||||
@@ -301,7 +301,7 @@ int32_t mousejacker_app(void* p) {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, plugin_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -332,7 +332,7 @@ int32_t mousejacker_app(void* p) {
|
||||
PluginEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
@@ -382,7 +382,7 @@ int32_t mousejacker_app(void* p) {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
furi_thread_free(plugin_state->mjthread);
|
||||
@@ -393,6 +393,7 @@ int32_t mousejacker_app(void* p) {
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
furi_mutex_free(plugin_state->mutex);
|
||||
free(plugin_state);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -21,6 +21,7 @@ typedef struct {
|
||||
} MJDuckyKey;
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
bool ducky_err;
|
||||
bool addr_err;
|
||||
bool is_thread_running;
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
#include "multi_converter_mode_select.h"
|
||||
|
||||
static void multi_converter_render_callback(Canvas* const canvas, void* ctx) {
|
||||
const MultiConverterState* multi_converter_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(multi_converter_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const MultiConverterState* multi_converter_state = ctx;
|
||||
furi_mutex_acquire(multi_converter_state->mutex, FuriWaitForever);
|
||||
|
||||
if(multi_converter_state->mode == ModeDisplay) {
|
||||
multi_converter_mode_display_draw(canvas, multi_converter_state);
|
||||
@@ -19,7 +18,7 @@ static void multi_converter_render_callback(Canvas* const canvas, void* ctx) {
|
||||
multi_converter_mode_select_draw(canvas, multi_converter_state);
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, multi_converter_state);
|
||||
furi_mutex_release(multi_converter_state->mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -62,8 +61,8 @@ int32_t multi_converter_app(void* p) {
|
||||
MultiConverterState* multi_converter_state = malloc(sizeof(MultiConverterState));
|
||||
|
||||
// set mutex for plugin state (different threads can access it)
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, multi_converter_state, sizeof(multi_converter_state))) {
|
||||
multi_converter_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!multi_converter_state->mutex) {
|
||||
FURI_LOG_E("MultiConverter", "cannot create mutex\r\n");
|
||||
furi_message_queue_free(event_queue);
|
||||
free(multi_converter_state);
|
||||
@@ -72,11 +71,11 @@ int32_t multi_converter_app(void* p) {
|
||||
|
||||
// register callbacks for drawing and input processing
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, multi_converter_render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, multi_converter_render_callback, multi_converter_state);
|
||||
view_port_input_callback_set(view_port, multi_converter_input_callback, event_queue);
|
||||
|
||||
// open GUI and register view_port
|
||||
Gui* gui = furi_record_open("gui");
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
multi_converter_init(multi_converter_state);
|
||||
@@ -85,8 +84,7 @@ int32_t multi_converter_app(void* p) {
|
||||
MultiConverterEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
MultiConverterState* multi_converter_state =
|
||||
(MultiConverterState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(multi_converter_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
@@ -148,20 +146,18 @@ int32_t multi_converter_app(void* p) {
|
||||
} else if(multi_converter_state->keyboard_lock) {
|
||||
multi_converter_state->keyboard_lock = 0;
|
||||
}
|
||||
} else {
|
||||
// event timeout
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, multi_converter_state);
|
||||
furi_mutex_release(multi_converter_state->mutex);
|
||||
}
|
||||
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close("gui");
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(multi_converter_state->mutex);
|
||||
free(multi_converter_state);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -70,6 +70,7 @@ struct MultiConverterUnit {
|
||||
};
|
||||
|
||||
struct MultiConverterState {
|
||||
FuriMutex* mutex;
|
||||
char buffer_orig[MULTI_CONVERTER_NUMBER_DIGITS + 1];
|
||||
char buffer_dest[MULTI_CONVERTER_NUMBER_DIGITS + 1];
|
||||
MultiConverterUnitType unit_type_orig;
|
||||
|
||||
@@ -11,6 +11,10 @@ void nfc_magic_scene_file_select_on_enter(void* context) {
|
||||
// Process file_select return
|
||||
nfc_device_set_loading_callback(nfc_magic->nfc_dev, nfc_magic_show_loading_popup, nfc_magic);
|
||||
|
||||
if(!furi_string_size(nfc_magic->nfc_dev->load_path)) {
|
||||
furi_string_set_str(nfc_magic->nfc_dev->load_path, NFC_APP_FOLDER);
|
||||
}
|
||||
|
||||
if(nfc_file_select(nfc_magic->nfc_dev)) {
|
||||
if(nfc_magic_scene_file_select_is_file_suitable(nfc_magic->nfc_dev)) {
|
||||
scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneWriteConfirm);
|
||||
|
||||
@@ -29,8 +29,7 @@ typedef struct {
|
||||
} PluginEvent;
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
FuriMutex* mutex;
|
||||
} PluginState;
|
||||
|
||||
char rate_text_fmt[] = "Transfer rate: %dMbps";
|
||||
@@ -96,13 +95,13 @@ static void insert_addr(uint8_t* addr, uint8_t addr_size) {
|
||||
}
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
furi_assert(ctx);
|
||||
const PluginState* plugin_state = ctx;
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
|
||||
uint8_t rate = 2;
|
||||
char sniffing[] = "Yes";
|
||||
|
||||
const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(plugin_state == NULL) {
|
||||
return;
|
||||
}
|
||||
// border around the edge of the screen
|
||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
@@ -126,7 +125,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas_draw_str_aligned(canvas, 30, 50, AlignLeft, AlignBottom, addresses_header_text);
|
||||
canvas_draw_str_aligned(canvas, 30, 60, AlignLeft, AlignBottom, sniffed_address);
|
||||
|
||||
release_mutex((ValueMutex*)ctx, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -321,8 +320,8 @@ int32_t nrfsniff_app(void* p) {
|
||||
hexlify(address, 5, top_address);
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
|
||||
PluginState* plugin_state = malloc(sizeof(PluginState));
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
|
||||
plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!plugin_state->mutex) {
|
||||
furi_message_queue_free(event_queue);
|
||||
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
||||
free(plugin_state);
|
||||
@@ -333,7 +332,7 @@ int32_t nrfsniff_app(void* p) {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, plugin_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -348,7 +347,7 @@ int32_t nrfsniff_app(void* p) {
|
||||
PluginEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
@@ -439,7 +438,7 @@ int32_t nrfsniff_app(void* p) {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
clear_cache();
|
||||
@@ -454,6 +453,8 @@ int32_t nrfsniff_app(void* p) {
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
furi_mutex_free(plugin_state->mutex);
|
||||
free(plugin_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
8
applications/plugins/picopass/picopass_keys.c
Normal file
8
applications/plugins/picopass/picopass_keys.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "picopass_keys.h"
|
||||
|
||||
const uint8_t picopass_iclass_key[] = {0xaf, 0xa7, 0x85, 0xa7, 0xda, 0xb3, 0x33, 0x78};
|
||||
const uint8_t picopass_factory_credit_key[] = {0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x00};
|
||||
const uint8_t picopass_factory_debit_key[] = {0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87};
|
||||
const uint8_t picopass_xice_key[] = {0x20, 0x20, 0x66, 0x66, 0x66, 0x66, 0x88, 0x88};
|
||||
const uint8_t picopass_xicl_key[] = {0x20, 0x20, 0x66, 0x66, 0x66, 0x66, 0x88, 0x88};
|
||||
const uint8_t picopass_xics_key[] = {0x66, 0x66, 0x20, 0x20, 0x66, 0x66, 0x88, 0x88};
|
||||
10
applications/plugins/picopass/picopass_keys.h
Normal file
10
applications/plugins/picopass/picopass_keys.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "picopass_device.h"
|
||||
|
||||
extern const uint8_t picopass_iclass_key[PICOPASS_BLOCK_LEN];
|
||||
extern const uint8_t picopass_factory_credit_key[PICOPASS_BLOCK_LEN];
|
||||
extern const uint8_t picopass_factory_debit_key[PICOPASS_BLOCK_LEN];
|
||||
extern const uint8_t picopass_xice_key[PICOPASS_BLOCK_LEN];
|
||||
extern const uint8_t picopass_xicl_key[PICOPASS_BLOCK_LEN];
|
||||
extern const uint8_t picopass_xics_key[PICOPASS_BLOCK_LEN];
|
||||
@@ -4,13 +4,6 @@
|
||||
|
||||
#define TAG "PicopassWorker"
|
||||
|
||||
const uint8_t picopass_iclass_key[] = {0xaf, 0xa7, 0x85, 0xa7, 0xda, 0xb3, 0x33, 0x78};
|
||||
const uint8_t picopass_factory_credit_key[] = {0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x00};
|
||||
const uint8_t picopass_factory_debit_key[] = {0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87};
|
||||
const uint8_t picopass_xice_key[] = {0x20, 0x20, 0x66, 0x66, 0x66, 0x66, 0x88, 0x88};
|
||||
const uint8_t picopass_xicl_key[] = {0x20, 0x20, 0x66, 0x66, 0x66, 0x66, 0x88, 0x88};
|
||||
const uint8_t picopass_xics_key[] = {0x66, 0x66, 0x20, 0x20, 0x66, 0x66, 0x88, 0x88};
|
||||
|
||||
static void picopass_worker_enable_field() {
|
||||
furi_hal_nfc_ll_txrx_on();
|
||||
furi_hal_nfc_exit_sleep();
|
||||
@@ -179,50 +172,6 @@ ReturnCode picopass_read_preauth(PicopassBlock* AA1) {
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
static ReturnCode picopass_auth_standard(uint8_t* csn, uint8_t* div_key) {
|
||||
rfalPicoPassReadCheckRes rcRes;
|
||||
rfalPicoPassCheckRes chkRes;
|
||||
|
||||
ReturnCode err;
|
||||
|
||||
uint8_t mac[4] = {0};
|
||||
uint8_t ccnr[12] = {0};
|
||||
|
||||
err = rfalPicoPassPollerReadCheck(&rcRes);
|
||||
if(err != ERR_NONE) {
|
||||
FURI_LOG_E(TAG, "rfalPicoPassPollerReadCheck error %d", err);
|
||||
return err;
|
||||
}
|
||||
memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0
|
||||
|
||||
loclass_iclass_calc_div_key(csn, (uint8_t*)picopass_iclass_key, div_key, false);
|
||||
loclass_opt_doReaderMAC(ccnr, div_key, mac);
|
||||
|
||||
return rfalPicoPassPollerCheck(mac, &chkRes);
|
||||
}
|
||||
|
||||
static ReturnCode picopass_auth_factory(uint8_t* csn, uint8_t* div_key) {
|
||||
rfalPicoPassReadCheckRes rcRes;
|
||||
rfalPicoPassCheckRes chkRes;
|
||||
|
||||
ReturnCode err;
|
||||
|
||||
uint8_t mac[4] = {0};
|
||||
uint8_t ccnr[12] = {0};
|
||||
|
||||
err = rfalPicoPassPollerReadCheck(&rcRes);
|
||||
if(err != ERR_NONE) {
|
||||
FURI_LOG_E(TAG, "rfalPicoPassPollerReadCheck error %d", err);
|
||||
return err;
|
||||
}
|
||||
memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0
|
||||
|
||||
loclass_iclass_calc_div_key(csn, (uint8_t*)picopass_factory_debit_key, div_key, false);
|
||||
loclass_opt_doReaderMAC(ccnr, div_key, mac);
|
||||
|
||||
return rfalPicoPassPollerCheck(mac, &chkRes);
|
||||
}
|
||||
|
||||
static ReturnCode picopass_auth_dict(
|
||||
uint8_t* csn,
|
||||
PicopassPacs* pacs,
|
||||
@@ -291,19 +240,14 @@ static ReturnCode picopass_auth_dict(
|
||||
ReturnCode picopass_auth(PicopassBlock* AA1, PicopassPacs* pacs) {
|
||||
ReturnCode err;
|
||||
|
||||
FURI_LOG_I(TAG, "Trying standard legacy key");
|
||||
err = picopass_auth_standard(
|
||||
AA1[PICOPASS_CSN_BLOCK_INDEX].data, AA1[PICOPASS_KD_BLOCK_INDEX].data);
|
||||
FURI_LOG_I(TAG, "Starting system dictionary attack [Standard KDF]");
|
||||
err = picopass_auth_dict(
|
||||
AA1[PICOPASS_CSN_BLOCK_INDEX].data,
|
||||
pacs,
|
||||
AA1[PICOPASS_KD_BLOCK_INDEX].data,
|
||||
IclassEliteDictTypeFlipper,
|
||||
false);
|
||||
if(err == ERR_NONE) {
|
||||
memcpy(pacs->key, picopass_iclass_key, PICOPASS_BLOCK_LEN);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
FURI_LOG_I(TAG, "Trying factory default key");
|
||||
err = picopass_auth_factory(
|
||||
AA1[PICOPASS_CSN_BLOCK_INDEX].data, AA1[PICOPASS_KD_BLOCK_INDEX].data);
|
||||
if(err == ERR_NONE) {
|
||||
memcpy(pacs->key, picopass_factory_debit_key, PICOPASS_BLOCK_LEN);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
@@ -329,17 +273,6 @@ ReturnCode picopass_auth(PicopassBlock* AA1, PicopassPacs* pacs) {
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
FURI_LOG_I(TAG, "Starting system dictionary attack [Standard KDF]");
|
||||
err = picopass_auth_dict(
|
||||
AA1[PICOPASS_CSN_BLOCK_INDEX].data,
|
||||
pacs,
|
||||
AA1[PICOPASS_KD_BLOCK_INDEX].data,
|
||||
IclassEliteDictTypeFlipper,
|
||||
false);
|
||||
if(err == ERR_NONE) {
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "picopass_device.h"
|
||||
#include "picopass_keys.h"
|
||||
|
||||
typedef struct PicopassWorker PicopassWorker;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "../picopass_i.h"
|
||||
#include "../picopass_keys.h"
|
||||
|
||||
enum SubmenuIndex {
|
||||
SubmenuIndexWriteStandard,
|
||||
@@ -8,11 +9,6 @@ enum SubmenuIndex {
|
||||
SubmenuIndexWriteCustom, //TODO: user input of key
|
||||
};
|
||||
|
||||
extern const uint8_t picopass_xice_key[];
|
||||
extern const uint8_t picopass_xicl_key[];
|
||||
extern const uint8_t picopass_xics_key[];
|
||||
extern const uint8_t picopass_iclass_key[];
|
||||
|
||||
void picopass_scene_key_menu_submenu_callback(void* context, uint32_t index) {
|
||||
Picopass* picopass = context;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "../picopass_i.h"
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
extern const uint8_t picopass_factory_debit_key[];
|
||||
#include "../picopass_keys.h"
|
||||
|
||||
void picopass_read_card_worker_callback(PicopassWorkerEvent event, void* context) {
|
||||
UNUSED(event);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "../picopass_i.h"
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
extern const uint8_t picopass_iclass_key[];
|
||||
#include "../picopass_keys.h"
|
||||
|
||||
void picopass_scene_read_factory_success_widget_callback(
|
||||
GuiButtonType result,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
typedef struct {
|
||||
uint8_t status;
|
||||
FuriMutex* mutex;
|
||||
} SentryState;
|
||||
|
||||
typedef enum {
|
||||
@@ -22,10 +23,9 @@ typedef struct {
|
||||
const char* status_texts[3] = {"[Press OK to open safe]", "Sending...", "Done !"};
|
||||
|
||||
static void sentry_safe_render_callback(Canvas* const canvas, void* ctx) {
|
||||
const SentryState* sentry_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(sentry_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const SentryState* sentry_state = ctx;
|
||||
furi_mutex_acquire(sentry_state->mutex, FuriWaitForever);
|
||||
|
||||
// Before the function is called, the state is set with the canvas_reset(canvas)
|
||||
|
||||
@@ -41,7 +41,7 @@ static void sentry_safe_render_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 50, AlignCenter, AlignBottom, status_texts[sentry_state->status]);
|
||||
|
||||
release_mutex((ValueMutex*)ctx, sentry_state);
|
||||
furi_mutex_release(sentry_state->mutex);
|
||||
}
|
||||
|
||||
static void sentry_safe_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -89,8 +89,8 @@ int32_t sentry_safe_app(void* p) {
|
||||
|
||||
sentry_state->status = 0;
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, sentry_state, sizeof(SentryState))) {
|
||||
sentry_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!sentry_state->mutex) {
|
||||
FURI_LOG_E("SentrySafe", "cannot create mutex\r\n");
|
||||
furi_message_queue_free(event_queue);
|
||||
free(sentry_state);
|
||||
@@ -98,7 +98,7 @@ int32_t sentry_safe_app(void* p) {
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, sentry_safe_render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, sentry_safe_render_callback, sentry_state);
|
||||
view_port_input_callback_set(view_port, sentry_safe_input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -109,7 +109,7 @@ int32_t sentry_safe_app(void* p) {
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
|
||||
SentryState* sentry_state = (SentryState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(sentry_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
@@ -151,7 +151,7 @@ int32_t sentry_safe_app(void* p) {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, sentry_state);
|
||||
furi_mutex_release(sentry_state->mutex);
|
||||
}
|
||||
|
||||
// Reset GPIO pins to default state
|
||||
@@ -162,7 +162,7 @@ int32_t sentry_safe_app(void* p) {
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(sentry_state->mutex);
|
||||
free(sentry_state);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -49,6 +49,7 @@ typedef struct {
|
||||
Direction nextMovement; // if backward of currentMovement, ignore
|
||||
Point fruit;
|
||||
GameState state;
|
||||
FuriMutex* mutex;
|
||||
} SnakeState;
|
||||
|
||||
typedef enum {
|
||||
@@ -91,12 +92,10 @@ const NotificationSequence sequence_eat = {
|
||||
};
|
||||
|
||||
static void snake_game_render_callback(Canvas* const canvas, void* ctx) {
|
||||
const SnakeState* snake_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(snake_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const SnakeState* snake_state = ctx;
|
||||
|
||||
// Before the function is called, the state is set with the canvas_reset(canvas)
|
||||
furi_mutex_acquire(snake_state->mutex, FuriWaitForever);
|
||||
|
||||
// Frame
|
||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
@@ -133,7 +132,7 @@ static void snake_game_render_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas_draw_str_aligned(canvas, 64, 41, AlignCenter, AlignBottom, buffer);
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, snake_state);
|
||||
furi_mutex_release(snake_state->mutex);
|
||||
}
|
||||
|
||||
static void snake_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -323,15 +322,16 @@ int32_t snake_game_app(void* p) {
|
||||
SnakeState* snake_state = malloc(sizeof(SnakeState));
|
||||
snake_game_init_game(snake_state);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, snake_state, sizeof(SnakeState))) {
|
||||
snake_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
|
||||
if(!snake_state->mutex) {
|
||||
FURI_LOG_E("SnakeGame", "cannot create mutex\r\n");
|
||||
free(snake_state);
|
||||
return 255;
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, snake_game_render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, snake_game_render_callback, snake_state);
|
||||
view_port_input_callback_set(view_port, snake_game_input_callback, event_queue);
|
||||
|
||||
FuriTimer* timer =
|
||||
@@ -349,7 +349,7 @@ int32_t snake_game_app(void* p) {
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
|
||||
SnakeState* snake_state = (SnakeState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(snake_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
@@ -388,7 +388,7 @@ int32_t snake_game_app(void* p) {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, snake_state);
|
||||
furi_mutex_release(snake_state->mutex);
|
||||
}
|
||||
|
||||
// Return backlight to normal state
|
||||
@@ -401,7 +401,7 @@ int32_t snake_game_app(void* p) {
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(snake_state->mutex);
|
||||
free(snake_state);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -53,4 +53,5 @@ typedef struct {
|
||||
int8_t selected_card;
|
||||
CardAnimation animation;
|
||||
uint8_t* buffer;
|
||||
FuriMutex* mutex;
|
||||
} GameState;
|
||||
@@ -154,10 +154,9 @@ static void draw_animation(Canvas* const canvas, const GameState* game_state) {
|
||||
}
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
const GameState* game_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(game_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const GameState* game_state = ctx;
|
||||
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
|
||||
|
||||
switch(game_state->state) {
|
||||
case GameStateAnimate:
|
||||
@@ -173,7 +172,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
break;
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, game_state);
|
||||
furi_mutex_release(game_state->mutex);
|
||||
}
|
||||
|
||||
void remove_drag(GameState* game_state) {
|
||||
@@ -468,8 +467,8 @@ int32_t solitaire_app(void* p) {
|
||||
game_state->state = GameStateStart;
|
||||
|
||||
game_state->processing = true;
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, game_state, sizeof(GameState))) {
|
||||
game_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!game_state->mutex) {
|
||||
FURI_LOG_E(APP_NAME, "cannot create mutex\r\n");
|
||||
return_code = 255;
|
||||
goto free_and_exit;
|
||||
@@ -479,20 +478,20 @@ int32_t solitaire_app(void* p) {
|
||||
notification_message_block(notification, &sequence_display_backlight_enforce_on);
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, game_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
FuriTimer* timer = furi_timer_alloc(update_timer_callback, FuriTimerTypePeriodic, event_queue);
|
||||
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 30);
|
||||
|
||||
Gui* gui = furi_record_open("gui");
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
AppEvent event;
|
||||
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 150);
|
||||
GameState* localstate = (GameState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
|
||||
bool hadChange = false;
|
||||
if(event_status == FuriStatusOk) {
|
||||
if(event.type == EventTypeKey) {
|
||||
@@ -504,7 +503,7 @@ int32_t solitaire_app(void* p) {
|
||||
case InputKeyRight:
|
||||
case InputKeyLeft:
|
||||
case InputKeyOk:
|
||||
localstate->input = event.input.key;
|
||||
game_state->input = event.input.key;
|
||||
break;
|
||||
case InputKeyBack:
|
||||
processing = false;
|
||||
@@ -520,12 +519,12 @@ int32_t solitaire_app(void* p) {
|
||||
case InputKeyRight:
|
||||
case InputKeyLeft:
|
||||
case InputKeyOk:
|
||||
if(event.input.key == InputKeyOk && localstate->state == GameStateStart) {
|
||||
localstate->state = GameStatePlay;
|
||||
if(event.input.key == InputKeyOk && game_state->state == GameStateStart) {
|
||||
game_state->state = GameStatePlay;
|
||||
init(game_state);
|
||||
} else {
|
||||
hadChange = true;
|
||||
localstate->input = event.input.key;
|
||||
game_state->input = event.input.key;
|
||||
}
|
||||
break;
|
||||
case InputKeyBack:
|
||||
@@ -538,16 +537,16 @@ int32_t solitaire_app(void* p) {
|
||||
}
|
||||
}
|
||||
} else if(event.type == EventTypeTick) {
|
||||
tick(localstate, notification);
|
||||
processing = localstate->processing;
|
||||
localstate->input = InputKeyMAX;
|
||||
tick(game_state, notification);
|
||||
processing = game_state->processing;
|
||||
game_state->input = InputKeyMAX;
|
||||
}
|
||||
} else {
|
||||
//FURI_LOG_W(APP_NAME, "osMessageQueue: event timeout");
|
||||
// event timeout
|
||||
}
|
||||
if(hadChange || game_state->state == GameStateAnimate) view_port_update(view_port);
|
||||
release_mutex(&state_mutex, localstate);
|
||||
furi_mutex_release(game_state->mutex);
|
||||
}
|
||||
|
||||
notification_message_block(notification, &sequence_display_backlight_enforce_auto);
|
||||
@@ -557,7 +556,7 @@ int32_t solitaire_app(void* p) {
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
view_port_free(view_port);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(game_state->mutex);
|
||||
|
||||
free_and_exit:
|
||||
free(game_state->animation.buffer);
|
||||
|
||||
Submodule applications/plugins/subbrute updated: ed94bc8786...19153c7239
@@ -61,6 +61,8 @@ typedef struct {
|
||||
|
||||
bool ctl_request_exit; // can be set to true if the worker should exit
|
||||
bool ctl_pause; // can be set to true if the worker should pause
|
||||
bool ctl_request_skip; // can be set to true if the worker should skip the current file
|
||||
bool ctl_request_prev; // can be set to true if the worker should go to the previous file
|
||||
|
||||
bool is_running; // indicates if the worker is running
|
||||
} PlaylistWorker;
|
||||
@@ -185,6 +187,18 @@ static int playlist_worker_process(
|
||||
status = 1;
|
||||
break;
|
||||
}
|
||||
if(worker->ctl_request_skip) {
|
||||
worker->ctl_request_skip = false;
|
||||
FURI_LOG_D(TAG, " (TX) Requested to skip. Cancelling and resending...");
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
if(worker->ctl_request_prev) {
|
||||
worker->ctl_request_prev = false;
|
||||
FURI_LOG_D(TAG, " (TX) Requested to prev. Cancelling and resending...");
|
||||
status = 3;
|
||||
break;
|
||||
}
|
||||
furi_delay_ms(50);
|
||||
}
|
||||
|
||||
@@ -213,6 +227,22 @@ static bool playlist_worker_wait_pause(PlaylistWorker* worker) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void updatePlayListView(PlaylistWorker* worker, const char* str) {
|
||||
furi_string_reset(worker->meta->prev_3_path);
|
||||
furi_string_set(worker->meta->prev_3_path, furi_string_get_cstr(worker->meta->prev_2_path));
|
||||
|
||||
furi_string_reset(worker->meta->prev_2_path);
|
||||
furi_string_set(worker->meta->prev_2_path, furi_string_get_cstr(worker->meta->prev_1_path));
|
||||
|
||||
furi_string_reset(worker->meta->prev_1_path);
|
||||
furi_string_set(worker->meta->prev_1_path, furi_string_get_cstr(worker->meta->prev_0_path));
|
||||
|
||||
furi_string_reset(worker->meta->prev_0_path);
|
||||
furi_string_set(worker->meta->prev_0_path, str);
|
||||
|
||||
view_port_update(worker->meta->view_port);
|
||||
}
|
||||
|
||||
static bool playlist_worker_play_playlist_once(
|
||||
PlaylistWorker* worker,
|
||||
Storage* storage,
|
||||
@@ -226,6 +256,7 @@ static bool playlist_worker_play_playlist_once(
|
||||
FURI_LOG_E(TAG, "Failed to rewind file");
|
||||
return false;
|
||||
}
|
||||
|
||||
while(flipper_format_read_string(fff_head, "sub", data)) {
|
||||
if(!playlist_worker_wait_pause(worker)) {
|
||||
break;
|
||||
@@ -238,18 +269,7 @@ static bool playlist_worker_play_playlist_once(
|
||||
const char* str = furi_string_get_cstr(data);
|
||||
|
||||
// it's not fancy, but it works for now :)
|
||||
furi_string_reset(worker->meta->prev_3_path);
|
||||
furi_string_set(
|
||||
worker->meta->prev_3_path, furi_string_get_cstr(worker->meta->prev_2_path));
|
||||
furi_string_reset(worker->meta->prev_2_path);
|
||||
furi_string_set(
|
||||
worker->meta->prev_2_path, furi_string_get_cstr(worker->meta->prev_1_path));
|
||||
furi_string_reset(worker->meta->prev_1_path);
|
||||
furi_string_set(
|
||||
worker->meta->prev_1_path, furi_string_get_cstr(worker->meta->prev_0_path));
|
||||
furi_string_reset(worker->meta->prev_0_path);
|
||||
furi_string_set(worker->meta->prev_0_path, str);
|
||||
view_port_update(worker->meta->view_port);
|
||||
updatePlayListView(worker, str);
|
||||
|
||||
for(int i = 0; i < 1; i++) {
|
||||
if(!playlist_worker_wait_pause(worker)) {
|
||||
@@ -279,6 +299,23 @@ static bool playlist_worker_play_playlist_once(
|
||||
// exited, exit loop
|
||||
} else if(status == 2) {
|
||||
return false;
|
||||
} else if(status == 3) {
|
||||
//aqui rebobinamos y avanzamos de nuevo el fichero n-1 veces
|
||||
//decrementamos el contador de ficheros enviados
|
||||
worker->meta->current_count--;
|
||||
if(worker->meta->current_count > 0) {
|
||||
worker->meta->current_count--;
|
||||
}
|
||||
//rebobinamos el fichero
|
||||
if(!flipper_format_rewind(fff_head)) {
|
||||
FURI_LOG_E(TAG, "Failed to rewind file");
|
||||
return false;
|
||||
}
|
||||
//avanzamos el fichero n-1 veces
|
||||
for(int j = 0; j < worker->meta->current_count; j++) {
|
||||
flipper_format_read_string(fff_head, "sub", data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // end of loop
|
||||
@@ -591,6 +628,8 @@ static void render_callback(Canvas* canvas, void* ctx) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
furi_string_free(temp_str);
|
||||
@@ -711,6 +750,10 @@ int32_t playlist_app(void* p) {
|
||||
if(input.type == InputTypeShort && app->meta->playlist_repetitions > 0) {
|
||||
--app->meta->playlist_repetitions;
|
||||
}
|
||||
} else if(app->meta->state == STATE_SENDING) {
|
||||
if(input.type == InputTypeShort) {
|
||||
app->worker->ctl_request_prev = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -719,6 +762,10 @@ int32_t playlist_app(void* p) {
|
||||
if(input.type == InputTypeShort) {
|
||||
++app->meta->playlist_repetitions;
|
||||
}
|
||||
} else if(app->meta->state == STATE_SENDING) {
|
||||
if(input.type == InputTypeShort) {
|
||||
app->worker->ctl_request_skip = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# ARM SWD (Single Wire Debug) Probe
|
||||
|
||||
Modern microcontrollers have support for the two wire debug interface SWD, which makes wiring a lot simpler.
|
||||
When reverse engineering, finding these two pins is a los easier than with JTAG, where you had to wire up twice or more pins. However, finding the two pins is still a bit of work, which gets simplified even more with this application.
|
||||
|
||||
This application tries to detect a valid SWD response on the wires you have picked and beeps when you have found the correct pins, showing the detected ID register and, more important, the SWD pinout. It doesn't matter which two pins you choose, just pick any two from the GPIOs on the breakout header.
|
||||
|
||||
To achieve this, the application sends packets and scans the response on all pins and elaborates the pins within a few retries. Using some kind of bisect pattern reduces this number to a hand full of tries, yielding in a seemingly instant detection.
|
||||
|
||||
For the user it is as simple as a continuity tester - wire up your two test needles (or accupuncture needles), connect the obvious GND pin and probe all test pads.
|
||||
Now it depends on your bisect capabilities finding all pad combinations, how long it will take this time.
|
||||
|
||||
https://cdn.discordapp.com/attachments/954430078882816021/1071603366741938176/20230205_022641.mp4
|
||||
|
||||
https://cdn.discordapp.com/attachments/1071712925171056690/1072306469057347594/qFlipper_2023-02-07_01-01-24.mp4
|
||||
|
||||
Discussion thread: https://discord.com/channels/740930220399525928/1071712925171056690
|
||||
|
||||
@@ -471,7 +471,10 @@ uint8_t swd_read_memory(AppFSM* const ctx, uint8_t ap, uint32_t address, uint32_
|
||||
ret |= swd_read_ap(ctx, ap, MEMAP_DRW, data);
|
||||
|
||||
if(ret != 1) {
|
||||
DBG("read from 0x%08lX failed", address);
|
||||
swd_abort(ctx);
|
||||
} else {
|
||||
DBG("read 0x%08lX from 0x%08lX", *data, address);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -705,7 +708,9 @@ static void swd_script_log(ScriptContext* ctx, FuriLogLevel level, const char* f
|
||||
size_t pos = strlen(buffer);
|
||||
vsnprintf(&buffer[pos], sizeof(buffer) - pos - 2, format, argp);
|
||||
strcat(buffer, "\n");
|
||||
usb_uart_tx_data(ctx->app->uart, (uint8_t*)buffer, strlen(buffer));
|
||||
if(!usb_uart_tx_data(ctx->app->uart, (uint8_t*)buffer, strlen(buffer))) {
|
||||
DBGS("Sending via USB failed");
|
||||
}
|
||||
} else {
|
||||
LOG(buffer);
|
||||
}
|
||||
@@ -1379,9 +1384,10 @@ static bool swd_scriptfunc_mem_write(ScriptContext* ctx) {
|
||||
|
||||
furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever);
|
||||
access_ok = swd_write_memory(ctx->app, ctx->selected_ap, address, data) == 1;
|
||||
furi_mutex_release(ctx->app->swd_mutex);
|
||||
access_ok |= ctx->errors_ignore;
|
||||
swd_read_memory(ctx->app, ctx->selected_ap, address, &data);
|
||||
furi_mutex_release(ctx->app->swd_mutex);
|
||||
|
||||
DBG("read %08lX from %08lX", data, address);
|
||||
|
||||
if(!access_ok) {
|
||||
@@ -1406,6 +1412,60 @@ static bool swd_scriptfunc_mem_write(ScriptContext* ctx) {
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool swd_scriptfunc_mem_read(ScriptContext* ctx) {
|
||||
uint32_t address = 0;
|
||||
bool success = true;
|
||||
|
||||
/* get file */
|
||||
if(!swd_script_skip_whitespace(ctx)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "missing whitespace");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* get address */
|
||||
if(!swd_script_get_number(ctx, &address)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "failed to parse address");
|
||||
return false;
|
||||
}
|
||||
|
||||
DBG("read from %08lX", address);
|
||||
|
||||
uint32_t data = 0;
|
||||
bool access_ok = false;
|
||||
for(uint32_t tries = 0; tries < ctx->max_tries; tries++) {
|
||||
if(ctx->abort) {
|
||||
DBGS("aborting");
|
||||
break;
|
||||
}
|
||||
|
||||
furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever);
|
||||
access_ok = swd_read_memory(ctx->app, ctx->selected_ap, address, &data) == 1;
|
||||
furi_mutex_release(ctx->app->swd_mutex);
|
||||
|
||||
if(!access_ok) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "Failed to read from %08lX", address);
|
||||
snprintf(
|
||||
ctx->app->state_string,
|
||||
sizeof(ctx->app->state_string),
|
||||
"Failed read 0x%08lX",
|
||||
address);
|
||||
swd_script_gui_refresh(ctx);
|
||||
} else {
|
||||
swd_script_log(ctx, FuriLogLevelDefault, "%08lX", data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!access_ok) {
|
||||
notification_message_block(ctx->app->notification, &seq_error);
|
||||
success = false;
|
||||
}
|
||||
|
||||
swd_script_seek_newline(ctx);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool swd_scriptfunc_mem_ldmst(ScriptContext* ctx) {
|
||||
uint32_t address = 0;
|
||||
uint32_t data = 0;
|
||||
@@ -1633,6 +1693,275 @@ static bool swd_scriptfunc_ap_read(ScriptContext* ctx) {
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool swd_scriptfunc_core_halt(ScriptContext* ctx) {
|
||||
bool succ = false;
|
||||
|
||||
furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever);
|
||||
uint32_t reg_dhcsr = SCS_DHCSR_KEY | SCS_DHCSR_C_HALT | SCS_DHCSR_C_DEBUGEN;
|
||||
|
||||
succ = swd_write_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, reg_dhcsr) == 1;
|
||||
|
||||
if(!succ) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "swd_write_memory failed");
|
||||
} else {
|
||||
swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, ®_dhcsr);
|
||||
|
||||
if(!(reg_dhcsr & SCS_DHCSR_S_HALT)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "Core did not halt");
|
||||
succ = false;
|
||||
} else {
|
||||
swd_script_log(ctx, FuriLogLevelDefault, "Core halted");
|
||||
}
|
||||
}
|
||||
|
||||
furi_mutex_release(ctx->app->swd_mutex);
|
||||
swd_script_seek_newline(ctx);
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
static bool swd_scriptfunc_core_continue(ScriptContext* ctx) {
|
||||
bool succ = false;
|
||||
uint32_t data = 0;
|
||||
|
||||
furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever);
|
||||
succ = swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, &data) == 1;
|
||||
|
||||
if(!(data & SCS_DHCSR_S_HALT)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "Core is not in debug state");
|
||||
succ = false;
|
||||
} else {
|
||||
succ = swd_write_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, SCS_DHCSR_KEY) == 1;
|
||||
furi_mutex_release(ctx->app->swd_mutex);
|
||||
}
|
||||
|
||||
if(!succ) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "swd_write_memory failed");
|
||||
} else {
|
||||
swd_script_log(ctx, FuriLogLevelDefault, "Core continued");
|
||||
}
|
||||
|
||||
swd_script_seek_newline(ctx);
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
static bool swd_scriptfunc_core_step(ScriptContext* ctx) {
|
||||
bool succ = false;
|
||||
uint32_t data = 0;
|
||||
|
||||
furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever);
|
||||
succ = swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, &data) == 1;
|
||||
|
||||
if(!(data & SCS_DHCSR_S_HALT)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "Core is not in debug state");
|
||||
succ = false;
|
||||
} else {
|
||||
succ = swd_write_memory(
|
||||
ctx->app,
|
||||
ctx->selected_ap,
|
||||
SCS_DHCSR,
|
||||
SCS_DHCSR_KEY | SCS_DHCSR_C_STEP | SCS_DHCSR_C_MASKINTS |
|
||||
SCS_DHCSR_C_DEBUGEN) == 1;
|
||||
}
|
||||
furi_mutex_release(ctx->app->swd_mutex);
|
||||
|
||||
if(!succ) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "swd_write_memory failed");
|
||||
} else {
|
||||
swd_script_log(ctx, FuriLogLevelDefault, "Core stepped");
|
||||
}
|
||||
|
||||
swd_script_seek_newline(ctx);
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
static struct cpu_regs_type {
|
||||
uint8_t regsel;
|
||||
const char* desc;
|
||||
} cpu_regs[] = {
|
||||
{0x00, "R00"}, {0x01, "R01"}, {0x02, "R02"}, {0x03, "R03"}, {0x04, "R04"},
|
||||
{0x05, "R05"}, {0x06, "R06"}, {0x07, "R07"}, {0x08, "R08"}, {0x09, "R09"},
|
||||
{0x0A, "R10"}, {0x0B, "R11"}, {0x0C, "R12"}, {0x0D, "SP/R13"}, {0x0E, "LR/R14"},
|
||||
{0x0F, "PC/R15"}, {0x10, "xPSR"}, {0x11, "MSP"}, {0x12, "PSP"}, {0x14, "Flags"},
|
||||
{0x21, "FPCSR"}, {0x40, "FP S00"}, {0x41, "FP S01"}, {0x42, "FP S02"}, {0x43, "FP S03"},
|
||||
{0x44, "FP S04"}, {0x45, "FP S05"}, {0x46, "FP S06"}, {0x47, "FP S07"}, {0x48, "FP S08"},
|
||||
{0x49, "FP S09"}, {0x4A, "FP S10"}, {0x4B, "FP S11"}, {0x4C, "FP S12"}, {0x4D, "FP S13"},
|
||||
{0x4E, "FP S14"}, {0x4F, "FP S15"}, {0x50, "FP S16"}, {0x51, "FP S17"}, {0x52, "FP S18"},
|
||||
{0x53, "FP S19"}, {0x54, "FP S20"}, {0x55, "FP S21"}, {0x56, "FP S22"}, {0x57, "FP S23"},
|
||||
{0x58, "FP S24"}, {0x59, "FP S25"}, {0x5A, "FP S26"}, {0x5B, "FP S27"}, {0x5C, "FP S28"},
|
||||
{0x5D, "FP S29"}, {0x5E, "FP S30"}, {0x5F, "FP S31"}};
|
||||
|
||||
static bool swd_scriptfunc_core_regs(ScriptContext* ctx) {
|
||||
bool succ = false;
|
||||
|
||||
furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever);
|
||||
|
||||
uint32_t reg_dhcsr = 0;
|
||||
uint32_t reg_cpacr = 0;
|
||||
swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, ®_dhcsr);
|
||||
swd_read_memory(ctx->app, ctx->selected_ap, SCS_CPACR, ®_cpacr);
|
||||
|
||||
/* when FPU is enabled/available, CP10 and CP11 are implemented */
|
||||
bool has_fpu = ((reg_cpacr >> 20) & 0x0F) != 0;
|
||||
|
||||
if(!(reg_dhcsr & SCS_DHCSR_S_HALT)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "Core is not in debug state");
|
||||
succ = false;
|
||||
} else {
|
||||
for(size_t pos = 0; pos < COUNT(cpu_regs); pos++) {
|
||||
if(!has_fpu && (cpu_regs[pos].regsel >= 0x20)) {
|
||||
continue;
|
||||
}
|
||||
uint32_t core_data = 0;
|
||||
succ =
|
||||
swd_write_memory(
|
||||
ctx->app, ctx->selected_ap, SCS_DCRSR, SCS_DCRSR_RD | cpu_regs[pos].regsel) ==
|
||||
1;
|
||||
succ &= swd_read_memory(ctx->app, ctx->selected_ap, SCS_DCRDR, &core_data) == 1;
|
||||
|
||||
if(!succ) {
|
||||
swd_script_log(ctx, FuriLogLevelDefault, "%08s ----------", cpu_regs[pos].desc);
|
||||
} else {
|
||||
swd_script_log(
|
||||
ctx, FuriLogLevelDefault, "%06s 0x%08X", cpu_regs[pos].desc, core_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
furi_mutex_release(ctx->app->swd_mutex);
|
||||
|
||||
swd_script_seek_newline(ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool swd_scriptfunc_core_reg_get(ScriptContext* ctx) {
|
||||
uint32_t core_reg = 0;
|
||||
uint32_t core_data = 0;
|
||||
bool succ = false;
|
||||
|
||||
if(!swd_script_skip_whitespace(ctx)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "missing whitespace");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!swd_script_get_number(ctx, &core_reg)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "failed to parse register");
|
||||
return false;
|
||||
}
|
||||
|
||||
furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever);
|
||||
uint32_t reg_dhcsr = 0;
|
||||
uint32_t reg_cpacr = 0;
|
||||
swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, ®_dhcsr);
|
||||
swd_read_memory(ctx->app, ctx->selected_ap, SCS_CPACR, ®_cpacr);
|
||||
|
||||
/* when FPU is enabled/available, CP10 and CP11 are implemented */
|
||||
bool has_fpu = ((reg_cpacr >> 20) & 0x0F) != 0;
|
||||
|
||||
if(!(reg_dhcsr & SCS_DHCSR_S_HALT)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "Core is not in debug state");
|
||||
succ = false;
|
||||
} else {
|
||||
if(!has_fpu && (core_reg >= 0x20)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "Core has no FP extensions");
|
||||
succ = false;
|
||||
} else {
|
||||
succ = swd_write_memory(
|
||||
ctx->app, ctx->selected_ap, SCS_DCRSR, SCS_DCRSR_RD | core_reg) == 1;
|
||||
succ &= swd_read_memory(ctx->app, ctx->selected_ap, SCS_DCRDR, &core_data) == 1;
|
||||
if(!succ) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "swd_write_memory failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
furi_mutex_release(ctx->app->swd_mutex);
|
||||
|
||||
if(succ) {
|
||||
swd_script_log(ctx, FuriLogLevelDefault, "0x%08X", core_data);
|
||||
}
|
||||
|
||||
swd_script_seek_newline(ctx);
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
static bool swd_scriptfunc_core_reg_set(ScriptContext* ctx) {
|
||||
uint32_t core_reg = 0;
|
||||
uint32_t core_data = 0;
|
||||
bool succ = false;
|
||||
|
||||
if(!swd_script_skip_whitespace(ctx)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "missing whitespace");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!swd_script_get_number(ctx, &core_reg)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "failed to parse register");
|
||||
return false;
|
||||
}
|
||||
if(!swd_script_skip_whitespace(ctx)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "missing whitespace");
|
||||
return false;
|
||||
}
|
||||
if(!swd_script_get_number(ctx, &core_data)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "failed to parse data");
|
||||
return false;
|
||||
}
|
||||
|
||||
furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever);
|
||||
uint32_t reg_dhcsr = 0;
|
||||
uint32_t reg_cpacr = 0;
|
||||
|
||||
swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, ®_dhcsr);
|
||||
swd_read_memory(ctx->app, ctx->selected_ap, SCS_CPACR, ®_cpacr);
|
||||
|
||||
/* when FPU is enabled/available, CP10 and CP11 are implemented */
|
||||
bool has_fpu = ((reg_cpacr >> 20) & 0x0F) != 0;
|
||||
|
||||
if(!(reg_dhcsr & SCS_DHCSR_S_HALT)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "Core is not in debug state");
|
||||
succ = false;
|
||||
} else {
|
||||
if(!has_fpu && (core_reg >= 0x20)) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "Core has no FP extensions");
|
||||
succ = false;
|
||||
} else {
|
||||
succ = swd_write_memory(ctx->app, ctx->selected_ap, SCS_DCRDR, core_data) == 1;
|
||||
succ &= swd_write_memory(
|
||||
ctx->app, ctx->selected_ap, SCS_DCRSR, SCS_DCRSR_WR | core_reg) == 1;
|
||||
if(!succ) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "swd_write_memory failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
furi_mutex_release(ctx->app->swd_mutex);
|
||||
|
||||
swd_script_seek_newline(ctx);
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
static bool swd_scriptfunc_core_cpuid(ScriptContext* ctx) {
|
||||
bool succ = false;
|
||||
uint32_t reg_cpuid = 0;
|
||||
|
||||
furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever);
|
||||
succ = swd_read_memory(ctx->app, ctx->selected_ap, SCS_CPUID, ®_cpuid) == 1;
|
||||
furi_mutex_release(ctx->app->swd_mutex);
|
||||
|
||||
if(!succ) {
|
||||
swd_script_log(ctx, FuriLogLevelError, "swd_read_memory failed");
|
||||
} else {
|
||||
swd_script_log(ctx, FuriLogLevelDefault, "0x%08X", reg_cpuid);
|
||||
}
|
||||
|
||||
swd_script_seek_newline(ctx);
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
static const ScriptFunctionInfo script_funcs[] = {
|
||||
{"#", &swd_scriptfunc_comment},
|
||||
{".label", &swd_scriptfunc_label},
|
||||
@@ -1650,12 +1979,20 @@ static const ScriptFunctionInfo script_funcs[] = {
|
||||
{"mem_dump", &swd_scriptfunc_mem_dump},
|
||||
{"mem_ldmst", &swd_scriptfunc_mem_ldmst},
|
||||
{"mem_write", &swd_scriptfunc_mem_write},
|
||||
{"mem_read", &swd_scriptfunc_mem_read},
|
||||
{"dp_write", &swd_scriptfunc_dp_write},
|
||||
{"dp_read", &swd_scriptfunc_dp_read},
|
||||
{"ap_scan", &swd_scriptfunc_apscan},
|
||||
{"ap_select", &swd_scriptfunc_apselect},
|
||||
{"ap_read", &swd_scriptfunc_ap_read},
|
||||
{"ap_write", &swd_scriptfunc_ap_write}};
|
||||
{"ap_write", &swd_scriptfunc_ap_write},
|
||||
{"core_halt", &swd_scriptfunc_core_halt},
|
||||
{"core_step", &swd_scriptfunc_core_step},
|
||||
{"core_continue", &swd_scriptfunc_core_continue},
|
||||
{"core_regs", &swd_scriptfunc_core_regs},
|
||||
{"core_reg_get", &swd_scriptfunc_core_reg_get},
|
||||
{"core_reg_set", &swd_scriptfunc_core_reg_set},
|
||||
{"core_cpuid", &swd_scriptfunc_core_cpuid}};
|
||||
|
||||
/************************** script main code **************************/
|
||||
|
||||
@@ -2487,7 +2824,6 @@ static void swd_main_loop(AppFSM* ctx) {
|
||||
}
|
||||
|
||||
case ModePageDPRegs:
|
||||
case ModePageDPID:
|
||||
case ModePageAPID: {
|
||||
furi_mutex_acquire(ctx->swd_mutex, FuriWaitForever);
|
||||
/* set debug enable request */
|
||||
@@ -2532,6 +2868,7 @@ static void swd_main_loop(AppFSM* ctx) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ModePageDPID:
|
||||
case ModePageCoresight:
|
||||
furi_delay_ms(50);
|
||||
break;
|
||||
|
||||
@@ -87,6 +87,21 @@ typedef enum {
|
||||
#define AP_IDR 0xFC
|
||||
#define AP_BASE 0xF8
|
||||
|
||||
#define SCS_CPUID 0xE000ED00u
|
||||
#define SCS_CPACR 0xE000ED88u
|
||||
#define SCS_DHCSR 0xE000EDF0u
|
||||
#define SCS_DHCSR_S_HALT (1u << 17)
|
||||
#define SCS_DHCSR_C_MASKINTS (1u << 3)
|
||||
#define SCS_DHCSR_C_STEP (1u << 2)
|
||||
#define SCS_DHCSR_C_HALT (1u << 1)
|
||||
#define SCS_DHCSR_C_DEBUGEN (1u << 0)
|
||||
#define SCS_DHCSR_KEY 0xA05F0000u
|
||||
#define SCS_DCRSR 0xE000EDF4u
|
||||
#define SCS_DCRSR_RD 0x00000000u
|
||||
#define SCS_DCRSR_WR 0x00010000u
|
||||
#define SCS_DCRDR 0xE000EDF8u
|
||||
#define SCS_DEMCR 0xE000EDFCu
|
||||
|
||||
typedef enum { KeyNone, KeyUp, KeyRight, KeyDown, KeyLeft, KeyOK } KeyCode;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -76,7 +76,7 @@ static void usb_uart_vcp_deinit(UsbUart* usb_uart, uint8_t vcp_ch) {
|
||||
}
|
||||
}
|
||||
|
||||
void usb_uart_tx_data(UsbUart* usb_uart, uint8_t* data, size_t length) {
|
||||
bool usb_uart_tx_data(UsbUart* usb_uart, uint8_t* data, size_t length) {
|
||||
uint32_t pos = 0;
|
||||
while(pos < length) {
|
||||
size_t pkt_size = length - pos;
|
||||
@@ -85,14 +85,19 @@ void usb_uart_tx_data(UsbUart* usb_uart, uint8_t* data, size_t length) {
|
||||
pkt_size = USB_CDC_PKT_LEN;
|
||||
}
|
||||
|
||||
if(furi_semaphore_acquire(usb_uart->tx_sem, 100) == FuriStatusOk) {
|
||||
furi_check(furi_mutex_acquire(usb_uart->usb_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
furi_hal_cdc_send(usb_uart->cfg.vcp_ch, &data[pos], pkt_size);
|
||||
furi_check(furi_mutex_release(usb_uart->usb_mutex) == FuriStatusOk);
|
||||
usb_uart->st.tx_cnt += pkt_size;
|
||||
pos += pkt_size;
|
||||
if(furi_semaphore_acquire(usb_uart->tx_sem, 100) != FuriStatusOk) {
|
||||
return false;
|
||||
}
|
||||
if(furi_mutex_acquire(usb_uart->usb_mutex, 100) != FuriStatusOk) {
|
||||
furi_semaphore_release(usb_uart->tx_sem);
|
||||
return false;
|
||||
}
|
||||
furi_hal_cdc_send(usb_uart->cfg.vcp_ch, &data[pos], pkt_size);
|
||||
furi_mutex_release(usb_uart->usb_mutex);
|
||||
usb_uart->st.tx_cnt += pkt_size;
|
||||
pos += pkt_size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t usb_uart_worker(void* context) {
|
||||
@@ -118,10 +123,11 @@ static int32_t usb_uart_worker(void* context) {
|
||||
}
|
||||
|
||||
if(events & WorkerEvtCdcRx) {
|
||||
furi_check(furi_mutex_acquire(usb_uart->usb_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
size_t len =
|
||||
furi_hal_cdc_receive(usb_uart->cfg.vcp_ch, &data[remain], USB_CDC_PKT_LEN);
|
||||
furi_check(furi_mutex_release(usb_uart->usb_mutex) == FuriStatusOk);
|
||||
size_t len = 0;
|
||||
if(furi_mutex_acquire(usb_uart->usb_mutex, 100) == FuriStatusOk) {
|
||||
len = furi_hal_cdc_receive(usb_uart->cfg.vcp_ch, &data[remain], USB_CDC_PKT_LEN);
|
||||
furi_mutex_release(usb_uart->usb_mutex);
|
||||
}
|
||||
|
||||
if(len > 0) {
|
||||
usb_uart->st.rx_cnt += len;
|
||||
|
||||
@@ -26,4 +26,4 @@ void usb_uart_get_config(UsbUart* usb_uart, UsbUartConfig* cfg);
|
||||
|
||||
void usb_uart_get_state(UsbUart* usb_uart, UsbUartState* st);
|
||||
|
||||
void usb_uart_tx_data(UsbUart* usb_uart, uint8_t* data, size_t length);
|
||||
bool usb_uart_tx_data(UsbUart* usb_uart, uint8_t* data, size_t length);
|
||||
|
||||
@@ -70,6 +70,7 @@ typedef struct {
|
||||
uint16_t fallSpeed;
|
||||
GameState gameState;
|
||||
FuriTimer* timer;
|
||||
FuriMutex* mutex;
|
||||
} TetrisState;
|
||||
|
||||
typedef enum {
|
||||
@@ -126,11 +127,9 @@ static void tetris_game_draw_playfield(Canvas* const canvas, const TetrisState*
|
||||
}
|
||||
|
||||
static void tetris_game_render_callback(Canvas* const canvas, void* ctx) {
|
||||
const TetrisState* tetris_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(tetris_state == NULL) {
|
||||
FURI_LOG_E("TetrisGame", "it null");
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const TetrisState* tetris_state = ctx;
|
||||
furi_mutex_acquire(tetris_state->mutex, FuriWaitForever);
|
||||
|
||||
tetris_game_draw_border(canvas);
|
||||
tetris_game_draw_playfield(canvas, tetris_state);
|
||||
@@ -158,7 +157,7 @@ static void tetris_game_render_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(canvas, 32, 73, AlignCenter, AlignBottom, buffer);
|
||||
}
|
||||
release_mutex((ValueMutex*)ctx, tetris_state);
|
||||
furi_mutex_release(tetris_state->mutex);
|
||||
}
|
||||
|
||||
static void tetris_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -357,8 +356,8 @@ int32_t tetris_game_app() {
|
||||
|
||||
TetrisState* tetris_state = malloc(sizeof(TetrisState));
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, tetris_state, sizeof(TetrisState))) {
|
||||
tetris_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!tetris_state->mutex) {
|
||||
FURI_LOG_E("TetrisGame", "cannot create mutex\r\n");
|
||||
furi_message_queue_free(event_queue);
|
||||
free(tetris_state);
|
||||
@@ -375,7 +374,7 @@ int32_t tetris_game_app() {
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_set_orientation(view_port, ViewPortOrientationVertical);
|
||||
view_port_draw_callback_set(view_port, tetris_game_render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, tetris_game_render_callback, tetris_state);
|
||||
view_port_input_callback_set(view_port, tetris_game_input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -395,7 +394,7 @@ int32_t tetris_game_app() {
|
||||
// This 10U implicitly sets the game loop speed. downRepeatCounter relies on this value
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 10U);
|
||||
|
||||
TetrisState* tetris_state = (TetrisState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(tetris_state->mutex, FuriWaitForever);
|
||||
|
||||
memcpy(newPiece, &tetris_state->currPiece, sizeof(tetris_state->currPiece));
|
||||
bool wasDownMove = false;
|
||||
@@ -462,7 +461,7 @@ int32_t tetris_game_app() {
|
||||
tetris_game_process_step(tetris_state, newPiece, wasDownMove);
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, tetris_state);
|
||||
furi_mutex_release(tetris_state->mutex);
|
||||
}
|
||||
|
||||
furi_timer_free(tetris_state->timer);
|
||||
@@ -471,7 +470,7 @@ int32_t tetris_game_app() {
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(tetris_state->mutex);
|
||||
vTaskPrioritySet(timer_task, origTimerPrio);
|
||||
free(newPiece);
|
||||
free(tetris_state);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
typedef enum { EventTypeTick, EventTypeKey } EventType;
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
FuriTimer* timer;
|
||||
uint8_t selBoxX;
|
||||
uint8_t selBoxY;
|
||||
@@ -172,10 +173,9 @@ static void tictactoe_state_init(TicTacToeState* tictactoe_state) {
|
||||
}
|
||||
|
||||
static void tictactoe_draw_callback(Canvas* const canvas, void* ctx) {
|
||||
TicTacToeState* ticst = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(ticst == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
TicTacToeState* ticst = ctx;
|
||||
furi_mutex_acquire(ticst->mutex, FuriWaitForever);
|
||||
|
||||
if(ticst->selX > 3) {
|
||||
ticst->selX = 3;
|
||||
@@ -284,7 +284,7 @@ static void tictactoe_draw_callback(Canvas* const canvas, void* ctx) {
|
||||
|
||||
tictactoe_draw(canvas, ticst);
|
||||
|
||||
release_mutex((ValueMutex*)ctx, ticst);
|
||||
furi_mutex_release(ticst->mutex);
|
||||
}
|
||||
|
||||
static void tictactoe_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -307,8 +307,9 @@ int32_t tictactoe_game_app(void* p) {
|
||||
|
||||
TicTacToeState* tictactoe_state = malloc(sizeof(TicTacToeState));
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, tictactoe_state, sizeof(TicTacToeState))) {
|
||||
tictactoe_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
|
||||
if(!tictactoe_state->mutex) {
|
||||
FURI_LOG_E(TAG, "Cannot create mutex\r\n");
|
||||
furi_message_queue_free(event_queue);
|
||||
free(tictactoe_state);
|
||||
@@ -317,7 +318,7 @@ int32_t tictactoe_game_app(void* p) {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, tictactoe_draw_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, tictactoe_draw_callback, tictactoe_state);
|
||||
view_port_input_callback_set(view_port, tictactoe_input_callback, event_queue);
|
||||
|
||||
tictactoe_state->timer =
|
||||
@@ -333,7 +334,7 @@ int32_t tictactoe_game_app(void* p) {
|
||||
GameEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
TicTacToeState* tictactoe_state = (TicTacToeState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(tictactoe_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// Key events
|
||||
@@ -366,7 +367,7 @@ int32_t tictactoe_game_app(void* p) {
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, tictactoe_state);
|
||||
furi_mutex_release(tictactoe_state->mutex);
|
||||
}
|
||||
|
||||
furi_timer_free(tictactoe_state->timer);
|
||||
@@ -375,7 +376,7 @@ int32_t tictactoe_game_app(void* p) {
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(tictactoe_state->mutex);
|
||||
free(tictactoe_state);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -23,12 +23,14 @@
|
||||
#define IDLE_TIMEOUT 60000
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
furi_assert(ctx);
|
||||
PluginState* plugin_state = ctx;
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
if(plugin_state != NULL) {
|
||||
totp_scene_director_render(canvas, plugin_state);
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -137,8 +139,8 @@ int32_t totp_app() {
|
||||
return 254;
|
||||
}
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
|
||||
plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!plugin_state->mutex) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Cannot create mutex\r\n");
|
||||
totp_plugin_state_free(plugin_state);
|
||||
return 255;
|
||||
@@ -157,7 +159,7 @@ int32_t totp_app() {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, plugin_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -169,7 +171,7 @@ int32_t totp_app() {
|
||||
while(processing) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
|
||||
PluginState* plugin_state_m = acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
if(event.type == EventTypeKey) {
|
||||
@@ -179,16 +181,16 @@ int32_t totp_app() {
|
||||
if(event.type == EventForceCloseApp) {
|
||||
processing = false;
|
||||
} else {
|
||||
processing = totp_scene_director_handle_event(&event, plugin_state_m);
|
||||
processing = totp_scene_director_handle_event(&event, plugin_state);
|
||||
}
|
||||
} else if(
|
||||
plugin_state_m->pin_set && plugin_state_m->current_scene != TotpSceneAuthentication &&
|
||||
plugin_state->pin_set && plugin_state->current_scene != TotpSceneAuthentication &&
|
||||
furi_get_tick() - last_user_interaction_time > IDLE_TIMEOUT) {
|
||||
totp_scene_director_activate_scene(plugin_state_m, TotpSceneAuthentication, NULL);
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL);
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, plugin_state_m);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
totp_cli_unregister_command_handler(cli_context);
|
||||
@@ -199,7 +201,7 @@ int32_t totp_app() {
|
||||
gui_remove_view_port(plugin_state->gui, view_port);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(plugin_state->mutex);
|
||||
totp_plugin_state_free(plugin_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -87,4 +87,5 @@ typedef struct {
|
||||
* @brief Notification method
|
||||
*/
|
||||
NotificationMethod notification_method;
|
||||
FuriMutex* mutex;
|
||||
} PluginState;
|
||||
|
||||
@@ -57,8 +57,10 @@ static void totp_type_code_worker_type_code(TotpTypeCodeWorkerContext* context)
|
||||
}
|
||||
|
||||
static int32_t totp_type_code_worker_callback(void* context) {
|
||||
ValueMutex context_mutex;
|
||||
if(!init_mutex(&context_mutex, context, sizeof(TotpTypeCodeWorkerContext))) {
|
||||
furi_assert(context);
|
||||
TotpTypeCodeWorkerContext* ctxx = context;
|
||||
ctxx->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!ctxx->mutex) {
|
||||
return 251;
|
||||
}
|
||||
|
||||
@@ -70,15 +72,16 @@ static int32_t totp_type_code_worker_callback(void* context) {
|
||||
furi_check((flags & FuriFlagError) == 0); //-V562
|
||||
if(flags & TotpTypeCodeWorkerEventStop) break;
|
||||
|
||||
TotpTypeCodeWorkerContext* h_context = acquire_mutex_block(&context_mutex);
|
||||
TotpTypeCodeWorkerContext* h_context = context;
|
||||
furi_mutex_acquire(ctxx->mutex, FuriWaitForever);
|
||||
if(flags & TotpTypeCodeWorkerEventType) {
|
||||
totp_type_code_worker_type_code(h_context);
|
||||
}
|
||||
|
||||
release_mutex(&context_mutex, h_context);
|
||||
furi_mutex_release(ctxx->mutex);
|
||||
}
|
||||
|
||||
delete_mutex(&context_mutex);
|
||||
furi_mutex_free(ctxx->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ typedef struct {
|
||||
FuriThread* thread;
|
||||
FuriMutex* string_sync;
|
||||
FuriHalUsbInterface* usb_mode_prev;
|
||||
FuriMutex* mutex;
|
||||
} TotpTypeCodeWorkerContext;
|
||||
|
||||
enum TotpTypeCodeWorkerEvents {
|
||||
|
||||
@@ -62,6 +62,7 @@ typedef struct SGpioButtons {
|
||||
} SGpioButtons;
|
||||
|
||||
typedef struct SWiFiDeauthApp {
|
||||
FuriMutex* mutex;
|
||||
Gui* m_gui;
|
||||
FuriThread* m_worker_thread;
|
||||
//NotificationApp* m_notification;
|
||||
@@ -121,10 +122,9 @@ static void esp8266_deauth_app_init(SWiFiDeauthApp* const app) {
|
||||
}
|
||||
|
||||
static void esp8266_deauth_module_render_callback(Canvas* const canvas, void* ctx) {
|
||||
SWiFiDeauthApp* app = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(app == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
SWiFiDeauthApp* app = ctx;
|
||||
furi_mutex_acquire(app->mutex, FuriWaitForever);
|
||||
|
||||
//if(app->m_needUpdateGUI)
|
||||
//{
|
||||
@@ -206,7 +206,7 @@ static void esp8266_deauth_module_render_callback(Canvas* const canvas, void* ct
|
||||
break;
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, app);
|
||||
furi_mutex_release(app->mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -235,14 +235,15 @@ static int32_t uart_worker(void* context) {
|
||||
furi_assert(context);
|
||||
DEAUTH_APP_LOG_I("[UART] Worker thread init");
|
||||
|
||||
SWiFiDeauthApp* app = acquire_mutex((ValueMutex*)context, 25);
|
||||
SWiFiDeauthApp* app = context;
|
||||
furi_mutex_acquire(app->mutex, FuriWaitForever);
|
||||
if(app == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
FuriStreamBuffer* rx_stream = app->m_rx_stream;
|
||||
|
||||
release_mutex((ValueMutex*)context, app);
|
||||
furi_mutex_release(app->mutex);
|
||||
|
||||
#if ENABLE_MODULE_POWER
|
||||
bool initialized = false;
|
||||
@@ -259,7 +260,8 @@ static int32_t uart_worker(void* context) {
|
||||
if(events & WorkerEventStop) break;
|
||||
if(events & WorkerEventRx) {
|
||||
DEAUTH_APP_LOG_I("[UART] Received data");
|
||||
SWiFiDeauthApp* app = acquire_mutex((ValueMutex*)context, 25);
|
||||
SWiFiDeauthApp* app = context;
|
||||
furi_mutex_acquire(app->mutex, FuriWaitForever);
|
||||
if(app == NULL) {
|
||||
return 1;
|
||||
}
|
||||
@@ -307,7 +309,7 @@ static int32_t uart_worker(void* context) {
|
||||
}
|
||||
#endif // ENABLE_MODULE_POWER
|
||||
|
||||
release_mutex((ValueMutex*)context, app);
|
||||
furi_mutex_release(app->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,8 +358,8 @@ int32_t esp8266_deauth_app(void* p) {
|
||||
#endif
|
||||
#endif // ENABLE_MODULE_DETECTION
|
||||
|
||||
ValueMutex app_data_mutex;
|
||||
if(!init_mutex(&app_data_mutex, app, sizeof(SWiFiDeauthApp))) {
|
||||
app->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!app->mutex) {
|
||||
DEAUTH_APP_LOG_E("cannot create mutex\r\n");
|
||||
free(app);
|
||||
return 255;
|
||||
@@ -365,10 +367,10 @@ int32_t esp8266_deauth_app(void* p) {
|
||||
|
||||
DEAUTH_APP_LOG_I("Mutex created");
|
||||
|
||||
//app->m_notification = furi_record_open("notification");
|
||||
//app->m_notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, esp8266_deauth_module_render_callback, &app_data_mutex);
|
||||
view_port_draw_callback_set(view_port, esp8266_deauth_module_render_callback, app);
|
||||
view_port_input_callback_set(view_port, esp8266_deauth_module_input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -382,7 +384,7 @@ int32_t esp8266_deauth_app(void* p) {
|
||||
app->m_worker_thread = furi_thread_alloc();
|
||||
furi_thread_set_name(app->m_worker_thread, "WiFiDeauthModuleUARTWorker");
|
||||
furi_thread_set_stack_size(app->m_worker_thread, 1 * 1024);
|
||||
furi_thread_set_context(app->m_worker_thread, &app_data_mutex);
|
||||
furi_thread_set_context(app->m_worker_thread, app);
|
||||
furi_thread_set_callback(app->m_worker_thread, uart_worker);
|
||||
furi_thread_start(app->m_worker_thread);
|
||||
DEAUTH_APP_LOG_I("UART thread allocated");
|
||||
@@ -398,7 +400,7 @@ int32_t esp8266_deauth_app(void* p) {
|
||||
SPluginEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
SWiFiDeauthApp* app = (SWiFiDeauthApp*)acquire_mutex_block(&app_data_mutex);
|
||||
furi_mutex_acquire(app->mutex, FuriWaitForever);
|
||||
|
||||
#if ENABLE_MODULE_DETECTION
|
||||
if(!app->m_wifiDeauthModuleAttached) {
|
||||
@@ -484,7 +486,7 @@ int32_t esp8266_deauth_app(void* p) {
|
||||
#endif
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&app_data_mutex, app);
|
||||
furi_mutex_release(app->mutex);
|
||||
}
|
||||
|
||||
DEAUTH_APP_LOG_I("Start exit app");
|
||||
@@ -514,7 +516,7 @@ int32_t esp8266_deauth_app(void* p) {
|
||||
|
||||
// Close gui record
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close("notification");
|
||||
//furi_record_close(RECORD_NOTIFICATION);
|
||||
app->m_gui = NULL;
|
||||
|
||||
view_port_free(view_port);
|
||||
@@ -523,7 +525,7 @@ int32_t esp8266_deauth_app(void* p) {
|
||||
|
||||
furi_stream_buffer_free(app->m_rx_stream);
|
||||
|
||||
delete_mutex(&app_data_mutex);
|
||||
furi_mutex_free(app->mutex);
|
||||
|
||||
// Free rest
|
||||
free(app);
|
||||
|
||||
@@ -83,6 +83,7 @@ typedef enum EWorkerEventFlags {
|
||||
} EWorkerEventFlags;
|
||||
|
||||
typedef struct SWiFiScannerApp {
|
||||
FuriMutex* mutex;
|
||||
Gui* m_gui;
|
||||
FuriThread* m_worker_thread;
|
||||
NotificationApp* m_notification;
|
||||
@@ -162,10 +163,9 @@ void DrawSignalStrengthBar(Canvas* canvas, int rssi, int x, int y, int width, in
|
||||
}
|
||||
|
||||
static void wifi_module_render_callback(Canvas* const canvas, void* ctx) {
|
||||
SWiFiScannerApp* app = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(app == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
SWiFiScannerApp* app = ctx;
|
||||
furi_mutex_acquire(app->mutex, FuriWaitForever);
|
||||
|
||||
canvas_clear(canvas);
|
||||
|
||||
@@ -433,7 +433,7 @@ static void wifi_module_render_callback(Canvas* const canvas, void* ctx) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
release_mutex((ValueMutex*)ctx, app);
|
||||
furi_mutex_release(app->mutex);
|
||||
}
|
||||
|
||||
static void wifi_module_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -460,14 +460,15 @@ static void uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
|
||||
static int32_t uart_worker(void* context) {
|
||||
furi_assert(context);
|
||||
|
||||
SWiFiScannerApp* app = acquire_mutex((ValueMutex*)context, 25);
|
||||
SWiFiScannerApp* app = context;
|
||||
furi_mutex_acquire(app->mutex, FuriWaitForever);
|
||||
if(app == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
FuriStreamBuffer* rx_stream = app->m_rx_stream;
|
||||
|
||||
release_mutex((ValueMutex*)context, app);
|
||||
furi_mutex_release(app->mutex);
|
||||
|
||||
while(true) {
|
||||
uint32_t events = furi_thread_flags_wait(
|
||||
@@ -527,7 +528,8 @@ static int32_t uart_worker(void* context) {
|
||||
} while(end < stringSize);
|
||||
furi_string_free(chunk);
|
||||
|
||||
app = acquire_mutex((ValueMutex*)context, 25);
|
||||
app = context;
|
||||
furi_mutex_acquire(app->mutex, FuriWaitForever);
|
||||
if(app == NULL) {
|
||||
return 1;
|
||||
}
|
||||
@@ -584,7 +586,7 @@ static int32_t uart_worker(void* context) {
|
||||
}
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)context, app);
|
||||
furi_mutex_release(app->mutex);
|
||||
|
||||
// Clear string array
|
||||
for(index = 0; index < EChunkArrayData_ENUM_MAX; ++index) {
|
||||
@@ -665,8 +667,9 @@ int32_t wifi_scanner_app(void* p) {
|
||||
#endif // ENABLE_MODULE_POWER
|
||||
#endif // ENABLE_MODULE_DETECTION
|
||||
|
||||
ValueMutex app_data_mutex;
|
||||
if(!init_mutex(&app_data_mutex, app, sizeof(SWiFiScannerApp))) {
|
||||
app->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
|
||||
if(!app->mutex) {
|
||||
WIFI_APP_LOG_E("cannot create mutex\r\n");
|
||||
free(app);
|
||||
return 255;
|
||||
@@ -674,10 +677,10 @@ int32_t wifi_scanner_app(void* p) {
|
||||
|
||||
WIFI_APP_LOG_I("Mutex created");
|
||||
|
||||
app->m_notification = furi_record_open("notification");
|
||||
app->m_notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, wifi_module_render_callback, &app_data_mutex);
|
||||
view_port_draw_callback_set(view_port, wifi_module_render_callback, app);
|
||||
view_port_input_callback_set(view_port, wifi_module_input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
@@ -691,7 +694,7 @@ int32_t wifi_scanner_app(void* p) {
|
||||
app->m_worker_thread = furi_thread_alloc();
|
||||
furi_thread_set_name(app->m_worker_thread, "WiFiModuleUARTWorker");
|
||||
furi_thread_set_stack_size(app->m_worker_thread, 1024);
|
||||
furi_thread_set_context(app->m_worker_thread, &app_data_mutex);
|
||||
furi_thread_set_context(app->m_worker_thread, app);
|
||||
furi_thread_set_callback(app->m_worker_thread, uart_worker);
|
||||
furi_thread_start(app->m_worker_thread);
|
||||
WIFI_APP_LOG_I("UART thread allocated");
|
||||
@@ -710,7 +713,7 @@ int32_t wifi_scanner_app(void* p) {
|
||||
SPluginEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
SWiFiScannerApp* app = (SWiFiScannerApp*)acquire_mutex_block(&app_data_mutex);
|
||||
furi_mutex_acquire(app->mutex, FuriWaitForever);
|
||||
|
||||
#if ENABLE_MODULE_DETECTION
|
||||
if(!app->m_wifiModuleAttached) {
|
||||
@@ -807,7 +810,7 @@ int32_t wifi_scanner_app(void* p) {
|
||||
#endif
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&app_data_mutex, app);
|
||||
furi_mutex_release(app->mutex);
|
||||
}
|
||||
|
||||
WIFI_APP_LOG_I("Start exit app");
|
||||
@@ -831,7 +834,7 @@ int32_t wifi_scanner_app(void* p) {
|
||||
|
||||
// Close gui record
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close("notification");
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
app->m_gui = NULL;
|
||||
|
||||
view_port_free(view_port);
|
||||
@@ -840,7 +843,7 @@ int32_t wifi_scanner_app(void* p) {
|
||||
|
||||
furi_stream_buffer_free(app->m_rx_stream);
|
||||
|
||||
delete_mutex(&app_data_mutex);
|
||||
furi_mutex_free(app->mutex);
|
||||
|
||||
// Free rest
|
||||
free(app);
|
||||
|
||||
@@ -51,6 +51,7 @@ typedef struct {
|
||||
} Projectile;
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* mutex;
|
||||
GameState game_state;
|
||||
Player player;
|
||||
|
||||
@@ -65,10 +66,9 @@ typedef struct {
|
||||
} PluginState;
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(plugin_state == NULL) {
|
||||
return;
|
||||
}
|
||||
furi_assert(ctx);
|
||||
const PluginState* plugin_state = ctx;
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
|
||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
|
||||
@@ -180,7 +180,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
//canvas_draw_str_aligned(canvas, 32, 16, AlignLeft, AlignBottom, info);
|
||||
//free(info);
|
||||
|
||||
release_mutex((ValueMutex*)ctx, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
@@ -294,8 +294,8 @@ int32_t zombiez_game_app(void* p) {
|
||||
PluginState* plugin_state = malloc(sizeof(PluginState));
|
||||
zombiez_state_init(plugin_state);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
|
||||
plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(!plugin_state->mutex) {
|
||||
FURI_LOG_E("Zombiez", "cannot create mutex\r\n");
|
||||
return_code = 255;
|
||||
goto free_and_exit;
|
||||
@@ -303,7 +303,7 @@ int32_t zombiez_game_app(void* p) {
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_draw_callback_set(view_port, render_callback, plugin_state);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
FuriTimer* timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, event_queue);
|
||||
@@ -317,7 +317,7 @@ int32_t zombiez_game_app(void* p) {
|
||||
bool isRunning = true;
|
||||
while(isRunning) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex);
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
if(event_status == FuriStatusOk) {
|
||||
if(event.type == EventTypeKey) {
|
||||
if(event.input.type == InputTypePress) {
|
||||
@@ -377,12 +377,10 @@ int32_t zombiez_game_app(void* p) {
|
||||
} else if(event.type == EventTypeTick) {
|
||||
tick(plugin_state);
|
||||
}
|
||||
} else {
|
||||
// event timeout
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, plugin_state);
|
||||
furi_mutex_release(plugin_state->mutex);
|
||||
}
|
||||
|
||||
furi_timer_free(timer);
|
||||
@@ -390,7 +388,7 @@ int32_t zombiez_game_app(void* p) {
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
delete_mutex(&state_mutex);
|
||||
furi_mutex_free(plugin_state->mutex);
|
||||
|
||||
free_and_exit:
|
||||
free(plugin_state);
|
||||
|
||||
@@ -45,3 +45,5 @@ C1B74D7478053AE2
|
||||
|
||||
# default iCLASS RFIDeas
|
||||
6B65797374726B72
|
||||
|
||||
5C100DF7042EAE64
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 21st Feb, 2023
|
||||
# Last Checked 21st Feb, 2023
|
||||
# Last Updated 07th Mar, 2023
|
||||
# Last Checked 07th Mar, 2023
|
||||
#
|
||||
name: POWER
|
||||
type: raw
|
||||
@@ -1091,6 +1091,18 @@ type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 270 18152 3021 8955 523 499 495 1497 492 504 500 468 526 496 498 498 496 499 495 501 493 502 492 1499 500 496 498 524 470 1521 498 497 497 499 495 1496 492 1499 500 1491 497 1494 494 1497 502 494 500 495 499 497 497 498 496 500 494 528 466 530 464 531 473 522 493 503 491 504 500 495 499 497 497 498 496 500 494 501 493 503 491 504 500 495 499 496 498 498 496 499 495 501 493 529 465 531 473 522 472 523 492 504 490 505 499 496 498 498 496 499 495 1496 492 1499 500 1492 496 1494 525 2947 2999 8953 525 1519 469 499 516 507 497 498 496 500 494 501 493 503 491 504 500 495 499 1492 496 499 495 501 493 1498 501 495 499 1492 496 1522 466 1524 496 1496 492 1499 500 1492 496 499 495 500 494 502 492 504 500 495 499 496 498 498 496 499 495 500 494 502 492 530 474 521 473 523 523 472 522 474 489 506 498 497 497 499 495 500 494 502 492 503 501 494 500 496 498 497 497 499 495 500 494 502 492 503 501 521 473 523 471 524 522 474 520 475 498 497 497 499 495 500 494 2978 2999 8952 525 1492 496 499 495 501 493 503 491 504 500 495 499 497 497 525 469 526 468 1524 516 479 494 501 493 503 491 504 500 495 499 497 497 1494 494 1497 492 1500 499 1492 496 499 495 1497 491 531 473 1518 522 1469 499 496 498 498 496 500 494 1497 491 1500 499 1492 496 499 495 501 493 502 492 504 500 495 499 523 471 525 469 526 520 1472 516 1475 493 502 492 504 500 495 499 1492 496 499 495 501 493 502 492 504 500 495 499 496 498 498 496 1522 466 1525 525 1466 491 1500 499
|
||||
# POWER_ON
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 4455 4310 587 1553 587 481 588 1552 587 1553 587 482 587 483 586 1553 585 483 586 483 587 1553 586 483 586 483 585 1553 586 1553 586 483 586 1553 586 1553 586 483 586 483 585 1553 586 1553 587 1552 586 1553 585 1554 585 483 586 1552 588 1552 585 483 586 483 586 483 586 483 585 484 585 484 585 483 586 483 586 483 585 484 586 483 586 483 586 483 586 1553 585 1553 585 1554 585 1553 585 1554 585 1553 586 1553 585 1554 584 5128 4426 4312 584 1554 585 484 585 1553 585 1554 585 483 586 483 585 1554 584 484 585 484 584 1553 584 485 584 484 585 1554 584 1555 583 485 584 1552 586 1553 585 484 585 483 585 1553 583 1554 585 1553 584 1554 583 1554 584 485 584 1554 584 1554 583 484 585 484 585 484 584 484 584 485 584 484 585 484 584 485 583 485 583 484 585 484 585 484 584 485 583 1555 584 1554 584 1553 584 1553 585 1553 584 1553 585 1553 584 1555 583
|
||||
# POWER_ON
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 530 374 30128 50095 3452 1625 471 1229 471 459 471 459 471 459 444 459 471 459 470 459 471 459 471 459 471 459 444 460 470 459 471 1230 470 459 470 460 443 460 470 460 469 460 470 460 470 460 443 1231 470 1230 470 460 470 460 470 460 443 487 443 460 469 460 470 461 468 461 469 1232 442 461 469 1232 468 1232 442 1232 468 1232 468 1232 468 1232 441 461 469 1232 468 1232 442 488 442 461 469 462 468 463 466 463 467 485 418 488 442 485 444 1234 467 1256 418 1256 444 1256 444 1256 444 1256 418 1256 444 1256 444 485 444 486 417 486 444 1256 444 485 444 485 444 486 417 486 444 1257 443 486 444 485 444 1257 417 486 444 486 443 486 444 1257 417 1257 443 486 444 486 444 486 443 486 417 513 416 487 443 487 442 486 444 1257 416 1257 443 487 442 486 444 486 443 487 416 513 416 487 443 486 443 487 443 487 442 487 416 514 415 1258 442 487 442 487 443 487 416 514 416 488 442 487 443 488 442 488 442 1258 415 1258 442 488 442 488 441 488 442 488 415 488 441 488 442 488 442 1259 441 1259 415 489 440 489 441 488 442 489 440 488 415 1259 441 1260 440 1260 414 516 414 489 439 491 440 489 440 490 439 490 414 516 413 490 438 491 438 492 438 491 415 539 389 517 413 514 391 516 414 539 414 516 390 539 388 542 363 540 390 1311 389 540 389 540 363 567 363 540 390 540 389 540 390 540 390 540 363 567 363 541 389 540 390 540 389 540 390 541 362 567 363 541 389 541 389 541 389 541 389 541 362 568 361 541 389 541 389 542 388 541 389 541 362 542 388 542 387 542 388 542 388 543 387 567 335 567 363 567 363 567 363 567 363 567 336 594 335 568 362 567 362 568 361 568 362 567 336 595 335 568 362 568 361 568 362 1338 362 1339 334 569 361 569 360 569 361 569 360 569 334 570 360 570 360 595 334 595 334 1366 307 1366 334 595 335 595 335 595 335 596 306 623 307 596 334 596 333 597 333 622 307 597 306 597 333 623 306 623 306 624 306 624 306 624 278 1395 305 1395 305 650 279 651 360
|
||||
#
|
||||
name: TEMP+
|
||||
type: raw
|
||||
@@ -1572,3 +1584,99 @@ type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 8362 4223 595 1983 1116 1480 592 1987 1081 1567 1070 1524 550 2029 1043 1540 1042 1568 1043 1532 549 2030 1042 1540 1042 1568 1042 1532 1042 1532 549 2022 549 2065 1043 1528 1043 1532 1043 1524 1042 1576 1042 1532 1042 1525 548 2030 549 2082 1042 1524 1042 1533 1042 1525 1042 1576 1042 1533 1042 1525 1041 1533 1042 1569 1042 1533 1042 1533 1042 1525 1041 1577 1041 1533 1042 1525 1041 1534 1041 1569 1042 1533 1041 1534 1040 1526 1041 1578 1041 1534 1041 1526 1040 1534 1041 1570 1041 1534 1015 1560 1015 1552 1015 1604 1040 1535 1040 1527 1039 1535 1014 1597 1013 1561 1014 1561 1013 1554 519 2129 987 1554 544 2036 518 2093 987
|
||||
# POWER_OFF
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 4453 4313 586 1554 585 483 586 1554 587 1552 587 483 587 484 586 1552 587 482 588 483 586 1553 586 483 587 483 586 1554 586 1553 585 484 587 1553 586 484 587 1553 586 1554 586 1553 586 1554 586 483 586 1553 586 1553 586 1555 585 483 586 482 588 483 585 484 585 1554 586 483 587 484 585 1553 587 1554 584 1554 585 484 586 484 586 483 586 483 586 484 586 482 588 483 584 484 586 1553 585 1555 584 1555 586 1553 586 1554 585 5129 4428 4312 585 1553 586 483 586 1555 584 1553 586 484 583 486 584 1555 585 484 585 483 586 1554 585 483 586 484 585 1554 585 1554 585 484 585 1554 585 484 584 1554 585 1554 584 1554 585 1554 586 483 585 1554 585 1555 584 1553 584 484 586 483 586 483 585 484 586 1554 583 484 586 483 585 1553 585 1553 585 1553 585 484 584 485 585 485 584 484 585 484 585 485 584 484 585 483 586 1554 585 1553 585 1554 584 1553 585 1553 585
|
||||
# TEMP_17
|
||||
name: TEMP-
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 4459 4311 588 1552 588 482 588 1552 589 1552 588 481 589 481 589 1552 588 482 587 483 587 1553 587 482 588 481 589 1553 588 1552 588 482 587 1554 586 483 587 1553 587 482 588 1552 588 1553 587 1553 588 1552 588 1552 588 1553 587 482 587 1553 588 481 589 482 587 482 587 483 587 482 587 483 588 482 587 483 587 482 587 483 587 482 587 483 586 483 587 1553 587 1553 587 1553 587 1554 586 1553 588 1553 587 1554 587 1553 587 5130 4431 4314 586 1553 588 482 588 1553 586 1554 587 483 587 483 587 1553 587 483 587 483 586 1554 587 483 586 483 587 1553 587 1553 587 482 588 1553 587 482 587 1553 587 483 587 1553 587 1554 586 1554 586 1554 586 1553 587 1554 587 482 588 1553 587 483 586 484 586 483 586 483 587 483 587 483 587 483 586 483 586 483 587 483 586 484 586 483 587 483 586 1554 586 1554 586 1554 586 1554 586 1554 586 1554 586 1555 586 1554 586
|
||||
# TEMP_30
|
||||
name: TEMP+
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 4489 4254 647 1493 645 425 619 1521 619 1521 619 452 617 453 616 1526 613 478 591 479 590 1551 589 481 588 481 589 1552 588 1552 588 482 588 1552 588 482 588 1552 588 482 588 1552 588 1553 587 1553 587 1552 588 1553 588 1552 588 482 588 1553 587 482 588 482 588 482 588 482 588 482 588 1552 588 482 588 1552 588 1552 588 482 588 482 588 482 588 482 588 482 588 1553 587 482 588 482 588 1553 587 1553 587 1553 587 1553 587 5130 4432 4313 587 1553 587 483 587 1553 587 1553 587 483 587 483 587 1553 587 483 587 483 587 1553 587 483 587 483 587 1553 587 1554 586 483 586 1553 587 483 587 1553 587 483 587 1553 587 1553 587 1554 586 1554 586 1554 586 1554 587 483 587 1553 587 483 587 483 587 483 587 483 587 483 587 1554 586 483 587 1554 586 1554 586 483 587 483 587 483 587 483 586 484 586 1554 586 484 586 483 587 1554 586 1554 586 1554 586 1554 586
|
||||
# POWER_OFF
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 479 397 30131 50087 3427 1674 447 1253 447 483 446 483 446 483 420 483 447 483 447 483 447 483 447 483 420 510 419 483 447 483 446 1254 446 483 420 510 419 484 446 483 447 484 445 483 446 484 419 1255 445 1254 446 484 445 484 445 484 419 484 446 484 446 484 445 484 446 484 445 1255 418 484 446 1255 445 1255 418 1255 445 1255 445 1254 446 1255 419 484 446 1255 445 1255 418 511 418 485 445 484 445 484 446 484 445 485 418 511 418 484 446 1255 445 1255 418 1255 445 1255 444 1256 444 1256 417 1256 445 1255 443 487 418 511 419 485 444 1255 445 485 445 485 420 509 418 485 445 1255 445 485 444 485 445 1256 417 512 418 485 444 485 445 1256 417 1256 444 485 444 485 420 509 444 486 418 511 418 485 445 485 444 1256 444 486 418 512 417 485 420 509 445 485 445 485 445 485 417 1256 444 486 444 485 445 1256 417 1256 443 486 444 485 444 486 444 485 444 485 418 485 444 485 444 485 444 486 443 486 417 1257 420 509 420 510 444 485 444 486 444 485 418 485 445 485 443 487 444 1256 444 1256 417 485 442 487 420 510 444 485 444 486 417 1256 420 1280 443 1257 417 512 393 510 444 486 442 487 443 486 419 510 417 513 419 484 419 510 444 486 419 510 419 510 393 537 415 488 420 510 418 510 419 510 419 510 392 537 392 511 445 484 419 511 418 511 418 511 392 538 391 511 419 511 419 511 418 511 418 511 391 511 419 512 418 511 418 511 419 511 418 512 391 512 418 512 417 512 417 512 418 512 417 512 391 512 418 512 417 512 417 512 417 512 391 539 390 513 416 513 417 512 417 513 417 537 366 564 365 514 416 537 392 537 392 538 392 538 365 564 365 538 392 538 392 538 391 538 391 538 365 564 365 538 392 538 391 1309 391 1308 365 538 391 538 392 538 391 538 392 538 365 565 364 538 392 538 391 539 391 1309 364 1309 391 538 391 539 391 538 391 538 391 539 364 538 392 539 390 539 391 539 390 539 364 565 364 539 391 539 390 1309 391 539 390 1309 364 539 391 539 390 539 391 539 498
|
||||
#
|
||||
name: MODE
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 479 396 30132 50085 3427 1674 446 1254 446 483 446 483 446 483 420 483 446 483 447 483 446 483 446 483 420 510 419 483 446 483 446 1254 446 483 420 510 419 483 446 484 446 483 446 484 446 483 420 1254 446 1254 446 484 445 484 446 483 420 484 446 484 445 484 446 484 445 484 419 1255 445 484 445 1254 446 1255 418 1255 446 1255 445 1255 445 1254 419 484 446 1255 445 1255 418 511 419 484 446 484 445 484 445 484 445 485 418 511 418 484 446 1255 445 1255 418 1255 445 1255 445 1255 446 1255 418 1256 445 1255 445 484 419 511 418 485 444 1256 444 485 445 484 445 485 417 485 445 1256 444 485 444 485 445 1256 417 485 445 485 444 486 443 1256 417 1283 417 1256 444 485 420 509 445 485 417 485 445 485 443 486 443 1257 443 487 417 485 420 510 444 485 443 487 419 510 416 513 417 1256 442 487 420 510 419 1281 392 1281 419 510 443 486 420 510 443 487 416 513 417 486 443 486 443 486 444 486 419 510 417 1257 419 511 443 487 418 511 418 511 392 511 419 511 419 511 418 511 443 1258 391 1282 443 487 418 511 418 511 418 512 391 538 418 1256 417 1282 418 1282 391 512 417 512 417 512 417 512 417 513 417 512 391 513 416 536 393 536 393 536 393 537 366 563 367 537 393 536 393 536 393 537 393 537 366 564 366 537 393 537 393 1308 392 537 366 563 366 537 393 537 393 537 392 537 393 537 366 564 366 537 393 537 392 537 393 537 392 537 366 564 365 537 393 537 392 537 392 537 392 537 366 564 366 537 392 537 392 537 393 537 392 537 366 564 365 538 392 538 392 538 391 538 392 538 365 538 392 537 392 538 391 538 391 538 391 538 365 565 364 538 392 538 391 538 392 538 391 538 365 538 391 538 392 538 391 538 391 1309 364 1310 390 539 391 539 390 539 390 539 364 566 363 539 391 539 390 539 390 539 390 1310 363 1310 391 539 390 539 390 540 363 567 362 540 390 539 390 540 390 541 388 564 338 568 362 565 364 565 364 565 365 1335 338 1336 364 565 364 565 364 565 364 566 364 1309 391
|
||||
#
|
||||
name: TEMP+
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 531 372 30125 50084 3425 1651 471 1229 471 458 471 458 445 485 445 458 472 458 472 458 471 458 471 458 445 485 444 459 471 458 472 1229 471 458 445 485 444 459 470 459 471 459 471 459 470 459 444 1230 470 1230 470 459 471 459 470 459 444 459 470 459 471 459 470 459 470 460 470 1204 469 459 470 1230 470 1231 442 1231 469 1231 469 1231 469 1231 443 460 469 1231 469 1231 442 487 443 461 468 461 468 461 468 461 469 462 441 489 441 461 468 1255 445 1255 418 1282 418 1282 418 1256 444 1256 418 1256 444 1256 444 485 445 485 418 485 445 1256 444 485 444 485 444 485 418 485 444 1256 444 485 444 485 444 1256 417 485 445 485 444 485 444 485 444 485 418 512 417 1256 444 485 444 485 445 485 418 512 417 485 444 1256 444 486 443 486 416 513 417 486 444 486 443 486 443 486 444 486 417 1257 443 486 444 1257 443 1257 416 486 444 486 443 486 443 487 442 487 416 513 416 487 418 511 443 487 442 487 418 1282 440 462 442 487 442 488 442 487 443 487 416 514 415 487 418 512 442 1258 442 1258 414 489 418 512 417 512 417 512 440 490 440 1260 413 1260 417 1283 441 488 391 539 390 512 441 488 417 512 417 513 416 512 391 539 390 513 438 491 417 513 416 513 416 513 389 540 390 514 415 513 417 513 416 513 416 514 388 541 388 1285 415 538 391 514 415 538 365 541 389 538 391 538 391 538 391 538 391 539 364 565 364 538 392 538 391 538 391 539 390 539 364 539 390 538 391 539 390 539 390 539 391 539 363 539 390 539 390 539 390 539 390 539 390 539 363 540 390 539 390 539 390 539 391 539 364 566 363 540 390 540 390 540 390 539 390 540 362 566 363 540 390 540 389 540 389 540 390 540 362 567 362 540 390 540 389 1311 389 1311 362 566 363 541 389 566 363 566 363 566 363 566 337 566 363 566 363 566 363 1337 336 1363 337 566 363 566 363 566 363 566 363 566 363 540 363 567 362 567 362 567 362 567 336 594 335 567 363 1337 363 1338 362 568 334 594 335 568 362 568 362 568 361 1364 496
|
||||
#
|
||||
name: TEMP-
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 479 398 30129 50086 3427 1675 446 1254 446 483 446 483 420 510 420 483 446 483 447 483 446 483 446 483 420 510 419 483 447 483 446 1254 446 484 419 510 420 484 446 483 446 484 446 484 445 484 419 1254 446 1254 446 484 445 484 445 484 419 484 446 484 446 484 445 484 446 484 419 1281 419 484 446 1255 445 1254 419 1254 446 1255 445 1255 445 1255 418 484 446 1255 445 1255 445 484 419 485 445 484 445 484 445 484 445 484 418 511 419 484 445 1255 445 1255 418 1282 418 1255 445 1255 445 1255 418 1282 418 1256 444 485 444 485 418 485 444 1256 443 486 444 485 445 485 418 485 444 1256 444 485 444 485 420 1281 418 485 443 486 444 485 420 1280 444 485 418 485 420 1280 444 486 443 487 417 512 416 487 420 510 444 1256 444 485 417 513 416 487 443 486 420 510 419 510 420 510 417 1257 443 486 419 510 419 1281 417 1257 419 510 420 510 420 509 419 511 418 511 392 511 419 510 443 486 419 511 418 510 393 1308 392 511 419 510 419 510 419 511 418 511 391 511 419 511 418 511 418 1281 419 1281 416 487 418 511 418 511 418 511 419 511 392 1281 419 1282 418 1282 392 537 392 511 418 511 419 511 419 511 419 511 392 538 392 512 418 511 419 511 418 512 418 512 391 538 391 512 418 512 417 512 418 512 417 512 391 539 390 512 417 1283 417 512 417 512 391 539 390 513 416 513 417 513 416 513 416 537 366 540 390 537 393 537 392 537 392 537 392 537 366 564 365 537 393 537 392 537 392 537 392 537 366 564 365 538 392 537 392 537 392 538 391 537 366 538 392 538 391 538 392 538 392 538 391 538 365 538 392 538 392 538 391 538 391 538 391 538 365 538 392 538 391 538 392 538 391 538 364 565 364 538 391 538 392 538 391 1309 364 1336 364 538 392 538 391 538 391 538 391 538 364 539 391 538 391 539 390 539 391 1309 364 1309 391 538 391 539 391 539 390 539 363 566 363 539 391 539 390 539 390 539 390 539 363 566 364 539 391 539 391 539 390 1310 363 566 364 539 391 539 390 540 389 1310 497
|
||||
#
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 454 414 452 413 453 413 453 413 453 412 454 25103 3488 1708 454 1278 454 413 453 413 453 413 453 1278 454 413 453 413 453 412 453 413 453 1278 479 388 478 1254 478 1255 477 389 476 1257 475 1283 449 1283 449 1284 448 1284 448 417 449 417 449 1284 448 417 449 417 449 417 449 417 449 418 448 417 449 418 448 417 449 418 448 418 448 1284 448 418 448 1284 448 418 448 418 448 418 448 1284 448 1284 448 418 448 418 448 418 448 418 448 1284 448 418 448 418 447 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 1284 448 1284 448 1285 447 418 448 418 448 1285 447 1285 447 1285 447 35478 3510 1713 449 1284 448 418 448 418 448 417 449 1284 448 418 448 418 448 418 448 418 448 1284 448 418 448 1284 448 1284 448 417 449 1284 448 1284 448 1284 448 1284 448 1284 448 418 448 418 448 1284 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 447 418 448 418 448 418 448 1284 448 418 448 418 448 418 448 418 448 1285 447 418 448 418 447 418 448 418 448 418 448 418 448 418 448 418 448 418 447 418 448 418 448 419 447 419 447 1285 447 418 448 418 448 418 448 418 448 418 448 1285 447 419 447 418 448 1285 447 1285 447 418 448 35479 3509 1713 449 1284 448 417 449 417 449 417 449 1284 448 418 448 418 448 418 448 418 448 1284 448 418 448 1284 448 1284 448 418 448 1284 448 1284 448 1284 448 1284 448 1284 448 418 448 418 448 1284 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 447 418 448 418 448 1285 447 418 448 418 448 1285 447 418 448 418 448 418 448 418 448 418 448 418 448 1285 447 418 448 418 448 1285 447 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 419 447 418 448 418 448 1285 447 419 447 1285 447 418 448 418 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 1285 447 1286 446 419 447 419 447 419 447 419 447 419 447 419 447 419 447 420 446 419 446 420 446 1286 446 1286 446 420 446 420 446 419 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 1287 445 420 446 420 446 420 446 420 446 421 445 1287 445 1287 445 421 445 421 445 421 445 421 445 421 445 421 445 421 445 1288 444 421 445 421 445 421 445 422 444 421 445 422 444 421 445 422 444 422 444 1288 444 1288 444 422 444 422 444 422 444 422 444 1289 443
|
||||
#
|
||||
name: TEMP+
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 453 414 452 413 453 412 454 414 452 413 453 25102 3490 1707 455 1278 483 384 482 383 482 383 482 1249 483 384 481 384 481 385 480 385 480 1251 481 387 478 1252 480 1253 478 414 451 1281 450 1282 449 1283 448 1283 449 1284 448 417 449 417 449 1284 448 417 449 417 449 417 449 417 449 418 448 417 449 417 449 417 449 417 449 417 449 1284 448 417 449 1284 448 417 449 417 449 417 449 1284 448 1284 448 417 449 417 449 417 449 418 448 1284 448 418 448 417 449 418 448 418 448 417 449 418 448 418 448 418 448 418 448 418 448 418 448 1284 448 1284 448 1284 448 418 448 418 448 1284 448 1284 448 1284 448 35479 3509 1713 449 1284 448 418 448 417 449 418 448 1284 448 417 449 418 448 417 449 418 448 1284 448 418 448 1284 448 1284 448 418 448 1284 448 1284 448 1284 448 1284 448 1284 448 418 448 418 448 1284 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 1284 448 418 448 418 448 418 447 418 448 1285 447 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 1284 448 418 448 418 448 418 448 418 447 418 448 1285 447 418 448 418 448 1285 447 1284 448 418 448 35478 3510 1713 449 1284 448 417 449 417 449 417 449 1284 448 417 449 417 449 417 449 417 449 1284 448 418 448 1284 448 1284 448 417 449 1284 448 1284 448 1284 448 1284 448 1284 448 418 448 417 449 1284 448 418 448 418 448 418 448 418 448 418 448 417 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 447 418 448 418 448 418 448 418 448 1284 448 418 448 418 448 1284 448 418 448 418 448 418 448 418 447 418 448 1284 448 1285 447 418 448 418 448 1284 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 419 447 418 447 419 447 418 448 418 448 418 448 418 448 1285 447 1285 447 419 447 1285 447 419 447 418 448 419 447 419 447 419 447 418 448 419 447 419 447 419 447 419 447 419 447 419 446 419 447 419 447 419 447 419 447 419 447 1285 447 1286 446 419 447 419 447 419 447 419 447 419 447 420 446 419 447 419 447 419 447 419 447 1286 446 1286 446 419 447 1286 446 419 447 420 446 419 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 445 1286 446 420 446 420 446 420 446 420 446 420 446 1287 445 1287 445 420 446 420 446 420 446 421 445 420 446 421 445 421 445 1287 445 421 445 420 446 421 445 421 445 421 445 421 445 421 445 421 445 1287 445 421 445 421 445 1287 445 1287 445 421 445 421 445 1287 445
|
||||
#
|
||||
name: TEMP-
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 454 414 451 413 453 413 453 413 453 413 453 25102 3489 1708 454 1277 455 413 452 413 453 413 453 1278 454 412 454 412 454 412 454 412 453 1278 454 413 478 1253 479 1254 477 389 476 1257 475 1283 448 1284 448 1284 448 1284 448 417 449 417 449 1284 448 417 449 417 449 417 449 417 449 418 448 418 448 418 448 418 448 418 448 417 448 1284 448 417 449 1284 448 418 448 418 448 418 448 1284 448 1284 448 418 448 418 448 418 448 418 448 1284 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 419 447 1285 447 1285 447 1285 447 419 447 419 447 1285 447 1285 447 1285 447 35505 3483 1713 449 1284 448 417 449 417 449 418 448 1284 448 417 449 417 449 417 449 418 448 1284 448 418 448 1284 448 1284 448 418 448 1284 448 1284 448 1284 448 1284 448 1284 448 417 449 418 448 1284 448 417 449 418 448 418 448 418 448 418 448 418 448 418 448 418 447 418 448 418 448 418 448 1285 447 418 448 418 448 418 448 418 448 1284 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 1285 447 418 448 418 448 418 448 418 448 418 448 1285 447 418 447 418 448 1284 448 1285 447 418 448 35481 3508 1713 448 1284 448 417 449 418 448 418 448 1284 448 418 448 418 448 417 449 418 448 1284 448 418 448 1284 448 1284 448 418 448 1284 448 1284 448 1284 448 1284 448 1284 448 418 448 418 448 1285 447 418 448 418 448 418 448 418 448 418 448 418 448 419 447 418 448 418 448 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 446 419 447 419 447 419 447 1286 446 419 447 419 447 419 446 419 447 419 447 419 447 1286 446 419 447 419 447 1286 446 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 446 419 447 419 447 419 447 419 447 419 447 1286 446 1286 446 420 446 1286 446 420 446 420 446 419 446 420 446 420 446 420 446 420 446 420 446 420 446 420 445 420 446 421 445 420 446 421 445 421 445 420 446 421 445 1287 445 1287 445 421 445 421 445 422 444 446 420 446 420 423 443 446 420 446 420 446 420 446 420 1312 420 1312 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 419 446 420 446 420 1313 419 446 420 446 420 447 419 447 419 446 420 1313 419 1313 419 447 419 447 419 446 420 447 419 446 420 447 419 447 419 1313 419 447 419 446 420 447 419 447 419 447 419 447 419 447 419 447 419 1313 419 447 419 1313 419 447 419 1313 419 447 419 447 419 1313 419
|
||||
#
|
||||
name: MODE
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 484 410 456 385 481 385 481 384 482 385 481 25074 3521 1676 483 1249 483 410 484 382 485 381 485 1247 485 381 484 381 485 381 484 382 483 1248 484 383 482 1249 482 1250 481 385 480 1253 478 1254 478 1255 477 1256 476 1256 476 389 477 389 477 1256 476 390 476 390 476 390 476 389 477 390 476 390 476 390 476 390 476 390 476 389 476 1256 476 390 476 1256 476 390 476 390 476 390 476 1256 476 1256 476 390 476 390 476 390 476 390 476 1257 475 390 476 390 476 390 476 390 476 390 476 390 476 390 476 390 475 391 475 391 475 390 476 1257 475 1257 475 1257 475 391 475 391 475 1257 475 1258 474 1258 474 35476 3516 1682 476 1256 476 390 476 389 477 389 477 1256 476 389 477 389 477 389 477 389 477 1256 476 389 477 1256 476 1256 476 390 476 1256 476 1256 476 1256 476 1256 476 1256 476 390 476 390 476 1256 476 390 476 390 476 390 476 390 476 390 476 390 476 390 476 390 476 390 476 390 476 390 476 1256 476 390 476 390 476 390 476 390 476 1257 475 390 476 390 476 390 475 391 475 390 476 391 475 391 475 391 475 391 475 391 475 391 475 391 475 391 475 1257 475 391 475 391 475 391 475 391 475 391 475 1258 474 392 474 392 474 1258 474 1259 473 416 450 35476 3516 1682 477 1257 475 390 476 390 476 390 476 1256 476 390 476 390 476 390 476 390 476 1257 475 390 476 1257 475 1257 475 390 476 1257 475 1257 475 1257 475 1257 475 1258 474 391 475 391 475 1258 474 391 475 391 475 391 475 391 475 391 475 391 475 391 475 391 475 391 475 391 475 391 475 391 475 391 475 392 474 391 475 391 475 391 475 392 474 392 474 391 475 392 474 1282 450 416 450 1283 449 416 450 416 450 416 450 416 450 393 473 416 449 416 450 416 450 1283 449 1283 449 417 449 417 449 416 449 417 449 416 450 416 450 417 449 416 450 416 450 417 449 416 450 417 449 417 449 1283 449 417 449 1283 449 417 449 417 449 417 449 417 449 417 449 417 449 417 448 417 449 417 449 417 449 417 449 417 449 417 449 417 449 417 449 417 449 417 449 1284 448 1283 449 417 449 417 449 417 449 417 449 417 449 417 449 417 449 417 449 417 449 417 449 1284 448 1284 448 417 449 418 448 417 449 418 448 418 448 418 448 418 448 418 448 418 448 418 448 417 449 418 447 418 448 418 448 418 448 418 448 418 448 1284 448 418 448 418 448 418 448 418 448 418 448 1284 448 1285 447 418 448 418 448 418 448 418 448 418 448 418 448 418 448 1285 447 418 448 418 448 418 448 418 448 418 448 419 447 418 448 418 448 1285 447 418 447 419 447 419 447 418 448 419 447 1285 447 419 447
|
||||
#
|
||||
name: MODE
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 536 335 510 363 509 363 509 335 565 311 505 25378 3540 1697 455 1317 427 418 455 417 455 417 455 1289 456 390 455 417 455 417 455 417 428 1317 454 392 480 1265 480 1265 480 393 479 1268 476 1269 476 1269 476 1269 476 1269 476 397 475 369 476 1269 476 396 476 397 476 396 449 397 476 396 476 397 448 396 476 397 475 397 476 370 475 1270 475 397 475 1270 475 397 475 397 448 397 475 1271 474 1271 474 398 474 398 474 371 474 398 475 398 474 398 447 398 475 398 474 398 447 399 474 400 472 423 449 371 474 399 473 399 473 423 422 1324 421 1324 421 1324 421 423 450 1296 449 423 449 1297 448 1297 448 34986 3534 1704 476 1269 476 396 476 369 476 396 476 1270 475 396 476 369 476 397 476 396 476 1270 475 397 448 1297 448 1297 449 397 476 1270 475 1270 475 1270 475 1270 475 1270 476 397 475 397 475 1270 475 370 475 397 476 397 475 397 448 398 474 397 475 397 476 370 475 398 474 397 475 398 447 1298 447 398 475 398 474 398 447 398 474 1272 473 399 473 398 474 372 473 399 473 399 474 423 422 399 474 423 449 423 449 396 449 423 450 423 449 1296 449 1296 449 423 422 424 449 423 449 423 422 423 449 1297 448 1297 448 424 448 1297 448 1297 448 423 450 34986 3535 1703 476 1269 476 369 476 396 476 396 477 1269 476 396 449 396 477 396 476 396 476 1270 475 369 476 1270 475 1270 475 397 476 1270 475 1270 475 1270 475 1270 475 1270 475 397 476 370 475 1270 475 397 476 397 475 397 448 397 475 397 476 397 475 370 475 398 474 398 475 398 447 398 474 398 474 398 474 371 474 398 474 399 473 371 474 422 451 1272 473 423 449 422 423 1323 422 423 450 1296 449 423 449 423 449 395 450 423 449 423 449 423 422 423 449 423 449 1296 450 1296 449 423 449 396 449 423 449 423 449 423 422 423 449 424 448 424 421 1324 421 1324 421 1324 421 1324 421 424 449 1297 448 424 448 1297 448 1297 448 1297 448 1297 448 1297 448 424 448 397 448 424 448 424 448 424 421 424 449 424 448 424 448 397 448 424 448 424 448 425 420 425 448 1298 447 1298 447 425 447 425 420 425 447 425 447 425 448 397 448 425 447 425 448 425 420 425 448 1298 447 1298 447 425 448 425 447 398 447 425 448 425 447 425 420 425 447 425 448 425 420 425 447 425 447 425 447 398 447 426 446 426 446 426 419 426 446 1299 446 426 446 426 447 398 447 426 446 426 446 1299 446 1299 446 426 419 426 446 426 446 426 447 399 446 427 446 426 446 1300 445 400 445 427 445 427 446 427 418 427 446 427 445 428 444 400 445 453 419 453 419 453 392 453 419 453 420 1326 419 1326 419 453 419
|
||||
# SWING_WIDE
|
||||
name: SWING
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 484 362 510 363 482 390 454 391 457 416 456 25430 3517 1720 457 1287 458 416 484 387 486 387 458 1286 458 387 485 387 457 414 431 414 458 1286 457 415 459 1286 457 1288 457 415 458 1288 456 1290 455 1290 480 1267 478 1292 453 392 453 420 453 1293 451 421 452 420 425 420 452 420 452 420 452 392 453 420 453 420 452 420 425 420 453 1293 452 421 452 1293 452 421 452 393 452 420 452 1293 452 1294 451 421 452 393 452 420 452 420 452 420 425 420 453 420 452 420 452 393 452 420 452 420 452 420 425 420 452 420 453 420 452 393 452 1293 451 1294 452 1294 451 421 451 1294 451 421 452 1294 451 1294 451 34985 3537 1726 452 1294 451 393 452 420 453 420 452 1293 452 421 424 420 453 420 452 420 452 1293 452 393 453 1293 452 1294 451 421 452 1293 452 1294 451 1294 451 1294 451 1294 451 421 452 421 424 1321 424 421 452 421 452 420 425 421 452 420 452 421 451 393 452 421 452 420 452 421 424 421 452 1294 451 421 452 421 451 394 451 421 451 1294 451 421 452 421 424 421 452 421 451 421 424 421 451 421 451 421 451 394 451 421 451 421 451 421 424 1321 424 1322 423 422 451 421 452 421 451 394 451 421 451 1294 451 1295 450 422 451 1294 451 1295 450 422 423 34985 3536 1726 452 1293 452 420 452 420 453 420 425 1320 425 421 452 420 452 420 452 393 452 1293 451 421 452 1293 451 1294 451 421 452 1293 452 1294 451 1294 451 1294 451 1294 451 421 424 421 452 1293 452 421 452 420 452 393 452 420 452 420 452 420 425 420 452 420 453 420 425 421 452 420 452 420 452 393 452 421 452 420 452 420 425 421 452 420 452 1294 451 421 452 394 451 1294 450 421 452 421 452 421 424 421 451 421 452 421 424 1322 423 421 452 421 451 1294 451 421 452 394 451 421 452 421 451 421 424 421 452 421 451 421 451 394 451 421 451 421 451 421 424 421 452 421 451 1294 451 1295 450 422 423 422 452 1294 450 1295 451 1295 450 1295 450 422 450 422 451 394 451 421 452 421 452 421 424 422 451 421 451 421 451 394 451 421 451 421 452 421 424 1322 423 1323 422 422 451 422 451 421 451 394 451 421 451 422 450 394 451 421 451 422 450 422 423 1322 422 1323 422 423 450 1295 450 423 450 422 450 395 450 422 450 422 450 422 423 422 451 422 450 422 450 395 450 422 451 422 450 395 450 422 450 422 451 1295 449 423 422 422 451 422 450 422 450 395 450 1295 449 1295 450 423 450 422 451 422 423 422 451 422 450 422 450 395 450 1295 449 423 450 422 451 395 450 422 450 422 450 422 423 422 451 422 450 422 451 1295 449 1296 449 396 449 423 450 1296 448 423 450 423 422
|
||||
#
|
||||
name: TEMP+
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 511 362 483 363 509 362 483 391 454 391 457 25457 3518 1719 457 1287 458 389 456 415 457 415 457 1287 485 389 456 388 457 415 457 415 457 1286 459 387 458 1286 459 1287 458 415 483 1262 483 1263 482 1264 481 1265 480 1291 454 419 453 420 425 1320 425 420 453 420 452 420 453 392 453 420 452 420 452 393 452 420 453 420 452 420 425 1320 425 420 453 1293 452 420 453 420 452 393 452 1293 452 1293 452 420 453 420 452 420 425 420 453 420 453 420 452 393 452 420 452 420 452 420 425 420 453 420 452 420 425 420 452 420 452 420 452 1293 452 1293 452 1293 452 393 452 1293 452 420 453 1293 452 1293 452 34983 3540 1724 452 1293 452 420 452 420 425 420 452 1293 452 420 453 420 453 392 453 420 452 1293 452 420 452 1293 452 1293 452 393 452 1293 452 1293 452 1293 452 1293 452 1294 451 420 452 421 452 1293 452 421 424 420 452 420 452 420 452 393 452 420 452 420 452 420 425 421 452 420 453 420 452 1293 452 394 451 421 451 421 451 393 452 1294 451 421 451 421 451 421 424 421 451 421 451 421 452 393 452 421 452 421 451 421 424 421 452 421 451 421 451 1294 451 394 451 421 452 421 451 394 451 421 451 1294 451 421 452 421 424 1322 423 1322 423 422 451 34985 3539 1724 452 1293 452 420 452 420 453 393 452 1293 452 421 452 420 452 420 425 420 452 1293 452 421 452 1293 452 1294 451 421 424 1321 424 1322 424 1321 424 1321 424 1321 424 421 451 421 452 1294 451 421 452 393 452 421 451 421 452 420 425 421 452 420 452 421 451 393 452 420 452 421 452 421 424 421 451 421 452 421 451 393 452 421 451 421 451 1294 451 394 452 421 451 1294 451 421 452 421 424 421 452 421 451 421 451 1294 451 1295 451 394 451 422 451 1294 450 422 451 421 424 421 451 421 451 421 452 394 451 422 451 422 450 394 451 421 451 421 451 421 424 422 451 422 450 1295 450 1295 450 422 450 395 450 422 450 422 450 422 423 422 450 422 450 422 451 394 451 422 450 422 450 395 450 422 450 422 450 422 423 422 451 422 450 422 450 395 450 1295 449 1296 449 423 449 423 450 423 422 423 450 422 450 423 449 396 449 423 450 423 449 423 422 1324 420 1324 422 424 449 1297 448 424 449 423 422 423 450 424 448 424 448 396 449 423 449 423 449 424 421 424 449 424 449 423 449 396 449 423 449 424 449 1297 447 425 420 425 448 424 449 424 421 425 448 1297 447 1298 447 425 447 425 448 397 448 425 447 424 448 425 420 426 447 1322 423 450 423 449 423 422 423 450 422 450 423 450 395 450 422 450 422 1323 421 451 395 450 423 1323 421 1324 421 451 421 451 422 423 422
|
||||
#
|
||||
name: TEMP-
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 538 335 510 362 510 362 510 338 507 338 534 25377 3593 1642 510 1235 510 363 537 335 509 363 509 1209 537 335 510 361 511 362 510 362 483 1262 483 363 508 1236 508 1237 507 366 478 1268 477 1269 476 1269 476 1270 475 1270 475 397 475 370 475 1270 475 397 475 397 475 397 448 397 476 397 475 397 476 369 476 397 475 397 475 370 475 1270 475 397 475 1270 475 397 475 397 448 397 475 1271 474 1270 475 397 475 397 475 370 475 398 474 398 474 397 448 398 475 398 474 397 475 370 475 398 474 398 475 370 475 398 475 398 474 398 447 1299 447 1299 446 1299 446 398 474 1271 474 399 474 1271 474 1272 473 34986 3534 1703 476 1269 476 396 476 369 476 396 476 1269 476 396 476 397 448 397 476 396 477 1269 476 397 448 1297 448 1297 448 396 476 1270 475 1270 475 1270 475 1270 475 1270 475 397 475 397 475 1270 475 370 475 397 475 397 475 397 448 397 475 397 475 397 475 370 475 397 475 397 475 397 448 1298 447 398 475 398 475 398 447 398 474 1271 474 398 474 398 474 395 450 422 450 422 450 422 423 422 450 422 450 423 450 395 450 422 451 422 450 423 422 1323 422 423 449 423 449 422 450 395 450 423 449 1296 450 422 450 395 450 1296 449 1296 449 423 449 34986 3535 1703 476 1269 476 396 476 396 449 397 475 1270 475 396 477 396 476 369 476 397 476 1269 476 397 475 1270 476 1270 475 397 448 1298 447 1298 447 1297 448 1298 447 1298 448 398 474 398 474 1295 450 398 447 398 474 422 450 422 451 395 450 422 450 422 450 422 423 422 451 422 450 422 450 395 450 422 450 422 451 422 423 422 450 422 451 422 423 1323 423 422 450 422 451 1295 450 422 450 395 450 422 450 422 451 422 423 423 450 1295 450 422 450 422 451 1295 450 395 450 422 450 423 449 422 423 423 449 423 450 422 423 423 449 423 450 422 450 396 449 423 449 423 449 423 422 1324 421 1323 422 423 450 423 449 423 449 396 449 423 449 423 449 423 422 423 450 423 450 423 449 396 449 423 449 423 450 396 449 424 448 424 449 423 422 424 449 424 448 1297 448 1297 448 424 448 397 448 424 449 424 448 424 421 424 448 424 449 424 449 396 449 424 448 1297 448 1297 448 424 448 1297 448 397 448 424 448 424 449 424 421 425 448 424 448 424 448 398 447 424 448 424 448 425 420 425 447 425 447 425 448 397 448 1298 447 425 447 425 447 398 448 425 447 425 447 1298 447 1298 447 425 420 425 447 425 448 425 447 398 447 425 447 426 446 1299 446 426 419 426 447 425 447 426 446 399 446 426 446 426 447 426 419 1326 419 1327 418 1327 419 426 446 1300 445 426 446 426 419 427 446
|
||||
# SWING_WIDE
|
||||
name: SWING
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 454 413 453 412 454 412 454 412 454 413 453 25102 3490 1707 483 1249 484 383 483 383 482 383 509 1222 483 383 482 384 481 385 480 385 480 1250 482 386 479 1252 479 1254 477 414 451 1281 450 1282 449 1283 449 1283 449 1284 448 417 448 417 449 1284 448 417 449 417 449 418 448 417 449 417 449 417 449 417 449 417 449 417 449 417 449 1284 448 418 448 1284 448 418 448 418 448 418 448 1284 448 1284 448 418 448 418 448 417 448 418 448 1284 448 417 449 417 448 418 448 417 449 417 449 417 449 418 448 417 449 418 448 418 448 418 448 1284 448 1284 448 1284 449 417 449 418 448 1284 448 1284 448 1284 448 35505 3485 1712 449 1283 449 417 449 417 449 417 449 1284 448 417 449 417 449 417 449 417 449 1284 448 417 449 1284 448 1284 448 417 449 1284 448 1284 448 1284 448 1283 449 1284 448 417 449 417 449 1284 448 417 449 417 449 417 449 417 449 417 449 417 449 417 449 417 449 418 448 418 448 417 449 1284 448 417 449 417 449 417 449 417 449 1284 448 417 448 418 448 418 448 417 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 1284 448 418 448 418 448 418 448 418 448 418 448 1284 448 418 448 418 448 1285 447 1285 447 418 448 35504 3486 1712 449 1283 449 417 449 417 448 417 449 1284 448 417 449 417 449 417 449 417 448 1284 448 417 449 1284 448 1284 448 417 449 1283 449 1284 448 1284 448 1284 448 1284 449 417 449 417 449 1284 448 417 449 417 449 418 448 417 449 417 449 417 449 418 448 417 449 417 449 418 448 418 448 418 448 417 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 1284 448 1284 448 1284 448 418 448 418 448 418 448 1284 448 418 448 418 448 1284 448 1284 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 418 448 1285 447 1285 447 418 448 1285 447 1285 447 1285 447 1285 447 1285 447 419 447 418 448 419 447 418 448 418 448 418 448 419 447 419 447 418 448 418 448 419 447 419 447 419 447 1285 447 1285 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 1286 446 1285 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 419 447 1286 446 420 446 420 446 420 446 420 446 419 447 1286 446 1286 446 419 447 420 446 420 446 420 446 420 446 420 446 420 446 1286 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 420 446 1286 446 420 446 420 446 420 446 1287 445 1287 445 1287 445
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 21st Feb, 2023
|
||||
# Last Checked 21st Feb, 2023
|
||||
# Last Updated 07th Mar, 2023
|
||||
# Last Checked 07th Mar, 2023
|
||||
#
|
||||
name: POWER
|
||||
type: parsed
|
||||
@@ -2092,3 +2092,9 @@ type: parsed
|
||||
protocol: NECext
|
||||
address: 30 FC 00 00
|
||||
command: 17 E8 00 00
|
||||
#
|
||||
name: POWER
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 00 00 00 00
|
||||
command: 04 00 00 00
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 15th Feb, 2023
|
||||
# Last Checked 21st Feb, 2023
|
||||
# Last Checked 07th Mar, 2023
|
||||
#
|
||||
name: POWER
|
||||
type: raw
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 21st Feb, 2023
|
||||
# Last Checked 21st Feb, 2023
|
||||
# Last Updated 07th Mar, 2023
|
||||
# Last Checked 07th Mar, 2023
|
||||
#
|
||||
# ON
|
||||
name: POWER
|
||||
@@ -844,3 +844,33 @@ type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 8811 4222 530 1580 531 1579 531 507 531 507 531 507 531 508 531 508 530 1582 528 1583 527 535 503 1608 502 536 501 1609 501 537 501 1610 500 538 500 1611 499 538 500 539 500 538 500 1611 500 539 499 538 500 1611 499 539 499 1611 499 1611 500 1611 499 539 499 1611 500 1611 500 539 499 35437 8784 4252 500 1611 500 1612 500 539 500 539 500 539 500 539 500 539 500 1611 500 1612 499 539 500 1612 500 539 500 1612 499 539 500 1612 500 539 500 1612 499 539 500 539 500 539 499 1612 499 540 499 539 500 1612 499 539 500 1612 499 1613 499 1612 499 539 500 1612 500 1612 500 539 500
|
||||
#
|
||||
name: VOL+
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 01 00 00 00
|
||||
command: 06 00 00 00
|
||||
#
|
||||
name: VOL-
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 01 00 00 00
|
||||
command: 09 00 00 00
|
||||
#
|
||||
name: MUTE
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 01 00 00 00
|
||||
command: 1A 00 00 00
|
||||
#
|
||||
name: POWER
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 01 00 00 00
|
||||
command: 00 00 00 00
|
||||
#
|
||||
name: MUTE
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 9035 4437 563 548 563 548 563 522 594 1645 591 1639 592 518 593 548 563 552 563 1640 592 548 563 553 562 1668 564 524 592 1642 594 1674 562 1673 563 1639 593 548 563 552 564 1669 562 548 563 520 615 529 586 1645 587 529 587 1650 586 1646 586 529 586 1650 586 1649 587 1646 586 524 587 524 587 524 587 524 587 525 643 467 644 440 671 467 644 472 643 1592 644 1593 643 1593 642 1594 641 1594 587 1649 585 1651 563 1682 562 14430 9008 2205 562
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 15th Feb, 2023
|
||||
# Last Checked 21st Feb, 2023
|
||||
# Last Updated 07th Mar, 2023
|
||||
# Last Checked 07th Mar, 2023
|
||||
#
|
||||
name: POWER
|
||||
type: parsed
|
||||
@@ -1863,3 +1863,39 @@ type: parsed
|
||||
protocol: RC5
|
||||
address: 00 00 00 00
|
||||
command: 17 00 00 00
|
||||
#
|
||||
name: POWER
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 12 00 00 00
|
||||
#
|
||||
name: VOL+
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 1A 00 00 00
|
||||
#
|
||||
name: VOL-
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 1E 00 00 00
|
||||
#
|
||||
name: MUTE
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 10 00 00 00
|
||||
#
|
||||
name: CH+
|
||||
type: parsed
|
||||
protocol: SIRC20
|
||||
address: 10 01 00 00
|
||||
command: 34 00 00 00
|
||||
#
|
||||
name: CH-
|
||||
type: parsed
|
||||
protocol: SIRC20
|
||||
address: 10 01 00 00
|
||||
command: 33 00 00 00
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,17.0,,
|
||||
Version,+,18.0,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@@ -156,6 +156,7 @@ Header,+,lib/toolbox/manchester_decoder.h,,
|
||||
Header,+,lib/toolbox/manchester_encoder.h,,
|
||||
Header,+,lib/toolbox/md5.h,,
|
||||
Header,+,lib/toolbox/path.h,,
|
||||
Header,+,lib/toolbox/pretty_format.h,,
|
||||
Header,+,lib/toolbox/protocols/protocol_dict.h,,
|
||||
Header,+,lib/toolbox/random_name.h,,
|
||||
Header,+,lib/toolbox/saved_struct.h,,
|
||||
@@ -439,7 +440,6 @@ Function,-,_wctomb_r,int,"_reent*, char*, wchar_t, _mbstate_t*"
|
||||
Function,-,a64l,long,const char*
|
||||
Function,+,abort,void,
|
||||
Function,-,abs,int,int
|
||||
Function,+,acquire_mutex,void*,"ValueMutex*, uint32_t"
|
||||
Function,-,aligned_alloc,void*,"size_t, size_t"
|
||||
Function,+,aligned_free,void,void*
|
||||
Function,+,aligned_malloc,void*,"size_t, size_t"
|
||||
@@ -573,7 +573,6 @@ Function,-,ctermid,char*,char*
|
||||
Function,-,ctime,char*,const time_t*
|
||||
Function,-,ctime_r,char*,"const time_t*, char*"
|
||||
Function,-,cuserid,char*,char*
|
||||
Function,+,delete_mutex,_Bool,ValueMutex*
|
||||
Function,+,dialog_ex_alloc,DialogEx*,
|
||||
Function,+,dialog_ex_disable_extended_events,void,DialogEx*
|
||||
Function,+,dialog_ex_enable_extended_events,void,DialogEx*
|
||||
@@ -684,6 +683,7 @@ Function,+,file_browser_worker_set_folder_callback,void,"BrowserWorker*, Browser
|
||||
Function,+,file_browser_worker_set_item_callback,void,"BrowserWorker*, BrowserWorkerListItemCallback"
|
||||
Function,+,file_browser_worker_set_list_callback,void,"BrowserWorker*, BrowserWorkerListLoadCallback"
|
||||
Function,+,file_browser_worker_set_long_load_callback,void,"BrowserWorker*, BrowserWorkerLongLoadCallback"
|
||||
Function,+,file_info_is_dir,_Bool,const FileInfo*
|
||||
Function,+,file_stream_alloc,Stream*,Storage*
|
||||
Function,+,file_stream_close,_Bool,Stream*
|
||||
Function,+,file_stream_get_error,FS_Error,Stream*
|
||||
@@ -707,6 +707,7 @@ Function,-,flipper_application_preload_status_to_string,const char*,FlipperAppli
|
||||
Function,+,flipper_application_spawn,FuriThread*,"FlipperApplication*, void*"
|
||||
Function,+,flipper_format_buffered_file_alloc,FlipperFormat*,Storage*
|
||||
Function,+,flipper_format_buffered_file_close,_Bool,FlipperFormat*
|
||||
Function,+,flipper_format_buffered_file_open_always,_Bool,"FlipperFormat*, const char*"
|
||||
Function,+,flipper_format_buffered_file_open_existing,_Bool,"FlipperFormat*, const char*"
|
||||
Function,+,flipper_format_delete_key,_Bool,"FlipperFormat*, const char*"
|
||||
Function,+,flipper_format_file_alloc,FlipperFormat*,Storage*
|
||||
@@ -1234,6 +1235,7 @@ Function,+,furi_thread_flags_get,uint32_t,
|
||||
Function,+,furi_thread_flags_set,uint32_t,"FuriThreadId, uint32_t"
|
||||
Function,+,furi_thread_flags_wait,uint32_t,"uint32_t, uint32_t, uint32_t"
|
||||
Function,+,furi_thread_free,void,FuriThread*
|
||||
Function,+,furi_thread_get_appid,const char*,FuriThreadId
|
||||
Function,+,furi_thread_get_current,FuriThread*,
|
||||
Function,+,furi_thread_get_current_id,FuriThreadId,
|
||||
Function,+,furi_thread_get_current_priority,FuriThreadPriority,
|
||||
@@ -1248,6 +1250,7 @@ Function,+,furi_thread_is_suspended,_Bool,FuriThreadId
|
||||
Function,+,furi_thread_join,_Bool,FuriThread*
|
||||
Function,+,furi_thread_mark_as_service,void,FuriThread*
|
||||
Function,+,furi_thread_resume,void,FuriThreadId
|
||||
Function,+,furi_thread_set_appid,void,"FuriThread*, const char*"
|
||||
Function,+,furi_thread_set_callback,void,"FuriThread*, FuriThreadCallback"
|
||||
Function,+,furi_thread_set_context,void,"FuriThread*, void*"
|
||||
Function,+,furi_thread_set_current_priority,void,FuriThreadPriority
|
||||
@@ -1312,7 +1315,6 @@ Function,+,icon_get_data,const uint8_t*,const Icon*
|
||||
Function,+,icon_get_height,uint8_t,const Icon*
|
||||
Function,+,icon_get_width,uint8_t,const Icon*
|
||||
Function,-,index,char*,"const char*, int"
|
||||
Function,+,init_mutex,_Bool,"ValueMutex*, void*, size_t"
|
||||
Function,-,initstate,char*,"unsigned, char*, size_t"
|
||||
Function,+,input_get_key_name,const char*,InputKey
|
||||
Function,+,input_get_type_name,const char*,InputType
|
||||
@@ -1491,6 +1493,7 @@ Function,+,power_get_pubsub,FuriPubSub*,Power*
|
||||
Function,+,power_is_battery_healthy,_Bool,Power*
|
||||
Function,+,power_off,void,Power*
|
||||
Function,+,power_reboot,void,PowerBootMode
|
||||
Function,+,pretty_format_bytes_hex_canonical,void,"FuriString*, size_t, const char*, const uint8_t*, size_t"
|
||||
Function,-,printf,int,"const char*, ..."
|
||||
Function,+,property_value_out,void,"PropertyValueContext*, const char*, unsigned int, ..."
|
||||
Function,+,protocol_dict_alloc,ProtocolDict*,"const ProtocolBase**, size_t"
|
||||
@@ -1534,12 +1537,10 @@ Function,+,rand,int,
|
||||
Function,-,rand_r,int,unsigned*
|
||||
Function,+,random,long,
|
||||
Function,-,rawmemchr,void*,"const void*, int"
|
||||
Function,-,read_mutex,_Bool,"ValueMutex*, void*, size_t, uint32_t"
|
||||
Function,+,realloc,void*,"void*, size_t"
|
||||
Function,-,reallocarray,void*,"void*, size_t, size_t"
|
||||
Function,-,reallocf,void*,"void*, size_t"
|
||||
Function,-,realpath,char*,"const char*, char*"
|
||||
Function,+,release_mutex,_Bool,"ValueMutex*, const void*"
|
||||
Function,-,remove,int,const char*
|
||||
Function,-,rename,int,"const char*, const char*"
|
||||
Function,-,renameat,int,"int, const char*, int, const char*"
|
||||
@@ -1617,14 +1618,18 @@ Function,-,srand48,void,long
|
||||
Function,-,srandom,void,unsigned
|
||||
Function,+,sscanf,int,"const char*, const char*, ..."
|
||||
Function,+,storage_common_copy,FS_Error,"Storage*, const char*, const char*"
|
||||
Function,+,storage_common_exists,_Bool,"Storage*, const char*"
|
||||
Function,+,storage_common_fs_info,FS_Error,"Storage*, const char*, uint64_t*, uint64_t*"
|
||||
Function,+,storage_common_merge,FS_Error,"Storage*, const char*, const char*"
|
||||
Function,+,storage_common_migrate,FS_Error,"Storage*, const char*, const char*"
|
||||
Function,+,storage_common_mkdir,FS_Error,"Storage*, const char*"
|
||||
Function,+,storage_common_remove,FS_Error,"Storage*, const char*"
|
||||
Function,+,storage_common_rename,FS_Error,"Storage*, const char*, const char*"
|
||||
Function,+,storage_common_resolve_path_and_ensure_app_directory,void,"Storage*, FuriString*"
|
||||
Function,+,storage_common_stat,FS_Error,"Storage*, const char*, FileInfo*"
|
||||
Function,+,storage_common_timestamp,FS_Error,"Storage*, const char*, uint32_t*"
|
||||
Function,+,storage_dir_close,_Bool,File*
|
||||
Function,+,storage_dir_exists,_Bool,"Storage*, const char*"
|
||||
Function,+,storage_dir_open,_Bool,"File*, const char*"
|
||||
Function,+,storage_dir_read,_Bool,"File*, FileInfo*, char*, uint16_t"
|
||||
Function,-,storage_dir_rewind,_Bool,File*
|
||||
@@ -1995,7 +2000,6 @@ Function,+,widget_alloc,Widget*,
|
||||
Function,+,widget_free,void,Widget*
|
||||
Function,+,widget_get_view,View*,Widget*
|
||||
Function,+,widget_reset,void,Widget*
|
||||
Function,-,write_mutex,_Bool,"ValueMutex*, void*, size_t, uint32_t"
|
||||
Function,-,xPortGetFreeHeapSize,size_t,
|
||||
Function,-,xPortGetMinimumEverFreeHeapSize,size_t,
|
||||
Function,-,xPortStartScheduler,BaseType_t,
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,17.0,,
|
||||
Version,+,18.0,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@@ -504,7 +504,6 @@ Function,-,acosh,double,double
|
||||
Function,-,acoshf,float,float
|
||||
Function,-,acoshl,long double,long double
|
||||
Function,-,acosl,long double,long double
|
||||
Function,+,acquire_mutex,void*,"ValueMutex*, uint32_t"
|
||||
Function,-,aligned_alloc,void*,"size_t, size_t"
|
||||
Function,+,aligned_free,void,void*
|
||||
Function,+,aligned_malloc,void*,"size_t, size_t"
|
||||
@@ -740,7 +739,6 @@ Function,-,ctermid,char*,char*
|
||||
Function,-,ctime,char*,const time_t*
|
||||
Function,-,ctime_r,char*,"const time_t*, char*"
|
||||
Function,-,cuserid,char*,char*
|
||||
Function,+,delete_mutex,_Bool,ValueMutex*
|
||||
Function,+,dialog_ex_alloc,DialogEx*,
|
||||
Function,+,dialog_ex_disable_extended_events,void,DialogEx*
|
||||
Function,+,dialog_ex_enable_extended_events,void,DialogEx*
|
||||
@@ -1406,7 +1404,7 @@ Function,+,furi_hal_spi_release,void,FuriHalSpiBusHandle*
|
||||
Function,+,furi_hal_subghz_check_radio,_Bool,
|
||||
Function,+,furi_hal_subghz_disable_ext_power,void,
|
||||
Function,-,furi_hal_subghz_dump_state,void,
|
||||
Function,+,furi_hal_subghz_enable_ext_power,void,
|
||||
Function,+,furi_hal_subghz_enable_ext_power,_Bool,
|
||||
Function,+,furi_hal_subghz_flush_rx,void,
|
||||
Function,+,furi_hal_subghz_flush_tx,void,
|
||||
Function,+,furi_hal_subghz_get_extend_settings,void,"_Bool*, _Bool*"
|
||||
@@ -1778,7 +1776,6 @@ Function,+,infrared_worker_tx_set_get_signal_callback,void,"InfraredWorker*, Inf
|
||||
Function,+,infrared_worker_tx_set_signal_sent_callback,void,"InfraredWorker*, InfraredWorkerMessageSentCallback, void*"
|
||||
Function,+,infrared_worker_tx_start,void,InfraredWorker*
|
||||
Function,+,infrared_worker_tx_stop,void,InfraredWorker*
|
||||
Function,+,init_mutex,_Bool,"ValueMutex*, void*, size_t"
|
||||
Function,-,initstate,char*,"unsigned, char*, size_t"
|
||||
Function,+,input_get_key_name,const char*,InputKey
|
||||
Function,+,input_get_type_name,const char*,InputType
|
||||
@@ -1989,7 +1986,7 @@ Function,+,menu_free,void,Menu*
|
||||
Function,+,menu_get_view,View*,Menu*
|
||||
Function,+,menu_reset,void,Menu*
|
||||
Function,+,menu_set_selected_item,void,"Menu*, uint32_t"
|
||||
Function,-,mf_classic_auth_attempt,_Bool,"FuriHalNfcTxRxContext*, MfClassicAuthContext*, uint64_t"
|
||||
Function,-,mf_classic_auth_attempt,_Bool,"FuriHalNfcTxRxContext*, Crypto1*, MfClassicAuthContext*, uint64_t"
|
||||
Function,-,mf_classic_auth_init_context,void,"MfClassicAuthContext*, uint8_t"
|
||||
Function,-,mf_classic_auth_write_block,_Bool,"FuriHalNfcTxRxContext*, MfClassicBlock*, uint8_t, MfClassicKey, uint64_t"
|
||||
Function,-,mf_classic_authenticate,_Bool,"FuriHalNfcTxRxContext*, uint8_t, uint64_t, MfClassicKey"
|
||||
@@ -2310,12 +2307,10 @@ Function,+,rand,int,
|
||||
Function,-,rand_r,int,unsigned*
|
||||
Function,+,random,long,
|
||||
Function,-,rawmemchr,void*,"const void*, int"
|
||||
Function,-,read_mutex,_Bool,"ValueMutex*, void*, size_t, uint32_t"
|
||||
Function,+,realloc,void*,"void*, size_t"
|
||||
Function,-,reallocarray,void*,"void*, size_t, size_t"
|
||||
Function,-,reallocf,void*,"void*, size_t"
|
||||
Function,-,realpath,char*,"const char*, char*"
|
||||
Function,+,release_mutex,_Bool,"ValueMutex*, const void*"
|
||||
Function,-,remainder,double,"double, double"
|
||||
Function,-,remainderf,float,"float, float"
|
||||
Function,-,remainderl,long double,"long double, long double"
|
||||
@@ -4714,7 +4709,6 @@ Function,+,widget_alloc,Widget*,
|
||||
Function,+,widget_free,void,Widget*
|
||||
Function,+,widget_get_view,View*,Widget*
|
||||
Function,+,widget_reset,void,Widget*
|
||||
Function,-,write_mutex,_Bool,"ValueMutex*, void*, size_t, uint32_t"
|
||||
Function,-,xPortGetFreeHeapSize,size_t,
|
||||
Function,-,xPortGetMinimumEverFreeHeapSize,size_t,
|
||||
Function,-,xPortStartScheduler,BaseType_t,
|
||||
|
||||
|
@@ -21,8 +21,6 @@
|
||||
#define INIT_TIMEOUT 10
|
||||
|
||||
static uint32_t furi_hal_subghz_debug_gpio_buff[2];
|
||||
static bool last_OTG_state = false;
|
||||
static bool ext_power_is_enabled_already = false;
|
||||
|
||||
/* DMA Channels definition */
|
||||
#define SUBGHZ_DMA DMA2
|
||||
@@ -80,18 +78,20 @@ void furi_hal_subghz_init(void) {
|
||||
furi_hal_subghz_init_check();
|
||||
}
|
||||
|
||||
void furi_hal_subghz_enable_ext_power(void) {
|
||||
if(ext_power_is_enabled_already && furi_hal_power_is_otg_enabled()) return;
|
||||
ext_power_is_enabled_already = true;
|
||||
last_OTG_state = furi_hal_power_is_otg_enabled();
|
||||
if(furi_hal_subghz.radio_type != SubGhzRadioInternal && !furi_hal_power_is_otg_enabled()) {
|
||||
furi_hal_power_enable_otg();
|
||||
bool furi_hal_subghz_enable_ext_power(void) {
|
||||
if(furi_hal_subghz.radio_type != SubGhzRadioInternal) {
|
||||
uint8_t attempts = 0;
|
||||
while(!furi_hal_power_is_otg_enabled() && attempts++ < 2) {
|
||||
furi_hal_power_enable_otg();
|
||||
//CC1101 power-up time
|
||||
furi_delay_ms(5);
|
||||
}
|
||||
}
|
||||
return furi_hal_power_is_otg_enabled();
|
||||
}
|
||||
|
||||
void furi_hal_subghz_disable_ext_power(void) {
|
||||
ext_power_is_enabled_already = false;
|
||||
if(furi_hal_subghz.radio_type != SubGhzRadioInternal && !last_OTG_state) {
|
||||
if(furi_hal_subghz.radio_type != SubGhzRadioInternal) {
|
||||
furi_hal_power_disable_otg();
|
||||
}
|
||||
}
|
||||
@@ -99,8 +99,6 @@ void furi_hal_subghz_disable_ext_power(void) {
|
||||
bool furi_hal_subghz_check_radio(void) {
|
||||
bool result = true;
|
||||
|
||||
furi_hal_subghz_enable_ext_power();
|
||||
|
||||
furi_hal_spi_acquire(furi_hal_subghz.spi_bus_handle);
|
||||
|
||||
uint8_t ver = cc1101_get_version(furi_hal_subghz.spi_bus_handle);
|
||||
@@ -113,7 +111,6 @@ bool furi_hal_subghz_check_radio(void) {
|
||||
|
||||
result = false;
|
||||
}
|
||||
furi_hal_subghz_disable_ext_power();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -124,7 +121,6 @@ bool furi_hal_subghz_init_check(void) {
|
||||
furi_hal_subghz.state = SubGhzStateIdle;
|
||||
furi_hal_subghz.preset = FuriHalSubGhzPresetIDLE;
|
||||
|
||||
furi_hal_subghz_enable_ext_power();
|
||||
furi_hal_spi_acquire(furi_hal_subghz.spi_bus_handle);
|
||||
|
||||
#ifdef FURI_HAL_SUBGHZ_TX_GPIO
|
||||
@@ -176,7 +172,6 @@ bool furi_hal_subghz_init_check(void) {
|
||||
} else {
|
||||
FURI_LOG_E(TAG, "Failed to initialization");
|
||||
}
|
||||
furi_hal_subghz_disable_ext_power();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -193,8 +188,6 @@ void furi_hal_subghz_sleep() {
|
||||
|
||||
furi_hal_spi_release(furi_hal_subghz.spi_bus_handle);
|
||||
|
||||
furi_hal_subghz_disable_ext_power();
|
||||
|
||||
furi_hal_subghz.preset = FuriHalSubGhzPresetIDLE;
|
||||
}
|
||||
|
||||
@@ -339,7 +332,6 @@ void furi_hal_subghz_shutdown() {
|
||||
// Reset and shutdown
|
||||
cc1101_shutdown(furi_hal_subghz.spi_bus_handle);
|
||||
furi_hal_spi_release(furi_hal_subghz.spi_bus_handle);
|
||||
furi_hal_subghz_disable_ext_power();
|
||||
}
|
||||
|
||||
void furi_hal_subghz_reset() {
|
||||
@@ -352,7 +344,6 @@ void furi_hal_subghz_reset() {
|
||||
}
|
||||
|
||||
void furi_hal_subghz_idle() {
|
||||
furi_hal_subghz_enable_ext_power();
|
||||
furi_hal_spi_acquire(furi_hal_subghz.spi_bus_handle);
|
||||
cc1101_switch_to_idle(furi_hal_subghz.spi_bus_handle);
|
||||
furi_hal_spi_release(furi_hal_subghz.spi_bus_handle);
|
||||
|
||||
@@ -317,8 +317,9 @@ SubGhzRadioType furi_hal_subghz_get_radio_type(void);
|
||||
bool furi_hal_subghz_check_radio(void);
|
||||
|
||||
/** Turn on the power of the external radio module
|
||||
* @return true if power-up is successful
|
||||
*/
|
||||
void furi_hal_subghz_enable_ext_power(void);
|
||||
bool furi_hal_subghz_enable_ext_power(void);
|
||||
|
||||
/** Turn off the power of the external radio module
|
||||
*/
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
#include "valuemutex.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
bool init_mutex(ValueMutex* valuemutex, void* value, size_t size) {
|
||||
// mutex without name,
|
||||
// no attributes (unfortunately robust mutex is not supported by FreeRTOS),
|
||||
// with dynamic memory allocation
|
||||
valuemutex->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(valuemutex->mutex == NULL) return false;
|
||||
|
||||
valuemutex->value = value;
|
||||
valuemutex->size = size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool delete_mutex(ValueMutex* valuemutex) {
|
||||
if(furi_mutex_acquire(valuemutex->mutex, FuriWaitForever) == FuriStatusOk) {
|
||||
furi_mutex_free(valuemutex->mutex);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void* acquire_mutex(ValueMutex* valuemutex, uint32_t timeout) {
|
||||
if(furi_mutex_acquire(valuemutex->mutex, timeout) == FuriStatusOk) {
|
||||
return valuemutex->value;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool release_mutex(ValueMutex* valuemutex, const void* value) {
|
||||
if(value != valuemutex->value) return false;
|
||||
|
||||
if(furi_mutex_release(valuemutex->mutex) != FuriStatusOk) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout) {
|
||||
void* value = acquire_mutex(valuemutex, timeout);
|
||||
if(value == NULL || len > valuemutex->size) return false;
|
||||
memcpy(data, value, len > 0 ? len : valuemutex->size);
|
||||
if(!release_mutex(valuemutex, value)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool write_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout) {
|
||||
void* value = acquire_mutex(valuemutex, timeout);
|
||||
if(value == NULL || len > valuemutex->size) return false;
|
||||
memcpy(value, data, len > 0 ? len : valuemutex->size);
|
||||
if(!release_mutex(valuemutex, value)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "mutex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* == ValueMutex ==
|
||||
|
||||
* The most simple concept is ValueMutex.
|
||||
* It is wrapper around mutex and value pointer.
|
||||
* You can take and give mutex to work with value and read and write value.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
void* value;
|
||||
size_t size;
|
||||
FuriMutex* mutex;
|
||||
} ValueMutex;
|
||||
|
||||
/**
|
||||
* Creates ValueMutex.
|
||||
*/
|
||||
bool init_mutex(ValueMutex* valuemutex, void* value, size_t size);
|
||||
|
||||
/**
|
||||
* Free resources allocated by `init_mutex`.
|
||||
* This function doesn't free the memory occupied by `ValueMutex` itself.
|
||||
*/
|
||||
bool delete_mutex(ValueMutex* valuemutex);
|
||||
|
||||
/**
|
||||
* Call for work with data stored in mutex.
|
||||
* @return pointer to data if success, NULL otherwise.
|
||||
*/
|
||||
void* acquire_mutex(ValueMutex* valuemutex, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* Helper: infinitely wait for mutex
|
||||
*/
|
||||
static inline void* acquire_mutex_block(ValueMutex* valuemutex) {
|
||||
return acquire_mutex(valuemutex, FuriWaitForever);
|
||||
}
|
||||
|
||||
/**
|
||||
* With statement for value mutex, acts as lambda
|
||||
* @param name a resource name, const char*
|
||||
* @param function_body a (){} lambda declaration,
|
||||
* executed within you parent function context.
|
||||
*/
|
||||
#define with_value_mutex(value_mutex, function_body) \
|
||||
{ \
|
||||
void* p = acquire_mutex_block(value_mutex); \
|
||||
furi_check(p); \
|
||||
({ void __fn__ function_body __fn__; })(p); \
|
||||
release_mutex(value_mutex, p); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Release mutex after end of work with data.
|
||||
* Call `release_mutex` and pass ValueData instance and pointer to data.
|
||||
*/
|
||||
bool release_mutex(ValueMutex* valuemutex, const void* value);
|
||||
|
||||
/**
|
||||
* Instead of take-access-give sequence you can use `read_mutex` and `write_mutex` functions.
|
||||
* Both functions return true in case of success, false otherwise.
|
||||
*/
|
||||
bool read_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout);
|
||||
|
||||
bool write_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout);
|
||||
|
||||
inline static bool write_mutex_block(ValueMutex* valuemutex, void* data, size_t len) {
|
||||
return write_mutex(valuemutex, data, len, FuriWaitForever);
|
||||
}
|
||||
|
||||
inline static bool read_mutex_block(ValueMutex* valuemutex, void* data, size_t len) {
|
||||
return read_mutex(valuemutex, data, len, FuriWaitForever);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
Usage example
|
||||
|
||||
```C
|
||||
// MANIFEST
|
||||
// name="example-provider-app"
|
||||
// stack=128
|
||||
|
||||
void provider_app(void* _p) {
|
||||
// create record with mutex
|
||||
uint32_t example_value = 0;
|
||||
ValueMutex example_mutex;
|
||||
// call `init_mutex`.
|
||||
if(!init_mutex(&example_mutex, (void*)&example_value, sizeof(uint32_t))) {
|
||||
printf("critical error\n");
|
||||
flapp_exit(NULL);
|
||||
}
|
||||
|
||||
furi_record_create("provider/example", (void*)&example_mutex);
|
||||
|
||||
// we are ready to provide record to other apps
|
||||
flapp_ready();
|
||||
|
||||
// get value and increment it
|
||||
while(1) {
|
||||
uint32_t* value = acquire_mutex(&example_mutex, OsWaitForever);
|
||||
if(value != NULL) {
|
||||
value++;
|
||||
}
|
||||
release_mutex(&example_mutex, value);
|
||||
|
||||
furi_delay_ms(100);
|
||||
}
|
||||
}
|
||||
|
||||
// MANIFEST
|
||||
// name="example-consumer-app"
|
||||
// stack=128
|
||||
// require="example-provider-app"
|
||||
void consumer_app(void* _p) {
|
||||
// this app run after flapp_ready call in all requirements app
|
||||
|
||||
// open mutex value
|
||||
ValueMutex* counter_mutex = furi_record_open("provider/example");
|
||||
if(counter_mutex == NULL) {
|
||||
printf("critical error\n");
|
||||
flapp_exit(NULL);
|
||||
}
|
||||
|
||||
// continuously read value every 1s
|
||||
uint32_t counter;
|
||||
while(1) {
|
||||
if(read_mutex(counter_mutex, &counter, sizeof(counter), OsWaitForever)) {
|
||||
printf("counter value: %d\n", counter);
|
||||
}
|
||||
|
||||
furi_delay_ms(1000);
|
||||
}
|
||||
}
|
||||
```
|
||||
*/
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "core/semaphore.h"
|
||||
#include "core/thread.h"
|
||||
#include "core/timer.h"
|
||||
#include "core/valuemutex.h"
|
||||
#include "core/string.h"
|
||||
#include "core/stream_buffer.h"
|
||||
|
||||
|
||||
@@ -902,6 +902,32 @@ void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool nfc_worker_mf_get_b_key_from_sector_trailer(
|
||||
FuriHalNfcTxRxContext* tx_rx,
|
||||
uint16_t sector,
|
||||
uint64_t key,
|
||||
uint64_t* found_key) {
|
||||
// Some access conditions allow reading B key via A key
|
||||
|
||||
uint8_t block = mf_classic_get_sector_trailer_block_num_by_sector(sector);
|
||||
|
||||
Crypto1 crypto = {};
|
||||
MfClassicBlock block_tmp = {};
|
||||
MfClassicAuthContext auth_context = {.sector = sector, .key_a = MF_CLASSIC_NO_KEY, .key_b = 0};
|
||||
|
||||
furi_hal_nfc_sleep();
|
||||
|
||||
if(mf_classic_auth_attempt(tx_rx, &crypto, &auth_context, key)) {
|
||||
if(mf_classic_read_block(tx_rx, &crypto, block, &block_tmp)) {
|
||||
*found_key = nfc_util_bytes2num(&block_tmp.value[10], sizeof(uint8_t) * 6);
|
||||
|
||||
return *found_key;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void nfc_worker_mf_classic_key_attack(
|
||||
NfcWorker* nfc_worker,
|
||||
uint64_t key,
|
||||
@@ -947,6 +973,16 @@ static void nfc_worker_mf_classic_key_attack(
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||
|
||||
uint64_t found_key;
|
||||
if(nfc_worker_mf_get_b_key_from_sector_trailer(tx_rx, i, key, &found_key)) {
|
||||
FURI_LOG_D(TAG, "Found B key via reading sector %d", i);
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyB, found_key);
|
||||
|
||||
if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) {
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) {
|
||||
@@ -1038,6 +1074,19 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||
|
||||
uint64_t found_key;
|
||||
if(nfc_worker_mf_get_b_key_from_sector_trailer(
|
||||
&tx_rx, i, key, &found_key)) {
|
||||
FURI_LOG_D(TAG, "Found B key via reading sector %d", i);
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyB, found_key);
|
||||
|
||||
if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) {
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||
}
|
||||
|
||||
nfc_worker_mf_classic_key_attack(nfc_worker, found_key, &tx_rx, i + 1);
|
||||
}
|
||||
nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
|
||||
deactivated = true;
|
||||
}
|
||||
|
||||
@@ -541,6 +541,7 @@ bool mf_classic_authenticate_skip_activate(
|
||||
|
||||
bool mf_classic_auth_attempt(
|
||||
FuriHalNfcTxRxContext* tx_rx,
|
||||
Crypto1* crypto,
|
||||
MfClassicAuthContext* auth_ctx,
|
||||
uint64_t key) {
|
||||
furi_assert(tx_rx);
|
||||
@@ -549,15 +550,14 @@ bool mf_classic_auth_attempt(
|
||||
bool need_halt = (auth_ctx->key_a == MF_CLASSIC_NO_KEY) &&
|
||||
(auth_ctx->key_b == MF_CLASSIC_NO_KEY);
|
||||
|
||||
Crypto1 crypto;
|
||||
if(auth_ctx->key_a == MF_CLASSIC_NO_KEY) {
|
||||
// Try AUTH with key A
|
||||
if(mf_classic_auth(
|
||||
tx_rx,
|
||||
mf_classic_get_first_block_num_of_sector(auth_ctx->sector),
|
||||
mf_classic_get_sector_trailer_block_num_by_sector(auth_ctx->sector),
|
||||
key,
|
||||
MfClassicKeyA,
|
||||
&crypto,
|
||||
crypto,
|
||||
false,
|
||||
0)) {
|
||||
auth_ctx->key_a = key;
|
||||
@@ -573,10 +573,10 @@ bool mf_classic_auth_attempt(
|
||||
// Try AUTH with key B
|
||||
if(mf_classic_auth(
|
||||
tx_rx,
|
||||
mf_classic_get_first_block_num_of_sector(auth_ctx->sector),
|
||||
mf_classic_get_sector_trailer_block_num_by_sector(auth_ctx->sector),
|
||||
key,
|
||||
MfClassicKeyB,
|
||||
&crypto,
|
||||
crypto,
|
||||
false,
|
||||
0)) {
|
||||
auth_ctx->key_b = key;
|
||||
@@ -672,6 +672,9 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u
|
||||
do {
|
||||
if(blocks_read == total_blocks) break;
|
||||
if(!key_b_found) break;
|
||||
if(key_a_found) {
|
||||
furi_hal_nfc_sleep();
|
||||
}
|
||||
FURI_LOG_D(TAG, "Try to read blocks with key B");
|
||||
key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b));
|
||||
if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto, false, 0)) break;
|
||||
|
||||
@@ -175,6 +175,7 @@ bool mf_classic_authenticate_skip_activate(
|
||||
|
||||
bool mf_classic_auth_attempt(
|
||||
FuriHalNfcTxRxContext* tx_rx,
|
||||
Crypto1* crypto,
|
||||
MfClassicAuthContext* auth_ctx,
|
||||
uint64_t key);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user