Add switching of modulations on long-press of OK

This commit is contained in:
ALEEF02
2023-07-24 17:08:44 -04:00
parent 27dc328614
commit 2dc5d49be1
4 changed files with 255 additions and 64 deletions

View File

@@ -12,6 +12,7 @@
typedef struct { typedef struct {
uint32_t center_freq; uint32_t center_freq;
uint8_t width; uint8_t width;
uint8_t mod;
uint8_t band; uint8_t band;
uint8_t vscroll; uint8_t vscroll;
@@ -19,6 +20,7 @@ typedef struct {
uint32_t spacing; uint32_t spacing;
bool mode_change; bool mode_change;
bool mod_change;
float max_rssi; float max_rssi;
uint8_t max_rssi_dec; uint8_t max_rssi_dec;
@@ -147,6 +149,24 @@ static void spectrum_analyzer_render_callback(Canvas* const canvas, void* ctx) {
snprintf(tmp_str, 21, "Mode: %s", temp_mode_str); snprintf(tmp_str, 21, "Mode: %s", temp_mode_str);
canvas_draw_str_aligned(canvas, 127, 4, AlignRight, AlignTop, tmp_str); canvas_draw_str_aligned(canvas, 127, 4, AlignRight, AlignTop, tmp_str);
} }
if(model->mod_change) {
char temp_mod_str[12];
switch(model->mod) {
case NARROW_MOD:
strncpy(temp_mod_str, "NARROW", 12);
break;
default:
strncpy(temp_mod_str, "DEFAULT", 12);
break;
}
// Current modulation label
char tmp_str[27];
snprintf(tmp_str, 27, "Modulation: %s", temp_mod_str);
canvas_draw_str_aligned(canvas, 127, 4, AlignRight, AlignTop, tmp_str);
}
// Draw cross and label // Draw cross and label
if(model->max_rssi > PEAK_THRESHOLD) { if(model->max_rssi > PEAK_THRESHOLD) {
// Compress height to max of 64 values (255>>2) // Compress height to max of 64 values (255>>2)
@@ -194,8 +214,8 @@ static void spectrum_analyzer_render_callback(Canvas* const canvas, void* ctx) {
static void spectrum_analyzer_input_callback(InputEvent* input_event, void* ctx) { static void spectrum_analyzer_input_callback(InputEvent* input_event, void* ctx) {
SpectrumAnalyzer* spectrum_analyzer = ctx; SpectrumAnalyzer* spectrum_analyzer = ctx;
// Only handle short presses // Handle short and long presses
if(input_event->type == InputTypeShort) { if(input_event->type == InputTypeShort || input_event->type == InputTypeLong) {
furi_message_queue_put(spectrum_analyzer->event_queue, input_event, FuriWaitForever); furi_message_queue_put(spectrum_analyzer->event_queue, input_event, FuriWaitForever);
} }
} }
@@ -376,6 +396,7 @@ SpectrumAnalyzer* spectrum_analyzer_alloc() {
model->center_freq = DEFAULT_FREQ; model->center_freq = DEFAULT_FREQ;
model->width = WIDE; model->width = WIDE;
model->mod = DEFAULT_MOD;
model->band = BAND_400; model->band = BAND_400;
model->vscroll = DEFAULT_VSCROLL; model->vscroll = DEFAULT_VSCROLL;
@@ -470,6 +491,8 @@ int32_t spectrum_analyzer_app(void* p) {
break; break;
} }
switch(input.type) {
case InputTypeShort:
switch(input.key) { switch(input.key) {
case InputKeyUp: case InputKeyUp:
model->vscroll = MAX(model->vscroll - vstep, MIN_VSCROLL); model->vscroll = MAX(model->vscroll - vstep, MIN_VSCROLL);
@@ -515,7 +538,6 @@ int32_t spectrum_analyzer_app(void* p) {
break; break;
} }
} }
model->mode_change = true; model->mode_change = true;
view_port_update(spectrum_analyzer->view_port); view_port_update(spectrum_analyzer->view_port);
@@ -533,6 +555,36 @@ int32_t spectrum_analyzer_app(void* p) {
default: default:
break; break;
} }
break;
case InputTypeLong:
switch(input.key) {
case InputKeyOk:
FURI_LOG_D("Spectrum", "InputTypeLong");
switch(model->mod) {
case NARROW_MOD:
model->mod = DEFAULT_MOD;
break;
case DEFAULT_MOD:
default:
model->mod = NARROW_MOD;
break;
}
model->mod_change = true;
view_port_update(spectrum_analyzer->view_port);
furi_delay_ms(1000);
model->mod_change = false;
spectrum_analyzer_worker_set_modulation(
spectrum_analyzer->worker,
spectrum_analyzer->model->mod);
break;
}
break;
default:
break;
}
furi_mutex_release(spectrum_analyzer->model_mutex); furi_mutex_release(spectrum_analyzer->model_mutex);
view_port_update(spectrum_analyzer->view_port); view_port_update(spectrum_analyzer->view_port);

View File

@@ -78,3 +78,7 @@
#define UPPER(a, b, c) ((((a) - (b) + ((c) / 2)) / (c)) * (c)) #define UPPER(a, b, c) ((((a) - (b) + ((c) / 2)) / (c)) * (c))
#define LOWER(a, b, c) ((((a) + (b)) / (c)) * (c)) #define LOWER(a, b, c) ((((a) + (b)) / (c)) * (c))
/* Modulation references */
#define DEFAULT_MOD 0
#define NARROW_MOD 1

View File

@@ -20,6 +20,7 @@ struct SpectrumAnalyzerWorker {
uint32_t channel0_frequency; uint32_t channel0_frequency;
uint32_t spacing; uint32_t spacing;
uint8_t width; uint8_t width;
uint8_t modulation;
float max_rssi; float max_rssi;
uint8_t max_rssi_dec; uint8_t max_rssi_dec;
uint8_t max_rssi_channel; uint8_t max_rssi_channel;
@@ -66,18 +67,57 @@ static int32_t spectrum_analyzer_worker_thread(void* context) {
subghz_devices_flush_rx(instance->radio_device); subghz_devices_flush_rx(instance->radio_device);
subghz_devices_set_rx(instance->radio_device); subghz_devices_set_rx(instance->radio_device);
const uint8_t radio_config[] = { // Default modulation
const uint8_t default_modulation[] = {
/* Frequency Synthesizer Control */
CC1101_FSCTRL0, CC1101_FSCTRL0,
0x00, 0x00,
CC1101_FSCTRL1, CC1101_FSCTRL1,
0x12, 0x12, // IF = (26*10^6) / (2^10) * 0x12 = 304687.5 Hz
CC1101_AGCCTRL2,
0xC0,
// Modem Configuration
// CC1101_MDMCFG0,
// 0x00, // Channel spacing is 25kHz
// CC1101_MDMCFG1,
// 0x00, // Channel spacing is 25kHz
// CC1101_MDMCFG2,
// 0x30, // Format ASK/OOK, No preamble/sync
// CC1101_MDMCFG3,
// 0x32, // Data rate is 121.399 kBaud
CC1101_MDMCFG4, CC1101_MDMCFG4,
0x6C, 0x6C, // Rx BW filter is 270.83 kHz
/* Main Radio Control State Machine */
// CC1101_MCSM0,
// 0x18, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
// CC1101_FOCCFG,
// 0x18, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
// CC1101_AGCTRL0,0x40, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary
// CC1101_AGCTRL1,0x00, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
// CC1101_AGCCTRL2, 0x03, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB
//MAGN_TARGET for RX filter BW =< 100 kHz is 0x3. For higher RX filter BW's MAGN_TARGET is 0x7.
// CC1101_AGCCTRL0,
// 0x91, // 10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
// CC1101_AGCCTRL1,
// 0x0, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
CC1101_AGCCTRL2,
0xC0, // 03 - The 3 highest DVGA gain settings can not be used; 000 - MAX LNA+LNA2; 000 - MAIN_TARGET 24 dB
/* Wake on radio and timeouts control */
// CC1101_WORCTRL,
// 0xFB, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
// CC1101_FREND0,
// 0x11, // Adjusts current TX LO buffer + high is PATABLE[1]
// CC1101_FREND1,
// 0xB6, //
CC1101_TEST2, CC1101_TEST2,
0x88, 0x88,
CC1101_TEST1, CC1101_TEST1,
@@ -97,16 +137,94 @@ static int32_t spectrum_analyzer_worker_thread(void* context) {
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00
}; };
// Narrow modulation
const uint8_t narrow_modulation[] = {
/* Frequency Synthesizer Control */
CC1101_FSCTRL0,
0x00,
CC1101_FSCTRL1,
0x00, // IF = (26*10^6) / (2^10) * 0x00 = 0 Hz
// Modem Configuration
// CC1101_MDMCFG0,
// 0x00, // Channel spacing is 25kHz
// CC1101_MDMCFG1,
// 0x00, // Channel spacing is 25kHz
// CC1101_MDMCFG2,
// 0x30, // Format ASK/OOK, No preamble/sync
// CC1101_MDMCFG3,
// 0x32, // Data rate is 121.399 kBaud
CC1101_MDMCFG4,
0xFC, // Rx BW filter is 58.04 kHz
/* Main Radio Control State Machine */
// CC1101_MCSM0,
// 0x18, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
// CC1101_FOCCFG,
// 0x18, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
// CC1101_AGCTRL0,0x40, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary
// CC1101_AGCTRL1,0x00, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
// CC1101_AGCCTRL2, 0x03, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB
//MAGN_TARGET for RX filter BW =< 100 kHz is 0x3. For higher RX filter BW's MAGN_TARGET is 0x7.
CC1101_AGCCTRL0,
0x30, // 00 - NO hysteresis, ymmetric dead zone, high gain ; 11 - 32 samples agc; 00 - Normal AGC, 00 - 8dB boundary
CC1101_AGCCTRL1,
0x0, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
CC1101_AGCCTRL2,
0x84, // 02 - The 2 highest DVGA gain settings can not be used; 000 - MAX LNA+LNA2; 100 - MAIN_TARGET 36 dB
/* Wake on radio and timeouts control */
// CC1101_WORCTRL,
// 0xFB, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
// CC1101_FREND0,
// 0x11, // Adjusts current TX LO buffer + high is PATABLE[1]
// CC1101_FREND1,
// 0xB6, //
CC1101_TEST2,
0x88,
CC1101_TEST1,
0x31,
CC1101_TEST0,
0x09,
/* End */
0,
0,
// ook_async_patable
0x00,
0xC0, // 12dBm 0xC0, 10dBm 0xC5, 7dBm 0xCD, 5dBm 0x86, 0dBm 0x50, -6dBm 0x37, -10dBm 0x26, -15dBm 0x1D, -20dBm 0x17, -30dBm 0x03
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
};
const uint8_t* modulations[] = {default_modulation, narrow_modulation};
while(instance->should_work) { while(instance->should_work) {
furi_delay_ms(50); furi_delay_ms(50);
// FURI_LOG_T("SpectrumWorker", "spectrum_analyzer_worker_thread: Worker Loop"); // FURI_LOG_T("SpectrumWorker", "spectrum_analyzer_worker_thread: Worker Loop");
subghz_devices_idle(instance->radio_device); subghz_devices_idle(instance->radio_device);
subghz_devices_load_preset( subghz_devices_load_preset(
instance->radio_device, FuriHalSubGhzPresetCustom, (uint8_t*)radio_config); instance->radio_device, FuriHalSubGhzPresetCustom, (uint8_t*)modulations[instance->modulation]);
//subghz_devices_load_preset(
// instance->radio_device, FuriHalSubGhzPresetCustom, (uint8_t*)default_modulation);
//furi_hal_subghz_load_custom_preset(modulations[instance->modulation]);
// TODO: Check filter! // TODO: Check filter!
// spectrum_analyzer_worker_set_filter(instance); // spectrum_analyzer_worker_set_filter(instance);
@@ -222,6 +340,19 @@ void spectrum_analyzer_worker_set_frequencies(
instance->width = width; instance->width = width;
} }
void spectrum_analyzer_worker_set_modulation(
SpectrumAnalyzerWorker* instance,
uint8_t modulation) {
furi_assert(instance);
FURI_LOG_D(
"SpectrumWorker",
"spectrum_analyzer_worker_set_modulation - modulation = %u",
modulation);
instance->modulation = modulation;
}
void spectrum_analyzer_worker_start(SpectrumAnalyzerWorker* instance) { void spectrum_analyzer_worker_start(SpectrumAnalyzerWorker* instance) {
FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_start"); FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_start");

View File

@@ -28,6 +28,10 @@ void spectrum_analyzer_worker_set_frequencies(
uint32_t spacing, uint32_t spacing,
uint8_t width); uint8_t width);
void spectrum_analyzer_worker_set_modulation(
SpectrumAnalyzerWorker* instance,
uint8_t modulation);
void spectrum_analyzer_worker_start(SpectrumAnalyzerWorker* instance); void spectrum_analyzer_worker_start(SpectrumAnalyzerWorker* instance);
void spectrum_analyzer_worker_stop(SpectrumAnalyzerWorker* instance); void spectrum_analyzer_worker_stop(SpectrumAnalyzerWorker* instance);