mirror of
https://protopirate.net/ProtoPirate/ProtoPirate.git
synced 2026-03-29 13:19:55 +00:00
186 lines
6.4 KiB
C
186 lines
6.4 KiB
C
// protopirate_app_i.c
|
|
#include "protopirate_app_i.h"
|
|
|
|
#define TAG "ProtoPirateTxRx"
|
|
|
|
void protopirate_preset_init(
|
|
void* context,
|
|
const char* preset_name,
|
|
uint32_t frequency,
|
|
uint8_t* preset_data,
|
|
size_t preset_data_size) {
|
|
furi_check(context);
|
|
ProtoPirateApp* app = context;
|
|
furi_string_set(app->txrx->preset->name, preset_name);
|
|
app->txrx->preset->frequency = frequency;
|
|
app->txrx->preset->data = preset_data;
|
|
app->txrx->preset->data_size = preset_data_size;
|
|
}
|
|
|
|
// Convert full FuriHal preset name to short name used by settings
|
|
const char* preset_name_to_short(const char* preset_name) {
|
|
if(!preset_name) return "AM650";
|
|
|
|
// Check for full FuriHal names
|
|
if(strstr(preset_name, "Ook650") || strstr(preset_name, "OOK650")) return "AM650";
|
|
if(strstr(preset_name, "Ook270") || strstr(preset_name, "OOK270")) return "AM270";
|
|
if(strstr(preset_name, "2FSKDev238") || strstr(preset_name, "Dev238")) return "FM238";
|
|
if(strstr(preset_name, "2FSKDev12K") || strstr(preset_name, "Dev12K")) return "FM12K";
|
|
if(strstr(preset_name, "2FSKDev476") || strstr(preset_name, "Dev476")) return "FM476";
|
|
|
|
// Check for short names already
|
|
if(strcmp(preset_name, "AM650") == 0) return "AM650";
|
|
if(strcmp(preset_name, "AM270") == 0) return "AM270";
|
|
if(strcmp(preset_name, "FM238") == 0) return "FM238";
|
|
if(strcmp(preset_name, "FM12K") == 0) return "FM12K";
|
|
if(strcmp(preset_name, "FM476") == 0) return "FM476";
|
|
if(strcmp(preset_name, "FuriHalSubGhzPresetCustom") == 0) return "Custom";
|
|
|
|
// Default fallback
|
|
return "AM650";
|
|
}
|
|
|
|
void protopirate_get_frequency_modulation(
|
|
ProtoPirateApp* app,
|
|
FuriString* frequency,
|
|
FuriString* modulation) {
|
|
furi_check(app);
|
|
if(frequency != NULL) {
|
|
unsigned long mhz = (unsigned long)((app->txrx->preset->frequency / 1000000UL) % 1000UL);
|
|
unsigned long khz = (unsigned long)((app->txrx->preset->frequency / 10000UL) % 100UL);
|
|
furi_string_printf(frequency, "%03lu.%02lu", mhz, khz);
|
|
}
|
|
if(modulation != NULL) {
|
|
furi_string_printf(modulation, "%.2s", furi_string_get_cstr(app->txrx->preset->name));
|
|
}
|
|
}
|
|
|
|
void protopirate_begin(ProtoPirateApp* app, uint8_t* preset_data) {
|
|
furi_check(app);
|
|
subghz_devices_reset(app->txrx->radio_device);
|
|
subghz_devices_idle(app->txrx->radio_device);
|
|
subghz_devices_load_preset(app->txrx->radio_device, FuriHalSubGhzPresetCustom, preset_data);
|
|
app->txrx->txrx_state = ProtoPirateTxRxStateIDLE;
|
|
}
|
|
|
|
uint32_t protopirate_rx(ProtoPirateApp* app, uint32_t frequency) {
|
|
furi_check(app);
|
|
furi_check(app->txrx);
|
|
furi_check(app->radio_initialized);
|
|
furi_check(app->txrx->radio_device);
|
|
furi_check(app->txrx->worker);
|
|
|
|
if(!subghz_devices_is_frequency_valid(app->txrx->radio_device, frequency)) {
|
|
furi_crash("ProtoPirate: Incorrect RX frequency.");
|
|
}
|
|
furi_check(
|
|
app->txrx->txrx_state != ProtoPirateTxRxStateRx &&
|
|
app->txrx->txrx_state != ProtoPirateTxRxStateSleep);
|
|
|
|
subghz_devices_idle(app->txrx->radio_device);
|
|
uint32_t value = subghz_devices_set_frequency(app->txrx->radio_device, frequency);
|
|
subghz_devices_flush_rx(app->txrx->radio_device);
|
|
subghz_devices_set_rx(app->txrx->radio_device);
|
|
|
|
subghz_devices_start_async_rx(
|
|
app->txrx->radio_device, subghz_worker_rx_callback, app->txrx->worker);
|
|
|
|
subghz_worker_start(app->txrx->worker);
|
|
app->txrx->txrx_state = ProtoPirateTxRxStateRx;
|
|
return value;
|
|
}
|
|
|
|
void protopirate_idle(ProtoPirateApp* app) {
|
|
furi_check(app);
|
|
furi_check(app->txrx->txrx_state != ProtoPirateTxRxStateSleep);
|
|
subghz_devices_idle(app->txrx->radio_device);
|
|
app->txrx->txrx_state = ProtoPirateTxRxStateIDLE;
|
|
}
|
|
|
|
void protopirate_rx_end(ProtoPirateApp* app) {
|
|
furi_check(app);
|
|
furi_check(app->txrx->txrx_state == ProtoPirateTxRxStateRx);
|
|
if(subghz_worker_is_running(app->txrx->worker)) {
|
|
subghz_worker_stop(app->txrx->worker);
|
|
subghz_devices_stop_async_rx(app->txrx->radio_device);
|
|
}
|
|
subghz_devices_idle(app->txrx->radio_device);
|
|
app->txrx->txrx_state = ProtoPirateTxRxStateIDLE;
|
|
}
|
|
|
|
void protopirate_sleep(ProtoPirateApp* app) {
|
|
furi_check(app);
|
|
subghz_devices_sleep(app->txrx->radio_device);
|
|
app->txrx->txrx_state = ProtoPirateTxRxStateSleep;
|
|
}
|
|
|
|
void protopirate_hopper_update(ProtoPirateApp* app) {
|
|
furi_check(app);
|
|
|
|
switch(app->txrx->hopper_state) {
|
|
case ProtoPirateHopperStateOFF:
|
|
case ProtoPirateHopperStatePause:
|
|
return;
|
|
case ProtoPirateHopperStateRSSITimeOut:
|
|
if(app->txrx->hopper_timeout != 0) {
|
|
app->txrx->hopper_timeout--;
|
|
return;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
float rssi = -127.0f;
|
|
if(app->txrx->hopper_state != ProtoPirateHopperStateRSSITimeOut) {
|
|
rssi = subghz_devices_get_rssi(app->txrx->radio_device);
|
|
|
|
if(rssi > -90.0f) {
|
|
app->txrx->hopper_timeout = 10;
|
|
app->txrx->hopper_state = ProtoPirateHopperStateRSSITimeOut;
|
|
return;
|
|
}
|
|
} else {
|
|
app->txrx->hopper_state = ProtoPirateHopperStateRunning;
|
|
}
|
|
|
|
if(app->txrx->hopper_idx_frequency <
|
|
subghz_setting_get_hopper_frequency_count(app->setting) - 1) {
|
|
app->txrx->hopper_idx_frequency++;
|
|
} else {
|
|
app->txrx->hopper_idx_frequency = 0;
|
|
}
|
|
|
|
if(app->txrx->txrx_state == ProtoPirateTxRxStateRx) {
|
|
protopirate_rx_end(app);
|
|
}
|
|
if(app->txrx->txrx_state == ProtoPirateTxRxStateIDLE) {
|
|
subghz_receiver_reset(app->txrx->receiver);
|
|
app->txrx->preset->frequency =
|
|
subghz_setting_get_hopper_frequency(app->setting, app->txrx->hopper_idx_frequency);
|
|
protopirate_rx(app, app->txrx->preset->frequency);
|
|
}
|
|
}
|
|
|
|
void protopirate_tx(ProtoPirateApp* app, uint32_t frequency) {
|
|
furi_check(app);
|
|
if(!subghz_devices_is_frequency_valid(app->txrx->radio_device, frequency)) {
|
|
return;
|
|
}
|
|
|
|
furi_check(app->txrx->txrx_state == ProtoPirateTxRxStateIDLE);
|
|
|
|
subghz_devices_idle(app->txrx->radio_device);
|
|
subghz_devices_set_frequency(app->txrx->radio_device, frequency);
|
|
subghz_devices_set_tx(app->txrx->radio_device);
|
|
|
|
app->txrx->txrx_state = ProtoPirateTxRxStateTx;
|
|
}
|
|
|
|
void protopirate_tx_stop(ProtoPirateApp* app) {
|
|
furi_check(app);
|
|
furi_check(app->txrx->txrx_state == ProtoPirateTxRxStateTx);
|
|
|
|
subghz_devices_idle(app->txrx->radio_device);
|
|
app->txrx->txrx_state = ProtoPirateTxRxStateIDLE;
|
|
}
|