mirror of https://github.com/g4klx/MMDVM.git
Code complete, but untested.
This commit is contained in:
parent
121c76f3d8
commit
c2959466fd
|
@ -53,6 +53,7 @@ const uint32_t PLL_FILTER_LEN = 7U;
|
|||
float32_t PLL_FILTER_COEFFS[] = {3.196252e-02F, 1.204223e-01F, 2.176819e-01F, 2.598666e-01F, 2.176819e-01F, 1.204223e-01F, 3.196252e-02F};
|
||||
|
||||
CAX25Demodulator::CAX25Demodulator(float32_t* coeffs, uint16_t length) :
|
||||
m_frame(),
|
||||
m_audioFilter(),
|
||||
m_audioState(),
|
||||
m_lpfFilter(),
|
||||
|
@ -64,7 +65,12 @@ m_pllFilter(),
|
|||
m_pllState(),
|
||||
m_pllLast(false),
|
||||
m_pllBits(1U),
|
||||
m_pllCount(0.0F)
|
||||
m_pllCount(0.0F),
|
||||
m_hdlcOnes(0U),
|
||||
m_hdlcFlag(false),
|
||||
m_hdlcBuffer(0U),
|
||||
m_hdlcBits(0U),
|
||||
m_hdlcState(AX25_IDLE)
|
||||
{
|
||||
m_delayLine = new bool[2U * DELAY_LEN];
|
||||
|
||||
|
@ -110,10 +116,17 @@ bool CAX25Demodulator::process(const q15_t* samples, uint8_t length, CAX25Frame&
|
|||
if (sample) {
|
||||
// We will only ever get one frame because there are
|
||||
// not enough bits in a block for more than one.
|
||||
if (result)
|
||||
hdlc_decoder_(NRZI(bit), true);
|
||||
else
|
||||
result = hdlc_decoder_(NRZI(bit), true);
|
||||
if (result) {
|
||||
HDLC(NRZI(bit));
|
||||
} else {
|
||||
result = HDLC(NRZI(bit));
|
||||
if (result) {
|
||||
::memcpy(frame.m_data, m_frame.m_data, AX25_MAX_PACKET_LEN);
|
||||
frame.m_length = frame.m_length;
|
||||
frame.m_fcs = m_frame.m_fcs;
|
||||
m_frame.m_length = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,3 +184,83 @@ bool CAX25Demodulator::PLL(bool input)
|
|||
return sample;
|
||||
}
|
||||
|
||||
bool CAX25Demodulator::HDLC(bool b)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (m_hdlcOnes == 5U) {
|
||||
if (b) {
|
||||
// flag byte
|
||||
m_hdlcFlag = true;
|
||||
} else {
|
||||
// bit stuffing...
|
||||
m_hdlcFlag = false;
|
||||
m_hdlcOnes = 0U;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
m_hdlcBuffer >>= 1;
|
||||
m_hdlcBuffer |= b ? 128U : 0U;
|
||||
m_hdlcBits++; // Free-running until Sync byte.
|
||||
|
||||
if (b)
|
||||
m_hdlcOnes++;
|
||||
else
|
||||
m_hdlcOnes = 0U;
|
||||
|
||||
if (m_hdlcFlag) {
|
||||
switch (m_hdlcBuffer) {
|
||||
case 0x7E:
|
||||
if (m_frame.m_length > 0U) {
|
||||
result = m_frame.checkCRC();
|
||||
if (!result)
|
||||
m_frame.m_length = 0U;
|
||||
}
|
||||
m_hdlcState = AX25_SYNC;
|
||||
m_hdlcFlag = false;
|
||||
m_hdlcBits = 0U;
|
||||
break;
|
||||
|
||||
case 0xFE:
|
||||
// Frame aborted
|
||||
m_frame.m_length = 0U;
|
||||
m_hdlcState = AX25_IDLE;
|
||||
m_hdlcFlag = false;
|
||||
m_hdlcBits = 0U;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
switch (m_hdlcState) {
|
||||
case AX25_IDLE:
|
||||
break;
|
||||
|
||||
case AX25_SYNC:
|
||||
if (m_hdlcBits == 8U) { // 8th bit.
|
||||
// Start of frame data.
|
||||
m_hdlcState = AX25_RECEIVE;
|
||||
m_frame.append(m_hdlcBuffer);
|
||||
m_hdlcBits = 0U;
|
||||
}
|
||||
break;
|
||||
|
||||
case AX25_RECEIVE:
|
||||
if (m_hdlcBits == 8U) { // 8th bit.
|
||||
m_frame.append(m_hdlcBuffer);
|
||||
m_hdlcBits = 0U;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
|
||||
#include "AX25Frame.h"
|
||||
|
||||
enum AX25_STATE {
|
||||
AX25_IDLE,
|
||||
AX25_SYNC,
|
||||
AX25_RECEIVE
|
||||
};
|
||||
|
||||
class CAX25Demodulator {
|
||||
public:
|
||||
|
@ -31,6 +36,7 @@ public:
|
|||
bool process(const q15_t* samples, uint8_t length, CAX25Frame& frame);
|
||||
|
||||
private:
|
||||
CAX25Frame m_frame;
|
||||
arm_fir_instance_f32 m_audioFilter;
|
||||
float32_t m_audioState[20U];
|
||||
arm_fir_instance_q15 m_lpfFilter;
|
||||
|
@ -43,10 +49,16 @@ private:
|
|||
bool m_pllLast;
|
||||
uint8_t m_pllBits;
|
||||
float32_t m_pllCount;
|
||||
uint16_t m_hdlcOnes;
|
||||
bool m_hdlcFlag;
|
||||
uint16_t m_hdlcBuffer;
|
||||
uint16_t m_hdlcBits;
|
||||
AX25_STATE m_hdlcState;
|
||||
|
||||
bool delay(bool b);
|
||||
bool NRZI(bool b);
|
||||
bool PLL(bool b);
|
||||
bool HDLC(bool b);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,16 @@ m_fcs(0U)
|
|||
{
|
||||
}
|
||||
|
||||
bool CAX25Frame::append(uint16_t c)
|
||||
{
|
||||
if (m_length == AX25_MAX_PACKET_LEN)
|
||||
return false;
|
||||
|
||||
m_data[m_length++] = uint8_t(c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAX25Frame::checkCRC()
|
||||
{
|
||||
union {
|
||||
|
|
|
@ -21,13 +21,17 @@
|
|||
|
||||
#include "Config.h"
|
||||
|
||||
const uint16_t AX25_MAX_PACKET_LEN = 300U;
|
||||
|
||||
class CAX25Frame {
|
||||
public:
|
||||
CAX25Frame();
|
||||
|
||||
bool append(uint16_t c);
|
||||
|
||||
bool checkCRC();
|
||||
|
||||
uint8_t m_data[300U];
|
||||
uint8_t m_data[AX25_MAX_PACKET_LEN];
|
||||
uint16_t m_length;
|
||||
uint16_t m_fcs;
|
||||
};
|
||||
|
|
12
AX25RX.cpp
12
AX25RX.cpp
|
@ -114,29 +114,29 @@ void CAX25RX::samples(q15_t* samples, uint8_t length)
|
|||
CAX25Frame frame;
|
||||
|
||||
bool ret = m_demod1.process(output, length, frame);
|
||||
if (ret) {
|
||||
if (ret && frame.m_length > 10U) {
|
||||
if (m_lastFCS != frame.m_fcs) {
|
||||
DEBUG1("Decoder 1 reported");
|
||||
m_lastFCS = frame.m_fcs;
|
||||
serial.writeAX25Data(frame.m_data, frame.m_length);
|
||||
serial.writeAX25Data(frame.m_data, frame.m_length - 2U);
|
||||
}
|
||||
}
|
||||
|
||||
ret = m_demod2.process(output, length, frame);
|
||||
if (ret) {
|
||||
if (ret && frame.m_length > 10U) {
|
||||
if (m_lastFCS != frame.m_fcs) {
|
||||
DEBUG1("Decoder 2 reported");
|
||||
m_lastFCS = frame.m_fcs;
|
||||
serial.writeAX25Data(frame.m_data, frame.m_length);
|
||||
serial.writeAX25Data(frame.m_data, frame.m_length - 2U);
|
||||
}
|
||||
}
|
||||
|
||||
ret = m_demod3.process(output, length, frame);
|
||||
if (ret) {
|
||||
if (ret && frame.m_length > 10U) {
|
||||
if (m_lastFCS != frame.m_fcs) {
|
||||
DEBUG1("Decoder 3 reported");
|
||||
m_lastFCS = frame.m_fcs;
|
||||
serial.writeAX25Data(frame.m_data, frame.m_length);
|
||||
serial.writeAX25Data(frame.m_data, frame.m_length - 2U);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue