From f0387d25ddb1b1cb58a06daa762fcce718b96dd2 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 12 Feb 2017 18:37:00 +0000 Subject: [PATCH] Add BER display to the Nextion and reduce Talker Id logging. --- DMRSlot.cpp | 93 ++++++++++++------ DMRSlot.h | 2 + DStarControl.cpp | 21 ++--- Display.cpp | 36 +++++++ Display.h | 8 ++ Modem.cpp | 65 +++---------- Nextion.cpp | 208 ++++++++++++++++++++++++++++++----------- Nextion.h | 10 ++ Nextion/NX3224T024.HMI | Bin 426885 -> 433990 bytes Nextion/NX3224T024.tft | Bin 432498 -> 437369 bytes P25Control.cpp | 8 +- YSFControl.cpp | 7 +- 12 files changed, 312 insertions(+), 146 deletions(-) diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 59d5a0a..39bd9b9 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -54,6 +54,12 @@ FLCO CDMRSlot::m_flco2; unsigned char CDMRSlot::m_id2 = 0U; bool CDMRSlot::m_voice2 = true; +const unsigned char TALKER_ID_NONE = 0x00U; +const unsigned char TALKER_ID_HEADER = 0x01U; +const unsigned char TALKER_ID_BLOCK1 = 0x02U; +const unsigned char TALKER_ID_BLOCK2 = 0x04U; +const unsigned char TALKER_ID_BLOCK3 = 0x08U; + // #define DUMP_DMR CDMRSlot::CDMRSlot(unsigned int slotNo, unsigned int timeout) : @@ -65,10 +71,12 @@ m_rfEmbeddedLC(), m_rfEmbeddedData(NULL), m_rfEmbeddedReadN(0U), m_rfEmbeddedWriteN(1U), +m_rfTalkerId(TALKER_ID_NONE), m_netEmbeddedLC(), m_netEmbeddedData(NULL), m_netEmbeddedReadN(0U), m_netEmbeddedWriteN(1U), +m_netTalkerId(TALKER_ID_NONE), m_rfLC(NULL), m_netLC(NULL), m_rfDataHeader(), @@ -222,8 +230,10 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) m_rfSeqNo = 0U; m_rfBits = 1U; m_rfErrs = 0U; + m_rfEmbeddedReadN = 0U; m_rfEmbeddedWriteN = 1U; + m_rfTalkerId = TALKER_ID_NONE; m_minRSSI = m_rssi; m_maxRSSI = m_rssi; @@ -452,7 +462,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) if (ret) { trellis.encode(payload, data + 2U); } else { - LogMessage("DMR Slot %u, unfixable RF rate 3/4 data", m_slotNo); + LogDebug("DMR Slot %u, unfixable rate 3/4 data", m_slotNo); CUtils::dump(1U, "Data", data + 2U, DMR_FRAME_LENGTH_BYTES); } } @@ -485,7 +495,8 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) 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 (%.1f%%)", m_slotNo, errors, float(errors) / 1.41F); + m_display->writeDMRBER(m_slotNo, float(errors) / 1.41F); m_rfErrs += errors; } @@ -518,7 +529,8 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) 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 (%.1f%%)", m_slotNo, m_rfN, errors, float(errors) / 1.41F); + m_display->writeDMRBER(m_slotNo, float(errors) / 1.41F); m_rfErrs += errors; } @@ -547,23 +559,35 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) break; case FLCO_GPS_INFO: ::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo); - CUtils::dump(1U, text, data, 9U); + CUtils::dump(2U, text, data, 9U); break; case FLCO_TALKER_ALIAS_HEADER: - ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo); - CUtils::dump(1U, text, data, 9U); + if (!(m_rfTalkerId & TALKER_ID_HEADER)) { + ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo); + CUtils::dump(2U, text, data, 9U); + m_rfTalkerId |= TALKER_ID_HEADER; + } break; case FLCO_TALKER_ALIAS_BLOCK1: - ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo); - CUtils::dump(1U, text, data, 9U); + if (!(m_rfTalkerId & TALKER_ID_BLOCK1)) { + ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo); + CUtils::dump(2U, text, data, 9U); + m_rfTalkerId |= TALKER_ID_BLOCK1; + } break; case FLCO_TALKER_ALIAS_BLOCK2: - ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo); - CUtils::dump(1U, text, data, 9U); + if (!(m_rfTalkerId & TALKER_ID_BLOCK2)) { + ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo); + CUtils::dump(2U, text, data, 9U); + m_rfTalkerId |= TALKER_ID_BLOCK2; + } break; case FLCO_TALKER_ALIAS_BLOCK3: - ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo); - CUtils::dump(1U, text, data, 9U); + if (!(m_rfTalkerId & TALKER_ID_BLOCK3)) { + ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo); + CUtils::dump(2U, text, data, 9U); + m_rfTalkerId |= TALKER_ID_BLOCK3; + } break; default: ::sprintf(text, "DMR Slot %u, Unknown Embedded Data", m_slotNo); @@ -657,8 +681,10 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) m_rfSeqNo = 0U; m_rfBits = 1U; m_rfErrs = 0U; + m_rfEmbeddedReadN = 0U; m_rfEmbeddedWriteN = 1U; + m_rfTalkerId = TALKER_ID_NONE; m_minRSSI = m_rssi; m_maxRSSI = m_rssi; @@ -686,7 +712,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) 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 (%.1f%%)", m_slotNo, m_rfN, errors, float(errors) / 1.41F); m_rfErrs += errors; } @@ -710,6 +736,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) setShortLC(m_slotNo, dstId, flco, true); m_display->writeDMR(m_slotNo, src, flco == FLCO_GROUP, dst, "R"); m_display->writeDMRRSSI(m_slotNo, m_rssi); + m_display->writeDMRBER(m_slotNo, float(errors) / 1.41F); } LogMessage("DMR Slot %u, received RF late entry from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str()); @@ -939,8 +966,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) m_netLost = 0U; m_netBits = 1U; m_netErrs = 0U; + m_netEmbeddedReadN = 0U; m_netEmbeddedWriteN = 1U; + m_netTalkerId = TALKER_ID_NONE; if (m_duplex) { m_queue.clear(); @@ -1195,8 +1224,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) m_netLost = 0U; m_netBits = 1U; m_netErrs = 0U; + m_netEmbeddedReadN = 0U; m_netEmbeddedWriteN = 1U; + m_netTalkerId = TALKER_ID_NONE; m_netState = RS_NET_AUDIO; @@ -1284,23 +1315,35 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) break; case FLCO_GPS_INFO: ::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo); - CUtils::dump(1U, text, data, 9U); + CUtils::dump(2U, text, data, 9U); break; case FLCO_TALKER_ALIAS_HEADER: - ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo); - CUtils::dump(1U, text, data, 9U); + if (!(m_netTalkerId & TALKER_ID_HEADER)) { + ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo); + CUtils::dump(2U, text, data, 9U); + m_netTalkerId |= TALKER_ID_HEADER; + } break; case FLCO_TALKER_ALIAS_BLOCK1: - ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo); - CUtils::dump(1U, text, data, 9U); + if (!(m_netTalkerId & TALKER_ID_BLOCK1)) { + ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo); + CUtils::dump(2U, text, data, 9U); + m_netTalkerId |= TALKER_ID_BLOCK1; + } break; case FLCO_TALKER_ALIAS_BLOCK2: - ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo); - CUtils::dump(1U, text, data, 9U); + if (!(m_netTalkerId & TALKER_ID_BLOCK2)) { + ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo); + CUtils::dump(2U, text, data, 9U); + m_netTalkerId |= TALKER_ID_BLOCK2; + } break; case FLCO_TALKER_ALIAS_BLOCK3: - ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo); - CUtils::dump(1U, text, data, 9U); + if (!(m_netTalkerId & TALKER_ID_BLOCK3)) { + ::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo); + CUtils::dump(2U, text, data, 9U); + m_netTalkerId |= TALKER_ID_BLOCK3; + } break; default: ::sprintf(text, "DMR Slot %u, Unknown Embedded Data", m_slotNo); @@ -1426,12 +1469,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) CDMRTrellis trellis; unsigned char payload[18U]; bool ret = trellis.decode(data + 2U, payload); - if (ret) { + if (ret) trellis.encode(payload, data + 2U); - } else { - LogMessage("DMR Slot %u, unfixable network rate 3/4 data", m_slotNo); - CUtils::dump(1U, "Data", data + 2U, DMR_FRAME_LENGTH_BYTES); - } } // Regenerate the Slot Type diff --git a/DMRSlot.h b/DMRSlot.h index ac5290e..a4f87ae 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -61,10 +61,12 @@ private: CDMREmbeddedData* m_rfEmbeddedData; unsigned int m_rfEmbeddedReadN; unsigned int m_rfEmbeddedWriteN; + unsigned char m_rfTalkerId; CDMREmbeddedData m_netEmbeddedLC; CDMREmbeddedData* m_netEmbeddedData; unsigned int m_netEmbeddedReadN; unsigned int m_netEmbeddedWriteN; + unsigned char m_netTalkerId; CDMRLC* m_rfLC; CDMRLC* m_netLC; CDMRDataHeader m_rfDataHeader; diff --git a/DStarControl.cpp b/DStarControl.cpp index c5288ab..f8d4e9c 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -300,12 +300,14 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) return false; } else if (m_rfState == RS_RF_AUDIO) { unsigned int errors = 0U; - if (!m_rfHeader.isDataPacket()) + if (!m_rfHeader.isDataPacket()) { errors = m_fec.regenerateDStar(data + 1U); + m_display->writeDStarBER(float(errors) / 0.48F); + LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F); + m_rfErrs += errors; + } - m_rfErrs += errors; m_rfBits += 48U; - m_rfFrames++; // The sync is regenerated by the modem so can do exact match @@ -318,8 +320,6 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) m_display->writeDStarRSSI(m_rssi); } - // LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors); - if (m_net) writeNetworkDataRF(data, errors, false); @@ -428,14 +428,14 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) delete header; unsigned int errors = 0U; - if (!m_rfHeader.isDataPacket()) + if (!m_rfHeader.isDataPacket()) { errors = m_fec.regenerateDStar(data + 1U); + LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F); + m_rfErrs += errors; + } - m_rfErrs += errors; m_rfBits += 48U; - // LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors); - if (m_net) writeNetworkDataRF(data, errors, false); @@ -451,6 +451,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) if (m_netState == RS_NET_IDLE) { m_display->writeDStar((char*)my1, (char*)my2, (char*)your, "R", " "); m_display->writeDStarRSSI(m_rssi); + m_display->writeDStarBER(float(errors) / 0.48F); } LogMessage("D-Star, received RF late entry from %8.8s/%4.4s to %8.8s", my1, my2, your); @@ -624,8 +625,6 @@ void CDStarControl::writeNetwork() m_netN = n; - // LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_netN, errors); - // Regenerate the sync if (n == 0U) CSync::addDStarSync(data + 2U); diff --git a/Display.cpp b/Display.cpp index 199351c..7959d69 100644 --- a/Display.cpp +++ b/Display.cpp @@ -90,6 +90,11 @@ void CDisplay::writeDStarRSSI(unsigned char rssi) writeDStarRSSIInt(rssi); } +void CDisplay::writeDStarBER(float ber) +{ + writeDStarBERInt(ber); +} + void CDisplay::clearDStar() { if (m_timer1.hasExpired()) { @@ -122,6 +127,11 @@ void CDisplay::writeDMRRSSI(unsigned int slotNo, unsigned char rssi) writeDMRRSSIInt(slotNo, rssi); } +void CDisplay::writeDMRBER(unsigned int slotNo, float ber) +{ + writeDMRBERInt(slotNo, ber); +} + void CDisplay::clearDMR(unsigned int slotNo) { if (slotNo == 1U) { @@ -162,6 +172,11 @@ void CDisplay::writeFusionRSSI(unsigned char rssi) writeFusionRSSIInt(rssi); } +void CDisplay::writeFusionBER(float ber) +{ + writeFusionBERInt(ber); +} + void CDisplay::clearFusion() { if (m_timer1.hasExpired()) { @@ -190,6 +205,11 @@ void CDisplay::writeP25RSSI(unsigned char rssi) writeP25RSSIInt(rssi); } +void CDisplay::writeP25BER(float ber) +{ + writeP25BERInt(ber); +} + void CDisplay::clearP25() { if (m_timer1.hasExpired()) { @@ -265,14 +285,30 @@ void CDisplay::writeDStarRSSIInt(unsigned char rssi) { } +void CDisplay::writeDStarBERInt(float ber) +{ +} + void CDisplay::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi) { } +void CDisplay::writeDMRBERInt(unsigned int slotNo, float ber) +{ +} + void CDisplay::writeFusionRSSIInt(unsigned char rssi) { } +void CDisplay::writeFusionBERInt(float ber) +{ +} + void CDisplay::writeP25RSSIInt(unsigned char rssi) { } + +void CDisplay::writeP25BERInt(float ber) +{ +} diff --git a/Display.h b/Display.h index 3444a76..9e3d884 100644 --- a/Display.h +++ b/Display.h @@ -37,18 +37,22 @@ public: void writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); void writeDStarRSSI(unsigned char rssi); + void writeDStarBER(float ber); void clearDStar(); void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); void writeDMRRSSI(unsigned int slotNo, unsigned char rssi); + void writeDMRBER(unsigned int slotNo, float ber); void clearDMR(unsigned int slotNo); void writeFusion(const char* source, const char* dest, const char* type, const char* origin); void writeFusionRSSI(unsigned char rssi); + void writeFusionBER(float ber); void clearFusion(); void writeP25(const char* source, bool group, unsigned int dest, const char* type); void writeP25RSSI(unsigned char rssi); + void writeP25BER(float ber); void clearP25(); void writeCW(); @@ -65,18 +69,22 @@ protected: virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) = 0; virtual void writeDStarRSSIInt(unsigned char rssi); + virtual void writeDStarBERInt(float ber); 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 writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi); + virtual void writeDMRBERInt(unsigned int slotNo, float ber); virtual void clearDMRInt(unsigned int slotNo) = 0; virtual void writeFusionInt(const char* source, const char* dest, const char* type, const char* origin) = 0; virtual void writeFusionRSSIInt(unsigned char rssi); + virtual void writeFusionBERInt(float ber); virtual void clearFusionInt() = 0; virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type) = 0; virtual void writeP25RSSIInt(unsigned char rssi); + virtual void writeP25BERInt(float ber); virtual void clearP25Int() = 0; virtual void writeCWInt() = 0; diff --git a/Modem.cpp b/Modem.cpp index 4fab28d..2c0fe9b 100644 --- a/Modem.cpp +++ b/Modem.cpp @@ -465,7 +465,19 @@ void CModem::clock(unsigned int ms) LogWarning("Received a NAK from the MMDVM, command = 0x%02X, reason = %u", m_buffer[3U], m_buffer[4U]); break; - default: + case MMDVM_DEBUG1: + case MMDVM_DEBUG2: + case MMDVM_DEBUG3: + case MMDVM_DEBUG4: + case MMDVM_DEBUG5: + printDebug(); + break; + + case MMDVM_SAMPLES: + printSamples(); + break; + + default: LogMessage("Unknown message, type: %02X", m_buffer[2U]); CUtils::dump("Buffer dump", m_buffer, m_length); break; @@ -1112,39 +1124,6 @@ RESP_TYPE_MMDVM CModem::getResponse() if (ret == 0) return RTM_TIMEOUT; - switch (m_buffer[2U]) { - case MMDVM_DSTAR_HEADER: - case MMDVM_DSTAR_DATA: - case MMDVM_DSTAR_LOST: - case MMDVM_DSTAR_EOT: - case MMDVM_DMR_DATA1: - case MMDVM_DMR_DATA2: - case MMDVM_DMR_LOST1: - case MMDVM_DMR_LOST2: - case MMDVM_YSF_DATA: - case MMDVM_YSF_LOST: - case MMDVM_P25_HDR: - case MMDVM_P25_LDU: - case MMDVM_P25_LOST: - case MMDVM_GET_STATUS: - case MMDVM_GET_VERSION: - case MMDVM_ACK: - case MMDVM_NAK: - case MMDVM_SERIAL: - case MMDVM_SAMPLES: - case MMDVM_DEBUG1: - case MMDVM_DEBUG2: - case MMDVM_DEBUG3: - case MMDVM_DEBUG4: - case MMDVM_DEBUG5: - break; - - default: - LogError("Unknown message, type: %02X", m_buffer[2U]); - m_offset = 0U; - return RTM_ERROR; - } - m_offset = 3U; } @@ -1167,23 +1146,9 @@ RESP_TYPE_MMDVM CModem::getResponse() m_offset = 0U; - switch (m_buffer[2U]) { - case MMDVM_DEBUG1: - case MMDVM_DEBUG2: - case MMDVM_DEBUG3: - case MMDVM_DEBUG4: - case MMDVM_DEBUG5: - printDebug(); - return RTM_TIMEOUT; + // CUtils::dump(1U, "Received", m_buffer, m_length); - case MMDVM_SAMPLES: - printSamples(); - return RTM_TIMEOUT; - - default: - // CUtils::dump(1U, "Received", m_buffer, m_length); - return RTM_OK; - } + return RTM_OK; } HW_TYPE CModem::getHWType() const diff --git a/Nextion.cpp b/Nextion.cpp index a0635a5..f434c57 100644 --- a/Nextion.cpp +++ b/Nextion.cpp @@ -25,10 +25,14 @@ #include #include -const unsigned int DSTAR_RSSI_COUNT = 3U; // 3 * 420ms = 1260ms -const unsigned int DMR_RSSI_COUNT = 4U; // 4 * 360ms = 1440ms +const unsigned int DSTAR_RSSI_COUNT = 3U; // 3 * 420ms = 1260ms +const unsigned int DSTAR_BER_COUNT = 63U; // 63 * 20ms = 1260ms +const unsigned int DMR_RSSI_COUNT = 4U; // 4 * 360ms = 1440ms +const unsigned int DMR_BER_COUNT = 24U; // 24 * 60ms = 1440ms const unsigned int YSF_RSSI_COUNT = 13U; // 13 * 100ms = 1300ms -const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms +const unsigned int YSF_BER_COUNT = 13U; // 13 * 100ms = 1300ms +const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms +const unsigned int P25_BER_COUNT = 7U; // 7 * 180ms = 1260ms CNextion::CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness) : CDisplay(), @@ -41,8 +45,14 @@ m_displayClock(displayClock), m_utc(utc), m_idleBrightness(idleBrightness), m_clockDisplayTimer(1000U, 0U, 400U), -m_rssiCount1(0U), -m_rssiCount2(0U) +m_rssiAccum1(0U), +m_rssiAccum2(0U), +m_berAccum1(0.0F), +m_berAccum2(0.0F), +m_rssiCount1(1U), +m_rssiCount2(1U), +m_berCount1(1U), +m_berCount2(1U) { assert(serial != NULL); assert(brightness >= 0U && brightness <= 100U); @@ -129,8 +139,8 @@ void CNextion::writeDStarInt(const char* my1, const char* my2, const char* your, assert(type != NULL); assert(reflector != NULL); - if (m_mode != MODE_DSTAR) - sendCommand("page DStar"); + if (m_mode != MODE_DSTAR) + sendCommand("page DStar"); char text[30U]; ::sprintf(text, "dim=%u", m_brightness); @@ -150,20 +160,38 @@ void CNextion::writeDStarInt(const char* my1, const char* my2, const char* your, m_clockDisplayTimer.stop(); m_mode = MODE_DSTAR; - m_rssiCount1 = 0U; + m_rssiAccum1 = 0U; + m_berAccum1 = 0.0F; + m_rssiCount1 = 1U; + m_berCount1 = 1U; } void CNextion::writeDStarRSSIInt(unsigned char rssi) { - if (m_rssiCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t3.txt=\"-%udBm\"", rssi); - sendCommand(text); - } - + m_rssiAccum1 += rssi; m_rssiCount1++; - if (m_rssiCount1 >= DSTAR_RSSI_COUNT) - m_rssiCount1 = 0U; + + if (m_rssiCount1 == DSTAR_RSSI_COUNT) { + char text[20U]; + ::sprintf(text, "t3.txt=\"-%udBm\"", m_rssiAccum1 / DSTAR_RSSI_COUNT); + sendCommand(text); + m_rssiAccum1 = 0U; + m_rssiCount1 = 1U; + } +} + +void CNextion::writeDStarBERInt(float ber) +{ + m_berAccum1 += ber; + m_berCount1++; + + if (m_berCount1 == DSTAR_BER_COUNT) { + char text[20U]; + ::sprintf(text, "t4.txt=\"%.1f%%\"", m_berAccum1 / float(DSTAR_BER_COUNT)); + sendCommand(text); + m_berAccum1 = 0.0F; + m_berCount1 = 1U; + } } void CNextion::clearDStarInt() @@ -172,6 +200,7 @@ void CNextion::clearDStarInt() sendCommand("t1.txt=\"\""); sendCommand("t2.txt=\"\""); sendCommand("t3.txt=\"\""); + sendCommand("t4.txt=\"\""); } void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) @@ -208,32 +237,67 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro m_clockDisplayTimer.stop(); m_mode = MODE_DMR; - m_rssiCount1 = 0U; - m_rssiCount2 = 0U; + m_rssiAccum1 = 0U; + m_rssiAccum2 = 0U; + m_berAccum1 = 0.0F; + m_berAccum2 = 0.0F; + m_rssiCount1 = 1U; + m_rssiCount2 = 1U; + m_berCount1 = 1U; + m_berCount2 = 1U; } void CNextion::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi) { if (slotNo == 1U) { - if (m_rssiCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t4.txt=\"-%udBm\"", rssi); - sendCommand(text); - } - + m_rssiAccum1 += rssi; m_rssiCount1++; - if (m_rssiCount1 >= DMR_RSSI_COUNT) - m_rssiCount1 = 0U; - } else { - if (m_rssiCount2 == 0U) { + + if (m_rssiCount1 == DMR_RSSI_COUNT) { char text[20U]; - ::sprintf(text, "t5.txt=\"-%udBm\"", rssi); + ::sprintf(text, "t4.txt=\"-%udBm\"", m_rssiAccum1 / DMR_RSSI_COUNT); sendCommand(text); + m_rssiAccum1 = 0U; + m_rssiCount1 = 1U; } - + } else { + m_rssiAccum2 += rssi; m_rssiCount2++; - if (m_rssiCount2 >= DMR_RSSI_COUNT) - m_rssiCount2 = 0U; + + if (m_rssiCount2 == DMR_RSSI_COUNT) { + char text[20U]; + ::sprintf(text, "t5.txt=\"-%udBm\"", m_rssiAccum2 / DMR_RSSI_COUNT); + sendCommand(text); + m_rssiAccum2 = 0U; + m_rssiCount2 = 1U; + } + } +} + +void CNextion::writeDMRBERInt(unsigned int slotNo, float ber) +{ + if (slotNo == 1U) { + m_berAccum1 += ber; + m_berCount1++; + + if (m_berCount1 == DMR_BER_COUNT) { + char text[20U]; + ::sprintf(text, "t6.txt=\"%.1f%%\"", m_berAccum1 / DMR_BER_COUNT); + sendCommand(text); + m_berAccum1 = 0U; + m_berCount1 = 1U; + } + } else { + m_berAccum2 += ber; + m_berCount2++; + + if (m_berCount2 == DMR_BER_COUNT) { + char text[20U]; + ::sprintf(text, "t7.txt=\"%.1f%%\"", m_berAccum2 / DMR_BER_COUNT); + sendCommand(text); + m_berAccum2 = 0U; + m_berCount2 = 1U; + } } } @@ -243,11 +307,13 @@ void CNextion::clearDMRInt(unsigned int slotNo) sendCommand("t0.txt=\"1 Listening\""); sendCommand("t1.txt=\"\""); sendCommand("t4.txt=\"\""); - } else { + sendCommand("t6.txt=\"\""); + } else { sendCommand("t2.txt=\"2 Listening\""); sendCommand("t3.txt=\"\""); sendCommand("t5.txt=\"\""); - } + sendCommand("t7.txt=\"\""); + } } void CNextion::writeFusionInt(const char* source, const char* dest, const char* type, const char* origin) @@ -277,20 +343,38 @@ void CNextion::writeFusionInt(const char* source, const char* dest, const char* m_clockDisplayTimer.stop(); m_mode = MODE_YSF; - m_rssiCount1 = 0U; + m_rssiAccum1 = 0U; + m_berAccum1 = 0.0F; + m_rssiCount1 = 1U; + m_berCount1 = 1U; } void CNextion::writeFusionRSSIInt(unsigned char rssi) { - if (m_rssiCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t3.txt=\"-%udBm\"", rssi); - sendCommand(text); - } - + m_rssiAccum1 += rssi; m_rssiCount1++; - if (m_rssiCount1 >= YSF_RSSI_COUNT) - m_rssiCount1 = 0U; + + if (m_rssiCount1 == YSF_RSSI_COUNT) { + char text[20U]; + ::sprintf(text, "t3.txt=\"-%udBm\"", m_rssiAccum1 / YSF_RSSI_COUNT); + sendCommand(text); + m_rssiAccum1 = 0U; + m_rssiCount1 = 1U; + } +} + +void CNextion::writeFusionBERInt(float ber) +{ + m_berAccum1 += ber; + m_berCount1++; + + if (m_berCount1 == YSF_BER_COUNT) { + char text[20U]; + ::sprintf(text, "t4.txt=\"%.1f%%\"", m_berAccum1 / float(YSF_BER_COUNT)); + sendCommand(text); + m_berAccum1 = 0.0F; + m_berCount1 = 1U; + } } void CNextion::clearFusionInt() @@ -299,6 +383,7 @@ void CNextion::clearFusionInt() sendCommand("t1.txt=\"\""); sendCommand("t2.txt=\"\""); sendCommand("t3.txt=\"\""); + sendCommand("t4.txt=\"\""); } void CNextion::writeP25Int(const char* source, bool group, unsigned int dest, const char* type) @@ -322,20 +407,38 @@ void CNextion::writeP25Int(const char* source, bool group, unsigned int dest, co m_clockDisplayTimer.stop(); m_mode = MODE_P25; - m_rssiCount1 = 0U; + m_rssiAccum1 = 0U; + m_berAccum1 = 0.0F; + m_rssiCount1 = 1U; + m_berCount1 = 1U; } void CNextion::writeP25RSSIInt(unsigned char rssi) { - if (m_rssiCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t2.txt=\"-%udBm\"", rssi); - sendCommand(text); - } - + m_rssiAccum1 += rssi; m_rssiCount1++; - if (m_rssiCount1 >= P25_RSSI_COUNT) - m_rssiCount1 = 0U; + + if (m_rssiCount1 == P25_RSSI_COUNT) { + char text[20U]; + ::sprintf(text, "t2.txt=\"-%udBm\"", m_rssiAccum1 / P25_RSSI_COUNT); + sendCommand(text); + m_rssiAccum1 = 0U; + m_rssiCount1 = 1U; + } +} + +void CNextion::writeP25BERInt(float ber) +{ + m_berAccum1 += ber; + m_berCount1++; + + if (m_berCount1 == P25_BER_COUNT) { + char text[20U]; + ::sprintf(text, "t3.txt=\"%.1f%%\"", m_berAccum1 / float(P25_BER_COUNT)); + sendCommand(text); + m_berAccum1 = 0.0F; + m_berCount1 = 1U; + } } void CNextion::clearP25Int() @@ -343,6 +446,7 @@ void CNextion::clearP25Int() sendCommand("t0.txt=\"Listening\""); sendCommand("t1.txt=\"\""); sendCommand("t2.txt=\"\""); + sendCommand("t3.txt=\"\""); } void CNextion::writeCWInt() diff --git a/Nextion.h b/Nextion.h index e1b8242..c5a931b 100644 --- a/Nextion.h +++ b/Nextion.h @@ -43,18 +43,22 @@ protected: virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector); virtual void writeDStarRSSIInt(unsigned char rssi); + virtual void writeDStarBERInt(float ber); virtual void clearDStarInt(); virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi); + virtual void writeDMRBERInt(unsigned int slotNo, float ber); virtual void clearDMRInt(unsigned int slotNo); virtual void writeFusionInt(const char* source, const char* dest, const char* type, const char* origin); virtual void writeFusionRSSIInt(unsigned char rssi); + virtual void writeFusionBERInt(float ber); virtual void clearFusionInt(); virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type); virtual void writeP25RSSIInt(unsigned char rssi); + virtual void writeP25BERInt(float ber); virtual void clearP25Int(); virtual void writeCWInt(); @@ -72,8 +76,14 @@ private: bool m_utc; unsigned int m_idleBrightness; CTimer m_clockDisplayTimer; + unsigned int m_rssiAccum1; + unsigned int m_rssiAccum2; + float m_berAccum1; + float m_berAccum2; unsigned int m_rssiCount1; unsigned int m_rssiCount2; + unsigned int m_berCount1; + unsigned int m_berCount2; void sendCommand(const char* command); }; diff --git a/Nextion/NX3224T024.HMI b/Nextion/NX3224T024.HMI index 49cb09204c86c0faa6186f480c2807d120dda2f0..9caff5979adbb3a98ed14a23fada6f5276403a9f 100644 GIT binary patch delta 4600 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 Ufq$R!aHdqtp6-_p{^B412AhngRR910 delta 3002 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 reJvNGH`q-cwnzo<3xhYmKzp18v9)50WI-a

