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;
}
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;
};
};

Wyświetl plik

@ -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
}
}
};
}
}

Wyświetl plik

@ -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;