Fix subghz merge

This commit is contained in:
Willy-JL
2023-07-14 00:03:56 +02:00
parent b670631aa3
commit f03cac5bdb
57 changed files with 1452 additions and 316 deletions

View File

@@ -0,0 +1,6 @@
# Placeholder
App(
appid="drivers",
name="Drivers device",
apptype=FlipperAppType.METAPACKAGE,
)

View File

@@ -0,0 +1,8 @@
App(
appid="radio_device_cc1101_ext",
apptype=FlipperAppType.PLUGIN,
targets=["f7"],
entry_point="subghz_device_cc1101_ext_ep",
requires=["subghz"],
fap_libs=["hwdrivers"],
)

View File

@@ -0,0 +1,206 @@
/**
* @file furi_hal_subghz.h
* SubGhz HAL API
*/
#pragma once
#include <lib/subghz/devices/preset.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <toolbox/level_duration.h>
#include <furi_hal_gpio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Mirror RX/TX async modulation signal to specified pin
*
* @warning Configures pin to output mode. Make sure it is not connected
* directly to power or ground.
*
* @param[in] pin pointer to the gpio pin structure or NULL to disable
*/
void subghz_device_cc1101_ext_set_async_mirror_pin(const GpioPin* pin);
/** Get data GPIO
*
* @return pointer to the gpio pin structure
*/
const GpioPin* subghz_device_cc1101_ext_get_data_gpio();
/** Initialize device
*
* @return true if success
*/
bool subghz_device_cc1101_ext_alloc();
/** Deinitialize device
*/
void subghz_device_cc1101_ext_free();
/** Check and switch to power save mode Used by internal API-HAL
* initialization routine Can be used to reinitialize device to safe state and
* send it to sleep
*/
bool subghz_device_cc1101_ext_is_connect();
/** Send device to sleep mode
*/
void subghz_device_cc1101_ext_sleep();
/** Dump info to stdout
*/
void subghz_device_cc1101_ext_dump_state();
/** Load custom registers from preset
*
* @param preset_data registers to load
*/
void subghz_device_cc1101_ext_load_custom_preset(const uint8_t* preset_data);
/** Load registers
*
* @param data Registers data
*/
void subghz_device_cc1101_ext_load_registers(const uint8_t* data);
/** Load PATABLE
*
* @param data 8 uint8_t values
*/
void subghz_device_cc1101_ext_load_patable(const uint8_t data[8]);
/** Write packet to FIFO
*
* @param data bytes array
* @param size size
*/
void subghz_device_cc1101_ext_write_packet(const uint8_t* data, uint8_t size);
/** Check if receive pipe is not empty
*
* @return true if not empty
*/
bool subghz_device_cc1101_ext_rx_pipe_not_empty();
/** Check if received data crc is valid
*
* @return true if valid
*/
bool subghz_device_cc1101_ext_is_rx_data_crc_valid();
/** Read packet from FIFO
*
* @param data pointer
* @param size size
*/
void subghz_device_cc1101_ext_read_packet(uint8_t* data, uint8_t* size);
/** Flush rx FIFO buffer
*/
void subghz_device_cc1101_ext_flush_rx();
/** Flush tx FIFO buffer
*/
void subghz_device_cc1101_ext_flush_tx();
/** Shutdown Issue SPWD command
* @warning registers content will be lost
*/
void subghz_device_cc1101_ext_shutdown();
/** Reset Issue reset command
* @warning registers content will be lost
*/
void subghz_device_cc1101_ext_reset();
/** Switch to Idle
*/
void subghz_device_cc1101_ext_idle();
/** Switch to Receive
*/
void subghz_device_cc1101_ext_rx();
/** Switch to Transmit
*
* @return true if the transfer is allowed by belonging to the region
*/
bool subghz_device_cc1101_ext_tx();
/** Get RSSI value in dBm
*
* @return RSSI value
*/
float subghz_device_cc1101_ext_get_rssi();
/** Get LQI
*
* @return LQI value
*/
uint8_t subghz_device_cc1101_ext_get_lqi();
/** Check if frequency is in valid range
*
* @param value frequency in Hz
*
* @return true if frequency is valid, otherwise false
*/
bool subghz_device_cc1101_ext_is_frequency_valid(uint32_t value);
/** Set frequency
*
* @param value frequency in Hz
*
* @return real frequency in Hz
*/
uint32_t subghz_device_cc1101_ext_set_frequency(uint32_t value);
/* High Level API */
/** Signal Timings Capture callback */
typedef void (*SubGhzDeviceCC1101ExtCaptureCallback)(bool level, uint32_t duration, void* context);
/** Enable signal timings capture Initializes GPIO and TIM2 for timings capture
*
* @param callback SubGhzDeviceCC1101ExtCaptureCallback
* @param context callback context
*/
void subghz_device_cc1101_ext_start_async_rx(
SubGhzDeviceCC1101ExtCaptureCallback callback,
void* context);
/** Disable signal timings capture Resets GPIO and TIM2
*/
void subghz_device_cc1101_ext_stop_async_rx();
/** Async TX callback type
* @param context callback context
* @return LevelDuration
*/
typedef LevelDuration (*SubGhzDeviceCC1101ExtCallback)(void* context);
/** Start async TX Initializes GPIO, TIM2 and DMA1 for signal output
*
* @param callback SubGhzDeviceCC1101ExtCallback
* @param context callback context
*
* @return true if the transfer is allowed by belonging to the region
*/
bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callback, void* context);
/** Wait for async transmission to complete
*
* @return true if TX complete
*/
bool subghz_device_cc1101_ext_is_async_tx_complete();
/** Stop async transmission and cleanup resources Resets GPIO, TIM2, and DMA1
*/
void subghz_device_cc1101_ext_stop_async_tx();
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,110 @@
#include "cc1101_ext_interconnect.h"
#include "cc1101_ext.h"
#include <lib/subghz/devices/cc1101_configs.h>
#define TAG "SubGhzDeviceCC1101Ext"
static bool subghz_device_cc1101_ext_interconnect_is_frequency_valid(uint32_t frequency) {
bool ret = subghz_device_cc1101_ext_is_frequency_valid(frequency);
if(!ret) {
furi_crash("SubGhz: Incorrect frequency.");
}
return ret;
}
static uint32_t subghz_device_cc1101_ext_interconnect_set_frequency(uint32_t frequency) {
subghz_device_cc1101_ext_interconnect_is_frequency_valid(frequency);
return subghz_device_cc1101_ext_set_frequency(frequency);
}
static bool subghz_device_cc1101_ext_interconnect_start_async_tx(void* callback, void* context) {
return subghz_device_cc1101_ext_start_async_tx(
(SubGhzDeviceCC1101ExtCallback)callback, context);
}
static void subghz_device_cc1101_ext_interconnect_start_async_rx(void* callback, void* context) {
subghz_device_cc1101_ext_start_async_rx(
(SubGhzDeviceCC1101ExtCaptureCallback)callback, context);
}
static void subghz_device_cc1101_ext_interconnect_load_preset(
FuriHalSubGhzPreset preset,
uint8_t* preset_data) {
switch(preset) {
case FuriHalSubGhzPresetOok650Async:
subghz_device_cc1101_ext_load_custom_preset(
subghz_device_cc1101_preset_ook_650khz_async_regs);
break;
case FuriHalSubGhzPresetOok270Async:
subghz_device_cc1101_ext_load_custom_preset(
subghz_device_cc1101_preset_ook_270khz_async_regs);
break;
case FuriHalSubGhzPreset2FSKDev238Async:
subghz_device_cc1101_ext_load_custom_preset(
subghz_device_cc1101_preset_2fsk_dev2_38khz_async_regs);
break;
case FuriHalSubGhzPreset2FSKDev476Async:
subghz_device_cc1101_ext_load_custom_preset(
subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs);
break;
case FuriHalSubGhzPresetMSK99_97KbAsync:
subghz_device_cc1101_ext_load_custom_preset(
subghz_device_cc1101_preset_msk_99_97kb_async_regs);
break;
case FuriHalSubGhzPresetGFSK9_99KbAsync:
subghz_device_cc1101_ext_load_custom_preset(
subghz_device_cc1101_preset_gfsk_9_99kb_async_regs);
break;
default:
subghz_device_cc1101_ext_load_custom_preset(preset_data);
}
}
const SubGhzDeviceInterconnect subghz_device_cc1101_ext_interconnect = {
.begin = subghz_device_cc1101_ext_alloc,
.end = subghz_device_cc1101_ext_free,
.is_connect = subghz_device_cc1101_ext_is_connect,
.reset = subghz_device_cc1101_ext_reset,
.sleep = subghz_device_cc1101_ext_sleep,
.idle = subghz_device_cc1101_ext_idle,
.load_preset = subghz_device_cc1101_ext_interconnect_load_preset,
.set_frequency = subghz_device_cc1101_ext_interconnect_set_frequency,
.is_frequency_valid = subghz_device_cc1101_ext_is_frequency_valid,
.set_async_mirror_pin = subghz_device_cc1101_ext_set_async_mirror_pin,
.get_data_gpio = subghz_device_cc1101_ext_get_data_gpio,
.set_tx = subghz_device_cc1101_ext_tx,
.flush_tx = subghz_device_cc1101_ext_flush_tx,
.start_async_tx = subghz_device_cc1101_ext_interconnect_start_async_tx,
.is_async_complete_tx = subghz_device_cc1101_ext_is_async_tx_complete,
.stop_async_tx = subghz_device_cc1101_ext_stop_async_tx,
.set_rx = subghz_device_cc1101_ext_rx,
.flush_rx = subghz_device_cc1101_ext_flush_rx,
.start_async_rx = subghz_device_cc1101_ext_interconnect_start_async_rx,
.stop_async_rx = subghz_device_cc1101_ext_stop_async_rx,
.get_rssi = subghz_device_cc1101_ext_get_rssi,
.get_lqi = subghz_device_cc1101_ext_get_lqi,
.rx_pipe_not_empty = subghz_device_cc1101_ext_rx_pipe_not_empty,
.is_rx_data_crc_valid = subghz_device_cc1101_ext_is_rx_data_crc_valid,
.read_packet = subghz_device_cc1101_ext_read_packet,
.write_packet = subghz_device_cc1101_ext_write_packet,
};
const SubGhzDevice subghz_device_cc1101_ext = {
.name = SUBGHZ_DEVICE_CC1101_EXT_NAME,
.interconnect = &subghz_device_cc1101_ext_interconnect,
};
static const FlipperAppPluginDescriptor subghz_device_cc1101_ext_descriptor = {
.appid = SUBGHZ_RADIO_DEVICE_PLUGIN_APP_ID,
.ep_api_version = SUBGHZ_RADIO_DEVICE_PLUGIN_API_VERSION,
.entry_point = &subghz_device_cc1101_ext,
};
const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep() {
return &subghz_device_cc1101_ext_descriptor;
}