EHzmn#7m| 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 G)qevzZx;0c diff --git a/P25Control.cpp b/P25Control.cpp index 26b139e..b457534 100644 --- a/P25Control.cpp +++ b/P25Control.cpp @@ -207,7 +207,9 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len) // Regenerate Audio unsigned int errors = m_audio.process(data + 2U); - LogDebug("P25, LDU1 audio, errs: %u/1233", errors); + LogDebug("P25, LDU1 audio, errs: %u/1233 (%.1f%%)", errors, float(errors) / 12.33F); + + m_display->writeP25BER(float(errors) / 12.33F); m_rfBits += 1233U; m_rfErrs += errors; @@ -260,7 +262,9 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len) // Regenerate Audio unsigned int errors = m_audio.process(data + 2U); - LogDebug("P25, LDU2 audio, errs: %u/1233", errors); + LogDebug("P25, LDU2 audio, errs: %u/1233 (%.1f%%)", errors, float(errors) / 12.33F); + + m_display->writeP25BER(float(errors) / 12.33F); m_rfBits += 1233U; m_rfErrs += errors; diff --git a/YSFControl.cpp b/YSFControl.cpp index 92fc796..233d284 100644 --- a/YSFControl.cpp +++ b/YSFControl.cpp @@ -273,6 +273,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) unsigned int errors = m_rfPayload.processVDMode1Audio(data + 2U); m_rfErrs += errors; m_rfBits += 235U; + m_display->writeFusionBER(float(errors) / 2.35F); LogDebug("YSF, V/D Mode 1, seq %u, AMBE FEC %u/235 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 2.35F); } break; @@ -282,6 +283,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) unsigned int errors = m_rfPayload.processVDMode2Audio(data + 2U); m_rfErrs += errors; m_rfBits += 135U; + m_display->writeFusionBER(float(errors) / 1.35F); LogDebug("YSF, V/D Mode 2, seq %u, Repetition FEC %u/135 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 1.35F); } break; @@ -297,6 +299,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) unsigned int errors = m_rfPayload.processVoiceFRModeAudio(data + 2U); m_rfErrs += errors; m_rfBits += 720U; + m_display->writeFusionBER(float(errors) / 7.2F); LogDebug("YSF, V Mode 3, seq %u, AMBE FEC %u/720 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 7.2F); } valid = false; @@ -542,7 +545,6 @@ void CYSFControl::writeNetwork() // if (send) { m_netErrs += errors; m_netBits += 235U; - LogDebug("YSF, V/D Mode 1, seq %u, AMBE FEC %u/235 (%.1f%%)", n, errors, float(errors) / 2.35F); // } } break; @@ -554,13 +556,11 @@ void CYSFControl::writeNetwork() // if (send) { m_netErrs += errors; m_netBits += 135U; - LogDebug("YSF, V/D Mode 2, seq %u, Repetition FEC %u/135 (%.1f%%)", n, errors, float(errors) / 1.35F); // } } break; case YSF_DT_DATA_FR_MODE: - LogDebug("YSF, Network data FICH B=%u/%u F=%u/%u", bn, bt, fn, ft); m_netPayload.processDataFRModeData(data + 35U, fn, gateway); break; @@ -572,7 +572,6 @@ void CYSFControl::writeNetwork() // if (send) { m_netErrs += errors; m_netBits += 720U; - LogDebug("YSF, V Mode 3, seq %u, AMBE FEC %u/720 (%.1f%%)", n, errors, float(errors) / 7.2F); // } } break;