diff --git a/DMRDMOTX.cpp b/DMRDMOTX.cpp index 33966d9..fe64db6 100644 --- a/DMRDMOTX.cpp +++ b/DMRDMOTX.cpp @@ -23,10 +23,10 @@ #include "DMRSlotType.h" // Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB -static q15_t DMR_C4FSK_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, +static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, 11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112, -553, -847, -731, -340, 104, 401}; // numTaps = 45, L = 5 -const uint16_t DMR_C4FSK_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L +const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L const q15_t DMR_LEVELA = 2889; const q15_t DMR_LEVELB = 963; @@ -68,10 +68,10 @@ m_cachPtr(0U) { ::memset(m_modState, 0x00U, 16U * sizeof(q15_t)); - m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH; - m_modFilter.phaseLength = DMR_C4FSK_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = DMR_C4FSK_FILTER; - m_modFilter.pState = m_modState; + m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH; + m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN; + m_modFilter.pCoeffs = RRC_0_2_FILTER; + m_modFilter.pState = m_modState; } void CDMRDMOTX::process() diff --git a/DMRTX.cpp b/DMRTX.cpp index 12013b7..e202a3f 100644 --- a/DMRTX.cpp +++ b/DMRTX.cpp @@ -23,10 +23,10 @@ #include "DMRSlotType.h" // Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB -static q15_t DMR_C4FSK_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, +static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, 11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112, -553, -847, -731, -340, 104, 401}; // numTaps = 45, L = 5 -const uint16_t DMR_C4FSK_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L +const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L const q15_t DMR_LEVELA = 2889; const q15_t DMR_LEVELB = 963; @@ -73,10 +73,10 @@ m_abort() { ::memset(m_modState, 0x00U, 16U * sizeof(q15_t)); - m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH; - m_modFilter.phaseLength = DMR_C4FSK_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = DMR_C4FSK_FILTER; - m_modFilter.pState = m_modState; + m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH; + m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN; + m_modFilter.pCoeffs = RRC_0_2_FILTER; + m_modFilter.pState = m_modState; ::memcpy(m_newShortLC, EMPTY_SHORT_LC, 12U); ::memcpy(m_shortLC, EMPTY_SHORT_LC, 12U); diff --git a/DStarTX.cpp b/DStarTX.cpp index ec0bc9f..4ed0bf6 100644 --- a/DStarTX.cpp +++ b/DStarTX.cpp @@ -28,8 +28,8 @@ const uint8_t BIT_SYNC = 0xAAU; const uint8_t FRAME_SYNC[] = {0xEAU, 0xA6U, 0x00U}; // Generated using gaussfir(0.35, 1, 5) in MATLAB -static q15_t DSTAR_GMSK_FILTER[] = {0, 0, 0, 0, 212, 743, 1974, 3965, 6026, 6929, 6026, 3965, 1974, 743, 212}; // numTaps = 15, L = 5 -const uint16_t DSTAR_GMSK_FILTER_PHASE_LEN = 3U; // phaseLength = numTaps/L +static q15_t GAUSSIAN_0_35_FILTER[] = {0, 0, 0, 0, 212, 743, 1974, 3965, 6026, 6929, 6026, 3965, 1974, 743, 212}; // numTaps = 15, L = 5 +const uint16_t GAUSSIAN_0_35_FILTER_PHASE_LEN = 3U; // phaseLength = numTaps/L const q15_t DSTAR_LEVEL0 = -4000; const q15_t DSTAR_LEVEL1 = 4000; @@ -198,10 +198,10 @@ m_txDelay(60U) // 100ms { ::memset(m_modState, 0x00U, 20U * sizeof(q15_t)); - m_modFilter.L = DSTAR_RADIO_BIT_LENGTH; - m_modFilter.phaseLength = DSTAR_GMSK_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = DSTAR_GMSK_FILTER; - m_modFilter.pState = m_modState; + m_modFilter.L = DSTAR_RADIO_BIT_LENGTH; + m_modFilter.phaseLength = GAUSSIAN_0_35_FILTER_PHASE_LEN; + m_modFilter.pCoeffs = GAUSSIAN_0_35_FILTER; + m_modFilter.pState = m_modState; } void CDStarTX::process() diff --git a/IO.cpp b/IO.cpp index 352e22c..f6e73a8 100644 --- a/IO.cpp +++ b/IO.cpp @@ -23,18 +23,23 @@ #include "IO.h" // Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB -static q15_t C4FSK_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, +static q15_t RRC_0_2_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, 11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112, -553, -847, -731, -340, 104, 401, 0}; -const uint16_t C4FSK_FILTER_LEN = 42U; +const uint16_t RRC_0_2_FILTER_LEN = 42U; + +// Generated using rcosdesign(0.2, 8, 5, 'normal') in MATLAB +static q15_t RC_0_2_FILTER[] = {0, -413, -750, -845, -587, 0, 741, 1347, 1520, 1062, 0, -1383, -2582, -3021, -2222, 0, 3434, 7487, 11318, 14054, 15044, 14054, + 11318, 7487, 3434, 0, -2222, -3021, -2582, -1383, 0, 1062, 1520, 1347, 741, 0, -587, -845, -750, -413}; +const uint16_t RC_0_2_FILTER_LEN = 40U; // Generated using gaussfir(0.5, 4, 5) in MATLAB -static q15_t GMSK_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0}; -const uint16_t GMSK_FILTER_LEN = 12U; +static q15_t GAUSSIAN_0_5_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0}; +const uint16_t GAUSSIAN_0_5_FILTER_LEN = 12U; // One symbol boxcar filter -static q15_t P25_FILTER[] = {3000, 3000, 3000, 3000, 3000, 0}; -const uint16_t P25_FILTER_LEN = 6U; +static q15_t BOXCAR_FILTER[] = {3000, 3000, 3000, 3000, 3000, 0}; +const uint16_t BOXCAR_FILTER_LEN = 6U; const uint16_t DC_OFFSET = 2048U; @@ -43,12 +48,14 @@ m_started(false), m_rxBuffer(RX_RINGBUFFER_SIZE), m_txBuffer(TX_RINGBUFFER_SIZE), m_rssiBuffer(RX_RINGBUFFER_SIZE), -m_C4FSKFilter(), -m_GMSKFilter(), -m_P25Filter(), -m_C4FSKState(), -m_GMSKState(), -m_P25State(), +m_rrcFilter(), +m_rcFilter(), +m_gaussianFilter(), +m_boxcarFilter(), +m_rrcState(), +m_rcState(), +m_gaussianState(), +m_boxcarState(), m_pttInvert(false), m_rxLevel(128 * 128), m_cwIdTXLevel(128 * 128), @@ -64,21 +71,26 @@ m_dacOverflow(0U), m_watchdog(0U), m_lockout(false) { - ::memset(m_C4FSKState, 0x00U, 70U * sizeof(q15_t)); - ::memset(m_GMSKState, 0x00U, 40U * sizeof(q15_t)); - ::memset(m_P25State, 0x00U, 30U * sizeof(q15_t)); + ::memset(m_rrcState, 0x00U, 70U * sizeof(q15_t)); + ::memset(m_rcState, 0x00U, 70U * sizeof(q15_t)); + ::memset(m_gaussianState, 0x00U, 40U * sizeof(q15_t)); + ::memset(m_boxcarState, 0x00U, 30U * sizeof(q15_t)); - m_C4FSKFilter.numTaps = C4FSK_FILTER_LEN; - m_C4FSKFilter.pState = m_C4FSKState; - m_C4FSKFilter.pCoeffs = C4FSK_FILTER; + m_rrcFilter.numTaps = RRC_0_2_FILTER_LEN; + m_rrcFilter.pState = m_rrcState; + m_rrcFilter.pCoeffs = RRC_0_2_FILTER; - m_GMSKFilter.numTaps = GMSK_FILTER_LEN; - m_GMSKFilter.pState = m_GMSKState; - m_GMSKFilter.pCoeffs = GMSK_FILTER; + m_rcFilter.numTaps = RC_0_2_FILTER_LEN; + m_rcFilter.pState = m_rcState; + m_rcFilter.pCoeffs = RC_0_2_FILTER; - m_P25Filter.numTaps = P25_FILTER_LEN; - m_P25Filter.pState = m_P25State; - m_P25Filter.pCoeffs = P25_FILTER; + m_gaussianFilter.numTaps = GAUSSIAN_0_5_FILTER_LEN; + m_gaussianFilter.pState = m_gaussianState; + m_gaussianFilter.pCoeffs = GAUSSIAN_0_5_FILTER; + + m_boxcarFilter.numTaps = BOXCAR_FILTER_LEN; + m_boxcarFilter.pState = m_boxcarState; + m_boxcarFilter.pCoeffs = BOXCAR_FILTER; initInt(); } @@ -160,21 +172,21 @@ void CIO::process() if (m_modemState == STATE_IDLE) { if (m_dstarEnable) { q15_t GMSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE); dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE); } if (m_p25Enable) { q15_t P25Vals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_P25Filter, samples, P25Vals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE); p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE); } if (m_dmrEnable || m_ysfEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE); if (m_dmrEnable) { if (m_duplex) @@ -189,14 +201,14 @@ void CIO::process() } else if (m_modemState == STATE_DSTAR) { if (m_dstarEnable) { q15_t GMSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE); dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE); } } else if (m_modemState == STATE_DMR) { if (m_dmrEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE); if (m_duplex) { // If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs @@ -211,20 +223,23 @@ void CIO::process() } else if (m_modemState == STATE_YSF) { if (m_ysfEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE); ysfRX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE); } } else if (m_modemState == STATE_P25) { if (m_p25Enable) { - q15_t P25Vals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_P25Filter, samples, P25Vals, RX_BLOCK_SIZE); + q15_t P25Vals1[RX_BLOCK_SIZE]; + ::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals1, RX_BLOCK_SIZE); - p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE); + q15_t P25Vals2[RX_BLOCK_SIZE]; + ::arm_fir_fast_q15(&m_rcFilter, P25Vals1, P25Vals2, RX_BLOCK_SIZE); + + p25RX.samples(P25Vals2, rssi, RX_BLOCK_SIZE); } } else if (m_modemState == STATE_DSTARCAL) { q15_t GMSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE); calDStarRX.samples(GMSKVals, RX_BLOCK_SIZE); } else if (m_modemState == STATE_RSSICAL) { diff --git a/P25TX.cpp b/P25TX.cpp index 1dde485..a6147ba 100644 --- a/P25TX.cpp +++ b/P25TX.cpp @@ -25,18 +25,18 @@ // Generated using rcosdesign(0.2, 8, 5, 'normal') in MATLAB // numTaps = 40, L = 5 -static q15_t P25_C4FSK_FILTER[] = {-413, -751, -845, -587, 0, 740, 1348, 1520, 1063, 0, -1383, -2583, -3021, -2222, 0, 3435, 7488, 11318, 14053, 15044, 14053, +static q15_t RC_0_2_FILTER[] = {-413, -751, -845, -587, 0, 740, 1348, 1520, 1063, 0, -1383, -2583, -3021, -2222, 0, 3435, 7488, 11318, 14053, 15044, 14053, 11318, 7488, 3435, 0, -2222, -3021, -2583, -1383, 0, 1063, 1520, 1348, 740, 0, -587, -845, -751, -413, 0}; -const uint16_t P25_C4FSK_FILTER_PHASE_LEN = 8U; // phaseLength = numTaps/L +const uint16_t RC_0_2_FILTER_PHASE_LEN = 8U; // phaseLength = numTaps/L // Generated in MATLAB using the following commands, and then normalised for unity gain // shape2 = 'Inverse-sinc Lowpass'; // d2 = fdesign.interpolator(2, shape2); // h2 = design(d2, 'SystemObject', true); -static q15_t P25_LP_FILTER[] = {170, 401, 340, -203, -715, -478, 281, 419, -440, -1002, -103, 1114, 528, -1389, -1520, 1108, 2674, -388, -4662, +static q15_t LOWPASS_FILTER[] = {170, 401, 340, -203, -715, -478, 281, 419, -440, -1002, -103, 1114, 528, -1389, -1520, 1108, 2674, -388, -4662, -2132, 9168, 20241, 20241, 9168, -2132, -4662, -388, 2674, 1108, -1520, -1389, 528, 1114, -103, -1002, -440, 419, 281, -478, -715, -203, 340, 401, 170}; -const uint16_t P25_LP_FILTER_LEN = 44U; +const uint16_t LOWPASS_FILTER_LEN = 44U; const q15_t P25_LEVELA = 1698; const q15_t P25_LEVELB = 566; @@ -59,14 +59,14 @@ m_txDelay(240U) // 200ms ::memset(m_modState, 0x00U, 16U * sizeof(q15_t)); ::memset(m_lpState, 0x00U, 70U * sizeof(q15_t)); - m_modFilter.L = P25_RADIO_SYMBOL_LENGTH; - m_modFilter.phaseLength = P25_C4FSK_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = P25_C4FSK_FILTER; - m_modFilter.pState = m_modState; + m_modFilter.L = P25_RADIO_SYMBOL_LENGTH; + m_modFilter.phaseLength = RC_0_2_FILTER_PHASE_LEN; + m_modFilter.pCoeffs = RC_0_2_FILTER; + m_modFilter.pState = m_modState; - m_lpFilter.numTaps = P25_LP_FILTER_LEN; + m_lpFilter.numTaps = LOWPASS_FILTER_LEN; m_lpFilter.pState = m_lpState; - m_lpFilter.pCoeffs = P25_LP_FILTER; + m_lpFilter.pCoeffs = LOWPASS_FILTER; } void CP25TX::process() diff --git a/YSFTX.cpp b/YSFTX.cpp index 5c72efd..e6010b9 100644 --- a/YSFTX.cpp +++ b/YSFTX.cpp @@ -24,10 +24,10 @@ #include "YSFDefines.h" // Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB -static q15_t YSF_C4FSK_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, +static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, 11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112, -553, -847, -731, -340, 104, 401}; // numTaps = 45, L = 5 -const uint16_t YSF_C4FSK_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L +const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L const q15_t YSF_LEVELA_HI = 3900; const q15_t YSF_LEVELB_HI = 1300; @@ -54,10 +54,10 @@ m_loDev(false) { ::memset(m_modState, 0x00U, 16U * sizeof(q15_t)); - m_modFilter.L = YSF_RADIO_SYMBOL_LENGTH; - m_modFilter.phaseLength = YSF_C4FSK_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = YSF_C4FSK_FILTER; - m_modFilter.pState = m_modState; + m_modFilter.L = YSF_RADIO_SYMBOL_LENGTH; + m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN; + m_modFilter.pCoeffs = RRC_0_2_FILTER; + m_modFilter.pState = m_modState; } void CYSFTX::process()