From 39eb3e835e87694b87965af76307b657e35f2f8f Mon Sep 17 00:00:00 2001 From: Krzysiek Egzmont Date: Sat, 16 Dec 2023 14:46:01 +0100 Subject: [PATCH] Scan range in spectrum --- app/chFrScanner.c | 5 +- app/chFrScanner.h | 1 + app/main.c | 3 + app/spectrum.c | 143 ++++++++++++++++++++++++++++++++++++++++------ app/spectrum.h | 6 +- misc.h | 4 ++ ui/main.c | 3 +- 7 files changed, 139 insertions(+), 26 deletions(-) diff --git a/app/chFrScanner.c b/app/chFrScanner.c index 10050ecea..4d7f8441c 100644 --- a/app/chFrScanner.c +++ b/app/chFrScanner.c @@ -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 diff --git a/app/chFrScanner.h b/app/chFrScanner.h index b3695eef6..4038461a9 100644 --- a/app/chFrScanner.h +++ b/app/chFrScanner.h @@ -12,6 +12,7 @@ extern bool gScanPauseMode; #ifdef ENABLE_SCAN_RANGES extern uint32_t gScanRangeStart; +extern uint32_t gScanRangeStop; #endif void CHFRSCANNER_Found(void); diff --git a/app/main.c b/app/main.c index efbd11966..ee5e11c4a 100644 --- a/app/main.c +++ b/app/main.c @@ -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; } diff --git a/app/spectrum.c b/app/spectrum.c index a437ffdd8..e4fff724a 100644 --- a/app/spectrum.c +++ b/app/spectrum.c @@ -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,11 +633,24 @@ 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 @@ -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); diff --git a/app/spectrum.h b/app/spectrum.h index 042af92fa..1c1cce528 100644 --- a/app/spectrum.h +++ b/app/spectrum.h @@ -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); diff --git a/misc.h b/misc.h index 7e05ea534..4376bf70c 100644 --- a/misc.h +++ b/misc.h @@ -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) diff --git a/ui/main.c b/ui/main.c index 9aff3041d..93c4af44f 100644 --- a/ui/main.c +++ b/ui/main.c @@ -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; }