View File

@@ -0,0 +1,8 @@
#pragma once
#include <lib/subghz/devices/types.h>
#define SUBGHZ_DEVICE_CC1101_EXT_NAME "cc1101_ext"
typedef struct SubGhzDeviceCC1101Ext SubGhzDeviceCC1101Ext;
const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep();

View File

@@ -720,7 +720,7 @@ void playlist_free(Playlist* app) {
free(app);
}
int32_t playlist_app(char* p) {
int32_t playlist_app(void* p) {
UNUSED(p);
dolphin_deed(DolphinDeedPluginStart);

View File

@@ -1,29 +1,10 @@
App(
appid="subghz_remote",
name="Sub-GHz Remote",
<<<<<<< HEAD:applications/external/subghz_remote/application.fam
apptype=FlipperAppType.EXTERNAL,
entry_point="subghz_remote_app",
cdefines=[
"APP_SUBGHZREMOTE",
"SUBREM_LIGHT",
],
requires=[
"gui",
"dialogs",
],
stack_size=2 * 1024,
order=11,
fap_icon="subrem_10px.png",
fap_category="Sub-GHz",
=======
apptype=FlipperAppType.MENUEXTERNAL,
entry_point="subghz_remote_app",
icon="A_SubGHzRemote_14",
stack_size=2 * 1024,
order=11,
fap_libs=["assets",],
fap_icon="icon.png",
fap_category="Sub-Ghz",
>>>>>>> ea357b8eafe91c3a07cb89c3b90d03b78e2633ff:applications/main/subghz_remote/application.fam
)

View File

@@ -0,0 +1,375 @@
#pragma once
#include <lib/subghz/subghz_worker.h>
#include <lib/subghz/subghz_setting.h>
#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;
typedef void (*SubGhzTxRxNeedSaveCallback)(void* context);
typedef enum {
SubGhzTxRxStartTxStateOk,
SubGhzTxRxStartTxStateErrorOnlyRx,
SubGhzTxRxStartTxStateErrorParserOthers,
} SubGhzTxRxStartTxState;
// Type from subghz_types.h need for txrx working
/** SubGhzTxRx state */
typedef enum {
SubGhzTxRxStateIDLE,
SubGhzTxRxStateRx,
SubGhzTxRxStateTx,
SubGhzTxRxStateSleep,
} SubGhzTxRxState;
/** SubGhzHopperState state */
typedef enum {
SubGhzHopperStateOFF,
SubGhzHopperStateRunning,
SubGhzHopperStatePause,
SubGhzHopperStateRSSITimeOut,
} SubGhzHopperState;
/** SubGhzSpeakerState state */
typedef enum {
SubGhzSpeakerStateDisable,
SubGhzSpeakerStateShutdown,
SubGhzSpeakerStateEnable,
} SubGhzSpeakerState;
/** SubGhzRadioDeviceType */
typedef enum {
SubGhzRadioDeviceTypeAuto,
SubGhzRadioDeviceTypeInternal,
SubGhzRadioDeviceTypeExternalCC1101,
} SubGhzRadioDeviceType;
/**
* Allocate SubGhzTxRx
*
* @return SubGhzTxRx* pointer to SubGhzTxRx
*/
SubGhzTxRx* subghz_txrx_alloc();
/**
* Free SubGhzTxRx
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_free(SubGhzTxRx* instance);
/**
* Check if the database is loaded
*
* @param instance Pointer to a SubGhzTxRx
* @return bool True if the database is loaded
*/
bool subghz_txrx_is_database_loaded(SubGhzTxRx* instance);
/**
* Set preset
*
* @param instance Pointer to a SubGhzTxRx
* @param preset_name Name of preset
* @param frequency Frequency in Hz
* @param preset_data Data of preset
* @param preset_data_size Size of preset data
*/
void subghz_txrx_set_preset(
SubGhzTxRx* instance,
const char* preset_name,
uint32_t frequency,
uint8_t* preset_data,
size_t preset_data_size);
/**
* Get name of preset
*
* @param instance Pointer to a SubGhzTxRx
* @param preset String of preset
* @return const char* Name of preset
*/
const char* subghz_txrx_get_preset_name(SubGhzTxRx* instance, const char* preset);
/**
* Get of preset
*
* @param instance Pointer to a SubGhzTxRx
* @return SubGhzRadioPreset Preset
*/
SubGhzRadioPreset subghz_txrx_get_preset(SubGhzTxRx* instance);
/**
* Get string frequency and modulation
*
* @param instance Pointer to a SubGhzTxRx
* @param frequency Pointer to a string frequency
* @param modulation Pointer to a string modulation
*/
void subghz_txrx_get_frequency_and_modulation(
SubGhzTxRx* instance,
FuriString* frequency,
FuriString* modulation,
bool long_name);
/**
* Start TX CC1101
*
* @param instance Pointer to a SubGhzTxRx
* @param flipper_format Pointer to a FlipperFormat
* @return SubGhzTxRxStartTxState
*/
SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat* flipper_format);
/**
* Start RX CC1101
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_rx_start(SubGhzTxRx* instance);
/**
* Stop TX/RX CC1101
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_stop(SubGhzTxRx* instance);
/**
* Set sleep mode CC1101
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_sleep(SubGhzTxRx* instance);
/**
* Update frequency CC1101 in automatic mode (hopper)
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_hopper_update(SubGhzTxRx* instance);
/**
* Get state hopper
*
* @param instance Pointer to a SubGhzTxRx
* @return SubGhzHopperState
*/
SubGhzHopperState subghz_txrx_hopper_get_state(SubGhzTxRx* instance);
/**
* Set state hopper
*
* @param instance Pointer to a SubGhzTxRx
* @param state State hopper
*/
void subghz_txrx_hopper_set_state(SubGhzTxRx* instance, SubGhzHopperState state);
/**
* Unpause hopper
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_hopper_unpause(SubGhzTxRx* instance);
/**
* Set pause hopper
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_hopper_pause(SubGhzTxRx* instance);
/**
* Speaker on
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_speaker_on(SubGhzTxRx* instance);
/**
* Speaker off
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_speaker_off(SubGhzTxRx* instance);
/**
* Speaker mute
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_speaker_mute(SubGhzTxRx* instance);
/**
* Speaker unmute
*
* @param instance Pointer to a SubGhzTxRx
*/
void subghz_txrx_speaker_unmute(SubGhzTxRx* instance);
/**
* Set state speaker
*
* @param instance Pointer to a SubGhzTxRx
* @param state State speaker
*/
void subghz_txrx_speaker_set_state(SubGhzTxRx* instance, SubGhzSpeakerState state);
/**
* Get state speaker
*
* @param instance Pointer to a SubGhzTxRx
* @return SubGhzSpeakerState
*/
SubGhzSpeakerState subghz_txrx_speaker_get_state(SubGhzTxRx* instance);
/**
* load decoder by name protocol
*
* @param instance Pointer to a SubGhzTxRx
* @param name_protocol Name protocol
* @return bool True if the decoder is loaded
*/
bool subghz_txrx_load_decoder_by_name_protocol(SubGhzTxRx* instance, const char* name_protocol);
/**
* Get decoder
*
* @param instance Pointer to a SubGhzTxRx
* @return SubGhzProtocolDecoderBase* Pointer to a SubGhzProtocolDecoderBase
*/
SubGhzProtocolDecoderBase* subghz_txrx_get_decoder(SubGhzTxRx* instance);
/**
* Set callback for save data
*
* @param instance Pointer to a SubGhzTxRx
* @param callback Callback for save data
* @param context Context for callback
*/
void subghz_txrx_set_need_save_callback(
SubGhzTxRx* instance,
SubGhzTxRxNeedSaveCallback callback,
void* context);
/**
* Get pointer to a load data key
*
* @param instance Pointer to a SubGhzTxRx
* @return FlipperFormat*
*/
FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance);
/**
* Get pointer to a SugGhzSetting
*
* @param instance Pointer to a SubGhzTxRx
* @return SubGhzSetting*
*/
SubGhzSetting* subghz_txrx_get_setting(SubGhzTxRx* instance);
/**
* Is it possible to save this protocol
*
* @param instance Pointer to a SubGhzTxRx
* @return bool True if it is possible to save this protocol
*/
bool subghz_txrx_protocol_is_serializable(SubGhzTxRx* instance);
/**
* Is it possible to send this protocol
*
* @param instance Pointer to a SubGhzTxRx
* @return bool True if it is possible to send this protocol
*/
bool subghz_txrx_protocol_is_transmittable(SubGhzTxRx* instance, bool check_type);
/**
* Set filter, what types of decoder to use
*
* @param instance Pointer to a SubGhzTxRx
* @param filter Filter
*/
void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag filter);
/**
* Set callback for receive data
*
* @param instance Pointer to a SubGhzTxRx
* @param callback Callback for receive data
* @param context Context for callback
*/
void subghz_txrx_set_rx_calback(
SubGhzTxRx* instance,
SubGhzReceiverCallback callback,
void* context);
/**
* Set callback for Raw decoder, end of data transfer
*
* @param instance Pointer to a SubGhzTxRx
* @param callback Callback for Raw decoder, end of data transfer
* @param context Context for callback
*/
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);
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

