kopia lustrzana https://github.com/piotr022/UV_K5_playground
rssi_sbar added printing MIC IN amplitude during TX, fixes with batt voltage display
rodzic
90a1eea584
commit
2d48467914
|
@ -26,7 +26,7 @@ Spectrum scanner. It prints a spectrum graph. Zoom in well as resolution can be
|
|||
|
||||
## src/rssi_sbar ![auto release build](https://github.com/piotr022/UV_K5_playground/actions/workflows/c-cpp.yml/badge.svg)
|
||||
![rssi printer](./docs/rssi_sbar.png)
|
||||
sbar with calibrated S steps
|
||||
sbar with calibrated S steps, on TX prints mic in amplitude
|
||||
* download mod [uv_k5_01_26_rssi_sbar_encoded.bin](https://github.com/piotr022/UV_K5_playground/releases/latest)
|
||||
* flash with original quansheng update tool
|
||||
|
||||
|
|
|
@ -229,9 +229,10 @@ public:
|
|||
|
||||
if (s32Number < 0)
|
||||
{
|
||||
U8NumBuff[0] = '-';
|
||||
PrintCharacter('-');
|
||||
// U8NumBuff[0] = '-';
|
||||
s32Number = -s32Number;
|
||||
isNegative = true;
|
||||
// isNegative = true;
|
||||
}
|
||||
|
||||
for (int i = 8; i >= u8DigsToCut; --i) // assuming powersOfTen is an array of powers of 10
|
||||
|
|
|
@ -63,6 +63,22 @@ namespace Radio
|
|||
return (Fw.BK4819Read(0x39) << 16) | Fw.BK4819Read(0x38);
|
||||
}
|
||||
|
||||
signed short GetRssi()
|
||||
{
|
||||
short s16Rssi = ((Fw.BK4819Read(0x67) >> 1) & 0xFF);
|
||||
return s16Rssi - 160;
|
||||
}
|
||||
|
||||
bool IsSqlOpen()
|
||||
{
|
||||
return Fw.BK4819Read(0x0C) & 0b10;
|
||||
}
|
||||
|
||||
unsigned char GetAFAmplitude()
|
||||
{
|
||||
return 0b111111 - (Fw.BK4819Read(0x6F) & 0b111111);
|
||||
}
|
||||
|
||||
void SendSyncAirCopyMode72(unsigned char *p8Data)
|
||||
{
|
||||
Fw.BK4819ConfigureAndStartTxFsk();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
#include "system.hpp"
|
||||
#include "uv_k5_display.hpp"
|
||||
#include "radio.hpp"
|
||||
#include "registers.hpp"
|
||||
|
||||
namespace Rssi
|
||||
{
|
||||
|
@ -23,12 +25,15 @@ namespace Rssi
|
|||
|
||||
struct TRssi
|
||||
{
|
||||
TRssi(unsigned char u8Val)
|
||||
TRssi(){};
|
||||
TRssi(signed short s16Rssi)
|
||||
:s16Rssi(s16Rssi)
|
||||
{
|
||||
s16Rssi *= -1;
|
||||
unsigned char i;
|
||||
for (i = 0; i < sizeof(U8RssiMap); i++)
|
||||
{
|
||||
if (u8Val >= U8RssiMap[i])
|
||||
if (s16Rssi >= U8RssiMap[i])
|
||||
{
|
||||
u8SValue = i + 1;
|
||||
return;
|
||||
|
@ -37,6 +42,7 @@ namespace Rssi
|
|||
u8SValue = i + 1;
|
||||
}
|
||||
|
||||
short s16Rssi;
|
||||
unsigned char u8SValue;
|
||||
};
|
||||
}
|
||||
|
@ -46,7 +52,9 @@ template <
|
|||
const System::TOrgData &FwData,
|
||||
TUV_K5Display &DisplayBuff,
|
||||
CDisplay<TUV_K5Display> &Display,
|
||||
const TUV_K5SmallNumbers &FontSmallNr>
|
||||
CDisplay<TUV_K5Display> &DisplayStatusBar,
|
||||
const TUV_K5SmallNumbers &FontSmallNr,
|
||||
Radio::CBK4819<Fw> &RadioDriver>
|
||||
class CRssiSbar : public IView
|
||||
{
|
||||
public:
|
||||
|
@ -57,133 +65,20 @@ public:
|
|||
static constexpr auto BlocksCnt = (128 - ChartStartX) / (BlockSizeX + BlockSpace);
|
||||
static constexpr auto LinearBlocksCnt = 9;
|
||||
static constexpr auto VoltageOffset = 77;
|
||||
// eScreenRefreshFlag HandleBackground(TViewContext &Context) override
|
||||
// {
|
||||
// static bool bIsCleared = true;
|
||||
// static unsigned char u8SqlDelayCnt = 0xFF;
|
||||
static constexpr auto MaxBarPoints = 13;
|
||||
static inline unsigned char *const pDData = FwData.pDisplayBuffer + 128 * 3;
|
||||
|
||||
// // TUV_K5Display StatusBarBuff(FwData.pStatusBarData);
|
||||
// // CDisplay<TUV_K5Display> DisplayStatusBar(StatusBarBuff);
|
||||
// // DisplayStatusBar.SetFont(&FontSmallNr);
|
||||
|
||||
// if (Context.OriginalFwStatus.b1RadioSpiCommInUse)
|
||||
// {
|
||||
// return eScreenRefreshFlag::NoRefresh;
|
||||
// }
|
||||
unsigned int u32DrawVoltagePsc = 0;
|
||||
Rssi::TRssi RssiData;
|
||||
unsigned char u8AfAmp = 0;
|
||||
bool bPtt = false;
|
||||
|
||||
// // static unsigned int u32DrawVoltagePsc = 0;
|
||||
// // if (u32DrawVoltagePsc++ % 16)
|
||||
// // {
|
||||
// // memset(FwData.pStatusBarData + VoltageOffset, 0, 4 * 5);
|
||||
// // DisplayStatusBar.SetCoursor(0, VoltageOffset);
|
||||
// // DisplayStatusBar.PrintFixedDigitsNumber2(*FwData.p16Voltage, 2, 1);
|
||||
// // memset(FwData.pStatusBarData + VoltageOffset + 7 + 1, 0b1100000, 2); // dot
|
||||
// // DisplayStatusBar.SetCoursor(0, VoltageOffset + 7 + 4);
|
||||
// // DisplayStatusBar.PrintFixedDigitsNumber2(*FwData.p16Voltage, 0, 2);
|
||||
// // memcpy(FwData.pStatusBarData + VoltageOffset + 4 * 6 + 2, FwData.pSmallLeters + 128 * 2 + 102, 5); // V character
|
||||
// // Fw.FlushStatusbarBufferToScreen();
|
||||
// // }
|
||||
|
||||
// if (Fw.BK4819Read(0x0C) & 0b10)
|
||||
// {
|
||||
// u8SqlDelayCnt = 0;
|
||||
// }
|
||||
|
||||
// auto *pDData = (unsigned char *)DisplayBuff.GetCoursorData(DisplayBuff.GetCoursorPosition(3, 0));
|
||||
// if (u8SqlDelayCnt > 20 || Context.OriginalFwStatus.b1MenuDrawed)
|
||||
// {
|
||||
// if (!bIsCleared)
|
||||
// {
|
||||
// bIsCleared = true;
|
||||
// memset(pDData, 0, DisplayBuff.SizeX);
|
||||
// if (!Context.OriginalFwStatus.b1MenuDrawed)
|
||||
// {
|
||||
// return eScreenRefreshFlag::MainScreen;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return eScreenRefreshFlag::NoRefresh;
|
||||
// }
|
||||
|
||||
// u8SqlDelayCnt++;
|
||||
// bIsCleared = false;
|
||||
|
||||
// memset(pDData, 0, DisplayBuff.SizeX);
|
||||
|
||||
// Display.SetCoursor(3, 0);
|
||||
// Display.SetFont(&FontSmallNr);
|
||||
|
||||
// char C8RssiString[] = "g000";
|
||||
// unsigned char u8Rssi = ((Fw.BK4819Read(0x67) >> 1) & 0xFF);
|
||||
// if (!u8Rssi)
|
||||
// {
|
||||
// return eScreenRefreshFlag::NoRefresh;
|
||||
// }
|
||||
|
||||
// if (u8Rssi > 160)
|
||||
// {
|
||||
// u8Rssi -= 160;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// u8Rssi = 160 - u8Rssi;
|
||||
// C8RssiString[0] = '-';
|
||||
// }
|
||||
|
||||
// u8Rssi += 10;
|
||||
// unsigned char u8RssiCpy = u8Rssi;
|
||||
// unsigned char hundreds = 0;
|
||||
// while (u8RssiCpy >= 100)
|
||||
// {
|
||||
// hundreds++;
|
||||
// u8RssiCpy -= 100;
|
||||
// }
|
||||
|
||||
// unsigned char tens = 0;
|
||||
// while (u8RssiCpy >= 10)
|
||||
// {
|
||||
// tens++;
|
||||
// u8RssiCpy -= 10;
|
||||
// }
|
||||
|
||||
// C8RssiString[1] = '0' + hundreds;
|
||||
// C8RssiString[2] = '0' + tens;
|
||||
// C8RssiString[3] = '0' + u8RssiCpy;
|
||||
// Display.Print(C8RssiString);
|
||||
|
||||
// unsigned char u8Sub = (u8Rssi * BlocksCnt) >> 7;
|
||||
// unsigned char u8BlocksToFill = (u8Sub > BlocksCnt ? BlocksCnt : u8Sub);
|
||||
// u8BlocksToFill = Rssi::TRssi(u8Rssi).u8SValue;
|
||||
|
||||
// char C8SignalString[] = " ";
|
||||
|
||||
// if (u8BlocksToFill > 9)
|
||||
// {
|
||||
// memcpy(pDData + 5 * 7, FwData.pSmallLeters + 109 - 3 * 8, 8);
|
||||
// C8SignalString[1] = '0';
|
||||
// C8SignalString[0] = '0' + u8BlocksToFill - 9;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// memcpy(pDData + 5 * 7, FwData.pSmallLeters + 109, 8);
|
||||
// C8SignalString[0] = '0' + u8BlocksToFill;
|
||||
// C8SignalString[1] = ' ';
|
||||
// }
|
||||
|
||||
// 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;
|
||||
// unsigned char u8X = i * (BlockSizeX + BlockSpace) + ChartStartX;
|
||||
// Display.DrawRectangle(u8X, 24 + BlockSizeY - u8BlockHeight, BlockSizeX,
|
||||
// u8BlockHeight, i < LinearBlocksCnt);
|
||||
// }
|
||||
|
||||
// return eScreenRefreshFlag::MainScreen;
|
||||
// }
|
||||
CRssiSbar()
|
||||
{
|
||||
Display.SetFont(&FontSmallNr);
|
||||
DisplayStatusBar.SetFont(&FontSmallNr);
|
||||
}
|
||||
|
||||
eScreenRefreshFlag HandleBackground(TViewContext &Context) override
|
||||
{
|
||||
|
@ -195,13 +90,13 @@ public:
|
|||
return eScreenRefreshFlag::NoRefresh;
|
||||
}
|
||||
|
||||
if (Fw.BK4819Read(0x0C) & 0b10)
|
||||
bPtt = !(GPIOC->DATA & GPIO_PIN_5);
|
||||
if (RadioDriver.IsSqlOpen() || bPtt)
|
||||
{
|
||||
u8SqlDelayCnt = 0;
|
||||
}
|
||||
|
||||
unsigned char *pDData = FwData.pDisplayBuffer + 128 * 3;
|
||||
if (u8SqlDelayCnt > 20 || Context.OriginalFwStatus.b1MenuDrawed)
|
||||
if (u8SqlDelayCnt > 10 || Context.OriginalFwStatus.b1MenuDrawed)
|
||||
{
|
||||
if (!bIsCleared)
|
||||
{
|
||||
|
@ -219,76 +114,110 @@ public:
|
|||
u8SqlDelayCnt++;
|
||||
bIsCleared = false;
|
||||
|
||||
memset(pDData, 0, DisplayBuff.SizeX);
|
||||
|
||||
Display.SetCoursor(3, 0);
|
||||
Display.SetFont(&FontSmallNr);
|
||||
|
||||
short u8Rssi = (Fw.BK4819Read(0x67) & 0xFF);
|
||||
if (!u8Rssi)
|
||||
if (Context.ViewStack.GetTop() || !(u32DrawVoltagePsc++ % 8))
|
||||
{
|
||||
return eScreenRefreshFlag::NoRefresh;
|
||||
PrintBatteryVoltage();
|
||||
return eScreenRefreshFlag::StatusBar;
|
||||
}
|
||||
|
||||
if (u8Rssi > 160)
|
||||
if(bPtt)
|
||||
{
|
||||
u8Rssi -= 160;
|
||||
RssiData.s16Rssi = RadioDriver.GetAFAmplitude();
|
||||
RssiData.u8SValue = (MaxBarPoints * RssiData.s16Rssi) >> 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8Rssi = 160 - u8Rssi;
|
||||
Display.Print("-");
|
||||
RssiData = RadioDriver.GetRssi();
|
||||
}
|
||||
|
||||
u8Rssi += 10;
|
||||
unsigned char u8RssiCpy = u8Rssi;
|
||||
unsigned char hundreds = 0;
|
||||
while (u8RssiCpy >= 100)
|
||||
ProcessDrawings();
|
||||
return eScreenRefreshFlag::MainScreen;
|
||||
}
|
||||
|
||||
void ProcessDrawings()
|
||||
{
|
||||
ClearSbarLine();
|
||||
|
||||
PrintNumber(RssiData.s16Rssi);
|
||||
PrintSValue(RssiData.u8SValue);
|
||||
PrintSbar(RssiData.u8SValue);
|
||||
}
|
||||
|
||||
void ClearSbarLine()
|
||||
{
|
||||
memset(pDData, 0, DisplayBuff.SizeX);
|
||||
}
|
||||
|
||||
void PrintNumber(short s16Number)
|
||||
{
|
||||
Display.SetCoursor(3, 0);
|
||||
if(s16Number > 0)
|
||||
{
|
||||
hundreds++;
|
||||
u8RssiCpy -= 100;
|
||||
Display.PrintCharacter(' ');
|
||||
}
|
||||
|
||||
unsigned char tens = 0;
|
||||
while (u8RssiCpy >= 10)
|
||||
Display.PrintFixedDigitsNumber2(s16Number, 0, 3);
|
||||
}
|
||||
|
||||
void PrintSValue(unsigned char u8SValue)
|
||||
{
|
||||
if(bPtt) // print TX
|
||||
{
|
||||
tens++;
|
||||
u8RssiCpy -= 10;
|
||||
memcpy(pDData + 5 * 7, FwData.pSmallLeters + 128*2 + 8*3 + 2, 15);
|
||||
unsigned char* pNegative = pDData + 5 * 7 - 2;
|
||||
for(unsigned char i = 0; i < 19; i++)
|
||||
{
|
||||
*pNegative++ ^= 0xFF;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Display.Print("g" + '0' + hundreds + '0' + tens + '0' + u8RssiCpy);
|
||||
|
||||
unsigned char u8Sub = (u8Rssi * BlocksCnt) >> 7;
|
||||
unsigned char u8BlocksToFill = (u8Sub > BlocksCnt ? BlocksCnt : u8Sub);
|
||||
u8BlocksToFill = Rssi::TRssi(u8Rssi).u8SValue;
|
||||
|
||||
char C8SignalString[] = " ";
|
||||
|
||||
if (u8BlocksToFill > 9)
|
||||
if (u8SValue > 9)
|
||||
{
|
||||
memcpy(pDData + 5 * 7, FwData.pSmallLeters + 109 - 3 * 8, 8);
|
||||
C8SignalString[1] = '0';
|
||||
C8SignalString[0] = '0' + u8BlocksToFill - 9;
|
||||
C8SignalString[0] = '0' + u8SValue - 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pDData + 5 * 7, FwData.pSmallLeters + 109, 8);
|
||||
C8SignalString[0] = '0' + u8BlocksToFill;
|
||||
C8SignalString[0] = '0' + u8SValue;
|
||||
C8SignalString[1] = ' ';
|
||||
}
|
||||
|
||||
Display.SetCoursor(3, 5 * 7 + 8);
|
||||
Display.Print(C8SignalString);
|
||||
}
|
||||
|
||||
u8BlocksToFill = u8BlocksToFill > 13 ? 13 : u8BlocksToFill;
|
||||
for (unsigned char i = 0; i < u8BlocksToFill; i++)
|
||||
void PrintSbar(unsigned char u8SValue)
|
||||
{
|
||||
u8SValue = u8SValue > MaxBarPoints ? MaxBarPoints : u8SValue;
|
||||
for (unsigned char i = 0; i < u8SValue; i++)
|
||||
{
|
||||
unsigned char u8BlockHeight = i + 1 > BlockSizeY ? BlockSizeY : i + 1;
|
||||
unsigned char u8X = i * (BlockSizeX + BlockSpace) + ChartStartX;
|
||||
Display.DrawRectangle(u8X, 24 + BlockSizeY - u8BlockHeight, BlockSizeX,
|
||||
u8BlockHeight, i < LinearBlocksCnt);
|
||||
}
|
||||
}
|
||||
|
||||
return eScreenRefreshFlag::MainScreen;
|
||||
void PrintBatteryVoltage()
|
||||
{
|
||||
if(*(FwData.pStatusBarData + VoltageOffset + 4 * 6 + 1) ||
|
||||
*(FwData.pStatusBarData + VoltageOffset + 4 * 6 - 6))
|
||||
{ // disable printing when function or charging icon are printed
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned short u16Voltage = *FwData.p16Voltage > 1000 ? 999 : *FwData.p16Voltage;
|
||||
|
||||
memset(FwData.pStatusBarData + VoltageOffset, 0, 4 * 5);
|
||||
DisplayStatusBar.SetCoursor(0, VoltageOffset);
|
||||
DisplayStatusBar.PrintFixedDigitsNumber2(u16Voltage, 2, 1);
|
||||
memset(FwData.pStatusBarData + VoltageOffset + 7 + 1, 0b1100000, 2); // dot
|
||||
DisplayStatusBar.SetCoursor(0, VoltageOffset + 7 + 4);
|
||||
DisplayStatusBar.PrintFixedDigitsNumber2(u16Voltage, 0, 2);
|
||||
memcpy(FwData.pStatusBarData + VoltageOffset + 4 * 6 + 2, FwData.pSmallLeters + 128 * 2 + 102, 5); // V character
|
||||
}
|
||||
};
|
|
@ -11,6 +11,7 @@ target_link_libraries(${NAME}
|
|||
orginal_fw
|
||||
uv_k5_system
|
||||
lcd
|
||||
views
|
||||
)
|
||||
|
||||
target_include_directories(${NAME} PUBLIC
|
||||
|
|
|
@ -1,39 +1,61 @@
|
|||
#include "system.hpp"
|
||||
#include "hardware/hardware.hpp"
|
||||
#include "registers.hpp"
|
||||
#include "uv_k5_display.hpp"
|
||||
#include "messenger.hpp"
|
||||
#include "radio.hpp"
|
||||
#include "rssi_sbar.hpp"
|
||||
#include <string.h>
|
||||
#include "manager.hpp"
|
||||
|
||||
Hardware::THardware Hw;
|
||||
const System::TOrgFunctions& Fw = System::OrgFunc_01_26;
|
||||
const System::TOrgData& FwData = System::OrgData_01_26;
|
||||
const System::TOrgFunctions &Fw = System::OrgFunc_01_26;
|
||||
const System::TOrgData &FwData = System::OrgData_01_26;
|
||||
|
||||
TUV_K5Display DisplayBuff(FwData.pDisplayBuffer);
|
||||
const TUV_K5SmallNumbers FontSmallNr(FwData.pSmallDigs);
|
||||
CDisplay Display(DisplayBuff);
|
||||
|
||||
TUV_K5Display StatusBarBuff(FwData.pStatusBarData);
|
||||
CDisplay DisplayStatusBar(StatusBarBuff);
|
||||
|
||||
Radio::CBK4819<System::OrgFunc_01_26> RadioDriver;
|
||||
|
||||
CRssiSbar<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
DisplayBuff,
|
||||
Display,
|
||||
DisplayStatusBar,
|
||||
FontSmallNr,
|
||||
RadioDriver>
|
||||
RssiSbar;
|
||||
|
||||
static IView * const Views[] = {&RssiSbar};
|
||||
CViewManager<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
8, 2, sizeof(Views) / sizeof(*Views)>
|
||||
Manager(Views);
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
return 0;
|
||||
Fw.IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
Fw.IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
{
|
||||
static bool bFirstInit = false;
|
||||
if(!bFirstInit)
|
||||
if (!bFirstInit)
|
||||
{
|
||||
System::CopyDataSection();
|
||||
__libc_init_array();
|
||||
bFirstInit = true;
|
||||
}
|
||||
|
||||
static unsigned int u32StupidCounter = 1;
|
||||
if((!(u32StupidCounter++ % 10) && u32StupidCounter > 200)) // exit key
|
||||
{
|
||||
CRssiPrinter::Handle(Fw, FwData);
|
||||
}
|
||||
Fw.IRQ_SYSTICK();
|
||||
RadioDriver.InterruptHandler();
|
||||
Manager.Handle();
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#include "system.hpp"
|
||||
#include "hardware/hardware.hpp"
|
||||
#include "registers.hpp"
|
||||
#include "uv_k5_display.hpp"
|
||||
#include "rssi_sbar.hpp"
|
||||
#include <string.h>
|
||||
|
||||
Hardware::THardware Hw;
|
||||
const System::TOrgFunctions& Fw = System::OrgFunc_01_26;
|
||||
const System::TOrgData& FwData = System::OrgData_01_26;
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
{
|
||||
static bool bFirstInit = false;
|
||||
if(!bFirstInit)
|
||||
{
|
||||
System::CopyDataSection();
|
||||
__libc_init_array();
|
||||
bFirstInit = true;
|
||||
}
|
||||
|
||||
static unsigned int u32StupidCounter = 1;
|
||||
if((!(u32StupidCounter++ % 10) && u32StupidCounter > 200)) // exit key
|
||||
{
|
||||
CRssiPrinter::Handle(Fw, FwData);
|
||||
}
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
Ładowanie…
Reference in New Issue