kopia lustrzana https://github.com/piotr022/UV_K5_playground
Merge branch 'piotr022:main' into main
commit
26726b344b
|
@ -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