View File

@@ -10,6 +10,6 @@ App(
stack_size=2 * 1024,
order=50,
fap_description="File Editor for the SubGhz Remote app",
fap_category="Sub-Ghz",
fap_category="Sub-GHz",
fap_icon="subrem_10px.png",
)

View File

@@ -11,10 +11,7 @@ App(
],
provides=[
"subghz_start",
"subghz_load_extended_settings",
],
sdk_headers=[
"helpers/subghz_txrx.h",
"subghz_load_dangerous_settings",
],
icon="A_Sub1ghz_14",
stack_size=3 * 1024,
@@ -32,9 +29,9 @@ App(
)
App(
appid="subghz_load_extended_settings",
appid="subghz_load_dangerous_settings",
apptype=FlipperAppType.STARTUP,
entry_point="subghz_extended_freq",
entry_point="subghz_dangerous_freq",
requires=["storage", "subghz"],
order=650,
)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)) {

View File

@@ -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);

View File

@@ -8,6 +8,21 @@
#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();
@@ -28,16 +43,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);
@@ -48,18 +62,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);
}
@@ -145,7 +173,12 @@ static uint32_t subghz_txrx_rx(SubGhzTxRx* instance, uint32_t frequency) {
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;
@@ -154,7 +187,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;
}
@@ -165,24 +198,21 @@ 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);
subghz_devices_idle(instance->radio_device);
@@ -250,8 +280,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;
@@ -294,7 +324,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);
@@ -307,7 +337,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) {
@@ -357,7 +386,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) {
@@ -638,4 +667,4 @@ void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) {
SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) {
furi_assert(instance);
return instance->receiver;
}
}

View File

@@ -7,10 +7,7 @@
#include <lib/subghz/receiver.h>
#include <lib/subghz/transmitter.h>
#include <lib/subghz/protocols/raw.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <lib/subghz/devices/devices.h>
typedef struct SubGhzTxRx SubGhzTxRx;

View File

@@ -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;

View File

@@ -35,6 +35,13 @@ typedef enum {
SubGhzSpeakerStateEnable,
} SubGhzSpeakerState;
/** SubGhzRadioDeviceType */
typedef enum {
SubGhzRadioDeviceTypeAuto,
SubGhzRadioDeviceTypeInternal,
SubGhzRadioDeviceTypeExternalCC1101,
} SubGhzRadioDeviceType;
/** SubGhzRxKeyState state */
typedef enum {
SubGhzRxKeyStateIDLE,

View File

@@ -52,6 +52,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) {
@@ -116,15 +119,17 @@ void subghz_scene_read_raw_on_enter(void* context) {
// Start sending immediately with favorites
if(subghz->fav_timeout) {
with_view_model(
subghz->subghz_read_raw->view,
SubGhzReadRAWModel * model,
{
scene_manager_handle_custom_event(
subghz->scene_manager, SubGhzCustomEventViewReadRAWSendStart);
model->status = SubGhzReadRAWStatusTXRepeat;
},
true);
scene_manager_handle_custom_event(
subghz->scene_manager, SubGhzCustomEventViewReadRAWSendStart);
// with_view_model(
// subghz->subghz_read_raw->view,
// SubGhzReadRAWModel * model,
// {
// scene_manager_handle_custom_event(
// subghz->scene_manager, SubGhzCustomEventViewReadRAWSendStart);
// model->status = SubGhzReadRAWStatusTXRepeat;
// },
// true);
}
}
@@ -267,7 +272,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) {
@@ -327,8 +334,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);

View File

@@ -80,6 +80,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) {

View File

@@ -14,6 +14,7 @@ void subghz_scene_rpc_on_enter(void* context) {
popup_set_header(popup, "Sub-GHz", 89, 42, AlignCenter, AlignBottom);
popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup);

View File

@@ -163,7 +163,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 {

View File

@@ -39,6 +39,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;
}
@@ -66,19 +68,19 @@ void subghz_scene_transmitter_on_enter(void* context) {
// Auto send and exit with favorites
if(subghz->fav_timeout) {
subghz_custom_btn_set(0);
// subghz_custom_btn_set(0);
scene_manager_handle_custom_event(
subghz->scene_manager, SubGhzCustomEventViewTransmitterSendStart);
with_view_model(
subghz->subghz_transmitter->view,
SubGhzViewTransmitterModel * model,
{ model->show_button = false; },
true);
// with_view_model(
// subghz->subghz_transmitter->view,
// SubGhzViewTransmitterModel * model,
// { model->show_button = false; },
// true);
subghz->fav_timer = furi_timer_alloc(fav_timer_callback, FuriTimerTypeOnce, subghz);
furi_timer_start(
subghz->fav_timer,
XTREME_SETTINGS()->favorite_timeout * furi_kernel_get_tick_frequency());
subghz->state_notifications = SubGhzNotificationStateTx;
// subghz->state_notifications = SubGhzNotificationStateTx;
}
}

View File

@@ -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"
@@ -65,7 +69,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);
@@ -109,7 +113,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");
@@ -157,21 +161,29 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) {
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;
}
@@ -186,11 +198,12 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) {
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"
@@ -214,25 +227,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("Frequency is outside of default range. Check docs.\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);
@@ -276,12 +293,17 @@ 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));
int ret = sscanf(furi_string_get_cstr(args), "%lu %lu", &frequency, &device_ind);
if(ret != 2) {
printf(
"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;
}
}
@@ -302,14 +324,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);
@@ -325,10 +347,13 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
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(
@@ -346,8 +371,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();
@@ -435,6 +463,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 = furi_string_alloc();
@@ -486,25 +515,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);
@@ -512,7 +539,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);
}
@@ -554,10 +582,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");
@@ -652,12 +681,17 @@ static void subghz_cli_command_encrypt_raw(Cli* cli, FuriString* args) {
static void subghz_cli_command_chat(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 chat", "<Frequency: in Hz>", furi_string_get_cstr(args));
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;
}
}
@@ -681,7 +715,8 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args, void* context) {
}
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)) {
@@ -823,6 +858,10 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args, void* context) {
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);

View File

@@ -0,0 +1,23 @@
#include <furi.h>
#include <furi_hal.h>
#include <firmware/targets/f7/furi_hal/furi_hal_subghz_i.h>
#include <flipper_format/flipper_format_i.h>
void subghz_dangerous_freq() {
bool is_extended_i = false;
Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
if(flipper_format_file_open_existing(fff_data_file, "/ext/subghz/assets/dangerous_settings")) {
flipper_format_read_bool(
fff_data_file, "yes_i_want_to_destroy_my_flipper", &is_extended_i, 1);
}
furi_hal_subghz_set_dangerous_frequency(is_extended_i);
flipper_format_free(fff_data_file);
furi_record_close(RECORD_STORAGE);
}

View File

