diff --git a/libs/k5_uv_system/system.hpp b/libs/k5_uv_system/system.hpp index 5136f25..578d828 100644 --- a/libs/k5_uv_system/system.hpp +++ b/libs/k5_uv_system/system.hpp @@ -68,7 +68,8 @@ namespace System void(*BK4819ConfigureAndStartTxFsk)(); void(*BK4819ConfigureAndStartRxFsk)(); void(*BK4819SetGpio)(unsigned int u32Pin, bool bState); - + void(*FlushStatusbarBufferToScreen)(); + void(*UpdateStatusBar)(); }; struct TOrgData @@ -76,7 +77,9 @@ namespace System unsigned char* pDisplayBuffer; unsigned char* pSmallDigs; unsigned char* pSmallLeters; - unsigned char *p8FlashLightStatus; + unsigned char* p8FlashLightStatus; + unsigned char* pStatusBarData; + unsigned short* p16Voltage; }; inline const TOrgFunctions OrgFunc_01_26 = @@ -105,6 +108,8 @@ namespace System .BK4819ConfigureAndStartTxFsk = (decltype(TOrgFunctions::BK4819ConfigureAndStartTxFsk) (0x1cd8 + 1)), .BK4819ConfigureAndStartRxFsk = (decltype(TOrgFunctions::BK4819ConfigureAndStartRxFsk) (0xa63c + 1)), .BK4819SetGpio = (decltype(TOrgFunctions::BK4819SetGpio) (0xa794 + 1)), + .FlushStatusbarBufferToScreen = (decltype(TOrgFunctions::FlushStatusbarBufferToScreen) (0xb6b0 + 1)), + .UpdateStatusBar = (decltype(TOrgFunctions::UpdateStatusBar) (0x9c10 + 1)), }; inline const TOrgData OrgData_01_26 = @@ -113,6 +118,8 @@ namespace System .pSmallDigs = (decltype(TOrgData::pSmallDigs)) 0xD620, .pSmallLeters = (decltype(TOrgData::pSmallLeters)) 0xD348, .p8FlashLightStatus = (decltype(TOrgData::p8FlashLightStatus)) 0x200003b3, + .pStatusBarData = (decltype(TOrgData::pStatusBarData)) 0x20000684, + .p16Voltage = (decltype(TOrgData::p16Voltage)) 0x20000406, }; } diff --git a/libs/lcd/lcd.hpp b/libs/lcd/lcd.hpp index cec98e8..ab79046 100644 --- a/libs/lcd/lcd.hpp +++ b/libs/lcd/lcd.hpp @@ -230,7 +230,7 @@ public: 10000000, // 10^7 100000000 // 10^8 }; - void PrintFixedDigitsNumber2(int s32Number, unsigned char u8DigsToCut = 2) + void PrintFixedDigitsNumber2(int s32Number, unsigned char u8DigsToCut = 2, unsigned char u8FixedDigtsCnt = 0) { char U8NumBuff[11] = {0}; // 9 digits, sign, and null terminator int startIdx = 0; @@ -263,6 +263,11 @@ public: U8NumBuff[isNegative] = '0'; // Print the string from the start index + if(u8FixedDigtsCnt) + { + startIdx = 9 - u8DigsToCut - u8FixedDigtsCnt; + } + Print(U8NumBuff + startIdx); } diff --git a/libs/lcd/uv_k5_display.hpp b/libs/lcd/uv_k5_display.hpp index 8e9556b..7124a50 100644 --- a/libs/lcd/uv_k5_display.hpp +++ b/libs/lcd/uv_k5_display.hpp @@ -33,6 +33,38 @@ struct TUV_K5Display : public IBitmap<128, 56, 8> } }; +struct TUV_K5StatusBar : public IBitmap<128, 8, 8> +{ + constexpr TUV_K5StatusBar(const unsigned char* p8ScreenData) : IBitmap(p8ScreenData){}; + bool GetPixel(unsigned char u8X, unsigned char u8Y) const override + { + return 0; + } + + void SetPixel(unsigned char u8X, unsigned char u8Y) const override + { + unsigned char u8Line = u8Y / LineHeight; + unsigned char* pStart = (unsigned char*)pBuffStart; + auto Position = GetCoursorPosition(u8Line, u8X); + if(Position > (SizeY / LineHeight) * SizeX) + { + return; + } + + *(pStart + Position) |= 0b1 << (u8Y % LineHeight); + } + + void* GetCoursorData(unsigned short u16CoursorPosition) const override + { + return (void*) (&pBuffStart[u16CoursorPosition]); + } + + void ClearAll() override + { + memset((void*)pBuffStart, 0, (SizeY / LineHeight) * SizeX); + } +}; + struct TUV_K5SmallNumbers : public IFont { static constexpr auto FixedSizeY = 7; diff --git a/libs/radio/radio.hpp b/libs/radio/radio.hpp index 89e346d..3d44bcd 100644 --- a/libs/radio/radio.hpp +++ b/libs/radio/radio.hpp @@ -11,15 +11,28 @@ namespace Radio RxDone = 1 << 13, }; - enum class eModulation : unsigned char + enum class eFskMode : unsigned char { - Ffsk, - Fsk, + Fsk1200 = 0, + Ffsk1200_1200_1800, + Ffsk1200_1200_2400, + NoaaSame, + ModesCount, }; - struct TRadioConf + struct TFskModeBits { - eModulation Modulation; + unsigned char u8TxModeBits; + unsigned char u8RxBandWidthBits; + unsigned char u8RxModeBits; + }; + + inline const TFskModeBits ModesBits[(int)eFskMode::ModesCount] = + {// Tx mode Rx badwitdh Rx Mode + {0b000, 0b000, 0b000}, // Fsk1200 + {0b001, 0b001, 0b111}, // Ffsk1200_1200_1800 + {0b011, 0b100, 0b100}, // Ffsk1200_1200_2400 + {0b101, 0b010, 0b000}, // NoaaSame }; enum class eState : unsigned char @@ -53,6 +66,7 @@ namespace Radio { Fw.BK4819ConfigureAndStartTxFsk(); Fw.AirCopyFskSetup(); + SetFskMode(eFskMode::Fsk1200); Fw.AirCopy72(p8Data); Fw.BK4819SetGpio(1, false); } @@ -62,6 +76,18 @@ namespace Radio Fw.BK4819Write(0x30, Fw.BK4819Read(0x30) & ~0b1010); } + void SetFskMode(eFskMode Mode) + { + auto const& ModeParams = ModesBits[(int)Mode]; + auto Reg58 = Fw.BK4819Read(0x58); + Reg58 &= ~((0b111 << 1) | (0b111 << 10) | (0b111 << 13)); + Reg58 |= (ModeParams.u8RxBandWidthBits << 1) + | (ModeParams.u8RxModeBits << 10) + | (ModeParams.u8TxModeBits << 13); + Fw.BK4819Write(0x58, 0); + Fw.BK4819Write(0x58, Reg58); + } + void FixIrqEnRegister() // original firmware overrides IRQ_EN reg, so we need to reenable it { auto const OldIrqEnReg = Fw.BK4819Read(0x3F); @@ -85,13 +111,7 @@ namespace Radio u16RxDataLen = 0; Fw.AirCopyFskSetup(); - // Fw.BK4819Write(0x2, 0); // clear irq - // Fw.BK4819Write(0x59, 1 << 14); // clear rx fifo - // Fw.BK4819Write(0x59, 0b0011'0000'0110'1000); // enable rx - // Fw.BK4819Write(0x3f, 1 << 13); // enable rx done irq - - // Fw.BK4819Write(0x30, 0); - // Fw.BK4819Write(0x30, 0b1011'1101'1111'0001); + SetFskMode(eFskMode::Fsk1200); Fw.BK4819ConfigureAndStartRxFsk(); State = eState::RxPending; } diff --git a/src/rssi_sbar/rssi_sbar.hpp b/src/rssi_sbar/rssi_sbar.hpp index 01de740..245cb64 100644 --- a/src/rssi_sbar/rssi_sbar.hpp +++ b/src/rssi_sbar/rssi_sbar.hpp @@ -44,26 +44,43 @@ namespace Rssi class CRssiPrinter { public: - static constexpr auto ChartStartX = 5 * 7 + 8 + 3*7;//32; + static constexpr auto ChartStartX = 5 * 7 + 8 + 3 * 7; // 32; static constexpr auto BlockSizeX = 4; static constexpr auto BlockSizeY = 7; static constexpr auto BlockSpace = 1; static constexpr auto BlocksCnt = (128 - ChartStartX) / (BlockSizeX + BlockSpace); static constexpr auto LinearBlocksCnt = 9; + static constexpr auto VoltageOffset = 77; static void Handle(const System::TOrgFunctions &Fw, const System::TOrgData &FwData) { static bool bIsCleared = true; static unsigned char u8SqlDelayCnt = 0xFF; TUV_K5Display DisplayBuff(FwData.pDisplayBuffer); + TUV_K5Display StatusBarBuff(FwData.pStatusBarData); const TUV_K5SmallNumbers FontSmallNr(FwData.pSmallDigs); CDisplay Display(DisplayBuff); + CDisplay DisplayStatusBar(StatusBarBuff); + DisplayStatusBar.SetFont(&FontSmallNr); if (!(GPIOC->DATA & 0b1)) { return; } + 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(); + } + auto *pMenuCheckData = (unsigned char *)DisplayBuff.GetCoursorData(DisplayBuff.GetCoursorPosition(2, 6 * 8 + 1)); if (Fw.BK4819Read(0x0C) & 0b10) { @@ -140,7 +157,7 @@ public: if (u8BlocksToFill > 9) { - memcpy(pDData + 5*7, FwData.pSmallLeters + 109 - 3*8, 8); + memcpy(pDData + 5 * 7, FwData.pSmallLeters + 109 - 3 * 8, 8); C8SignalString[1] = '0'; C8SignalString[0] = '0' + u8BlocksToFill - 9; }