mirror of
https://github.com/armel/uv-k1-k5v3-firmware-custom.git
synced 2026-10-02 03:15:37 +00:00
Add scan RSSI sparkline indicator
This commit is contained in:
1 parent
8f11a32c9d
commit
25ea1f827b
5 files changed
+153
-1
No files matched your search
@@ -197,6 +197,7 @@ enable_feature(ENABLE_FEAT_F4HWN_INV)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_CTR)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_SCAN_PROGRESS)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_SCAN_FASTER)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_SCAN_RSSI)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_RESCUE_OPS)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_VOL)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_AUDIO)
|
||||
|
||||
+75
-1
@@ -1,5 +1,6 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/chFrScanner.h"
|
||||
@@ -232,6 +233,65 @@ static uint32_t scanFastPrevFrequency;
|
||||
static bool scanFastLastFullTuneCandidate;
|
||||
static VFO_Info_t scanFastDisplayVfo;
|
||||
static bool scanFastDisplayVfoValid;
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCAN_RSSI
|
||||
static uint16_t scanRssiSparkline[CHFRSCANNER_RSSI_SPARKLINE_WIDTH];
|
||||
static uint8_t scanRssiSparklineWrite;
|
||||
static uint8_t scanRssiSparklineCount;
|
||||
|
||||
static void ScanRssiSparklineReset(void)
|
||||
{
|
||||
memset(scanRssiSparkline, 0, sizeof(scanRssiSparkline));
|
||||
scanRssiSparklineWrite = 0;
|
||||
scanRssiSparklineCount = 0;
|
||||
}
|
||||
|
||||
static void ScanRssiSparklinePush(uint16_t rssi)
|
||||
{
|
||||
scanRssiSparkline[scanRssiSparklineWrite] = rssi;
|
||||
scanRssiSparklineWrite++;
|
||||
if (scanRssiSparklineWrite >= CHFRSCANNER_RSSI_SPARKLINE_WIDTH)
|
||||
scanRssiSparklineWrite = 0;
|
||||
|
||||
if (scanRssiSparklineCount < CHFRSCANNER_RSSI_SPARKLINE_WIDTH)
|
||||
scanRssiSparklineCount++;
|
||||
}
|
||||
|
||||
bool CHFRSCANNER_HasScanRssiSparkline(void)
|
||||
{
|
||||
return gScanStateDir != SCAN_OFF && scanRssiSparklineCount > 1;
|
||||
}
|
||||
|
||||
uint8_t CHFRSCANNER_GetScanRssiSparklineLevel(uint8_t index)
|
||||
{
|
||||
uint16_t minRssi = SCAN_FAST_RSSI_MAX;
|
||||
uint16_t rssi = 0;
|
||||
uint8_t oldest;
|
||||
|
||||
if (index >= CHFRSCANNER_RSSI_SPARKLINE_WIDTH || scanRssiSparklineCount == 0)
|
||||
return 0;
|
||||
|
||||
if (index < CHFRSCANNER_RSSI_SPARKLINE_WIDTH - scanRssiSparklineCount)
|
||||
return 0;
|
||||
|
||||
oldest = (uint8_t)((scanRssiSparklineWrite + CHFRSCANNER_RSSI_SPARKLINE_WIDTH - scanRssiSparklineCount)
|
||||
% CHFRSCANNER_RSSI_SPARKLINE_WIDTH);
|
||||
index -= (uint8_t)(CHFRSCANNER_RSSI_SPARKLINE_WIDTH - scanRssiSparklineCount);
|
||||
|
||||
for (uint8_t i = 0; i < scanRssiSparklineCount; i++)
|
||||
{
|
||||
const uint16_t sample = scanRssiSparkline[(oldest + i) % CHFRSCANNER_RSSI_SPARKLINE_WIDTH];
|
||||
if (sample != 0 && sample < minRssi)
|
||||
minRssi = sample;
|
||||
}
|
||||
|
||||
rssi = scanRssiSparkline[(oldest + index) % CHFRSCANNER_RSSI_SPARKLINE_WIDTH];
|
||||
if (rssi == 0 || minRssi == SCAN_FAST_RSSI_MAX || rssi <= minRssi + 2)
|
||||
return 0;
|
||||
|
||||
// 48 RSSI units ~= 24 dB. This keeps quiet jitter low while strong hits pop.
|
||||
return (uint8_t)MIN(((uint32_t)(rssi - minRssi) * 5u + 24u) / 48u, 5u);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ScanFastResetState(void)
|
||||
{
|
||||
@@ -538,6 +598,9 @@ static scan_fast_result_t ScanRangeFastPrecheck(void)
|
||||
ScanFastTune(freq);
|
||||
|
||||
const uint16_t rssi = ScanFastReadCandidateRssi();
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCAN_RSSI
|
||||
ScanRssiSparklinePush(rssi);
|
||||
#endif
|
||||
if (ScanFastIsCandidate(rssi))
|
||||
{
|
||||
ScanRangeFastRefineCandidate(rssi);
|
||||
@@ -573,7 +636,12 @@ static bool MemChannelFastPrecheck(uint16_t channel)
|
||||
scanFastReg30 = BK4819_ReadRegister(BK4819_REG_30) & ~BK4819_REG_30_MASK_ENABLE_AF_DAC;
|
||||
ScanFastTune(frequency);
|
||||
|
||||
if (ScanFastIsCandidate(ScanFastReadCandidateRssi()))
|
||||
const uint16_t rssi = ScanFastReadCandidateRssi();
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCAN_RSSI
|
||||
ScanRssiSparklinePush(rssi);
|
||||
#endif
|
||||
|
||||
if (ScanFastIsCandidate(rssi))
|
||||
{
|
||||
scanFastLastFullTuneCandidate = true;
|
||||
return true; // signal detected: let the full tune path follow
|
||||
@@ -637,6 +705,9 @@ void CHFRSCANNER_Start(const bool storeBackupSettings, const int8_t scan_directi
|
||||
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
|
||||
gScanStateDir = scan_direction;
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCAN_RSSI
|
||||
ScanRssiSparklineReset();
|
||||
#endif
|
||||
ScanFastResetState();
|
||||
#endif
|
||||
|
||||
@@ -820,6 +891,9 @@ void CHFRSCANNER_Stop(void)
|
||||
}
|
||||
|
||||
gScanStateDir = SCAN_OFF;
|
||||
#if defined(ENABLE_FEAT_F4HWN_SCAN_FASTER) && defined(ENABLE_FEAT_F4HWN_SCAN_RSSI)
|
||||
ScanRssiSparklineReset();
|
||||
#endif
|
||||
|
||||
const uint32_t chFr = gScanKeepResult ? lastFoundFrqOrChan : initialFrqOrChan;
|
||||
const bool channelChanged = chFr != initialFrqOrChan;
|
||||
|
||||
@@ -26,6 +26,11 @@ void CHFRSCANNER_ManualResume(const int8_t scan_direction);
|
||||
void CHFRSCANNER_ContinueScanning(void);
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
|
||||
const VFO_Info_t *CHFRSCANNER_GetScanDisplayVfo(void);
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCAN_RSSI
|
||||
bool CHFRSCANNER_HasScanRssiSparkline(void);
|
||||
uint8_t CHFRSCANNER_GetScanRssiSparklineLevel(uint8_t index);
|
||||
#define CHFRSCANNER_RSSI_SPARKLINE_WIDTH 24u
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_FEAT_F4HWN_RESUME_STATE) || defined(ENABLE_SCAN_RANGES)
|
||||
|
||||
@@ -140,6 +140,71 @@ const char *VfoStateStr[] = {
|
||||
[VFO_STATE_VOLTAGE_HIGH]="VOLT HIGH"
|
||||
};
|
||||
|
||||
#if defined(ENABLE_FEAT_F4HWN_SCAN_FASTER) && defined(ENABLE_FEAT_F4HWN_SCAN_RSSI)
|
||||
static uint8_t UI_MAIN_GetScanRssiSparklineMask(uint8_t previousLevel, uint8_t level)
|
||||
{
|
||||
uint8_t mask = 0;
|
||||
const uint8_t bottom = 5;
|
||||
|
||||
if (level == 0)
|
||||
return (uint8_t)(1u << bottom);
|
||||
|
||||
const uint8_t top = bottom + 1 - level;
|
||||
uint8_t bridgeTop = top;
|
||||
uint8_t bridgeBottom = top;
|
||||
|
||||
if (previousLevel > 0)
|
||||
{
|
||||
const uint8_t previousTop = bottom + 1 - previousLevel;
|
||||
if (previousTop < bridgeTop)
|
||||
bridgeTop = previousTop;
|
||||
else if (previousTop > bridgeBottom)
|
||||
bridgeBottom = previousTop;
|
||||
}
|
||||
|
||||
// Solid crest line with a small vertical bridge to avoid broken diagonals.
|
||||
for (uint8_t y = bridgeTop; y <= bridgeBottom; y++)
|
||||
mask |= (uint8_t)(1u << y);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void UI_MAIN_DrawScanRssiSparkline(uint8_t line)
|
||||
{
|
||||
uint8_t *p_line = gFrameBuffer[line];
|
||||
const uint8_t x0 = 7;
|
||||
uint8_t level[CHFRSCANNER_RSSI_SPARKLINE_WIDTH];
|
||||
|
||||
if (!CHFRSCANNER_HasScanRssiSparkline())
|
||||
return;
|
||||
|
||||
for (uint8_t i = 0; i < CHFRSCANNER_RSSI_SPARKLINE_WIDTH; i++)
|
||||
level[i] = CHFRSCANNER_GetScanRssiSparklineLevel(i);
|
||||
|
||||
for (uint8_t i = 0; i < CHFRSCANNER_RSSI_SPARKLINE_WIDTH; i++)
|
||||
{
|
||||
const uint8_t previousRaw = (i > 0) ? level[i - 1] : 0;
|
||||
const uint8_t nextRaw = (i + 1 < CHFRSCANNER_RSSI_SPARKLINE_WIDTH) ? level[i + 1] : 0;
|
||||
uint8_t displayLevel = (uint8_t)((previousRaw + 2u * level[i] + nextRaw + 2u) >> 2);
|
||||
uint8_t previousLevel = previousRaw;
|
||||
|
||||
if (level[i] == 0 && previousRaw == 0 && nextRaw == 0)
|
||||
displayLevel = 0;
|
||||
else if (displayLevel == 0)
|
||||
displayLevel = 1;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
const uint8_t previousPreviousRaw = (i > 1) ? level[i - 2] : 0;
|
||||
previousLevel = (uint8_t)((previousPreviousRaw + 2u * previousRaw + level[i] + 2u) >> 2);
|
||||
}
|
||||
|
||||
const uint8_t mask = UI_MAIN_GetScanRssiSparklineMask(previousLevel, displayLevel);
|
||||
p_line[x0 + i] = (p_line[x0 + i] & 0x80) | mask;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCAN_PROGRESS
|
||||
static void ScanProgress_ResetSession(void)
|
||||
{
|
||||
@@ -1442,6 +1507,11 @@ void UI_DisplayMain(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(ENABLE_FEAT_F4HWN_SCAN_FASTER) && defined(ENABLE_FEAT_F4HWN_SCAN_RSSI)
|
||||
if (vfo_num == gEeprom.RX_VFO && gScanStateDir != SCAN_OFF && !FUNCTION_IsRx())
|
||||
UI_MAIN_DrawScanRssiSparkline(line);
|
||||
#endif
|
||||
|
||||
if(TX_freq_check(frequency) != 0 && gEeprom.VfoInfo[vfo_num].TX_LOCK == true)
|
||||
{
|
||||
if (!FUNCTION_IsRx() || RxOnVfofrequency != frequency)
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
"ENABLE_FEAT_F4HWN_MEM": false,
|
||||
"ENABLE_FEAT_F4HWN_SCAN_PROGRESS": false,
|
||||
"ENABLE_FEAT_F4HWN_SCAN_FASTER": false,
|
||||
"ENABLE_FEAT_F4HWN_SCAN_RSSI": false,
|
||||
"ENABLE_FEAT_F4HWN_BEAM": false,
|
||||
"ENABLE_FEAT_F4HWN_LOGO": false,
|
||||
"ENABLE_FEAT_F4HWN_LOGO_SAV": false,
|
||||
@@ -199,6 +200,7 @@
|
||||
"ENABLE_FEAT_F4HWN_AUDIO_SCOPE": true,
|
||||
"ENABLE_FEAT_F4HWN_SCAN_PROGRESS": true,
|
||||
"ENABLE_FEAT_F4HWN_SCAN_FASTER": true,
|
||||
"ENABLE_FEAT_F4HWN_SCAN_RSSI": true,
|
||||
"ENABLE_FEAT_F4HWN_BEAM": true,
|
||||
"ENABLE_FEAT_F4HWN_QRCODE": true,
|
||||
"ENABLE_FEAT_F4HWN_MEM": true,
|
||||
|
||||
Reference in new issue
Block a user