@@ -1,19 +0,0 @@
#include <furi.h>
#include <furi_hal.h>
#include <furi_hal_subghz_i.h>
#include <flipper_format/flipper_format_i.h>
void subghz_extended_freq() {
bool is_extended_i = false;
Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* file = flipper_format_file_alloc(storage);
if(flipper_format_file_open_existing(file, "/ext/subghz/assets/extend_range.txt")) {
flipper_format_read_bool(file, "use_ext_range_at_own_risk", &is_extended_i, 1);
}
furi_hal_subghz_set_extended_frequency(is_extended_i);
flipper_format_free(file);
furi_record_close(RECORD_STORAGE);
}

View File

@@ -170,7 +170,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(

View File

@@ -59,6 +59,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;

View File

@@ -1,17 +1,14 @@
#pragma once
#include <gui/view.h>
#include "../helpers/subghz_types.h"
#include "../helpers/subghz_custom_event.h"
#define SUBGHZ_RAW_THRESHOLD_MIN -90.0f
typedef void (*SubGhzReadRAWCallback)(SubGhzCustomEvent event, void* context);
typedef struct SubGhzReadRAW SubGhzReadRAW;
typedef struct {
View* view;
SubGhzReadRAWCallback callback;
void* context;
} SubGhzReadRAW;
typedef void (*SubGhzReadRAWCallback)(SubGhzCustomEvent event, void* context);
typedef enum {
SubGhzReadRAWStatusStart,
@@ -26,22 +23,6 @@ typedef enum {
SubGhzReadRAWStatusSaveKey,
} SubGhzReadRAWStatus;
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;
} SubGhzReadRAWModel;
void subghz_read_raw_set_callback(
SubGhzReadRAW* subghz_read_raw,
SubGhzReadRAWCallback callback,
@@ -56,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);

View File

@@ -51,6 +51,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;

View File

@@ -1,30 +1,22 @@
#pragma once
#include <gui/view.h>
#include "../helpers/subghz_types.h"
#include "../helpers/subghz_custom_event.h"
typedef struct {
FuriString* frequency_str;
FuriString* preset_str;
FuriString* key_str;
bool show_button;
FuriString* temp_button_id;
bool draw_temp_button;
} SubGhzViewTransmitterModel;
typedef struct SubGhzViewTransmitter SubGhzViewTransmitter;
typedef void (*SubGhzViewTransmitterCallback)(SubGhzCustomEvent event, void* context);
typedef struct {
View* view;
SubGhzViewTransmitterCallback callback;
void* context;
} SubGhzViewTransmitter;
void subghz_view_transmitter_set_callback(
SubGhzViewTransmitter* subghz_transmitter,
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);

View File

@@ -1,7 +1,6 @@
entry,status,name,type,params
Version,+,34.1,,
Header,+,applications/main/archive/helpers/favorite_timeout.h,,
Header,+,applications/main/subghz/helpers/subghz_txrx.h,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
@@ -2983,42 +2982,6 @@ Function,+,subghz_tx_rx_worker_set_callback_have_read,void,"SubGhzTxRxWorker*, S
Function,+,subghz_tx_rx_worker_start,_Bool,"SubGhzTxRxWorker*, uint32_t"
Function,+,subghz_tx_rx_worker_stop,void,SubGhzTxRxWorker*
Function,+,subghz_tx_rx_worker_write,_Bool,"SubGhzTxRxWorker*, uint8_t*, size_t"
Function,+,subghz_txrx_alloc,SubGhzTxRx*,
Function,+,subghz_txrx_free,void,SubGhzTxRx*
Function,-,subghz_txrx_get_debug_pin_state,_Bool,SubGhzTxRx*
Function,+,subghz_txrx_get_decoder,SubGhzProtocolDecoderBase*,SubGhzTxRx*
Function,-,subghz_txrx_get_fff_data,FlipperFormat*,SubGhzTxRx*
Function,-,subghz_txrx_get_frequency_and_modulation,void,"SubGhzTxRx*, FuriString*, FuriString*, _Bool"
Function,-,subghz_txrx_get_preset,SubGhzRadioPreset,SubGhzTxRx*
Function,+,subghz_txrx_get_preset_name,const char*,"SubGhzTxRx*, const char*"
Function,-,subghz_txrx_get_receiver,SubGhzReceiver*,SubGhzTxRx*
Function,+,subghz_txrx_get_setting,SubGhzSetting*,SubGhzTxRx*
Function,-,subghz_txrx_hopper_get_state,SubGhzHopperState,SubGhzTxRx*
Function,-,subghz_txrx_hopper_pause,void,SubGhzTxRx*
Function,-,subghz_txrx_hopper_set_state,void,"SubGhzTxRx*, SubGhzHopperState"
Function,-,subghz_txrx_hopper_unpause,void,SubGhzTxRx*
Function,-,subghz_txrx_hopper_update,void,SubGhzTxRx*
Function,-,subghz_txrx_is_database_loaded,_Bool,SubGhzTxRx*
Function,+,subghz_txrx_load_decoder_by_name_protocol,_Bool,"SubGhzTxRx*, const char*"
Function,-,subghz_txrx_protocol_is_serializable,_Bool,SubGhzTxRx*
Function,-,subghz_txrx_protocol_is_transmittable,_Bool,"SubGhzTxRx*, _Bool"
Function,-,subghz_txrx_receiver_set_filter,void,"SubGhzTxRx*, SubGhzProtocolFlag"
Function,+,subghz_txrx_reset_dynamic_and_custom_btns,void,SubGhzTxRx*
Function,-,subghz_txrx_rx_start,void,SubGhzTxRx*
Function,-,subghz_txrx_set_debug_pin_state,void,"SubGhzTxRx*, _Bool"
Function,+,subghz_txrx_set_need_save_callback,void,"SubGhzTxRx*, SubGhzTxRxNeedSaveCallback, void*"
Function,+,subghz_txrx_set_preset,void,"SubGhzTxRx*, const char*, uint32_t, uint8_t*, size_t"
Function,+,subghz_txrx_set_raw_file_encoder_worker_callback_end,void,"SubGhzTxRx*, SubGhzProtocolEncoderRAWCallbackEnd, void*"
Function,-,subghz_txrx_set_rx_calback,void,"SubGhzTxRx*, SubGhzReceiverCallback, void*"
Function,-,subghz_txrx_sleep,void,SubGhzTxRx*
Function,-,subghz_txrx_speaker_get_state,SubGhzSpeakerState,SubGhzTxRx*
Function,-,subghz_txrx_speaker_mute,void,SubGhzTxRx*
Function,-,subghz_txrx_speaker_off,void,SubGhzTxRx*
Function,-,subghz_txrx_speaker_on,void,SubGhzTxRx*
Function,-,subghz_txrx_speaker_set_state,void,"SubGhzTxRx*, SubGhzSpeakerState"
Function,-,subghz_txrx_speaker_unmute,void,SubGhzTxRx*
Function,+,subghz_txrx_stop,void,SubGhzTxRx*
Function,+,subghz_txrx_tx_start,SubGhzTxRxStartTxState,"SubGhzTxRx*, FlipperFormat*"
Function,+,subghz_worker_alloc,SubGhzWorker*,
Function,+,subghz_worker_free,void,SubGhzWorker*
Function,+,subghz_worker_is_running,_Bool,SubGhzWorker*
1 entry status name type params
2 Version + 34.1
3 Header + applications/main/archive/helpers/favorite_timeout.h
Header + applications/main/subghz/helpers/subghz_txrx.h
4 Header + applications/services/bt/bt_service/bt.h
5 Header + applications/services/cli/cli.h
6 Header + applications/services/cli/cli_vcp.h
2982 Function + subghz_tx_rx_worker_start _Bool SubGhzTxRxWorker*, uint32_t
2983 Function + subghz_tx_rx_worker_stop void SubGhzTxRxWorker*
2984 Function + subghz_tx_rx_worker_write _Bool SubGhzTxRxWorker*, uint8_t*, size_t
Function + subghz_txrx_alloc SubGhzTxRx*
Function + subghz_txrx_free void SubGhzTxRx*
Function - subghz_txrx_get_debug_pin_state _Bool SubGhzTxRx*
Function + subghz_txrx_get_decoder SubGhzProtocolDecoderBase* SubGhzTxRx*
Function - subghz_txrx_get_fff_data FlipperFormat* SubGhzTxRx*
Function - subghz_txrx_get_frequency_and_modulation void SubGhzTxRx*, FuriString*, FuriString*, _Bool
Function - subghz_txrx_get_preset SubGhzRadioPreset SubGhzTxRx*
Function + subghz_txrx_get_preset_name const char* SubGhzTxRx*, const char*
Function - subghz_txrx_get_receiver SubGhzReceiver* SubGhzTxRx*
Function + subghz_txrx_get_setting SubGhzSetting* SubGhzTxRx*
Function - subghz_txrx_hopper_get_state SubGhzHopperState SubGhzTxRx*
Function - subghz_txrx_hopper_pause void SubGhzTxRx*
Function - subghz_txrx_hopper_set_state void SubGhzTxRx*, SubGhzHopperState
Function - subghz_txrx_hopper_unpause void SubGhzTxRx*
Function - subghz_txrx_hopper_update void SubGhzTxRx*
Function - subghz_txrx_is_database_loaded _Bool SubGhzTxRx*
Function + subghz_txrx_load_decoder_by_name_protocol _Bool SubGhzTxRx*, const char*
Function - subghz_txrx_protocol_is_serializable _Bool SubGhzTxRx*
Function - subghz_txrx_protocol_is_transmittable _Bool SubGhzTxRx*, _Bool
Function - subghz_txrx_receiver_set_filter void SubGhzTxRx*, SubGhzProtocolFlag
Function + subghz_txrx_reset_dynamic_and_custom_btns void SubGhzTxRx*
Function - subghz_txrx_rx_start void SubGhzTxRx*
Function - subghz_txrx_set_debug_pin_state void SubGhzTxRx*, _Bool
Function + subghz_txrx_set_need_save_callback void SubGhzTxRx*, SubGhzTxRxNeedSaveCallback, void*
Function + subghz_txrx_set_preset void SubGhzTxRx*, const char*, uint32_t, uint8_t*, size_t
Function + subghz_txrx_set_raw_file_encoder_worker_callback_end void SubGhzTxRx*, SubGhzProtocolEncoderRAWCallbackEnd, void*
Function - subghz_txrx_set_rx_calback void SubGhzTxRx*, SubGhzReceiverCallback, void*
Function - subghz_txrx_sleep void SubGhzTxRx*
Function - subghz_txrx_speaker_get_state SubGhzSpeakerState SubGhzTxRx*
Function - subghz_txrx_speaker_mute void SubGhzTxRx*
Function - subghz_txrx_speaker_off void SubGhzTxRx*
Function - subghz_txrx_speaker_on void SubGhzTxRx*
Function - subghz_txrx_speaker_set_state void SubGhzTxRx*, SubGhzSpeakerState
Function - subghz_txrx_speaker_unmute void SubGhzTxRx*
Function + subghz_txrx_stop void SubGhzTxRx*
Function + subghz_txrx_tx_start SubGhzTxRxStartTxState SubGhzTxRx*, FlipperFormat*
2985 Function + subghz_worker_alloc SubGhzWorker*
2986 Function + subghz_worker_free void SubGhzWorker*
2987 Function + subghz_worker_is_running _Bool SubGhzWorker*

View File

@@ -14,7 +14,6 @@ env.Append(
File("transmitter.h"),
File("protocols/raw.h"),
File("blocks/const.h"),
File("blocks/custom_btn.h"),
File("blocks/decoder.h"),
File("blocks/encoder.h"),
File("blocks/generic.h"),
@@ -22,6 +21,7 @@ env.Append(
File("blocks/custom_btn.h"),
File("subghz_setting.h"),
File("subghz_protocol_registry.h"),
File("devices/cc1101_configs.h"),
],
)

View File

@@ -0,0 +1,96 @@
#include "cc1101_int_interconnect.h"
#include <furi_hal.h>
#include "../cc1101_configs.h"
#define TAG "SubGhzDeviceCC1101Int"
static bool subghz_device_cc1101_int_interconnect_is_frequency_valid(uint32_t frequency) {
bool ret = furi_hal_subghz_is_frequency_valid(frequency);
if(!ret) {
furi_crash("SubGhz: Incorrect frequency.");
}
return ret;
}
static uint32_t subghz_device_cc1101_int_interconnect_set_frequency(uint32_t frequency) {
subghz_device_cc1101_int_interconnect_is_frequency_valid(frequency);
return furi_hal_subghz_set_frequency_and_path(frequency);
}
static bool subghz_device_cc1101_int_interconnect_start_async_tx(void* callback, void* context) {
return furi_hal_subghz_start_async_tx((FuriHalSubGhzAsyncTxCallback)callback, context);
}
static void subghz_device_cc1101_int_interconnect_start_async_rx(void* callback, void* context) {
furi_hal_subghz_start_async_rx((FuriHalSubGhzCaptureCallback)callback, context);
}
static void subghz_device_cc1101_int_interconnect_load_preset(
FuriHalSubGhzPreset preset,
uint8_t* preset_data) {
switch(preset) {
case FuriHalSubGhzPresetOok650Async:
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_ook_650khz_async_regs);
break;
case FuriHalSubGhzPresetOok270Async:
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_ook_270khz_async_regs);
break;
case FuriHalSubGhzPreset2FSKDev238Async:
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_2fsk_dev2_38khz_async_regs);
break;
case FuriHalSubGhzPreset2FSKDev476Async:
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs);
break;
case FuriHalSubGhzPresetMSK99_97KbAsync:
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_msk_99_97kb_async_regs);
break;
case FuriHalSubGhzPresetGFSK9_99KbAsync:
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_gfsk_9_99kb_async_regs);
break;
default:
furi_hal_subghz_load_custom_preset(preset_data);
}
}
static bool subghz_device_cc1101_int_interconnect_is_connect(void) {
return true;
}
const SubGhzDeviceInterconnect subghz_device_cc1101_int_interconnect = {
.begin = NULL,
.end = furi_hal_subghz_shutdown,
.is_connect = subghz_device_cc1101_int_interconnect_is_connect,
.reset = furi_hal_subghz_reset,
.sleep = furi_hal_subghz_sleep,
.idle = furi_hal_subghz_idle,
.load_preset = subghz_device_cc1101_int_interconnect_load_preset,
.set_frequency = subghz_device_cc1101_int_interconnect_set_frequency,
.is_frequency_valid = furi_hal_subghz_is_frequency_valid,
.set_async_mirror_pin = furi_hal_subghz_set_async_mirror_pin,
.get_data_gpio = furi_hal_subghz_get_data_gpio,
.set_tx = furi_hal_subghz_tx,
.flush_tx = furi_hal_subghz_flush_tx,
.start_async_tx = subghz_device_cc1101_int_interconnect_start_async_tx,
.is_async_complete_tx = furi_hal_subghz_is_async_tx_complete,
.stop_async_tx = furi_hal_subghz_stop_async_tx,
.set_rx = furi_hal_subghz_rx,
.flush_rx = furi_hal_subghz_flush_rx,
.start_async_rx = subghz_device_cc1101_int_interconnect_start_async_rx,
.stop_async_rx = furi_hal_subghz_stop_async_rx,
.get_rssi = furi_hal_subghz_get_rssi,
.get_lqi = furi_hal_subghz_get_lqi,
.rx_pipe_not_empty = furi_hal_subghz_rx_pipe_not_empty,
.is_rx_data_crc_valid = furi_hal_subghz_is_rx_data_crc_valid,
.read_packet = furi_hal_subghz_read_packet,
.write_packet = furi_hal_subghz_write_packet,
};
const SubGhzDevice subghz_device_cc1101_int = {
.name = SUBGHZ_DEVICE_CC1101_INT_NAME,
.interconnect = &subghz_device_cc1101_int_interconnect,
};

