Merge branch 'piotr022:main' into main

pull/49/head
Mikhail 2023-07-23 13:05:46 +07:00 zatwierdzone przez GitHub
commit 26726b344b
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
24 zmienionych plików z 945 dodań i 226 usunięć

Wyświetl plik

@ -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)

Wyświetl plik

@ -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))
};

Wyświetl plik

@ -1,5 +1,16 @@
#pragma once
namespace Button
{
enum : unsigned char
{
Ok = 10,
Up = 11,
Down = 12,
Exit = 13,
};
}
template<class KeyboardUserType>
class CKeyboard
{

Wyświetl plik

@ -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();

Wyświetl plik

@ -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

Wyświetl plik

@ -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;
}
}
};

Wyświetl plik

@ -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
{
}
};

Wyświetl plik

@ -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);
}
}
};

111
libs/views/menu.hpp 100644
Wyświetl plik

@ -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;
}
};

Wyświetl plik

@ -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;

Wyświetl plik

@ -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"

Wyświetl plik

@ -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

Wyświetl plik

@ -7,3 +7,4 @@ add_subdirectory(spectrum)
add_subdirectory(spectrum_fagci)
add_subdirectory(t9_texting)
add_subdirectory(messenger)
add_subdirectory(rssi_sbar_hot)

Wyświetl plik

@ -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,

Wyświetl plik

@ -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();
}
};

Wyświetl plik

@ -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}
)

Wyświetl plik

@ -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

Wyświetl plik

@ -0,0 +1,17 @@
#include "registers.hpp"
class CExec final
{
public:
CExec(){};
void InterruptCallback()
{
CheckButtons();
}
private:
void CheckButtons() const
{
}
};

Wyświetl plik

@ -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])

Wyświetl plik

@ -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();
}

Wyświetl plik

@ -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};
};
}

Wyświetl plik

@ -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();
}

Wyświetl plik

@ -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
}