0
mirror of https://github.com/OneOfEleven/uv-k5-firmware-custom.git synced 2025-04-27 22:01:26 +03:00
uv-k5-firmware-custom/panadapter.c

263 lines
7.5 KiB
C
Raw Normal View History

2023-11-18 18:44:10 +00:00
2023-11-19 06:59:38 +00:00
#ifdef ENABLE_AM_FIX
#include "am_fix.h"
#endif
2023-11-19 18:57:43 +00:00
#include "app/dtmf.h"
2023-11-18 18:44:10 +00:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
#include "driver/uart.h"
#endif
#include "panadapter.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "driver/bk4819.h"
#include "functions.h"
#include "misc.h"
#include "radio.h"
#include "settings.h"
2023-11-19 18:57:43 +00:00
#include "ui/inputbox.h"
2023-11-18 18:44:10 +00:00
#include "ui/main.h"
#include "ui/ui.h"
bool g_panadapter_enabled;
2023-11-19 10:45:46 +00:00
#ifdef ENABLE_PANADAPTER_PEAK_FREQ
uint32_t g_panadapter_peak_freq;
2023-11-19 10:45:46 +00:00
#endif
2023-11-20 13:20:12 +00:00
int g_panadapter_vfo_tick; // >0 if we're currently monitoring the VFO/center frequency
unsigned int g_panadapter_cycles; //
uint8_t g_panadapter_max_rssi; //
uint8_t g_panadapter_min_rssi; //
uint8_t g_panadapter_rssi[PANADAPTER_BINS + 1 + PANADAPTER_BINS]; // holds the RSSI samples
int panadapter_rssi_index; //
int panadapter_delay; // used to give the VCO/PLL/RSSI time to settle
2023-11-20 13:20:12 +00:00
const uint8_t panadapter_min_rssi = (-147 + 160) * 2; // -147dBm (S0) min RSSI value
2023-11-18 18:44:10 +00:00
2023-11-20 13:52:39 +00:00
inline void PAN_restart(const bool full)
{
if (full)
2023-11-22 17:49:21 +00:00
g_panadapter_cycles = 0;
2023-11-20 13:52:39 +00:00
panadapter_rssi_index = 0;
panadapter_delay = 3;
}
2023-11-19 06:59:38 +00:00
bool PAN_scanning(void)
{
2023-11-20 13:20:12 +00:00
return (g_eeprom.config.setting.panadapter && g_panadapter_enabled && g_panadapter_vfo_tick <= 0) ? true : false;
2023-11-19 06:59:38 +00:00
}
2023-11-18 18:44:10 +00:00
2023-11-20 11:11:58 +00:00
void PAN_update_min_max(void)
{ // compute the min/max RSSI values
register unsigned int i;
register const uint8_t *p = g_panadapter_rssi;
register uint8_t max_rssi = *p;
register uint8_t min_rssi = *p++;
2023-11-20 11:11:58 +00:00
2023-11-20 11:24:39 +00:00
for (i = ARRAY_SIZE(g_panadapter_rssi) - 1; i > 0; i--)
2023-11-20 11:11:58 +00:00
{
2023-11-20 11:24:39 +00:00
const uint8_t rssi = *p++;
if (max_rssi < rssi) max_rssi = rssi;
if (min_rssi > rssi) min_rssi = rssi;
2023-11-20 11:11:58 +00:00
}
2023-11-20 11:24:39 +00:00
g_panadapter_max_rssi = max_rssi;
g_panadapter_min_rssi = min_rssi;
2023-11-20 11:11:58 +00:00
}
#ifdef ENABLE_PANADAPTER_PEAK_FREQ
void PAN_find_peak(void)
2023-11-20 13:20:12 +00:00
{ // find the peak frequency
2023-11-20 11:11:58 +00:00
const int32_t center_freq = g_tx_vfo->p_rx->frequency;
int32_t step_size = g_tx_vfo->step_freq;
int i;
uint8_t threshold_rssi;
uint8_t peak_rssi = 0;
uint32_t peak_freq = 0;
uint8_t span_rssi = g_panadapter_max_rssi - g_panadapter_min_rssi;
2023-11-20 11:11:58 +00:00
if (span_rssi < 80)
span_rssi = 80;
threshold_rssi = g_panadapter_min_rssi + (span_rssi / 4);
// limit the step size
step_size = (step_size < PANADAPTER_MIN_STEP) ? PANADAPTER_MIN_STEP : (step_size > PANADAPTER_MAX_STEP) ? PANADAPTER_MAX_STEP : step_size;
for (i = 0; i < (int)ARRAY_SIZE(g_panadapter_rssi); i++)
{
const uint8_t rssi = g_panadapter_rssi[i];
if (peak_rssi < rssi && rssi >= threshold_rssi && (i < (PANADAPTER_BINS - 1) || i > (PANADAPTER_BINS + 1)))
{
peak_rssi = rssi;
peak_freq = center_freq + (step_size * (i - PANADAPTER_BINS));
2023-11-20 11:11:58 +00:00
}
}
g_panadapter_peak_freq = peak_freq;
2023-11-20 11:11:58 +00:00
}
#endif
2023-11-18 18:44:10 +00:00
void PAN_set_freq(void)
2023-11-20 13:20:12 +00:00
{ // set the VCO/PLL frequency
2023-11-18 18:44:10 +00:00
2023-11-20 13:20:12 +00:00
int32_t freq = g_tx_vfo->p_rx->frequency;
2023-11-20 11:24:39 +00:00
2023-11-22 17:49:21 +00:00
if (g_current_function == FUNCTION_TRANSMIT || panadapter_rssi_index < 0)
return;
2023-11-20 13:20:12 +00:00
// if not paused on the VFO/center freq, add the panadapter bin offset frequency
2023-11-22 17:49:21 +00:00
if (g_panadapter_enabled && g_panadapter_vfo_tick <= 0)
2023-11-20 13:20:12 +00:00
{
int32_t step_size = g_tx_vfo->step_freq;
// limit the step size
step_size = (step_size < PANADAPTER_MIN_STEP) ? PANADAPTER_MIN_STEP : (step_size > PANADAPTER_MAX_STEP) ? PANADAPTER_MAX_STEP : step_size;
2023-11-18 18:44:10 +00:00
2023-11-20 11:11:58 +00:00
freq += step_size * (panadapter_rssi_index - PANADAPTER_BINS);
2023-11-20 13:20:12 +00:00
}
2023-11-18 18:44:10 +00:00
BK4819_set_rf_frequency(freq, true); // set the VCO/PLL
2023-11-20 13:20:12 +00:00
//BK4819_set_rf_filter_path(freq); // set the proper LNA/PA filter path .. don't bother, we're not moving far from the VFO/center frequency
2023-11-18 18:44:10 +00:00
2023-11-19 06:59:38 +00:00
#ifdef ENABLE_AM_FIX
2023-11-20 11:24:39 +00:00
// set front end gains
2023-11-20 13:20:12 +00:00
if (g_panadapter_vfo_tick <= 0 || g_tx_vfo->channel.mod_mode == MOD_MODE_FM)
2023-11-19 06:59:38 +00:00
BK4819_write_reg(0x13, (g_orig_lnas << 8) | (g_orig_lna << 5) | (g_orig_mixer << 3) | (g_orig_pga << 0));
else
AM_fix_set_front_end_gains(g_eeprom.config.setting.tx_vfo_num);
2023-11-18 18:44:10 +00:00
#endif
}
2023-11-19 06:59:38 +00:00
void PAN_process_10ms(void)
2023-11-18 18:44:10 +00:00
{
2023-11-19 06:59:38 +00:00
if (!g_eeprom.config.setting.panadapter ||
2023-11-20 13:20:12 +00:00
#ifdef ENABLE_FMRADIO
g_fm_radio_mode ||
#endif
2023-11-19 06:59:38 +00:00
g_reduced_service ||
g_current_function == FUNCTION_POWER_SAVE ||
g_current_display_screen == DISPLAY_SEARCH ||
g_css_scan_mode != CSS_SCAN_MODE_OFF ||
g_scan_state_dir != SCAN_STATE_DIR_OFF ||
2023-12-08 14:04:02 +00:00
#ifdef ENABLE_DTMF_CALLING
g_dtmf_call_state != DTMF_CALL_STATE_NONE ||
#endif
2023-11-26 19:09:10 +00:00
g_eeprom.config.setting.dual_watch != DUAL_WATCH_OFF)
2023-11-18 18:44:10 +00:00
{
2023-11-19 10:45:46 +00:00
if (g_panadapter_enabled)
2023-11-19 06:59:38 +00:00
{ // disable the panadapter
2023-11-20 13:20:12 +00:00
g_panadapter_enabled = false;
2023-11-22 17:49:21 +00:00
PAN_restart(true);
2023-11-18 18:44:10 +00:00
PAN_set_freq();
2023-11-19 06:59:38 +00:00
g_update_display = true;
2023-11-18 18:44:10 +00:00
}
2023-11-19 06:59:38 +00:00
return;
2023-11-18 18:44:10 +00:00
}
if (g_current_function == FUNCTION_TRANSMIT || g_monitor_enabled)
2023-11-20 11:11:58 +00:00
{
panadapter_rssi_index = -1;
2023-11-19 23:58:27 +00:00
return;
2023-11-20 11:11:58 +00:00
}
2023-11-19 23:58:27 +00:00
2023-11-19 10:45:46 +00:00
if (!g_panadapter_enabled)
2023-11-19 06:59:38 +00:00
{ // enable the panadapter
2023-11-20 13:52:39 +00:00
PAN_restart(false);
2023-11-20 13:20:12 +00:00
g_panadapter_vfo_tick = 0;
2023-11-19 18:57:43 +00:00
g_panadapter_enabled = true;
2023-11-19 06:59:38 +00:00
PAN_set_freq();
g_update_display = true;
return;
}
2023-11-18 18:44:10 +00:00
2023-11-20 11:11:58 +00:00
if (panadapter_rssi_index < 0)
2023-11-20 13:20:12 +00:00
{ // guess we've just come out of TX mode
2023-11-22 17:49:21 +00:00
g_panadapter_vfo_tick = 100; // 1 sec - stay on the VFO frequency for at least this amount of time after PTT release
2023-11-20 13:52:39 +00:00
PAN_restart(false);
2023-11-22 17:49:21 +00:00
// PAN_set_freq();
2023-11-20 11:11:58 +00:00
return;
}
2023-11-20 13:20:12 +00:00
if (g_panadapter_vfo_tick > 0)
{ // we're paused on/monitoring the VFO/center frequency
2023-11-19 09:13:21 +00:00
2023-11-20 13:20:12 +00:00
// save the current RSSI value into the center of the panadapter
2023-11-19 11:11:44 +00:00
const int16_t rssi = g_current_rssi[g_eeprom.config.setting.tx_vfo_num];
g_panadapter_rssi[PANADAPTER_BINS] = (rssi > 255) ? 255 : (rssi < panadapter_min_rssi) ? panadapter_min_rssi : rssi;
2023-11-19 09:13:21 +00:00
2023-11-20 11:11:58 +00:00
PAN_update_min_max();
2023-11-20 13:20:12 +00:00
// stay on the VFO/center frequency for a further 400ms after carrier drop
g_panadapter_vfo_tick = g_squelch_open ? 40 : g_panadapter_vfo_tick - 1;
2023-11-20 11:41:36 +00:00
2023-11-20 23:29:06 +00:00
if (g_panadapter_vfo_tick > 0)
{
if (--panadapter_delay <= 0)
{ // update the screen every 200ms while on the VFO/center frequency
panadapter_delay = 20;
if (!g_dtmf_input_mode)
UI_DisplayMain_pan(true);
//else
// g_update_display = true;
2023-11-20 23:29:06 +00:00
}
return;
}
2023-11-20 23:29:06 +00:00
// back to scan/sweep mode
PAN_set_freq();
panadapter_delay = 3; // give the VCO/PLL/RSSI a little more time to settle
2023-11-18 18:44:10 +00:00
}
2023-11-20 11:41:36 +00:00
// scanning/sweeping
2023-11-19 07:52:46 +00:00
// let the VCO/PLL/RSSI settle before sampling the RSSI
if (--panadapter_delay >= 0)
return;
panadapter_delay = 0;
2023-11-20 13:20:12 +00:00
// save the current RSSI value into the panadapter
2023-11-20 11:41:36 +00:00
const uint16_t rssi = BK4819_GetRSSI();
g_panadapter_rssi[panadapter_rssi_index] = (rssi > 255) ? 255 : (rssi < panadapter_min_rssi) ? panadapter_min_rssi : rssi;
2023-11-19 07:52:46 +00:00
2023-11-21 19:05:43 +00:00
// next scan/sweep frequency
2023-11-20 11:41:36 +00:00
if (++panadapter_rssi_index >= (int)ARRAY_SIZE(g_panadapter_rssi))
{
2023-11-20 11:41:36 +00:00
panadapter_rssi_index = 0;
2023-11-20 13:20:12 +00:00
panadapter_delay = 3; // give the VCO/PLL/RSSI a little more time to settle
}
2023-11-18 18:44:10 +00:00
2023-11-20 23:29:06 +00:00
// if (g_tx_vfo->channel.mod_mode == MOD_MODE_FM && g_panadapter_cycles > 0)
// { // switch back to the VFO/center frequency for 100ms once every 400ms
// g_panadapter_vfo_tick = ((panadapter_rssi_index % 40) == 0) ? 10 : 0;
// }
// else
2023-11-20 11:41:36 +00:00
{ // switch back to the VFO/center frequency for 100ms once per full sweep/scan cycle
2023-11-20 13:20:12 +00:00
g_panadapter_vfo_tick = (panadapter_rssi_index == 0) ? 10 : 0;
2023-11-18 18:44:10 +00:00
}
2023-11-20 13:20:12 +00:00
// set the VCO/PLL frequency
2023-11-18 18:44:10 +00:00
PAN_set_freq();
2023-11-20 13:20:12 +00:00
if (panadapter_rssi_index != 0)
return;
2023-11-20 11:41:36 +00:00
2023-11-20 13:20:12 +00:00
// completed a full sweep/scan, draw the panadapter on-screen
2023-11-19 10:45:46 +00:00
2023-11-21 19:05:43 +00:00
if (g_panadapter_cycles + 1) // prevent wrap-a-round/over-flow
2023-11-20 13:20:12 +00:00
g_panadapter_cycles++;
2023-11-19 10:45:46 +00:00
2023-11-20 13:20:12 +00:00
PAN_update_min_max();
#ifdef ENABLE_PANADAPTER_PEAK_FREQ
PAN_find_peak();
#endif
2023-11-22 17:49:21 +00:00
if (!g_dtmf_input_mode)
UI_DisplayMain_pan(true);
// else
// g_update_display = true;
2023-11-18 18:44:10 +00:00
}