Add volatile scanrange exclusions

This commit is contained in:
Armel FAUVEAU committed 2026-05-04 03:36:40 +02:00
1 parent 3e6b169b7b
commit 932d6e954a
4 files changed
+168 -10

No files matched your search

+145 -7
View File
@@ -20,6 +20,22 @@ bool gScanPauseMode;
#ifdef ENABLE_SCAN_RANGES
uint32_t gScanRangeStart;
uint32_t gScanRangeStop;
#define SCAN_RANGE_SKIP_MAX 32
#if (SCAN_RANGE_SKIP_MAX & (SCAN_RANGE_SKIP_MAX - 1)) != 0
#error SCAN_RANGE_SKIP_MAX must be a power of two
#endif
typedef struct {
uint16_t sample[SCAN_RANGE_SKIP_MAX];
uint32_t start;
uint32_t stop;
uint16_t step;
uint8_t count;
uint8_t next;
} ScanRangeSkipList_t;
static ScanRangeSkipList_t scanRangeSkip;
#endif
typedef enum {
@@ -43,6 +59,123 @@ uint8_t initialCROSS_BAND_RX_TX;
static void NextFreqChannel(void);
static void NextMemChannel(void);
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
static void ScanFastResetState(void);
#endif
#ifdef ENABLE_SCAN_RANGES
static void ScanRangeSkipClear(void)
{
scanRangeSkip.count = 0;
scanRangeSkip.next = 0;
}
static void ScanRangeSkipSync(void)
{
const uint16_t step = gRxVfo->StepFrequency;
if (scanRangeSkip.start == gScanRangeStart &&
scanRangeSkip.stop == gScanRangeStop &&
scanRangeSkip.step == step)
{
return;
}
ScanRangeSkipClear();
scanRangeSkip.start = gScanRangeStart;
scanRangeSkip.stop = gScanRangeStop;
scanRangeSkip.step = step;
}
static uint16_t ScanRangeSkipSampleForFrequency(uint32_t frequency)
{
const uint16_t step = gRxVfo->StepFrequency;
if (!gScanRangeStart || step == 0 || frequency < gScanRangeStart || frequency > gScanRangeStop)
return 0;
const uint32_t sample = (frequency - gScanRangeStart) / step;
if (sample >= 0xFFFFu)
return 0;
return (uint16_t)(sample + 1);
}
static bool ScanRangeSkipContainsFrequency(uint32_t frequency)
{
const uint16_t sample = ScanRangeSkipSampleForFrequency(frequency);
if (sample == 0)
return false;
for (uint8_t i = 0; i < scanRangeSkip.count; ++i)
if (scanRangeSkip.sample[i] == sample)
return true;
return false;
}
static uint32_t ScanRangeNextFrequency(void)
{
uint32_t frequency;
uint8_t guard = SCAN_RANGE_SKIP_MAX + 1;
ScanRangeSkipSync();
do
{
frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop);
gRxVfo->freq_config_RX.Frequency = frequency;
} while (--guard && ScanRangeSkipContainsFrequency(frequency));
return frequency;
}
bool CHFRSCANNER_ExcludeCurrentScanRange(void)
{
ScanRangeSkipSync();
uint16_t sample = ScanRangeSkipSampleForFrequency(lastFoundFrqOrChan);
if (sample == 0)
sample = ScanRangeSkipSampleForFrequency(gRxVfo->freq_config_RX.Frequency);
if (sample == 0)
return false;
for (uint8_t i = 0; i < scanRangeSkip.count; ++i)
if (scanRangeSkip.sample[i] == sample)
return true;
scanRangeSkip.sample[scanRangeSkip.next] = sample;
scanRangeSkip.next = (scanRangeSkip.next + 1) & (SCAN_RANGE_SKIP_MAX - 1);
if (scanRangeSkip.count < SCAN_RANGE_SKIP_MAX)
scanRangeSkip.count++;
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
ScanFastResetState();
#endif
return true;
}
bool CHFRSCANNER_HasScanRangeExcludedOrdinal(uint32_t first_ordinal, uint32_t last_ordinal)
{
if (first_ordinal == 0)
first_ordinal = 1;
if (last_ordinal < first_ordinal)
return false;
if (first_ordinal > 0xFFFFu)
return false;
if (last_ordinal > 0xFFFFu)
last_ordinal = 0xFFFFu;
for (uint8_t i = 0; i < scanRangeSkip.count; ++i) {
const uint16_t sample = scanRangeSkip.sample[i];
if (sample >= first_ordinal && sample <= last_ordinal)
return true;
}
return false;
}
#endif
static void CHFRSCANNER_AbortActiveReception(void)
{
@@ -333,8 +466,7 @@ static void ScanRangeFastRefineCandidate(uint16_t firstRssi)
{
const uint32_t prevRxFrequency = gRxVfo->pRX->Frequency;
gRxVfo->freq_config_RX.Frequency =
APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop);
gRxVfo->freq_config_RX.Frequency = ScanRangeNextFrequency();
RADIO_ApplyOffset(gRxVfo);
const uint32_t freq = gRxVfo->pRX->Frequency;
@@ -380,8 +512,7 @@ static scan_fast_result_t ScanRangeFastPrecheck(void)
for (uint8_t i = 0; i < SCAN_FAST_PRECHECK_STEPS; ++i)
{
gRxVfo->freq_config_RX.Frequency =
APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop);
gRxVfo->freq_config_RX.Frequency = ScanRangeNextFrequency();
RADIO_ApplyOffset(gRxVfo);
const uint32_t freq = gRxVfo->pRX->Frequency;
@@ -467,13 +598,20 @@ static void SetMemScanProgressChannel(uint16_t channel)
#if defined(ENABLE_FEAT_F4HWN_RESUME_STATE) || defined(ENABLE_SCAN_RANGES)
void CHFRSCANNER_ScanRange(void) {
gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency;
if (gScanRangeStart) {
gScanRangeStart = 0;
return;
}
gScanRangeStart = gTxVfo->pRX->Frequency;
gScanRangeStop = gEeprom.VfoInfo[!gEeprom.TX_VFO].freq_config_RX.Frequency;
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
ScanFastResetState();
#endif
if(gScanRangeStart > gScanRangeStop)
SWAP(gScanRangeStart, gScanRangeStop);
ScanRangeSkipSync();
}
#endif
@@ -725,14 +863,14 @@ static void NextFreqChannel(void)
if (fastResult == SCAN_FAST_DISABLED)
{
scanFastLastFullTuneCandidate = false;
gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop);
gRxVfo->freq_config_RX.Frequency = ScanRangeNextFrequency();
}
else
{
scanFastLastFullTuneCandidate = true;
}
#else
gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop);
gRxVfo->freq_config_RX.Frequency = ScanRangeNextFrequency();
#endif
}
else
+2
View File
@@ -15,6 +15,8 @@ extern bool gScanPauseMode;
#ifdef ENABLE_SCAN_RANGES
extern uint32_t gScanRangeStart;
extern uint32_t gScanRangeStop;
bool CHFRSCANNER_ExcludeCurrentScanRange(void);
bool CHFRSCANNER_HasScanRangeExcludedOrdinal(uint32_t first_ordinal, uint32_t last_ordinal);
#endif
void CHFRSCANNER_Found(void);
+15 -1
View File
@@ -762,11 +762,25 @@ static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld)
if (bKeyPressed) { // long press MENU key
#ifdef ENABLE_FEAT_F4HWN
// Exclude channel
// Exclude current scan entry
if(gScanStateDir != SCAN_OFF)
{
if(FUNCTION_IsRx() || gScanPauseDelayIn_10ms > 9)
{
#ifdef ENABLE_SCAN_RANGES
if(gScanRangeStart && !IS_MR_CHANNEL(gNextMrChannel))
{
if(CHFRSCANNER_ExcludeCurrentScanRange())
{
UI_MAIN_NotifyScanProgressDataChanged();
lastFoundFrqOrChan = lastFoundFrqOrChanOld;
CHFRSCANNER_ContinueScanning();
}
return;
}
#endif
ChannelAttributes_t *att = MR_GetChannelAttributes(lastFoundFrqOrChan);
att->exclude = true;
+6 -2
View File
@@ -221,7 +221,7 @@ static bool ScanProgress_BucketHasExcludedOrdinal(uint32_t first_ordinal, uint32
return false;
}
static void ScanProgress_DrawGaugeLine(uint8_t line, uint32_t current_index, uint32_t total, uint8_t width, bool memory_mode, uint8_t extra_left_offset)
static void ScanProgress_DrawGaugeLine(uint8_t line, uint32_t current_index, uint32_t total, uint8_t width, bool memory_mode, bool range_mode, uint8_t extra_left_offset)
{
const bool forward = ScanProgress_IsForward();
@@ -260,6 +260,10 @@ static void ScanProgress_DrawGaugeLine(uint8_t line, uint32_t current_index, uin
if (memory_mode)
excluded = ScanProgress_BucketHasExcludedOrdinal(first_ordinal, last_ordinal);
#ifdef ENABLE_SCAN_RANGES
else if (range_mode)
excluded = CHFRSCANNER_HasScanRangeExcludedOrdinal(first_ordinal, last_ordinal);
#endif
if (processed && !excluded) {
pixel = 0x2d;
@@ -502,7 +506,7 @@ static bool UI_DrawScanProgress(void)
UI_PrintStringSmallNormal(text, 2, 0, line);
#endif
ScanProgress_DrawGaugeLine(line, current_index, total, width, show_memory, extra_offset);
ScanProgress_DrawGaugeLine(line, current_index, total, width, show_memory, show_range, extra_offset);
return true;
}