View File

@@ -0,0 +1,8 @@
#pragma once
#include "../types.h"
#define SUBGHZ_DEVICE_CC1101_INT_NAME "cc1101_int"
typedef struct SubGhzDeviceCC1101Int SubGhzDeviceCC1101Int;
extern const SubGhzDevice subghz_device_cc1101_int;

View File

@@ -0,0 +1,13 @@
#pragma once
#include "registry.h"
#ifdef __cplusplus
extern "C" {
#endif
extern const SubGhzDeviceRegistry subghz_device_registry;
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,52 @@
#pragma once
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct SubGhzDevice SubGhzDevice;
void subghz_devices_init();
void subghz_devices_deinit(void);
const SubGhzDevice* subghz_devices_get_by_name(const char* device_name);
const char* subghz_devices_get_name(const SubGhzDevice* device);
bool subghz_devices_begin(const SubGhzDevice* device);
void subghz_devices_end(const SubGhzDevice* device);
bool subghz_devices_is_connect(const SubGhzDevice* device);
void subghz_devices_reset(const SubGhzDevice* device);
void subghz_devices_sleep(const SubGhzDevice* device);
void subghz_devices_idle(const SubGhzDevice* device);
void subghz_devices_load_preset(
const SubGhzDevice* device,
FuriHalSubGhzPreset preset,
uint8_t* preset_data);
uint32_t subghz_devices_set_frequency(const SubGhzDevice* device, uint32_t frequency);
bool subghz_devices_is_frequency_valid(const SubGhzDevice* device, uint32_t frequency);
void subghz_devices_set_async_mirror_pin(const SubGhzDevice* device, const GpioPin* gpio);
const GpioPin* subghz_devices_get_data_gpio(const SubGhzDevice* device);
bool subghz_devices_set_tx(const SubGhzDevice* device);
void subghz_devices_flush_tx(const SubGhzDevice* device);
bool subghz_devices_start_async_tx(const SubGhzDevice* device, void* callback, void* context);
bool subghz_devices_is_async_complete_tx(const SubGhzDevice* device);
void subghz_devices_stop_async_tx(const SubGhzDevice* device);
void subghz_devices_set_rx(const SubGhzDevice* device);
void subghz_devices_flush_rx(const SubGhzDevice* device);
void subghz_devices_start_async_rx(const SubGhzDevice* device, void* callback, void* context);
void subghz_devices_stop_async_rx(const SubGhzDevice* device);
float subghz_devices_get_rssi(const SubGhzDevice* device);
uint8_t subghz_devices_get_lqi(const SubGhzDevice* device);
bool subghz_devices_rx_pipe_not_empty(const SubGhzDevice* device);
bool subghz_devices_is_rx_data_crc_valid(const SubGhzDevice* device);
void subghz_devices_read_packet(const SubGhzDevice* device, uint8_t* data, uint8_t* size);
void subghz_devices_write_packet(const SubGhzDevice* device, const uint8_t* data, uint8_t size);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,13 @@
#pragma once
/** Radio Presets */
typedef enum {
FuriHalSubGhzPresetIDLE, /**< default configuration */
FuriHalSubGhzPresetOok270Async, /**< OOK, bandwidth 270kHz, asynchronous */
FuriHalSubGhzPresetOok650Async, /**< OOK, bandwidth 650kHz, asynchronous */
FuriHalSubGhzPreset2FSKDev238Async, /**< FM, deviation 2.380371 kHz, asynchronous */
FuriHalSubGhzPreset2FSKDev476Async, /**< FM, deviation 47.60742 kHz, asynchronous */
FuriHalSubGhzPresetMSK99_97KbAsync, /**< MSK, deviation 47.60742 kHz, 99.97Kb/s, asynchronous */
FuriHalSubGhzPresetGFSK9_99KbAsync, /**< GFSK, deviation 19.042969 kHz, 9.996Kb/s, asynchronous */
FuriHalSubGhzPresetCustom, /**Custom Preset*/
} FuriHalSubGhzPreset;

View File

@@ -0,0 +1,76 @@
#include "registry.h"
#include "cc1101_int/cc1101_int_interconnect.h"
#include <flipper_application/plugins/plugin_manager.h>
#include <loader/firmware_api/firmware_api.h>
#define TAG "SubGhzDeviceRegistry"
struct SubGhzDeviceRegistry {
const SubGhzDevice** items;
size_t size;
PluginManager* manager;
};
static SubGhzDeviceRegistry* subghz_device_registry = NULL;
void subghz_device_registry_init(void) {
SubGhzDeviceRegistry* subghz_device =
(SubGhzDeviceRegistry*)malloc(sizeof(SubGhzDeviceRegistry));
subghz_device->manager = plugin_manager_alloc(
SUBGHZ_RADIO_DEVICE_PLUGIN_APP_ID,
SUBGHZ_RADIO_DEVICE_PLUGIN_API_VERSION,
firmware_api_interface);
//ToDo: fix path to plugins
if(plugin_manager_load_all(subghz_device->manager, "/any/apps_data/subghz/plugins") !=
//if(plugin_manager_load_all(subghz_device->manager, APP_DATA_PATH("plugins")) !=
PluginManagerErrorNone) {
FURI_LOG_E(TAG, "Failed to load all libs");
}
subghz_device->size = plugin_manager_get_count(subghz_device->manager) + 1;
subghz_device->items =
(const SubGhzDevice**)malloc(sizeof(SubGhzDevice*) * subghz_device->size);
subghz_device->items[0] = &subghz_device_cc1101_int;
for(uint32_t i = 1; i < subghz_device->size; i++) {
const SubGhzDevice* plugin = plugin_manager_get_ep(subghz_device->manager, i - 1);
subghz_device->items[i] = plugin;
}
FURI_LOG_I(TAG, "Loaded %zu radio device", subghz_device->size);
subghz_device_registry = subghz_device;
}
void subghz_device_registry_deinit(void) {
plugin_manager_free(subghz_device_registry->manager);
free(subghz_device_registry->items);
free(subghz_device_registry);
subghz_device_registry = NULL;
}
bool subghz_device_registry_is_valid(void) {
return subghz_device_registry != NULL;
}
const SubGhzDevice* subghz_device_registry_get_by_name(const char* name) {
furi_assert(subghz_device_registry);
if(name != NULL) {
for(size_t i = 0; i < subghz_device_registry->size; i++) {
if(strcmp(name, subghz_device_registry->items[i]->name) == 0) {
return subghz_device_registry->items[i];
}
}
}
return NULL;
}
const SubGhzDevice* subghz_device_registry_get_by_index(size_t index) {
furi_assert(subghz_device_registry);
if(index < subghz_device_registry->size) {
return subghz_device_registry->items[index];
} else {
return NULL;
}
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct SubGhzDevice SubGhzDevice;
void subghz_device_registry_init(void);
void subghz_device_registry_deinit(void);
bool subghz_device_registry_is_valid(void);
/**
* Registration by name SubGhzDevice.
* @param name SubGhzDevice name
* @return SubGhzDevice* pointer to a SubGhzDevice instance
*/
const SubGhzDevice* subghz_device_registry_get_by_name(const char* name);
/**
* Registration subghzdevice by index in array SubGhzDevice.
* @param index SubGhzDevice by index in array
* @return SubGhzDevice* pointer to a SubGhzDevice instance
*/
const SubGhzDevice* subghz_device_registry_get_by_index(size_t index);
/**
* Getting the number of registered subghzdevices.
* @param subghz_device SubGhzDeviceRegistry
* @return Number of subghzdevices
*/
size_t subghz_device_registry_count(void);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,91 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <furi.h>
#include <furi_hal.h>
#include "preset.h"
#include <flipper_application/flipper_application.h>
#define SUBGHZ_RADIO_DEVICE_PLUGIN_APP_ID "subghz_radio_device"
#define SUBGHZ_RADIO_DEVICE_PLUGIN_API_VERSION 1
typedef struct SubGhzDeviceRegistry SubGhzDeviceRegistry;
typedef struct SubGhzDevice SubGhzDevice;
typedef bool (*SubGhzBegin)(void);
typedef void (*SubGhzEnd)(void);
typedef bool (*SubGhzIsConnect)(void);
typedef void (*SubGhzReset)(void);
typedef void (*SubGhzSleep)(void);
typedef void (*SubGhzIdle)(void);
typedef void (*SubGhzLoadPreset)(FuriHalSubGhzPreset preset, uint8_t* preset_data);
typedef uint32_t (*SubGhzSetFrequency)(uint32_t frequency);
typedef bool (*SubGhzIsFrequencyValid)(uint32_t frequency);
typedef void (*SubGhzSetAsyncMirrorPin)(const GpioPin* gpio);
typedef const GpioPin* (*SubGhzGetDataGpio)(void);
typedef bool (*SubGhzSetTx)(void);
typedef void (*SubGhzFlushTx)(void);
typedef bool (*SubGhzStartAsyncTx)(void* callback, void* context);
typedef bool (*SubGhzIsAsyncCompleteTx)(void);
typedef void (*SubGhzStopAsyncTx)(void);
typedef void (*SubGhzSetRx)(void);
typedef void (*SubGhzFlushRx)(void);
typedef void (*SubGhzStartAsyncRx)(void* callback, void* context);
typedef void (*SubGhzStopAsyncRx)(void);
typedef float (*SubGhzGetRSSI)(void);
typedef uint8_t (*SubGhzGetLQI)(void);
typedef bool (*SubGhzRxPipeNotEmpty)(void);
typedef bool (*SubGhzRxIsDataCrcValid)(void);
typedef void (*SubGhzReadPacket)(uint8_t* data, uint8_t* size);
typedef void (*SubGhzWritePacket)(const uint8_t* data, uint8_t size);
typedef struct {
SubGhzBegin begin;
SubGhzEnd end;
SubGhzIsConnect is_connect;
SubGhzReset reset;
SubGhzSleep sleep;
SubGhzIdle idle;
SubGhzLoadPreset load_preset;
SubGhzSetFrequency set_frequency;
SubGhzIsFrequencyValid is_frequency_valid;
SubGhzSetAsyncMirrorPin set_async_mirror_pin;
SubGhzGetDataGpio get_data_gpio;
SubGhzSetTx set_tx;
SubGhzFlushTx flush_tx;
SubGhzStartAsyncTx start_async_tx;
SubGhzIsAsyncCompleteTx is_async_complete_tx;
SubGhzStopAsyncTx stop_async_tx;
SubGhzSetRx set_rx;
SubGhzFlushRx flush_rx;
SubGhzStartAsyncRx start_async_rx;
SubGhzStopAsyncRx stop_async_rx;
SubGhzGetRSSI get_rssi;
SubGhzGetLQI get_lqi;
SubGhzRxPipeNotEmpty rx_pipe_not_empty;
SubGhzRxIsDataCrcValid is_rx_data_crc_valid;
SubGhzReadPacket read_packet;
SubGhzWritePacket write_packet;
} SubGhzDeviceInterconnect;
struct SubGhzDevice {
const char* name;
const SubGhzDeviceInterconnect* interconnect;
};

View File

@@ -1,10 +1,6 @@
#pragma once
#include "base.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME "Alutech AT-4N"
typedef struct SubGhzProtocolDecoderAlutech_at_4n SubGhzProtocolDecoderAlutech_at_4n;
@@ -128,7 +124,3 @@ SubGhzProtocolStatus
* @param output Resulting text
*/
void subghz_protocol_decoder_alutech_at_4n_get_string(void* context, FuriString* output);
#ifdef __cplusplus
}
#endif

View File

@@ -2,10 +2,6 @@
#include "base.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SUBGHZ_PROTOCOL_KEELOQ_NAME "KeeLoq"
typedef struct SubGhzProtocolDecoderKeeloq SubGhzProtocolDecoderKeeloq;
@@ -153,7 +149,3 @@ SubGhzProtocolStatus
* @param output Resulting text
*/
void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output);
#ifdef __cplusplus
}
#endif

