kopia lustrzana https://github.com/piotr022/UV_K5_playground
refactor, feat: 100KHz to track satellite doppler shift, better smaller steps, better defaults
rodzic
1e533bc6b8
commit
1d65b2e798
|
@ -26,7 +26,7 @@ Features:
|
|||
|
||||
* no scan sound
|
||||
* squelch by user input level
|
||||
* 0.2 .. 3.2MHz frequency ranges
|
||||
* 0.1 .. 3.2MHz frequency ranges
|
||||
* ticks by frequency (100,500,1000KHz)
|
||||
* catch signal peak frequency
|
||||
* automatic frequency change step
|
||||
|
@ -41,8 +41,11 @@ How to start:
|
|||
|
||||
How to operate:
|
||||
|
||||
* press **8** / **2** for zoom in / zoom out
|
||||
* press and hold **3** / **9** to set squelch level
|
||||
* press **UP** / **DOWN** key to change frequency
|
||||
* press **1** / **7** to control measurement time (increasing "sensitivity")
|
||||
* press **2** / **8** to to set frequency change step
|
||||
* press **9** / **3** for zoom in / zoom out
|
||||
* press and hold **\*** / **F** to set squelch level
|
||||
* press **5** to toggle backlight
|
||||
* press **0** to remove frequency from sspectrum to scan
|
||||
* press **EXIT** to disable spectrum view
|
||||
|
|
|
@ -270,10 +270,9 @@ public:
|
|||
const char dot[1] = {64};
|
||||
for (unsigned char i = 0; i < len; i++) {
|
||||
if (pointAt == len - i) {
|
||||
u16CoursorPosition++;
|
||||
auto *pCoursorPosition = Bitmap.GetCoursorData(u16CoursorPosition);
|
||||
auto *pCoursorPosition = Bitmap.GetCoursorData(u16CoursorPosition + 1);
|
||||
memcpy(pCoursorPosition, dot, 1);
|
||||
u16CoursorPosition++;
|
||||
u16CoursorPosition += 2;
|
||||
}
|
||||
PrintCharacter(str[i]);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
enum Keys {
|
||||
NUM0,
|
||||
NUM1,
|
||||
NUM2,
|
||||
NUM3,
|
||||
NUM4,
|
||||
NUM5,
|
||||
NUM6,
|
||||
NUM7,
|
||||
NUM8,
|
||||
NUM9,
|
||||
MENU, // 10
|
||||
UP, // 11
|
||||
DOWN, // 12
|
||||
EXIT, // 13
|
||||
ASTERISK, // 14
|
||||
FUNCTION, // 15
|
||||
_NA16,
|
||||
_NA17,
|
||||
_NA18,
|
||||
_NA19,
|
||||
_NA20,
|
||||
_NA21,
|
||||
FN2, // 22
|
||||
FN1, // 23
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "keys.hpp"
|
||||
#include "radio.hpp"
|
||||
#include "system.hpp"
|
||||
#include "types.hpp"
|
||||
|
@ -6,10 +7,15 @@
|
|||
|
||||
template <Radio::CBK4819 &RadioDriver> class CSpectrum {
|
||||
public:
|
||||
static constexpr auto ExitKey = 13;
|
||||
static constexpr auto DrawingEndY = 42;
|
||||
static constexpr auto BarPos = 5 * 128;
|
||||
|
||||
static constexpr u32 modeHalfSpectrumBW[6] = {50_KHz, 100_KHz, 200_KHz,
|
||||
400_KHz, 800_KHz, 1600_KHz};
|
||||
static constexpr u16 modeScanStep[6] = {1562_Hz, 6250_Hz, 12500_Hz,
|
||||
25_KHz, 25_KHz, 25_KHz};
|
||||
static constexpr u8 modeXdiv[6] = {1, 2, 2, 2, 1, 0};
|
||||
|
||||
u8 rssiHistory[128] = {};
|
||||
u32 fMeasure;
|
||||
|
||||
|
@ -18,16 +24,16 @@ public:
|
|||
u8 peakI = 0;
|
||||
u32 peakF = 0;
|
||||
u8 rssiMin = 255;
|
||||
|
||||
u16 scanDelay = 1200;
|
||||
u8 btnCounter = 0;
|
||||
|
||||
bool resetBlacklist = false;
|
||||
|
||||
CSpectrum()
|
||||
: DisplayBuff(gDisplayBuffer), Display(DisplayBuff),
|
||||
FontSmallNr(gSmallDigs), frequencyChangeStep(400_KHz), bwMul(2),
|
||||
FontSmallNr(gSmallDigs), scanDelay(1600), mode(4),
|
||||
rssiTriggerLevel(60) {
|
||||
Display.SetFont(&FontSmallNr);
|
||||
frequencyChangeStep = modeHalfSpectrumBW[mode];
|
||||
};
|
||||
|
||||
void Scan() {
|
||||
|
@ -73,7 +79,7 @@ public:
|
|||
|
||||
void DrawSpectrum() {
|
||||
for (u8 x = 0; x < 128; ++x) {
|
||||
auto v = rssiHistory[x >> BWMul2XDiv()];
|
||||
auto v = rssiHistory[x >> modeXdiv[mode]];
|
||||
if (v != 255) {
|
||||
Display.DrawHLine(Rssi2Y(v), DrawingEndY, x);
|
||||
}
|
||||
|
@ -87,9 +93,6 @@ public:
|
|||
Display.SetCoursorXY(112, 0);
|
||||
Display.PrintFixedDigitsNumber3(GetBW(), 4, 2, 1);
|
||||
|
||||
/* Display.SetCoursorXY(0, 0);
|
||||
Display.PrintFixedDigitsNumber2(rssiMinV, 0); */
|
||||
|
||||
Display.SetCoursorXY(44, 0);
|
||||
Display.PrintFixedDigitsNumber3(peakF, 2, 6, 3);
|
||||
|
||||
|
@ -101,9 +104,6 @@ public:
|
|||
|
||||
Display.SetCoursorXY(57, 48);
|
||||
Display.PrintFixedDigitsNumber3(frequencyChangeStep, 4, 2, 1);
|
||||
|
||||
/* Display.SetCoursorXY(0, 8);
|
||||
Display.PrintFixedDigitsNumber2(rssiMaxV, 0); */
|
||||
}
|
||||
|
||||
void DrawRssiTriggerLevel() {
|
||||
|
@ -127,61 +127,56 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void OnKey(u8 key) {
|
||||
switch (key) {
|
||||
case 14:
|
||||
UpdateRssiTriggerLevel(1);
|
||||
DelayMs(90);
|
||||
break;
|
||||
case 15:
|
||||
UpdateRssiTriggerLevel(-1);
|
||||
DelayMs(90);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnKeyDown(u8 key) {
|
||||
switch (key) {
|
||||
case 1:
|
||||
case Keys::NUM1:
|
||||
if (scanDelay < 8000) {
|
||||
scanDelay += 200;
|
||||
rssiMin = 255;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
case Keys::NUM7:
|
||||
if (scanDelay > 800) {
|
||||
scanDelay -= 200;
|
||||
rssiMin = 255;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case Keys::NUM3:
|
||||
UpdateBWMul(1);
|
||||
resetBlacklist = true;
|
||||
break;
|
||||
case 9:
|
||||
case Keys::NUM9:
|
||||
UpdateBWMul(-1);
|
||||
resetBlacklist = true;
|
||||
break;
|
||||
case 2:
|
||||
case Keys::NUM2:
|
||||
UpdateFreqChangeStep(100_KHz);
|
||||
break;
|
||||
case 8:
|
||||
case Keys::NUM8:
|
||||
UpdateFreqChangeStep(-100_KHz);
|
||||
break;
|
||||
case 11: // up
|
||||
case Keys::UP:
|
||||
UpdateCurrentFreq(frequencyChangeStep);
|
||||
resetBlacklist = true;
|
||||
break;
|
||||
case 12: // down
|
||||
case Keys::DOWN:
|
||||
UpdateCurrentFreq(-frequencyChangeStep);
|
||||
resetBlacklist = true;
|
||||
break;
|
||||
case 5:
|
||||
case Keys::NUM5:
|
||||
ToggleBacklight();
|
||||
break;
|
||||
case 0:
|
||||
case Keys::NUM0:
|
||||
Blacklist();
|
||||
break;
|
||||
case Keys::ASTERISK:
|
||||
UpdateRssiTriggerLevel(1);
|
||||
DelayMs(90);
|
||||
break;
|
||||
case Keys::FUNCTION:
|
||||
UpdateRssiTriggerLevel(-1);
|
||||
DelayMs(90);
|
||||
break;
|
||||
}
|
||||
ResetPeak();
|
||||
}
|
||||
|
@ -189,12 +184,16 @@ public:
|
|||
bool HandleUserInput() {
|
||||
btnPrev = btn;
|
||||
btn = PollKeyboard();
|
||||
if (btn == ExitKey) {
|
||||
if (btn == Keys::EXIT) {
|
||||
DeInit();
|
||||
return false;
|
||||
}
|
||||
OnKey(btn);
|
||||
if (btn != 255 && btnPrev == 255) {
|
||||
if (btn != 255 && btn == btnPrev) {
|
||||
btnCounter = clamp(btnCounter + 1, 0, 255);
|
||||
} else {
|
||||
btnCounter = 0;
|
||||
}
|
||||
if ((btn != 255 && btnPrev == 255) || btnCounter > 16) {
|
||||
OnKeyDown(btn);
|
||||
}
|
||||
return true;
|
||||
|
@ -203,7 +202,7 @@ public:
|
|||
void Render() {
|
||||
DisplayBuff.ClearAll();
|
||||
DrawTicks();
|
||||
DrawArrow(peakI << BWMul2XDiv());
|
||||
DrawArrow(peakI << modeXdiv[mode]);
|
||||
DrawSpectrum();
|
||||
DrawRssiTriggerLevel();
|
||||
DrawNums();
|
||||
|
@ -212,24 +211,22 @@ public:
|
|||
|
||||
void Update() {
|
||||
if (peakRssi >= rssiTriggerLevel) {
|
||||
Listen(1600);
|
||||
return;
|
||||
Listen();
|
||||
}
|
||||
if (peakRssi < rssiTriggerLevel) {
|
||||
Scan();
|
||||
}
|
||||
Scan();
|
||||
}
|
||||
|
||||
void UpdateRssiTriggerLevel(i32 diff) {
|
||||
if ((diff > 0 && rssiTriggerLevel < 255) ||
|
||||
(diff < 0 && rssiTriggerLevel > 0)) {
|
||||
rssiTriggerLevel += diff;
|
||||
}
|
||||
}
|
||||
void UpdateRssiTriggerLevel(i32 diff) { rssiTriggerLevel += diff; }
|
||||
|
||||
void UpdateBWMul(i32 diff) {
|
||||
if ((diff > 0 && bwMul < 4) || (diff < 0 && bwMul > 0)) {
|
||||
bwMul += diff;
|
||||
if ((diff > 0 && mode < 5) || (diff < 0 && mode > 0)) {
|
||||
mode += diff;
|
||||
SetBW();
|
||||
rssiMin = 255;
|
||||
frequencyChangeStep = modeHalfSpectrumBW[mode];
|
||||
}
|
||||
frequencyChangeStep = 100_KHz << bwMul;
|
||||
}
|
||||
|
||||
void UpdateCurrentFreq(i64 diff) {
|
||||
|
@ -267,7 +264,9 @@ private:
|
|||
oldAFSettings = BK4819Read(0x47);
|
||||
oldBWSettings = BK4819Read(0x43);
|
||||
MuteAF();
|
||||
SetWideBW();
|
||||
SetBW();
|
||||
ResetPeak();
|
||||
resetBlacklist = true;
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -282,19 +281,21 @@ private:
|
|||
|
||||
void ResetPeak() {
|
||||
peakRssi = 0;
|
||||
peakF = currentFreq;
|
||||
// peakF = currentFreq;
|
||||
peakT = 0;
|
||||
}
|
||||
|
||||
void SetWideBW() {
|
||||
void SetBW() {
|
||||
auto Reg = BK4819Read(0x43);
|
||||
Reg &= ~(0b11 << 4);
|
||||
BK4819Write(0x43, Reg | (0b11 << 4));
|
||||
if (mode >= 3)
|
||||
Reg |= 0b11 << 4;
|
||||
BK4819Write(0x43, Reg);
|
||||
}
|
||||
void MuteAF() { BK4819Write(0x47, 0); }
|
||||
void RestoreOldAFSettings() { BK4819Write(0x47, oldAFSettings); }
|
||||
|
||||
void Listen(u16 durationMs) {
|
||||
void Listen() {
|
||||
if (fMeasure != peakF) {
|
||||
fMeasure = peakF;
|
||||
RadioDriver.SetFrequency(fMeasure);
|
||||
|
@ -302,26 +303,17 @@ private:
|
|||
RadioDriver.ToggleAFDAC(true);
|
||||
}
|
||||
for (u8 i = 0; i < 16 && PollKeyboard() == 255; ++i) {
|
||||
DelayMs(durationMs >> 4);
|
||||
DelayMs(64);
|
||||
}
|
||||
peakRssi = rssiHistory[peakI] = GetRssi();
|
||||
}
|
||||
|
||||
u16 GetScanStep() { return 25_KHz >> (2 >> bwMul); }
|
||||
u32 GetBW() { return 200_KHz << bwMul; }
|
||||
u32 GetFStart() { return currentFreq - (100_KHz << bwMul); }
|
||||
u32 GetFEnd() { return currentFreq + (100_KHz << bwMul); }
|
||||
u16 GetScanStep() { return modeScanStep[mode]; }
|
||||
u32 GetBW() { return modeHalfSpectrumBW[mode] << 1; }
|
||||
u32 GetFStart() { return currentFreq - modeHalfSpectrumBW[mode]; }
|
||||
u32 GetFEnd() { return currentFreq + modeHalfSpectrumBW[mode]; }
|
||||
|
||||
u8 BWMul2XDiv() { return clamp(4 - bwMul, 0, 2); }
|
||||
u8 GetMeasurementsCount() {
|
||||
if (bwMul == 3) {
|
||||
return 64;
|
||||
}
|
||||
if (bwMul > 3) {
|
||||
return 128;
|
||||
}
|
||||
return 32;
|
||||
}
|
||||
u8 GetMeasurementsCount() { return 128 >> modeXdiv[mode]; }
|
||||
|
||||
void ResetRSSI() {
|
||||
RadioDriver.ToggleRXDSP(false);
|
||||
|
@ -331,7 +323,7 @@ private:
|
|||
u8 GetRssi() {
|
||||
ResetRSSI();
|
||||
|
||||
DelayUs(scanDelay);
|
||||
DelayUs(scanDelay << (mode < 3));
|
||||
return (BK4819Read(0x67) & 0x1FF) >> 1;
|
||||
}
|
||||
|
||||
|
@ -355,25 +347,20 @@ private:
|
|||
return v;
|
||||
}
|
||||
|
||||
u32 modulo(u32 num, u32 div) {
|
||||
while (num >= div)
|
||||
num -= div;
|
||||
return num;
|
||||
}
|
||||
|
||||
TUV_K5Display DisplayBuff;
|
||||
CDisplay<const TUV_K5Display> Display;
|
||||
const TUV_K5SmallNumbers FontSmallNr;
|
||||
|
||||
u32 frequencyChangeStep;
|
||||
u8 bwMul;
|
||||
u16 scanDelay;
|
||||
u8 mode;
|
||||
u8 rssiTriggerLevel;
|
||||
|
||||
u8 btn = 255;
|
||||
u8 btnPrev = 255;
|
||||
u8 btn;
|
||||
u8 btnPrev;
|
||||
u32 currentFreq;
|
||||
u16 oldAFSettings;
|
||||
u16 oldBWSettings;
|
||||
u32 frequencyChangeStep;
|
||||
|
||||
bool isInitialized = false;
|
||||
};
|
||||
|
|
Ładowanie…
Reference in New Issue