From ba1896968a26375013cd2d731d7892fe5da2c47e Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Fri, 26 Nov 2021 14:14:30 +0000 Subject: [PATCH] port upstream changes manually from https://github.com/jelimoore/dvmhost ceb967b3c9b519a22c3ec4d5cfe10f44cc413c01; add support to set rf power from configuration; --- host/Host.cpp | 11 +++++++ modem/Modem.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++++++ modem/Modem.h | 10 ++++++ 3 files changed, 105 insertions(+) diff --git a/host/Host.cpp b/host/Host.cpp index 27484b7c..e9a986f3 100644 --- a/host/Host.cpp +++ b/host/Host.cpp @@ -13,6 +13,7 @@ /* * Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX * Copyright (C) 2017-2021 by Bryan Biedenkapp N2PLL +* Copyright (C) 2021 by Nat Moore * * 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 @@ -1504,6 +1505,7 @@ bool Host::createModem() uint8_t p25CorrCount = (uint8_t)modemConf["p25CorrCount"].as(4U); int rxDCOffset = modemConf["rxDCOffset"].as(0); int txDCOffset = modemConf["txDCOffset"].as(0); + uint8_t rfPower = (uint8_t)modemConf["rfPower"].as(100U); int dmrSymLevel3Adj = modemConf["dmrSymLvl3Adj"].as(0); int dmrSymLevel1Adj = modemConf["dmrSymLvl1Adj"].as(0); int p25SymLevel3Adj = modemConf["p25SymLvl3Adj"].as(0); @@ -1524,6 +1526,13 @@ bool Host::createModem() if (packetPlayoutTime < 1U) packetPlayoutTime = 1U; + if (rfPower == 0U) { // clamp to 1 + rfPower = 1U; + } + if (rfPower > 100U) { // clamp to 100 + rfPower = 100U; + } + LogInfo("Modem Parameters"); LogInfo(" Port Type: %s", portType.c_str()); @@ -1609,6 +1618,7 @@ bool Host::createModem() LogInfo(" P25 Corr. Count: %u (%.1fms)", p25CorrCount, float(p25CorrCount) * 0.667F); LogInfo(" RX DC Offset: %d", rxDCOffset); LogInfo(" TX DC Offset: %d", txDCOffset); + LogInfo(" RF Power Level: %u", rfPower); LogInfo(" RX Level: %.1f%%", rxLevel); LogInfo(" CW Id TX Level: %.1f%%", cwIdTXLevel); LogInfo(" DMR TX Level: %.1f%%", dmrTXLevel); @@ -1625,6 +1635,7 @@ bool Host::createModem() m_modem->setLevels(rxLevel, cwIdTXLevel, dmrTXLevel, p25TXLevel); m_modem->setSymbolAdjust(dmrSymLevel3Adj, dmrSymLevel1Adj, p25SymLevel3Adj, p25SymLevel1Adj); m_modem->setDCOffsetParams(txDCOffset, rxDCOffset); + m_modem->setRFParams(m_rxFrequency, m_txFrequency, rfPower); m_modem->setDMRColorCode(m_dmrColorCode); m_modem->setP25NAC(m_p25NAC); diff --git a/modem/Modem.cpp b/modem/Modem.cpp index ee416103..9952c2d7 100644 --- a/modem/Modem.cpp +++ b/modem/Modem.cpp @@ -13,6 +13,7 @@ /* * Copyright (C) 2011-2021 by Jonathan Naylor G4KLX * Copyright (C) 2017-2021 by Bryan Biedenkapp N2PLL +* Copyright (C) 2021 by Nat Moore * * 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 @@ -94,6 +95,9 @@ Modem::Modem(port::IModemPort* port, bool duplex, bool rxInvert, bool txInvert, m_p25Enabled(false), m_rxDCOffset(0), m_txDCOffset(0), + m_rxFrequency(0U), + m_txFrequency(0U), + m_rfPower(0U), m_dmrSymLevel3Adj(0), m_dmrSymLevel1Adj(0), m_p25SymLevel3Adj(0), @@ -214,6 +218,19 @@ void Modem::setSymbolAdjust(int dmrSymLevel3Adj, int dmrSymLevel1Adj, int p25Sym m_p25SymLevel1Adj = 0; } +/// +/// Sets the RF parameters. +/// +/// +/// +/// +void Modem::setRFParams(uint32_t rxFreq, uint32_t txFreq, uint8_t rfPower) +{ + m_rfPower = rfPower; + m_rxFrequency = rxFreq; + m_txFrequency = txFreq; +} + /// /// Sets the DMR color code. /// @@ -358,6 +375,16 @@ bool Modem::open() return true; } + ret = writeRFParams(); + if (!ret) { + ret = writeRFParams(); + if (!ret) { + LogError(LOG_MODEM, "Modem unresponsive to RF parameters set after 2 attempts. Stopping."); + m_port->close(); + return false; + } + } + ret = writeConfig(); if (!ret) { ret = writeConfig(); @@ -1438,6 +1465,63 @@ bool Modem::writeSymbolAdjust() return true; } +/// +/// Write RF parameters to the air interface modem. +/// +/// +bool Modem::writeRFParams() +{ + unsigned char buffer[13U]; + + buffer[0U] = DVM_FRAME_START; + buffer[1U] = 13U; + buffer[2U] = CMD_SET_RFPARAMS; + + buffer[3U] = 0x00U; + + buffer[4U] = (m_rxFrequency >> 0) & 0xFFU; + buffer[5U] = (m_rxFrequency >> 8) & 0xFFU; + buffer[6U] = (m_rxFrequency >> 16) & 0xFFU; + buffer[7U] = (m_rxFrequency >> 24) & 0xFFU; + + buffer[8U] = (m_txFrequency >> 0) & 0xFFU; + buffer[9U] = (m_txFrequency >> 8) & 0xFFU; + buffer[10U] = (m_txFrequency >> 16) & 0xFFU; + buffer[11U] = (m_txFrequency >> 24) & 0xFFU; + + buffer[12U] = (unsigned char)(m_rfPower * 2.55F + 0.5F); + + // CUtils::dump(1U, "Written", buffer, len); + + int ret = m_port->write(buffer, 13U); + if (ret <= 0) + return false; + + unsigned int count = 0U; + RESP_TYPE_DVM resp; + do { + Thread::sleep(10U); + + resp = getResponse(); + if (resp == RTM_OK && m_buffer[2U] != RSN_OK && m_buffer[2U] != RSN_NAK) { + count++; + if (count >= MAX_RESPONSES) { + LogError(LOG_MODEM, "The DVM is not responding to the SET_RFPARAMS command"); + return false; + } + } + } while (resp == RTM_OK && m_buffer[2U] != RSN_OK && m_buffer[2U] != RSN_NAK); + + // CUtils::dump(1U, "Response", m_buffer, m_length); + + if (resp == RTM_OK && m_buffer[2U] == RSN_NAK) { + LogError(LOG_MODEM, "Received a NAK to the SET_RFPARAMS command from the modem"); + return false; + } + + return true; +} + /// /// Print debug air interface messages to the host log. /// diff --git a/modem/Modem.h b/modem/Modem.h index c6ac59b6..2a30ac33 100644 --- a/modem/Modem.h +++ b/modem/Modem.h @@ -13,6 +13,7 @@ /* * Copyright (C) 2011-2021 by Jonathan Naylor G4KLX * Copyright (C) 2017-2021 by Bryan Biedenkapp N2PLL +* Copyright (C) 2021 by Nat Moore * * 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 @@ -100,6 +101,7 @@ namespace modem CMD_SET_SYMLVLADJ = 0x04U, CMD_SET_RXLEVEL = 0x05U, + CMD_SET_RFPARAMS = 0x06U, CMD_CAL_DATA = 0x08U, CMD_RSSI_DATA = 0x09U, @@ -190,6 +192,8 @@ namespace modem void setLevels(float rxLevel, float cwIdTXLevel, float dmrTXLevel, float p25TXLevel); /// Sets the symbol adjustment levels. void setSymbolAdjust(int dmrSymLevel3Adj, int dmrSymLevel1Adj, int p25SymLevel3Adj, int p25SymLevel1Adj); + /// Sets the RF parameters. + void setRFParams(uint32_t rxFreq, uint32_t txFreq, uint8_t rfPower); /// Sets the DMR color code. void setDMRColorCode(uint32_t colorCode); /// Sets the P25 NAC. @@ -312,6 +316,10 @@ namespace modem int m_rxDCOffset; int m_txDCOffset; + uint32_t m_rxFrequency; + uint32_t m_txFrequency; + uint8_t m_rfPower; + int m_dmrSymLevel3Adj; int m_dmrSymLevel1Adj; int m_p25SymLevel3Adj; @@ -360,6 +368,8 @@ namespace modem bool writeConfig(); /// Write symbol level adjustments to the air interface modem. bool writeSymbolAdjust(); + /// Write RF parameters to the air interface modem. + bool writeRFParams(); /// Print debug air interface messages to the host log. void printDebug(const uint8_t* buffer, uint16_t len);