View File

@@ -2,10 +2,6 @@
#include "base.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME "Nice FloR-S"
typedef struct SubGhzProtocolDecoderNiceFlorS SubGhzProtocolDecoderNiceFlorS;
@@ -133,7 +129,3 @@ SubGhzProtocolStatus
* @param output Resulting text
*/
void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* output);
#ifdef __cplusplus
}
#endif

View File

@@ -40,6 +40,7 @@ struct SubGhzProtocolEncoderRAW {
bool is_running;
FuriString* file_name;
FuriString* radio_device_name;
SubGhzFileEncoderWorker* file_worker_encoder;
};
@@ -282,6 +283,7 @@ void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_raw;
instance->file_name = furi_string_alloc();
instance->radio_device_name = furi_string_alloc();
instance->is_running = false;
return instance;
}
@@ -300,6 +302,7 @@ void subghz_protocol_encoder_raw_free(void* context) {
SubGhzProtocolEncoderRAW* instance = context;
subghz_protocol_encoder_raw_stop(instance);
furi_string_free(instance->file_name);
furi_string_free(instance->radio_device_name);
free(instance);
}
@@ -318,7 +321,9 @@ static bool subghz_protocol_encoder_raw_worker_init(SubGhzProtocolEncoderRAW* in
instance->file_worker_encoder = subghz_file_encoder_worker_alloc();
if(subghz_file_encoder_worker_start(
instance->file_worker_encoder, furi_string_get_cstr(instance->file_name))) {
instance->file_worker_encoder,
furi_string_get_cstr(instance->file_name),
furi_string_get_cstr(instance->radio_device_name))) {
//the worker needs a file in order to open and read part of the file
furi_delay_ms(100);
instance->is_running = true;
@@ -328,7 +333,10 @@ static bool subghz_protocol_encoder_raw_worker_init(SubGhzProtocolEncoderRAW* in
return instance->is_running;
}
void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char* file_path) {
void subghz_protocol_raw_gen_fff_data(
FlipperFormat* flipper_format,
const char* file_path,
const char* radio_device_name) {
do {
stream_clean(flipper_format_get_raw_stream(flipper_format));
if(!flipper_format_write_string_cstr(flipper_format, "Protocol", "RAW")) {
@@ -340,6 +348,12 @@ void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char*
FURI_LOG_E(TAG, "Unable to add File_name");
break;
}
if(!flipper_format_write_string_cstr(
flipper_format, "Radio_device_name", radio_device_name)) {
FURI_LOG_E(TAG, "Unable to add Radio_device_name");
break;
}
} while(false);
}
@@ -364,6 +378,13 @@ SubGhzProtocolStatus
}
furi_string_set(instance->file_name, temp_str);
if(!flipper_format_read_string(flipper_format, "Radio_device_name", temp_str)) {
FURI_LOG_E(TAG, "Missing Radio_device_name");
res = SubGhzProtocolStatusErrorParserOthers;
break;
}
furi_string_set(instance->radio_device_name, temp_str);
if(!subghz_protocol_encoder_raw_worker_init(instance)) {
res = SubGhzProtocolStatusErrorEncoderGetUpload;
break;

View File

@@ -126,8 +126,12 @@ void subghz_protocol_raw_file_encoder_worker_set_callback_end(
* File generation for RAW work.
* @param flipper_format Pointer to a FlipperFormat instance
* @param file_path File path
* @param radio_dev_name Radio device name
*/
void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char* file_path);
void subghz_protocol_raw_gen_fff_data(
FlipperFormat* flipper_format,
const char* file_path,
const char* radio_dev_name);
/**
* Deserialize and generating an upload to send.

View File

@@ -1,10 +1,6 @@
#pragma once
#include "base.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SUBGHZ_PROTOCOL_SECPLUS_V2_NAME "Security+ 2.0"
typedef struct SubGhzProtocolDecoderSecPlus_v2 SubGhzProtocolDecoderSecPlus_v2;
@@ -129,7 +125,3 @@ SubGhzProtocolStatus
* @param output Resulting text
*/
void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* output);
#ifdef __cplusplus
}
#endif

