diff --git a/src/common/Defines.h b/src/common/Defines.h index 60040731..9ac96a2b 100644 --- a/src/common/Defines.h +++ b/src/common/Defines.h @@ -109,7 +109,7 @@ typedef unsigned long long ulong64_t; #define __PROG_NAME__ "" #define __NET_NAME__ "DVM_DMR_P25" #define __EXE_NAME__ "" -#define __VER__ "D03.60.00-alpha (" __GIT_VER__ ")" +#define __VER__ "D03.60.00 (" __GIT_VER__ ")" #define __BUILD__ __DATE__ " " __TIME__ #define HOST_SW_API diff --git a/src/host/calibrate/HostCal.cpp b/src/host/calibrate/HostCal.cpp index f2d968f3..0146ea9e 100644 --- a/src/host/calibrate/HostCal.cpp +++ b/src/host/calibrate/HostCal.cpp @@ -93,7 +93,7 @@ int HostCal::run(int argc, char **argv) ::LogInfo(">> Modem Calibration"); yaml::Node systemConf = m_conf["system"]; - m_duplex = systemConf["duplex"].as(true); + m_startupDuplex = m_duplex = systemConf["duplex"].as(true); // try to load bandplan identity table std::string idenLookupFile = systemConf["iden_table"]["file"].as(); @@ -428,6 +428,13 @@ int HostCal::run(int argc, char **argv) } break; + case ')': + { + m_duplex = !m_duplex; + writeConfig(); + } + break; + /** Mode Commands */ case 'Z': { @@ -549,7 +556,6 @@ int HostCal::run(int argc, char **argv) break; case 'B': case 'J': - case ')': { m_mode = STATE_DMR; if (c == 'J') { @@ -560,11 +566,8 @@ int HostCal::run(int argc, char **argv) m_modeStr = DMR_FEC_STR; m_dmrRx1K = false; } - if (c == ')') { - m_duplex = true; - } else { - m_duplex = false; - } + + m_duplex = m_startupDuplex; m_dmrEnabled = true; m_p25Enabled = false; m_nxdnEnabled = false; @@ -585,7 +588,8 @@ int HostCal::run(int argc, char **argv) m_modeStr = P25_FEC_STR; m_p25Rx1K = false; } - m_duplex = false; + + m_duplex = m_startupDuplex; m_dmrEnabled = false; m_p25Enabled = true; m_p25TduTest = false; @@ -601,7 +605,8 @@ int HostCal::run(int argc, char **argv) if (m_modem->getVersion() >= 3U) { m_mode = STATE_NXDN; m_modeStr = NXDN_FEC_STR; - m_duplex = false; + + m_duplex = m_startupDuplex; m_dmrEnabled = false; m_p25Enabled = false; m_p25Rx1K = false; @@ -620,6 +625,7 @@ int HostCal::run(int argc, char **argv) { m_mode = STATE_RSSI_CAL; m_modeStr = RSSI_CAL_STR; + m_duplex = true; m_dmrEnabled = false; m_dmrRx1K = false; @@ -720,6 +726,7 @@ void HostCal::displayHelp() if (!m_modem->m_flashDisabled) { LogMessage(LOG_CAL, " U Read modem configuration area and reset local configuration"); } + LogMessage(LOG_CAL, " ) Swap Duplex Flag (depending on mode this will enable/disable duplex)"); LogMessage(LOG_CAL, " Q/q Quit"); LogMessage(LOG_CAL, "Level Adjustment Commands:"); if (!m_isHotspot) { diff --git a/src/host/setup/HostSetup.cpp b/src/host/setup/HostSetup.cpp index b84edd09..1233c3d4 100644 --- a/src/host/setup/HostSetup.cpp +++ b/src/host/setup/HostSetup.cpp @@ -66,21 +66,21 @@ using namespace lookups; // Voice LC MS Header, CC: 1, srcID: 1, dstID: TG9 const uint8_t VH_DMO1K[] = { - 0x00U, 0x20U, 0x08U, 0x08U, 0x02U, 0x38U, 0x15U, 0x00U, 0x2CU, 0xA0U, 0x14U, - 0x60U, 0x84U, 0x6DU, 0x5DU, 0x7FU, 0x77U, 0xFDU, 0x75U, 0x7EU, 0x30U, 0x30U, - 0x01U, 0x10U, 0x01U, 0x40U, 0x03U, 0xC0U, 0x13U, 0xC1U, 0x1EU, 0x80U, 0x6FU }; + 0x00U, 0x20U, 0x08U, 0x08U, 0x02U, 0x38U, 0x15U, 0x00U, 0x2CU, 0xA0U, 0x14U, + 0x60U, 0x84U, 0x6DU, 0x5DU, 0x7FU, 0x77U, 0xFDU, 0x75U, 0x7EU, 0x30U, 0x30U, + 0x01U, 0x10U, 0x01U, 0x40U, 0x03U, 0xC0U, 0x13U, 0xC1U, 0x1EU, 0x80U, 0x6FU }; // Voice Term MS with LC, CC: 1, srcID: 1, dstID: TG9 const uint8_t VT_DMO1K[] = { - 0x00U, 0x4FU, 0x08U, 0xDCU, 0x02U, 0x88U, 0x15U, 0x78U, 0x2CU, 0xD0U, 0x14U, - 0xC0U, 0x84U, 0xADU, 0x5DU, 0x7FU, 0x77U, 0xFDU, 0x75U, 0x79U, 0x65U, 0x24U, - 0x02U, 0x28U, 0x06U, 0x20U, 0x0FU, 0x80U, 0x1BU, 0xC1U, 0x07U, 0x80U, 0x5CU }; + 0x00U, 0x4FU, 0x08U, 0xDCU, 0x02U, 0x88U, 0x15U, 0x78U, 0x2CU, 0xD0U, 0x14U, + 0xC0U, 0x84U, 0xADU, 0x5DU, 0x7FU, 0x77U, 0xFDU, 0x75U, 0x79U, 0x65U, 0x24U, + 0x02U, 0x28U, 0x06U, 0x20U, 0x0FU, 0x80U, 0x1BU, 0xC1U, 0x07U, 0x80U, 0x5CU }; // Voice coding data + FEC, 1031 Hz Test Pattern const uint8_t VOICE_1K[] = { - 0xCEU, 0xA8U, 0xFEU, 0x83U, 0xACU, 0xC4U, 0x58U, 0x20U, 0x0AU, 0xCEU, 0xA8U, - 0xFEU, 0x83U, 0xA0U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x0CU, 0xC4U, 0x58U, - 0x20U, 0x0AU, 0xCEU, 0xA8U, 0xFEU, 0x83U, 0xACU, 0xC4U, 0x58U, 0x20U, 0x0AU }; + 0xCEU, 0xA8U, 0xFEU, 0x83U, 0xACU, 0xC4U, 0x58U, 0x20U, 0x0AU, 0xCEU, 0xA8U, + 0xFEU, 0x83U, 0xA0U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x0CU, 0xC4U, 0x58U, + 0x20U, 0x0AU, 0xCEU, 0xA8U, 0xFEU, 0x83U, 0xACU, 0xC4U, 0x58U, 0x20U, 0x0AU }; // Recommended 1011 Hz test pattern for P25 Phase 1 (ANSI/TIA-102.CAAA) // NAC: 0x293, srcID: 1, dstID: TG1 @@ -211,8 +211,7 @@ int HostSetup::run(int argc, char** argv) yaml::Node logConf = m_conf["log"]; yaml::Node systemConf = m_conf["system"]; yaml::Node modemConfig = systemConf["modem"]; - m_duplex = systemConf["duplex"].as(true); - m_startupDuplex = m_duplex; + m_startupDuplex = m_duplex = systemConf["duplex"].as(true); // try to load bandplan identity table std::string idenLookupFile = systemConf["iden_table"]["file"].as(); @@ -1508,6 +1507,7 @@ bool HostSetup::writeConfig(uint8_t modeOverride) buffer[3U] |= 0x04U; if (m_debug) buffer[3U] |= 0x10U; + buffer[3U] |= 0x40U; // force DMO for calibration if (!m_duplex) buffer[3U] |= 0x80U; diff --git a/src/host/setup/SetupMainWnd.h b/src/host/setup/SetupMainWnd.h index 3db87ea5..b4fc39d6 100644 --- a/src/host/setup/SetupMainWnd.h +++ b/src/host/setup/SetupMainWnd.h @@ -121,6 +121,7 @@ public: // calibrate menu m_calibrateMenuSeparator1.setSeparator(); m_calibrateMenuSeparator2.setSeparator(); + m_calibrateMenuSeparator3.setSeparator(); m_dmrCal.addCallback("toggled", [&]() { m_setup->m_mode = STATE_DMR_CAL; m_setup->m_modeStr = DMR_CAL_STR; @@ -132,6 +133,7 @@ public: m_setup->m_p25TduTest = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -148,6 +150,7 @@ public: m_setup->m_p25TduTest = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -164,6 +167,7 @@ public: m_setup->m_p25TduTest = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -180,6 +184,7 @@ public: m_setup->m_p25TduTest = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -196,6 +201,7 @@ public: m_setup->m_p25TduTest = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -212,6 +218,7 @@ public: m_setup->m_p25TduTest = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -226,6 +233,7 @@ public: m_setup->m_p25TduTest = true; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(); m_setup->m_queue.clear(); @@ -246,6 +254,7 @@ public: m_setup->m_p25TduTest = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -259,18 +268,12 @@ public: m_setup->m_mode = STATE_DMR; m_setup->m_modeStr = DMR_FEC_STR; m_setup->m_dmrRx1K = false; -/* - if (c == ')') { - m_setup->m_duplex = true; - } else { - m_setup->m_duplex = false; - } -*/ - m_setup->m_duplex = false; + m_setup->m_duplex = m_setup->m_startupDuplex; m_setup->m_dmrEnabled = true; m_setup->m_p25Enabled = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(true); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -280,18 +283,12 @@ public: m_setup->m_mode = STATE_DMR; m_setup->m_modeStr = DMR_FEC_1K_STR; m_setup->m_dmrRx1K = true; -/* - if (c == ')') { - m_setup->m_duplex = true; - } else { - m_setup->m_duplex = false; - } -*/ - m_setup->m_duplex = false; + m_setup->m_duplex = m_setup->m_startupDuplex; m_setup->m_dmrEnabled = true; m_setup->m_p25Enabled = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(true); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -301,12 +298,13 @@ public: m_setup->m_mode = STATE_P25; m_setup->m_modeStr = P25_FEC_STR; m_setup->m_p25Rx1K = false; - m_setup->m_duplex = false; + m_setup->m_duplex = m_setup->m_startupDuplex; m_setup->m_dmrEnabled = false; m_setup->m_p25Enabled = true; m_setup->m_p25TduTest = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(true); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -316,12 +314,13 @@ public: m_setup->m_mode = STATE_P25; m_setup->m_modeStr = P25_FEC_1K_STR; m_setup->m_p25Rx1K = true; - m_setup->m_duplex = false; + m_setup->m_duplex = m_setup->m_startupDuplex; m_setup->m_dmrEnabled = false; m_setup->m_p25Enabled = true; m_setup->m_p25TduTest = false; m_setup->m_nxdnEnabled = false; + updateDuplexState(); resetBERWnd(true); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -332,13 +331,14 @@ public: if (m_setup->m_modem->getVersion() >= 3U) { m_setup->m_mode = STATE_NXDN; m_setup->m_modeStr = NXDN_FEC_STR; - m_setup->m_duplex = false; + m_setup->m_duplex = m_setup->m_startupDuplex; m_setup->m_dmrEnabled = false; m_setup->m_p25Enabled = false; m_setup->m_p25Rx1K = false; m_setup->m_p25TduTest = false; m_setup->m_nxdnEnabled = true; + updateDuplexState(); resetBERWnd(true); LogMessage(LOG_CAL, " - %s", m_setup->m_modeStr.c_str()); @@ -392,6 +392,13 @@ public: m_setup->writeConfig(); } }); + m_toggleDuplex.addCallback("toggled", this, [&]() { + if (m_setup->m_isHotspot && m_setup->m_isConnected) { + m_setup->m_duplex = !m_setup->m_duplex; + LogMessage(LOG_CAL, "Hotspot Rx: %s", m_setup->m_duplex ? "Rx Antenna" : "Tx Antenna"); + m_setup->writeConfig(); + } + }); m_adjustLevel.addAccelerator(FKey::Meta_l); // Meta/Alt + L m_adjustLevel.addCallback("clicked", this, [&]() { @@ -472,7 +479,7 @@ public: const FString line(2, UniChar::BoxDrawingsHorizontal); FMessageBox info("About", line + __PROG_NAME__ + line + L"\n\n" L"Version " + __VER__ + L"\n\n" - L"Copyright (c) 2017-2023 Bryan Biedenkapp, N2PLL and DVMProject (https://github.com/dvmproject) Authors." + L"\n" + L"Copyright (c) 2017-2024 Bryan Biedenkapp, N2PLL and DVMProject (https://github.com/dvmproject) Authors." + L"\n" L"Portions Copyright (c) 2015-2021 by Jonathan Naylor, G4KLX and others", FMessageBox::ButtonType::Ok, FMessageBox::ButtonType::Reject, FMessageBox::ButtonType::Reject, this); info.setCenterText(); @@ -506,9 +513,20 @@ public: m_toggleDCBlocker.setChecked(); } + updateDuplexState(); updateMenuStates(); } + /// + /// Helper to update duplex toggle menu state. + /// + void updateDuplexState() + { + if (m_setup->m_duplex) { + m_toggleDuplex.setChecked(); + } + } + /// /// Helper to update menu states. /// @@ -530,6 +548,8 @@ public: m_togglePTTInvert.setDisable(); m_toggleDCBlocker.setDisable(); + m_toggleDuplex.setEnable(); + m_adjSymLevel.setDisable(); m_adjHSBandwidth.setEnable(); m_adjHSGain.setEnable(); @@ -540,6 +560,8 @@ public: m_togglePTTInvert.setEnable(); m_toggleDCBlocker.setEnable(); + m_toggleDuplex.setDisable(); + m_adjSymLevel.setEnable(); m_adjHSBandwidth.setDisable(); m_adjHSGain.setDisable(); @@ -601,6 +623,8 @@ private: FCheckMenuItem m_togglePTTInvert{"PTT Invert", &m_calibrateMenu}; FCheckMenuItem m_toggleDCBlocker{"DC Blocker", &m_calibrateMenu}; FMenuItem m_calibrateMenuSeparator2{&m_calibrateMenu}; + FCheckMenuItem m_toggleDuplex{"Rx on Hotspot Rx Antenna", &m_calibrateMenu}; + FMenuItem m_calibrateMenuSeparator3{&m_calibrateMenu}; FMenuItem m_adjustLevel{"&Level Adjustment", &m_calibrateMenu}; FMenu m_engineeringMenu{"&Engineering", &m_menuBar}; @@ -678,6 +702,14 @@ private: void cb_connectToModemClick() { if (!m_setup->m_isConnected) { + bool modemDebugState = g_modemDebug; + if (g_modemDebug) { + g_modemDebug = false; + } + + m_setup->m_debug = false; + m_setup->m_modem->m_debug = false; + FMessageBox wait("Wait", L"Please wait...\nConnecting to modem...", FMessageBox::ButtonType::Reject, FMessageBox::ButtonType::Reject, FMessageBox::ButtonType::Reject, this); wait.setCenterText(); @@ -727,6 +759,13 @@ private: return; } + if (g_modemDebug != modemDebugState) { + g_modemDebug = modemDebugState; + m_setup->m_debug = g_modemDebug; + m_setup->m_modem->m_debug = g_modemDebug; + m_setup->writeConfig(); + } + m_setup->m_isConnected = true; m_connectToModemItem.setDisable();