kopia lustrzana https://github.com/piotr022/UV_K5_playground
performance tuning, cleanup, use of radio library, static methods for less ram usage, user-friendly SetCursorXY
rodzic
26726b344b
commit
d68ec04a16
|
@ -49,6 +49,11 @@ public:
|
|||
u16CoursorPosition = (u8Line * Bitmap.SizeX) + u8X;
|
||||
}
|
||||
|
||||
void SetCoursorXY(unsigned char x, unsigned char y) const
|
||||
{
|
||||
u16CoursorPosition = x + (y << 4);
|
||||
}
|
||||
|
||||
void SetFont(const IFont *pFont) const
|
||||
{
|
||||
pCurrentFont = pFont;
|
||||
|
@ -267,4 +272,4 @@ private:
|
|||
const BitmapType &Bitmap;
|
||||
mutable const IFont *pCurrentFont;
|
||||
mutable unsigned short u16CoursorPosition;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -74,12 +74,12 @@ namespace Radio
|
|||
// Fw.BK4819WriteFrequency(u32FrequencyD10);
|
||||
// }
|
||||
|
||||
unsigned int GetFrequency()
|
||||
static unsigned int GetFrequency()
|
||||
{
|
||||
return (Fw.BK4819Read(0x39) << 16) | Fw.BK4819Read(0x38);
|
||||
}
|
||||
|
||||
signed short GetRssi()
|
||||
static signed short GetRssi()
|
||||
{
|
||||
short s16Rssi = ((Fw.BK4819Read(0x67) >> 1) & 0xFF);
|
||||
return s16Rssi - 160;
|
||||
|
@ -95,7 +95,7 @@ namespace Radio
|
|||
return Fw.BK4819Read(0x0C) & 0b10;
|
||||
}
|
||||
|
||||
void SetFrequency(unsigned int u32Freq)
|
||||
static void SetFrequency(unsigned int u32Freq)
|
||||
{
|
||||
Fw.BK4819Write(0x39, ((u32Freq >> 16) & 0xFFFF));
|
||||
Fw.BK4819Write(0x38, (u32Freq & 0xFFFF));
|
||||
|
@ -283,4 +283,4 @@ namespace Radio
|
|||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "radio.hpp"
|
||||
#include "system.hpp"
|
||||
#include "uv_k5_display.hpp"
|
||||
#include "radio.hpp"
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed short i16;
|
||||
|
@ -11,82 +11,71 @@ typedef unsigned int u32;
|
|||
typedef signed long long i64;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
static constexpr auto operator""_Hz(u64 Hz) { return Hz / 10; }
|
||||
static constexpr auto operator""_KHz(u64 KHz) { return KHz * 1000_Hz; }
|
||||
static constexpr auto operator""_MHz(u64 KHz) { return KHz * 1000_KHz; }
|
||||
static constexpr auto operator""_ms(u64 us) { return us * 1000; }
|
||||
static constexpr auto operator""_s(u64 us) { return us * 1000_ms; }
|
||||
|
||||
template <const System::TOrgFunctions &Fw, const System::TOrgData &FwData, Radio::CBK4819<Fw> &RadioDriver>
|
||||
template <const System::TOrgFunctions &Fw, const System::TOrgData &FwData,
|
||||
Radio::CBK4819<Fw> &RadioDriver>
|
||||
class CSpectrum {
|
||||
public:
|
||||
static constexpr auto ExitKey = 13;
|
||||
static constexpr auto DrawingSizeY = 16 + 6 * 8;
|
||||
static constexpr auto DrawingEndY = 42;
|
||||
static constexpr auto BarPos = 5 * 128;
|
||||
|
||||
u8 rssiHistory[128] = {};
|
||||
u8 measurementsCount = 32;
|
||||
u8 rssiMin = 255, rssiMax = 0;
|
||||
u8 rssiMin = 255;
|
||||
u8 highestPeakX = 0;
|
||||
u8 highestPeakT = 0;
|
||||
u8 highestPeakRssi = 0;
|
||||
u32 highestPeakF = 0;
|
||||
u32 FStart, FEnd, fMeasure;
|
||||
u32 FStart;
|
||||
|
||||
CSpectrum()
|
||||
: DisplayBuff(FwData.pDisplayBuffer), FontSmallNr(FwData.pSmallDigs),
|
||||
Display(DisplayBuff), scanDelay(800), sampleZoom(2), scanStep(25_KHz),
|
||||
rssiTriggerLevel(65) {
|
||||
frequencyChangeStep(100_KHz), rssiTriggerLevel(65) {
|
||||
Display.SetFont(&FontSmallNr);
|
||||
};
|
||||
|
||||
inline void Measure() {
|
||||
if (highestPeakRssi >= rssiTriggerLevel) {
|
||||
// listen
|
||||
if (fMeasure != highestPeakF) {
|
||||
fMeasure = highestPeakF;
|
||||
SetFrequency(fMeasure);
|
||||
}
|
||||
Fw.BK4819Write(0x47, u16OldAfSettings);
|
||||
Fw.DelayUs(1_s);
|
||||
|
||||
// check signal level
|
||||
Fw.BK4819Write(0x47, 0); // AF
|
||||
|
||||
highestPeakRssi = GetRssi(fMeasure, scanDelay);
|
||||
|
||||
rssiHistory[highestPeakX >> sampleZoom] = highestPeakRssi;
|
||||
return;
|
||||
inline bool ListenPeak() {
|
||||
if (highestPeakRssi < rssiTriggerLevel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
u8 rssi = 0;
|
||||
u8 xPeak = 64;
|
||||
u32 fPeak = currentFreq;
|
||||
// measure peak for this moment
|
||||
highestPeakRssi = GetRssi(highestPeakF); // also sets freq for us
|
||||
rssiHistory[highestPeakX >> sampleZoom] = highestPeakRssi;
|
||||
|
||||
Fw.BK4819Write(0x47, 0);
|
||||
if (highestPeakRssi >= rssiTriggerLevel) {
|
||||
Listen(1000000);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void Scan() {
|
||||
u8 rssi = 0, rssiMax = 0;
|
||||
u8 iPeak = 0;
|
||||
u32 fPeak = currentFreq, fMeasure = FStart;
|
||||
|
||||
rssiMin = 255;
|
||||
rssiMax = 0;
|
||||
fMeasure = FStart;
|
||||
|
||||
for (u8 i = 0; i < measurementsCount; ++i, fMeasure += scanStep) {
|
||||
rssi = rssiHistory[i] = GetRssi(fMeasure, scanDelay);
|
||||
rssi = rssiHistory[i] = GetRssi(fMeasure);
|
||||
if (rssi < rssiMin) {
|
||||
rssiMin = rssi;
|
||||
}
|
||||
if (rssi > rssiMax) {
|
||||
rssiMax = rssi;
|
||||
fPeak = fMeasure;
|
||||
xPeak = i << sampleZoom;
|
||||
iPeak = i;
|
||||
}
|
||||
}
|
||||
|
||||
++highestPeakT;
|
||||
if (highestPeakT >= 8 || rssiMax > highestPeakRssi) {
|
||||
if (rssiMax > highestPeakRssi || highestPeakT >= (8 << sampleZoom)) {
|
||||
highestPeakT = 0;
|
||||
highestPeakRssi = rssiMax;
|
||||
highestPeakX = xPeak;
|
||||
highestPeakX = iPeak << sampleZoom;
|
||||
highestPeakF = fPeak;
|
||||
}
|
||||
}
|
||||
|
@ -98,25 +87,28 @@ public:
|
|||
}
|
||||
|
||||
inline void DrawNums() {
|
||||
Display.SetCoursor(0, 0);
|
||||
Display.SetCoursorXY(0, 0);
|
||||
Display.PrintFixedDigitsNumber2(scanDelay, 0);
|
||||
|
||||
Display.SetCoursor(0, 8 * 2 + 5 * 7);
|
||||
Display.SetCoursorXY(51, 0);
|
||||
Display.PrintFixedDigitsNumber2(scanStep << (7 - sampleZoom));
|
||||
|
||||
Display.SetCoursor(1, 8 * 2 + 6 * 7);
|
||||
Display.SetCoursorXY(58, 8);
|
||||
Display.PrintFixedDigitsNumber2(scanStep);
|
||||
|
||||
Display.SetCoursor(1, 8 * 2 + 13 * 7);
|
||||
Display.SetCoursorXY(107, 8);
|
||||
Display.PrintFixedDigitsNumber2(highestPeakRssi, 0);
|
||||
|
||||
Display.SetCoursor(0, 8 * 2 + 10 * 7);
|
||||
Display.SetCoursorXY(86, 0);
|
||||
Display.PrintFixedDigitsNumber2(highestPeakF);
|
||||
|
||||
Display.SetCoursor(6, 8 * 2 + 4 * 7);
|
||||
Display.SetCoursorXY(44, 48);
|
||||
Display.PrintFixedDigitsNumber2(currentFreq);
|
||||
|
||||
Display.SetCoursor(1, 0);
|
||||
Display.SetCoursorXY(100, 48);
|
||||
Display.PrintFixedDigitsNumber2(frequencyChangeStep);
|
||||
|
||||
Display.SetCoursorXY(0, 8);
|
||||
Display.PrintFixedDigitsNumber2(rssiTriggerLevel, 0);
|
||||
}
|
||||
|
||||
|
@ -150,7 +142,7 @@ public:
|
|||
}
|
||||
|
||||
void HandleUserInput() {
|
||||
switch (u8LastBtnPressed) {
|
||||
switch (lastButtonPressed) {
|
||||
case 1:
|
||||
UpdateScanDelay(200);
|
||||
break;
|
||||
|
@ -176,10 +168,16 @@ public:
|
|||
UpdateScanStep(1);
|
||||
break;
|
||||
case 11: // up
|
||||
UpdateCurrentFreq(100_KHz);
|
||||
UpdateCurrentFreq(frequencyChangeStep);
|
||||
break;
|
||||
case 12: // down
|
||||
UpdateCurrentFreq(-100_KHz);
|
||||
UpdateCurrentFreq(-frequencyChangeStep);
|
||||
break;
|
||||
case 14:
|
||||
UpdateFreqChangeStep(100_KHz);
|
||||
break;
|
||||
case 15:
|
||||
UpdateFreqChangeStep(-100_KHz);
|
||||
break;
|
||||
default:
|
||||
isUserInput = false;
|
||||
|
@ -198,7 +196,7 @@ public:
|
|||
|
||||
void Update() {
|
||||
if (bDisplayCleared) {
|
||||
currentFreq = GetFrequency();
|
||||
currentFreq = RadioDriver.GetFrequency();
|
||||
OnUserInput();
|
||||
u16OldAfSettings = Fw.BK4819Read(0x47);
|
||||
Fw.BK4819Write(0x47, 0); // mute AF during scan
|
||||
|
@ -207,7 +205,8 @@ public:
|
|||
|
||||
HandleUserInput();
|
||||
|
||||
Measure();
|
||||
if (!ListenPeak())
|
||||
Scan();
|
||||
}
|
||||
|
||||
void UpdateRssiTriggerLevel(i32 diff) {
|
||||
|
@ -241,11 +240,15 @@ public:
|
|||
OnUserInput();
|
||||
}
|
||||
|
||||
void UpdateFreqChangeStep(i64 diff) {
|
||||
frequencyChangeStep = clamp(frequencyChangeStep + diff, 100_KHz, 2_MHz);
|
||||
OnUserInput();
|
||||
}
|
||||
|
||||
inline void OnUserInput() {
|
||||
isUserInput = true;
|
||||
u32 halfOfScanRange = scanStep << (6 - sampleZoom);
|
||||
FStart = currentFreq - halfOfScanRange;
|
||||
FEnd = currentFreq + halfOfScanRange;
|
||||
|
||||
// reset peak
|
||||
highestPeakT = 0;
|
||||
|
@ -253,7 +256,7 @@ public:
|
|||
highestPeakX = 64;
|
||||
highestPeakF = currentFreq;
|
||||
|
||||
Fw.DelayUs(90_ms);
|
||||
Fw.DelayUs(90000);
|
||||
}
|
||||
|
||||
void Handle() {
|
||||
|
@ -269,8 +272,8 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
u8LastBtnPressed = Fw.PollKeyboard();
|
||||
if (u8LastBtnPressed == ExitKey) {
|
||||
lastButtonPressed = Fw.PollKeyboard();
|
||||
if (lastButtonPressed == ExitKey) {
|
||||
working = false;
|
||||
RestoreParams();
|
||||
return;
|
||||
|
@ -285,28 +288,26 @@ private:
|
|||
bDisplayCleared = true;
|
||||
DisplayBuff.ClearAll();
|
||||
Fw.FlushFramebufferToScreen();
|
||||
SetFrequency(currentFreq);
|
||||
RadioDriver.SetFrequency(currentFreq);
|
||||
Fw.BK4819Write(0x47, u16OldAfSettings); // set previous AF settings
|
||||
}
|
||||
}
|
||||
|
||||
void SetFrequency(u32 f) {
|
||||
Fw.BK4819Write(0x39, (f >> 16) & 0xFFFF);
|
||||
Fw.BK4819Write(0x38, f & 0xFFFF);
|
||||
Fw.BK4819Write(0x30, 0);
|
||||
Fw.BK4819Write(0x30, 0xbff1);
|
||||
inline void Listen(u32 duration) {
|
||||
Fw.BK4819Write(0x47, u16OldAfSettings);
|
||||
for (u8 i = 0; i < 16 && lastButtonPressed == 255; ++i) {
|
||||
lastButtonPressed = Fw.PollKeyboard();
|
||||
Fw.DelayUs(duration >> 4);
|
||||
}
|
||||
Fw.BK4819Write(0x47, 0);
|
||||
}
|
||||
|
||||
u8 GetRssi(u32 f, u32 delay = 800) {
|
||||
SetFrequency(f);
|
||||
Fw.DelayUs(delay);
|
||||
u8 GetRssi(u32 f) {
|
||||
RadioDriver.SetFrequency(f);
|
||||
Fw.DelayUs(scanDelay);
|
||||
return Fw.BK4819Read(0x67);
|
||||
}
|
||||
|
||||
u32 GetFrequency() {
|
||||
return (Fw.BK4819Read(0x39) << 16) | Fw.BK4819Read(0x38);
|
||||
}
|
||||
|
||||
inline bool IsFlashLightOn() { return GPIOC->DATA & GPIO_PIN_3; }
|
||||
inline void TurnOffFlashLight() {
|
||||
GPIOC->DATA &= ~GPIO_PIN_3;
|
||||
|
@ -335,13 +336,14 @@ private:
|
|||
const TUV_K5SmallNumbers FontSmallNr;
|
||||
CDisplay<const TUV_K5Display> Display;
|
||||
|
||||
u8 u8LastBtnPressed;
|
||||
u8 lastButtonPressed;
|
||||
u32 currentFreq;
|
||||
u16 u16OldAfSettings;
|
||||
|
||||
u16 scanDelay;
|
||||
u8 sampleZoom;
|
||||
u32 scanStep;
|
||||
u32 frequencyChangeStep;
|
||||
u8 rssiTriggerLevel;
|
||||
|
||||
bool working = false;
|
||||
|
|
Ładowanie…
Reference in New Issue