performance tuning, cleanup, use of radio library, static methods for less ram usage, user-friendly SetCursorXY

pull/49/head
Mikhail Yudin 2023-07-23 21:23:53 +07:00
rodzic 26726b344b
commit d68ec04a16
3 zmienionych plików z 81 dodań i 74 usunięć

Wyświetl plik

@ -49,6 +49,11 @@ public:
u16CoursorPosition = (u8Line * Bitmap.SizeX) + u8X; u16CoursorPosition = (u8Line * Bitmap.SizeX) + u8X;
} }
void SetCoursorXY(unsigned char x, unsigned char y) const
{
u16CoursorPosition = x + (y << 4);
}
void SetFont(const IFont *pFont) const void SetFont(const IFont *pFont) const
{ {
pCurrentFont = pFont; pCurrentFont = pFont;
@ -267,4 +272,4 @@ private:
const BitmapType &Bitmap; const BitmapType &Bitmap;
mutable const IFont *pCurrentFont; mutable const IFont *pCurrentFont;
mutable unsigned short u16CoursorPosition; mutable unsigned short u16CoursorPosition;
}; };

Wyświetl plik

@ -74,12 +74,12 @@ namespace Radio
// Fw.BK4819WriteFrequency(u32FrequencyD10); // Fw.BK4819WriteFrequency(u32FrequencyD10);
// } // }
unsigned int GetFrequency() static unsigned int GetFrequency()
{ {
return (Fw.BK4819Read(0x39) << 16) | Fw.BK4819Read(0x38); return (Fw.BK4819Read(0x39) << 16) | Fw.BK4819Read(0x38);
} }
signed short GetRssi() static signed short GetRssi()
{ {
short s16Rssi = ((Fw.BK4819Read(0x67) >> 1) & 0xFF); short s16Rssi = ((Fw.BK4819Read(0x67) >> 1) & 0xFF);
return s16Rssi - 160; return s16Rssi - 160;
@ -95,7 +95,7 @@ namespace Radio
return Fw.BK4819Read(0x0C) & 0b10; return Fw.BK4819Read(0x0C) & 0b10;
} }
void SetFrequency(unsigned int u32Freq) static void SetFrequency(unsigned int u32Freq)
{ {
Fw.BK4819Write(0x39, ((u32Freq >> 16) & 0xFFFF)); Fw.BK4819Write(0x39, ((u32Freq >> 16) & 0xFFFF));
Fw.BK4819Write(0x38, (u32Freq & 0xFFFF)); Fw.BK4819Write(0x38, (u32Freq & 0xFFFF));
@ -283,4 +283,4 @@ namespace Radio
} }
} }
}; };
} }

