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 #ifdef ENABLE_SCAN_RANGES
uint32_t gScanRangeStart; uint32_t gScanRangeStart;
uint32_t gScanRangeStop;
#endif #endif
typedef enum { typedef enum {
@@ -157,9 +158,7 @@ static void NextFreqChannel(void)
{ {
#ifdef ENABLE_SCAN_RANGES #ifdef ENABLE_SCAN_RANGES
if(gScanRangeStart) { if(gScanRangeStart) {
uint32_t start = gScanRangeStart; gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop);
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));
} }
else else
#endif #endif

View File

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

View File

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

View File

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

View File

@@ -138,17 +138,17 @@ typedef struct KeyboardState {
typedef struct ScanInfo { typedef struct ScanInfo {
uint16_t rssi, rssiMin, rssiMax; uint16_t rssi, rssiMin, rssiMax;
uint8_t i, iPeak; uint16_t i, iPeak;
uint32_t f, fPeak; uint32_t f, fPeak;
uint16_t scanStep; uint16_t scanStep;
uint8_t measurementsCount; uint16_t measurementsCount;
} ScanInfo; } ScanInfo;
typedef struct PeakInfo { typedef struct PeakInfo {
uint16_t t; uint16_t t;
uint16_t rssi; uint16_t rssi;
uint32_t f; uint32_t f;
uint8_t i; uint16_t i;
} PeakInfo; } PeakInfo;
void APP_RunSpectrum(void); 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; }) #define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
#endif #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_MR_CHANNEL(x) ((x) <= MR_CHANNEL_LAST)
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST) #define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
#define IS_VALID_CHANNEL(x) ((x) < LAST_CHANNEL) #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); UI_PrintString("ScnRng", 5, 0, line, 8);
sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000); sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000);
UI_PrintStringSmall(String, 56, 0, line); UI_PrintStringSmall(String, 56, 0, line);
uint32_t frq = gEeprom.VfoInfo[vfo_num].pRX->Frequency; sprintf(String, "%3u.%05u", gScanRangeStop / 100000, gScanRangeStop % 100000);
sprintf(String, "%3u.%05u", frq / 100000, frq % 100000);
UI_PrintStringSmall(String, 56, 0, line + 1); UI_PrintStringSmall(String, 56, 0, line + 1);
continue; continue;
} }