From 35c0a83d379905c41d934413fc413e44595fe0f6 Mon Sep 17 00:00:00 2001 From: Tony Corbett Date: Sat, 28 May 2016 23:29:30 +0300 Subject: [PATCH 01/13] Add a clock to the idle screen --- Conf.cpp | 16 +++++++++++++++ Conf.h | 4 ++++ HD44780.cpp | 56 ++++++++++++++++++++++++++++++++++++++------------- HD44780.h | 6 ++++-- MMDVM.ini | 8 ++++++-- MMDVMHost.cpp | 10 +++++++-- 6 files changed, 80 insertions(+), 20 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index fbfd217..12c333a 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -119,6 +119,8 @@ m_hd44780PWM(false), m_hd44780PWMPin(), m_hd44780PWMBright(), m_hd44780PWMDim(), +m_hd44780DisplayClock(false), +m_hd44780UTC(false), m_nextionPort("/dev/ttyAMA0"), m_nextionBrightness(50U), m_oledType(3), @@ -370,6 +372,10 @@ bool CConf::read() m_hd44780PWMBright = (unsigned int)::atoi(value); else if (::strcmp(key, "PWMDim") == 0) m_hd44780PWMDim = (unsigned int)::atoi(value); + else if (::strcmp(key, "DisplayClock") == 0) + m_hd44780DisplayClock = ::atoi(value) == 1; + else if (::strcmp(key, "UTC") == 0) + m_hd44780UTC = ::atoi(value) == 1; else if (::strcmp(key, "Pins") == 0) { char* p = ::strtok(value, ",\r\n"); while (p != NULL) { @@ -754,6 +760,16 @@ unsigned int CConf::getHD44780PWMDim() const return m_hd44780PWMDim; } +bool CConf::getHD44780DisplayClock() const +{ + return m_hd44780DisplayClock; +} + +bool CConf::getHD44780UTC() const +{ + return m_hd44780UTC; +} + std::string CConf::getNextionPort() const { return m_nextionPort; diff --git a/Conf.h b/Conf.h index 3ee3a3e..b74e14e 100644 --- a/Conf.h +++ b/Conf.h @@ -126,6 +126,8 @@ public: unsigned int getHD44780PWMPin() const; unsigned int getHD44780PWMBright() const; unsigned int getHD44780PWMDim() const; + bool getHD44780DisplayClock() const; + bool getHD44780UTC() const; // The Nextion section std::string getNextionPort() const; @@ -221,6 +223,8 @@ private: unsigned int m_hd44780PWMPin; unsigned int m_hd44780PWMBright; unsigned int m_hd44780PWMDim; + bool m_hd44780DisplayClock; + bool m_hd44780UTC; std::string m_nextionPort; unsigned int m_nextionBrightness; diff --git a/HD44780.cpp b/HD44780.cpp index 821d41d..8504eb9 100644 --- a/HD44780.cpp +++ b/HD44780.cpp @@ -31,7 +31,7 @@ const char* LISTENING = "Listening "; const char* DEADSPACE = " "; -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) : +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 displayClock, bool utc, bool duplex) : CDisplay(), m_rows(rows), m_cols(cols), @@ -47,11 +47,13 @@ m_pwm(pwm), m_pwmPin(pwmPin), m_pwmBright(pwmBright), m_pwmDim(pwmDim), +m_displayClock(displayClock), +m_utc(utc), m_duplex(duplex), //m_duplex(true), // uncomment to force duplex display for testing! m_fd(-1), m_dmr(false), -m_timer(1000U, 0U, 250U) // 250ms +m_clockDisplayTimer(1000U, 0U, 75U) // Update the clock display every 75ms { assert(rows > 1U); assert(cols > 15U); @@ -288,6 +290,7 @@ void CHD44780::adafruitLCDColour(ADAFRUIT_COLOUR colour) void CHD44780::setIdleInt() { + m_clockDisplayTimer.start(); // Start the clock display in IDLE only ::lcdClear(m_fd); #ifdef ADAFRUIT_DISPLAY @@ -302,7 +305,9 @@ void CHD44780::setIdleInt() } ::lcdPosition(m_fd, 0, 0); - ::lcdPrintf(m_fd, "%-6s / %u", m_callsign.c_str(), m_dmrid); + ::lcdPrintf(m_fd, "%-6s", m_callsign.c_str()); + ::lcdPosition(m_fd, m_cols - 7, 0); + ::lcdPrintf(m_fd, "%7u", m_dmrid); ::lcdPosition(m_fd, 0, 1); ::lcdPutchar(m_fd, 2); @@ -310,7 +315,8 @@ void CHD44780::setIdleInt() ::lcdPutchar(m_fd, 3); ::lcdPutchar(m_fd, 4); ::lcdPutchar(m_fd, 2); - ::lcdPuts(m_fd, " Idle"); + if (!m_displayClock || m_cols > 16) + ::lcdPuts(m_fd, " Idle"); m_dmr = false; } @@ -323,6 +329,7 @@ void CHD44780::setErrorInt(const char* text) adafruitLCDColour(AC_RED); #endif + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); if (m_pwm) { @@ -351,6 +358,7 @@ void CHD44780::setLockoutInt() adafruitLCDColour(AC_RED); #endif + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); if (m_pwm) { @@ -385,6 +393,7 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your, adafruitLCDColour(AC_RED); #endif + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); if (m_pwm) { @@ -448,6 +457,8 @@ void CHD44780::clearDStarInt() adafruitLCDColour(AC_PURPLE); #endif + m_clockDisplayTimer.stop(); // Stop the clock display + if (m_rows == 2U && m_cols == 16U) { ::lcdPosition(m_fd, 0, 1); ::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING); @@ -475,6 +486,7 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro assert(type != NULL); if (!m_dmr) { + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); #ifdef ADAFRUIT_DISPLAY @@ -520,8 +532,6 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); ::lcdPuts(m_fd, "1 "); ::sprintf(buffer, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE); - - // Thread this out? ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, buffer); if (m_cols > 16) { @@ -536,8 +546,6 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro ::lcdPosition(m_fd, 0, (m_rows / 2)); ::lcdPuts(m_fd, "2 "); ::sprintf(buffer, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE); - - // Thread this out? ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, buffer); if (m_cols > 16) { @@ -577,6 +585,7 @@ void CHD44780::clearDMRInt(unsigned int slotNo) adafruitLCDColour(AC_PURPLE); #endif + m_clockDisplayTimer.stop(); // Stop the clock display if (m_duplex) { if (slotNo == 1U) { ::lcdPosition(m_fd, 0, 0); @@ -605,6 +614,7 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, const char* adafruitLCDColour(AC_RED); #endif + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); if (m_pwm) { @@ -657,6 +667,8 @@ void CHD44780::clearFusionInt() adafruitLCDColour(AC_PURPLE); #endif + m_clockDisplayTimer.stop(); // Stop the clock display + if (m_rows == 2U && m_cols == 16U) { ::lcdPosition(m_fd, 0, 1); ::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING); @@ -680,13 +692,29 @@ void CHD44780::clearFusionInt() void CHD44780::clockInt(unsigned int ms) { - m_timer.clock(ms); - if (m_timer.isRunning() && m_timer.hasExpired()) { - // Do work every 250ms here + // Update the clock display in IDLE mode every 75ms + m_clockDisplayTimer.clock(ms); + if (m_displayClock && m_clockDisplayTimer.isRunning() && m_clockDisplayTimer.hasExpired()) { + time_t currentTime; + struct tm *Time; + time(¤tTime); // Get the current time - // Start the timer with m_timer.start(); - // and stop it with m_timer.stop(); - m_timer.start(); + if (m_utc){ + Time = gmtime(¤tTime); + } else { + Time = localtime(¤tTime); + } + + //int Day = Time->tm_mday; + //int Month = Time->tm_mon + 1; + //int Year = Time->tm_year + 1900; + int Hour = Time->tm_hour; + int Min = Time->tm_min; + int Sec = Time->tm_sec; + + ::lcdPosition(m_fd, m_cols - 8, 1); + ::lcdPrintf(m_fd, "%02d:%02d:%02d", Hour, Min, Sec); + m_clockDisplayTimer.start(); // restart the clock display timer } } diff --git a/HD44780.h b/HD44780.h index 332a14f..a776413 100644 --- a/HD44780.h +++ b/HD44780.h @@ -53,7 +53,7 @@ enum ADAFRUIT_COLOUR { 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); + 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 displayClock, bool utc, bool duplex); virtual ~CHD44780(); virtual bool open(); @@ -91,10 +91,12 @@ private: unsigned int m_pwmPin; unsigned int m_pwmBright; unsigned int m_pwmDim; + bool m_displayClock; + bool m_utc; bool m_duplex; int m_fd; bool m_dmr; - CTimer m_timer; + CTimer m_clockDisplayTimer; #ifdef ADAFRUIT_DISPLAY void adafruitLCDSetup(); diff --git a/MMDVM.ini b/MMDVM.ini index 5cb9235..c859b73 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -95,12 +95,16 @@ Pins=11,10,0,1,2,3 # For Adafruit i2c HD44780 # Pins=115,113,112,111,110,109 -# PWM brightness control -PWM=1 +# PWM backlight +PWM=0 PWMPin=21 PWMBright=100 PWMDim=16 +# Display a clock when in IDLE? (HD44780 ONLY!) +DisplayClock=1 +ZuluClock=0 + [Nextion] Port=/dev/ttyAMA0 Brightness=50 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 514605b..c1d047f 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -801,20 +801,26 @@ void CMMDVMHost::createDisplay() unsigned int pwmPin = m_conf.getHD44780PWMPin(); unsigned int pwmBright = m_conf.getHD44780PWMBright(); unsigned int pwmDim = m_conf.getHD44780PWMDim(); + bool displayClock = m_conf.getHD44780DisplayClock(); + bool utc = m_conf.getHD44780UTC(); if (pins.size() == 6U) { LogInfo(" Rows: %u", rows); LogInfo(" Columns: %u", columns); LogInfo(" Pins: %u,%u,%u,%u,%u,%u", pins.at(0U), pins.at(1U), pins.at(2U), pins.at(3U), pins.at(4U), pins.at(5U)); + LogInfo(" PWM Backlight: %s", pwm ? "yes" : "no"); if (pwm) { - LogInfo("PWM Brightness Control Enabled"); LogInfo(" PWM Pin: %u", pwmPin); LogInfo(" PWM Bright: %u", pwmBright); LogInfo(" PWM Dim: %u", pwmDim); } - m_display = new CHD44780(rows, columns, m_callsign, dmrid, pins, pwm, pwmPin, pwmBright, pwmDim, m_duplex); + LogInfo(" Clock Display: %s", displayClock ? "yes" : "no"); + if (displayClock) + LogInfo(" Display UTC: %s", utc ? "yes" : "no"); + + m_display = new CHD44780(rows, columns, m_callsign, dmrid, pins, pwm, pwmPin, pwmBright, pwmDim, displayClock, utc, m_duplex); } #endif #if defined(OLED) From 124f465a5818734038841e8b13dddd1afcdcaabf Mon Sep 17 00:00:00 2001 From: Tony Corbett Date: Sat, 28 May 2016 23:36:04 +0300 Subject: [PATCH 02/13] Correct MMDVM.ini flag error for UTC clock display --- MMDVM.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MMDVM.ini b/MMDVM.ini index c859b73..fc475e7 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -103,7 +103,7 @@ PWMDim=16 # Display a clock when in IDLE? (HD44780 ONLY!) DisplayClock=1 -ZuluClock=0 +UTC=0 [Nextion] Port=/dev/ttyAMA0 From 26fabb2b68945218bc4a39941763f2ee03bb3d9e Mon Sep 17 00:00:00 2001 From: Tony Corbett Date: Sun, 29 May 2016 10:13:43 +0300 Subject: [PATCH 03/13] Impliment clock on all HD44780 sizes and redesigned IDLE screen --- HD44780.cpp | 130 +++++++++++++++++++++++++++--------------------- HD44780.layouts | 58 +++++++++++++++++++++ 2 files changed, 130 insertions(+), 58 deletions(-) create mode 100644 HD44780.layouts diff --git a/HD44780.cpp b/HD44780.cpp index 8504eb9..339a3c8 100644 --- a/HD44780.cpp +++ b/HD44780.cpp @@ -31,6 +31,9 @@ const char* LISTENING = "Listening "; const char* DEADSPACE = " "; +char m_buffer1[128U]; +char m_buffer2[128U]; + 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 displayClock, bool utc, bool duplex) : CDisplay(), m_rows(rows), @@ -304,19 +307,21 @@ void CHD44780::setIdleInt() ::pwmWrite(m_pwmPin, (m_pwmDim / 100) * 1024); } + // Print callsign and ID at on top row for all screen sizes ::lcdPosition(m_fd, 0, 0); ::lcdPrintf(m_fd, "%-6s", m_callsign.c_str()); ::lcdPosition(m_fd, m_cols - 7, 0); ::lcdPrintf(m_fd, "%7u", m_dmrid); - ::lcdPosition(m_fd, 0, 1); + // Print MMDVM and Idle on bottom row for all screen sizes + ::lcdPosition(m_fd, 0, m_rows - 1); ::lcdPutchar(m_fd, 2); ::lcdPutchar(m_fd, 2); ::lcdPutchar(m_fd, 3); ::lcdPutchar(m_fd, 4); ::lcdPutchar(m_fd, 2); - if (!m_displayClock || m_cols > 16) - ::lcdPuts(m_fd, " Idle"); + ::lcdPosition(m_fd, m_cols - 4, m_rows - 1); + ::lcdPuts(m_fd, "Idle"); // Gets overwritten by clock on 2 line screen m_dmr = false; } @@ -407,45 +412,45 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your, ::lcdPuts(m_fd, "D-Star"); if (m_rows == 2U && m_cols == 16U) { - char buffer[16U]; - ::sprintf(buffer, "%s %.8s/%.4s", type, my1, my2); +// char buffer[16U]; + ::sprintf(m_buffer1, "%s %.8s/%.4s", type, my1, my2); ::lcdPosition(m_fd, 0, 1); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } else if (m_rows == 4U && m_cols == 16U) { - char buffer[16U]; - ::sprintf(buffer, "%s %.8s/%.4s", type, my1, my2); +// char buffer[16U]; + ::sprintf(m_buffer1, "%s %.8s/%.4s", type, my1, my2); ::lcdPosition(m_fd, 0, 1); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); if (strcmp(reflector, " ") == 0) - ::sprintf(buffer, "%.8s", your); + ::sprintf(m_buffer1, "%.8s", your); else - ::sprintf(buffer, "%.8s<%.8s", your, reflector); + ::sprintf(m_buffer1, "%.8s<%.8s", your, reflector); ::lcdPosition(m_fd, 0, 2); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } else if (m_rows == 4U && m_cols == 20U) { - char buffer[20U]; - ::sprintf(buffer, "%s %.8s/%.4s >", type, my1, my2); + char m_buffer1[20U]; + ::sprintf(m_buffer1, "%s %.8s/%.4s >", type, my1, my2); ::lcdPosition(m_fd, 0, 1); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); if (strcmp(reflector, " ") == 0) - ::sprintf(buffer, "%.8s", your); + ::sprintf(m_buffer1, "%.8s", your); else - ::sprintf(buffer, "%.8s <- %.8s", your, reflector); + ::sprintf(m_buffer1, "%.8s <- %.8s", your, reflector); ::lcdPosition(m_fd, 0, 2); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } else if (m_rows == 2 && m_cols == 40U) { - char buffer[40U]; + char m_buffer1[40U]; if (strcmp(reflector, " ") == 0) - ::sprintf(buffer, "%s %.8s/%.4s > %.8s", type, my1, my2, your); + ::sprintf(m_buffer1, "%s %.8s/%.4s > %.8s", type, my1, my2, your); else - ::sprintf(buffer, "%s %.8s/%.4s > %.8s via %.8s", type, my1, my2, your, reflector); + ::sprintf(m_buffer1, "%s %.8s/%.4s > %.8s via %.8s", type, my1, my2, your, reflector); ::lcdPosition(m_fd, 0, 1); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } m_dmr = false; @@ -482,7 +487,7 @@ void CHD44780::clearDStarInt() void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) { - char buffer[128]; // force 128 char buffer - we're never getting that far but stops us overflowing it! +// char buffer[128]; // force 128 char buffer - we're never getting that far but stops us overflowing it! assert(type != NULL); if (!m_dmr) { @@ -503,8 +508,8 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro if (m_duplex) { if (m_rows > 2U) { ::lcdPosition(m_fd, 0, (m_rows / 2) - 2); - ::sprintf(buffer, "%s%s", "DMR", DEADSPACE); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::sprintf(m_buffer1, "%s%s", "DMR", DEADSPACE); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } if (slotNo == 1U) { @@ -516,8 +521,8 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro } } else { ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); - ::sprintf(buffer, "%s%s", "DMR", DEADSPACE); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::sprintf(m_buffer1, "%s%s", "DMR", DEADSPACE); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); ::lcdPosition(m_fd, 0, (m_rows / 2)); ::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING); } @@ -531,8 +536,8 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro if (slotNo == 1U) { ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); ::lcdPuts(m_fd, "1 "); - ::sprintf(buffer, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE); - ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, buffer); + ::sprintf(m_buffer1, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE); + ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, m_buffer1); if (m_cols > 16) { ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); @@ -545,8 +550,8 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro } else { ::lcdPosition(m_fd, 0, (m_rows / 2)); ::lcdPuts(m_fd, "2 "); - ::sprintf(buffer, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE); - ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, buffer); + ::sprintf(m_buffer2, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE); + ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, m_buffer2); if (m_cols > 16) { ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); @@ -560,16 +565,16 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro } else { ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); ::lcdPutchar(m_fd, 0); - ::sprintf(buffer, " %s%s", src.c_str(), DEADSPACE); - ::lcdPrintf(m_fd, "%.*s", m_cols - 4U, buffer); + ::sprintf(m_buffer2, " %s%s", src.c_str(), DEADSPACE); + ::lcdPrintf(m_fd, "%.*s", m_cols - 4U, m_buffer2); ::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar); ::lcdPosition(m_fd, m_cols - 1U, (m_rows / 2) - 1); ::lcdPutchar(m_fd, 5); ::lcdPosition(m_fd, 0, (m_rows / 2)); ::lcdPutchar(m_fd, 1); - ::sprintf(buffer, " %s%s", dst.c_str(), DEADSPACE); - ::lcdPrintf(m_fd, "%.*s", m_cols - 4U, buffer); + ::sprintf(m_buffer2, " %s%s", dst.c_str(), DEADSPACE); + ::lcdPrintf(m_fd, "%.*s", m_cols - 4U, m_buffer2); ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); ::lcdPosition(m_fd, m_cols - 1U, (m_rows / 2)); ::lcdPutchar(m_fd, 6); @@ -579,7 +584,7 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro void CHD44780::clearDMRInt(unsigned int slotNo) { - char buffer[128]; // force 128 char buffer - we're never getting that far but stops us overflowing it! +// char buffer[128]; // force 128 char buffer - we're never getting that far but stops us overflowing it! #ifdef ADAFRUIT_DISPLAY adafruitLCDColour(AC_PURPLE); @@ -596,8 +601,8 @@ void CHD44780::clearDMRInt(unsigned int slotNo) } } else { ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); - ::sprintf(buffer, "%s%s", "DMR", DEADSPACE); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::sprintf(m_buffer2, "%s%s", "DMR", DEADSPACE); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer2); ::lcdPosition(m_fd, 0, (m_rows / 2)); ::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING); } @@ -628,34 +633,34 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, const char* ::lcdPuts(m_fd, "System Fusion"); if (m_rows == 2U && m_cols == 16U) { - char buffer[16U]; - ::sprintf(buffer, "%.10s >", source); + char m_buffer1[16U]; + ::sprintf(m_buffer1, "%.10s >", source); ::lcdPosition(m_fd, 0, 1); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } else if (m_rows == 4U && m_cols == 16U) { - char buffer[16U]; - ::sprintf(buffer, "%.10s >", source); + char m_buffer1[16U]; + ::sprintf(m_buffer1, "%.10s >", source); ::lcdPosition(m_fd, 0, 1); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); - ::sprintf(buffer, "%.10s", dest); + ::sprintf(m_buffer1, "%.10s", dest); ::lcdPosition(m_fd, 0, 2); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } else if (m_rows == 4U && m_cols == 20U) { - char buffer[20U]; - ::sprintf(buffer, "%.10s >", source); + char m_buffer1[20U]; + ::sprintf(m_buffer1, "%.10s >", source); ::lcdPosition(m_fd, 0, 1); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); - ::sprintf(buffer, "%.10s", dest); + ::sprintf(m_buffer1, "%.10s", dest); ::lcdPosition(m_fd, 0, 2); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } else if (m_rows == 2 && m_cols == 40U) { - char buffer[40U]; - ::sprintf(buffer, "%.10s > %.10s", source, dest); + char m_buffer1[40U]; + ::sprintf(m_buffer1, "%.10s > %.10s", source, dest); ::lcdPosition(m_fd, 0, 1); - ::lcdPrintf(m_fd, "%.*s", m_cols, buffer); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } m_dmr = false; @@ -705,15 +710,24 @@ void CHD44780::clockInt(unsigned int ms) Time = localtime(¤tTime); } - //int Day = Time->tm_mday; - //int Month = Time->tm_mon + 1; - //int Year = Time->tm_year + 1900; + int Day = Time->tm_mday; + int Month = Time->tm_mon + 1; + int Year = Time->tm_year + 1900; int Hour = Time->tm_hour; int Min = Time->tm_min; int Sec = Time->tm_sec; - ::lcdPosition(m_fd, m_cols - 8, 1); + if (m_cols == 16U && m_rows == 2U) { + ::lcdPosition(m_fd, m_cols - 8, 1); + } else { + ::lcdPosition(m_fd, (m_cols - 8) / 2, m_rows == 2 ? 1 : 2); + } ::lcdPrintf(m_fd, "%02d:%02d:%02d", Hour, Min, Sec); + + if (m_cols != 16U && m_rows != 2U) { + ::lcdPosition(m_fd, (m_cols - 8) / 2, m_rows == 2 ? 0 : 1); + ::lcdPrintf(m_fd, "%02d/%02d/%2d", Day, Month, Year%100); + } m_clockDisplayTimer.start(); // restart the clock display timer } } diff --git a/HD44780.layouts b/HD44780.layouts new file mode 100644 index 0000000..03560cf --- /dev/null +++ b/HD44780.layouts @@ -0,0 +1,58 @@ +IDLE SCREEN LAYOUTS +------------------- + +16 x 2 +------ + + With clock Without clock + ---------- ------------- + + 0 1 0 1 + 0123456789012345 0123456789012345 + +----------------+ +----------------+ +0|AAAAAA NNNNNNN| 0|AAAAAA NNNNNNN| +1|MMDVM HH:MM:SS| 1|MMDVM Idle| + +----------------+ +----------------+ + +40 x 2 +------ + + With clock Without clock + ---------- ------------- + + 0 1 2 3 0 1 2 3 + 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789 + +----------------------------------------+ +----------------------------------------+ +0|AAAAAA DD/MM/YY NNNNNNN| 0|AAAAAA NNNNNNN| +1|MMDVM HH:MM:SS Idle| 1|MMDVM Idle| + +----------------------------------------+ +----------------------------------------+ + +16 x 4 +------ + + With clock Without clock + ---------- ------------- + + 0 1 0 1 + 0123456789012345 0123456789012345 + +----------------+ +----------------+ +0|AAAAAA NNNNNNN| 0|AAAAAA NNNNNNN| +1| DD/MM/YY | 1| | +2| HH:MM:SS | 2| | +3|MMDVM Idle| 3|MMDVM Idle| + +----------------+ +----------------+ + +20 x 4 +------ + + With clock Without clock + ---------- ------------- + + 0 1 0 1 + 01234567890123456479 01234567890123456789 + +--------------------+ +--------------------+ +0|AAAAAA NNNNNNN| 0|AAAAAA NNNNNNN| +1| DD/MM/YY | 1| | +2| HH:MM:SS | 2| | +3|MMDVM Idle| 3|MMDVM Idle| + +--------------------+ +--------------------+ From 96d6883fea35455bd7803eb6b5c2b2d5aa97ee60 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 1 Jun 2016 09:32:10 +0100 Subject: [PATCH 04/13] Modify display to allow space for a clock on the idle screen. --- Nextion/MMDVM_2.4.HMI | Bin 272703 -> 273578 bytes Nextion/MMDVM_2.4.tft | Bin 347440 -> 348542 bytes Nextion/MMDVM_3.2.HMI | Bin 272703 -> 273578 bytes Nextion/MMDVM_3.2.tft | Bin 347483 -> 348588 bytes Nextion/MMDVM_3.5.HMI | Bin 628337 -> 629212 bytes Nextion/MMDVM_3.5.tft | Bin 699828 -> 700933 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Nextion/MMDVM_2.4.HMI b/Nextion/MMDVM_2.4.HMI index 3b33f0ce574d2f6b51ea4fb878533e37455b838c..d3014ac753bf24f8f16a1b7f1724a743c0b3a883 100644 GIT binary patch delta 1129 zcmYk*Yluu?9LMqBne!j^LOa=6!|u+^S!dR`j9i8+R$A<8)Q)A66!FHTyzqiJQ8qRv zx0<0mwJxQ!vhKMIFRV-1yi-bSE+vwcLbxUugSkUvb3`h?)_WiYh;f@r$3?%?tj$6X;ihGPRZ) z>;Qr)8zJ>uThY)tbh$A|Q!iF_6J3nnXK|<0f_RjHWQE1Zc!s>S7;_;WD*xl?twzzCnGs zW%{=94t4N~dRSfx%*T0}#0#3ngaJHZCMNMBn4%Y`r~NU@bd$M1*K{-WVV>y)#)Z^{ zN4-K>Ov?2j9p(D)9-2WSsCyZWV+VE6K~s238!@p$KfQ>?u$kJ}LIvAQZ>K(FP46=9 zr4CM054D5!ARA~BCukail~iJDkw8Oi24vT9Wqu@7t^U%cwQ^5 zdXTyrefS!hL6_##|^v|fHDQu;U=%y}uX$%8h{k8xV1Wkvi4?|5?8>7_04C72V;tY-99<_0w3VKXGran9!qpC+r KR2t%22K)xGJHXQb delta 1008 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 delta 1028 zcmYk)Ur1A77{~G7Ip3=9md(KO91Z4!7BL>XQ54>6m88I@?( zg?8avH-bTsN+1O7CNYSFAW0%nX(5P#b=RFiVbA+W=wP4s%foy2z6Un3;ZP z-WIRhK6hoot6FX9aaZ65E*MHJ+EnJBz#8DS8F`CF5;%z9pFgdfojq*h$rf{j;9z?Q#zjEm0ICY%K>sJpF?HV zEEZIqLlxcmcGWi(Iwq2^B(CttcknQec}M?V3JM1*$D(u&su0?2{Gvw)qfP7jm*Q+5!OV#bfXw$9b9JLSAgt zunD|oV<7%xRHBNFV^DgU4PlkFLAm-xqHF|@Stq%&pL+F+RQvUFSJ@ceuoh-m!aM0% z){Qyod6|EaUSLfuNvFhR)`1z&H@d|JG0IvPV+qftU$7=7q+e>onBv98Je$A?M_*!u pt;7d5jy*x$r`Qm>SQ{g31D4qcf<=6!3LK!n>R~D6Q(rjm&p!i}u37*9 diff --git a/Nextion/MMDVM_3.2.tft b/Nextion/MMDVM_3.2.tft index fd2752d6bf00327ca34a6aa3c339f65fa2f43d66..84d851985af552fcdf49b7f1c7d63415956aa051 100644 GIT binary patch delta 4677 zcmcK6dvF!i9S895?w-9sAY34?OWfrK!oy$!2{A}YAY2|+gn$ZyU{QICN~>t0I?5H5 zFtikiVit@=9%9FWL265U@n}&C0@X^#X#vrSI4D))hyvPTzvtT#=#2lCfzSD#-=6c^ z&1Uaj4n3B$X?;#LP&g`Qu)%eEf#ps!nyG{D{>;ww@pd=hid9{ySgZ=3KywXl1AGnr0-;wB32F}CMCT9(Hj=hH5x zO|&J?bc>ROCbJEY#b4pK-x4QUQ10hu^#0#@^y5O)ig(K%iPfm0l9Df1uc znuP$pFcnjsg=~<8+zZ>F1jBLKjc%{>7eoUp{dm{jT3*lP&wtPID={78eY<>l*AZH| zhbvEf&&nBCfah97Yx=VBugd+BScHu@*gAT%+;5C+!cL6Jj0RQt4@bEbeh~Wu4r5E( z^Oq6ruJAj>-oa^Pw%6IBd;79*2HDQ6EZej(*3%j2)aBKe`OBjZF5|IkXRPCOv^|$c zEBmo|pH5 z-g2azC2MIC8?0%(!XdzW)WcEvAsvM7d@?;0$zqy^A=Jkes*Iopqm{3rF2*X4rvdJi z%j8BHVz)e|iW9SILYc1AaIL(9hFB^$%H8r9O~SOW7SaIK)WcvojHXblyjU)w2|TI% zYih7jxskefR{1#^;El9~6S751d-|?2MFUKdcgsiR7P+5>_*k}RrCl;blekHyX@Cam zVYOUKQ+Qwbm^|JpZLbs=c9BO7S}12w7j2Z|v=d5{OKBE{&=`ix(X;?Rk;~*}+7eCF z!;3Tnuh4uPQ9e%NIHl~gW_b`&t?i-_G=(L~^)^SJ5B7`FAr|tj7-F5=L6bNl|4jpQ z%(UkTWRm8iQn^Z2%fZy(a^>OF#R%n5G{7ygmWEg_cglCHX?(3oUR!(OzVccc;125H zE;*0JQLDUIE}^+tr@Vn0JgvNmx@c71LIdoVA4xxMFQSXArUBB|YnUe=k(=dS8sfO* zyVq`$)ijA42D(c~J`2{eFLz=)@Wv9KpP@j5eNnK>5HOZs_isUdknTD7z z8&qkM2jpk6bqBkv2MsY)PL}g!15M&Z`F9%NOX}gY{D!7bmBr`NLp8q?`DvpGOjMpk z4JIp3qb_DB&!Pbq%C&ME4RKJOQY96Y1DV$bz^K2eMGf<cQnA8)WZS!HcjAD<S3ImKnG!!^5gOenuo2_$4hdj>bt1H zp8`GquXEyJpANi11Dud8LYoU|h(U6aDtF6A1;QI)I)(Rq$x~Oo+)pk2|Pf3ERsu9Uq%fcQLd*h zRw_48-v1^$;DG#$hG^5pT0{d3lau9ra+Ul&4e^%zOtvZ1E}Fy@awZM%AoWly7t<78 zSKcqvZ*oZBIQ8*~O3l>Zr1B~1;*9dYXjc?;we1RNE-GmZ)p8guz;qg5f%01AZL}p` zr5<+E47^1X_*nU5nnN63H+vwH4nmFcc*?h)@;c?C%AY9r>TcVW(Ev4amRv~rsgXP6 zVR=U8_OSP+LXM>YZtsz{jqc>c!(5ucQsp|iLPpe}L3uTGu||144X{HVq9IPpoQrMl zBS*{IXcE7Wzo7wMqaOBLtml6pCvhB7>4^LX&BZC@uc^UVWv9rV-lHC3G(ZF~oP3K0_>_A1T%M#UR9s>!{bYZdz!>Fm z)L^3WB`gMfNZ8o#7nHbXn-rJ zhZ=bmO`%SCg^Xwdo0We{4Yn$$U*O>4B~7-|00-q)vO_O>`rdLR4REu3NUo7D%fHbO zU&;=>wM&kqN!%)bP6IqeJv=Qpr8%VVi6+hR3z|UdQoE=vHRzz6LtW%4=hIH;r`(@r zVHAyFtei-@AuXSjduU7ig?jia&A<_wz*nW3pv*piahidSG=+)E)08(TZ&q$Di~800 LNmF&`$^HKUtMbTk delta 4344 zcmcK7dvF!y83yoYcfUO(;c^b-b`o}TLJ|xlArNjs&?EeY6rx9MpG{}^R%vtmKN8sk}gf~o|Ete_!o`dZn+Z!$UL1a;*c za)WEj&A4D}k@2lXLF+){1z-8hK~R@xW(1vCrl(t7QB_qPoX#?1(-bR)RRs;j=BHLg zSO3bc{zJO@S9SFt+SPwpuzQdh5Zsz$F0?jw^`Dc){vBQYYjRD@st%^)n(=P+kpDE! z3$pV~dCwkv<-h&5mtOx^(2#EuJYh?|DYhmCZ`YZA!GU};^!tk&8Ptz3(V(HPF%KXI1x8siW}69aF+z7)ox{E zF;>7y4?0J?Ex{+%Zb9T>ti>G};Yl|~*5M_*+dW*pI+%8$n;+SMLm1gBEG!M~x!8>c z-9~fEVVuFLSXa|cquDgw@~!PzVbjf#0&AF6k)v-SD87iRhg(yv)w$v7mf%oWXtZvz zzREk_bWr40Yo#^I3$|R$?T=U+t@eVh-XGSm_g?FeHKVxef;ZHLXSYsS9VOujRs}z( zbG^vltTcP@1wpEg+tck5`{4oSdq;!4Np9(H*V!MJscGAsvF>G7%E8BcQyP3i9ehe{ zoK`+VJw%<*ayfzeXp&1+d0PHn9+02Op1fy#l*tLQNiL-ctdlQOFNGr<9K0w0LX#+R z!%BZSfW}d$d)f~*HVM^%Fj|8&na)BaqLxojmB^=#UX;D@&j53 zJ1w+`rlE{F7(_ErP4h8Tc_xkGM&*SxiEYX+D!yQ6_a z9VZF=P~Jy9JV_lqE!WW~wkU6v+h`8oQspvgP^nx+?G%P-GLm{|lndkv z>SKd!SLJP2fXm$HMgm)ImR4LX$|%)?}`nPvcmo+)NEt zD6gb89#vjNJ#3b5$>Y?A(>t_~dbmhVmkVW!e4hGvQy!O2s*kqO1Zw3h>fvtc;9j|e zCh>}LyL_F-(W(3aH8`$(lG^x0`BPee9+_dED9uC>jbMPRq=mR5lXrC?7HIMaO~V@M z;0c<6^)w$lm0zb(98`XvCebe|TvJYyxJh}javOE9oq9MZKbO6-!*8`*PL#8=kz(n7 zP1e!`cFAMZ!`IZoIr%M(BbUF@9OO%17E*%} zA%U#i&|%cW6zZT+UPYs5Ql2Akq&ZkZUHnXy2dTl&l^>-xT9sE*4=>0Ld4l?I0CXkdrq8{#{4pQ=dT8BN#ugW)QE;^};kK{?!Pf>%^ zX-&>h8)ucjq8_sHLx;%8)W4Ye^-c^2inMy`=tsgM2glqzX{xTZwb$!mSy z{~qq-#K+@utK2V7(FD2|gqBecxo{a)o?W?vd|NAK%D$p?1ken!s(cg?f0NI@lt&(j?9( ze@XdQ&DR{_=-n^8>Ky7Ij~e*Oh15ooa(`NaNy?LH4z8yW%#{mhAs(R~HY&fRe4M7? zQ|jO|nt^X<9GOMTeE)NZq9UANB(1|@`AMJ&MCMIW&oB)WHnuVX<5#H&ecA zWXj9%Ucgo$=pk4WOYU54i4(j2AH2uTV^piDm zro2-=P80a8{1f%?ck1Btl!mi33UfhN>LxR24hofvsX?i78MRTNJeYd8T+WfpsE>7W zrz(GzXJzlwaQz@TiTe0)X(}9+X|hi4qzN3A-%t;^1H#M7mp)BmmhyG7iN;KPNC!Tq9-Q*fgd9VCOqYvPX_dd0Z_2+)t0G)k zAjin*auH2nwS19!*iRk26Pm&S4oTz;3QKv?qj3yZuBHZKlxwJsI^|1f0j^VSqM5jZ zMsTlOM*HJA`3LzqO~XH_gMZNsbgK-{GBm*<0|RLkqm;+eB$g?!RDN6euyWqu;GwDf Kw{zD~*#8C?Aa~RN diff --git a/Nextion/MMDVM_3.5.HMI b/Nextion/MMDVM_3.5.HMI index b3eb571553145987d58973f42eb3cbf9e95353ea..0e06f3100fa645e23f554b4789f0348d81dc3ac6 100644 GIT binary patch delta 1232 zcmYk(dq`AS90&04oqI>;XrbwK$5is#j1F6h)f5>P(ZgZ_FWM0M&&JjtQA<&~i)<4` z(}R-c#i-<=*B?O%_QZ+?gQ5pX^iRve(pnb924w{0UoDl@_ne5j@cW$axt!;{V`u6{ zF4kqI)J#tcsOM{2e!cmEexVsTB)S%Lb`2F*|GLA1ffdG=kx9-v*(GrGkbu!GV5(7V z_TH?~nKe{-SSHJ2d0Ba^e3mblHN;=*WZPCToZGZc7`2ucu;lLvQC8`Nz$ZRSTUUNN z0+3gLB6*wx%wpJbFd^dJ6do8?szMtQLdQ{1^DN!lr zqZLb|9c%xP18MQ2>EdTuljI_IlcFkbH8!JTrff?IyEi4u%`Mm^D^sG;+>HaWRfPnO z$hZneaY_!Ta2gloe=1zUZCRFP7{YzIT!nuzDz~Zd67S_{2I~U~4EZJ@D&+rZVVi|U zsVvHfM)_Mtc;%9eXt3&xxrTI89FfUzM3WK8oy>@bM%=|y9}tGkzZJ!L8pdH7!VT)+ zDUD!S0nmaiG=Odz#ARw?kXpE^^L6UMO`UIR?@$LXXbfu#fp!egFrHBtvnFtb63k&^ zVV>$>KFybty2Qb_gT+N^-WBS?SFGkW(|6PJWQjgw^jayhOnPH=%W$5rY)FV zrWX2%2Cm@g;w?27;~g6dA5{m2pC1Q4 zYNC)@DAKuvdSL79*H+K~7SLF(tVhJvUv8>Vi*KY+T+?}shEP6L9ixdxu$#7Ehz2l9 zgP0glyA@Llw$6U)!DOAQwAIwXLK;Jkw!;@xdo@!R2PiL+Vq+nzI_RPKIIQzA{r!6!8Z|yq{-jzV&%M@B8%py8GVnjhe4lYEqTe z>pBF~^KYDTKYU#`G&?dPy|6t!P+GNlpA7@^jM15Qx#~ifz{-q(*)3qHS<3^5Q$~Br zP-U_#md*09@>uz-f?UcFgBx?TTf}&GsSQ~8!>2K}Ys1d5V|_LXM*FQR$GSkCK(X$x zjy3(?_m#jek9LZrFN>GP6Is|LYO7x{3f|X`$^XyAOoXA&lc`QI!=8^8$da@umruJy zz+QqikPFpEt6K!DwTR2|ZZX^1hTU?h3JDyS2UO_5DcPsOX=LR)70%*@45S!t;-PF( zVF1r%fS)Arn)9}j$40gbnZphYd-k>wh8`KzexpQgp z%1ExjNC6N+8Q)kG8>xlO)W%kwx6ypG>AXkx_v?I+nmDBM5$!SR;37@HDO9_~X$V;w z!*`v7-Gg`){BbV%)v{q4 z#ms=ZL@l*3N9VaTA7P#Ab-zL92sN=t=N4@%b+Mf$@Sb`onxu9sp*H+FPo^fO=v<*} zKqUtU^)!K7Gzy#lyAbMV3>`Z6(;!Bu1G`Lpr&bz44|Q{aj7X}t9IjUD;xvjo)WSV# z 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 From ed8ea924688d40586e0bda13676e5341b785277e Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 1 Jun 2016 09:43:39 +0100 Subject: [PATCH 05/13] Re-add debug BER displays for D-Star and DMR. --- DMRSlot.cpp | 22 +++++++--------------- DStarControl.cpp | 4 ++-- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 28e6d76..123767d 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -389,7 +389,7 @@ void CDMRSlot::writeModem(unsigned char *data) unsigned char fid = m_rfLC->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) { errors = m_fec.regenerateDMR(data + 2U); - // LogDebug("DMR Slot %u, audio sequence no. 0, errs: %u/141", m_slotNo, errors); + LogDebug("DMR Slot %u, audio sequence no. 0, errs: %u/141", m_slotNo, errors); m_rfErrs += errors; } @@ -426,7 +426,7 @@ void CDMRSlot::writeModem(unsigned char *data) unsigned char fid = m_rfLC->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) { errors = m_fec.regenerateDMR(data + 2U); - // LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141", m_slotNo, m_rfN, errors); + LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141", m_slotNo, m_rfN, errors); m_rfErrs += errors; } @@ -509,7 +509,7 @@ void CDMRSlot::writeModem(unsigned char *data) unsigned char fid = m_rfLC->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) { errors = m_fec.regenerateDMR(data + 2U); - // LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141", m_slotNo, m_rfN, errors); + LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141", m_slotNo, m_rfN, errors); m_rfErrs += errors; } @@ -942,12 +942,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) if (m_netState == RS_NET_AUDIO) { unsigned char fid = m_netLC->getFID(); - if (fid == FID_ETSI || fid == FID_DMRA) { - unsigned int errors = m_fec.regenerateDMR(data + 2U); - // LogDebug("DMR Slot %u, audio, errs: %u/141", m_slotNo, errors); - m_netErrs += errors; - } - + if (fid == FID_ETSI || fid == FID_DMRA) + m_netErrs += m_fec.regenerateDMR(data + 2U); m_netBits += 141U; data[0U] = TAG_DATA; @@ -986,12 +982,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) return; unsigned char fid = m_netLC->getFID(); - if (fid == FID_ETSI || fid == FID_DMRA) { - unsigned int errors = m_fec.regenerateDMR(data + 2U); - // LogDebug("DMR Slot %u, audio, errs: %u/141", m_slotNo, errors); - m_netErrs += errors; - } - + if (fid == FID_ETSI || fid == FID_DMRA) + m_netErrs += m_fec.regenerateDMR(data + 2U); m_netBits += 141U; // Regenerate the embedded LC diff --git a/DStarControl.cpp b/DStarControl.cpp index c28a9e5..9706cbb 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -246,7 +246,7 @@ bool CDStarControl::writeModem(unsigned char *data) if (m_rfN == 0U) CSync::addDStarSync(data + 1U); - // LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors); + LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors); if (m_net) writeNetworkDataRF(data, errors, false); @@ -355,7 +355,7 @@ bool CDStarControl::writeModem(unsigned char *data) m_rfErrs += errors; m_rfBits += 48U; - // LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors); + LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors); if (m_net) writeNetworkDataRF(data, errors, false); From dad34ada6928907ff8cd5faf972771db9542e1c7 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 1 Jun 2016 11:55:24 +0100 Subject: [PATCH 06/13] Add the idle clock to the Nextion display. --- Conf.cpp | 16 ++++++++++++++++ Conf.h | 12 ++++++++---- MMDVM.ini | 5 ++--- MMDVMHost.cpp | 7 ++++++- Nextion.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- Nextion.h | 8 +++++++- 6 files changed, 86 insertions(+), 11 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 12c333a..4735f75 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -123,6 +123,8 @@ m_hd44780DisplayClock(false), m_hd44780UTC(false), m_nextionPort("/dev/ttyAMA0"), m_nextionBrightness(50U), +m_nextionDisplayClock(false), +m_nextionUTC(false), m_oledType(3), m_oledBrightness(0), m_oledInvert(0) @@ -389,6 +391,10 @@ bool CConf::read() m_nextionPort = value; else if (::strcmp(key, "Brightness") == 0) m_nextionBrightness = (unsigned int)::atoi(value); + else if (::strcmp(key, "DisplayClock") == 0) + m_nextionDisplayClock = ::atoi(value) == 1; + else if (::strcmp(key, "UTC") == 0) + m_nextionUTC = ::atoi(value) == 1; } else if (section == SECTION_OLED) { if (::strcmp(key, "Type") == 0) m_oledType = (unsigned char)::atoi(value); @@ -780,6 +786,16 @@ unsigned int CConf::getNextionBrightness() const return m_nextionBrightness; } +bool CConf::getNextionDisplayClock() const +{ + return m_nextionDisplayClock; +} + +bool CConf::getNextionUTC() const +{ + return m_nextionUTC; +} + unsigned char CConf::getOLEDType() const { return m_oledType; diff --git a/Conf.h b/Conf.h index b74e14e..5f0a359 100644 --- a/Conf.h +++ b/Conf.h @@ -126,12 +126,14 @@ public: unsigned int getHD44780PWMPin() const; unsigned int getHD44780PWMBright() const; unsigned int getHD44780PWMDim() const; - bool getHD44780DisplayClock() const; - bool getHD44780UTC() const; + bool getHD44780DisplayClock() const; + bool getHD44780UTC() const; // The Nextion section std::string getNextionPort() const; unsigned int getNextionBrightness() const; + bool getNextionDisplayClock() const; + bool getNextionUTC() const; // The OLED section unsigned char getOLEDType() const; @@ -223,11 +225,13 @@ private: unsigned int m_hd44780PWMPin; unsigned int m_hd44780PWMBright; unsigned int m_hd44780PWMDim; - bool m_hd44780DisplayClock; - bool m_hd44780UTC; + bool m_hd44780DisplayClock; + bool m_hd44780UTC; std::string m_nextionPort; unsigned int m_nextionBrightness; + bool m_nextionDisplayClock; + bool m_nextionUTC; unsigned char m_oledType; unsigned char m_oledBrightness; diff --git a/MMDVM.ini b/MMDVM.ini index fc475e7..a92d104 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -100,17 +100,16 @@ PWM=0 PWMPin=21 PWMBright=100 PWMDim=16 - -# Display a clock when in IDLE? (HD44780 ONLY!) DisplayClock=1 UTC=0 [Nextion] Port=/dev/ttyAMA0 Brightness=50 +DisplayClock=1 +UTC=0 [OLED] Type=3 Brightness=0 Invert=0 - diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index c1d047f..954c2bf 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -787,11 +787,16 @@ void CMMDVMHost::createDisplay() } else if (type == "Nextion") { std::string port = m_conf.getNextionPort(); unsigned int brightness = m_conf.getNextionBrightness(); + bool displayClock = m_conf.getNextionDisplayClock(); + bool utc = m_conf.getNextionUTC(); LogInfo(" Port: %s", port.c_str()); LogInfo(" Brightness: %u", brightness); + LogInfo(" Clock Display: %s", displayClock ? "yes" : "no"); + if (displayClock) + LogInfo(" Display UTC: %s", utc ? "yes" : "no"); - m_display = new CNextion(m_callsign, dmrid, port, brightness); + m_display = new CNextion(m_callsign, dmrid, port, brightness, displayClock, utc); #if defined(HD44780) } else if (type == "HD44780") { unsigned int rows = m_conf.getHD44780Rows(); diff --git a/Nextion.cpp b/Nextion.cpp index a3e777c..4cc22f8 100644 --- a/Nextion.cpp +++ b/Nextion.cpp @@ -22,14 +22,18 @@ #include #include #include +#include -CNextion::CNextion(const std::string& callsign, unsigned int dmrid, const std::string& port, unsigned int brightness) : +CNextion::CNextion(const std::string& callsign, unsigned int dmrid, const std::string& port, unsigned int brightness, bool displayClock, bool utc) : CDisplay(), m_callsign(callsign), m_dmrid(dmrid), m_serial(port, SERIAL_9600), m_brightness(brightness), -m_mode(MODE_IDLE) +m_mode(MODE_IDLE), +m_displayClock(displayClock), +m_utc(utc), +m_clockDisplayTimer(1000U, 0U, 400U) { assert(brightness >= 0U && brightness <= 100U); } @@ -67,6 +71,8 @@ void CNextion::setIdleInt() sendCommand(command); sendCommand("t1.txt=\"MMDVM IDLE\""); + m_clockDisplayTimer.start(); + m_mode = MODE_IDLE; } @@ -82,6 +88,8 @@ void CNextion::setErrorInt(const char* text) sendCommand(command); sendCommand("t1.txt=\"ERROR\""); + m_clockDisplayTimer.stop(); + m_mode = MODE_ERROR; } @@ -91,6 +99,8 @@ void CNextion::setLockoutInt() sendCommand("t0.txt=\"LOCKOUT\""); + m_clockDisplayTimer.stop(); + m_mode = MODE_LOCKOUT; } @@ -117,6 +127,8 @@ void CNextion::writeDStarInt(const char* my1, const char* my2, const char* your, sendCommand(text); } + m_clockDisplayTimer.stop(); + m_mode = MODE_DSTAR; } @@ -158,6 +170,8 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro sendCommand(text); } + m_clockDisplayTimer.stop(); + m_mode = MODE_DMR; } @@ -193,6 +207,8 @@ void CNextion::writeFusionInt(const char* source, const char* dest, const char* sendCommand(text); } + m_clockDisplayTimer.stop(); + m_mode = MODE_YSF; } @@ -203,6 +219,35 @@ void CNextion::clearFusionInt() sendCommand("t2.txt=\"\""); } +void CNextion::clockInt(unsigned int ms) +{ + // Update the clock display in IDLE mode every 400ms + m_clockDisplayTimer.clock(ms); + if (m_displayClock && m_mode == MODE_IDLE && m_clockDisplayTimer.isRunning() && m_clockDisplayTimer.hasExpired()) { + time_t currentTime; + struct tm *Time; + ::time(¤tTime); // Get the current time + + if (m_utc) + Time = ::gmtime(¤tTime); + else + Time = ::localtime(¤tTime); + + int Day = Time->tm_mday; + int Month = Time->tm_mon + 1; + int Year = Time->tm_year + 1900; + int Hour = Time->tm_hour; + int Min = Time->tm_min; + int Sec = Time->tm_sec; + + char text[50U]; + ::sprintf(text, "t2.txt=\"%02d:%02d:%02d %02d/%02d/%2d\"", Hour, Min, Sec, Day, Month, Year % 100); + sendCommand(text); + + m_clockDisplayTimer.start(); // restart the clock display timer + } +} + void CNextion::close() { m_serial.close(); diff --git a/Nextion.h b/Nextion.h index 86667e6..319b23d 100644 --- a/Nextion.h +++ b/Nextion.h @@ -22,13 +22,14 @@ #include "Display.h" #include "Defines.h" #include "SerialController.h" +#include "Timer.h" #include class CNextion : public CDisplay { public: - CNextion(const std::string& callsign, unsigned int dmrid, const std::string& port, unsigned int brightness); + CNextion(const std::string& callsign, unsigned int dmrid, const std::string& port, unsigned int brightness, bool displayClock, bool utc); virtual ~CNextion(); virtual bool open(); @@ -49,12 +50,17 @@ protected: virtual void writeFusionInt(const char* source, const char* dest, const char* type, const char* origin); virtual void clearFusionInt(); + virtual void clockInt(unsigned int ms); + private: std::string m_callsign; unsigned int m_dmrid; CSerialController m_serial; unsigned int m_brightness; unsigned char m_mode; + bool m_displayClock; + bool m_utc; + CTimer m_clockDisplayTimer; void sendCommand(const char* command); }; From 6c805b7a2f82718d261b2406824335b3d9d75d69 Mon Sep 17 00:00:00 2001 From: afg Date: Fri, 3 Jun 2016 16:28:55 +0200 Subject: [PATCH 07/13] solved no CW-ID --- MMDVMHost.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 954c2bf..94626fb 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -255,6 +255,7 @@ int CMMDVMHost::run() LogInfo(" Time: %u mins", time); m_cwIdTimer.setTimeout(time * 60U); + m_cwIdTimer.start(); } CTimer dmrBeaconTimer(1000U, 4U); @@ -547,9 +548,12 @@ int CMMDVMHost::run() m_cwIdTimer.clock(ms); if (m_cwIdTimer.isRunning() && m_cwIdTimer.hasExpired()) { - if (m_mode == MODE_IDLE && !m_modem->hasTX()) + if (m_mode == MODE_IDLE && !m_modem->hasTX()){ + LogDebug("sending CW ID"); m_modem->sendCWId(m_callsign); - m_cwIdTimer.start(); + + m_cwIdTimer.start(); //reset only after sending ID, timer-overflow after 49 days doesnt matter + } } dmrBeaconTimer.clock(ms); From fa8caf8c922937ca3d2d92f7536519f108ae7fe5 Mon Sep 17 00:00:00 2001 From: Tony Corbett G0WFV Date: Sat, 4 Jun 2016 15:22:39 +0100 Subject: [PATCH 08/13] Implement scrolling of long src and dest on HD44780/Adafruit LCDs Also tidyed up my comments and cleared lines where I've left old code commented out and the new code has proved to work just fine! --- HD44780.cpp | 105 ++++++++++++++++++++++++++++++++++------------------ HD44780.h | 2 + 2 files changed, 70 insertions(+), 37 deletions(-) diff --git a/HD44780.cpp b/HD44780.cpp index 339a3c8..610bcc9 100644 --- a/HD44780.cpp +++ b/HD44780.cpp @@ -53,10 +53,12 @@ m_pwmDim(pwmDim), m_displayClock(displayClock), m_utc(utc), m_duplex(duplex), -//m_duplex(true), // uncomment to force duplex display for testing! +//m_duplex(true), // uncomment to force duplex display for testing! m_fd(-1), m_dmr(false), -m_clockDisplayTimer(1000U, 0U, 75U) // Update the clock display every 75ms +m_clockDisplayTimer(1000U, 0U, 75U), // Update the clock display every 75ms +m_scrollTimer1(1000U, 0U, 250U), // Scroll speed for slot 1 - every 250ms +m_scrollTimer2(1000U, 0U, 250U) // Scroll speed for slot 2 - every 250ms { assert(rows > 1U); assert(cols > 15U); @@ -293,7 +295,7 @@ void CHD44780::adafruitLCDColour(ADAFRUIT_COLOUR colour) void CHD44780::setIdleInt() { - m_clockDisplayTimer.start(); // Start the clock display in IDLE only + m_clockDisplayTimer.start(); // Start the clock display in IDLE only ::lcdClear(m_fd); #ifdef ADAFRUIT_DISPLAY @@ -321,7 +323,7 @@ void CHD44780::setIdleInt() ::lcdPutchar(m_fd, 4); ::lcdPutchar(m_fd, 2); ::lcdPosition(m_fd, m_cols - 4, m_rows - 1); - ::lcdPuts(m_fd, "Idle"); // Gets overwritten by clock on 2 line screen + ::lcdPuts(m_fd, "Idle"); // Gets overwritten by clock on 2 line screen m_dmr = false; } @@ -334,7 +336,9 @@ void CHD44780::setErrorInt(const char* text) adafruitLCDColour(AC_RED); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display + m_scrollTimer1.stop(); // Stop the scroll timer on slot 1 + m_scrollTimer2.stop(); // Stop the scroll timer on slot 2 ::lcdClear(m_fd); if (m_pwm) { @@ -363,7 +367,9 @@ void CHD44780::setLockoutInt() adafruitLCDColour(AC_RED); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display + m_scrollTimer1.stop(); // Stop the scroll timer on slot 1 + m_scrollTimer2.stop(); // Stop the scroll timer on slot 2 ::lcdClear(m_fd); if (m_pwm) { @@ -398,7 +404,7 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your, adafruitLCDColour(AC_RED); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); if (m_pwm) { @@ -412,12 +418,10 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your, ::lcdPuts(m_fd, "D-Star"); if (m_rows == 2U && m_cols == 16U) { -// char buffer[16U]; ::sprintf(m_buffer1, "%s %.8s/%.4s", type, my1, my2); ::lcdPosition(m_fd, 0, 1); ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } else if (m_rows == 4U && m_cols == 16U) { -// char buffer[16U]; ::sprintf(m_buffer1, "%s %.8s/%.4s", type, my1, my2); ::lcdPosition(m_fd, 0, 1); ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); @@ -462,7 +466,7 @@ void CHD44780::clearDStarInt() adafruitLCDColour(AC_PURPLE); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display if (m_rows == 2U && m_cols == 16U) { ::lcdPosition(m_fd, 0, 1); @@ -487,11 +491,10 @@ void CHD44780::clearDStarInt() void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) { -// char buffer[128]; // force 128 char buffer - we're never getting that far but stops us overflowing it! assert(type != NULL); if (!m_dmr) { - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); #ifdef ADAFRUIT_DISPLAY @@ -536,31 +539,37 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro if (slotNo == 1U) { ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); ::lcdPuts(m_fd, "1 "); - ::sprintf(m_buffer1, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE); + ::sprintf(m_buffer2, "%s > %s%s ", src.c_str(), group ? "TG" : "", dst.c_str()); ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, m_buffer1); - if (m_cols > 16) { - ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); - ::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar); - ::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2) - 1); - ::lcdPuts(m_fd, " "); - ::lcdPutchar(m_fd, 6); - ::lcdPutchar(m_fd, 5); + // Start the scroll timer on slot 1 if text in m_buffer1 will not fit in the space available + if (strlen(m_buffer1) - 5 > m_cols - 5 ) { + m_scrollTimer1.start(); } + + ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); + ::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar); + ::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2) - 1); + ::lcdPuts(m_fd, " "); + ::lcdPutchar(m_fd, 6); + ::lcdPutchar(m_fd, 5); } else { ::lcdPosition(m_fd, 0, (m_rows / 2)); ::lcdPuts(m_fd, "2 "); - ::sprintf(m_buffer2, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE); + ::sprintf(m_buffer2, "%s > %s%s ", src.c_str(), group ? "TG" : "", dst.c_str()); ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, m_buffer2); - if (m_cols > 16) { - ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); - ::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar); - ::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2)); - ::lcdPuts(m_fd, " "); - ::lcdPutchar(m_fd, 6); - ::lcdPutchar(m_fd, 5); + // Start the scroll timer on slot 2 if text in m_buffer2 will not fit in the space available + if (strlen(m_buffer2) - 5 > m_cols - 5 ) { + m_scrollTimer2.start(); } + + ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); + ::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar); + ::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2)); + ::lcdPuts(m_fd, " "); + ::lcdPutchar(m_fd, 6); + ::lcdPutchar(m_fd, 5); } } else { ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); @@ -584,13 +593,14 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro void CHD44780::clearDMRInt(unsigned int slotNo) { -// char buffer[128]; // force 128 char buffer - we're never getting that far but stops us overflowing it! - #ifdef ADAFRUIT_DISPLAY adafruitLCDColour(AC_PURPLE); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display + m_scrollTimer1.stop(); // Stop the scroll timer on slot 1 + m_scrollTimer2.stop(); // Stop the scroll timer on slot 2 + if (m_duplex) { if (slotNo == 1U) { ::lcdPosition(m_fd, 0, 0); @@ -619,7 +629,7 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, const char* adafruitLCDColour(AC_RED); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); if (m_pwm) { @@ -672,7 +682,7 @@ void CHD44780::clearFusionInt() adafruitLCDColour(AC_PURPLE); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display if (m_rows == 2U && m_cols == 16U) { ::lcdPosition(m_fd, 0, 1); @@ -697,14 +707,17 @@ void CHD44780::clearFusionInt() void CHD44780::clockInt(unsigned int ms) { - // Update the clock display in IDLE mode every 75ms m_clockDisplayTimer.clock(ms); + m_scrollTimer1.clock(ms); + m_scrollTimer2.clock(ms); + + // Idle clock display if (m_displayClock && m_clockDisplayTimer.isRunning() && m_clockDisplayTimer.hasExpired()) { time_t currentTime; struct tm *Time; - time(¤tTime); // Get the current time + time(¤tTime); - if (m_utc){ + if (m_utc) { Time = gmtime(¤tTime); } else { Time = localtime(¤tTime); @@ -728,7 +741,25 @@ void CHD44780::clockInt(unsigned int ms) ::lcdPosition(m_fd, (m_cols - 8) / 2, m_rows == 2 ? 0 : 1); ::lcdPrintf(m_fd, "%02d/%02d/%2d", Day, Month, Year%100); } - m_clockDisplayTimer.start(); // restart the clock display timer + m_clockDisplayTimer.start(); + } + + // Slot 1 scrolling + if (m_scrollTimer1.isRunning() && m_scrollTimer1.hasExpired()) { + strncat(m_buffer1, m_buffer1, 1); // Move the first character to the end of the buffer + memmove(m_buffer1, m_buffer1 + 1, strlen(m_buffer1)); // Strip the first character + ::lcdPosition(m_fd, 2, (m_rows / 2) - 1); // Position on the LCD + ::lcdPrintf(m_fd, "%.*s", m_cols - 5U, m_buffer1); // Print it out + m_scrollTimer1.start(); // Restart the scroll timer + } + + // Slot 2 scrolling + if (m_scrollTimer2.isRunning() && m_scrollTimer2.hasExpired()) { + strncat(m_buffer2, m_buffer2, 1); + memmove(m_buffer2, m_buffer2 + 1, strlen(m_buffer2)); + ::lcdPosition(m_fd, 2, (m_rows / 2)); + ::lcdPrintf(m_fd, "%.*s", m_cols - 5U, m_buffer2); + m_scrollTimer2.start(); } } diff --git a/HD44780.h b/HD44780.h index a776413..2a803de 100644 --- a/HD44780.h +++ b/HD44780.h @@ -97,6 +97,8 @@ private: int m_fd; bool m_dmr; CTimer m_clockDisplayTimer; + CTimer m_scrollTimer1; + CTimer m_scrollTimer2; #ifdef ADAFRUIT_DISPLAY void adafruitLCDSetup(); From 52dbea66332f8dc9c0eb53e83335f57ab0064e66 Mon Sep 17 00:00:00 2001 From: Tony Corbett G0WFV Date: Sun, 5 Jun 2016 19:06:04 +0100 Subject: [PATCH 09/13] Attempt to fix scrolling issues reported on 20x4 LCD Please test and report in the the exisiting issue on git - I don't have a 20x4 LCD to hand, so am unable to test this myself! --- HD44780.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/HD44780.cpp b/HD44780.cpp index 610bcc9..010beab 100644 --- a/HD44780.cpp +++ b/HD44780.cpp @@ -295,6 +295,8 @@ void CHD44780::adafruitLCDColour(ADAFRUIT_COLOUR colour) void CHD44780::setIdleInt() { + m_scrollTimer1.stop(); // Stop the scroll timer on slot 1 + m_scrollTimer2.stop(); // Stop the scroll timer on slot 2 m_clockDisplayTimer.start(); // Start the clock display in IDLE only ::lcdClear(m_fd); @@ -516,13 +518,16 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro } if (slotNo == 1U) { + m_scrollTimer2.stop(); ::lcdPosition(m_fd, 0, (m_rows / 2)); ::lcdPrintf(m_fd, "2 %.*s", m_cols - 2U, LISTENING); } else { + m_scrollTimer1.stop(); ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); ::lcdPrintf(m_fd, "1 %.*s", m_cols - 2U, LISTENING); } } else { + m_scrollTimer2.stop(); ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); ::sprintf(m_buffer1, "%s%s", "DMR", DEADSPACE); ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); @@ -598,23 +603,24 @@ void CHD44780::clearDMRInt(unsigned int slotNo) #endif m_clockDisplayTimer.stop(); // Stop the clock display - m_scrollTimer1.stop(); // Stop the scroll timer on slot 1 - m_scrollTimer2.stop(); // Stop the scroll timer on slot 2 if (m_duplex) { if (slotNo == 1U) { + m_scrollTimer1.stop(); // Stop the scroll timer on slot 1 ::lcdPosition(m_fd, 0, 0); ::lcdPrintf(m_fd, "1 %.*s", m_cols - 2U, LISTENING); } else { + m_scrollTimer2.stop(); // Stop the scroll timer on slot 2 ::lcdPosition(m_fd, 0, 1); ::lcdPrintf(m_fd, "2 %.*s", m_cols - 2U, LISTENING); } } else { - ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); - ::sprintf(m_buffer2, "%s%s", "DMR", DEADSPACE); - ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer2); - ::lcdPosition(m_fd, 0, (m_rows / 2)); - ::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING); + m_scrollTimer2.stop(); // Stop the scroll timer on slot 2 + ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); + ::sprintf(m_buffer2, "%s%s", "DMR", DEADSPACE); + ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer2); + ::lcdPosition(m_fd, 0, (m_rows / 2)); + ::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING); } } From b54f1a0b144ad8dc1427f2d1e5a790903c523130 Mon Sep 17 00:00:00 2001 From: Tony Corbett Date: Sun, 5 Jun 2016 22:28:41 +0300 Subject: [PATCH 10/13] Fix TS1 not displaying --- HD44780.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HD44780.cpp b/HD44780.cpp index 010beab..37cbc60 100644 --- a/HD44780.cpp +++ b/HD44780.cpp @@ -544,7 +544,7 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro if (slotNo == 1U) { ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); ::lcdPuts(m_fd, "1 "); - ::sprintf(m_buffer2, "%s > %s%s ", src.c_str(), group ? "TG" : "", dst.c_str()); + ::sprintf(m_buffer1, "%s > %s%s ", src.c_str(), group ? "TG" : "", dst.c_str()); ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, m_buffer1); // Start the scroll timer on slot 1 if text in m_buffer1 will not fit in the space available From eba4ddeb2a30ee4ab90e7ef25c6a346bc1b8539b Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 6 Jun 2016 17:40:27 +0100 Subject: [PATCH 11/13] Use the Thread class for delays. --- MMDVMHost.cpp | 10 ++-- MMDVMHost.vcxproj | 2 + MMDVMHost.vcxproj.filters | 6 +++ Makefile | 4 +- Makefile.Pi.Adafruit | 2 +- Makefile.Pi.HD44780 | 2 +- Makefile.Pi.OLED | 2 +- Modem.cpp | 29 +++--------- Thread.cpp | 99 +++++++++++++++++++++++++++++++++++++++ Thread.h | 56 ++++++++++++++++++++++ 10 files changed, 178 insertions(+), 34 deletions(-) create mode 100644 Thread.cpp create mode 100644 Thread.h diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 94626fb..eb28ac7 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -27,6 +27,7 @@ #include "NullDisplay.h" #include "YSFControl.h" #include "Nextion.h" +#include "Thread.h" #if defined(HD44780) #include "HD44780.h" @@ -568,13 +569,8 @@ int CMMDVMHost::run() m_dmrTXTimer.stop(); } - if (ms < 5U) { -#if defined(_WIN32) || defined(_WIN64) - ::Sleep(5UL); // 5ms -#else - ::usleep(5000); // 5ms -#endif - } + if (ms < 5U) + CThread::sleep(5U); } LogMessage("MMDVMHost-%s is exiting on receipt of SIGHUP1", VERSION); diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj index 1803f8c..1fc5912 100644 --- a/MMDVMHost.vcxproj +++ b/MMDVMHost.vcxproj @@ -187,6 +187,7 @@ + @@ -236,6 +237,7 @@ + diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters index b271f59..cf774a7 100644 --- a/MMDVMHost.vcxproj.filters +++ b/MMDVMHost.vcxproj.filters @@ -164,6 +164,9 @@ Header Files + + Header Files + @@ -301,5 +304,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Makefile b/Makefile index 830ee36..9e24b70 100644 --- a/Makefile +++ b/Makefile @@ -9,8 +9,8 @@ LDFLAGS = -g OBJECTS = \ AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o Log.o MMDVMHost.o Modem.o \ - Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \ - YSFFICH.o YSFNetwork.o YSFPayload.o + Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ + YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.Adafruit b/Makefile.Pi.Adafruit index 5ef85b3..e929fb6 100644 --- a/Makefile.Pi.Adafruit +++ b/Makefile.Pi.Adafruit @@ -9,7 +9,7 @@ LDFLAGS = -g -L/usr/local/lib OBJECTS = \ AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o MMDVMHost.o \ - Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFControl.o \ + Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.HD44780 b/Makefile.Pi.HD44780 index 7ac9e20..9294ead 100644 --- a/Makefile.Pi.HD44780 +++ b/Makefile.Pi.HD44780 @@ -9,7 +9,7 @@ LDFLAGS = -g -L/usr/local/lib OBJECTS = \ AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o MMDVMHost.o \ - Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFControl.o \ + Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.OLED b/Makefile.Pi.OLED index bd7df7f..95298f7 100644 --- a/Makefile.Pi.OLED +++ b/Makefile.Pi.OLED @@ -9,7 +9,7 @@ LDFLAGS = -g -L/usr/local/lib OBJECTS = \ AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o OLED.o Log.o MMDVMHost.o \ - Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFControl.o \ + Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Modem.cpp b/Modem.cpp index a03e5f3..c16bf43 100644 --- a/Modem.cpp +++ b/Modem.cpp @@ -20,6 +20,7 @@ #include "DMRDefines.h" #include "YSFDefines.h" #include "Defines.h" +#include "Thread.h" #include "Modem.h" #include "Utils.h" #include "Log.h" @@ -717,11 +718,7 @@ bool CModem::readVersion() return false; for (unsigned int count = 0U; count < MAX_RESPONSES; count++) { -#if defined(_WIN32) || defined(_WIN64) - ::Sleep(10UL); -#else - ::usleep(10000UL); -#endif + CThread::sleep(10U); RESP_TYPE_MMDVM resp = getResponse(); if (resp == RTM_OK && m_buffer[2U] == MMDVM_GET_VERSION) { LogInfo("MMDVM protocol version: %u, description: %.*s", m_buffer[3U], m_length - 4U, m_buffer + 4U); @@ -729,11 +726,7 @@ bool CModem::readVersion() } } -#if defined(_WIN32) || defined(_WIN64) - ::Sleep(1000UL); // 1s -#else - ::sleep(1UL); // 1s -#endif + CThread::sleep(1000U); } LogError("Unable to read the firmware version after six attempts"); @@ -802,13 +795,9 @@ bool CModem::setConfig() unsigned int count = 0U; RESP_TYPE_MMDVM resp; do { -#if defined(_WIN32) || defined(_WIN64) - ::Sleep(10UL); -#else - ::usleep(10000UL); -#endif - resp = getResponse(); + CThread::sleep(10U); + resp = getResponse(); if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) { count++; if (count >= MAX_RESPONSES) { @@ -861,13 +850,9 @@ bool CModem::setFrequency() unsigned int count = 0U; RESP_TYPE_MMDVM resp; do { -#if defined(_WIN32) || defined(_WIN64) - ::Sleep(10UL); -#else - ::usleep(10000UL); -#endif - resp = getResponse(); + CThread::sleep(10U); + resp = getResponse(); if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) { count++; if (count >= MAX_RESPONSES) { diff --git a/Thread.cpp b/Thread.cpp new file mode 100644 index 0000000..9f43374 --- /dev/null +++ b/Thread.cpp @@ -0,0 +1,99 @@ +/* + * 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 + * 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 "Thread.h" + +#if defined(_WIN32) || defined(_WIN64) + +CThread::CThread() : +m_handle() +{ +} + +CThread::~CThread() +{ +} + +bool CThread::run() +{ + m_handle = ::CreateThread(NULL, 0, &helper, this, 0, NULL); + + return m_handle != NULL; +} + + +void CThread::wait() +{ + ::WaitForSingleObject(m_handle, INFINITE); + + ::CloseHandle(m_handle); +} + + +DWORD CThread::helper(LPVOID arg) +{ + CThread* p = (CThread*)arg; + + p->entry(); + + return 0UL; +} + +void CThread::sleep(unsigned int ms) +{ + ::Sleep(ms); +} + +#else + +CThread::CThread() : +m_thread() +{ +} + +CThread::~CThread() +{ +} + +bool CThread::run() +{ + return ::pthread_create(&m_thread, NULL, helper, this) == 0; +} + + +void CThread::wait() +{ + ::pthread_join(m_thread, NULL); +} + + +void* CThread::helper(void* arg) +{ + CThread* p = (CThread*)arg; + + p->entry(); + + return NULL; +} + +void CThread::sleep(unsigned int ms) +{ + ::usleep(ms * 1000); +} + +#endif diff --git a/Thread.h b/Thread.h new file mode 100644 index 0000000..8a6843f --- /dev/null +++ b/Thread.h @@ -0,0 +1,56 @@ +/* + * 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 + * 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. + */ + +#if !defined(THREAD_H) +#define THREAD_H + +#if defined(_WIN32) || defined(_WIN64) +#include +#else +#include +#endif + +class CThread +{ +public: + CThread(); + virtual ~CThread(); + + virtual bool run(); + + virtual void entry() = 0; + + virtual void wait(); + + static void sleep(unsigned int ms); + +private: +#if defined(_WIN32) || defined(_WIN64) + HANDLE m_handle; +#else + pthread_t m_thread; +#endif + +#if defined(_WIN32) || defined(_WIN64) + static DWORD __stdcall helper(LPVOID arg); +#else + static void* helper(void* arg); +#endif +}; + +#endif From 277becca53dd00fc7d2a667d868c82182bc5394b Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 6 Jun 2016 19:26:47 +0100 Subject: [PATCH 12/13] Fix Linux threading compile issues. --- Makefile | 4 ++-- Makefile.Pi.Adafruit | 2 +- Makefile.Pi.HD44780 | 2 +- Makefile.Pi.OLED | 4 ++-- Thread.cpp | 2 ++ Thread.h | 2 +- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 9e24b70..d464064 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ CC = gcc CXX = g++ -CFLAGS = -g -O3 -Wall -std=c++0x -LIBS = +CFLAGS = -g -O3 -Wall -std=c++0x -pthread +LIBS = -lpthread LDFLAGS = -g OBJECTS = \ diff --git a/Makefile.Pi.Adafruit b/Makefile.Pi.Adafruit index e929fb6..7e5a9a5 100644 --- a/Makefile.Pi.Adafruit +++ b/Makefile.Pi.Adafruit @@ -2,7 +2,7 @@ # Support for the Adafruit i2c 16 x 2 RGB LCD Pi Plate CC = gcc CXX = g++ -CFLAGS = -g -O3 -Wall -std=c++0x -DHD44780 -DADAFRUIT_DISPLAY -I/usr/local/include +CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHD44780 -DADAFRUIT_DISPLAY -I/usr/local/include LIBS = -lwiringPi -lwiringPiDev -lpthread LDFLAGS = -g -L/usr/local/lib diff --git a/Makefile.Pi.HD44780 b/Makefile.Pi.HD44780 index 9294ead..e44d606 100644 --- a/Makefile.Pi.HD44780 +++ b/Makefile.Pi.HD44780 @@ -2,7 +2,7 @@ CC = gcc CXX = g++ -CFLAGS = -g -O3 -Wall -std=c++0x -DHD44780 -I/usr/local/include +CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHD44780 -I/usr/local/include LIBS = -lwiringPi -lwiringPiDev -lpthread LDFLAGS = -g -L/usr/local/lib diff --git a/Makefile.Pi.OLED b/Makefile.Pi.OLED index 95298f7..7af4bed 100644 --- a/Makefile.Pi.OLED +++ b/Makefile.Pi.OLED @@ -2,8 +2,8 @@ CC = gcc CXX = g++ -CFLAGS = -g -O3 -Wall -std=c++0x -DOLED -I/usr/local/include -LIBS = -lArduiPi_OLED +CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DOLED -I/usr/local/include +LIBS = -lArduiPi_OLED -lpthread LDFLAGS = -g -L/usr/local/lib OBJECTS = \ diff --git a/Thread.cpp b/Thread.cpp index 9f43374..b334436 100644 --- a/Thread.cpp +++ b/Thread.cpp @@ -61,6 +61,8 @@ void CThread::sleep(unsigned int ms) #else +#include + CThread::CThread() : m_thread() { diff --git a/Thread.h b/Thread.h index 8a6843f..352d938 100644 --- a/Thread.h +++ b/Thread.h @@ -41,7 +41,7 @@ public: private: #if defined(_WIN32) || defined(_WIN64) - HANDLE m_handle; + HANDLE m_handle; #else pthread_t m_thread; #endif From 1ef55c46e23c434acf77739c21539449e916b69f Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 7 Jun 2016 07:30:42 +0100 Subject: [PATCH 13/13] Correct the MR setting. --- YSFControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YSFControl.cpp b/YSFControl.cpp index ee180b7..4d5ee00 100644 --- a/YSFControl.cpp +++ b/YSFControl.cpp @@ -459,7 +459,7 @@ void CYSFControl::writeNetwork() } fich.setVoIP(true); - fich.setMR(YSF_MR_NOT_BUSY); + fich.setMR(YSF_MR_BUSY); fich.encode(data + 35U); }