fix for spectrum scanner, added possibility to switch center freq and peak printing

pull/16/head
Piotr Lewandowski 2023-07-06 20:25:23 +02:00
rodzic fc0a057248
commit 94ce3e5059
9 zmienionych plików z 154 dodań i 34 usunięć

Wyświetl plik

@ -6,15 +6,14 @@ sbar with calibrated S steps
* flash with original quansheng update tool
Please, consider paying tribute to the two fallen Quashengs that were bricked during the development process. Their sacrifice played a crucial role in shaping this project. To show your appreciation and support for our ongoing work, you can make a [donation](https://paypal.me/sq9p).
## src/spectrum ![auto release build](https://github.com/piotr022/UV_K5_playground/actions/workflows/c-cpp.yml/badge.svg)
![rssi printer](./docs/spectrum.png)
It's still in beta. It prints a spectrum graph that covers +/- 1 MHz from the center frequency. Overall, it prints 2 MHz of the band.
Spectrum scanner. It prints a spectrum graph that covers +/- 1 MHz from the center frequency. Prints center frequency, and frequency with highest amplitude.
* download mod [uv_k5_01_26_spectrum_2MHz_encoded.bin](https://github.com/piotr022/UV_K5_playground/releases/latest)
* to enable spectum view press flash light button
* (optional) turn down the volume
* to disable, power off radio xD
* use *up* and *down* key to change center frequency
* press PTT to disable spectrum view
## src/rssi_printer ![auto release build](https://github.com/piotr022/UV_K5_playground/actions/workflows/c-cpp.yml/badge.svg)
![rssi printer](./docs/rssi_printer.png)

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 190 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 53 KiB

Wyświetl plik

@ -4,6 +4,18 @@ namespace System
using VoidFxPointer = void(*)(void);
static constexpr auto CortexM0VectorsCnt = 16+32;
struct TCortexM0Stacking
{
unsigned int R0;
unsigned int R1;
unsigned int R2;
unsigned int R3;
unsigned int R12;
unsigned int LR;
unsigned int PC;
unsigned int xPSR;
};
struct TVectorTable
{
VoidFxPointer Vectors[CortexM0VectorsCnt];

Wyświetl plik

@ -201,24 +201,71 @@ public:
memset(U8NumBuff, 0, sizeof(U8NumBuff));
char *pString = U8NumBuff + u8Digts;
*pString = '\0';
*pString = '\0';
if (s32Number < 0)
{
U8NumBuff[0] = '-';
s32Number = -s32Number;
s32Number = -s32Number;
}
while (u8Digts--)
{
*--pString = '0' + (s32Number % 10);
s32Number /= 10;
*--pString = '0' + (s32Number % 10);
s32Number /= 10;
}
Print(U8NumBuff);
return u8Digts * pCurrentFont->GetSizeX('0');
}
static constexpr int powersOfTen[9] = {
1, // 10^0
10, // 10^1
100, // 10^2
1000, // 10^3
10000, // 10^4
100000, // 10^5
1000000, // 10^6
10000000, // 10^7
100000000 // 10^8
};
void PrintFixedDigitsNumber2(int s32Number)
{
char U8NumBuff[11] = {0}; // 9 digits, sign, and null terminator
int startIdx = 0;
bool isNegative = false;
if (s32Number < 0)
{
U8NumBuff[0] = '-';
s32Number = -s32Number;
isNegative = true;
}
for (int i = 8; i >= 2; --i) // assuming powersOfTen is an array of powers of 10
{
int digit = 0;
while (s32Number >= powersOfTen[i])
{
s32Number -= powersOfTen[i];
++digit;
}
U8NumBuff[isNegative + (8 - i)] = '0' + digit;
// We found the first non-zero digit
if (digit != 0 && startIdx == (isNegative ? 1 : 0))
startIdx = isNegative + (8 - i);
}
// If the number was 0, we write a single 0.
if (startIdx == (isNegative ? 1 : 0))
U8NumBuff[isNegative] = '0';
// Print the string from the start index
Print(U8NumBuff + startIdx);
}
private:
const BitmapType &Bitmap;
mutable const IFont *pCurrentFont;

Wyświetl plik

@ -13,7 +13,7 @@ int main()
{
System::JumpToOrginalFw();
return 0;
}
}
void MultiIrq_Handler(unsigned int u32IrqSource)
{

Wyświetl plik

@ -26,7 +26,7 @@ void MultiIrq_Handler(unsigned int u32IrqSource)
}
static unsigned int u32StupidCounter = 1;
if((!(u32StupidCounter++ % 15) && u32StupidCounter > 200)) // exit key
if((!(u32StupidCounter++ % 10) && u32StupidCounter > 200)) // exit key
{
CRssiPrinter::Handle(Fw, FwData);
}

Wyświetl plik

@ -154,6 +154,7 @@ public:
Display.SetCoursor(3, 5 * 7 + 8);
Display.Print(C8SignalString);
u8BlocksToFill = u8BlocksToFill > 13 ? 13 : u8BlocksToFill;
for (unsigned char i = 0; i < u8BlocksToFill; i++)
{
unsigned char u8BlockHeight = i + 1 > BlockSizeY ? BlockSizeY : i + 1;
@ -161,11 +162,7 @@ public:
Display.DrawRectangle(u8X, 24 + BlockSizeY - u8BlockHeight, BlockSizeX,
u8BlockHeight, i < LinearBlocksCnt);
}
// Turn the proper pixel on, and the ones below it on as well
// The code to turn just the correct pixel on is: U8ScreenHistory[u8ChartPosition - ChartStartX] = (1 << u8PrintShift) & 0xFF;
// U8ScreenHistory[u8ChartPosition - ChartStartX] = ~(0xFF >> (7 - u8PrintShift));
// memcpy(pDData, FwData.pSmallLeters, 256 * 2);
Fw.FlushFramebufferToScreen();
}
};

