kopia lustrzana https://github.com/piotr022/UV_K5_playground
Porównaj commity
21 Commity
release-58
...
main
Autor | SHA1 | Data |
---|---|---|
Piotr Lewandowski | 37b86a2d22 | |
Piotr Lewandowski (SQ9P) | 9150e39105 | |
Mikhail Yudin | d050bdcf19 | |
Mikhail Yudin | 28817c7d3b | |
Mikhail Yudin | 487b281779 | |
Mikhail Yudin | b56c2eb68a | |
Mikhail Yudin | a8bb4df507 | |
Mikhail Yudin | 3b0508bee8 | |
Mikhail | f1396c3105 | |
Mikhail Yudin | 1d65b2e798 | |
Piotr Lewandowski (SQ9P) | aebb19b637 | |
Andrej | c470b8545e | |
Andrej | c669df83a2 | |
Piotr Lewandowski (SQ9P) | 1e533bc6b8 | |
Mikhail Yudin | 7dcfdd2360 | |
Mikhail Yudin | 3d9171dc9e | |
Piotr Lewandowski | 8d6d99de50 | |
Piotr Lewandowski | 5a999abd10 | |
Dual Tachyon | b4dad1ec2c | |
Piotr Lewandowski (SQ9P) | 74da1c24ec | |
Mikhail Yudin | 00b4452cb2 |
|
@ -1,3 +1,6 @@
|
|||
[submodule "tools/fw_tools"]
|
||||
path = tools/fw_tools
|
||||
url = https://github.com/amnemonic/Quansheng_UV-K5_Firmware.git
|
||||
[submodule "tools/k5prog"]
|
||||
path = tools/k5prog
|
||||
url = git@github.com:sq5bpf/k5prog.git
|
||||
|
|
|
@ -31,6 +31,7 @@ set(COMPILER_OPTIONS -mthumb -mcpu=cortex-m0 -mfpu=auto -mfloat-abi=soft -fno-ex
|
|||
-O${OPTI_FLAG} -Wl,--gc-sections $<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
|
||||
)
|
||||
|
||||
add_subdirectory(tools)
|
||||
add_subdirectory(libs)
|
||||
add_subdirectory(src)
|
||||
|
||||
|
|
38
README.md
38
README.md
|
@ -12,6 +12,44 @@ AFSK messenger with T9 typing support
|
|||
* if message is cleared use **EXIT** to exit messenger view
|
||||
* There is no timeout for the button. If you want to type letters located on the same button in a row, use an asterisk (*) to confirm the selected character
|
||||
|
||||
## src/spectrum_fagci ![auto release build](https://github.com/piotr022/UV_K5_playground/actions/workflows/c-cpp.yml/badge.svg)
|
||||
|
||||
Spectrum scanner by [@fagci](https://github.com/fagci)
|
||||
|
||||
![spectrum_fagci](./docs/spectrum_fagci.gif)
|
||||
|
||||
[more videos](https://youtube.com/playlist?list=PL67vBSofOrHMyXOEhonOzQz5gJzsZFiDq)
|
||||
|
||||
[download mod](https://github.com/piotr022/UV_K5_playground/releases/latest)
|
||||
|
||||
Features:
|
||||
|
||||
* no scan sound
|
||||
* squelch by user input level
|
||||
* 0.1 .. 3.2MHz frequency ranges
|
||||
* ticks by frequency (100,500,1000KHz)
|
||||
* catch signal peak frequency
|
||||
* automatic frequency change step
|
||||
* automatic scan step
|
||||
* frequency blacklist to remove unwanted signals
|
||||
* backlight control
|
||||
|
||||
How to start:
|
||||
|
||||
* set squelch level to 0 or go into monitor mode before enabling mod
|
||||
* to enable spectum view press **flash light button**
|
||||
|
||||
How to operate:
|
||||
|
||||
* press **UP** / **DOWN** key to change frequency
|
||||
* press **1** / **7** to control measurement time (increasing "sensitivity")
|
||||
* press **2** / **8** to to set frequency change step
|
||||
* press **9** / **3** for zoom in / zoom out
|
||||
* press and hold **\*** / **F** to set squelch level
|
||||
* press **5** to toggle backlight
|
||||
* press **0** to remove frequency from sspectrum to scan
|
||||
* press **EXIT** to disable spectrum view
|
||||
|
||||
## src/spectrum ![auto release build](https://github.com/piotr022/UV_K5_playground/actions/workflows/c-cpp.yml/badge.svg)
|
||||
![spectrum](./docs/spectrum.gif)
|
||||
**update**
|
||||
|
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 4.0 MiB |
|
@ -12,6 +12,7 @@ target_include_directories(${NAME} PRIVATE
|
|||
target_sources(${NAME} PRIVATE
|
||||
system.cpp
|
||||
vtable.s
|
||||
api.s
|
||||
)
|
||||
|
||||
target_link_libraries(${NAME}
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
.globl PrintTextOnScreen
|
||||
PrintTextOnScreen = 0x874C + 1;
|
||||
|
||||
.globl DelayMs
|
||||
DelayMs = 0xD0EC + 1;
|
||||
|
||||
.globl DelayUs
|
||||
DelayUs = 0xD100 + 1;
|
||||
|
||||
.globl WriteSerialData
|
||||
WriteSerialData = 0xBE44 + 1;
|
||||
|
||||
.globl BK4819Write
|
||||
BK4819Write = 0xAF00 + 1;
|
||||
|
||||
.globl BK4819Read
|
||||
BK4819Read = 0xA960 + 1;
|
||||
|
||||
.globl FlushFramebufferToScreen
|
||||
FlushFramebufferToScreen = 0xB638 + 1;
|
||||
|
||||
.globl PollKeyboard
|
||||
PollKeyboard = 0xb0b8 + 1;
|
||||
|
||||
.globl FormatString
|
||||
FormatString = 0xC6E8 + 1;
|
||||
|
||||
.globl PrintSmallDigits
|
||||
PrintSmallDigits = 0x870C + 1;
|
||||
|
||||
.globl PrintFrequency
|
||||
PrintFrequency = 0x864C + 1;
|
||||
|
||||
.globl AirCopy72
|
||||
AirCopy72 = 0xA67C + 1;
|
||||
|
||||
.globl AirCopyFskSetup
|
||||
AirCopyFskSetup = 0xA518 + 1;
|
||||
|
||||
.globl BK4819Reset
|
||||
BK4819Reset = 0xa7cc + 1;
|
||||
|
||||
.globl IntDivide
|
||||
IntDivide = 0x128 + 1;
|
||||
|
||||
.globl Strlen
|
||||
Strlen = 0x1c0 + 1;
|
||||
|
||||
.globl BK4819SetChannelBandwidth
|
||||
BK4819SetChannelBandwidth = 0xaa48 + 1;
|
||||
|
||||
.globl BK4819WriteFrequency
|
||||
BK4819WriteFrequency = 0xaabc + 1;
|
||||
|
||||
.globl BK4819SetPaGain
|
||||
BK4819SetPaGain = 0xaad4 + 1;
|
||||
|
||||
.globl BK4819ConfigureAndStartTxFsk
|
||||
BK4819ConfigureAndStartTxFsk = 0x1cd8 + 1;
|
||||
|
||||
.globl BK4819ConfigureAndStartRxFsk
|
||||
BK4819ConfigureAndStartRxFsk = 0xa63c + 1;
|
||||
|
||||
.globl BK4819SetGpio
|
||||
BK4819SetGpio = 0xa794 + 1;
|
||||
|
||||
.globl FlushStatusbarBufferToScreen
|
||||
FlushStatusbarBufferToScreen = 0xb6b0 + 1;
|
||||
|
||||
.globl UpdateStatusBar
|
||||
UpdateStatusBar = 0x9c10 + 1;
|
||||
|
||||
.globl AdcReadout
|
||||
AdcReadout = 0x9d7c + 1;
|
||||
|
||||
.globl SomeAmStuff
|
||||
SomeAmStuff = 0xc158 + 1;
|
||||
|
||||
.globl IRQ_RESET
|
||||
IRQ_RESET = 0xd4 + 1;
|
||||
|
||||
.globl IRQ_SYSTICK
|
||||
IRQ_SYSTICK = 0xc398 + 1;
|
||||
|
||||
.globl ConfigureTrimValuesFromNVR
|
||||
ConfigureTrimValuesFromNVR = 0x20000230 + 1;
|
||||
|
||||
.globl FLASH_ReadNvrWord
|
||||
FLASH_ReadNvrWord = 0x20000214 + 1;
|
||||
|
||||
.globl SystemReset
|
||||
SystemReset = 0x200001f8 + 1;
|
||||
|
||||
.globl FLASH_SetProgramTime
|
||||
FLASH_SetProgramTime = 0x200001d4 + 1;
|
||||
|
||||
.globl FLASH_SetMode
|
||||
FLASH_SetMode = 0x200001b4 + 1;
|
||||
|
||||
.globl FLASH_WakeFromDeepSleep
|
||||
FLASH_WakeFromDeepSleep = 0x20000194 + 1;
|
||||
|
||||
.globl FLASH_SetEraseTime
|
||||
FLASH_SetEraseTime = 0x20000170 + 1;
|
||||
|
||||
.globl FLASH_SetReadMode
|
||||
FLASH_SetReadMode = 0x20000148 + 1;
|
||||
|
||||
.globl FLASH_Set_NVR_SEL
|
||||
FLASH_Set_NVR_SEL = 0x20000128 + 1;
|
||||
|
||||
.globl FLASH_ReadByAPB
|
||||
FLASH_ReadByAPB = 0x200000e8 + 1;
|
||||
|
||||
.globl FLASH_ReadByAHB
|
||||
FLASH_ReadByAHB = 0x200000dc + 1;
|
||||
|
||||
.globl FLASH_Unlock
|
||||
FLASH_Unlock = 0x200000d0 + 1;
|
||||
|
||||
.globl FLASH_Lock
|
||||
FLASH_Lock = 0x200000c4 + 1;
|
||||
|
||||
.globl FLASH_MaskUnlock
|
||||
FLASH_MaskUnlock = 0x200000b0 + 1;
|
||||
|
||||
.globl FLASH_SetMaskSel
|
||||
FLASH_SetMaskSel = 0x20000094 + 1;
|
||||
|
||||
.globl FLASH_MaskLock
|
||||
FLASH_MaskLock = 0x20000080 + 1;
|
||||
|
||||
.globl FLASH_Init
|
||||
FLASH_Init = 0x2000005c + 1;
|
||||
|
||||
.globl FLASH_Start
|
||||
FLASH_Start = 0x20000044 + 1;
|
||||
|
||||
.globl FLASH_IsInitBusy
|
||||
FLASH_IsInitBusy = 0x2000002c + 1;
|
||||
|
||||
.globl FLASH_IsBusy
|
||||
FLASH_IsBusy = 0x20000014 + 1;
|
||||
|
||||
.globl FLASH_RebootToBootloader
|
||||
FLASH_RebootToBootloader = 0x20000000 + 1;
|
||||
|
||||
.globl gDisplayBuffer
|
||||
gDisplayBuffer = 0x20000704;
|
||||
|
||||
.globl gSmallDigs
|
||||
gSmallDigs = 0xD620;
|
||||
|
||||
.globl gSmallLeters
|
||||
gSmallLeters = 0xD348;
|
||||
|
||||
.globl gFlashLightStatus
|
||||
gFlashLightStatus = 0x200003b3;
|
||||
|
||||
.globl gStatusBarData
|
||||
gStatusBarData = 0x20000684;
|
||||
|
||||
.globl gVoltage
|
||||
gVoltage = 0x20000406;
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
#include "registers.hpp"
|
||||
#include "system.hpp"
|
||||
|
||||
namespace Adc
|
||||
{
|
||||
inline unsigned short ReadSingleChannelSync(unsigned char u8Channel)
|
||||
{
|
||||
ADC->ADC_START |= 1;
|
||||
|
||||
while(!(ADC->CHANNEL[u8Channel].STAT & 1))
|
||||
{
|
||||
}
|
||||
|
||||
ADC->ADC_IF = 1 << u8Channel;
|
||||
return ADC->CHANNEL[u8Channel].DATA & 0xFFF;
|
||||
}
|
||||
};
|
|
@ -60,6 +60,24 @@ struct TSysCon
|
|||
unsigned int PLL_ST;
|
||||
};
|
||||
|
||||
struct TAdc
|
||||
{
|
||||
unsigned int ADC_CFG;
|
||||
unsigned int ADC_START;
|
||||
unsigned int ADC_IE;
|
||||
unsigned int ADC_IF;
|
||||
struct
|
||||
{
|
||||
unsigned int STAT;
|
||||
unsigned int DATA;
|
||||
}CHANNEL[16];
|
||||
unsigned int ADC_FIFO_STAT;
|
||||
unsigned int ADC_FIFO_DATA;
|
||||
unsigned int EXTTRIG_SEL;
|
||||
unsigned int ADC_CALIB_OFFSET;
|
||||
unsigned int ADC_CALIB_KD;
|
||||
};
|
||||
|
||||
#define GPIO_BASE 0x400B0000
|
||||
#define GPIO ((TPort*)GPIO_BASE)
|
||||
#define __BKPT(value) __asm volatile ("bkpt "#value)
|
||||
|
@ -94,4 +112,7 @@ struct TSysCon
|
|||
#define SYSCON_BASE 0x40000000
|
||||
#define SYSCON ((TSysCon*)SYSCON_BASE)
|
||||
|
||||
#define ADC_BASE 0x400BA000
|
||||
#define ADC ((TAdc*)ADC_BASE)
|
||||
|
||||
|
||||
|
|
|
@ -21,5 +21,5 @@ void System::CopyDataSection()
|
|||
|
||||
extern "C" unsigned int __wrap___udivsi3(unsigned int a, unsigned int b)
|
||||
{
|
||||
return OrgFunc_01_26.IntDivide(a, b);
|
||||
}
|
||||
return IntDivide(a, b);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,72 @@
|
|||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
void PrintTextOnScreen(const char* U8Text,
|
||||
unsigned int u32StartPixel,
|
||||
unsigned int u32StopPixel,
|
||||
unsigned int u32LineNumber,
|
||||
unsigned int u32PxPerChar,
|
||||
unsigned int u32Centered
|
||||
);
|
||||
|
||||
void DelayMs(unsigned int u32Ms);
|
||||
void DelayUs(unsigned int u32Us);
|
||||
int WriteSerialData(unsigned char* p8Data, unsigned char u8Len);
|
||||
void BK4819Write(unsigned int u32Address, unsigned int u32Data);
|
||||
unsigned int BK4819Read(unsigned int u32Address);
|
||||
void FlushFramebufferToScreen(void);
|
||||
unsigned int PollKeyboard(void);
|
||||
char* FormatString(char *, const char *, ...);
|
||||
void PrintSmallDigits(unsigned int u32Len, const int* p32Number, int s32X, int s32Y);
|
||||
void PrintFrequency(int frequency,int xpos,int ypos,int param_4,int param_5);
|
||||
void AirCopy72(unsigned char*);
|
||||
void AirCopyFskSetup();
|
||||
void BK4819Reset();
|
||||
int IntDivide(int s32Divident, int s32Divisor);
|
||||
int Strlen(const char *string);
|
||||
void BK4819SetChannelBandwidth(bool narrow);
|
||||
void BK4819WriteFrequency(unsigned int u32Frequency);
|
||||
void BK4819SetPaGain(unsigned short u16PaBias, unsigned int u32Frequency);
|
||||
void BK4819ConfigureAndStartTxFsk();
|
||||
void BK4819ConfigureAndStartRxFsk();
|
||||
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);
|
||||
// API available in the SRAM overlay installed by FW
|
||||
void ConfigureTrimValuesFromNVR(void);
|
||||
unsigned int FLASH_ReadNvrWord(unsigned int u32Offset);
|
||||
void SystemReset(void);
|
||||
void FLASH_SetProgramTime(void);
|
||||
void FLASH_SetMode(unsigned int u32Mode);
|
||||
void FLASH_WakeFromDeepSleep(void);
|
||||
void FLASH_SetEraseTime(void);
|
||||
void FLASH_SetReadMode(unsigned int u32Mode);
|
||||
void FLASH_Set_NVR_SEL(unsigned int u32Sel);
|
||||
unsigned int FLASH_ReadByAPB(unsigned int u32Offset);
|
||||
unsigned int FLASH_ReadByAHB(unsigned int u32Offset);
|
||||
void FLASH_Unlock(void);
|
||||
void FLASH_Lock(void);
|
||||
void FLASH_MaskUnlock(void);
|
||||
void FLASH_SetMaskSel(unsigned int u32Mask);
|
||||
void FLASH_MaskLock(void);
|
||||
void FLASH_Init(unsigned int u32ReadMode);
|
||||
void FLASH_Start(void);
|
||||
int FLASH_IsInitBusy(void);
|
||||
int FLASH_IsBusy(void);
|
||||
int FLASH_RebootToBootloader(void);
|
||||
};
|
||||
|
||||
extern unsigned char gDisplayBuffer[];
|
||||
extern unsigned char gSmallDigs[];
|
||||
extern unsigned char gSmallLeters[];
|
||||
extern unsigned char gFlashLightStatus;
|
||||
extern unsigned char gStatusBarData[];
|
||||
extern unsigned short gVoltage;
|
||||
|
||||
namespace System
|
||||
{
|
||||
using VoidFxPointer = void(*)(void);
|
||||
|
@ -32,94 +100,6 @@ namespace System
|
|||
};
|
||||
|
||||
void CopyDataSection();
|
||||
|
||||
struct TOrgFunctions
|
||||
{
|
||||
void(*PrintTextOnScreen)(const char* U8Text,
|
||||
unsigned int u32StartPixel,
|
||||
unsigned int u32StopPixel,
|
||||
unsigned int u32LineNumber,
|
||||
unsigned int u32PxPerChar,
|
||||
unsigned int u32Centered
|
||||
);
|
||||
|
||||
void(*DelayMs)(unsigned int u32Ms);
|
||||
void(*DelayUs)(unsigned int u32Us);
|
||||
int(*WriteSerialData)(unsigned char* p8Data, unsigned char u8Len);
|
||||
void(*BK4819Write)(unsigned int u32Address, unsigned int u32Data);
|
||||
unsigned int(*BK4819Read)(unsigned int u32Address);
|
||||
void(*FlushFramebufferToScreen)(void);
|
||||
unsigned int(*PollKeyboard)(void);
|
||||
char* (*FormatString)(char *, const char *, ...);
|
||||
void(*PrintSmallDigits)(unsigned int u32Len, const int* p32Number, int s32X, int s32Y);
|
||||
void(*PrintFrequency)(int frequency,int xpos,int ypos,int param_4,int param_5);
|
||||
void(*AirCopy72)(unsigned char*);
|
||||
void(*AirCopyFskSetup)();
|
||||
void(*BK4819Reset)();
|
||||
int(*IntDivide)(int s32Divident, int s32Divisor);
|
||||
void(*BK4819WriteFrequency)(unsigned int u32Frequency);
|
||||
void(*BK4819SetPaGain)(unsigned short u16PaBias, unsigned int u32Frequency);
|
||||
void(*BK4819ConfigureAndStartTxFsk)();
|
||||
void(*BK4819ConfigureAndStartRxFsk)();
|
||||
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);
|
||||
|
||||
};
|
||||
|
||||
struct TOrgData
|
||||
{
|
||||
unsigned char* pDisplayBuffer;
|
||||
unsigned char* pSmallDigs;
|
||||
unsigned char* pSmallLeters;
|
||||
unsigned char* p8FlashLightStatus;
|
||||
unsigned char* pStatusBarData;
|
||||
unsigned short* p16Voltage;
|
||||
};
|
||||
|
||||
inline const TOrgFunctions OrgFunc_01_26 =
|
||||
{
|
||||
.PrintTextOnScreen = (decltype(TOrgFunctions::PrintTextOnScreen))(0x874C + 1),
|
||||
.DelayMs = (decltype(TOrgFunctions::DelayMs)) (0xD0EC + 1),
|
||||
.DelayUs = (decltype(TOrgFunctions::DelayUs)) (0xD100 + 1),
|
||||
.WriteSerialData = (int(*)(unsigned char*, unsigned char))(0xBE44 + 1),
|
||||
.BK4819Write = (decltype(TOrgFunctions::BK4819Write) (0xAF00 + 1)),
|
||||
.BK4819Read = (decltype(TOrgFunctions::BK4819Read) (0xA960 + 1)),
|
||||
.FlushFramebufferToScreen = (decltype(TOrgFunctions::FlushFramebufferToScreen) (0xB638 + 1)),
|
||||
.PollKeyboard = (decltype(TOrgFunctions::PollKeyboard) (0xb0b8 + 1)),
|
||||
.FormatString = (decltype(TOrgFunctions::FormatString) (0xC6E8 + 1)),
|
||||
.PrintSmallDigits = (decltype(TOrgFunctions::PrintSmallDigits) (0x870C + 1)),
|
||||
.PrintFrequency = (decltype(TOrgFunctions::PrintFrequency) (0x864C + 1)),
|
||||
.AirCopy72 = (decltype(TOrgFunctions::AirCopy72) (0xA67C + 1)),
|
||||
.AirCopyFskSetup = (decltype(TOrgFunctions::AirCopyFskSetup) (0xA518 + 1)),
|
||||
.BK4819Reset = (decltype(TOrgFunctions::BK4819Reset) (0xa7cc + 1)),
|
||||
.IntDivide = (decltype(TOrgFunctions::IntDivide) (0x128 + 1)),
|
||||
.BK4819WriteFrequency = (decltype(TOrgFunctions::BK4819WriteFrequency) (0xaabc + 1)),
|
||||
.BK4819SetPaGain = (decltype(TOrgFunctions::BK4819SetPaGain) (0xaad4 + 1)),
|
||||
.BK4819ConfigureAndStartTxFsk = (decltype(TOrgFunctions::BK4819ConfigureAndStartTxFsk) (0x1cd8 + 1)),
|
||||
.BK4819ConfigureAndStartRxFsk = (decltype(TOrgFunctions::BK4819ConfigureAndStartRxFsk) (0xa63c + 1)),
|
||||
.BK4819SetGpio = (decltype(TOrgFunctions::BK4819SetGpio) (0xa794 + 1)),
|
||||
.FlushStatusbarBufferToScreen = (decltype(TOrgFunctions::FlushStatusbarBufferToScreen) (0xb6b0 + 1)),
|
||||
.UpdateStatusBar = (decltype(TOrgFunctions::UpdateStatusBar) (0x9c10 + 1)),
|
||||
.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))
|
||||
};
|
||||
|
||||
inline const TOrgData OrgData_01_26 =
|
||||
{
|
||||
.pDisplayBuffer = (decltype(TOrgData::pDisplayBuffer)) 0x20000704,
|
||||
.pSmallDigs = (decltype(TOrgData::pSmallDigs)) 0xD620,
|
||||
.pSmallLeters = (decltype(TOrgData::pSmallLeters)) 0xD348,
|
||||
.p8FlashLightStatus = (decltype(TOrgData::p8FlashLightStatus)) 0x200003b3,
|
||||
.pStatusBarData = (decltype(TOrgData::pStatusBarData)) 0x20000684,
|
||||
.p16Voltage = (decltype(TOrgData::p16Voltage)) 0x20000406,
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" void __libc_init_array();
|
||||
extern "C" void __libc_init_array();
|
||||
|
|
481
libs/lcd/lcd.hpp
481
libs/lcd/lcd.hpp
|
@ -1,275 +1,280 @@
|
|||
#pragma once
|
||||
#include <type_traits>
|
||||
#include <string.h>
|
||||
#include <type_traits>
|
||||
#include "system.hpp"
|
||||
|
||||
struct ILcd
|
||||
{
|
||||
virtual void UpdateScreen() = 0;
|
||||
struct ILcd {
|
||||
virtual void UpdateScreen() = 0;
|
||||
};
|
||||
|
||||
template <unsigned short _SizeX, unsigned short _SizeY, unsigned char _LineHeight>
|
||||
struct IBitmap
|
||||
{
|
||||
constexpr IBitmap(const unsigned char *_pBuffStart) : pBuffStart(_pBuffStart){};
|
||||
static constexpr auto SizeX = _SizeX;
|
||||
static constexpr auto SizeY = _SizeY;
|
||||
static constexpr auto LineHeight = _LineHeight;
|
||||
static constexpr auto Lines = _SizeX / _LineHeight;
|
||||
static constexpr unsigned short GetCoursorPosition(unsigned char u8Line, unsigned char u8XPos)
|
||||
{
|
||||
return (u8Line * SizeX) + u8XPos;
|
||||
}
|
||||
template <unsigned short _SizeX, unsigned short _SizeY,
|
||||
unsigned char _LineHeight>
|
||||
struct IBitmap {
|
||||
constexpr IBitmap(const unsigned char *_pBuffStart)
|
||||
: pBuffStart(_pBuffStart){};
|
||||
static constexpr auto SizeX = _SizeX;
|
||||
static constexpr auto SizeY = _SizeY;
|
||||
static constexpr auto LineHeight = _LineHeight;
|
||||
static constexpr auto Lines = _SizeX / _LineHeight;
|
||||
static constexpr unsigned short GetCoursorPosition(unsigned char u8Line,
|
||||
unsigned char u8XPos) {
|
||||
return (u8Line * SizeX) + u8XPos;
|
||||
}
|
||||
|
||||
virtual bool GetPixel(unsigned char u8X, unsigned char u8Y) const = 0;
|
||||
virtual void SetPixel(unsigned char u8X, unsigned char u8Y) const = 0;
|
||||
virtual void *GetCoursorData(unsigned short u16CoursorPosition) const { return nullptr; }
|
||||
virtual void ClearAll() = 0;
|
||||
const unsigned char *pBuffStart;
|
||||
virtual bool GetPixel(unsigned char u8X, unsigned char u8Y) const = 0;
|
||||
virtual void SetPixel(unsigned char u8X, unsigned char u8Y) const = 0;
|
||||
virtual void *GetCoursorData(unsigned short u16CoursorPosition) const {
|
||||
return nullptr;
|
||||
}
|
||||
virtual void ClearAll() = 0;
|
||||
const unsigned char *pBuffStart;
|
||||
};
|
||||
|
||||
struct IFont
|
||||
{
|
||||
virtual bool GetPixel(char c8Character, unsigned char u8X, unsigned char u8Y) const = 0;
|
||||
virtual unsigned char *GetRaw(char c8Character) const = 0;
|
||||
virtual unsigned char GetSizeX(char c8Character) const = 0;
|
||||
virtual unsigned char GetSizeY(char c8Character) const = 0;
|
||||
struct IFont {
|
||||
virtual bool GetPixel(char c8Character, unsigned char u8X,
|
||||
unsigned char u8Y) const = 0;
|
||||
virtual unsigned char *GetRaw(char c8Character) const = 0;
|
||||
virtual unsigned char GetSizeX(char c8Character) const = 0;
|
||||
virtual unsigned char GetSizeY(char c8Character) const = 0;
|
||||
};
|
||||
|
||||
template <class BitmapType>
|
||||
class CDisplay
|
||||
{
|
||||
template <class BitmapType> class CDisplay {
|
||||
public:
|
||||
constexpr CDisplay(BitmapType &_Bitmap)
|
||||
: Bitmap(_Bitmap), pCurrentFont(nullptr), u16CoursorPosition(0)
|
||||
{
|
||||
}
|
||||
constexpr CDisplay(BitmapType &_Bitmap)
|
||||
: Bitmap(_Bitmap), pCurrentFont(nullptr), u16CoursorPosition(0) {}
|
||||
|
||||
void SetCoursor(unsigned char u8Line, unsigned char u8X) const
|
||||
{
|
||||
u16CoursorPosition = (u8Line * Bitmap.SizeX) + u8X;
|
||||
}
|
||||
void SetCoursor(unsigned char u8Line, unsigned char u8X) const {
|
||||
u16CoursorPosition = (u8Line * Bitmap.SizeX) + u8X;
|
||||
}
|
||||
|
||||
void SetCoursorXY(unsigned char x, unsigned char y) const
|
||||
{
|
||||
u16CoursorPosition = x + (y << 4);
|
||||
}
|
||||
void SetCoursorXY(unsigned char x, unsigned char y) const {
|
||||
u16CoursorPosition = x + (y << 4);
|
||||
}
|
||||
|
||||
void SetFont(const IFont *pFont) const
|
||||
{
|
||||
pCurrentFont = pFont;
|
||||
}
|
||||
void SetFont(const IFont *pFont) const { pCurrentFont = pFont; }
|
||||
|
||||
void DrawLine(int sx, int ex, int ny)
|
||||
{
|
||||
for (int i = sx; i <= ex; i++)
|
||||
{
|
||||
if (i < Bitmap.SizeX && ny < Bitmap.SizeY)
|
||||
{
|
||||
Bitmap.SetPixel(i, ny);
|
||||
}
|
||||
void DrawLine(int sx, int ex, int ny) {
|
||||
for (int i = sx; i <= ex; i++) {
|
||||
if (i < Bitmap.SizeX && ny < Bitmap.SizeY) {
|
||||
Bitmap.SetPixel(i, ny);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawHLine(int sy, int ey, int nx, bool bCropped = false)
|
||||
{
|
||||
for (int i = sy; i <= ey; i++)
|
||||
{
|
||||
if (i < Bitmap.SizeY && nx < Bitmap.SizeX && (!bCropped || i % 2))
|
||||
{
|
||||
Bitmap.SetPixel(nx, i);
|
||||
}
|
||||
void DrawHLine(int sy, int ey, int nx, bool bCropped = false) {
|
||||
for (int i = sy; i <= ey; i++) {
|
||||
if (i < Bitmap.SizeY && nx < Bitmap.SizeX && (!bCropped || i % 2)) {
|
||||
Bitmap.SetPixel(nx, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCircle(unsigned char cx, unsigned char cy, unsigned int r, bool bFilled = false)
|
||||
{
|
||||
int x = 0;
|
||||
int y = r;
|
||||
int d = 3 - 2 * r;
|
||||
if (!r)
|
||||
return;
|
||||
void DrawCircle(unsigned char cx, unsigned char cy, unsigned int r,
|
||||
bool bFilled = false) {
|
||||
int x = 0;
|
||||
int y = r;
|
||||
int d = 3 - 2 * r;
|
||||
if (!r)
|
||||
return;
|
||||
|
||||
while (y >= x)
|
||||
{
|
||||
// when bFilled is true, draw lines to fill the circle
|
||||
if (bFilled)
|
||||
{
|
||||
DrawLine(cx - x, cx + x, cy - y);
|
||||
DrawLine(cx - y, cx + y, cy - x);
|
||||
DrawLine(cx - x, cx + x, cy + y);
|
||||
DrawLine(cx - y, cx + y, cy + x);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cx + x < Bitmap.SizeX && cy + y < Bitmap.SizeY)
|
||||
Bitmap.SetPixel(cx + x, cy - y); // 1st quarter
|
||||
if (cx + y < Bitmap.SizeX && cy + x < Bitmap.SizeY)
|
||||
Bitmap.SetPixel(cx + y, cy - x); // 2nd quarter
|
||||
if (cx - x >= 0 && cy + y < Bitmap.SizeY)
|
||||
Bitmap.SetPixel(cx - x, cy - y); // 3rd quarter
|
||||
if (cx - y >= 0 && cy + x < Bitmap.SizeY)
|
||||
Bitmap.SetPixel(cx - y, cy - x); // 4th quarter
|
||||
if (cx + x < Bitmap.SizeX && cy + y < Bitmap.SizeY)
|
||||
Bitmap.SetPixel(cx + x, cy + y); // 5th quarter
|
||||
if (cx + y < Bitmap.SizeX && cy - x >= 0)
|
||||
Bitmap.SetPixel(cx + y, cy + x); // 6th quarter
|
||||
if (cx - x >= 0 && cy - y >= 0)
|
||||
Bitmap.SetPixel(cx - x, cy + y); // 7th quarter
|
||||
if (cx - y >= 0 && cy - x >= 0)
|
||||
Bitmap.SetPixel(cx - y, cy + x); // 8th quarter
|
||||
}
|
||||
x++;
|
||||
if (d < 0)
|
||||
d += 4 * x + 6;
|
||||
else
|
||||
{
|
||||
y--;
|
||||
d += 4 * (x - y) + 10;
|
||||
}
|
||||
while (y >= x) {
|
||||
// when bFilled is true, draw lines to fill the circle
|
||||
if (bFilled) {
|
||||
DrawLine(cx - x, cx + x, cy - y);
|
||||
DrawLine(cx - y, cx + y, cy - x);
|
||||
DrawLine(cx - x, cx + x, cy + y);
|
||||
DrawLine(cx - y, cx + y, cy + x);
|
||||
} else {
|
||||
if (cx + x < Bitmap.SizeX && cy + y < Bitmap.SizeY)
|
||||
Bitmap.SetPixel(cx + x, cy - y); // 1st quarter
|
||||
if (cx + y < Bitmap.SizeX && cy + x < Bitmap.SizeY)
|
||||
Bitmap.SetPixel(cx + y, cy - x); // 2nd quarter
|
||||
if (cx - x >= 0 && cy + y < Bitmap.SizeY)
|
||||
Bitmap.SetPixel(cx - x, cy - y); // 3rd quarter
|
||||
if (cx - y >= 0 && cy + x < Bitmap.SizeY)
|
||||
Bitmap.SetPixel(cx - y, cy - x); // 4th quarter
|
||||
if (cx + x < Bitmap.SizeX && cy + y < Bitmap.SizeY)
|
||||
Bitmap.SetPixel(cx + x, cy + y); // 5th quarter
|
||||
if (cx + y < Bitmap.SizeX && cy - x >= 0)
|
||||
Bitmap.SetPixel(cx + y, cy + x); // 6th quarter
|
||||
if (cx - x >= 0 && cy - y >= 0)
|
||||
Bitmap.SetPixel(cx - x, cy + y); // 7th quarter
|
||||
if (cx - y >= 0 && cy - x >= 0)
|
||||
Bitmap.SetPixel(cx - y, cy + x); // 8th quarter
|
||||
}
|
||||
}
|
||||
|
||||
void DrawRectangle(unsigned char sx, unsigned char sy, unsigned char width, unsigned char height, bool bFilled)
|
||||
{
|
||||
unsigned char maxX = (sx + width < Bitmap.SizeX) ? sx + width : Bitmap.SizeX;
|
||||
unsigned char maxY = (sy + height < Bitmap.SizeY) ? sy + height : Bitmap.SizeY;
|
||||
|
||||
// Draw vertical lines
|
||||
for (unsigned char y = sy; y < maxY; y++)
|
||||
{
|
||||
Bitmap.SetPixel(sx, y);
|
||||
Bitmap.SetPixel(maxX - 1, y);
|
||||
x++;
|
||||
if (d < 0)
|
||||
d += 4 * x + 6;
|
||||
else {
|
||||
y--;
|
||||
d += 4 * (x - y) + 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw horizontal lines
|
||||
for (unsigned char x = sx; x < maxX; x++)
|
||||
{
|
||||
Bitmap.SetPixel(x, sy);
|
||||
Bitmap.SetPixel(x, maxY - 1);
|
||||
void DrawRectangle(unsigned char sx, unsigned char sy, unsigned char width,
|
||||
unsigned char height, bool bFilled) {
|
||||
unsigned char maxX =
|
||||
(sx + width < Bitmap.SizeX) ? sx + width : Bitmap.SizeX;
|
||||
unsigned char maxY =
|
||||
(sy + height < Bitmap.SizeY) ? sy + height : Bitmap.SizeY;
|
||||
|
||||
// Draw vertical lines
|
||||
for (unsigned char y = sy; y < maxY; y++) {
|
||||
Bitmap.SetPixel(sx, y);
|
||||
Bitmap.SetPixel(maxX - 1, y);
|
||||
}
|
||||
|
||||
// Draw horizontal lines
|
||||
for (unsigned char x = sx; x < maxX; x++) {
|
||||
Bitmap.SetPixel(x, sy);
|
||||
Bitmap.SetPixel(x, maxY - 1);
|
||||
}
|
||||
|
||||
// If filled, draw horizontal lines within the rectangle
|
||||
if (bFilled) {
|
||||
for (unsigned char x = sx + 1; x < maxX - 1; x++) {
|
||||
for (unsigned char y = sy + 1; y < maxY - 1; y++) {
|
||||
Bitmap.SetPixel(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If filled, draw horizontal lines within the rectangle
|
||||
if (bFilled)
|
||||
{
|
||||
for (unsigned char x = sx + 1; x < maxX - 1; x++)
|
||||
{
|
||||
for (unsigned char y = sy + 1; y < maxY - 1; y++)
|
||||
{
|
||||
Bitmap.SetPixel(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char PrintCharacter(const char c8Character) const
|
||||
{
|
||||
if (!pCurrentFont)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto *const pFontRawData = pCurrentFont->GetRaw(c8Character);
|
||||
auto *pCoursorPosition = Bitmap.GetCoursorData(u16CoursorPosition);
|
||||
auto const CopySize = pCurrentFont->GetSizeY(c8Character) * (BitmapType::LineHeight / 8);
|
||||
if (pCoursorPosition && !(BitmapType::LineHeight % 8))
|
||||
{
|
||||
if (pFontRawData)
|
||||
memcpy(pCoursorPosition, pFontRawData, CopySize);
|
||||
else
|
||||
memset(pCoursorPosition, 0, CopySize);
|
||||
}
|
||||
|
||||
u16CoursorPosition += pCurrentFont->GetSizeY(c8Character);
|
||||
unsigned char PrintCharacter(const char c8Character) const {
|
||||
if (!pCurrentFont) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Print(const char *C8String) const
|
||||
{
|
||||
for (unsigned char i = 0; i < strlen(C8String); i++)
|
||||
{
|
||||
PrintCharacter(C8String[i]);
|
||||
const auto *const pFontRawData = pCurrentFont->GetRaw(c8Character);
|
||||
auto *pCoursorPosition = Bitmap.GetCoursorData(u16CoursorPosition);
|
||||
auto const CopySize =
|
||||
pCurrentFont->GetSizeY(c8Character) * (BitmapType::LineHeight / 8);
|
||||
if (pCoursorPosition && !(BitmapType::LineHeight % 8)) {
|
||||
if (pFontRawData)
|
||||
memcpy(pCoursorPosition, pFontRawData, CopySize);
|
||||
else
|
||||
memset(pCoursorPosition, 0, CopySize);
|
||||
}
|
||||
|
||||
u16CoursorPosition += pCurrentFont->GetSizeY(c8Character);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Print(const char *C8String) const {
|
||||
for (unsigned char i = 0; i < Strlen(C8String); i++) {
|
||||
PrintCharacter(C8String[i]);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char PrintFixedDigtsNumer(int s32Number, unsigned char u8Digts) {
|
||||
char U8NumBuff[32];
|
||||
memset(U8NumBuff, 0, sizeof(U8NumBuff));
|
||||
|
||||
char *pString = U8NumBuff + u8Digts;
|
||||
*pString = '\0';
|
||||
|
||||
if (s32Number < 0) {
|
||||
U8NumBuff[0] = '-';
|
||||
s32Number = -s32Number;
|
||||
}
|
||||
|
||||
while (u8Digts--) {
|
||||
*--pString = '0' + (s32Number % 10);
|
||||
s32Number /= 10;
|
||||
}
|
||||
|
||||
Print(U8NumBuff);
|
||||
return u8Digts * pCurrentFont->GetSizeX('0');
|
||||
}
|
||||
|
||||
static constexpr int powersOfTen[9] = {
|
||||
1, // 10^0
|
||||
10, // 10^1
|
||||
100, // 10^2
|
||||
1000, // 10^3
|
||||
10000, // 10^4
|
||||
100000, // 10^5
|
||||
1000000, // 10^6
|
||||
10000000, // 10^7
|
||||
100000000 // 10^8
|
||||
};
|
||||
void PrintFixedDigitsNumber2(int s32Number, unsigned char u8DigsToCut = 2,
|
||||
unsigned char u8FixedDigtsCnt = 0) {
|
||||
char U8NumBuff[11] = {0}; // 9 digits, sign, and null terminator
|
||||
int startIdx = 0;
|
||||
bool isNegative = false;
|
||||
|
||||
if (s32Number < 0) {
|
||||
PrintCharacter('-');
|
||||
// U8NumBuff[0] = '-';
|
||||
s32Number = -s32Number;
|
||||
// isNegative = true;
|
||||
}
|
||||
|
||||
for (int i = 8; i >= u8DigsToCut;
|
||||
--i) // assuming powersOfTen is an array of powers of 10
|
||||
{
|
||||
int digit = 0;
|
||||
while (s32Number >= powersOfTen[i]) {
|
||||
s32Number -= powersOfTen[i];
|
||||
++digit;
|
||||
}
|
||||
}
|
||||
U8NumBuff[isNegative + (8 - i)] = '0' + digit;
|
||||
|
||||
unsigned char PrintFixedDigtsNumer(int s32Number, unsigned char u8Digts)
|
||||
{
|
||||
char U8NumBuff[32];
|
||||
memset(U8NumBuff, 0, sizeof(U8NumBuff));
|
||||
// We found the first non-zero digit
|
||||
if (digit != 0 && startIdx == (isNegative ? 1 : 0))
|
||||
startIdx = isNegative + (8 - i);
|
||||
}
|
||||
|
||||
char *pString = U8NumBuff + u8Digts;
|
||||
*pString = '\0';
|
||||
// If the number was 0, we write a single 0.
|
||||
if (startIdx == (isNegative ? 1 : 0))
|
||||
U8NumBuff[isNegative] = '0';
|
||||
|
||||
if (s32Number < 0)
|
||||
{
|
||||
U8NumBuff[0] = '-';
|
||||
s32Number = -s32Number;
|
||||
// Print the string from the start index
|
||||
if (u8FixedDigtsCnt) {
|
||||
startIdx = 9 - u8DigsToCut - u8FixedDigtsCnt;
|
||||
}
|
||||
|
||||
Print(U8NumBuff + startIdx);
|
||||
}
|
||||
void PrintFixedDigitsNumber3(int s32Number, unsigned char u8DigsToCut = 2,
|
||||
unsigned char u8FixedDigtsCnt = 0,
|
||||
unsigned char pointAt = 128) {
|
||||
char U8NumBuff[11] = {0}; // 9 digits, sign, and null terminator
|
||||
unsigned char startIdx = 0;
|
||||
|
||||
for (unsigned char i = 8; i >= u8DigsToCut; --i) {
|
||||
int digit = 0;
|
||||
while (s32Number >= powersOfTen[i]) {
|
||||
s32Number -= powersOfTen[i];
|
||||
++digit;
|
||||
}
|
||||
U8NumBuff[8 - i] = '0' + digit;
|
||||
|
||||
while (u8Digts--)
|
||||
{
|
||||
*--pString = '0' + (s32Number % 10);
|
||||
s32Number /= 10;
|
||||
// We found the first non-zero digit
|
||||
if (digit != 0 && startIdx == 0)
|
||||
startIdx = 8 - i;
|
||||
}
|
||||
|
||||
// Print the string from the start index
|
||||
startIdx = 9 - u8DigsToCut - u8FixedDigtsCnt;
|
||||
|
||||
const char *str = U8NumBuff + startIdx;
|
||||
const char len = Strlen(str);
|
||||
const char dot[1] = {64};
|
||||
for (unsigned char i = 0; i < len; i++) {
|
||||
if (pointAt == len - i) {
|
||||
auto *pCoursorPosition = Bitmap.GetCoursorData(u16CoursorPosition + 1);
|
||||
memcpy(pCoursorPosition, dot, 1);
|
||||
u16CoursorPosition += 2;
|
||||
}
|
||||
|
||||
Print(U8NumBuff);
|
||||
return u8Digts * pCurrentFont->GetSizeX('0');
|
||||
}
|
||||
|
||||
static constexpr int powersOfTen[9] = {
|
||||
1, // 10^0
|
||||
10, // 10^1
|
||||
100, // 10^2
|
||||
1000, // 10^3
|
||||
10000, // 10^4
|
||||
100000, // 10^5
|
||||
1000000, // 10^6
|
||||
10000000, // 10^7
|
||||
100000000 // 10^8
|
||||
};
|
||||
void PrintFixedDigitsNumber2(int s32Number, unsigned char u8DigsToCut = 2, unsigned char u8FixedDigtsCnt = 0)
|
||||
{
|
||||
char U8NumBuff[11] = {0}; // 9 digits, sign, and null terminator
|
||||
int startIdx = 0;
|
||||
bool isNegative = false;
|
||||
|
||||
if (s32Number < 0)
|
||||
{
|
||||
PrintCharacter('-');
|
||||
// U8NumBuff[0] = '-';
|
||||
s32Number = -s32Number;
|
||||
// isNegative = true;
|
||||
}
|
||||
|
||||
for (int i = 8; i >= u8DigsToCut; --i) // assuming powersOfTen is an array of powers of 10
|
||||
{
|
||||
int digit = 0;
|
||||
while (s32Number >= powersOfTen[i])
|
||||
{
|
||||
s32Number -= powersOfTen[i];
|
||||
++digit;
|
||||
}
|
||||
U8NumBuff[isNegative + (8 - i)] = '0' + digit;
|
||||
|
||||
// We found the first non-zero digit
|
||||
if (digit != 0 && startIdx == (isNegative ? 1 : 0))
|
||||
startIdx = isNegative + (8 - i);
|
||||
}
|
||||
|
||||
// If the number was 0, we write a single 0.
|
||||
if (startIdx == (isNegative ? 1 : 0))
|
||||
U8NumBuff[isNegative] = '0';
|
||||
|
||||
// Print the string from the start index
|
||||
if (u8FixedDigtsCnt)
|
||||
{
|
||||
startIdx = 9 - u8DigsToCut - u8FixedDigtsCnt;
|
||||
}
|
||||
|
||||
Print(U8NumBuff + startIdx);
|
||||
}
|
||||
PrintCharacter(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const BitmapType &Bitmap;
|
||||
mutable const IFont *pCurrentFont;
|
||||
mutable unsigned short u16CoursorPosition;
|
||||
const BitmapType &Bitmap;
|
||||
mutable const IFont *pCurrentFont;
|
||||
mutable unsigned short u16CoursorPosition;
|
||||
};
|
||||
|
|
|
@ -3,239 +3,286 @@
|
|||
#include "registers.hpp"
|
||||
#include "system.hpp"
|
||||
#include <functional>
|
||||
#include <cstring>
|
||||
|
||||
static constexpr auto operator""_Hz(unsigned long long Hertz) {
|
||||
return Hertz / 10;
|
||||
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""_KHz(unsigned long long KiloHertz)
|
||||
{
|
||||
return KiloHertz * 1000_Hz;
|
||||
}
|
||||
|
||||
static constexpr auto operator""_MHz(unsigned long long KiloHertz) {
|
||||
return KiloHertz * 1000_KHz;
|
||||
static constexpr auto operator""_MHz(unsigned long long KiloHertz)
|
||||
{
|
||||
return KiloHertz * 1000_KHz;
|
||||
}
|
||||
|
||||
namespace Radio {
|
||||
enum eIrq : unsigned short {
|
||||
FifoAlmostFull = 1 << 12,
|
||||
RxDone = 1 << 13,
|
||||
};
|
||||
namespace Radio
|
||||
{
|
||||
enum eIrq : unsigned short
|
||||
{
|
||||
FifoAlmostFull = 1 << 12,
|
||||
RxDone = 1 << 13,
|
||||
};
|
||||
|
||||
enum class eFskMode : unsigned char {
|
||||
Fsk1200 = 0,
|
||||
Ffsk1200_1200_1800,
|
||||
Ffsk1200_1200_2400,
|
||||
NoaaSame,
|
||||
ModesCount,
|
||||
};
|
||||
enum class eFskMode : unsigned char
|
||||
{
|
||||
Fsk1200 = 0,
|
||||
Ffsk1200_1200_1800,
|
||||
Ffsk1200_1200_2400,
|
||||
NoaaSame,
|
||||
ModesCount,
|
||||
};
|
||||
|
||||
struct TFskModeBits {
|
||||
unsigned char u8TxModeBits;
|
||||
unsigned char u8RxBandWidthBits;
|
||||
unsigned char u8RxModeBits;
|
||||
};
|
||||
struct TFskModeBits
|
||||
{
|
||||
unsigned char u8TxModeBits;
|
||||
unsigned char u8RxBandWidthBits;
|
||||
unsigned char u8RxModeBits;
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
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
|
||||
};
|
||||
|
||||
enum class eState : unsigned char {
|
||||
Idle,
|
||||
RxPending,
|
||||
};
|
||||
enum class eState : unsigned char
|
||||
{
|
||||
Idle,
|
||||
RxPending,
|
||||
};
|
||||
|
||||
using CallbackRxDoneType = CCallback<void, unsigned char, bool>;
|
||||
template <const System::TOrgFunctions &Fw> class CBK4819 {
|
||||
CallbackRxDoneType CallbackRxDone;
|
||||
unsigned char *p8RxBuff;
|
||||
unsigned char u8RxBuffSize;
|
||||
using CallbackRxDoneType = CCallback<void, unsigned char, bool>;
|
||||
class CBK4819
|
||||
{
|
||||
CallbackRxDoneType CallbackRxDone;
|
||||
unsigned char *p8RxBuff;
|
||||
unsigned char u8RxBuffSize;
|
||||
|
||||
public:
|
||||
CBK4819() : State(eState::Idle), u16RxDataLen(0){};
|
||||
public:
|
||||
CBK4819() : State(eState::Idle), u16RxDataLen(0){};
|
||||
|
||||
// void SetFrequency(unsigned int u32FrequencyD10)
|
||||
// {
|
||||
// Fw.BK4819WriteFrequency(u32FrequencyD10);
|
||||
// }
|
||||
// void SetFrequency(unsigned int u32FrequencyD10)
|
||||
// {
|
||||
// BK4819WriteFrequency(u32FrequencyD10);
|
||||
// }
|
||||
|
||||
static unsigned int GetFrequency() {
|
||||
return (Fw.BK4819Read(0x39) << 16) | Fw.BK4819Read(0x38);
|
||||
}
|
||||
|
||||
static signed short GetRssi() {
|
||||
short s16Rssi = ((Fw.BK4819Read(0x67) >> 1) & 0xFF);
|
||||
return s16Rssi - 160;
|
||||
}
|
||||
|
||||
bool IsTx() { return Fw.BK4819Read(0x30) & 0b10; }
|
||||
|
||||
bool IsSqlOpen() { return Fw.BK4819Read(0x0C) & 0b10; }
|
||||
|
||||
static 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 Fw.BK4819Read(0x6F) & 0b1111111; }
|
||||
|
||||
static void ToggleAFDAC(bool enabled) {
|
||||
auto Reg = Fw.BK4819Read(0x30);
|
||||
Reg &= ~(1 << 9);
|
||||
if (enabled)
|
||||
Reg |= (1 << 9);
|
||||
Fw.BK4819Write(0x30, Reg);
|
||||
}
|
||||
|
||||
void SendSyncAirCopyMode72(unsigned char *p8Data) {
|
||||
Fw.BK4819ConfigureAndStartTxFsk();
|
||||
Fw.AirCopyFskSetup();
|
||||
Fw.AirCopy72(p8Data);
|
||||
Fw.BK4819SetGpio(1, false);
|
||||
}
|
||||
|
||||
void DisablePa() { Fw.BK4819Write(0x30, Fw.BK4819Read(0x30) & ~0b1010); }
|
||||
|
||||
void SetFskMode(eFskMode Mode) {
|
||||
auto const &ModeParams = ModesBits[(int)Mode];
|
||||
auto Reg58 = Fw.BK4819Read(0x58);
|
||||
Reg58 &= ~((0b111 << 1) | (0b111 << 10) | (0b111 << 13));
|
||||
Reg58 |= (ModeParams.u8RxBandWidthBits << 1) |
|
||||
(ModeParams.u8RxModeBits << 10) | (ModeParams.u8TxModeBits << 13);
|
||||
Fw.BK4819Write(0x58, 0);
|
||||
Fw.BK4819Write(0x58, Reg58);
|
||||
}
|
||||
|
||||
void FixIrqEnRegister() // original firmware overrides IRQ_EN reg, so we need
|
||||
// to reenable it
|
||||
{
|
||||
auto const OldIrqEnReg = Fw.BK4819Read(0x3F);
|
||||
if ((OldIrqEnReg & (eIrq::FifoAlmostFull | eIrq::RxDone)) !=
|
||||
(eIrq::FifoAlmostFull | eIrq::RxDone)) {
|
||||
Fw.BK4819Write(0x3F, OldIrqEnReg | eIrq::FifoAlmostFull | eIrq::RxDone);
|
||||
}
|
||||
}
|
||||
|
||||
void RecieveAsyncAirCopyMode(unsigned char *p8Data, unsigned char u8DataLen,
|
||||
CallbackRxDoneType Callback) {
|
||||
if (!p8Data || !u8DataLen) {
|
||||
return;
|
||||
}
|
||||
|
||||
CallbackRxDone = Callback;
|
||||
p8RxBuff = p8Data;
|
||||
u8RxBuffSize = u8DataLen;
|
||||
u16RxDataLen = 0;
|
||||
|
||||
Fw.AirCopyFskSetup();
|
||||
Fw.BK4819ConfigureAndStartRxFsk();
|
||||
State = eState::RxPending;
|
||||
}
|
||||
|
||||
void DisableFskModem() {
|
||||
auto const FskSettings = Fw.BK4819Read(0x58);
|
||||
Fw.BK4819Write(0x58, FskSettings & ~1);
|
||||
}
|
||||
|
||||
void ClearRxFifoBuff() {
|
||||
auto const Reg59 = Fw.BK4819Read(0x59);
|
||||
Fw.BK4819Write(0x59, 1 << 14);
|
||||
Fw.BK4819Write(0x59, Reg59);
|
||||
}
|
||||
|
||||
unsigned short GetIrqReg() {
|
||||
Fw.BK4819Write(0x2, 0);
|
||||
return Fw.BK4819Read(0x2);
|
||||
}
|
||||
|
||||
bool CheckCrc() { return Fw.BK4819Read(0x0B) & (1 << 4); }
|
||||
|
||||
bool IsLockedByOrgFw() { return !(GPIOC->DATA & 0b1); }
|
||||
|
||||
unsigned short u16DebugIrq;
|
||||
|
||||
void HandleRxDone() {
|
||||
ClearRxFifoBuff();
|
||||
DisableFskModem();
|
||||
State = eState::Idle;
|
||||
CallbackRxDone(u16RxDataLen, CheckCrc());
|
||||
}
|
||||
|
||||
void InterruptHandler() {
|
||||
if (IsLockedByOrgFw()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (State == eState::RxPending) {
|
||||
FixIrqEnRegister();
|
||||
if (!(Fw.BK4819Read(0x0C) & 1)) // irq request indicator
|
||||
static unsigned int GetFrequency()
|
||||
{
|
||||
return;
|
||||
return (BK4819Read(0x39) << 16) | BK4819Read(0x38);
|
||||
}
|
||||
|
||||
auto const IrqReg = GetIrqReg();
|
||||
|
||||
if (IrqReg & eIrq::RxDone) {
|
||||
// HandleRxDone();
|
||||
static signed short GetRssi()
|
||||
{
|
||||
short s16Rssi = ((BK4819Read(0x67) >> 1) & 0xFF);
|
||||
return s16Rssi - 160;
|
||||
}
|
||||
|
||||
if (IrqReg & eIrq::FifoAlmostFull) {
|
||||
HandleFifoAlmostFull();
|
||||
}
|
||||
}
|
||||
}
|
||||
bool IsTx() { return BK4819Read(0x30) & 0b10; }
|
||||
|
||||
eState State;
|
||||
unsigned short u16RxDataLen;
|
||||
bool IsSqlOpen() { return BK4819Read(0x0C) & 0b10; }
|
||||
|
||||
private:
|
||||
void HandleFifoAlmostFull() {
|
||||
for (unsigned char i = 0; i < 4; i++) {
|
||||
auto const RxData = Fw.BK4819Read(0x5F);
|
||||
if (p8RxBuff && u16RxDataLen < u8RxBuffSize - 2) {
|
||||
memcpy(p8RxBuff + u16RxDataLen, &RxData, 2);
|
||||
static void SetFrequency(unsigned int u32Freq)
|
||||
{
|
||||
BK4819Write(0x39, ((u32Freq >> 16) & 0xFFFF));
|
||||
BK4819Write(0x38, (u32Freq & 0xFFFF));
|
||||
auto OldReg = BK4819Read(0x30);
|
||||
BK4819Write(0x30, 0);
|
||||
BK4819Write(0x30, OldReg);
|
||||
}
|
||||
|
||||
u16RxDataLen += 2;
|
||||
}
|
||||
void SetAgcTable(unsigned short *p16AgcTable)
|
||||
{
|
||||
for (unsigned char i = 0; i < 5; i++)
|
||||
{
|
||||
BK4819Write(0x10 + i, p16AgcTable[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (u16RxDataLen >= u8RxBuffSize) {
|
||||
State = eState::Idle;
|
||||
CallbackRxDone(u8RxBuffSize, CheckCrc());
|
||||
}
|
||||
}
|
||||
};
|
||||
void GetAgcTable(unsigned short *p16AgcTable)
|
||||
{
|
||||
for (unsigned char i = 0; i < 5; i++)
|
||||
{
|
||||
p16AgcTable[i] = BK4819Read(0x10 + i);
|
||||
}
|
||||
}
|
||||
|
||||
void SetDeviationPresent(unsigned char u8Present)
|
||||
{
|
||||
auto Reg40 = BK4819Read(0x40);
|
||||
Reg40 &= ~(1 << 12);
|
||||
Reg40 |= (u8Present << 12);
|
||||
BK4819Write(0x40, Reg40);
|
||||
}
|
||||
|
||||
void SetCalibration(unsigned char bOn)
|
||||
{
|
||||
auto Reg30 = BK4819Read(0x31);
|
||||
Reg30 &= ~(1 << 3);
|
||||
Reg30 |= (bOn << 3);
|
||||
BK4819Write(0x31, Reg30);
|
||||
}
|
||||
|
||||
unsigned char GetAFAmplitude() { return BK4819Read(0x6F) & 0b1111111; }
|
||||
|
||||
static void ToggleAFDAC(bool enabled)
|
||||
{
|
||||
auto Reg = BK4819Read(0x30);
|
||||
Reg &= ~(1 << 9);
|
||||
if (enabled)
|
||||
Reg |= (1 << 9);
|
||||
BK4819Write(0x30, Reg);
|
||||
}
|
||||
|
||||
static void ToggleRXDSP(bool enabled)
|
||||
{
|
||||
auto Reg = BK4819Read(0x30);
|
||||
Reg &= ~1;
|
||||
if (enabled)
|
||||
Reg |= 1;
|
||||
BK4819Write(0x30, Reg);
|
||||
}
|
||||
|
||||
void SendSyncAirCopyMode72(unsigned char *p8Data)
|
||||
{
|
||||
BK4819ConfigureAndStartTxFsk();
|
||||
AirCopyFskSetup();
|
||||
AirCopy72(p8Data);
|
||||
BK4819SetGpio(1, false);
|
||||
}
|
||||
|
||||
void DisablePa() { BK4819Write(0x30, BK4819Read(0x30) & ~0b1010); }
|
||||
|
||||
void SetFskMode(eFskMode Mode)
|
||||
{
|
||||
auto const &ModeParams = ModesBits[(int)Mode];
|
||||
auto Reg58 = BK4819Read(0x58);
|
||||
Reg58 &= ~((0b111 << 1) | (0b111 << 10) | (0b111 << 13));
|
||||
Reg58 |= (ModeParams.u8RxBandWidthBits << 1) |
|
||||
(ModeParams.u8RxModeBits << 10) | (ModeParams.u8TxModeBits << 13);
|
||||
BK4819Write(0x58, 0);
|
||||
BK4819Write(0x58, Reg58);
|
||||
}
|
||||
|
||||
void FixIrqEnRegister() // original firmware overrides IRQ_EN reg, so we need
|
||||
// to reenable it
|
||||
{
|
||||
auto const OldIrqEnReg = BK4819Read(0x3F);
|
||||
if ((OldIrqEnReg & (eIrq::FifoAlmostFull | eIrq::RxDone)) !=
|
||||
(eIrq::FifoAlmostFull | eIrq::RxDone))
|
||||
{
|
||||
BK4819Write(0x3F, OldIrqEnReg | eIrq::FifoAlmostFull | eIrq::RxDone);
|
||||
}
|
||||
}
|
||||
|
||||
void RecieveAsyncAirCopyMode(unsigned char *p8Data, unsigned char u8DataLen,
|
||||
CallbackRxDoneType Callback)
|
||||
{
|
||||
if (!p8Data || !u8DataLen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CallbackRxDone = Callback;
|
||||
p8RxBuff = p8Data;
|
||||
u8RxBuffSize = u8DataLen;
|
||||
u16RxDataLen = 0;
|
||||
|
||||
AirCopyFskSetup();
|
||||
BK4819ConfigureAndStartRxFsk();
|
||||
State = eState::RxPending;
|
||||
}
|
||||
|
||||
void DisableFskModem()
|
||||
{
|
||||
auto const FskSettings = BK4819Read(0x58);
|
||||
BK4819Write(0x58, FskSettings & ~1);
|
||||
}
|
||||
|
||||
void ClearRxFifoBuff()
|
||||
{
|
||||
auto const Reg59 = BK4819Read(0x59);
|
||||
BK4819Write(0x59, 1 << 14);
|
||||
BK4819Write(0x59, Reg59);
|
||||
}
|
||||
|
||||
unsigned short GetIrqReg()
|
||||
{
|
||||
BK4819Write(0x2, 0);
|
||||
return BK4819Read(0x2);
|
||||
}
|
||||
|
||||
bool CheckCrc() { return BK4819Read(0x0B) & (1 << 4); }
|
||||
|
||||
bool IsLockedByOrgFw() { return !(GPIOC->DATA & 0b1); }
|
||||
|
||||
unsigned short u16DebugIrq;
|
||||
|
||||
void HandleRxDone()
|
||||
{
|
||||
ClearRxFifoBuff();
|
||||
DisableFskModem();
|
||||
State = eState::Idle;
|
||||
CallbackRxDone(u16RxDataLen, CheckCrc());
|
||||
}
|
||||
|
||||
void InterruptHandler()
|
||||
{
|
||||
if (IsLockedByOrgFw())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (State == eState::RxPending)
|
||||
{
|
||||
FixIrqEnRegister();
|
||||
if (!(BK4819Read(0x0C) & 1)) // irq request indicator
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto const IrqReg = GetIrqReg();
|
||||
|
||||
if (IrqReg & eIrq::RxDone)
|
||||
{
|
||||
// HandleRxDone();
|
||||
}
|
||||
|
||||
if (IrqReg & eIrq::FifoAlmostFull)
|
||||
{
|
||||
HandleFifoAlmostFull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eState State;
|
||||
unsigned short u16RxDataLen;
|
||||
|
||||
private:
|
||||
void HandleFifoAlmostFull()
|
||||
{
|
||||
for (unsigned char i = 0; i < 4; i++)
|
||||
{
|
||||
auto const RxData = BK4819Read(0x5F);
|
||||
if (p8RxBuff && u16RxDataLen < u8RxBuffSize - 2)
|
||||
{
|
||||
memcpy(p8RxBuff + u16RxDataLen, &RxData, 2);
|
||||
}
|
||||
|
||||
u16RxDataLen += 2;
|
||||
}
|
||||
|
||||
if (u16RxDataLen >= u8RxBuffSize)
|
||||
{
|
||||
State = eState::Idle;
|
||||
CallbackRxDone(u8RxBuffSize, CheckCrc());
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace Radio
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
#pragma once
|
||||
#include "manager.hpp"
|
||||
#include "registers.hpp"
|
||||
#include "hardware/adc.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>
|
||||
Radio::CBK4819 &RadioDriver>
|
||||
class CAmTx : public IView
|
||||
{
|
||||
static constexpr bool bAmpTests = true;
|
||||
bool bAmMode = false;
|
||||
bool bEnabled = false;
|
||||
unsigned short u16OldAmp = 0;
|
||||
unsigned short u16ActualAmp = 0;
|
||||
int s32DeltaAmp = 0;
|
||||
unsigned int u32StartFreq = 0;
|
||||
bool bInit = false;
|
||||
// unsigned short U16OldAgcTable[5];
|
||||
// unsigned short U16NewAgcTable[5] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
|
||||
|
||||
|
@ -29,37 +30,22 @@ public:
|
|||
return eScreenRefreshFlag::NoRefresh;
|
||||
}
|
||||
|
||||
if constexpr (bAmpTests)
|
||||
if(bInit)
|
||||
{
|
||||
// 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;
|
||||
bInit = false;
|
||||
RadioDriver.SetDeviationPresent(0);
|
||||
u32StartFreq = RadioDriver.GetFrequency();
|
||||
}
|
||||
|
||||
RadioDriver.SetDeviationPresent(0);
|
||||
auto InitialBias = Fw.BK4819Read(0x36);
|
||||
HandleTests();
|
||||
|
||||
u32StartFreq = RadioDriver.GetFrequency();
|
||||
|
||||
while (CheckForPtt())
|
||||
if(CheckForPtt())
|
||||
{
|
||||
HandleMicInput();
|
||||
HandleTxAm();
|
||||
//HandleTxWfm();
|
||||
return eScreenRefreshFlag::MainScreen;
|
||||
}
|
||||
|
||||
RadioDriver.SetFrequency(u32StartFreq);
|
||||
RadioDriver.SetDeviationPresent(1);
|
||||
Fw.BK4819Write(0x36, InitialBias);
|
||||
|
||||
Context.ViewStack.Pop();
|
||||
return eScreenRefreshFlag::NoRefresh;
|
||||
|
@ -76,16 +62,17 @@ public:
|
|||
// 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);
|
||||
AdcReadout(U16AdcData, U16AdcData+1);
|
||||
FormatString(S8DebugStr, "in 1: %05i ", U16AdcData[0]);
|
||||
PrintTextOnScreen(S8DebugStr, 0, 127, 0, 8, 0);
|
||||
FormatString(S8DebugStr, "in 2: %05i ", U16AdcData[1]);
|
||||
PrintTextOnScreen(S8DebugStr, 0, 127, 2, 8, 0);
|
||||
}
|
||||
|
||||
void HandleMicInput()
|
||||
{
|
||||
unsigned short u16ActualAmp = Fw.BK4819Read(0x64);
|
||||
u16ActualAmp = BK4819Read(0x64);
|
||||
// u16ActualAmp = BK4819Read(0x6F) & 0b1111111;
|
||||
s32DeltaAmp = u16OldAmp - u16ActualAmp;
|
||||
u16OldAmp = u16ActualAmp;
|
||||
}
|
||||
|
@ -98,7 +85,7 @@ public:
|
|||
MicAmp = 0b111;
|
||||
if (MicAmp < 0)
|
||||
MicAmp = 0;
|
||||
Fw.BK4819Write(0x36, ((MicAmp & 0b111) << 3) | (MicAmp & 0b111));
|
||||
BK4819Write(0x36, ((MicAmp & 0b111) << 3) | (MicAmp & 0b111));
|
||||
}
|
||||
|
||||
void HandleTxWfm()
|
||||
|
@ -131,6 +118,7 @@ public:
|
|||
return eScreenRefreshFlag::StatusBar;
|
||||
}
|
||||
|
||||
bInit = true;
|
||||
Context.ViewStack.Push(*this);
|
||||
return eScreenRefreshFlag::StatusBar;
|
||||
}
|
||||
|
@ -145,7 +133,7 @@ public:
|
|||
if (GPIOC->DATA & GPIO_PIN_3)
|
||||
{
|
||||
GPIOC->DATA &= ~GPIO_PIN_3;
|
||||
*FwData.p8FlashLightStatus = 3;
|
||||
gFlashLightStatus = 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -154,17 +142,17 @@ public:
|
|||
|
||||
void DrawAmIcon(bool bDraw)
|
||||
{
|
||||
memset(FwData.pStatusBarData, 0, 14);
|
||||
memset(gStatusBarData, 0, 14);
|
||||
if (!bDraw)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(FwData.pStatusBarData, FwData.pSmallLeters + 223, 12);
|
||||
unsigned char *pNegative = FwData.pStatusBarData;
|
||||
memcpy(gStatusBarData, gSmallLeters + 223, 12);
|
||||
unsigned char *pNegative = gStatusBarData;
|
||||
for (unsigned char i = 0; i < 14; i++)
|
||||
{
|
||||
*pNegative++ ^= 0xFF;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "keyboard.hpp"
|
||||
|
||||
inline char S8Label[20];
|
||||
template <const System::TOrgFunctions &Fw>
|
||||
class CHeater : public IMenuElement
|
||||
{
|
||||
bool bEnabled = false;
|
||||
|
@ -28,23 +27,22 @@ class CHeater : public IMenuElement
|
|||
bEnabled = !bEnabled;
|
||||
if(bEnabled)
|
||||
{
|
||||
Fw.BK4819SetGpio(1, true);
|
||||
BK4819SetGpio(1, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Fw.BK4819SetGpio(1, false);
|
||||
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);
|
||||
FormatString(S8Label, "AM RX %u", u8Mode);
|
||||
return S8Label;
|
||||
}
|
||||
|
||||
|
@ -59,11 +57,11 @@ class CAmRx : public IMenuElement
|
|||
if(u8Mode > 2)
|
||||
u8Mode = 0;
|
||||
|
||||
// Fw.SomeAmStuff(u8Mode);
|
||||
// SomeAmStuff(u8Mode);
|
||||
}
|
||||
};
|
||||
|
||||
template <const System::TOrgFunctions &Fw, Radio::CBK4819<Fw> &RadioDriver>
|
||||
template <Radio::CBK4819 &RadioDriver>
|
||||
class CMicVal : public IMenuElement
|
||||
{
|
||||
unsigned char u8Mode = 0;
|
||||
|
@ -71,7 +69,7 @@ class CMicVal : public IMenuElement
|
|||
public:
|
||||
const char *GetLabel() override
|
||||
{
|
||||
Fw.FormatString(S8Label, "MIC in %u", Fw.BK4819Read(0x64));
|
||||
FormatString(S8Label, "MIC in %u", BK4819Read(0x64));
|
||||
return S8Label;
|
||||
}
|
||||
|
||||
|
@ -80,7 +78,7 @@ class CMicVal : public IMenuElement
|
|||
}
|
||||
};
|
||||
|
||||
template <const System::TOrgFunctions &Fw, Radio::CBK4819<Fw> &RadioDriver>
|
||||
template <Radio::CBK4819 &RadioDriver>
|
||||
class CRssiVal : public IMenuElement
|
||||
{
|
||||
unsigned char u8Mode = 0;
|
||||
|
@ -89,11 +87,11 @@ class CRssiVal : public IMenuElement
|
|||
public:
|
||||
const char *GetLabel() override
|
||||
{
|
||||
Fw.FormatString(S8Label, "RSSI %i", RadioDriver.GetRssi());
|
||||
FormatString(S8Label, "RSSI %i", RadioDriver.GetRssi());
|
||||
return S8Label;
|
||||
}
|
||||
|
||||
void HandleUserAction(unsigned char u8Button) override
|
||||
{
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
#include "keyboard.hpp"
|
||||
#include "registers.hpp"
|
||||
|
||||
template <const System::TOrgFunctions &Fw,
|
||||
const System::TOrgData &FwData,
|
||||
template <
|
||||
unsigned char BackgroundViewPrescaler,
|
||||
unsigned char MainViewPrescaler,
|
||||
unsigned char RegisteredViews>
|
||||
|
@ -48,7 +47,7 @@ class CViewManager
|
|||
% MainViewPrescaler))
|
||||
{
|
||||
if(!MainViewContext.OriginalFwStatus.b1RadioSpiCommInUse)
|
||||
Keyboard.Handle(Fw.PollKeyboard());
|
||||
Keyboard.Handle(PollKeyboard());
|
||||
|
||||
u8ScreenRefreshFlag |=
|
||||
pViewStackTop->HandleMainView(MainViewContext);
|
||||
|
@ -56,12 +55,12 @@ class CViewManager
|
|||
|
||||
if(u8ScreenRefreshFlag & eScreenRefreshFlag::MainScreen)
|
||||
{
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FlushFramebufferToScreen();
|
||||
}
|
||||
|
||||
if(u8ScreenRefreshFlag & eScreenRefreshFlag::StatusBar)
|
||||
{
|
||||
Fw.FlushStatusbarBufferToScreen();
|
||||
FlushStatusbarBufferToScreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,8 +83,8 @@ class CViewManager
|
|||
|
||||
inline void CheckOriginalFwStatus()
|
||||
{
|
||||
const auto *pMenuCheckData = (unsigned char *)(FwData.pDisplayBuffer + 2*128 + 6 * 8 + 1);
|
||||
const auto *pFrequencyScanCheckData = (unsigned char *)(FwData.pDisplayBuffer + 6*128 + 3 * 8 + 2);
|
||||
const auto *pMenuCheckData = (unsigned char *)(gDisplayBuffer + 2*128 + 6 * 8 + 1);
|
||||
const auto *pFrequencyScanCheckData = (unsigned char *)(gDisplayBuffer + 6*128 + 3 * 8 + 2);
|
||||
MainViewContext.OriginalFwStatus.b1MenuDrawed = *pMenuCheckData == 0xFF;
|
||||
MainViewContext.OriginalFwStatus.b1FrequencyScan = *pFrequencyScanCheckData;
|
||||
MainViewContext.OriginalFwStatus.b1RadioSpiCommInUse = !(GPIOC->DATA & 0b1);
|
||||
|
@ -109,4 +108,4 @@ class CViewManager
|
|||
pTop->HandleReleasedButton(MainViewContext, u8Key);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,8 +8,6 @@ struct IMenuElement
|
|||
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;
|
||||
|
@ -73,18 +71,18 @@ public:
|
|||
|
||||
void DrawMenu()
|
||||
{
|
||||
memset(FwData.pDisplayBuffer, 0, 128*6);
|
||||
memset(gDisplayBuffer, 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);
|
||||
PrintTextOnScreen(Element->GetLabel(), 0, 127, u8Line << 1, 8, 0);
|
||||
}
|
||||
|
||||
for(auto i = 0; i < 256; i++)
|
||||
FwData.pDisplayBuffer[i + 2*128] ^= 0xFF;
|
||||
gDisplayBuffer[i + 2*128] ^= 0xFF;
|
||||
}
|
||||
|
||||
IMenuElement* GetElement(signed char s8Idx)
|
||||
|
@ -102,10 +100,10 @@ public:
|
|||
if (GPIOC->DATA & GPIO_PIN_3)
|
||||
{
|
||||
GPIOC->DATA &= ~GPIO_PIN_3;
|
||||
*FwData.p8FlashLightStatus = 3;
|
||||
gFlashLightStatus = 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
template <
|
||||
TUV_K5Display &DisplayBuff,
|
||||
CDisplay<TUV_K5Display> &Display,
|
||||
const System::TOrgFunctions &Fw,
|
||||
const System::TOrgData &FwData,
|
||||
Radio::CBK4819<Fw> &RadioDriver>
|
||||
Radio::CBK4819 &RadioDriver>
|
||||
class CMessenger : public IView
|
||||
{
|
||||
public:
|
||||
|
@ -66,7 +64,7 @@ public:
|
|||
if (u8RxDoneLabelCnt < 100)
|
||||
{
|
||||
u8RxDoneLabelCnt++;
|
||||
Fw.PrintTextOnScreen("> RX <", 0, 128, 2, 8, 1);
|
||||
PrintTextOnScreen("> RX <", 0, 128, 2, 8, 1);
|
||||
}
|
||||
|
||||
switch (State)
|
||||
|
@ -100,8 +98,8 @@ public:
|
|||
void PrintTxData()
|
||||
{
|
||||
char C8PrintBuff[30];
|
||||
Fw.FormatString(C8PrintBuff, ">%s", T9.C8WorkingBuff);
|
||||
Fw.PrintTextOnScreen(C8PrintBuff, 0, 128, 0, 8, 0);
|
||||
FormatString(C8PrintBuff, ">%s", T9.C8WorkingBuff);
|
||||
PrintTextOnScreen(C8PrintBuff, 0, 128, 0, 8, 0);
|
||||
}
|
||||
|
||||
void PrintRxData()
|
||||
|
@ -109,9 +107,9 @@ public:
|
|||
// char *tempRxBuff = S8RxBuff + MaxCharsInLine;
|
||||
// char C8Temp = tempRxBuff[MaxCharsInLine];
|
||||
// S8RxBuff[MaxCharsInLine] = '\0';
|
||||
Fw.PrintTextOnScreen(S8RxBuff, 1, 128, 3, 8, 0);
|
||||
PrintTextOnScreen(S8RxBuff, 1, 128, 3, 8, 0);
|
||||
// S8RxBuff[MaxCharsInLine] = C8Temp;
|
||||
// Fw.PrintTextOnScreen(tempRxBuff, 1, 128, 5, 8, 0);
|
||||
// PrintTextOnScreen(tempRxBuff, 1, 128, 5, 8, 0);
|
||||
}
|
||||
|
||||
void HandleInitTx()
|
||||
|
@ -124,7 +122,7 @@ public:
|
|||
State = eState::InitRx;
|
||||
}
|
||||
|
||||
Fw.PrintTextOnScreen("> TX <", 0, 128, 2, 8, 1);
|
||||
PrintTextOnScreen("> TX <", 0, 128, 2, 8, 1);
|
||||
}
|
||||
void RxDoneHandler(unsigned char u8DataLen, bool bCrcOk)
|
||||
{
|
||||
|
@ -142,12 +140,12 @@ private:
|
|||
{
|
||||
bEnabled = true;
|
||||
GPIOC->DATA &= ~GPIO_PIN_3;
|
||||
*FwData.p8FlashLightStatus = 3;
|
||||
gFlashLightStatus = 3;
|
||||
}
|
||||
|
||||
if (bEnabled)
|
||||
{
|
||||
// Keyboard.Handle(Fw.PollKeyboard());
|
||||
// Keyboard.Handle(PollKeyboard());
|
||||
}
|
||||
|
||||
return bEnabled;
|
||||
|
@ -161,7 +159,7 @@ private:
|
|||
|
||||
void ClearDrawings()
|
||||
{
|
||||
memset(FwData.pDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY);
|
||||
memset(gDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY);
|
||||
}
|
||||
|
||||
void HandlePressedButton(unsigned char u8Button) override
|
||||
|
@ -194,4 +192,4 @@ private:
|
|||
bool bEnabled;
|
||||
eState State;
|
||||
unsigned char u8RxDoneLabelCnt;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#include "manager.hpp"
|
||||
|
||||
template <
|
||||
System::TOrgFunctions &Fw,
|
||||
System::TOrgData &FwData,
|
||||
TUV_K5Display &DisplayBuff,
|
||||
CDisplay<TUV_K5Display> &Display,
|
||||
TUV_K5SmallNumbers &FontSmallNr>
|
||||
|
@ -25,7 +23,7 @@ public:
|
|||
return eScreenRefreshFlag::NoRefresh;
|
||||
}
|
||||
|
||||
if (Fw.BK4819Read(0x0C) & 0b10)
|
||||
if (BK4819Read(0x0C) & 0b10)
|
||||
{
|
||||
u8SqlDelayCnt = 0;
|
||||
}
|
||||
|
@ -55,7 +53,7 @@ public:
|
|||
Display.SetFont(&FontSmallNr);
|
||||
|
||||
char C8RssiString[] = "g000";
|
||||
unsigned char u8Rssi = ((Fw.BK4819Read(0x67) >> 1) & 0xFF);
|
||||
unsigned char u8Rssi = ((BK4819Read(0x67) >> 1) & 0xFF);
|
||||
if (!u8Rssi)
|
||||
{
|
||||
return eScreenRefreshFlag::NoRefresh;
|
||||
|
@ -101,4 +99,4 @@ public:
|
|||
u8ChartPosition++;
|
||||
return eScreenRefreshFlag::MainScreen;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -49,13 +49,11 @@ namespace Rssi
|
|||
}
|
||||
|
||||
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>
|
||||
Radio::CBK4819 &RadioDriver>
|
||||
class CRssiSbar : public IView, public IMenuElement
|
||||
{
|
||||
public:
|
||||
|
@ -67,7 +65,7 @@ public:
|
|||
static constexpr auto LinearBlocksCnt = 9;
|
||||
static constexpr auto VoltageOffset = 77;
|
||||
static constexpr auto MaxBarPoints = 13;
|
||||
static inline unsigned char *const pDData = FwData.pDisplayBuffer + 128 * 3;
|
||||
static inline unsigned char *const pDData = gDisplayBuffer + 128 * 3;
|
||||
|
||||
unsigned int u32DrawVoltagePsc = 0;
|
||||
Rssi::TRssi RssiData;
|
||||
|
@ -188,7 +186,7 @@ public:
|
|||
{
|
||||
if (bPtt) // print TX
|
||||
{
|
||||
memcpy(pDData + 5 * 7, FwData.pSmallLeters + 128 * 2 + 8 * 3 + 2, 15);
|
||||
memcpy(pDData + 5 * 7, gSmallLeters + 128 * 2 + 8 * 3 + 2, 15);
|
||||
unsigned char *pNegative = pDData + 5 * 7 - 2;
|
||||
for (unsigned char i = 0; i < 19; i++)
|
||||
{
|
||||
|
@ -205,13 +203,13 @@ public:
|
|||
}
|
||||
else if (u8SValue > 9)
|
||||
{
|
||||
memcpy(pDData + 5 * 7, FwData.pSmallLeters + 109 - 3 * 8, 8);
|
||||
memcpy(pDData + 5 * 7, gSmallLeters + 109 - 3 * 8, 8);
|
||||
C8SignalString[1] = '0';
|
||||
C8SignalString[0] = '0' + u8SValue - 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pDData + 5 * 7, FwData.pSmallLeters + 109, 8);
|
||||
memcpy(pDData + 5 * 7, gSmallLeters + 109, 8);
|
||||
C8SignalString[0] = '0' + u8SValue;
|
||||
C8SignalString[1] = ' ';
|
||||
}
|
||||
|
@ -234,20 +232,20 @@ public:
|
|||
|
||||
void PrintBatteryVoltage()
|
||||
{
|
||||
if(*(FwData.pStatusBarData + VoltageOffset + 4 * 6 + 1) ||
|
||||
*(FwData.pStatusBarData + VoltageOffset + 4 * 6 - 6))
|
||||
if(gStatusBarData[VoltageOffset + 4 * 6 + 1] ||
|
||||
gStatusBarData[VoltageOffset + 4 * 6 - 6])
|
||||
{ // disable printing when function or charging icon are printed
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned short u16Voltage = *FwData.p16Voltage > 1000 ? 999 : *FwData.p16Voltage;
|
||||
unsigned short u16Voltage = gVoltage > 1000 ? 999 : gVoltage;
|
||||
|
||||
memset(FwData.pStatusBarData + VoltageOffset, 0, 4 * 5);
|
||||
memset(gStatusBarData + VoltageOffset, 0, 4 * 5);
|
||||
DisplayStatusBar.SetCoursor(0, VoltageOffset);
|
||||
DisplayStatusBar.PrintFixedDigitsNumber2(u16Voltage, 2, 1);
|
||||
memset(FwData.pStatusBarData + VoltageOffset + 7 + 1, 0b1100000, 2); // dot
|
||||
memset(gStatusBarData + VoltageOffset + 7 + 1, 0b1100000, 2); // dot
|
||||
DisplayStatusBar.SetCoursor(0, VoltageOffset + 7 + 4);
|
||||
DisplayStatusBar.PrintFixedDigitsNumber2(u16Voltage, 0, 2);
|
||||
memcpy(FwData.pStatusBarData + VoltageOffset + 4 * 6 + 2, FwData.pSmallLeters + 128 * 2 + 102, 5); // V character
|
||||
memcpy(gStatusBarData + VoltageOffset + 4 * 6 + 2, gSmallLeters + 128 * 2 + 102, 5); // V character
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,3 +8,4 @@ add_subdirectory(spectrum_fagci)
|
|||
add_subdirectory(t9_texting)
|
||||
add_subdirectory(messenger)
|
||||
add_subdirectory(rssi_sbar_hot)
|
||||
add_subdirectory(am_tx)
|
|
@ -0,0 +1,84 @@
|
|||
set(NAME am_tx)
|
||||
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}
|
||||
)
|
||||
|
||||
add_custom_target(${NAME}_flash_uart
|
||||
COMMAND ${CMAKE_BINARY_DIR}/tools/k5prog -F -p ${SERIAL_PORT} -b ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin -Y -Y -Y
|
||||
DEPENDS ${NAME}_encoded
|
||||
DEPENDS k5prog
|
||||
)
|
|
@ -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,64 @@
|
|||
#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"
|
||||
|
||||
TUV_K5Display DisplayBuff(gDisplayBuffer);
|
||||
const TUV_K5SmallNumbers FontSmallNr(gSmallDigs);
|
||||
CDisplay Display(DisplayBuff);
|
||||
|
||||
TUV_K5Display StatusBarBuff(gStatusBarData);
|
||||
CDisplay DisplayStatusBar(StatusBarBuff);
|
||||
|
||||
Radio::CBK4819 RadioDriver;
|
||||
|
||||
// CRssiSbar<
|
||||
// System::OrgFunc_01_26,
|
||||
// System::OrgData_01_26,
|
||||
// DisplayBuff,
|
||||
// Display,
|
||||
// DisplayStatusBar,
|
||||
// FontSmallNr,
|
||||
// RadioDriver>
|
||||
// RssiSbar;
|
||||
|
||||
CAmTx<
|
||||
DisplayBuff,
|
||||
Display,
|
||||
DisplayStatusBar,
|
||||
FontSmallNr,
|
||||
RadioDriver>
|
||||
AmTx;
|
||||
|
||||
static IView * const Views[] = {&AmTx};
|
||||
CViewManager<
|
||||
8, 1, sizeof(Views) / sizeof(*Views)>
|
||||
Manager(Views);
|
||||
|
||||
int main()
|
||||
{
|
||||
IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
{
|
||||
static bool bFirstInit = false;
|
||||
if (!bFirstInit)
|
||||
{
|
||||
System::CopyDataSection();
|
||||
__libc_init_array();
|
||||
bFirstInit = true;
|
||||
}
|
||||
|
||||
Manager.Handle();
|
||||
IRQ_SYSTICK();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#include "system.hpp"
|
||||
#include "hardware/hardware.hpp"
|
||||
#include "registers.hpp"
|
||||
#include "uv_k5_display.hpp"
|
||||
#include "rssi_sbar.hpp"
|
||||
#include <string.h>
|
||||
|
||||
Hardware::THardware Hw;
|
||||
const System::TOrgFunctions& Fw = System::OrgFunc_01_26;
|
||||
const System::TOrgData& FwData = System::OrgData_01_26;
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
{
|
||||
static bool bFirstInit = false;
|
||||
if(!bFirstInit)
|
||||
{
|
||||
System::CopyDataSection();
|
||||
__libc_init_array();
|
||||
bFirstInit = true;
|
||||
}
|
||||
|
||||
static unsigned int u32StupidCounter = 1;
|
||||
if((!(u32StupidCounter++ % 10) && u32StupidCounter > 200)) // exit key
|
||||
{
|
||||
CRssiPrinter::Handle(Fw, FwData);
|
||||
}
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
|
@ -69,11 +69,21 @@ add_custom_command(TARGET ${NAME}
|
|||
)
|
||||
|
||||
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"
|
||||
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}
|
||||
)
|
||||
)
|
||||
|
||||
if(NOT DEFINED ${SERIAL_PORT})
|
||||
set(SERIAL_PORT /dev/ttyUSB0)
|
||||
endif()
|
||||
|
||||
add_custom_target(${NAME}_flash_uart
|
||||
COMMAND ${CMAKE_BINARY_DIR}/tools/k5prog -F -p ${SERIAL_PORT} -b ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin -Y -Y -Y
|
||||
DEPENDS ${NAME}_encoded
|
||||
DEPENDS k5prog
|
||||
)
|
||||
|
|
|
@ -3,26 +3,19 @@
|
|||
#include "messenger.hpp"
|
||||
#include "radio.hpp"
|
||||
|
||||
const System::TOrgFunctions &Fw = System::OrgFunc_01_26;
|
||||
const System::TOrgData &FwData = System::OrgData_01_26;
|
||||
Radio::CBK4819 RadioDriver;
|
||||
|
||||
Radio::CBK4819<System::OrgFunc_01_26> RadioDriver;
|
||||
|
||||
CMessenger<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
RadioDriver>
|
||||
Messenger;
|
||||
CMessenger<RadioDriver> Messenger;
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
|
@ -37,5 +30,5 @@ extern "C" void SysTick_Handler()
|
|||
|
||||
RadioDriver.InterruptHandler();
|
||||
Messenger.Handle();
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
||||
IRQ_SYSTICK();
|
||||
}
|
||||
|
|
|
@ -5,25 +5,18 @@
|
|||
#include "rssi_sbar.hpp"
|
||||
#include "manager.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);
|
||||
TUV_K5Display DisplayBuff(gDisplayBuffer);
|
||||
const TUV_K5SmallNumbers FontSmallNr(gSmallDigs);
|
||||
CDisplay Display(DisplayBuff);
|
||||
|
||||
Radio::CBK4819<System::OrgFunc_01_26> RadioDriver;
|
||||
Radio::CBK4819 RadioDriver;
|
||||
CMessenger<
|
||||
DisplayBuff,
|
||||
Display,
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
RadioDriver>
|
||||
Messenger;
|
||||
|
||||
CRssiSbar<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
DisplayBuff,
|
||||
Display,
|
||||
FontSmallNr>
|
||||
|
@ -31,8 +24,6 @@ CRssiSbar<
|
|||
|
||||
static IView * const Views[] = {&Messenger, &RssiSbar};
|
||||
CViewManager<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
16, 2, sizeof(Views) / sizeof(*Views)>
|
||||
Manager(Views);
|
||||
|
||||
|
@ -60,4 +51,4 @@ extern "C" void SysTick_Handler()
|
|||
RadioDriver.InterruptHandler();
|
||||
Manager.Handle();
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,7 @@
|
|||
#include "radio.hpp"
|
||||
#include "t9.hpp"
|
||||
|
||||
template <const System::TOrgFunctions &Fw,
|
||||
const System::TOrgData &FwData,
|
||||
Radio::CBK4819<Fw> &RadioDriver>
|
||||
template <Radio::CBK4819 &RadioDriver>
|
||||
class CMessenger
|
||||
{
|
||||
public:
|
||||
|
@ -23,7 +21,7 @@ public:
|
|||
};
|
||||
|
||||
CMessenger()
|
||||
: DisplayBuff(FwData.pDisplayBuffer),
|
||||
: DisplayBuff(gDisplayBuffer),
|
||||
Display(DisplayBuff),
|
||||
Keyboard(*this),
|
||||
T9(S8TxBuff),
|
||||
|
@ -45,7 +43,7 @@ public:
|
|||
{
|
||||
bDisplayCleared = true;
|
||||
ClearDrawings();
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FlushFramebufferToScreen();
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -61,22 +59,22 @@ public:
|
|||
|
||||
Display.DrawHLine(3, 3 + 10, 1 * 8 + T9.GetIdx() * 8 + 2);
|
||||
// print tx data
|
||||
Fw.FormatString(C8PrintBuff, ">%s", T9.C8WorkingBuff);
|
||||
Fw.PrintTextOnScreen(C8PrintBuff, 0, 128, 0, 8, 0);
|
||||
FormatString(C8PrintBuff, ">%s", T9.C8WorkingBuff);
|
||||
PrintTextOnScreen(C8PrintBuff, 0, 128, 0, 8, 0);
|
||||
|
||||
// print rx data
|
||||
char C8Temp = S8RxBuff[MaxCharsInLine];
|
||||
S8RxBuff[MaxCharsInLine] = '\0';
|
||||
Fw.PrintTextOnScreen(S8RxBuff, 1, 128, 3, 8, 0);
|
||||
PrintTextOnScreen(S8RxBuff, 1, 128, 3, 8, 0);
|
||||
S8RxBuff[MaxCharsInLine] = C8Temp;
|
||||
Fw.PrintTextOnScreen(S8RxBuff + MaxCharsInLine, 1, 128, 5, 8, 0);
|
||||
PrintTextOnScreen(S8RxBuff + MaxCharsInLine, 1, 128, 5, 8, 0);
|
||||
|
||||
Display.DrawRectangle(0, (8 * 4) - 6, 127, 24 + 6, false);
|
||||
|
||||
if (u8RxDoneLabelCnt < 100)
|
||||
{
|
||||
u8RxDoneLabelCnt++;
|
||||
Fw.PrintTextOnScreen(" >> RX << ", 0, 128, 2, 8, 1);
|
||||
PrintTextOnScreen(" >> RX << ", 0, 128, 2, 8, 1);
|
||||
}
|
||||
|
||||
switch (State)
|
||||
|
@ -97,14 +95,14 @@ public:
|
|||
State = eState::InitRx;
|
||||
}
|
||||
|
||||
Fw.PrintTextOnScreen(" >> TX << ", 0, 128, 2, 8, 1);
|
||||
PrintTextOnScreen(" >> TX << ", 0, 128, 2, 8, 1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FlushFramebufferToScreen();
|
||||
}
|
||||
|
||||
void RxDoneHandler(unsigned char u8DataLen, bool bCrcOk)
|
||||
|
@ -123,12 +121,12 @@ private:
|
|||
{
|
||||
bEnabled = true;
|
||||
GPIOC->DATA &= ~GPIO_PIN_3;
|
||||
*FwData.p8FlashLightStatus = 3;
|
||||
gFlashLightStatus = 3;
|
||||
}
|
||||
|
||||
if (bEnabled)
|
||||
{
|
||||
Keyboard.Handle(Fw.PollKeyboard());
|
||||
Keyboard.Handle(PollKeyboard());
|
||||
}
|
||||
|
||||
return bEnabled;
|
||||
|
@ -142,7 +140,7 @@ private:
|
|||
|
||||
void ClearDrawings()
|
||||
{
|
||||
memset(FwData.pDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY);
|
||||
memset(gDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY);
|
||||
}
|
||||
|
||||
void HandlePressedButton(unsigned char u8Button)
|
||||
|
@ -178,4 +176,4 @@ private:
|
|||
bool bEnabled;
|
||||
eState State;
|
||||
unsigned char u8RxDoneLabelCnt;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -75,4 +75,10 @@ add_custom_target(${NAME}_flash
|
|||
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}
|
||||
)
|
||||
)
|
||||
|
||||
add_custom_target(${NAME}_flash_uart
|
||||
COMMAND ${CMAKE_BINARY_DIR}/tools/k5prog -F -p ${SERIAL_PORT} -b ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin -Y -Y -Y
|
||||
DEPENDS ${NAME}_encoded
|
||||
DEPENDS k5prog
|
||||
)
|
||||
|
|
|
@ -8,22 +8,18 @@
|
|||
|
||||
extern "C" void __libc_init_array();
|
||||
|
||||
const System::TOrgFunctions& Fw = System::OrgFunc_01_26;
|
||||
|
||||
Radio::CBK4819<System::OrgFunc_01_26> RadioDriver;
|
||||
CSpectrum<System::OrgFunc_01_26,
|
||||
System::OrgData_01_26, RadioDriver>
|
||||
Spectrum;
|
||||
Radio::CBK4819 RadioDriver;
|
||||
CSpectrum<RadioDriver> Spectrum;
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
|
@ -41,5 +37,5 @@ extern "C" void SysTick_Handler()
|
|||
{
|
||||
Spectrum.Handle();
|
||||
}
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
||||
IRQ_SYSTICK();
|
||||
}
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
#include "uv_k5_display.hpp"
|
||||
#include "radio.hpp"
|
||||
|
||||
template <const System::TOrgFunctions &Fw,
|
||||
const System::TOrgData &FwData,
|
||||
Radio::CBK4819<Fw> &RadioDriver>
|
||||
template <Radio::CBK4819 &RadioDriver>
|
||||
class CSpectrum
|
||||
{
|
||||
public:
|
||||
|
@ -23,7 +21,7 @@ public:
|
|||
};
|
||||
|
||||
CSpectrum()
|
||||
: DisplayBuff(FwData.pDisplayBuffer), FontSmallNr(FwData.pSmallDigs), Display(DisplayBuff), State(eState::Init), u8RxCnt(0){};
|
||||
: DisplayBuff(gDisplayBuffer), FontSmallNr(gSmallDigs), Display(DisplayBuff), State(eState::Init), u8RxCnt(0){};
|
||||
|
||||
void Handle()
|
||||
{
|
||||
|
@ -38,14 +36,14 @@ public:
|
|||
{
|
||||
|
||||
|
||||
Fw.DelayMs(600);
|
||||
DelayMs(600);
|
||||
//memset(U8Buff, 0, sizeof(U8Buff));
|
||||
RadioDriver.RecieveAsyncAirCopyMode(U8Buff, sizeof(U8Buff), Radio::CallbackRxDoneType(this, &CSpectrum::RxDoneHandler));
|
||||
State = eState::RxPending;
|
||||
// while(State == eState::RxPending)
|
||||
// {
|
||||
// RadioDriver.InterruptHandler();
|
||||
// // if(Fw.PollKeyboard() != 0xFF)
|
||||
// // if(PollKeyboard() != 0xFF)
|
||||
// // {
|
||||
// // break;
|
||||
// // }
|
||||
|
@ -59,13 +57,13 @@ public:
|
|||
char kupa[20];
|
||||
U8Buff[10] = 0;
|
||||
DisplayBuff.ClearAll();
|
||||
Fw.FormatString(kupa, "RX DONE %u", u8RxCnt);
|
||||
Fw.PrintTextOnScreen(kupa, 0, 127, 0, 8, 0);
|
||||
Fw.FormatString(kupa, "LEN: %i", RadioDriver.u16RxDataLen);
|
||||
Fw.PrintTextOnScreen(kupa, 0, 127, 2, 8, 0);
|
||||
Fw.FormatString(kupa, "S: %s", U8Buff);
|
||||
Fw.PrintTextOnScreen(kupa, 0, 127, 4, 8, 0);
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FormatString(kupa, "RX DONE %u", u8RxCnt);
|
||||
PrintTextOnScreen(kupa, 0, 127, 0, 8, 0);
|
||||
FormatString(kupa, "LEN: %i", RadioDriver.u16RxDataLen);
|
||||
PrintTextOnScreen(kupa, 0, 127, 2, 8, 0);
|
||||
FormatString(kupa, "S: %s", U8Buff);
|
||||
PrintTextOnScreen(kupa, 0, 127, 4, 8, 0);
|
||||
FlushFramebufferToScreen();
|
||||
|
||||
static unsigned int u32Cnt = 1;
|
||||
if(!(u32Cnt++%8))
|
||||
|
@ -74,29 +72,29 @@ public:
|
|||
State = eState::Init;
|
||||
}
|
||||
|
||||
// Fw.WriteSerialData((unsigned char *)"RX packet, hex: ", 17);
|
||||
// WriteSerialData((unsigned char *)"RX packet, hex: ", 17);
|
||||
// for (unsigned int i = 0; i < sizeof(U8Buff); i++)
|
||||
// {
|
||||
// Fw.FormatString(kupa, "%02X", U8Buff[i]);
|
||||
// Fw.WriteSerialData((unsigned char *)kupa, 1);
|
||||
// FormatString(kupa, "%02X", U8Buff[i]);
|
||||
// WriteSerialData((unsigned char *)kupa, 1);
|
||||
// }
|
||||
// Fw.WriteSerialData((unsigned char *)"\n", 1);
|
||||
// WriteSerialData((unsigned char *)"\n", 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case eState::RxPending:
|
||||
{
|
||||
|
||||
//Fw.AirCopyFskSetup();
|
||||
//AirCopyFskSetup();
|
||||
char kupa[20];
|
||||
DisplayBuff.ClearAll();
|
||||
Fw.FormatString(kupa, "Rx: %u kHz", Fw.IntDivide(RadioDriver.GetFrequency(), 100));
|
||||
Fw.PrintTextOnScreen(kupa, 0, 127, 0, 8, 0);
|
||||
Fw.FormatString(kupa, "0x3F: 0x%04X", Fw.BK4819Read(0x3F));
|
||||
Fw.PrintTextOnScreen(kupa, 0, 127, 2, 8, 0);
|
||||
Fw.FormatString(kupa, "len: %i", Fw.BK4819Read(0x5D) >> 8);
|
||||
Fw.PrintTextOnScreen(kupa, 0, 127, 4, 8, 0);
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FormatString(kupa, "Rx: %u kHz", IntDivide(RadioDriver.GetFrequency(), 100));
|
||||
PrintTextOnScreen(kupa, 0, 127, 0, 8, 0);
|
||||
FormatString(kupa, "0x3F: 0x%04X", BK4819Read(0x3F));
|
||||
PrintTextOnScreen(kupa, 0, 127, 2, 8, 0);
|
||||
FormatString(kupa, "len: %i", BK4819Read(0x5D) >> 8);
|
||||
PrintTextOnScreen(kupa, 0, 127, 4, 8, 0);
|
||||
FlushFramebufferToScreen();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -110,18 +108,18 @@ public:
|
|||
if(!(u32Cnt++%8))
|
||||
{
|
||||
u8TxCnt++;
|
||||
Fw.FormatString((char *)C8TxStr, "packet %i", u8TxCnt);
|
||||
FormatString((char *)C8TxStr, "packet %i", u8TxCnt);
|
||||
RadioDriver.SendSyncAirCopyMode72((unsigned char *)C8TxStr);
|
||||
}
|
||||
|
||||
DisplayBuff.ClearAll();
|
||||
Fw.FormatString(kupa, "TX: %u kHz", Fw.IntDivide(RadioDriver.GetFrequency(), 100));
|
||||
Fw.PrintTextOnScreen(kupa, 0, 127, 0, 8, 0);
|
||||
Fw.FormatString(kupa, "Irq: 0x%04X", RadioDriver.GetIrqReg());
|
||||
Fw.PrintTextOnScreen(kupa, 0, 127, 2, 8, 0);
|
||||
Fw.FormatString(kupa, "S: %s", C8TxStr);
|
||||
Fw.PrintTextOnScreen(kupa, 0, 127, 4, 8, 0);
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FormatString(kupa, "TX: %u kHz", IntDivide(RadioDriver.GetFrequency(), 100));
|
||||
PrintTextOnScreen(kupa, 0, 127, 0, 8, 0);
|
||||
FormatString(kupa, "Irq: 0x%04X", RadioDriver.GetIrqReg());
|
||||
PrintTextOnScreen(kupa, 0, 127, 2, 8, 0);
|
||||
FormatString(kupa, "S: %s", C8TxStr);
|
||||
PrintTextOnScreen(kupa, 0, 127, 4, 8, 0);
|
||||
FlushFramebufferToScreen();
|
||||
|
||||
|
||||
return;
|
||||
|
@ -144,4 +142,4 @@ private:
|
|||
eState State;
|
||||
unsigned char U8Buff[72];
|
||||
unsigned char u8RxCnt;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -74,4 +74,10 @@ add_custom_target(${NAME}_flash
|
|||
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}
|
||||
)
|
||||
)
|
||||
|
||||
add_custom_target(${NAME}_flash_uart
|
||||
COMMAND ${CMAKE_BINARY_DIR}/tools/k5prog -F -p ${SERIAL_PORT} -b ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin -Y -Y -Y
|
||||
DEPENDS ${NAME}_encoded
|
||||
DEPENDS k5prog
|
||||
)
|
||||
|
|
|
@ -7,18 +7,17 @@
|
|||
|
||||
extern "C" void __libc_init_array();
|
||||
|
||||
const System::TOrgFunctions& Fw = System::OrgFunc_01_26;
|
||||
CSPong<System::OrgFunc_01_26, System::OrgData_01_26> Pong;
|
||||
CSPong Pong;
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
|
@ -36,5 +35,5 @@ extern "C" void SysTick_Handler()
|
|||
{
|
||||
Pong.Handle();
|
||||
}
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
||||
IRQ_SYSTICK();
|
||||
}
|
||||
|
|
|
@ -3,14 +3,13 @@
|
|||
#include "uv_k5_display.hpp"
|
||||
#include "gpt_pong.hpp"
|
||||
|
||||
template <const System::TOrgFunctions &Fw, const System::TOrgData &FwData>
|
||||
class CSPong
|
||||
{
|
||||
public:
|
||||
static constexpr auto StepSize = 0xFFFF / TUV_K5Display::SizeX;
|
||||
static constexpr auto StepSizeFreq = 10'000;
|
||||
CSPong()
|
||||
: DisplayBuff(FwData.pDisplayBuffer), FontSmallNr(FwData.pSmallDigs), Display(DisplayBuff), x(DisplayBuff.SizeX / 2), y(DisplayBuff.SizeY / 2)
|
||||
: DisplayBuff(gDisplayBuffer), FontSmallNr(gSmallDigs), Display(DisplayBuff), x(DisplayBuff.SizeX / 2), y(DisplayBuff.SizeY / 2)
|
||||
,bEnabled(true){};
|
||||
|
||||
void Handle()
|
||||
|
@ -23,7 +22,7 @@ public:
|
|||
DisplayBuff.ClearAll();
|
||||
char C8RssiString[] = "000";
|
||||
|
||||
unsigned int u32Key = Fw.PollKeyboard();
|
||||
unsigned int u32Key = PollKeyboard();
|
||||
if(u32Key == 13) // exit key
|
||||
{
|
||||
bEnabled = false;
|
||||
|
@ -47,7 +46,7 @@ public:
|
|||
u32Cnt++;
|
||||
if((u32Cnt >> 8) % 2)
|
||||
{
|
||||
unsigned int* p32Buff = (unsigned int*)FwData.pDisplayBuffer;
|
||||
unsigned int* p32Buff = (unsigned int*)gDisplayBuffer;
|
||||
for(int i = 0; i < (DisplayBuff.SizeX * DisplayBuff.SizeY) / (8*4); i++)
|
||||
{
|
||||
*p32Buff = ~(*p32Buff);
|
||||
|
@ -56,7 +55,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FlushFramebufferToScreen();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -67,4 +66,4 @@ private:
|
|||
|
||||
unsigned char x, y;
|
||||
bool bEnabled;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -74,4 +74,10 @@ add_custom_target(${NAME}_flash
|
|||
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}
|
||||
)
|
||||
)
|
||||
|
||||
add_custom_target(${NAME}_flash_uart
|
||||
COMMAND ${CMAKE_BINARY_DIR}/tools/k5prog -F -p ${SERIAL_PORT} -b ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin -Y -Y -Y
|
||||
DEPENDS ${NAME}_encoded
|
||||
DEPENDS k5prog
|
||||
)
|
||||
|
|
|
@ -6,18 +6,16 @@
|
|||
#include <string.h>
|
||||
|
||||
Hardware::THardware Hw;
|
||||
const System::TOrgFunctions& Fw = System::OrgFunc_01_26;
|
||||
const System::TOrgData& FwData = System::OrgData_01_26;
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
|
@ -33,7 +31,7 @@ extern "C" void SysTick_Handler()
|
|||
static unsigned int u32StupidCounter = 1;
|
||||
if((!(u32StupidCounter++ % 15) && u32StupidCounter > 200)) // exit key
|
||||
{
|
||||
CRssiPrinter::Handle(Fw, FwData);
|
||||
CRssiPrinter::Handle();
|
||||
}
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
||||
IRQ_SYSTICK();
|
||||
}
|
||||
|
|
|
@ -6,14 +6,14 @@ class CRssiPrinter
|
|||
{
|
||||
public:
|
||||
static constexpr auto ChartStartX = 4*7 + 4;
|
||||
static void Handle(const System::TOrgFunctions& Fw, const System::TOrgData& FwData)
|
||||
static void Handle(void)
|
||||
{
|
||||
static bool bIsCleared = true;
|
||||
static unsigned char u8ChartPosition = 0;
|
||||
static unsigned char u8SqlDelayCnt = 0xFF;
|
||||
static unsigned char U8ScreenHistory[128 - ChartStartX] = {0};
|
||||
TUV_K5Display DisplayBuff(FwData.pDisplayBuffer);
|
||||
const TUV_K5SmallNumbers FontSmallNr(FwData.pSmallDigs);
|
||||
TUV_K5Display DisplayBuff(gDisplayBuffer);
|
||||
const TUV_K5SmallNumbers FontSmallNr(gSmallDigs);
|
||||
CDisplay Display(DisplayBuff);
|
||||
|
||||
if(!(GPIOC->DATA & 0b1))
|
||||
|
@ -22,7 +22,7 @@ class CRssiPrinter
|
|||
}
|
||||
|
||||
auto* pMenuCheckData = (unsigned char*)DisplayBuff.GetCoursorData(DisplayBuff.GetCoursorPosition(2, 6*8 + 1));
|
||||
if(Fw.BK4819Read(0x0C) & 0b10)
|
||||
if(BK4819Read(0x0C) & 0b10)
|
||||
{
|
||||
u8SqlDelayCnt = 0;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class CRssiPrinter
|
|||
u8ChartPosition = 0;
|
||||
if(*pMenuCheckData != 0xFF)
|
||||
{
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FlushFramebufferToScreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ class CRssiPrinter
|
|||
Display.SetFont(&FontSmallNr);
|
||||
|
||||
char C8RssiString[] = "g000";
|
||||
unsigned char u8Rssi = ((Fw.BK4819Read(0x67) >> 1) & 0xFF);
|
||||
unsigned char u8Rssi = ((BK4819Read(0x67) >> 1) & 0xFF);
|
||||
if(!u8Rssi)
|
||||
{
|
||||
return;
|
||||
|
@ -96,6 +96,6 @@ class CRssiPrinter
|
|||
memcpy(pDData, U8ScreenHistory, sizeof(U8ScreenHistory));
|
||||
|
||||
u8ChartPosition++;
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FlushFramebufferToScreen();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -75,4 +75,10 @@ add_custom_target(${NAME}_flash
|
|||
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}
|
||||
)
|
||||
)
|
||||
|
||||
add_custom_target(${NAME}_flash_uart
|
||||
COMMAND ${CMAKE_BINARY_DIR}/tools/k5prog -F -p ${SERIAL_PORT} -b ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin -Y -Y -Y
|
||||
DEPENDS ${NAME}_encoded
|
||||
DEPENDS k5prog
|
||||
)
|
||||
|
|
|
@ -6,21 +6,16 @@
|
|||
#include "rssi_sbar.hpp"
|
||||
#include "manager.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);
|
||||
TUV_K5Display DisplayBuff(gDisplayBuffer);
|
||||
const TUV_K5SmallNumbers FontSmallNr(gSmallDigs);
|
||||
CDisplay Display(DisplayBuff);
|
||||
|
||||
TUV_K5Display StatusBarBuff(FwData.pStatusBarData);
|
||||
TUV_K5Display StatusBarBuff(gStatusBarData);
|
||||
CDisplay DisplayStatusBar(StatusBarBuff);
|
||||
|
||||
Radio::CBK4819<System::OrgFunc_01_26> RadioDriver;
|
||||
Radio::CBK4819 RadioDriver;
|
||||
|
||||
CRssiSbar<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
DisplayBuff,
|
||||
Display,
|
||||
DisplayStatusBar,
|
||||
|
@ -30,8 +25,6 @@ CRssiSbar<
|
|||
|
||||
#ifdef AM_TX
|
||||
CAmTx<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
DisplayBuff,
|
||||
Display,
|
||||
DisplayStatusBar,
|
||||
|
@ -49,20 +42,18 @@ static IView *const Views[] =
|
|||
};
|
||||
|
||||
CViewManager<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
8, 2, sizeof(Views) / sizeof(*Views)>
|
||||
Manager(Views);
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
|
@ -77,5 +68,5 @@ extern "C" void SysTick_Handler()
|
|||
|
||||
RadioDriver.InterruptHandler();
|
||||
Manager.Handle();
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
||||
IRQ_SYSTICK();
|
||||
}
|
||||
|
|
|
@ -75,4 +75,10 @@ add_custom_target(${NAME}_flash
|
|||
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}
|
||||
)
|
||||
)
|
||||
|
||||
add_custom_target(${NAME}_flash_uart
|
||||
COMMAND ${CMAKE_BINARY_DIR}/tools/k5prog -F -p ${SERIAL_PORT} -b ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin -Y -Y -Y
|
||||
DEPENDS ${NAME}_encoded
|
||||
DEPENDS k5prog
|
||||
)
|
||||
|
|
|
@ -7,21 +7,16 @@
|
|||
#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);
|
||||
TUV_K5Display DisplayBuff(gDisplayBuffer);
|
||||
const TUV_K5SmallNumbers FontSmallNr(gSmallDigs);
|
||||
CDisplay Display(DisplayBuff);
|
||||
|
||||
TUV_K5Display StatusBarBuff(FwData.pStatusBarData);
|
||||
TUV_K5Display StatusBarBuff(gStatusBarData);
|
||||
CDisplay DisplayStatusBar(StatusBarBuff);
|
||||
|
||||
Radio::CBK4819<System::OrgFunc_01_26> RadioDriver;
|
||||
Radio::CBK4819 RadioDriver;
|
||||
|
||||
CRssiSbar<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
DisplayBuff,
|
||||
Display,
|
||||
DisplayStatusBar,
|
||||
|
@ -29,8 +24,6 @@ CRssiSbar<
|
|||
RadioDriver>
|
||||
RssiSbar;
|
||||
// CAmTx<
|
||||
// System::OrgFunc_01_26,
|
||||
// System::OrgData_01_26,
|
||||
// DisplayBuff,
|
||||
// Display,
|
||||
// DisplayStatusBar,
|
||||
|
@ -38,32 +31,29 @@ CRssiSbar<
|
|||
// 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;
|
||||
CHeater Heater;
|
||||
CAmRx AmRx;
|
||||
// CMicVal<RadioDriver> MicVal;
|
||||
// CRssiVal<RadioDriver> RssiVal;
|
||||
|
||||
static IMenuElement * const MainMenuElements[] = {&Heater, &AmRx, &RssiSbar};
|
||||
|
||||
CMenu<System::OrgFunc_01_26,
|
||||
System::OrgData_01_26> Menu(MainMenuElements);
|
||||
CMenu 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();
|
||||
IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
|
@ -78,5 +68,5 @@ extern "C" void SysTick_Handler()
|
|||
|
||||
// RadioDriver.InterruptHandler();
|
||||
Manager.Handle();
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
||||
IRQ_SYSTICK();
|
||||
}
|
||||
|
|
|
@ -76,4 +76,10 @@ add_custom_target(${NAME}_flash
|
|||
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}
|
||||
)
|
||||
)
|
||||
|
||||
add_custom_target(${NAME}_flash_uart
|
||||
COMMAND ${CMAKE_BINARY_DIR}/tools/k5prog -F -p ${SERIAL_PORT} -b ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin -Y -Y -Y
|
||||
DEPENDS ${NAME}_encoded
|
||||
DEPENDS k5prog
|
||||
)
|
||||
|
|
|
@ -6,21 +6,19 @@
|
|||
#include <string.h>
|
||||
|
||||
Hardware::THardware Hw;
|
||||
const System::TOrgFunctions& Fw = System::OrgFunc_01_26;
|
||||
const System::TOrgData& FwData = System::OrgData_01_26;
|
||||
|
||||
CSpectrum<System::OrgFunc_01_26, System::OrgData_01_26> Spectrum;
|
||||
CSpectrum Spectrum;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
|
@ -37,8 +35,8 @@ extern "C" void SysTick_Handler()
|
|||
bFirstInit = true;
|
||||
}
|
||||
|
||||
bool bPreventWhileKeypadPolling = pStackedRegs->LR > (unsigned int)Fw.PollKeyboard &&
|
||||
pStackedRegs->PC < (unsigned int)Fw.PollKeyboard + 0x100; // i made a mistake and compared PC and LR, but this works fine xD
|
||||
bool bPreventWhileKeypadPolling = pStackedRegs->LR > (unsigned int)PollKeyboard &&
|
||||
pStackedRegs->PC < (unsigned int)PollKeyboard + 0x100; // i made a mistake and compared PC and LR, but this works fine xD
|
||||
|
||||
static unsigned int u32StupidCounter = 1;
|
||||
if(u32StupidCounter++ > 200 && !bPreventWhileKeypadPolling)
|
||||
|
@ -46,5 +44,5 @@ extern "C" void SysTick_Handler()
|
|||
Spectrum.Handle();
|
||||
}
|
||||
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
||||
IRQ_SYSTICK();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ static constexpr auto operator""_MHz(unsigned long long KiloHertz)
|
|||
return KiloHertz * 1000_KHz;
|
||||
}
|
||||
|
||||
template <const System::TOrgFunctions &Fw, const System::TOrgData &FwData>
|
||||
class CSpectrum
|
||||
{
|
||||
public:
|
||||
|
@ -33,8 +32,8 @@ public:
|
|||
static constexpr auto PressDuration = 30;
|
||||
static constexpr auto BWStep = 200_KHz;
|
||||
CSpectrum()
|
||||
: DisplayBuff(FwData.pDisplayBuffer),
|
||||
FontSmallNr(FwData.pSmallDigs),
|
||||
: DisplayBuff(gDisplayBuffer),
|
||||
FontSmallNr(gSmallDigs),
|
||||
Display(DisplayBuff),
|
||||
bDisplayCleared(true),
|
||||
u32ScanRange(1_MHz),
|
||||
|
@ -58,9 +57,9 @@ public:
|
|||
{
|
||||
bDisplayCleared = true;
|
||||
ClearDrawings();
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FlushFramebufferToScreen();
|
||||
SetFrequency(u32OldFreq);
|
||||
Fw.BK4819Write(0x47, u16OldAfSettings); // set previous AF settings
|
||||
BK4819Write(0x47, u16OldAfSettings); // set previous AF settings
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -69,8 +68,8 @@ public:
|
|||
if (bDisplayCleared)
|
||||
{
|
||||
u32OldFreq = GetFrequency();
|
||||
u16OldAfSettings = Fw.BK4819Read(0x47);
|
||||
Fw.BK4819Write(0x47, 0); // mute AF during scan
|
||||
u16OldAfSettings = BK4819Read(0x47);
|
||||
BK4819Write(0x47, 0); // mute AF during scan
|
||||
}
|
||||
|
||||
bDisplayCleared = false;
|
||||
|
@ -118,7 +117,7 @@ public:
|
|||
{
|
||||
if (!(u8Pos % (DisplayBuff.SizeX / LabelsCnt)) || u8Pos == DisplayBuff.SizeX - 1)
|
||||
{
|
||||
*(FwData.pDisplayBuffer + 2 * DisplayBuff.SizeX + u8Pos) = 0xFF;
|
||||
gDisplayBuffer[2 * DisplayBuff.SizeX + u8Pos] = 0xFF;
|
||||
}
|
||||
|
||||
auto const FreqOffset = (u8Pos * u32ScanRange) >> 7;
|
||||
|
@ -140,7 +139,7 @@ public:
|
|||
}
|
||||
}
|
||||
// Display.DrawRectangle(0,0, 7, 7, 0);
|
||||
memcpy(FwData.pDisplayBuffer + 8 * 2 + 10 * 6 + 2, FwData.pSmallLeters + 18 + 5, 7);
|
||||
memcpy(gDisplayBuffer + 8 * 2 + 10 * 6 + 2, gSmallLeters + 18 + 5, 7);
|
||||
Display.SetCoursor(0, 0);
|
||||
Display.PrintFixedDigitsNumber2(u32OldFreq);
|
||||
Display.SetCoursor(1, 0);
|
||||
|
@ -152,31 +151,31 @@ public:
|
|||
Display.SetCoursor(0, 8 * 2 + 10 * 7);
|
||||
Display.PrintFixedDigitsNumber2(u32Peak);
|
||||
|
||||
memcpy(FwData.pDisplayBuffer + 128 * 2 + u8PeakPos - 3, FwData.pSmallLeters + 18 + 5, 7);
|
||||
Fw.FlushFramebufferToScreen();
|
||||
memcpy(gDisplayBuffer + 128 * 2 + u8PeakPos - 3, gSmallLeters + 18 + 5, 7);
|
||||
FlushFramebufferToScreen();
|
||||
}
|
||||
|
||||
private:
|
||||
void SetFrequency(unsigned int u32Freq)
|
||||
{
|
||||
Fw.BK4819Write(0x39, ((u32Freq >> 16) & 0xFFFF));
|
||||
Fw.BK4819Write(0x38, (u32Freq & 0xFFFF));
|
||||
// Fw.BK4819Write(0x37,7951);
|
||||
Fw.BK4819Write(0x30, 0);
|
||||
Fw.BK4819Write(0x30, 0xbff1);
|
||||
BK4819Write(0x39, ((u32Freq >> 16) & 0xFFFF));
|
||||
BK4819Write(0x38, (u32Freq & 0xFFFF));
|
||||
// BK4819Write(0x37,7951);
|
||||
BK4819Write(0x30, 0);
|
||||
BK4819Write(0x30, 0xbff1);
|
||||
}
|
||||
|
||||
unsigned char GetRssi(unsigned int u32Freq)
|
||||
{
|
||||
SetFrequency(u32Freq);
|
||||
Fw.DelayUs(800);
|
||||
return ((Fw.BK4819Read(0x67) >> 1) & 0xFF);
|
||||
DelayUs(800);
|
||||
return ((BK4819Read(0x67) >> 1) & 0xFF);
|
||||
}
|
||||
|
||||
unsigned int GetFrequency()
|
||||
{
|
||||
unsigned short u16f1 = Fw.BK4819Read(0x39);
|
||||
unsigned short u16f2 = Fw.BK4819Read(0x38);
|
||||
unsigned short u16f1 = BK4819Read(0x39);
|
||||
unsigned short u16f2 = BK4819Read(0x38);
|
||||
return ((u16f1 << 16) | u16f2);
|
||||
}
|
||||
|
||||
|
@ -187,12 +186,12 @@ private:
|
|||
{
|
||||
bEnabled = true;
|
||||
GPIOC->DATA &= ~GPIO_PIN_3;
|
||||
*FwData.p8FlashLightStatus = 3;
|
||||
gFlashLightStatus = 3;
|
||||
}
|
||||
|
||||
if (bEnabled)
|
||||
{
|
||||
u8LastBtnPressed = Fw.PollKeyboard();
|
||||
u8LastBtnPressed = PollKeyboard();
|
||||
}
|
||||
|
||||
bool bPtt = !(GPIOC->DATA & GPIO_PIN_5);
|
||||
|
@ -206,7 +205,7 @@ private:
|
|||
|
||||
void ClearDrawings()
|
||||
{
|
||||
memset(FwData.pDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY);
|
||||
memset(gDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY);
|
||||
}
|
||||
|
||||
TUV_K5Display DisplayBuff;
|
||||
|
@ -223,4 +222,4 @@ private:
|
|||
unsigned char u8ResolutionDiv;
|
||||
bool bEnabled;
|
||||
char C8Info[20];
|
||||
};
|
||||
};
|
||||
|
|
|
@ -78,3 +78,9 @@ 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}
|
||||
)
|
||||
|
||||
add_custom_target(${NAME}_flash_uart
|
||||
COMMAND ${CMAKE_BINARY_DIR}/tools/k5prog -F -p ${SERIAL_PORT} -b ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin -Y -Y -Y
|
||||
DEPENDS ${NAME}_encoded
|
||||
DEPENDS k5prog
|
||||
)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
enum Keys {
|
||||
NUM0,
|
||||
NUM1,
|
||||
NUM2,
|
||||
NUM3,
|
||||
NUM4,
|
||||
NUM5,
|
||||
NUM6,
|
||||
NUM7,
|
||||
NUM8,
|
||||
NUM9,
|
||||
MENU, // 10
|
||||
UP, // 11
|
||||
DOWN, // 12
|
||||
EXIT, // 13
|
||||
ASTERISK, // 14
|
||||
FUNCTION, // 15
|
||||
_NA16,
|
||||
_NA17,
|
||||
_NA18,
|
||||
_NA19,
|
||||
_NA20,
|
||||
_NA21,
|
||||
FN2, // 22
|
||||
FN1, // 23
|
||||
};
|
|
@ -1,24 +1,21 @@
|
|||
#include "hardware/hardware.hpp"
|
||||
#include "radio.hpp"
|
||||
#include "registers.hpp"
|
||||
#include "spectrum.hpp"
|
||||
#include "system.hpp"
|
||||
#include "radio.hpp"
|
||||
#include "uv_k5_display.hpp"
|
||||
#include <string.h>
|
||||
|
||||
Hardware::THardware Hw;
|
||||
const System::TOrgFunctions &Fw = System::OrgFunc_01_26;
|
||||
const System::TOrgData &FwData = System::OrgData_01_26;
|
||||
|
||||
Radio::CBK4819<System::OrgFunc_01_26> RadioDriver;
|
||||
CSpectrum<System::OrgFunc_01_26, System::OrgData_01_26, RadioDriver> Spectrum;
|
||||
Radio::CBK4819 RadioDriver;
|
||||
CSpectrum<RadioDriver> Spectrum;
|
||||
|
||||
int main() {
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler() { Fw.IRQ_RESET(); }
|
||||
extern "C" void Reset_Handler() { IRQ_RESET(); }
|
||||
|
||||
extern "C" void SysTick_Handler() {
|
||||
static bool bFirstInit = false;
|
||||
|
@ -30,5 +27,5 @@ extern "C" void SysTick_Handler() {
|
|||
|
||||
Spectrum.Handle();
|
||||
|
||||
Fw.IRQ_SYSTICK();
|
||||
IRQ_SYSTICK();
|
||||
}
|
||||
|
|
|
@ -1,372 +1,367 @@
|
|||
#pragma once
|
||||
#include "keys.hpp"
|
||||
#include "radio.hpp"
|
||||
#include "system.hpp"
|
||||
#include "types.hpp"
|
||||
#include "uv_k5_display.hpp"
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed short i16;
|
||||
typedef unsigned short u16;
|
||||
typedef signed int i32;
|
||||
typedef unsigned int u32;
|
||||
typedef signed long long i64;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
template <const System::TOrgFunctions &Fw, const System::TOrgData &FwData,
|
||||
Radio::CBK4819<Fw> &RadioDriver>
|
||||
class CSpectrum {
|
||||
template <Radio::CBK4819 &RadioDriver> class CSpectrum {
|
||||
public:
|
||||
static constexpr auto ExitKey = 13;
|
||||
static constexpr auto DrawingEndY = 42;
|
||||
static constexpr auto BarPos = 5 * 128;
|
||||
|
||||
u8 rssiHistory[64] = {};
|
||||
u8 measurementsCount = 32;
|
||||
static constexpr auto ModesCount = 7;
|
||||
static constexpr auto LastLowBWModeIndex = 3;
|
||||
|
||||
static constexpr u32 modeHalfSpectrumBW[ModesCount] = {
|
||||
16_KHz, 50_KHz, 100_KHz, 200_KHz, 400_KHz, 800_KHz, 1600_KHz};
|
||||
static constexpr u16 modeScanStep[ModesCount] = {
|
||||
1_KHz, 3125_Hz, 6250_Hz, 12500_Hz, 25_KHz, 25_KHz, 25_KHz};
|
||||
static constexpr u8 modeXdiv[ModesCount] = {2, 2, 2, 2, 2, 1, 0};
|
||||
|
||||
u8 rssiHistory[128] = {};
|
||||
u32 fMeasure;
|
||||
|
||||
u8 peakT = 0;
|
||||
u8 peakRssi = 0;
|
||||
u8 peakI = 0;
|
||||
u32 peakF = 0;
|
||||
u8 rssiMin = 255;
|
||||
u8 highestPeakX = 0;
|
||||
u8 highestPeakT = 0;
|
||||
u8 highestPeakRssi = 0;
|
||||
u32 highestPeakF = 0;
|
||||
u32 FStart, fMeasure;
|
||||
u8 btnCounter = 0;
|
||||
|
||||
CSpectrum()
|
||||
: DisplayBuff(FwData.pDisplayBuffer), FontSmallNr(FwData.pSmallDigs),
|
||||
Display(DisplayBuff), scanDelay(800), sampleZoom(2), scanStep(25_KHz),
|
||||
frequencyChangeStep(100_KHz), rssiTriggerLevel(65) {
|
||||
: DisplayBuff(gDisplayBuffer), Display(DisplayBuff),
|
||||
FontSmallNr(gSmallDigs), scanDelay(800), mode(5), rssiTriggerLevel(50) {
|
||||
Display.SetFont(&FontSmallNr);
|
||||
frequencyChangeStep = modeHalfSpectrumBW[mode];
|
||||
};
|
||||
|
||||
inline bool ListenPeak() {
|
||||
if (highestPeakRssi < rssiTriggerLevel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fMeasure != highestPeakF) {
|
||||
fMeasure = highestPeakF;
|
||||
RadioDriver.SetFrequency(fMeasure);
|
||||
Fw.BK4819Write(0x47, u16OldAfSettings);
|
||||
RadioDriver.ToggleAFDAC(true);
|
||||
}
|
||||
|
||||
// measure peak for this moment
|
||||
|
||||
highestPeakRssi = GetRssi(); // also sets freq for us
|
||||
rssiHistory[highestPeakX >> sampleZoom] = highestPeakRssi;
|
||||
|
||||
if (highestPeakRssi >= rssiTriggerLevel) {
|
||||
Listen(1000000);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void Scan() {
|
||||
void Scan() {
|
||||
u8 rssi = 0, rssiMax = 0;
|
||||
u8 iPeak = 0;
|
||||
u32 fPeak = currentFreq;
|
||||
|
||||
rssiMin = 255;
|
||||
fMeasure = FStart;
|
||||
RadioDriver.ToggleAFDAC(false);
|
||||
Fw.BK4819Write(0x47, 0);
|
||||
fMeasure = GetFStart();
|
||||
|
||||
for (u8 i = 0; i < measurementsCount; ++i, fMeasure += scanStep) {
|
||||
rssi = rssiHistory[i] = GetRssi(fMeasure);
|
||||
if (rssi < rssiMin) {
|
||||
rssiMin = rssi;
|
||||
// RadioDriver.ToggleAFDAC(false);
|
||||
MuteAF();
|
||||
|
||||
u16 scanStep = GetScanStep();
|
||||
u8 measurementsCount = GetMeasurementsCount();
|
||||
|
||||
for (u8 i = 0;
|
||||
i < measurementsCount && (PollKeyboard() == 255 || resetBlacklist);
|
||||
++i, fMeasure += scanStep) {
|
||||
if (!resetBlacklist && rssiHistory[i] == 255) {
|
||||
continue;
|
||||
}
|
||||
RadioDriver.SetFrequency(fMeasure);
|
||||
rssi = rssiHistory[i] = GetRssi();
|
||||
if (rssi > rssiMax) {
|
||||
rssiMax = rssi;
|
||||
fPeak = fMeasure;
|
||||
iPeak = i;
|
||||
}
|
||||
if (rssi < rssiMin) {
|
||||
rssiMin = rssi;
|
||||
}
|
||||
}
|
||||
resetBlacklist = false;
|
||||
++peakT;
|
||||
|
||||
++highestPeakT;
|
||||
if (rssiMax > highestPeakRssi || highestPeakT >= (8 << sampleZoom)) {
|
||||
highestPeakT = 0;
|
||||
highestPeakRssi = rssiMax;
|
||||
highestPeakX = iPeak << sampleZoom;
|
||||
highestPeakF = fPeak;
|
||||
if (rssiMax > peakRssi || peakT >= 16) {
|
||||
peakT = 0;
|
||||
peakRssi = rssiMax;
|
||||
peakF = fPeak;
|
||||
peakI = iPeak;
|
||||
}
|
||||
}
|
||||
|
||||
inline void DrawSpectrum() {
|
||||
void DrawSpectrum() {
|
||||
for (u8 x = 0; x < 128; ++x) {
|
||||
Display.DrawHLine(Rssi2Y(rssiHistory[x >> sampleZoom]), DrawingEndY, x);
|
||||
auto v = rssiHistory[x >> modeXdiv[mode]];
|
||||
if (v != 255) {
|
||||
Display.DrawHLine(Rssi2Y(v), DrawingEndY, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void DrawNums() {
|
||||
void DrawNums() {
|
||||
Display.SetCoursorXY(0, 0);
|
||||
Display.PrintFixedDigitsNumber2(scanDelay, 0);
|
||||
Display.PrintFixedDigitsNumber3(scanDelay, 2, 2, 1);
|
||||
|
||||
Display.SetCoursorXY(51, 0);
|
||||
Display.PrintFixedDigitsNumber2(scanStep << (7 - sampleZoom));
|
||||
Display.SetCoursorXY(105, 0);
|
||||
Display.PrintFixedDigitsNumber3(GetBW(), 3, 3, 2);
|
||||
|
||||
Display.SetCoursorXY(58, 8);
|
||||
Display.PrintFixedDigitsNumber2(scanStep);
|
||||
Display.SetCoursorXY(42, 0);
|
||||
Display.PrintFixedDigitsNumber3(peakF, 2, 6, 3);
|
||||
|
||||
Display.SetCoursorXY(107, 8);
|
||||
Display.PrintFixedDigitsNumber2(highestPeakRssi, 0);
|
||||
Display.SetCoursorXY(0, 48);
|
||||
Display.PrintFixedDigitsNumber3(GetFStart(), 4, 4, 1);
|
||||
|
||||
Display.SetCoursorXY(86, 0);
|
||||
Display.PrintFixedDigitsNumber2(highestPeakF);
|
||||
Display.SetCoursorXY(98, 48);
|
||||
Display.PrintFixedDigitsNumber3(GetFEnd(), 4, 4, 1);
|
||||
|
||||
Display.SetCoursorXY(44, 48);
|
||||
Display.PrintFixedDigitsNumber2(currentFreq);
|
||||
|
||||
Display.SetCoursorXY(100, 48);
|
||||
Display.PrintFixedDigitsNumber2(frequencyChangeStep);
|
||||
|
||||
Display.SetCoursorXY(0, 8);
|
||||
Display.PrintFixedDigitsNumber2(rssiTriggerLevel, 0);
|
||||
Display.SetCoursorXY(52, 48);
|
||||
Display.PrintFixedDigitsNumber3(frequencyChangeStep, 3, 3, 2);
|
||||
}
|
||||
|
||||
inline void DrawRssiTriggerLevel() {
|
||||
Display.DrawLine(0, 127, Rssi2Y(rssiTriggerLevel));
|
||||
}
|
||||
|
||||
inline void DrawTicks() {
|
||||
u32 f = modulo(FStart, 1_MHz);
|
||||
u32 step = scanStep >> sampleZoom;
|
||||
for (u8 i = 0; i < 128; ++i, f += step) {
|
||||
u8 barValue = 0b00001000;
|
||||
modulo(f, 100_KHz) < step && (barValue |= 0b00010000);
|
||||
modulo(f, 500_KHz) < step && (barValue |= 0b00100000);
|
||||
modulo(f, 1_MHz) < step && (barValue |= 0b11000000);
|
||||
|
||||
*(FwData.pDisplayBuffer + BarPos + i) |= barValue;
|
||||
void DrawRssiTriggerLevel() {
|
||||
u8 y = Rssi2Y(rssiTriggerLevel);
|
||||
for (u8 x = 0; x < 126; x += 4) {
|
||||
Display.DrawLine(x, x + 2, y);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTicks() {
|
||||
// center
|
||||
*(FwData.pDisplayBuffer + BarPos + 64) |= 0b10101010;
|
||||
gDisplayBuffer[BarPos + 64] = 0b00111000;
|
||||
}
|
||||
|
||||
inline void DrawArrow(u8 x) {
|
||||
u8 *peakPos = FwData.pDisplayBuffer + BarPos + x;
|
||||
x > 1 && (*(peakPos - 2) |= 0b01000000);
|
||||
x > 0 && (*(peakPos - 1) |= 0b01100000);
|
||||
(*(peakPos) |= 0b01110000);
|
||||
x < 127 && (*(peakPos + 1) |= 0b01100000);
|
||||
x < 128 && (*(peakPos + 2) |= 0b01000000);
|
||||
void DrawArrow(u8 x) {
|
||||
for (signed i = -2; i <= 2; ++i) {
|
||||
signed v = x + i;
|
||||
if (!(v & 128)) {
|
||||
gDisplayBuffer[BarPos + v] |= (0b01111000 << abs(i)) & 0b01111000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleUserInput() {
|
||||
switch (lastButtonPressed) {
|
||||
case 1:
|
||||
UpdateScanDelay(200);
|
||||
void OnKeyDown(u8 key) {
|
||||
switch (key) {
|
||||
case Keys::NUM1:
|
||||
if (scanDelay < 8000) {
|
||||
scanDelay += 100;
|
||||
rssiMin = 255;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
UpdateScanDelay(-200);
|
||||
case Keys::NUM7:
|
||||
if (scanDelay > 400) {
|
||||
scanDelay -= 100;
|
||||
rssiMin = 255;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
UpdateSampleZoom(1);
|
||||
case Keys::NUM3:
|
||||
UpdateBWMul(1);
|
||||
resetBlacklist = true;
|
||||
break;
|
||||
case 8:
|
||||
UpdateSampleZoom(-1);
|
||||
case Keys::NUM9:
|
||||
UpdateBWMul(-1);
|
||||
resetBlacklist = true;
|
||||
break;
|
||||
case 3:
|
||||
UpdateRssiTriggerLevel(5);
|
||||
break;
|
||||
case 9:
|
||||
UpdateRssiTriggerLevel(-5);
|
||||
break;
|
||||
case 4:
|
||||
UpdateScanStep(-1);
|
||||
UpdateSampleZoom(1);
|
||||
break;
|
||||
case 6:
|
||||
UpdateScanStep(1);
|
||||
UpdateSampleZoom(-1);
|
||||
break;
|
||||
case 11: // up
|
||||
UpdateCurrentFreq(frequencyChangeStep);
|
||||
break;
|
||||
case 12: // down
|
||||
UpdateCurrentFreq(-frequencyChangeStep);
|
||||
break;
|
||||
case 14:
|
||||
case Keys::NUM2:
|
||||
UpdateFreqChangeStep(100_KHz);
|
||||
break;
|
||||
case 15:
|
||||
case Keys::NUM8:
|
||||
UpdateFreqChangeStep(-100_KHz);
|
||||
break;
|
||||
case 5:
|
||||
case Keys::UP:
|
||||
UpdateCurrentFreq(frequencyChangeStep);
|
||||
resetBlacklist = true;
|
||||
break;
|
||||
case Keys::DOWN:
|
||||
UpdateCurrentFreq(-frequencyChangeStep);
|
||||
resetBlacklist = true;
|
||||
break;
|
||||
case Keys::NUM5:
|
||||
ToggleBacklight();
|
||||
default:
|
||||
isUserInput = false;
|
||||
break;
|
||||
case Keys::NUM0:
|
||||
Blacklist();
|
||||
break;
|
||||
case Keys::ASTERISK:
|
||||
UpdateRssiTriggerLevel(1);
|
||||
DelayMs(90);
|
||||
break;
|
||||
case Keys::FUNCTION:
|
||||
UpdateRssiTriggerLevel(-1);
|
||||
DelayMs(90);
|
||||
break;
|
||||
}
|
||||
ResetPeak();
|
||||
}
|
||||
|
||||
bool HandleUserInput() {
|
||||
btnPrev = btn;
|
||||
btn = PollKeyboard();
|
||||
if (btn == Keys::EXIT) {
|
||||
DeInit();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (btn != 255) {
|
||||
if (btn == btnPrev && btnCounter < 255) {
|
||||
btnCounter++;
|
||||
}
|
||||
if (btnPrev == 255 || btnCounter > 16) {
|
||||
OnKeyDown(btn);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
btnCounter = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Render() {
|
||||
DisplayBuff.ClearAll();
|
||||
DrawTicks();
|
||||
DrawArrow(highestPeakX);
|
||||
DrawArrow(peakI << modeXdiv[mode]);
|
||||
DrawSpectrum();
|
||||
DrawRssiTriggerLevel();
|
||||
DrawNums();
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FlushFramebufferToScreen();
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (bDisplayCleared) {
|
||||
currentFreq = RadioDriver.GetFrequency();
|
||||
OnUserInput();
|
||||
u16OldAfSettings = Fw.BK4819Read(0x47);
|
||||
Fw.BK4819Write(0x47, 0); // mute AF during scan
|
||||
if (peakRssi >= rssiTriggerLevel) {
|
||||
ToggleGreen(true);
|
||||
GPIOC->DATA |= GPIO_PIN_4;
|
||||
Listen();
|
||||
}
|
||||
bDisplayCleared = false;
|
||||
|
||||
HandleUserInput();
|
||||
|
||||
if (!ListenPeak())
|
||||
if (peakRssi < rssiTriggerLevel) {
|
||||
ToggleGreen(false);
|
||||
GPIOC->DATA &= ~GPIO_PIN_4;
|
||||
Scan();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateRssiTriggerLevel(i32 diff) {
|
||||
rssiTriggerLevel = clamp(rssiTriggerLevel + diff, 10, 255);
|
||||
OnUserInput();
|
||||
}
|
||||
void UpdateRssiTriggerLevel(i32 diff) { rssiTriggerLevel += diff; }
|
||||
|
||||
void UpdateScanDelay(i32 diff) {
|
||||
scanDelay = clamp(scanDelay + diff, 800, 3200);
|
||||
OnUserInput();
|
||||
}
|
||||
|
||||
void UpdateSampleZoom(i32 diff) {
|
||||
sampleZoom = clamp(sampleZoom - diff, 1, 5);
|
||||
measurementsCount = 1 << (7 - sampleZoom);
|
||||
OnUserInput();
|
||||
void UpdateBWMul(i32 diff) {
|
||||
if ((diff > 0 && mode < (ModesCount - 1)) || (diff < 0 && mode > 0)) {
|
||||
mode += diff;
|
||||
SetBW();
|
||||
rssiMin = 255;
|
||||
frequencyChangeStep = modeHalfSpectrumBW[mode];
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCurrentFreq(i64 diff) {
|
||||
currentFreq = clamp(currentFreq + diff, 18_MHz, 1300_MHz);
|
||||
OnUserInput();
|
||||
}
|
||||
|
||||
void UpdateScanStep(i32 diff) {
|
||||
if (diff > 0 && scanStep < 25_KHz) {
|
||||
scanStep <<= 1;
|
||||
if ((diff > 0 && currentFreq < 1300_MHz) ||
|
||||
(diff < 0 && currentFreq > 18_MHz)) {
|
||||
currentFreq += diff;
|
||||
}
|
||||
if (diff < 0 && scanStep > 6250_Hz) {
|
||||
scanStep >>= 1;
|
||||
}
|
||||
OnUserInput();
|
||||
}
|
||||
|
||||
void UpdateFreqChangeStep(i64 diff) {
|
||||
frequencyChangeStep = clamp(frequencyChangeStep + diff, 100_KHz, 2_MHz);
|
||||
OnUserInput();
|
||||
}
|
||||
|
||||
inline void OnUserInput() {
|
||||
isUserInput = true;
|
||||
u32 halfOfScanRange = scanStep << (6 - sampleZoom);
|
||||
FStart = currentFreq - halfOfScanRange;
|
||||
|
||||
// reset peak
|
||||
highestPeakT = 0;
|
||||
highestPeakRssi = 0;
|
||||
highestPeakX = 64;
|
||||
highestPeakF = currentFreq;
|
||||
|
||||
Fw.DelayUs(90000);
|
||||
}
|
||||
void Blacklist() { rssiHistory[peakI] = 255; }
|
||||
|
||||
void Handle() {
|
||||
if (RadioDriver.IsLockedByOrgFw()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!working) {
|
||||
if (IsFlashLightOn()) {
|
||||
working = true;
|
||||
TurnOffFlashLight();
|
||||
}
|
||||
return;
|
||||
if (!isInitialized && IsFlashLightOn()) {
|
||||
TurnOffFlashLight();
|
||||
Init();
|
||||
}
|
||||
|
||||
lastButtonPressed = Fw.PollKeyboard();
|
||||
if (lastButtonPressed == ExitKey) {
|
||||
working = false;
|
||||
RestoreParams();
|
||||
return;
|
||||
if (isInitialized && HandleUserInput()) {
|
||||
Update();
|
||||
Render();
|
||||
}
|
||||
Update();
|
||||
Render();
|
||||
}
|
||||
|
||||
private:
|
||||
void RestoreParams() {
|
||||
if (!bDisplayCleared) {
|
||||
bDisplayCleared = true;
|
||||
DisplayBuff.ClearAll();
|
||||
Fw.FlushFramebufferToScreen();
|
||||
RadioDriver.SetFrequency(currentFreq);
|
||||
Fw.BK4819Write(0x47, u16OldAfSettings); // set previous AF settings
|
||||
}
|
||||
void Init() {
|
||||
currentFreq = RadioDriver.GetFrequency();
|
||||
oldAFSettings = BK4819Read(0x47);
|
||||
oldBWSettings = BK4819Read(0x43);
|
||||
MuteAF();
|
||||
SetBW();
|
||||
ResetPeak();
|
||||
resetBlacklist = true;
|
||||
ToggleGreen(false);
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
inline void Listen(u32 duration) {
|
||||
for (u8 i = 0; i < 16 && lastButtonPressed == 255; ++i) {
|
||||
lastButtonPressed = Fw.PollKeyboard();
|
||||
Fw.DelayUs(duration >> 4);
|
||||
void DeInit() {
|
||||
DisplayBuff.ClearAll();
|
||||
FlushFramebufferToScreen();
|
||||
RadioDriver.SetFrequency(currentFreq);
|
||||
RestoreOldAFSettings();
|
||||
BK4819Write(0x43, oldBWSettings);
|
||||
ToggleGreen(true);
|
||||
isInitialized = false;
|
||||
}
|
||||
|
||||
void ResetPeak() { peakRssi = 0; }
|
||||
|
||||
void SetBW() { BK4819SetChannelBandwidth(mode <= LastLowBWModeIndex); }
|
||||
void MuteAF() { BK4819Write(0x47, 0); }
|
||||
void RestoreOldAFSettings() { BK4819Write(0x47, oldAFSettings); }
|
||||
|
||||
void Listen() {
|
||||
if (fMeasure != peakF) {
|
||||
fMeasure = peakF;
|
||||
RadioDriver.SetFrequency(fMeasure);
|
||||
RestoreOldAFSettings();
|
||||
// RadioDriver.ToggleAFDAC(true);
|
||||
}
|
||||
for (u8 i = 0; i < 16 && PollKeyboard() == 255; ++i) {
|
||||
DelayMs(64);
|
||||
}
|
||||
peakRssi = rssiHistory[peakI] = GetRssi();
|
||||
}
|
||||
|
||||
u16 GetScanStep() { return modeScanStep[mode]; }
|
||||
u32 GetBW() { return modeHalfSpectrumBW[mode] << 1; }
|
||||
u32 GetFStart() { return currentFreq - modeHalfSpectrumBW[mode]; }
|
||||
u32 GetFEnd() { return currentFreq + modeHalfSpectrumBW[mode]; }
|
||||
|
||||
u8 GetMeasurementsCount() { return 128 >> modeXdiv[mode]; }
|
||||
|
||||
void ResetRSSI() {
|
||||
RadioDriver.ToggleRXDSP(false);
|
||||
RadioDriver.ToggleRXDSP(true);
|
||||
}
|
||||
|
||||
u8 GetRssi() {
|
||||
Fw.BK4819Read(0x67); //reset RSSI =)
|
||||
Fw.DelayUs(scanDelay);
|
||||
return Fw.BK4819Read(0x67);
|
||||
ResetRSSI();
|
||||
|
||||
DelayUs(scanDelay << (mode <= LastLowBWModeIndex));
|
||||
auto v = BK4819Read(0x67) & 0x1FF;
|
||||
return v < 255 ? v : 255;
|
||||
}
|
||||
|
||||
u8 GetRssi(u32 f) {
|
||||
RadioDriver.SetFrequency(f);
|
||||
return GetRssi();
|
||||
}
|
||||
|
||||
inline bool IsFlashLightOn() { return GPIOC->DATA & GPIO_PIN_3; }
|
||||
inline void TurnOffFlashLight() {
|
||||
bool IsFlashLightOn() { return GPIOC->DATA & GPIO_PIN_3; }
|
||||
void TurnOffFlashLight() {
|
||||
GPIOC->DATA &= ~GPIO_PIN_3;
|
||||
*FwData.p8FlashLightStatus = 3;
|
||||
gFlashLightStatus = 3;
|
||||
}
|
||||
|
||||
inline void ToggleBacklight() { GPIOB->DATA ^= GPIO_PIN_6; }
|
||||
void ToggleBacklight() { GPIOB->DATA ^= GPIO_PIN_6; }
|
||||
|
||||
inline u8 Rssi2Y(u8 rssi) {
|
||||
return clamp(DrawingEndY - (rssi - rssiMin), 1, DrawingEndY);
|
||||
void ToggleRed(bool flag) { BK4819SetGpio(5, flag); }
|
||||
void ToggleGreen(bool flag) { BK4819SetGpio(6, flag); }
|
||||
|
||||
u8 Rssi2Y(u8 rssi) {
|
||||
return DrawingEndY - clamp(rssi - rssiMin, 0, DrawingEndY);
|
||||
}
|
||||
|
||||
inline i32 clamp(i32 v, i32 min, i32 max) {
|
||||
if (v < min)
|
||||
return min;
|
||||
if (v > max)
|
||||
return max;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline u32 modulo(u32 num, u32 div) {
|
||||
while (num >= div)
|
||||
num -= div;
|
||||
return num;
|
||||
i32 clamp(i32 v, i32 min, i32 max) {
|
||||
return v <= min ? min : (v >= max ? max : v);
|
||||
}
|
||||
|
||||
TUV_K5Display DisplayBuff;
|
||||
const TUV_K5SmallNumbers FontSmallNr;
|
||||
CDisplay<const TUV_K5Display> Display;
|
||||
|
||||
u8 lastButtonPressed;
|
||||
u32 currentFreq;
|
||||
u16 u16OldAfSettings;
|
||||
const TUV_K5SmallNumbers FontSmallNr;
|
||||
|
||||
u16 scanDelay;
|
||||
u8 sampleZoom;
|
||||
u32 scanStep;
|
||||
u32 frequencyChangeStep;
|
||||
u8 mode;
|
||||
u8 rssiTriggerLevel;
|
||||
|
||||
bool working = false;
|
||||
bool isUserInput = false;
|
||||
bool bDisplayCleared = true;
|
||||
u8 btn;
|
||||
u8 btnPrev;
|
||||
u32 currentFreq;
|
||||
u16 oldAFSettings;
|
||||
u16 oldBWSettings;
|
||||
u32 frequencyChangeStep;
|
||||
|
||||
bool isInitialized;
|
||||
bool resetBlacklist;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed short i16;
|
||||
typedef unsigned short u16;
|
||||
typedef signed int i32;
|
||||
typedef unsigned int u32;
|
||||
typedef signed long long i64;
|
||||
typedef unsigned long long u64;
|
||||
|
|
@ -77,4 +77,10 @@ add_custom_target(${NAME}_flash
|
|||
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}
|
||||
)
|
||||
)
|
||||
|
||||
add_custom_target(${NAME}_flash_uart
|
||||
COMMAND ${CMAKE_BINARY_DIR}/tools/k5prog -F -p ${SERIAL_PORT} -b ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin -Y -Y -Y
|
||||
DEPENDS ${NAME}_encoded
|
||||
DEPENDS k5prog
|
||||
)
|
||||
|
|
|
@ -6,20 +6,18 @@
|
|||
#include <string.h>
|
||||
|
||||
Hardware::THardware Hw;
|
||||
const System::TOrgFunctions& Fw = System::OrgFunc_01_26;
|
||||
const System::TOrgData& FwData = System::OrgData_01_26;
|
||||
|
||||
CT9Texting<System::OrgFunc_01_26, System::OrgData_01_26> T9Texting;
|
||||
CT9Texting T9Texting;
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
|
@ -36,13 +34,13 @@ extern "C" void SysTick_Handler()
|
|||
bFirstInit = true;
|
||||
}
|
||||
|
||||
bool bPreventWhileKeypadPolling = pStackedRegs->LR > (unsigned int)Fw.PollKeyboard &&
|
||||
pStackedRegs->PC < (unsigned int)Fw.PollKeyboard + 0x100; // i made a mistake and compared PC and LR, but this works fine xD
|
||||
bool bPreventWhileKeypadPolling = pStackedRegs->LR > (unsigned int)PollKeyboard &&
|
||||
pStackedRegs->PC < (unsigned int)PollKeyboard + 0x100; // i made a mistake and compared PC and LR, but this works fine xD
|
||||
|
||||
static unsigned int u32StupidCounter = 1;
|
||||
if(u32StupidCounter++ > 200 && !bPreventWhileKeypadPolling)
|
||||
{
|
||||
T9Texting.Handle();
|
||||
}
|
||||
Fw.IRQ_SYSTICK();
|
||||
}
|
||||
IRQ_SYSTICK();
|
||||
}
|
||||
|
|
|
@ -3,12 +3,11 @@
|
|||
#include "uv_k5_display.hpp"
|
||||
#include "keyboard.hpp"
|
||||
|
||||
template <const System::TOrgFunctions &Fw, const System::TOrgData &FwData>
|
||||
class CT9Texting
|
||||
{
|
||||
public:
|
||||
CT9Texting()
|
||||
: DisplayBuff(FwData.pDisplayBuffer),
|
||||
: DisplayBuff(gDisplayBuffer),
|
||||
Display(DisplayBuff),
|
||||
Keyboard(*this),
|
||||
bDisplayCleared(true),
|
||||
|
@ -67,7 +66,7 @@ public:
|
|||
// Clear cMessage
|
||||
memset(cMessage, 0, 30);
|
||||
c_index = 0;
|
||||
Fw.FlushFramebufferToScreen();
|
||||
FlushFramebufferToScreen();
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -123,8 +122,8 @@ public:
|
|||
prev_key = key;
|
||||
// Display.DrawRectangle(0,0, 7, 7, 0);
|
||||
ClearDrawings();
|
||||
Fw.PrintTextOnScreen(cMessage, 0, 128, 0, 8, 0);
|
||||
Fw.FlushFramebufferToScreen();
|
||||
PrintTextOnScreen(cMessage, 0, 128, 0, 8, 0);
|
||||
FlushFramebufferToScreen();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -136,15 +135,15 @@ private:
|
|||
{
|
||||
bEnabled = true;
|
||||
GPIOC->DATA &= ~GPIO_PIN_3;
|
||||
*FwData.p8FlashLightStatus = 3;
|
||||
gFlashLightStatus = 3;
|
||||
}
|
||||
|
||||
if (bEnabled)
|
||||
{
|
||||
u8LastBtnPressed = Fw.PollKeyboard();
|
||||
u8LastBtnPressed = PollKeyboard();
|
||||
}
|
||||
|
||||
// u8LastBtnPressed = Fw.PollKeyboard();
|
||||
// u8LastBtnPressed = PollKeyboard();
|
||||
// if (u8LastBtnPressed == EnableKey)
|
||||
// {
|
||||
// u8PressCnt++;
|
||||
|
@ -161,7 +160,7 @@ private:
|
|||
|
||||
void ClearDrawings()
|
||||
{
|
||||
memset(FwData.pDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY);
|
||||
memset(gDisplayBuffer, 0, (DisplayBuff.SizeX / 8) * DisplayBuff.SizeY);
|
||||
}
|
||||
|
||||
TUV_K5Display DisplayBuff;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
set(NAME k5prog)
|
||||
set(k5prog_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/k5prog)
|
||||
|
||||
project(${NAME})
|
||||
|
||||
set(CMAKE_C_COMPILER "gcc")
|
||||
add_executable(${NAME} ${k5prog_SRC_DIR}/k5prog.c)
|
||||
target_include_directories(${NAME} PUBLIC ${k5prog_SRC_DIR})
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 15e1dde73e70ec0f3e4c68e48d7e7ddc017cc250
|
Ładowanie…
Reference in New Issue