mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-30 02:18:11 -07:00
fmt
This commit is contained in:
@@ -17,483 +17,516 @@
|
||||
#include <flipper_format/flipper_format.h>
|
||||
|
||||
typedef struct {
|
||||
int status;
|
||||
ViewPort* view_port;
|
||||
FuriString* up_button;
|
||||
FuriString* down_button;
|
||||
FuriString* left_button;
|
||||
FuriString* right_button;
|
||||
FuriString* ok_button;
|
||||
FuriString* back_button;
|
||||
FuriString* up_hold_button;
|
||||
FuriString* down_hold_button;
|
||||
FuriString* left_hold_button;
|
||||
FuriString* right_hold_button;
|
||||
FuriString* ok_hold_button;
|
||||
}IRApp;
|
||||
int status;
|
||||
ViewPort* view_port;
|
||||
FuriString* up_button;
|
||||
FuriString* down_button;
|
||||
FuriString* left_button;
|
||||
FuriString* right_button;
|
||||
FuriString* ok_button;
|
||||
FuriString* back_button;
|
||||
FuriString* up_hold_button;
|
||||
FuriString* down_hold_button;
|
||||
FuriString* left_hold_button;
|
||||
FuriString* right_hold_button;
|
||||
FuriString* ok_hold_button;
|
||||
} IRApp;
|
||||
|
||||
// Screen is 128x64 px
|
||||
static void app_draw_callback(Canvas* canvas, void* ctx) {
|
||||
// Show config is incorrect when cannot read the remote file
|
||||
// Showing button string in the screen, upper part is short press, lower part is long press
|
||||
IRApp* app = ctx;
|
||||
if(app->status){
|
||||
canvas_clear(canvas);
|
||||
view_port_set_orientation(app->view_port, ViewPortOrientationHorizontal);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 62, 5, AlignCenter, AlignTop, "Config is incorrect.");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignTop, "Please configure map.");
|
||||
canvas_draw_str_aligned(canvas, 62, 60, AlignCenter, AlignBottom, "Press Back to Exit.");
|
||||
}else{
|
||||
canvas_clear(canvas);
|
||||
view_port_set_orientation(app->view_port, ViewPortOrientationVertical);
|
||||
canvas_draw_icon(canvas, 1, 5, &I_ButtonUp_7x4);
|
||||
canvas_draw_icon(canvas, 1, 15, &I_ButtonDown_7x4);
|
||||
canvas_draw_icon(canvas, 2, 23, &I_ButtonLeft_4x7);
|
||||
canvas_draw_icon(canvas, 2, 33, &I_ButtonRight_4x7);
|
||||
canvas_draw_icon(canvas, 0, 42, &I_Ok_btn_9x9);
|
||||
canvas_draw_icon(canvas, 0, 53, &I_back_10px);
|
||||
// Show config is incorrect when cannot read the remote file
|
||||
// Showing button string in the screen, upper part is short press, lower part is long press
|
||||
IRApp* app = ctx;
|
||||
if(app->status) {
|
||||
canvas_clear(canvas);
|
||||
view_port_set_orientation(app->view_port, ViewPortOrientationHorizontal);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 62, 5, AlignCenter, AlignTop, "Config is incorrect.");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignTop, "Please configure map.");
|
||||
canvas_draw_str_aligned(canvas, 62, 60, AlignCenter, AlignBottom, "Press Back to Exit.");
|
||||
} else {
|
||||
canvas_clear(canvas);
|
||||
view_port_set_orientation(app->view_port, ViewPortOrientationVertical);
|
||||
canvas_draw_icon(canvas, 1, 5, &I_ButtonUp_7x4);
|
||||
canvas_draw_icon(canvas, 1, 15, &I_ButtonDown_7x4);
|
||||
canvas_draw_icon(canvas, 2, 23, &I_ButtonLeft_4x7);
|
||||
canvas_draw_icon(canvas, 2, 33, &I_ButtonRight_4x7);
|
||||
canvas_draw_icon(canvas, 0, 42, &I_Ok_btn_9x9);
|
||||
canvas_draw_icon(canvas, 0, 53, &I_back_10px);
|
||||
|
||||
//Labels
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
//Labels
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_draw_str_aligned(canvas, 32, 8,AlignCenter,AlignCenter, furi_string_get_cstr(app->up_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 18,AlignCenter,AlignCenter, furi_string_get_cstr(app->down_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 28,AlignCenter,AlignCenter, furi_string_get_cstr(app->left_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 38,AlignCenter,AlignCenter, furi_string_get_cstr(app->right_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 48,AlignCenter,AlignCenter, furi_string_get_cstr(app->ok_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 58, AlignCenter, AlignCenter, furi_string_get_cstr(app->back_button));
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 32, 8, AlignCenter, AlignCenter, furi_string_get_cstr(app->up_button));
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 32, 18, AlignCenter, AlignCenter, furi_string_get_cstr(app->down_button));
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 32, 28, AlignCenter, AlignCenter, furi_string_get_cstr(app->left_button));
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 32, 38, AlignCenter, AlignCenter, furi_string_get_cstr(app->right_button));
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 32, 48, AlignCenter, AlignCenter, furi_string_get_cstr(app->ok_button));
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 32, 58, AlignCenter, AlignCenter, furi_string_get_cstr(app->back_button));
|
||||
|
||||
canvas_draw_line(canvas, 0, 65, 64, 65);
|
||||
|
||||
canvas_draw_icon(canvas, 1, 70, &I_ButtonUp_7x4);
|
||||
canvas_draw_icon(canvas, 1, 80, &I_ButtonDown_7x4);
|
||||
canvas_draw_icon(canvas, 2, 88, &I_ButtonLeft_4x7);
|
||||
canvas_draw_icon(canvas, 2, 98, &I_ButtonRight_4x7);
|
||||
canvas_draw_icon(canvas, 0, 107, &I_Ok_btn_9x9);
|
||||
canvas_draw_icon(canvas, 0, 118, &I_back_10px);
|
||||
|
||||
canvas_draw_str_aligned(canvas, 32, 73,AlignCenter,AlignCenter, furi_string_get_cstr(app->up_hold_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 83,AlignCenter,AlignCenter, furi_string_get_cstr(app->down_hold_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 93,AlignCenter,AlignCenter, furi_string_get_cstr(app->left_hold_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 103,AlignCenter,AlignCenter, furi_string_get_cstr(app->right_hold_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 113,AlignCenter,AlignCenter, furi_string_get_cstr(app->ok_hold_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 123, AlignCenter, AlignCenter, "Exit App");
|
||||
}
|
||||
canvas_draw_line(canvas, 0, 65, 64, 65);
|
||||
|
||||
canvas_draw_icon(canvas, 1, 70, &I_ButtonUp_7x4);
|
||||
canvas_draw_icon(canvas, 1, 80, &I_ButtonDown_7x4);
|
||||
canvas_draw_icon(canvas, 2, 88, &I_ButtonLeft_4x7);
|
||||
canvas_draw_icon(canvas, 2, 98, &I_ButtonRight_4x7);
|
||||
canvas_draw_icon(canvas, 0, 107, &I_Ok_btn_9x9);
|
||||
canvas_draw_icon(canvas, 0, 118, &I_back_10px);
|
||||
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 32, 73, AlignCenter, AlignCenter, furi_string_get_cstr(app->up_hold_button));
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 32, 83, AlignCenter, AlignCenter, furi_string_get_cstr(app->down_hold_button));
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 32, 93, AlignCenter, AlignCenter, furi_string_get_cstr(app->left_hold_button));
|
||||
canvas_draw_str_aligned(
|
||||
canvas,
|
||||
32,
|
||||
103,
|
||||
AlignCenter,
|
||||
AlignCenter,
|
||||
furi_string_get_cstr(app->right_hold_button));
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 32, 113, AlignCenter, AlignCenter, furi_string_get_cstr(app->ok_hold_button));
|
||||
canvas_draw_str_aligned(canvas, 32, 123, AlignCenter, AlignCenter, "Exit App");
|
||||
}
|
||||
}
|
||||
|
||||
static void app_input_callback(InputEvent* input_event, void* ctx) {
|
||||
furi_assert(ctx);
|
||||
furi_assert(ctx);
|
||||
|
||||
FuriMessageQueue* event_queue = ctx;
|
||||
furi_message_queue_put(event_queue, input_event, FuriWaitForever);
|
||||
FuriMessageQueue* event_queue = ctx;
|
||||
furi_message_queue_put(event_queue, input_event, FuriWaitForever);
|
||||
}
|
||||
|
||||
int32_t infrared_remote_app(void* p) {
|
||||
UNUSED(p);
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
|
||||
UNUSED(p);
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
|
||||
|
||||
// App button string
|
||||
IRApp* app = malloc(sizeof(IRApp));
|
||||
app->up_button = furi_string_alloc();
|
||||
app->down_button = furi_string_alloc();
|
||||
app->left_button = furi_string_alloc();
|
||||
app->right_button = furi_string_alloc();
|
||||
app->ok_button = furi_string_alloc();
|
||||
app->back_button = furi_string_alloc();
|
||||
app->up_hold_button = furi_string_alloc();
|
||||
app->down_hold_button = furi_string_alloc();
|
||||
app->left_hold_button = furi_string_alloc();
|
||||
app->right_hold_button = furi_string_alloc();
|
||||
app->ok_hold_button = furi_string_alloc();
|
||||
app->view_port = view_port_alloc();
|
||||
// App button string
|
||||
IRApp* app = malloc(sizeof(IRApp));
|
||||
app->up_button = furi_string_alloc();
|
||||
app->down_button = furi_string_alloc();
|
||||
app->left_button = furi_string_alloc();
|
||||
app->right_button = furi_string_alloc();
|
||||
app->ok_button = furi_string_alloc();
|
||||
app->back_button = furi_string_alloc();
|
||||
app->up_hold_button = furi_string_alloc();
|
||||
app->down_hold_button = furi_string_alloc();
|
||||
app->left_hold_button = furi_string_alloc();
|
||||
app->right_hold_button = furi_string_alloc();
|
||||
app->ok_hold_button = furi_string_alloc();
|
||||
app->view_port = view_port_alloc();
|
||||
|
||||
// Configure view port
|
||||
view_port_draw_callback_set(app->view_port, app_draw_callback, app);
|
||||
view_port_input_callback_set(app->view_port, app_input_callback, event_queue);
|
||||
// Configure view port
|
||||
view_port_draw_callback_set(app->view_port, app_draw_callback, app);
|
||||
view_port_input_callback_set(app->view_port, app_input_callback, event_queue);
|
||||
|
||||
// Register view port in GUI
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, app->view_port, GuiLayerFullscreen);
|
||||
// Register view port in GUI
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, app->view_port, GuiLayerFullscreen);
|
||||
|
||||
InputEvent event;
|
||||
InputEvent event;
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
FlipperFormat* ff = flipper_format_file_alloc(storage);
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
FlipperFormat* ff = flipper_format_file_alloc(storage);
|
||||
|
||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
DialogsFileBrowserOptions browser_options;
|
||||
dialog_file_browser_set_basic_options(&browser_options, ".txt", &I_sub1_10px);
|
||||
FuriString* map_file = furi_string_alloc();
|
||||
furi_string_set(map_file,"/ext/infrared/ir_remote");
|
||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
DialogsFileBrowserOptions browser_options;
|
||||
dialog_file_browser_set_basic_options(&browser_options, ".txt", &I_sub1_10px);
|
||||
FuriString* map_file = furi_string_alloc();
|
||||
furi_string_set(map_file, "/ext/infrared/ir_remote");
|
||||
|
||||
bool res = dialog_file_browser_show(dialogs, map_file, map_file, &browser_options);
|
||||
bool res = dialog_file_browser_show(dialogs, map_file, map_file, &browser_options);
|
||||
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
|
||||
// if user didn't choose anything, free everything and exit
|
||||
if(!res){
|
||||
FURI_LOG_I(TAG, "exit");
|
||||
flipper_format_free(ff);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
// if user didn't choose anything, free everything and exit
|
||||
if(!res) {
|
||||
FURI_LOG_I(TAG, "exit");
|
||||
flipper_format_free(ff);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
furi_string_free(app->up_button);
|
||||
furi_string_free(app->down_button);
|
||||
furi_string_free(app->left_button);
|
||||
furi_string_free(app->right_button);
|
||||
furi_string_free(app->ok_button);
|
||||
furi_string_free(app->back_button);
|
||||
furi_string_free(app->up_hold_button);
|
||||
furi_string_free(app->down_hold_button);
|
||||
furi_string_free(app->left_hold_button);
|
||||
furi_string_free(app->right_hold_button);
|
||||
furi_string_free(app->ok_hold_button);
|
||||
furi_string_free(app->up_button);
|
||||
furi_string_free(app->down_button);
|
||||
furi_string_free(app->left_button);
|
||||
furi_string_free(app->right_button);
|
||||
furi_string_free(app->ok_button);
|
||||
furi_string_free(app->back_button);
|
||||
furi_string_free(app->up_hold_button);
|
||||
furi_string_free(app->down_hold_button);
|
||||
furi_string_free(app->left_hold_button);
|
||||
furi_string_free(app->right_hold_button);
|
||||
furi_string_free(app->ok_hold_button);
|
||||
|
||||
view_port_enabled_set(app->view_port, false);
|
||||
gui_remove_view_port(gui, app->view_port);
|
||||
view_port_free(app->view_port);
|
||||
free(app);
|
||||
furi_message_queue_free(event_queue);
|
||||
view_port_enabled_set(app->view_port, false);
|
||||
gui_remove_view_port(gui, app->view_port);
|
||||
view_port_free(app->view_port);
|
||||
free(app);
|
||||
furi_message_queue_free(event_queue);
|
||||
|
||||
furi_record_close(RECORD_GUI);
|
||||
return 255;
|
||||
}
|
||||
furi_record_close(RECORD_GUI);
|
||||
return 255;
|
||||
}
|
||||
|
||||
InfraredRemote* remote = infrared_remote_alloc();
|
||||
FuriString* remote_path = furi_string_alloc();
|
||||
|
||||
InfraredRemote* remote = infrared_remote_alloc();
|
||||
FuriString* remote_path = furi_string_alloc();
|
||||
InfraredSignal* up_signal = infrared_signal_alloc();
|
||||
InfraredSignal* down_signal = infrared_signal_alloc();
|
||||
InfraredSignal* left_signal = infrared_signal_alloc();
|
||||
InfraredSignal* right_signal = infrared_signal_alloc();
|
||||
InfraredSignal* ok_signal = infrared_signal_alloc();
|
||||
InfraredSignal* back_signal = infrared_signal_alloc();
|
||||
InfraredSignal* up_hold_signal = infrared_signal_alloc();
|
||||
InfraredSignal* down_hold_signal = infrared_signal_alloc();
|
||||
InfraredSignal* left_hold_signal = infrared_signal_alloc();
|
||||
InfraredSignal* right_hold_signal = infrared_signal_alloc();
|
||||
InfraredSignal* ok_hold_signal = infrared_signal_alloc();
|
||||
|
||||
InfraredSignal* up_signal = infrared_signal_alloc();
|
||||
InfraredSignal* down_signal = infrared_signal_alloc();
|
||||
InfraredSignal* left_signal = infrared_signal_alloc();
|
||||
InfraredSignal* right_signal = infrared_signal_alloc();
|
||||
InfraredSignal* ok_signal = infrared_signal_alloc();
|
||||
InfraredSignal* back_signal = infrared_signal_alloc();
|
||||
InfraredSignal* up_hold_signal = infrared_signal_alloc();
|
||||
InfraredSignal* down_hold_signal = infrared_signal_alloc();
|
||||
InfraredSignal* left_hold_signal = infrared_signal_alloc();
|
||||
InfraredSignal* right_hold_signal = infrared_signal_alloc();
|
||||
InfraredSignal* ok_hold_signal = infrared_signal_alloc();
|
||||
bool up_enabled = false;
|
||||
bool down_enabled = false;
|
||||
bool left_enabled = false;
|
||||
bool right_enabled = false;
|
||||
bool ok_enabled = false;
|
||||
bool back_enabled = false;
|
||||
bool up_hold_enabled = false;
|
||||
bool down_hold_enabled = false;
|
||||
bool left_hold_enabled = false;
|
||||
bool right_hold_enabled = false;
|
||||
bool ok_hold_enabled = false;
|
||||
|
||||
bool up_enabled = false;
|
||||
bool down_enabled = false;
|
||||
bool left_enabled = false;
|
||||
bool right_enabled = false;
|
||||
bool ok_enabled = false;
|
||||
bool back_enabled = false;
|
||||
bool up_hold_enabled = false;
|
||||
bool down_hold_enabled = false;
|
||||
bool left_hold_enabled = false;
|
||||
bool right_hold_enabled = false;
|
||||
bool ok_hold_enabled = false;
|
||||
if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(map_file))) {
|
||||
FURI_LOG_E(TAG, "Could not open MAP file %s", furi_string_get_cstr(map_file));
|
||||
app->status = 1;
|
||||
} else {
|
||||
//Filename Assignment/Check Start
|
||||
|
||||
if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(map_file))) {
|
||||
FURI_LOG_E(TAG, "Could not open MAP file %s",furi_string_get_cstr(map_file));
|
||||
app->status = 1;
|
||||
} else {
|
||||
//Filename Assignment/Check Start
|
||||
if(!flipper_format_read_string(ff, "REMOTE", remote_path)) {
|
||||
FURI_LOG_E(TAG, "Could not read REMOTE string");
|
||||
app->status = 1;
|
||||
} else {
|
||||
if(!infrared_remote_load(remote, remote_path)) {
|
||||
FURI_LOG_E(TAG, "Could not load ir file: %s", furi_string_get_cstr(remote_path));
|
||||
app->status = 1;
|
||||
} else {
|
||||
FURI_LOG_I(TAG, "Loaded REMOTE file: %s", furi_string_get_cstr(remote_path));
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "REMOTE", remote_path)) {
|
||||
FURI_LOG_E(TAG, "Could not read REMOTE string");
|
||||
app->status = 1;
|
||||
} else {
|
||||
if(!infrared_remote_load(remote, remote_path)){
|
||||
FURI_LOG_E(TAG, "Could not load ir file: %s",furi_string_get_cstr(remote_path));
|
||||
app->status = 1;
|
||||
}else{
|
||||
FURI_LOG_I(TAG, "Loaded REMOTE file: %s", furi_string_get_cstr(remote_path));
|
||||
}
|
||||
}
|
||||
//assign variables to values within map file
|
||||
//set missing filenames to N/A
|
||||
//assign button signals
|
||||
size_t index = 0;
|
||||
if(!flipper_format_read_string(ff, "UP", app->up_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read UP string");
|
||||
furi_string_set(app->up_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->up_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
up_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
up_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "DOWN", app->down_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read DOWN string");
|
||||
furi_string_set(app->down_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->down_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
down_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
down_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
//assign variables to values within map file
|
||||
//set missing filenames to N/A
|
||||
//assign button signals
|
||||
size_t index = 0;
|
||||
if(!flipper_format_read_string(ff, "UP", app->up_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read UP string");
|
||||
furi_string_set(app->up_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->up_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
up_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
up_enabled = true;
|
||||
}
|
||||
}
|
||||
if(!flipper_format_read_string(ff, "LEFT", app->left_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read LEFT string");
|
||||
furi_string_set(app->left_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->left_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
left_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
left_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "DOWN", app->down_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read DOWN string");
|
||||
furi_string_set(app->down_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->down_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
down_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
down_enabled = true;
|
||||
}
|
||||
}
|
||||
if(!flipper_format_read_string(ff, "RIGHT", app->right_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read RIGHT string");
|
||||
furi_string_set(app->right_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->right_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
right_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
right_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "LEFT", app->left_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read LEFT string");
|
||||
furi_string_set(app->left_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->left_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
left_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
left_enabled = true;
|
||||
}
|
||||
}
|
||||
if(!flipper_format_read_string(ff, "OK", app->ok_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read OK string");
|
||||
furi_string_set(app->ok_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->ok_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
ok_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
ok_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "RIGHT", app->right_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read RIGHT string");
|
||||
furi_string_set(app->right_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->right_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
right_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
right_enabled = true;
|
||||
}
|
||||
}
|
||||
if(!flipper_format_read_string(ff, "BACK", app->back_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read BACK string");
|
||||
furi_string_set(app->back_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->back_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
back_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
back_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "OK", app->ok_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read OK string");
|
||||
furi_string_set(app->ok_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->ok_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
ok_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
ok_enabled = true;
|
||||
}
|
||||
}
|
||||
if(!flipper_format_read_string(ff, "UPHOLD", app->up_hold_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read UPHOLD string");
|
||||
furi_string_set(app->up_hold_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->up_hold_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
up_hold_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
up_hold_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "BACK", app->back_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read BACK string");
|
||||
furi_string_set(app->back_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->back_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
back_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
back_enabled = true;
|
||||
}
|
||||
}
|
||||
if(!flipper_format_read_string(ff, "DOWNHOLD", app->down_hold_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read DOWNHOLD string");
|
||||
furi_string_set(app->down_hold_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->down_hold_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
down_hold_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
down_hold_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "UPHOLD", app->up_hold_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read UPHOLD string");
|
||||
furi_string_set(app->up_hold_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->up_hold_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
up_hold_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
up_hold_enabled = true;
|
||||
}
|
||||
}
|
||||
if(!flipper_format_read_string(ff, "LEFTHOLD", app->left_hold_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read LEFTHOLD string");
|
||||
furi_string_set(app->left_hold_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->left_hold_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
left_hold_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
left_hold_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "DOWNHOLD", app->down_hold_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read DOWNHOLD string");
|
||||
furi_string_set(app->down_hold_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->down_hold_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
down_hold_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
down_hold_enabled = true;
|
||||
}
|
||||
}
|
||||
if(!flipper_format_read_string(ff, "RIGHTHOLD", app->right_hold_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read RIGHTHOLD string");
|
||||
furi_string_set(app->right_hold_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->right_hold_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
right_hold_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
right_hold_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "LEFTHOLD", app->left_hold_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read LEFTHOLD string");
|
||||
furi_string_set(app->left_hold_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->left_hold_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
left_hold_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
left_hold_enabled = true;
|
||||
}
|
||||
}
|
||||
if(!flipper_format_read_string(ff, "OKHOLD", app->ok_hold_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read OKHOLD string");
|
||||
furi_string_set(app->ok_hold_button, "N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(
|
||||
remote, furi_string_get_cstr(app->ok_hold_button), &index)) {
|
||||
FURI_LOG_W(TAG, "Error");
|
||||
} else {
|
||||
ok_hold_signal =
|
||||
infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
ok_hold_enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(ff, "RIGHTHOLD", app->right_hold_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read RIGHTHOLD string");
|
||||
furi_string_set(app->right_hold_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->right_hold_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
right_hold_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
right_hold_enabled = true;
|
||||
}
|
||||
}
|
||||
furi_string_free(remote_path);
|
||||
|
||||
if(!flipper_format_read_string(ff, "OKHOLD", app->ok_hold_button)) {
|
||||
FURI_LOG_W(TAG, "Could not read OKHOLD string");
|
||||
furi_string_set(app->ok_hold_button,"N/A");
|
||||
} else {
|
||||
if(!infrared_remote_find_button_by_name(remote,furi_string_get_cstr(app->ok_hold_button),&index)){
|
||||
FURI_LOG_W(TAG,"Error");
|
||||
}else{
|
||||
ok_hold_signal = infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
|
||||
ok_hold_enabled = true;
|
||||
}
|
||||
}
|
||||
flipper_format_free(ff);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
}
|
||||
|
||||
furi_string_free(remote_path);
|
||||
|
||||
flipper_format_free(ff);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
bool running = true;
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
bool running = true;
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
if(app->status) {
|
||||
view_port_update(app->view_port);
|
||||
while(running) {
|
||||
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
|
||||
if(event.type == InputTypeShort) {
|
||||
switch(event.key) {
|
||||
case InputKeyBack:
|
||||
running = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
view_port_update(app->view_port);
|
||||
while(running) {
|
||||
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
|
||||
// short press signal
|
||||
if(event.type == InputTypeShort) {
|
||||
switch(event.key) {
|
||||
case InputKeyUp:
|
||||
if(up_enabled) {
|
||||
infrared_signal_transmit(up_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "up");
|
||||
}
|
||||
break;
|
||||
case InputKeyDown:
|
||||
if(down_enabled) {
|
||||
infrared_signal_transmit(down_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "down");
|
||||
}
|
||||
break;
|
||||
case InputKeyRight:
|
||||
if(right_enabled) {
|
||||
infrared_signal_transmit(right_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "right");
|
||||
}
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(left_enabled) {
|
||||
infrared_signal_transmit(left_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "left");
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(ok_enabled) {
|
||||
infrared_signal_transmit(ok_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "ok");
|
||||
}
|
||||
break;
|
||||
case InputKeyBack:
|
||||
if(back_enabled) {
|
||||
infrared_signal_transmit(back_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "back");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
// long press signal
|
||||
} else if(event.type == InputTypeLong) {
|
||||
switch(event.key) {
|
||||
case InputKeyUp:
|
||||
if(up_hold_enabled) {
|
||||
infrared_signal_transmit(up_hold_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "up!");
|
||||
}
|
||||
break;
|
||||
case InputKeyDown:
|
||||
if(down_hold_enabled) {
|
||||
infrared_signal_transmit(down_hold_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "down!");
|
||||
}
|
||||
break;
|
||||
case InputKeyRight:
|
||||
if(right_hold_enabled) {
|
||||
infrared_signal_transmit(right_hold_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "right!");
|
||||
}
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(left_hold_enabled) {
|
||||
infrared_signal_transmit(left_hold_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "left!");
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(ok_hold_enabled) {
|
||||
infrared_signal_transmit(ok_hold_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "ok!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
} else if(event.type == InputTypeRelease) {
|
||||
notification_message(notification, &sequence_blink_stop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(app->status){
|
||||
view_port_update(app->view_port);
|
||||
while(running) {
|
||||
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
|
||||
if(event.type == InputTypeShort) {
|
||||
switch(event.key) {
|
||||
case InputKeyBack:
|
||||
running = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
view_port_update(app->view_port);
|
||||
while(running) {
|
||||
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
|
||||
// short press signal
|
||||
if(event.type == InputTypeShort) {
|
||||
switch(event.key) {
|
||||
case InputKeyUp:
|
||||
if(up_enabled){
|
||||
infrared_signal_transmit(up_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "up");
|
||||
}
|
||||
break;
|
||||
case InputKeyDown:
|
||||
if(down_enabled){
|
||||
infrared_signal_transmit(down_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "down");
|
||||
}
|
||||
break;
|
||||
case InputKeyRight:
|
||||
if(right_enabled){
|
||||
infrared_signal_transmit(right_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "right");
|
||||
}
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(left_enabled){
|
||||
infrared_signal_transmit(left_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "left");
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(ok_enabled){
|
||||
infrared_signal_transmit(ok_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "ok");
|
||||
}
|
||||
break;
|
||||
case InputKeyBack:
|
||||
if(back_enabled){
|
||||
infrared_signal_transmit(back_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "back");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
// long press signal
|
||||
}else if (event.type == InputTypeLong){
|
||||
switch(event.key) {
|
||||
case InputKeyUp:
|
||||
if(up_hold_enabled){
|
||||
infrared_signal_transmit(up_hold_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "up!");
|
||||
}
|
||||
break;
|
||||
case InputKeyDown:
|
||||
if(down_hold_enabled){
|
||||
infrared_signal_transmit(down_hold_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "down!");
|
||||
}
|
||||
break;
|
||||
case InputKeyRight:
|
||||
if(right_hold_enabled){
|
||||
infrared_signal_transmit(right_hold_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "right!");
|
||||
}
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(left_hold_enabled){
|
||||
infrared_signal_transmit(left_hold_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "left!");
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(ok_hold_enabled){
|
||||
infrared_signal_transmit(ok_hold_signal);
|
||||
notification_message(notification, &sequence_blink_start_magenta);
|
||||
FURI_LOG_I(TAG, "ok!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
}else if(event.type == InputTypeRelease){
|
||||
notification_message(notification, &sequence_blink_stop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Free all things
|
||||
furi_string_free(app->up_button);
|
||||
furi_string_free(app->down_button);
|
||||
furi_string_free(app->left_button);
|
||||
furi_string_free(app->right_button);
|
||||
furi_string_free(app->ok_button);
|
||||
furi_string_free(app->back_button);
|
||||
furi_string_free(app->up_hold_button);
|
||||
furi_string_free(app->down_hold_button);
|
||||
furi_string_free(app->left_hold_button);
|
||||
furi_string_free(app->right_hold_button);
|
||||
furi_string_free(app->ok_hold_button);
|
||||
|
||||
// Free all things
|
||||
furi_string_free(app->up_button);
|
||||
furi_string_free(app->down_button);
|
||||
furi_string_free(app->left_button);
|
||||
furi_string_free(app->right_button);
|
||||
furi_string_free(app->ok_button);
|
||||
furi_string_free(app->back_button);
|
||||
furi_string_free(app->up_hold_button);
|
||||
furi_string_free(app->down_hold_button);
|
||||
furi_string_free(app->left_hold_button);
|
||||
furi_string_free(app->right_hold_button);
|
||||
furi_string_free(app->ok_hold_button);
|
||||
infrared_remote_free(remote);
|
||||
view_port_enabled_set(app->view_port, false);
|
||||
gui_remove_view_port(gui, app->view_port);
|
||||
view_port_free(app->view_port);
|
||||
free(app);
|
||||
furi_message_queue_free(event_queue);
|
||||
|
||||
infrared_remote_free(remote);
|
||||
view_port_enabled_set(app->view_port, false);
|
||||
gui_remove_view_port(gui, app->view_port);
|
||||
view_port_free(app->view_port);
|
||||
free(app);
|
||||
furi_message_queue_free(event_queue);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_record_close(RECORD_GUI);
|
||||
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_record_close(RECORD_GUI);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -3,49 +3,48 @@
|
||||
#include <cc1101.h>
|
||||
#include <furi_hal_subghz_configs.h>
|
||||
|
||||
|
||||
static const uint8_t furi_hal_subghz_preset_2fsk_dev9_5khz_async_regs[][2] = {
|
||||
/* GPIO GD0 */
|
||||
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
|
||||
/* GPIO GD0 */
|
||||
{CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input
|
||||
|
||||
/* Frequency Synthesizer Control */
|
||||
{CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
|
||||
/* Frequency Synthesizer Control */
|
||||
{CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
|
||||
|
||||
/* Packet engine */
|
||||
{CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
|
||||
{CC1101_PKTCTRL1, 0x04},
|
||||
/* Packet engine */
|
||||
{CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening
|
||||
{CC1101_PKTCTRL1, 0x04},
|
||||
|
||||
// // Modem Configuration
|
||||
{CC1101_MDMCFG0, 0x00},
|
||||
{CC1101_MDMCFG1, 0x02},
|
||||
{CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized)
|
||||
{CC1101_MDMCFG3, 0x83}, // Data rate is 4.79794 kBaud
|
||||
{CC1101_MDMCFG4, 0x67}, //Rx BW filter is 270.833333 kHz
|
||||
{CC1101_DEVIATN, 0x24}, //Deviation 9.5 kHz
|
||||
// // Modem Configuration
|
||||
{CC1101_MDMCFG0, 0x00},
|
||||
{CC1101_MDMCFG1, 0x02},
|
||||
{CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized)
|
||||
{CC1101_MDMCFG3, 0x83}, // Data rate is 4.79794 kBaud
|
||||
{CC1101_MDMCFG4, 0x67}, //Rx BW filter is 270.833333 kHz
|
||||
{CC1101_DEVIATN, 0x24}, //Deviation 9.5 kHz
|
||||
|
||||
/* Main Radio Control State Machine */
|
||||
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
|
||||
/* Main Radio Control State Machine */
|
||||
{CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
|
||||
|
||||
/* Frequency Offset Compensation Configuration */
|
||||
{CC1101_FOCCFG,
|
||||
0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
|
||||
/* Frequency Offset Compensation Configuration */
|
||||
{CC1101_FOCCFG,
|
||||
0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
|
||||
|
||||
/* Automatic Gain Control */
|
||||
{CC1101_AGCCTRL0,
|
||||
0x91}, //10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
|
||||
{CC1101_AGCCTRL1,
|
||||
0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
|
||||
{CC1101_AGCCTRL2, 0x07}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB
|
||||
/* Automatic Gain Control */
|
||||
{CC1101_AGCCTRL0,
|
||||
0x91}, //10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
|
||||
{CC1101_AGCCTRL1,
|
||||
0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
|
||||
{CC1101_AGCCTRL2, 0x07}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB
|
||||
|
||||
/* Wake on radio and timeouts control */
|
||||
{CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
|
||||
/* Wake on radio and timeouts control */
|
||||
{CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
|
||||
|
||||
/* Frontend configuration */
|
||||
{CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer
|
||||
{CC1101_FREND1, 0x56},
|
||||
/* Frontend configuration */
|
||||
{CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer
|
||||
{CC1101_FREND1, 0x56},
|
||||
|
||||
/* End */
|
||||
{0, 0},
|
||||
/* End */
|
||||
{0, 0},
|
||||
};
|
||||
//
|
||||
//
|
||||
@@ -100,12 +99,11 @@ static const uint8_t furi_hal_subghz_preset_2fsk_dev9_5khz_async_regs[][2] = {
|
||||
// {0, 0},
|
||||
//};
|
||||
|
||||
|
||||
void pocsag_hal_reset() {
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_idle();
|
||||
furi_hal_subghz_load_registers((uint8_t*)furi_hal_subghz_preset_2fsk_dev9_5khz_async_regs);
|
||||
furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable);
|
||||
// furi_hal_subghz_load_registers((uint8_t*)furi_hal_subghz_preset_ook_650khz_async_regs);
|
||||
// furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable);
|
||||
// furi_hal_subghz_load_registers((uint8_t*)furi_hal_subghz_preset_ook_650khz_async_regs);
|
||||
// furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable);
|
||||
}
|
||||
@@ -32,7 +32,7 @@ bool pocsag_tx_rx_worker_write(PocsagTxRxWorker* instance, uint8_t* data, size_t
|
||||
size_t stream_tx_free_byte = furi_stream_buffer_spaces_available(instance->stream_tx);
|
||||
if(size && (stream_tx_free_byte >= size)) {
|
||||
if(furi_stream_buffer_send(
|
||||
instance->stream_tx, data, size, POCSAG_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF) ==
|
||||
instance->stream_tx, data, size, POCSAG_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF) ==
|
||||
size) {
|
||||
ret = true;
|
||||
}
|
||||
@@ -51,9 +51,9 @@ size_t pocsag_tx_rx_worker_read(PocsagTxRxWorker* instance, uint8_t* data, size_
|
||||
}
|
||||
|
||||
void pocsag_tx_rx_worker_set_callback_have_read(
|
||||
PocsagTxRxWorker* instance,
|
||||
PocsagTxRxWorkerCallbackHaveRead callback,
|
||||
void* context) {
|
||||
PocsagTxRxWorker* instance,
|
||||
PocsagTxRxWorkerCallbackHaveRead callback,
|
||||
void* context) {
|
||||
furi_assert(instance);
|
||||
furi_assert(callback);
|
||||
furi_assert(context);
|
||||
@@ -82,10 +82,10 @@ bool pocsag_tx_rx_worker_rx(PocsagTxRxWorker* instance, uint8_t* data, uint8_t*
|
||||
|
||||
if(furi_hal_subghz_rx_pipe_not_empty()) {
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"RSSI: %03.1fdbm LQI: %d",
|
||||
(double)furi_hal_subghz_get_rssi(),
|
||||
furi_hal_subghz_get_lqi());
|
||||
TAG,
|
||||
"RSSI: %03.1fdbm LQI: %d",
|
||||
(double)furi_hal_subghz_get_rssi(),
|
||||
furi_hal_subghz_get_lqi());
|
||||
if(furi_hal_subghz_is_rx_data_crc_valid()) {
|
||||
furi_hal_subghz_read_packet(data, size);
|
||||
ret = true;
|
||||
@@ -130,9 +130,9 @@ static int32_t pocsag_tx_rx_worker_thread(void* context) {
|
||||
PocsagTxRxWorker* instance = context;
|
||||
FURI_LOG_I(TAG, "Worker start");
|
||||
|
||||
// furi_hal_subghz_reset();
|
||||
// furi_hal_subghz_idle();
|
||||
// furi_hal_subghz_load_preset(FuriHalSubGhzPresetGFSK9_99KbAsync);
|
||||
// furi_hal_subghz_reset();
|
||||
// furi_hal_subghz_idle();
|
||||
// furi_hal_subghz_load_preset(FuriHalSubGhzPresetGFSK9_99KbAsync);
|
||||
pocsag_hal_reset();
|
||||
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
@@ -152,15 +152,15 @@ static int32_t pocsag_tx_rx_worker_thread(void* context) {
|
||||
timeout_tx = 10; //20ms
|
||||
if(size_tx > POCSAG_TXRX_WORKER_MAX_TXRX_SIZE) {
|
||||
furi_stream_buffer_receive(
|
||||
instance->stream_tx,
|
||||
&data,
|
||||
POCSAG_TXRX_WORKER_MAX_TXRX_SIZE,
|
||||
POCSAG_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF);
|
||||
instance->stream_tx,
|
||||
&data,
|
||||
POCSAG_TXRX_WORKER_MAX_TXRX_SIZE,
|
||||
POCSAG_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF);
|
||||
pocsag_tx_rx_worker_tx(instance, data, POCSAG_TXRX_WORKER_MAX_TXRX_SIZE);
|
||||
} else {
|
||||
//todo checking that he managed to write all the data to the TX buffer
|
||||
furi_stream_buffer_receive(
|
||||
instance->stream_tx, &data, size_tx, POCSAG_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF);
|
||||
instance->stream_tx, &data, size_tx, POCSAG_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF);
|
||||
pocsag_tx_rx_worker_tx(instance, data, size_tx);
|
||||
}
|
||||
} else {
|
||||
@@ -173,10 +173,10 @@ static int32_t pocsag_tx_rx_worker_thread(void* context) {
|
||||
}
|
||||
//todo checking that he managed to write all the data to the RX buffer
|
||||
furi_stream_buffer_send(
|
||||
instance->stream_rx,
|
||||
&data,
|
||||
size_rx[0],
|
||||
POCSAG_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF);
|
||||
instance->stream_rx,
|
||||
&data,
|
||||
size_rx[0],
|
||||
POCSAG_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF);
|
||||
if(callback_rx) {
|
||||
instance->callback_have_read(instance->context_have_read);
|
||||
callback_rx = false;
|
||||
@@ -202,11 +202,11 @@ PocsagTxRxWorker* pocsag_tx_rx_worker_alloc() {
|
||||
PocsagTxRxWorker* instance = malloc(sizeof(PocsagTxRxWorker));
|
||||
|
||||
instance->thread =
|
||||
furi_thread_alloc_ex("PocsagTxRxWorker", 2048, pocsag_tx_rx_worker_thread, instance);
|
||||
furi_thread_alloc_ex("PocsagTxRxWorker", 2048, pocsag_tx_rx_worker_thread, instance);
|
||||
instance->stream_tx =
|
||||
furi_stream_buffer_alloc(sizeof(uint8_t) * POCSAG_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t));
|
||||
furi_stream_buffer_alloc(sizeof(uint8_t) * POCSAG_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t));
|
||||
instance->stream_rx =
|
||||
furi_stream_buffer_alloc(sizeof(uint8_t) * POCSAG_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t));
|
||||
furi_stream_buffer_alloc(sizeof(uint8_t) * POCSAG_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t));
|
||||
|
||||
instance->status = PocsagTxRxWorkerStatusIDLE;
|
||||
instance->worker_stoping = true;
|
||||
|
||||
@@ -48,9 +48,9 @@ size_t pocsag_tx_rx_worker_read(PocsagTxRxWorker* instance, uint8_t* data, size_
|
||||
* @param context
|
||||
*/
|
||||
void pocsag_tx_rx_worker_set_callback_have_read(
|
||||
PocsagTxRxWorker* instance,
|
||||
PocsagTxRxWorkerCallbackHaveRead callback,
|
||||
void* context);
|
||||
PocsagTxRxWorker* instance,
|
||||
PocsagTxRxWorkerCallbackHaveRead callback,
|
||||
void* context);
|
||||
|
||||
/**
|
||||
* Allocate SubGhzTxRxWorker
|
||||
|
||||
@@ -12,13 +12,11 @@ enum {
|
||||
#define FREQUENCY 433920000
|
||||
//439987500
|
||||
|
||||
|
||||
uint32_t pocsag_exit(void* context) {
|
||||
UNUSED(context);
|
||||
return VIEW_NONE;
|
||||
}
|
||||
|
||||
|
||||
void subghz_tx_rx_read_callback(void* context) {
|
||||
furi_assert(context);
|
||||
PocsagApp* app = context;
|
||||
@@ -30,47 +28,39 @@ void subghz_tx_rx_read_callback(void* context) {
|
||||
FURI_LOG_I(TAG, "%d", cnt);
|
||||
}
|
||||
|
||||
|
||||
void pocsag_submenu_callback(void* context, uint32_t index) {
|
||||
uint8_t buf[] = {
|
||||
1,2,3,4,5,6,7,8,9,0,
|
||||
1,2,3,4,5,6,7,8,9,0,
|
||||
1,2,3,4,5,6,7,8,9,0,
|
||||
1,2,3,4,5,6,7,8,9,0,
|
||||
1,2,3,4,5,6,7,8,9,0,
|
||||
1,2,3,4,5,6,7,8,9,0,
|
||||
1,2,3,4,5,6,7,8,9,0,
|
||||
1,2,3,4,5,6,7,8,9,0,
|
||||
1,2,3,4,5,6,7,8,9,0,
|
||||
1,2,3,4,5,6,7,8,9,0,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
|
||||
6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
|
||||
6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
|
||||
};
|
||||
furi_assert(context);
|
||||
PocsagApp* app = context;
|
||||
|
||||
switch (index) {
|
||||
case PocsagSubmenuIndexReceive:
|
||||
if (pocsag_tx_rx_worker_is_running(app->subghz_tx_rx))
|
||||
FURI_LOG_I(TAG, "Receiver is already running...");
|
||||
else {
|
||||
FURI_LOG_I(TAG, "Start receiver...");
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
pocsag_tx_rx_worker_start(app->subghz_tx_rx, FREQUENCY);
|
||||
}
|
||||
break;
|
||||
case PocsagSubmenuIndexStopReceive:
|
||||
FURI_LOG_I(TAG, "Stop receiver...");
|
||||
pocsag_tx_rx_worker_stop(app->subghz_tx_rx);
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
break;
|
||||
case PocsagSubmenuIndexTestSend:
|
||||
if (pocsag_tx_rx_worker_is_running(app->subghz_tx_rx)) {
|
||||
pocsag_tx_rx_worker_write(app->subghz_tx_rx, buf, sizeof(buf));
|
||||
}
|
||||
break;
|
||||
switch(index) {
|
||||
case PocsagSubmenuIndexReceive:
|
||||
if(pocsag_tx_rx_worker_is_running(app->subghz_tx_rx))
|
||||
FURI_LOG_I(TAG, "Receiver is already running...");
|
||||
else {
|
||||
FURI_LOG_I(TAG, "Start receiver...");
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
pocsag_tx_rx_worker_start(app->subghz_tx_rx, FREQUENCY);
|
||||
}
|
||||
break;
|
||||
case PocsagSubmenuIndexStopReceive:
|
||||
FURI_LOG_I(TAG, "Stop receiver...");
|
||||
pocsag_tx_rx_worker_stop(app->subghz_tx_rx);
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
break;
|
||||
case PocsagSubmenuIndexTestSend:
|
||||
if(pocsag_tx_rx_worker_is_running(app->subghz_tx_rx)) {
|
||||
pocsag_tx_rx_worker_write(app->subghz_tx_rx, buf, sizeof(buf));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PocsagApp* pocsag_app_alloc() {
|
||||
PocsagApp* app = malloc(sizeof(PocsagApp));
|
||||
|
||||
@@ -80,24 +70,26 @@ PocsagApp* pocsag_app_alloc() {
|
||||
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||
|
||||
app->submenu = submenu_alloc();
|
||||
submenu_add_item(app->submenu, "Receive", PocsagSubmenuIndexReceive, pocsag_submenu_callback, app);
|
||||
submenu_add_item(app->submenu, "Stop receive", PocsagSubmenuIndexStopReceive, pocsag_submenu_callback, app);
|
||||
submenu_add_item(app->submenu, "Test send", PocsagSubmenuIndexTestSend, pocsag_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
app->submenu, "Receive", PocsagSubmenuIndexReceive, pocsag_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
app->submenu, "Stop receive", PocsagSubmenuIndexStopReceive, pocsag_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
app->submenu, "Test send", PocsagSubmenuIndexTestSend, pocsag_submenu_callback, app);
|
||||
view_set_previous_callback(submenu_get_view(app->submenu), pocsag_exit);
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, PocsagViewSubmenu, submenu_get_view(app->submenu));
|
||||
app->view_dispatcher, PocsagViewSubmenu, submenu_get_view(app->submenu));
|
||||
|
||||
app->view_id = PocsagViewSubmenu;
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id);
|
||||
|
||||
app->subghz_tx_rx = pocsag_tx_rx_worker_alloc();
|
||||
pocsag_tx_rx_worker_set_callback_have_read(app->subghz_tx_rx, subghz_tx_rx_read_callback, app);
|
||||
// pocsag_hal_reset();
|
||||
// pocsag_hal_reset();
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
|
||||
void pocsag_app_free(PocsagApp* app) {
|
||||
furi_assert(app);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, PocsagViewSubmenu);
|
||||
@@ -113,7 +105,6 @@ void pocsag_app_free(PocsagApp* app) {
|
||||
free(app);
|
||||
}
|
||||
|
||||
|
||||
int32_t pocsag(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <gui/modules/submenu.h>
|
||||
#include "core/pocsag_tx_rx_worker.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
Gui* gui;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
@@ -19,7 +18,6 @@ typedef struct {
|
||||
PocsagTxRxWorker* subghz_tx_rx;
|
||||
} PocsagApp;
|
||||
|
||||
|
||||
enum {
|
||||
PocsagViewSubmenu,
|
||||
};
|
||||
@@ -41,63 +41,58 @@ typedef struct {
|
||||
|
||||
static void draw_callback(Canvas* canvas, void* ctx) {
|
||||
UNUSED(ctx);
|
||||
char temp_str[36];
|
||||
char temp_str[36];
|
||||
canvas_clear(canvas);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
switch (Count) {
|
||||
case -1:
|
||||
snprintf(temp_str,sizeof(temp_str),"Set: BULB %li sec",Time);
|
||||
break;
|
||||
case 0:
|
||||
snprintf(temp_str,sizeof(temp_str),"Set: infinite, %li sec",Time);
|
||||
break;
|
||||
default:
|
||||
snprintf(temp_str,sizeof(temp_str),"Set: %li frames, %li sec",Count,Time);
|
||||
}
|
||||
canvas_draw_str(canvas, 3, 15, temp_str);
|
||||
snprintf(temp_str,sizeof(temp_str),"Left: %li frames, %li sec",WorkCount,WorkTime);
|
||||
canvas_draw_str(canvas, 3, 35, temp_str);
|
||||
switch(Count) {
|
||||
case -1:
|
||||
snprintf(temp_str, sizeof(temp_str), "Set: BULB %li sec", Time);
|
||||
break;
|
||||
case 0:
|
||||
snprintf(temp_str, sizeof(temp_str), "Set: infinite, %li sec", Time);
|
||||
break;
|
||||
default:
|
||||
snprintf(temp_str, sizeof(temp_str), "Set: %li frames, %li sec", Count, Time);
|
||||
}
|
||||
canvas_draw_str(canvas, 3, 15, temp_str);
|
||||
snprintf(temp_str, sizeof(temp_str), "Left: %li frames, %li sec", WorkCount, WorkTime);
|
||||
canvas_draw_str(canvas, 3, 35, temp_str);
|
||||
|
||||
switch (Backlight) {
|
||||
case 1:
|
||||
canvas_draw_str(canvas, 13, 55, "ON");
|
||||
break;
|
||||
case 2:
|
||||
canvas_draw_str(canvas, 13, 55, "OFF");
|
||||
break;
|
||||
default:
|
||||
canvas_draw_str(canvas, 13, 55, "AUTO");
|
||||
}
|
||||
switch(Backlight) {
|
||||
case 1:
|
||||
canvas_draw_str(canvas, 13, 55, "ON");
|
||||
break;
|
||||
case 2:
|
||||
canvas_draw_str(canvas, 13, 55, "OFF");
|
||||
break;
|
||||
default:
|
||||
canvas_draw_str(canvas, 13, 55, "AUTO");
|
||||
}
|
||||
|
||||
//canvas_draw_icon(canvas, 90, 17, &I_ButtonUp_7x4);
|
||||
//canvas_draw_icon(canvas, 100, 17, &I_ButtonDown_7x4);
|
||||
//canvas_draw_icon(canvas, 27, 17, &I_ButtonLeftSmall_3x5);
|
||||
//canvas_draw_icon(canvas, 37, 17, &I_ButtonRightSmall_3x5);
|
||||
//canvas_draw_icon(canvas, 3, 48, &I_Pin_star_7x7);
|
||||
//canvas_draw_icon(canvas, 90, 17, &I_ButtonUp_7x4);
|
||||
//canvas_draw_icon(canvas, 100, 17, &I_ButtonDown_7x4);
|
||||
//canvas_draw_icon(canvas, 27, 17, &I_ButtonLeftSmall_3x5);
|
||||
//canvas_draw_icon(canvas, 37, 17, &I_ButtonRightSmall_3x5);
|
||||
//canvas_draw_icon(canvas, 3, 48, &I_Pin_star_7x7);
|
||||
|
||||
canvas_draw_icon(canvas, 85, 41, &I_ButtonUp_7x4);
|
||||
canvas_draw_icon(canvas, 85, 57, &I_ButtonDown_7x4);
|
||||
canvas_draw_icon(canvas, 59, 48, &I_ButtonLeft_4x7);
|
||||
canvas_draw_icon(canvas, 72, 48, &I_ButtonRight_4x7);
|
||||
canvas_draw_icon(canvas, 3, 48, &I_Pin_star_7x7);
|
||||
canvas_draw_icon(canvas, 85, 41, &I_ButtonUp_7x4);
|
||||
canvas_draw_icon(canvas, 85, 57, &I_ButtonDown_7x4);
|
||||
canvas_draw_icon(canvas, 59, 48, &I_ButtonLeft_4x7);
|
||||
canvas_draw_icon(canvas, 72, 48, &I_ButtonRight_4x7);
|
||||
canvas_draw_icon(canvas, 3, 48, &I_Pin_star_7x7);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 65, 55, "F");
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 85, 55, "S");
|
||||
|
||||
|
||||
canvas_draw_icon(canvas, 59, 48, &I_ButtonLeft_4x7);
|
||||
canvas_draw_icon(canvas, 72, 48, &I_ButtonRight_4x7);
|
||||
|
||||
|
||||
|
||||
|
||||
if(Work) {canvas_draw_icon(canvas, 106, 46, &I_loading_10px);}
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 65, 55, "F");
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 85, 55, "S");
|
||||
|
||||
canvas_draw_icon(canvas, 59, 48, &I_ButtonLeft_4x7);
|
||||
canvas_draw_icon(canvas, 72, 48, &I_ButtonRight_4x7);
|
||||
|
||||
if(Work) {
|
||||
canvas_draw_icon(canvas, 106, 46, &I_loading_10px);
|
||||
}
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, void* ctx) {
|
||||
@@ -119,7 +114,7 @@ static void timer_callback(FuriMessageQueue* event_queue) {
|
||||
|
||||
int32_t zeitraffer_app(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
|
||||
// Текущее событие типа кастомного типа ZeitrafferEvent
|
||||
ZeitrafferEvent event;
|
||||
// Очередь событий на 8 элементов размера ZeitrafferEvent
|
||||
@@ -137,9 +132,9 @@ int32_t zeitraffer_app(void* p) {
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
// Подключаем view port к GUI в полноэкранном режиме
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
// Конфигурим пины
|
||||
gpio_item_configure_all_pins(GpioModeOutputPushPull);
|
||||
|
||||
// Конфигурим пины
|
||||
gpio_item_configure_all_pins(GpioModeOutputPushPull);
|
||||
|
||||
// Создаем периодический таймер с коллбэком, куда в качестве
|
||||
// контекста будет передаваться наша очередь событий
|
||||
@@ -149,262 +144,277 @@ int32_t zeitraffer_app(void* p) {
|
||||
|
||||
// Включаем нотификации
|
||||
NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
|
||||
// Загружаем настройки
|
||||
FlipperFormat* load = flipper_format_file_alloc(storage);
|
||||
|
||||
do {
|
||||
|
||||
if(!flipper_format_file_open_existing(load, CONFIG_FILE_PATH)) {notification_message(notifications, &sequence_error); break;}
|
||||
if(!flipper_format_read_int32(load, "Time", &Time, 1)) {notification_message(notifications, &sequence_error); break;}
|
||||
if(!flipper_format_read_int32(load, "Count", &Count, 1)) {notification_message(notifications, &sequence_error); break;}
|
||||
if(!flipper_format_read_int32(load, "Backlight", &Backlight, 1)) {notification_message(notifications, &sequence_error); break;}
|
||||
if(!flipper_format_read_int32(load, "Delay", &Delay, 1)) {notification_message(notifications, &sequence_error); break;}
|
||||
notification_message(notifications, &sequence_success);
|
||||
|
||||
} while(0);
|
||||
|
||||
flipper_format_free(load);
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
|
||||
// Загружаем настройки
|
||||
FlipperFormat* load = flipper_format_file_alloc(storage);
|
||||
|
||||
do {
|
||||
if(!flipper_format_file_open_existing(load, CONFIG_FILE_PATH)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_read_int32(load, "Time", &Time, 1)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_read_int32(load, "Count", &Count, 1)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_read_int32(load, "Backlight", &Backlight, 1)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_read_int32(load, "Delay", &Delay, 1)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
notification_message(notifications, &sequence_success);
|
||||
|
||||
} while(0);
|
||||
|
||||
flipper_format_free(load);
|
||||
|
||||
// Бесконечный цикл обработки очереди событий
|
||||
while(1) {
|
||||
// Выбираем событие из очереди в переменную event (ждем бесконечно долго, если очередь пуста)
|
||||
// и проверяем, что у нас получилось это сделать
|
||||
furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk);
|
||||
|
||||
// Наше событие — это нажатие кнопки
|
||||
if(event.type == EventTypeInput) {
|
||||
if(event.input.type == InputTypeShort) { // Короткие нажатия
|
||||
|
||||
if(event.input.key == InputKeyBack) {
|
||||
if(Work) { // Если таймер запущен - нефиг мацать кнопки!
|
||||
notification_message(notifications, &sequence_error);
|
||||
}
|
||||
else {
|
||||
WorkCount = Count;
|
||||
WorkTime = 3;
|
||||
if (Count == 0) {
|
||||
InfiniteShot = true;
|
||||
WorkCount = 1;
|
||||
}
|
||||
else
|
||||
InfiniteShot = false;
|
||||
|
||||
notification_message(notifications, &sequence_success);
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyRight) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
}
|
||||
else {
|
||||
Count++;
|
||||
notification_message(notifications, &sequence_click);
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyLeft) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
}
|
||||
else {
|
||||
Count--;
|
||||
notification_message(notifications, &sequence_click);
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyUp) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
}
|
||||
else {
|
||||
Time++;
|
||||
notification_message(notifications, &sequence_click);
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyDown) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
}
|
||||
else {
|
||||
Time--;
|
||||
notification_message(notifications, &sequence_click);
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyOk) {
|
||||
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_click);
|
||||
furi_timer_stop(timer);
|
||||
Work = false;
|
||||
}
|
||||
else {
|
||||
furi_timer_start(timer, 1000);
|
||||
Work = true;
|
||||
|
||||
if (WorkCount == 0)
|
||||
WorkCount = Count;
|
||||
|
||||
if (WorkTime == 0)
|
||||
WorkTime = Delay;
|
||||
|
||||
if (Count == 0) {
|
||||
InfiniteShot = true;
|
||||
WorkCount = 1;
|
||||
}
|
||||
else
|
||||
InfiniteShot = false;
|
||||
|
||||
if (Count == -1) {
|
||||
gpio_item_set_pin(4, true);
|
||||
gpio_item_set_pin(5, true);
|
||||
Bulb = true;
|
||||
WorkCount = 1;
|
||||
WorkTime = Time;
|
||||
}
|
||||
else
|
||||
Bulb = false;
|
||||
|
||||
notification_message(notifications, &sequence_success);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(event.input.type == InputTypeLong) { // Длинные нажатия
|
||||
// Если нажата кнопка "назад", то выходим из цикла, а следовательно и из приложения
|
||||
if(event.input.key == InputKeyBack) {
|
||||
if(furi_timer_is_running(timer)) { // А если работает таймер - не выходим :D
|
||||
notification_message(notifications, &sequence_error);
|
||||
}
|
||||
else {
|
||||
notification_message(notifications, &sequence_click);
|
||||
gpio_item_set_all_pins(false);
|
||||
furi_timer_stop(timer);
|
||||
notification_message(notifications, &sequence_display_backlight_enforce_auto);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyOk) {
|
||||
// Нам ваша подсветка и нахой не нужна! Или нужна?
|
||||
Backlight++;
|
||||
if (Backlight > 2) Backlight = 0;
|
||||
}
|
||||
// Наше событие — это нажатие кнопки
|
||||
if(event.type == EventTypeInput) {
|
||||
if(event.input.type == InputTypeShort) { // Короткие нажатия
|
||||
|
||||
}
|
||||
if(event.input.key == InputKeyBack) {
|
||||
if(Work) { // Если таймер запущен - нефиг мацать кнопки!
|
||||
notification_message(notifications, &sequence_error);
|
||||
} else {
|
||||
WorkCount = Count;
|
||||
WorkTime = 3;
|
||||
if(Count == 0) {
|
||||
InfiniteShot = true;
|
||||
WorkCount = 1;
|
||||
} else
|
||||
InfiniteShot = false;
|
||||
|
||||
if(event.input.type == InputTypeRepeat) { // Зажатые кнопки
|
||||
if(event.input.key == InputKeyRight) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
}
|
||||
else {
|
||||
Count = Count+10;
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyLeft) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
}
|
||||
else {
|
||||
Count = Count-10;
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyUp) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
}
|
||||
else {
|
||||
Time = Time+10;
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyDown) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
}
|
||||
else {
|
||||
Time = Time-10;
|
||||
}
|
||||
}
|
||||
}
|
||||
notification_message(notifications, &sequence_success);
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyRight) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
} else {
|
||||
Count++;
|
||||
notification_message(notifications, &sequence_click);
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyLeft) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
} else {
|
||||
Count--;
|
||||
notification_message(notifications, &sequence_click);
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyUp) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
} else {
|
||||
Time++;
|
||||
notification_message(notifications, &sequence_click);
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyDown) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
} else {
|
||||
Time--;
|
||||
notification_message(notifications, &sequence_click);
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyOk) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_click);
|
||||
furi_timer_stop(timer);
|
||||
Work = false;
|
||||
} else {
|
||||
furi_timer_start(timer, 1000);
|
||||
Work = true;
|
||||
|
||||
if(WorkCount == 0) WorkCount = Count;
|
||||
|
||||
if(WorkTime == 0) WorkTime = Delay;
|
||||
|
||||
if(Count == 0) {
|
||||
InfiniteShot = true;
|
||||
WorkCount = 1;
|
||||
} else
|
||||
InfiniteShot = false;
|
||||
|
||||
if(Count == -1) {
|
||||
gpio_item_set_pin(4, true);
|
||||
gpio_item_set_pin(5, true);
|
||||
Bulb = true;
|
||||
WorkCount = 1;
|
||||
WorkTime = Time;
|
||||
} else
|
||||
Bulb = false;
|
||||
|
||||
notification_message(notifications, &sequence_success);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(event.input.type == InputTypeLong) { // Длинные нажатия
|
||||
// Если нажата кнопка "назад", то выходим из цикла, а следовательно и из приложения
|
||||
if(event.input.key == InputKeyBack) {
|
||||
if(furi_timer_is_running(timer)) { // А если работает таймер - не выходим :D
|
||||
notification_message(notifications, &sequence_error);
|
||||
} else {
|
||||
notification_message(notifications, &sequence_click);
|
||||
gpio_item_set_all_pins(false);
|
||||
furi_timer_stop(timer);
|
||||
notification_message(
|
||||
notifications, &sequence_display_backlight_enforce_auto);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyOk) {
|
||||
// Нам ваша подсветка и нахой не нужна! Или нужна?
|
||||
Backlight++;
|
||||
if(Backlight > 2) Backlight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(event.input.type == InputTypeRepeat) { // Зажатые кнопки
|
||||
if(event.input.key == InputKeyRight) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
} else {
|
||||
Count = Count + 10;
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyLeft) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
} else {
|
||||
Count = Count - 10;
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyUp) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
} else {
|
||||
Time = Time + 10;
|
||||
}
|
||||
}
|
||||
if(event.input.key == InputKeyDown) {
|
||||
if(furi_timer_is_running(timer)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
} else {
|
||||
Time = Time - 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Наше событие — это сработавший таймер
|
||||
else if(event.type == EventTypeTick) {
|
||||
|
||||
WorkTime--;
|
||||
|
||||
if( WorkTime < 1 ) { // фоткаем
|
||||
notification_message(notifications, &sequence_blink_white_100);
|
||||
if (Bulb) {
|
||||
gpio_item_set_all_pins(false); WorkCount = 0;
|
||||
}
|
||||
else {
|
||||
WorkCount--;
|
||||
view_port_update(view_port);
|
||||
notification_message(notifications, &sequence_click);
|
||||
// Дрыгаем ногами
|
||||
//gpio_item_set_all_pins(true);
|
||||
gpio_item_set_pin(4, true);
|
||||
gpio_item_set_pin(5, true);
|
||||
furi_delay_ms(400); // На короткие нажатия фотик плохо реагирует
|
||||
gpio_item_set_pin(4, false);
|
||||
gpio_item_set_pin(5, false);
|
||||
//gpio_item_set_all_pins(false);
|
||||
else if(event.type == EventTypeTick) {
|
||||
WorkTime--;
|
||||
|
||||
if (InfiniteShot) WorkCount++;
|
||||
|
||||
WorkTime = Time;
|
||||
view_port_update(view_port);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Отправляем нотификацию мигания синим светодиодом
|
||||
notification_message(notifications, &sequence_blink_blue_100);
|
||||
}
|
||||
|
||||
if( WorkCount < 1 ) { // закончили
|
||||
gpio_item_set_all_pins(false);
|
||||
furi_timer_stop(timer);
|
||||
notification_message(notifications, &sequence_audiovisual_alert);
|
||||
WorkTime = 3;
|
||||
WorkCount = 0;
|
||||
}
|
||||
|
||||
switch (Backlight) { // чо по подсветке?
|
||||
case 1:
|
||||
notification_message(notifications, &sequence_display_backlight_on);
|
||||
break;
|
||||
case 2:
|
||||
notification_message(notifications, &sequence_display_backlight_off);
|
||||
break;
|
||||
default:
|
||||
notification_message(notifications, &sequence_display_backlight_enforce_auto);
|
||||
}
|
||||
|
||||
if(WorkTime < 1) { // фоткаем
|
||||
notification_message(notifications, &sequence_blink_white_100);
|
||||
if(Bulb) {
|
||||
gpio_item_set_all_pins(false);
|
||||
WorkCount = 0;
|
||||
} else {
|
||||
WorkCount--;
|
||||
view_port_update(view_port);
|
||||
notification_message(notifications, &sequence_click);
|
||||
// Дрыгаем ногами
|
||||
//gpio_item_set_all_pins(true);
|
||||
gpio_item_set_pin(4, true);
|
||||
gpio_item_set_pin(5, true);
|
||||
furi_delay_ms(400); // На короткие нажатия фотик плохо реагирует
|
||||
gpio_item_set_pin(4, false);
|
||||
gpio_item_set_pin(5, false);
|
||||
//gpio_item_set_all_pins(false);
|
||||
|
||||
if(InfiniteShot) WorkCount++;
|
||||
|
||||
WorkTime = Time;
|
||||
view_port_update(view_port);
|
||||
}
|
||||
} else {
|
||||
// Отправляем нотификацию мигания синим светодиодом
|
||||
notification_message(notifications, &sequence_blink_blue_100);
|
||||
}
|
||||
|
||||
if(WorkCount < 1) { // закончили
|
||||
gpio_item_set_all_pins(false);
|
||||
furi_timer_stop(timer);
|
||||
notification_message(notifications, &sequence_audiovisual_alert);
|
||||
WorkTime = 3;
|
||||
WorkCount = 0;
|
||||
}
|
||||
|
||||
switch(Backlight) { // чо по подсветке?
|
||||
case 1:
|
||||
notification_message(notifications, &sequence_display_backlight_on);
|
||||
break;
|
||||
case 2:
|
||||
notification_message(notifications, &sequence_display_backlight_off);
|
||||
break;
|
||||
default:
|
||||
notification_message(notifications, &sequence_display_backlight_enforce_auto);
|
||||
}
|
||||
}
|
||||
if (Time < 1) Time = 1; // Не даём открутить таймер меньше единицы
|
||||
if (Count < -1) Count = 0; // А тут даём, бо 0 кадров это бесконечная съёмка, а -1 кадров - BULB
|
||||
}
|
||||
if(Time < 1) Time = 1; // Не даём открутить таймер меньше единицы
|
||||
if(Count < -1)
|
||||
Count = 0; // А тут даём, бо 0 кадров это бесконечная съёмка, а -1 кадров - BULB
|
||||
}
|
||||
|
||||
// Схороняем настройки
|
||||
FlipperFormat* save = flipper_format_file_alloc(storage);
|
||||
|
||||
// Схороняем настройки
|
||||
FlipperFormat* save = flipper_format_file_alloc(storage);
|
||||
do {
|
||||
if(!flipper_format_file_open_always(save, CONFIG_FILE_PATH)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_write_header_cstr(save, "Zeitraffer", 1)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_write_comment_cstr(
|
||||
save,
|
||||
"Zeitraffer app settings: № of frames, interval time, backlight type, Delay")) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_write_int32(save, "Time", &Time, 1)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_write_int32(save, "Count", &Count, 1)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_write_int32(save, "Backlight", &Backlight, 1)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_write_int32(save, "Delay", &Delay, 1)) {
|
||||
notification_message(notifications, &sequence_error);
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
} while(0);
|
||||
|
||||
if(!flipper_format_file_open_always(save, CONFIG_FILE_PATH)) {notification_message(notifications, &sequence_error); break;}
|
||||
if(!flipper_format_write_header_cstr(save, "Zeitraffer", 1)) {notification_message(notifications, &sequence_error); break;}
|
||||
if(!flipper_format_write_comment_cstr(save, "Zeitraffer app settings: № of frames, interval time, backlight type, Delay")) {notification_message(notifications, &sequence_error); break;}
|
||||
if(!flipper_format_write_int32(save, "Time", &Time, 1)) {notification_message(notifications, &sequence_error); break;}
|
||||
if(!flipper_format_write_int32(save, "Count", &Count, 1)) {notification_message(notifications, &sequence_error); break;}
|
||||
if(!flipper_format_write_int32(save, "Backlight", &Backlight, 1)) {notification_message(notifications, &sequence_error); break;}
|
||||
if(!flipper_format_write_int32(save, "Delay", &Delay, 1)) {notification_message(notifications, &sequence_error); break;}
|
||||
|
||||
} while(0);
|
||||
flipper_format_free(save);
|
||||
|
||||
flipper_format_free(save);
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
// Очищаем таймер
|
||||
furi_timer_free(timer);
|
||||
|
||||
Reference in New Issue
Block a user