mirror of https://github.com/g4klx/MMDVM.git
Update to send and receive the new EOF marker.
This commit is contained in:
parent
7275f65e44
commit
63a8e61a45
16
M17Defines.h
16
M17Defines.h
|
@ -31,9 +31,17 @@ const unsigned int M17_SYNC_LENGTH_BYTES = M17_SYNC_LENGTH_BITS / 8U;
|
|||
const unsigned int M17_SYNC_LENGTH_SYMBOLS = M17_SYNC_LENGTH_BITS / 2U;
|
||||
const unsigned int M17_SYNC_LENGTH_SAMPLES = M17_SYNC_LENGTH_SYMBOLS * M17_RADIO_SYMBOL_LENGTH;
|
||||
|
||||
const unsigned int M17_EOF_LENGTH_BITS = 26U;
|
||||
const unsigned int M17_EOF_LENGTH_BYTES = 4U;
|
||||
const unsigned int M17_EOF_LENGTH_SYMBOLS = M17_EOF_LENGTH_BITS / 2U;
|
||||
const unsigned int M17_EOF_LENGTH_SAMPLES = M17_EOF_LENGTH_SYMBOLS * M17_RADIO_SYMBOL_LENGTH;
|
||||
|
||||
const uint8_t M17_LINK_SETUP_SYNC_BYTES[] = {0x55U, 0xF7U};
|
||||
const uint8_t M17_STREAM_SYNC_BYTES[] = {0xFFU, 0x5DU};
|
||||
|
||||
const uint8_t M17_EOF_MASK[] = {0xFFU, 0xFFU, 0xFFU, 0xC0U};
|
||||
const uint8_t M17_EOF_BYTES[] = {0x55U, 0x7DU, 0x77U, 0x40U};
|
||||
|
||||
const uint16_t M17_LINK_SETUP_SYNC_BITS = 0x55F7U;
|
||||
const uint16_t M17_STREAM_SYNC_BITS = 0xFF5DU;
|
||||
|
||||
|
@ -53,5 +61,13 @@ const int8_t M17_STREAM_SYNC_SYMBOLS_VALUES[] = {-3, -3, -3, -3, +3, +3, -3, +3}
|
|||
|
||||
const uint8_t M17_STREAM_SYNC_SYMBOLS = 0x0DU;
|
||||
|
||||
// 5 5 7 D 7 7 4
|
||||
// 01 01 01 01 01 11 11 01 01 11 01 11 01
|
||||
// +3 +3 +3 +3 +3 -3 -3 +3 +3 -3 +3 -3 +3
|
||||
|
||||
const int8_t M17_EOF_SYMBOLS_VALUES[] = {+3, +3, +3, +3, +3, -3, -3, +3, +3, -3, +3, -3, +3};
|
||||
|
||||
const uint16_t M17_EOF_SYMBOLS = 0x1F35U;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
77
M17RX.cpp
77
M17RX.cpp
|
@ -28,6 +28,7 @@ const q15_t SCALING_FACTOR = 18750; // Q15(0.55)
|
|||
|
||||
const uint8_t MAX_SYNC_BIT_START_ERRS = 0U;
|
||||
const uint8_t MAX_SYNC_BIT_RUN_ERRS = 2U;
|
||||
const uint8_t MAX_EOF_BIT_ERRS = 2U;
|
||||
|
||||
const uint8_t MAX_SYNC_SYMBOL_START_ERRS = 0U;
|
||||
const uint8_t MAX_SYNC_SYMBOL_RUN_ERRS = 1U;
|
||||
|
@ -53,6 +54,8 @@ m_endPtr(NOENDPTR),
|
|||
m_syncPtr(NOENDPTR),
|
||||
m_minSyncPtr(NOENDPTR),
|
||||
m_maxSyncPtr(NOENDPTR),
|
||||
m_minEOFPtr(NOENDPTR),
|
||||
m_maxEOFPtr(NOENDPTR),
|
||||
m_maxCorr(0),
|
||||
m_lostCount(0U),
|
||||
m_countdown(0U),
|
||||
|
@ -79,6 +82,8 @@ void CM17RX::reset()
|
|||
m_syncPtr = NOENDPTR;
|
||||
m_minSyncPtr = NOENDPTR;
|
||||
m_maxSyncPtr = NOENDPTR;
|
||||
m_minEOFPtr = NOENDPTR;
|
||||
m_maxEOFPtr = NOENDPTR;
|
||||
m_centreVal = 0;
|
||||
m_thresholdVal = 0;
|
||||
m_lostCount = 0U;
|
||||
|
@ -157,6 +162,14 @@ void CM17RX::processNone(q15_t sample)
|
|||
if (m_maxSyncPtr >= M17_FRAME_LENGTH_SAMPLES)
|
||||
m_maxSyncPtr -= M17_FRAME_LENGTH_SAMPLES;
|
||||
|
||||
m_minEOFPtr = m_minSyncPtr + M17_EOF_LENGTH_SAMPLES - M17_SYNC_LENGTH_SAMPLES;
|
||||
if (m_minEOFPtr >= M17_FRAME_LENGTH_SAMPLES)
|
||||
m_minEOFPtr -= M17_FRAME_LENGTH_SAMPLES;
|
||||
|
||||
m_maxEOFPtr = m_maxSyncPtr + M17_EOF_LENGTH_SAMPLES - M17_SYNC_LENGTH_SAMPLES;
|
||||
if (m_maxEOFPtr >= M17_FRAME_LENGTH_SAMPLES)
|
||||
m_maxEOFPtr -= M17_FRAME_LENGTH_SAMPLES;
|
||||
|
||||
m_state = m_nextState;
|
||||
m_countdown = 0U;
|
||||
m_nextState = M17RXS_NONE;
|
||||
|
@ -183,6 +196,46 @@ void CM17RX::processData(q15_t sample)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_minEOFPtr < m_maxEOFPtr) {
|
||||
if (m_dataPtr >= m_minEOFPtr && m_dataPtr <= m_maxEOFPtr) {
|
||||
bool ret = detectEOF();
|
||||
if (ret) {
|
||||
DEBUG2("M17RX: eof found pos", m_dataPtr);
|
||||
|
||||
io.setDecode(false);
|
||||
io.setADCDetection(false);
|
||||
|
||||
serial.writeM17EOT();
|
||||
|
||||
m_state = M17RXS_NONE;
|
||||
m_endPtr = NOENDPTR;
|
||||
m_averagePtr = NOAVEPTR;
|
||||
m_countdown = 0U;
|
||||
m_nextState = M17RXS_NONE;
|
||||
m_maxCorr = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_dataPtr >= m_minEOFPtr || m_dataPtr <= m_maxEOFPtr) {
|
||||
bool ret = detectEOF();
|
||||
if (ret) {
|
||||
DEBUG2("M17RX: eof found pos", m_dataPtr);
|
||||
|
||||
io.setDecode(false);
|
||||
io.setADCDetection(false);
|
||||
|
||||
serial.writeM17EOT();
|
||||
|
||||
m_state = M17RXS_NONE;
|
||||
m_endPtr = NOENDPTR;
|
||||
m_averagePtr = NOAVEPTR;
|
||||
m_countdown = 0U;
|
||||
m_nextState = M17RXS_NONE;
|
||||
m_maxCorr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_dataPtr == m_endPtr) {
|
||||
// Only update the centre and threshold if they are from a good sync
|
||||
if (m_lostCount == MAX_SYNC_FRAMES) {
|
||||
|
@ -193,6 +246,14 @@ void CM17RX::processData(q15_t sample)
|
|||
m_maxSyncPtr = m_syncPtr + 1U;
|
||||
if (m_maxSyncPtr >= M17_FRAME_LENGTH_SAMPLES)
|
||||
m_maxSyncPtr -= M17_FRAME_LENGTH_SAMPLES;
|
||||
|
||||
m_minEOFPtr = m_minSyncPtr + M17_EOF_LENGTH_SAMPLES - M17_SYNC_LENGTH_SAMPLES;
|
||||
if (m_minEOFPtr >= M17_FRAME_LENGTH_SAMPLES)
|
||||
m_minEOFPtr -= M17_FRAME_LENGTH_SAMPLES;
|
||||
|
||||
m_maxEOFPtr = m_maxSyncPtr + M17_EOF_LENGTH_SAMPLES - M17_SYNC_LENGTH_SAMPLES;
|
||||
if (m_maxEOFPtr >= M17_FRAME_LENGTH_SAMPLES)
|
||||
m_maxEOFPtr -= M17_FRAME_LENGTH_SAMPLES;
|
||||
}
|
||||
|
||||
calculateLevels(m_startPtr, M17_FRAME_LENGTH_SYMBOLS);
|
||||
|
@ -324,6 +385,22 @@ bool CM17RX::correlateSync(uint8_t syncSymbols, const int8_t* syncSymbolValues,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CM17RX::detectEOF()
|
||||
{
|
||||
uint16_t startPtr = m_dataPtr + M17_FRAME_LENGTH_SAMPLES - M17_EOF_LENGTH_SAMPLES + M17_RADIO_SYMBOL_LENGTH;
|
||||
if (startPtr >= M17_FRAME_LENGTH_SAMPLES)
|
||||
startPtr -= M17_FRAME_LENGTH_SAMPLES;
|
||||
|
||||
uint8_t eof[M17_EOF_LENGTH_BYTES];
|
||||
samplesToBits(startPtr, M17_EOF_LENGTH_SYMBOLS, eof, 0U, m_centreVal, m_thresholdVal);
|
||||
|
||||
uint8_t errs = 0U;
|
||||
for (uint8_t i = 0U; i < M17_EOF_LENGTH_BYTES; i++)
|
||||
errs += countBits8((eof[i] ^ M17_EOF_BYTES[i]) & M17_EOF_MASK[i]);
|
||||
|
||||
return errs <= MAX_EOF_BIT_ERRS;
|
||||
}
|
||||
|
||||
void CM17RX::calculateLevels(uint16_t start, uint16_t count)
|
||||
{
|
||||
q15_t maxPos = -16000;
|
||||
|
|
3
M17RX.h
3
M17RX.h
|
@ -50,6 +50,8 @@ private:
|
|||
uint16_t m_syncPtr;
|
||||
uint16_t m_minSyncPtr;
|
||||
uint16_t m_maxSyncPtr;
|
||||
uint16_t m_minEOFPtr;
|
||||
uint16_t m_maxEOFPtr;
|
||||
q31_t m_maxCorr;
|
||||
uint16_t m_lostCount;
|
||||
uint8_t m_countdown;
|
||||
|
@ -65,6 +67,7 @@ private:
|
|||
void processNone(q15_t sample);
|
||||
void processData(q15_t sample);
|
||||
bool correlateSync(uint8_t syncSymbols, const int8_t* syncSymbolValues, const uint8_t* syncBytes, uint8_t maxSymbolErrs, uint8_t maxBitErrs);
|
||||
bool detectEOF();
|
||||
void calculateLevels(uint16_t start, uint16_t count);
|
||||
void samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
|
||||
void writeRSSILinkSetup(uint8_t* data);
|
||||
|
|
29
M17TX.cpp
29
M17TX.cpp
|
@ -114,7 +114,7 @@ void CM17TX::process()
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t CM17TX::writeData(const uint8_t* data, uint8_t length)
|
||||
uint8_t CM17TX::writeHeader(const uint8_t* data, uint8_t length)
|
||||
{
|
||||
if (length != (M17_FRAME_LENGTH_BYTES + 1U))
|
||||
return 4U;
|
||||
|
@ -129,6 +129,33 @@ uint8_t CM17TX::writeData(const uint8_t* data, uint8_t length)
|
|||
return 0U;
|
||||
}
|
||||
|
||||
uint8_t CM17TX::writeStream(const uint8_t* data, uint8_t length)
|
||||
{
|
||||
if (length != (M17_FRAME_LENGTH_BYTES + 1U))
|
||||
return 4U;
|
||||
|
||||
uint16_t space = m_buffer.getSpace();
|
||||
if (space < M17_FRAME_LENGTH_BYTES)
|
||||
return 5U;
|
||||
|
||||
for (uint8_t i = 0U; i < M17_FRAME_LENGTH_BYTES; i++)
|
||||
m_buffer.put(data[i + 1U]);
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
uint8_t CM17TX::writeEOT()
|
||||
{
|
||||
uint16_t space = m_buffer.getSpace();
|
||||
if (space < M17_EOF_LENGTH_BYTES)
|
||||
return 5U;
|
||||
|
||||
for (uint8_t i = 0U; i < M17_EOF_LENGTH_BYTES; i++)
|
||||
m_buffer.put(M17_EOF_BYTES[i]);
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
void CM17TX::writeByte(uint8_t c)
|
||||
{
|
||||
q15_t inBuffer[4U];
|
||||
|
|
4
M17TX.h
4
M17TX.h
|
@ -29,7 +29,9 @@ class CM17TX {
|
|||
public:
|
||||
CM17TX();
|
||||
|
||||
uint8_t writeData(const uint8_t* data, uint8_t length);
|
||||
uint8_t writeHeader(const uint8_t* data, uint8_t length);
|
||||
uint8_t writeStream(const uint8_t* data, uint8_t length);
|
||||
uint8_t writeEOT();
|
||||
|
||||
void process();
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ const uint8_t MMDVM_M17_LINK_SETUP = 0x45U;
|
|||
const uint8_t MMDVM_M17_STREAM = 0x46U;
|
||||
const uint8_t MMDVM_M17_PACKET = 0x47U;
|
||||
const uint8_t MMDVM_M17_LOST = 0x48U;
|
||||
const uint8_t MMDVM_M17_EOT = 0x49U;
|
||||
|
||||
const uint8_t MMDVM_POCSAG_DATA = 0x50U;
|
||||
|
||||
|
@ -1305,7 +1306,7 @@ void CSerialPort::processMessage(uint8_t type, const uint8_t* buffer, uint16_t l
|
|||
case MMDVM_M17_LINK_SETUP:
|
||||
if (m_m17Enable) {
|
||||
if (m_modemState == STATE_IDLE || m_modemState == STATE_M17)
|
||||
err = m17TX.writeData(buffer, length);
|
||||
err = m17TX.writeHeader(buffer, length);
|
||||
}
|
||||
if (err == 0U) {
|
||||
if (m_modemState == STATE_IDLE)
|
||||
|
@ -1319,7 +1320,7 @@ void CSerialPort::processMessage(uint8_t type, const uint8_t* buffer, uint16_t l
|
|||
case MMDVM_M17_STREAM:
|
||||
if (m_m17Enable) {
|
||||
if (m_modemState == STATE_IDLE || m_modemState == STATE_M17)
|
||||
err = m17TX.writeData(buffer, length);
|
||||
err = m17TX.writeStream(buffer, length);
|
||||
}
|
||||
if (err == 0U) {
|
||||
if (m_modemState == STATE_IDLE)
|
||||
|
@ -1329,6 +1330,20 @@ void CSerialPort::processMessage(uint8_t type, const uint8_t* buffer, uint16_t l
|
|||
sendNAK(type, err);
|
||||
}
|
||||
break;
|
||||
|
||||
case MMDVM_M17_EOT:
|
||||
if (m_m17Enable) {
|
||||
if (m_modemState == STATE_IDLE || m_modemState == STATE_M17)
|
||||
err = m17TX.writeEOT();
|
||||
}
|
||||
if (err == 0U) {
|
||||
if (m_modemState == STATE_IDLE)
|
||||
setMode(STATE_M17);
|
||||
} else {
|
||||
DEBUG2("Received invalid M17 EOT", err);
|
||||
sendNAK(type, err);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(MODE_POCSAG)
|
||||
|
@ -1726,6 +1741,23 @@ void CSerialPort::writeM17Stream(const uint8_t* data, uint8_t length)
|
|||
writeInt(1U, reply, count);
|
||||
}
|
||||
|
||||
void CSerialPort::writeM17EOT()
|
||||
{
|
||||
if (m_modemState != STATE_M17 && m_modemState != STATE_IDLE)
|
||||
return;
|
||||
|
||||
if (!m_m17Enable)
|
||||
return;
|
||||
|
||||
uint8_t reply[3U];
|
||||
|
||||
reply[0U] = MMDVM_FRAME_START;
|
||||
reply[1U] = 3U;
|
||||
reply[2U] = MMDVM_M17_EOT;
|
||||
|
||||
writeInt(1U, reply, 3);
|
||||
}
|
||||
|
||||
void CSerialPort::writeM17Lost()
|
||||
{
|
||||
if (m_modemState != STATE_M17 && m_modemState != STATE_IDLE)
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
void writeM17LinkSetup(const uint8_t* data, uint8_t length);
|
||||
void writeM17Stream(const uint8_t* data, uint8_t length);
|
||||
void writeM17Lost();
|
||||
void writeM17EOT();
|
||||
#endif
|
||||
|
||||
#if defined(MODE_AX25)
|
||||
|
|
Loading…
Reference in New Issue