View File

@@ -2,10 +2,6 @@
#include "base.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME "Somfy Telis"
typedef struct SubGhzProtocolDecoderSomfyTelis SubGhzProtocolDecoderSomfyTelis;
@@ -129,7 +125,3 @@ SubGhzProtocolStatus
* @param output Resulting text
*/
void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* output);
#ifdef __cplusplus
}
#endif

View File

@@ -2,10 +2,6 @@
#include "base.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SUBGHZ_PROTOCOL_STAR_LINE_NAME "Star Line"
typedef struct SubGhzProtocolDecoderStarLine SubGhzProtocolDecoderStarLine;
@@ -131,7 +127,3 @@ SubGhzProtocolStatus
* @param output Resulting text
*/
void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* output);
#ifdef __cplusplus
}
#endif

View File

@@ -3,6 +3,7 @@
#include <toolbox/stream/stream.h>
#include <flipper_format/flipper_format.h>
#include <flipper_format/flipper_format_i.h>
#include <lib/subghz/devices/devices.h>
#define TAG "SubGhzFileEncoderWorker"
@@ -21,6 +22,7 @@ struct SubGhzFileEncoderWorker {
bool is_storage_slow;
FuriString* str_data;
FuriString* file_path;
const SubGhzDevice* device;
SubGhzFileEncoderWorkerCallbackEnd callback_end;
void* context_end;
@@ -180,10 +182,13 @@ static int32_t subghz_file_encoder_worker_thread(void* context) {
if(instance->is_storage_slow) {
FURI_LOG_E(TAG, "Storage is slow");
}
FURI_LOG_I(TAG, "End read file");
while(!furi_hal_subghz_is_async_tx_complete() && instance->worker_running) {
while(instance->device && !subghz_devices_is_async_complete_tx(instance->device) &&
instance->worker_running) {
furi_delay_ms(5);
}
FURI_LOG_I(TAG, "End transmission");
while(instance->worker_running) {
if(instance->worker_stopping) {
@@ -230,12 +235,16 @@ void subghz_file_encoder_worker_free(SubGhzFileEncoderWorker* instance) {
free(instance);
}
bool subghz_file_encoder_worker_start(SubGhzFileEncoderWorker* instance, const char* file_path) {
bool subghz_file_encoder_worker_start(
SubGhzFileEncoderWorker* instance,
const char* file_path,
const char* radio_device_name) {
furi_assert(instance);
furi_assert(!instance->worker_running);
furi_stream_buffer_reset(instance->stream);
furi_string_set(instance->file_path, file_path);
instance->device = subghz_devices_get_by_name(radio_device_name);
instance->worker_running = true;
furi_thread_start(instance->thread);

View File

@@ -51,9 +51,14 @@ LevelDuration subghz_file_encoder_worker_get_level_duration(void* context);
/**
* Start SubGhzFileEncoderWorker.
* @param instance Pointer to a SubGhzFileEncoderWorker instance
* @param file_path File path
* @param radio_device_name Radio device name
* @return bool - true if ok
*/
bool subghz_file_encoder_worker_start(SubGhzFileEncoderWorker* instance, const char* file_path);
bool subghz_file_encoder_worker_start(
SubGhzFileEncoderWorker* instance,
const char* file_path,
const char* radio_device_name);
/**
* Stop SubGhzFileEncoderWorker

View File

@@ -3,7 +3,7 @@
//#include "subghz_i.h"
#include <furi.h>
#include <furi_hal_subghz_configs.h>
#include <lib/subghz/devices/cc1101_configs.h>
#define TAG "SubGhzSetting"
@@ -141,8 +141,7 @@ void subghz_setting_free(SubGhzSetting* instance) {
static void subghz_setting_load_default_preset(
SubGhzSetting* instance,
const char* preset_name,
const uint8_t* preset_data,
const uint8_t preset_pa_table[8]) {
const uint8_t* preset_data) {
furi_assert(instance);
furi_assert(preset_data);
uint32_t preset_data_count = 0;
@@ -158,10 +157,8 @@ static void subghz_setting_load_default_preset(
preset_data_count += 2;
item->custom_preset_data_size = sizeof(uint8_t) * preset_data_count + sizeof(uint8_t) * 8;
item->custom_preset_data = malloc(item->custom_preset_data_size);
//load preset register
memcpy(&item->custom_preset_data[0], &preset_data[0], preset_data_count);
//load pa table
memcpy(&item->custom_preset_data[preset_data_count], &preset_pa_table[0], 8);
//load preset register + pa table
memcpy(&item->custom_preset_data[0], &preset_data[0], item->custom_preset_data_size);
}
static void subghz_setting_load_default_region(
@@ -185,25 +182,13 @@ static void subghz_setting_load_default_region(
}
subghz_setting_load_default_preset(
instance,
"AM270",
(uint8_t*)furi_hal_subghz_preset_ook_270khz_async_regs,
furi_hal_subghz_preset_ook_async_patable);
instance, "AM270", subghz_device_cc1101_preset_ook_270khz_async_regs);
subghz_setting_load_default_preset(
instance,
"AM650",
(uint8_t*)furi_hal_subghz_preset_ook_650khz_async_regs,
furi_hal_subghz_preset_ook_async_patable);
instance, "AM650", subghz_device_cc1101_preset_ook_650khz_async_regs);
subghz_setting_load_default_preset(
instance,
"FM238",
(uint8_t*)furi_hal_subghz_preset_2fsk_dev2_38khz_async_regs,
furi_hal_subghz_preset_2fsk_async_patable);
instance, "FM238", subghz_device_cc1101_preset_2fsk_dev2_38khz_async_regs);
subghz_setting_load_default_preset(
instance,
"FM476",
(uint8_t*)furi_hal_subghz_preset_2fsk_dev47_6khz_async_regs,
furi_hal_subghz_preset_2fsk_async_patable);
instance, "FM476", subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs);
}
// Region check removed
@@ -262,6 +247,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) {
}
while(flipper_format_read_uint32(
fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) {
//Todo: add a frequency support check depending on the selected radio device
if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32);
FrequencyList_push_back(instance->frequencies, temp_data32);

View File

@@ -21,6 +21,8 @@ struct SubGhzTxRxWorker {
SubGhzTxRxWorkerStatus status;
uint32_t frequency;
const SubGhzDevice* device;
const GpioPin* device_data_gpio;
SubGhzTxRxWorkerCallbackHaveRead callback_have_read;
void* context_have_read;
@@ -65,7 +67,7 @@ bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t*
uint8_t timeout = 100;
bool ret = false;
if(instance->status != SubGhzTxRxWorkerStatusRx) {
furi_hal_subghz_rx();
subghz_devices_set_rx(instance->device);
instance->status = SubGhzTxRxWorkerStatusRx;
furi_delay_tick(1);
}
@@ -74,24 +76,24 @@ bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t*
furi_delay_tick(1);
if(!--timeout) {
FURI_LOG_W(TAG, "RX cc1101_g0 timeout");
furi_hal_subghz_flush_rx();
furi_hal_subghz_rx();
subghz_devices_flush_rx(instance->device);
subghz_devices_set_rx(instance->device);
break;
}
}
if(furi_hal_subghz_rx_pipe_not_empty()) {
if(subghz_devices_rx_pipe_not_empty(instance->device)) {
FURI_LOG_I(
TAG,
"RSSI: %03.1fdbm LQI: %d",
(double)furi_hal_subghz_get_rssi(),
furi_hal_subghz_get_lqi());
if(furi_hal_subghz_is_rx_data_crc_valid()) {
furi_hal_subghz_read_packet(data, size);
(double)subghz_devices_get_rssi(instance->device),
subghz_devices_get_lqi(instance->device));
if(subghz_devices_is_rx_data_crc_valid(instance->device)) {
subghz_devices_read_packet(instance->device, data, size);
ret = true;
}
furi_hal_subghz_flush_rx();
furi_hal_subghz_rx();
subghz_devices_flush_rx(instance->device);
subghz_devices_set_rx(instance->device);
}
return ret;
}
@@ -99,10 +101,10 @@ bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t*
void subghz_tx_rx_worker_tx(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) {
uint8_t timeout = 200;
if(instance->status != SubGhzTxRxWorkerStatusIDLE) {
furi_hal_subghz_idle();
subghz_devices_idle(instance->device);
}
furi_hal_subghz_write_packet(data, size);
furi_hal_subghz_tx(); //start send
subghz_devices_write_packet(instance->device, data, size);
subghz_devices_set_tx(instance->device); //start send
instance->status = SubGhzTxRxWorkerStatusTx;
while(!furi_hal_gpio_read(
instance->device_data_gpio)) { // Wait for GDO0 to be set -> sync transmitted
@@ -120,7 +122,7 @@ void subghz_tx_rx_worker_tx(SubGhzTxRxWorker* instance, uint8_t* data, size_t si
break;
}
}
furi_hal_subghz_idle();
subghz_devices_idle(instance->device);
instance->status = SubGhzTxRxWorkerStatusIDLE;
}
/** Worker thread
@@ -130,6 +132,7 @@ void subghz_tx_rx_worker_tx(SubGhzTxRxWorker* instance, uint8_t* data, size_t si
*/
static int32_t subghz_tx_rx_worker_thread(void* context) {
SubGhzTxRxWorker* instance = context;
furi_assert(instance->device);
FURI_LOG_I(TAG, "Worker start");
subghz_devices_begin(instance->device);
@@ -138,8 +141,10 @@ static int32_t subghz_tx_rx_worker_thread(void* context) {
subghz_devices_idle(instance->device);
subghz_devices_load_preset(instance->device, FuriHalSubGhzPresetGFSK9_99KbAsync, NULL);
furi_hal_subghz_set_frequency_and_path(instance->frequency);
furi_hal_subghz_flush_rx();
furi_hal_gpio_init(instance->device_data_gpio, GpioModeInput, GpioPullNo, GpioSpeedLow);
subghz_devices_set_frequency(instance->device, instance->frequency);
subghz_devices_flush_rx(instance->device);
uint8_t data[SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE + 1] = {0};
size_t size_tx = 0;
@@ -193,8 +198,8 @@ static int32_t subghz_tx_rx_worker_thread(void* context) {
furi_delay_tick(1);
}
furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate);
furi_hal_subghz_sleep();
subghz_devices_sleep(instance->device);
subghz_devices_end(instance->device);
FURI_LOG_I(TAG, "Worker stop");
return 0;
@@ -226,7 +231,10 @@ void subghz_tx_rx_worker_free(SubGhzTxRxWorker* instance) {
free(instance);
}
bool subghz_tx_rx_worker_start(SubGhzTxRxWorker* instance, uint32_t frequency) {
bool subghz_tx_rx_worker_start(
SubGhzTxRxWorker* instance,
const SubGhzDevice* device,
uint32_t frequency) {
furi_assert(instance);
furi_assert(!instance->worker_running);
bool res = false;
@@ -237,6 +245,7 @@ bool subghz_tx_rx_worker_start(SubGhzTxRxWorker* instance, uint32_t frequency) {
if(furi_hal_subghz_is_tx_allowed(frequency)) {
instance->frequency = frequency;
instance->device = device;
res = true;
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include <furi_hal.h>
#include <devices/devices.h>
#ifdef __cplusplus
extern "C" {
@@ -67,9 +68,13 @@ void subghz_tx_rx_worker_free(SubGhzTxRxWorker* instance);
/**
* Start SubGhzTxRxWorker
* @param instance Pointer to a SubGhzTxRxWorker instance
* @param device Pointer to a SubGhzDevice instance
* @return bool - true if ok
*/
bool subghz_tx_rx_worker_start(SubGhzTxRxWorker* instance, uint32_t frequency);
bool subghz_tx_rx_worker_start(
SubGhzTxRxWorker* instance,
const SubGhzDevice* device,
uint32_t frequency);
/**
* Stop SubGhzTxRxWorker

View File

@@ -21,6 +21,12 @@
#define SUBGHZ_RAW_FILE_VERSION 1
#define SUBGHZ_RAW_FILE_TYPE "Flipper SubGhz RAW File"
#define SUBGHZ_KEYSTORE_DIR_NAME EXT_PATH("subghz/assets/keeloq_mfcodes")
#define SUBGHZ_KEYSTORE_DIR_USER_NAME EXT_PATH("subghz/assets/keeloq_mfcodes_user")
#define SUBGHZ_CAME_ATOMO_DIR_NAME EXT_PATH("subghz/assets/came_atomo")
#define SUBGHZ_NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s")
#define SUBGHZ_ALUTECH_AT_4N_DIR_NAME EXT_PATH("subghz/assets/alutech_at_4n")
typedef struct SubGhzProtocolRegistry SubGhzProtocolRegistry;
typedef struct SubGhzEnvironment SubGhzEnvironment;