Skorp subghz signal archive (#667)
* SubGhz: Add millis() furi, add subghz history struct * SubGhz: Fix subghz history * Gubghz: Fix code repeat history, add clean history * SubGhz: reading and adding keys to history * Gui: Renaming Sub 1-Ghz -> SubGhz * Archive: Renaming Sub 1-Ghz -> SubGhz * SubGhz: Add menu history, modified button for sending a signal, changed output of data about accepted protocol * Archive: Fix name subghz * SubGhz: Menu navigation * Assets: Add assets/SubGHz/icon.png * Assets: add new icons for subghz * SubGhz: Fix name Add manually scene * SubGhz: Fix load icon Read scene. rename encoder struct, rename protocol function load from file, add load raw data protocol, add info pleasant signals all protocol * SubGhz: fix memory leak * SubGhz: change of receiving frequency for read scene * SubGhz: Add save/load frequency and preset, add automatic configuration of transmit/receive to the desired frequency and modulation, add button "save" config scene * SubGhz: Fix frequency and preset, fix frequency add manualli scene, fix re-executing the parser * Furi-hal-subghz: add 2-FSK config, fix ook config 650KHz BW Tx filter * Fix formatting and release build * SubGhz: Delete read scene * SubGhz: Fix frequency add manualli scene, refactoring code * SubGhz: 2 profiles for OOK, fix broken build. * SubGhz: Add passing static codes from read scene, add notification read scene, refactoring code * SubGhz: fix assert on worker double stop. Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
@@ -58,7 +58,7 @@ void subghz_analyze_draw(Canvas* canvas, SubghzAnalyzeModel* model) {
|
||||
|
||||
default:
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
elements_multiline_text(canvas, 0, 20, string_get_cstr(model->text));
|
||||
elements_multiline_text(canvas, 0, 18, string_get_cstr(model->text));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ void subghz_analyze_enter(void* context) {
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_idle();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
|
||||
with_view_model(
|
||||
subghz_analyze->view, (SubghzAnalyzeModel * model) {
|
||||
|
@@ -1,25 +1,55 @@
|
||||
#include "subghz_receiver.h"
|
||||
#include "../subghz_i.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
#include <furi-hal.h>
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
#include <notification/notification-messages.h>
|
||||
#include <lib/subghz/protocols/subghz_protocol_princeton.h>
|
||||
|
||||
#include <assets_icons.h>
|
||||
|
||||
#define FRAME_HEIGHT 12
|
||||
#define MAX_LEN_PX 100
|
||||
#define MENU_ITEMS 4
|
||||
|
||||
typedef enum {
|
||||
ReceiverSceneStart,
|
||||
ReceiverSceneMain,
|
||||
ReceiverSceneConfig,
|
||||
ReceiverSceneInfo,
|
||||
} SubghzReceiverScene;
|
||||
|
||||
static const Icon* ReceiverItemIcons[] = {
|
||||
[TYPE_PROTOCOL_UNKNOWN] = &I_quest_7x8,
|
||||
[TYPE_PROTOCOL_STATIC] = &I_unlock_7x8,
|
||||
[TYPE_PROTOCOL_DYNAMIC] = &I_lock_7x8,
|
||||
};
|
||||
|
||||
struct SubghzReceiver {
|
||||
View* view;
|
||||
SubghzReceiverCallback callback;
|
||||
void* context;
|
||||
SubGhzWorker* worker;
|
||||
SubGhzProtocol* protocol;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
string_t text;
|
||||
uint16_t scene;
|
||||
SubGhzProtocolCommon* protocol;
|
||||
SubGhzProtocolCommon* protocol_result;
|
||||
SubGhzHistory* history;
|
||||
uint8_t frequency;
|
||||
uint8_t temp_frequency;
|
||||
uint32_t real_frequency;
|
||||
|
||||
uint8_t tab_idx;
|
||||
uint8_t menu_idx;
|
||||
uint16_t idx;
|
||||
uint16_t list_offset;
|
||||
uint16_t history_item;
|
||||
bool menu;
|
||||
} SubghzReceiverModel;
|
||||
|
||||
void subghz_receiver_set_callback(
|
||||
@@ -32,50 +62,323 @@ void subghz_receiver_set_callback(
|
||||
subghz_receiver->context = context;
|
||||
}
|
||||
|
||||
void subghz_receiver_set_protocol(SubghzReceiver* subghz_receiver, SubGhzProtocolCommon* protocol) {
|
||||
void subghz_receiver_set_protocol(
|
||||
SubghzReceiver* subghz_receiver,
|
||||
SubGhzProtocolCommon* protocol_result,
|
||||
SubGhzProtocol* protocol) {
|
||||
furi_assert(subghz_receiver);
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
model->protocol = protocol;
|
||||
model->protocol_result = protocol_result;
|
||||
return true;
|
||||
});
|
||||
subghz_receiver->protocol = protocol;
|
||||
}
|
||||
|
||||
SubGhzProtocolCommon* subghz_receiver_get_protocol(SubghzReceiver* subghz_receiver) {
|
||||
furi_assert(subghz_receiver);
|
||||
SubGhzProtocolCommon* result = NULL;
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
result = model->protocol_result;
|
||||
return false;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void subghz_receiver_set_worker(SubghzReceiver* subghz_receiver, SubGhzWorker* worker) {
|
||||
furi_assert(subghz_receiver);
|
||||
subghz_receiver->worker = worker;
|
||||
}
|
||||
|
||||
static void subghz_receiver_update_offset(SubghzReceiver* subghz_receiver) {
|
||||
furi_assert(subghz_receiver);
|
||||
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
size_t history_item = model->history_item;
|
||||
uint16_t bounds = history_item > 3 ? 2 : history_item;
|
||||
|
||||
if(history_item > 3 && model->idx >= history_item - 1) {
|
||||
model->list_offset = model->idx - 3;
|
||||
} else if(model->list_offset < model->idx - bounds) {
|
||||
model->list_offset = CLAMP(model->list_offset + 1, history_item - bounds, 0);
|
||||
} else if(model->list_offset > model->idx - bounds) {
|
||||
model->list_offset = CLAMP(model->idx - 1, history_item - bounds, 0);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
static void subghz_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_draw_box(canvas, 0, 0 + idx * FRAME_HEIGHT, scrollbar ? 122 : 127, FRAME_HEIGHT);
|
||||
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_dot(canvas, 0, 0 + idx * FRAME_HEIGHT);
|
||||
canvas_draw_dot(canvas, 1, 0 + idx * FRAME_HEIGHT);
|
||||
canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 1);
|
||||
|
||||
canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 11);
|
||||
canvas_draw_dot(canvas, scrollbar ? 121 : 126, 0 + idx * FRAME_HEIGHT);
|
||||
canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11);
|
||||
}
|
||||
|
||||
void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) {
|
||||
bool scrollbar = model->history_item > 4;
|
||||
string_t str_buff;
|
||||
char buffer[64];
|
||||
string_init(str_buff);
|
||||
|
||||
canvas_clear(canvas);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
elements_multiline_text(canvas, 0, 10, string_get_cstr(model->text));
|
||||
|
||||
elements_button_left(canvas, "Back");
|
||||
if(model->protocol && model->protocol->to_save_string &&
|
||||
strcmp(model->protocol->name, "KeeLoq")) {
|
||||
elements_button_right(canvas, "Save");
|
||||
switch(model->scene) {
|
||||
case ReceiverSceneMain:
|
||||
for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) {
|
||||
size_t idx = CLAMP(i + model->list_offset, model->history_item, 0);
|
||||
subghz_history_get_text_item_menu(model->history, str_buff, idx);
|
||||
elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX);
|
||||
if(model->idx == idx) {
|
||||
subghz_receiver_draw_frame(canvas, i, scrollbar);
|
||||
} else {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
}
|
||||
canvas_draw_icon(
|
||||
canvas,
|
||||
1,
|
||||
2 + i * FRAME_HEIGHT,
|
||||
ReceiverItemIcons[subghz_history_get_type_protocol(model->history, idx)]);
|
||||
canvas_draw_str(canvas, 15, 9 + i * FRAME_HEIGHT, string_get_cstr(str_buff));
|
||||
string_clean(str_buff);
|
||||
}
|
||||
if(scrollbar) {
|
||||
elements_scrollbar_pos(canvas, 126, 0, 49, model->idx, model->history_item);
|
||||
}
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"%03ld.%03ld OOK",
|
||||
model->real_frequency / 1000000 % 1000,
|
||||
model->real_frequency / 1000 % 1000);
|
||||
canvas_draw_str(canvas, 60, 61, buffer);
|
||||
elements_button_left(canvas, "Config");
|
||||
break;
|
||||
|
||||
case ReceiverSceneStart:
|
||||
canvas_draw_icon(canvas, 0, 0, &I_RFIDDolphinReceive_97x61);
|
||||
canvas_invert_color(canvas);
|
||||
canvas_draw_box(canvas, 80, 2, 20, 20);
|
||||
canvas_invert_color(canvas);
|
||||
canvas_draw_icon(canvas, 75, 8, &I_sub1_10px);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 63, 40, "Scanning...");
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"%03ld.%03ld OOK",
|
||||
model->real_frequency / 1000000 % 1000,
|
||||
model->real_frequency / 1000 % 1000);
|
||||
canvas_draw_str(canvas, 60, 61, buffer);
|
||||
elements_button_left(canvas, "Config");
|
||||
break;
|
||||
|
||||
case ReceiverSceneConfig:
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"Frequency: < %03ld.%03ldMHz >",
|
||||
model->real_frequency / 1000000 % 1000,
|
||||
model->real_frequency / 1000 % 1000);
|
||||
canvas_draw_str(canvas, 0, 8, buffer);
|
||||
elements_button_center(canvas, "Save");
|
||||
break;
|
||||
|
||||
case ReceiverSceneInfo:
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
elements_multiline_text(canvas, 0, 8, string_get_cstr(model->text));
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"%03ld.%03ld",
|
||||
subghz_history_get_frequency(model->history, model->idx) / 1000000 % 1000,
|
||||
subghz_history_get_frequency(model->history, model->idx) / 1000 % 1000);
|
||||
canvas_draw_str(canvas, 90, 8, buffer);
|
||||
if(model->protocol_result && model->protocol_result->to_save_string &&
|
||||
strcmp(model->protocol_result->name, "KeeLoq")) {
|
||||
elements_button_right(canvas, "Save");
|
||||
elements_button_center(canvas, "Send");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
string_clear(str_buff);
|
||||
}
|
||||
|
||||
bool subghz_receiver_input(InputEvent* event, void* context) {
|
||||
furi_assert(context);
|
||||
|
||||
uint8_t scene = 0;
|
||||
SubghzReceiver* subghz_receiver = context;
|
||||
|
||||
if(event->type != InputTypeShort) return false;
|
||||
|
||||
bool can_be_saved = false;
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
can_be_saved =
|
||||
(model->protocol && model->protocol->to_save_string &&
|
||||
strcmp(model->protocol->name, "KeeLoq"));
|
||||
scene = model->scene;
|
||||
return false;
|
||||
});
|
||||
|
||||
if(event->key == InputKeyBack) {
|
||||
return false;
|
||||
} else if(event->key == InputKeyLeft) {
|
||||
subghz_receiver->callback(SubghzReceverEventBack, subghz_receiver->context);
|
||||
} else if(can_be_saved && event->key == InputKeyRight) {
|
||||
subghz_receiver->callback(SubghzReceverEventSave, subghz_receiver->context);
|
||||
if(scene != ReceiverSceneInfo && event->type != InputTypeShort) return false;
|
||||
|
||||
bool can_be_saved = false;
|
||||
|
||||
switch(scene) {
|
||||
case ReceiverSceneMain:
|
||||
if(event->key == InputKeyBack) {
|
||||
return false;
|
||||
} else if(event->key == InputKeyUp) {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
if(model->idx != 0) model->idx--;
|
||||
return true;
|
||||
});
|
||||
} else if(event->key == InputKeyDown) {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
if(model->idx != subghz_history_get_item(model->history) - 1) model->idx++;
|
||||
return true;
|
||||
});
|
||||
} else if(event->key == InputKeyLeft) {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
model->scene = ReceiverSceneConfig;
|
||||
model->temp_frequency = model->frequency;
|
||||
return true;
|
||||
});
|
||||
subghz_receiver->callback(SubghzReceverEventConfig, subghz_receiver->context);
|
||||
} else if(event->key == InputKeyOk) {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
string_clean(model->text);
|
||||
model->protocol_result = subghz_protocol_get_by_name(
|
||||
subghz_receiver->protocol,
|
||||
subghz_history_get_name(model->history, model->idx));
|
||||
if(model->protocol_result->to_load_protocol != NULL) {
|
||||
model->protocol_result->to_load_protocol(
|
||||
model->protocol_result,
|
||||
subghz_history_get_raw_data(model->history, model->idx));
|
||||
model->protocol_result->to_string(model->protocol_result, model->text);
|
||||
model->scene = ReceiverSceneInfo;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case ReceiverSceneInfo:
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
can_be_saved =
|
||||
(model->protocol_result && model->protocol_result->to_save_string &&
|
||||
strcmp(model->protocol_result->name, "KeeLoq"));
|
||||
return false;
|
||||
});
|
||||
if(event->key == InputKeyBack && event->type == InputTypeShort) {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
subghz_rx_end(subghz_receiver->worker);
|
||||
model->real_frequency =
|
||||
subghz_rx(subghz_receiver->worker, subghz_frequencies[model->frequency]);
|
||||
model->scene = ReceiverSceneMain;
|
||||
return true;
|
||||
});
|
||||
subghz_receiver->callback(SubghzReceverEventMain, subghz_receiver->context);
|
||||
} else if(can_be_saved && event->key == InputKeyRight) {
|
||||
subghz_receiver->callback(SubghzReceverEventSave, subghz_receiver->context);
|
||||
return false;
|
||||
} else if(can_be_saved && event->key == InputKeyOk && event->type == InputTypePress) {
|
||||
subghz_rx_end(subghz_receiver->worker);
|
||||
subghz_receiver->callback(SubghzReceverEventSendStart, subghz_receiver->context);
|
||||
return true;
|
||||
} else if(can_be_saved && event->key == InputKeyOk && event->type == InputTypeRelease) {
|
||||
subghz_receiver->callback(SubghzReceverEventSendStop, subghz_receiver->context);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ReceiverSceneConfig:
|
||||
if(event->key == InputKeyBack) {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
model->frequency = model->temp_frequency;
|
||||
model->real_frequency = subghz_frequencies[model->frequency];
|
||||
if(subghz_history_get_item(model->history) == 0) {
|
||||
model->scene = ReceiverSceneStart;
|
||||
} else {
|
||||
model->scene = ReceiverSceneMain;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
subghz_receiver->callback(SubghzReceverEventMain, subghz_receiver->context);
|
||||
} else if(event->key == InputKeyOk) {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
subghz_rx_end(subghz_receiver->worker);
|
||||
model->real_frequency =
|
||||
subghz_rx(subghz_receiver->worker, subghz_frequencies[model->frequency]);
|
||||
if(subghz_history_get_item(model->history) == 0) {
|
||||
model->scene = ReceiverSceneStart;
|
||||
} else {
|
||||
model->scene = ReceiverSceneMain;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
subghz_receiver->callback(SubghzReceverEventMain, subghz_receiver->context);
|
||||
} else {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
bool model_updated = false;
|
||||
|
||||
if(event->key == InputKeyLeft) {
|
||||
if(model->frequency > 0) model->frequency--;
|
||||
model_updated = true;
|
||||
} else if(event->key == InputKeyRight) {
|
||||
if(model->frequency < subghz_frequencies_count - 1) model->frequency++;
|
||||
model_updated = true;
|
||||
}
|
||||
if(model_updated) {
|
||||
model->real_frequency = subghz_frequencies[model->frequency];
|
||||
}
|
||||
return model_updated;
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case ReceiverSceneStart:
|
||||
if(event->key == InputKeyBack) {
|
||||
return false;
|
||||
} else if(event->key == InputKeyLeft) {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
model->temp_frequency = model->frequency;
|
||||
model->scene = ReceiverSceneConfig;
|
||||
return true;
|
||||
});
|
||||
subghz_receiver->callback(SubghzReceverEventConfig, subghz_receiver->context);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
subghz_receiver_update_offset(subghz_receiver);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,19 +389,53 @@ void subghz_receiver_text_callback(string_t text, void* context) {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
string_set(model->text, text);
|
||||
model->scene = 0;
|
||||
model->scene = ReceiverSceneMain;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void subghz_receiver_protocol_callback(SubGhzProtocolCommon* parser, void* context) {
|
||||
furi_assert(context);
|
||||
SubghzReceiver* subghz_receiver = context;
|
||||
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
model->protocol_result = parser;
|
||||
subghz_history_set_frequency_preset(
|
||||
model->history,
|
||||
model->history_item,
|
||||
model->real_frequency,
|
||||
FuriHalSubGhzPresetOok650Async);
|
||||
subghz_history_add_to_history(model->history, parser);
|
||||
|
||||
model->history_item = subghz_history_get_item(model->history);
|
||||
model->scene = ReceiverSceneMain;
|
||||
return true;
|
||||
});
|
||||
subghz_protocol_reset(subghz_receiver->protocol);
|
||||
subghz_receiver_update_offset(subghz_receiver);
|
||||
}
|
||||
|
||||
void subghz_receiver_enter(void* context) {
|
||||
furi_assert(context);
|
||||
SubghzReceiver* subghz_receiver = context;
|
||||
//Start CC1101 Rx
|
||||
subghz_begin(FuriHalSubGhzPresetOok650Async);
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
model->protocol->to_string(model->protocol, model->text);
|
||||
subghz_rx_end(subghz_receiver->worker);
|
||||
model->frequency = subghz_frequencies_433_92;
|
||||
model->real_frequency =
|
||||
subghz_rx(subghz_receiver->worker, subghz_frequencies[model->frequency]);
|
||||
if(subghz_history_get_item(model->history) == 0) {
|
||||
model->scene = ReceiverSceneStart;
|
||||
} else {
|
||||
model->scene = ReceiverSceneMain;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
subghz_protocol_enable_dump(
|
||||
subghz_receiver->protocol, subghz_receiver_protocol_callback, subghz_receiver);
|
||||
}
|
||||
|
||||
void subghz_receiver_exit(void* context) {
|
||||
@@ -109,6 +446,9 @@ void subghz_receiver_exit(void* context) {
|
||||
string_clean(model->text);
|
||||
return true;
|
||||
});
|
||||
// Stop CC1101 Rx
|
||||
subghz_rx_end(subghz_receiver->worker);
|
||||
subghz_sleep();
|
||||
}
|
||||
|
||||
SubghzReceiver* subghz_receiver_alloc() {
|
||||
@@ -126,6 +466,7 @@ SubghzReceiver* subghz_receiver_alloc() {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
string_init(model->text);
|
||||
model->history = subghz_history_alloc();
|
||||
return true;
|
||||
});
|
||||
return subghz_receiver;
|
||||
@@ -137,7 +478,8 @@ void subghz_receiver_free(SubghzReceiver* subghz_receiver) {
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
string_clear(model->text);
|
||||
return true;
|
||||
subghz_history_free(model->history);
|
||||
return false;
|
||||
});
|
||||
view_free(subghz_receiver->view);
|
||||
free(subghz_receiver);
|
||||
@@ -147,3 +489,44 @@ View* subghz_receiver_get_view(SubghzReceiver* subghz_receiver) {
|
||||
furi_assert(subghz_receiver);
|
||||
return subghz_receiver->view;
|
||||
}
|
||||
|
||||
uint32_t subghz_receiver_get_frequency(SubghzReceiver* subghz_receiver) {
|
||||
furi_assert(subghz_receiver);
|
||||
uint32_t frequency;
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
frequency = subghz_history_get_frequency(model->history, model->idx);
|
||||
return false;
|
||||
});
|
||||
return frequency;
|
||||
}
|
||||
|
||||
FuriHalSubGhzPreset subghz_receiver_get_preset(SubghzReceiver* subghz_receiver) {
|
||||
furi_assert(subghz_receiver);
|
||||
FuriHalSubGhzPreset preset;
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
preset = subghz_history_get_preset(model->history, model->idx);
|
||||
return false;
|
||||
});
|
||||
return preset;
|
||||
}
|
||||
|
||||
void subghz_receiver_frequency_preset_to_str(SubghzReceiver* subghz_receiver, string_t output) {
|
||||
furi_assert(subghz_receiver);
|
||||
uint32_t frequency;
|
||||
uint32_t preset;
|
||||
with_view_model(
|
||||
subghz_receiver->view, (SubghzReceiverModel * model) {
|
||||
frequency = subghz_history_get_frequency(model->history, model->idx);
|
||||
preset = (uint32_t)subghz_history_get_preset(model->history, model->idx);
|
||||
return false;
|
||||
});
|
||||
|
||||
string_cat_printf(
|
||||
output,
|
||||
"Frequency: %d\n"
|
||||
"Preset: %d\n",
|
||||
(int)frequency,
|
||||
(int)preset);
|
||||
}
|
@@ -2,10 +2,19 @@
|
||||
|
||||
#include <gui/view.h>
|
||||
#include <lib/subghz/protocols/subghz_protocol_common.h>
|
||||
#include <lib/subghz/protocols/subghz_protocol.h>
|
||||
#include <lib/subghz/subghz_worker.h>
|
||||
#include "../subghz_history.h"
|
||||
|
||||
typedef enum {
|
||||
SubghzReceverEventOK,
|
||||
SubghzReceverEventConfig,
|
||||
SubghzReceverEventMain,
|
||||
SubghzReceverEventSave,
|
||||
SubghzReceverEventBack,
|
||||
SubghzReceverEventMore,
|
||||
SubghzReceverEventSendStart,
|
||||
SubghzReceverEventSendStop
|
||||
} SubghzReceverEvent;
|
||||
|
||||
typedef struct SubghzReceiver SubghzReceiver;
|
||||
@@ -23,4 +32,12 @@ void subghz_receiver_free(SubghzReceiver* subghz_receiver);
|
||||
|
||||
View* subghz_receiver_get_view(SubghzReceiver* subghz_receiver);
|
||||
|
||||
void subghz_receiver_set_protocol(SubghzReceiver* subghz_receiver, SubGhzProtocolCommon* protocol);
|
||||
void subghz_receiver_set_protocol(
|
||||
SubghzReceiver* subghz_receiver,
|
||||
SubGhzProtocolCommon* protocol_result,
|
||||
SubGhzProtocol* protocol);
|
||||
SubGhzProtocolCommon* subghz_receiver_get_protocol(SubghzReceiver* subghz_receiver);
|
||||
void subghz_receiver_set_worker(SubghzReceiver* subghz_receiver, SubGhzWorker* worker);
|
||||
uint32_t subghz_receiver_get_frequency(SubghzReceiver* subghz_receiver);
|
||||
FuriHalSubGhzPreset subghz_receiver_get_preset(SubghzReceiver* subghz_receiver);
|
||||
void subghz_receiver_frequency_preset_to_str(SubghzReceiver* subghz_receiver, string_t output);
|
||||
|
@@ -112,7 +112,7 @@ void subghz_static_enter(void* context) {
|
||||
SubghzStatic* instance = context;
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
|
||||
hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||
hal_gpio_write(&gpio_cc1101_g0, false);
|
||||
|
@@ -119,7 +119,7 @@ void subghz_test_carrier_enter(void* context) {
|
||||
SubghzTestCarrier* subghz_test_carrier = context;
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
|
||||
hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
|
@@ -166,7 +166,7 @@ void subghz_test_packet_enter(void* context) {
|
||||
SubghzTestPacket* instance = context;
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
|
||||
with_view_model(
|
||||
instance->view, (SubghzTestPacketModel * model) {
|
||||
|
@@ -8,7 +8,8 @@
|
||||
#include <gui/elements.h>
|
||||
#include <notification/notification-messages.h>
|
||||
|
||||
#include <assets_icons.h>
|
||||
//#include <assets_icons.h>
|
||||
#include <gui/icon_i.h>
|
||||
|
||||
struct SubghzTransmitter {
|
||||
View* view;
|
||||
@@ -19,6 +20,8 @@ struct SubghzTransmitter {
|
||||
typedef struct {
|
||||
string_t text;
|
||||
uint16_t scene;
|
||||
uint32_t real_frequency;
|
||||
FuriHalSubGhzPreset preset;
|
||||
SubGhzProtocolCommon* protocol;
|
||||
} SubghzTransmitterModel;
|
||||
|
||||
@@ -42,14 +45,65 @@ void subghz_transmitter_set_protocol(
|
||||
});
|
||||
}
|
||||
|
||||
void subghz_transmitter_set_frequency_preset(
|
||||
SubghzTransmitter* subghz_transmitter,
|
||||
uint32_t frequency,
|
||||
FuriHalSubGhzPreset preset) {
|
||||
with_view_model(
|
||||
subghz_transmitter->view, (SubghzTransmitterModel * model) {
|
||||
model->real_frequency = frequency;
|
||||
model->preset = preset;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
static void subghz_transmitter_button_right(Canvas* canvas, const char* str) {
|
||||
const uint8_t button_height = 13;
|
||||
const uint8_t vertical_offset = 3;
|
||||
const uint8_t horizontal_offset = 1;
|
||||
const uint8_t string_width = canvas_string_width(canvas, str);
|
||||
const Icon* icon = &I_ButtonCenter_7x7;
|
||||
const uint8_t icon_offset = 3;
|
||||
const uint8_t icon_width_with_offset = icon->width + icon_offset;
|
||||
const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
|
||||
|
||||
const uint8_t x = (canvas_width(canvas) - button_width) / 2 + 40;
|
||||
const uint8_t y = canvas_height(canvas);
|
||||
|
||||
canvas_draw_box(canvas, x, y - button_height, button_width, button_height);
|
||||
|
||||
canvas_draw_line(canvas, x - 1, y, x - 1, y - button_height + 0);
|
||||
canvas_draw_line(canvas, x - 2, y, x - 2, y - button_height + 1);
|
||||
canvas_draw_line(canvas, x - 3, y, x - 3, y - button_height + 2);
|
||||
|
||||
canvas_draw_line(canvas, x + button_width + 0, y, x + button_width + 0, y - button_height + 0);
|
||||
canvas_draw_line(canvas, x + button_width + 1, y, x + button_width + 1, y - button_height + 1);
|
||||
canvas_draw_line(canvas, x + button_width + 2, y, x + button_width + 2, y - button_height + 2);
|
||||
|
||||
canvas_invert_color(canvas);
|
||||
canvas_draw_icon(
|
||||
canvas, x + horizontal_offset, y - button_height + vertical_offset, &I_ButtonCenter_7x7);
|
||||
canvas_draw_str(
|
||||
canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str);
|
||||
canvas_invert_color(canvas);
|
||||
}
|
||||
|
||||
void subghz_transmitter_draw(Canvas* canvas, SubghzTransmitterModel* model) {
|
||||
char buffer[64];
|
||||
canvas_clear(canvas);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
elements_multiline_text(canvas, 0, 10, string_get_cstr(model->text));
|
||||
elements_multiline_text(canvas, 0, 8, string_get_cstr(model->text));
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"%03ld.%03ld",
|
||||
model->real_frequency / 1000000 % 1000,
|
||||
model->real_frequency / 1000 % 1000);
|
||||
canvas_draw_str(canvas, 90, 8, buffer);
|
||||
|
||||
if(model->protocol && model->protocol->get_upload_protocol) {
|
||||
elements_button_center(canvas, "Send");
|
||||
subghz_transmitter_button_right(canvas, "Send");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -27,3 +27,7 @@ View* subghz_transmitter_get_view(SubghzTransmitter* subghz_transmitter);
|
||||
void subghz_transmitter_set_protocol(
|
||||
SubghzTransmitter* subghz_transmitter,
|
||||
SubGhzProtocolCommon* protocol);
|
||||
void subghz_transmitter_set_frequency_preset(
|
||||
SubghzTransmitter* subghz_transmitter,
|
||||
uint32_t frequency,
|
||||
FuriHalSubGhzPreset preset);
|
||||
|
Reference in New Issue
Block a user