From bc6c6509732e6e6f1b2144dfedb4a9020b08fbf3 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 12 Feb 2017 18:44:45 +0000 Subject: [PATCH] Improve YSF and P25 receive BER. --- P25RX.cpp | 181 +++++++++++++++++++++++++++++------------------------- P25RX.h | 3 +- YSFRX.cpp | 149 +++++++++++++++++++++++++++----------------- YSFRX.h | 3 +- 4 files changed, 192 insertions(+), 144 deletions(-) diff --git a/P25RX.cpp b/P25RX.cpp index 49509f5..c032668 100644 --- a/P25RX.cpp +++ b/P25RX.cpp @@ -25,7 +25,7 @@ #include "P25RX.h" #include "Utils.h" -const q15_t SCALING_FACTOR = 18750; // Q15(0.55) +const q15_t SCALING_FACTOR = 18750; // Q15(0.57) const uint8_t MAX_SYNC_BIT_START_ERRS = 2U; const uint8_t MAX_SYNC_BIT_RUN_ERRS = 4U; @@ -36,6 +36,8 @@ const uint8_t BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x0 #define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) +const uint8_t NOAVEPTR = 99U; + const uint16_t NOENDPTR = 9999U; const unsigned int MAX_SYNC_FRAMES = 4U + 1U; @@ -58,11 +60,9 @@ m_lostCount(0U), m_countdown(0U), m_centre(), m_centreVal(0), -m_centreBest(0), m_threshold(), m_thresholdVal(0), -m_thresholdBest(0), -m_averagePtr(0u), +m_averagePtr(NOAVEPTR), m_rssiAccum(0U), m_rssiCount(0U) { @@ -74,7 +74,7 @@ void CP25RX::reset() m_dataPtr = 0U; m_bitPtr = 0U; m_maxCorr = 0; - m_averagePtr = 0U; + m_averagePtr = NOAVEPTR; m_hdrStartPtr = NOENDPTR; m_lduStartPtr = NOENDPTR; m_lduEndPtr = NOENDPTR; @@ -138,6 +138,8 @@ void CP25RX::processNone(q15_t sample) io.setDecode(true); io.setADCDetection(true); + m_averagePtr = NOAVEPTR; + m_countdown = 5U; } } @@ -146,15 +148,6 @@ void CP25RX::processNone(q15_t sample) m_countdown--; if (m_countdown == 1U) { - for (uint8_t i = 0U; i < 16U; i++) { - m_centre[i] = m_centreBest; - m_threshold[i] = m_thresholdBest; - } - - m_centreVal = m_centreBest; - m_thresholdVal = m_thresholdBest; - m_averagePtr = 0U; - // These are the sync positions for the following LDU after a HDR m_minSyncPtr = m_hdrSyncPtr + P25_HDR_FRAME_LENGTH_SAMPLES - 1U; if (m_minSyncPtr >= P25_LDU_FRAME_LENGTH_SAMPLES) @@ -180,34 +173,9 @@ void CP25RX::processHdr(q15_t sample) } if (m_dataPtr == m_maxSyncPtr) { - bool isSync = false; - if (m_minSyncPtr < m_maxSyncPtr) { - if (m_lduSyncPtr >= m_minSyncPtr && m_lduSyncPtr <= m_maxSyncPtr) - isSync = true; - } else { - if (m_lduSyncPtr >= m_minSyncPtr || m_lduSyncPtr <= m_maxSyncPtr) - isSync = true; - } + if (m_hdrSyncPtr != m_lduSyncPtr) { + calculateLevels(m_hdrStartPtr, P25_HDR_FRAME_LENGTH_SYMBOLS); - if (isSync) { - m_threshold[m_averagePtr] = m_thresholdBest; - m_centre[m_averagePtr] = m_centreBest; - - m_averagePtr++; - if (m_averagePtr >= 16U) - m_averagePtr = 0U; - - // Find the average centre and threshold values - m_centreVal = 0; - m_thresholdVal = 0; - for (uint8_t i = 0U; i < 16U; i++) { - m_centreVal += m_centre[i]; - m_thresholdVal += m_threshold[i]; - } - m_centreVal >>= 4; - m_thresholdVal >>= 4; - - DEBUG4("P25RX: sync found in Hdr (best) pos/centre/threshold", m_hdrSyncPtr, m_centreBest, m_thresholdBest); DEBUG4("P25RX: sync found in Hdr pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal); uint8_t frame[P25_HDR_FRAME_LENGTH_BYTES + 1U]; @@ -246,26 +214,6 @@ void CP25RX::processLdu(q15_t sample) if (m_dataPtr == m_lduEndPtr) { // Only update the centre and threshold if they are from a good sync if (m_lostCount == MAX_SYNC_FRAMES) { - m_threshold[m_averagePtr] = m_thresholdBest; - m_centre[m_averagePtr] = m_centreBest; - - m_averagePtr++; - if (m_averagePtr >= 16U) - m_averagePtr = 0U; - - // Find the average centre and threshold values - m_centreVal = 0; - m_thresholdVal = 0; - for (uint8_t i = 0U; i < 16U; i++) { - m_centreVal += m_centre[i]; - m_thresholdVal += m_threshold[i]; - } - m_centreVal >>= 4; - m_thresholdVal >>= 4; - - DEBUG4("P25RX: sync found in Ldu (best) pos/centre/threshold", m_lduSyncPtr, m_centreBest, m_thresholdBest); - DEBUG4("P25RX: sync found in Ldu pos/centre/threshold", m_lduSyncPtr, m_centreVal, m_thresholdVal); - m_minSyncPtr = m_lduSyncPtr + P25_LDU_FRAME_LENGTH_SAMPLES - 1U; if (m_minSyncPtr >= P25_LDU_FRAME_LENGTH_SAMPLES) m_minSyncPtr -= P25_LDU_FRAME_LENGTH_SAMPLES; @@ -275,6 +223,10 @@ void CP25RX::processLdu(q15_t sample) m_maxSyncPtr -= P25_LDU_FRAME_LENGTH_SAMPLES; } + calculateLevels(m_lduStartPtr, P25_LDU_FRAME_LENGTH_SYMBOLS); + + DEBUG4("P25RX: sync found in Ldu pos/centre/threshold", m_lduSyncPtr, m_centreVal, m_thresholdVal); + uint8_t frame[P25_LDU_FRAME_LENGTH_BYTES + 3U]; samplesToBits(m_lduStartPtr, P25_LDU_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal); #if defined(DUMP_SAMPLES) @@ -291,9 +243,11 @@ void CP25RX::processLdu(q15_t sample) serial.writeP25Lost(); - m_state = P25RXS_NONE; - m_lduEndPtr = NOENDPTR; - m_maxCorr = 0; + m_state = P25RXS_NONE; + m_lduEndPtr = NOENDPTR; + m_averagePtr = NOAVEPTR; + m_countdown = 0U; + m_maxCorr = 0; } else { frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; @@ -312,8 +266,8 @@ bool CP25RX::correlateSync() ptr -= P25_LDU_FRAME_LENGTH_SAMPLES; q31_t corr = 0; + q15_t min = 16000; q15_t max = -16000; - q15_t min = 16000; for (uint8_t i = 0U; i < P25_SYNC_LENGTH_SYMBOLS; i++) { q15_t val = m_buffer[ptr]; @@ -344,40 +298,38 @@ bool CP25RX::correlateSync() } if (corr > m_maxCorr) { - q15_t centre = (max + min) >> 1; + if (m_averagePtr == NOAVEPTR) { + m_centreVal = (max + min) >> 1; - q31_t v1 = (max - centre) * SCALING_FACTOR; - q15_t threshold = q15_t(v1 >> 15); - - uint8_t sync[P25_SYNC_BYTES_LENGTH]; + q31_t v1 = (max - m_centreVal) * SCALING_FACTOR; + m_thresholdVal = q15_t(v1 >> 15); + } uint16_t startPtr = m_dataPtr + P25_LDU_FRAME_LENGTH_SAMPLES - P25_SYNC_LENGTH_SAMPLES + P25_RADIO_SYMBOL_LENGTH; if (startPtr >= P25_LDU_FRAME_LENGTH_SAMPLES) startPtr -= P25_LDU_FRAME_LENGTH_SAMPLES; + uint8_t sync[P25_SYNC_BYTES_LENGTH]; + samplesToBits(startPtr, P25_SYNC_LENGTH_SYMBOLS, sync, 0U, m_centreVal, m_thresholdVal); + uint8_t maxErrs; - if (m_state == P25RXS_NONE) { - samplesToBits(startPtr, P25_SYNC_LENGTH_SYMBOLS, sync, 0U, centre, threshold); + if (m_state == P25RXS_NONE) maxErrs = MAX_SYNC_BIT_START_ERRS; - } else { - samplesToBits(startPtr, P25_SYNC_LENGTH_SYMBOLS, sync, 0U, m_centreVal, m_thresholdVal); + else maxErrs = MAX_SYNC_BIT_RUN_ERRS; - } uint8_t errs = 0U; for (uint8_t i = 0U; i < P25_SYNC_BYTES_LENGTH; i++) errs += countBits8(sync[i] ^ P25_SYNC_BYTES[i]); if (errs <= maxErrs) { - m_maxCorr = corr; - m_thresholdBest = threshold; - m_centreBest = centre; - m_lostCount = MAX_SYNC_FRAMES; + m_maxCorr = corr; + m_lostCount = MAX_SYNC_FRAMES; - m_lduSyncPtr = m_dataPtr; + m_lduSyncPtr = m_dataPtr; // These are the positions of the start and end of an LDU - m_lduStartPtr = startPtr; + m_lduStartPtr = startPtr; m_lduEndPtr = m_dataPtr + P25_LDU_FRAME_LENGTH_SAMPLES - P25_SYNC_LENGTH_SAMPLES - 1U; if (m_lduEndPtr >= P25_LDU_FRAME_LENGTH_SAMPLES) @@ -407,6 +359,70 @@ bool CP25RX::correlateSync() return false; } +void CP25RX::calculateLevels(uint16_t start, uint16_t count) +{ + q15_t maxPos = -16000; + q15_t minPos = 16000; + q15_t maxNeg = 16000; + q15_t minNeg = -16000; + + for (uint16_t i = 0U; i < count; i++) { + q15_t sample = m_buffer[start]; + + if (sample > 0) { + if (sample > maxPos) + maxPos = sample; + if (sample < minPos) + minPos = sample; + } else { + if (sample < maxNeg) + maxNeg = sample; + if (sample > minNeg) + minNeg = sample; + } + + start += P25_RADIO_SYMBOL_LENGTH; + if (start >= P25_LDU_FRAME_LENGTH_SAMPLES) + start -= P25_LDU_FRAME_LENGTH_SAMPLES; + } + + q15_t posThresh = (maxPos + minPos) >> 1; + q15_t negThresh = (maxNeg + minNeg) >> 1; + + q15_t centre = (posThresh + negThresh) >> 1; + + q15_t threshold = posThresh - centre; + + DEBUG5("P25RX: pos/neg/centre/threshold", posThresh, negThresh, centre, threshold); + + if (m_averagePtr == NOAVEPTR) { + for (uint8_t i = 0U; i < 16U; i++) { + m_centre[i] = centre; + m_threshold[i] = threshold; + } + + m_averagePtr = 0U; + } else { + m_centre[m_averagePtr] = centre; + m_threshold[m_averagePtr] = threshold; + + m_averagePtr++; + if (m_averagePtr >= 16U) + m_averagePtr = 0U; + } + + m_centreVal = 0; + m_thresholdVal = 0; + + for (uint8_t i = 0U; i < 16U; i++) { + m_centreVal += m_centre[i]; + m_thresholdVal += m_threshold[i]; + } + + m_centreVal >>= 4; + m_thresholdVal >>= 4; +} + void CP25RX::samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold) { for (uint16_t i = 0U; i < count; i++) { @@ -467,9 +483,6 @@ void CP25RX::writeSync(uint16_t start) q15_t sync[P25_SYNC_LENGTH_SYMBOLS]; for (uint16_t i = 0U; i < P25_SYNC_LENGTH_SYMBOLS; i++) { - if (i == (P25_SYNC_LENGTH_SYMBOLS - 1U)) - DEBUG4("P25RX: sync1/sync2/start", m_hdrSyncPtr, m_lduSyncPtr, start); - sync[i] = m_buffer[start]; start += P25_RADIO_SYMBOL_LENGTH; diff --git a/P25RX.h b/P25RX.h index 9dd0c08..a34965b 100644 --- a/P25RX.h +++ b/P25RX.h @@ -54,10 +54,8 @@ private: uint8_t m_countdown; q15_t m_centre[16U]; q15_t m_centreVal; - q15_t m_centreBest; q15_t m_threshold[16U]; q15_t m_thresholdVal; - q15_t m_thresholdBest; uint8_t m_averagePtr; uint32_t m_rssiAccum; uint16_t m_rssiCount; @@ -66,6 +64,7 @@ private: void processHdr(q15_t sample); void processLdu(q15_t sample); bool correlateSync(); + 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 writeRSSILdu(uint8_t* ldu); void writeSync(uint16_t start); diff --git a/YSFRX.cpp b/YSFRX.cpp index e81cfc5..d20cd68 100644 --- a/YSFRX.cpp +++ b/YSFRX.cpp @@ -36,6 +36,8 @@ const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02 #define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) +const uint8_t NOAVEPTR = 99U; + const uint16_t NOENDPTR = 9999U; const unsigned int MAX_SYNC_FRAMES = 4U + 1U; @@ -56,11 +58,9 @@ m_lostCount(0U), m_countdown(0U), m_centre(), m_centreVal(0), -m_centreBest(0), m_threshold(), m_thresholdVal(0), -m_thresholdBest(0), -m_averagePtr(0u), +m_averagePtr(NOAVEPTR), m_rssiAccum(0U), m_rssiCount(0U) { @@ -72,7 +72,7 @@ void CYSFRX::reset() m_dataPtr = 0U; m_bitPtr = 0U; m_maxCorr = 0; - m_averagePtr = 0U; + m_averagePtr = NOAVEPTR; m_startPtr = NOENDPTR; m_endPtr = NOENDPTR; m_syncPtr = NOENDPTR; @@ -131,6 +131,8 @@ void CYSFRX::processNone(q15_t sample) io.setDecode(true); io.setADCDetection(true); + m_averagePtr = NOAVEPTR; + m_countdown = 5U; } } @@ -139,15 +141,6 @@ void CYSFRX::processNone(q15_t sample) m_countdown--; if (m_countdown == 1U) { - for (uint8_t i = 0U; i < 16U; i++) { - m_centre[i] = m_centreBest; - m_threshold[i] = m_thresholdBest; - } - - m_centreVal = m_centreBest; - m_thresholdVal = m_thresholdBest; - m_averagePtr = 0U; - m_minSyncPtr = m_syncPtr + YSF_FRAME_LENGTH_SAMPLES - 1U; if (m_minSyncPtr >= YSF_FRAME_LENGTH_SAMPLES) m_minSyncPtr -= YSF_FRAME_LENGTH_SAMPLES; @@ -174,26 +167,6 @@ void CYSFRX::processData(q15_t sample) if (m_dataPtr == m_endPtr) { // Only update the centre and threshold if they are from a good sync if (m_lostCount == MAX_SYNC_FRAMES) { - m_threshold[m_averagePtr] = m_thresholdBest; - m_centre[m_averagePtr] = m_centreBest; - - m_averagePtr++; - if (m_averagePtr >= 16U) - m_averagePtr = 0U; - - // Find the average centre and threshold values - m_centreVal = 0; - m_thresholdVal = 0; - for (uint8_t i = 0U; i < 16U; i++) { - m_centreVal += m_centre[i]; - m_thresholdVal += m_threshold[i]; - } - m_centreVal >>= 4; - m_thresholdVal >>= 4; - - DEBUG4("YSFRX: sync found (best) pos/centre/threshold", m_syncPtr, m_centreBest, m_thresholdBest); - DEBUG4("YSFRX: sync found pos/centre/threshold", m_syncPtr, m_centreVal, m_thresholdVal); - m_minSyncPtr = m_syncPtr + YSF_FRAME_LENGTH_SAMPLES - 1U; if (m_minSyncPtr >= YSF_FRAME_LENGTH_SAMPLES) m_minSyncPtr -= YSF_FRAME_LENGTH_SAMPLES; @@ -203,6 +176,10 @@ void CYSFRX::processData(q15_t sample) m_maxSyncPtr -= YSF_FRAME_LENGTH_SAMPLES; } + calculateLevels(m_startPtr, YSF_FRAME_LENGTH_SYMBOLS); + + DEBUG4("YSFRX: sync found pos/centre/threshold", m_syncPtr, m_centreVal, m_thresholdVal); + uint8_t frame[YSF_FRAME_LENGTH_BYTES + 3U]; samplesToBits(m_startPtr, YSF_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal); #if defined(DUMP_SAMPLES) @@ -219,10 +196,11 @@ void CYSFRX::processData(q15_t sample) serial.writeYSFLost(); - m_state = YSFRXS_NONE; - m_endPtr = NOENDPTR; - m_countdown = 0U; - m_maxCorr = 0; + m_state = YSFRXS_NONE; + m_endPtr = NOENDPTR; + m_averagePtr = NOAVEPTR; + m_countdown = 0U; + m_maxCorr = 0; } else { frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; @@ -241,8 +219,8 @@ bool CYSFRX::correlateSync() ptr -= YSF_FRAME_LENGTH_SAMPLES; q31_t corr = 0; + q15_t min = 16000; q15_t max = -16000; - q15_t min = 16000; for (uint8_t i = 0U; i < YSF_SYNC_LENGTH_SYMBOLS; i++) { q15_t val = m_buffer[ptr]; @@ -273,36 +251,34 @@ bool CYSFRX::correlateSync() } if (corr > m_maxCorr) { - q15_t centre = (max + min) >> 1; + if (m_averagePtr == NOAVEPTR) { + m_centreVal = (max + min) >> 1; - q31_t v1 = (max - centre) * SCALING_FACTOR; - q15_t threshold = q15_t(v1 >> 15); - - uint8_t sync[YSF_SYNC_BYTES_LENGTH]; + q31_t v1 = (max - m_centreVal) * SCALING_FACTOR; + m_thresholdVal = q15_t(v1 >> 15); + } uint16_t startPtr = m_dataPtr + YSF_FRAME_LENGTH_SAMPLES - YSF_SYNC_LENGTH_SAMPLES + YSF_RADIO_SYMBOL_LENGTH; if (startPtr >= YSF_FRAME_LENGTH_SAMPLES) startPtr -= YSF_FRAME_LENGTH_SAMPLES; + uint8_t sync[YSF_SYNC_BYTES_LENGTH]; + samplesToBits(startPtr, YSF_SYNC_LENGTH_SYMBOLS, sync, 0U, m_centreVal, m_thresholdVal); + uint8_t maxErrs; - if (m_state == YSFRXS_NONE) { - samplesToBits(startPtr, YSF_SYNC_LENGTH_SYMBOLS, sync, 0U, centre, threshold); + if (m_state == YSFRXS_NONE) maxErrs = MAX_SYNC_BIT_START_ERRS; - } else { - samplesToBits(startPtr, YSF_SYNC_LENGTH_SYMBOLS, sync, 0U, m_centreVal, m_thresholdVal); + else maxErrs = MAX_SYNC_BIT_RUN_ERRS; - } uint8_t errs = 0U; for (uint8_t i = 0U; i < YSF_SYNC_BYTES_LENGTH; i++) errs += countBits8(sync[i] ^ YSF_SYNC_BYTES[i]); if (errs <= maxErrs) { - m_maxCorr = corr; - m_thresholdBest = threshold; - m_centreBest = centre; - m_lostCount = MAX_SYNC_FRAMES; - m_syncPtr = m_dataPtr; + m_maxCorr = corr; + m_lostCount = MAX_SYNC_FRAMES; + m_syncPtr = m_dataPtr; m_startPtr = startPtr; @@ -318,6 +294,70 @@ bool CYSFRX::correlateSync() return false; } +void CYSFRX::calculateLevels(uint16_t start, uint16_t count) +{ + q15_t maxPos = -16000; + q15_t minPos = 16000; + q15_t maxNeg = 16000; + q15_t minNeg = -16000; + + for (uint16_t i = 0U; i < count; i++) { + q15_t sample = m_buffer[start]; + + if (sample > 0) { + if (sample > maxPos) + maxPos = sample; + if (sample < minPos) + minPos = sample; + } else { + if (sample < maxNeg) + maxNeg = sample; + if (sample > minNeg) + minNeg = sample; + } + + start += YSF_RADIO_SYMBOL_LENGTH; + if (start >= YSF_FRAME_LENGTH_SAMPLES) + start -= YSF_FRAME_LENGTH_SAMPLES; + } + + q15_t posThresh = (maxPos + minPos) >> 1; + q15_t negThresh = (maxNeg + minNeg) >> 1; + + q15_t centre = (posThresh + negThresh) >> 1; + + q15_t threshold = posThresh - centre; + + DEBUG5("YSFRX: pos/neg/centre/threshold", posThresh, negThresh, centre, threshold); + + if (m_averagePtr == NOAVEPTR) { + for (uint8_t i = 0U; i < 16U; i++) { + m_centre[i] = centre; + m_threshold[i] = threshold; + } + + m_averagePtr = 0U; + } else { + m_centre[m_averagePtr] = centre; + m_threshold[m_averagePtr] = threshold; + + m_averagePtr++; + if (m_averagePtr >= 16U) + m_averagePtr = 0U; + } + + m_centreVal = 0; + m_thresholdVal = 0; + + for (uint8_t i = 0U; i < 16U; i++) { + m_centreVal += m_centre[i]; + m_thresholdVal += m_threshold[i]; + } + + m_centreVal >>= 4; + m_thresholdVal >>= 4; +} + void CYSFRX::samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold) { for (uint16_t i = 0U; i < count; i++) { @@ -378,9 +418,6 @@ void CYSFRX::writeSync(uint16_t start) q15_t sync[YSF_SYNC_LENGTH_SYMBOLS]; for (uint16_t i = 0U; i < YSF_SYNC_LENGTH_SYMBOLS; i++) { - if (i == (YSF_SYNC_LENGTH_SYMBOLS - 1U)) - DEBUG3("YSFRX: sync/start", m_syncPtr, start); - sync[i] = m_buffer[start]; start += YSF_RADIO_SYMBOL_LENGTH; diff --git a/YSFRX.h b/YSFRX.h index 9e5d48d..870daab 100644 --- a/YSFRX.h +++ b/YSFRX.h @@ -51,10 +51,8 @@ private: uint8_t m_countdown; q15_t m_centre[16U]; q15_t m_centreVal; - q15_t m_centreBest; q15_t m_threshold[16U]; q15_t m_thresholdVal; - q15_t m_thresholdBest; uint8_t m_averagePtr; uint32_t m_rssiAccum; uint16_t m_rssiCount; @@ -62,6 +60,7 @@ private: void processNone(q15_t sample); void processData(q15_t sample); bool correlateSync(); + 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 writeRSSIData(uint8_t* data); void writeSync(uint16_t start);