From ed6586fa582b57b46aef41722d8bc8c537320019 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 5 May 2016 17:56:18 +0100 Subject: [PATCH] Split the DMR TX hang time from the mode hang time. --- Conf.cpp | 8 ++++++ Conf.h | 2 ++ MMDVM.ini | 1 + MMDVMHost.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++-------- MMDVMHost.h | 3 +- Modem.cpp | 5 ++++ Modem.h | 2 ++ 7 files changed, 85 insertions(+), 13 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 7e7f6de..06fede0 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -87,6 +87,7 @@ m_dmrSelfOnly(false), m_dmrPrefixes(), m_dmrBlackList(), m_dmrLookupFile(), +m_dmrTXHang(4U), m_fusionEnabled(true), m_fusionParrotEnabled(false), m_dstarNetworkEnabled(true), @@ -295,6 +296,8 @@ bool CConf::read() } } else if (::strcmp(key, "LookupFile") == 0) m_dmrLookupFile = value; + else if (::strcmp(key, "TXHang") == 0) + m_dmrTXHang = (unsigned int)::atoi(value); } else if (section == SECTION_FUSION) { if (::strcmp(key, "Enable") == 0) m_fusionEnabled = ::atoi(value) == 1; @@ -583,6 +586,11 @@ std::string CConf::getDMRLookupFile() const return m_dmrLookupFile; } +unsigned int CConf::getDMRTXHang() const +{ + return m_dmrTXHang; +} + bool CConf::getFusionEnabled() const { return m_fusionEnabled; diff --git a/Conf.h b/Conf.h index 2e3e177..400440b 100644 --- a/Conf.h +++ b/Conf.h @@ -82,6 +82,7 @@ public: std::vector getDMRPrefixes() const; std::vector getDMRBlackList() const; std::string getDMRLookupFile() const; + unsigned int getDMRTXHang() const; // The System Fusion section bool getFusionEnabled() const; @@ -176,6 +177,7 @@ private: std::vector m_dmrPrefixes; std::vector m_dmrBlackList; std::string m_dmrLookupFile; + unsigned int m_dmrTXHang; bool m_fusionEnabled; bool m_fusionParrotEnabled; diff --git a/MMDVM.ini b/MMDVM.ini index 2e4f311..0151080 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -50,6 +50,7 @@ ColorCode=1 SelfOnly=0 # Prefixes=234,235 LookupFile=DMRIds.dat +TXHang=4 [System Fusion] Enable=1 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index e1d68ef..620fd76 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -43,7 +43,7 @@ #endif #if defined(_WIN32) || defined(_WIN64) -const char* DEFAULT_INI_FILE = "mmdvm.ini"; +const char* DEFAULT_INI_FILE = "MMDVM.ini"; #else const char* DEFAULT_INI_FILE = "/etc/MMDVM.ini"; #endif @@ -105,6 +105,7 @@ m_dmrNetwork(NULL), m_display(NULL), m_mode(MODE_IDLE), m_modeTimer(1000U), +m_dmrTXTimer(1000U), m_duplex(false), m_dstarEnabled(false), m_dmrEnabled(false), @@ -258,6 +259,7 @@ int CMMDVMHost::run() std::vector blackList = m_conf.getDMRBlackList(); unsigned int timeout = m_conf.getTimeout(); std::string lookupFile = m_conf.getDMRLookupFile(); + unsigned int txHang = m_conf.getDMRTXHang(); LogInfo("DMR Parameters"); LogInfo(" Id: %u", id); @@ -268,8 +270,11 @@ int CMMDVMHost::run() LogInfo(" Black List: %u", blackList.size()); LogInfo(" Timeout: %us", timeout); LogInfo(" Lookup File: %s", lookupFile.length() > 0U ? lookupFile.c_str() : "None"); + LogInfo(" TX Hang: %us", txHang); dmr = new CDMRControl(id, colorCode, selfOnly, prefixes, blackList, timeout, m_modem, m_dmrNetwork, m_display, m_duplex, lookupFile); + + m_dmrTXTimer.setTimeout(txHang); } CYSFControl* ysf = NULL; @@ -326,17 +331,29 @@ int CMMDVMHost::run() if (m_mode == MODE_IDLE) { if (m_duplex) { bool ret = dmr->processWakeup(data); - if (ret) + if (ret) { setMode(MODE_DMR); + dmrBeaconTimer.stop(); + } } else { setMode(MODE_DMR); dmr->writeModemSlot1(data); dmrBeaconTimer.stop(); } } else if (m_mode == MODE_DMR) { - dmr->writeModemSlot1(data); - dmrBeaconTimer.stop(); - m_modeTimer.start(); + if (m_duplex && !m_modem->hasTX()) { + bool ret = dmr->processWakeup(data); + if (ret) { + m_modem->writeDMRStart(true); + m_dmrTXTimer.start(); + } + } else { + dmr->writeModemSlot1(data); + dmrBeaconTimer.stop(); + m_modeTimer.start(); + if (m_duplex) + m_dmrTXTimer.start(); + } } else if (m_mode != MODE_LOCKOUT) { LogWarning("DMR modem data received when in mode %u", m_mode); } @@ -347,17 +364,29 @@ int CMMDVMHost::run() if (m_mode == MODE_IDLE) { if (m_duplex) { bool ret = dmr->processWakeup(data); - if (ret) + if (ret) { setMode(MODE_DMR); + dmrBeaconTimer.stop(); + } } else { setMode(MODE_DMR); dmr->writeModemSlot2(data); dmrBeaconTimer.stop(); } } else if (m_mode == MODE_DMR) { - dmr->writeModemSlot2(data); - dmrBeaconTimer.stop(); - m_modeTimer.start(); + if (m_duplex && !m_modem->hasTX()) { + bool ret = dmr->processWakeup(data); + if (ret) { + m_modem->writeDMRStart(true); + m_dmrTXTimer.start(); + } + } else { + dmr->writeModemSlot2(data); + dmrBeaconTimer.stop(); + m_modeTimer.start(); + if (m_duplex) + m_dmrTXTimer.start(); + } } else if (m_mode != MODE_LOCKOUT) { LogWarning("DMR modem data received when in mode %u", m_mode); } @@ -405,6 +434,10 @@ int CMMDVMHost::run() if (m_mode == MODE_IDLE) setMode(MODE_DMR); if (m_mode == MODE_DMR) { + if (m_duplex) { + m_modem->writeDMRStart(true); + m_dmrTXTimer.start(); + } m_modem->writeDMRData1(data, len); dmrBeaconTimer.stop(); m_modeTimer.start(); @@ -421,6 +454,10 @@ int CMMDVMHost::run() if (m_mode == MODE_IDLE) setMode(MODE_DMR); if (m_mode == MODE_DMR) { + if (m_duplex) { + m_modem->writeDMRStart(true); + m_dmrTXTimer.start(); + } m_modem->writeDMRData2(data, len); dmrBeaconTimer.stop(); m_modeTimer.start(); @@ -480,6 +517,12 @@ int CMMDVMHost::run() dmrBeaconTimer.stop(); } + m_dmrTXTimer.clock(ms); + if (m_dmrTXTimer.isRunning() && m_dmrTXTimer.hasExpired()) { + m_modem->writeDMRStart(false); + m_dmrTXTimer.stop(); + } + if (ms < 5U) { #if defined(_WIN32) || defined(_WIN64) ::Sleep(5UL); // 5ms @@ -740,8 +783,10 @@ void CMMDVMHost::setMode(unsigned char mode, bool logging) if (m_dstarNetwork != NULL) m_dstarNetwork->enable(false); m_modem->setMode(MODE_DMR); - if (m_duplex) + if (m_duplex) { m_modem->writeDMRStart(true); + m_dmrTXTimer.start(); + } m_mode = MODE_DMR; m_modeTimer.start(); break; @@ -765,8 +810,10 @@ void CMMDVMHost::setMode(unsigned char mode, bool logging) m_dstarNetwork->enable(false); if (m_dmrNetwork != NULL) m_dmrNetwork->enable(false); - if (m_mode == MODE_DMR && m_duplex) + if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) { m_modem->writeDMRStart(false); + m_dmrTXTimer.stop(); + } m_modem->setMode(MODE_IDLE); m_display->setLockout(); m_mode = MODE_LOCKOUT; @@ -780,6 +827,10 @@ void CMMDVMHost::setMode(unsigned char mode, bool logging) m_dstarNetwork->enable(false); if (m_dmrNetwork != NULL) m_dmrNetwork->enable(false); + if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) { + m_modem->writeDMRStart(false); + m_dmrTXTimer.stop(); + } m_display->setError("MODEM"); m_mode = MODE_ERROR; m_modeTimer.stop(); @@ -792,8 +843,10 @@ void CMMDVMHost::setMode(unsigned char mode, bool logging) m_dstarNetwork->enable(true); if (m_dmrNetwork != NULL) m_dmrNetwork->enable(true); - if (m_mode == MODE_DMR && m_duplex) + if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) { m_modem->writeDMRStart(false); + m_dmrTXTimer.stop(); + } m_modem->setMode(MODE_IDLE); m_display->setIdle(); m_mode = MODE_IDLE; diff --git a/MMDVMHost.h b/MMDVMHost.h index 10ef47e..60e9415 100644 --- a/MMDVMHost.h +++ b/MMDVMHost.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX * * 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 @@ -44,6 +44,7 @@ private: IDisplay* m_display; unsigned char m_mode; CTimer m_modeTimer; + CTimer m_dmrTXTimer; bool m_duplex; bool m_dstarEnabled; bool m_dmrEnabled; diff --git a/Modem.cpp b/Modem.cpp index 29f03f8..8226b51 100644 --- a/Modem.cpp +++ b/Modem.cpp @@ -651,6 +651,11 @@ bool CModem::hasYSFSpace() const return space > 1U; } +bool CModem::hasTX() const +{ + return m_tx; +} + bool CModem::hasLockout() const { return m_lockout; diff --git a/Modem.h b/Modem.h index b72aa62..8c9fd4b 100644 --- a/Modem.h +++ b/Modem.h @@ -52,6 +52,8 @@ public: bool hasDMRSpace2() const; bool hasYSFSpace() const; + bool hasTX() const; + bool hasLockout() const; bool hasError() const;