mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-21 20:42:15 -07:00
add TX
This commit is contained in:
@@ -11,6 +11,13 @@ typedef enum {
|
||||
|
||||
//SubRemCustomEvent
|
||||
SubRemCustomEventViewRemoteBack = 100,
|
||||
SubRemCustomEventViewRemoteStartUP,
|
||||
SubRemCustomEventViewRemoteStartDOWN,
|
||||
SubRemCustomEventViewRemoteStartLEFT,
|
||||
SubRemCustomEventViewRemoteStartRIGHT,
|
||||
SubRemCustomEventViewRemoteStartOK,
|
||||
SubRemCustomEventViewRemoteStop,
|
||||
|
||||
// SubRemCustomEventSceneDeleteSuccess = 100,
|
||||
// SubRemCustomEventSceneDelete,
|
||||
// SubRemCustomEventSceneDeleteRAW,
|
||||
|
||||
@@ -10,6 +10,7 @@ void subrem_scene_openmapfile_on_enter(void* context) {
|
||||
// } else {
|
||||
// scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSavedMenu);
|
||||
// }
|
||||
scene_manager_next_scene(app->scene_manager, SubRemSceneRemote);
|
||||
} else {
|
||||
scene_manager_search_and_switch_to_previous_scene(app->scene_manager, SubRemSceneStart);
|
||||
}
|
||||
|
||||
@@ -21,11 +21,18 @@ bool subrem_scene_remote_update_data_show(void* context) {
|
||||
subrem_view_remote_add_data_to_show(
|
||||
//app->subrem_remote_view, "N/A", "N/A", "N/A", "N/A", "N/A");
|
||||
app->subrem_remote_view,
|
||||
"UP",
|
||||
"DOWN",
|
||||
"LEFT",
|
||||
"RIGHT",
|
||||
"OK");
|
||||
// "UP",
|
||||
// "DOWN",
|
||||
// "LEFT",
|
||||
// "RIGHT",
|
||||
// "OK");
|
||||
|
||||
furi_string_get_cstr(app->subs_preset[0]->label),
|
||||
furi_string_get_cstr(app->subs_preset[1]->label),
|
||||
furi_string_get_cstr(app->subs_preset[2]->label),
|
||||
furi_string_get_cstr(app->subs_preset[3]->label),
|
||||
furi_string_get_cstr(app->subs_preset[4]->label));
|
||||
|
||||
// SubGhzProtocolDecoderBase* decoder = subghz_txrx_get_decoder(app->txrx);
|
||||
|
||||
// if(decoder) {
|
||||
@@ -105,7 +112,16 @@ bool subrem_scene_remote_on_event(void* context, SceneManagerEvent event) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, SubRemSceneStart);
|
||||
return true;
|
||||
} else if(event.event == SubRemCustomEventViewRemoteStartUP) {
|
||||
if(subghz_tx_start_sub(app, app->subs_preset[0])) {
|
||||
notification_message(app->notifications, &sequence_blink_start_magenta);
|
||||
}
|
||||
} else if(event.event == SubRemCustomEventViewRemoteStop) {
|
||||
subghz_tx_stop_sub(app, app->subs_preset[0]);
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
}
|
||||
// notification_message(app->notification, &sequence_blink_stop);
|
||||
|
||||
// else if(event.event == SubGhzCustomEventViewTransmitterError) {
|
||||
// furi_string_set(app->error_str, "Protocol not\nfound!");
|
||||
// scene_manager_next_scene(app->scene_manager, SubGhzSceneShowErrorSub);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "subghz_remote_app_i.h"
|
||||
|
||||
#include <lib/subghz/protocols/protocol_items.h>
|
||||
|
||||
static bool subghz_remote_app_custom_event_callback(void* context, uint32_t event) {
|
||||
furi_assert(context);
|
||||
SubGhzRemoteApp* app = context;
|
||||
@@ -21,6 +23,17 @@ static void subghz_remote_app_tick_event_callback(void* context) {
|
||||
SubGhzRemoteApp* subghz_remote_app_alloc() {
|
||||
SubGhzRemoteApp* app = malloc(sizeof(SubGhzRemoteApp));
|
||||
|
||||
// Enable power for External CC1101 if it is connected
|
||||
furi_hal_subghz_enable_ext_power();
|
||||
// Auto switch to internal radio if external radio is not available
|
||||
furi_delay_ms(15);
|
||||
if(!furi_hal_subghz_check_radio()) {
|
||||
furi_hal_subghz_select_radio_type(SubGhzRadioInternal);
|
||||
furi_hal_subghz_init_radio_type(SubGhzRadioInternal);
|
||||
}
|
||||
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
|
||||
// // Enable 5v power, multiple attempts to avoid issues with power chip protection false triggering
|
||||
// uint8_t attempts = 0;
|
||||
// while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
|
||||
@@ -109,6 +122,21 @@ SubGhzRemoteApp* subghz_remote_app_alloc() {
|
||||
app->setting = subghz_setting_alloc();
|
||||
subghz_setting_load(app->setting, EXT_PATH("subghz/assets/setting_user"));
|
||||
|
||||
app->environment = subghz_environment_alloc();
|
||||
|
||||
subghz_environment_load_keystore(app->environment, EXT_PATH("subghz/assets/keeloq_mfcodes"));
|
||||
subghz_environment_load_keystore(
|
||||
app->environment, EXT_PATH("subghz/assets/keeloq_mfcodes_user"));
|
||||
subghz_environment_set_came_atomo_rainbow_table_file_name(
|
||||
app->environment, EXT_PATH("subghz/assets/came_atomo"));
|
||||
subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
|
||||
app->environment, EXT_PATH("subghz/assets/alutech_at_4n"));
|
||||
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
|
||||
app->environment, EXT_PATH("subghz/assets/nice_flor_s"));
|
||||
subghz_environment_set_protocol_registry(app->environment, (void*)&subghz_protocol_registry);
|
||||
|
||||
app->receiver = subghz_receiver_alloc_init(app->environment);
|
||||
|
||||
scene_manager_next_scene(app->scene_manager, SubRemSceneStart);
|
||||
|
||||
return app;
|
||||
@@ -117,6 +145,13 @@ SubGhzRemoteApp* subghz_remote_app_alloc() {
|
||||
void subghz_remote_app_free(SubGhzRemoteApp* app) {
|
||||
furi_assert(app);
|
||||
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
|
||||
// Disable power for External CC1101 if it was enabled and module is connected
|
||||
furi_hal_subghz_disable_ext_power();
|
||||
// Reinit SPI handles for internal radio / nfc
|
||||
furi_hal_subghz_init_radio_type(SubGhzRadioInternal);
|
||||
|
||||
// Submenu
|
||||
view_dispatcher_remove_view(app->view_dispatcher, SubRemViewSubmenu);
|
||||
submenu_free(app->submenu);
|
||||
@@ -140,6 +175,8 @@ void subghz_remote_app_free(SubGhzRemoteApp* app) {
|
||||
view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDRemote);
|
||||
subrem_view_remote_free(app->subrem_remote_view);
|
||||
|
||||
subghz_receiver_free(app->receiver);
|
||||
subghz_environment_free(app->environment);
|
||||
subghz_setting_free(app->setting);
|
||||
|
||||
for(uint8_t i = 0; i < SUBREM_MAX_SUB_KEY_COUNT; i++) {
|
||||
|
||||
+128
-16
@@ -8,11 +8,11 @@
|
||||
#define TAG "SubGhzRemote"
|
||||
|
||||
static const char* map_file_labels[SUBREM_MAX_SUB_KEY_COUNT][2] = {
|
||||
{"OK", "OKLABEL"},
|
||||
{"UP", "ULABEL"},
|
||||
{"DOWN", "DLABEL"},
|
||||
{"LEFT", "LLABEL"},
|
||||
{"RIGHT", "RLABEL"},
|
||||
{"OK", "OKLABEL"},
|
||||
};
|
||||
|
||||
bool subrem_set_preset_data(SubGhzSetting* setting, FreqPreset* freq_preset, const char* preset) {
|
||||
@@ -42,7 +42,9 @@ SubRemSubFilePreset* subrem_sub_file_preset_alloc() {
|
||||
|
||||
sub_preset->fff_data = flipper_format_string_alloc();
|
||||
sub_preset->file_path = furi_string_alloc();
|
||||
sub_preset->protocaol_name = furi_string_alloc();
|
||||
sub_preset->label = furi_string_alloc_set_str("N/A");
|
||||
|
||||
sub_preset->type = SubRemSubKeyTypeNoData;
|
||||
|
||||
return sub_preset;
|
||||
@@ -52,13 +54,35 @@ void subrem_sub_file_preset_free(SubRemSubFilePreset* sub_preset) {
|
||||
furi_assert(sub_preset);
|
||||
|
||||
furi_string_free(sub_preset->label);
|
||||
furi_string_free(sub_preset->protocaol_name);
|
||||
furi_string_free(sub_preset->file_path);
|
||||
flipper_format_free(sub_preset->fff_data);
|
||||
|
||||
free(sub_preset);
|
||||
}
|
||||
|
||||
static bool subrem_sub_file_preset_load(SubGhzRemoteApp* app, FlipperFormat* fff_data_file) {
|
||||
void subrem_subs_file_preset_reset(SubRemSubFilePreset* sub_preset) {
|
||||
furi_assert(sub_preset);
|
||||
|
||||
furi_string_set_str(sub_preset->label, "N/A");
|
||||
furi_string_reset(sub_preset->protocaol_name);
|
||||
furi_string_reset(sub_preset->file_path);
|
||||
|
||||
Stream* fff_data_stream = flipper_format_get_raw_stream(sub_preset->fff_data);
|
||||
stream_clean(fff_data_stream);
|
||||
|
||||
sub_preset->type = SubRemSubKeyTypeNoData;
|
||||
}
|
||||
|
||||
void subrem_sub_file_presets_reset(SubGhzRemoteApp* app) {
|
||||
furi_assert(app);
|
||||
|
||||
for(uint8_t i = 0; i < SUBREM_MAX_SUB_KEY_COUNT; i++) {
|
||||
subrem_subs_file_preset_reset(app->subs_preset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static bool subrem_sub_file_presets_load(SubGhzRemoteApp* app, FlipperFormat* fff_data_file) {
|
||||
furi_assert(app);
|
||||
bool ret = false;
|
||||
|
||||
@@ -83,7 +107,7 @@ static bool subrem_sub_file_preset_load(SubGhzRemoteApp* app, FlipperFormat* fff
|
||||
map_file_labels[i][0],
|
||||
furi_string_get_cstr(app->subs_preset[i]->label),
|
||||
furi_string_get_cstr(app->subs_preset[i]->file_path));
|
||||
app->subs_preset[i]->type = SubRemSubKeyTypeHaveFileName; // TODO
|
||||
app->subs_preset[i]->type = SubRemSubKeyTypeHaveFileName; // TODO:
|
||||
ret = true;
|
||||
}
|
||||
flipper_format_rewind(fff_data_file);
|
||||
@@ -91,6 +115,67 @@ static bool subrem_sub_file_preset_load(SubGhzRemoteApp* app, FlipperFormat* fff
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool subghz_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset) {
|
||||
furi_assert(app);
|
||||
furi_assert(sub_preset);
|
||||
bool ret = false;
|
||||
|
||||
FURI_LOG_I(TAG, "Send %s", furi_string_get_cstr(sub_preset->label));
|
||||
|
||||
do {
|
||||
flipper_format_rewind(sub_preset->fff_data); // FIXME:
|
||||
|
||||
app->transmitter = subghz_transmitter_alloc_init(
|
||||
app->environment, furi_string_get_cstr(sub_preset->protocaol_name));
|
||||
|
||||
if(app->transmitter) {
|
||||
if(subghz_transmitter_deserialize(app->transmitter, sub_preset->fff_data) !=
|
||||
SubGhzProtocolStatusOk) {
|
||||
FURI_LOG_E(TAG, "Deserialize error!");
|
||||
break;
|
||||
}
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_idle();
|
||||
furi_hal_subghz_load_custom_preset(sub_preset->freq_preset.data);
|
||||
furi_hal_gpio_init(
|
||||
furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
furi_hal_subghz_idle();
|
||||
|
||||
furi_hal_subghz_set_frequency_and_path(sub_preset->freq_preset.frequency);
|
||||
furi_hal_gpio_write(furi_hal_subghz.cc1101_g0_pin, false);
|
||||
furi_hal_gpio_init(
|
||||
furi_hal_subghz.cc1101_g0_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
if(!furi_hal_subghz_tx()) {
|
||||
FURI_LOG_E(TAG, "Sending not allowed");
|
||||
break;
|
||||
}
|
||||
|
||||
furi_hal_subghz_start_async_tx(subghz_transmitter_yield, app->transmitter);
|
||||
|
||||
ret = true;
|
||||
}
|
||||
} while(false);
|
||||
|
||||
// ret = false; // TODO:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_tx_stop_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset) {
|
||||
furi_assert(app);
|
||||
furi_assert(sub_preset);
|
||||
|
||||
//Stop TX
|
||||
furi_hal_subghz_stop_async_tx();
|
||||
|
||||
subghz_transmitter_stop(app->transmitter);
|
||||
subghz_transmitter_free(app->transmitter);
|
||||
furi_hal_subghz_idle();
|
||||
|
||||
// TODO: need saving logic
|
||||
}
|
||||
|
||||
static bool subrem_sub_presets_check(SubGhzRemoteApp* app, FlipperFormat* fff_data_file) {
|
||||
furi_assert(app);
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
@@ -98,10 +183,6 @@ static bool subrem_sub_presets_check(SubGhzRemoteApp* app, FlipperFormat* fff_da
|
||||
bool ret = false;
|
||||
SubRemSubFilePreset* sub_preset;
|
||||
|
||||
// TODO:
|
||||
// const SubGhzProtocolRegistry* protocol_registry_items =
|
||||
// subghz_environment_get_protocol_registry(app->environment);
|
||||
|
||||
for(uint8_t i = 0; i < SUBREM_MAX_SUB_KEY_COUNT; i++) {
|
||||
sub_preset = app->subs_preset[i];
|
||||
if(sub_preset->type == SubRemSubKeyTypeNoData) {
|
||||
@@ -172,16 +253,44 @@ static bool subrem_sub_presets_check(SubGhzRemoteApp* app, FlipperFormat* fff_da
|
||||
flipper_format_get_raw_stream(fff_data));
|
||||
}
|
||||
|
||||
// subghz_protocol_registry_get_by_name(
|
||||
// protocol_registry_items, furi_string_get_cstr(temp_str)); // TODO: check dynamic and protocol found
|
||||
const SubGhzProtocolRegistry* protocol_registry_items =
|
||||
subghz_environment_get_protocol_registry(app->environment);
|
||||
|
||||
const SubGhzProtocol* protocol = subghz_protocol_registry_get_by_name(
|
||||
protocol_registry_items, furi_string_get_cstr(temp_str));
|
||||
|
||||
if(!protocol) {
|
||||
FURI_LOG_E(TAG, "Protocol not found");
|
||||
break;
|
||||
} else if(protocol->flag & SubGhzProtocolFlag_Send) { // FIXME:
|
||||
|
||||
if(protocol->type == SubGhzProtocolTypeStatic) {
|
||||
sub_preset->type = SubRemSubKeyTypeStaticKey;
|
||||
} else if(protocol->type == SubGhzProtocolTypeDynamic) {
|
||||
sub_preset->type = SubRemSubKeyTypeDynamicKey;
|
||||
} else if(protocol->type == SubGhzProtocolTypeRAW) {
|
||||
sub_preset->type = SubRemSubKeyTypeRawKey;
|
||||
// } else if(protocol->type == SubGhzProtocolTypeBinRAW) { // TODO: BINRAW
|
||||
} else {
|
||||
FURI_LOG_E(TAG, "Unsuported Protocol");
|
||||
break;
|
||||
}
|
||||
|
||||
furi_string_set(sub_preset->protocaol_name, temp_str);
|
||||
} // TODO: check dynamic and protocol found
|
||||
|
||||
ret |= true;
|
||||
|
||||
if(ret) {
|
||||
FURI_LOG_I(TAG, "Protocol Loaded");
|
||||
}
|
||||
} while(false);
|
||||
|
||||
flipper_format_file_close(fff_data_file);
|
||||
}
|
||||
furi_string_free(temp_str);
|
||||
|
||||
ret = false; // TODO:
|
||||
//ret = false; // TODO:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -194,14 +303,19 @@ bool subrem_map_file_load(SubGhzRemoteApp* app, const char* file_path) {
|
||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||
bool ret = false;
|
||||
FURI_LOG_I(TAG, "Open Map File.."); // drop
|
||||
|
||||
subrem_sub_file_presets_reset(app);
|
||||
|
||||
if(!flipper_format_file_open_existing(fff_data_file, file_path)) {
|
||||
FURI_LOG_E(TAG, "Could not open MAP file %s", file_path);
|
||||
} else {
|
||||
if(!subrem_sub_file_preset_load(app, fff_data_file)) {
|
||||
if(!subrem_sub_file_presets_load(app, fff_data_file)) {
|
||||
// TODO: error popup or return error type
|
||||
FURI_LOG_E(TAG, "Could no Sub file path in MAP file");
|
||||
} else if(!(flipper_format_file_close(fff_data_file) &&
|
||||
subrem_sub_presets_check(app, fff_data_file))) {
|
||||
} else if(
|
||||
(flipper_format_file_close(fff_data_file)) &&
|
||||
(subrem_sub_presets_check(app, fff_data_file))) {
|
||||
FURI_LOG_I(TAG, "Load Map File Seccesful");
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
@@ -211,8 +325,7 @@ bool subrem_map_file_load(SubGhzRemoteApp* app, const char* file_path) {
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
FURI_LOG_I(TAG, "Load Map File Done"); // drop
|
||||
ret = false; // TODO
|
||||
//ret = false; // TODO:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -232,7 +345,6 @@ bool subrem_load_from_file(SubGhzRemoteApp* app) {
|
||||
if(res) {
|
||||
res = subrem_map_file_load(app, furi_string_get_cstr(app->file_path));
|
||||
// FIXME res = subghz_key_load(app, furi_string_get_cstr(app->file_path), true);
|
||||
res = false;
|
||||
}
|
||||
|
||||
furi_string_free(file_path);
|
||||
|
||||
@@ -44,6 +44,7 @@ typedef struct {
|
||||
FlipperFormat* fff_data;
|
||||
FreqPreset freq_preset;
|
||||
FuriString* file_path;
|
||||
FuriString* protocaol_name;
|
||||
FuriString* label;
|
||||
SubRemSubKeyType type;
|
||||
} SubRemSubFilePreset;
|
||||
@@ -70,6 +71,9 @@ typedef struct {
|
||||
SubRemSubFilePreset* subs_preset[SUBREM_MAX_SUB_KEY_COUNT];
|
||||
|
||||
SubGhzSetting* setting;
|
||||
SubGhzEnvironment* environment;
|
||||
SubGhzReceiver* receiver;
|
||||
SubGhzTransmitter* transmitter;
|
||||
|
||||
// AvrIspProgrammerView* subghz_remote_programmer_view;
|
||||
// AvrIspReaderView* subghz_remote_reader_view;
|
||||
@@ -79,4 +83,7 @@ typedef struct {
|
||||
// AvrIspError error;
|
||||
} SubGhzRemoteApp;
|
||||
|
||||
bool subrem_load_from_file(SubGhzRemoteApp* app);
|
||||
bool subrem_load_from_file(SubGhzRemoteApp* app);
|
||||
|
||||
bool subghz_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset);
|
||||
void subghz_tx_stop_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset);
|
||||
@@ -185,6 +185,8 @@ bool subrem_view_remote_input(InputEvent* event, void* context) {
|
||||
SubRemViewRemoteModel * model,
|
||||
{ model->pressed_btn = 1; },
|
||||
true);
|
||||
subrem_view_remote->callback(
|
||||
SubRemCustomEventViewRemoteStartUP, subrem_view_remote->context);
|
||||
return true;
|
||||
} else if(event->type == InputTypeRelease) {
|
||||
with_view_model(
|
||||
@@ -192,6 +194,8 @@ bool subrem_view_remote_input(InputEvent* event, void* context) {
|
||||
SubRemViewRemoteModel * model,
|
||||
{ model->pressed_btn = 0; },
|
||||
true);
|
||||
subrem_view_remote->callback(
|
||||
SubRemCustomEventViewRemoteStop, subrem_view_remote->context);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user