diff --git a/openrtx/include/protocols/M17/M17Demodulator.h b/openrtx/include/protocols/M17/M17Demodulator.h index d794d289..9ea5cce4 100644 --- a/openrtx/include/protocols/M17/M17Demodulator.h +++ b/openrtx/include/protocols/M17/M17Demodulator.h @@ -252,6 +252,11 @@ private: */ int8_t quantize(int32_t offset); + /** + * Compute Hamming Distance between two bytes + */ + uint8_t hammingDistance(uint8_t x, uint8_t y); + }; } /* M17 */ diff --git a/openrtx/src/protocols/M17/M17Demodulator.cpp b/openrtx/src/protocols/M17/M17Demodulator.cpp index 4ac5e6d3..4cf4ebe1 100644 --- a/openrtx/src/protocols/M17/M17Demodulator.cpp +++ b/openrtx/src/protocols/M17/M17Demodulator.cpp @@ -272,6 +272,11 @@ bool M17Demodulator::isFrameLSF() return isLSF; } +uint8_t M17Demodulator::hammingDistance(uint8_t x, uint8_t y) +{ + return __builtin_popcount(x ^ y); +} + void M17Demodulator::update() { M17::sync_t syncword = { 0, false }; @@ -283,6 +288,7 @@ void M17Demodulator::update() FILE *csv_log = fopen("demod_log_2.csv", "a"); #endif + if(baseband.data != NULL) { // Apply RRC on the baseband buffer @@ -342,12 +348,12 @@ void M17Demodulator::update() // printf(" %02X%02X", (*idleFrame)[i], (*idleFrame)[i+1]); //} } - // Check if the decoded syncword matches with frame or lsf sync + // If syncword is not valid, lock is lost, accept 2 bit errors if (frameIndex == M17_SYNCWORD_SYMBOLS && - ((*activeFrame)[0] != stream_syncword_bytes[0] || - (*activeFrame)[1] != stream_syncword_bytes[1]) && - ((*activeFrame)[0] != lsf_syncword_bytes[0] || - (*activeFrame)[1] != lsf_syncword_bytes[1])) + (hammingDistance((*activeFrame)[0], stream_syncword_bytes[0]) + + hammingDistance((*activeFrame)[1], stream_syncword_bytes[1]) > 2) && + (hammingDistance((*activeFrame)[0], lsf_syncword_bytes[0]) + + hammingDistance((*activeFrame)[1], lsf_syncword_bytes[1]) > 2)) { locked = false; std::swap(activeFrame, idleFrame);