kopia lustrzana https://github.com/piotr022/UV_K5_playground
rodzic
74da1c24ec
commit
5a999abd10
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -4,246 +4,291 @@
|
|||
#include "system.hpp"
|
||||
#include <functional>
|
||||
|
||||
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>;
|
||||
template <const System::TOrgFunctions &Fw>
|
||||
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)
|
||||
// {
|
||||
// Fw.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);
|
||||
}
|
||||
|
||||
static void ToggleRXDSP(bool enabled) {
|
||||
auto Reg = Fw.BK4819Read(0x30);
|
||||
Reg &= ~1;
|
||||
if (enabled)
|
||||
Reg |= 1;
|
||||
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 (Fw.BK4819Read(0x39) << 16) | Fw.BK4819Read(0x38);
|
||||
}
|
||||
|
||||
auto const IrqReg = GetIrqReg();
|
||||
|
||||
if (IrqReg & eIrq::RxDone) {
|
||||
// HandleRxDone();
|
||||
static signed short GetRssi()
|
||||
{
|
||||
short s16Rssi = ((Fw.BK4819Read(0x67) >> 1) & 0xFF);
|
||||
return s16Rssi - 160;
|
||||
}
|
||||
|
||||
if (IrqReg & eIrq::FifoAlmostFull) {
|
||||
HandleFifoAlmostFull();
|
||||
}
|
||||
}
|
||||
}
|
||||
bool IsTx() { return Fw.BK4819Read(0x30) & 0b10; }
|
||||
|
||||
eState State;
|
||||
unsigned short u16RxDataLen;
|
||||
bool IsSqlOpen() { return Fw.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)
|
||||
{
|
||||
Fw.BK4819Write(0x39, ((u32Freq >> 16) & 0xFFFF));
|
||||
Fw.BK4819Write(0x38, (u32Freq & 0xFFFF));
|
||||
auto OldReg = Fw.BK4819Read(0x30);
|
||||
Fw.BK4819Write(0x30, 0);
|
||||
Fw.BK4819Write(0x30, OldReg);
|
||||
}
|
||||
|
||||
u16RxDataLen += 2;
|
||||
}
|
||||
void SetAgcTable(unsigned short *p16AgcTable)
|
||||
{
|
||||
for (unsigned char i = 0; i < 5; i++)
|
||||
{
|
||||
Fw.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] = 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; }
|
||||
|
||||
unsigned short GetVoiceAmplitude()
|
||||
{
|
||||
// Fw.BK4819Write(0x64, 0);
|
||||
return Fw.BK4819Read(0x64);
|
||||
}
|
||||
|
||||
static void ToggleAFDAC(bool enabled)
|
||||
{
|
||||
auto Reg = Fw.BK4819Read(0x30);
|
||||
Reg &= ~(1 << 9);
|
||||
if (enabled)
|
||||
Reg |= (1 << 9);
|
||||
Fw.BK4819Write(0x30, Reg);
|
||||
}
|
||||
|
||||
static void ToggleRXDSP(bool enabled)
|
||||
{
|
||||
auto Reg = Fw.BK4819Read(0x30);
|
||||
Reg &= ~1;
|
||||
if (enabled)
|
||||
Reg |= 1;
|
||||
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
|
||||
{
|
||||
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 = Fw.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,6 +1,7 @@
|
|||
#pragma once
|
||||
#include "manager.hpp"
|
||||
#include "registers.hpp"
|
||||
#include "hardware/adc.hpp"
|
||||
|
||||
template <
|
||||
const System::TOrgFunctions &Fw,
|
||||
|
@ -16,8 +17,10 @@ class CAmTx : public IView
|
|||
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 +32,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;
|
||||
|
@ -67,25 +55,55 @@ public:
|
|||
|
||||
void HandleTests()
|
||||
{
|
||||
HandleMicInput();
|
||||
char S8DebugStr[20];
|
||||
// int MicAmp = s32DeltaAmp / 8; // RadioDriver.GetAFAmplitude();
|
||||
// MicAmp = 4 + MicAmp;
|
||||
// if (MicAmp > 0b111)
|
||||
// MicAmp = 0b111;
|
||||
// if (MicAmp < 0)
|
||||
// MicAmp = 0;
|
||||
unsigned short U16AdcData[2];
|
||||
Fw.AdcReadout(U16AdcData, U16AdcData+1);
|
||||
Fw.FormatString(S8DebugStr, "in 1: %05i ", U16AdcData[0]);
|
||||
if constexpr(!bAmpTests)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// HandleMicInput();
|
||||
char S8DebugStr[6 * 40 + 1];
|
||||
// static constexpr auto reg = 0x6F;
|
||||
DisplayBuff.ClearAll();
|
||||
|
||||
Fw.FormatString(S8DebugStr, "%05i %05i ", RadioDriver.GetVoiceAmplitude(), RadioDriver.GetAFAmplitude());
|
||||
Fw.PrintTextOnScreen(S8DebugStr, 0, 127, 0, 8, 0);
|
||||
Fw.FormatString(S8DebugStr, "in 2: %05i ", U16AdcData[1]);
|
||||
Fw.PrintTextOnScreen(S8DebugStr, 0, 127, 2, 8, 0);
|
||||
DrawMicInChart();
|
||||
}
|
||||
|
||||
void DrawMicInChart()
|
||||
{
|
||||
static constexpr auto chartBottomY = 55;
|
||||
static constexpr auto chartTopY = 16;
|
||||
unsigned char u8LastYpoint;
|
||||
for(unsigned short x = 0; x < 128; x++)
|
||||
{
|
||||
auto ypoint = RadioDriver.GetVoiceAmplitude();
|
||||
ypoint >>= 6;
|
||||
if(ypoint >= chartBottomY - chartTopY)
|
||||
{
|
||||
ypoint = chartTopY;
|
||||
}
|
||||
else
|
||||
{
|
||||
ypoint = chartBottomY - ypoint;
|
||||
}
|
||||
|
||||
if(!x) u8LastYpoint = ypoint;
|
||||
DisplayBuff.SetPixel(x, ypoint);
|
||||
while (ypoint != u8LastYpoint)
|
||||
{
|
||||
u8LastYpoint += u8LastYpoint < ypoint ? 1 : -1;
|
||||
DisplayBuff.SetPixel(x, u8LastYpoint);
|
||||
}
|
||||
|
||||
u8LastYpoint = ypoint;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleMicInput()
|
||||
{
|
||||
unsigned short u16ActualAmp = Fw.BK4819Read(0x64);
|
||||
u16ActualAmp = Fw.BK4819Read(0x64);
|
||||
// u16ActualAmp = Fw.BK4819Read(0x6F) & 0b1111111;
|
||||
s32DeltaAmp = u16OldAmp - u16ActualAmp;
|
||||
u16OldAmp = u16ActualAmp;
|
||||
}
|
||||
|
@ -131,6 +149,7 @@ public:
|
|||
return eScreenRefreshFlag::StatusBar;
|
||||
}
|
||||
|
||||
bInit = true;
|
||||
Context.ViewStack.Push(*this);
|
||||
return eScreenRefreshFlag::StatusBar;
|
||||
}
|
||||
|
|
|
@ -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,78 @@
|
|||
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}
|
||||
)
|
|
@ -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,71 @@
|
|||
#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"
|
||||
|
||||
const System::TOrgFunctions &Fw = System::OrgFunc_01_26;
|
||||
const System::TOrgData &FwData = System::OrgData_01_26;
|
||||
|
||||
TUV_K5Display DisplayBuff(FwData.pDisplayBuffer);
|
||||
const TUV_K5SmallNumbers FontSmallNr(FwData.pSmallDigs);
|
||||
CDisplay Display(DisplayBuff);
|
||||
|
||||
TUV_K5Display StatusBarBuff(FwData.pStatusBarData);
|
||||
CDisplay DisplayStatusBar(StatusBarBuff);
|
||||
|
||||
Radio::CBK4819<System::OrgFunc_01_26> RadioDriver;
|
||||
|
||||
// CRssiSbar<
|
||||
// System::OrgFunc_01_26,
|
||||
// System::OrgData_01_26,
|
||||
// DisplayBuff,
|
||||
// Display,
|
||||
// DisplayStatusBar,
|
||||
// FontSmallNr,
|
||||
// RadioDriver>
|
||||
// RssiSbar;
|
||||
|
||||
CAmTx<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
DisplayBuff,
|
||||
Display,
|
||||
DisplayStatusBar,
|
||||
FontSmallNr,
|
||||
RadioDriver>
|
||||
AmTx;
|
||||
|
||||
static IView * const Views[] = {&AmTx};
|
||||
CViewManager<
|
||||
System::OrgFunc_01_26,
|
||||
System::OrgData_01_26,
|
||||
8, 1, sizeof(Views) / sizeof(*Views)>
|
||||
Manager(Views);
|
||||
|
||||
int main()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void Reset_Handler()
|
||||
{
|
||||
Fw.IRQ_RESET();
|
||||
}
|
||||
|
||||
extern "C" void SysTick_Handler()
|
||||
{
|
||||
static bool bFirstInit = false;
|
||||
if (!bFirstInit)
|
||||
{
|
||||
System::CopyDataSection();
|
||||
__libc_init_array();
|
||||
bFirstInit = true;
|
||||
}
|
||||
|
||||
Manager.Handle();
|
||||
Fw.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
|
||||
|
||||
}
|
Ładowanie…
Reference in New Issue