mirror of
https://github.com/g4klx/MMDVM.git
synced 2026-10-15 16:24:11 +02:00
Compare commits
182
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ef05cb6c0 | ||
|
|
2cf2ce4dfa | ||
|
|
5f29808b80 | ||
|
|
063b21f999 | ||
|
|
89b8641955 | ||
|
|
6397c720e8 | ||
|
|
50c1e5aa3f | ||
|
|
970d02773f | ||
|
|
4ed53348b0 | ||
|
|
ff375abb0e | ||
|
|
893d48256b | ||
|
|
9f2ece50d9 | ||
|
|
a4166efa84 | ||
|
|
3a807535fa | ||
|
|
088d6b857c | ||
|
|
1fb7b53b9b | ||
|
|
8b0c87a1aa | ||
|
|
4c7eab5720 | ||
|
|
e9c1ced5d9 | ||
|
|
1ffee17475 | ||
|
|
1214fb0590 | ||
|
|
69f2d82082 | ||
|
|
5f7efa8bcb | ||
|
|
c06a32af07 | ||
|
|
1d8f82a47c | ||
|
|
b40701a8e6 | ||
|
|
4add1453a4 | ||
|
|
2f05727b25 | ||
|
|
608a10d159 | ||
|
|
eb51c9dd17 | ||
|
|
7519429c43 | ||
|
|
7ef6708d9d | ||
|
|
7bfe400c8a | ||
|
|
a0706c9fd4 | ||
|
|
b0e2867663 | ||
|
|
63165a0f9f | ||
|
|
cb25a64a4b | ||
|
|
21cd848064 | ||
|
|
e0f2206825 | ||
|
|
2099096acb | ||
|
|
a69d1adaf0 | ||
|
|
59cbc6846d | ||
|
|
51b0be7e2e | ||
|
|
2eff3090a9 | ||
|
|
748d5823ef | ||
|
|
d30d768bdc | ||
|
|
ce51b8daa8 | ||
|
|
fcd4357bd9 | ||
|
|
7107625b12 | ||
|
|
aa70be0973 | ||
|
|
fe5e9bf4ea | ||
|
|
554094540d | ||
|
|
cadbfaa546 | ||
|
|
1d7b351511 | ||
|
|
ddaac983a4 | ||
|
|
bd413d2e05 | ||
|
|
06b5a08b6d | ||
|
|
4b3736a189 | ||
|
|
7ab774d941 | ||
|
|
700190db9a | ||
|
|
fd5822df19 | ||
|
|
1a1f721b3f | ||
|
|
d31b71fab1 | ||
|
|
508c3000fa | ||
|
|
bed9665b3a | ||
|
|
ae5328142e | ||
|
|
fcd1012ff4 | ||
|
|
056016c022 | ||
|
|
8ad8a18c0e | ||
|
|
f2e9f2d753 | ||
|
|
a582cbe1e3 | ||
|
|
355f7d0152 | ||
|
|
7454a08e4a | ||
|
|
96dc2282a8 | ||
|
|
8a646f36d4 | ||
|
|
00891dfa2f | ||
|
|
0fc3e8182d | ||
|
|
95c1cf1f6c | ||
|
|
335fba3930 | ||
|
|
0bfc59b2d7 | ||
|
|
8409d7e425 | ||
|
|
374fae594c | ||
|
|
387221665f | ||
|
|
3bef5acb6e | ||
|
|
24ac2b902d | ||
|
|
605f079075 | ||
|
|
dbd84d7803 | ||
|
|
8da0ea7740 | ||
|
|
6098ac3e6d | ||
|
|
c1f12705a9 | ||
|
|
46035fa212 | ||
|
|
373e1893bc | ||
|
|
aa52b03bc2 | ||
|
|
6192a88b98 | ||
|
|
017df518a6 | ||
|
|
cf849ccf65 | ||
|
|
8651e3a77b | ||
|
|
83dd360062 | ||
|
|
d298a5bde5 | ||
|
|
925263a216 | ||
|
|
551aa3bb20 | ||
|
|
c62a686d30 | ||
|
|
cb78220156 | ||
|
|
cb00f4aba7 | ||
|
|
750ac02b7e | ||
|
|
22297c613c | ||
|
|
91a87f4581 | ||
|
|
4ccc004de3 | ||
|
|
bf1de4f307 | ||
|
|
24741a11c6 | ||
|
|
293a5b6912 | ||
|
|
442627dc35 | ||
|
|
5f8a323dde | ||
|
|
11809a6baf | ||
|
|
7e8d018242 | ||
|
|
436ca1d851 | ||
|
|
1162354c43 | ||
|
|
3b84cf85c3 | ||
|
|
ec34eb4a64 | ||
|
|
9a5f932e6a | ||
|
|
ef8f5bb80b | ||
|
|
b76e95b540 | ||
|
|
0231ce38d5 | ||
|
|
037810b23b | ||
|
|
b017e75787 | ||
|
|
8ff924e376 | ||
|
|
f7de632cd5 | ||
|
|
6221386873 | ||
|
|
cc3c676082 | ||
|
|
a554a86202 | ||
|
|
3c1b41c03f | ||
|
|
4eda2b61f5 | ||
|
|
f06bd5125b | ||
|
|
84df334f52 | ||
|
|
b88a3d02bf | ||
|
|
a0afe0e54f | ||
|
|
7e85a64a41 | ||
|
|
c820b22524 | ||
|
|
7fae32042f | ||
|
|
edbf2b3ec0 | ||
|
|
ac31999d9d | ||
|
|
2833ed2d2e | ||
|
|
ebd86df3ef | ||
|
|
918403c399 | ||
|
|
7c243af5da | ||
|
|
2b502848c1 | ||
|
|
d91a155084 | ||
|
|
7bb042a6ca | ||
|
|
14ce682210 | ||
|
|
dc9d83f9f0 | ||
|
|
fbd9c4d18b | ||
|
|
76312c7bb9 | ||
|
|
2a5690fd4d | ||
|
|
58966406da | ||
|
|
161736925e | ||
|
|
9398d03e0b | ||
|
|
e707391a5e | ||
|
|
cff5a58bc7 | ||
|
|
51577efd79 | ||
|
|
064de9fef7 | ||
|
|
c43616f3c5 | ||
|
|
e6adc0a296 | ||
|
|
13f340917e | ||
|
|
f195fd6f66 | ||
|
|
469be87dc3 | ||
|
|
7f8a0a71f5 | ||
|
|
16a43db79a | ||
|
|
a033b2db7b | ||
|
|
88ab312da0 | ||
|
|
8ce38eec9a | ||
|
|
49383ca921 | ||
|
|
ed07175437 | ||
|
|
c8208ab1df | ||
|
|
68f0fa8132 | ||
|
|
954131f73c | ||
|
|
06ec4b79a5 | ||
|
|
90797696dd | ||
|
|
de0aed2d2b | ||
|
|
4b253f888d | ||
|
|
c22f360ed1 | ||
|
|
5d74c2f7bf | ||
|
|
316085f2a6 |
+1
-1
@@ -24,7 +24,7 @@
|
||||
const unsigned int BUFFER_LENGTH = 200U;
|
||||
|
||||
const uint32_t PLLMAX = 0x10000U;
|
||||
const uint32_t PLLINC = PLLMAX / DSTAR_RADIO_BIT_LENGTH;
|
||||
const uint32_t PLLINC = PLLMAX / DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
const uint32_t INC = PLLINC / 32U;
|
||||
|
||||
// D-Star bit order version of 0x55 0x2D 0x16
|
||||
|
||||
+37
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2015 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2009-2015,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,30 +19,50 @@
|
||||
#if !defined(DSTARDEFINES_H)
|
||||
#define DSTARDEFINES_H
|
||||
|
||||
const unsigned int DSTAR_RADIO_BIT_LENGTH = 5U; // At 24 kHz sample rate
|
||||
const unsigned int DSTAR_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
|
||||
|
||||
const unsigned int DSTAR_HEADER_LENGTH_BYTES = 41U;
|
||||
const unsigned int DSTAR_HEADER_LENGTH_BITS = DSTAR_HEADER_LENGTH_BYTES * 8U;
|
||||
const unsigned int DSTAR_HEADER_LENGTH_BYTES = 41U;
|
||||
|
||||
const unsigned int DSTAR_FEC_SECTION_LENGTH_BYTES = 83U;
|
||||
const unsigned int DSTAR_FEC_SECTION_LENGTH_BITS = 660U;
|
||||
const unsigned int DSTAR_FEC_SECTION_LENGTH_BYTES = 83U;
|
||||
const unsigned int DSTAR_FEC_SECTION_LENGTH_SYMBOLS = 660U;
|
||||
const unsigned int DSTAR_FEC_SECTION_LENGTH_SAMPLES = DSTAR_FEC_SECTION_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
|
||||
const unsigned int DSTAR_DATA_LENGTH_BYTES = 12U;
|
||||
const unsigned int DSTAR_DATA_LENGTH_BITS = DSTAR_DATA_LENGTH_BYTES * 8U;
|
||||
const unsigned int DSTAR_DATA_LENGTH_BYTES = 12U;
|
||||
const unsigned int DSTAR_DATA_LENGTH_SYMBOLS = DSTAR_DATA_LENGTH_BYTES * 8U;
|
||||
const unsigned int DSTAR_DATA_LENGTH_SAMPLES = DSTAR_DATA_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
|
||||
const uint8_t DSTAR_EOT_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
const unsigned int DSTAR_EOT_LENGTH_BYTES = 6U;
|
||||
const unsigned int DSTAR_EOT_LENGTH_BITS = DSTAR_EOT_LENGTH_BYTES * 8U;
|
||||
const unsigned int DSTAR_END_SYNC_LENGTH_BYTES = 6U;
|
||||
const unsigned int DSTAR_END_SYNC_LENGTH_BITS = DSTAR_END_SYNC_LENGTH_BYTES * 8U;
|
||||
|
||||
const uint8_t DSTAR_DATA_SYNC_LENGTH_BYTES = 3U;
|
||||
const uint8_t DSTAR_DATA_SYNC_LENGTH_BITS = DSTAR_DATA_SYNC_LENGTH_BYTES * 8U;
|
||||
const unsigned int DSTAR_FRAME_SYNC_LENGTH_BYTES = 3U;
|
||||
const unsigned int DSTAR_FRAME_SYNC_LENGTH_SYMBOLS = DSTAR_FRAME_SYNC_LENGTH_BYTES * 8U;
|
||||
const unsigned int DSTAR_FRAME_SYNC_LENGTH_SAMPLES = DSTAR_FRAME_SYNC_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
|
||||
const uint8_t DSTAR_DATA_SYNC_BYTES[] = {0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x55, 0x2D, 0x16};
|
||||
const unsigned int DSTAR_DATA_SYNC_LENGTH_BYTES = 3U;
|
||||
const unsigned int DSTAR_DATA_SYNC_LENGTH_SYMBOLS = DSTAR_DATA_SYNC_LENGTH_BYTES * 8U;
|
||||
const unsigned int DSTAR_DATA_SYNC_LENGTH_SAMPLES = DSTAR_DATA_SYNC_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
|
||||
const uint8_t DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U;
|
||||
const uint8_t DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U;
|
||||
const uint8_t DSTAR_DATA_SYNC_BYTES[] = {0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x55, 0x2D, 0x16};
|
||||
|
||||
const uint8_t DSTAR_SCRAMBLER_BYTES[] = {0x70U, 0x4FU, 0x93U};
|
||||
// D-Star bit order version of 0x55 0x6E 0x0A
|
||||
const uint32_t DSTAR_FRAME_SYNC_DATA = 0x00557650U;
|
||||
const uint32_t DSTAR_FRAME_SYNC_MASK = 0x00FFFFFFU;
|
||||
const bool DSTAR_FRAME_SYNC_SYMBOLS[] = {false, true, false, true, false, true, false, true, false, true, true, true, false, true, true, false, false, true, false, true, false, false, false, false};
|
||||
|
||||
// D-Star bit order version of 0x55 0x2D 0x16
|
||||
const uint32_t DSTAR_DATA_SYNC_DATA = 0x00AAB468U;
|
||||
const uint32_t DSTAR_DATA_SYNC_MASK = 0x00FFFFFFU;
|
||||
const bool DSTAR_DATA_SYNC_SYMBOLS[] = {true, false, true, false, true, false, true, false, true, false, true, true, false, true, false, false, false, true, true, false, true, false, false, false};
|
||||
|
||||
// D-Star bit order version of 0x55 0x55 0xC8 0x7A
|
||||
const uint32_t DSTAR_END_SYNC_DATA = 0xAAAA135EU;
|
||||
const uint32_t DSTAR_END_SYNC_MASK = 0xFFFFFFFFU;
|
||||
const uint8_t DSTAR_END_SYNC_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
const uint8_t DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U;
|
||||
const uint8_t DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U;
|
||||
|
||||
const uint8_t DSTAR_SCRAMBLER_BYTES[] = {0x70U, 0x4FU, 0x93U};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+238
-137
@@ -22,18 +22,12 @@
|
||||
#include "DStarRX.h"
|
||||
#include "Utils.h"
|
||||
|
||||
const unsigned int BUFFER_LENGTH = 200U;
|
||||
|
||||
const uint32_t PLLMAX = 0x10000U;
|
||||
const uint32_t PLLINC = PLLMAX / DSTAR_RADIO_BIT_LENGTH;
|
||||
const uint32_t INC = PLLINC / 32U;
|
||||
|
||||
const unsigned int MAX_SYNC_BITS = 100U * DSTAR_DATA_LENGTH_BITS;
|
||||
const unsigned int MAX_FRAMES = 150U;
|
||||
|
||||
// D-Star bit order version of 0x55 0x55 0x6E 0x0A
|
||||
const uint32_t FRAME_SYNC_DATA = 0x00557650U;
|
||||
const uint32_t FRAME_SYNC_MASK = 0x00FFFFFFU;
|
||||
const uint8_t FRAME_SYNC_ERRS = 2U;
|
||||
const uint8_t FRAME_SYNC_ERRS = 1U;
|
||||
|
||||
// D-Star bit order version of 0x55 0x2D 0x16
|
||||
const uint32_t DATA_SYNC_DATA = 0x00AAB468U;
|
||||
@@ -237,14 +231,24 @@ const uint16_t CCITT_TABLE[] = {
|
||||
0xf78fU, 0xe606U, 0xd49dU, 0xc514U, 0xb1abU, 0xa022U, 0x92b9U, 0x8330U,
|
||||
0x7bc7U, 0x6a4eU, 0x58d5U, 0x495cU, 0x3de3U, 0x2c6aU, 0x1ef1U, 0x0f78U};
|
||||
|
||||
const uint16_t NOENDPTR = 9999U;
|
||||
|
||||
CDStarRX::CDStarRX() :
|
||||
m_pll(0U),
|
||||
m_prev(false),
|
||||
m_rxState(DSRXS_NONE),
|
||||
m_patternBuffer(0x00U),
|
||||
m_rxBuffer(),
|
||||
m_rxBufferBits(0U),
|
||||
m_dataBits(0U),
|
||||
m_bitBuffer(),
|
||||
m_headerBuffer(),
|
||||
m_dataBuffer(),
|
||||
m_bitPtr(0U),
|
||||
m_headerPtr(0U),
|
||||
m_dataPtr(0U),
|
||||
m_startPtr(NOENDPTR),
|
||||
m_syncPtr(NOENDPTR),
|
||||
m_minSyncPtr(NOENDPTR),
|
||||
m_maxSyncPtr(NOENDPTR),
|
||||
m_maxFrameCorr(0),
|
||||
m_maxDataCorr(0),
|
||||
m_frameCount(0U),
|
||||
m_countdown(0U),
|
||||
m_mar(0U),
|
||||
m_pathMetric(),
|
||||
m_pathMemory0(),
|
||||
@@ -259,14 +263,20 @@ m_rssiCount(0U)
|
||||
|
||||
void CDStarRX::reset()
|
||||
{
|
||||
m_pll = 0U;
|
||||
m_prev = false;
|
||||
m_rxState = DSRXS_NONE;
|
||||
m_patternBuffer = 0x00U;
|
||||
m_rxBufferBits = 0U;
|
||||
m_dataBits = 0U;
|
||||
m_rssiAccum = 0U;
|
||||
m_rssiCount = 0U;
|
||||
m_rxState = DSRXS_NONE;
|
||||
m_headerPtr = 0U;
|
||||
m_dataPtr = 0U;
|
||||
m_bitPtr = 0U;
|
||||
m_maxFrameCorr = 0;
|
||||
m_maxDataCorr = 0;
|
||||
m_startPtr = NOENDPTR;
|
||||
m_syncPtr = NOENDPTR;
|
||||
m_minSyncPtr = NOENDPTR;
|
||||
m_maxSyncPtr = NOENDPTR;
|
||||
m_frameCount = 0U;
|
||||
m_countdown = 0U;
|
||||
m_rssiAccum = 0U;
|
||||
m_rssiCount = 0U;
|
||||
}
|
||||
|
||||
void CDStarRX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length)
|
||||
@@ -275,125 +285,117 @@ void CDStarRX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t lengt
|
||||
m_rssiAccum += rssi[i];
|
||||
m_rssiCount++;
|
||||
|
||||
bool bit = samples[i] < 0;
|
||||
q15_t sample = samples[i];
|
||||
|
||||
if (bit != m_prev) {
|
||||
if (m_pll < (PLLMAX / 2U))
|
||||
m_pll += INC;
|
||||
else
|
||||
m_pll -= INC;
|
||||
m_bitBuffer[m_bitPtr] <<= 1;
|
||||
if (sample < 0)
|
||||
m_bitBuffer[m_bitPtr] |= 0x01U;
|
||||
|
||||
m_dataBuffer[m_dataPtr] = sample;
|
||||
|
||||
switch (m_rxState) {
|
||||
case DSRXS_HEADER:
|
||||
processHeader(sample);
|
||||
break;
|
||||
case DSRXS_DATA:
|
||||
processData();
|
||||
break;
|
||||
default:
|
||||
processNone(sample);
|
||||
break;
|
||||
}
|
||||
|
||||
m_prev = bit;
|
||||
m_dataPtr++;
|
||||
if (m_dataPtr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||
m_dataPtr = 0U;
|
||||
|
||||
m_pll += PLLINC;
|
||||
|
||||
if (m_pll >= PLLMAX) {
|
||||
m_pll -= PLLMAX;
|
||||
|
||||
switch (m_rxState) {
|
||||
case DSRXS_NONE:
|
||||
processNone(bit);
|
||||
break;
|
||||
case DSRXS_HEADER:
|
||||
processHeader(bit);
|
||||
break;
|
||||
case DSRXS_DATA:
|
||||
processData(bit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_bitPtr++;
|
||||
if (m_bitPtr >= DSTAR_RADIO_SYMBOL_LENGTH)
|
||||
m_bitPtr = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
void CDStarRX::processNone(bool bit)
|
||||
void CDStarRX::processNone(q15_t sample)
|
||||
{
|
||||
m_patternBuffer <<= 1;
|
||||
if (bit)
|
||||
m_patternBuffer |= 0x01U;
|
||||
|
||||
// Fuzzy matching of the frame sync sequence
|
||||
if (countBits32((m_patternBuffer & FRAME_SYNC_MASK) ^ FRAME_SYNC_DATA) <= FRAME_SYNC_ERRS) {
|
||||
DEBUG1("DStarRX: found frame sync in None");
|
||||
|
||||
::memset(m_rxBuffer, 0x00U, DSTAR_FEC_SECTION_LENGTH_BYTES);
|
||||
m_rxBufferBits = 0U;
|
||||
bool ret = correlateFrameSync();
|
||||
if (ret) {
|
||||
m_countdown = 5U;
|
||||
|
||||
m_headerBuffer[m_headerPtr] = sample;
|
||||
m_headerPtr++;
|
||||
|
||||
m_rssiAccum = 0U;
|
||||
m_rssiCount = 0U;
|
||||
|
||||
m_rxState = DSRXS_HEADER;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Exact matching of the data sync bit sequence
|
||||
if (countBits32((m_patternBuffer & DATA_SYNC_MASK) ^ DATA_SYNC_DATA) == 0U) {
|
||||
// Fuzzy matching of the data sync bit sequence
|
||||
ret = correlateDataSync();
|
||||
if (ret) {
|
||||
DEBUG1("DStarRX: found data sync in None");
|
||||
|
||||
io.setDecode(true);
|
||||
io.setADCDetection(true);
|
||||
|
||||
// Suppress RSSI on the dummy sync message
|
||||
m_rssiAccum = 0U;
|
||||
m_rssiCount = 0U;
|
||||
|
||||
::memcpy(m_rxBuffer, DSTAR_DATA_SYNC_BYTES, DSTAR_DATA_LENGTH_BYTES);
|
||||
writeRSSIData(m_rxBuffer);
|
||||
|
||||
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
||||
m_rxBufferBits = 0U;
|
||||
|
||||
m_dataBits = MAX_SYNC_BITS;
|
||||
m_rxState = DSRXS_DATA;
|
||||
return;
|
||||
m_rxState = DSRXS_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
void CDStarRX::processHeader(bool bit)
|
||||
void CDStarRX::processHeader(q15_t sample)
|
||||
{
|
||||
m_patternBuffer <<= 1;
|
||||
if (bit)
|
||||
m_patternBuffer |= 0x01U;
|
||||
if (m_countdown > 0U) {
|
||||
correlateFrameSync();
|
||||
m_countdown--;
|
||||
}
|
||||
|
||||
WRITE_BIT2(m_rxBuffer, m_rxBufferBits, bit);
|
||||
m_rxBufferBits++;
|
||||
m_headerBuffer[m_headerPtr] = sample;
|
||||
m_headerPtr++;
|
||||
|
||||
// A full FEC header
|
||||
if (m_rxBufferBits == DSTAR_FEC_SECTION_LENGTH_BITS) {
|
||||
// Process the scrambling, interleaving and FEC, then return if the chcksum was correct
|
||||
unsigned char header[DSTAR_HEADER_LENGTH_BYTES];
|
||||
bool ok = rxHeader(m_rxBuffer, header);
|
||||
if (ok) {
|
||||
if (m_headerPtr == (DSTAR_FEC_SECTION_LENGTH_SAMPLES + DSTAR_RADIO_SYMBOL_LENGTH)) {
|
||||
uint8_t buffer[DSTAR_FEC_SECTION_LENGTH_BYTES];
|
||||
samplesToBits(m_headerBuffer, DSTAR_RADIO_SYMBOL_LENGTH, DSTAR_FEC_SECTION_LENGTH_SYMBOLS, buffer, DSTAR_FEC_SECTION_LENGTH_SAMPLES);
|
||||
|
||||
// Process the scrambling, interleaving and FEC, then return true if the chcksum was correct
|
||||
uint8_t header[DSTAR_HEADER_LENGTH_BYTES];
|
||||
bool ok = rxHeader(buffer, header);
|
||||
if (!ok) {
|
||||
// The checksum failed, return to looking for syncs
|
||||
m_rxState = DSRXS_NONE;
|
||||
m_maxFrameCorr = 0;
|
||||
m_maxDataCorr = 0;
|
||||
} else {
|
||||
io.setDecode(true);
|
||||
io.setADCDetection(true);
|
||||
|
||||
writeRSSIHeader(header);
|
||||
|
||||
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
||||
m_rxBufferBits = 0U;
|
||||
|
||||
m_rxState = DSRXS_DATA;
|
||||
m_dataBits = MAX_SYNC_BITS;
|
||||
} else {
|
||||
// The checksum failed, return to looking for syncs
|
||||
m_rxState = DSRXS_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// Ready to start the first data section
|
||||
if (m_headerPtr == (DSTAR_FEC_SECTION_LENGTH_SAMPLES + 2U * DSTAR_RADIO_SYMBOL_LENGTH)) {
|
||||
m_frameCount = 0U;
|
||||
m_dataPtr = 0U;
|
||||
|
||||
m_startPtr = 476U;
|
||||
m_syncPtr = 471U;
|
||||
m_maxSyncPtr = 472U;
|
||||
m_minSyncPtr = 470U;
|
||||
|
||||
DEBUG5("DStarRX: calc start/sync/max/min", m_startPtr, m_syncPtr, m_maxSyncPtr, m_minSyncPtr);
|
||||
|
||||
m_rxState = DSRXS_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
void CDStarRX::processData(bool bit)
|
||||
void CDStarRX::processData()
|
||||
{
|
||||
m_patternBuffer <<= 1;
|
||||
if (bit)
|
||||
m_patternBuffer |= 0x01U;
|
||||
|
||||
WRITE_BIT2(m_rxBuffer, m_rxBufferBits, bit);
|
||||
m_rxBufferBits++;
|
||||
|
||||
// Fuzzy matching of the end frame sequences
|
||||
if (countBits32((m_patternBuffer & END_SYNC_MASK) ^ END_SYNC_DATA) <= END_SYNC_ERRS) {
|
||||
if (countBits32((m_bitBuffer[m_bitPtr] & DSTAR_END_SYNC_MASK) ^ DSTAR_END_SYNC_DATA) <= END_SYNC_ERRS) {
|
||||
DEBUG1("DStarRX: Found end sync in Data");
|
||||
|
||||
io.setDecode(false);
|
||||
@@ -401,35 +403,24 @@ void CDStarRX::processData(bool bit)
|
||||
|
||||
serial.writeDStarEOT();
|
||||
|
||||
m_maxFrameCorr = 0;
|
||||
m_maxDataCorr = 0;
|
||||
|
||||
m_rxState = DSRXS_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Fuzzy matching of the data sync bit sequence
|
||||
bool syncSeen = false;
|
||||
if (m_rxBufferBits >= (DSTAR_DATA_LENGTH_BITS - 3U)) {
|
||||
if (countBits32((m_patternBuffer & DATA_SYNC_MASK) ^ DATA_SYNC_DATA) <= DATA_SYNC_ERRS) {
|
||||
m_rxBufferBits = DSTAR_DATA_LENGTH_BITS;
|
||||
m_dataBits = MAX_SYNC_BITS;
|
||||
syncSeen = true;
|
||||
}
|
||||
if (m_minSyncPtr < m_maxSyncPtr) {
|
||||
if (m_dataPtr >= m_minSyncPtr && m_dataPtr <= m_maxSyncPtr)
|
||||
correlateDataSync();
|
||||
} else {
|
||||
if (m_dataPtr >= m_minSyncPtr || m_dataPtr <= m_maxSyncPtr)
|
||||
correlateDataSync();
|
||||
}
|
||||
|
||||
// Check to see if the sync is arriving late
|
||||
if (m_rxBufferBits == DSTAR_DATA_LENGTH_BITS && !syncSeen) {
|
||||
for (uint8_t i = 1U; i <= 3U; i++) {
|
||||
uint32_t syncMask = DATA_SYNC_MASK >> i;
|
||||
uint32_t syncData = DATA_SYNC_DATA >> i;
|
||||
if (countBits32((m_patternBuffer & syncMask) ^ syncData) <= DATA_SYNC_ERRS) {
|
||||
m_rxBufferBits -= i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_dataBits--;
|
||||
|
||||
if (m_dataBits == 0U) {
|
||||
// We've not seen a data sync for too long, signal RXLOST and change to RX_NONE
|
||||
if (m_frameCount >= MAX_FRAMES) {
|
||||
DEBUG1("DStarRX: data sync timed out, lost lock");
|
||||
|
||||
io.setDecode(false);
|
||||
@@ -437,24 +428,35 @@ void CDStarRX::processData(bool bit)
|
||||
|
||||
serial.writeDStarLost();
|
||||
|
||||
m_maxFrameCorr = 0;
|
||||
m_maxDataCorr = 0;
|
||||
|
||||
m_rxState = DSRXS_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Send a data frame to the host if the required number of bits have been received, or if a data sync has been seen
|
||||
if (m_rxBufferBits == DSTAR_DATA_LENGTH_BITS) {
|
||||
if (syncSeen) {
|
||||
m_rxBuffer[9U] = DSTAR_DATA_SYNC_BYTES[9U];
|
||||
m_rxBuffer[10U] = DSTAR_DATA_SYNC_BYTES[10U];
|
||||
m_rxBuffer[11U] = DSTAR_DATA_SYNC_BYTES[11U];
|
||||
writeRSSIData(m_rxBuffer);
|
||||
} else {
|
||||
serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES);
|
||||
}
|
||||
// Send a data frame to the host if the required number of bits have been received
|
||||
if (m_dataPtr == m_maxSyncPtr) {
|
||||
uint8_t buffer[DSTAR_DATA_LENGTH_BYTES + 2U];
|
||||
samplesToBits(m_dataBuffer, m_startPtr, DSTAR_DATA_LENGTH_SYMBOLS, buffer, DSTAR_DATA_LENGTH_SAMPLES);
|
||||
|
||||
// Start the next frame
|
||||
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
||||
m_rxBufferBits = 0U;
|
||||
if ((m_frameCount % 21U) == 0U) {
|
||||
if (m_frameCount == 0U) {
|
||||
buffer[9U] = DSTAR_DATA_SYNC_BYTES[9U];
|
||||
buffer[10U] = DSTAR_DATA_SYNC_BYTES[10U];
|
||||
buffer[11U] = DSTAR_DATA_SYNC_BYTES[11U];
|
||||
DEBUG5("DStarRX: found start/sync/max/min", m_startPtr, m_syncPtr, m_maxSyncPtr, m_minSyncPtr);
|
||||
}
|
||||
|
||||
writeRSSIData(buffer);
|
||||
} else {
|
||||
serial.writeDStarData(buffer, DSTAR_DATA_LENGTH_BYTES);
|
||||
}
|
||||
|
||||
m_frameCount++;
|
||||
|
||||
m_maxFrameCorr = 0;
|
||||
m_maxDataCorr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,6 +502,105 @@ void CDStarRX::writeRSSIData(unsigned char* data)
|
||||
m_rssiCount = 0U;
|
||||
}
|
||||
|
||||
bool CDStarRX::correlateFrameSync()
|
||||
{
|
||||
if (countBits32((m_bitBuffer[m_bitPtr] & DSTAR_FRAME_SYNC_MASK) ^ DSTAR_FRAME_SYNC_DATA) <= FRAME_SYNC_ERRS) {
|
||||
uint16_t ptr = m_dataPtr + DSTAR_DATA_LENGTH_SAMPLES - DSTAR_FRAME_SYNC_LENGTH_SAMPLES + DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||
|
||||
q31_t corr = 0;
|
||||
|
||||
for (uint8_t i = 0U; i < DSTAR_FRAME_SYNC_LENGTH_SYMBOLS; i++) {
|
||||
q15_t val = m_dataBuffer[ptr];
|
||||
|
||||
if (DSTAR_FRAME_SYNC_SYMBOLS[i])
|
||||
corr -= val;
|
||||
else
|
||||
corr += val;
|
||||
|
||||
ptr += DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||
}
|
||||
|
||||
if (corr > m_maxFrameCorr) {
|
||||
m_maxFrameCorr = corr;
|
||||
m_headerPtr = 0U;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDStarRX::correlateDataSync()
|
||||
{
|
||||
uint8_t maxErrs = 0U;
|
||||
if (m_rxState == DSRXS_DATA)
|
||||
maxErrs = DATA_SYNC_ERRS;
|
||||
|
||||
if (countBits32((m_bitBuffer[m_bitPtr] & DSTAR_DATA_SYNC_MASK) ^ DSTAR_DATA_SYNC_DATA) <= maxErrs) {
|
||||
uint16_t ptr = m_dataPtr + DSTAR_DATA_LENGTH_SAMPLES - DSTAR_DATA_SYNC_LENGTH_SAMPLES + DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||
|
||||
q31_t corr = 0;
|
||||
|
||||
for (uint8_t i = 0U; i < DSTAR_DATA_SYNC_LENGTH_SYMBOLS; i++) {
|
||||
q15_t val = m_dataBuffer[ptr];
|
||||
|
||||
if (DSTAR_DATA_SYNC_SYMBOLS[i])
|
||||
corr -= val;
|
||||
else
|
||||
corr += val;
|
||||
|
||||
ptr += DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||
}
|
||||
|
||||
if (corr > m_maxDataCorr) {
|
||||
m_maxDataCorr = corr;
|
||||
m_frameCount = 0U;
|
||||
|
||||
m_syncPtr = m_dataPtr;
|
||||
|
||||
m_startPtr = m_dataPtr + DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
if (m_startPtr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||
m_startPtr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||
|
||||
m_maxSyncPtr = m_syncPtr + 1U;
|
||||
if (m_maxSyncPtr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||
m_maxSyncPtr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||
|
||||
m_minSyncPtr = m_syncPtr + DSTAR_DATA_LENGTH_SAMPLES - 1U;
|
||||
if (m_minSyncPtr >= DSTAR_DATA_LENGTH_SAMPLES)
|
||||
m_minSyncPtr -= DSTAR_DATA_LENGTH_SAMPLES;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDStarRX::samplesToBits(const q15_t* inBuffer, uint16_t start, uint16_t count, uint8_t* outBuffer, uint16_t limit)
|
||||
{
|
||||
for (uint16_t i = 0U; i < count; i++) {
|
||||
q15_t sample = inBuffer[start];
|
||||
|
||||
if (sample < 0)
|
||||
WRITE_BIT2(outBuffer, i, true);
|
||||
else
|
||||
WRITE_BIT2(outBuffer, i, false);
|
||||
|
||||
start += DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
if (start >= limit)
|
||||
start -= limit;
|
||||
}
|
||||
}
|
||||
|
||||
bool CDStarRX::rxHeader(uint8_t* in, uint8_t* out)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -37,13 +37,21 @@ public:
|
||||
void reset();
|
||||
|
||||
private:
|
||||
uint32_t m_pll;
|
||||
bool m_prev;
|
||||
DSRX_STATE m_rxState;
|
||||
uint32_t m_patternBuffer;
|
||||
uint8_t m_rxBuffer[100U];
|
||||
unsigned int m_rxBufferBits;
|
||||
unsigned int m_dataBits;
|
||||
uint32_t m_bitBuffer[DSTAR_RADIO_SYMBOL_LENGTH];
|
||||
q15_t m_headerBuffer[DSTAR_FEC_SECTION_LENGTH_SAMPLES + 2U * DSTAR_RADIO_SYMBOL_LENGTH];
|
||||
q15_t m_dataBuffer[DSTAR_DATA_LENGTH_SAMPLES];
|
||||
uint16_t m_bitPtr;
|
||||
uint16_t m_headerPtr;
|
||||
uint16_t m_dataPtr;
|
||||
uint16_t m_startPtr;
|
||||
uint16_t m_syncPtr;
|
||||
uint16_t m_minSyncPtr;
|
||||
uint16_t m_maxSyncPtr;
|
||||
q31_t m_maxFrameCorr;
|
||||
q31_t m_maxDataCorr;
|
||||
uint16_t m_frameCount;
|
||||
uint8_t m_countdown;
|
||||
unsigned int m_mar;
|
||||
int m_pathMetric[4U];
|
||||
unsigned int m_pathMemory0[42U];
|
||||
@@ -54,9 +62,12 @@ private:
|
||||
uint32_t m_rssiAccum;
|
||||
uint16_t m_rssiCount;
|
||||
|
||||
void processNone(bool bit);
|
||||
void processHeader(bool bit);
|
||||
void processData(bool bit);
|
||||
void processNone(q15_t sample);
|
||||
void processHeader(q15_t sample);
|
||||
void processData();
|
||||
bool correlateFrameSync();
|
||||
bool correlateDataSync();
|
||||
void samplesToBits(const q15_t* inBuffer, uint16_t start, uint16_t count, uint8_t* outBuffer, uint16_t limit);
|
||||
void writeRSSIHeader(unsigned char* header);
|
||||
void writeRSSIData(unsigned char* data);
|
||||
bool rxHeader(uint8_t* in, uint8_t* out);
|
||||
|
||||
+7
-7
@@ -198,7 +198,7 @@ m_txDelay(60U) // 100ms
|
||||
{
|
||||
::memset(m_modState, 0x00U, 20U * sizeof(q15_t));
|
||||
|
||||
m_modFilter.L = DSTAR_RADIO_BIT_LENGTH;
|
||||
m_modFilter.L = DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
m_modFilter.phaseLength = GAUSSIAN_0_35_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = GAUSSIAN_0_35_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
@@ -252,8 +252,8 @@ void CDStarTX::process()
|
||||
m_buffer.get();
|
||||
|
||||
for (uint8_t j = 0U; j < 3U; j++) {
|
||||
for (uint8_t i = 0U; i < DSTAR_EOT_LENGTH_BYTES; i++)
|
||||
m_poBuffer[m_poLen++] = DSTAR_EOT_BYTES[i];
|
||||
for (uint8_t i = 0U; i < DSTAR_END_SYNC_LENGTH_BYTES; i++)
|
||||
m_poBuffer[m_poLen++] = DSTAR_END_SYNC_BYTES[i];
|
||||
}
|
||||
|
||||
m_poPtr = 0U;
|
||||
@@ -262,11 +262,11 @@ void CDStarTX::process()
|
||||
if (m_poLen > 0U) {
|
||||
uint16_t space = io.getSpace();
|
||||
|
||||
while (space > (8U * DSTAR_RADIO_BIT_LENGTH)) {
|
||||
while (space > (8U * DSTAR_RADIO_SYMBOL_LENGTH)) {
|
||||
uint8_t c = m_poBuffer[m_poPtr++];
|
||||
writeByte(c);
|
||||
|
||||
space -= 8U * DSTAR_RADIO_BIT_LENGTH;
|
||||
space -= 8U * DSTAR_RADIO_SYMBOL_LENGTH;
|
||||
|
||||
if (m_poPtr >= m_poLen) {
|
||||
m_poPtr = 0U;
|
||||
@@ -412,7 +412,7 @@ void CDStarTX::txHeader(const uint8_t* in, uint8_t* out) const
|
||||
void CDStarTX::writeByte(uint8_t c)
|
||||
{
|
||||
q15_t inBuffer[8U];
|
||||
q15_t outBuffer[DSTAR_RADIO_BIT_LENGTH * 8U];
|
||||
q15_t outBuffer[DSTAR_RADIO_SYMBOL_LENGTH * 8U];
|
||||
|
||||
uint8_t mask = 0x01U;
|
||||
|
||||
@@ -427,7 +427,7 @@ void CDStarTX::writeByte(uint8_t c)
|
||||
|
||||
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, outBuffer, 8U);
|
||||
|
||||
io.write(STATE_DSTAR, outBuffer, DSTAR_RADIO_BIT_LENGTH * 8U);
|
||||
io.write(STATE_DSTAR, outBuffer, DSTAR_RADIO_SYMBOL_LENGTH * 8U);
|
||||
}
|
||||
|
||||
void CDStarTX::setTXDelay(uint8_t delay)
|
||||
|
||||
@@ -235,14 +235,16 @@ void CFM::stateMachine(bool validSignal)
|
||||
}
|
||||
|
||||
if (m_state == FS_LISTENING && m_modemState == STATE_FM) {
|
||||
DEBUG1("Change to STATE_IDLE");
|
||||
m_modemState = STATE_IDLE;
|
||||
m_callsignTimer.stop();
|
||||
m_timeoutTimer.stop();
|
||||
m_kerchunkTimer.stop();
|
||||
m_ackMinTimer.stop();
|
||||
m_ackDelayTimer.stop();
|
||||
m_hangTimer.stop();
|
||||
if (!m_callsign.isWanted() && !m_rfAck.isWanted()) {
|
||||
DEBUG1("Change to STATE_IDLE");
|
||||
m_modemState = STATE_IDLE;
|
||||
m_callsignTimer.stop();
|
||||
m_timeoutTimer.stop();
|
||||
m_kerchunkTimer.stop();
|
||||
m_ackMinTimer.stop();
|
||||
m_ackDelayTimer.stop();
|
||||
m_hangTimer.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,6 +281,9 @@ void CFM::listeningState(bool validSignal)
|
||||
|
||||
m_callsignTimer.start();
|
||||
|
||||
io.setDecode(true);
|
||||
io.setADCDetection(true);
|
||||
|
||||
DEBUG1("Change to STATE_FM");
|
||||
m_modemState = STATE_FM;
|
||||
}
|
||||
@@ -297,6 +302,9 @@ void CFM::kerchunkState(bool validSignal)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
io.setDecode(false);
|
||||
io.setADCDetection(false);
|
||||
|
||||
DEBUG1("State to LISTENING");
|
||||
m_state = FS_LISTENING;
|
||||
m_kerchunkTimer.stop();
|
||||
@@ -317,6 +325,9 @@ void CFM::relayingState(bool validSignal)
|
||||
m_timeoutTone.start();
|
||||
}
|
||||
} else {
|
||||
io.setDecode(false);
|
||||
io.setADCDetection(false);
|
||||
|
||||
DEBUG1("State to RELAYING_WAIT");
|
||||
m_state = FS_RELAYING_WAIT;
|
||||
m_ackDelayTimer.start();
|
||||
@@ -331,6 +342,9 @@ void CFM::relayingState(bool validSignal)
|
||||
void CFM::relayingWaitState(bool validSignal)
|
||||
{
|
||||
if (validSignal) {
|
||||
io.setDecode(true);
|
||||
io.setADCDetection(true);
|
||||
|
||||
DEBUG1("State to RELAYING");
|
||||
m_state = FS_RELAYING;
|
||||
m_ackDelayTimer.stop();
|
||||
@@ -366,6 +380,9 @@ void CFM::relayingWaitState(bool validSignal)
|
||||
void CFM::hangState(bool validSignal)
|
||||
{
|
||||
if (validSignal) {
|
||||
io.setDecode(true);
|
||||
io.setADCDetection(true);
|
||||
|
||||
DEBUG1("State to RELAYING");
|
||||
m_state = FS_RELAYING;
|
||||
DEBUG1("Stop ack");
|
||||
@@ -393,6 +410,9 @@ void CFM::hangState(bool validSignal)
|
||||
void CFM::timeoutState(bool validSignal)
|
||||
{
|
||||
if (!validSignal) {
|
||||
io.setDecode(false);
|
||||
io.setADCDetection(false);
|
||||
|
||||
DEBUG1("State to TIMEOUT_WAIT");
|
||||
m_state = FS_TIMEOUT_WAIT;
|
||||
m_ackDelayTimer.start();
|
||||
@@ -407,6 +427,9 @@ void CFM::timeoutState(bool validSignal)
|
||||
void CFM::timeoutWaitState(bool validSignal)
|
||||
{
|
||||
if (validSignal) {
|
||||
io.setDecode(true);
|
||||
io.setADCDetection(true);
|
||||
|
||||
DEBUG1("State to TIMEOUT");
|
||||
m_state = FS_TIMEOUT;
|
||||
m_ackDelayTimer.stop();
|
||||
|
||||
@@ -205,6 +205,11 @@ void CFMKeyer::stop()
|
||||
m_audioPos = 0U;
|
||||
}
|
||||
|
||||
bool CFMKeyer::isWanted() const
|
||||
{
|
||||
return m_wanted;
|
||||
}
|
||||
|
||||
bool CFMKeyer::isRunning() const
|
||||
{
|
||||
return m_poPos > 0U || m_dotPos > 0U || m_audioPos > 0U;
|
||||
|
||||
@@ -35,6 +35,8 @@ public:
|
||||
|
||||
bool isRunning() const;
|
||||
|
||||
bool isWanted() const;
|
||||
|
||||
private:
|
||||
bool m_wanted;
|
||||
uint8_t m_poBuffer[1000U];
|
||||
|
||||
@@ -26,31 +26,12 @@
|
||||
static q31_t DC_FILTER[] = {3367972, 0, 3367972, 0, 2140747704, 0}; // {b0, 0, b1, b2, -a1, -a2}
|
||||
const uint32_t DC_FILTER_STAGES = 1U; // One Biquad stage
|
||||
|
||||
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
|
||||
static q15_t RRC_0_2_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
|
||||
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
|
||||
-553, -847, -731, -340, 104, 401, 0};
|
||||
const uint16_t RRC_0_2_FILTER_LEN = 42U;
|
||||
// One symbol boxcar filters
|
||||
static q15_t BOXCAR5_FILTER[] = {12000, 12000, 12000, 12000, 12000, 0};
|
||||
const uint16_t BOXCAR5_FILTER_LEN = 6U;
|
||||
|
||||
// Generated using rcosdesign(0.2, 8, 10, 'sqrt') in MATLAB
|
||||
static q15_t NXDN_0_2_FILTER[] = {284, 198, 73, -78, -240, -393, -517, -590, -599, -533, -391, -181, 79, 364, 643, 880, 1041, 1097, 1026, 819,
|
||||
483, 39, -477, -1016, -1516, -1915, -2150, -2164, -1914, -1375, -545, 557, 1886, 3376, 4946, 6502, 7946, 9184,
|
||||
10134, 10731, 10935, 10731, 10134, 9184, 7946, 6502, 4946, 3376, 1886, 557, -545, -1375, -1914, -2164, -2150,
|
||||
-1915, -1516, -1016, -477, 39, 483, 819, 1026, 1097, 1041, 880, 643, 364, 79, -181, -391, -533, -599, -590,
|
||||
-517, -393, -240, -78, 73, 198, 284, 0};
|
||||
const uint16_t NXDN_0_2_FILTER_LEN = 82U;
|
||||
|
||||
static q15_t NXDN_ISINC_FILTER[] = {790, -1085, -1073, -553, 747, 2341, 3156, 2152, -893, -4915, -7834, -7536, -3102, 4441, 12354, 17394, 17394,
|
||||
12354, 4441, -3102, -7536, -7834, -4915, -893, 2152, 3156, 2341, 747, -553, -1073, -1085, 790};
|
||||
const uint16_t NXDN_ISINC_FILTER_LEN = 32U;
|
||||
|
||||
// Generated using gaussfir(0.5, 4, 5) in MATLAB
|
||||
static q15_t GAUSSIAN_0_5_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0};
|
||||
const uint16_t GAUSSIAN_0_5_FILTER_LEN = 12U;
|
||||
|
||||
// One symbol boxcar filter
|
||||
static q15_t BOXCAR_FILTER[] = {12000, 12000, 12000, 12000, 12000, 0};
|
||||
const uint16_t BOXCAR_FILTER_LEN = 6U;
|
||||
static q15_t BOXCAR10_FILTER[] = {6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000};
|
||||
const uint16_t BOXCAR10_FILTER_LEN = 10U;
|
||||
|
||||
const uint16_t DC_OFFSET = 2048U;
|
||||
|
||||
@@ -61,16 +42,10 @@ m_txBuffer(TX_RINGBUFFER_SIZE),
|
||||
m_rssiBuffer(RX_RINGBUFFER_SIZE),
|
||||
m_dcFilter(),
|
||||
m_dcState(),
|
||||
m_rrcFilter(),
|
||||
m_gaussianFilter(),
|
||||
m_boxcarFilter(),
|
||||
m_nxdnFilter(),
|
||||
m_nxdnISincFilter(),
|
||||
m_rrcState(),
|
||||
m_gaussianState(),
|
||||
m_boxcarState(),
|
||||
m_nxdnState(),
|
||||
m_nxdnISincState(),
|
||||
m_boxcar5Filter(),
|
||||
m_boxcar10Filter(),
|
||||
m_boxcar5State(),
|
||||
m_boxcar10State(),
|
||||
m_pttInvert(false),
|
||||
m_rxLevel(128 * 128),
|
||||
m_cwIdTXLevel(128 * 128),
|
||||
@@ -91,37 +66,22 @@ m_dacOverflow(0U),
|
||||
m_watchdog(0U),
|
||||
m_lockout(false)
|
||||
{
|
||||
::memset(m_rrcState, 0x00U, 70U * sizeof(q15_t));
|
||||
::memset(m_gaussianState, 0x00U, 40U * sizeof(q15_t));
|
||||
::memset(m_boxcarState, 0x00U, 30U * sizeof(q15_t));
|
||||
::memset(m_nxdnState, 0x00U, 110U * sizeof(q15_t));
|
||||
::memset(m_nxdnISincState, 0x00U, 60U * sizeof(q15_t));
|
||||
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
|
||||
::memset(m_boxcar5State, 0x00U, 30U * sizeof(q15_t));
|
||||
::memset(m_boxcar10State, 0x00U, 40U * sizeof(q15_t));
|
||||
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
|
||||
|
||||
m_dcFilter.numStages = DC_FILTER_STAGES;
|
||||
m_dcFilter.pState = m_dcState;
|
||||
m_dcFilter.pCoeffs = DC_FILTER;
|
||||
m_dcFilter.postShift = 0;
|
||||
|
||||
m_rrcFilter.numTaps = RRC_0_2_FILTER_LEN;
|
||||
m_rrcFilter.pState = m_rrcState;
|
||||
m_rrcFilter.pCoeffs = RRC_0_2_FILTER;
|
||||
m_boxcar5Filter.numTaps = BOXCAR5_FILTER_LEN;
|
||||
m_boxcar5Filter.pState = m_boxcar5State;
|
||||
m_boxcar5Filter.pCoeffs = BOXCAR5_FILTER;
|
||||
|
||||
m_gaussianFilter.numTaps = GAUSSIAN_0_5_FILTER_LEN;
|
||||
m_gaussianFilter.pState = m_gaussianState;
|
||||
m_gaussianFilter.pCoeffs = GAUSSIAN_0_5_FILTER;
|
||||
|
||||
m_boxcarFilter.numTaps = BOXCAR_FILTER_LEN;
|
||||
m_boxcarFilter.pState = m_boxcarState;
|
||||
m_boxcarFilter.pCoeffs = BOXCAR_FILTER;
|
||||
|
||||
m_nxdnFilter.numTaps = NXDN_0_2_FILTER_LEN;
|
||||
m_nxdnFilter.pState = m_nxdnState;
|
||||
m_nxdnFilter.pCoeffs = NXDN_0_2_FILTER;
|
||||
|
||||
m_nxdnISincFilter.numTaps = NXDN_ISINC_FILTER_LEN;
|
||||
m_nxdnISincFilter.pState = m_nxdnISincState;
|
||||
m_nxdnISincFilter.pCoeffs = NXDN_ISINC_FILTER;
|
||||
m_boxcar10Filter.numTaps = BOXCAR10_FILTER_LEN;
|
||||
m_boxcar10Filter.pState = m_boxcar10State;
|
||||
m_boxcar10Filter.pCoeffs = BOXCAR10_FILTER;
|
||||
|
||||
initInt();
|
||||
|
||||
@@ -308,54 +268,37 @@ void CIO::process()
|
||||
#endif
|
||||
|
||||
if (m_modemState == STATE_IDLE) {
|
||||
if (m_dstarEnable) {
|
||||
q15_t GMSKVals[RX_BLOCK_SIZE];
|
||||
#if defined(USE_DCBLOCKER)
|
||||
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
|
||||
#else
|
||||
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||
#endif
|
||||
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
if (m_dstarEnable || m_dmrEnable || m_ysfEnable || m_p25Enable) {
|
||||
q15_t vals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
|
||||
|
||||
if (m_p25Enable) {
|
||||
q15_t P25Vals[RX_BLOCK_SIZE];
|
||||
#if defined(USE_DCBLOCKER)
|
||||
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, P25Vals, RX_BLOCK_SIZE);
|
||||
#else
|
||||
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
|
||||
#endif
|
||||
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
if (m_dstarEnable)
|
||||
dstarRX.samples(vals, rssi, RX_BLOCK_SIZE);
|
||||
|
||||
if (m_nxdnEnable) {
|
||||
q15_t NXDNValsTmp[RX_BLOCK_SIZE];
|
||||
#if defined(USE_DCBLOCKER)
|
||||
::arm_fir_fast_q15(&m_nxdnFilter, dcSamples, NXDNValsTmp, RX_BLOCK_SIZE);
|
||||
#else
|
||||
::arm_fir_fast_q15(&m_nxdnFilter, samples, NXDNValsTmp, RX_BLOCK_SIZE);
|
||||
#endif
|
||||
q15_t NXDNVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_nxdnISincFilter, NXDNValsTmp, NXDNVals, RX_BLOCK_SIZE);
|
||||
|
||||
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if (m_dmrEnable || m_ysfEnable) {
|
||||
q15_t RRCVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_rrcFilter, samples, RRCVals, RX_BLOCK_SIZE);
|
||||
if (m_p25Enable)
|
||||
p25RX.samples(vals, rssi, RX_BLOCK_SIZE);
|
||||
|
||||
if (m_ysfEnable)
|
||||
ysfRX.samples(RRCVals, rssi, RX_BLOCK_SIZE);
|
||||
ysfRX.samples(vals, rssi, RX_BLOCK_SIZE);
|
||||
|
||||
if (m_dmrEnable) {
|
||||
if (m_duplex)
|
||||
dmrIdleRX.samples(RRCVals, RX_BLOCK_SIZE);
|
||||
dmrIdleRX.samples(vals, RX_BLOCK_SIZE);
|
||||
else
|
||||
dmrDMORX.samples(RRCVals, rssi, RX_BLOCK_SIZE);
|
||||
dmrDMORX.samples(vals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_nxdnEnable) {
|
||||
q15_t vals[RX_BLOCK_SIZE];
|
||||
#if defined(USE_DCBLOCKER)
|
||||
::arm_fir_fast_q15(&m_boxcar10Filter, dcSamples, vals, RX_BLOCK_SIZE);
|
||||
#else
|
||||
::arm_fir_fast_q15(&m_boxcar10Filter, samples, vals, RX_BLOCK_SIZE);
|
||||
#endif
|
||||
nxdnRX.samples(vals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if (m_fmEnable) {
|
||||
bool cos = getCOSInt();
|
||||
#if defined(USE_DCBLOCKER)
|
||||
@@ -366,61 +309,59 @@ void CIO::process()
|
||||
}
|
||||
} else if (m_modemState == STATE_DSTAR) {
|
||||
if (m_dstarEnable) {
|
||||
q15_t GMSKVals[RX_BLOCK_SIZE];
|
||||
q15_t vals[RX_BLOCK_SIZE];
|
||||
#if defined(USE_DCBLOCKER)
|
||||
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_boxcar5Filter, dcSamples, vals, RX_BLOCK_SIZE);
|
||||
#else
|
||||
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
|
||||
#endif
|
||||
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
|
||||
|
||||
dstarRX.samples(vals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
} else if (m_modemState == STATE_DMR) {
|
||||
if (m_dmrEnable) {
|
||||
q15_t DMRVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_rrcFilter, samples, DMRVals, RX_BLOCK_SIZE);
|
||||
q15_t vals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
|
||||
|
||||
if (m_duplex) {
|
||||
// If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs
|
||||
if (m_tx)
|
||||
dmrRX.samples(DMRVals, rssi, control, RX_BLOCK_SIZE);
|
||||
dmrRX.samples(vals, rssi, control, RX_BLOCK_SIZE);
|
||||
else
|
||||
dmrIdleRX.samples(DMRVals, RX_BLOCK_SIZE);
|
||||
dmrIdleRX.samples(vals, RX_BLOCK_SIZE);
|
||||
} else {
|
||||
dmrDMORX.samples(DMRVals, rssi, RX_BLOCK_SIZE);
|
||||
dmrDMORX.samples(vals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
} else if (m_modemState == STATE_YSF) {
|
||||
if (m_ysfEnable) {
|
||||
q15_t YSFVals[RX_BLOCK_SIZE];
|
||||
q15_t vals[RX_BLOCK_SIZE];
|
||||
#if defined(USE_DCBLOCKER)
|
||||
::arm_fir_fast_q15(&m_rrcFilter, dcSamples, YSFVals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_boxcar5Filter, dcSamples, vals, RX_BLOCK_SIZE);
|
||||
#else
|
||||
::arm_fir_fast_q15(&m_rrcFilter, samples, YSFVals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
|
||||
#endif
|
||||
ysfRX.samples(YSFVals, rssi, RX_BLOCK_SIZE);
|
||||
ysfRX.samples(vals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
} else if (m_modemState == STATE_P25) {
|
||||
if (m_p25Enable) {
|
||||
q15_t P25Vals[RX_BLOCK_SIZE];
|
||||
q15_t vals[RX_BLOCK_SIZE];
|
||||
#if defined(USE_DCBLOCKER)
|
||||
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, P25Vals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_boxcar5Filter, dcSamples, vals, RX_BLOCK_SIZE);
|
||||
#else
|
||||
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
|
||||
#endif
|
||||
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
|
||||
p25RX.samples(vals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
} else if (m_modemState == STATE_NXDN) {
|
||||
} else if (m_modemState == STATE_NXDN) {
|
||||
if (m_nxdnEnable) {
|
||||
q15_t NXDNValsTmp[RX_BLOCK_SIZE];
|
||||
q15_t vals[RX_BLOCK_SIZE];
|
||||
#if defined(USE_DCBLOCKER)
|
||||
::arm_fir_fast_q15(&m_nxdnFilter, dcSamples, NXDNValsTmp, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_boxcar10Filter, dcSamples, vals, RX_BLOCK_SIZE);
|
||||
#else
|
||||
::arm_fir_fast_q15(&m_nxdnFilter, samples, NXDNValsTmp, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_boxcar10Filter, samples, vals, RX_BLOCK_SIZE);
|
||||
#endif
|
||||
q15_t NXDNVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_nxdnISincFilter, NXDNValsTmp, NXDNVals, RX_BLOCK_SIZE);
|
||||
|
||||
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
|
||||
nxdnRX.samples(vals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
} else if (m_modemState == STATE_FM) {
|
||||
bool cos = getCOSInt();
|
||||
@@ -430,10 +371,13 @@ void CIO::process()
|
||||
fm.samples(cos, samples, RX_BLOCK_SIZE);
|
||||
#endif
|
||||
} else if (m_modemState == STATE_DSTARCAL) {
|
||||
q15_t GMSKVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||
|
||||
calDStarRX.samples(GMSKVals, RX_BLOCK_SIZE);
|
||||
q15_t vals[RX_BLOCK_SIZE];
|
||||
#if defined(USE_DCBLOCKER)
|
||||
::arm_fir_fast_q15(&m_boxcar5Filter, dcSamples, vals, RX_BLOCK_SIZE);
|
||||
#else
|
||||
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
|
||||
#endif
|
||||
calDStarRX.samples(vals, RX_BLOCK_SIZE);
|
||||
} else if (m_modemState == STATE_RSSICAL) {
|
||||
calRSSI.samples(rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
@@ -66,16 +66,10 @@ private:
|
||||
arm_biquad_casd_df1_inst_q31 m_dcFilter;
|
||||
q31_t m_dcState[4];
|
||||
|
||||
arm_fir_instance_q15 m_rrcFilter;
|
||||
arm_fir_instance_q15 m_gaussianFilter;
|
||||
arm_fir_instance_q15 m_boxcarFilter;
|
||||
arm_fir_instance_q15 m_nxdnFilter;
|
||||
arm_fir_instance_q15 m_nxdnISincFilter;
|
||||
q15_t m_rrcState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
|
||||
q15_t m_gaussianState[40U]; // NoTaps + BlockSize - 1, 12 + 20 - 1 plus some spare
|
||||
q15_t m_boxcarState[30U]; // NoTaps + BlockSize - 1, 6 + 20 - 1 plus some spare
|
||||
q15_t m_nxdnState[110U]; // NoTaps + BlockSize - 1, 82 + 20 - 1 plus some spare
|
||||
q15_t m_nxdnISincState[60U]; // NoTaps + BlockSize - 1, 32 + 20 - 1 plus some spare
|
||||
arm_fir_instance_q15 m_boxcar5Filter;
|
||||
arm_fir_instance_q15 m_boxcar10Filter;
|
||||
q15_t m_boxcar5State[30U]; // NoTaps + BlockSize - 1, 6 + 20 - 1 plus some spare
|
||||
q15_t m_boxcar10State[40U]; // NoTaps + BlockSize - 1, 10 + 20 - 1 plus some spare
|
||||
|
||||
bool m_pttInvert;
|
||||
q15_t m_rxLevel;
|
||||
|
||||
@@ -155,7 +155,7 @@ LDFLAGS_F722 =-T stm32f722_link.ld $(MCFLAGS_F7) --specs=nosys.specs $(INCLUDES_
|
||||
# Common flags
|
||||
CFLAGS=-Os -ffunction-sections -fdata-sections -fno-builtin -Wno-implicit -DCUSTOM_NEW -DNO_EXCEPTIONS
|
||||
CXXFLAGS=-Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS
|
||||
LDFLAGS=-Os --specs=nano.specs
|
||||
LDFLAGS=-Os --specs=nano.specs -Wl,-Map=bin/mmdvm.map
|
||||
|
||||
# Build Rules
|
||||
.PHONY: all release dis pi pi-f722 f4m nucleo f767 dvm drcc_nqf clean
|
||||
|
||||
+3
-6
@@ -54,7 +54,7 @@ m_poBuffer(),
|
||||
m_poLen(0U),
|
||||
m_poPtr(0U),
|
||||
m_txDelay(240U), // 200ms
|
||||
m_txHang(6000U), // 5s
|
||||
m_txHang(3000U), // 5s
|
||||
m_txCount(0U)
|
||||
{
|
||||
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
|
||||
@@ -72,10 +72,7 @@ m_txCount(0U)
|
||||
|
||||
void CNXDNTX::process()
|
||||
{
|
||||
if (m_buffer.getData() == 0U && m_poLen == 0U && m_txCount == 0U)
|
||||
return;
|
||||
|
||||
if (m_poLen == 0U) {
|
||||
if (m_poLen == 0U && m_buffer.getData() > 0U) {
|
||||
if (!m_tx) {
|
||||
for (uint16_t i = 0U; i < m_txDelay; i++)
|
||||
m_poBuffer[m_poLen++] = NXDN_SYNC;
|
||||
@@ -200,5 +197,5 @@ uint8_t CNXDNTX::getSpace() const
|
||||
|
||||
void CNXDNTX::setParams(uint8_t txHang)
|
||||
{
|
||||
m_txHang = txHang * 1200U;
|
||||
m_txHang = txHang * 600U;
|
||||
}
|
||||
|
||||
@@ -70,10 +70,7 @@ m_txCount(0U)
|
||||
|
||||
void CP25TX::process()
|
||||
{
|
||||
if (m_buffer.getData() == 0U && m_poLen == 0U && m_txCount == 0U)
|
||||
return;
|
||||
|
||||
if (m_poLen == 0U) {
|
||||
if (m_poLen == 0U && m_buffer.getData() > 0U) {
|
||||
if (!m_tx) {
|
||||
for (uint16_t i = 0U; i < m_txDelay; i++)
|
||||
m_poBuffer[m_poLen++] = P25_START_SYNC;
|
||||
|
||||
+2
-3
@@ -103,7 +103,7 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U;
|
||||
#define HW_TYPE "MMDVM"
|
||||
#endif
|
||||
|
||||
#define DESCRIPTION "20200512 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG/FM)"
|
||||
#define DESCRIPTION "20200520 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG/FM)"
|
||||
|
||||
#if defined(GITVERSION)
|
||||
#define concat(h, a, b, c) h " " a " " b " GitID #" c ""
|
||||
@@ -592,8 +592,7 @@ void CSerialPort::process()
|
||||
m_buffer[0U] = c;
|
||||
m_ptr = 1U;
|
||||
m_len = 0U;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
m_ptr = 0U;
|
||||
m_len = 0U;
|
||||
}
|
||||
|
||||
+1
-1
@@ -906,7 +906,7 @@ int CSerialPort::availableForWriteInt(uint8_t n)
|
||||
#if defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER)
|
||||
return AvailForWriteUSART1();
|
||||
#elif defined(DRCC_DVM)
|
||||
AvailForWriteUSART2();
|
||||
return AvailForWriteUSART2();
|
||||
#else
|
||||
return AvailForWriteUART5();
|
||||
#endif
|
||||
|
||||
@@ -66,9 +66,6 @@ m_txCount(0U)
|
||||
|
||||
void CYSFTX::process()
|
||||
{
|
||||
if (m_buffer.getData() == 0U && m_poLen == 0U && m_txCount == 0U)
|
||||
return;
|
||||
|
||||
// If we have YSF data to transmit, do so.
|
||||
if (m_poLen == 0U && m_buffer.getData() > 0U) {
|
||||
if (!m_tx) {
|
||||
@@ -191,4 +188,3 @@ void CYSFTX::setParams(bool on, uint8_t txHang)
|
||||
m_loDev = on;
|
||||
m_txHang = txHang * 1200U;
|
||||
}
|
||||
|
||||
|
||||
+33
-29
@@ -22,36 +22,40 @@
|
||||
/*
|
||||
Pin definitions for DRCC_DVM BG7NQF board rev1
|
||||
|
||||
PTT PB12 output
|
||||
LED_PTT PB4 output
|
||||
LED_COS PB5 output
|
||||
LED_SRV PB10 output
|
||||
COS PB13 input
|
||||
TX/PTT_LED PB12 output
|
||||
RX/COS_LED PB5 output
|
||||
STATUS_LED PB10 output
|
||||
|
||||
DSTAR N/A
|
||||
DMR N/A
|
||||
YSF N/A
|
||||
P25 N/A
|
||||
NXDN N/A
|
||||
POCSAG N/A
|
||||
COS_IN PB13 input
|
||||
|
||||
MDSTAR PB14 output
|
||||
MDMR PB8 output
|
||||
MYSF PB9 output
|
||||
MP25 PB15 output
|
||||
MNXDN N/A
|
||||
MPOCSAG N/A
|
||||
DSTAR N/A
|
||||
DMR N/A
|
||||
YSF N/A
|
||||
P25 N/A
|
||||
NXDN N/A
|
||||
POCSAG N/A
|
||||
|
||||
RX PB0 analog input
|
||||
RSSI PB1 analog input
|
||||
TX PA4 analog output
|
||||
MDMR/BIT0 PB8 output
|
||||
MYSF/BIT1 PB9 output
|
||||
MDSTAR/BIT2 PB14 output
|
||||
MP25/BIT3 PB15 output Generic Mode Pins
|
||||
MNXDN N/A
|
||||
MPOCSAG N/A
|
||||
|
||||
EXT_CLK PA15 input
|
||||
RX PA0 analog input
|
||||
RSSI PA1 analog input
|
||||
TX PA4 analog output
|
||||
|
||||
UART1_TX PA9 output
|
||||
UART1_RX PA10 output
|
||||
UART2_TX PA2 output
|
||||
UART2_RX PA3 output
|
||||
EXT_CLK PA15 input
|
||||
|
||||
UART1_TX PA9 output
|
||||
UART1_RX PA10 output Host Data Communication
|
||||
|
||||
UART2_TX PA2 output
|
||||
UART2_RX PA3 output Nextion Data Communication
|
||||
|
||||
I2C1_SCL PB6 output
|
||||
I2C1_SDA PB7 output OLED Data Communication as master
|
||||
|
||||
*/
|
||||
|
||||
@@ -124,13 +128,13 @@ UART2_RX PA3 output
|
||||
|
||||
#define PIN_RX GPIO_Pin_0
|
||||
#define PIN_RX_CH ADC_Channel_0
|
||||
#define PORT_RX GPIOB
|
||||
#define RCC_Per_RX RCC_AHB1Periph_GPIOB
|
||||
#define PORT_RX GPIOA
|
||||
#define RCC_Per_RX RCC_AHB1Periph_GPIOA
|
||||
|
||||
#define PIN_RSSI GPIO_Pin_1
|
||||
#define PIN_RSSI_CH ADC_Channel_1
|
||||
#define PORT_RSSI GPIOB
|
||||
#define RCC_Per_RSSI RCC_AHB1Periph_GPIOB
|
||||
#define PORT_RSSI GPIOA
|
||||
#define RCC_Per_RSSI RCC_AHB1Periph_GPIOA
|
||||
|
||||
#define PIN_TX GPIO_Pin_4
|
||||
#define PIN_TX_CH DAC_Channel_1
|
||||
|
||||
Reference in New Issue
Block a user