kopia lustrzana https://github.com/piotr022/UV_K5_playground
				
				
				
			
							rodzic
							
								
									46e2f31bbd
								
							
						
					
					
						commit
						dfa9f9c46b
					
				| 
						 | 
				
			
			@ -49,6 +49,17 @@ struct TGpio
 | 
			
		|||
   unsigned int DIR;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct TSysCon
 | 
			
		||||
{
 | 
			
		||||
   unsigned int CLK_SEL;
 | 
			
		||||
   unsigned int DIV_CLK_GATE;
 | 
			
		||||
   unsigned int DEV_CLK_GATE;
 | 
			
		||||
   unsigned int RC_FREQ_DELTA;
 | 
			
		||||
   unsigned int CHIP_ID[4];
 | 
			
		||||
   unsigned int PLL_CTRL;
 | 
			
		||||
   unsigned int PLL_ST;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define GPIO_BASE 0x400B0000
 | 
			
		||||
#define GPIO ((TPort*)GPIO_BASE)
 | 
			
		||||
#define __BKPT(value)                       __asm volatile ("bkpt "#value)
 | 
			
		||||
| 
						 | 
				
			
			@ -79,3 +90,8 @@ struct TGpio
 | 
			
		|||
#define GPIO_PIN_13 (1 << 13)
 | 
			
		||||
#define GPIO_PIN_14 (1 << 14)
 | 
			
		||||
#define GPIO_PIN_15 (1 << 15)
 | 
			
		||||
 | 
			
		||||
#define SYSCON_BASE 0x40000000
 | 
			
		||||
#define SYSCON ((TSysCon*)SYSCON_BASE)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,6 +64,8 @@ namespace System
 | 
			
		|||
      void(*BK4819SetGpio)(unsigned int u32Pin, bool bState);
 | 
			
		||||
      void(*FlushStatusbarBufferToScreen)();
 | 
			
		||||
      void(*UpdateStatusBar)();
 | 
			
		||||
      void(*AdcReadout)(unsigned short* p16Data1, unsigned short* p16Data2);
 | 
			
		||||
      void(*SomeAmStuff)(unsigned int u32Param);
 | 
			
		||||
      void (*IRQ_RESET)(void);
 | 
			
		||||
      void (*IRQ_SYSTICK)(void);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +105,8 @@ namespace System
 | 
			
		|||
      .BK4819SetGpio = (decltype(TOrgFunctions::BK4819SetGpio) (0xa794 + 1)),
 | 
			
		||||
      .FlushStatusbarBufferToScreen = (decltype(TOrgFunctions::FlushStatusbarBufferToScreen) (0xb6b0 + 1)),
 | 
			
		||||
      .UpdateStatusBar = (decltype(TOrgFunctions::UpdateStatusBar) (0x9c10 + 1)),
 | 
			
		||||
      .AdcReadout = (decltype(TOrgFunctions::AdcReadout) (0x9d7c + 1)),
 | 
			
		||||
      .SomeAmStuff = (decltype(TOrgFunctions::SomeAmStuff) (0xc158 + 1)),
 | 
			
		||||
      .IRQ_RESET = (decltype(TOrgFunctions::IRQ_RESET) (0xd4 + 1)),
 | 
			
		||||
      .IRQ_SYSTICK = (decltype(TOrgFunctions::IRQ_SYSTICK) (0xc398 + 1))
 | 
			
		||||
   };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,16 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace Button
 | 
			
		||||
{
 | 
			
		||||
   enum : unsigned char
 | 
			
		||||
   {
 | 
			
		||||
      Ok = 10,
 | 
			
		||||
      Up = 11,
 | 
			
		||||
      Down = 12,
 | 
			
		||||
      Exit = 13,
 | 
			
		||||
   };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class KeyboardUserType>
 | 
			
		||||
class CKeyboard
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,21 @@
 | 
			
		|||
#include <functional>
 | 
			
		||||
#include "callback.hpp"
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Radio
 | 
			
		||||
{
 | 
			
		||||
   enum eIrq : unsigned short
 | 
			
		||||
| 
						 | 
				
			
			@ -29,11 +44,12 @@ namespace Radio
 | 
			
		|||
   };
 | 
			
		||||
 | 
			
		||||
   constexpr 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
 | 
			
		||||
       {
 | 
			
		||||
           // 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,10 +69,10 @@ namespace Radio
 | 
			
		|||
   public:
 | 
			
		||||
      CBK4819() : State(eState::Idle), u16RxDataLen(0){};
 | 
			
		||||
 | 
			
		||||
      void SetFrequency(unsigned int u32FrequencyD10)
 | 
			
		||||
      {
 | 
			
		||||
         Fw.BK4819WriteFrequency(u32FrequencyD10);
 | 
			
		||||
      }
 | 
			
		||||
      // void SetFrequency(unsigned int u32FrequencyD10)
 | 
			
		||||
      // {
 | 
			
		||||
      //    Fw.BK4819WriteFrequency(u32FrequencyD10);
 | 
			
		||||
      // }
 | 
			
		||||
 | 
			
		||||
      unsigned int GetFrequency()
 | 
			
		||||
      {
 | 
			
		||||
| 
						 | 
				
			
			@ -69,14 +85,60 @@ namespace Radio
 | 
			
		|||
         return s16Rssi - 160;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      bool IsTx()
 | 
			
		||||
      {
 | 
			
		||||
         return Fw.BK4819Read(0x30) & 0b10;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      bool IsSqlOpen()
 | 
			
		||||
      {
 | 
			
		||||
         return Fw.BK4819Read(0x0C) & 0b10;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void SetFrequency(unsigned int u32Freq)
 | 
			
		||||
      {
 | 
			
		||||
         Fw.BK4819Write(0x39, ((u32Freq >> 16) & 0xFFFF));
 | 
			
		||||
         Fw.BK4819Write(0x38, (u32Freq & 0xFFFF));
 | 
			
		||||
         auto OldReg = Fw.BK4819Read(0x30);
 | 
			
		||||
         Fw.BK4819Write(0x30, 0);
 | 
			
		||||
         Fw.BK4819Write(0x30, OldReg);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void SetAgcTable(unsigned short* p16AgcTable)
 | 
			
		||||
      {
 | 
			
		||||
         for(unsigned char i = 0; i < 5; i++)
 | 
			
		||||
         {
 | 
			
		||||
            Fw.BK4819Write(0x10 + i, p16AgcTable[i]);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void GetAgcTable(unsigned short* p16AgcTable)
 | 
			
		||||
      {
 | 
			
		||||
         for(unsigned char i = 0; i < 5; i++)
 | 
			
		||||
         {
 | 
			
		||||
            p16AgcTable[i] = Fw.BK4819Read(0x10 + i);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void SetDeviationPresent(unsigned char u8Present)
 | 
			
		||||
      {
 | 
			
		||||
         auto Reg40 = Fw.BK4819Read(0x40);
 | 
			
		||||
         Reg40 &= ~(1 << 12);
 | 
			
		||||
         Reg40 |= (u8Present << 12);
 | 
			
		||||
         Fw.BK4819Write(0x40, Reg40);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void SetCalibration(unsigned char bOn)
 | 
			
		||||
      {
 | 
			
		||||
         auto Reg30 = Fw.BK4819Read(0x31);
 | 
			
		||||
         Reg30 &= ~(1 << 3);
 | 
			
		||||
         Reg30 |= (bOn << 3);
 | 
			
		||||
         Fw.BK4819Write(0x31, Reg30);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      unsigned char GetAFAmplitude()
 | 
			
		||||
      {
 | 
			
		||||
         return 0b111111 - (Fw.BK4819Read(0x6F) & 0b111111);
 | 
			
		||||
         return Fw.BK4819Read(0x6F) & 0b1111111;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void SendSyncAirCopyMode72(unsigned char *p8Data)
 | 
			
		||||
| 
						 | 
				
			
			@ -94,12 +156,10 @@ namespace Radio
 | 
			
		|||
 | 
			
		||||
      void SetFskMode(eFskMode Mode)
 | 
			
		||||
      {
 | 
			
		||||
         auto const& ModeParams = ModesBits[(int)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);
 | 
			
		||||
         Reg58 |= (ModeParams.u8RxBandWidthBits << 1) | (ModeParams.u8RxModeBits << 10) | (ModeParams.u8TxModeBits << 13);
 | 
			
		||||
         Fw.BK4819Write(0x58, 0);
 | 
			
		||||
         Fw.BK4819Write(0x58, Reg58);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -107,8 +167,8 @@ namespace Radio
 | 
			
		|||
      void FixIrqEnRegister() // original firmware overrides IRQ_EN reg, so we need to reenable it
 | 
			
		||||
      {
 | 
			
		||||
         auto const OldIrqEnReg = Fw.BK4819Read(0x3F);
 | 
			
		||||
         if((OldIrqEnReg & (eIrq::FifoAlmostFull | eIrq::RxDone)) != 
 | 
			
		||||
            (eIrq::FifoAlmostFull | eIrq::RxDone))
 | 
			
		||||
         if ((OldIrqEnReg & (eIrq::FifoAlmostFull | eIrq::RxDone)) !=
 | 
			
		||||
             (eIrq::FifoAlmostFull | eIrq::RxDone))
 | 
			
		||||
         {
 | 
			
		||||
            Fw.BK4819Write(0x3F, OldIrqEnReg | eIrq::FifoAlmostFull | eIrq::RxDone);
 | 
			
		||||
         }
 | 
			
		||||
| 
						 | 
				
			
			@ -177,7 +237,6 @@ namespace Radio
 | 
			
		|||
            return;
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
         if (State == eState::RxPending)
 | 
			
		||||
         {
 | 
			
		||||
            FixIrqEnRegister();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
set(NAME views)
 | 
			
		||||
 | 
			
		||||
add_library(${NAME} INTERFACE)
 | 
			
		||||
add_library(${NAME} STATIC)
 | 
			
		||||
 | 
			
		||||
target_include_directories(${NAME} INTERFACE
 | 
			
		||||
	.
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ target_sources(${NAME} PRIVATE
 | 
			
		|||
   views.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(${NAME} INTERFACE
 | 
			
		||||
target_link_libraries(${NAME}
 | 
			
		||||
   uv_k5_system
 | 
			
		||||
   lcd
 | 
			
		||||
   keyboard
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,170 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
#include "manager.hpp"
 | 
			
		||||
#include "registers.hpp"
 | 
			
		||||
 | 
			
		||||
template <
 | 
			
		||||
    const System::TOrgFunctions &Fw,
 | 
			
		||||
    const System::TOrgData &FwData,
 | 
			
		||||
    TUV_K5Display &DisplayBuff,
 | 
			
		||||
    CDisplay<TUV_K5Display> &Display,
 | 
			
		||||
    CDisplay<TUV_K5Display> &DisplayStatusBar,
 | 
			
		||||
    const TUV_K5SmallNumbers &FontSmallNr,
 | 
			
		||||
    Radio::CBK4819<Fw> &RadioDriver>
 | 
			
		||||
class CAmTx : public IView
 | 
			
		||||
{
 | 
			
		||||
   static constexpr bool bAmpTests = true;
 | 
			
		||||
   bool bAmMode = false;
 | 
			
		||||
   bool bEnabled = false;
 | 
			
		||||
   unsigned short u16OldAmp = 0;
 | 
			
		||||
   int s32DeltaAmp = 0;
 | 
			
		||||
   unsigned int u32StartFreq = 0;
 | 
			
		||||
   // unsigned short U16OldAgcTable[5];
 | 
			
		||||
   // unsigned short U16NewAgcTable[5] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
   eScreenRefreshFlag HandleMainView(TViewContext &Context) override
 | 
			
		||||
   {
 | 
			
		||||
      if (Context.OriginalFwStatus.b1RadioSpiCommInUse || !RadioDriver.IsTx())
 | 
			
		||||
      {
 | 
			
		||||
         return eScreenRefreshFlag::NoRefresh;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if constexpr (bAmpTests)
 | 
			
		||||
      {
 | 
			
		||||
         // Fw.BK4819Write(0x29, 0);
 | 
			
		||||
         // Fw.BK4819Write(0x2B, 0);
 | 
			
		||||
         // Fw.BK4819Write(0x19, 0);
 | 
			
		||||
         // RadioDriver.SetDeviationPresent(0);
 | 
			
		||||
         HandleTests();
 | 
			
		||||
         if (!CheckForPtt())
 | 
			
		||||
         {
 | 
			
		||||
            RadioDriver.SetDeviationPresent(1);
 | 
			
		||||
            Context.ViewStack.Pop();
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
         return eScreenRefreshFlag::MainScreen;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      RadioDriver.SetDeviationPresent(0);
 | 
			
		||||
      auto InitialBias = Fw.BK4819Read(0x36);
 | 
			
		||||
 | 
			
		||||
      u32StartFreq = RadioDriver.GetFrequency();
 | 
			
		||||
 | 
			
		||||
      while (CheckForPtt())
 | 
			
		||||
      {
 | 
			
		||||
         HandleMicInput();
 | 
			
		||||
         HandleTxAm();
 | 
			
		||||
         //HandleTxWfm();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      RadioDriver.SetFrequency(u32StartFreq);
 | 
			
		||||
      RadioDriver.SetDeviationPresent(1);
 | 
			
		||||
      Fw.BK4819Write(0x36, InitialBias);
 | 
			
		||||
 | 
			
		||||
      Context.ViewStack.Pop();
 | 
			
		||||
      return eScreenRefreshFlag::NoRefresh;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void HandleTests()
 | 
			
		||||
   {
 | 
			
		||||
      HandleMicInput();
 | 
			
		||||
      char S8DebugStr[20];
 | 
			
		||||
      // int MicAmp = s32DeltaAmp / 8; // RadioDriver.GetAFAmplitude();
 | 
			
		||||
      // MicAmp = 4 + MicAmp;
 | 
			
		||||
      // if (MicAmp > 0b111)
 | 
			
		||||
      //    MicAmp = 0b111;
 | 
			
		||||
      // if (MicAmp < 0)
 | 
			
		||||
      //    MicAmp = 0;
 | 
			
		||||
      unsigned short U16AdcData[2];
 | 
			
		||||
      Fw.AdcReadout(U16AdcData, U16AdcData+1);
 | 
			
		||||
      Fw.FormatString(S8DebugStr, "in 1: %05i   ", U16AdcData[0]);
 | 
			
		||||
      Fw.PrintTextOnScreen(S8DebugStr, 0, 127, 0, 8, 0);
 | 
			
		||||
      Fw.FormatString(S8DebugStr, "in 2: %05i   ", U16AdcData[1]);
 | 
			
		||||
      Fw.PrintTextOnScreen(S8DebugStr, 0, 127, 2, 8, 0);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void HandleMicInput()
 | 
			
		||||
   {
 | 
			
		||||
      unsigned short u16ActualAmp = Fw.BK4819Read(0x64);
 | 
			
		||||
      s32DeltaAmp = u16OldAmp - u16ActualAmp;
 | 
			
		||||
      u16OldAmp = u16ActualAmp;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void HandleTxAm()
 | 
			
		||||
   {
 | 
			
		||||
      int MicAmp = s32DeltaAmp / 8; // RadioDriver.GetAFAmplitude();
 | 
			
		||||
      MicAmp = 4 + MicAmp;
 | 
			
		||||
      if (MicAmp > 0b111)
 | 
			
		||||
         MicAmp = 0b111;
 | 
			
		||||
      if (MicAmp < 0)
 | 
			
		||||
         MicAmp = 0;
 | 
			
		||||
      Fw.BK4819Write(0x36, ((MicAmp & 0b111) << 3) | (MicAmp & 0b111));
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void HandleTxWfm()
 | 
			
		||||
   {
 | 
			
		||||
      RadioDriver.SetFrequency(u32StartFreq + s32DeltaAmp);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   // always called, can be used to update some notifications on status bar
 | 
			
		||||
   eScreenRefreshFlag HandleBackground(TViewContext &Context)
 | 
			
		||||
   {
 | 
			
		||||
      if (CheckForFlashlight())
 | 
			
		||||
      {
 | 
			
		||||
         bAmMode = !bAmMode;
 | 
			
		||||
         if(!bAmMode)
 | 
			
		||||
         {
 | 
			
		||||
            DrawAmIcon(false);
 | 
			
		||||
            return eScreenRefreshFlag::StatusBar;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!bAmMode)
 | 
			
		||||
      {
 | 
			
		||||
         return eScreenRefreshFlag::NoRefresh;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      DrawAmIcon(true);
 | 
			
		||||
 | 
			
		||||
      if (!CheckForPtt())
 | 
			
		||||
      {
 | 
			
		||||
         return eScreenRefreshFlag::StatusBar;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      Context.ViewStack.Push(*this);
 | 
			
		||||
      return eScreenRefreshFlag::StatusBar;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   bool CheckForPtt()
 | 
			
		||||
   {
 | 
			
		||||
      return !(GPIOC->DATA & GPIO_PIN_5);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   bool CheckForFlashlight()
 | 
			
		||||
   {
 | 
			
		||||
      if (GPIOC->DATA & GPIO_PIN_3)
 | 
			
		||||
      {
 | 
			
		||||
         GPIOC->DATA &= ~GPIO_PIN_3;
 | 
			
		||||
         *FwData.p8FlashLightStatus = 3;
 | 
			
		||||
         return true;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return false;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void DrawAmIcon(bool bDraw)
 | 
			
		||||
   {
 | 
			
		||||
      memset(FwData.pStatusBarData, 0, 14);
 | 
			
		||||
      if (!bDraw)
 | 
			
		||||
      {
 | 
			
		||||
         return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      memcpy(FwData.pStatusBarData, FwData.pSmallLeters + 223, 12);
 | 
			
		||||
      unsigned char *pNegative = FwData.pStatusBarData;
 | 
			
		||||
      for (unsigned char i = 0; i < 14; i++)
 | 
			
		||||
      {
 | 
			
		||||
         *pNegative++ ^= 0xFF;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
#include "menu.hpp"
 | 
			
		||||
#include "system.hpp"
 | 
			
		||||
#include "keyboard.hpp"
 | 
			
		||||
 
 | 
			
		||||
inline char S8Label[20];
 | 
			
		||||
template <const System::TOrgFunctions &Fw>
 | 
			
		||||
class CHeater : public IMenuElement
 | 
			
		||||
{
 | 
			
		||||
   bool bEnabled = false;
 | 
			
		||||
 | 
			
		||||
   public:
 | 
			
		||||
   const char *GetLabel() override
 | 
			
		||||
   {
 | 
			
		||||
      if(bEnabled)
 | 
			
		||||
         return "Heater    ON";
 | 
			
		||||
      
 | 
			
		||||
      return "Heater    OFF";
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void HandleUserAction(unsigned char u8Button) override
 | 
			
		||||
   {
 | 
			
		||||
      if(u8Button != Button::Ok)
 | 
			
		||||
      {
 | 
			
		||||
         return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      bEnabled = !bEnabled;
 | 
			
		||||
      if(bEnabled)
 | 
			
		||||
      {
 | 
			
		||||
         Fw.BK4819SetGpio(1, true);
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
         Fw.BK4819SetGpio(1, false);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <const System::TOrgFunctions &Fw>
 | 
			
		||||
class CAmRx : public IMenuElement
 | 
			
		||||
{
 | 
			
		||||
   unsigned char u8Mode = 0;
 | 
			
		||||
   public:
 | 
			
		||||
   const char *GetLabel() override
 | 
			
		||||
   {
 | 
			
		||||
      Fw.FormatString(S8Label, "AM RX     %u", u8Mode);
 | 
			
		||||
      return S8Label;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void HandleUserAction(unsigned char u8Button) override
 | 
			
		||||
   {
 | 
			
		||||
      if(u8Button != Button::Ok)
 | 
			
		||||
      {
 | 
			
		||||
         return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      u8Mode++;
 | 
			
		||||
      if(u8Mode > 2)
 | 
			
		||||
         u8Mode = 0;
 | 
			
		||||
      
 | 
			
		||||
      // Fw.SomeAmStuff(u8Mode);
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <const System::TOrgFunctions &Fw, Radio::CBK4819<Fw> &RadioDriver>
 | 
			
		||||
class CMicVal : public IMenuElement
 | 
			
		||||
{
 | 
			
		||||
   unsigned char u8Mode = 0;
 | 
			
		||||
 | 
			
		||||
   public:
 | 
			
		||||
   const char *GetLabel() override
 | 
			
		||||
   {
 | 
			
		||||
      Fw.FormatString(S8Label, "MIC in    %u", Fw.BK4819Read(0x64));
 | 
			
		||||
      return S8Label;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void HandleUserAction(unsigned char u8Button) override
 | 
			
		||||
   {
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <const System::TOrgFunctions &Fw, Radio::CBK4819<Fw> &RadioDriver>
 | 
			
		||||
class CRssiVal : public IMenuElement
 | 
			
		||||
{
 | 
			
		||||
   unsigned char u8Mode = 0;
 | 
			
		||||
   char S8Label[20];
 | 
			
		||||
 | 
			
		||||
   public:
 | 
			
		||||
   const char *GetLabel() override
 | 
			
		||||
   {                         
 | 
			
		||||
      Fw.FormatString(S8Label, "RSSI     %i", RadioDriver.GetRssi());
 | 
			
		||||
      return S8Label;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void HandleUserAction(unsigned char u8Button) override
 | 
			
		||||
   {
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +24,8 @@ class CViewManager
 | 
			
		|||
      :  Modules(_Modules),
 | 
			
		||||
         MainViewContext({MainViewStack, 0, 0}),
 | 
			
		||||
         Keyboard(*this)
 | 
			
		||||
         {};
 | 
			
		||||
         {
 | 
			
		||||
         };
 | 
			
		||||
   
 | 
			
		||||
   void Handle()
 | 
			
		||||
   {
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +47,9 @@ class CViewManager
 | 
			
		|||
      if(pViewStackTop && !(MainViewContext.u32SystemCounter 
 | 
			
		||||
                              % MainViewPrescaler))
 | 
			
		||||
      {
 | 
			
		||||
         Keyboard.Handle(Fw.PollKeyboard());
 | 
			
		||||
         if(!MainViewContext.OriginalFwStatus.b1RadioSpiCommInUse)
 | 
			
		||||
            Keyboard.Handle(Fw.PollKeyboard());
 | 
			
		||||
 | 
			
		||||
         u8ScreenRefreshFlag |= 
 | 
			
		||||
            pViewStackTop->HandleMainView(MainViewContext);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +97,7 @@ class CViewManager
 | 
			
		|||
      auto* const pTop = MainViewStack.GetTop();
 | 
			
		||||
      if(pTop)
 | 
			
		||||
      {
 | 
			
		||||
         pTop->HandlePressedButton(u8Key);
 | 
			
		||||
         pTop->HandlePressedButton(MainViewContext, u8Key);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +106,7 @@ class CViewManager
 | 
			
		|||
      auto* const pTop = MainViewStack.GetTop();
 | 
			
		||||
      if(pTop)
 | 
			
		||||
      {
 | 
			
		||||
         pTop->HandleReleasedButton(u8Key);
 | 
			
		||||
         pTop->HandleReleasedButton(MainViewContext, u8Key);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,111 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
#include "views.hpp"
 | 
			
		||||
#include "keyboard.hpp"
 | 
			
		||||
 | 
			
		||||
struct IMenuElement
 | 
			
		||||
{
 | 
			
		||||
   virtual const char *GetLabel() = 0;
 | 
			
		||||
   virtual void HandleUserAction(unsigned char u8Button) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <const System::TOrgFunctions &Fw,
 | 
			
		||||
          const System::TOrgData &FwData>
 | 
			
		||||
class CMenu : public IView
 | 
			
		||||
{
 | 
			
		||||
   static constexpr auto MenuLines = 3;
 | 
			
		||||
   IMenuElement* const* MenuElements;
 | 
			
		||||
   const unsigned char ElementsCnt;
 | 
			
		||||
   unsigned char u8Selected = 0;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
   template<unsigned char ArrSize>
 | 
			
		||||
   constexpr CMenu(IMenuElement* const (&_MenuElemets)[ArrSize])
 | 
			
		||||
   :MenuElements(_MenuElemets), ElementsCnt(ArrSize)
 | 
			
		||||
   {
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   eScreenRefreshFlag HandleMainView(TViewContext &Context) override
 | 
			
		||||
   {
 | 
			
		||||
      DrawMenu();
 | 
			
		||||
      return eScreenRefreshFlag::MainScreen;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   eScreenRefreshFlag HandleBackground(TViewContext &Context) override
 | 
			
		||||
   {
 | 
			
		||||
      if(CheckForFlashlight())
 | 
			
		||||
      {
 | 
			
		||||
         if(Context.ViewStack.GetTop() == this)
 | 
			
		||||
         {
 | 
			
		||||
            Context.ViewStack.Pop();
 | 
			
		||||
         }
 | 
			
		||||
         else
 | 
			
		||||
         {
 | 
			
		||||
            Context.ViewStack.Push(*this);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return eScreenRefreshFlag::NoRefresh;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void HandlePressedButton(TViewContext &Context, unsigned char u8Key) override
 | 
			
		||||
   {
 | 
			
		||||
      switch (u8Key)
 | 
			
		||||
      {
 | 
			
		||||
      case Button::Exit:
 | 
			
		||||
         Context.ViewStack.Pop();
 | 
			
		||||
         break;
 | 
			
		||||
 | 
			
		||||
      case Button::Down:
 | 
			
		||||
         if (u8Selected < ElementsCnt - 1)
 | 
			
		||||
            u8Selected++;
 | 
			
		||||
         break;
 | 
			
		||||
 | 
			
		||||
      case Button::Up:
 | 
			
		||||
         if (u8Selected)
 | 
			
		||||
            u8Selected--;
 | 
			
		||||
         break;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
         MenuElements[u8Selected]->HandleUserAction(u8Key);
 | 
			
		||||
         break;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void DrawMenu()
 | 
			
		||||
   {
 | 
			
		||||
      memset(FwData.pDisplayBuffer, 0, 128*6);
 | 
			
		||||
      for(unsigned char u8Line = 0; u8Line < MenuLines; u8Line++)
 | 
			
		||||
      {
 | 
			
		||||
         auto* Element = GetElement(u8Selected - 1 + u8Line);
 | 
			
		||||
         if(!Element)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
         Fw.PrintTextOnScreen(Element->GetLabel(), 0, 127, u8Line << 1, 8, 0);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      for(auto i = 0; i < 256; i++)
 | 
			
		||||
         FwData.pDisplayBuffer[i + 2*128] ^= 0xFF; 
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   IMenuElement* GetElement(signed char s8Idx)
 | 
			
		||||
   {
 | 
			
		||||
      if(s8Idx >= 0 && s8Idx < ElementsCnt)
 | 
			
		||||
      {
 | 
			
		||||
         return MenuElements[s8Idx];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return nullptr;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   bool CheckForFlashlight()
 | 
			
		||||
   {
 | 
			
		||||
      if (GPIOC->DATA & GPIO_PIN_3)
 | 
			
		||||
      {
 | 
			
		||||
         GPIOC->DATA &= ~GPIO_PIN_3;
 | 
			
		||||
         *FwData.p8FlashLightStatus = 3;
 | 
			
		||||
         return true;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return false;
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#include "uv_k5_display.hpp"
 | 
			
		||||
#include "radio.hpp"
 | 
			
		||||
#include "registers.hpp"
 | 
			
		||||
#include "menu.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Rssi
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +28,7 @@ namespace Rssi
 | 
			
		|||
   {
 | 
			
		||||
      TRssi(){};
 | 
			
		||||
      TRssi(signed short s16Rssi)
 | 
			
		||||
      :s16Rssi(s16Rssi)
 | 
			
		||||
          : s16Rssi(s16Rssi)
 | 
			
		||||
      {
 | 
			
		||||
         s16Rssi *= -1;
 | 
			
		||||
         unsigned char i;
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +56,7 @@ template <
 | 
			
		|||
    CDisplay<TUV_K5Display> &DisplayStatusBar,
 | 
			
		||||
    const TUV_K5SmallNumbers &FontSmallNr,
 | 
			
		||||
    Radio::CBK4819<Fw> &RadioDriver>
 | 
			
		||||
class CRssiSbar : public IView
 | 
			
		||||
class CRssiSbar : public IView, public IMenuElement
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
   static constexpr auto ChartStartX = 5 * 7 + 8 + 3 * 7; // 32;
 | 
			
		||||
| 
						 | 
				
			
			@ -68,11 +69,11 @@ public:
 | 
			
		|||
   static constexpr auto MaxBarPoints = 13;
 | 
			
		||||
   static inline unsigned char *const pDData = FwData.pDisplayBuffer + 128 * 3;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   unsigned int u32DrawVoltagePsc = 0;
 | 
			
		||||
   Rssi::TRssi RssiData;
 | 
			
		||||
   unsigned char u8AfAmp = 0;
 | 
			
		||||
   bool bPtt = false;
 | 
			
		||||
   bool b59Mode = false;
 | 
			
		||||
 | 
			
		||||
   CRssiSbar()
 | 
			
		||||
   {
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +81,24 @@ public:
 | 
			
		|||
      DisplayStatusBar.SetFont(&FontSmallNr);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   const char *GetLabel() override
 | 
			
		||||
   {
 | 
			
		||||
      if (!b59Mode)
 | 
			
		||||
         return "S-metr  normal";
 | 
			
		||||
 | 
			
		||||
      return "S-metr    59";
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   void HandleUserAction(unsigned char u8Button) override
 | 
			
		||||
   {
 | 
			
		||||
      if (u8Button != Button::Ok)
 | 
			
		||||
      {
 | 
			
		||||
         return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      b59Mode = !b59Mode;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   eScreenRefreshFlag HandleBackground(TViewContext &Context) override
 | 
			
		||||
   {
 | 
			
		||||
      static bool bIsCleared = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -121,9 +140,14 @@ public:
 | 
			
		|||
      u8SqlDelayCnt++;
 | 
			
		||||
      bIsCleared = false;
 | 
			
		||||
 | 
			
		||||
      if(bPtt)
 | 
			
		||||
      if(b59Mode)
 | 
			
		||||
      {
 | 
			
		||||
         RssiData = 0;
 | 
			
		||||
      }
 | 
			
		||||
      else if (bPtt)
 | 
			
		||||
      {
 | 
			
		||||
         RssiData.s16Rssi = RadioDriver.GetAFAmplitude();
 | 
			
		||||
         RssiData.s16Rssi = RssiData.s16Rssi < 30 ? 0 : RssiData.s16Rssi - 30; 
 | 
			
		||||
         RssiData.u8SValue = (MaxBarPoints * RssiData.s16Rssi) >> 6;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +162,7 @@ public:
 | 
			
		|||
   void ProcessDrawings()
 | 
			
		||||
   {
 | 
			
		||||
      ClearSbarLine();
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      PrintNumber(RssiData.s16Rssi);
 | 
			
		||||
      PrintSValue(RssiData.u8SValue);
 | 
			
		||||
      PrintSbar(RssiData.u8SValue);
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +176,7 @@ public:
 | 
			
		|||
   void PrintNumber(short s16Number)
 | 
			
		||||
   {
 | 
			
		||||
      Display.SetCoursor(3, 0);
 | 
			
		||||
      if(s16Number > 0)
 | 
			
		||||
      if (s16Number > 0)
 | 
			
		||||
      {
 | 
			
		||||
         Display.PrintCharacter(' ');
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -162,11 +186,11 @@ public:
 | 
			
		|||
 | 
			
		||||
   void PrintSValue(unsigned char u8SValue)
 | 
			
		||||
   {
 | 
			
		||||
      if(bPtt) // print TX
 | 
			
		||||
      if (bPtt) // print TX
 | 
			
		||||
      {
 | 
			
		||||
         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++)
 | 
			
		||||
         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;
 | 
			
		||||
         }
 | 
			
		||||
| 
						 | 
				
			
			@ -174,7 +198,12 @@ public:
 | 
			
		|||
      }
 | 
			
		||||
 | 
			
		||||
      char C8SignalString[] = "  ";
 | 
			
		||||
      if (u8SValue > 9)
 | 
			
		||||
      if(b59Mode)
 | 
			
		||||
      {
 | 
			
		||||
         C8SignalString[0] = '5';
 | 
			
		||||
         C8SignalString[1] = '9';
 | 
			
		||||
      }
 | 
			
		||||
      else if (u8SValue > 9)
 | 
			
		||||
      {
 | 
			
		||||
         memcpy(pDData + 5 * 7, FwData.pSmallLeters + 109 - 3 * 8, 8);
 | 
			
		||||
         C8SignalString[1] = '0';
 | 
			
		||||
| 
						 | 
				
			
			@ -205,7 +234,7 @@ public:
 | 
			
		|||
 | 
			
		||||
   void PrintBatteryVoltage()
 | 
			
		||||
   {
 | 
			
		||||
      if(*(FwData.pStatusBarData + VoltageOffset + 4 * 6 + 1) || 
 | 
			
		||||
      if(*(FwData.pStatusBarData + VoltageOffset + 4 * 6 + 1) ||
 | 
			
		||||
          *(FwData.pStatusBarData + VoltageOffset + 4 * 6 - 6))
 | 
			
		||||
      {  // disable printing when function or charging icon are printed
 | 
			
		||||
         return;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,4 +2,7 @@
 | 
			
		|||
#include "manager.hpp"
 | 
			
		||||
#include "rssi_printer.hpp"
 | 
			
		||||
#include "rssi_sbar.hpp"
 | 
			
		||||
#include "messenger.hpp"
 | 
			
		||||
#include "messenger.hpp"
 | 
			
		||||
#include "am_tx.hpp"
 | 
			
		||||
#include "menu.hpp"
 | 
			
		||||
#include "heater.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -29,15 +29,14 @@ struct TViewContext
 | 
			
		|||
struct IView
 | 
			
		||||
{
 | 
			
		||||
   IView* pNext;
 | 
			
		||||
   
 | 
			
		||||
   // only called by manager only when on top of view stack
 | 
			
		||||
   virtual eScreenRefreshFlag HandleMainView(TViewContext& Context) {return eScreenRefreshFlag::NoRefresh;} 
 | 
			
		||||
 | 
			
		||||
   // always called, can be used to update some notifications on status bar
 | 
			
		||||
   virtual eScreenRefreshFlag HandleBackground(TViewContext& Context) {return eScreenRefreshFlag::NoRefresh;} 
 | 
			
		||||
 | 
			
		||||
   virtual void HandlePressedButton(unsigned char u8Key) {};
 | 
			
		||||
   virtual void HandleReleasedButton(unsigned char u8Key) {};
 | 
			
		||||
   virtual void HandlePressedButton(TViewContext& Context, unsigned char u8Key) {};
 | 
			
		||||
   virtual void HandleReleasedButton(TViewContext& Context, unsigned char u8Key) {};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class CViewStack
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,3 +7,4 @@ add_subdirectory(spectrum)
 | 
			
		|||
add_subdirectory(spectrum_fagci)
 | 
			
		||||
add_subdirectory(t9_texting)
 | 
			
		||||
add_subdirectory(messenger)
 | 
			
		||||
add_subdirectory(rssi_sbar_hot)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
#include "uv_k5_display.hpp"
 | 
			
		||||
#include "messenger.hpp"
 | 
			
		||||
#include "radio.hpp"
 | 
			
		||||
#include "am_tx.hpp"
 | 
			
		||||
#include "rssi_sbar.hpp"
 | 
			
		||||
#include "manager.hpp"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +28,26 @@ CRssiSbar<
 | 
			
		|||
    RadioDriver>
 | 
			
		||||
    RssiSbar;
 | 
			
		||||
 | 
			
		||||
static IView * const Views[] = {&RssiSbar};
 | 
			
		||||
#ifdef AM_TX
 | 
			
		||||
CAmTx<
 | 
			
		||||
    System::OrgFunc_01_26,
 | 
			
		||||
    System::OrgData_01_26,
 | 
			
		||||
    DisplayBuff,
 | 
			
		||||
    Display,
 | 
			
		||||
    DisplayStatusBar,
 | 
			
		||||
    FontSmallNr,
 | 
			
		||||
    RadioDriver>
 | 
			
		||||
    AmTx;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static IView *const Views[] =
 | 
			
		||||
{
 | 
			
		||||
    &RssiSbar,
 | 
			
		||||
#ifdef AM_TX
 | 
			
		||||
    &AmTx,
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CViewManager<
 | 
			
		||||
    System::OrgFunc_01_26,
 | 
			
		||||
    System::OrgData_01_26,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,186 +0,0 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
#include "system.hpp"
 | 
			
		||||
#include "uv_k5_display.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Rssi
 | 
			
		||||
{
 | 
			
		||||
   inline const unsigned char U8RssiMap[] =
 | 
			
		||||
       {
 | 
			
		||||
           141,
 | 
			
		||||
           135,
 | 
			
		||||
           129,
 | 
			
		||||
           123,
 | 
			
		||||
           117,
 | 
			
		||||
           111,
 | 
			
		||||
           105,
 | 
			
		||||
           99,
 | 
			
		||||
           93,
 | 
			
		||||
           83,
 | 
			
		||||
           73,
 | 
			
		||||
           63,
 | 
			
		||||
           53,
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   struct TRssi
 | 
			
		||||
   {
 | 
			
		||||
      TRssi(unsigned char u8Val)
 | 
			
		||||
      {
 | 
			
		||||
         unsigned char i;
 | 
			
		||||
         for (i = 0; i < sizeof(U8RssiMap); i++)
 | 
			
		||||
         {
 | 
			
		||||
            if (u8Val >= U8RssiMap[i])
 | 
			
		||||
            {
 | 
			
		||||
               u8SValue = i + 1;
 | 
			
		||||
               return;
 | 
			
		||||
            }
 | 
			
		||||
         }
 | 
			
		||||
         u8SValue = i + 1;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      unsigned char u8SValue;
 | 
			
		||||
   };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class CRssiPrinter
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
   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();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (Fw.BK4819Read(0x0C) & 0b10)
 | 
			
		||||
      {
 | 
			
		||||
         u8SqlDelayCnt = 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      auto *pMenuCheckData = (unsigned char *)DisplayBuff.GetCoursorData(DisplayBuff.GetCoursorPosition(2, 6 * 8 + 1));
 | 
			
		||||
      auto *pFrequencyScanCheckData = (unsigned char *)DisplayBuff.GetCoursorData(DisplayBuff.GetCoursorPosition(6, 3 * 8 +2));
 | 
			
		||||
      auto *pDData = (unsigned char *)DisplayBuff.GetCoursorData(DisplayBuff.GetCoursorPosition(3, 0));
 | 
			
		||||
      if (u8SqlDelayCnt > 20 || *pMenuCheckData == 0xFF || *pFrequencyScanCheckData)
 | 
			
		||||
      {
 | 
			
		||||
         if (!bIsCleared)
 | 
			
		||||
         {
 | 
			
		||||
            bIsCleared = true;
 | 
			
		||||
            memset(pDData, 0, DisplayBuff.SizeX);
 | 
			
		||||
            if (*pMenuCheckData != 0xFF || *pFrequencyScanCheckData)
 | 
			
		||||
            {
 | 
			
		||||
               Fw.FlushFramebufferToScreen();
 | 
			
		||||
            }
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
         return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      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;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      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);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      Fw.FlushFramebufferToScreen();
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
set(NAME rssi_sbar_hot)
 | 
			
		||||
set(MCU_TARGET_FILES_DIR ../mcu_target_common)
 | 
			
		||||
 | 
			
		||||
add_executable(${NAME}  
 | 
			
		||||
        main.cpp
 | 
			
		||||
        hardware/hardware.cpp
 | 
			
		||||
        dp32g030.s
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(${NAME}
 | 
			
		||||
        orginal_fw
 | 
			
		||||
        uv_k5_system
 | 
			
		||||
        lcd
 | 
			
		||||
        views
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_include_directories(${NAME} PUBLIC
 | 
			
		||||
        ./
 | 
			
		||||
        Drivers/CMSIS/Device/ST/STM32G0xx/Include
 | 
			
		||||
        Drivers/CMSIS/DSP/Include
 | 
			
		||||
        Drivers/CMSIS/Include
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_compile_definitions(${NAME} PRIVATE
 | 
			
		||||
        ${STM32_DEFINES}
 | 
			
		||||
        $<$<CONFIG:Debug>:DEBUG_ENABLED>
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_compile_options(${NAME} PRIVATE
 | 
			
		||||
        ${COMPILER_OPTIONS}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_link_options(${NAME} PRIVATE
 | 
			
		||||
        #-print-multi-lib
 | 
			
		||||
        -T ${CMAKE_CURRENT_SOURCE_DIR}/memory.ld
 | 
			
		||||
        -mcpu=cortex-m0
 | 
			
		||||
        -mthumb
 | 
			
		||||
        -mfpu=auto
 | 
			
		||||
        -mfloat-abi=soft
 | 
			
		||||
        -specs=nosys.specs
 | 
			
		||||
        -specs=nano.specs
 | 
			
		||||
        -lc
 | 
			
		||||
        -lm
 | 
			
		||||
        -lnosys
 | 
			
		||||
        -Wl,-Map=${PROJECT_NAME}.map,--cref
 | 
			
		||||
        -Wl,--gc-sections
 | 
			
		||||
        -Wl,--print-memory-usage
 | 
			
		||||
        -Wstack-usage=128
 | 
			
		||||
        -Wno-register
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_custom_command(TARGET ${NAME}
 | 
			
		||||
        POST_BUILD
 | 
			
		||||
        COMMAND arm-none-eabi-size ${NAME}
 | 
			
		||||
)
 | 
			
		||||
#convert to hex
 | 
			
		||||
add_custom_command(TARGET ${NAME}
 | 
			
		||||
        POST_BUILD
 | 
			
		||||
        COMMAND arm-none-eabi-objcopy -O ihex ${NAME} ${NAME}.hex
 | 
			
		||||
        COMMAND arm-none-eabi-objcopy -O binary ${NAME} ${NAME}.bin
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
get_target_property(BOOTLOADER_BIN_PATH orginal_fw BOOTLOADER_BIN_PATH)
 | 
			
		||||
add_custom_command(TARGET ${NAME}
 | 
			
		||||
        POST_BUILD
 | 
			
		||||
        COMMAND ${CMAKE_COMMAND} -E echo "generating full binary with bootloader to ${NAME}_with_bootloader.bin"
 | 
			
		||||
        COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/fw_merger.py ${BOOTLOADER_BIN_PATH} ${NAME}.bin ${NAME}_with_bootloader.bin
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_custom_target(${NAME}_flash
 | 
			
		||||
	COMMAND openocd -f interface/cmsis-dap.cfg -f ${PROJECT_SOURCE_DIR}/openocd_scripts/dp32g030.cfg -c "write_image ${PROJECT_SOURCE_DIR}/build/src/rssi_printer/rssi_printer.bin 0x1000" -c "halt" -c "shutdown"
 | 
			
		||||
	DEPENDS ${NAME}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_custom_target(${NAME}_encoded
 | 
			
		||||
	COMMAND python ${PROJECT_SOURCE_DIR}/tools/fw_tools/python-utils/fw_pack.py ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin ${CMAKE_CURRENT_SOURCE_DIR}/../orginal_fw/k5_26_encrypted_18to1300MHz.ver.bin ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_encoded.bin
 | 
			
		||||
	DEPENDS ${NAME}
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
  .syntax unified
 | 
			
		||||
  .cpu cortex-m0
 | 
			
		||||
  .fpu softvfp
 | 
			
		||||
  .thumb
 | 
			
		||||
 | 
			
		||||
  .section .text.Reset_Handler
 | 
			
		||||
  .weak Reset_Handler
 | 
			
		||||
  .type Reset_Handler, %function
 | 
			
		||||
Reset_Handler:
 | 
			
		||||
  ldr   r0, =_estack
 | 
			
		||||
  mov   sp, r0          /* set stack pointer */
 | 
			
		||||
 | 
			
		||||
  bl main
 | 
			
		||||
 | 
			
		||||
LoopForever:
 | 
			
		||||
    b LoopForever
 | 
			
		||||
 | 
			
		||||
.size Reset_Handler, .-Reset_Handler
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
#include "registers.hpp"
 | 
			
		||||
 | 
			
		||||
class CExec final
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
   CExec(){};
 | 
			
		||||
 | 
			
		||||
   void InterruptCallback()
 | 
			
		||||
   {
 | 
			
		||||
      CheckButtons();
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   private:
 | 
			
		||||
   void CheckButtons() const
 | 
			
		||||
   {
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
import sys
 | 
			
		||||
 | 
			
		||||
def merge_files(in1, in2, out):
 | 
			
		||||
    f1 = open(in1, 'rb')
 | 
			
		||||
    f2 = open(in2, 'rb')
 | 
			
		||||
    fo = open(out, 'wb')
 | 
			
		||||
 | 
			
		||||
    fo.write(f1.read())
 | 
			
		||||
    fo.write(f2.read())
 | 
			
		||||
    fo.close()
 | 
			
		||||
    f1.close()
 | 
			
		||||
    f2.close() 
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
   args = sys.argv
 | 
			
		||||
   merge_files(args[1], args[2], args[3])
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
#include "hardware.hpp"
 | 
			
		||||
#include "registers.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Hardware;
 | 
			
		||||
 | 
			
		||||
void TPower::EnableDbg()
 | 
			
		||||
{
 | 
			
		||||
   GPIOB->DIR &= ~(GPIO_PIN_11|GPIO_PIN_14);
 | 
			
		||||
   // PB11 alternate fx to SWDIO
 | 
			
		||||
   GPIO->PORTB_SEL1 &= ~(0b1111 << 12);
 | 
			
		||||
   GPIO->PORTB_SEL1 |= (0b1 << 12);
 | 
			
		||||
 | 
			
		||||
   // PB14 alternate fx to SWDIO
 | 
			
		||||
   GPIO->PORTB_SEL1 &= ~(0b1111 << 24);
 | 
			
		||||
   GPIO->PORTB_SEL1 |= (0b1 << 24);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TSystem::Delay(unsigned int u32Ticks)
 | 
			
		||||
{
 | 
			
		||||
   for(volatile unsigned int i = 0; i < u32Ticks; i++)
 | 
			
		||||
   {
 | 
			
		||||
      __asm volatile ("dsb sy" : : : "memory");
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TFlashLight::On()
 | 
			
		||||
{
 | 
			
		||||
   GPIOC->DATA |= 1 << 3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TFlashLight::Off()
 | 
			
		||||
{
 | 
			
		||||
   GPIOC->DATA &= ~(1 << 3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TFlashLight::Toggle()
 | 
			
		||||
{
 | 
			
		||||
   GPIOC->DATA ^= 1 << 3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TFlashLight::BlinkSync(unsigned char u8BlinksCnt)
 | 
			
		||||
{
 | 
			
		||||
   for(unsigned char i = 0; i < u8BlinksCnt*2; i++)
 | 
			
		||||
   {
 | 
			
		||||
      Toggle();
 | 
			
		||||
      System.Delay(200000);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   Off();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
namespace Hardware
 | 
			
		||||
{
 | 
			
		||||
   struct TPower
 | 
			
		||||
   {
 | 
			
		||||
      void EnableDbg();
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   struct TSystem
 | 
			
		||||
   {
 | 
			
		||||
      static void Delay(unsigned int u32Ticks);
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   struct TFlashLight
 | 
			
		||||
   {
 | 
			
		||||
      TFlashLight(TSystem& Sys) :System(Sys){};
 | 
			
		||||
      void On();
 | 
			
		||||
      void Off();
 | 
			
		||||
      void Toggle();
 | 
			
		||||
      void BlinkSync(unsigned char u8BlinksCnt);
 | 
			
		||||
      TSystem& System;
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   struct THardware
 | 
			
		||||
   {
 | 
			
		||||
      TPower Power;
 | 
			
		||||
      TSystem System;
 | 
			
		||||
      TFlashLight FlashLight = {System};
 | 
			
		||||
   };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
#include "system.hpp"
 | 
			
		||||
#include "uv_k5_display.hpp"
 | 
			
		||||
#include "messenger.hpp"
 | 
			
		||||
#include "radio.hpp"
 | 
			
		||||
#include "am_tx.hpp"
 | 
			
		||||
#include "rssi_sbar.hpp"
 | 
			
		||||
#include "manager.hpp"
 | 
			
		||||
#include "heater.hpp"
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
// CAmTx<
 | 
			
		||||
//     System::OrgFunc_01_26,
 | 
			
		||||
//     System::OrgData_01_26,
 | 
			
		||||
//     DisplayBuff,
 | 
			
		||||
//     Display,
 | 
			
		||||
//     DisplayStatusBar,
 | 
			
		||||
//     FontSmallNr,
 | 
			
		||||
//     RadioDriver>
 | 
			
		||||
//     AmTx;
 | 
			
		||||
 | 
			
		||||
CHeater<System::OrgFunc_01_26> Heater;
 | 
			
		||||
CAmRx<System::OrgFunc_01_26> AmRx;
 | 
			
		||||
// CMicVal<System::OrgFunc_01_26, RadioDriver> MicVal;
 | 
			
		||||
// CRssiVal<System::OrgFunc_01_26, RadioDriver> RssiVal;
 | 
			
		||||
 | 
			
		||||
static IMenuElement * const MainMenuElements[] = {&Heater, &AmRx, &RssiSbar};
 | 
			
		||||
 | 
			
		||||
CMenu<System::OrgFunc_01_26,
 | 
			
		||||
      System::OrgData_01_26> Menu(MainMenuElements);
 | 
			
		||||
 | 
			
		||||
static IView * const Views[] = {&RssiSbar, &Menu};
 | 
			
		||||
CViewManager<
 | 
			
		||||
    System::OrgFunc_01_26,
 | 
			
		||||
    System::OrgData_01_26,
 | 
			
		||||
    8, 1, sizeof(Views) / sizeof(*Views)>
 | 
			
		||||
    Manager(Views);
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   // RadioDriver.InterruptHandler();
 | 
			
		||||
   Manager.Handle();
 | 
			
		||||
   Fw.IRQ_SYSTICK();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,90 @@
 | 
			
		|||
ENTRY(Reset_Handler)
 | 
			
		||||
EXTERN(VectorTable)
 | 
			
		||||
 | 
			
		||||
MEMORY
 | 
			
		||||
{
 | 
			
		||||
    RAM (rwx) : ORIGIN = 0x2000138C, LENGTH = 256
 | 
			
		||||
    FLASH (rx)  : ORIGIN = 0x00000000, LENGTH = 60K
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_estack = 0x20001388;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
    . = 0x0;
 | 
			
		||||
    .isr_vectors : 
 | 
			
		||||
    {
 | 
			
		||||
     . = ALIGN(4);
 | 
			
		||||
     KEEP(*(.isr_vectors))
 | 
			
		||||
     . = ALIGN(4);
 | 
			
		||||
    } >FLASH
 | 
			
		||||
 | 
			
		||||
    .org_fw_rest :
 | 
			
		||||
    {
 | 
			
		||||
      . = ALIGN(4);
 | 
			
		||||
      KEEP(*(.org_fw_rest))
 | 
			
		||||
    } > FLASH
 | 
			
		||||
    /*
 | 
			
		||||
    .org_vectors :
 | 
			
		||||
    {
 | 
			
		||||
      . = ALIGN(4);
 | 
			
		||||
      __org_vectors_start = .;
 | 
			
		||||
      KEEP(*(.org_vectors))
 | 
			
		||||
    } > FLASH
 | 
			
		||||
    */
 | 
			
		||||
    .text :
 | 
			
		||||
    {
 | 
			
		||||
        . = ALIGN(4);
 | 
			
		||||
        *(.text)   
 | 
			
		||||
        *(.text*) 
 | 
			
		||||
        *(.rodata)
 | 
			
		||||
        *(.rodata*)
 | 
			
		||||
        KEEP (*(.init))
 | 
			
		||||
        KEEP (*(.fini))
 | 
			
		||||
        . = ALIGN(4);
 | 
			
		||||
    } >FLASH
 | 
			
		||||
 | 
			
		||||
    .preinit_array     :
 | 
			
		||||
    {
 | 
			
		||||
      __preinit_array_start = .;
 | 
			
		||||
      KEEP (*(.preinit_array*))
 | 
			
		||||
      __preinit_array_end = .;
 | 
			
		||||
    } >FLASH
 | 
			
		||||
    .init_array :
 | 
			
		||||
    {
 | 
			
		||||
      __init_array_start = .;
 | 
			
		||||
      KEEP (*(SORT(.init_array.*)))
 | 
			
		||||
      KEEP (*(.init_array*))
 | 
			
		||||
      __init_array_end = .;
 | 
			
		||||
    } >FLASH
 | 
			
		||||
    .fini_array :
 | 
			
		||||
    {
 | 
			
		||||
      PROVIDE_HIDDEN (__fini_array_start = .);
 | 
			
		||||
      KEEP (*(SORT(.fini_array.*)))
 | 
			
		||||
      KEEP (*(.fini_array*))
 | 
			
		||||
      PROVIDE_HIDDEN (__fini_array_end = .);
 | 
			
		||||
      . = ALIGN(4);
 | 
			
		||||
      _flash_data_start = .;
 | 
			
		||||
    } >FLASH
 | 
			
		||||
    
 | 
			
		||||
     _sidata = LOADADDR(.data);
 | 
			
		||||
    .data : AT (_flash_data_start)
 | 
			
		||||
    {
 | 
			
		||||
        . = ALIGN(4);
 | 
			
		||||
        _sdata = .;
 | 
			
		||||
        *(.data)
 | 
			
		||||
        *(.data*)
 | 
			
		||||
        *(.ramsection)
 | 
			
		||||
        _edata = .;
 | 
			
		||||
    } >RAM
 | 
			
		||||
 | 
			
		||||
    .bss :
 | 
			
		||||
    {
 | 
			
		||||
      . = ALIGN(4);
 | 
			
		||||
       _sbss = .;
 | 
			
		||||
        *(.bss)       
 | 
			
		||||
      _ebss = .;
 | 
			
		||||
    } >RAM
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
		Ładowanie…
	
		Reference in New Issue