From 3cef7709a902a5d4bc407b9341a7a8f6846273b6 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Sun, 5 Dec 2021 10:06:16 -0500 Subject: [PATCH] remove calState (this was causing copy-and-paste superfluous code); simplify setting up some ADF7021 parameters; consolidate DMR cal back into DMRTx instead of DMRDMOTx; --- ADF7021.cpp | 688 ++++++++++++++++++----------------------------- FirmwareMain.cpp | 14 +- Globals.h | 5 +- IO.cpp | 18 +- IO.h | 4 +- SerialPort.cpp | 99 +++---- SerialPort.h | 8 +- dmr/CalDMR.cpp | 12 +- dmr/DMRDMOTX.cpp | 45 +--- dmr/DMRDMOTX.h | 20 +- dmr/DMRTX.cpp | 50 +++- dmr/DMRTX.h | 8 +- 12 files changed, 416 insertions(+), 555 deletions(-) diff --git a/ADF7021.cpp b/ADF7021.cpp index 77447a0..baccaad 100644 --- a/ADF7021.cpp +++ b/ADF7021.cpp @@ -54,6 +54,11 @@ volatile uint32_t AD7021_CONTROL; uint32_t ADF7021_RX_REG0; uint32_t ADF7021_TX_REG0; uint32_t ADF7021_REG1; +uint32_t ADF7021_REG2; +uint32_t ADF7021_REG3; +uint32_t ADF7021_REG4; +uint32_t ADF7021_REG10; +uint32_t ADF7021_REG13; uint32_t div2; uint32_t f_div; @@ -290,11 +295,6 @@ void IO::interrupt2() /// void IO::rf1Conf(DVM_STATE modemState, bool reset) { - uint32_t ADF7021_REG2 = 0U; - uint32_t ADF7021_REG3 = 0U; - uint32_t ADF7021_REG4 = 0U; - uint32_t ADF7021_REG10 = 0U; - uint32_t ADF7021_REG13 = 0U; int32_t AFC_OFFSET = 0; uint32_t txFrequencyTmp, rxFrequencyTmp; @@ -375,226 +375,8 @@ void IO::rf1Conf(DVM_STATE modemState, bool reset) ADF7021_TX_REG0 |= (uint32_t)TX_N_Divider << 19; // frequency - 15-bit Frac_N ADF7021_TX_REG0 |= (uint32_t)TX_F_Divider << 4; // frequency - 8-bit Int_N - /* - ** Configure the remaining registers based on modem state. - */ - - switch (modemState) { - case STATE_CW: // 4FSK - { - // Dev: +1 symb (variable), symb rate = 4800 - - /* - ** Tx/Rx Clock (Register 3) & AFC (Register 10) - */ - ADF7021_REG3 = ADF7021_REG3_DMR; - ADF7021_REG10 = ADF7021_REG10_DMR; - - /* - ** Demodulator Setup (Register 4) - */ - uint16_t discBW = ADF7021_DISC_BW_DMR; - if (discBW + m_dmrDiscBWAdj < 0U) - discBW = 0U; - else - discBW = ADF7021_DISC_BW_DMR + m_dmrDiscBWAdj; - if (discBW > ADF7021_DISC_BW_MAX) - discBW = ADF7021_DISC_BW_MAX; - - uint16_t postBW = ADF7021_POST_BW_DMR; - if (postBW + m_dmrPostBWAdj < 0) - postBW = 0U; - else - postBW = ADF7021_POST_BW_DMR + m_dmrPostBWAdj; - if (postBW > ADF7021_POST_BW_MAX) - postBW = ADF7021_POST_BW_MAX; - - // K=32 - ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 - ADF7021_REG4 |= (uint32_t)0b011 << 4; // mode, 4FSK - ADF7021_REG4 |= (uint32_t)0b0 << 7; // cross product - ADF7021_REG4 |= (uint32_t)0b11 << 8; // invert clk/data - ADF7021_REG4 |= (uint32_t)(discBW & 0x3FFU) << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)(postBW & 0xFFFU) << 20; // post demod BW - ADF7021_REG4 |= (uint32_t)0b10 << 30; // IF filter (25 kHz) - - /* - ** 3FSK/4FSK Demod (Register 13) - */ - ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 - ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_DMR << 4; // slicer threshold - - /* - ** Transmit Modulation (Register 2) - */ - ADF7021_REG2 = (uint32_t)0b0010; // register 2 - ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level - ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA - ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) - ADF7021_REG2 |= (uint32_t)(m_cwIdTXLevel / div2) << 19; // deviation - ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) - } - break; - - case STATE_DMR: // 4FSK - { - // Dev: +1 symb 648 Hz, symb rate = 4800 - - /* - ** Tx/Rx Clock (Register 3) & AFC (Register 10) - */ - ADF7021_REG3 = ADF7021_REG3_DMR; - ADF7021_REG10 = ADF7021_REG10_DMR; - - /* - ** Demodulator Setup (Register 4) - */ - uint16_t discBW = ADF7021_DISC_BW_DMR; - if (discBW + m_dmrDiscBWAdj < 0U) - discBW = 0U; - else - discBW = ADF7021_DISC_BW_DMR + m_dmrDiscBWAdj; - if (discBW > ADF7021_DISC_BW_MAX) - discBW = ADF7021_DISC_BW_MAX; - - uint16_t postBW = ADF7021_POST_BW_DMR; - if (postBW + m_dmrPostBWAdj < 0) - postBW = 0U; - else - postBW = ADF7021_POST_BW_DMR + m_dmrPostBWAdj; - if (postBW > ADF7021_POST_BW_MAX) - postBW = ADF7021_POST_BW_MAX; - - // K=32 - ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 - ADF7021_REG4 |= (uint32_t)0b011 << 4; // mode, 4FSK - ADF7021_REG4 |= (uint32_t)0b0 << 7; // cross product - ADF7021_REG4 |= (uint32_t)0b11 << 8; // invert clk/data - ADF7021_REG4 |= (uint32_t)(discBW & 0x3FFU) << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)(postBW & 0xFFFU) << 20; // post demod BW - ADF7021_REG4 |= (uint32_t)0b10 << 30; // IF filter (25 kHz) - - /* - ** 3FSK/4FSK Demod (Register 13) - */ - ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 - ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_DMR << 4; // slicer threshold - - /* - ** Transmit Modulation (Register 2) - */ - ADF7021_REG2 = (uint32_t)0b0010; // register 2 - ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level - ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA - ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) - ADF7021_REG2 |= (uint32_t)(dmrDev / div2) << 19; // deviation -#if defined(ADF7021_DISABLE_RC_4FSK) - ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK) -#else - ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) -#endif - } - break; - - case STATE_P25: // 4FSK - { - // Dev: +1 symb 600 Hz, symb rate = 4800 - - /* - ** Tx/Rx Clock (Register 3) & AFC (Register 10) - */ - ADF7021_REG3 = ADF7021_REG3_P25; - ADF7021_REG10 = ADF7021_REG10_P25; - - /* - ** Demodulator Setup (Register 4) - */ - uint16_t discBW = ADF7021_DISC_BW_P25; - if (discBW + m_dmrDiscBWAdj < 0U) - discBW = 0U; - else - discBW = ADF7021_DISC_BW_P25 + m_dmrDiscBWAdj; - if (discBW > ADF7021_DISC_BW_MAX) - discBW = ADF7021_DISC_BW_MAX; - - uint16_t postBW = ADF7021_POST_BW_P25; - if (postBW + m_dmrPostBWAdj < 0) - postBW = 0U; - else - postBW = ADF7021_POST_BW_P25 + m_dmrPostBWAdj; - if (postBW > ADF7021_POST_BW_MAX) - postBW = ADF7021_POST_BW_MAX; - - // K=32 - ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 - ADF7021_REG4 |= (uint32_t)0b011 << 4; // mode, 4FSK - ADF7021_REG4 |= (uint32_t)0b0 << 7; // cross product - ADF7021_REG4 |= (uint32_t)0b11 << 8; // invert clk/data - ADF7021_REG4 |= (uint32_t)(discBW & 0x3FFU) << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)(postBW & 0xFFFU) << 20; // post demod BW - ADF7021_REG4 |= (uint32_t)0b00 << 30; // IF filter (12.5 kHz) - - /* - ** 3FSK/4FSK Demod (Register 13) - */ - ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 - ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_P25 << 4; // slicer threshold - - /* - ** Transmit Modulation (Register 2) - */ - ADF7021_REG2 = (uint32_t)0b0010; // register 2 - ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level - ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA - ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) - ADF7021_REG2 |= (uint32_t)(p25Dev / div2) << 19; // deviation -#if defined(ENABLE_P25_WIDE) || defined(ADF7021_DISABLE_RC_4FSK) - ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK) -#else - ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) -#endif - } - break; - default: // GMSK - { - // Dev: 1200 Hz, symb rate = 4800 - - /* - ** Tx/Rx Clock (Register 3) & AFC (Register 10) - */ - ADF7021_REG3 = ADF7021_REG3_DEFAULT; - ADF7021_REG10 = ADF7021_REG10_DEFAULT; - - /* - ** Demodulator Setup (Register 4) - */ - // K=32 - ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 - ADF7021_REG4 |= (uint32_t)0b001 << 4; // mode, GMSK - ADF7021_REG4 |= (uint32_t)0b1 << 7; // dot product - ADF7021_REG4 |= (uint32_t)0b10 << 8; // invert data - ADF7021_REG4 |= (uint32_t)ADF7021_DISC_BW_DEFAULT << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)ADF7021_POST_BW_DEFAULT << 20; // post demod BW - ADF7021_REG4 |= (uint32_t)0b00 << 30; // IF filter (12.5 kHz) - - /* - ** 3FSK/4FSK Demod (Register 13) - */ - ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 - ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_DEFAULT << 4; // slicer threshold - - /* - ** Transmit Modulation (Register 2) - */ - ADF7021_REG2 = (uint32_t)0b0010; // register 2 - ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level - ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA - ADF7021_REG2 |= (uint32_t)0b00 << 28; // normal - ADF7021_REG2 |= (uint32_t)(ADF7021_DEV_DEFAULT / div2) << 19; // deviation - ADF7021_REG2 |= (uint32_t)0b001 << 4; // modulation (GMSK) - } - break; - } + // configure ADF Tx/RX + configureTxRx(modemState); // write registers /* @@ -703,188 +485,24 @@ void IO::rf1Conf(DVM_STATE modemState, bool reset) #endif AD7021_1_IOCTL(); -#if defined(DUPLEX) - // if duplex -- auto setup the second ADF7021 - if (m_duplex && (modemState != STATE_CW)) - rf2Conf(modemState); -#endif -} - -#if defined(DUPLEX) -/// -/// Sets the ADF7021 RF configuration. -/// -/// -/// -void IO::rf2Conf(DVM_STATE modemState) -{ - uint32_t ADF7021_REG2 = 0U; - uint32_t ADF7021_REG3 = 0U; - uint32_t ADF7021_REG4 = 0U; - uint32_t ADF7021_REG10 = 0U; - uint32_t ADF7021_REG13 = 0U; - - switch (modemState) { - case STATE_DMR: // 4FSK - { - // Dev: +1 symb 648 Hz, symb rate = 4800 - - /* - ** Tx/Rx Clock (Register 3) & AFC (Register 10) - */ - ADF7021_REG3 = ADF7021_REG3_DMR; - ADF7021_REG10 = ADF7021_REG10_DMR; - - /* - ** Demodulator Setup (Register 4) - */ - uint16_t discBW = ADF7021_DISC_BW_DMR; - if (discBW + m_dmrDiscBWAdj < 0U) - discBW = 0U; - else - discBW = ADF7021_DISC_BW_DMR + m_dmrDiscBWAdj; - if (discBW > ADF7021_DISC_BW_MAX) - discBW = ADF7021_DISC_BW_MAX; - - uint16_t postBW = ADF7021_POST_BW_DMR; - if (postBW + m_dmrPostBWAdj < 0) - postBW = 0U; - else - postBW = ADF7021_POST_BW_DMR + m_dmrPostBWAdj; - if (postBW > ADF7021_POST_BW_MAX) - postBW = ADF7021_POST_BW_MAX; - - // K=32 - ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 - ADF7021_REG4 |= (uint32_t)0b011 << 4; // mode, 4FSK - ADF7021_REG4 |= (uint32_t)0b0 << 7; // cross product - ADF7021_REG4 |= (uint32_t)0b11 << 8; // invert clk/data - ADF7021_REG4 |= (uint32_t)(discBW & 0x3FFU) << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)(postBW & 0xFFFU) << 20; // post demod BW - ADF7021_REG4 |= (uint32_t)0b10 << 30; // IF filter (25 kHz) - - /* - ** 3FSK/4FSK Demod (Register 13) - */ - ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 - ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_DMR << 4; // slicer threshold - - /* - ** Transmit Modulation (Register 2) - */ - ADF7021_REG2 = (uint32_t)0b0010; // register 2 - ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level - ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA - ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) - ADF7021_REG2 |= (uint32_t)(dmrDev / div2) << 19; // deviation -#if defined(ADF7021_DISABLE_RC_4FSK) - ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK) -#else - ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) -#endif - } - break; - - case STATE_P25: // 4FSK - { - // Dev: +1 symb 600 Hz, symb rate = 4800 - - /* - ** Tx/Rx Clock (Register 3) & AFC (Register 10) - */ - ADF7021_REG3 = ADF7021_REG3_P25; - ADF7021_REG10 = ADF7021_REG10_P25; - - /* - ** Demodulator Setup (Register 4) - */ - uint16_t discBW = ADF7021_DISC_BW_P25; - if (discBW + m_dmrDiscBWAdj < 0U) - discBW = 0U; - else - discBW = ADF7021_DISC_BW_P25 + m_dmrDiscBWAdj; - if (discBW > ADF7021_DISC_BW_MAX) - discBW = ADF7021_DISC_BW_MAX; - - uint16_t postBW = ADF7021_POST_BW_P25; - if (postBW + m_dmrPostBWAdj < 0) - postBW = 0U; - else - postBW = ADF7021_POST_BW_P25 + m_dmrPostBWAdj; - if (postBW > ADF7021_POST_BW_MAX) - postBW = ADF7021_POST_BW_MAX; - - // K=32 - ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 - ADF7021_REG4 |= (uint32_t)0b011 << 4; // mode, 4FSK - ADF7021_REG4 |= (uint32_t)0b0 << 7; // cross product - ADF7021_REG4 |= (uint32_t)0b11 << 8; // invert clk/data - ADF7021_REG4 |= (uint32_t)(discBW & 0x3FFU) << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)(postBW & 0xFFFU) << 20; // post demod BW - ADF7021_REG4 |= (uint32_t)0b00 << 30; // IF filter (12.5 kHz) - - /* - ** 3FSK/4FSK Demod (Register 13) - */ - ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 - ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_P25 << 4; // slicer threshold - - /* - ** Transmit Modulation (Register 2) - */ - ADF7021_REG2 = (uint32_t)0b0010; // register 2 - ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level - ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA - ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) - ADF7021_REG2 |= (uint32_t)(p25Dev / div2) << 19; // deviation -#if defined(ENABLE_P25_WIDE) || defined(ADF7021_DISABLE_RC_4FSK) - ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK) -#else - ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) -#endif - } - break; - default: // GMSK - { - // Dev: 1200 Hz, symb rate = 4800 - - /* - ** Tx/Rx Clock (Register 3) & AFC (Register 10) - */ - ADF7021_REG3 = ADF7021_REG3_DEFAULT; - ADF7021_REG10 = ADF7021_REG10_DEFAULT; - - /* - ** Demodulator Setup (Register 4) - */ - // K=32 - ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 - ADF7021_REG4 |= (uint32_t)0b001 << 4; // mode, GMSK - ADF7021_REG4 |= (uint32_t)0b1 << 7; // dot product - ADF7021_REG4 |= (uint32_t)0b10 << 8; // invert data - ADF7021_REG4 |= (uint32_t)ADF7021_DISC_BW_DEFAULT << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)ADF7021_POST_BW_DEFAULT << 20; // post demod BW - ADF7021_REG4 |= (uint32_t)0b00 << 30; // IF filter (12.5 kHz) - - /* - ** 3FSK/4FSK Demod (Register 13) - */ - ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 - ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_DEFAULT << 4; // slicer threshold - - /* - ** Transmit Modulation (Register 2) - */ - ADF7021_REG2 = (uint32_t)0b0010; // register 2 - ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level - ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA - ADF7021_REG2 |= (uint32_t)0b00 << 28; // normal - ADF7021_REG2 |= (uint32_t)(ADF7021_DEV_DEFAULT / div2) << 19; // deviation - ADF7021_REG2 |= (uint32_t)0b001 << 4; // modulation (GMSK) - } - break; - } - +#if defined(DUPLEX) + // if duplex -- auto setup the second ADF7021 + if (m_duplex && (modemState != STATE_CW)) + rf2Conf(modemState); +#endif +} + +#if defined(DUPLEX) +/// +/// Sets the ADF7021 RF configuration. +/// +/// +/// +void IO::rf2Conf(DVM_STATE modemState) +{ + // configure ADF Tx/RX + configureTxRx(modemState); + // write registers /* ** VCO/Oscillator (Register 1) @@ -1015,7 +633,7 @@ void IO::setRFAdjust(int8_t dmrDiscBWAdj, int8_t p25DiscBWAdj, int8_t dmrPostBWA /// /// /// -void IO::updateCal() +void IO::updateCal(DVM_STATE modemState) { uint32_t ADF7021_REG2; float divider; @@ -1028,19 +646,13 @@ void IO::updateCal() AD7021_CONTROL = ADF7021_REG1; AD7021_1_IOCTL(); + // configure ADF Tx/RX + configureTxRx(modemState); + /* - ** Transmit Modulation (Register 2) + ** Demodulator Setup (Register 4) */ - ADF7021_REG2 = (uint32_t)0b0010; // register 2 - ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level - ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA - ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) - if (m_modemState == STATE_DMR) { - ADF7021_REG2 |= (uint32_t)(dmrDev / div2) << 19; // DMR deviation - ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) - } - - AD7021_CONTROL = ADF7021_REG2; + AD7021_CONTROL = ADF7021_REG4; AD7021_1_IOCTL(); /* @@ -1067,6 +679,12 @@ void IO::updateCal() ADF7021_TX_REG0 |= (uint32_t)TX_N_Divider << 19; // frequency - 15-bit Frac_N ADF7021_TX_REG0 |= (uint32_t)TX_F_Divider << 4; // frequency - 8-bit Int_N + /* + ** Transmit Modulation (Register 2) + */ + AD7021_CONTROL = ADF7021_REG2; + AD7021_1_IOCTL(); + if (m_tx) setTX(); else @@ -1102,7 +720,7 @@ uint16_t IO::readRSSI() SDATA(LOW); #if defined(DUPLEX) - if (m_duplex || m_calState == STATE_RSSI_CAL) + if (m_duplex || m_modemState == STATE_RSSI_CAL) SLE2(HIGH); else SLE1(HIGH); @@ -1125,7 +743,7 @@ uint16_t IO::readRSSI() } #if defined(DUPLEX) - if (m_duplex || m_calState == STATE_RSSI_CAL) + if (m_duplex || m_modemState == STATE_RSSI_CAL) SLE2(LOW); else SLE1(LOW); @@ -1234,6 +852,234 @@ void IO::configureBand() f_div = 1U; } +/// +/// +/// +/// +void IO::configureTxRx(DVM_STATE modemState) +{ + /* + ** Configure the remaining registers based on modem state. + */ + + switch (modemState) { + case STATE_CW: // 4FSK + { + // Dev: +1 symb (variable), symb rate = 4800 + + /* + ** Tx/Rx Clock (Register 3) & AFC (Register 10) + */ + ADF7021_REG3 = ADF7021_REG3_DMR; + ADF7021_REG10 = ADF7021_REG10_DMR; + + /* + ** Demodulator Setup (Register 4) + */ + uint16_t discBW = ADF7021_DISC_BW_DMR; + if (discBW + m_dmrDiscBWAdj < 0U) + discBW = 0U; + else + discBW = ADF7021_DISC_BW_DMR + m_dmrDiscBWAdj; + if (discBW > ADF7021_DISC_BW_MAX) + discBW = ADF7021_DISC_BW_MAX; + + uint16_t postBW = ADF7021_POST_BW_DMR; + if (postBW + m_dmrPostBWAdj < 0) + postBW = 0U; + else + postBW = ADF7021_POST_BW_DMR + m_dmrPostBWAdj; + if (postBW > ADF7021_POST_BW_MAX) + postBW = ADF7021_POST_BW_MAX; + + // K=32 + ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 + ADF7021_REG4 |= (uint32_t)0b011 << 4; // mode, 4FSK + ADF7021_REG4 |= (uint32_t)0b0 << 7; // cross product + ADF7021_REG4 |= (uint32_t)0b11 << 8; // invert clk/data + ADF7021_REG4 |= (uint32_t)(discBW & 0x3FFU) << 10; // discriminator BW + ADF7021_REG4 |= (uint32_t)(postBW & 0xFFFU) << 20; // post demod BW + ADF7021_REG4 |= (uint32_t)0b10 << 30; // IF filter (25 kHz) + + /* + ** 3FSK/4FSK Demod (Register 13) + */ + ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 + ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_DMR << 4; // slicer threshold + + /* + ** Transmit Modulation (Register 2) + */ + ADF7021_REG2 = (uint32_t)0b0010; // register 2 + ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level + ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA + ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) + ADF7021_REG2 |= (uint32_t)(m_cwIdTXLevel / div2) << 19; // deviation + ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) + } + break; + + case STATE_DMR: // 4FSK + { + // Dev: +1 symb 648 Hz, symb rate = 4800 + + /* + ** Tx/Rx Clock (Register 3) & AFC (Register 10) + */ + ADF7021_REG3 = ADF7021_REG3_DMR; + ADF7021_REG10 = ADF7021_REG10_DMR; + + /* + ** Demodulator Setup (Register 4) + */ + uint16_t discBW = ADF7021_DISC_BW_DMR; + if (discBW + m_dmrDiscBWAdj < 0U) + discBW = 0U; + else + discBW = ADF7021_DISC_BW_DMR + m_dmrDiscBWAdj; + if (discBW > ADF7021_DISC_BW_MAX) + discBW = ADF7021_DISC_BW_MAX; + + uint16_t postBW = ADF7021_POST_BW_DMR; + if (postBW + m_dmrPostBWAdj < 0) + postBW = 0U; + else + postBW = ADF7021_POST_BW_DMR + m_dmrPostBWAdj; + if (postBW > ADF7021_POST_BW_MAX) + postBW = ADF7021_POST_BW_MAX; + + // K=32 + ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 + ADF7021_REG4 |= (uint32_t)0b011 << 4; // mode, 4FSK + ADF7021_REG4 |= (uint32_t)0b0 << 7; // cross product + ADF7021_REG4 |= (uint32_t)0b11 << 8; // invert clk/data + ADF7021_REG4 |= (uint32_t)(discBW & 0x3FFU) << 10; // discriminator BW + ADF7021_REG4 |= (uint32_t)(postBW & 0xFFFU) << 20; // post demod BW + ADF7021_REG4 |= (uint32_t)0b10 << 30; // IF filter (25 kHz) + + /* + ** 3FSK/4FSK Demod (Register 13) + */ + ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 + ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_DMR << 4; // slicer threshold + + /* + ** Transmit Modulation (Register 2) + */ + ADF7021_REG2 = (uint32_t)0b0010; // register 2 + ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level + ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA + ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) + ADF7021_REG2 |= (uint32_t)(dmrDev / div2) << 19; // deviation +#if defined(ADF7021_DISABLE_RC_4FSK) + ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK) +#else + ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) +#endif + } + break; + + case STATE_P25: // 4FSK + { + // Dev: +1 symb 600 Hz, symb rate = 4800 + + /* + ** Tx/Rx Clock (Register 3) & AFC (Register 10) + */ + ADF7021_REG3 = ADF7021_REG3_P25; + ADF7021_REG10 = ADF7021_REG10_P25; + + /* + ** Demodulator Setup (Register 4) + */ + uint16_t discBW = ADF7021_DISC_BW_P25; + if (discBW + m_dmrDiscBWAdj < 0U) + discBW = 0U; + else + discBW = ADF7021_DISC_BW_P25 + m_dmrDiscBWAdj; + if (discBW > ADF7021_DISC_BW_MAX) + discBW = ADF7021_DISC_BW_MAX; + + uint16_t postBW = ADF7021_POST_BW_P25; + if (postBW + m_dmrPostBWAdj < 0) + postBW = 0U; + else + postBW = ADF7021_POST_BW_P25 + m_dmrPostBWAdj; + if (postBW > ADF7021_POST_BW_MAX) + postBW = ADF7021_POST_BW_MAX; + + // K=32 + ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 + ADF7021_REG4 |= (uint32_t)0b011 << 4; // mode, 4FSK + ADF7021_REG4 |= (uint32_t)0b0 << 7; // cross product + ADF7021_REG4 |= (uint32_t)0b11 << 8; // invert clk/data + ADF7021_REG4 |= (uint32_t)(discBW & 0x3FFU) << 10; // discriminator BW + ADF7021_REG4 |= (uint32_t)(postBW & 0xFFFU) << 20; // post demod BW + ADF7021_REG4 |= (uint32_t)0b00 << 30; // IF filter (12.5 kHz) + + /* + ** 3FSK/4FSK Demod (Register 13) + */ + ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 + ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_P25 << 4; // slicer threshold + + /* + ** Transmit Modulation (Register 2) + */ + ADF7021_REG2 = (uint32_t)0b0010; // register 2 + ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level + ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA + ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) + ADF7021_REG2 |= (uint32_t)(p25Dev / div2) << 19; // deviation +#if defined(ENABLE_P25_WIDE) || defined(ADF7021_DISABLE_RC_4FSK) + ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK) +#else + ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) +#endif + } + break; + default: // GMSK + { + // Dev: 1200 Hz, symb rate = 4800 + + /* + ** Tx/Rx Clock (Register 3) & AFC (Register 10) + */ + ADF7021_REG3 = ADF7021_REG3_DEFAULT; + ADF7021_REG10 = ADF7021_REG10_DEFAULT; + + /* + ** Demodulator Setup (Register 4) + */ + // K=32 + ADF7021_REG4 = (uint32_t)0b0100 << 0; // register 4 + ADF7021_REG4 |= (uint32_t)0b001 << 4; // mode, GMSK + ADF7021_REG4 |= (uint32_t)0b1 << 7; // dot product + ADF7021_REG4 |= (uint32_t)0b10 << 8; // invert data + ADF7021_REG4 |= (uint32_t)ADF7021_DISC_BW_DEFAULT << 10; // discriminator BW + ADF7021_REG4 |= (uint32_t)ADF7021_POST_BW_DEFAULT << 20; // post demod BW + ADF7021_REG4 |= (uint32_t)0b00 << 30; // IF filter (12.5 kHz) + + /* + ** 3FSK/4FSK Demod (Register 13) + */ + ADF7021_REG13 = (uint32_t)0b1101 << 0; // register 13 + ADF7021_REG13 |= (uint32_t)ADF7021_SLICER_TH_DEFAULT << 4; // slicer threshold + + /* + ** Transmit Modulation (Register 2) + */ + ADF7021_REG2 = (uint32_t)0b0010; // register 2 + ADF7021_REG2 |= (uint32_t)m_rfPower << 13; // power level + ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA + ADF7021_REG2 |= (uint32_t)0b00 << 28; // normal + ADF7021_REG2 |= (uint32_t)(ADF7021_DEV_DEFAULT / div2) << 19; // deviation + ADF7021_REG2 |= (uint32_t)0b001 << 4; // modulation (GMSK) + } + break; + } +} + /// /// /// diff --git a/FirmwareMain.cpp b/FirmwareMain.cpp index 09054c7..bdeadb1 100644 --- a/FirmwareMain.cpp +++ b/FirmwareMain.cpp @@ -38,7 +38,6 @@ // --------------------------------------------------------------------------- DVM_STATE m_modemState = STATE_IDLE; -DVM_STATE m_calState = STATE_IDLE; DVM_STATE m_modemStatePrev = STATE_IDLE; bool m_cwIdState = false; @@ -64,12 +63,12 @@ bool m_dcd = false; uint8_t m_control; -#if defined(DUPLEX) /** DMR BS */ +#if defined(DUPLEX) dmr::DMRIdleRX dmrIdleRX; dmr::DMRRX dmrRX; -dmr::DMRTX dmrTX; #endif +dmr::DMRTX dmrTX; /** DMR MS-DMO */ dmr::DMRDMORX dmrDMORX; @@ -107,7 +106,7 @@ void loop() serial.process(); // The following is for transmitting - if (m_dmrEnable && m_modemState == STATE_DMR && m_calState == STATE_IDLE) { + if (m_dmrEnable && m_modemState == STATE_DMR) { #if defined(DUPLEX) if (m_duplex) dmrTX.process(); @@ -122,16 +121,15 @@ void loop() p25TX.process(); if (m_modemState == STATE_DMR_DMO_CAL_1K || m_modemState == STATE_DMR_CAL_1K || - m_modemState == STATE_DMR_LF_CAL || m_modemState == STATE_DMR_CAL) + m_modemState == STATE_DMR_LF_CAL || m_modemState == STATE_DMR_CAL || + m_modemState == STATE_INT_CAL) calDMR.process(); if (m_modemState == STATE_P25_CAL_1K || m_modemState == STATE_P25_LF_CAL || m_modemState == STATE_P25_CAL) calP25.process(); -#if defined(SEND_RSSI_DATA) - if (m_calState == STATE_RSSI_CAL) + if (m_modemState == STATE_RSSI_CAL) calRSSI.process(); -#endif if (m_modemState == STATE_CW || m_modemState == STATE_IDLE) cwIdTX.process(); diff --git a/Globals.h b/Globals.h index c40c796..918f0da 100644 --- a/Globals.h +++ b/Globals.h @@ -85,7 +85,6 @@ const uint8_t MARK_NONE = 0x00U; // --------------------------------------------------------------------------- extern DVM_STATE m_modemState; -extern DVM_STATE m_calState; extern DVM_STATE m_modemStatePrev; extern bool m_cwIdState; @@ -106,12 +105,12 @@ extern uint8_t m_control; extern SerialPort serial; extern IO io; -#if defined(DUPLEX) /** DMR BS */ +#if defined(DUPLEX) extern dmr::DMRIdleRX dmrIdleRX; extern dmr::DMRRX dmrRX; -extern dmr::DMRTX dmrTX; #endif +extern dmr::DMRTX dmrTX; /** DMR MS-DMO */ extern dmr::DMRDMORX dmrDMORX; diff --git a/IO.cpp b/IO.cpp index 7a112e7..7a010e3 100644 --- a/IO.cpp +++ b/IO.cpp @@ -268,8 +268,22 @@ void IO::setDecode(bool dcd) /// void IO::setMode(DVM_STATE modemState) { - setDMRInt(modemState == STATE_DMR); - setP25Int(modemState == STATE_P25); + DVM_STATE relativeState = modemState; + + if ((modemState != STATE_IDLE) && (m_modemStatePrev != modemState)) { + DEBUG2("IO: setMode(): setting RF hardware", modemState); + if (serial.isCalState(modemState)) { + relativeState = serial.calRelativeState(modemState); + } + } + else { + return; + } + + rf1Conf(relativeState, true); + + setDMRInt(relativeState == STATE_DMR); + setP25Int(relativeState == STATE_P25); } /// diff --git a/IO.h b/IO.h index 3137211..4a03747 100644 --- a/IO.h +++ b/IO.h @@ -132,7 +132,7 @@ public: void getUDID(uint8_t* buffer); /// - void updateCal(); + void updateCal(DVM_STATE modemState); /// void delayBit(void); @@ -203,6 +203,8 @@ private: #endif /// void configureBand(); + /// + void configureTxRx(DVM_STATE modemState); /// void setTX(); diff --git a/SerialPort.cpp b/SerialPort.cpp index 0e7e39d..3cd38f4 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -103,8 +103,7 @@ SerialPort::SerialPort() : m_buffer(), m_ptr(0U), m_len(0U), - m_debug(false), - m_firstCal(false) + m_debug(false) { // stub } @@ -193,6 +192,8 @@ void SerialPort::process() break; case CMD_CAL_DATA: + DEBUG_DUMP(m_buffer + 3U, 2U); + DEBUG2("SerialPort: process(): CAL_DATA: len = ", m_len - 3U); if (m_modemState == STATE_DMR_DMO_CAL_1K || m_modemState == STATE_DMR_CAL_1K || m_modemState == STATE_DMR_LF_CAL || m_modemState == STATE_DMR_CAL) err = calDMR.write(m_buffer + 3U, m_len - 3U); @@ -361,6 +362,46 @@ void SerialPort::process() } } +/// +/// Helper to check if the modem is in a calibration state. +/// +/// +/// +bool SerialPort::isCalState(DVM_STATE state) +{ + // calibration mode check + if (state != STATE_P25_CAL_1K && + state != STATE_DMR_DMO_CAL_1K && state != STATE_DMR_CAL_1K && + state != STATE_DMR_LF_CAL && state != STATE_P25_LF_CAL && + state != STATE_RSSI_CAL && + state != STATE_P25_CAL && state != STATE_DMR_CAL && + state != STATE_INT_CAL) + return true; + + return false; +} + +/// +/// Helper to determine digital mode if the modem is in a calibration state. +/// +/// +/// +DVM_STATE SerialPort::calRelativeState(DVM_STATE state) +{ + if (isCalState(state)) { + if (state == STATE_DMR_DMO_CAL_1K || state == STATE_DMR_CAL_1K || + state == STATE_DMR_LF_CAL || state == STATE_DMR_CAL || + state == STATE_RSSI_CAL || state == STATE_INT_CAL) { + return STATE_DMR; + } else if(state != STATE_P25_CAL_1K && state != STATE_P25_LF_CAL && + state == STATE_P25_CAL) { + return STATE_P25; + } + } + + return STATE_CW; +} + /// /// Write DMR frame data to serial port. /// @@ -898,38 +939,26 @@ uint8_t SerialPort::setConfig(const uint8_t* data, uint8_t length) uint8_t dmrTXLevel = data[10U]; uint8_t p25TXLevel = data[12U]; - io.setDeviations(dmrTXLevel, p25TXLevel); - - if (modemState == STATE_DMR_CAL || modemState == STATE_DMR_DMO_CAL_1K || modemState == STATE_RSSI_CAL || - modemState == STATE_INT_CAL) { - m_dmrEnable = true; - m_modemState = STATE_DMR; - m_calState = modemState; - if (m_firstCal) - io.updateCal(); - if (modemState == STATE_RSSI_CAL) - io.rf1Conf(STATE_DMR, true); - } else { - m_modemState = modemState; - m_calState = STATE_IDLE; - } + m_modemState = modemState; m_dmrEnable = dmrEnable; m_p25Enable = p25Enable; m_duplex = !simplex; #if !defined(DUPLEX) - if (m_duplex && m_calState == STATE_IDLE) { + if (m_duplex) { DEBUG1("Full duplex not supported with this firmware"); return RSN_INVALID_REQUEST; } #elif defined(DUPLEX) && (defined(ZUMSPOT_ADF7021) || defined(LONESTAR_USB) || defined(SKYBRIDGE_HS)) - if (io.isDualBand() && m_duplex && m_calState == STATE_IDLE) { + if (io.isDualBand() && m_duplex) { DEBUG1("Full duplex is not supported on this board"); return RSN_INVALID_REQUEST; } #endif + io.setDeviations(dmrTXLevel, p25TXLevel); + p25TX.setPreambleCount(fdmaPreamble); dmrDMOTX.setPreambleCount(fdmaPreamble); @@ -944,20 +973,12 @@ uint8_t SerialPort::setConfig(const uint8_t* data, uint8_t length) dmrDMORX.setColorCode(colorCode); - if (!m_firstCal || (modemState != STATE_DMR_CAL && modemState != STATE_DMR_DMO_CAL_1K && - modemState != STATE_RSSI_CAL && modemState != STATE_INT_CAL)) { - if(m_dmrEnable) - io.rf1Conf(STATE_DMR, true); - else if(m_p25Enable) - io.rf1Conf(STATE_P25, true); + if (m_modemState != STATE_IDLE && isCalState(m_modemState)) { + io.updateCal(calRelativeState(m_modemState)); } io.start(); - if (modemState == STATE_DMR_CAL || modemState == STATE_DMR_DMO_CAL_1K || - modemState == STATE_RSSI_CAL || modemState == STATE_INT_CAL) - m_firstCal = true; - return RSN_OK; } @@ -973,7 +994,6 @@ uint8_t SerialPort::setMode(const uint8_t* data, uint8_t length) return RSN_ILLEGAL_LENGTH; DVM_STATE modemState = DVM_STATE(data[0U]); - DVM_STATE tmpState; if (modemState == m_modemState) return RSN_OK; @@ -982,19 +1002,7 @@ uint8_t SerialPort::setMode(const uint8_t* data, uint8_t length) if (ret != RSN_OK) return ret; - if (modemState == STATE_DMR_CAL || modemState == STATE_DMR_DMO_CAL_1K || - modemState == STATE_RSSI_CAL || modemState == STATE_INT_CAL) { - m_dmrEnable = true; - tmpState = STATE_DMR; - m_calState = modemState; - if (m_firstCal) - io.updateCal(); - } else { - tmpState = modemState; - m_calState = STATE_IDLE; - } - - setMode(tmpState); + setMode(modemState); return RSN_OK; } @@ -1108,11 +1116,6 @@ void SerialPort::setMode(DVM_STATE modemState) m_modemState = modemState; - if ((modemState != STATE_IDLE) && (m_modemStatePrev != modemState)) { - DEBUG1("SerialPort: setMode(): setting RF hardware"); - io.rf1Conf(modemState, true); - } - io.setMode(m_modemState); } diff --git a/SerialPort.h b/SerialPort.h index d78a180..3054e3c 100644 --- a/SerialPort.h +++ b/SerialPort.h @@ -145,6 +145,11 @@ public: /// Process data from serial port. void process(); + /// Helper to check if the modem is in a calibration state. + bool isCalState(DVM_STATE state); + /// Helper to determine digital mode if the modem is in a calibration state. + DVM_STATE calRelativeState(DVM_STATE state); + /// Write DMR frame data to serial port. void writeDMRData(bool slot, const uint8_t* data, uint8_t length); /// Write lost DMR frame data to serial port. @@ -178,8 +183,7 @@ private: uint8_t m_ptr; uint8_t m_len; - bool m_debug; - bool m_firstCal; + bool m_debug; /// Write acknowlegement. void sendACK(); diff --git a/dmr/CalDMR.cpp b/dmr/CalDMR.cpp index af76239..4af7185 100644 --- a/dmr/CalDMR.cpp +++ b/dmr/CalDMR.cpp @@ -113,19 +113,21 @@ CalDMR::CalDMR() : /// void CalDMR::process() { - switch (m_calState) { + switch (m_modemState) { case STATE_DMR_CAL: case STATE_DMR_LF_CAL: if (m_transmit) { - dmrDMOTX.setCal(true); - dmrDMOTX.process(); + dmrTX.setCal(true); + dmrTX.process(); } else { - dmrDMOTX.setCal(false); + dmrTX.setCal(false); } break; case STATE_DMR_CAL_1K: +#if defined(DUPLEX) dmr1kcal(); +#endif break; case STATE_DMR_DMO_CAL_1K: dmrDMO1kcal(); @@ -181,6 +183,7 @@ void CalDMR::createDataDMO1k(uint8_t n) /// void CalDMR::dmr1kcal() { +#if defined(DUPLEX) dmrTX.process(); uint16_t space = dmrTX.getSpace2(); @@ -223,6 +226,7 @@ void CalDMR::dmr1kcal() m_state = DMRCAL1K_IDLE; break; } +#endif } /// diff --git a/dmr/DMRDMOTX.cpp b/dmr/DMRDMOTX.cpp index d49b398..a6b8923 100644 --- a/dmr/DMRDMOTX.cpp +++ b/dmr/DMRDMOTX.cpp @@ -57,8 +57,7 @@ DMRDMOTX::DMRDMOTX() : m_poBuffer(), m_poLen(0U), m_poPtr(0U), - m_preambleCnt(DMRDMO_FIXED_DELAY), - m_cal(false) + m_preambleCnt(DMRDMO_FIXED_DELAY) { /* stub */ } @@ -130,15 +129,6 @@ uint8_t DMRDMOTX::writeData(const uint8_t* data, uint8_t length) return RSN_OK; } -/// -/// -/// -/// -void DMRDMOTX::setCal(bool start) -{ - m_cal = start ? true : false; -} - /// /// Sets the FDMA preamble count. /// @@ -165,39 +155,6 @@ uint16_t DMRDMOTX::getSpace() const // --------------------------------------------------------------------------- // Private Class Members // --------------------------------------------------------------------------- -/// -/// -/// -void DMRDMOTX::createCal() -{ - // 1.2 kHz sine wave generation - if (m_calState == STATE_DMR_CAL) { - for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) { - m_poBuffer[i] = 0x5FU; // +3, +3, -3, -3 pattern for deviation cal. - } - - m_poLen = DMR_FRAME_LENGTH_BYTES; - } - - // 80 Hz square wave generation - if (m_modemState == STATE_DMR_LF_CAL) { - for (unsigned int i = 0U; i < 7U; i++) { - m_poBuffer[i] = 0x55U; // +3, +3, ... pattern - } - - m_poBuffer[7U] = 0x5FU; // +3, +3, -3, -3 pattern - - for (unsigned int i = 8U; i < 15U; i++) { - m_poBuffer[i] = 0xFFU; // -3, -3, ... pattern - } - - m_poLen = 15U; - } - - m_poLen = DMR_FRAME_LENGTH_BYTES; - m_poPtr = 0U; -} - /// /// /// diff --git a/dmr/DMRDMOTX.h b/dmr/DMRDMOTX.h index 619aeae..cedeb2a 100644 --- a/dmr/DMRDMOTX.h +++ b/dmr/DMRDMOTX.h @@ -43,13 +43,13 @@ namespace dmr // Constants // --------------------------------------------------------------------------- -#define DMRDMO_FIXED_DELAY 300 // 300 = 62.49ms - // Delay Value * 0.2083 = Preamble Length (ms) + #define DMRDMO_FIXED_DELAY 300 // 300 = 62.49ms + // Delay Value * 0.2083 = Preamble Length (ms) -// --------------------------------------------------------------------------- -// Class Declaration -// Implements transmitter logic for DMR DMO mode operation. -// --------------------------------------------------------------------------- + // --------------------------------------------------------------------------- + // Class Declaration + // Implements transmitter logic for DMR DMO mode operation. + // --------------------------------------------------------------------------- class DSP_FW_API DMRDMOTX { public: @@ -62,9 +62,6 @@ namespace dmr /// Write data to the local buffer. uint8_t writeData(const uint8_t* data, uint8_t length); - /// Helper to set the calibration state for Tx. - void setCal(bool start); - /// Sets the FDMA preamble count. void setPreambleCount(uint8_t preambleCnt); @@ -80,11 +77,6 @@ namespace dmr uint32_t m_preambleCnt; - bool m_cal; - - /// - void createCal(); - /// void writeByte(uint8_t c); }; diff --git a/dmr/DMRTX.cpp b/dmr/DMRTX.cpp index be2e111..485bac1 100644 --- a/dmr/DMRTX.cpp +++ b/dmr/DMRTX.cpp @@ -34,8 +34,6 @@ using namespace dmr; -#if defined(DUPLEX) - // --------------------------------------------------------------------------- // Constants // --------------------------------------------------------------------------- @@ -119,6 +117,7 @@ void DMRTX::process() break; case DMRTXSTATE_CAL: + createCal(); break; default: @@ -278,6 +277,15 @@ void DMRTX::setStart(bool start) m_abort[1U] = false; } +/// +/// Helper to set the calibration state for Tx. +/// +/// +void DMRTX::setCal(bool start) +{ + m_state = start ? DMRTXSTATE_CAL : DMRTXSTATE_IDLE; +} + /// /// Helper to get how much space the slot 1 ring buffer has for samples. /// @@ -367,6 +375,42 @@ void DMRTX::createData(uint8_t slotIndex) m_poPtr = 0U; } +/// +/// +/// +void DMRTX::createCal() +{ + // 1.2 kHz sine wave generation + if (m_modemState == STATE_DMR_CAL) { + for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) { + m_poBuffer[i] = DMR_START_SYNC; + m_markBuffer[i] = MARK_NONE; + } + + m_poLen = DMR_FRAME_LENGTH_BYTES; + } + + // 80 Hz square wave generation + if (m_modemState == STATE_DMR_LF_CAL) { + for (unsigned int i = 0U; i < 7U; i++) { + m_poBuffer[i] = 0x55U; // +3, +3, ... pattern + m_markBuffer[i] = MARK_NONE; + } + + m_poBuffer[7U] = 0x5FU; // +3, +3, -3, -3 pattern + + for (unsigned int i = 8U; i < 15U; i++) { + m_poBuffer[i] = 0xFFU; // -3, -3, ... pattern + m_markBuffer[i] = MARK_NONE; + } + + m_poLen = 15U; + } + + m_poLen = DMR_FRAME_LENGTH_BYTES; + m_poPtr = 0U; +} + /// /// /// @@ -452,5 +496,3 @@ void DMRTX::writeByte(uint8_t c, uint8_t control) io.write(&bit, 1, &control_tmp); } } - -#endif // DUPLEX diff --git a/dmr/DMRTX.h b/dmr/DMRTX.h index d2c6bfc..9a64bd4 100644 --- a/dmr/DMRTX.h +++ b/dmr/DMRTX.h @@ -36,8 +36,6 @@ #include "dmr/DMRDefines.h" #include "SerialBuffer.h" -#if defined(DUPLEX) - namespace dmr { // --------------------------------------------------------------------------- @@ -78,6 +76,8 @@ namespace dmr /// Helper to set the start state for Tx. void setStart(bool start); + /// Helper to set the calibration state for Tx. + void setCal(bool start); /// Helper to get how much space the slot 1 ring buffer has for samples. uint8_t getSpace1() const; @@ -122,12 +122,12 @@ namespace dmr void createData(uint8_t slotIndex); /// void createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex); + /// + void createCal(); /// void writeByte(uint8_t c, uint8_t control); }; } // namespace dmr -#endif // DUPLEX - #endif // __DMR_TX_H__