mirror of https://github.com/g4klx/MMDVM.git
First woring AX.25 decoder (in simulation).
This commit is contained in:
parent
e332dbba8e
commit
af11be16dc
|
@ -21,27 +21,27 @@
|
|||
#include "Globals.h"
|
||||
#include "AX25Demodulator.h"
|
||||
|
||||
const float32_t DELAY = 0.000448F;
|
||||
const float32_t SAMPLE_RATE = 24000.0F;
|
||||
const float32_t SYMBOL_RATE = 1200.0F;
|
||||
|
||||
const uint16_t DELAY_LEN = uint16_t((DELAY / (1.0F / SAMPLE_RATE)) + 0.5F);
|
||||
const uint16_t DELAY_LEN = 11U;
|
||||
|
||||
const float32_t SAMPLES_PER_SYMBOL = SAMPLE_RATE / SYMBOL_RATE;
|
||||
const float32_t PLL_LIMIT = SAMPLES_PER_SYMBOL / 2.0F;
|
||||
|
||||
// XXX This is for the wrong sample rate
|
||||
const uint32_t LPF_FILTER_LEN = 96U;
|
||||
|
||||
q15_t LPF_FILTER_COEFFS[] = {
|
||||
0, 1, 3, 5, 8, 11, 14, 17, 19, 20, 18, 14,
|
||||
7, -2, -16, -33, -53, -76, -101, -126, -151, -174, -194, -208,
|
||||
-215, -212, -199, -173, -133, -79, -10, 74, 173, 287, 413, 549,
|
||||
693, 842, 993, 1142, 1287, 1423, 1547, 1656, 1747, 1817, 1865, 1889,
|
||||
1889, 1865, 1817, 1747, 1656, 1547, 1423, 1287, 1142, 993, 842, 693,
|
||||
549, 413, 287, 173, 74, -10, -79, -133, -173, -199, -212, -215,
|
||||
-208, -194, -174, -151, -126, -101, -76, -53, -33, -16, -2, 7,
|
||||
14, 18, 20, 19, 17, 14, 11, 8, 5, 3, 1, 0,
|
||||
0, 0, 0, 1, 2, 5, 8, 12, 18, 23,
|
||||
29, 33, 36, 36, 33, 25, 13, -5, -28, -57,
|
||||
-89, -123, -159, -194, -225, -249, -264, -267, -254, -224,
|
||||
-175, -104, -12, 102, 236, 389, 557, 738, 926, 1117,
|
||||
1306, 1486, 1654, 1802, 1927, 2025, 2092, 2126, 2126, 2092,
|
||||
2025, 1927, 1802, 1654, 1486, 1306, 1117, 926, 738, 557,
|
||||
389, 236, 102, -12, -104, -175, -224, -254, -267, -264,
|
||||
-249, -225, -194, -159, -123, -89, -57, -28, -5, 13,
|
||||
25, 33, 36, 36, 33, 29, 23, 18, 12, 8,
|
||||
5, 2, 1, 0, 0, 0
|
||||
};
|
||||
|
||||
// 64 Hz loop filter.
|
||||
|
@ -53,7 +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) :
|
||||
CAX25Demodulator::CAX25Demodulator(q15_t* coeffs, uint16_t length) :
|
||||
m_frame(),
|
||||
m_audioFilter(),
|
||||
m_audioState(),
|
||||
|
@ -73,7 +73,7 @@ m_hdlcBuffer(0U),
|
|||
m_hdlcBits(0U),
|
||||
m_hdlcState(AX25_IDLE)
|
||||
{
|
||||
m_delayLine = new bool[2U * DELAY_LEN];
|
||||
m_delayLine = new bool[DELAY_LEN];
|
||||
|
||||
m_audioFilter.numTaps = length;
|
||||
m_audioFilter.pState = m_audioState;
|
||||
|
@ -88,21 +88,16 @@ m_hdlcState(AX25_IDLE)
|
|||
m_pllFilter.pCoeffs = PLL_FILTER_COEFFS;
|
||||
}
|
||||
|
||||
bool CAX25Demodulator::process(const q15_t* samples, uint8_t length, CAX25Frame& frame)
|
||||
bool CAX25Demodulator::process(q15_t* samples, uint8_t length, CAX25Frame& frame)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
float32_t input[RX_BLOCK_SIZE];
|
||||
for (size_t i = 0; i < length; i++)
|
||||
input[i] = float(samples[i]);
|
||||
|
||||
float32_t fa[RX_BLOCK_SIZE];
|
||||
::arm_fir_f32(&m_audioFilter, input, fa, RX_BLOCK_SIZE);
|
||||
q15_t fa[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_audioFilter, samples, fa, RX_BLOCK_SIZE);
|
||||
|
||||
int16_t buffer[RX_BLOCK_SIZE];
|
||||
for (uint8_t i = 0; i < length; i++) {
|
||||
int16_t sample = int16_t(fa[i]);
|
||||
bool level = (sample >= 0);
|
||||
bool level = (fa[i] >= 0);
|
||||
bool delayed = delay(level);
|
||||
buffer[i] = (int16_t(level ^ delayed) << 1) - 1;
|
||||
}
|
||||
|
@ -124,7 +119,7 @@ bool CAX25Demodulator::process(const q15_t* samples, uint8_t length, CAX25Frame&
|
|||
if (result) {
|
||||
// Copy the frame data.
|
||||
::memcpy(frame.m_data, m_frame.m_data, AX25_MAX_PACKET_LEN);
|
||||
frame.m_length = frame.m_length;
|
||||
frame.m_length = m_frame.m_length;
|
||||
frame.m_fcs = m_frame.m_fcs;
|
||||
m_frame.m_length = 0U;
|
||||
}
|
||||
|
@ -160,7 +155,7 @@ bool CAX25Demodulator::PLL(bool input)
|
|||
{
|
||||
bool sample = false;
|
||||
|
||||
if (input != m_pllLast or m_pllBits > 16U) {
|
||||
if (input != m_pllLast || m_pllBits > 16U) {
|
||||
// Record transition.
|
||||
m_pllLast = input;
|
||||
|
||||
|
@ -214,10 +209,12 @@ bool CAX25Demodulator::HDLC(bool b)
|
|||
|
||||
switch (m_hdlcBuffer) {
|
||||
case 0x7E:
|
||||
if (m_frame.m_length > 2U) {
|
||||
if (m_frame.m_length >= 13U) {
|
||||
result = m_frame.checkCRC();
|
||||
if (!result)
|
||||
m_frame.m_length = 0U;
|
||||
} else {
|
||||
m_frame.m_length = 0U;
|
||||
}
|
||||
m_hdlcState = AX25_SYNC;
|
||||
m_hdlcFlag = false;
|
||||
|
|
|
@ -31,21 +31,21 @@ enum AX25_STATE {
|
|||
|
||||
class CAX25Demodulator {
|
||||
public:
|
||||
CAX25Demodulator(float32_t* coeffs, uint16_t length);
|
||||
CAX25Demodulator(q15_t* coeffs, uint16_t length);
|
||||
|
||||
bool process(const q15_t* samples, uint8_t length, CAX25Frame& frame);
|
||||
bool process(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_audioFilter;
|
||||
q15_t m_audioState[40U]; // NoTaps + BlockSize - 1, 9 + 20 - 1 plus some spare
|
||||
arm_fir_instance_q15 m_lpfFilter;
|
||||
q15_t m_lpfState[120U]; // NoTaps + BlockSize - 1, 96 + 20 - 1 plus some spare
|
||||
bool* m_delayLine;
|
||||
uint16_t m_delayPos;
|
||||
bool m_nrziState;
|
||||
arm_fir_instance_f32 m_pllFilter;
|
||||
float32_t m_pllState[7U];
|
||||
float32_t m_pllState[20U]; // NoTaps + BlockSize - 1, 7 + 1 - 1 plus some spare
|
||||
bool m_pllLast;
|
||||
uint8_t m_pllBits;
|
||||
float32_t m_pllCount;
|
||||
|
|
|
@ -21,38 +21,38 @@
|
|||
#include "AX25Frame.h"
|
||||
|
||||
const uint16_t CCITT_TABLE[] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0};
|
||||
0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
|
||||
0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
|
||||
0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
|
||||
0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
|
||||
0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
|
||||
0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
|
||||
0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
|
||||
0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
|
||||
0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
|
||||
0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
|
||||
0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
|
||||
0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
|
||||
0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
|
||||
0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
|
||||
0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
|
||||
0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
|
||||
0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
|
||||
0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
|
||||
0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
|
||||
0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
|
||||
0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
|
||||
0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
|
||||
0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
|
||||
0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
|
||||
0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
|
||||
0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
|
||||
0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
|
||||
0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
|
||||
0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
|
||||
0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
|
||||
0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
|
||||
0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78 };
|
||||
|
||||
CAX25Frame::CAX25Frame() :
|
||||
m_data(),
|
||||
|
|
324
AX25RX.cpp
324
AX25RX.cpp
|
@ -20,47 +20,255 @@
|
|||
#include "Globals.h"
|
||||
#include "AX25RX.h"
|
||||
|
||||
// XXX There are for the wrong sample rate
|
||||
// 1200Hz = -12dB, 2200Hz = 0dB; 3381Hz cutoff; cosine.
|
||||
q15_t dB12[] = {
|
||||
176,
|
||||
-812,
|
||||
-3916,
|
||||
-7586,
|
||||
23536,
|
||||
-7586,
|
||||
-3916,
|
||||
-812,
|
||||
176
|
||||
};
|
||||
|
||||
// 1200Hz = -9dB, 2200Hz = 0dB; 3252Hz cutoff, 3.7 gain; cosine.
|
||||
float32_t dB9[] = {
|
||||
-0.00232554104135,
|
||||
-0.142858725752,
|
||||
-0.449053780255,
|
||||
-0.770264863826,
|
||||
2.77651146344,
|
||||
-0.770264863826,
|
||||
-0.449053780255,
|
||||
-0.142858725752,
|
||||
-0.00232554104135};
|
||||
// 1200Hz = -11dB, 2200Hz = 0dB; 3258Hz cutoff; cosine.
|
||||
q15_t dB11[] = {
|
||||
121,
|
||||
-957,
|
||||
-3959,
|
||||
-7383,
|
||||
23871,
|
||||
-7383,
|
||||
-3959,
|
||||
-957,
|
||||
121
|
||||
};
|
||||
|
||||
// 1200Hz = -6dB, 2200Hz = 0dB; 2640Hz cutoff, 2.59 gain; cosine.
|
||||
float32_t dB6[] = {
|
||||
-0.0209448226653,
|
||||
-0.130107651829,
|
||||
-0.299004731072,
|
||||
-0.45336946386,
|
||||
2.0629448761,
|
||||
-0.45336946386,
|
||||
-0.299004731072,
|
||||
-0.130107651829,
|
||||
-0.0209448226653};
|
||||
// 1200Hz = -10dB, 2200Hz = 0dB; 3118Hz cutoff; cosine.
|
||||
q15_t dB10[] = {
|
||||
56,
|
||||
-1110,
|
||||
-3987,
|
||||
-7141,
|
||||
24254,
|
||||
-7141,
|
||||
-3987,
|
||||
-1110,
|
||||
56
|
||||
};
|
||||
|
||||
// 1200Hz = -3dB, 2200Hz = 0dB; 1700Hz cutoff, 1.68 gain; cosine.
|
||||
float32_t dB3[] = {
|
||||
-0.0231416146776,
|
||||
-0.0833375337803,
|
||||
-0.147937602401,
|
||||
-0.197411259519,
|
||||
1.46066084756,
|
||||
-0.197411259519,
|
||||
-0.147937602401,
|
||||
-0.0833375337803,
|
||||
-0.0231416146776};
|
||||
// 1200Hz = -9dB, 2200Hz = 0dB; 2959Hz cutoff; cosine.
|
||||
q15_t dB9[] = {
|
||||
-19,
|
||||
-1268,
|
||||
-3994,
|
||||
-6856,
|
||||
24688,
|
||||
-6856,
|
||||
-3994,
|
||||
-1268,
|
||||
-19
|
||||
};
|
||||
|
||||
// 1200Hz = -8dB, 2200Hz = 0dB; 2778Hz cutoff; cosine.
|
||||
q15_t dB8[] = {
|
||||
-104,
|
||||
-1424,
|
||||
-3968,
|
||||
-6516,
|
||||
25182,
|
||||
-6516,
|
||||
-3968,
|
||||
-1424,
|
||||
-104
|
||||
};
|
||||
|
||||
// 1200Hz = -7dB, 2200Hz = 0dB; 2573Hz cutoff; cosine.
|
||||
q15_t dB7[] = {
|
||||
-196,
|
||||
-1565,
|
||||
-3896,
|
||||
-6114,
|
||||
25742,
|
||||
-6114,
|
||||
-3896,
|
||||
-1565,
|
||||
-196
|
||||
};
|
||||
|
||||
// 1200Hz = -6dB, 2200Hz = 0dB; 2343Hz cutoff; cosine.
|
||||
q15_t dB6[] = {
|
||||
-288,
|
||||
-1676,
|
||||
-3761,
|
||||
-5642,
|
||||
26370,
|
||||
-5642,
|
||||
-3761,
|
||||
-1676,
|
||||
-288
|
||||
};
|
||||
|
||||
// 1200Hz = -5dB, 2200Hz = 0dB; 2085Hz cutoff; cosine.
|
||||
q15_t dB5[] = {
|
||||
-370,
|
||||
-1735,
|
||||
-3545,
|
||||
-5088,
|
||||
27075,
|
||||
-5088,
|
||||
-3545,
|
||||
-1735,
|
||||
-370
|
||||
};
|
||||
|
||||
// 1200Hz = -4dB, 2200Hz = 0dB; 1790Hz cutoff; cosine.
|
||||
q15_t dB4[] = {
|
||||
-432,
|
||||
-1715,
|
||||
-3220,
|
||||
-4427,
|
||||
27880,
|
||||
-4427,
|
||||
-3220,
|
||||
-1715,
|
||||
-432
|
||||
};
|
||||
|
||||
// 1200Hz = -3dB, 2200Hz = 0dB; 1456Hz cutoff; cosine.
|
||||
q15_t dB3[] = {
|
||||
-452,
|
||||
-1582,
|
||||
-2759,
|
||||
-3646,
|
||||
28792,
|
||||
-3646,
|
||||
-2759,
|
||||
-1582,
|
||||
-452
|
||||
};
|
||||
|
||||
// 1200Hz = -2dB, 2200Hz = 0dB; 1070Hz cutoff; cosine.
|
||||
q15_t dB2[] = {
|
||||
-408,
|
||||
-1295,
|
||||
-2123,
|
||||
-2710,
|
||||
29846,
|
||||
-2710,
|
||||
-2123,
|
||||
-1295,
|
||||
-408
|
||||
};
|
||||
|
||||
// 1200Hz = -1dB, 2200Hz = 0dB; 605Hz cutoff; cosine.
|
||||
q15_t dB1[] = {
|
||||
-268,
|
||||
-795,
|
||||
-1244,
|
||||
-1546,
|
||||
31116,
|
||||
-1546,
|
||||
-1244,
|
||||
-795,
|
||||
-268
|
||||
};
|
||||
|
||||
q15_t dB0[] = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
32767,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
// 1200Hz = 0dB, 2200Hz = -1dB; 4130Hz cutoff; cosine.
|
||||
q15_t dB_1[] = {
|
||||
-419,
|
||||
-177,
|
||||
3316,
|
||||
8650,
|
||||
11278,
|
||||
8650,
|
||||
3316,
|
||||
-177,
|
||||
-419
|
||||
};
|
||||
|
||||
// 1200Hz = 0dB, 2200Hz = -2dB; 3190Hz cutoff; cosine.
|
||||
q15_t dB_2[] = {
|
||||
-90,
|
||||
1033,
|
||||
3975,
|
||||
7267,
|
||||
8711,
|
||||
7267,
|
||||
3975,
|
||||
1033,
|
||||
-90
|
||||
};
|
||||
|
||||
// 1200Hz = 0dB, 2200Hz = -3dB; 2330Hz cutoff; cosine.
|
||||
q15_t dB_3[] = {
|
||||
292,
|
||||
1680,
|
||||
3752,
|
||||
5615,
|
||||
6362,
|
||||
5615,
|
||||
3752,
|
||||
1680,
|
||||
292
|
||||
};
|
||||
|
||||
// 1200Hz = 0dB, 2200Hz = -4dB; 2657Hz cutoff; boxcar.
|
||||
q15_t dB_4[] = {
|
||||
917,
|
||||
3024,
|
||||
5131,
|
||||
6684,
|
||||
7255,
|
||||
6684,
|
||||
5131,
|
||||
3024,
|
||||
917
|
||||
};
|
||||
|
||||
// 1200Hz = 0dB, 2200Hz = -5dB; 2360Hz cutoff; boxcar.
|
||||
q15_t dB_5[] = {
|
||||
1620,
|
||||
3339,
|
||||
4925,
|
||||
6042,
|
||||
6444,
|
||||
6042,
|
||||
4925,
|
||||
3339,
|
||||
1620
|
||||
};
|
||||
|
||||
// 1200Hz = 0dB, 2200Hz = -6dB; 2067Hz cutoff; boxcar.
|
||||
q15_t dB_6[] = {
|
||||
2161,
|
||||
3472,
|
||||
4605,
|
||||
5373,
|
||||
5644,
|
||||
5373,
|
||||
4605,
|
||||
3472,
|
||||
2161
|
||||
};
|
||||
|
||||
/*
|
||||
* Generated with Scipy Filter, 152 coefficients, 1100-2300Hz bandpass,
|
||||
* Hann window.
|
||||
* Hann window, starting and ending 0 value coefficients removed.
|
||||
*
|
||||
* np.array(
|
||||
* firwin2(152,
|
||||
|
@ -77,24 +285,23 @@ float32_t dB3[] = {
|
|||
* window='hann') * 32768,
|
||||
* dtype=int)[10:-10]
|
||||
*/
|
||||
const uint32_t FILTER_LEN = 132U;
|
||||
|
||||
const uint32_t FILTER_LEN = 132;
|
||||
q15_t FILTER_COEFFS[] = {
|
||||
0, 5, 12, 18, 21, 19, 11, -2, -15,
|
||||
-25, -27, -21, -11, -3, -5, -19, -43, -69,
|
||||
-83, -73, -35, 27, 98, 155, 180, 163, 109,
|
||||
39, -20, -45, -26, 23, 74, 89, 39, -81,
|
||||
-247, -407, -501, -480, -334, -92, 175, 388, 479,
|
||||
429, 275, 99, 5, 68, 298, 626, 913, 994,
|
||||
740, 115, -791, -1770, -2544, -2847, -2509, -1527, -76,
|
||||
1518, 2875, 3653, 3653, 2875, 1518, -76, -1527, -2509,
|
||||
-2847, -2544, -1770, -791, 115, 740, 994, 913, 626,
|
||||
298, 68, 5, 99, 275, 429, 479, 388, 175,
|
||||
-92, -334, -480, -501, -407, -247, -81, 39, 89,
|
||||
74, 23, -26, -45, -20, 39, 109, 163, 180,
|
||||
155, 98, 27, -35, -73, -83, -69, -43, -19,
|
||||
-5, -3, -11, -21, -27, -25, -15, -2, 11,
|
||||
19, 21, 18, 12, 5, 0};
|
||||
0, 5, 12, 18, 21, 19, 11, -2, -15, -25,
|
||||
-27, -21, -11, -3, -5, -19, -43, -69, -83, -73,
|
||||
-35, 27, 98, 155, 180, 163, 109, 39, -20, -45,
|
||||
-26, 23, 74, 89, 39, -81, -247, -407, -501, -480,
|
||||
-334, -92, 175, 388, 479, 429, 275, 99, 5, 68,
|
||||
298, 626, 913, 994, 740, 115, -791, -1770, -2544, -2847,
|
||||
-2509, -1527, -76, 1518, 2875, 3653, 3653, 2875, 1518, -76,
|
||||
-1527, -2509, -2847, -2544, -1770, -791, 115, 740, 994, 913,
|
||||
626, 298, 68, 5, 99, 275, 429, 479, 388, 175,
|
||||
-92, -334, -480, -501, -407, -247, -81, 39, 89, 74,
|
||||
23, -26, -45, -20, 39, 109, 163, 180, 155, 98,
|
||||
27, -35, -73, -83, -69, -43, -19, -5, -3, -11,
|
||||
-21, -27, -25, -15, -2, 11, 19, 21, 18, 12,
|
||||
5, 0
|
||||
};
|
||||
|
||||
CAX25RX::CAX25RX() :
|
||||
m_filter(),
|
||||
|
@ -114,33 +321,28 @@ void CAX25RX::samples(q15_t* samples, uint8_t length)
|
|||
q15_t output[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_filter, samples, output, RX_BLOCK_SIZE);
|
||||
|
||||
m_lastFCS = 0U;
|
||||
CAX25Frame frame;
|
||||
|
||||
bool ret = m_demod1.process(output, length, frame);
|
||||
if (ret && frame.m_length > 10U) {
|
||||
if (m_lastFCS != frame.m_fcs) {
|
||||
if (ret && frame.m_fcs != m_lastFCS) {
|
||||
DEBUG1("Decoder 1 reported");
|
||||
m_lastFCS = frame.m_fcs;
|
||||
serial.writeAX25Data(frame.m_data, frame.m_length - 2U);
|
||||
}
|
||||
}
|
||||
|
||||
ret = m_demod2.process(output, length, frame);
|
||||
if (ret && frame.m_length > 10U) {
|
||||
if (m_lastFCS != frame.m_fcs) {
|
||||
if (ret && frame.m_fcs != m_lastFCS) {
|
||||
DEBUG1("Decoder 2 reported");
|
||||
m_lastFCS = frame.m_fcs;
|
||||
serial.writeAX25Data(frame.m_data, frame.m_length - 2U);
|
||||
}
|
||||
}
|
||||
|
||||
ret = m_demod3.process(output, length, frame);
|
||||
if (ret && frame.m_length > 10U) {
|
||||
if (m_lastFCS != frame.m_fcs) {
|
||||
if (ret && frame.m_fcs != m_lastFCS) {
|
||||
DEBUG1("Decoder 3 reported");
|
||||
m_lastFCS = frame.m_fcs;
|
||||
serial.writeAX25Data(frame.m_data, frame.m_length - 2U);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue