Scan range in spectrum

This commit is contained in:
Krzysiek Egzmont
2023-12-16 14:46:01 +01:00
parent 0d66eb8577
commit 39eb3e835e
7 changed files with 139 additions and 26 deletions

View File

@@ -11,6 +11,7 @@ bool gScanPauseMode;
#ifdef ENABLE_SCAN_RANGES
uint32_t gScanRangeStart;
uint32_t gScanRangeStop;
#endif
typedef enum {
@@ -157,9 +158,7 @@ static void NextFreqChannel(void)
{
#ifdef ENABLE_SCAN_RANGES
if(gScanRangeStart) {
uint32_t start = gScanRangeStart;
uint32_t end = gEeprom.VfoInfo[(gEeprom.TX_VFO+1)%2].freq_config_RX.Frequency;
gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, MIN(start, end), MAX(start, end));
gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop);
}
else
#endif

View File

@@ -12,6 +12,7 @@ extern bool gScanPauseMode;
#ifdef ENABLE_SCAN_RANGES
extern uint32_t gScanRangeStart;
extern uint32_t gScanRangeStop;
#endif
void CHFRSCANNER_Found(void);

View File

@@ -52,6 +52,9 @@ void toggle_chan_scanlist(void)
if(!IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
#ifdef ENABLE_SCAN_RANGES
gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency;
gScanRangeStop = gEeprom.VfoInfo[!gEeprom.TX_VFO].freq_config_RX.Frequency;
if(gScanRangeStart > gScanRangeStop)
SWAP(gScanRangeStart, gScanRangeStop);
#endif
return;
}

View File