Wyświetl plik

@ -19,6 +19,10 @@ int main()
void MultiIrq_Handler(unsigned int u32IrqSource)
{
unsigned int u32Dummy;
System::TCortexM0Stacking* pStackedRegs =
(System::TCortexM0Stacking*)(((unsigned int*)&u32Dummy) + 1);
static bool bFirstInit = false;
if(!bFirstInit)
{
@ -27,8 +31,11 @@ void MultiIrq_Handler(unsigned int u32IrqSource)
bFirstInit = true;
}
bool bPreventWhileKeypadPolling = pStackedRegs->LR > (unsigned int)Fw.PollKeyboard &&
pStackedRegs->PC < (unsigned int)Fw.PollKeyboard + 0x100; // i made a mistake and compared PC and LR, but this works fine xD
static unsigned int u32StupidCounter = 1;
if(u32StupidCounter++ > 200)
if(u32StupidCounter++ > 200 && !bPreventWhileKeypadPolling)
{
Spectrum.Handle();
}

Wyświetl plik

@ -28,18 +28,24 @@ public:
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;
static constexpr auto DrawingEndY = 32;
static constexpr auto DrawingSizeY = 16 + 4 * 8;
static constexpr auto DrawingEndY = 57;
static constexpr auto LabelsCnt = 6;
static constexpr auto PressDuration = 30;
CSpectrum()
: DisplayBuff(FwData.pDisplayBuffer),
FontSmallNr(FwData.pSmallDigs),
Display(DisplayBuff),
bDisplayCleared(true){};
bDisplayCleared(true),
u8PressCnt(0),
bEnabled(0)
{
Display.SetFont(&FontSmallNr);
};
void Handle()
{
if ((GPIOA->DATA & ((1 << 0xA) | (1 << 0xB) | (1 << 0xC) | (1 << 0xD))) || !(GPIOC->DATA & 0b1))
if (!(GPIOC->DATA & 0b1))
{
return;
}
@ -66,23 +72,53 @@ public:
}
bDisplayCleared = false;
if (u8LastBtnPressed == 11) // up
{
u32OldFreq += 100_KHz;
}
else if (u8LastBtnPressed == 12) // down
{
u32OldFreq -= 100_KHz;
}
ClearDrawings();
unsigned int u32Peak;
unsigned char u8MaxRssi = 0;
unsigned char u8PeakPos;
for (unsigned char u8Pos = 0; u8Pos < DisplayBuff.SizeX; u8Pos++)
{
if (!(u8Pos % (DisplayBuff.SizeX / LabelsCnt)))
{
Display.DrawHLine(16, 18, u8Pos);
Display.DrawHLine(10, 15, u8Pos);
}
auto const FreqOffset = u8Pos * ScanRange / (DisplayBuff.SizeX - 1);
auto const Rssi = GetRssi(u32OldFreq - (ScanRange / 2) + FreqOffset);
signed char u8Sub = ((Rssi * 120) >> 7) - 12;
auto const FreqOffset = (u8Pos * ScanRange) >> 7;
auto const Rssi = GetRssi(u32OldFreq - (ScanRange >> 1) + FreqOffset);
signed char u8Sub = ((Rssi * 200) >> 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 - (ScanRange >> 1) + FreqOffset;
}
}
// Display.DrawRectangle(0,0, 7, 7, 0);
memcpy(FwData.pDisplayBuffer + 8 * 2 + 10 * 6, FwData.pSmallLeters + 18 + 5, 7);
Display.SetCoursor(0, 0);
Display.PrintFixedDigitsNumber2(u32OldFreq);
// 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();
}
@ -112,24 +148,43 @@ private:
bool FreeToDraw()
{
bool bLedKey = GPIOA->DATA & GPIO_PIN_3; // Fw.PollKeyboard(); keyboard polling causes many problems probably it disrupt main fw polling procedure
auto *pMenuCheckData = (unsigned char *)DisplayBuff.GetCoursorData(
DisplayBuff.GetCoursorPosition(1, 6 * 8 + 1));
unsigned char u8Keyboard = 0;
if (bLedKey)
bool bFlashlight = (GPIOC->DATA & GPIO_PIN_3);
if (bFlashlight)
{
u8Keyboard = Fw.PollKeyboard();
bEnabled = true;
GPIOC->DATA &= ~GPIO_PIN_3;
}
return bLedKey && *pMenuCheckData != 0xFF && u8Keyboard != EnableKey;
bool bPtt = !(GPIOC->DATA & GPIO_PIN_5);
if(bPtt)
{
bEnabled = false;
}
if(bEnabled)
{
u8LastBtnPressed = Fw.PollKeyboard();
}
// u8LastBtnPressed = Fw.PollKeyboard();
// if (u8LastBtnPressed == EnableKey)
// {
// u8PressCnt++;
// }
// if (u8PressCnt > (bEnabled ? 3 : PressDuration))
// {
// u8PressCnt = 0;
// bEnabled = !bEnabled;
// }
return bEnabled;
}
void ClearDrawings()
{
auto *p8Drw = (unsigned char *)DisplayBuff.GetCoursorData(
DisplayBuff.GetCoursorPosition(2, 0));
memset(p8Drw, 0, DrawingSize);
memset(FwData.pDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY);
}
TUV_K5Display DisplayBuff;
@ -139,4 +194,7 @@ private:
unsigned int u32OldFreq;
unsigned short u16OldAfSettings;
unsigned char u8PressCnt;
bool bEnabled;
unsigned char u8LastBtnPressed;
};