diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index afe522e..64f2825 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -384,15 +384,17 @@ int CMMDVMHost::run() bool CMMDVMHost::createModem() { - std::string port = m_conf.getModemPort(); - bool rxInvert = m_conf.getModemRXInvert(); - bool txInvert = m_conf.getModemTXInvert(); - bool pttInvert = m_conf.getModemPTTInvert(); - unsigned int txDelay = m_conf.getModemTXDelay(); - unsigned int rxLevel = m_conf.getModemRXLevel(); - unsigned int txLevel = m_conf.getModemTXLevel(); - bool debug = m_conf.getModemDebug(); - unsigned int colorCode = m_conf.getDMRColorCode(); + std::string port = m_conf.getModemPort(); + bool rxInvert = m_conf.getModemRXInvert(); + bool txInvert = m_conf.getModemTXInvert(); + bool pttInvert = m_conf.getModemPTTInvert(); + unsigned int txDelay = m_conf.getModemTXDelay(); + unsigned int rxLevel = m_conf.getModemRXLevel(); + unsigned int txLevel = m_conf.getModemTXLevel(); + bool debug = m_conf.getModemDebug(); + unsigned int colorCode = m_conf.getDMRColorCode(); + unsigned int rxFrequency = m_conf.getRxFrequency(); + unsigned int txFrequency = m_conf.getTxFrequency(); LogInfo("Modem Parameters"); LogInfo(" Port: %s", port.c_str()); @@ -402,9 +404,12 @@ bool CMMDVMHost::createModem() LogInfo(" TX Delay: %u", txDelay); LogInfo(" RX Level: %u", rxLevel); LogInfo(" TX Level: %u", txLevel); + LogInfo(" RX Frequency: %uHz", rxFrequency); + LogInfo(" TX Frequency: %uHz", txFrequency); m_modem = new CModem(port, rxInvert, txInvert, pttInvert, txDelay, rxLevel, txLevel, debug); m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled); + m_modem->setRFParams(rxFrequency, txFrequency); m_modem->setDMRParams(colorCode); bool ret = m_modem->open(); diff --git a/Modem.cpp b/Modem.cpp index 3b2fe37..3cfabcb 100644 --- a/Modem.cpp +++ b/Modem.cpp @@ -40,6 +40,7 @@ const unsigned char MMDVM_GET_VERSION = 0x00U; const unsigned char MMDVM_GET_STATUS = 0x01U; const unsigned char MMDVM_SET_CONFIG = 0x02U; const unsigned char MMDVM_SET_MODE = 0x03U; +const unsigned char MMDVM_SET_FREQ = 0x04U; const unsigned char MMDVM_DSTAR_HEADER = 0x10U; const unsigned char MMDVM_DSTAR_DATA = 0x11U; @@ -82,6 +83,8 @@ m_txDelay(txDelay), m_rxLevel(rxLevel), m_txLevel(txLevel), m_debug(debug), +m_rxFrequency(0U), +m_txFrequency(0U), m_dstarEnabled(false), m_dmrEnabled(false), m_ysfEnabled(false), @@ -113,6 +116,12 @@ CModem::~CModem() delete[] m_buffer; } +void CModem::setRFParams(unsigned int rxFrequency, unsigned int txFrequency) +{ + m_rxFrequency = rxFrequency; + m_txFrequency = txFrequency; +} + void CModem::setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled) { m_dstarEnabled = dstarEnabled; @@ -147,6 +156,12 @@ bool CModem::open() return false; } + ret = setFrequency(); + if (!ret) { + m_serial.close(); + return false; + } + m_statusTimer.start(); m_inactivityTimer.start(); @@ -775,6 +790,64 @@ bool CModem::setConfig() return true; } +bool CModem::setFrequency() +{ + unsigned char buffer[15U]; + + buffer[0U] = MMDVM_FRAME_START; + + buffer[1U] = 12U; + + buffer[2U] = MMDVM_SET_FREQ; + + 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; + + // CUtils::dump("Written", buffer, 12U); + + int ret = m_serial.write(buffer, 12U); + if (ret != 10) + return false; + + unsigned int count = 0U; + unsigned int length; + RESP_TYPE_MMDVM resp; + do { +#if defined(_WIN32) || defined(_WIN64) + ::Sleep(10UL); +#else + ::usleep(10000UL); +#endif + resp = getResponse(m_buffer, length); + + if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) { + count++; + if (count >= MAX_RESPONSES) { + LogError("The MMDVM is not responding to the SET_FREQ command"); + return false; + } + } + } while (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK); + + // CUtils::dump("Response", m_buffer, length); + + if (resp == RTM_OK && m_buffer[2U] == MMDVM_NAK) { + LogError("Received a NAK to the SET_FREQ command from the modem"); + return false; + } + + return true; +} + RESP_TYPE_MMDVM CModem::getResponse(unsigned char *buffer, unsigned int& length) { // Get the start of the frame or nothing at all diff --git a/Modem.h b/Modem.h index 0a41431..a6f7a13 100644 --- a/Modem.h +++ b/Modem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2015 by Jonathan Naylor G4KLX + * Copyright (C) 2011-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 @@ -34,36 +34,37 @@ enum RESP_TYPE_MMDVM { class CModem { public: CModem(const std::string& port, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int rxLevel, unsigned int txLevel, bool debug = false); - virtual ~CModem(); + ~CModem(); - virtual void setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled); - virtual void setDMRParams(unsigned int colorCode); + void setRFParams(unsigned int rxFrequency, unsigned int txFrequency); + void setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled); + void setDMRParams(unsigned int colorCode); - virtual bool open(); + bool open(); - virtual unsigned int readDStarData(unsigned char* data); - virtual unsigned int readDMRData1(unsigned char* data); - virtual unsigned int readDMRData2(unsigned char* data); - virtual unsigned int readYSFData(unsigned char* data); + unsigned int readDStarData(unsigned char* data); + unsigned int readDMRData1(unsigned char* data); + unsigned int readDMRData2(unsigned char* data); + unsigned int readYSFData(unsigned char* data); - virtual bool hasDStarSpace() const; - virtual bool hasDMRSpace1() const; - virtual bool hasDMRSpace2() const; - virtual bool hasYSFSpace() const; + bool hasDStarSpace() const; + bool hasDMRSpace1() const; + bool hasDMRSpace2() const; + bool hasYSFSpace() const; - virtual bool writeDStarData(const unsigned char* data, unsigned int length); - virtual bool writeDMRData1(const unsigned char* data, unsigned int length); - virtual bool writeDMRData2(const unsigned char* data, unsigned int length); - virtual bool writeYSFData(const unsigned char* data, unsigned int length); + bool writeDStarData(const unsigned char* data, unsigned int length); + bool writeDMRData1(const unsigned char* data, unsigned int length); + bool writeDMRData2(const unsigned char* data, unsigned int length); + bool writeYSFData(const unsigned char* data, unsigned int length); - virtual bool writeDMRStart(bool tx); - virtual bool writeDMRShortLC(const unsigned char* lc); + bool writeDMRStart(bool tx); + bool writeDMRShortLC(const unsigned char* lc); - virtual bool setMode(unsigned char mode); + bool setMode(unsigned char mode); - virtual void clock(unsigned int ms); + void clock(unsigned int ms); - virtual void close(); + void close(); private: std::string m_port; @@ -75,6 +76,8 @@ private: unsigned int m_rxLevel; unsigned int m_txLevel; bool m_debug; + unsigned int m_rxFrequency; + unsigned int m_txFrequency; bool m_dstarEnabled; bool m_dmrEnabled; bool m_ysfEnabled; @@ -99,6 +102,7 @@ private: bool readVersion(); bool readStatus(); bool setConfig(); + bool setFrequency(); void printDebug();