kopia lustrzana https://github.com/piotr022/UV_K5_playground
219 wiersze
5.7 KiB
C++
219 wiersze
5.7 KiB
C++
#pragma once
|
|
#include "system.hpp"
|
|
#include "uv_k5_display.hpp"
|
|
|
|
#define REVERSE_UINT16(x) ((((x)&0xFF00) >> 8) | (((x)&0x00FF) << 8))
|
|
|
|
static constexpr auto operator""_Hz(unsigned long long Hertz)
|
|
{
|
|
return Hertz / 10;
|
|
}
|
|
|
|
static constexpr auto operator""_KHz(unsigned long long KiloHertz)
|
|
{
|
|
return KiloHertz * 1000_Hz;
|
|
}
|
|
|
|
static constexpr auto operator""_MHz(unsigned long long KiloHertz)
|
|
{
|
|
return KiloHertz * 1000_KHz;
|
|
}
|
|
|
|
template <const System::TOrgFunctions &Fw, const System::TOrgData &FwData>
|
|
class CSpectrum
|
|
{
|
|
public:
|
|
static constexpr auto StepSize = 0xFFFF / TUV_K5Display::SizeX;
|
|
static constexpr auto StepSizeFreq = 10'000;
|
|
static constexpr unsigned char EnableKey = 13;
|
|
static constexpr auto DrawingSize = TUV_K5Display::SizeX * 2;
|
|
static constexpr auto DrawingSizeY = 16 + 4 * 8;
|
|
static constexpr auto DrawingEndY = 57;
|
|
static constexpr auto LabelsCnt = 4;
|
|
static constexpr auto PressDuration = 30;
|
|
static constexpr auto BWStep = 200_KHz;
|
|
CSpectrum()
|
|
: DisplayBuff(FwData.pDisplayBuffer),
|
|
FontSmallNr(FwData.pSmallDigs),
|
|
Display(DisplayBuff),
|
|
bDisplayCleared(true),
|
|
u32ScanRange(1_MHz),
|
|
u8PressCnt(0),
|
|
u8ResolutionDiv(1),
|
|
bEnabled(0)
|
|
{
|
|
Display.SetFont(&FontSmallNr);
|
|
};
|
|
|
|
void Handle()
|
|
{
|
|
if (!(GPIOC->DATA & 0b1))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!FreeToDraw())
|
|
{
|
|
if (!bDisplayCleared)
|
|
{
|
|
bDisplayCleared = true;
|
|
ClearDrawings();
|
|
Fw.FlushFramebufferToScreen();
|
|
SetFrequency(u32OldFreq);
|
|
Fw.BK4819Write(0x47, u16OldAfSettings); // set previous AF settings
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (bDisplayCleared)
|
|
{
|
|
u32OldFreq = GetFrequency();
|
|
u16OldAfSettings = Fw.BK4819Read(0x47);
|
|
Fw.BK4819Write(0x47, 0); // mute AF during scan
|
|
}
|
|
|
|
bDisplayCleared = false;
|
|
switch (u8LastBtnPressed)
|
|
{
|
|
case 11: // up
|
|
u32OldFreq += 100_KHz;
|
|
break;
|
|
|
|
case 12: // down
|
|
u32OldFreq -= 100_KHz;
|
|
break;
|
|
|
|
case 2: // bw up
|
|
u32ScanRange += BWStep;
|
|
break;
|
|
|
|
case 8: // bw down
|
|
u32ScanRange -= u32ScanRange > BWStep ? BWStep : 0;
|
|
break;
|
|
|
|
case 1: // res up
|
|
u8ResolutionDiv++;
|
|
break;
|
|
|
|
case 7: // res down
|
|
if (u8ResolutionDiv)
|
|
u8ResolutionDiv--;
|
|
break;
|
|
}
|
|
|
|
ClearDrawings();
|
|
|
|
unsigned int u32Peak;
|
|
unsigned char u8MaxRssi = 0;
|
|
unsigned char u8PeakPos;
|
|
unsigned char Rssi = 0;
|
|
for (unsigned char u8Pos = 0; u8Pos < DisplayBuff.SizeX; u8Pos++)
|
|
{
|
|
if (!(u8Pos % (DisplayBuff.SizeX / LabelsCnt)) || u8Pos == DisplayBuff.SizeX - 1)
|
|
{
|
|
*(FwData.pDisplayBuffer + 2 * DisplayBuff.SizeX + u8Pos) = 0xFF;
|
|
}
|
|
|
|
auto const FreqOffset = (u8Pos * u32ScanRange) >> 7;
|
|
if (!u8Pos || (u8Pos & u8ResolutionDiv) == u8ResolutionDiv)
|
|
{
|
|
Rssi = GetRssi(u32OldFreq - (u32ScanRange >> 1) + FreqOffset);
|
|
}
|
|
|
|
signed char u8Sub = ((Rssi * 250) >> 7) - 20;
|
|
u8Sub = (u8Sub > DrawingSizeY ? DrawingSizeY : u8Sub);
|
|
u8Sub = (u8Sub < 0 ? 0 : u8Sub);
|
|
Display.DrawHLine(DrawingEndY - u8Sub, DrawingEndY, u8Pos);
|
|
|
|
if (Rssi > u8MaxRssi)
|
|
{
|
|
u8MaxRssi = Rssi;
|
|
u8PeakPos = u8Pos;
|
|
u32Peak = u32OldFreq - (u32ScanRange >> 1) + FreqOffset;
|
|
}
|
|
}
|
|
// Display.DrawRectangle(0,0, 7, 7, 0);
|
|
memcpy(FwData.pDisplayBuffer + 8 * 2 + 10 * 6 + 2, FwData.pSmallLeters + 18 + 5, 7);
|
|
Display.SetCoursor(0, 0);
|
|
Display.PrintFixedDigitsNumber2(u32OldFreq);
|
|
Display.SetCoursor(1, 0);
|
|
Display.PrintFixedDigitsNumber2(u32ScanRange, 2);
|
|
// Display.SetCoursor(1, 8 * 2 + 10 * 7);
|
|
// Display.PrintFixedDigitsNumber2(u8ResolutionDiv, 0);
|
|
|
|
// Display.DrawRectangle(8*2 + 10*6,0, 7, 7, 0);
|
|
Display.SetCoursor(0, 8 * 2 + 10 * 7);
|
|
Display.PrintFixedDigitsNumber2(u32Peak);
|
|
|
|
memcpy(FwData.pDisplayBuffer + 128 * 2 + u8PeakPos - 3, FwData.pSmallLeters + 18 + 5, 7);
|
|
Fw.FlushFramebufferToScreen();
|
|
}
|
|
|
|
private:
|
|
void SetFrequency(unsigned int u32Freq)
|
|
{
|
|
Fw.BK4819Write(0x39, ((u32Freq >> 16) & 0xFFFF));
|
|
Fw.BK4819Write(0x38, (u32Freq & 0xFFFF));
|
|
// Fw.BK4819Write(0x37,7951);
|
|
Fw.BK4819Write(0x30, 0);
|
|
Fw.BK4819Write(0x30, 0xbff1);
|
|
}
|
|
|
|
unsigned char GetRssi(unsigned int u32Freq)
|
|
{
|
|
SetFrequency(u32Freq);
|
|
Fw.DelayUs(800);
|
|
return ((Fw.BK4819Read(0x67) >> 1) & 0xFF);
|
|
}
|
|
|
|
unsigned int GetFrequency()
|
|
{
|
|
unsigned short u16f1 = Fw.BK4819Read(0x39);
|
|
unsigned short u16f2 = Fw.BK4819Read(0x38);
|
|
return ((u16f1 << 16) | u16f2);
|
|
}
|
|
|
|
bool FreeToDraw()
|
|
{
|
|
bool bFlashlight = (GPIOC->DATA & GPIO_PIN_3);
|
|
if (bFlashlight)
|
|
{
|
|
bEnabled = true;
|
|
GPIOC->DATA &= ~GPIO_PIN_3;
|
|
*FwData.p8FlashLightStatus = 3;
|
|
}
|
|
|
|
if (bEnabled)
|
|
{
|
|
u8LastBtnPressed = Fw.PollKeyboard();
|
|
}
|
|
|
|
bool bPtt = !(GPIOC->DATA & GPIO_PIN_5);
|
|
if (bPtt || u8LastBtnPressed == EnableKey)
|
|
{
|
|
bEnabled = false;
|
|
}
|
|
|
|
return bEnabled;
|
|
}
|
|
|
|
void ClearDrawings()
|
|
{
|
|
memset(FwData.pDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY);
|
|
}
|
|
|
|
TUV_K5Display DisplayBuff;
|
|
const TUV_K5SmallNumbers FontSmallNr;
|
|
CDisplay<const TUV_K5Display> Display;
|
|
bool bDisplayCleared;
|
|
|
|
unsigned int u32ScanRange;
|
|
unsigned int u32OldFreq;
|
|
unsigned short u16OldAfSettings;
|
|
unsigned char u8PressCnt;
|
|
unsigned char u8LastBtnPressed;
|
|
unsigned char u8ResolutionDiv;
|
|
bool bEnabled;
|
|
char C8Info[20];
|
|
}; |