2023-07-10 00:03:12 +00:00
|
|
|
#pragma once
|
|
|
|
|
#include "system.hpp"
|
|
|
|
|
#include "registers.hpp"
|
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
|
|
namespace Radio
|
|
|
|
|
{
|
2023-07-12 00:10:45 +00:00
|
|
|
enum eIrq : unsigned short
|
|
|
|
|
{
|
|
|
|
|
FifoAlmostFull = 1 << 12,
|
|
|
|
|
RxDone = 1 << 13,
|
|
|
|
|
};
|
|
|
|
|
|
2023-07-13 18:18:33 +00:00
|
|
|
enum class eFskMode : unsigned char
|
2023-07-10 00:03:12 +00:00
|
|
|
{
|
2023-07-13 18:18:33 +00:00
|
|
|
Fsk1200 = 0,
|
|
|
|
|
Ffsk1200_1200_1800,
|
|
|
|
|
Ffsk1200_1200_2400,
|
|
|
|
|
NoaaSame,
|
|
|
|
|
ModesCount,
|
2023-07-10 00:03:12 +00:00
|
|
|
};
|
|
|
|
|
|
2023-07-13 18:18:33 +00:00
|
|
|
struct TFskModeBits
|
2023-07-10 00:03:12 +00:00
|
|
|
{
|
2023-07-13 18:18:33 +00:00
|
|
|
unsigned char u8TxModeBits;
|
|
|
|
|
unsigned char u8RxBandWidthBits;
|
|
|
|
|
unsigned char u8RxModeBits;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline const 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
|
2023-07-10 00:03:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum class eState : unsigned char
|
|
|
|
|
{
|
|
|
|
|
Idle,
|
|
|
|
|
RxPending,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct IRadioUser
|
|
|
|
|
{
|
2023-07-12 00:10:45 +00:00
|
|
|
virtual void RxDoneHandler(unsigned char u8DataLen, bool bCrcOk){};
|
2023-07-10 00:03:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <const System::TOrgFunctions &Fw>
|
|
|
|
|
class CBK4819
|
|
|
|
|
{
|
|
|
|
|
public:
|
2023-07-12 00:10:45 +00:00
|
|
|
CBK4819() : State(eState::Idle), u16RxDataLen(0){};
|
2023-07-10 00:03:12 +00:00
|
|
|
|
|
|
|
|
void SetFrequency(unsigned int u32FrequencyD10)
|
|
|
|
|
{
|
|
|
|
|
Fw.BK4819WriteFrequency(u32FrequencyD10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int GetFrequency()
|
|
|
|
|
{
|
2023-07-12 00:10:45 +00:00
|
|
|
return (Fw.BK4819Read(0x39) << 16) | Fw.BK4819Read(0x38);
|
2023-07-10 00:03:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendSyncAirCopyMode72(unsigned char *p8Data)
|
|
|
|
|
{
|
|
|
|
|
Fw.BK4819ConfigureAndStartTxFsk();
|
|
|
|
|
Fw.AirCopyFskSetup();
|
2023-07-13 18:18:33 +00:00
|
|
|
SetFskMode(eFskMode::Fsk1200);
|
2023-07-10 00:03:12 +00:00
|
|
|
Fw.AirCopy72(p8Data);
|
2023-07-12 22:07:32 +00:00
|
|
|
Fw.BK4819SetGpio(1, false);
|
2023-07-12 20:59:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DisablePa()
|
|
|
|
|
{
|
|
|
|
|
Fw.BK4819Write(0x30, Fw.BK4819Read(0x30) & ~0b1010);
|
2023-07-10 00:03:12 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-13 18:18:33 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 00:10:45 +00:00
|
|
|
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, IRadioUser *pUser)
|
2023-07-10 00:03:12 +00:00
|
|
|
{
|
|
|
|
|
if (!p8Data || !u8DataLen)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pRadioUser = pUser;
|
|
|
|
|
p8RxBuff = p8Data;
|
|
|
|
|
u8RxBuffSize = u8DataLen;
|
2023-07-12 00:10:45 +00:00
|
|
|
u16RxDataLen = 0;
|
2023-07-10 00:03:12 +00:00
|
|
|
|
|
|
|
|
Fw.AirCopyFskSetup();
|
2023-07-13 18:18:33 +00:00
|
|
|
SetFskMode(eFskMode::Fsk1200);
|
2023-07-12 00:10:45 +00:00
|
|
|
Fw.BK4819ConfigureAndStartRxFsk();
|
2023-07-10 00:03:12 +00:00
|
|
|
State = eState::RxPending;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 00:10:45 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-10 00:03:12 +00:00
|
|
|
bool IsLockedByOrgFw()
|
|
|
|
|
{
|
|
|
|
|
return !(GPIOC->DATA & 0b1);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 00:10:45 +00:00
|
|
|
unsigned short u16DebugIrq;
|
|
|
|
|
|
|
|
|
|
void HandleRxDone()
|
|
|
|
|
{
|
|
|
|
|
ClearRxFifoBuff();
|
|
|
|
|
DisableFskModem();
|
|
|
|
|
State = eState::Idle;
|
|
|
|
|
if (pRadioUser)
|
|
|
|
|
{
|
|
|
|
|
pRadioUser->RxDoneHandler(u16RxDataLen, CheckCrc());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-10 00:03:12 +00:00
|
|
|
void InterruptHandler()
|
|
|
|
|
{
|
|
|
|
|
if (IsLockedByOrgFw())
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 00:10:45 +00:00
|
|
|
|
2023-07-10 00:03:12 +00:00
|
|
|
if (State == eState::RxPending)
|
|
|
|
|
{
|
2023-07-12 00:10:45 +00:00
|
|
|
FixIrqEnRegister();
|
|
|
|
|
if (!(Fw.BK4819Read(0x0C) & 1)) // irq request indicator
|
2023-07-10 00:03:12 +00:00
|
|
|
{
|
2023-07-12 00:10:45 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto const IrqReg = GetIrqReg();
|
|
|
|
|
|
|
|
|
|
if (IrqReg & eIrq::RxDone)
|
|
|
|
|
{
|
|
|
|
|
// HandleRxDone();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IrqReg & eIrq::FifoAlmostFull)
|
|
|
|
|
{
|
|
|
|
|
HandleFifoAlmostFull();
|
2023-07-10 00:03:12 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 00:10:45 +00:00
|
|
|
eState State;
|
|
|
|
|
unsigned short u16RxDataLen;
|
|
|
|
|
|
2023-07-10 00:03:12 +00:00
|
|
|
private:
|
2023-07-12 00:10:45 +00:00
|
|
|
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;
|
|
|
|
|
if (pRadioUser)
|
|
|
|
|
{
|
|
|
|
|
pRadioUser->RxDoneHandler(u8RxBuffSize, CheckCrc());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IRadioUser *pRadioUser;
|
2023-07-10 00:03:12 +00:00
|
|
|
unsigned char *p8RxBuff;
|
|
|
|
|
unsigned char u8RxBuffSize;
|
|
|
|
|
};
|
|
|
|
|
}
|