diff --git a/ADF7021.cpp b/ADF7021.cpp index 13ec434..77447a0 100644 --- a/ADF7021.cpp +++ b/ADF7021.cpp @@ -11,29 +11,29 @@ // Licensed under the GPLv2 License (https://opensource.org/licenses/GPL-2.0) // /* - * Copyright (C) 2020,2021 by Jonathan Naylor G4KLX - * Copyright (C) 2016 by Jim McLaughlin KI6ZUM - * Copyright (C) 2016,2017,2018,2019,2020 by Andy Uribe CA6JAU - * Copyright (C) 2017 by Danilo DB4PLE - * Copyright (C) 2021 Bryan Biedenkapp N2PLL - * - * Some of the code is based on work of Guus Van Dooren PE1PLM: - * https://github.com/ki6zum/gmsk-dstar/blob/master/firmware/dvmega/dvmega.ino - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ +* Copyright (C) 2020,2021 by Jonathan Naylor G4KLX +* Copyright (C) 2016 by Jim McLaughlin KI6ZUM +* Copyright (C) 2016,2017,2018,2019,2020 by Andy Uribe CA6JAU +* Copyright (C) 2017 by Danilo DB4PLE +* Copyright (C) 2021 Bryan Biedenkapp N2PLL +* +* Some of the code is based on work of Guus Van Dooren PE1PLM: +* https://github.com/ki6zum/gmsk-dstar/blob/master/firmware/dvmega/dvmega.ino +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ #include #include "Globals.h" @@ -63,8 +63,13 @@ uint16_t RX_F_Divider; // Rx - 15-bit Frational_N uint8_t TX_N_Divider; // Tx - 8-bit Integer_N uint16_t TX_F_Divider; // Tx - 15-bit Frational_N -uint16_t m_dmrDev; -uint16_t m_p25Dev; +uint16_t dmrDev; +uint16_t p25Dev; + +int8_t m_dmrDiscBWAdj; +int8_t m_p25DiscBWAdj; +int8_t m_dmrPostBWAdj; +int8_t m_p25PostBWAdj; // --------------------------------------------------------------------------- // Global Functions @@ -376,162 +381,218 @@ void IO::rf1Conf(DVM_STATE modemState, bool reset) 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) - */ - // 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)ADF7021_DISC_BW_DMR << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)ADF7021_POST_BW_DMR << 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) + { + // 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) - */ - // 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)ADF7021_DISC_BW_DMR << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)ADF7021_POST_BW_DMR << 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_dmrDev / div2) << 19; // deviation + { + // 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) + ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK) #else - ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) + 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) - */ - // 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)ADF7021_DISC_BW_P25 << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)ADF7021_POST_BW_P25 << 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)(m_p25Dev / div2) << 19; // deviation + { + // 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) + ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK) #else - ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) + 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) + { + // 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; } @@ -665,124 +726,162 @@ void IO::rf2Conf(DVM_STATE modemState) 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) - */ - // 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)ADF7021_DISC_BW_DMR << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)ADF7021_POST_BW_DMR << 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_dmrDev / div2) << 19; // deviation + { + // 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) + ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK) #else - ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) + 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) - */ - // 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)ADF7021_DISC_BW_P25 << 10; // discriminator BW - ADF7021_REG4 |= (uint32_t)ADF7021_POST_BW_P25 << 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)(m_p25Dev / div2) << 19; // deviation + { + // 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) + ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK) #else - ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) + 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) + { + // 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; } @@ -892,8 +991,25 @@ void IO::rf2Conf(DVM_STATE modemState) /// void IO::setDeviations(uint8_t dmrTXLevel, uint8_t p25TXLevel) { - m_dmrDev = uint16_t((ADF7021_DEV_DMR * uint16_t(dmrTXLevel)) / 128U); - m_p25Dev = uint16_t((ADF7021_DEV_P25 * uint16_t(p25TXLevel)) / 128U); + dmrDev = uint16_t((ADF7021_DEV_DMR * uint16_t(dmrTXLevel)) / 128U); + p25Dev = uint16_t((ADF7021_DEV_P25 * uint16_t(p25TXLevel)) / 128U); +} + +/// +/// Sets the RF adjustment parameters. +/// +/// +/// +/// +/// +/// +/// +void IO::setRFAdjust(int8_t dmrDiscBWAdj, int8_t p25DiscBWAdj, int8_t dmrPostBWAdj, int8_t p25PostBWAdj) +{ + m_dmrDiscBWAdj = dmrDiscBWAdj; + m_p25DiscBWAdj = p25DiscBWAdj; + m_dmrPostBWAdj = dmrPostBWAdj; + m_p25PostBWAdj = p25PostBWAdj; } /// @@ -920,7 +1036,7 @@ void IO::updateCal() 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)(m_dmrDev / div2) << 19; // DMR deviation + ADF7021_REG2 |= (uint32_t)(dmrDev / div2) << 19; // DMR deviation ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) } @@ -1093,7 +1209,11 @@ void IO::configureBand() // NOTE: I've included support for this band, but, this could be problematic due to // the external VCO control on most (if not all) hotspots ADF7021_REG1 = ADF7021_REG1_UHF_T; // UHF (470 - 520), external VCO +#if defined(FORCE_UHF_INTERAL_L) + div2 = 2U; +#else div2 = 1U; +#endif } /** 842 - 900mhz */ @@ -1176,12 +1296,12 @@ uint32_t CIO::TXfreq() uint16_t CIO::devDMR() { - return (uint16_t)((ADF7021_PFD * m_dmrDev) / (f_div * 65536)); + return (uint16_t)((ADF7021_PFD * dmrDev) / (f_div * 65536)); } uint16_t CIO::devP25() { - return (uint16_t)((ADF7021_PFD * m_p25Dev) / (f_div * 65536)); + return (uint16_t)((ADF7021_PFD * p25Dev) / (f_div * 65536)); } void CIO::printConf() diff --git a/ADF7021.h b/ADF7021.h index dab3727..7be1057 100644 --- a/ADF7021.h +++ b/ADF7021.h @@ -84,11 +84,14 @@ #define ADF_BIT_READ(value, bit) (((value) >> (bit)) & 0x01) #if defined(ADF7021_DISABLE_RC_4FSK) -#define ADF7021_EVEN_BIT true +#define ADF7021_EVEN_BIT true #else -#define ADF7021_EVEN_BIT false +#define ADF7021_EVEN_BIT false #endif // ADF7021_DISABLE_RC_4FSK +#define ADF7021_DISC_BW_MAX 660 +#define ADF7021_POST_BW_MAX 1023 + /* - Most of the registers values are obteined from ADI eval software: http://www.analog.com/en/products/rf-microwave/integrated-transceivers-transmitters-receivers/low-power-rf-transceivers/adf7021.html @@ -105,21 +108,6 @@ // Transmit the carrier frequency: // #define TEST_TX -/*********************/ - -// Disable TX Raised Cosine filter for 4FSK modulation in ADF7021: -// #define ADF7021_DISABLE_RC_4FSK - -// Support for ADF7021-N version: -// #define ADF7021_N_VER - -// Enable AFC support for DMR, YSF, P25, and M17 (experimental): -// (AFC is already enabled by default in D-Star) -// #define ADF7021_ENABLE_4FSK_AFC - -// Configure AFC with positive initial frequency offset: -// #define ADF7021_AFC_POS - /** Support for 14.7456 MHz TCXO (modified RF7021SE boards) */ #if defined(ADF7021_14_7456) @@ -133,12 +121,20 @@ */ #define ADF7021_REG1_VHF 0x02175041 /** 136 - 174mhz */ #define ADF7021_REG1_VHF_220 0x021B5041 /** 219 - 225mhz */ +#if defined(FORCE_UHF_INTERAL_L) +#define ADF7021_REG1_UHF_380 0x001B5041 /** 380 - 431mhz */ +#else #define ADF7021_REG1_UHF_380 0x021B5041 /** 380 - 431mhz */ // this could be problematic due to // the external VCO control +#endif // FORCE_UHF_INTERAL_L #define ADF7021_REG1_UHF_1 0x00575041 /** 431 - 450mhz */ #define ADF7021_REG1_UHF_2 0x01D75041 /** 450 - 470mhz */ +#if defined(FORCE_UHF_INTERAL_L) +#define ADF7021_REG1_UHF_T 0x00235041 /** 470 - 520mhz */ +#else #define ADF7021_REG1_UHF_T 0x02235041 /** 470 - 520mhz */ // this could be problematic due to // the external VCO control +#endif // FORCE_UHF_INTERAL_L #define ADF7021_REG1_800 0x00535041 /** 842 - 900mhz */ #define ADF7021_REG1_900 0x01D35041 /** 900 - 950mhz */ @@ -234,12 +230,20 @@ */ #define ADF7021_REG1_VHF 0x02175021 /** 136 - 174mhz */ #define ADF7021_REG1_VHF_220 0x021B5021 /** 219 - 225mhz */ +#if defined(FORCE_UHF_INTERAL_L) +#define ADF7021_REG1_UHF_380 0x001B5021 /** 380 - 431mhz */ +#else #define ADF7021_REG1_UHF_380 0x021B5021 /** 380 - 431mhz */ // this could be problematic due to -// the external VCO control + // the external VCO control +#endif // FORCE_UHF_INTERAL_L #define ADF7021_REG1_UHF_1 0x00575021 /** 431 - 450mhz */ #define ADF7021_REG1_UHF_2 0x01D75021 /** 450 - 470mhz */ +#if defined(FORCE_UHF_INTERAL_L) +#define ADF7021_REG1_UHF_T 0x00235021 /** 470 - 520mhz */ +#else #define ADF7021_REG1_UHF_T 0x02235021 /** 470 - 520mhz */ // this could be problematic due to // the external VCO control +#endif // FORCE_UHF_INTERAL_L #define ADF7021_REG1_800 0x00535021 /** 842 - 900mhz */ #define ADF7021_REG1_900 0x01D35021 /** 900 - 950mhz */ diff --git a/Defines.h b/Defines.h index a483955..bb7fcb5 100644 --- a/Defines.h +++ b/Defines.h @@ -126,6 +126,22 @@ typedef unsigned long long ulong64_t; // AGC OFF, highest gain // #define AD7021_GAIN_HIGH +// Disable TX Raised Cosine filter for 4FSK modulation in ADF7021 +// #define ADF7021_DISABLE_RC_4FSK + +// Support for ADF7021-N version: +// #define ADF7021_N_VER + +// Enable AFC support for DMR, YSF, P25, and M17 (experimental) +// (AFC is already enabled by default in D-Star) +// #define ADF7021_ENABLE_4FSK_AFC + +// Configure AFC with positive initial frequency offset +// #define ADF7021_AFC_POS + +// Force the internal L (internal VCO inductor) for UHF 380 and T-band +#define FORCE_UHF_INTERAL_L + // Enable mode detection #define ENABLE_SCAN_MODE diff --git a/IO.h b/IO.h index 74ae21c..3137211 100644 --- a/IO.h +++ b/IO.h @@ -112,6 +112,8 @@ public: void setDeviations(uint8_t dmrTXLevel, uint8_t p25TXLevel); /// Sets the RF parameters. uint8_t setRFParams(uint32_t rxFreq, uint32_t txFreq, uint8_t rfPower); + /// Sets the RF adjustment parameters. + void setRFAdjust(int8_t dmrDiscBWAdj, int8_t p25DiscBWAdj, int8_t dmrPostBWAdj, int8_t p25PostBWAdj); /// Flag indicating the TX ring buffer has overflowed. bool hasTXOverflow(void); diff --git a/Makefile.STM32FX b/Makefile.STM32FX index 51f5502..5705961 100644 --- a/Makefile.STM32FX +++ b/Makefile.STM32FX @@ -7,23 +7,23 @@ CLK_PI_F4=12000000 CLK_DEF=8000000 # Directory Structure -BINDIR=bin +BINDIR=. OBJDIR_F1=obj_f1 OBJDIR_F4=obj_f4 # Output files -BINELF_F1=mmdvm_f1.elf -BINHEX_F1=mmdvm_f1.hex -BINBIN_F1=mmdvm_f1.bin -BINELF_F1BL=mmdvm_f1bl.elf -BINHEX_F1BL=mmdvm_f1bl.hex -BINBIN_F1BL=mmdvm_f1bl.bin -BINELF_F1NOBL=mmdvm_f1nobl.elf -BINHEX_F1NOBL=mmdvm_f1nobl.hex -BINBIN_F1NOBL=mmdvm_f1nobl.bin -BINELF_F4=mmdvm_f4.elf -BINHEX_F4=mmdvm_f4.hex -BINBIN_F4=mmdvm_f4.bin +BINELF_F1=dvm-firmware-hs_f1.elf +BINHEX_F1=dvm-firmware-hs_f1.hex +BINBIN_F1=dvm-firmware-hs_f1.bin +BINELF_F1BL=dvm-firmware-hs_f1bl.elf +BINHEX_F1BL=dvm-firmware-hs_f1bl.hex +BINBIN_F1BL=dvm-firmware-hs_f1bl.bin +BINELF_F1NOBL=dvm-firmware-hs_f1nobl.elf +BINHEX_F1NOBL=dvm-firmware-hs_f1nobl.hex +BINBIN_F1NOBL=dvm-firmware-hs_f1nobl.bin +BINELF_F4=dvm-firwmare-hs_f4.elf +BINHEX_F4=dvm-firmware-hs_f4.hex +BINBIN_F4=dvm-firmware-hs_f4.bin # Header directories INC_F1= . $(F1_LIB_PATH)/CMSIS/ $(F1_LIB_PATH)/Device/ $(F1_LIB_PATH)/STM32F10x_StdPeriph_Driver/inc/ $(F1_LIB_PATH)/usb/inc/ @@ -64,64 +64,6 @@ NM=arm-none-eabi-nm SIZE=arm-none-eabi-size A2L=arm-none-eabi-addr2line -# Configure vars depending on OS -ifeq ($(OS),Windows_NT) - CLEANCMD=del /S *.o *.hex *.bin *.elf - MDDIRS=md $@ - DFU_UTIL=./$(F1_LIB_PATH)/utils/win/dfu-util.exe - STM32FLASH=./$(F1_LIB_PATH)/utils/win/stm32flash.exe -else - CLEANCMD=rm -f $(OBJ_F1BL) $(OBJ_F4) $(OBJ_F7) $(BINDIR)/*.hex $(BINDIR)/mmdvm_f1.bin $(BINDIR)/mmdvm_f1bl.bin $(BINDIR)/mmdvm_f1nobl.bin $(BINDIR)/*.elf - MDDIRS=mkdir $@ - - ifeq ($(shell uname -s),Linux) - ST_FLASH_ON_PATH=$(shell which st-flash) - ST_FLASH_IS_ON_PATH=$(.SHELLSTATUS) - ifeq ($(shell uname -m),x86_64) - DFU_RST=./$(F1_LIB_PATH)/utils/linux64/upload-reset - DFU_UTIL=./$(F1_LIB_PATH)/utils/linux64/dfu-util - DFU_RST=./$(F1_LIB_PATH)/utils/linux64/upload-reset - DFU_UTIL=./$(F1_LIB_PATH)/utils/linux64/dfu-util - ifeq ($(ST_FLASH_IS_ON_PATH),0) - ST_FLASH=$(ST_FLASH_ON_PATH) - ST_FLASH_OPTS=--flash=128k - else - ST_FLASH=./$(F1_LIB_PATH)/utils/linux64/st-flash - ST_FLASH_OPTS= - endif - STM32FLASH=./$(F1_LIB_PATH)/utils/linux64/stm32flash - else ifeq ($(shell uname -m),armv7l) - DFU_RST=./$(F1_LIB_PATH)/utils/rpi32/upload-reset - DFU_UTIL=./$(F1_LIB_PATH)/utils/rpi32/dfu-util - ST_FLASH=./$(F1_LIB_PATH)/utils/rpi32/st-flash - STM32FLASH=./$(F1_LIB_PATH)/utils/rpi32/stm32flash - else ifeq ($(shell uname -m),armv6l) - DFU_RST=./$(F1_LIB_PATH)/utils/rpi32/upload-reset - DFU_UTIL=./$(F1_LIB_PATH)/utils/rpi32/dfu-util - ST_FLASH=./$(F1_LIB_PATH)/utils/rpi32/st-flash - STM32FLASH=./$(F1_LIB_PATH)/utils/rpi32/stm32flash - else - DFU_RST=./$(F1_LIB_PATH)/utils/linux/upload-reset - DFU_UTIL=./$(F1_LIB_PATH)/utils/linux/dfu-util - ifeq ($(ST_FLASH_IS_ON_PATH),0) - ST_FLASH=$(ST_FLASH_ON_PATH) - ST_FLASH_OPTS=--flash=128k - else - ST_FLASH=./$(F1_LIB_PATH)/utils/linux/st-flash - ST_FLASH_OPTS= - endif - STM32FLASH=./$(F1_LIB_PATH)/utils/linux/stm32flash - endif - endif - - ifeq ($(shell uname -s),Darwin) - DFU_RST=./$(F1_LIB_PATH)/utils/macosx/upload-reset - DFU_UTIL=./$(F1_LIB_PATH)/utils/macosx/dfu-util - ST_FLASH=./$(F1_LIB_PATH)/utils/macosx/st-flash - STM32FLASH=./$(F1_LIB_PATH)/utils/macosx/stm32flash - endif -endif - # Default reference oscillator frequencies ifndef $(OSC) ifeq ($(MAKECMDGOALS),pi-f4) @@ -203,8 +145,18 @@ lonestar-usb: CFLAGS+=-DLONESTAR_USB -DSTM32_USB_HOST lonestar-usb: CXXFLAGS+=-DLONESTAR_USB -DSTM32_USB_HOST lonestar-usb: bl -mmdvm-hs-hat: zumspot-adf7021 -mmdvm-hs-hat-dual: zumspot-adf7021-duplex +mmdvm-hs-hat: CFLAGS+=-DMMDVM_HS_HAT_REV12 -DSTM32_USART1_HOST +mmdvm-hs-hat: CXXFLAGS+=-DMMDVM_HS_HAT_REV12 -DSTM32_USART1_HOST +mmdvm-hs-hat: hs +mmdvm-hs-hat-dual: CFLAGS+=-DDUPLEX +mmdvm-hs-hat-dual: CXXFLAGS+=-DDUPLEX +mmdvm-hs-hat-dual: mmdvm-hs-hat +mmdvm-hs-hat-usb: CFLAGS+=-DMMDVM_HS_HAT_REV12 -DSTM32_USB_HOST +mmdvm-hs-hat-usb: CXXFLAGS+=-DMMDVM_HS_HAT_REV12 -DSTM32_USB_HOST +mmdvm-hs-hat-usb: bl +mmdvm-hs-hat-usb-dual: CFLAGS+=-DDUPLEX +mmdvm-hs-hat-usb-dual: CXXFLAGS+=-DDUPLEX +mmdvm-hs-hat-usb-dual: mmdvm-hs-hat-usb pi-f4: CFLAGS+=$(CFLAGS_F4) $(DEFS_PI_F4) pi-f4: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_PI_F4) @@ -248,31 +200,34 @@ release_f4: $(OBJDIR_F4) release_f4: $(BINDIR)/$(BINBIN_F4) $(BINDIR): - $(MDDIRS) + mkdir $@ $(OBJDIR_F1): - $(MDDIRS) - $(MDDIRS)/dmr - $(MDDIRS)/p25 + mkdir $@ + mkdir $@/dmr + mkdir $@/p25 $(OBJDIR_F4): - $(MDDIRS) - $(MDDIRS)/dmr - $(MDDIRS)/p25 + mkdir $@ + mkdir $@/dmr + mkdir $@/p25 $(BINDIR)/$(BINBIN_F1BL): $(BINDIR)/$(BINELF_F1BL) $(CP) -O binary $< $@ $(BINDIR)/$(BINELF_F1BL): $(OBJ_F1BL) $(CXX) $(OBJ_F1BL) $(LDFLAGS) -o $@ $(SIZE) $(BINDIR)/$(BINELF_F1BL) + $(BINDIR)/$(BINBIN_F1NOBL): $(BINDIR)/$(BINELF_F1NOBL) $(CP) -O binary $< $@ $(BINDIR)/$(BINELF_F1NOBL): $(OBJ_F1BL) $(CXX) $(OBJ_F1BL) $(LDFLAGS) -o $@ $(SIZE) $(BINDIR)/$(BINELF_F1NOBL) + $(BINDIR)/$(BINBIN_F1): $(BINDIR)/$(BINELF_F1) $(CP) -O binary $< $@ $(BINDIR)/$(BINELF_F1): $(OBJ_F1) $(CXX) $(OBJ_F1) $(LDFLAGS) -o $@ $(SIZE) $(BINDIR)/$(BINELF_F1) + $(BINDIR)/$(BINBIN_F4): $(BINDIR)/$(BINELF_F4) $(CP) -O binary $< $@ $(BINDIR)/$(BINELF_F4): $(OBJ_F4) diff --git a/SerialPort.cpp b/SerialPort.cpp index 1dbff83..bfbe557 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -177,15 +177,11 @@ void SerialPort::process() break; case CMD_SET_SYMLVLADJ: - err = setSymbolLvlAdj(m_buffer + 3U, m_len - 3U); - if (err == RSN_OK) - sendACK(); - else - sendNAK(err); + sendACK(); // CMD_SET_RXLEVEL not supported by HS break; case CMD_SET_RXLEVEL: - sendNAK(RSN_INVALID_REQUEST); // CMD_SET_RXLEVEL not supported by HS + sendACK(); // CMD_SET_RXLEVEL not supported by HS break; case CMD_SET_RFPARAMS: @@ -200,10 +196,8 @@ void SerialPort::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) err = calDMR.write(m_buffer + 3U, m_len - 3U); -/* if (m_modemState == STATE_P25_CAL_1K || m_modemState == STATE_P25_LF_CAL || m_modemState == STATE_P25_CAL) err = calP25.write(m_buffer + 3U, m_len - 3U); -*/ if (err == RSN_OK) { sendACK(); } @@ -756,7 +750,7 @@ void SerialPort::getStatus() reply[1U] = 11U; reply[2U] = CMD_GET_STATUS; - reply[3U] = 0x00U; + reply[3U] = 0x01U; if (m_dmrEnable) reply[3U] |= 0x02U; if (m_p25Enable) @@ -823,7 +817,7 @@ void SerialPort::getVersion() ::memcpy(reply + 5U, 0x00U, 16U); io.getUDID(reply + 5U); - uint8_t count = 4U; + uint8_t count = 21U; for (uint8_t i = 0U; HARDWARE[i] != 0x00U; i++, count++) reply[count] = HARDWARE[i]; @@ -1127,49 +1121,6 @@ void SerialPort::setMode(DVM_STATE modemState) io.setMode(m_modemState); } -/// -/// Sets the fine-tune symbol levels. -/// -/// -/// -/// -uint8_t SerialPort::setSymbolLvlAdj(const uint8_t* data, uint8_t length) -{ - if (length < 4U) - return RSN_ILLEGAL_LENGTH; - - int8_t dmrSymLvl3Adj = int8_t(data[0U]) - 128; - if (dmrSymLvl3Adj > 128) - return RSN_INVALID_REQUEST; - if (dmrSymLvl3Adj < -128) - return RSN_INVALID_REQUEST; - - int8_t dmrSymLvl1Adj = int8_t(data[1U]) - 128; - if (dmrSymLvl1Adj > 128) - return RSN_INVALID_REQUEST; - if (dmrSymLvl1Adj < -128) - return RSN_INVALID_REQUEST; - - int8_t p25SymLvl3Adj = int8_t(data[2U]) - 128; - if (p25SymLvl3Adj > 128) - return RSN_INVALID_REQUEST; - if (p25SymLvl3Adj < -128) - return RSN_INVALID_REQUEST; - - int8_t p25SymLvl1Adj = int8_t(data[3U]) - 128; - if (p25SymLvl1Adj > 128) - return RSN_INVALID_REQUEST; - if (p25SymLvl1Adj < -128) - return RSN_INVALID_REQUEST; - - p25TX.setSymbolLvlAdj(p25SymLvl3Adj, p25SymLvl1Adj); - - dmrDMOTX.setSymbolLvlAdj(dmrSymLvl3Adj, dmrSymLvl1Adj); - dmrTX.setSymbolLvlAdj(dmrSymLvl3Adj, dmrSymLvl1Adj); - - return RSN_OK; -} - /// /// Sets the RF parameters. /// @@ -1178,7 +1129,7 @@ uint8_t SerialPort::setSymbolLvlAdj(const uint8_t* data, uint8_t length) /// uint8_t SerialPort::setRFParams(const uint8_t* data, uint8_t length) { - if (length < 10U) + if (length < 14U) return RSN_ILLEGAL_LENGTH; uint32_t rxFreq, txFreq; @@ -1196,5 +1147,31 @@ uint8_t SerialPort::setRFParams(const uint8_t* data, uint8_t length) rfPower = data[9U]; + int8_t dmrDiscBWAdj = int8_t(data[10U]) - 128; + if (dmrDiscBWAdj > 128) + return RSN_INVALID_REQUEST; + if (dmrDiscBWAdj < -128) + return RSN_INVALID_REQUEST; + + int8_t p25DiscBWAdj = int8_t(data[11U]) - 128; + if (p25DiscBWAdj > 128) + return RSN_INVALID_REQUEST; + if (p25DiscBWAdj < -128) + return RSN_INVALID_REQUEST; + + int8_t dmrPostBWAdj = int8_t(data[12U]) - 128; + if (dmrPostBWAdj > 128) + return RSN_INVALID_REQUEST; + if (dmrPostBWAdj < -128) + return RSN_INVALID_REQUEST; + + int8_t p25PostBWAdj = int8_t(data[13U]) - 128; + if (p25PostBWAdj > 128) + return RSN_INVALID_REQUEST; + if (p25PostBWAdj < -128) + return RSN_INVALID_REQUEST; + + io.setRFAdjust(dmrDiscBWAdj, p25DiscBWAdj, dmrPostBWAdj, p25PostBWAdj); + return io.setRFParams(rxFreq, txFreq, rfPower); } diff --git a/SerialPort.h b/SerialPort.h index 8e9e15e..d78a180 100644 --- a/SerialPort.h +++ b/SerialPort.h @@ -197,8 +197,6 @@ private: uint8_t setMode(const uint8_t* data, uint8_t length); /// Sets the modem state. void setMode(DVM_STATE modemState); - /// Sets the fine-tune symbol levels. - uint8_t setSymbolLvlAdj(const uint8_t* data, uint8_t length); /// Sets the RF parameters. uint8_t setRFParams(const uint8_t* data, uint8_t length); diff --git a/dmr/DMRDMOTX.cpp b/dmr/DMRDMOTX.cpp index 6e01f00..d49b398 100644 --- a/dmr/DMRDMOTX.cpp +++ b/dmr/DMRDMOTX.cpp @@ -153,16 +153,6 @@ void DMRDMOTX::setPreambleCount(uint8_t preambleCnt) m_preambleCnt = 1200U; } -/// -/// Sets the fine adjust 4FSK symbol levels. -/// -/// +3/-3 symbol adjust. -/// +1/-1 symbol adjust. -void DMRDMOTX::setSymbolLvlAdj(int8_t level3Adj, int8_t level1Adj) -{ - /* ignored ADF7021 doesn't allow direct symbol level adjustments */ -} - /// /// Helper to get how much space the ring buffer has for samples. /// diff --git a/dmr/DMRDMOTX.h b/dmr/DMRDMOTX.h index 86c13bf..619aeae 100644 --- a/dmr/DMRDMOTX.h +++ b/dmr/DMRDMOTX.h @@ -67,8 +67,6 @@ namespace dmr /// Sets the FDMA preamble count. void setPreambleCount(uint8_t preambleCnt); - /// Sets the fine adjust 4FSK symbol levels. - void setSymbolLvlAdj(int8_t level3Adj, int8_t level1Adj); /// Helper to get how much space the ring buffer has for samples. uint16_t getSpace() const; diff --git a/dmr/DMRTX.cpp b/dmr/DMRTX.cpp index deb63fd..be2e111 100644 --- a/dmr/DMRTX.cpp +++ b/dmr/DMRTX.cpp @@ -308,16 +308,6 @@ void DMRTX::setColorCode(uint8_t colorCode) slotType.encode(colorCode, DT_IDLE, m_idle); } -/// -/// Sets the fine adjust 4FSK symbol levels. -/// -/// +3/-3 symbol adjust. -/// +1/-1 symbol adjust. -void DMRTX::setSymbolLvlAdj(int8_t level3Adj, int8_t level1Adj) -{ - /* ignored ADF7021 doesn't allow direct symbol level adjustments */ -} - /// /// Helper to reset data values to defaults for slot 1 FIFO. /// diff --git a/dmr/DMRTX.h b/dmr/DMRTX.h index 0f52d1a..d2c6bfc 100644 --- a/dmr/DMRTX.h +++ b/dmr/DMRTX.h @@ -86,8 +86,6 @@ namespace dmr /// Sets the DMR color code. void setColorCode(uint8_t colorCode); - /// Sets the fine adjust 4FSK symbol levels. - void setSymbolLvlAdj(int8_t level3Adj, int8_t level1Adj); /// Helper to reset data values to defaults for slot 1 FIFO. void resetFifo1(); diff --git a/dvm-firmware-hs.vcxproj b/dvm-firmware-hs.vcxproj index c95692d..f3c2a71 100644 --- a/dvm-firmware-hs.vcxproj +++ b/dvm-firmware-hs.vcxproj @@ -87,7 +87,7 @@ Level3 true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + MMDVM_HS_DUAL_HAT_REV10;DUPLEX;STM32F10X_MD;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(ProjectDir);%(AdditionalIncludeDirectories) diff --git a/p25/P25TX.cpp b/p25/P25TX.cpp index f0eca9a..bf15da1 100644 --- a/p25/P25TX.cpp +++ b/p25/P25TX.cpp @@ -163,16 +163,6 @@ void P25TX::setPreambleCount(uint8_t preambleCnt) m_preambleCnt = 1200U; } -/// -/// Sets the fine adjust 4FSK symbol levels. -/// -/// +3/-3 symbol adjust. -/// +1/-1 symbol adjust. -void P25TX::setSymbolLvlAdj(int8_t level3Adj, int8_t level1Adj) -{ - /* ignored ADF7021 doesn't allow direct symbol level adjustments */ -} - /// /// Helper to set the calibration state for Tx. /// diff --git a/p25/P25TX.h b/p25/P25TX.h index f1e0899..b34d50d 100644 --- a/p25/P25TX.h +++ b/p25/P25TX.h @@ -71,8 +71,6 @@ namespace p25 /// Sets the FDMA preamble count. void setPreambleCount(uint8_t preambleCnt); - /// Sets the fine adjust 4FSK symbol levels. - void setSymbolLvlAdj(int8_t level3Adj, int8_t level1Adj); /// Helper to set the calibration state for Tx. void setCal(bool start);