mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-14 20:08:35 -07:00
Merge branch 'dev' of https://github.com/DarkFlippers/unleashed-firmware into xfw-dev
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
App(
|
||||
appid="subghz",
|
||||
name="SubGHz",
|
||||
apptype=FlipperAppType.APP,
|
||||
apptype=FlipperAppType.MENUEXTERNAL,
|
||||
targets=["f7"],
|
||||
entry_point="subghz_app",
|
||||
cdefines=["APP_SUBGHZ"],
|
||||
requires=[
|
||||
"gui",
|
||||
"cli",
|
||||
@@ -20,13 +19,16 @@ App(
|
||||
icon="A_Sub1ghz_14",
|
||||
stack_size=3 * 1024,
|
||||
order=10,
|
||||
fap_libs=["assets", "hwdrivers"],
|
||||
fap_icon="icon.png",
|
||||
fap_category="Sub-GHz",
|
||||
)
|
||||
|
||||
App(
|
||||
appid="subghz_start",
|
||||
targets=["f7"],
|
||||
apptype=FlipperAppType.STARTUP,
|
||||
entry_point="subghz_on_system_start",
|
||||
requires=["subghz"],
|
||||
order=40,
|
||||
)
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ typedef enum {
|
||||
SubmenuIndexBeninca868,
|
||||
SubmenuIndexAllmatic433,
|
||||
SubmenuIndexAllmatic868,
|
||||
SubmenuIndexCenturion433,
|
||||
SubmenuIndexIronLogic,
|
||||
SubmenuIndexElmesElectronic,
|
||||
SubmenuIndexSommer_FM_434,
|
||||
|
||||
@@ -28,6 +28,10 @@ struct SubGhzFrequencyAnalyzerWorker {
|
||||
FrequencyRSSI frequency_rssi_buf;
|
||||
SubGhzSetting* setting;
|
||||
|
||||
const SubGhzDevice* radio_device;
|
||||
FuriHalSpiBusHandle* spi_bus;
|
||||
bool ext_radio;
|
||||
|
||||
float filVal;
|
||||
float trigger_level;
|
||||
|
||||
@@ -35,14 +39,16 @@ struct SubGhzFrequencyAnalyzerWorker {
|
||||
void* context;
|
||||
};
|
||||
|
||||
static void subghz_frequency_analyzer_worker_load_registers(const uint8_t data[][2]) {
|
||||
furi_hal_spi_acquire(furi_hal_subghz.spi_bus_handle);
|
||||
static void subghz_frequency_analyzer_worker_load_registers(
|
||||
FuriHalSpiBusHandle* spi_bus,
|
||||
const uint8_t data[][2]) {
|
||||
furi_hal_spi_acquire(spi_bus);
|
||||
size_t i = 0;
|
||||
while(data[i][0]) {
|
||||
cc1101_write_reg(furi_hal_subghz.spi_bus_handle, data[i][0], data[i][1]);
|
||||
cc1101_write_reg(spi_bus, data[i][0], data[i][1]);
|
||||
i++;
|
||||
}
|
||||
furi_hal_spi_release(furi_hal_subghz.spi_bus_handle);
|
||||
furi_hal_spi_release(spi_bus);
|
||||
}
|
||||
|
||||
// running average with adaptive coefficient
|
||||
@@ -77,29 +83,35 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
|
||||
uint32_t frequency_temp = 0;
|
||||
CC1101Status status;
|
||||
|
||||
//Start CC1101
|
||||
furi_hal_subghz_reset();
|
||||
FuriHalSpiBusHandle* spi_bus = instance->spi_bus;
|
||||
const SubGhzDevice* radio_device = instance->radio_device;
|
||||
|
||||
furi_hal_spi_acquire(furi_hal_subghz.spi_bus_handle);
|
||||
cc1101_flush_rx(furi_hal_subghz.spi_bus_handle);
|
||||
cc1101_flush_tx(furi_hal_subghz.spi_bus_handle);
|
||||
cc1101_write_reg(furi_hal_subghz.spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHW);
|
||||
cc1101_write_reg(furi_hal_subghz.spi_bus_handle, CC1101_MDMCFG3,
|
||||
//Start CC1101
|
||||
// furi_hal_subghz_reset();
|
||||
subghz_devices_reset(radio_device);
|
||||
|
||||
furi_hal_spi_acquire(spi_bus);
|
||||
cc1101_flush_rx(spi_bus);
|
||||
cc1101_flush_tx(spi_bus);
|
||||
|
||||
// TODO probably can be used device.load_preset(FuriHalSubGhzPresetCustom, ...) for external cc1101
|
||||
cc1101_write_reg(spi_bus, CC1101_IOCFG0, CC1101IocfgHW);
|
||||
cc1101_write_reg(spi_bus, CC1101_MDMCFG3,
|
||||
0b01111111); // symbol rate
|
||||
cc1101_write_reg(
|
||||
furi_hal_subghz.spi_bus_handle,
|
||||
spi_bus,
|
||||
CC1101_AGCCTRL2,
|
||||
0b00000111); // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAGN_TARGET 42 dB
|
||||
cc1101_write_reg(
|
||||
furi_hal_subghz.spi_bus_handle,
|
||||
spi_bus,
|
||||
CC1101_AGCCTRL1,
|
||||
0b00001000); // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 1000 - Absolute carrier sense threshold disabled
|
||||
cc1101_write_reg(
|
||||
furi_hal_subghz.spi_bus_handle,
|
||||
spi_bus,
|
||||
CC1101_AGCCTRL0,
|
||||
0b00110000); // 00 - No hysteresis, medium asymmetric dead zone, medium gain ; 11 - 64 samples agc; 00 - Normal AGC, 00 - 4dB boundary
|
||||
|
||||
furi_hal_spi_release(furi_hal_subghz.spi_bus_handle);
|
||||
furi_hal_spi_release(spi_bus);
|
||||
|
||||
furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate);
|
||||
|
||||
@@ -112,34 +124,36 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
|
||||
|
||||
frequency_rssi.rssi_coarse = -127.0f;
|
||||
frequency_rssi.rssi_fine = -127.0f;
|
||||
furi_hal_subghz_idle();
|
||||
subghz_frequency_analyzer_worker_load_registers(subghz_preset_ook_650khz);
|
||||
// furi_hal_subghz_idle();
|
||||
subghz_devices_idle(radio_device);
|
||||
subghz_frequency_analyzer_worker_load_registers(spi_bus, subghz_preset_ook_650khz);
|
||||
|
||||
// First stage: coarse scan
|
||||
for(size_t i = 0; i < subghz_setting_get_frequency_count(instance->setting); i++) {
|
||||
uint32_t current_frequency = subghz_setting_get_frequency(instance->setting, i);
|
||||
if(furi_hal_subghz_is_frequency_valid(current_frequency) &&
|
||||
// if(furi_hal_subghz_is_frequency_valid(current_frequency) &&
|
||||
if(subghz_devices_is_frequency_valid(radio_device, current_frequency) &&
|
||||
(current_frequency != 467750000) && (current_frequency != 464000000) &&
|
||||
!((furi_hal_subghz.radio_type == SubGhzRadioExternal) &&
|
||||
!((instance->ext_radio) &&
|
||||
((current_frequency == 390000000) || (current_frequency == 312000000) ||
|
||||
(current_frequency == 312100000) || (current_frequency == 312200000) ||
|
||||
(current_frequency == 440175000)))) {
|
||||
furi_hal_spi_acquire(furi_hal_subghz.spi_bus_handle);
|
||||
cc1101_switch_to_idle(furi_hal_subghz.spi_bus_handle);
|
||||
frequency =
|
||||
cc1101_set_frequency(furi_hal_subghz.spi_bus_handle, current_frequency);
|
||||
furi_hal_spi_acquire(spi_bus);
|
||||
cc1101_switch_to_idle(spi_bus);
|
||||
frequency = cc1101_set_frequency(spi_bus, current_frequency);
|
||||
|
||||
cc1101_calibrate(furi_hal_subghz.spi_bus_handle);
|
||||
cc1101_calibrate(spi_bus);
|
||||
do {
|
||||
status = cc1101_get_status(furi_hal_subghz.spi_bus_handle);
|
||||
status = cc1101_get_status(spi_bus);
|
||||
} while(status.STATE != CC1101StateIDLE);
|
||||
|
||||
cc1101_switch_to_rx(furi_hal_subghz.spi_bus_handle);
|
||||
furi_hal_spi_release(furi_hal_subghz.spi_bus_handle);
|
||||
cc1101_switch_to_rx(spi_bus);
|
||||
furi_hal_spi_release(spi_bus);
|
||||
|
||||
furi_delay_ms(2);
|
||||
|
||||
rssi = furi_hal_subghz_get_rssi();
|
||||
// rssi = furi_hal_subghz_get_rssi();
|
||||
rssi = subghz_devices_get_rssi(radio_device);
|
||||
|
||||
rssi_avg += rssi;
|
||||
rssi_avg_samples++;
|
||||
@@ -163,28 +177,31 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
|
||||
|
||||
// Second stage: fine scan
|
||||
if(frequency_rssi.rssi_coarse > instance->trigger_level) {
|
||||
furi_hal_subghz_idle();
|
||||
subghz_frequency_analyzer_worker_load_registers(subghz_preset_ook_58khz);
|
||||
// furi_hal_subghz_idle();
|
||||
subghz_devices_idle(radio_device);
|
||||
subghz_frequency_analyzer_worker_load_registers(spi_bus, subghz_preset_ook_58khz);
|
||||
//for example -0.3 ... 433.92 ... +0.3 step 20KHz
|
||||
for(uint32_t i = frequency_rssi.frequency_coarse - 300000;
|
||||
i < frequency_rssi.frequency_coarse + 300000;
|
||||
i += 20000) {
|
||||
if(furi_hal_subghz_is_frequency_valid(i)) {
|
||||
furi_hal_spi_acquire(furi_hal_subghz.spi_bus_handle);
|
||||
cc1101_switch_to_idle(furi_hal_subghz.spi_bus_handle);
|
||||
frequency = cc1101_set_frequency(furi_hal_subghz.spi_bus_handle, i);
|
||||
// if(furi_hal_subghz_is_frequency_valid(i)) {
|
||||
if(subghz_devices_is_frequency_valid(radio_device, i)) {
|
||||
furi_hal_spi_acquire(spi_bus);
|
||||
cc1101_switch_to_idle(spi_bus);
|
||||
frequency = cc1101_set_frequency(spi_bus, i);
|
||||
|
||||
cc1101_calibrate(furi_hal_subghz.spi_bus_handle);
|
||||
cc1101_calibrate(spi_bus);
|
||||
do {
|
||||
status = cc1101_get_status(furi_hal_subghz.spi_bus_handle);
|
||||
status = cc1101_get_status(spi_bus);
|
||||
} while(status.STATE != CC1101StateIDLE);
|
||||
|
||||
cc1101_switch_to_rx(furi_hal_subghz.spi_bus_handle);
|
||||
furi_hal_spi_release(furi_hal_subghz.spi_bus_handle);
|
||||
cc1101_switch_to_rx(spi_bus);
|
||||
furi_hal_spi_release(spi_bus);
|
||||
|
||||
furi_delay_ms(2);
|
||||
|
||||
rssi = furi_hal_subghz_get_rssi();
|
||||
// rssi = furi_hal_subghz_get_rssi();
|
||||
rssi = subghz_devices_get_rssi(radio_device);
|
||||
|
||||
FURI_LOG_T(TAG, "#:%lu:%f", frequency, (double)rssi);
|
||||
|
||||
@@ -261,8 +278,10 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
|
||||
}
|
||||
|
||||
//Stop CC1101
|
||||
furi_hal_subghz_idle();
|
||||
furi_hal_subghz_sleep();
|
||||
// furi_hal_subghz_idle();
|
||||
// furi_hal_subghz_sleep();
|
||||
subghz_devices_idle(radio_device);
|
||||
subghz_devices_sleep(radio_device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -301,10 +320,26 @@ void subghz_frequency_analyzer_worker_set_pair_callback(
|
||||
instance->context = context;
|
||||
}
|
||||
|
||||
void subghz_frequency_analyzer_worker_start(SubGhzFrequencyAnalyzerWorker* instance) {
|
||||
void subghz_frequency_analyzer_worker_start(
|
||||
SubGhzFrequencyAnalyzerWorker* instance,
|
||||
SubGhzTxRx* txrx) {
|
||||
furi_assert(instance);
|
||||
furi_assert(!instance->worker_running);
|
||||
|
||||
SubGhzRadioDeviceType radio_type = subghz_txrx_radio_device_get(txrx);
|
||||
|
||||
if(radio_type == SubGhzRadioDeviceTypeExternalCC1101) {
|
||||
instance->spi_bus = &furi_hal_spi_bus_handle_external;
|
||||
instance->ext_radio = true;
|
||||
} else if(radio_type == SubGhzRadioDeviceTypeInternal) {
|
||||
instance->spi_bus = &furi_hal_spi_bus_handle_subghz;
|
||||
instance->ext_radio = false;
|
||||
} else {
|
||||
furi_crash("Unsuported external module");
|
||||
}
|
||||
|
||||
instance->radio_device = subghz_devices_get_by_name(subghz_txrx_radio_device_get_name(txrx));
|
||||
|
||||
instance->worker_running = true;
|
||||
|
||||
furi_thread_start(instance->thread);
|
||||
|
||||
@@ -45,8 +45,11 @@ void subghz_frequency_analyzer_worker_set_pair_callback(
|
||||
/** Start SubGhzFrequencyAnalyzerWorker
|
||||
*
|
||||
* @param instance SubGhzFrequencyAnalyzerWorker instance
|
||||
* @param txrx pointer to SubGhzTxRx
|
||||
*/
|
||||
void subghz_frequency_analyzer_worker_start(SubGhzFrequencyAnalyzerWorker* instance);
|
||||
void subghz_frequency_analyzer_worker_start(
|
||||
SubGhzFrequencyAnalyzerWorker* instance,
|
||||
SubGhzTxRx* txrx);
|
||||
|
||||
/** Stop SubGhzFrequencyAnalyzerWorker
|
||||
*
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
#include "subghz_testing.h"
|
||||
|
||||
const uint32_t subghz_frequencies_testing[] = {
|
||||
/* 300 - 348 */
|
||||
300000000,
|
||||
304500000,
|
||||
310000000,
|
||||
312025000,
|
||||
313250000,
|
||||
313625000,
|
||||
315000000,
|
||||
315225000,
|
||||
321950000,
|
||||
348000000,
|
||||
/* 387 - 464 */
|
||||
387000000,
|
||||
433075000, /* LPD433 first */
|
||||
433825000,
|
||||
433920000, /* LPD433 mid */
|
||||
434420000,
|
||||
434775000, /* LPD433 last channels */
|
||||
438900000,
|
||||
464000000,
|
||||
/* 779 - 928 */
|
||||
779000000,
|
||||
868150000,
|
||||
868350000,
|
||||
868550000,
|
||||
915000000,
|
||||
925000000,
|
||||
926500000,
|
||||
927950000,
|
||||
928000000,
|
||||
};
|
||||
|
||||
const uint32_t subghz_frequencies_count_testing =
|
||||
sizeof(subghz_frequencies_testing) / sizeof(uint32_t);
|
||||
const uint32_t subghz_frequencies_433_92_testing = 13;
|
||||
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
#include "../subghz_i.h"
|
||||
|
||||
extern const uint32_t subghz_frequencies_testing[];
|
||||
extern const uint32_t subghz_frequencies_count_testing;
|
||||
extern const uint32_t subghz_frequencies_433_92_testing;
|
||||
@@ -1,5 +1,9 @@
|
||||
#include "subghz_txrx_i.h"
|
||||
|
||||
#include <lib/subghz/protocols/protocol_items.h>
|
||||
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
|
||||
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
|
||||
|
||||
#include <lib/subghz/blocks/custom_btn.h>
|
||||
|
||||
#define TAG "SubGhz"
|
||||
@@ -128,27 +132,18 @@ void subghz_txrx_get_frequency_and_modulation(
|
||||
|
||||
static void subghz_txrx_begin(SubGhzTxRx* instance, uint8_t* preset_data) {
|
||||
furi_assert(instance);
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_idle();
|
||||
furi_hal_subghz_load_custom_preset(preset_data);
|
||||
furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
subghz_devices_reset(instance->radio_device);
|
||||
subghz_devices_idle(instance->radio_device);
|
||||
subghz_devices_load_preset(instance->radio_device, FuriHalSubGhzPresetCustom, preset_data);
|
||||
instance->txrx_state = SubGhzTxRxStateIDLE;
|
||||
}
|
||||
|
||||
static uint32_t subghz_txrx_rx(SubGhzTxRx* instance, uint32_t frequency) {
|
||||
furi_assert(instance);
|
||||
if(!furi_hal_subghz_is_frequency_valid(frequency)) {
|
||||
furi_crash("SubGhz: Incorrect RX frequency.");
|
||||
}
|
||||
furi_assert(
|
||||
instance->txrx_state != SubGhzTxRxStateRx && instance->txrx_state != SubGhzTxRxStateSleep);
|
||||
|
||||
furi_hal_subghz_idle();
|
||||
uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency);
|
||||
furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
furi_hal_subghz_flush_rx();
|
||||
subghz_txrx_speaker_on(instance);
|
||||
furi_hal_subghz_rx();
|
||||
subghz_devices_idle(instance->radio_device);
|
||||
|
||||
furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, instance->worker);
|
||||
subghz_worker_start(instance->worker);
|
||||
@@ -189,12 +184,11 @@ static bool subghz_txrx_tx(SubGhzTxRx* instance, uint32_t frequency) {
|
||||
furi_crash("SubGhz: Incorrect TX frequency.");
|
||||
}
|
||||
furi_assert(instance->txrx_state != SubGhzTxRxStateSleep);
|
||||
furi_hal_subghz_idle();
|
||||
furi_hal_subghz_set_frequency_and_path(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);
|
||||
bool ret = furi_hal_subghz_tx();
|
||||
|
||||
subghz_devices_idle(instance->radio_device);
|
||||
subghz_devices_set_frequency(instance->radio_device, frequency);
|
||||
|
||||
bool ret = subghz_devices_set_tx(instance->radio_device);
|
||||
if(ret) {
|
||||
subghz_txrx_speaker_on(instance);
|
||||
instance->txrx_state = SubGhzTxRxStateTx;
|
||||
@@ -420,13 +414,13 @@ void subghz_txrx_hopper_pause(SubGhzTxRx* instance) {
|
||||
void subghz_txrx_speaker_on(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
if(instance->debug_pin_state) {
|
||||
furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton);
|
||||
subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_ibutton);
|
||||
}
|
||||
|
||||
if(instance->speaker_state == SubGhzSpeakerStateEnable) {
|
||||
if(furi_hal_speaker_acquire(30)) {
|
||||
if(!instance->debug_pin_state) {
|
||||
furi_hal_subghz_set_async_mirror_pin(&gpio_speaker);
|
||||
subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_speaker);
|
||||
}
|
||||
} else {
|
||||
instance->speaker_state = SubGhzSpeakerStateDisable;
|
||||
@@ -437,12 +431,12 @@ void subghz_txrx_speaker_on(SubGhzTxRx* instance) {
|
||||
void subghz_txrx_speaker_off(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
if(instance->debug_pin_state) {
|
||||
furi_hal_subghz_set_async_mirror_pin(NULL);
|
||||
subghz_devices_set_async_mirror_pin(instance->radio_device, NULL);
|
||||
}
|
||||
if(instance->speaker_state != SubGhzSpeakerStateDisable) {
|
||||
if(furi_hal_speaker_is_mine()) {
|
||||
if(!instance->debug_pin_state) {
|
||||
furi_hal_subghz_set_async_mirror_pin(NULL);
|
||||
subghz_devices_set_async_mirror_pin(instance->radio_device, NULL);
|
||||
}
|
||||
furi_hal_speaker_release();
|
||||
if(instance->speaker_state == SubGhzSpeakerStateShutdown)
|
||||
@@ -454,12 +448,12 @@ void subghz_txrx_speaker_off(SubGhzTxRx* instance) {
|
||||
void subghz_txrx_speaker_mute(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
if(instance->debug_pin_state) {
|
||||
furi_hal_subghz_set_async_mirror_pin(NULL);
|
||||
subghz_devices_set_async_mirror_pin(instance->radio_device, NULL);
|
||||
}
|
||||
if(instance->speaker_state == SubGhzSpeakerStateEnable) {
|
||||
if(furi_hal_speaker_is_mine()) {
|
||||
if(!instance->debug_pin_state) {
|
||||
furi_hal_subghz_set_async_mirror_pin(NULL);
|
||||
subghz_devices_set_async_mirror_pin(instance->radio_device, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,12 +462,12 @@ void subghz_txrx_speaker_mute(SubGhzTxRx* instance) {
|
||||
void subghz_txrx_speaker_unmute(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
if(instance->debug_pin_state) {
|
||||
furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton);
|
||||
subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_ibutton);
|
||||
}
|
||||
if(instance->speaker_state == SubGhzSpeakerStateEnable) {
|
||||
if(furi_hal_speaker_is_mine()) {
|
||||
if(!instance->debug_pin_state) {
|
||||
furi_hal_subghz_set_async_mirror_pin(&gpio_speaker);
|
||||
subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_speaker);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -548,6 +542,82 @@ void subghz_txrx_set_raw_file_encoder_worker_callback_end(
|
||||
context);
|
||||
}
|
||||
|
||||
bool subghz_txrx_radio_device_is_external_connected(SubGhzTxRx* instance, const char* name) {
|
||||
furi_assert(instance);
|
||||
|
||||
bool is_connect = false;
|
||||
bool is_otg_enabled = furi_hal_power_is_otg_enabled();
|
||||
|
||||
if(!is_otg_enabled) {
|
||||
subghz_txrx_radio_device_power_on(instance);
|
||||
}
|
||||
|
||||
const SubGhzDevice* device = subghz_devices_get_by_name(name);
|
||||
if(device) {
|
||||
is_connect = subghz_devices_is_connect(device);
|
||||
}
|
||||
|
||||
if(!is_otg_enabled) {
|
||||
subghz_txrx_radio_device_power_off(instance);
|
||||
}
|
||||
return is_connect;
|
||||
}
|
||||
|
||||
SubGhzRadioDeviceType
|
||||
subghz_txrx_radio_device_set(SubGhzTxRx* instance, SubGhzRadioDeviceType radio_device_type) {
|
||||
furi_assert(instance);
|
||||
|
||||
if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 &&
|
||||
subghz_txrx_radio_device_is_external_connected(instance, SUBGHZ_DEVICE_CC1101_EXT_NAME)) {
|
||||
subghz_txrx_radio_device_power_on(instance);
|
||||
instance->radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME);
|
||||
subghz_devices_begin(instance->radio_device);
|
||||
instance->radio_device_type = SubGhzRadioDeviceTypeExternalCC1101;
|
||||
} else {
|
||||
subghz_txrx_radio_device_power_off(instance);
|
||||
if(instance->radio_device_type != SubGhzRadioDeviceTypeInternal) {
|
||||
subghz_devices_end(instance->radio_device);
|
||||
}
|
||||
instance->radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
|
||||
instance->radio_device_type = SubGhzRadioDeviceTypeInternal;
|
||||
}
|
||||
|
||||
return instance->radio_device_type;
|
||||
}
|
||||
|
||||
SubGhzRadioDeviceType subghz_txrx_radio_device_get(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->radio_device_type;
|
||||
}
|
||||
|
||||
float subghz_txrx_radio_device_get_rssi(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
return subghz_devices_get_rssi(instance->radio_device);
|
||||
}
|
||||
|
||||
const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
return subghz_devices_get_name(instance->radio_device);
|
||||
}
|
||||
|
||||
bool subghz_txrx_radio_device_is_frequecy_valid(SubGhzTxRx* instance, uint32_t frequency) {
|
||||
furi_assert(instance);
|
||||
return subghz_devices_is_frequency_valid(instance->radio_device, frequency);
|
||||
}
|
||||
|
||||
bool subghz_txrx_radio_device_is_tx_alowed(SubGhzTxRx* instance, uint32_t frequency) {
|
||||
furi_assert(instance);
|
||||
furi_assert(instance->txrx_state != SubGhzTxRxStateSleep);
|
||||
|
||||
subghz_devices_idle(instance->radio_device);
|
||||
subghz_devices_set_frequency(instance->radio_device, frequency);
|
||||
|
||||
bool ret = subghz_devices_set_tx(instance->radio_device);
|
||||
subghz_devices_idle(instance->radio_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state) {
|
||||
furi_assert(instance);
|
||||
instance->debug_pin_state = state;
|
||||
@@ -568,4 +638,4 @@ void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) {
|
||||
SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->receiver;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,13 +294,56 @@ void subghz_txrx_set_raw_file_encoder_worker_callback_end(
|
||||
SubGhzProtocolEncoderRAWCallbackEnd callback,
|
||||
void* context);
|
||||
|
||||
/* Checking if an external radio device is connected
|
||||
*
|
||||
* @param instance Pointer to a SubGhzTxRx
|
||||
* @param name Name of external radio device
|
||||
* @return bool True if is connected to the external radio device
|
||||
*/
|
||||
bool subghz_txrx_radio_device_is_external_connected(SubGhzTxRx* instance, const char* name);
|
||||
|
||||
/* Set the selected radio device to use
|
||||
*
|
||||
* @param instance Pointer to a SubGhzTxRx
|
||||
* @param radio_device_type Radio device type
|
||||
* @return SubGhzRadioDeviceType Type of installed radio device
|
||||
*/
|
||||
SubGhzRadioDeviceType
|
||||
subghz_txrx_radio_device_set(SubGhzTxRx* instance, SubGhzRadioDeviceType radio_device_type);
|
||||
|
||||
/* Get the selected radio device to use
|
||||
*
|
||||
* @param instance Pointer to a SubGhzTxRx
|
||||
* @return SubGhzRadioDeviceType Type of installed radio device
|
||||
*/
|
||||
SubGhzRadioDeviceType subghz_txrx_radio_device_get(SubGhzTxRx* instance);
|
||||
|
||||
/* Get RSSI the selected radio device to use
|
||||
*
|
||||
* @param instance Pointer to a SubGhzTxRx
|
||||
* @return float RSSI
|
||||
*/
|
||||
float subghz_txrx_radio_device_get_rssi(SubGhzTxRx* instance);
|
||||
|
||||
/* Get name the selected radio device to use
|
||||
*
|
||||
* @param instance Pointer to a SubGhzTxRx
|
||||
* @return const char* Name of installed radio device
|
||||
*/
|
||||
const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance);
|
||||
|
||||
/* Get get intelligence whether frequency the selected radio device to use
|
||||
*
|
||||
* @param instance Pointer to a SubGhzTxRx
|
||||
* @return bool True if the frequency is valid
|
||||
*/
|
||||
bool subghz_txrx_radio_device_is_frequecy_valid(SubGhzTxRx* instance, uint32_t frequency);
|
||||
|
||||
bool subghz_txrx_radio_device_is_tx_alowed(SubGhzTxRx* instance, uint32_t frequency);
|
||||
|
||||
void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state);
|
||||
bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance);
|
||||
|
||||
void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance);
|
||||
|
||||
SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "subghz_txrx.h"
|
||||
|
||||
struct SubGhzTxRx {
|
||||
@@ -26,4 +26,4 @@ struct SubGhzTxRx {
|
||||
void* need_save_context;
|
||||
|
||||
bool debug_pin_state;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -54,6 +54,7 @@ typedef enum {
|
||||
SubGhzLoadKeyStateOK,
|
||||
SubGhzLoadKeyStateParseErr,
|
||||
SubGhzLoadKeyStateOnlyRx,
|
||||
SubGhzLoadKeyStateUnsuportedFreq,
|
||||
SubGhzLoadKeyStateProtocolDescriptionErr,
|
||||
} SubGhzLoadKeyState;
|
||||
|
||||
@@ -75,9 +76,6 @@ typedef enum {
|
||||
SubGhzViewIdFrequencyAnalyzer,
|
||||
SubGhzViewIdReadRAW,
|
||||
|
||||
SubGhzViewIdStatic,
|
||||
SubGhzViewIdTestCarrier,
|
||||
SubGhzViewIdTestPacket,
|
||||
} SubGhzViewId;
|
||||
|
||||
/** SubGhz load type file */
|
||||
|
||||
BIN
applications/main/subghz/icon.png
Normal file
BIN
applications/main/subghz/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 299 B |
@@ -12,12 +12,6 @@ ADD_SCENE(subghz, show_only_rx, ShowOnlyRx)
|
||||
ADD_SCENE(subghz, saved_menu, SavedMenu)
|
||||
ADD_SCENE(subghz, delete, Delete)
|
||||
ADD_SCENE(subghz, delete_success, DeleteSuccess)
|
||||
ADD_SCENE(subghz, test, Test)
|
||||
ADD_SCENE(subghz, test_carrier, TestCarrier)
|
||||
#if FURI_DEBUG
|
||||
ADD_SCENE(subghz, test_static, TestStatic)
|
||||
ADD_SCENE(subghz, test_packet, TestPacket)
|
||||
#endif
|
||||
ADD_SCENE(subghz, set_type, SetType)
|
||||
ADD_SCENE(subghz, set_fix, SetFix)
|
||||
ADD_SCENE(subghz, set_cnt, SetCnt)
|
||||
|
||||
@@ -93,7 +93,9 @@ bool subghz_scene_decode_raw_start(SubGhz* subghz) {
|
||||
|
||||
subghz->decode_raw_file_worker_encoder = subghz_file_encoder_worker_alloc();
|
||||
if(subghz_file_encoder_worker_start(
|
||||
subghz->decode_raw_file_worker_encoder, furi_string_get_cstr(file_name))) {
|
||||
subghz->decode_raw_file_worker_encoder,
|
||||
furi_string_get_cstr(file_name),
|
||||
subghz_txrx_radio_device_get_name(subghz->txrx))) {
|
||||
//the worker needs a file in order to open and read part of the file
|
||||
furi_delay_ms(100);
|
||||
} else {
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
#include "../subghz_i.h"
|
||||
#include "../helpers/subghz_custom_event.h"
|
||||
#include <lib/toolbox/value_index.h>
|
||||
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
|
||||
|
||||
#define EXT_MODULES_COUNT (sizeof(radio_modules_variables_text) / sizeof(char* const))
|
||||
const char* const radio_modules_variables_text[] = {
|
||||
#define RADIO_DEVICE_COUNT 2
|
||||
const char* const radio_device_text[RADIO_DEVICE_COUNT] = {
|
||||
"Internal",
|
||||
"External",
|
||||
};
|
||||
|
||||
#define EXT_MOD_POWER_COUNT 2
|
||||
const char* const ext_mod_power_text[EXT_MOD_POWER_COUNT] = {
|
||||
"ON",
|
||||
"OFF",
|
||||
const uint32_t radio_device_value[RADIO_DEVICE_COUNT] = {
|
||||
SubGhzRadioDeviceTypeInternal,
|
||||
SubGhzRadioDeviceTypeExternalCC1101,
|
||||
};
|
||||
|
||||
#define TIMESTAMP_NAMES_COUNT 2
|
||||
@@ -35,19 +36,18 @@ const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = {
|
||||
"+10",
|
||||
};
|
||||
|
||||
static void subghz_scene_ext_module_changed(VariableItem* item) {
|
||||
static void subghz_scene_radio_settings_set_device(VariableItem* item) {
|
||||
SubGhz* subghz = variable_item_get_context(item);
|
||||
uint8_t value_index_exm = variable_item_get_current_value_index(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
|
||||
variable_item_set_current_value_text(item, radio_modules_variables_text[value_index_exm]);
|
||||
|
||||
subghz->last_settings->external_module_enabled = value_index_exm == 1;
|
||||
subghz_last_settings_save(subghz->last_settings);
|
||||
}
|
||||
|
||||
static void subghz_ext_module_start_var_list_enter_callback(void* context, uint32_t index) {
|
||||
SubGhz* subghz = context;
|
||||
view_dispatcher_send_custom_event(subghz->view_dispatcher, index);
|
||||
if(!subghz_txrx_radio_device_is_external_connected(
|
||||
subghz->txrx, SUBGHZ_DEVICE_CC1101_EXT_NAME) &&
|
||||
radio_device_value[index] == SubGhzRadioDeviceTypeExternalCC1101) {
|
||||
//ToDo correct if there is more than 1 module
|
||||
index = 0;
|
||||
}
|
||||
variable_item_set_current_value_text(item, radio_device_text[index]);
|
||||
subghz_txrx_radio_device_set(subghz->txrx, radio_device_value[index]);
|
||||
}
|
||||
|
||||
static void subghz_scene_receiver_config_set_debug_pin(VariableItem* item) {
|
||||
@@ -88,22 +88,22 @@ static void subghz_scene_receiver_config_set_debug_counter(VariableItem* item) {
|
||||
}
|
||||
}
|
||||
|
||||
static void subghz_scene_receiver_config_set_ext_mod_power(VariableItem* item) {
|
||||
SubGhz* subghz = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
// static void subghz_scene_receiver_config_set_ext_mod_power(VariableItem* item) {
|
||||
// SubGhz* subghz = variable_item_get_context(item);
|
||||
// uint8_t index = variable_item_get_current_value_index(item);
|
||||
|
||||
variable_item_set_current_value_text(item, ext_mod_power_text[index]);
|
||||
// variable_item_set_current_value_text(item, ext_mod_power_text[index]);
|
||||
|
||||
furi_hal_subghz_set_external_power_disable(index == 1);
|
||||
if(index == 1) {
|
||||
furi_hal_subghz_disable_ext_power();
|
||||
} else {
|
||||
furi_hal_subghz_enable_ext_power();
|
||||
}
|
||||
// furi_hal_subghz_set_external_power_disable(index == 1);
|
||||
// if(index == 1) {
|
||||
// furi_hal_subghz_disable_ext_power();
|
||||
// } else {
|
||||
// furi_hal_subghz_enable_ext_power();
|
||||
// }
|
||||
|
||||
subghz->last_settings->external_module_power_5v_disable = index == 1;
|
||||
subghz_last_settings_save(subghz->last_settings);
|
||||
}
|
||||
// subghz->last_settings->external_module_power_5v_disable = index == 1;
|
||||
// subghz_last_settings_save(subghz->last_settings);
|
||||
// }
|
||||
|
||||
static void subghz_scene_receiver_config_set_timestamp_file_names(VariableItem* item) {
|
||||
SubGhz* subghz = variable_item_get_context(item);
|
||||
@@ -120,29 +120,25 @@ void subghz_scene_radio_settings_on_enter(void* context) {
|
||||
|
||||
VariableItemList* variable_item_list = subghz->variable_item_list;
|
||||
uint8_t value_index;
|
||||
VariableItem* item;
|
||||
|
||||
value_index = furi_hal_subghz.radio_type;
|
||||
VariableItem* item = variable_item_list_add(
|
||||
variable_item_list, "Module", EXT_MODULES_COUNT, subghz_scene_ext_module_changed, subghz);
|
||||
|
||||
variable_item_list_set_enter_callback(
|
||||
variable_item_list, subghz_ext_module_start_var_list_enter_callback, subghz);
|
||||
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, radio_modules_variables_text[value_index]);
|
||||
|
||||
uint8_t value_count_device = RADIO_DEVICE_COUNT;
|
||||
if(subghz_txrx_radio_device_get(subghz->txrx) == SubGhzRadioDeviceTypeInternal &&
|
||||
!subghz_txrx_radio_device_is_external_connected(subghz->txrx, SUBGHZ_DEVICE_CC1101_EXT_NAME))
|
||||
value_count_device = 1; // Only 1 item if external disconnected
|
||||
item = variable_item_list_add(
|
||||
subghz->variable_item_list,
|
||||
"Ext Radio 5v",
|
||||
EXT_MOD_POWER_COUNT,
|
||||
subghz_scene_receiver_config_set_ext_mod_power,
|
||||
"Module",
|
||||
value_count_device,
|
||||
subghz_scene_radio_settings_set_device,
|
||||
subghz);
|
||||
value_index = furi_hal_subghz_get_external_power_disable();
|
||||
value_index = value_index_uint32(
|
||||
subghz_txrx_radio_device_get(subghz->txrx), radio_device_value, value_count_device);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, ext_mod_power_text[value_index]);
|
||||
variable_item_set_current_value_text(item, radio_device_text[value_index]);
|
||||
|
||||
item = variable_item_list_add(
|
||||
subghz->variable_item_list,
|
||||
variable_item_list,
|
||||
"Time in names",
|
||||
TIMESTAMP_NAMES_COUNT,
|
||||
subghz_scene_receiver_config_set_timestamp_file_names,
|
||||
@@ -153,7 +149,7 @@ void subghz_scene_radio_settings_on_enter(void* context) {
|
||||
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||
item = variable_item_list_add(
|
||||
subghz->variable_item_list,
|
||||
variable_item_list,
|
||||
"Counter incr.",
|
||||
DEBUG_COUNTER_COUNT,
|
||||
subghz_scene_receiver_config_set_debug_counter,
|
||||
@@ -182,7 +178,7 @@ void subghz_scene_radio_settings_on_enter(void* context) {
|
||||
}
|
||||
} else {
|
||||
item = variable_item_list_add(
|
||||
subghz->variable_item_list,
|
||||
variable_item_list,
|
||||
"Counter incr.",
|
||||
3,
|
||||
subghz_scene_receiver_config_set_debug_counter,
|
||||
@@ -208,7 +204,7 @@ void subghz_scene_radio_settings_on_enter(void* context) {
|
||||
variable_item_set_current_value_text(item, debug_counter_text[value_index]);
|
||||
|
||||
item = variable_item_list_add(
|
||||
subghz->variable_item_list,
|
||||
variable_item_list,
|
||||
"Debug Pin",
|
||||
DEBUG_P_COUNT,
|
||||
subghz_scene_receiver_config_set_debug_pin,
|
||||
@@ -227,25 +223,11 @@ bool subghz_scene_radio_settings_on_event(void* context, SceneManagerEvent event
|
||||
UNUSED(subghz);
|
||||
UNUSED(event);
|
||||
|
||||
// Set selected radio module
|
||||
furi_hal_subghz_select_radio_type(subghz->last_settings->external_module_enabled);
|
||||
furi_hal_subghz_init_radio_type(subghz->last_settings->external_module_enabled);
|
||||
|
||||
furi_hal_subghz_enable_ext_power();
|
||||
|
||||
// Check if module is present, if no -> show error
|
||||
if(!furi_hal_subghz_check_radio()) {
|
||||
subghz->last_settings->external_module_enabled = false;
|
||||
furi_hal_subghz_select_radio_type(SubGhzRadioInternal);
|
||||
furi_hal_subghz_init_radio_type(SubGhzRadioInternal);
|
||||
furi_string_set(subghz->error_str, "Please connect\nexternal radio");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void subghz_scene_radio_settings_on_exit(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
variable_item_list_set_selected_item(subghz->variable_item_list, 0);
|
||||
variable_item_list_reset(subghz->variable_item_list);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,9 @@ static void subghz_scene_receiver_update_statusbar(void* context) {
|
||||
furi_string_printf(
|
||||
modulation_str,
|
||||
"%s Mod: %s",
|
||||
furi_hal_subghz_get_radio_type() ? "Ext" : "Int",
|
||||
(subghz_txrx_radio_device_get(subghz->txrx) == SubGhzRadioDeviceTypeInternal) ?
|
||||
"Int" :
|
||||
"Ext",
|
||||
furi_string_get_cstr(temp_str));
|
||||
furi_string_free(temp_str);
|
||||
}
|
||||
@@ -253,8 +255,8 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz_scene_receiver_update_statusbar(subghz);
|
||||
}
|
||||
|
||||
//get RSSI
|
||||
SubGhzThresholdRssiData ret_rssi = subghz_threshold_get_rssi_data(subghz->threshold_rssi);
|
||||
SubGhzThresholdRssiData ret_rssi = subghz_threshold_get_rssi_data(
|
||||
subghz->threshold_rssi, subghz_txrx_radio_device_get_rssi(subghz->txrx));
|
||||
|
||||
subghz_receiver_rssi(subghz->subghz_receiver, ret_rssi.rssi);
|
||||
subghz_protocol_decoder_bin_raw_data_input_rssi(
|
||||
|
||||
@@ -91,6 +91,12 @@ void subghz_scene_set_type_on_enter(void* context) {
|
||||
SubmenuIndexAllmatic868,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: Centurion 433MHz",
|
||||
SubmenuIndexCenturion433,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: Sommer 434MHz",
|
||||
@@ -444,6 +450,15 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexCenturion433:
|
||||
generated_protocol = subghz_txrx_gen_keeloq_protocol(
|
||||
subghz->txrx, "AM650", 433920000, (key & 0x0000FFFF), 0x2, 0x0003, "Centurion");
|
||||
if(!generated_protocol) {
|
||||
furi_string_set(
|
||||
subghz->error_str, "Function requires\nan SD card with\nfresh databases.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexElmesElectronic:
|
||||
generated_protocol = subghz_txrx_gen_keeloq_protocol(
|
||||
subghz->txrx,
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
enum SubmenuIndex {
|
||||
SubmenuIndexRead = 10,
|
||||
SubmenuIndexSaved,
|
||||
SubmenuIndexTest,
|
||||
SubmenuIndexAddManually,
|
||||
SubmenuIndexFrequencyAnalyzer,
|
||||
SubmenuIndexReadRAW,
|
||||
SubmenuIndexExtSettings,
|
||||
SubmenuIndexRadioSetting,
|
||||
};
|
||||
|
||||
void subghz_scene_start_submenu_callback(void* context, uint32_t index) {
|
||||
@@ -52,14 +52,6 @@ void subghz_scene_start_on_enter(void* context) {
|
||||
SubmenuIndexExtSettings,
|
||||
subghz_scene_start_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_lockable_item(
|
||||
subghz->submenu,
|
||||
"Test",
|
||||
SubmenuIndexTest,
|
||||
subghz_scene_start_submenu_callback,
|
||||
subghz,
|
||||
!furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug),
|
||||
"Enable\nDebug!");
|
||||
submenu_set_selected_item(
|
||||
subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneStart));
|
||||
|
||||
@@ -74,54 +66,38 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
view_dispatcher_stop(subghz->view_dispatcher);
|
||||
return true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubmenuIndexExtSettings) {
|
||||
if(event.event == SubmenuIndexReadRAW) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexExtSettings);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneExtModuleSettings);
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW);
|
||||
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexRead) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRead);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexSaved) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexSaved);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexAddManually) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexAddManually);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetType);
|
||||
return true;
|
||||
} else {
|
||||
furi_hal_subghz_enable_ext_power();
|
||||
|
||||
if(!furi_hal_subghz_check_radio()) {
|
||||
furi_hal_subghz_select_radio_type(SubGhzRadioInternal);
|
||||
furi_hal_subghz_init_radio_type(SubGhzRadioInternal);
|
||||
subghz->last_settings->external_module_enabled = false;
|
||||
furi_string_set(subghz->error_str, "Please connect\nexternal radio");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexReadRAW) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW);
|
||||
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexRead) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRead);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexSaved) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexSaved);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexFrequencyAnalyzer) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer);
|
||||
dolphin_deed(DolphinDeedSubGhzFrequencyAnalyzer);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexTest) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexTest);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTest);
|
||||
return true;
|
||||
}
|
||||
} else if(event.event == SubmenuIndexFrequencyAnalyzer) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer);
|
||||
dolphin_deed(DolphinDeedSubGhzFrequencyAnalyzer);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexExtSettings) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexExtSettings);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneExtModuleSettings);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
#include "../subghz_i.h"
|
||||
|
||||
enum SubmenuIndex {
|
||||
SubmenuIndexCarrier,
|
||||
SubmenuIndexPacket,
|
||||
SubmenuIndexStatic,
|
||||
};
|
||||
|
||||
void subghz_scene_test_submenu_callback(void* context, uint32_t index) {
|
||||
SubGhz* subghz = context;
|
||||
view_dispatcher_send_custom_event(subghz->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void subghz_scene_test_on_enter(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"Carrier",
|
||||
SubmenuIndexCarrier,
|
||||
subghz_scene_test_submenu_callback,
|
||||
subghz);
|
||||
#if FURI_DEBUG
|
||||
submenu_add_item(
|
||||
subghz->submenu, "Packet", SubmenuIndexPacket, subghz_scene_test_submenu_callback, subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu, "Static", SubmenuIndexStatic, subghz_scene_test_submenu_callback, subghz);
|
||||
#endif
|
||||
submenu_set_selected_item(
|
||||
subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneTest));
|
||||
|
||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdMenu);
|
||||
}
|
||||
|
||||
bool subghz_scene_test_on_event(void* context, SceneManagerEvent event) {
|
||||
SubGhz* subghz = context;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubmenuIndexCarrier) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneTest, SubmenuIndexCarrier);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTestCarrier);
|
||||
return true;
|
||||
}
|
||||
#if FURI_DEBUG
|
||||
else if(event.event == SubmenuIndexPacket) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneTest, SubmenuIndexPacket);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTestPacket);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexStatic) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneTest, SubmenuIndexStatic);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTestStatic);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void subghz_scene_test_on_exit(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
submenu_reset(subghz->submenu);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#include "../subghz_i.h"
|
||||
#include "../views/subghz_test_carrier.h"
|
||||
|
||||
void subghz_scene_test_carrier_callback(SubGhzTestCarrierEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
SubGhz* subghz = context;
|
||||
view_dispatcher_send_custom_event(subghz->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void subghz_scene_test_carrier_on_enter(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
subghz_test_carrier_set_callback(
|
||||
subghz->subghz_test_carrier, subghz_scene_test_carrier_callback, subghz);
|
||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdTestCarrier);
|
||||
}
|
||||
|
||||
bool subghz_scene_test_carrier_on_event(void* context, SceneManagerEvent event) {
|
||||
SubGhz* subghz = context;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubGhzTestCarrierEventOnlyRx) {
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void subghz_scene_test_carrier_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#if FURI_DEBUG
|
||||
#include "../subghz_i.h"
|
||||
#include "../views/subghz_test_packet.h"
|
||||
|
||||
void subghz_scene_test_packet_callback(SubGhzTestPacketEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
SubGhz* subghz = context;
|
||||
view_dispatcher_send_custom_event(subghz->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void subghz_scene_test_packet_on_enter(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
subghz_test_packet_set_callback(
|
||||
subghz->subghz_test_packet, subghz_scene_test_packet_callback, subghz);
|
||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdTestPacket);
|
||||
}
|
||||
|
||||
bool subghz_scene_test_packet_on_event(void* context, SceneManagerEvent event) {
|
||||
SubGhz* subghz = context;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubGhzTestPacketEventOnlyRx) {
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void subghz_scene_test_packet_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
}
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
#if FURI_DEBUG
|
||||
#include "../subghz_i.h"
|
||||
#include "../views/subghz_test_static.h"
|
||||
|
||||
void subghz_scene_test_static_callback(SubGhzTestStaticEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
SubGhz* subghz = context;
|
||||
view_dispatcher_send_custom_event(subghz->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void subghz_scene_test_static_on_enter(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
subghz_test_static_set_callback(
|
||||
subghz->subghz_test_static, subghz_scene_test_static_callback, subghz);
|
||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdStatic);
|
||||
}
|
||||
|
||||
bool subghz_scene_test_static_on_event(void* context, SceneManagerEvent event) {
|
||||
SubGhz* subghz = context;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubGhzTestStaticEventOnlyRx) {
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void subghz_scene_test_static_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
}
|
||||
#endif
|
||||
@@ -114,6 +114,8 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
|
||||
// Open Notification record
|
||||
subghz->notifications = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
subghz->txrx = subghz_txrx_alloc();
|
||||
|
||||
if(!alloc_for_tx_only) {
|
||||
// SubMenu
|
||||
subghz->submenu = submenu_alloc();
|
||||
@@ -169,18 +171,12 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
|
||||
variable_item_list_get_view(subghz->variable_item_list));
|
||||
|
||||
// Frequency Analyzer
|
||||
subghz->subghz_frequency_analyzer = subghz_frequency_analyzer_alloc();
|
||||
// View knows too much
|
||||
subghz->subghz_frequency_analyzer = subghz_frequency_analyzer_alloc(subghz->txrx);
|
||||
view_dispatcher_add_view(
|
||||
subghz->view_dispatcher,
|
||||
SubGhzViewIdFrequencyAnalyzer,
|
||||
subghz_frequency_analyzer_get_view(subghz->subghz_frequency_analyzer));
|
||||
|
||||
// Carrier Test Module
|
||||
subghz->subghz_test_carrier = subghz_test_carrier_alloc();
|
||||
view_dispatcher_add_view(
|
||||
subghz->view_dispatcher,
|
||||
SubGhzViewIdTestCarrier,
|
||||
subghz_test_carrier_get_view(subghz->subghz_test_carrier));
|
||||
}
|
||||
// Read RAW
|
||||
subghz->subghz_read_raw = subghz_read_raw_alloc(alloc_for_tx_only);
|
||||
@@ -189,30 +185,12 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
|
||||
SubGhzViewIdReadRAW,
|
||||
subghz_read_raw_get_view(subghz->subghz_read_raw));
|
||||
|
||||
#if FURI_DEBUG
|
||||
// Packet Test
|
||||
subghz->subghz_test_packet = subghz_test_packet_alloc();
|
||||
view_dispatcher_add_view(
|
||||
subghz->view_dispatcher,
|
||||
SubGhzViewIdTestPacket,
|
||||
subghz_test_packet_get_view(subghz->subghz_test_packet));
|
||||
|
||||
// Static send
|
||||
subghz->subghz_test_static = subghz_test_static_alloc();
|
||||
view_dispatcher_add_view(
|
||||
subghz->view_dispatcher,
|
||||
SubGhzViewIdStatic,
|
||||
subghz_test_static_get_view(subghz->subghz_test_static));
|
||||
#endif
|
||||
|
||||
//init threshold rssi
|
||||
subghz->threshold_rssi = subghz_threshold_rssi_alloc();
|
||||
|
||||
//init TxRx & Protocol & History & KeyBoard
|
||||
subghz_unlock(subghz);
|
||||
|
||||
subghz->txrx = subghz_txrx_alloc();
|
||||
|
||||
SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx);
|
||||
|
||||
subghz_load_custom_presets(setting);
|
||||
@@ -268,21 +246,7 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) {
|
||||
subghz_txrx_stop(subghz->txrx);
|
||||
subghz_txrx_sleep(subghz->txrx);
|
||||
|
||||
#if FURI_DEBUG
|
||||
// Packet Test
|
||||
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTestPacket);
|
||||
subghz_test_packet_free(subghz->subghz_test_packet);
|
||||
|
||||
// Static
|
||||
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdStatic);
|
||||
subghz_test_static_free(subghz->subghz_test_static);
|
||||
#endif
|
||||
|
||||
if(!alloc_for_tx_only) {
|
||||
// Carrier Test
|
||||
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTestCarrier);
|
||||
subghz_test_carrier_free(subghz->subghz_test_carrier);
|
||||
|
||||
// Receiver
|
||||
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdReceiver);
|
||||
subghz_view_receiver_free(subghz->subghz_receiver);
|
||||
@@ -381,15 +345,6 @@ int32_t subghz_app(char* p) {
|
||||
subghz->raw_send_only = false;
|
||||
}
|
||||
|
||||
// Call enable power for external module
|
||||
furi_hal_subghz_enable_ext_power();
|
||||
|
||||
// Auto switch to internal radio if external radio is not available
|
||||
if(!furi_hal_subghz_check_radio()) {
|
||||
subghz->last_settings->external_module_enabled = false;
|
||||
furi_hal_subghz_select_radio_type(SubGhzRadioInternal);
|
||||
furi_hal_subghz_init_radio_type(SubGhzRadioInternal);
|
||||
}
|
||||
// Check argument and run corresponding scene
|
||||
bool is_favorite = process_favorite_launch(&p) && XTREME_SETTINGS()->favorite_timeout;
|
||||
if(p && strlen(p)) {
|
||||
@@ -449,10 +404,6 @@ int32_t subghz_app(char* p) {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
subghz_free(subghz, alloc_for_tx);
|
||||
|
||||
|
||||
@@ -19,6 +19,32 @@
|
||||
#define SUBGHZ_FREQUENCY_RANGE_STR \
|
||||
"299999755...348000000 or 386999938...464000000 or 778999847...928000000"
|
||||
|
||||
// Tx/Rx Carrier | only internal module
|
||||
// Tx/Rx command | both
|
||||
// Rx RAW | only internal module
|
||||
// Chat | both
|
||||
|
||||
#define TAG "SubGhz CLI"
|
||||
|
||||
static void subghz_cli_radio_device_power_on() {
|
||||
uint8_t attempts = 5;
|
||||
while(--attempts > 0) {
|
||||
if(furi_hal_power_enable_otg()) break;
|
||||
}
|
||||
if(attempts == 0) {
|
||||
if(furi_hal_power_get_usb_voltage() < 4.5f) {
|
||||
FURI_LOG_E(
|
||||
"TAG",
|
||||
"Error power otg enable. BQ2589 check otg fault = %d",
|
||||
furi_hal_power_check_otg_fault() ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void subghz_cli_radio_device_power_off() {
|
||||
if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
|
||||
}
|
||||
|
||||
void subghz_cli_command_tx_carrier(Cli* cli, FuriString* args, void* context) {
|
||||
UNUSED(context);
|
||||
uint32_t frequency = 433920000;
|
||||
@@ -42,9 +68,8 @@ void subghz_cli_command_tx_carrier(Cli* cli, FuriString* args, void* context) {
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
|
||||
|
||||
furi_hal_gpio_init(
|
||||
furi_hal_subghz.cc1101_g0_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||
furi_hal_gpio_write(furi_hal_subghz.cc1101_g0_pin, true);
|
||||
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||
furi_hal_gpio_write(&gpio_cc1101_g0, true);
|
||||
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
|
||||
@@ -105,6 +130,27 @@ void subghz_cli_command_rx_carrier(Cli* cli, FuriString* args, void* context) {
|
||||
furi_hal_subghz_sleep();
|
||||
}
|
||||
|
||||
static const SubGhzDevice* subghz_cli_command_get_device(uint32_t* device_ind) {
|
||||
const SubGhzDevice* device = NULL;
|
||||
switch(*device_ind) {
|
||||
case 1:
|
||||
subghz_cli_radio_device_power_on();
|
||||
device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME);
|
||||
break;
|
||||
|
||||
default:
|
||||
device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
|
||||
break;
|
||||
}
|
||||
//check if the device is connected
|
||||
if(!subghz_devices_is_connect(device)) {
|
||||
subghz_cli_radio_device_power_off();
|
||||
device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
|
||||
*device_ind = 0;
|
||||
}
|
||||
return device;
|
||||
}
|
||||
|
||||
void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) {
|
||||
UNUSED(context);
|
||||
uint32_t frequency = 433920000;
|
||||
@@ -129,14 +175,16 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) {
|
||||
furi_string_get_cstr(args));
|
||||
return;
|
||||
}
|
||||
if(!furi_hal_subghz_is_frequency_valid(frequency)) {
|
||||
printf(
|
||||
"Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n",
|
||||
frequency);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
subghz_devices_init();
|
||||
const SubGhzDevice* device = subghz_cli_command_get_device(&device_ind);
|
||||
if(!subghz_devices_is_frequency_valid(device, frequency)) {
|
||||
printf(
|
||||
"Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", frequency);
|
||||
subghz_devices_deinit();
|
||||
subghz_cli_radio_device_power_off();
|
||||
return;
|
||||
}
|
||||
printf(
|
||||
"Transmitting at %lu, key %lx, te %lu, repeat %lu. Press CTRL+C to stop\r\n",
|
||||
frequency,
|
||||
@@ -181,7 +229,7 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) {
|
||||
furi_hal_subghz_stop_async_tx();
|
||||
|
||||
} else {
|
||||
printf("Transmission on this frequency is restricted in your region\r\n");
|
||||
printf("Frequency is outside of default range. Check docs.\r\n");
|
||||
}
|
||||
|
||||
furi_hal_subghz_sleep();
|
||||
@@ -236,12 +284,15 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
|
||||
cli_print_usage("subghz rx", "<Frequency: in Hz>", furi_string_get_cstr(args));
|
||||
return;
|
||||
}
|
||||
if(!furi_hal_subghz_is_frequency_valid(frequency)) {
|
||||
printf(
|
||||
"Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n",
|
||||
frequency);
|
||||
return;
|
||||
}
|
||||
}
|
||||
subghz_devices_init();
|
||||
const SubGhzDevice* device = subghz_cli_command_get_device(&device_ind);
|
||||
if(!subghz_devices_is_frequency_valid(device, frequency)) {
|
||||
printf(
|
||||
"Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", frequency);
|
||||
subghz_devices_deinit();
|
||||
subghz_cli_radio_device_power_off();
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate context and buffers
|
||||
@@ -266,10 +317,10 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
|
||||
subghz_receiver_set_rx_callback(receiver, subghz_cli_command_rx_callback, instance);
|
||||
|
||||
// Configure radio
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
|
||||
furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
subghz_devices_begin(device);
|
||||
subghz_devices_reset(device);
|
||||
subghz_devices_load_preset(device, FuriHalSubGhzPresetOok650Async, NULL);
|
||||
frequency = subghz_devices_set_frequency(device, frequency);
|
||||
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
|
||||
@@ -336,9 +387,9 @@ void subghz_cli_command_rx_raw(Cli* cli, FuriString* args, void* context) {
|
||||
|
||||
// Configure radio
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok270Async);
|
||||
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_ook_650khz_async_regs);
|
||||
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
|
||||
furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
|
||||
@@ -609,13 +660,18 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args, void* context) {
|
||||
cli_print_usage("subghz chat", "<Frequency: in Hz>", furi_string_get_cstr(args));
|
||||
return;
|
||||
}
|
||||
if(!furi_hal_subghz_is_frequency_valid(frequency)) {
|
||||
printf(
|
||||
"Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n",
|
||||
frequency);
|
||||
return;
|
||||
}
|
||||
}
|
||||
subghz_devices_init();
|
||||
const SubGhzDevice* device = subghz_cli_command_get_device(&device_ind);
|
||||
if(!subghz_devices_is_frequency_valid(device, frequency)) {
|
||||
printf(
|
||||
"Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", frequency);
|
||||
subghz_devices_deinit();
|
||||
subghz_cli_radio_device_power_off();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
if(!furi_hal_subghz_is_tx_allowed(frequency)) {
|
||||
printf(
|
||||
"In your settings, only reception on this frequency (%lu) is allowed,\r\n"
|
||||
@@ -780,15 +836,6 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args, void* context) {
|
||||
static void subghz_cli_command(Cli* cli, FuriString* args, void* context) {
|
||||
FuriString* cmd = furi_string_alloc();
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
do {
|
||||
if(!args_read_string_and_trim(args, cmd)) {
|
||||
subghz_cli_command_print_usage();
|
||||
@@ -845,11 +892,6 @@ static void subghz_cli_command(Cli* cli, FuriString* args, void* context) {
|
||||
subghz_cli_command_print_usage();
|
||||
} while(false);
|
||||
|
||||
// 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);
|
||||
|
||||
furi_string_free(cmd);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) {
|
||||
subghz->dialogs, "Error in protocol\nparameters\ndescription");
|
||||
break;
|
||||
case SubGhzTxRxStartTxStateErrorOnlyRx:
|
||||
subghz_dialog_message_show_only_rx(subghz);
|
||||
subghz_dialog_message_freq_error(subghz, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -56,12 +56,16 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void subghz_dialog_message_show_only_rx(SubGhz* subghz) {
|
||||
void subghz_dialog_message_freq_error(SubGhz* subghz, bool only_rx) {
|
||||
DialogsApp* dialogs = subghz->dialogs;
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
const char* header_text = "Frequency not supported";
|
||||
const char* message_text = "Frequency\nis outside of\nsuported range.";
|
||||
|
||||
const char* header_text = "Transmission is blocked";
|
||||
const char* message_text = "Frequency\nis outside of\ndefault range.\nCheck docs.";
|
||||
if(only_rx) {
|
||||
header_text = "Transmission is blocked";
|
||||
message_text = "Frequency\nis outside of\ndefault range.\nCheck docs.";
|
||||
}
|
||||
|
||||
dialog_message_set_header(message, header_text, 63, 3, AlignCenter, AlignTop);
|
||||
dialog_message_set_text(message, message_text, 0, 17, AlignLeft, AlignTop);
|
||||
@@ -111,13 +115,14 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!furi_hal_subghz_is_frequency_valid(temp_data32)) {
|
||||
FURI_LOG_E(TAG, "Frequency not supported");
|
||||
if(!subghz_txrx_radio_device_is_frequecy_valid(subghz->txrx, temp_data32)) {
|
||||
FURI_LOG_E(TAG, "Frequency not supported on chosen radio module");
|
||||
load_key_state = SubGhzLoadKeyStateUnsuportedFreq;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!furi_hal_subghz_is_tx_allowed(temp_data32)) {
|
||||
FURI_LOG_E(TAG, "This frequency can only be used for RX");
|
||||
if(!subghz_txrx_radio_device_is_tx_alowed(subghz->txrx, temp_data32)) {
|
||||
FURI_LOG_E(TAG, "This frequency can only be used for RX on chosen radio module");
|
||||
load_key_state = SubGhzLoadKeyStateOnlyRx;
|
||||
break;
|
||||
}
|
||||
@@ -206,9 +211,15 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
|
||||
}
|
||||
return false;
|
||||
|
||||
case SubGhzLoadKeyStateUnsuportedFreq:
|
||||
if(show_dialog) {
|
||||
subghz_dialog_message_freq_error(subghz, false);
|
||||
}
|
||||
return false;
|
||||
|
||||
case SubGhzLoadKeyStateOnlyRx:
|
||||
if(show_dialog) {
|
||||
subghz_dialog_message_show_only_rx(subghz);
|
||||
subghz_dialog_message_freq_error(subghz, true);
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
@@ -9,11 +9,6 @@
|
||||
#include "views/subghz_frequency_analyzer.h"
|
||||
#include "views/subghz_read_raw.h"
|
||||
|
||||
#include "views/subghz_test_carrier.h"
|
||||
#if FURI_DEBUG
|
||||
#include "views/subghz_test_static.h"
|
||||
#include "views/subghz_test_packet.h"
|
||||
#endif
|
||||
#include <gui/gui.h>
|
||||
#include <assets_icons.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
@@ -81,11 +76,7 @@ struct SubGhz {
|
||||
SubGhzFrequencyAnalyzer* subghz_frequency_analyzer;
|
||||
SubGhzReadRAW* subghz_read_raw;
|
||||
bool raw_send_only;
|
||||
SubGhzTestCarrier* subghz_test_carrier;
|
||||
#if FURI_DEBUG
|
||||
SubGhzTestStatic* subghz_test_static;
|
||||
SubGhzTestPacket* subghz_test_packet;
|
||||
#endif
|
||||
|
||||
SubGhzLastSettings* last_settings;
|
||||
|
||||
SubGhzProtocolFlag filter;
|
||||
@@ -115,7 +106,7 @@ void subghz_blink_start(SubGhz* subghz);
|
||||
void subghz_blink_stop(SubGhz* subghz);
|
||||
|
||||
bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format);
|
||||
void subghz_dialog_message_show_only_rx(SubGhz* subghz);
|
||||
void subghz_dialog_message_freq_error(SubGhz* subghz, bool only_rx);
|
||||
|
||||
bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog);
|
||||
bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len);
|
||||
|
||||
@@ -119,17 +119,6 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
|
||||
|
||||
instance->timestamp_file_names = temp_timestamp_file_names;
|
||||
|
||||
if(instance->external_module_power_5v_disable) {
|
||||
furi_hal_subghz_set_external_power_disable(true);
|
||||
furi_hal_subghz_disable_ext_power();
|
||||
}
|
||||
|
||||
// Set selected radio module
|
||||
if(instance->external_module_enabled) {
|
||||
furi_hal_subghz_select_radio_type(SubGhzRadioExternal);
|
||||
furi_hal_subghz_init_radio_type(SubGhzRadioExternal);
|
||||
}
|
||||
|
||||
/*/} else {
|
||||
instance->preset = temp_preset;
|
||||
}*/
|
||||
|
||||
@@ -10,8 +10,10 @@ typedef struct {
|
||||
int32_t preset;
|
||||
uint32_t frequency_analyzer_feedback_level;
|
||||
float frequency_analyzer_trigger;
|
||||
// TODO not using but saved so as not to change the version
|
||||
bool external_module_enabled;
|
||||
bool external_module_power_5v_disable;
|
||||
// saved so as not to change the version
|
||||
bool timestamp_file_names;
|
||||
} SubGhzLastSettings;
|
||||
|
||||
|
||||
@@ -69,7 +69,11 @@ typedef struct {
|
||||
SubGhzViewReceiverBarShow bar_show;
|
||||
SubGhzViewReceiverMode mode;
|
||||
uint8_t u_rssi;
|
||||
|
||||
SubGhzRadioDeviceType device_type;
|
||||
|
||||
bool show_time;
|
||||
|
||||
bool nodraw;
|
||||
} SubGhzViewReceiverModel;
|
||||
|
||||
@@ -220,6 +224,17 @@ void subghz_view_receiver_add_data_progress(
|
||||
true);
|
||||
}
|
||||
|
||||
void subghz_view_receiver_set_radio_device_type(
|
||||
SubGhzViewReceiver* subghz_receiver,
|
||||
SubGhzRadioDeviceType device_type) {
|
||||
furi_assert(subghz_receiver);
|
||||
with_view_model(
|
||||
subghz_receiver->view,
|
||||
SubGhzViewReceiverModel * model,
|
||||
{ model->device_type = device_type; },
|
||||
true);
|
||||
}
|
||||
|
||||
static void subghz_view_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);
|
||||
@@ -296,12 +311,14 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
|
||||
if(model->history_item == 0) {
|
||||
// TODO
|
||||
if(model->mode == SubGhzViewReceiverModeLive) {
|
||||
canvas_draw_icon(
|
||||
canvas,
|
||||
0,
|
||||
0,
|
||||
furi_hal_subghz_get_radio_type() ? &I_Fishing_123x52 : &I_Scanning_123x52);
|
||||
(model->device_type == SubGhzRadioDeviceTypeInternal) ? &I_Scanning_123x52 :
|
||||
&I_Fishing_123x52);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 63, 46, "Scanning...");
|
||||
//canvas_draw_line(canvas, 46, 51, 125, 51);
|
||||
@@ -311,7 +328,8 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
||||
canvas,
|
||||
0,
|
||||
0,
|
||||
furi_hal_subghz_get_radio_type() ? &I_Fishing_123x52 : &I_Scanning_123x52);
|
||||
(model->device_type == SubGhzRadioDeviceTypeInternal) ? &I_Scanning_123x52 :
|
||||
&I_Fishing_123x52);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 63, 46, "Decoding...");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
@@ -33,6 +33,10 @@ void subghz_view_receiver_add_data_statusbar(
|
||||
const char* preset_str,
|
||||
const char* history_stat_str);
|
||||
|
||||
void subghz_view_receiver_set_radio_device_type(
|
||||
SubGhzViewReceiver* subghz_receiver,
|
||||
SubGhzRadioDeviceType device_type);
|
||||
|
||||
void subghz_view_receiver_add_data_progress(
|
||||
SubGhzViewReceiver* subghz_receiver,
|
||||
const char* progress_str);
|
||||
|
||||
@@ -38,6 +38,7 @@ struct SubGhzFrequencyAnalyzer {
|
||||
SubGhzFrequencyAnalyzerWorker* worker;
|
||||
SubGhzFrequencyAnalyzerCallback callback;
|
||||
void* context;
|
||||
SubGhzTxRx* txrx;
|
||||
bool locked;
|
||||
SubGHzFrequencyAnalyzerFeedbackLevel
|
||||
feedback_level; // 0 - no feedback, 1 - vibro only, 2 - vibro and sound
|
||||
@@ -60,6 +61,7 @@ typedef struct {
|
||||
uint8_t selected_index;
|
||||
uint8_t max_index;
|
||||
bool show_frame;
|
||||
bool is_ext_radio;
|
||||
} SubGhzFrequencyAnalyzerModel;
|
||||
|
||||
void subghz_frequency_analyzer_set_callback(
|
||||
@@ -166,7 +168,8 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel
|
||||
// Title
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(canvas, 0, 7, furi_hal_subghz_get_radio_type() ? "Ext" : "Int");
|
||||
|
||||
canvas_draw_str(canvas, 0, 7, model->is_ext_radio ? "Ext" : "Int");
|
||||
canvas_draw_str(canvas, 20, 7, "Frequency Analyzer");
|
||||
|
||||
// RSSI
|
||||
@@ -311,7 +314,9 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
|
||||
uint32_t prev_freq_to_save = model->frequency_to_save;
|
||||
uint32_t frequency_candidate = model->history_frequency[model->selected_index];
|
||||
if(frequency_candidate == 0 ||
|
||||
!furi_hal_subghz_is_frequency_valid(frequency_candidate) ||
|
||||
// !furi_hal_subghz_is_frequency_valid(frequency_candidate) ||
|
||||
!subghz_txrx_radio_device_is_frequecy_valid(
|
||||
instance->txrx, frequency_candidate) ||
|
||||
prev_freq_to_save == frequency_candidate) {
|
||||
frequency_candidate = 0;
|
||||
} else {
|
||||
@@ -333,7 +338,9 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
|
||||
uint32_t prev_freq_to_save = model->frequency_to_save;
|
||||
uint32_t frequency_candidate = subghz_frequency_find_correct(model->frequency);
|
||||
if(frequency_candidate == 0 ||
|
||||
!furi_hal_subghz_is_frequency_valid(frequency_candidate) ||
|
||||
// !furi_hal_subghz_is_frequency_valid(frequency_candidate) ||
|
||||
!subghz_txrx_radio_device_is_frequecy_valid(
|
||||
instance->txrx, frequency_candidate) ||
|
||||
prev_freq_to_save == frequency_candidate) {
|
||||
frequency_candidate = 0;
|
||||
} else {
|
||||
@@ -348,7 +355,9 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
|
||||
uint32_t prev_freq_to_save = model->frequency_to_save;
|
||||
uint32_t frequency_candidate = subghz_frequency_find_correct(model->frequency);
|
||||
if(frequency_candidate == 0 ||
|
||||
!furi_hal_subghz_is_frequency_valid(frequency_candidate) ||
|
||||
// !furi_hal_subghz_is_frequency_valid(frequency_candidate) ||
|
||||
!subghz_txrx_radio_device_is_frequecy_valid(
|
||||
instance->txrx, frequency_candidate) ||
|
||||
prev_freq_to_save == frequency_candidate) {
|
||||
frequency_candidate = 0;
|
||||
} else {
|
||||
@@ -539,7 +548,7 @@ void subghz_frequency_analyzer_enter(void* context) {
|
||||
(SubGhzFrequencyAnalyzerWorkerPairCallback)subghz_frequency_analyzer_pair_callback,
|
||||
instance);
|
||||
|
||||
subghz_frequency_analyzer_worker_start(instance->worker);
|
||||
subghz_frequency_analyzer_worker_start(instance->worker, instance->txrx);
|
||||
|
||||
instance->rssi_last = 0;
|
||||
instance->selected_index = 0;
|
||||
@@ -567,6 +576,8 @@ void subghz_frequency_analyzer_enter(void* context) {
|
||||
model->history_frequency_rx_count[0] = 0;
|
||||
model->frequency_to_save = 0;
|
||||
model->trigger = RSSI_MIN;
|
||||
model->is_ext_radio =
|
||||
(subghz_txrx_radio_device_get(instance->txrx) != SubGhzRadioDeviceTypeInternal);
|
||||
},
|
||||
true);
|
||||
}
|
||||
@@ -584,7 +595,7 @@ void subghz_frequency_analyzer_exit(void* context) {
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
}
|
||||
|
||||
SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc() {
|
||||
SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc(SubGhzTxRx* txrx) {
|
||||
SubGhzFrequencyAnalyzer* instance = malloc(sizeof(SubGhzFrequencyAnalyzer));
|
||||
|
||||
instance->feedback_level = 2;
|
||||
@@ -599,6 +610,8 @@ SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc() {
|
||||
view_set_enter_callback(instance->view, subghz_frequency_analyzer_enter);
|
||||
view_set_exit_callback(instance->view, subghz_frequency_analyzer_exit);
|
||||
|
||||
instance->txrx = txrx;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <gui/view.h>
|
||||
#include "../helpers/subghz_custom_event.h"
|
||||
#include "../helpers/subghz_txrx.h"
|
||||
|
||||
typedef enum {
|
||||
SubGHzFrequencyAnalyzerFeedbackLevelAll,
|
||||
@@ -18,7 +19,7 @@ void subghz_frequency_analyzer_set_callback(
|
||||
SubGhzFrequencyAnalyzerCallback callback,
|
||||
void* context);
|
||||
|
||||
SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc();
|
||||
SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc(SubGhzTxRx* txrx);
|
||||
|
||||
void subghz_frequency_analyzer_free(SubGhzFrequencyAnalyzer* subghz_static);
|
||||
|
||||
|
||||
@@ -11,6 +11,29 @@
|
||||
#define SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE 100
|
||||
#define TAG "SubGhzReadRAW"
|
||||
|
||||
struct SubGhzReadRAW {
|
||||
View* view;
|
||||
SubGhzReadRAWCallback callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
FuriString* frequency_str;
|
||||
FuriString* preset_str;
|
||||
FuriString* sample_write;
|
||||
FuriString* file_name;
|
||||
uint8_t* rssi_history;
|
||||
uint8_t rssi_current;
|
||||
bool rssi_history_end;
|
||||
uint8_t ind_write;
|
||||
uint8_t ind_sin;
|
||||
SubGhzReadRAWStatus status;
|
||||
bool raw_send_only;
|
||||
float raw_threshold_rssi;
|
||||
bool not_showing_samples;
|
||||
SubGhzRadioDeviceType device_type;
|
||||
} SubGhzReadRAWModel;
|
||||
|
||||
void subghz_read_raw_set_callback(
|
||||
SubGhzReadRAW* subghz_read_raw,
|
||||
SubGhzReadRAWCallback callback,
|
||||
@@ -266,9 +289,15 @@ void subghz_read_raw_draw(Canvas* canvas, SubGhzReadRAWModel* model) {
|
||||
canvas_draw_str(canvas, 35, 7, furi_string_get_cstr(model->preset_str));
|
||||
|
||||
if(model->not_showing_samples) {
|
||||
canvas_draw_str(canvas, 77, 7, furi_hal_subghz_get_radio_type() ? "R: Ext" : "R: Int");
|
||||
// TODO
|
||||
canvas_draw_str(
|
||||
canvas,
|
||||
77,
|
||||
7,
|
||||
(model->device_type == SubGhzRadioDeviceTypeInternal) ? "R: Int" : "R: Ext");
|
||||
} else {
|
||||
canvas_draw_str(canvas, 70, 7, furi_hal_subghz_get_radio_type() ? "E" : "I");
|
||||
canvas_draw_str(
|
||||
canvas, 70, 7, (model->device_type == SubGhzRadioDeviceTypeInternal) ? "I" : "E");
|
||||
}
|
||||
|
||||
canvas_draw_str_aligned(
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
#include "subghz_test_carrier.h"
|
||||
#include "../subghz_i.h"
|
||||
#include "../helpers/subghz_testing.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
|
||||
struct SubGhzTestCarrier {
|
||||
View* view;
|
||||
FuriTimer* timer;
|
||||
SubGhzTestCarrierCallback callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
SubGhzTestCarrierModelStatusRx,
|
||||
SubGhzTestCarrierModelStatusTx,
|
||||
} SubGhzTestCarrierModelStatus;
|
||||
|
||||
typedef struct {
|
||||
uint8_t frequency;
|
||||
uint32_t real_frequency;
|
||||
FuriHalSubGhzPath path;
|
||||
float rssi;
|
||||
SubGhzTestCarrierModelStatus status;
|
||||
} SubGhzTestCarrierModel;
|
||||
|
||||
void subghz_test_carrier_set_callback(
|
||||
SubGhzTestCarrier* subghz_test_carrier,
|
||||
SubGhzTestCarrierCallback callback,
|
||||
void* context) {
|
||||
furi_assert(subghz_test_carrier);
|
||||
furi_assert(callback);
|
||||
subghz_test_carrier->callback = callback;
|
||||
subghz_test_carrier->context = context;
|
||||
}
|
||||
|
||||
void subghz_test_carrier_draw(Canvas* canvas, SubGhzTestCarrierModel* model) {
|
||||
char buffer[64];
|
||||
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 0, 8, "CC1101 Basic Test");
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
// Frequency
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"Freq: %03ld.%03ld.%03ld Hz",
|
||||
model->real_frequency / 1000000 % 1000,
|
||||
model->real_frequency / 1000 % 1000,
|
||||
model->real_frequency % 1000);
|
||||
canvas_draw_str(canvas, 0, 20, buffer);
|
||||
// Path
|
||||
char* path_name = "Unknown";
|
||||
if(model->path == FuriHalSubGhzPathIsolate) {
|
||||
path_name = "isolate";
|
||||
} else if(model->path == FuriHalSubGhzPath433) {
|
||||
path_name = "433MHz";
|
||||
} else if(model->path == FuriHalSubGhzPath315) {
|
||||
path_name = "315MHz";
|
||||
} else if(model->path == FuriHalSubGhzPath868) {
|
||||
path_name = "868MHz";
|
||||
}
|
||||
snprintf(buffer, sizeof(buffer), "Path: %d - %s", model->path, path_name);
|
||||
canvas_draw_str(canvas, 0, 31, buffer);
|
||||
if(model->status == SubGhzTestCarrierModelStatusRx) {
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"RSSI: %ld.%ld dBm",
|
||||
(int32_t)(model->rssi),
|
||||
(int32_t)fabs(model->rssi * 10) % 10);
|
||||
canvas_draw_str(canvas, 0, 42, buffer);
|
||||
} else {
|
||||
canvas_draw_str(canvas, 0, 42, "TX");
|
||||
}
|
||||
}
|
||||
|
||||
bool subghz_test_carrier_input(InputEvent* event, void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestCarrier* subghz_test_carrier = context;
|
||||
|
||||
if(event->key == InputKeyBack || event->type != InputTypeShort) {
|
||||
return false;
|
||||
}
|
||||
|
||||
with_view_model(
|
||||
subghz_test_carrier->view,
|
||||
SubGhzTestCarrierModel * model,
|
||||
{
|
||||
furi_hal_subghz_idle();
|
||||
|
||||
if(event->key == InputKeyLeft) {
|
||||
if(model->frequency > 0) model->frequency--;
|
||||
} else if(event->key == InputKeyRight) {
|
||||
if(model->frequency < subghz_frequencies_count_testing - 1) model->frequency++;
|
||||
} else if(event->key == InputKeyDown) {
|
||||
if(model->path > 0) model->path--;
|
||||
} else if(event->key == InputKeyUp) {
|
||||
if(model->path < FuriHalSubGhzPath868) model->path++;
|
||||
} else if(event->key == InputKeyOk) {
|
||||
if(model->status == SubGhzTestCarrierModelStatusTx) {
|
||||
model->status = SubGhzTestCarrierModelStatusRx;
|
||||
} else {
|
||||
model->status = SubGhzTestCarrierModelStatusTx;
|
||||
}
|
||||
}
|
||||
|
||||
model->real_frequency =
|
||||
furi_hal_subghz_set_frequency(subghz_frequencies_testing[model->frequency]);
|
||||
furi_hal_subghz_set_path(model->path);
|
||||
|
||||
if(model->status == SubGhzTestCarrierModelStatusRx) {
|
||||
furi_hal_gpio_init(
|
||||
furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
furi_hal_subghz_rx();
|
||||
} else {
|
||||
furi_hal_gpio_init(
|
||||
furi_hal_subghz.cc1101_g0_pin,
|
||||
GpioModeOutputPushPull,
|
||||
GpioPullNo,
|
||||
GpioSpeedLow);
|
||||
furi_hal_gpio_write(furi_hal_subghz.cc1101_g0_pin, true);
|
||||
if(!furi_hal_subghz_tx()) {
|
||||
furi_hal_gpio_init(
|
||||
furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
subghz_test_carrier->callback(
|
||||
SubGhzTestCarrierEventOnlyRx, subghz_test_carrier->context);
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void subghz_test_carrier_enter(void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestCarrier* subghz_test_carrier = context;
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
|
||||
furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
with_view_model(
|
||||
subghz_test_carrier->view,
|
||||
SubGhzTestCarrierModel * model,
|
||||
{
|
||||
model->frequency = subghz_frequencies_433_92_testing; // 433
|
||||
model->real_frequency =
|
||||
furi_hal_subghz_set_frequency(subghz_frequencies_testing[model->frequency]);
|
||||
model->path = FuriHalSubGhzPathIsolate; // isolate
|
||||
model->rssi = 0.0f;
|
||||
model->status = SubGhzTestCarrierModelStatusRx;
|
||||
},
|
||||
true);
|
||||
|
||||
furi_hal_subghz_rx();
|
||||
|
||||
furi_timer_start(subghz_test_carrier->timer, furi_kernel_get_tick_frequency() / 4);
|
||||
}
|
||||
|
||||
void subghz_test_carrier_exit(void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestCarrier* subghz_test_carrier = context;
|
||||
|
||||
furi_timer_stop(subghz_test_carrier->timer);
|
||||
|
||||
// Reinitialize IC to default state
|
||||
furi_hal_subghz_sleep();
|
||||
}
|
||||
|
||||
void subghz_test_carrier_rssi_timer_callback(void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestCarrier* subghz_test_carrier = context;
|
||||
|
||||
with_view_model(
|
||||
subghz_test_carrier->view,
|
||||
SubGhzTestCarrierModel * model,
|
||||
{
|
||||
if(model->status == SubGhzTestCarrierModelStatusRx) {
|
||||
model->rssi = furi_hal_subghz_get_rssi();
|
||||
}
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
SubGhzTestCarrier* subghz_test_carrier_alloc() {
|
||||
SubGhzTestCarrier* subghz_test_carrier = malloc(sizeof(SubGhzTestCarrier));
|
||||
|
||||
// View allocation and configuration
|
||||
subghz_test_carrier->view = view_alloc();
|
||||
view_allocate_model(
|
||||
subghz_test_carrier->view, ViewModelTypeLocking, sizeof(SubGhzTestCarrierModel));
|
||||
view_set_context(subghz_test_carrier->view, subghz_test_carrier);
|
||||
view_set_draw_callback(subghz_test_carrier->view, (ViewDrawCallback)subghz_test_carrier_draw);
|
||||
view_set_input_callback(subghz_test_carrier->view, subghz_test_carrier_input);
|
||||
view_set_enter_callback(subghz_test_carrier->view, subghz_test_carrier_enter);
|
||||
view_set_exit_callback(subghz_test_carrier->view, subghz_test_carrier_exit);
|
||||
|
||||
subghz_test_carrier->timer = furi_timer_alloc(
|
||||
subghz_test_carrier_rssi_timer_callback, FuriTimerTypePeriodic, subghz_test_carrier);
|
||||
|
||||
return subghz_test_carrier;
|
||||
}
|
||||
|
||||
void subghz_test_carrier_free(SubGhzTestCarrier* subghz_test_carrier) {
|
||||
furi_assert(subghz_test_carrier);
|
||||
furi_timer_free(subghz_test_carrier->timer);
|
||||
view_free(subghz_test_carrier->view);
|
||||
free(subghz_test_carrier);
|
||||
}
|
||||
|
||||
View* subghz_test_carrier_get_view(SubGhzTestCarrier* subghz_test_carrier) {
|
||||
furi_assert(subghz_test_carrier);
|
||||
return subghz_test_carrier->view;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
|
||||
typedef enum {
|
||||
SubGhzTestCarrierEventOnlyRx,
|
||||
} SubGhzTestCarrierEvent;
|
||||
|
||||
typedef struct SubGhzTestCarrier SubGhzTestCarrier;
|
||||
|
||||
typedef void (*SubGhzTestCarrierCallback)(SubGhzTestCarrierEvent event, void* context);
|
||||
|
||||
void subghz_test_carrier_set_callback(
|
||||
SubGhzTestCarrier* subghz_test_carrier,
|
||||
SubGhzTestCarrierCallback callback,
|
||||
void* context);
|
||||
|
||||
SubGhzTestCarrier* subghz_test_carrier_alloc();
|
||||
|
||||
void subghz_test_carrier_free(SubGhzTestCarrier* subghz_test_carrier);
|
||||
|
||||
View* subghz_test_carrier_get_view(SubGhzTestCarrier* subghz_test_carrier);
|
||||
@@ -1,276 +0,0 @@
|
||||
#include "subghz_test_packet.h"
|
||||
#include "../subghz_i.h"
|
||||
#include "../helpers/subghz_testing.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
#include <toolbox/level_duration.h>
|
||||
#include <lib/subghz/protocols/princeton_for_testing.h>
|
||||
|
||||
#define SUBGHZ_TEST_PACKET_COUNT 500
|
||||
|
||||
struct SubGhzTestPacket {
|
||||
View* view;
|
||||
FuriTimer* timer;
|
||||
|
||||
SubGhzDecoderPrinceton* decoder;
|
||||
SubGhzEncoderPrinceton* encoder;
|
||||
volatile size_t packet_rx;
|
||||
SubGhzTestPacketCallback callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
SubGhzTestPacketModelStatusRx,
|
||||
SubGhzTestPacketModelStatusOnlyRx,
|
||||
SubGhzTestPacketModelStatusTx,
|
||||
} SubGhzTestPacketModelStatus;
|
||||
|
||||
typedef struct {
|
||||
uint8_t frequency;
|
||||
uint32_t real_frequency;
|
||||
FuriHalSubGhzPath path;
|
||||
float rssi;
|
||||
size_t packets;
|
||||
SubGhzTestPacketModelStatus status;
|
||||
} SubGhzTestPacketModel;
|
||||
|
||||
volatile bool subghz_test_packet_overrun = false;
|
||||
|
||||
void subghz_test_packet_set_callback(
|
||||
SubGhzTestPacket* subghz_test_packet,
|
||||
SubGhzTestPacketCallback callback,
|
||||
void* context) {
|
||||
furi_assert(subghz_test_packet);
|
||||
furi_assert(callback);
|
||||
subghz_test_packet->callback = callback;
|
||||
subghz_test_packet->context = context;
|
||||
}
|
||||
|
||||
static void subghz_test_packet_rx_callback(bool level, uint32_t duration, void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestPacket* instance = context;
|
||||
subghz_decoder_princeton_for_testing_parse(instance->decoder, level, duration);
|
||||
}
|
||||
|
||||
//todo
|
||||
static void subghz_test_packet_rx_pt_callback(SubGhzDecoderPrinceton* parser, void* context) {
|
||||
UNUSED(parser);
|
||||
furi_assert(context);
|
||||
SubGhzTestPacket* instance = context;
|
||||
instance->packet_rx++;
|
||||
}
|
||||
|
||||
static void subghz_test_packet_rssi_timer_callback(void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestPacket* instance = context;
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
SubGhzTestPacketModel * model,
|
||||
{
|
||||
if(model->status == SubGhzTestPacketModelStatusRx) {
|
||||
model->rssi = furi_hal_subghz_get_rssi();
|
||||
model->packets = instance->packet_rx;
|
||||
} else if(model->status == SubGhzTestPacketModelStatusTx) {
|
||||
model->packets =
|
||||
SUBGHZ_TEST_PACKET_COUNT -
|
||||
subghz_encoder_princeton_for_testing_get_repeat_left(instance->encoder);
|
||||
}
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void subghz_test_packet_draw(Canvas* canvas, SubGhzTestPacketModel* model) {
|
||||
char buffer[64];
|
||||
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 0, 8, "CC1101 Packet Test");
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
// Frequency
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"Freq: %03ld.%03ld.%03ld Hz",
|
||||
model->real_frequency / 1000000 % 1000,
|
||||
model->real_frequency / 1000 % 1000,
|
||||
model->real_frequency % 1000);
|
||||
canvas_draw_str(canvas, 0, 20, buffer);
|
||||
// Path
|
||||
char* path_name = "Unknown";
|
||||
if(model->path == FuriHalSubGhzPathIsolate) {
|
||||
path_name = "isolate";
|
||||
} else if(model->path == FuriHalSubGhzPath433) {
|
||||
path_name = "433MHz";
|
||||
} else if(model->path == FuriHalSubGhzPath315) {
|
||||
path_name = "315MHz";
|
||||
} else if(model->path == FuriHalSubGhzPath868) {
|
||||
path_name = "868MHz";
|
||||
}
|
||||
snprintf(buffer, sizeof(buffer), "Path: %d - %s", model->path, path_name);
|
||||
canvas_draw_str(canvas, 0, 31, buffer);
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "Packets: %zu", model->packets);
|
||||
canvas_draw_str(canvas, 0, 42, buffer);
|
||||
|
||||
if(model->status == SubGhzTestPacketModelStatusRx) {
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"RSSI: %ld.%ld dBm",
|
||||
(int32_t)(model->rssi),
|
||||
(int32_t)fabs(model->rssi * 10) % 10);
|
||||
canvas_draw_str(canvas, 0, 53, buffer);
|
||||
} else {
|
||||
canvas_draw_str(canvas, 0, 53, "TX");
|
||||
}
|
||||
}
|
||||
|
||||
static bool subghz_test_packet_input(InputEvent* event, void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestPacket* instance = context;
|
||||
|
||||
if(event->key == InputKeyBack || event->type != InputTypeShort) {
|
||||
return false;
|
||||
}
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
SubGhzTestPacketModel * model,
|
||||
{
|
||||
if(model->status == SubGhzTestPacketModelStatusRx) {
|
||||
furi_hal_subghz_stop_async_rx();
|
||||
} else if(model->status == SubGhzTestPacketModelStatusTx) {
|
||||
subghz_encoder_princeton_for_testing_stop(instance->encoder, furi_get_tick());
|
||||
furi_hal_subghz_stop_async_tx();
|
||||
}
|
||||
|
||||
if(event->key == InputKeyLeft) {
|
||||
if(model->frequency > 0) model->frequency--;
|
||||
} else if(event->key == InputKeyRight) {
|
||||
if(model->frequency < subghz_frequencies_count_testing - 1) model->frequency++;
|
||||
} else if(event->key == InputKeyDown) {
|
||||
if(model->path > 0) model->path--;
|
||||
} else if(event->key == InputKeyUp) {
|
||||
if(model->path < FuriHalSubGhzPath868) model->path++;
|
||||
} else if(event->key == InputKeyOk) {
|
||||
if(model->status == SubGhzTestPacketModelStatusRx) {
|
||||
model->status = SubGhzTestPacketModelStatusTx;
|
||||
} else {
|
||||
model->status = SubGhzTestPacketModelStatusRx;
|
||||
}
|
||||
}
|
||||
|
||||
model->real_frequency =
|
||||
furi_hal_subghz_set_frequency(subghz_frequencies_testing[model->frequency]);
|
||||
furi_hal_subghz_set_path(model->path);
|
||||
|
||||
if(model->status == SubGhzTestPacketModelStatusRx) {
|
||||
furi_hal_subghz_start_async_rx(subghz_test_packet_rx_callback, instance);
|
||||
} else {
|
||||
subghz_encoder_princeton_for_testing_set(
|
||||
instance->encoder,
|
||||
0x00AABBCC,
|
||||
SUBGHZ_TEST_PACKET_COUNT,
|
||||
subghz_frequencies_testing[model->frequency]);
|
||||
if(!furi_hal_subghz_start_async_tx(
|
||||
subghz_encoder_princeton_for_testing_yield, instance->encoder)) {
|
||||
model->status = SubGhzTestPacketModelStatusOnlyRx;
|
||||
instance->callback(SubGhzTestPacketEventOnlyRx, instance->context);
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void subghz_test_packet_enter(void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestPacket* instance = context;
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
SubGhzTestPacketModel * model,
|
||||
{
|
||||
model->frequency = subghz_frequencies_433_92_testing;
|
||||
model->real_frequency =
|
||||
furi_hal_subghz_set_frequency(subghz_frequencies_testing[model->frequency]);
|
||||
model->path = FuriHalSubGhzPathIsolate; // isolate
|
||||
model->rssi = 0.0f;
|
||||
model->status = SubGhzTestPacketModelStatusRx;
|
||||
},
|
||||
true);
|
||||
|
||||
furi_hal_subghz_start_async_rx(subghz_test_packet_rx_callback, instance);
|
||||
|
||||
furi_timer_start(instance->timer, furi_kernel_get_tick_frequency() / 4);
|
||||
}
|
||||
|
||||
void subghz_test_packet_exit(void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestPacket* instance = context;
|
||||
|
||||
furi_timer_stop(instance->timer);
|
||||
|
||||
// Reinitialize IC to default state
|
||||
with_view_model(
|
||||
instance->view,
|
||||
SubGhzTestPacketModel * model,
|
||||
{
|
||||
if(model->status == SubGhzTestPacketModelStatusRx) {
|
||||
furi_hal_subghz_stop_async_rx();
|
||||
} else if(model->status == SubGhzTestPacketModelStatusTx) {
|
||||
subghz_encoder_princeton_for_testing_stop(instance->encoder, furi_get_tick());
|
||||
furi_hal_subghz_stop_async_tx();
|
||||
}
|
||||
},
|
||||
true);
|
||||
furi_hal_subghz_sleep();
|
||||
}
|
||||
|
||||
SubGhzTestPacket* subghz_test_packet_alloc() {
|
||||
SubGhzTestPacket* instance = malloc(sizeof(SubGhzTestPacket));
|
||||
|
||||
// View allocation and configuration
|
||||
instance->view = view_alloc();
|
||||
view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(SubGhzTestPacketModel));
|
||||
view_set_context(instance->view, instance);
|
||||
view_set_draw_callback(instance->view, (ViewDrawCallback)subghz_test_packet_draw);
|
||||
view_set_input_callback(instance->view, subghz_test_packet_input);
|
||||
view_set_enter_callback(instance->view, subghz_test_packet_enter);
|
||||
view_set_exit_callback(instance->view, subghz_test_packet_exit);
|
||||
|
||||
instance->timer =
|
||||
furi_timer_alloc(subghz_test_packet_rssi_timer_callback, FuriTimerTypePeriodic, instance);
|
||||
|
||||
instance->decoder = subghz_decoder_princeton_for_testing_alloc();
|
||||
subghz_decoder_princeton_for_testing_set_callback(
|
||||
instance->decoder, subghz_test_packet_rx_pt_callback, instance);
|
||||
instance->encoder = subghz_encoder_princeton_for_testing_alloc();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void subghz_test_packet_free(SubGhzTestPacket* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
subghz_decoder_princeton_for_testing_free(instance->decoder);
|
||||
subghz_encoder_princeton_for_testing_free(instance->encoder);
|
||||
|
||||
furi_timer_free(instance->timer);
|
||||
view_free(instance->view);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
View* subghz_test_packet_get_view(SubGhzTestPacket* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->view;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
|
||||
typedef enum {
|
||||
SubGhzTestPacketEventOnlyRx,
|
||||
} SubGhzTestPacketEvent;
|
||||
|
||||
typedef struct SubGhzTestPacket SubGhzTestPacket;
|
||||
|
||||
typedef void (*SubGhzTestPacketCallback)(SubGhzTestPacketEvent event, void* context);
|
||||
|
||||
void subghz_test_packet_set_callback(
|
||||
SubGhzTestPacket* subghz_test_packet,
|
||||
SubGhzTestPacketCallback callback,
|
||||
void* context);
|
||||
|
||||
SubGhzTestPacket* subghz_test_packet_alloc();
|
||||
|
||||
void subghz_test_packet_free(SubGhzTestPacket* subghz_test_packet);
|
||||
|
||||
View* subghz_test_packet_get_view(SubGhzTestPacket* subghz_test_packet);
|
||||
@@ -1,194 +0,0 @@
|
||||
#include "subghz_test_static.h"
|
||||
#include "../subghz_i.h"
|
||||
#include "../helpers/subghz_testing.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <lib/subghz/protocols/princeton_for_testing.h>
|
||||
|
||||
#define TAG "SubGhzTestStatic"
|
||||
|
||||
typedef enum {
|
||||
SubGhzTestStaticStatusIDLE,
|
||||
SubGhzTestStaticStatusTX,
|
||||
} SubGhzTestStaticStatus;
|
||||
|
||||
static const uint32_t subghz_test_static_keys[] = {
|
||||
0x0074BADE,
|
||||
0x0074BADD,
|
||||
0x0074BADB,
|
||||
0x00E34A4E,
|
||||
};
|
||||
|
||||
struct SubGhzTestStatic {
|
||||
View* view;
|
||||
SubGhzTestStaticStatus status_tx;
|
||||
SubGhzEncoderPrinceton* encoder;
|
||||
SubGhzTestStaticCallback callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t frequency;
|
||||
uint32_t real_frequency;
|
||||
uint8_t button;
|
||||
} SubGhzTestStaticModel;
|
||||
|
||||
void subghz_test_static_set_callback(
|
||||
SubGhzTestStatic* subghz_test_static,
|
||||
SubGhzTestStaticCallback callback,
|
||||
void* context) {
|
||||
furi_assert(subghz_test_static);
|
||||
furi_assert(callback);
|
||||
subghz_test_static->callback = callback;
|
||||
subghz_test_static->context = context;
|
||||
}
|
||||
|
||||
void subghz_test_static_draw(Canvas* canvas, SubGhzTestStaticModel* model) {
|
||||
char buffer[64];
|
||||
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 0, 8, "CC1101 Static");
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
// Frequency
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"Freq: %03ld.%03ld.%03ld Hz",
|
||||
model->real_frequency / 1000000 % 1000,
|
||||
model->real_frequency / 1000 % 1000,
|
||||
model->real_frequency % 1000);
|
||||
canvas_draw_str(canvas, 0, 20, buffer);
|
||||
snprintf(buffer, sizeof(buffer), "Key: %d", model->button);
|
||||
canvas_draw_str(canvas, 0, 31, buffer);
|
||||
}
|
||||
|
||||
bool subghz_test_static_input(InputEvent* event, void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestStatic* instance = context;
|
||||
|
||||
if(event->key == InputKeyBack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
SubGhzTestStaticModel * model,
|
||||
{
|
||||
if(event->type == InputTypeShort) {
|
||||
if(event->key == InputKeyLeft) {
|
||||
if(model->frequency > 0) model->frequency--;
|
||||
} else if(event->key == InputKeyRight) {
|
||||
if(model->frequency < subghz_frequencies_count_testing - 1) model->frequency++;
|
||||
} else if(event->key == InputKeyDown) {
|
||||
if(model->button > 0) model->button--;
|
||||
} else if(event->key == InputKeyUp) {
|
||||
if(model->button < 3) model->button++;
|
||||
}
|
||||
}
|
||||
|
||||
model->real_frequency = subghz_frequencies_testing[model->frequency];
|
||||
|
||||
if(event->key == InputKeyOk) {
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
if(event->type == InputTypePress) {
|
||||
furi_hal_subghz_idle();
|
||||
furi_hal_subghz_set_frequency_and_path(
|
||||
subghz_frequencies_testing[model->frequency]);
|
||||
if(!furi_hal_subghz_tx()) {
|
||||
instance->callback(SubGhzTestStaticEventOnlyRx, instance->context);
|
||||
} else {
|
||||
notification_message_block(notification, &sequence_set_red_255);
|
||||
|
||||
FURI_LOG_I(TAG, "TX Start");
|
||||
|
||||
subghz_encoder_princeton_for_testing_set(
|
||||
instance->encoder,
|
||||
subghz_test_static_keys[model->button],
|
||||
10000,
|
||||
subghz_frequencies_testing[model->frequency]);
|
||||
|
||||
furi_hal_subghz_start_async_tx(
|
||||
subghz_encoder_princeton_for_testing_yield, instance->encoder);
|
||||
instance->status_tx = SubGhzTestStaticStatusTX;
|
||||
}
|
||||
} else if(event->type == InputTypeRelease) {
|
||||
if(instance->status_tx == SubGhzTestStaticStatusTX) {
|
||||
FURI_LOG_I(TAG, "TX Stop");
|
||||
subghz_encoder_princeton_for_testing_stop(
|
||||
instance->encoder, furi_get_tick());
|
||||
subghz_encoder_princeton_for_testing_print_log(instance->encoder);
|
||||
furi_hal_subghz_stop_async_tx();
|
||||
notification_message(notification, &sequence_reset_red);
|
||||
}
|
||||
instance->status_tx = SubGhzTestStaticStatusIDLE;
|
||||
}
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
}
|
||||
},
|
||||
true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void subghz_test_static_enter(void* context) {
|
||||
furi_assert(context);
|
||||
SubGhzTestStatic* instance = context;
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
|
||||
furi_hal_gpio_init(
|
||||
furi_hal_subghz.cc1101_g0_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||
furi_hal_gpio_write(furi_hal_subghz.cc1101_g0_pin, false);
|
||||
instance->status_tx = SubGhzTestStaticStatusIDLE;
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
SubGhzTestStaticModel * model,
|
||||
{
|
||||
model->frequency = subghz_frequencies_433_92_testing;
|
||||
model->real_frequency = subghz_frequencies_testing[model->frequency];
|
||||
model->button = 0;
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void subghz_test_static_exit(void* context) {
|
||||
furi_assert(context);
|
||||
furi_hal_subghz_sleep();
|
||||
}
|
||||
|
||||
SubGhzTestStatic* subghz_test_static_alloc() {
|
||||
SubGhzTestStatic* instance = malloc(sizeof(SubGhzTestStatic));
|
||||
|
||||
// View allocation and configuration
|
||||
instance->view = view_alloc();
|
||||
view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(SubGhzTestStaticModel));
|
||||
view_set_context(instance->view, instance);
|
||||
view_set_draw_callback(instance->view, (ViewDrawCallback)subghz_test_static_draw);
|
||||
view_set_input_callback(instance->view, subghz_test_static_input);
|
||||
view_set_enter_callback(instance->view, subghz_test_static_enter);
|
||||
view_set_exit_callback(instance->view, subghz_test_static_exit);
|
||||
|
||||
instance->encoder = subghz_encoder_princeton_for_testing_alloc();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void subghz_test_static_free(SubGhzTestStatic* instance) {
|
||||
furi_assert(instance);
|
||||
subghz_encoder_princeton_for_testing_free(instance->encoder);
|
||||
view_free(instance->view);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
View* subghz_test_static_get_view(SubGhzTestStatic* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->view;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
|
||||
typedef enum {
|
||||
SubGhzTestStaticEventOnlyRx,
|
||||
} SubGhzTestStaticEvent;
|
||||
|
||||
typedef struct SubGhzTestStatic SubGhzTestStatic;
|
||||
|
||||
typedef void (*SubGhzTestStaticCallback)(SubGhzTestStaticEvent event, void* context);
|
||||
|
||||
void subghz_test_static_set_callback(
|
||||
SubGhzTestStatic* subghz_test_static,
|
||||
SubGhzTestStaticCallback callback,
|
||||
void* context);
|
||||
|
||||
SubGhzTestStatic* subghz_test_static_alloc();
|
||||
|
||||
void subghz_test_static_free(SubGhzTestStatic* subghz_static);
|
||||
|
||||
View* subghz_test_static_get_view(SubGhzTestStatic* subghz_static);
|
||||
@@ -6,6 +6,22 @@
|
||||
|
||||
#include <lib/subghz/blocks/custom_btn.h>
|
||||
|
||||
struct SubGhzViewTransmitter {
|
||||
View* view;
|
||||
SubGhzViewTransmitterCallback callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
FuriString* frequency_str;
|
||||
FuriString* preset_str;
|
||||
FuriString* key_str;
|
||||
bool show_button;
|
||||
SubGhzRadioDeviceType device_type;
|
||||
FuriString* temp_button_id;
|
||||
bool draw_temp_button;
|
||||
} SubGhzViewTransmitterModel;
|
||||
|
||||
void subghz_view_transmitter_set_callback(
|
||||
SubGhzViewTransmitter* subghz_transmitter,
|
||||
SubGhzViewTransmitterCallback callback,
|
||||
@@ -85,7 +101,12 @@ void subghz_view_transmitter_draw(Canvas* canvas, SubGhzViewTransmitterModel* mo
|
||||
}
|
||||
|
||||
if(model->show_button) {
|
||||
canvas_draw_str(canvas, 58, 62, furi_hal_subghz_get_radio_type() ? "R: Ext" : "R: Int");
|
||||
// TODO
|
||||
canvas_draw_str(
|
||||
canvas,
|
||||
58,
|
||||
62,
|
||||
(model->device_type == SubGhzRadioDeviceTypeInternal) ? "R: Int" : "R: Ext");
|
||||
subghz_view_transmitter_button_right(canvas, "Send");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user