correct version string errors; debug/rework P25 Rx chain; remove P25 correlation count doesn't apply to hotspots; fix some DMR duplex mode issues;

pull/2/head
Bryan Biedenkapp 4 years ago
parent 1dd2852245
commit 0688a4487e

@ -74,16 +74,16 @@
#endif #endif
#if defined(ADF7021_14_7456) #if defined(ADF7021_14_7456)
#define DESCR_OSC "TCXO 14.7456" #define DESCR_OSC "TCXO 14.7456, "
#endif #endif
#if defined(ADF7021_12_2880) #if defined(ADF7021_12_2880)
#define DESCR_OSC "TCXO 12.2880" #define DESCR_OSC "TCXO 12.2880, "
#endif #endif
#if defined(ENABLE_ADF7021) && defined(ADF7021_N_VER) #if defined(ENABLE_ADF7021) && defined(ADF7021_N_VER)
#define RF_CHIP "ADF7021N" #define RF_CHIP "ADF7021N, "
#elif defined(ENABLE_ADF7021) #elif defined(ENABLE_ADF7021)
#define RF_CHIP "ADF7021" #define RF_CHIP "ADF7021, "
#endif #endif
#define DESCRIPTION "Digital Voice Modem DSP Hotspot [" BOARD_INFO "] (" RF_CHIP DESCR_DMR DESCR_P25 DESCR_OSC DESCR_RSSI "CW Id)" #define DESCRIPTION "Digital Voice Modem DSP Hotspot [" BOARD_INFO "] (" RF_CHIP DESCR_DMR DESCR_P25 DESCR_OSC DESCR_RSSI "CW Id)"
@ -900,10 +900,6 @@ uint8_t SerialPort::setConfig(const uint8_t* data, uint8_t length)
io.setDeviations(dmrTXLevel, p25TXLevel); io.setDeviations(dmrTXLevel, p25TXLevel);
uint8_t p25CorrCount = data[11U];
if (p25CorrCount > 255U)
return RSN_INVALID_P25_CORR_COUNT;
if (modemState == STATE_DMR_CAL || modemState == STATE_DMR_DMO_CAL_1K || modemState == STATE_RSSI_CAL || if (modemState == STATE_DMR_CAL || modemState == STATE_DMR_DMO_CAL_1K || modemState == STATE_RSSI_CAL ||
modemState == STATE_INT_CAL) { modemState == STATE_INT_CAL) {
m_dmrEnable = true; m_dmrEnable = true;
@ -938,7 +934,6 @@ uint8_t SerialPort::setConfig(const uint8_t* data, uint8_t length)
dmrDMOTX.setPreambleCount(fdmaPreamble); dmrDMOTX.setPreambleCount(fdmaPreamble);
p25RX.setNAC(nac); p25RX.setNAC(nac);
p25RX.setCorrCount(p25CorrCount);
#if defined(DUPLEX) #if defined(DUPLEX)
dmrTX.setColorCode(colorCode); dmrTX.setColorCode(colorCode);

@ -42,9 +42,6 @@ using namespace dmr;
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
const uint16_t SCAN_START = 390U;
const uint16_t SCAN_END = 500U;
const uint8_t MAX_SYNC_BYTES_ERRS = 3U; const uint8_t MAX_SYNC_BYTES_ERRS = 3U;
const uint8_t MAX_SYNC_LOST_FRAMES = 13U; const uint8_t MAX_SYNC_LOST_FRAMES = 13U;
@ -132,15 +129,24 @@ bool DMRSlotRX::databit(bool bit)
return m_state != DMRRXS_NONE; return m_state != DMRRXS_NONE;
if (m_state == DMRRXS_NONE) { if (m_state == DMRRXS_NONE) {
if (m_dataPtr >= SCAN_START && m_dataPtr <= SCAN_END)
correlateSync(); correlateSync();
} }
else { else {
uint16_t min = m_syncPtr + DMR_BUFFER_LENGTH_BITS - 2U;
uint16_t max = m_syncPtr + 2U;
if (min >= DMR_BUFFER_LENGTH_BITS)
min -= DMR_BUFFER_LENGTH_BITS;
if (max >= DMR_BUFFER_LENGTH_BITS)
max -= DMR_BUFFER_LENGTH_BITS;
uint16_t min = m_syncPtr - 1U; if (min < max) {
uint16_t max = m_syncPtr + 1U;
if (m_dataPtr >= min && m_dataPtr <= max) if (m_dataPtr >= min && m_dataPtr <= max)
correlateSync(); correlateSync();
} else {
if (m_dataPtr >= min || m_dataPtr <= max)
correlateSync();
}
} }
if (m_dataPtr == m_endPtr) { if (m_dataPtr == m_endPtr) {

@ -39,13 +39,11 @@ using namespace p25;
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
const uint8_t MAX_SYNC_BYTES_START_ERRS = 2U; const uint8_t MAX_SYNC_BITS_START_ERRS = 2U;
const uint8_t MAX_SYNC_BYTES_ERRS = 4U; const uint8_t MAX_SYNC_BITS_ERRS = 4U;
const uint16_t MAX_SYNC_FRAMES = 7U; const uint16_t MAX_SYNC_FRAMES = 7U;
const uint8_t CORRELATION_COUNTDOWN = 6U;
const uint16_t NOENDPTR = 9999U; const uint16_t NOENDPTR = 9999U;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -58,15 +56,9 @@ P25RX::P25RX() :
m_bitBuffer(0x00U), m_bitBuffer(0x00U),
m_buffer(), m_buffer(),
m_dataPtr(0U), m_dataPtr(0U),
m_minSyncPtr(0U),
m_maxSyncPtr(NOENDPTR),
m_startPtr(0U),
m_endPtr(NOENDPTR), m_endPtr(NOENDPTR),
m_syncPtr(0U),
m_lostCount(0U), m_lostCount(0U),
m_countdown(0U),
m_nac(0xF7EU), m_nac(0xF7EU),
m_corrCountdown(CORRELATION_COUNTDOWN),
m_state(P25RXS_NONE), m_state(P25RXS_NONE),
m_duid(0xFFU) m_duid(0xFFU)
{ {
@ -79,18 +71,11 @@ P25RX::P25RX() :
void P25RX::reset() void P25RX::reset()
{ {
m_bitBuffer = 0x00U; m_bitBuffer = 0x00U;
m_dataPtr = 0U; m_dataPtr = 0U;
m_minSyncPtr = 0U;
m_maxSyncPtr = NOENDPTR;
m_startPtr = 0U;
m_endPtr = NOENDPTR; m_endPtr = NOENDPTR;
m_syncPtr = 0U;
m_lostCount = 0U; m_lostCount = 0U;
m_countdown = 0U;
m_state = P25RXS_NONE; m_state = P25RXS_NONE;
@ -103,12 +88,20 @@ void P25RX::reset()
/// <param name="bit"></param> /// <param name="bit"></param>
void P25RX::databit(bool bit) void P25RX::databit(bool bit)
{ {
_WRITE_BIT(m_buffer, m_dataPtr, bit);
m_bitBuffer <<= 1; m_bitBuffer <<= 1;
if (bit) if (bit)
m_bitBuffer |= 0x01U; m_bitBuffer |= 0x01U;
if (m_state != P25RXS_NONE) {
_WRITE_BIT(m_buffer, m_dataPtr, bit);
m_dataPtr++;
if (m_dataPtr > P25_LDU_FRAME_LENGTH_BITS) {
m_duid = 0xFFU;
m_dataPtr = 0U;
}
}
if (m_state == P25RXS_SYNC) { if (m_state == P25RXS_SYNC) {
processBit(bit); processBit(bit);
} }
@ -121,36 +114,15 @@ void P25RX::databit(bool bit)
else { else {
bool ret = correlateSync(); bool ret = correlateSync();
if (ret) { if (ret) {
// on the first sync, start the countdown to the state change DEBUG3("P25RX: databit(): dataPtr/endPtr", m_dataPtr, m_endPtr);
if (m_countdown == 0U) {
io.setDecode(true);
m_countdown = m_corrCountdown;
DEBUG2("P25RX: databit(): correlation countdown", m_countdown);
}
}
if (m_countdown > 0U) for (uint8_t i = 0U; i < P25_SYNC_LENGTH_BYTES; i++)
m_countdown--; m_buffer[i] = P25_SYNC_BYTES[i];
if (m_countdown == 1U) {
m_minSyncPtr = m_syncPtr + P25_HDU_FRAME_LENGTH_BITS - 1U;
if (m_minSyncPtr >= P25_LDU_FRAME_LENGTH_BITS)
m_minSyncPtr -= P25_LDU_FRAME_LENGTH_BITS;
m_maxSyncPtr = m_syncPtr + P25_HDU_FRAME_LENGTH_BITS + 1U;
if (m_maxSyncPtr >= P25_LDU_FRAME_LENGTH_BITS)
m_maxSyncPtr -= P25_LDU_FRAME_LENGTH_BITS;
m_state = P25RXS_SYNC; m_state = P25RXS_SYNC;
m_countdown = 0U;
}
}
m_dataPtr++; io.setDecode(true);
if (m_dataPtr >= P25_LDU_FRAME_LENGTH_BITS) { }
m_duid = 0xFFU;
m_dataPtr = 0U;
} }
} }
@ -163,15 +135,6 @@ void P25RX::setNAC(uint16_t nac)
m_nac = nac; m_nac = nac;
} }
/// <summary>
/// Sets the P25 sync correlation countdown.
/// </summary>
/// <param name="count">Correlation Countdown Count.</param>
void P25RX::setCorrCount(uint8_t count)
{
m_corrCountdown = count;
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -181,22 +144,11 @@ void P25RX::setCorrCount(uint8_t count)
/// <param name="bit"></param> /// <param name="bit"></param>
void P25RX::processBit(bool bit) void P25RX::processBit(bool bit)
{ {
if (m_minSyncPtr < m_maxSyncPtr) { // process NID
if (m_dataPtr >= m_minSyncPtr && m_dataPtr <= m_maxSyncPtr) if (m_dataPtr == P25_SYNC_LENGTH_BITS + P25_NID_LENGTH_BITS + 1) {
correlateSync(); DEBUG3("P25RX: processBit(): dataPtr/endPtr", m_dataPtr, m_endPtr);
}
else {
if (m_dataPtr >= m_minSyncPtr || m_dataPtr <= m_maxSyncPtr)
correlateSync();
}
// initial sample processing does not have an end pointer -- we simply wait till we've read if (!decodeNid()) {
// the bits up to the maximum sync pointer
if (m_dataPtr == m_maxSyncPtr) {
DEBUG4("P25RX: processBit(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_maxSyncPtr);
DEBUG4("P25RX: processBit(): lostCount/maxSyncPtr/minSyncPtr", m_lostCount, m_maxSyncPtr, m_minSyncPtr);
if (!decodeNid(m_startPtr)) {
io.setDecode(false); io.setDecode(false);
serial.writeP25Lost(); serial.writeP25Lost();
@ -206,59 +158,38 @@ void P25RX::processBit(bool bit)
switch (m_duid) { switch (m_duid) {
case P25_DUID_HDU: case P25_DUID_HDU:
{ {
DEBUG2("P25RX: processBit(): sync found in HDU pos", m_syncPtr); DEBUG2("P25RX: processBit(): sync found in HDU pos", m_dataPtr);
m_endPtr = P25_HDU_FRAME_LENGTH_BITS;
uint8_t frame[P25_HDU_FRAME_LENGTH_BYTES + 1U];
bitsToBytes(m_startPtr + P25_NID_LENGTH_BITS, P25_HDU_FRAME_LENGTH_BITS, frame);
frame[0U] = 0x01U;
serial.writeP25Data(frame, P25_HDU_FRAME_LENGTH_BYTES + 1U);
reset();
} }
break; break;
case P25_DUID_TDU: case P25_DUID_TDU:
{ {
DEBUG2("P25RX: processBit(): sync found in TDU pos", m_syncPtr); DEBUG2("P25RX: processBit(): sync found in TDU pos", m_dataPtr);
m_endPtr = P25_TDU_FRAME_LENGTH_BITS;
uint8_t frame[P25_TDU_FRAME_LENGTH_BYTES + 1U];
bitsToBytes(m_startPtr + P25_NID_LENGTH_BITS, P25_TDU_FRAME_LENGTH_BITS, frame);
frame[0U] = 0x01U;
serial.writeP25Data(frame, P25_TDU_FRAME_LENGTH_BYTES + 1U);
reset();
} }
break; break;
case P25_DUID_LDU1: case P25_DUID_LDU1:
m_state = P25RXS_VOICE; m_state = P25RXS_VOICE;
m_endPtr = P25_LDU_FRAME_LENGTH_BITS;
return; return;
case P25_DUID_TSDU: case P25_DUID_TSDU:
{ {
DEBUG2("P25RX: processBit(): sync found in TSDU pos", m_syncPtr); DEBUG2("P25RX: processBit(): sync found in TSDU pos", m_dataPtr);
m_endPtr = P25_TSDU_FRAME_LENGTH_BITS;
uint8_t frame[P25_TSDU_FRAME_LENGTH_BYTES + 1U];
bitsToBytes(m_startPtr + P25_NID_LENGTH_BITS, P25_TSDU_FRAME_LENGTH_BITS, frame);
frame[0U] = 0x01U;
serial.writeP25Data(frame, P25_TSDU_FRAME_LENGTH_BYTES + 1U);
reset();
} }
break; break;
case P25_DUID_LDU2: case P25_DUID_LDU2:
m_state = P25RXS_VOICE; m_state = P25RXS_VOICE;
m_endPtr = P25_LDU_FRAME_LENGTH_BITS;
return; return;
case P25_DUID_PDU: case P25_DUID_PDU:
m_state = P25RXS_DATA; m_state = P25RXS_DATA;
m_endPtr = P25_LDU_FRAME_LENGTH_BITS;
return; return;
case P25_DUID_TDULC: case P25_DUID_TDULC:
{ {
DEBUG2("P25RX: processBit(): sync found in TDULC pos", m_syncPtr); DEBUG2("P25RX: processBit(): sync found in TDULC pos", m_dataPtr);
m_endPtr = P25_TDULC_FRAME_LENGTH_BITS;
uint8_t frame[P25_TDULC_FRAME_LENGTH_BYTES + 1U];
bitsToBytes(m_startPtr + P25_NID_LENGTH_BITS, P25_TDULC_FRAME_LENGTH_BITS, frame);
frame[0U] = 0x01U;
serial.writeP25Data(frame, P25_TDULC_FRAME_LENGTH_BYTES + 1U);
reset();
} }
break; break;
default: default:
@ -271,23 +202,25 @@ void P25RX::processBit(bool bit)
} }
} }
m_minSyncPtr = m_syncPtr + P25_LDU_FRAME_LENGTH_BITS - 1U;
if (m_minSyncPtr >= P25_LDU_FRAME_LENGTH_BITS)
m_minSyncPtr -= P25_LDU_FRAME_LENGTH_BITS;
m_maxSyncPtr = m_syncPtr + 1U;
if (m_maxSyncPtr >= P25_LDU_FRAME_LENGTH_BITS)
m_maxSyncPtr -= P25_LDU_FRAME_LENGTH_BITS;
m_lostCount = MAX_SYNC_FRAMES;
if (m_state == P25RXS_VOICE) { if (m_state == P25RXS_VOICE) {
m_lostCount = MAX_SYNC_FRAMES;
processVoice(bit); processVoice(bit);
} }
if (m_state == P25RXS_DATA) { if (m_state == P25RXS_DATA) {
m_lostCount = MAX_SYNC_FRAMES;
processData(bit); processData(bit);
} }
// since we aren't processing voice or data -- simply wait till we've reached the end pointer
if (m_dataPtr == m_endPtr) {
uint8_t frame[P25_HDU_FRAME_LENGTH_BYTES + 1U];
::memcpy(frame + 1U, m_buffer, m_endPtr / 8U);
frame[0U] = 0x01U;
serial.writeP25Data(frame, (m_endPtr / 8U) + 1U);
reset();
}
} }
/// <summary> /// <summary>
@ -296,53 +229,52 @@ void P25RX::processBit(bool bit)
/// <param name="bit"></param> /// <param name="bit"></param>
void P25RX::processVoice(bool bit) void P25RX::processVoice(bool bit)
{ {
if (m_minSyncPtr < m_maxSyncPtr) { // only search for a sync in the right place +-2 bits
if (m_dataPtr >= m_minSyncPtr && m_dataPtr <= m_maxSyncPtr) if (m_dataPtr >= (P25_SYNC_LENGTH_BITS - 2U) && m_dataPtr <= (P25_SYNC_LENGTH_BITS + 2U)) {
correlateSync();
}
else {
if (m_dataPtr >= m_minSyncPtr || m_dataPtr <= m_maxSyncPtr)
correlateSync(); correlateSync();
} }
if (m_dataPtr == m_endPtr) { // process NID
if (m_lostCount == MAX_SYNC_FRAMES) { if (m_dataPtr == P25_SYNC_LENGTH_BITS + P25_NID_LENGTH_BITS + 1) {
m_minSyncPtr = m_syncPtr + P25_LDU_FRAME_LENGTH_BITS - 1U; DEBUG3("P25RX: processVoice(): dataPtr/endPtr", m_dataPtr, m_endPtr);
if (m_minSyncPtr >= P25_LDU_FRAME_LENGTH_BITS)
m_minSyncPtr -= P25_LDU_FRAME_LENGTH_BITS;
m_maxSyncPtr = m_syncPtr + 1U;
if (m_maxSyncPtr >= P25_LDU_FRAME_LENGTH_BITS)
m_maxSyncPtr -= P25_LDU_FRAME_LENGTH_BITS;
}
m_lostCount--;
DEBUG4("P25RX: processVoice(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr);
DEBUG4("P25RX: processVoice(): lostCount/maxSyncPtr/minSyncPtr", m_lostCount, m_maxSyncPtr, m_minSyncPtr);
// we've not seen a data sync for too long, signal sync lost and change to P25RXS_NONE
if (m_lostCount == 0U) {
DEBUG1("P25RX: processVoice(): sync timeout in LDU, lost lock");
if (!decodeNid()) {
io.setDecode(false); io.setDecode(false);
serial.writeP25Lost(); serial.writeP25Lost();
reset(); reset();
} }
else { else {
if (!decodeNid(m_startPtr)) { switch (m_duid) {
io.setDecode(false); case P25_DUID_TDU:
{
serial.writeP25Lost(); DEBUG2("P25RX: processVoice(): sync found in TDU pos", m_dataPtr);
m_endPtr = P25_TDU_FRAME_LENGTH_BITS;
}
break;
case P25_DUID_LDU1:
m_endPtr = P25_LDU_FRAME_LENGTH_BITS;
return;
case P25_DUID_LDU2:
m_endPtr = P25_LDU_FRAME_LENGTH_BITS;
return;
default:
{
DEBUG3("P25RX: processVoice(): illegal DUID in NID", m_nac, m_duid);
reset(); reset();
} }
else { return;
if (m_duid == P25_DUID_TDU) { }
DEBUG2("P25RX: processBit(): sync found in TDU pos", m_syncPtr); }
}
// if we've reached the end pointer and the DUID is a TDU; send it
if (m_dataPtr == m_endPtr && m_duid == P25_DUID_TDU)
{
DEBUG2("P25RX: processVoice(): sync found in TDU pos", m_dataPtr);
uint8_t frame[P25_TDU_FRAME_LENGTH_BYTES + 1U]; uint8_t frame[P25_TDU_FRAME_LENGTH_BYTES + 1U];
bitsToBytes(m_startPtr + P25_NID_LENGTH_BITS, P25_TDU_FRAME_LENGTH_BITS, frame); ::memcpy(frame + 1U, m_buffer, m_endPtr / 8U);
frame[0U] = 0x01U; frame[0U] = 0x01U;
serial.writeP25Data(frame, P25_TDU_FRAME_LENGTH_BYTES + 1U); serial.writeP25Data(frame, P25_TDU_FRAME_LENGTH_BYTES + 1U);
@ -353,27 +285,36 @@ void P25RX::processVoice(bool bit)
return; return;
} }
DEBUG2("P25RX: processVoice(): sync found in LDU pos", m_syncPtr); // process voice frame
if (m_dataPtr == m_endPtr) {
m_lostCount--;
// we've not seen a data sync for too long, signal sync lost and change to P25RXS_NONE
if (m_lostCount == 0U) {
DEBUG1("P25RX: processVoice(): sync timeout in LDU, lost lock");
io.setDecode(false);
serial.writeP25Lost();
reset();
}
else {
DEBUG2("P25RX: processVoice(): sync found in LDU pos", m_dataPtr);
uint8_t frame[P25_LDU_FRAME_LENGTH_BYTES + 3U]; uint8_t frame[P25_LDU_FRAME_LENGTH_BYTES + 3U];
bitsToBytes(m_startPtr + P25_NID_LENGTH_BITS, P25_LDU_FRAME_LENGTH_BITS, frame); ::memcpy(frame + 1U, m_buffer, m_endPtr / 8U);
frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U;
#if defined(SEND_RSSI_DATA) #if defined(SEND_RSSI_DATA)
if (m_rssiCount > 0U) { uint16_t rssi = io.readRSSI();
uint16_t rssi = m_rssiAccum / m_rssiCount;
frame[217U] = (rssi >> 8) & 0xFFU; frame[217U] = (rssi >> 8) & 0xFFU;
frame[218U] = (rssi >> 0) & 0xFFU; frame[218U] = (rssi >> 0) & 0xFFU;
serial.writeP25Data(false, frame, P25_LDU_FRAME_LENGTH_BYTES + 3U); serial.writeP25Data(false, frame, P25_LDU_FRAME_LENGTH_BYTES + 3U);
}
else {
serial.writeP25Data(false, frame, P25_LDU_FRAME_LENGTH_BYTES + 1U);
}
#else #else
serial.writeP25Data(frame, P25_LDU_FRAME_LENGTH_BYTES + 1U); serial.writeP25Data(frame, P25_LDU_FRAME_LENGTH_BYTES + 1U);
#endif #endif
}
} }
} }
} }
@ -384,31 +325,40 @@ void P25RX::processVoice(bool bit)
/// <param name="bit"></param> /// <param name="bit"></param>
void P25RX::processData(bool bit) void P25RX::processData(bool bit)
{ {
if (m_minSyncPtr < m_maxSyncPtr) { // only search for a sync in the right place +-2 bits
if (m_dataPtr >= m_minSyncPtr && m_dataPtr <= m_maxSyncPtr) if (m_dataPtr >= (P25_SYNC_LENGTH_BITS - 2U) && m_dataPtr <= (P25_SYNC_LENGTH_BITS + 2U)) {
correlateSync();
}
else {
if (m_dataPtr >= m_minSyncPtr || m_dataPtr <= m_maxSyncPtr)
correlateSync(); correlateSync();
} }
if (m_dataPtr == m_endPtr) { // process NID
if (m_lostCount == MAX_SYNC_FRAMES) { if (m_dataPtr == P25_SYNC_LENGTH_BITS + P25_NID_LENGTH_BITS + 1) {
m_minSyncPtr = m_syncPtr + P25_LDU_FRAME_LENGTH_BITS - 1U; DEBUG3("P25RX: processVoice(): dataPtr/endPtr", m_dataPtr, m_endPtr);
if (m_minSyncPtr >= P25_LDU_FRAME_LENGTH_BITS)
m_minSyncPtr -= P25_LDU_FRAME_LENGTH_BITS;
m_maxSyncPtr = m_syncPtr + 1U; if (!decodeNid()) {
if (m_maxSyncPtr >= P25_LDU_FRAME_LENGTH_BITS) io.setDecode(false);
m_maxSyncPtr -= P25_LDU_FRAME_LENGTH_BITS;
serial.writeP25Lost();
reset();
}
else {
switch (m_duid) {
case P25_DUID_PDU:
m_endPtr = P25_LDU_FRAME_LENGTH_BITS;
return;
default:
{
DEBUG3("P25RX: processData(): illegal DUID in NID", m_nac, m_duid);
reset();
}
return;
}
}
} }
// process voice frame
if (m_dataPtr == m_endPtr) {
m_lostCount--; m_lostCount--;
DEBUG4("P25RX: processData(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr);
DEBUG4("P25RX: processData(): lostCount/maxSyncPtr/minSyncPtr", m_lostCount, m_maxSyncPtr, m_minSyncPtr);
// we've not seen a data sync for too long, signal sync lost and change to P25RXS_NONE // we've not seen a data sync for too long, signal sync lost and change to P25RXS_NONE
if (m_lostCount == 0U) { if (m_lostCount == 0U) {
DEBUG1("P25RX: processData(): sync timeout in PDU, lost lock"); DEBUG1("P25RX: processData(): sync timeout in PDU, lost lock");
@ -419,34 +369,13 @@ void P25RX::processData(bool bit)
reset(); reset();
} }
else { else {
if (!decodeNid(m_startPtr)) { DEBUG2("P25RX: processData(): sync found in PDU pos", m_dataPtr);
io.setDecode(false);
serial.writeP25Lost();
reset();
}
else {
DEBUG2("P25RX: processData(): sync found in PDU pos", m_syncPtr);
uint8_t frame[P25_LDU_FRAME_LENGTH_BYTES + 3U]; uint8_t frame[P25_LDU_FRAME_LENGTH_BYTES + 1U];
bitsToBytes(m_startPtr + P25_NID_LENGTH_BITS, P25_LDU_FRAME_LENGTH_BITS, frame); ::memcpy(frame + 1U, m_buffer, m_endPtr / 8U);
frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U;
#if defined(SEND_RSSI_DATA)
if (m_rssiCount > 0U) {
uint16_t rssi = m_rssiAccum / m_rssiCount;
frame[217U] = (rssi >> 8) & 0xFFU;
frame[218U] = (rssi >> 0) & 0xFFU;
serial.writeP25Data(false, frame, P25_LDU_FRAME_LENGTH_BYTES + 3U);
}
else {
serial.writeP25Data(false, frame, P25_LDU_FRAME_LENGTH_BYTES + 1U);
}
#else
serial.writeP25Data(frame, P25_LDU_FRAME_LENGTH_BYTES + 1U); serial.writeP25Data(frame, P25_LDU_FRAME_LENGTH_BYTES + 1U);
#endif
}
} }
} }
} }
@ -459,27 +388,22 @@ bool P25RX::correlateSync()
{ {
uint8_t maxErrs; uint8_t maxErrs;
if (m_state == P25RXS_NONE) if (m_state == P25RXS_NONE)
maxErrs = MAX_SYNC_BYTES_START_ERRS; maxErrs = MAX_SYNC_BITS_START_ERRS;
else else
maxErrs = MAX_SYNC_BYTES_ERRS; maxErrs = MAX_SYNC_BITS_ERRS;
uint8_t errs = countBits64((m_bitBuffer & P25_SYNC_BITS_MASK) ^ P25_SYNC_BITS); uint8_t errs = countBits64((m_bitBuffer & P25_SYNC_BITS_MASK) ^ P25_SYNC_BITS);
if (errs <= maxErrs) { if (errs <= maxErrs) {
DEBUG2("P25RX: correlateSync(): correlateSync errs", errs); DEBUG2("P25RX: correlateSync(): correlateSync errs", errs);
m_syncPtr = m_dataPtr; m_endPtr = m_dataPtr + P25_LDU_FRAME_LENGTH_BITS - P25_SYNC_LENGTH_BITS;
m_startPtr = m_dataPtr + P25_LDU_FRAME_LENGTH_BITS - P25_SYNC_LENGTH_BITS + 1;
if (m_startPtr >= P25_LDU_FRAME_LENGTH_BITS)
m_startPtr -= P25_LDU_FRAME_LENGTH_BITS;
m_endPtr = m_dataPtr + P25_LDU_FRAME_LENGTH_BITS - P25_SYNC_LENGTH_BITS - 1U;
if (m_endPtr >= P25_LDU_FRAME_LENGTH_BITS) if (m_endPtr >= P25_LDU_FRAME_LENGTH_BITS)
m_endPtr -= P25_LDU_FRAME_LENGTH_BITS; m_endPtr -= P25_LDU_FRAME_LENGTH_BITS;
m_lostCount = MAX_SYNC_FRAMES; m_lostCount = MAX_SYNC_FRAMES;
m_dataPtr = P25_SYNC_LENGTH_BITS;
DEBUG4("P25RX: correlateSync(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr); DEBUG3("P25RX: correlateSync(): dataPtr/endPtr", m_dataPtr, m_endPtr);
return true; return true;
} }
@ -490,15 +414,11 @@ bool P25RX::correlateSync()
/// <summary> /// <summary>
/// Helper to decode the P25 NID. /// Helper to decode the P25 NID.
/// </summary> /// </summary>
/// <param name="start"></param> bool P25RX::decodeNid()
bool P25RX::decodeNid(uint16_t start)
{ {
uint16_t nidStartPtr = start + P25_SYNC_LENGTH_BITS;
if (nidStartPtr >= P25_LDU_FRAME_LENGTH_BITS)
nidStartPtr -= P25_LDU_FRAME_LENGTH_BITS;
uint8_t nid[P25_NID_LENGTH_BYTES]; uint8_t nid[P25_NID_LENGTH_BYTES];
bitsToBytes(m_startPtr, P25_NID_LENGTH_BITS, nid); for (int i = 6U; i < 8U; i++)
nid[i - 6U] = m_buffer[i];
if (m_nac == 0xF7EU) { if (m_nac == 0xF7EU) {
m_duid = nid[1U] & 0x0FU; m_duid = nid[1U] & 0x0FU;
@ -518,55 +438,3 @@ bool P25RX::decodeNid(uint16_t start)
return false; return false;
} }
/// <summary>
///
/// </summary>
/// <param name="start"></param>
/// <param name="count"></param>
/// <param name="buffer"></param>
void P25RX::bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer)
{
for (uint8_t i = 0U; i < count; i++) {
buffer[i] = 0U;
buffer[i] |= _READ_BIT(m_buffer, start) << 7;
start++;
if (start >= P25_LDU_FRAME_LENGTH_BITS)
start -= P25_LDU_FRAME_LENGTH_BITS;
buffer[i] |= _READ_BIT(m_buffer, start) << 6;
start++;
if (start >= P25_LDU_FRAME_LENGTH_BITS)
start -= P25_LDU_FRAME_LENGTH_BITS;
buffer[i] |= _READ_BIT(m_buffer, start) << 5;
start++;
if (start >= P25_LDU_FRAME_LENGTH_BITS)
start -= P25_LDU_FRAME_LENGTH_BITS;
buffer[i] |= _READ_BIT(m_buffer, start) << 4;
start++;
if (start >= P25_LDU_FRAME_LENGTH_BITS)
start -= P25_LDU_FRAME_LENGTH_BITS;
buffer[i] |= _READ_BIT(m_buffer, start) << 3;
start++;
if (start >= P25_LDU_FRAME_LENGTH_BITS)
start -= P25_LDU_FRAME_LENGTH_BITS;
buffer[i] |= _READ_BIT(m_buffer, start) << 2;
start++;
if (start >= P25_LDU_FRAME_LENGTH_BITS)
start -= P25_LDU_FRAME_LENGTH_BITS;
buffer[i] |= _READ_BIT(m_buffer, start) << 1;
start++;
if (start >= P25_LDU_FRAME_LENGTH_BITS)
start -= P25_LDU_FRAME_LENGTH_BITS;
buffer[i] |= _READ_BIT(m_buffer, start) << 0;
start++;
if (start >= P25_LDU_FRAME_LENGTH_BITS)
start -= P25_LDU_FRAME_LENGTH_BITS;
}
}

@ -66,29 +66,19 @@ namespace p25
/// <summary>Sets the P25 NAC.</summary> /// <summary>Sets the P25 NAC.</summary>
void setNAC(uint16_t nac); void setNAC(uint16_t nac);
/// <summary>Sets the P25 sync correlation countdown.</summary>
void setCorrCount(uint8_t count);
private: private:
uint64_t m_bitBuffer; uint64_t m_bitBuffer;
uint8_t m_buffer[P25_LDU_FRAME_LENGTH_BITS / 8U + 3U]; uint8_t m_buffer[P25_LDU_FRAME_LENGTH_BYTES + 3U];
uint16_t m_dataPtr; uint16_t m_dataPtr;
uint16_t m_minSyncPtr;
uint16_t m_maxSyncPtr;
uint16_t m_startPtr;
uint16_t m_endPtr; uint16_t m_endPtr;
uint16_t m_syncPtr;
uint16_t m_lostCount; uint16_t m_lostCount;
uint8_t m_countdown;
uint16_t m_nac; uint16_t m_nac;
uint8_t m_corrCountdown;
P25RX_STATE m_state; P25RX_STATE m_state;
uint8_t m_duid; uint8_t m_duid;
@ -104,10 +94,7 @@ namespace p25
bool correlateSync(); bool correlateSync();
/// <summary>Helper to decode the P25 NID.</summary> /// <summary>Helper to decode the P25 NID.</summary>
bool decodeNid(uint16_t start); bool decodeNid();
/// <summary></summary>
void bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer);
}; };
} // namespace p25 } // namespace p25

Loading…
Cancel
Save

Powered by TurnKey Linux.