From 63a8e61a454644e37d23d9e02f3076882deade21 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 25 Aug 2021 21:11:09 +0100 Subject: [PATCH] Update to send and receive the new EOF marker. --- M17Defines.h | 16 +++++++++++ M17RX.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ M17RX.h | 3 ++ M17TX.cpp | 29 ++++++++++++++++++- M17TX.h | 4 ++- SerialPort.cpp | 36 +++++++++++++++++++++-- SerialPort.h | 1 + Version.h | 2 +- 8 files changed, 163 insertions(+), 5 deletions(-) diff --git a/M17Defines.h b/M17Defines.h index 0459b69..8f870e9 100644 --- a/M17Defines.h +++ b/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 diff --git a/M17RX.cpp b/M17RX.cpp index 15fc643..fcf71c9 100644 --- a/M17RX.cpp +++ b/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; diff --git a/M17RX.h b/M17RX.h index de6ed6d..b4a9048 100644 --- a/M17RX.h +++ b/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); diff --git a/M17TX.cpp b/M17TX.cpp index eb19833..6129623 100644 --- a/M17TX.cpp +++ b/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]; diff --git a/M17TX.h b/M17TX.h index 850fcf1..c7db314 100644 --- a/M17TX.h +++ b/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(); diff --git a/SerialPort.cpp b/SerialPort.cpp index 6eb6043..8442320 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -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) diff --git a/SerialPort.h b/SerialPort.h index 5a309e7..c013a7f 100644 --- a/SerialPort.h +++ b/SerialPort.h @@ -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) diff --git a/Version.h b/Version.h index 5a3bb77..49872f5 100644 --- a/Version.h +++ b/Version.h @@ -19,7 +19,7 @@ #if !defined(VERSION_H) #define VERSION_H -#define VERSION "20210823" +#define VERSION "20210825" #endif