From 5ea787bcbffa8b715f9d1c78cf66d1dde8f001d7 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Sun, 17 Apr 2022 10:49:04 -0400 Subject: [PATCH] correct strangeness in performing a single line calculation for Tx offset to fix rounding errors for issue #7; --- p25/lc/TDULC.cpp | 46 +++++++++++++++++++++++++++++++++------------- p25/lc/TSBK.cpp | 16 ++++++++++------ 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/p25/lc/TDULC.cpp b/p25/lc/TDULC.cpp index 807da2ce..6c252e7b 100644 --- a/p25/lc/TDULC.cpp +++ b/p25/lc/TDULC.cpp @@ -402,19 +402,39 @@ void TDULC::encodeLC(uint8_t* rs) { if ((m_siteIdenEntry.chBandwidthKhz() != 0.0F) && (m_siteIdenEntry.chSpaceKhz() != 0.0F) && (m_siteIdenEntry.txOffsetMhz() != 0U) && (m_siteIdenEntry.baseFrequency() != 0U)) { - uint32_t calcSpace = (uint32_t)(m_siteIdenEntry.chSpaceKhz() / 0.125); - uint32_t calcTxOffset = (uint32_t)((fabs(m_siteIdenEntry.txOffsetMhz()) / m_siteIdenEntry.chSpaceKhz()) * 1000); - if (m_siteIdenEntry.txOffsetMhz() > 0.0F) - calcTxOffset |= 0x2000U; // this sets a positive offset ... - - uint32_t calcBaseFreq = (uint32_t)(m_siteIdenEntry.baseFrequency() / 5); - uint8_t chanBw = (m_siteIdenEntry.chBandwidthKhz() >= 12.5F) ? P25_IDEN_UP_VU_BW_125K : P25_IDEN_UP_VU_BW_625K; - - rsValue = m_siteIdenEntry.channelId(); // Channel ID - rsValue = (rsValue << 4) + chanBw; // Channel Bandwidth - rsValue = (rsValue << 14) + calcTxOffset; // Transmit Offset - rsValue = (rsValue << 10) + calcSpace; // Channel Spacing - rsValue = (rsValue << 32) + calcBaseFreq; // Base Frequency + if (m_siteIdenEntry.baseFrequency() < 762000000U) { + uint32_t calcSpace = (uint32_t)(m_siteIdenEntry.chSpaceKhz() / 0.125); + + float fCalcTxOffset = (fabs(m_siteIdenEntry.txOffsetMhz()) / m_siteIdenEntry.chSpaceKhz()) * 1000.0F; + uint32_t uCalcTxOffset = (uint32_t)fCalcTxOffset; + if (m_siteIdenEntry.txOffsetMhz() > 0.0F) + uCalcTxOffset |= 0x2000U; // this sets a positive offset ... + + uint32_t calcBaseFreq = (uint32_t)(m_siteIdenEntry.baseFrequency() / 5); + uint8_t chanBw = (m_siteIdenEntry.chBandwidthKhz() >= 12.5F) ? P25_IDEN_UP_VU_BW_125K : P25_IDEN_UP_VU_BW_625K; + + rsValue = m_siteIdenEntry.channelId(); // Channel ID + rsValue = (rsValue << 4) + chanBw; // Channel Bandwidth + rsValue = (rsValue << 14) + uCalcTxOffset; // Transmit Offset + rsValue = (rsValue << 10) + calcSpace; // Channel Spacing + rsValue = (rsValue << 32) + calcBaseFreq; // Base Frequency + } else { + uint32_t calcSpace = (uint32_t)(m_siteIdenEntry.chSpaceKhz() / 0.125); + + float fCalcTxOffset = (fabs(m_siteIdenEntry.txOffsetMhz()) * 1000000.0F) / 250000.0F; + uint32_t uCalcTxOffset = (uint32_t)fCalcTxOffset; + if (m_siteIdenEntry.txOffsetMhz() > 0.0F) + uCalcTxOffset |= 0x2000U; // this sets a positive offset ... + + uint32_t calcBaseFreq = (uint32_t)(m_siteIdenEntry.baseFrequency() / 5); + uint16_t chanBw = (uint16_t)((m_siteIdenEntry.chBandwidthKhz() * 1000) / 125); + + rsValue = m_siteIdenEntry.channelId(); // Channel ID + rsValue = (rsValue << 4) + chanBw; // Channel Bandwidth + rsValue = (rsValue << 14) + uCalcTxOffset; // Transmit Offset + rsValue = (rsValue << 10) + calcSpace; // Channel Spacing + rsValue = (rsValue << 32) + calcBaseFreq; // Base Frequency + } } else { LogError(LOG_P25, "TDULC::encodeLC(), invalid values for LC_IDEN_UP, baseFrequency = %uHz, txOffsetMhz = %fMHz, chBandwidthKhz = %fKHz, chSpaceKhz = %fKHz", diff --git a/p25/lc/TSBK.cpp b/p25/lc/TSBK.cpp index 24a0d62a..e7f1f0a3 100644 --- a/p25/lc/TSBK.cpp +++ b/p25/lc/TSBK.cpp @@ -735,16 +735,18 @@ void TSBK::encode(uint8_t * data, bool rawTSBK, bool noTrellis) if ((m_siteIdenEntry.chBandwidthKhz() != 0.0F) && (m_siteIdenEntry.chSpaceKhz() != 0.0F) && (m_siteIdenEntry.txOffsetMhz() != 0.0F) && (m_siteIdenEntry.baseFrequency() != 0U)) { uint32_t calcSpace = (uint32_t)(m_siteIdenEntry.chSpaceKhz() / 0.125); - uint32_t calcTxOffset = (uint32_t)((fabs(m_siteIdenEntry.txOffsetMhz()) / m_siteIdenEntry.chSpaceKhz()) * 1000); + + float fCalcTxOffset = (fabs(m_siteIdenEntry.txOffsetMhz()) / m_siteIdenEntry.chSpaceKhz()) * 1000.0F; + uint32_t uCalcTxOffset = (uint32_t)fCalcTxOffset; if (m_siteIdenEntry.txOffsetMhz() > 0.0F) - calcTxOffset |= 0x2000U; // this sets a positive offset ... + uCalcTxOffset |= 0x2000U; // this sets a positive offset ... uint32_t calcBaseFreq = (uint32_t)(m_siteIdenEntry.baseFrequency() / 5); uint8_t chanBw = (m_siteIdenEntry.chBandwidthKhz() >= 12.5F) ? P25_IDEN_UP_VU_BW_125K : P25_IDEN_UP_VU_BW_625K; tsbkValue = m_siteIdenEntry.channelId(); // Channel ID tsbkValue = (tsbkValue << 4) + chanBw; // Channel Bandwidth - tsbkValue = (tsbkValue << 14) + calcTxOffset; // Transmit Offset + tsbkValue = (tsbkValue << 14) + uCalcTxOffset; // Transmit Offset tsbkValue = (tsbkValue << 10) + calcSpace; // Channel Spacing tsbkValue = (tsbkValue << 32) + calcBaseFreq; // Base Frequency } @@ -832,16 +834,18 @@ void TSBK::encode(uint8_t * data, bool rawTSBK, bool noTrellis) } uint32_t calcSpace = (uint32_t)(m_siteIdenEntry.chSpaceKhz() / 0.125); - uint32_t calcTxOffset = (uint32_t)((fabs(m_siteIdenEntry.txOffsetMhz()) * 1000000) / 250000); + + float fCalcTxOffset = (fabs(m_siteIdenEntry.txOffsetMhz()) * 1000000.0F) / 250000.0F; + uint32_t uCalcTxOffset = (uint32_t)fCalcTxOffset; if (m_siteIdenEntry.txOffsetMhz() > 0.0F) - calcTxOffset |= 0x100U; // this sets a positive offset ... + uCalcTxOffset |= 0x2000U; // this sets a positive offset ... uint32_t calcBaseFreq = (uint32_t)(m_siteIdenEntry.baseFrequency() / 5); uint16_t chanBw = (uint16_t)((m_siteIdenEntry.chBandwidthKhz() * 1000) / 125); tsbkValue = m_siteIdenEntry.channelId(); // Channel ID tsbkValue = (tsbkValue << 9) + chanBw; // Channel Bandwidth - tsbkValue = (tsbkValue << 9) + calcTxOffset; // Transmit Offset + tsbkValue = (tsbkValue << 9) + uCalcTxOffset; // Transmit Offset tsbkValue = (tsbkValue << 10) + calcSpace; // Channel Spacing tsbkValue = (tsbkValue << 32) + calcBaseFreq; // Base Frequency }