Wyświetl plik

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "radio.hpp"
#include "system.hpp" #include "system.hpp"
#include "uv_k5_display.hpp" #include "uv_k5_display.hpp"
#include "radio.hpp"
typedef unsigned char u8; typedef unsigned char u8;
typedef signed short i16; typedef signed short i16;
@ -11,82 +11,71 @@ typedef unsigned int u32;
typedef signed long long i64; typedef signed long long i64;
typedef unsigned long long u64; typedef unsigned long long u64;
static constexpr auto operator""_Hz(u64 Hz) { return Hz / 10; } template <const System::TOrgFunctions &Fw, const System::TOrgData &FwData,
static constexpr auto operator""_KHz(u64 KHz) { return KHz * 1000_Hz; } Radio::CBK4819<Fw> &RadioDriver>
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>
class CSpectrum { class CSpectrum {
public: public:
static constexpr auto ExitKey = 13; static constexpr auto ExitKey = 13;
static constexpr auto DrawingSizeY = 16 + 6 * 8;
static constexpr auto DrawingEndY = 42; static constexpr auto DrawingEndY = 42;
static constexpr auto BarPos = 5 * 128; static constexpr auto BarPos = 5 * 128;
u8 rssiHistory[128] = {}; u8 rssiHistory[128] = {};
u8 measurementsCount = 32; u8 measurementsCount = 32;
u8 rssiMin = 255, rssiMax = 0; u8 rssiMin = 255;
u8 highestPeakX = 0; u8 highestPeakX = 0;
u8 highestPeakT = 0; u8 highestPeakT = 0;
u8 highestPeakRssi = 0; u8 highestPeakRssi = 0;
u32 highestPeakF = 0; u32 highestPeakF = 0;
u32 FStart, FEnd, fMeasure; u32 FStart;
CSpectrum() CSpectrum()
: DisplayBuff(FwData.pDisplayBuffer), FontSmallNr(FwData.pSmallDigs), : DisplayBuff(FwData.pDisplayBuffer), FontSmallNr(FwData.pSmallDigs),
Display(DisplayBuff), scanDelay(800), sampleZoom(2), scanStep(25_KHz), Display(DisplayBuff), scanDelay(800), sampleZoom(2), scanStep(25_KHz),
rssiTriggerLevel(65) { frequencyChangeStep(100_KHz), rssiTriggerLevel(65) {
Display.SetFont(&FontSmallNr); Display.SetFont(&FontSmallNr);
}; };
inline void Measure() { inline bool ListenPeak() {
if (highestPeakRssi >= rssiTriggerLevel) { if (highestPeakRssi < rssiTriggerLevel) {
// listen return false;
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;
} }
u8 rssi = 0; // measure peak for this moment
u8 xPeak = 64; highestPeakRssi = GetRssi(highestPeakF); // also sets freq for us
u32 fPeak = currentFreq; 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; rssiMin = 255;
rssiMax = 0;
fMeasure = FStart;
for (u8 i = 0; i < measurementsCount; ++i, fMeasure += scanStep) { for (u8 i = 0; i < measurementsCount; ++i, fMeasure += scanStep) {
rssi = rssiHistory[i] = GetRssi(fMeasure, scanDelay); rssi = rssiHistory[i] = GetRssi(fMeasure);
if (rssi < rssiMin) { if (rssi < rssiMin) {
rssiMin = rssi; rssiMin = rssi;
} }
if (rssi > rssiMax) { if (rssi > rssiMax) {
rssiMax = rssi; rssiMax = rssi;
fPeak = fMeasure; fPeak = fMeasure;
xPeak = i << sampleZoom; iPeak = i;
} }
} }
++highestPeakT; ++highestPeakT;
if (highestPeakT >= 8 || rssiMax > highestPeakRssi) { if (rssiMax > highestPeakRssi || highestPeakT >= (8 << sampleZoom)) {
highestPeakT = 0; highestPeakT = 0;
highestPeakRssi = rssiMax; highestPeakRssi = rssiMax;
highestPeakX = xPeak; highestPeakX = iPeak << sampleZoom;
highestPeakF = fPeak; highestPeakF = fPeak;
} }
} }
@ -98,25 +87,28 @@ public:
} }
inline void DrawNums() { inline void DrawNums() {
Display.SetCoursor(0, 0); Display.SetCoursorXY(0, 0);
Display.PrintFixedDigitsNumber2(scanDelay, 0); Display.PrintFixedDigitsNumber2(scanDelay, 0);
Display.SetCoursor(0, 8 * 2 + 5 * 7); Display.SetCoursorXY(51, 0);
Display.PrintFixedDigitsNumber2(scanStep << (7 - sampleZoom)); Display.PrintFixedDigitsNumber2(scanStep << (7 - sampleZoom));
Display.SetCoursor(1, 8 * 2 + 6 * 7); Display.SetCoursorXY(58, 8);
Display.PrintFixedDigitsNumber2(scanStep); Display.PrintFixedDigitsNumber2(scanStep);
Display.SetCoursor(1, 8 * 2 + 13 * 7); Display.SetCoursorXY(107, 8);
Display.PrintFixedDigitsNumber2(highestPeakRssi, 0); Display.PrintFixedDigitsNumber2(highestPeakRssi, 0);
Display.SetCoursor(0, 8 * 2 + 10 * 7); Display.SetCoursorXY(86, 0);
Display.PrintFixedDigitsNumber2(highestPeakF); Display.PrintFixedDigitsNumber2(highestPeakF);
Display.SetCoursor(6, 8 * 2 + 4 * 7); Display.SetCoursorXY(44, 48);
Display.PrintFixedDigitsNumber2(currentFreq); Display.PrintFixedDigitsNumber2(currentFreq);
Display.SetCoursor(1, 0); Display.SetCoursorXY(100, 48);
Display.PrintFixedDigitsNumber2(frequencyChangeStep);
Display.SetCoursorXY(0, 8);
Display.PrintFixedDigitsNumber2(rssiTriggerLevel, 0); Display.PrintFixedDigitsNumber2(rssiTriggerLevel, 0);
} }
@ -150,7 +142,7 @@ public:
} }
void HandleUserInput() { void HandleUserInput() {
switch (u8LastBtnPressed) { switch (lastButtonPressed) {
case 1: case 1:
UpdateScanDelay(200); UpdateScanDelay(200);
break; break;
@ -176,10 +168,16 @@ public:
UpdateScanStep(1); UpdateScanStep(1);
break; break;
case 11: // up case 11: // up
UpdateCurrentFreq(100_KHz); UpdateCurrentFreq(frequencyChangeStep);
break; break;
case 12: // down case 12: // down
UpdateCurrentFreq(-100_KHz); UpdateCurrentFreq(-frequencyChangeStep);
break;
case 14:
UpdateFreqChangeStep(100_KHz);
break;
case 15:
UpdateFreqChangeStep(-100_KHz);
break; break;
default: default:
isUserInput = false; isUserInput = false;
@ -198,7 +196,7 @@ public:
void Update() { void Update() {
if (bDisplayCleared) { if (bDisplayCleared) {
currentFreq = GetFrequency(); currentFreq = RadioDriver.GetFrequency();
OnUserInput(); OnUserInput();
u16OldAfSettings = Fw.BK4819Read(0x47); u16OldAfSettings = Fw.BK4819Read(0x47);
Fw.BK4819Write(0x47, 0); // mute AF during scan Fw.BK4819Write(0x47, 0); // mute AF during scan
@ -207,7 +205,8 @@ public:
HandleUserInput(); HandleUserInput();
Measure(); if (!ListenPeak())
Scan();
} }
void UpdateRssiTriggerLevel(i32 diff) { void UpdateRssiTriggerLevel(i32 diff) {
@ -241,11 +240,15 @@ public:
OnUserInput(); OnUserInput();
} }
void UpdateFreqChangeStep(i64 diff) {
frequencyChangeStep = clamp(frequencyChangeStep + diff, 100_KHz, 2_MHz);
OnUserInput();
}
inline void OnUserInput() { inline void OnUserInput() {
isUserInput = true; isUserInput = true;
u32 halfOfScanRange = scanStep << (6 - sampleZoom); u32 halfOfScanRange = scanStep << (6 - sampleZoom);
FStart = currentFreq - halfOfScanRange; FStart = currentFreq - halfOfScanRange;
FEnd = currentFreq + halfOfScanRange;
// reset peak // reset peak
highestPeakT = 0; highestPeakT = 0;
@ -253,7 +256,7 @@ public:
highestPeakX = 64; highestPeakX = 64;
highestPeakF = currentFreq; highestPeakF = currentFreq;
Fw.DelayUs(90_ms); Fw.DelayUs(90000);
} }
void Handle() { void Handle() {
@ -269,8 +272,8 @@ public:
return; return;
} }
u8LastBtnPressed = Fw.PollKeyboard(); lastButtonPressed = Fw.PollKeyboard();
if (u8LastBtnPressed == ExitKey) { if (lastButtonPressed == ExitKey) {
working = false; working = false;
RestoreParams(); RestoreParams();
return; return;
@ -285,28 +288,26 @@ private:
bDisplayCleared = true; bDisplayCleared = true;
DisplayBuff.ClearAll(); DisplayBuff.ClearAll();
Fw.FlushFramebufferToScreen(); Fw.FlushFramebufferToScreen();
SetFrequency(currentFreq); RadioDriver.SetFrequency(currentFreq);
Fw.BK4819Write(0x47, u16OldAfSettings); // set previous AF settings Fw.BK4819Write(0x47, u16OldAfSettings); // set previous AF settings
} }
} }
void SetFrequency(u32 f) { inline void Listen(u32 duration) {
Fw.BK4819Write(0x39, (f >> 16) & 0xFFFF); Fw.BK4819Write(0x47, u16OldAfSettings);
Fw.BK4819Write(0x38, f & 0xFFFF); for (u8 i = 0; i < 16 && lastButtonPressed == 255; ++i) {
Fw.BK4819Write(0x30, 0); lastButtonPressed = Fw.PollKeyboard();
Fw.BK4819Write(0x30, 0xbff1); Fw.DelayUs(duration >> 4);
}
Fw.BK4819Write(0x47, 0);
} }
u8 GetRssi(u32 f, u32 delay = 800) { u8 GetRssi(u32 f) {
SetFrequency(f); RadioDriver.SetFrequency(f);
Fw.DelayUs(delay); Fw.DelayUs(scanDelay);
return Fw.BK4819Read(0x67); return Fw.BK4819Read(0x67);
} }
u32 GetFrequency() {
return (Fw.BK4819Read(0x39) << 16) | Fw.BK4819Read(0x38);
}
inline bool IsFlashLightOn() { return GPIOC->DATA & GPIO_PIN_3; } inline bool IsFlashLightOn() { return GPIOC->DATA & GPIO_PIN_3; }
inline void TurnOffFlashLight() { inline void TurnOffFlashLight() {
GPIOC->DATA &= ~GPIO_PIN_3; GPIOC->DATA &= ~GPIO_PIN_3;
@ -335,13 +336,14 @@ private:
const TUV_K5SmallNumbers FontSmallNr; const TUV_K5SmallNumbers FontSmallNr;
CDisplay<const TUV_K5Display> Display; CDisplay<const TUV_K5Display> Display;
u8 u8LastBtnPressed; u8 lastButtonPressed;
u32 currentFreq; u32 currentFreq;
u16 u16OldAfSettings; u16 u16OldAfSettings;
u16 scanDelay; u16 scanDelay;
u8 sampleZoom; u8 sampleZoom;
u32 scanStep; u32 scanStep;
u32 frequencyChangeStep;
u8 rssiTriggerLevel; u8 rssiTriggerLevel;
bool working = false; bool working = false;