[FL-3375] SubGhz: add CC1101 module external (#2747)
* SubGhz: add CC1101 Ext driver * SubGhz: move TIM2 -> TIM17 use cc1101_ext * FuriHal: SPI move channel DMA 3,4 -> 6.7 * Documentation: fix font * SubGhz: add work with SubGhz devices by link to device * SubGhz: add support switching external/internal cc1101 "subghz chat" * SubGhz: add support switching external/internal cc1101 "subghz tx" and "subghz rx" * SubGhz: add "Radio Settings" scene * SubGhz: add icon * SubGhz: add supported CC1101 external module in SubGhz app * SubGhz: fix check frequency supported radio device * SubGhz: fix clang-formatted * Sughz: move dirver CC1101_Ext to lib , compile cmd ./fbt launch_app APPSRC=radio_device_cc1101_ext * SubGhz: fix CLI * SubGhz: fix PVS * SubGhz: delete comments * SubGhz: fix unit_test * Format sources * Update api symbols and drivers targets * Drivers: find proper place for target option * SubGhz: external device connected method naming * Format sources * SubGhz: fix module selection menu, when external is not connected * SubGhz: fix furi_assert(device); * SubGhz: fix split h and c * SubGhz: furi_hal_subghz remove preset load function by name * SubGhz: deleted comments * Format Sources * SubGhz: add some consts and fix unit tests * Sync API Symbols Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
co-authored by
Aleksandr Kutuzov
parent
6d9de25494
commit
8c93695d01
@@ -76,12 +76,15 @@ void subghz_chat_worker_free(SubGhzChatWorker* instance) {
|
||||
free(instance);
|
||||
}
|
||||
|
||||
bool subghz_chat_worker_start(SubGhzChatWorker* instance, uint32_t frequency) {
|
||||
bool subghz_chat_worker_start(
|
||||
SubGhzChatWorker* instance,
|
||||
const SubGhzDevice* device,
|
||||
uint32_t frequency) {
|
||||
furi_assert(instance);
|
||||
furi_assert(!instance->worker_running);
|
||||
bool res = false;
|
||||
|
||||
if(subghz_tx_rx_worker_start(instance->subghz_txrx, frequency)) {
|
||||
if(subghz_tx_rx_worker_start(instance->subghz_txrx, device, frequency)) {
|
||||
furi_message_queue_reset(instance->event_queue);
|
||||
subghz_tx_rx_worker_set_callback_have_read(
|
||||
instance->subghz_txrx, subghz_chat_worker_update_rx_event_chat, instance);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "../subghz_i.h"
|
||||
#include <lib/subghz/devices/devices.h>
|
||||
#include <cli/cli.h>
|
||||
|
||||
typedef struct SubGhzChatWorker SubGhzChatWorker;
|
||||
@@ -20,7 +21,10 @@ typedef struct {
|
||||
|
||||
SubGhzChatWorker* subghz_chat_worker_alloc(Cli* cli);
|
||||
void subghz_chat_worker_free(SubGhzChatWorker* instance);
|
||||
bool subghz_chat_worker_start(SubGhzChatWorker* instance, uint32_t frequency);
|
||||
bool subghz_chat_worker_start(
|
||||
SubGhzChatWorker* instance,
|
||||
const SubGhzDevice* device,
|
||||
uint32_t frequency);
|
||||
void subghz_chat_worker_stop(SubGhzChatWorker* instance);
|
||||
bool subghz_chat_worker_is_running(SubGhzChatWorker* instance);
|
||||
SubGhzChatEvent subghz_chat_worker_get_event_chat(SubGhzChatWorker* instance);
|
||||
|
||||
@@ -32,9 +32,8 @@ float subghz_threshold_rssi_get(SubGhzThresholdRssi* instance) {
|
||||
return instance->threshold_rssi;
|
||||
}
|
||||
|
||||
SubGhzThresholdRssiData subghz_threshold_get_rssi_data(SubGhzThresholdRssi* instance) {
|
||||
SubGhzThresholdRssiData subghz_threshold_get_rssi_data(SubGhzThresholdRssi* instance, float rssi) {
|
||||
furi_assert(instance);
|
||||
float rssi = furi_hal_subghz_get_rssi();
|
||||
SubGhzThresholdRssiData ret = {.rssi = rssi, .is_above = false};
|
||||
|
||||
if(float_is_equal(instance->threshold_rssi, SUBGHZ_RAW_THRESHOLD_MIN)) {
|
||||
|
||||
@@ -38,6 +38,7 @@ float subghz_threshold_rssi_get(SubGhzThresholdRssi* instance);
|
||||
/** Check threshold
|
||||
*
|
||||
* @param instance Pointer to a SubGhzThresholdRssi
|
||||
* @param rssi Current RSSI
|
||||
* @return SubGhzThresholdRssiData
|
||||
*/
|
||||
SubGhzThresholdRssiData subghz_threshold_get_rssi_data(SubGhzThresholdRssi* instance);
|
||||
SubGhzThresholdRssiData subghz_threshold_get_rssi_data(SubGhzThresholdRssi* instance, float rssi);
|
||||
|
||||
@@ -1,9 +1,26 @@
|
||||
#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>
|
||||
|
||||
#define TAG "SubGhz"
|
||||
|
||||
static void subghz_txrx_radio_device_power_on(SubGhzTxRx* instance) {
|
||||
UNUSED(instance);
|
||||
uint8_t attempts = 0;
|
||||
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
|
||||
furi_hal_power_enable_otg();
|
||||
//CC1101 power-up time
|
||||
furi_delay_ms(10);
|
||||
}
|
||||
}
|
||||
|
||||
static void subghz_txrx_radio_device_power_off(SubGhzTxRx* instance) {
|
||||
UNUSED(instance);
|
||||
if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
|
||||
}
|
||||
|
||||
SubGhzTxRx* subghz_txrx_alloc() {
|
||||
SubGhzTxRx* instance = malloc(sizeof(SubGhzTxRx));
|
||||
instance->setting = subghz_setting_alloc();
|
||||
@@ -23,16 +40,15 @@ SubGhzTxRx* subghz_txrx_alloc() {
|
||||
instance->fff_data = flipper_format_string_alloc();
|
||||
|
||||
instance->environment = subghz_environment_alloc();
|
||||
instance->is_database_loaded = subghz_environment_load_keystore(
|
||||
instance->environment, EXT_PATH("subghz/assets/keeloq_mfcodes"));
|
||||
subghz_environment_load_keystore(
|
||||
instance->environment, EXT_PATH("subghz/assets/keeloq_mfcodes_user"));
|
||||
instance->is_database_loaded =
|
||||
subghz_environment_load_keystore(instance->environment, SUBGHZ_KEYSTORE_DIR_NAME);
|
||||
subghz_environment_load_keystore(instance->environment, SUBGHZ_KEYSTORE_DIR_USER_NAME);
|
||||
subghz_environment_set_came_atomo_rainbow_table_file_name(
|
||||
instance->environment, EXT_PATH("subghz/assets/came_atomo"));
|
||||
instance->environment, SUBGHZ_CAME_ATOMO_DIR_NAME);
|
||||
subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
|
||||
instance->environment, EXT_PATH("subghz/assets/alutech_at_4n"));
|
||||
instance->environment, SUBGHZ_ALUTECH_AT_4N_DIR_NAME);
|
||||
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
|
||||
instance->environment, EXT_PATH("subghz/assets/nice_flor_s"));
|
||||
instance->environment, SUBGHZ_NICE_FLOR_S_DIR_NAME);
|
||||
subghz_environment_set_protocol_registry(
|
||||
instance->environment, (void*)&subghz_protocol_registry);
|
||||
instance->receiver = subghz_receiver_alloc_init(instance->environment);
|
||||
@@ -43,18 +59,32 @@ SubGhzTxRx* subghz_txrx_alloc() {
|
||||
instance->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode);
|
||||
subghz_worker_set_context(instance->worker, instance->receiver);
|
||||
|
||||
//set default device External
|
||||
subghz_devices_init();
|
||||
instance->radio_device_type = SubGhzRadioDeviceTypeInternal;
|
||||
instance->radio_device_type =
|
||||
subghz_txrx_radio_device_set(instance, SubGhzRadioDeviceTypeExternalCC1101);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void subghz_txrx_free(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
if(instance->radio_device_type != SubGhzRadioDeviceTypeInternal) {
|
||||
subghz_txrx_radio_device_power_off(instance);
|
||||
subghz_devices_end(instance->radio_device);
|
||||
}
|
||||
|
||||
subghz_devices_deinit();
|
||||
|
||||
subghz_worker_free(instance->worker);
|
||||
subghz_receiver_free(instance->receiver);
|
||||
subghz_environment_free(instance->environment);
|
||||
flipper_format_free(instance->fff_data);
|
||||
furi_string_free(instance->preset->name);
|
||||
subghz_setting_free(instance->setting);
|
||||
|
||||
free(instance->preset);
|
||||
free(instance);
|
||||
}
|
||||
@@ -122,29 +152,26 @@ 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(&gpio_cc1101_g0, 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(&gpio_cc1101_g0, 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);
|
||||
uint32_t value = subghz_devices_set_frequency(instance->radio_device, frequency);
|
||||
subghz_devices_flush_rx(instance->radio_device);
|
||||
subghz_txrx_speaker_on(instance);
|
||||
|
||||
subghz_devices_start_async_rx(
|
||||
instance->radio_device, subghz_worker_rx_callback, instance->worker);
|
||||
subghz_worker_start(instance->worker);
|
||||
instance->txrx_state = SubGhzTxRxStateRx;
|
||||
return value;
|
||||
@@ -153,7 +180,7 @@ static uint32_t subghz_txrx_rx(SubGhzTxRx* instance, uint32_t frequency) {
|
||||
static void subghz_txrx_idle(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
furi_assert(instance->txrx_state != SubGhzTxRxStateSleep);
|
||||
furi_hal_subghz_idle();
|
||||
subghz_devices_idle(instance->radio_device);
|
||||
subghz_txrx_speaker_off(instance);
|
||||
instance->txrx_state = SubGhzTxRxStateIDLE;
|
||||
}
|
||||
@@ -164,30 +191,26 @@ static void subghz_txrx_rx_end(SubGhzTxRx* instance) {
|
||||
|
||||
if(subghz_worker_is_running(instance->worker)) {
|
||||
subghz_worker_stop(instance->worker);
|
||||
furi_hal_subghz_stop_async_rx();
|
||||
subghz_devices_stop_async_rx(instance->radio_device);
|
||||
}
|
||||
furi_hal_subghz_idle();
|
||||
subghz_devices_idle(instance->radio_device);
|
||||
subghz_txrx_speaker_off(instance);
|
||||
instance->txrx_state = SubGhzTxRxStateIDLE;
|
||||
}
|
||||
|
||||
void subghz_txrx_sleep(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
furi_hal_subghz_sleep();
|
||||
subghz_devices_sleep(instance->radio_device);
|
||||
instance->txrx_state = SubGhzTxRxStateSleep;
|
||||
}
|
||||
|
||||
static bool subghz_txrx_tx(SubGhzTxRx* instance, uint32_t frequency) {
|
||||
furi_assert(instance);
|
||||
if(!furi_hal_subghz_is_frequency_valid(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(&gpio_cc1101_g0, false);
|
||||
furi_hal_gpio_init(&gpio_cc1101_g0, 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;
|
||||
@@ -249,8 +272,8 @@ SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat*
|
||||
|
||||
if(ret == SubGhzTxRxStartTxStateOk) {
|
||||
//Start TX
|
||||
furi_hal_subghz_start_async_tx(
|
||||
subghz_transmitter_yield, instance->transmitter);
|
||||
subghz_devices_start_async_tx(
|
||||
instance->radio_device, subghz_transmitter_yield, instance->transmitter);
|
||||
}
|
||||
} else {
|
||||
ret = SubGhzTxRxStartTxStateErrorParserOthers;
|
||||
@@ -293,7 +316,7 @@ static void subghz_txrx_tx_stop(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
furi_assert(instance->txrx_state == SubGhzTxRxStateTx);
|
||||
//Stop TX
|
||||
furi_hal_subghz_stop_async_tx();
|
||||
subghz_devices_stop_async_tx(instance->radio_device);
|
||||
subghz_transmitter_stop(instance->transmitter);
|
||||
subghz_transmitter_free(instance->transmitter);
|
||||
|
||||
@@ -306,7 +329,6 @@ static void subghz_txrx_tx_stop(SubGhzTxRx* instance) {
|
||||
subghz_txrx_idle(instance);
|
||||
subghz_txrx_speaker_off(instance);
|
||||
//Todo: Show message
|
||||
// notification_message(notifications, &sequence_reset_red);
|
||||
}
|
||||
|
||||
FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance) {
|
||||
@@ -356,7 +378,7 @@ void subghz_txrx_hopper_update(SubGhzTxRx* instance) {
|
||||
float rssi = -127.0f;
|
||||
if(instance->hopper_state != SubGhzHopperStateRSSITimeOut) {
|
||||
// See RSSI Calculation timings in CC1101 17.3 RSSI
|
||||
rssi = furi_hal_subghz_get_rssi();
|
||||
rssi = subghz_devices_get_rssi(instance->radio_device);
|
||||
|
||||
// Stay if RSSI is high enough
|
||||
if(rssi > -90.0f) {
|
||||
@@ -414,7 +436,7 @@ void subghz_txrx_speaker_on(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
if(instance->speaker_state == SubGhzSpeakerStateEnable) {
|
||||
if(furi_hal_speaker_acquire(30)) {
|
||||
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;
|
||||
}
|
||||
@@ -425,7 +447,7 @@ void subghz_txrx_speaker_off(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
if(instance->speaker_state != SubGhzSpeakerStateDisable) {
|
||||
if(furi_hal_speaker_is_mine()) {
|
||||
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)
|
||||
instance->speaker_state = SubGhzSpeakerStateDisable;
|
||||
@@ -437,7 +459,7 @@ void subghz_txrx_speaker_mute(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
if(instance->speaker_state == SubGhzSpeakerStateEnable) {
|
||||
if(furi_hal_speaker_is_mine()) {
|
||||
furi_hal_subghz_set_async_mirror_pin(NULL);
|
||||
subghz_devices_set_async_mirror_pin(instance->radio_device, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,7 +468,7 @@ void subghz_txrx_speaker_unmute(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
if(instance->speaker_state == SubGhzSpeakerStateEnable) {
|
||||
if(furi_hal_speaker_is_mine()) {
|
||||
furi_hal_subghz_set_async_mirror_pin(&gpio_speaker);
|
||||
subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_speaker);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -519,3 +541,63 @@ void subghz_txrx_set_raw_file_encoder_worker_callback_end(
|
||||
callback,
|
||||
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);
|
||||
}
|
||||
|
||||
is_connect = subghz_devices_is_connect(subghz_devices_get_by_name(name));
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <lib/subghz/receiver.h>
|
||||
#include <lib/subghz/transmitter.h>
|
||||
#include <lib/subghz/protocols/raw.h>
|
||||
#include <lib/subghz/devices/devices.h>
|
||||
|
||||
typedef struct SubGhzTxRx SubGhzTxRx;
|
||||
|
||||
@@ -288,3 +289,48 @@ void subghz_txrx_set_raw_file_encoder_worker_callback_end(
|
||||
SubGhzTxRx* instance,
|
||||
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);
|
||||
@@ -21,6 +21,8 @@ struct SubGhzTxRx {
|
||||
|
||||
SubGhzTxRxState txrx_state;
|
||||
SubGhzSpeakerState speaker_state;
|
||||
const SubGhzDevice* radio_device;
|
||||
SubGhzRadioDeviceType radio_device_type;
|
||||
|
||||
SubGhzTxRxNeedSaveCallback need_save_callback;
|
||||
void* need_save_context;
|
||||
|
||||
@@ -35,6 +35,13 @@ typedef enum {
|
||||
SubGhzSpeakerStateEnable,
|
||||
} SubGhzSpeakerState;
|
||||
|
||||
/** SubGhzRadioDeviceType */
|
||||
typedef enum {
|
||||
SubGhzRadioDeviceTypeAuto,
|
||||
SubGhzRadioDeviceTypeInternal,
|
||||
SubGhzRadioDeviceTypeExternalCC1101,
|
||||
} SubGhzRadioDeviceType;
|
||||
|
||||
/** SubGhzRxKeyState state */
|
||||
typedef enum {
|
||||
SubGhzRxKeyStateIDLE,
|
||||
|
||||
@@ -24,3 +24,4 @@ ADD_SCENE(subghz, delete_raw, DeleteRAW)
|
||||
ADD_SCENE(subghz, need_saving, NeedSaving)
|
||||
ADD_SCENE(subghz, rpc, Rpc)
|
||||
ADD_SCENE(subghz, region_info, RegionInfo)
|
||||
ADD_SCENE(subghz, radio_settings, RadioSettings)
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "../subghz_i.h"
|
||||
#include <lib/toolbox/value_index.h>
|
||||
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
|
||||
|
||||
enum SubGhzRadioSettingIndex {
|
||||
SubGhzRadioSettingIndexDevice,
|
||||
};
|
||||
|
||||
#define RADIO_DEVICE_COUNT 2
|
||||
const char* const radio_device_text[RADIO_DEVICE_COUNT] = {
|
||||
"Internal",
|
||||
"External",
|
||||
};
|
||||
|
||||
const uint32_t radio_device_value[RADIO_DEVICE_COUNT] = {
|
||||
SubGhzRadioDeviceTypeInternal,
|
||||
SubGhzRadioDeviceTypeExternalCC1101,
|
||||
};
|
||||
|
||||
static void subghz_scene_radio_settings_set_device(VariableItem* item) {
|
||||
SubGhz* subghz = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
void subghz_scene_radio_settings_on_enter(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
VariableItem* item;
|
||||
uint8_t 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;
|
||||
item = variable_item_list_add(
|
||||
subghz->variable_item_list,
|
||||
"Module",
|
||||
value_count_device,
|
||||
subghz_scene_radio_settings_set_device,
|
||||
subghz);
|
||||
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, radio_device_text[value_index]);
|
||||
|
||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList);
|
||||
}
|
||||
|
||||
bool subghz_scene_radio_settings_on_event(void* context, SceneManagerEvent event) {
|
||||
SubGhz* subghz = context;
|
||||
bool consumed = false;
|
||||
UNUSED(subghz);
|
||||
UNUSED(event);
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -48,6 +48,9 @@ static void subghz_scene_read_raw_update_statusbar(void* context) {
|
||||
|
||||
furi_string_free(frequency_str);
|
||||
furi_string_free(modulation_str);
|
||||
|
||||
subghz_read_raw_set_radio_device_type(
|
||||
subghz->subghz_read_raw, subghz_txrx_radio_device_get(subghz->txrx));
|
||||
}
|
||||
|
||||
void subghz_scene_read_raw_callback(SubGhzCustomEvent event, void* context) {
|
||||
@@ -238,7 +241,9 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
|
||||
furi_string_printf(
|
||||
temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, RAW_FILE_NAME, SUBGHZ_APP_EXTENSION);
|
||||
subghz_protocol_raw_gen_fff_data(
|
||||
subghz_txrx_get_fff_data(subghz->txrx), furi_string_get_cstr(temp_str));
|
||||
subghz_txrx_get_fff_data(subghz->txrx),
|
||||
furi_string_get_cstr(temp_str),
|
||||
subghz_txrx_radio_device_get_name(subghz->txrx));
|
||||
furi_string_free(temp_str);
|
||||
|
||||
if(spl_count > 0) {
|
||||
@@ -298,8 +303,8 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz_read_raw_update_sample_write(
|
||||
subghz->subghz_read_raw, subghz_protocol_raw_get_sample_write(decoder_raw));
|
||||
|
||||
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_read_raw_add_data_rssi(
|
||||
subghz->subghz_read_raw, ret_rssi.rssi, ret_rssi.is_above);
|
||||
subghz_protocol_raw_save_to_file_pause(decoder_raw, !ret_rssi.is_above);
|
||||
|
||||
@@ -56,6 +56,9 @@ static void subghz_scene_receiver_update_statusbar(void* context) {
|
||||
subghz->state_notifications = SubGhzNotificationStateIDLE;
|
||||
}
|
||||
furi_string_free(history_stat_str);
|
||||
|
||||
subghz_view_receiver_set_radio_device_type(
|
||||
subghz->subghz_receiver, subghz_txrx_radio_device_get(subghz->txrx));
|
||||
}
|
||||
|
||||
void subghz_scene_receiver_callback(SubGhzCustomEvent event, void* context) {
|
||||
@@ -189,7 +192,8 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz_scene_receiver_update_statusbar(subghz);
|
||||
}
|
||||
|
||||
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(
|
||||
|
||||
@@ -122,7 +122,8 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
|
||||
SubGhzCustomEventManagerNoSet) {
|
||||
subghz_protocol_raw_gen_fff_data(
|
||||
subghz_txrx_get_fff_data(subghz->txrx),
|
||||
furi_string_get_cstr(subghz->file_path));
|
||||
furi_string_get_cstr(subghz->file_path),
|
||||
subghz_txrx_radio_device_get_name(subghz->txrx));
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet);
|
||||
} else {
|
||||
|
||||
@@ -8,7 +8,8 @@ enum SubmenuIndex {
|
||||
SubmenuIndexAddManually,
|
||||
SubmenuIndexFrequencyAnalyzer,
|
||||
SubmenuIndexReadRAW,
|
||||
SubmenuIndexShowRegionInfo
|
||||
SubmenuIndexShowRegionInfo,
|
||||
SubmenuIndexRadioSetting,
|
||||
};
|
||||
|
||||
void subghz_scene_start_submenu_callback(void* context, uint32_t index) {
|
||||
@@ -49,6 +50,12 @@ void subghz_scene_start_on_enter(void* context) {
|
||||
SubmenuIndexShowRegionInfo,
|
||||
subghz_scene_start_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"Radio Settings",
|
||||
SubmenuIndexRadioSetting,
|
||||
subghz_scene_start_submenu_callback,
|
||||
subghz);
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||
submenu_add_item(
|
||||
subghz->submenu, "Test", SubmenuIndexTest, subghz_scene_start_submenu_callback, subghz);
|
||||
@@ -104,6 +111,11 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexShowRegionInfo);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneRegionInfo);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexRadioSetting) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRadioSetting);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneRadioSettings);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -35,6 +35,8 @@ bool subghz_scene_transmitter_update_data_show(void* context) {
|
||||
furi_string_free(modulation_str);
|
||||
furi_string_free(key_str);
|
||||
}
|
||||
subghz_view_transmitter_set_radio_device_type(
|
||||
subghz->subghz_transmitter, subghz_txrx_radio_device_get(subghz->txrx));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
#include <lib/subghz/transmitter.h>
|
||||
#include <lib/subghz/subghz_file_encoder_worker.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/devices/devices.h>
|
||||
#include <lib/subghz/devices/cc1101_configs.h>
|
||||
|
||||
#include "helpers/subghz_chat.h"
|
||||
|
||||
@@ -24,6 +28,19 @@
|
||||
|
||||
#define SUBGHZ_REGION_FILENAME "/int/.region_data"
|
||||
|
||||
static void subghz_cli_radio_device_power_on() {
|
||||
uint8_t attempts = 0;
|
||||
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
|
||||
furi_hal_power_enable_otg();
|
||||
//CC1101 power-up time
|
||||
furi_delay_ms(10);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -44,7 +61,7 @@ void subghz_cli_command_tx_carrier(Cli* cli, FuriString* args, void* context) {
|
||||
}
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
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(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||
@@ -88,7 +105,7 @@ void subghz_cli_command_rx_carrier(Cli* cli, FuriString* args, void* context) {
|
||||
}
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_ook_650khz_async_regs);
|
||||
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
|
||||
printf("Receiving at frequency %lu Hz\r\n", frequency);
|
||||
printf("Press CTRL+C to stop\r\n");
|
||||
@@ -109,44 +126,70 @@ 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;
|
||||
}
|
||||
return device;
|
||||
}
|
||||
|
||||
void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) {
|
||||
UNUSED(context);
|
||||
uint32_t frequency = 433920000;
|
||||
uint32_t key = 0x0074BADE;
|
||||
uint32_t repeat = 10;
|
||||
uint32_t te = 403;
|
||||
uint32_t device_ind = 0; // 0 - CC1101_INT, 1 - CC1101_EXT
|
||||
|
||||
if(furi_string_size(args)) {
|
||||
int ret =
|
||||
sscanf(furi_string_get_cstr(args), "%lx %lu %lu %lu", &key, &frequency, &te, &repeat);
|
||||
if(ret != 4) {
|
||||
int ret = sscanf(
|
||||
furi_string_get_cstr(args),
|
||||
"%lx %lu %lu %lu %lu",
|
||||
&key,
|
||||
&frequency,
|
||||
&te,
|
||||
&repeat,
|
||||
&device_ind);
|
||||
if(ret != 5) {
|
||||
printf(
|
||||
"sscanf returned %d, key: %lx, frequency: %lu, te:%lu, repeat: %lu\r\n",
|
||||
"sscanf returned %d, key: %lx, frequency: %lu, te: %lu, repeat: %lu, device: %lu\r\n ",
|
||||
ret,
|
||||
key,
|
||||
frequency,
|
||||
te,
|
||||
repeat);
|
||||
repeat,
|
||||
device_ind);
|
||||
cli_print_usage(
|
||||
"subghz tx",
|
||||
"<3 Byte Key: in hex> <Frequency: in Hz> <Te us> <Repeat count>",
|
||||
"<3 Byte Key: in hex> <Frequency: in Hz> <Te us> <Repeat count> <Device: 0 - CC1101_INT, 1 - CC1101_EXT>",
|
||||
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",
|
||||
"Transmitting at %lu, key %lx, te %lu, repeat %lu device %lu. Press CTRL+C to stop\r\n",
|
||||
frequency,
|
||||
key,
|
||||
te,
|
||||
repeat);
|
||||
repeat,
|
||||
device_ind);
|
||||
|
||||
FuriString* flipper_format_string = furi_string_alloc_printf(
|
||||
"Protocol: Princeton\n"
|
||||
@@ -170,25 +213,29 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) {
|
||||
SubGhzTransmitter* transmitter = subghz_transmitter_alloc_init(environment, "Princeton");
|
||||
subghz_transmitter_deserialize(transmitter, flipper_format);
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
|
||||
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();
|
||||
|
||||
if(furi_hal_subghz_start_async_tx(subghz_transmitter_yield, transmitter)) {
|
||||
while(!(furi_hal_subghz_is_async_tx_complete() || cli_cmd_interrupt_received(cli))) {
|
||||
if(subghz_devices_start_async_tx(device, subghz_transmitter_yield, transmitter)) {
|
||||
while(!(subghz_devices_is_async_complete_tx(device) || cli_cmd_interrupt_received(cli))) {
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
furi_delay_ms(333);
|
||||
}
|
||||
furi_hal_subghz_stop_async_tx();
|
||||
subghz_devices_stop_async_tx(device);
|
||||
|
||||
} else {
|
||||
printf("Transmission on this frequency is restricted in your region\r\n");
|
||||
}
|
||||
|
||||
furi_hal_subghz_sleep();
|
||||
subghz_devices_sleep(device);
|
||||
subghz_devices_end(device);
|
||||
subghz_devices_deinit();
|
||||
subghz_cli_radio_device_power_off();
|
||||
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
|
||||
flipper_format_free(flipper_format);
|
||||
@@ -233,21 +280,29 @@ static void subghz_cli_command_rx_callback(
|
||||
void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
|
||||
UNUSED(context);
|
||||
uint32_t frequency = 433920000;
|
||||
uint32_t device_ind = 0; // 0 - CC1101_INT, 1 - CC1101_EXT
|
||||
|
||||
if(furi_string_size(args)) {
|
||||
int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency);
|
||||
if(ret != 1) {
|
||||
printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency);
|
||||
cli_print_usage("subghz rx", "<Frequency: in Hz>", furi_string_get_cstr(args));
|
||||
return;
|
||||
}
|
||||
if(!furi_hal_subghz_is_frequency_valid(frequency)) {
|
||||
int ret = sscanf(furi_string_get_cstr(args), "%lu %lu", &frequency, &device_ind);
|
||||
if(ret != 2) {
|
||||
printf(
|
||||
"Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n",
|
||||
frequency);
|
||||
"sscanf returned %d, frequency: %lu device: %lu\r\n", ret, frequency, device_ind);
|
||||
cli_print_usage(
|
||||
"subghz rx",
|
||||
"<Frequency: in Hz> <Device: 0 - CC1101_INT, 1 - CC1101_EXT>",
|
||||
furi_string_get_cstr(args));
|
||||
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
|
||||
SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx));
|
||||
@@ -256,14 +311,14 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
|
||||
furi_check(instance->stream);
|
||||
|
||||
SubGhzEnvironment* environment = subghz_environment_alloc();
|
||||
subghz_environment_load_keystore(environment, EXT_PATH("subghz/assets/keeloq_mfcodes"));
|
||||
subghz_environment_load_keystore(environment, EXT_PATH("subghz/assets/keeloq_mfcodes_user"));
|
||||
subghz_environment_load_keystore(environment, SUBGHZ_KEYSTORE_DIR_NAME);
|
||||
subghz_environment_load_keystore(environment, SUBGHZ_KEYSTORE_DIR_USER_NAME);
|
||||
subghz_environment_set_came_atomo_rainbow_table_file_name(
|
||||
environment, EXT_PATH("subghz/assets/came_atomo"));
|
||||
environment, SUBGHZ_CAME_ATOMO_DIR_NAME);
|
||||
subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
|
||||
environment, EXT_PATH("subghz/assets/alutech_at_4n"));
|
||||
environment, SUBGHZ_ALUTECH_AT_4N_DIR_NAME);
|
||||
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
|
||||
environment, EXT_PATH("subghz/assets/nice_flor_s"));
|
||||
environment, SUBGHZ_NICE_FLOR_S_DIR_NAME);
|
||||
subghz_environment_set_protocol_registry(environment, (void*)&subghz_protocol_registry);
|
||||
|
||||
SubGhzReceiver* receiver = subghz_receiver_alloc_init(environment);
|
||||
@@ -271,18 +326,21 @@ 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(&gpio_cc1101_g0, 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();
|
||||
|
||||
// Prepare and start RX
|
||||
furi_hal_subghz_start_async_rx(subghz_cli_command_rx_capture_callback, instance);
|
||||
subghz_devices_start_async_rx(device, subghz_cli_command_rx_capture_callback, instance);
|
||||
|
||||
// Wait for packets to arrive
|
||||
printf("Listening at %lu. Press CTRL+C to stop\r\n", frequency);
|
||||
printf(
|
||||
"Listening at frequency: %lu device: %lu. Press CTRL+C to stop\r\n",
|
||||
frequency,
|
||||
device_ind);
|
||||
LevelDuration level_duration;
|
||||
while(!cli_cmd_interrupt_received(cli)) {
|
||||
int ret = furi_stream_buffer_receive(
|
||||
@@ -300,8 +358,11 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
|
||||
}
|
||||
|
||||
// Shutdown radio
|
||||
furi_hal_subghz_stop_async_rx();
|
||||
furi_hal_subghz_sleep();
|
||||
subghz_devices_stop_async_rx(device);
|
||||
subghz_devices_sleep(device);
|
||||
subghz_devices_end(device);
|
||||
subghz_devices_deinit();
|
||||
subghz_cli_radio_device_power_off();
|
||||
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
|
||||
@@ -341,7 +402,7 @@ 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_270khz_async_regs);
|
||||
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
|
||||
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
@@ -389,6 +450,7 @@ void subghz_cli_command_rx_raw(Cli* cli, FuriString* args, void* context) {
|
||||
furi_stream_buffer_free(instance->stream);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) {
|
||||
UNUSED(context);
|
||||
FuriString* file_name;
|
||||
@@ -442,25 +504,23 @@ void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) {
|
||||
SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx));
|
||||
|
||||
SubGhzEnvironment* environment = subghz_environment_alloc();
|
||||
if(subghz_environment_load_keystore(
|
||||
environment, EXT_PATH("subghz/assets/keeloq_mfcodes"))) {
|
||||
if(subghz_environment_load_keystore(environment, SUBGHZ_KEYSTORE_DIR_NAME)) {
|
||||
printf("SubGhz decode_raw: Load_keystore keeloq_mfcodes \033[0;32mOK\033[0m\r\n");
|
||||
} else {
|
||||
printf("SubGhz decode_raw: Load_keystore keeloq_mfcodes \033[0;31mERROR\033[0m\r\n");
|
||||
}
|
||||
if(subghz_environment_load_keystore(
|
||||
environment, EXT_PATH("subghz/assets/keeloq_mfcodes_user"))) {
|
||||
if(subghz_environment_load_keystore(environment, SUBGHZ_KEYSTORE_DIR_USER_NAME)) {
|
||||
printf("SubGhz decode_raw: Load_keystore keeloq_mfcodes_user \033[0;32mOK\033[0m\r\n");
|
||||
} else {
|
||||
printf(
|
||||
"SubGhz decode_raw: Load_keystore keeloq_mfcodes_user \033[0;31mERROR\033[0m\r\n");
|
||||
}
|
||||
subghz_environment_set_came_atomo_rainbow_table_file_name(
|
||||
environment, EXT_PATH("subghz/assets/came_atomo"));
|
||||
environment, SUBGHZ_CAME_ATOMO_DIR_NAME);
|
||||
subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
|
||||
environment, EXT_PATH("subghz/assets/alutech_at_4n"));
|
||||
environment, SUBGHZ_ALUTECH_AT_4N_DIR_NAME);
|
||||
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
|
||||
environment, EXT_PATH("subghz/assets/nice_flor_s"));
|
||||
environment, SUBGHZ_NICE_FLOR_S_DIR_NAME);
|
||||
subghz_environment_set_protocol_registry(environment, (void*)&subghz_protocol_registry);
|
||||
|
||||
SubGhzReceiver* receiver = subghz_receiver_alloc_init(environment);
|
||||
@@ -468,7 +528,8 @@ void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) {
|
||||
subghz_receiver_set_rx_callback(receiver, subghz_cli_command_rx_callback, instance);
|
||||
|
||||
SubGhzFileEncoderWorker* file_worker_encoder = subghz_file_encoder_worker_alloc();
|
||||
if(subghz_file_encoder_worker_start(file_worker_encoder, furi_string_get_cstr(file_name))) {
|
||||
if(subghz_file_encoder_worker_start(
|
||||
file_worker_encoder, furi_string_get_cstr(file_name), NULL)) {
|
||||
//the worker needs a file in order to open and read part of the file
|
||||
furi_delay_ms(100);
|
||||
}
|
||||
@@ -510,10 +571,11 @@ static void subghz_cli_command_print_usage() {
|
||||
printf("subghz <cmd> <args>\r\n");
|
||||
printf("Cmd list:\r\n");
|
||||
|
||||
printf("\tchat <frequency:in Hz>\t - Chat with other Flippers\r\n");
|
||||
printf(
|
||||
"\ttx <3 byte Key: in hex> <frequency: in Hz> <te: us> <repeat: count>\t - Transmitting key\r\n");
|
||||
printf("\trx <frequency:in Hz>\t - Receive\r\n");
|
||||
"\tchat <frequency:in Hz> <device: 0 - CC1101_INT, 1 - CC1101_EXT>\t - Chat with other Flippers\r\n");
|
||||
printf(
|
||||
"\ttx <3 byte Key: in hex> <frequency: in Hz> <te: us> <repeat: count> <device: 0 - CC1101_INT, 1 - CC1101_EXT>\t - Transmitting key\r\n");
|
||||
printf("\trx <frequency:in Hz> <device: 0 - CC1101_INT, 1 - CC1101_EXT>\t - Receive\r\n");
|
||||
printf("\trx_raw <frequency:in Hz>\t - Receive RAW\r\n");
|
||||
printf("\tdecode_raw <file_name: path_RAW_file>\t - Testing\r\n");
|
||||
|
||||
@@ -611,21 +673,29 @@ static void subghz_cli_command_encrypt_raw(Cli* cli, FuriString* args) {
|
||||
|
||||
static void subghz_cli_command_chat(Cli* cli, FuriString* args) {
|
||||
uint32_t frequency = 433920000;
|
||||
uint32_t device_ind = 0; // 0 - CC1101_INT, 1 - CC1101_EXT
|
||||
|
||||
if(furi_string_size(args)) {
|
||||
int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency);
|
||||
if(ret != 1) {
|
||||
printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency);
|
||||
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);
|
||||
int ret = sscanf(furi_string_get_cstr(args), "%lu %lu", &frequency, &device_ind);
|
||||
if(ret != 2) {
|
||||
printf("sscanf returned %d, Frequency: %lu\r\n", ret, frequency);
|
||||
printf("sscanf returned %d, Device: %lu\r\n", ret, device_ind);
|
||||
cli_print_usage(
|
||||
"subghz chat",
|
||||
"<Frequency: in Hz> <Device: 0 - CC1101_INT, 1 - CC1101_EXT>",
|
||||
furi_string_get_cstr(args));
|
||||
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;
|
||||
}
|
||||
if(!furi_hal_region_is_frequency_allowed(frequency)) {
|
||||
printf(
|
||||
"In your region, only reception on this frequency (%lu) is allowed,\r\n"
|
||||
@@ -635,7 +705,8 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args) {
|
||||
}
|
||||
|
||||
SubGhzChatWorker* subghz_chat = subghz_chat_worker_alloc(cli);
|
||||
if(!subghz_chat_worker_start(subghz_chat, frequency)) {
|
||||
|
||||
if(!subghz_chat_worker_start(subghz_chat, device, frequency)) {
|
||||
printf("Startup error SubGhzChatWorker\r\n");
|
||||
|
||||
if(subghz_chat_worker_is_running(subghz_chat)) {
|
||||
@@ -781,6 +852,10 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args) {
|
||||
furi_string_free(name);
|
||||
furi_string_free(output);
|
||||
furi_string_free(sysmsg);
|
||||
|
||||
subghz_devices_deinit();
|
||||
subghz_cli_radio_device_power_off();
|
||||
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!furi_hal_subghz_is_frequency_valid(temp_data32)) {
|
||||
if(!subghz_txrx_radio_device_is_frequecy_valid(subghz->txrx, temp_data32)) {
|
||||
FURI_LOG_E(TAG, "Frequency not supported");
|
||||
break;
|
||||
}
|
||||
@@ -163,7 +163,8 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
|
||||
if(!strcmp(furi_string_get_cstr(temp_str), "RAW")) {
|
||||
//if RAW
|
||||
subghz->load_type_file = SubGhzLoadTypeFileRaw;
|
||||
subghz_protocol_raw_gen_fff_data(fff_data, file_path);
|
||||
subghz_protocol_raw_gen_fff_data(
|
||||
fff_data, file_path, subghz_txrx_radio_device_get_name(subghz->txrx));
|
||||
} else {
|
||||
subghz->load_type_file = SubGhzLoadTypeFileKey;
|
||||
stream_copy_full(
|
||||
|
||||
@@ -62,6 +62,7 @@ typedef struct {
|
||||
uint16_t history_item;
|
||||
SubGhzViewReceiverBarShow bar_show;
|
||||
uint8_t u_rssi;
|
||||
SubGhzRadioDeviceType device_type;
|
||||
} SubGhzViewReceiverModel;
|
||||
|
||||
void subghz_receiver_rssi(SubGhzViewReceiver* instance, float rssi) {
|
||||
@@ -173,6 +174,17 @@ void subghz_view_receiver_add_data_statusbar(
|
||||
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);
|
||||
@@ -190,9 +202,9 @@ static void subghz_view_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool s
|
||||
static void subghz_view_rssi_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
||||
for(uint8_t i = 1; i < model->u_rssi; i++) {
|
||||
if(i % 5) {
|
||||
canvas_draw_dot(canvas, 46 + i, 50);
|
||||
canvas_draw_dot(canvas, 47 + i, 51);
|
||||
canvas_draw_dot(canvas, 46 + i, 52);
|
||||
canvas_draw_dot(canvas, 47 + i, 53);
|
||||
canvas_draw_dot(canvas, 46 + i, 54);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,22 +244,28 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
|
||||
if(model->history_item == 0) {
|
||||
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52);
|
||||
canvas_draw_icon(canvas, 0, 0, &I_Scanning_short_96x52);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 63, 44, "Scanning...");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
}
|
||||
|
||||
if(model->device_type == SubGhzRadioDeviceTypeInternal) {
|
||||
canvas_draw_icon(canvas, 108, 0, &I_Internal_antenna_20x12);
|
||||
} else {
|
||||
canvas_draw_icon(canvas, 108, 0, &I_External_antenna_20x12);
|
||||
}
|
||||
|
||||
subghz_view_rssi_draw(canvas, model);
|
||||
switch(model->bar_show) {
|
||||
case SubGhzViewReceiverBarShowLock:
|
||||
canvas_draw_icon(canvas, 64, 55, &I_Lock_7x8);
|
||||
canvas_draw_str(canvas, 74, 62, "Locked");
|
||||
canvas_draw_icon(canvas, 64, 56, &I_Lock_7x8);
|
||||
canvas_draw_str(canvas, 74, 64, "Locked");
|
||||
break;
|
||||
case SubGhzViewReceiverBarShowToUnlockPress:
|
||||
canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str));
|
||||
canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str));
|
||||
canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str));
|
||||
canvas_draw_str(canvas, 44, 64, furi_string_get_cstr(model->frequency_str));
|
||||
canvas_draw_str(canvas, 79, 64, furi_string_get_cstr(model->preset_str));
|
||||
canvas_draw_str(canvas, 97, 64, furi_string_get_cstr(model->history_stat_str));
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
elements_bold_rounded_frame(canvas, 14, 8, 99, 48);
|
||||
elements_multiline_text(canvas, 65, 26, "To unlock\npress:");
|
||||
@@ -258,13 +276,13 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
||||
canvas_draw_dot(canvas, 17, 61);
|
||||
break;
|
||||
case SubGhzViewReceiverBarShowUnlock:
|
||||
canvas_draw_icon(canvas, 64, 55, &I_Unlock_7x8);
|
||||
canvas_draw_str(canvas, 74, 62, "Unlocked");
|
||||
canvas_draw_icon(canvas, 64, 56, &I_Unlock_7x8);
|
||||
canvas_draw_str(canvas, 74, 64, "Unlocked");
|
||||
break;
|
||||
default:
|
||||
canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str));
|
||||
canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str));
|
||||
canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str));
|
||||
canvas_draw_str(canvas, 44, 64, furi_string_get_cstr(model->frequency_str));
|
||||
canvas_draw_str(canvas, 79, 64, furi_string_get_cstr(model->preset_str));
|
||||
canvas_draw_str(canvas, 97, 64, furi_string_get_cstr(model->history_stat_str));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,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_item_to_menu(
|
||||
SubGhzViewReceiver* subghz_receiver,
|
||||
const char* name,
|
||||
|
||||
@@ -177,7 +177,8 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel
|
||||
}
|
||||
subghz_frequency_analyzer_log_frequency_draw(canvas, model);
|
||||
} else {
|
||||
canvas_draw_str(canvas, 20, 8, "Frequency Analyzer");
|
||||
canvas_draw_str(canvas, 0, 8, "Frequency Analyzer");
|
||||
canvas_draw_icon(canvas, 108, 0, &I_Internal_antenna_20x12);
|
||||
canvas_draw_str(canvas, 0, 64, "RSSI");
|
||||
subghz_frequency_analyzer_draw_rssi(canvas, model->rssi, 20, 64);
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ typedef struct {
|
||||
uint8_t ind_sin;
|
||||
SubGhzReadRAWStatus status;
|
||||
float raw_threshold_rssi;
|
||||
SubGhzRadioDeviceType device_type;
|
||||
} SubGhzReadRAWModel;
|
||||
|
||||
void subghz_read_raw_set_callback(
|
||||
@@ -56,6 +57,14 @@ void subghz_read_raw_add_data_statusbar(
|
||||
true);
|
||||
}
|
||||
|
||||
void subghz_read_raw_set_radio_device_type(
|
||||
SubGhzReadRAW* instance,
|
||||
SubGhzRadioDeviceType device_type) {
|
||||
furi_assert(instance);
|
||||
with_view_model(
|
||||
instance->view, SubGhzReadRAWModel * model, { model->device_type = device_type; }, true);
|
||||
}
|
||||
|
||||
void subghz_read_raw_add_data_rssi(SubGhzReadRAW* instance, float rssi, bool trace) {
|
||||
furi_assert(instance);
|
||||
uint8_t u_rssi = 0;
|
||||
@@ -279,11 +288,16 @@ void subghz_read_raw_draw(Canvas* canvas, SubGhzReadRAWModel* model) {
|
||||
uint8_t graphics_mode = 1;
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(canvas, 5, 7, furi_string_get_cstr(model->frequency_str));
|
||||
canvas_draw_str(canvas, 40, 7, furi_string_get_cstr(model->preset_str));
|
||||
canvas_draw_str(canvas, 0, 9, furi_string_get_cstr(model->frequency_str));
|
||||
canvas_draw_str(canvas, 35, 9, furi_string_get_cstr(model->preset_str));
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 126, 0, AlignRight, AlignTop, furi_string_get_cstr(model->sample_write));
|
||||
canvas, 106, 2, AlignRight, AlignTop, furi_string_get_cstr(model->sample_write));
|
||||
|
||||
if(model->device_type == SubGhzRadioDeviceTypeInternal) {
|
||||
canvas_draw_icon(canvas, 108, 0, &I_Internal_antenna_20x12);
|
||||
} else {
|
||||
canvas_draw_icon(canvas, 108, 0, &I_External_antenna_20x12);
|
||||
}
|
||||
canvas_draw_line(canvas, 0, 14, 115, 14);
|
||||
canvas_draw_line(canvas, 0, 48, 115, 48);
|
||||
canvas_draw_line(canvas, 115, 14, 115, 48);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
#include "../helpers/subghz_types.h"
|
||||
#include "../helpers/subghz_custom_event.h"
|
||||
|
||||
#define SUBGHZ_RAW_THRESHOLD_MIN -90.0f
|
||||
@@ -36,6 +37,10 @@ void subghz_read_raw_add_data_statusbar(
|
||||
const char* frequency_str,
|
||||
const char* preset_str);
|
||||
|
||||
void subghz_read_raw_set_radio_device_type(
|
||||
SubGhzReadRAW* instance,
|
||||
SubGhzRadioDeviceType device_type);
|
||||
|
||||
void subghz_read_raw_update_sample_write(SubGhzReadRAW* instance, size_t sample);
|
||||
|
||||
void subghz_read_raw_stop_send(SubGhzReadRAW* instance);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "subghz_test_carrier.h"
|
||||
#include "../subghz_i.h"
|
||||
#include "../helpers/subghz_testing.h"
|
||||
#include <lib/subghz/devices/cc1101_configs.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
@@ -138,7 +139,7 @@ void subghz_test_carrier_enter(void* context) {
|
||||
SubGhzTestCarrier* subghz_test_carrier = context;
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_ook_650khz_async_regs);
|
||||
|
||||
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "subghz_test_packet.h"
|
||||
#include "../subghz_i.h"
|
||||
#include "../helpers/subghz_testing.h"
|
||||
#include <lib/subghz/devices/cc1101_configs.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
@@ -194,7 +195,7 @@ void subghz_test_packet_enter(void* context) {
|
||||
SubGhzTestPacket* instance = context;
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_ook_650khz_async_regs);
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "subghz_test_static.h"
|
||||
#include "../subghz_i.h"
|
||||
#include "../helpers/subghz_testing.h"
|
||||
#include <lib/subghz/devices/cc1101_configs.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
@@ -141,7 +142,7 @@ void subghz_test_static_enter(void* context) {
|
||||
SubGhzTestStatic* instance = context;
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_ook_650khz_async_regs);
|
||||
|
||||
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||
furi_hal_gpio_write(&gpio_cc1101_g0, false);
|
||||
|
||||
@@ -15,6 +15,7 @@ typedef struct {
|
||||
FuriString* preset_str;
|
||||
FuriString* key_str;
|
||||
bool show_button;
|
||||
SubGhzRadioDeviceType device_type;
|
||||
} SubGhzViewTransmitterModel;
|
||||
|
||||
void subghz_view_transmitter_set_callback(
|
||||
@@ -46,6 +47,17 @@ void subghz_view_transmitter_add_data_to_show(
|
||||
true);
|
||||
}
|
||||
|
||||
void subghz_view_transmitter_set_radio_device_type(
|
||||
SubGhzViewTransmitter* subghz_transmitter,
|
||||
SubGhzRadioDeviceType device_type) {
|
||||
furi_assert(subghz_transmitter);
|
||||
with_view_model(
|
||||
subghz_transmitter->view,
|
||||
SubGhzViewTransmitterModel * model,
|
||||
{ model->device_type = device_type; },
|
||||
true);
|
||||
}
|
||||
|
||||
static void subghz_view_transmitter_button_right(Canvas* canvas, const char* str) {
|
||||
const uint8_t button_height = 12;
|
||||
const uint8_t vertical_offset = 3;
|
||||
@@ -56,7 +68,7 @@ static void subghz_view_transmitter_button_right(Canvas* canvas, const char* str
|
||||
const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_offset;
|
||||
const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
|
||||
|
||||
const uint8_t x = (canvas_width(canvas) - button_width) / 2 + 40;
|
||||
const uint8_t x = (canvas_width(canvas) - button_width) / 2 + 44;
|
||||
const uint8_t y = canvas_height(canvas);
|
||||
|
||||
canvas_draw_box(canvas, x, y - button_height, button_width, button_height);
|
||||
@@ -88,7 +100,14 @@ void subghz_view_transmitter_draw(Canvas* canvas, SubGhzViewTransmitterModel* mo
|
||||
canvas, 0, 0, AlignLeft, AlignTop, furi_string_get_cstr(model->key_str));
|
||||
canvas_draw_str(canvas, 78, 7, furi_string_get_cstr(model->frequency_str));
|
||||
canvas_draw_str(canvas, 113, 7, furi_string_get_cstr(model->preset_str));
|
||||
if(model->show_button) subghz_view_transmitter_button_right(canvas, "Send");
|
||||
if(model->show_button) {
|
||||
if(model->device_type == SubGhzRadioDeviceTypeInternal) {
|
||||
canvas_draw_icon(canvas, 108, 39, &I_Internal_antenna_20x12);
|
||||
} else {
|
||||
canvas_draw_icon(canvas, 108, 39, &I_External_antenna_20x12);
|
||||
}
|
||||
subghz_view_transmitter_button_right(canvas, "Send");
|
||||
}
|
||||
}
|
||||
|
||||
bool subghz_view_transmitter_input(InputEvent* event, void* context) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
#include "../helpers/subghz_types.h"
|
||||
#include "../helpers/subghz_custom_event.h"
|
||||
|
||||
typedef struct SubGhzViewTransmitter SubGhzViewTransmitter;
|
||||
@@ -12,6 +13,10 @@ void subghz_view_transmitter_set_callback(
|
||||
SubGhzViewTransmitterCallback callback,
|
||||
void* context);
|
||||
|
||||
void subghz_view_transmitter_set_radio_device_type(
|
||||
SubGhzViewTransmitter* subghz_transmitter,
|
||||
SubGhzRadioDeviceType device_type);
|
||||
|
||||
SubGhzViewTransmitter* subghz_view_transmitter_alloc();
|
||||
|
||||
void subghz_view_transmitter_free(SubGhzViewTransmitter* subghz_transmitter);
|
||||
|
||||
Reference in New Issue
Block a user