@@ -13,10 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app/spectrum.h"
#include "am_fix.h"
#include "audio.h"
#ifdef ENABLE_SCAN_RANGES
#include "chFrScanner.h"
#endif
#include "driver/backlight.h"
#include "frequencies.h"
#include "ui/helper.h"
@@ -53,6 +57,11 @@ PeakInfo peak;
ScanInfo scanInfo;
KeyboardState kbd = {KEY_INVALID, KEY_INVALID, 0};
#ifdef ENABLE_SCAN_RANGES
static uint16_t blacklistFreqs[15];
static uint8_t blacklistFreqsIdx;
#endif
const char *bwOptions[] = {" 25k", "12.5k", "6.25k"};
const uint8_t modulationTypeTuneSteps[] = {100, 50, 10};
const uint8_t modTypeReg47Values[] = {1, 7, 5};
@@ -260,12 +269,24 @@ static void ResetPeak() {
}
bool IsCenterMode() { return settings.scanStepIndex < S_STEP_2_5kHz; }
uint8_t GetStepsCount() { return 128 >> settings.stepsCount; }
// scan step in 0.01khz
uint16_t GetScanStep() { return scanStepValues[settings.scanStepIndex]; }
uint16_t GetStepsCount()
{
#ifdef ENABLE_SCAN_RANGES
if(gScanRangeStart) {
return (gScanRangeStop - gScanRangeStart) / GetScanStep();
}
#endif
return 128 >> settings.stepsCount;
}
uint32_t GetBW() { return GetStepsCount() * GetScanStep(); }
uint32_t GetFStart() {
return IsCenterMode() ? currentFreq - (GetBW() >> 1) : currentFreq;
}
uint32_t GetFEnd() { return currentFreq + GetBW(); }
static void TuneToPeak() {
@@ -352,6 +373,10 @@ static void ResetBlacklist() {
if (rssiHistory[i] == RSSI_MAX_VALUE)
rssiHistory[i] = 0;
}
#ifdef ENABLE_SCAN_RANGES
memset(blacklistFreqs, 0, sizeof(blacklistFreqs));
blacklistFreqsIdx = 0;
#endif
}
static void RelaunchScan() {
@@ -398,7 +423,20 @@ static void UpdatePeakInfo() {
UpdatePeakInfoForce();
}
static void Measure() { rssiHistory[scanInfo.i] = scanInfo.rssi = GetRssi(); }
static void Measure()
{
uint16_t rssi = scanInfo.rssi = GetRssi();
#ifdef ENABLE_SCAN_RANGES
if(scanInfo.measurementsCount > 128) {
uint8_t idx = (uint32_t)ARRAY_SIZE(rssiHistory) * 1000 / scanInfo.measurementsCount * scanInfo.i / 1000;
if(rssiHistory[idx] < rssi || isListening)
rssiHistory[idx] = rssi;
rssiHistory[(idx+1)%128] = 0;
return;
}
#endif
rssiHistory[scanInfo.i] = rssi;
}
// Update things by keypress
@@ -595,12 +633,25 @@ static void UpdateFreqInput(KEY_Code_t key) {
}
static void Blacklist() {
#ifdef ENABLE_SCAN_RANGES
blacklistFreqs[blacklistFreqsIdx++ % ARRAY_SIZE(blacklistFreqs)] = peak.i;
#endif
rssiHistory[peak.i] = RSSI_MAX_VALUE;
ResetPeak();
ToggleRX(false);
newScanStart = true;
ResetScanStats();
}
#ifdef ENABLE_SCAN_RANGES
static bool IsBlacklisted(uint16_t idx)
{
for(uint8_t i = 0; i < ARRAY_SIZE(blacklistFreqs); i++)
if(blacklistFreqs[i] == idx)
return true;
return false;
}
#endif
// Draw things
// applied x2 to prevent initial rounding
@@ -710,9 +761,11 @@ static void DrawRssiTriggerLevel() {
}
static void DrawTicks() {
uint32_t f = GetFStart() % 100000;
uint32_t step = GetScanStep();
for (uint8_t i = 0; i < 128; i += (1 << settings.stepsCount), f += step) {
uint32_t f = GetFStart();
uint32_t span = GetFEnd() - GetFStart();
uint32_t step = span / 128;
for (uint8_t i = 0; i < 128; i += (1 << settings.stepsCount)) {
f = GetFStart() + span * i / 128;
uint8_t barValue = 0b00000001;
(f % 10000) < step && (barValue |= 0b00000010);
(f % 50000) < step && (barValue |= 0b00000100);
@@ -764,10 +817,16 @@ static void OnKeyDown(uint8_t key) {
UpdateFreqChangeStep(false);
break;
case KEY_UP:
UpdateCurrentFreq(true);
#ifdef ENABLE_SCAN_RANGES
if(!gScanRangeStart)
#endif
UpdateCurrentFreq(true);
break;
case KEY_DOWN:
UpdateCurrentFreq(false);
#ifdef ENABLE_SCAN_RANGES
if(!gScanRangeStart)
#endif
UpdateCurrentFreq(false);
break;
case KEY_SIDE1:
Blacklist();
@@ -779,7 +838,10 @@ static void OnKeyDown(uint8_t key) {
UpdateRssiTriggerLevel(false);
break;
case KEY_5:
FreqInput();
#ifdef ENABLE_SCAN_RANGES
if(!gScanRangeStart)
#endif
FreqInput();
break;
case KEY_0:
ToggleModulation();
@@ -788,7 +850,10 @@ static void OnKeyDown(uint8_t key) {
ToggleListeningBW();
break;
case KEY_4:
ToggleStepsCount();
#ifdef ENABLE_SCAN_RANGES
if(!gScanRangeStart)
#endif
ToggleStepsCount();
break;
case KEY_SIDE2:
ToggleBacklight();
@@ -932,7 +997,7 @@ static void RenderStatus() {
static void RenderSpectrum() {
DrawTicks();
DrawArrow(peak.i << settings.stepsCount);
DrawArrow(128u * peak.i / GetStepsCount());
DrawSpectrum();
DrawRssiTriggerLevel();
DrawF(peak.f);
@@ -1049,7 +1114,11 @@ bool HandleUserInput() {
}
static void Scan() {
if (rssiHistory[scanInfo.i] != RSSI_MAX_VALUE) {
if (rssiHistory[scanInfo.i] != RSSI_MAX_VALUE
#ifdef ENABLE_SCAN_RANGES
&& !IsBlacklisted(scanInfo.i)
#endif
) {
SetF(scanInfo.f);
Measure();
UpdateScanInfo();
@@ -1070,6 +1139,10 @@ static void UpdateScan() {
return;
}
if(scanInfo.measurementsCount < 128)
memset(&rssiHistory[scanInfo.measurementsCount], 0,
sizeof(rssiHistory) - scanInfo.measurementsCount*sizeof(rssiHistory[0]));
redrawScreen = true;
preventKeypress = false;
@@ -1122,7 +1195,7 @@ static void UpdateListening() {
}
ToggleRX(false);
newScanStart = true;
ResetScanStats();
}
static void Tick() {
@@ -1135,6 +1208,26 @@ static void Tick() {
}
#endif
#ifdef ENABLE_SCAN_RANGES
if (gNextTimeslice_500ms) {
gNextTimeslice_500ms = false;
// if a lot of steps then it takes long time
// we don't want to wait for whole scan
// listening has it's own timer
if(GetStepsCount()>128 && !isListening) {
UpdatePeakInfo();
if (IsPeakOverLevel()) {
ToggleRX(true);
TuneToPeak();
return;
}
redrawScreen = true;
preventKeypress = false;
}
}
#endif
if (!preventKeypress) {
HandleUserInput();
}
@@ -1166,18 +1259,32 @@ void APP_RunSpectrum() {
// TX here coz it always? set to active VFO
vfo = gEeprom.TX_VFO;
// set the current frequency in the middle of the display
currentFreq = initialFreq = gEeprom.VfoInfo[vfo].pRX->Frequency -
((GetStepsCount() / 2) * GetScanStep());
#ifdef ENABLE_SCAN_RANGES
if(gScanRangeStart) {
currentFreq = initialFreq = gScanRangeStart;
for(uint8_t i = 0; i < ARRAY_SIZE(scanStepValues); i++) {
if(scanStepValues[i] >= gTxVfo->StepFrequency) {
settings.scanStepIndex = i;
break;
}
}
settings.stepsCount = STEPS_128;
}
else
#endif
currentFreq = initialFreq = gTxVfo->pRX->Frequency -
((GetStepsCount() / 2) * GetScanStep());
BackupRegisters();
isListening = true; // to turn off RX later
redrawStatus = true;
redrawScreen = false; // we will wait until scan done
redrawScreen = true;
newScanStart = true;
ToggleRX(true), ToggleRX(false); // hack to prevent noise when squelch off
RADIO_SetModulation(settings.modulationType = gRxVfo->Modulation);
RADIO_SetModulation(settings.modulationType = gTxVfo->Modulation);
BK4819_SetFilterBandwidth(settings.listenBw = BK4819_FILTER_BW_WIDE, false);

View File

@@ -138,17 +138,17 @@ typedef struct KeyboardState {
typedef struct ScanInfo {
uint16_t rssi, rssiMin, rssiMax;
uint8_t i, iPeak;
uint16_t i, iPeak;
uint32_t f, fPeak;
uint16_t scanStep;
uint8_t measurementsCount;
uint16_t measurementsCount;
} ScanInfo;
typedef struct PeakInfo {
uint16_t t;
uint16_t rssi;
uint32_t f;
uint8_t i;
uint16_t i;
} PeakInfo;
void APP_RunSpectrum(void);

4
misc.h
View File

@@ -32,6 +32,10 @@
#define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
#endif
#ifndef SWAP
#define SWAP(a, b) ({ __typeof__ (a) _c = (a); a = b; b = _c; })
#endif
#define IS_MR_CHANNEL(x) ((x) <= MR_CHANNEL_LAST)
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
#define IS_VALID_CHANNEL(x) ((x) < LAST_CHANNEL)

View File

@@ -348,8 +348,7 @@ void UI_DisplayMain(void)
UI_PrintString("ScnRng", 5, 0, line, 8);
sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000);
UI_PrintStringSmall(String, 56, 0, line);
uint32_t frq = gEeprom.VfoInfo[vfo_num].pRX->Frequency;
sprintf(String, "%3u.%05u", frq / 100000, frq % 100000);
sprintf(String, "%3u.%05u", gScanRangeStop / 100000, gScanRangeStop % 100000);
UI_PrintStringSmall(String, 56, 0, line + 1);
continue;
}