From bebd7c75965d220eee0f3ea8316f0845f1f344c8 Mon Sep 17 00:00:00 2001 From: Jan-Willem Ruys Date: Sat, 7 May 2016 00:07:18 +0200 Subject: [PATCH 01/12] Update HD44780.h Added AF_ON, AF_OFF to make editing easier for backlights that use inverted signals --- HD44780.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HD44780.h b/HD44780.h index 8ae98c7..95caa64 100644 --- a/HD44780.h +++ b/HD44780.h @@ -44,7 +44,8 @@ enum ADAFRUIT_COLOUR { #define AF_GREEN (AF_BASE + 7) #define AF_BLUE (AF_BASE + 8) #define AF_RW (AF_BASE + 14) -#define AF_RW (AF_BASE + 14) +#define AF_ON LOW +#define AF_OFF HIGH #define MCP23017 0x20 #endif From 50cfef2c6a1aedb3bd1a1d568eb97c2cfc2cc943 Mon Sep 17 00:00:00 2001 From: Jan-Willem Ruys Date: Sat, 7 May 2016 00:13:17 +0200 Subject: [PATCH 02/12] Update HD44780.cpp Added AF_ON, AF_OFF to make editing easier for backlights that use inverted signals --- HD44780.cpp | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/HD44780.cpp b/HD44780.cpp index 757668b..c3e03bd 100644 --- a/HD44780.cpp +++ b/HD44780.cpp @@ -107,44 +107,44 @@ void CHD44780::adafruitLCDColour(ADAFRUIT_COLOUR colour) { switch (colour) { case AC_OFF: - ::digitalWrite(AF_RED, HIGH); - ::digitalWrite(AF_GREEN, HIGH); - ::digitalWrite(AF_BLUE, HIGH); + ::digitalWrite(AF_RED, AF_OFF); + ::digitalWrite(AF_GREEN, AF_OFF); + ::digitalWrite(AF_BLUE, AF_OFF); break; case AC_WHITE: - ::digitalWrite(AF_RED, LOW); - ::digitalWrite(AF_GREEN, LOW); - ::digitalWrite(AF_BLUE, LOW); + ::digitalWrite(AF_RED, AF_ON); + ::digitalWrite(AF_GREEN, AF_ON); + ::digitalWrite(AF_BLUE, AF_ON); break; case AC_RED: - ::digitalWrite(AF_RED, LOW); - ::digitalWrite(AF_GREEN, HIGH); - ::digitalWrite(AF_BLUE, HIGH); + ::digitalWrite(AF_RED, AF_ON); + ::digitalWrite(AF_GREEN, AF_OFF); + ::digitalWrite(AF_BLUE, AF_OFF); break; case AC_GREEN: - ::digitalWrite(AF_RED, HIGH); - ::digitalWrite(AF_GREEN, LOW); - ::digitalWrite(AF_BLUE, HIGH); + ::digitalWrite(AF_RED, AF_OFF); + ::digitalWrite(AF_GREEN, AF_ON); + ::digitalWrite(AF_BLUE, AF_OFF); break; case AC_BLUE: - ::digitalWrite(AF_RED, HIGH); - ::digitalWrite(AF_GREEN, HIGH); - ::digitalWrite(AF_BLUE, LOW); + ::digitalWrite(AF_RED, AF_OFF); + ::digitalWrite(AF_GREEN, AF_OFF); + ::digitalWrite(AF_BLUE, AF_ON); break; case AC_PURPLE: - ::digitalWrite(AF_RED, LOW); - ::digitalWrite(AF_GREEN, HIGH); - ::digitalWrite(AF_BLUE, LOW); + ::digitalWrite(AF_RED, AF_ON); + ::digitalWrite(AF_GREEN, AF_OFF); + ::digitalWrite(AF_BLUE, AF_ON); break; case AC_YELLOW: - ::digitalWrite(AF_RED, LOW); - ::digitalWrite(AF_GREEN, LOW); - ::digitalWrite(AF_BLUE, HIGH); + ::digitalWrite(AF_RED, AF_ON); + ::digitalWrite(AF_GREEN, AF_ON); + ::digitalWrite(AF_BLUE, AF_OFF); break; case AC_ICE: - ::digitalWrite(AF_RED, HIGH); - ::digitalWrite(AF_GREEN, LOW); - ::digitalWrite(AF_BLUE, LOW); + ::digitalWrite(AF_RED, AF_OFF); + ::digitalWrite(AF_GREEN, AF_ON); + ::digitalWrite(AF_BLUE, AF_ON); break; default: break; From e84d27fc8cdf6330c19c8803304ec798ab900bc0 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 9 May 2016 09:31:59 +0100 Subject: [PATCH 03/12] Blank the D-Star reflector when not in use. --- TFTSerial.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TFTSerial.cpp b/TFTSerial.cpp index 4815ec2..4c58b39 100644 --- a/TFTSerial.cpp +++ b/TFTSerial.cpp @@ -174,6 +174,9 @@ void CTFTSerial::writeDStar(const char* my1, const char* my2, const char* your, ::sprintf(text, "via %.8s", reflector); gotoPosPixel(5U, 110U); displayText(text); + } else { + gotoPosPixel(5U, 110U); + displayText(" "); } m_mode = MODE_DSTAR; From 617a6cbfcbae55736d323cfae3c016a04255bdda Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 9 May 2016 09:52:14 +0100 Subject: [PATCH 04/12] Handle failed writes cleanly. --- DMRIPSC.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/DMRIPSC.cpp b/DMRIPSC.cpp index 966a272..16df31b 100644 --- a/DMRIPSC.cpp +++ b/DMRIPSC.cpp @@ -272,8 +272,15 @@ bool CDMRIPSC::write(const CDMRData& data) if (m_debug) CUtils::dump(1U, "IPSC Transmitted", buffer, HOMEBREW_DATA_PACKET_LENGTH); - for (unsigned int i = 0U; i < count; i++) - write(buffer, HOMEBREW_DATA_PACKET_LENGTH); + for (unsigned int i = 0U; i < count; i++) { + bool ret = write(buffer, HOMEBREW_DATA_PACKET_LENGTH); + if (!ret) { + LogError("Socket has failed when writing data to the master, retrying connection"); + close(); + open(); + return false; + } + } return true; } @@ -282,10 +289,12 @@ void CDMRIPSC::close() { LogMessage("Closing DMR IPSC"); - unsigned char buffer[9U]; - ::memcpy(buffer + 0U, "RPTCL", 5U); - ::memcpy(buffer + 5U, m_id, 4U); - write(buffer, 9U); + if (m_status == RUNNING) { + unsigned char buffer[9U]; + ::memcpy(buffer + 0U, "RPTCL", 5U); + ::memcpy(buffer + 5U, m_id, 4U); + write(buffer, 9U); + } m_socket.close(); } @@ -296,7 +305,7 @@ void CDMRIPSC::clock(unsigned int ms) unsigned int port; int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, port); if (length < 0) { - LogError("Socket has failed, retrying connection"); + LogError("Socket has failed, retrying connection to the master"); close(); open(); return; From bd5946ccd28c38ddd94419a06bd83b30eda03751 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 9 May 2016 18:14:27 +0100 Subject: [PATCH 05/12] Add a display hang time so quick transmissions aren't missed. --- DMRControl.cpp | 2 +- DMRControl.h | 2 +- DMRSlot.cpp | 4 +- DMRSlot.h | 4 +- DStarControl.cpp | 2 +- DStarControl.h | 4 +- Display.cpp | 163 ++++++++++++++++++++++++++++++++++++++++++++++- Display.h | 48 ++++++++++---- HD44780.cpp | 19 +++--- HD44780.h | 30 ++++----- MMDVMHost.cpp | 2 + MMDVMHost.h | 2 +- Nextion.cpp | 19 +++--- Nextion.h | 30 ++++----- NullDisplay.cpp | 21 +++--- NullDisplay.h | 30 ++++----- TFTSerial.cpp | 19 +++--- TFTSerial.h | 30 ++++----- YSFControl.cpp | 2 +- YSFControl.h | 4 +- 20 files changed, 313 insertions(+), 124 deletions(-) diff --git a/DMRControl.cpp b/DMRControl.cpp index 5957250..f35f7c9 100644 --- a/DMRControl.cpp +++ b/DMRControl.cpp @@ -20,7 +20,7 @@ #include #include -CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex, const std::string& lookupFile) : +CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile) : m_id(id), m_colorCode(colorCode), m_selfOnly(selfOnly), diff --git a/DMRControl.h b/DMRControl.h index 3820e47..5598564 100644 --- a/DMRControl.h +++ b/DMRControl.h @@ -30,7 +30,7 @@ class CDMRControl { public: - CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex, const std::string& lookupFile); + CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile); ~CDMRControl(); bool processWakeup(const unsigned char* data); diff --git a/DMRSlot.cpp b/DMRSlot.cpp index f595267..df79496 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -33,7 +33,7 @@ std::vector CDMRSlot::m_prefixes; std::vector CDMRSlot::m_blackList; CModem* CDMRSlot::m_modem = NULL; CDMRIPSC* CDMRSlot::m_network = NULL; -IDisplay* CDMRSlot::m_display = NULL; +CDisplay* CDMRSlot::m_display = NULL; bool CDMRSlot::m_duplex = true; CDMRLookup* CDMRSlot::m_lookup = NULL; @@ -1263,7 +1263,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } -void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex, CDMRLookup* lookup) +void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup) { assert(id != 0U); assert(modem != NULL); diff --git a/DMRSlot.h b/DMRSlot.h index fe769b6..ae368b5 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -50,7 +50,7 @@ public: void clock(); - static void init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex, CDMRLookup* lookup); + static void init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup); private: unsigned int m_slotNo; @@ -92,7 +92,7 @@ private: static std::vector m_blackList; static CModem* m_modem; static CDMRIPSC* m_network; - static IDisplay* m_display; + static CDisplay* m_display; static bool m_duplex; static CDMRLookup* m_lookup; diff --git a/DStarControl.cpp b/DStarControl.cpp index 51e7ad5..696e3a4 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -36,7 +36,7 @@ bool CallsignCompare(const std::string& arg, const unsigned char* my) // #define DUMP_DSTAR -CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, const std::vector& blackList, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex) : +CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, const std::vector& blackList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex) : m_callsign(NULL), m_gateway(NULL), m_selfOnly(selfOnly), diff --git a/DStarControl.h b/DStarControl.h index ef327b4..856e247 100644 --- a/DStarControl.h +++ b/DStarControl.h @@ -36,7 +36,7 @@ class CDStarControl { public: - CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, const std::vector& blackList, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex); + CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, const std::vector& blackList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex); ~CDStarControl(); bool writeModem(unsigned char* data); @@ -51,7 +51,7 @@ private: bool m_selfOnly; std::vector m_blackList; CDStarNetwork* m_network; - IDisplay* m_display; + CDisplay* m_display; bool m_duplex; CRingBuffer m_queue; CDStarHeader m_rfHeader; diff --git a/Display.cpp b/Display.cpp index 54b514b..e9858d6 100644 --- a/Display.cpp +++ b/Display.cpp @@ -17,7 +17,168 @@ */ #include "Display.h" +#include "Defines.h" -IDisplay::~IDisplay() +#include +#include +#include + +CDisplay::CDisplay() : +m_timer1(1000U, 3U), +m_timer2(1000U, 3U), +m_mode1(MODE_IDLE), +m_mode2(MODE_IDLE) { } + +CDisplay::~CDisplay() +{ +} + +void CDisplay::setIdle() +{ + m_timer1.stop(); + m_timer2.stop(); + + m_mode1 = MODE_IDLE; + m_mode2 = MODE_IDLE; + + setIdleInt(); +} + +void CDisplay::setLockout() +{ + m_timer1.stop(); + m_timer2.stop(); + + m_mode1 = MODE_IDLE; + m_mode2 = MODE_IDLE; + + setLockoutInt(); +} + +void CDisplay::setError(const char* text) +{ + assert(text != NULL); + + m_timer1.stop(); + m_timer2.stop(); + + m_mode1 = MODE_IDLE; + m_mode2 = MODE_IDLE; + + setErrorInt(text); +} + +void CDisplay::writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) +{ + assert(my1 != NULL); + assert(my2 != NULL); + assert(your != NULL); + assert(type != NULL); + assert(reflector != NULL); + + m_timer1.start(); + + writeDStarInt(my1, my2, your, type, reflector); +} + +void CDisplay::clearDStar() +{ + if (m_timer1.hasExpired()) { + clearDStarInt(); + m_timer1.stop(); + } else { + m_mode1 = MODE_DSTAR; + } +} + +void CDisplay::writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) +{ + assert(type != NULL); + + if (slotNo == 1U) + m_timer1.start(); + else + m_timer2.start(); + + writeDMRInt(slotNo, src, group, dst, type); +} + +void CDisplay::clearDMR(unsigned int slotNo) +{ + if (slotNo == 1U) { + if (m_timer1.hasExpired()) { + clearDMRInt(slotNo); + m_timer1.stop(); + } else { + m_mode1 = MODE_DMR; + } + } else { + if (m_timer2.hasExpired()) { + clearDMRInt(slotNo); + m_timer2.stop(); + } else { + m_mode2 = MODE_DMR; + } + } +} + +void CDisplay::writeFusion(const char* source, const char* dest) +{ + assert(source != NULL); + assert(dest != NULL); + + m_timer1.start(); + + writeFusionInt(source, dest); +} + +void CDisplay::clearFusion() +{ + if (m_timer1.hasExpired()) { + clearFusionInt(); + m_timer1.stop(); + } else { + m_mode1 = MODE_YSF; + } +} + +void CDisplay::clock(unsigned int ms) +{ + m_timer1.clock(ms); + if (m_timer1.isRunning() && m_timer1.hasExpired()) { + switch (m_mode1) { + case MODE_DSTAR: + clearDStarInt(); + break; + case MODE_DMR: + clearDMRInt(1U); + break; + case MODE_YSF: + clearFusionInt(); + break; + } + + m_mode1 = MODE_IDLE; + m_timer1.stop(); + } + + m_timer2.clock(ms); + if (m_timer2.isRunning() && m_timer2.hasExpired()) { + switch (m_mode2) { + case MODE_DSTAR: + clearDStarInt(); + break; + case MODE_DMR: + clearDMRInt(2U); + break; + case MODE_YSF: + clearFusionInt(); + break; + } + + m_mode2 = MODE_IDLE; + m_timer2.stop(); + } +} diff --git a/Display.h b/Display.h index 5dfdb32..ab52751 100644 --- a/Display.h +++ b/Display.h @@ -19,32 +19,54 @@ #if !defined(DISPLAY_H) #define DISPLAY_H +#include "Timer.h" + #include -class IDisplay +class CDisplay { public: - virtual ~IDisplay() = 0; + CDisplay(); + virtual ~CDisplay() = 0; - virtual bool open() = 0; + virtual bool open() = 0; - virtual void setIdle() = 0; + void setIdle(); + void setLockout(); + void setError(const char* text); - virtual void setLockout() = 0; - virtual void setError(const char* text) = 0; + void writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); + void clearDStar(); - virtual void writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) = 0; - virtual void clearDStar() = 0; + void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); + void clearDMR(unsigned int slotNo); - virtual void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) = 0; - virtual void clearDMR(unsigned int slotNo) = 0; + void writeFusion(const char* source, const char* dest); + void clearFusion(); - virtual void writeFusion(const char* source, const char* dest) = 0; - virtual void clearFusion() = 0; + virtual void close() = 0; - virtual void close() = 0; + void clock(unsigned int ms); + +protected: + virtual void setIdleInt() = 0; + virtual void setLockoutInt() = 0; + virtual void setErrorInt(const char* text) = 0; + + virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) = 0; + virtual void clearDStarInt() = 0; + + virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) = 0; + virtual void clearDMRInt(unsigned int slotNo) = 0; + + virtual void writeFusionInt(const char* source, const char* dest) = 0; + virtual void clearFusionInt() = 0; private: + CTimer m_timer1; + CTimer m_timer2; + unsigned char m_mode1; + unsigned char m_mode2; }; #endif diff --git a/HD44780.cpp b/HD44780.cpp index c3e03bd..29e320b 100644 --- a/HD44780.cpp +++ b/HD44780.cpp @@ -30,6 +30,7 @@ const char* LISTENING = "Listening "; CHD44780::CHD44780(unsigned int rows, unsigned int cols, const std::string& callsign, unsigned int dmrid, const std::vector& pins, bool pwm, unsigned int pwmPin, unsigned int pwmBright, unsigned int pwmDim, bool duplex) : +CDisplay(), m_rows(rows), m_cols(cols), m_callsign(callsign), @@ -152,7 +153,7 @@ void CHD44780::adafruitLCDColour(ADAFRUIT_COLOUR colour) } #endif -void CHD44780::setIdle() +void CHD44780::setIdleInt() { ::lcdClear(m_fd); @@ -176,7 +177,7 @@ void CHD44780::setIdle() m_dmr = false; } -void CHD44780::setError(const char* text) +void CHD44780::setErrorInt(const char* text) { assert(text != NULL); @@ -202,7 +203,7 @@ void CHD44780::setError(const char* text) m_dmr = false; } -void CHD44780::setLockout() +void CHD44780::setLockoutInt() { #ifdef ADAFRUIT_DISPLAY adafruitLCDColour(AC_RED); @@ -226,7 +227,7 @@ void CHD44780::setLockout() m_dmr = false; } -void CHD44780::writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) +void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) { assert(my1 != NULL); assert(my2 != NULL); @@ -295,7 +296,7 @@ void CHD44780::writeDStar(const char* my1, const char* my2, const char* your, co m_dmr = false; } -void CHD44780::clearDStar() +void CHD44780::clearDStarInt() { #ifdef ADAFRUIT_DISPLAY adafruitLCDColour(AC_ICE); @@ -322,7 +323,7 @@ void CHD44780::clearDStar() } } -void CHD44780::writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) +void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) { assert(type != NULL); @@ -466,7 +467,7 @@ void CHD44780::writeDMR(unsigned int slotNo, const std::string& src, bool group, m_dmr = true; } -void CHD44780::clearDMR(unsigned int slotNo) +void CHD44780::clearDMRInt(unsigned int slotNo) { #ifdef ADAFRUIT_DISPLAY adafruitLCDColour(AC_ICE); @@ -515,7 +516,7 @@ void CHD44780::clearDMR(unsigned int slotNo) } } -void CHD44780::writeFusion(const char* source, const char* dest) +void CHD44780::writeFusionInt(const char* source, const char* dest) { assert(source != NULL); assert(dest != NULL); @@ -570,7 +571,7 @@ void CHD44780::writeFusion(const char* source, const char* dest) m_dmr = false; } -void CHD44780::clearFusion() +void CHD44780::clearFusionInt() { #ifdef ADAFRUIT_DISPLAY adafruitLCDColour(AC_ICE); diff --git a/HD44780.h b/HD44780.h index 95caa64..b71456a 100644 --- a/HD44780.h +++ b/HD44780.h @@ -49,7 +49,7 @@ enum ADAFRUIT_COLOUR { #define MCP23017 0x20 #endif -class CHD44780 : public IDisplay +class CHD44780 : public CDisplay { public: CHD44780(unsigned int rows, unsigned int cols, const std::string& callsign, unsigned int dmrid, const std::vector& pins, bool pwm, unsigned int pwmPin, unsigned int pwmBright, unsigned int pwmDim, bool duplex); @@ -57,22 +57,22 @@ public: virtual bool open(); - virtual void setIdle(); - - virtual void setError(const char* text); - virtual void setLockout(); - - virtual void writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); - virtual void clearDStar(); - - virtual void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); - virtual void clearDMR(unsigned int slotNo); - - virtual void writeFusion(const char* source, const char* dest); - virtual void clearFusion(); - virtual void close(); +protected: + virtual void setIdleInt(); + virtual void setErrorInt(const char* text); + virtual void setLockoutInt(); + + virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); + virtual void clearDStarInt(); + + virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); + virtual void clearDMRInt(unsigned int slotNo); + + virtual void writeFusionInt(const char* source, const char* dest); + virtual void clearFusionInt(); + private: unsigned int m_rows; unsigned int m_cols; diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index ee0fd0a..f51c5f0 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -494,6 +494,8 @@ int CMMDVMHost::run() unsigned int ms = stopWatch.elapsed(); stopWatch.start(); + m_display->clock(ms); + m_modem->clock(ms); m_modeTimer.clock(ms); diff --git a/MMDVMHost.h b/MMDVMHost.h index 60e9415..794e8ee 100644 --- a/MMDVMHost.h +++ b/MMDVMHost.h @@ -41,7 +41,7 @@ private: CModem* m_modem; CDStarNetwork* m_dstarNetwork; CDMRIPSC* m_dmrNetwork; - IDisplay* m_display; + CDisplay* m_display; unsigned char m_mode; CTimer m_modeTimer; CTimer m_dmrTXTimer; diff --git a/Nextion.cpp b/Nextion.cpp index eec152d..3f71bae 100644 --- a/Nextion.cpp +++ b/Nextion.cpp @@ -24,6 +24,7 @@ #include CNextion::CNextion(const std::string& callsign, unsigned int dmrid, const std::string& size, const std::string& port, unsigned int brightness) : +CDisplay(), m_callsign(callsign), m_dmrid(dmrid), m_size(size), @@ -57,7 +58,7 @@ bool CNextion::open() return true; } -void CNextion::setIdle() +void CNextion::setIdleInt() { sendCommand("page MMDVM"); @@ -70,7 +71,7 @@ void CNextion::setIdle() m_mode = MODE_IDLE; } -void CNextion::setError(const char* text) +void CNextion::setErrorInt(const char* text) { assert(text != NULL); @@ -85,7 +86,7 @@ void CNextion::setError(const char* text) m_mode = MODE_ERROR; } -void CNextion::setLockout() +void CNextion::setLockoutInt() { sendCommand("page MMDVM"); @@ -94,7 +95,7 @@ void CNextion::setLockout() m_mode = MODE_LOCKOUT; } -void CNextion::writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) +void CNextion::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) { assert(my1 != NULL); assert(my2 != NULL); @@ -127,7 +128,7 @@ void CNextion::writeDStar(const char* my1, const char* my2, const char* your, co m_mode = MODE_DSTAR; } -void CNextion::clearDStar() +void CNextion::clearDStarInt() { sendCommand("t0.txt=\"Listening\""); sendCommand("t1.txt=\"\""); @@ -135,7 +136,7 @@ void CNextion::clearDStar() sendCommand("t2.txt=\"\""); } -void CNextion::writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) +void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) { assert(type != NULL); @@ -169,7 +170,7 @@ void CNextion::writeDMR(unsigned int slotNo, const std::string& src, bool group, m_mode = MODE_DMR; } -void CNextion::clearDMR(unsigned int slotNo) +void CNextion::clearDMRInt(unsigned int slotNo) { if (slotNo == 1U) { sendCommand("t0.txt=\"1 Listening\""); @@ -180,7 +181,7 @@ void CNextion::clearDMR(unsigned int slotNo) } } -void CNextion::writeFusion(const char* source, const char* dest) +void CNextion::writeFusionInt(const char* source, const char* dest) { assert(source != NULL); assert(dest != NULL); @@ -198,7 +199,7 @@ void CNextion::writeFusion(const char* source, const char* dest) m_mode = MODE_YSF; } -void CNextion::clearFusion() +void CNextion::clearFusionInt() { sendCommand("t0.txt=\"Listening\""); sendCommand("t1.txt=\"\""); diff --git a/Nextion.h b/Nextion.h index b07c7ca..911c636 100644 --- a/Nextion.h +++ b/Nextion.h @@ -25,7 +25,7 @@ #include -class CNextion : public IDisplay +class CNextion : public CDisplay { public: CNextion(const std::string& callsign, unsigned int dmrid, const std::string& size, const std::string& port, unsigned int brightness); @@ -33,22 +33,22 @@ public: virtual bool open(); - virtual void setIdle(); - - virtual void setError(const char* text); - virtual void setLockout(); - - virtual void writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); - virtual void clearDStar(); - - virtual void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); - virtual void clearDMR(unsigned int slotNo); - - virtual void writeFusion(const char* source, const char* dest); - virtual void clearFusion(); - virtual void close(); +protected: + virtual void setIdleInt(); + virtual void setErrorInt(const char* text); + virtual void setLockoutInt(); + + virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); + virtual void clearDStarInt(); + + virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); + virtual void clearDMRInt(unsigned int slotNo); + + virtual void writeFusionInt(const char* source, const char* dest); + virtual void clearFusionInt(); + private: std::string m_callsign; unsigned int m_dmrid; diff --git a/NullDisplay.cpp b/NullDisplay.cpp index 59186a6..2aec2c3 100644 --- a/NullDisplay.cpp +++ b/NullDisplay.cpp @@ -18,7 +18,8 @@ #include "NullDisplay.h" -CNullDisplay::CNullDisplay() +CNullDisplay::CNullDisplay() : +CDisplay() { } @@ -31,39 +32,39 @@ bool CNullDisplay::open() return true; } -void CNullDisplay::setIdle() +void CNullDisplay::setIdleInt() { } -void CNullDisplay::setError(const char* text) +void CNullDisplay::setErrorInt(const char* text) { } -void CNullDisplay::setLockout() +void CNullDisplay::setLockoutInt() { } -void CNullDisplay::writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) +void CNullDisplay::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) { } -void CNullDisplay::clearDStar() +void CNullDisplay::clearDStarInt() { } -void CNullDisplay::writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) +void CNullDisplay::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) { } -void CNullDisplay::clearDMR(unsigned int slotNo) +void CNullDisplay::clearDMRInt(unsigned int slotNo) { } -void CNullDisplay::writeFusion(const char* source, const char* dest) +void CNullDisplay::writeFusionInt(const char* source, const char* dest) { } -void CNullDisplay::clearFusion() +void CNullDisplay::clearFusionInt() { } diff --git a/NullDisplay.h b/NullDisplay.h index 9e2f153..57f18d8 100644 --- a/NullDisplay.h +++ b/NullDisplay.h @@ -23,7 +23,7 @@ #include -class CNullDisplay : public IDisplay +class CNullDisplay : public CDisplay { public: CNullDisplay(); @@ -31,22 +31,22 @@ public: virtual bool open(); - virtual void setIdle(); - - virtual void setError(const char* text); - virtual void setLockout(); - - virtual void writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); - virtual void clearDStar(); - - virtual void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); - virtual void clearDMR(unsigned int slotNo); - - virtual void writeFusion(const char* source, const char* dest); - virtual void clearFusion(); - virtual void close(); +protected: + virtual void setIdleInt(); + virtual void setErrorInt(const char* text); + virtual void setLockoutInt(); + + virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); + virtual void clearDStarInt(); + + virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); + virtual void clearDMRInt(unsigned int slotNo); + + virtual void writeFusionInt(const char* source, const char* dest); + virtual void clearFusionInt(); + private: }; diff --git a/TFTSerial.cpp b/TFTSerial.cpp index 4c58b39..8466742 100644 --- a/TFTSerial.cpp +++ b/TFTSerial.cpp @@ -45,6 +45,7 @@ const unsigned char FONT_LARGE = 3U; // x = 0 to 127, y = 0 to 159 - Portrait CTFTSerial::CTFTSerial(const std::string& callsign, unsigned int dmrid, const std::string& port, unsigned int brightness) : +CDisplay(), m_callsign(callsign), m_dmrid(dmrid), m_serial(port, SERIAL_9600), @@ -79,7 +80,7 @@ bool CTFTSerial::open() return true; } -void CTFTSerial::setIdle() +void CTFTSerial::setIdleInt() { // Clear the screen clearScreen(); @@ -101,7 +102,7 @@ void CTFTSerial::setIdle() m_mode = MODE_IDLE; } -void CTFTSerial::setError(const char* text) +void CTFTSerial::setErrorInt(const char* text) { assert(text != NULL); @@ -126,7 +127,7 @@ void CTFTSerial::setError(const char* text) m_mode = MODE_ERROR; } -void CTFTSerial::setLockout() +void CTFTSerial::setLockoutInt() { // Clear the screen clearScreen(); @@ -142,7 +143,7 @@ void CTFTSerial::setLockout() m_mode = MODE_LOCKOUT; } -void CTFTSerial::writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) +void CTFTSerial::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) { assert(my1 != NULL); assert(my2 != NULL); @@ -182,7 +183,7 @@ void CTFTSerial::writeDStar(const char* my1, const char* my2, const char* your, m_mode = MODE_DSTAR; } -void CTFTSerial::clearDStar() +void CTFTSerial::clearDStarInt() { gotoPosPixel(5U, 70U); displayText(" Listening "); @@ -194,7 +195,7 @@ void CTFTSerial::clearDStar() displayText(" "); } -void CTFTSerial::writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) +void CTFTSerial::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) { assert(type != NULL); @@ -241,7 +242,7 @@ void CTFTSerial::writeDMR(unsigned int slotNo, const std::string& src, bool grou m_mode = MODE_DMR; } -void CTFTSerial::clearDMR(unsigned int slotNo) +void CTFTSerial::clearDMRInt(unsigned int slotNo) { if (slotNo == 1U) { gotoPosPixel(5U, 55U); @@ -258,7 +259,7 @@ void CTFTSerial::clearDMR(unsigned int slotNo) } } -void CTFTSerial::writeFusion(const char* source, const char* dest) +void CTFTSerial::writeFusionInt(const char* source, const char* dest) { assert(source != NULL); assert(dest != NULL); @@ -287,7 +288,7 @@ void CTFTSerial::writeFusion(const char* source, const char* dest) m_mode = MODE_YSF; } -void CTFTSerial::clearFusion() +void CTFTSerial::clearFusionInt() { gotoPosPixel(5U, 80U); displayText(" Listening "); diff --git a/TFTSerial.h b/TFTSerial.h index 9147cef..acb2b65 100644 --- a/TFTSerial.h +++ b/TFTSerial.h @@ -25,7 +25,7 @@ #include -class CTFTSerial : public IDisplay +class CTFTSerial : public CDisplay { public: CTFTSerial(const std::string& callsign, unsigned int dmrid, const std::string& port, unsigned int brightness); @@ -33,22 +33,22 @@ public: virtual bool open(); - virtual void setIdle(); - - virtual void setError(const char* text); - virtual void setLockout(); - - virtual void writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); - virtual void clearDStar(); - - virtual void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); - virtual void clearDMR(unsigned int slotNo); - - virtual void writeFusion(const char* source, const char* dest); - virtual void clearFusion(); - virtual void close(); +protected: + virtual void setIdleInt(); + virtual void setErrorInt(const char* text); + virtual void setLockoutInt(); + + virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); + virtual void clearDStarInt(); + + virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); + virtual void clearDMRInt(unsigned int slotNo); + + virtual void writeFusionInt(const char* source, const char* dest); + virtual void clearFusionInt(); + private: std::string m_callsign; unsigned int m_dmrid; diff --git a/YSFControl.cpp b/YSFControl.cpp index 3cd7e28..0433d3d 100644 --- a/YSFControl.cpp +++ b/YSFControl.cpp @@ -24,7 +24,7 @@ // #define DUMP_YSF -CYSFControl::CYSFControl(const std::string& callsign, IDisplay* display, unsigned int timeout, bool duplex, bool parrot) : +CYSFControl::CYSFControl(const std::string& callsign, CDisplay* display, unsigned int timeout, bool duplex, bool parrot) : m_display(display), m_duplex(duplex), m_queue(2000U, "YSF Control"), diff --git a/YSFControl.h b/YSFControl.h index 56434ee..c25b279 100644 --- a/YSFControl.h +++ b/YSFControl.h @@ -33,7 +33,7 @@ class CYSFControl { public: - CYSFControl(const std::string& callsign, IDisplay* display, unsigned int timeout, bool duplex, bool parrot); + CYSFControl(const std::string& callsign, CDisplay* display, unsigned int timeout, bool duplex, bool parrot); ~CYSFControl(); bool writeModem(unsigned char* data); @@ -43,7 +43,7 @@ public: void clock(); private: - IDisplay* m_display; + CDisplay* m_display; bool m_duplex; CRingBuffer m_queue; RPT_RF_STATE m_state; From 68d58a3de613ebd5c54ebe92c37bc9466948441d Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 9 May 2016 21:55:44 +0100 Subject: [PATCH 06/12] Add the CW Id. --- Conf.cpp | 20 ++++++++++++++++++++ Conf.h | 7 +++++++ MMDVM.ini | 4 ++++ MMDVMHost.cpp | 52 +++++++++++++++++++++++++++++++++++---------------- MMDVMHost.h | 2 ++ Modem.cpp | 22 ++++++++++++++++++++++ Modem.h | 2 ++ 7 files changed, 93 insertions(+), 16 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 06fede0..6c6befa 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -32,6 +32,7 @@ enum SECTION { SECTION_GENERAL, SECTION_INFO, SECTION_LOG, + SECTION_CWID, SECTION_MODEM, SECTION_DSTAR, SECTION_DMR, @@ -65,6 +66,8 @@ m_logDisplayLevel(0U), m_logFileLevel(0U), m_logFilePath(), m_logFileRoot(), +m_cwIdEnabled(false), +m_cwIdTime(10U), m_modemPort(), m_modemRXInvert(false), m_modemTXInvert(false), @@ -148,6 +151,8 @@ bool CConf::read() section = SECTION_INFO; else if (::strncmp(buffer, "[Log]", 5U) == 0) section = SECTION_LOG; + else if (::strncmp(buffer, "[CW Id]", 7U) == 0) + section = SECTION_CWID; else if (::strncmp(buffer, "[Modem]", 7U) == 0) section = SECTION_MODEM; else if (::strncmp(buffer, "[D-Star]", 8U) == 0) @@ -223,6 +228,11 @@ bool CConf::read() m_logFileLevel = (unsigned int)::atoi(value); else if (::strcmp(key, "DisplayLevel") == 0) m_logDisplayLevel = (unsigned int)::atoi(value); + } else if (section == SECTION_CWID) { + if (::strcmp(key, "Enable") == 0) + m_cwIdEnabled = ::atoi(value) == 1; + else if (::strcmp(key, "Time") == 0) + m_cwIdTime = (unsigned int)::atoi(value); } else if (section == SECTION_MODEM) { if (::strcmp(key, "Port") == 0) m_modemPort = value; @@ -476,6 +486,16 @@ std::string CConf::getLogFileRoot() const return m_logFileRoot; } +bool CConf::getCWIdEnabled() const +{ + return m_cwIdEnabled; +} + +unsigned int CConf::getCWIdTime() const +{ + return m_cwIdTime; +} + std::string CConf::getModemPort() const { return m_modemPort; diff --git a/Conf.h b/Conf.h index 400440b..baee772 100644 --- a/Conf.h +++ b/Conf.h @@ -55,6 +55,10 @@ public: std::string getLogFilePath() const; std::string getLogFileRoot() const; + // The CW ID section + bool getCWIdEnabled() const; + unsigned int getCWIdTime() const; + // The Modem section std::string getModemPort() const; bool getModemRXInvert() const; @@ -153,6 +157,9 @@ private: std::string m_logFilePath; std::string m_logFileRoot; + bool m_cwIdEnabled; + unsigned int m_cwIdTime; + std::string m_modemPort; bool m_modemRXInvert; bool m_modemTXInvert; diff --git a/MMDVM.ini b/MMDVM.ini index 0151080..7588645 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -24,6 +24,10 @@ FileLevel=1 FilePath=. FileRoot=MMDVM +[CW Id] +Enable=1 +Time=10 + [Modem] # Port=/dev/ttyACM0 Port=\\.\COM3 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index f51c5f0..a692f4d 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -107,10 +107,12 @@ m_display(NULL), m_mode(MODE_IDLE), m_modeTimer(1000U), m_dmrTXTimer(1000U), +m_cwIdTimer(1000U), m_duplex(false), m_dstarEnabled(false), m_dmrEnabled(false), -m_ysfEnabled(false) +m_ysfEnabled(false), +m_callsign() { } @@ -223,6 +225,15 @@ int CMMDVMHost::run() return 1; } + if (m_conf.getCWIdEnabled()) { + unsigned int time = m_conf.getCWIdTime(); + + LogInfo("CW Id Parameters"); + LogInfo(" Time: %u mins", time); + + m_cwIdTimer.setTimeout(time * 60U); + } + CTimer dmrBeaconTimer(1000U, 4U); bool dmrBeaconsEnabled = m_dmrEnabled && m_conf.getDMRBeacons(); @@ -231,21 +242,20 @@ int CMMDVMHost::run() CDStarControl* dstar = NULL; if (m_dstarEnabled) { - std::string callsign = m_conf.getCallsign(); std::string module = m_conf.getDStarModule(); bool selfOnly = m_conf.getDStarSelfOnly(); unsigned int timeout = m_conf.getTimeout(); std::vector blackList = m_conf.getDStarBlackList(); LogInfo("D-Star Parameters"); - LogInfo(" Callsign: %s", callsign.c_str()); + LogInfo(" Callsign: %s", m_callsign.c_str()); LogInfo(" Module: %s", module.c_str()); LogInfo(" Self Only: %s", selfOnly ? "yes" : "no"); if (blackList.size() > 0U) LogInfo(" Black List: %u", blackList.size()); LogInfo(" Timeout: %us", timeout); - dstar = new CDStarControl(callsign, module, selfOnly, blackList, m_dstarNetwork, m_display, timeout, m_duplex); + dstar = new CDStarControl(m_callsign, module, selfOnly, blackList, m_dstarNetwork, m_display, timeout, m_duplex); } CDMRControl* dmr = NULL; @@ -277,16 +287,15 @@ int CMMDVMHost::run() CYSFControl* ysf = NULL; if (m_ysfEnabled) { - std::string callsign = m_conf.getCallsign(); unsigned int timeout = m_conf.getTimeout(); bool parrot = m_conf.getFusionParrotEnabled(); LogInfo("System Fusion Parameters"); - LogInfo(" Callsign: %s", callsign.c_str()); + LogInfo(" Callsign: %s", m_callsign.c_str()); LogInfo(" Timeout: %us", timeout); LogInfo(" Parrot: %s", parrot ? "enabled" : "disabled"); - ysf = new CYSFControl(callsign, m_display, timeout, m_duplex, parrot); + ysf = new CYSFControl(m_callsign, m_display, timeout, m_duplex, parrot); } m_modeTimer.setTimeout(m_conf.getModeHang()); @@ -511,6 +520,12 @@ int CMMDVMHost::run() if (m_dmrNetwork != NULL) m_dmrNetwork->clock(ms); + m_cwIdTimer.clock(ms); + if (m_cwIdTimer.isRunning() && m_cwIdTimer.hasExpired()) { + m_modem->sendCWId(m_callsign); + m_cwIdTimer.start(); + } + dmrBeaconTimer.clock(ms); if (dmrBeaconTimer.isRunning() && dmrBeaconTimer.hasExpired()) { setMode(MODE_IDLE, false); @@ -652,7 +667,6 @@ bool CMMDVMHost::createDMRNetwork() m_dmrNetwork = new CDMRIPSC(address, port, local, id, password, m_duplex, VERSION, debug, slot1, slot2); - std::string callsign = m_conf.getCallsign(); unsigned int rxFrequency = m_conf.getRxFrequency(); unsigned int txFrequency = m_conf.getTxFrequency(); unsigned int power = m_conf.getPower(); @@ -665,7 +679,7 @@ bool CMMDVMHost::createDMRNetwork() std::string url = m_conf.getURL(); LogInfo("Info Parameters"); - LogInfo(" Callsign: %s", callsign.c_str()); + LogInfo(" Callsign: %s", m_callsign.c_str()); LogInfo(" RX Frequency: %uHz", rxFrequency); LogInfo(" TX Frequency: %uHz", txFrequency); LogInfo(" Power: %uW", power); @@ -676,7 +690,7 @@ bool CMMDVMHost::createDMRNetwork() LogInfo(" Description: \"%s\"", description.c_str()); LogInfo(" URL: \"%s\"", url.c_str()); - m_dmrNetwork->setConfig(callsign, rxFrequency, txFrequency, power, colorCode, latitude, longitude, height, location, description, url); + m_dmrNetwork->setConfig(m_callsign, rxFrequency, txFrequency, power, colorCode, latitude, longitude, height, location, description, url); bool ret = m_dmrNetwork->open(); if (!ret) { @@ -696,13 +710,13 @@ void CMMDVMHost::readParams() m_dmrEnabled = m_conf.getDMREnabled(); m_ysfEnabled = m_conf.getFusionEnabled(); m_duplex = m_conf.getDuplex(); + m_callsign = m_conf.getCallsign(); } void CMMDVMHost::createDisplay() { - std::string type = m_conf.getDisplay(); - std::string callsign = m_conf.getCallsign(); - unsigned int dmrid = m_conf.getDMRId(); + std::string type = m_conf.getDisplay(); + unsigned int dmrid = m_conf.getDMRId(); LogInfo("Display Parameters"); LogInfo(" Type: %s", type.c_str()); @@ -714,7 +728,7 @@ void CMMDVMHost::createDisplay() LogInfo(" Port: %s", port.c_str()); LogInfo(" Brightness: %u", brightness); - m_display = new CTFTSerial(callsign, dmrid, port, brightness); + m_display = new CTFTSerial(m_callsign, dmrid, port, brightness); } else if (type == "Nextion") { std::string size = m_conf.getNextionSize(); std::string port = m_conf.getNextionPort(); @@ -724,7 +738,7 @@ void CMMDVMHost::createDisplay() LogInfo(" Port: %s", port.c_str()); LogInfo(" Brightness: %u", brightness); - m_display = new CNextion(callsign, dmrid, size, port, brightness); + m_display = new CNextion(m_callsign, dmrid, size, port, brightness); #if defined(HD44780) } else if (type == "HD44780") { unsigned int rows = m_conf.getHD44780Rows(); @@ -747,7 +761,7 @@ void CMMDVMHost::createDisplay() LogInfo(" PWM Dim: %u", pwmDim); } - m_display = new CHD44780(rows, columns, callsign, dmrid, pins, pwm, pwmPin, pwmBright, pwmDim, m_duplex); + m_display = new CHD44780(rows, columns, m_callsign, dmrid, pins, pwm, pwmPin, pwmBright, pwmDim, m_duplex); } #endif } else { @@ -775,6 +789,7 @@ void CMMDVMHost::setMode(unsigned char mode, bool logging) m_modem->setMode(MODE_DSTAR); m_mode = MODE_DSTAR; m_modeTimer.start(); + m_cwIdTimer.stop(); break; case MODE_DMR: @@ -789,6 +804,7 @@ void CMMDVMHost::setMode(unsigned char mode, bool logging) } m_mode = MODE_DMR; m_modeTimer.start(); + m_cwIdTimer.stop(); break; case MODE_YSF: @@ -801,6 +817,7 @@ void CMMDVMHost::setMode(unsigned char mode, bool logging) m_modem->setMode(MODE_YSF); m_mode = MODE_YSF; m_modeTimer.start(); + m_cwIdTimer.stop(); break; case MODE_LOCKOUT: @@ -818,6 +835,7 @@ void CMMDVMHost::setMode(unsigned char mode, bool logging) m_display->setLockout(); m_mode = MODE_LOCKOUT; m_modeTimer.stop(); + m_cwIdTimer.stop(); break; case MODE_ERROR: @@ -834,6 +852,7 @@ void CMMDVMHost::setMode(unsigned char mode, bool logging) m_display->setError("MODEM"); m_mode = MODE_ERROR; m_modeTimer.stop(); + m_cwIdTimer.stop(); break; default: @@ -851,6 +870,7 @@ void CMMDVMHost::setMode(unsigned char mode, bool logging) m_display->setIdle(); m_mode = MODE_IDLE; m_modeTimer.stop(); + m_cwIdTimer.start(); break; } } diff --git a/MMDVMHost.h b/MMDVMHost.h index 794e8ee..d129647 100644 --- a/MMDVMHost.h +++ b/MMDVMHost.h @@ -45,10 +45,12 @@ private: unsigned char m_mode; CTimer m_modeTimer; CTimer m_dmrTXTimer; + CTimer m_cwIdTimer; bool m_duplex; bool m_dstarEnabled; bool m_dmrEnabled; bool m_ysfEnabled; + std::string m_callsign; void readParams(); bool createModem(); diff --git a/Modem.cpp b/Modem.cpp index 8226b51..1e35bf3 100644 --- a/Modem.cpp +++ b/Modem.cpp @@ -43,6 +43,8 @@ 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_SEND_CWID = 0x0AU; + const unsigned char MMDVM_DSTAR_HEADER = 0x10U; const unsigned char MMDVM_DSTAR_DATA = 0x11U; const unsigned char MMDVM_DSTAR_LOST = 0x12U; @@ -1013,6 +1015,26 @@ bool CModem::setMode(unsigned char mode) return m_serial.write(buffer, 4U) == 4; } +bool CModem::sendCWId(const std::string& callsign) +{ + unsigned int length = callsign.length(); + if (length > 200U) + length = 200U; + + unsigned char buffer[205U]; + + buffer[0U] = MMDVM_FRAME_START; + buffer[1U] = length + 3U; + buffer[2U] = MMDVM_SEND_CWID; + + for (unsigned int i = 0U; i < length; i++) + buffer[i + 3U] = callsign.at(i); + + // CUtils::dump(1U, "Written", buffer, length + 3U); + + return m_serial.write(buffer, length + 3U) == (length + 3U); +} + bool CModem::writeDMRStart(bool tx) { if (tx && m_tx) diff --git a/Modem.h b/Modem.h index 8c9fd4b..4655d54 100644 --- a/Modem.h +++ b/Modem.h @@ -67,6 +67,8 @@ public: bool setMode(unsigned char mode); + bool sendCWId(const std::string& callsign); + void clock(unsigned int ms); void close(); From 35632e025560daacac1508bad6e9e0614f2c2e72 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 10 May 2016 06:34:53 +0100 Subject: [PATCH 07/12] Remove a compiler warning. --- Modem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modem.cpp b/Modem.cpp index 1e35bf3..f34ac4a 100644 --- a/Modem.cpp +++ b/Modem.cpp @@ -1032,7 +1032,7 @@ bool CModem::sendCWId(const std::string& callsign) // CUtils::dump(1U, "Written", buffer, length + 3U); - return m_serial.write(buffer, length + 3U) == (length + 3U); + return m_serial.write(buffer, length + 3U) == int(length + 3U); } bool CModem::writeDMRStart(bool tx) From 3b48aa3985399817745fe2ae2a8ac715a1ebfba9 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 10 May 2016 07:20:38 +0100 Subject: [PATCH 08/12] Add more robustness to the IPSC link. --- DMRIPSC.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/DMRIPSC.cpp b/DMRIPSC.cpp index 16df31b..90fec99 100644 --- a/DMRIPSC.cpp +++ b/DMRIPSC.cpp @@ -119,11 +119,7 @@ bool CDMRIPSC::open() if (!ret) return false; - ret = writeLogin(); - if (!ret) { - m_socket.close(); - return false; - } + writeLogin(); m_status = WAITING_LOGIN; m_timeoutTimer.start(); @@ -272,15 +268,8 @@ bool CDMRIPSC::write(const CDMRData& data) if (m_debug) CUtils::dump(1U, "IPSC Transmitted", buffer, HOMEBREW_DATA_PACKET_LENGTH); - for (unsigned int i = 0U; i < count; i++) { - bool ret = write(buffer, HOMEBREW_DATA_PACKET_LENGTH); - if (!ret) { - LogError("Socket has failed when writing data to the master, retrying connection"); - close(); - open(); - return false; - } - } + for (unsigned int i = 0U; i < count; i++) + write(buffer, HOMEBREW_DATA_PACKET_LENGTH); return true; } @@ -332,7 +321,7 @@ void CDMRIPSC::clock(unsigned int ms) m_retryTimer.start(); m_pingTimer.stop(); } else { - LogError("Login to the master has failed"); + LogError("Login to the master has failed, stopping IPSC"); m_status = DISCONNECTED; m_timeoutTimer.stop(); m_retryTimer.stop(); @@ -497,5 +486,13 @@ bool CDMRIPSC::write(const unsigned char* data, unsigned int length) // if (m_debug) // CUtils::dump(1U, "IPSC Transmitted", data, length); - return m_socket.write(data, length, m_address, m_port); + bool ret = m_socket.write(data, length, m_address, m_port); + if (!ret) { + LogError("Socket has failed when writing data to the master, retrying connection"); + close(); + open(); + return false; + } + + return true; } From efca4fa0cb0c0c19bf66b3fda1657572939d9f6a Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 10 May 2016 07:44:45 +0100 Subject: [PATCH 09/12] Shorten the failure timeout. --- DMRIPSC.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DMRIPSC.cpp b/DMRIPSC.cpp index 90fec99..a65a874 100644 --- a/DMRIPSC.cpp +++ b/DMRIPSC.cpp @@ -45,7 +45,7 @@ m_slot1(slot1), m_slot2(slot2), m_status(DISCONNECTED), m_retryTimer(1000U, 10U), -m_timeoutTimer(1000U, 600U), +m_timeoutTimer(1000U, 60U), m_pingTimer(1000U, 5U), m_buffer(NULL), m_salt(NULL), From 7a3d77d5f55a44ed118db335e08dadcfb6529590 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 10 May 2016 08:00:41 +0100 Subject: [PATCH 10/12] Simplify the IPSC class. --- DMRIPSC.cpp | 53 +++++++++++++++++++++-------------------------------- DMRIPSC.h | 1 - 2 files changed, 21 insertions(+), 33 deletions(-) diff --git a/DMRIPSC.cpp b/DMRIPSC.cpp index a65a874..9688a2c 100644 --- a/DMRIPSC.cpp +++ b/DMRIPSC.cpp @@ -44,9 +44,8 @@ m_enabled(false), m_slot1(slot1), m_slot2(slot2), m_status(DISCONNECTED), -m_retryTimer(1000U, 10U), +m_retryTimer(1000U, 5U), m_timeoutTimer(1000U, 60U), -m_pingTimer(1000U, 5U), m_buffer(NULL), m_salt(NULL), m_streamId(NULL), @@ -119,8 +118,6 @@ bool CDMRIPSC::open() if (!ret) return false; - writeLogin(); - m_status = WAITING_LOGIN; m_timeoutTimer.start(); m_retryTimer.start(); @@ -319,13 +316,11 @@ void CDMRIPSC::clock(unsigned int ms) m_status = WAITING_LOGIN; m_timeoutTimer.start(); m_retryTimer.start(); - m_pingTimer.stop(); } else { LogError("Login to the master has failed, stopping IPSC"); m_status = DISCONNECTED; m_timeoutTimer.stop(); m_retryTimer.stop(); - m_pingTimer.stop(); } } else if (::memcmp(m_buffer, "RPTACK", 6U) == 0) { switch (m_status) { @@ -346,8 +341,7 @@ void CDMRIPSC::clock(unsigned int ms) LogMessage("Logged into the master successfully"); m_status = RUNNING; m_timeoutTimer.start(); - m_retryTimer.stop(); - m_pingTimer.start(); + m_retryTimer.start(); break; default: break; @@ -365,31 +359,26 @@ void CDMRIPSC::clock(unsigned int ms) } } - if (m_status != RUNNING) { - m_retryTimer.clock(ms); - if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) { - switch (m_status) { - case WAITING_LOGIN: - writeLogin(); - break; - case WAITING_AUTHORISATION: - writeAuthorisation(); - break; - case WAITING_CONFIG: - writeConfig(); - break; - default: - break; - } + m_retryTimer.clock(ms); + if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) { + switch (m_status) { + case WAITING_LOGIN: + writeLogin(); + break; + case WAITING_AUTHORISATION: + writeAuthorisation(); + break; + case WAITING_CONFIG: + writeConfig(); + break; + case RUNNING: + writePing(); + break; + default: + break; + } - m_retryTimer.start(); - } - } else { - m_pingTimer.clock(ms); - if (m_pingTimer.isRunning() && m_pingTimer.hasExpired()) { - writePing(); - m_pingTimer.start(); - } + m_retryTimer.start(); } m_timeoutTimer.clock(ms); diff --git a/DMRIPSC.h b/DMRIPSC.h index 069febe..209f29a 100644 --- a/DMRIPSC.h +++ b/DMRIPSC.h @@ -73,7 +73,6 @@ private: STATUS m_status; CTimer m_retryTimer; CTimer m_timeoutTimer; - CTimer m_pingTimer; unsigned char* m_buffer; unsigned char* m_salt; uint32_t* m_streamId; From 6dd10a54634f51ffe6d6d3b434920dcfdf286918 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 10 May 2016 08:18:10 +0100 Subject: [PATCH 11/12] Add special ALL id (0xFFFFFF). --- DMRLookup.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DMRLookup.cpp b/DMRLookup.cpp index 12bf0ae..e9de15b 100644 --- a/DMRLookup.cpp +++ b/DMRLookup.cpp @@ -72,6 +72,9 @@ std::string CDMRLookup::find(unsigned int id) const { std::string callsign; + if (id == 0xFFFFFFU) + return std::string("ALL"); + try { callsign = m_table.at(id); } catch (...) { From b594fce3015658161aec5868b5e629a18ab64618 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 10 May 2016 13:28:00 +0100 Subject: [PATCH 12/12] Changes to how the display timeout is handled. --- Display.cpp | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/Display.cpp b/Display.cpp index e9858d6..dcedceb 100644 --- a/Display.cpp +++ b/Display.cpp @@ -79,6 +79,7 @@ void CDisplay::writeDStar(const char* my1, const char* my2, const char* your, co assert(reflector != NULL); m_timer1.start(); + m_mode1 = MODE_IDLE; writeDStarInt(my1, my2, your, type, reflector); } @@ -88,6 +89,7 @@ void CDisplay::clearDStar() if (m_timer1.hasExpired()) { clearDStarInt(); m_timer1.stop(); + m_mode1 = MODE_IDLE; } else { m_mode1 = MODE_DSTAR; } @@ -97,10 +99,13 @@ void CDisplay::writeDMR(unsigned int slotNo, const std::string& src, bool group, { assert(type != NULL); - if (slotNo == 1U) + if (slotNo == 1U) { m_timer1.start(); - else + m_mode1 = MODE_IDLE; + } else { m_timer2.start(); + m_mode2 = MODE_IDLE; + } writeDMRInt(slotNo, src, group, dst, type); } @@ -111,6 +116,7 @@ void CDisplay::clearDMR(unsigned int slotNo) if (m_timer1.hasExpired()) { clearDMRInt(slotNo); m_timer1.stop(); + m_mode1 = MODE_IDLE; } else { m_mode1 = MODE_DMR; } @@ -118,6 +124,7 @@ void CDisplay::clearDMR(unsigned int slotNo) if (m_timer2.hasExpired()) { clearDMRInt(slotNo); m_timer2.stop(); + m_mode2 = MODE_IDLE; } else { m_mode2 = MODE_DMR; } @@ -130,6 +137,7 @@ void CDisplay::writeFusion(const char* source, const char* dest) assert(dest != NULL); m_timer1.start(); + m_mode1 = MODE_IDLE; writeFusionInt(source, dest); } @@ -139,6 +147,7 @@ void CDisplay::clearFusion() if (m_timer1.hasExpired()) { clearFusionInt(); m_timer1.stop(); + m_mode1 = MODE_IDLE; } else { m_mode1 = MODE_YSF; } @@ -151,34 +160,31 @@ void CDisplay::clock(unsigned int ms) switch (m_mode1) { case MODE_DSTAR: clearDStarInt(); + m_mode1 = MODE_IDLE; + m_timer1.stop(); break; case MODE_DMR: clearDMRInt(1U); + m_mode1 = MODE_IDLE; + m_timer1.stop(); break; case MODE_YSF: clearFusionInt(); + m_mode1 = MODE_IDLE; + m_timer1.stop(); + break; + default: break; } - - m_mode1 = MODE_IDLE; - m_timer1.stop(); } + // Timer/mode 2 are only used for DMR m_timer2.clock(ms); if (m_timer2.isRunning() && m_timer2.hasExpired()) { - switch (m_mode2) { - case MODE_DSTAR: - clearDStarInt(); - break; - case MODE_DMR: + if (m_mode2 == MODE_DMR) { clearDMRInt(2U); - break; - case MODE_YSF: - clearFusionInt(); - break; + m_mode2 = MODE_IDLE; + m_timer2.stop(); } - - m_mode2 = MODE_IDLE; - m_timer2.stop(); } }