diff --git a/Configuration.cpp b/Configuration.cpp index f10115db8..0122fcf81 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -262,7 +262,7 @@ private: void initialise_models (); bool open_rig (); - bool set_mode (); + //bool set_mode (); void close_rig (); void enumerate_rigs (); void set_rig_invariants (); @@ -328,7 +328,7 @@ private: // typenames used as arguments must match registered type names :( Q_SIGNAL void stop_transceiver () const; - Q_SIGNAL void frequency (Frequency rx) const; + Q_SIGNAL void frequency (Frequency rx, Transceiver::MODE) const; Q_SIGNAL void tx_frequency (Frequency tx, bool rationalize_mode) const; Q_SIGNAL void mode (Transceiver::MODE, bool rationalize) const; Q_SIGNAL void ptt (bool) const; @@ -389,7 +389,20 @@ private: bool rig_changed_; TransceiverState cached_rig_state_; bool ptt_state_; + + // the following members are required to get the rig into split the + // first time monitor or tune or Tx occur bool setup_split_; + Frequency required_tx_frequency_; // this is needed because DX Lab + // Suite Commander in particular + // insists on reporting out of + // date state after successful + // commands to change the rig + // state :( Zero is valid and it + // means that we don't know the Tx + // frequency rather than implying + // no split. + bool enforce_mode_and_split_; FrequencyDelta transceiver_offset_; @@ -515,6 +528,7 @@ void Configuration::transceiver_tx_frequency (Frequency f) #endif m_->setup_split_ = true; + m_->required_tx_frequency_ = f; m_->transceiver_tx_frequency (f); } @@ -544,6 +558,7 @@ void Configuration::sync_transceiver (bool force_signal, bool enforce_mode_and_s m_->enforce_mode_and_split_ = enforce_mode_and_split; m_->setup_split_ = enforce_mode_and_split; + m_->required_tx_frequency_ = 0; m_->sync_transceiver (force_signal); } @@ -584,6 +599,7 @@ Configuration::impl::impl (Configuration * self, QSettings * settings, QWidget * , rig_changed_ {false} , ptt_state_ {false} , setup_split_ {false} + , required_tx_frequency_ {0} , enforce_mode_and_split_ {false} , transceiver_offset_ {0} , default_audio_input_device_selected_ {false} @@ -1570,6 +1586,7 @@ void Configuration::impl::on_CAT_poll_interval_spin_box_valueChanged (int /* val void Configuration::impl::on_split_mode_button_group_buttonClicked (int /* id */) { setup_split_ = true; + required_tx_frequency_ = 0; } void Configuration::impl::on_test_CAT_push_button_clicked () @@ -1822,51 +1839,61 @@ bool Configuration::impl::open_rig () void Configuration::impl::transceiver_frequency (Frequency f) { - if (set_mode () || cached_rig_state_.frequency () != f) + Transceiver::MODE mode {Transceiver::UNK}; + switch (static_cast (ui_->TX_mode_button_group->checkedId ())) + { + case data_mode_USB: mode = Transceiver::USB; break; + case data_mode_data: mode = Transceiver::DIG_U; break; + case data_mode_none: break; + } + + if (cached_rig_state_.frequency () != f + || (mode != Transceiver::UNK && mode != cached_rig_state_.mode ())) { cached_rig_state_.frequency (f); + cached_rig_state_.mode (mode); // lookup offset transceiver_offset_ = stations_.offset (f); - Q_EMIT frequency (f + transceiver_offset_); + Q_EMIT frequency (f + transceiver_offset_, mode); } } -bool Configuration::impl::set_mode () -{ - // Some rigs change frequency when switching between some modes so - // we need to check if we change mode and not elide the frequency - // setting in the same as the cached frequency. - bool mode_changed {false}; +// bool Configuration::impl::set_mode () +// { +// // Some rigs change frequency when switching between some modes so +// // we need to check if we change mode and not elide the frequency +// // setting in the same as the cached frequency. +// bool mode_changed {false}; - auto data_mode = static_cast (ui_->TX_mode_button_group->checkedId ()); +// auto data_mode = static_cast (ui_->TX_mode_button_group->checkedId ()); - // Set mode if we are responsible for it. - if (data_mode_USB == data_mode && cached_rig_state_.mode () != Transceiver::USB) - { - if (Transceiver::USB != cached_rig_state_.mode ()) - { - cached_rig_state_.mode (Transceiver::USB); - Q_EMIT mode (Transceiver::USB, cached_rig_state_.split () && data_mode_none != data_mode_); - mode_changed = true; - } - } - if (data_mode_data == data_mode && cached_rig_state_.mode () != Transceiver::DIG_U) - { - if (Transceiver::DIG_U != cached_rig_state_.mode ()) - { - cached_rig_state_.mode (Transceiver::DIG_U); - Q_EMIT mode (Transceiver::DIG_U, cached_rig_state_.split () && data_mode_none != data_mode_); - mode_changed = true; - } - } +// // Set mode if we are responsible for it. +// if (data_mode_USB == data_mode && cached_rig_state_.mode () != Transceiver::USB) +// { +// if (Transceiver::USB != cached_rig_state_.mode ()) +// { +// cached_rig_state_.mode (Transceiver::USB); +// Q_EMIT mode (Transceiver::USB, cached_rig_state_.split () && data_mode_none != data_mode_); +// mode_changed = true; +// } +// } +// if (data_mode_data == data_mode && cached_rig_state_.mode () != Transceiver::DIG_U) +// { +// if (Transceiver::DIG_U != cached_rig_state_.mode ()) +// { +// cached_rig_state_.mode (Transceiver::DIG_U); +// Q_EMIT mode (Transceiver::DIG_U, cached_rig_state_.split () && data_mode_none != data_mode_); +// mode_changed = true; +// } +// } - return mode_changed; -} +// return mode_changed; +// } void Configuration::impl::transceiver_tx_frequency (Frequency f) { - if (set_mode () || cached_rig_state_.tx_frequency () != f || cached_rig_state_.split () != !!f) + if (/* set_mode () || */ cached_rig_state_.tx_frequency () != f || cached_rig_state_.split () != !!f) { cached_rig_state_.tx_frequency (f); cached_rig_state_.split (f); @@ -1897,7 +1924,7 @@ void Configuration::impl::transceiver_mode (MODE m) void Configuration::impl::transceiver_ptt (bool on) { - set_mode (); + // set_mode (); cached_rig_state_.ptt (on); @@ -1931,7 +1958,7 @@ void Configuration::impl::handle_transceiver_update (TransceiverState state) || TransceiverFactory::PTT_method_DTR == ptt_method || TransceiverFactory::PTT_method_RTS == ptt_method); - set_mode (); + // set_mode (); // Follow the setup choice. split_mode_selected = static_cast (ui_->split_mode_button_group->checkedId ()); @@ -1958,22 +1985,24 @@ void Configuration::impl::handle_transceiver_update (TransceiverState state) // ui_->split_mode_button_group->button (split_mode)->setChecked (true); // split_mode_selected = split_mode; setup_split_ = true; + required_tx_frequency_ = 0; // Q_EMIT self_->transceiver_failure (tr ("Rig split mode setting not consistent with WSJT-X settings. Changing WSJT-X settings for you.")); Q_EMIT self_->transceiver_failure (tr ("Rig split mode setting not consistent with WSJT-X settings.")); } } - set_mode (); + // set_mode (); } } // One time rig setup split if (setup_split_ && cached_rig_state_.split () != state.split ()) { - Q_EMIT tx_frequency (TransceiverFactory::split_mode_none != split_mode_selected ? state.tx_frequency () : 0, true); + Q_EMIT tx_frequency (TransceiverFactory::split_mode_none != split_mode_selected ? (required_tx_frequency_ ? required_tx_frequency_ : state.tx_frequency ()) : 0, true); } setup_split_ = false; + required_tx_frequency_ = 0; } else { diff --git a/DXLabSuiteCommanderTransceiver.cpp b/DXLabSuiteCommanderTransceiver.cpp index b6f36d1e1..f78ffd721 100644 --- a/DXLabSuiteCommanderTransceiver.cpp +++ b/DXLabSuiteCommanderTransceiver.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "NetworkServerLookup.hpp" @@ -110,19 +111,27 @@ void DXLabSuiteCommanderTransceiver::do_ptt (bool on) } update_PTT (on); - - // do_frequency (state ().frequency ()); // gets Commander synchronized } -void DXLabSuiteCommanderTransceiver::do_frequency (Frequency f) +void DXLabSuiteCommanderTransceiver::do_frequency (Frequency f, MODE m) { #if WSJT_TRACE_CAT qDebug () << "DXLabSuiteCommanderTransceiver::do_frequency:" << f << state (); #endif - // number is localised - // avoid floating point translation errors by adding a small number (0.1Hz) - simple_command ("CmdSetFreq" + QString ("%L1").arg (f / 1e3 + 1e-4, 10, 'f', 3).toLocal8Bit ()); + auto f_string = frequency_to_string (f); + if (UNK != m) + { + auto m_string = map_mode (m); + auto params = ("" + f_string + "" + m_string + "Y").arg (f_string.size ()).arg (m_string.size ()); + simple_command (("CmdSetFreqMode" + params).arg (params.size ())); + update_mode (m); + } + else + { + auto params = ("" + f_string).arg (f_string.size ()); + simple_command (("CmdSetFreq" + params).arg (params.size ())); + } update_rx_frequency (f); } @@ -134,46 +143,30 @@ void DXLabSuiteCommanderTransceiver::do_tx_frequency (Frequency tx, bool /* rati if (tx) { - simple_command ("CmdSplit<1:2>on"); - update_split (true); - - // number is localised - // avoid floating point translation errors by adding a small number (0.1Hz) - - // set TX frequency after going split because going split - // rationalises TX VFO mode and that can change the frequency on - // Yaesu rigs if CW is involved - simple_command ("CmdSetTxFreq" + QString ("%L1").arg (tx / 1e3 + 1e-4, 10, 'f', 3).toLocal8Bit ()); + auto f_string = frequency_to_string (tx); + auto params = ("" + f_string + "Y").arg (f_string.size ()); + simple_command (("CmdQSXSplit" + params).arg (params.size ())); } else { simple_command ("CmdSplit<1:3>off"); } + update_split (tx); update_other_frequency (tx); - - do_frequency (state ().frequency ()); // gets Commander synchronized } -void DXLabSuiteCommanderTransceiver::do_mode (MODE mode, bool /* rationalise */) +void DXLabSuiteCommanderTransceiver::do_mode (MODE m, bool /* rationalise */) { #if WSJT_TRACE_CAT - qDebug () << "DXLabSuiteCommanderTransceiver::do_mode:" << mode << state (); + qDebug () << "DXLabSuiteCommanderTransceiver::do_mode:" << m << state (); #endif - auto mapped = map_mode (mode); - simple_command ((QString ("CmdSetMode<1:%2>").arg (5 + mapped.size ()).arg (mapped.size ()) + mapped).toLocal8Bit ()); + auto m_string = map_mode (m); + auto params = ("<1:%1>" + m_string).arg (m_string.size ()); - if (state ().split ()) - { - // this toggle ensures that the TX VFO mode is the same as the RX VFO - simple_command ("CmdSplit<1:3>off"); - simple_command ("CmdSplit<1:2>on"); - } + simple_command (("CmdSetMode" + params).arg (params.size ())); - do_frequency (state ().frequency ()); // gets Commander synchronized - - // setting TX frequency rationalises the mode on Icoms so get current and set - poll (); + update_mode (m); } void DXLabSuiteCommanderTransceiver::poll () @@ -187,14 +180,14 @@ void DXLabSuiteCommanderTransceiver::poll () auto reply = command_with_reply ("CmdGetFreq", quiet); if (0 == reply.indexOf ("') + 1).replace (",", "").replace (".", ""); - - if (!state ().ptt ()) // Commander is not reliable on frequency - // polls while transmitting + auto f = string_to_frequency (reply.mid (reply.indexOf ('>') + 1)); + if (f) { - update_rx_frequency (reply.toUInt ()); + if (!state ().ptt ()) // Commander is not reliable on frequency + // polls while transmitting + { + update_rx_frequency (f); + } } } else @@ -211,11 +204,14 @@ void DXLabSuiteCommanderTransceiver::poll () reply = command_with_reply ("CmdGetTXFreq", quiet); if (0 == reply.indexOf ("') + 1).replace (",", "").replace (".", ""); - if ("000" != text) + auto f = string_to_frequency (reply.mid (reply.indexOf ('>') + 1)); + if (f) { - update_other_frequency (text.toUInt ()); + if (!state ().ptt ()) // Commander is not reliable on frequency + // polls while transmitting + { + update_other_frequency (f); + } } } else @@ -323,7 +319,7 @@ void DXLabSuiteCommanderTransceiver::poll () } } -void DXLabSuiteCommanderTransceiver::simple_command (QByteArray const& cmd, bool no_debug) +void DXLabSuiteCommanderTransceiver::simple_command (QString const& cmd, bool no_debug) { Q_ASSERT (commander_); @@ -344,17 +340,10 @@ void DXLabSuiteCommanderTransceiver::simple_command (QByteArray const& cmd, bool } } -QByteArray DXLabSuiteCommanderTransceiver::command_with_reply (QByteArray const& cmd, bool no_debug) +QString DXLabSuiteCommanderTransceiver::command_with_reply (QString const& cmd, bool no_debug) { Q_ASSERT (commander_); - if (!no_debug) - { -#if WSJT_TRACE_CAT - qDebug () << "DXLabSuiteCommanderTransceiver:command_with_reply(" << cmd << ')'; -#endif - } - if (!write_to_port (cmd)) { #if WSJT_TRACE_CAT @@ -363,7 +352,7 @@ QByteArray DXLabSuiteCommanderTransceiver::command_with_reply (QByteArray const& throw error { tr ("DX Lab Suite Commander failed to send command \"%1\": %2\n") - .arg (cmd.constData ()) + .arg (cmd) .arg (commander_->errorString ()) }; } @@ -383,7 +372,7 @@ QByteArray DXLabSuiteCommanderTransceiver::command_with_reply (QByteArray const& throw error { tr ("DX Lab Suite Commander send command \"%1\" read reply failed: %2\n") - .arg (cmd.constData ()) + .arg (cmd) .arg (commander_->errorString ()) }; } @@ -397,11 +386,16 @@ QByteArray DXLabSuiteCommanderTransceiver::command_with_reply (QByteArray const& throw error { tr ("DX Lab Suite Commander retries exhausted sending command \"%1\"") - .arg (cmd.constData ()) + .arg (cmd) }; } auto result = commander_->readAll (); + // qDebug () << "result: " << result; + // for (int i = 0; i < result.size (); ++i) + // { + // qDebug () << i << ":" << hex << int (result[i]); + // } if (!no_debug) { @@ -410,11 +404,12 @@ QByteArray DXLabSuiteCommanderTransceiver::command_with_reply (QByteArray const& #endif } - return result; + return result; // converting raw UTF-8 bytes to QString } -bool DXLabSuiteCommanderTransceiver::write_to_port (QByteArray const& data) +bool DXLabSuiteCommanderTransceiver::write_to_port (QString const& s) { + auto data = s.toLocal8Bit (); auto to_send = data.constData (); auto length = data.size (); @@ -431,3 +426,31 @@ bool DXLabSuiteCommanderTransceiver::write_to_port (QByteArray const& data) } return true; } + +QString DXLabSuiteCommanderTransceiver::frequency_to_string (Frequency f) const +{ + // number is localized and in kHz, avoid floating point translation + // errors by adding a small number (0.1Hz) + return QString {"%L1"}.arg (f / 1e3 + 1e-4, 10, 'f', 3); +} + +auto DXLabSuiteCommanderTransceiver::string_to_frequency (QString s) const -> Frequency +{ + // temporary hack because Commander is returning invalid UTF-8 bytes + s.replace (QChar {QChar::ReplacementCharacter}, locale_.groupSeparator ()); + + // remove DP - relies on n.nnn kHz format so we can do ulonglong + // conversion to Hz + bool ok; + + // auto f = locale_.toDouble (s, &ok); // use when CmdSendFreq and + // CmdSendTxFreq reinstated + + auto f = QLocale::c ().toDouble (s, &ok); // temporary fix + + if (!ok) + { + throw error {tr ("DX Lab Suite Commander sent an unrecognized frequency")}; + } + return (f + 1e-4) * 1e3; +} diff --git a/DXLabSuiteCommanderTransceiver.hpp b/DXLabSuiteCommanderTransceiver.hpp index 4ef11dfc2..e23c32a58 100644 --- a/DXLabSuiteCommanderTransceiver.hpp +++ b/DXLabSuiteCommanderTransceiver.hpp @@ -8,6 +8,7 @@ class QTcpSocket; class QByteArray; +class QString; // // DX Lab Suite Commander Interface @@ -32,7 +33,7 @@ public: protected: void do_start () override; void do_stop () override; - void do_frequency (Frequency) override; + void do_frequency (Frequency, MODE = UNK) override; void do_tx_frequency (Frequency, bool rationalise_mode) override; void do_mode (MODE, bool rationalise) override; void do_ptt (bool on) override; @@ -40,14 +41,17 @@ protected: void poll () override; private: - void simple_command (QByteArray const&, bool no_debug = false); - QByteArray command_with_reply (QByteArray const&, bool no_debug = false); - bool write_to_port (QByteArray const&); + void simple_command (QString const&, bool no_debug = false); + QString command_with_reply (QString const&, bool no_debug = false); + bool write_to_port (QString const&); + QString frequency_to_string (Frequency) const; + Frequency string_to_frequency (QString) const; std::unique_ptr wrapped_; bool use_for_ptt_; QString server_; QTcpSocket * commander_; + QLocale locale_; }; #endif diff --git a/EmulateSplitTransceiver.cpp b/EmulateSplitTransceiver.cpp index 4c959eb31..0e47a902c 100644 --- a/EmulateSplitTransceiver.cpp +++ b/EmulateSplitTransceiver.cpp @@ -20,17 +20,17 @@ void EmulateSplitTransceiver::start () noexcept wrapped_->tx_frequency (0, false); } -void EmulateSplitTransceiver::frequency (Frequency rx) noexcept +void EmulateSplitTransceiver::frequency (Frequency rx, MODE m) noexcept { #if WSJT_TRACE_CAT - qDebug () << "EmulateSplitTransceiver::frequency:" << rx; + qDebug () << "EmulateSplitTransceiver::frequency:" << rx << "mode:" << m; #endif // Save frequency parameters. frequency_[0] = rx; // Set active frequency. - wrapped_->frequency (rx); + wrapped_->frequency (rx, m); } void EmulateSplitTransceiver::tx_frequency (Frequency tx, bool /* rationalise_mode */) noexcept diff --git a/EmulateSplitTransceiver.hpp b/EmulateSplitTransceiver.hpp index c57c3c4d9..d08887154 100644 --- a/EmulateSplitTransceiver.hpp +++ b/EmulateSplitTransceiver.hpp @@ -32,7 +32,7 @@ public: explicit EmulateSplitTransceiver (std::unique_ptr wrapped); void start () noexcept override; - void frequency (Frequency) noexcept override; + void frequency (Frequency, MODE) noexcept override; void tx_frequency (Frequency, bool rationalise_mode) noexcept override; void ptt (bool on) noexcept override; diff --git a/HRDTransceiver.cpp b/HRDTransceiver.cpp index 48c471278..93fb85943 100644 --- a/HRDTransceiver.cpp +++ b/HRDTransceiver.cpp @@ -499,12 +499,17 @@ void HRDTransceiver::set_button (int button_index, bool checked) } } -void HRDTransceiver::do_frequency (Frequency f) +void HRDTransceiver::do_frequency (Frequency f, MODE m) { #if WSJT_TRACE_CAT qDebug () << "HRDTransceiver::do_frequency:" << f << "reversed:" << reversed_; #endif + if (UNK != m) + { + do_mode (m, false); + } + auto fo_string = QString::number (f); if (vfo_count_ > 1 && reversed_) { diff --git a/HRDTransceiver.hpp b/HRDTransceiver.hpp index e3872c926..724ad0ee8 100644 --- a/HRDTransceiver.hpp +++ b/HRDTransceiver.hpp @@ -40,9 +40,9 @@ protected: // Implement the TransceiverBase interface. void do_start () override; void do_stop () override; - void do_frequency (Frequency) override; - void do_tx_frequency (Frequency, bool rationalise_mode) override; - void do_mode (MODE, bool rationalise) override; + void do_frequency (Frequency, MODE = UNK) override; + void do_tx_frequency (Frequency, bool rationalise_mode = true) override; + void do_mode (MODE, bool rationalise = true) override; void do_ptt (bool on) override; // Implement the PollingTransceiver interface. diff --git a/HamlibTransceiver.cpp b/HamlibTransceiver.cpp index 08bd14d1e..c1a963669 100644 --- a/HamlibTransceiver.cpp +++ b/HamlibTransceiver.cpp @@ -293,7 +293,7 @@ void HamlibTransceiver::do_start () #endif error_check (rig_get_mode (rig_.data (), RIG_VFO_CURR, &m, &w), tr ("getting current mode")); #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::init_rig rig_get_mode current mode =" << m << "bw =" << w; + qDebug () << "HamlibTransceiver::init_rig rig_get_mode current mode =" << rig_strrmode (m) << "bw =" << w; #endif if (!rig_->caps->set_vfo) @@ -324,7 +324,7 @@ void HamlibTransceiver::do_start () #endif error_check (rig_get_mode (rig_.data (), RIG_VFO_CURR, &mb, &wb), tr ("getting other VFO mode")); #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::init_rig rig_get_mode other mode =" << mb << "bw =" << wb; + qDebug () << "HamlibTransceiver::init_rig rig_get_mode other mode =" << rig_strrmode (mb) << "bw =" << wb; #endif update_other_frequency (f2); @@ -363,7 +363,7 @@ void HamlibTransceiver::do_start () #endif error_check (rig_get_mode (rig_.data (), RIG_VFO_CURR, &m, &w), tr ("getting mode")); #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::init_rig rig_get_mode mode =" << m << "bw =" << w; + qDebug () << "HamlibTransceiver::init_rig rig_get_mode mode =" << rig_strrmode (m) << "bw =" << w; #endif update_rx_frequency (f1); @@ -382,11 +382,11 @@ void HamlibTransceiver::do_start () if (rig_->caps->get_vfo) { #if WSJT_TRACE_CAT - qDebug ().nospace () << "HamlibTransceiver::init_rig rig_get_vfo current VFO"; + qDebug () << "HamlibTransceiver::init_rig rig_get_vfo current VFO"; #endif error_check (rig_get_vfo (rig_.data (), &v), tr ("getting current VFO")); // has side effect of establishing current VFO inside hamlib #if WSJT_TRACE_CAT - qDebug ().nospace () << "HamlibTransceiver::init_rig rig_get_vfo current VFO = 0x" << hex << v; + qDebug () << "HamlibTransceiver::init_rig rig_get_vfo current VFO = " << rig_strvfo (v); #endif } @@ -399,7 +399,7 @@ void HamlibTransceiver::do_start () #endif error_check (rig_get_mode (rig_.data (), RIG_VFO_CURR, &m, &w), tr ("getting current mode")); #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::init_rig rig_get_mode current mode =" << m << "bw =" << w; + qDebug () << "HamlibTransceiver::init_rig rig_get_mode current mode =" << rig_strrmode (m) << "bw =" << w; #endif } } @@ -431,11 +431,11 @@ auto HamlibTransceiver::get_vfos () const -> std::tuple { vfo_t v; #if WSJT_TRACE_CAT - qDebug ().nospace () << "HamlibTransceiver::get_vfos rig_get_vfo"; + qDebug () << "HamlibTransceiver::get_vfos rig_get_vfo"; #endif error_check (rig_get_vfo (rig_.data (), &v), tr ("getting current VFO")); // has side effect of establishing current VFO inside hamlib #if WSJT_TRACE_CAT - qDebug ().nospace () << "HamlibTransceiver::get_vfos rig_get_vfo VFO = 0x" << hex << v; + qDebug () << "HamlibTransceiver::get_vfos rig_get_vfo VFO = " << rig_strvfo (v); #endif reversed_ = RIG_VFO_B == v; @@ -464,18 +464,23 @@ auto HamlibTransceiver::get_vfos () const -> std::tuple } #if WSJT_TRACE_CAT - qDebug ().nospace () << "HamlibTransceiver::get_vfos RX VFO = 0x" << hex << rx_vfo << " TX VFO = 0x" << hex << tx_vfo; + qDebug () << "HamlibTransceiver::get_vfos RX VFO = " << rig_strvfo (rx_vfo) << " TX VFO = " << rig_strvfo (tx_vfo); #endif return std::make_tuple (rx_vfo, tx_vfo); } -void HamlibTransceiver::do_frequency (Frequency f) +void HamlibTransceiver::do_frequency (Frequency f, MODE m) { #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::do_frequency:" << f << "reversed:" << reversed_; + qDebug () << "HamlibTransceiver::do_frequency:" << f << "mode:" << m << "reversed:" << reversed_; #endif + if (UNK != m) + { + do_mode (m, false); + } + if (!is_dummy_) { error_check (rig_set_freq (rig_.data (), RIG_VFO_CURR, f), tr ("setting frequency")); @@ -492,12 +497,33 @@ void HamlibTransceiver::do_tx_frequency (Frequency tx, bool rationalise_mode) if (!is_dummy_) { + auto split = tx ? RIG_SPLIT_ON : RIG_SPLIT_OFF; + update_split (tx); auto vfos = get_vfos (); - // auto rx_vfo = std::get<0> (vfos); + // auto rx_vfo = std::get<0> (vfos); // or use RIG_VFO_CURR auto tx_vfo = std::get<1> (vfos); if (tx) { + // Doing set split for the 1st of two times, this one + // ensures that the internal Hamlib state is correct + // otherwise rig_set_split_freq() will target the wrong VFO + // on some rigs +#if WSJT_TRACE_CAT + qDebug () << "HamlibTransceiver::do_tx_frequency rig_set_split_vfo split =" << split; +#endif + auto rc = rig_set_split_vfo (rig_.data (), RIG_VFO_CURR, split, tx_vfo); + if (tx || (-RIG_ENAVAIL != rc && -RIG_ENIMPL != rc)) + { + // On rigs that can't have split controlled only throw an + // exception when an error other than command not accepted + // is returned when trying to leave split mode. This allows + // fake split mode and non-split mode to work without error + // on such rigs without having to know anything about the + // specific rig. + error_check (rc, tr ("setting/unsetting split mode")); + } + #if WSJT_TRACE_CAT qDebug () << "HamlibTransceiver::do_tx_frequency rig_set_split_freq"; #endif @@ -515,14 +541,14 @@ void HamlibTransceiver::do_tx_frequency (Frequency tx, bool rationalise_mode) #endif error_check (rig_get_split_mode (rig_.data (), RIG_VFO_CURR, ¤t_mode, ¤t_width), tr ("getting mode of split TX VFO")); #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::do_tx_frequency rig_get_split_mode mode =" << current_mode << "bw =" << current_width; + qDebug () << "HamlibTransceiver::do_tx_frequency rig_get_split_mode mode = " << rig_strrmode (current_mode) << "bw =" << current_width; #endif auto new_mode = map_mode (state ().mode ()); if (new_mode != current_mode) { #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::do_tx_frequency rig_set_split_mode mode =" << new_mode; + qDebug () << "HamlibTransceiver::do_tx_frequency rig_set_split_mode mode = " << rig_strrmode (new_mode); #endif error_check (rig_set_split_mode (rig_.data (), RIG_VFO_CURR, new_mode, rig_passband_wide (rig_.data (), new_mode)), tr ("setting split TX VFO mode")); } @@ -533,7 +559,6 @@ void HamlibTransceiver::do_tx_frequency (Frequency tx, bool rationalise_mode) // of split when you switch RX VFO (to set split mode above for // example) - auto split = tx ? RIG_SPLIT_ON : RIG_SPLIT_OFF; #if WSJT_TRACE_CAT qDebug () << "HamlibTransceiver::do_tx_frequency rig_set_split_vfo split =" << split; #endif @@ -550,7 +575,6 @@ void HamlibTransceiver::do_tx_frequency (Frequency tx, bool rationalise_mode) } } - update_split (tx); update_other_frequency (tx); } @@ -574,14 +598,14 @@ void HamlibTransceiver::do_mode (MODE mode, bool rationalise) #endif error_check (rig_get_mode (rig_.data (), RIG_VFO_CURR, ¤t_mode, ¤t_width), tr ("getting current VFO mode")); #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::do_mode rig_get_mode mode =" << current_mode << "bw =" << current_width; + qDebug () << "HamlibTransceiver::do_mode rig_get_mode mode = " << rig_strrmode (current_mode) << "bw =" << current_width; #endif auto new_mode = map_mode (mode); if (new_mode != current_mode) { #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::do_mode rig_set_mode mode =" << new_mode; + qDebug () << "HamlibTransceiver::do_mode rig_set_mode mode = " << rig_strrmode (new_mode); #endif error_check (rig_set_mode (rig_.data (), RIG_VFO_CURR, new_mode, rig_passband_wide (rig_.data (), new_mode)), tr ("setting current VFO mode")); } @@ -593,13 +617,13 @@ void HamlibTransceiver::do_mode (MODE mode, bool rationalise) #endif error_check (rig_get_split_mode (rig_.data (), RIG_VFO_CURR, ¤t_mode, ¤t_width), tr ("getting split TX VFO mode")); #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::do_mode rig_get_split_mode mode =" << current_mode << "bw =" << current_width; + qDebug () << "HamlibTransceiver::do_mode rig_get_split_mode mode = " << rig_strrmode (current_mode) << "bw =" << current_width; #endif if (new_mode != current_mode) { #if WSJT_TRACE_CAT - qDebug () << "HamlibTransceiver::do_mode rig_set_split_mode mode =" << new_mode; + qDebug () << "HamlibTransceiver::do_mode rig_set_split_mode mode = " << rig_strrmode (new_mode); #endif hamlib_tx_vfo_fixup fixup (rig_.data (), tx_vfo); error_check (rig_set_split_mode (rig_.data (), RIG_VFO_CURR, new_mode, rig_passband_wide (rig_.data (), new_mode)), tr ("setting split TX VFO mode")); @@ -638,12 +662,12 @@ void HamlibTransceiver::poll () if (rig_->caps->get_vfo) { #if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS - qDebug ().nospace () << "HamlibTransceiver::poll rig_get_vfo"; + qDebug () << "HamlibTransceiver::poll rig_get_vfo"; #endif vfo_t v; error_check (rig_get_vfo (rig_.data (), &v), tr ("getting current VFO")); // has side effect of establishing current VFO inside hamlib #if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS - qDebug ().nospace () << "HamlibTransceiver::poll rig_get_vfo VFO = 0x" << hex << v; + qDebug () << "HamlibTransceiver::poll rig_get_vfo VFO = " << rig_strvfo (v); #endif reversed_ = RIG_VFO_B == v; @@ -687,7 +711,7 @@ void HamlibTransceiver::poll () #endif error_check (rig_get_mode (rig_.data (), RIG_VFO_CURR, &m, &w), tr ("getting current VFO mode")); #if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS - qDebug () << "HamlibTransceiver::poll rig_get_mode mode =" << m << "bw =" << w; + qDebug () << "HamlibTransceiver::poll rig_get_mode mode =" << rig_strrmode (m) << "bw =" << w; #endif update_mode (map_mode (m)); @@ -695,14 +719,14 @@ void HamlibTransceiver::poll () if (rig_->caps->get_split_vfo && split_query_works_) { #if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS - qDebug ().nospace () << "HamlibTransceiver::poll rig_get_split_vfo"; + qDebug () << "HamlibTransceiver::poll rig_get_split_vfo"; #endif vfo_t v {RIG_VFO_NONE}; // so we can tell if it doesn't get updated :( auto rc = rig_get_split_vfo (rig_.data (), RIG_VFO_CURR, &s, &v); if (-RIG_OK == rc && RIG_SPLIT_ON == s) { #if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS - qDebug ().nospace () << "HamlibTransceiver::poll rig_get_split_vfo split = " << s << " VFO = 0x" << hex << v; + qDebug () << "HamlibTransceiver::poll rig_get_split_vfo split = " << s << " VFO = " << rig_strvfo (v); #endif update_split (true); @@ -714,7 +738,7 @@ void HamlibTransceiver::poll () else if (-RIG_OK == rc) // not split { #if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS - qDebug ().nospace () << "HamlibTransceiver::poll rig_get_split_vfo split = " << s << " VFO = 0x" << hex << v; + qDebug () << "HamlibTransceiver::poll rig_get_split_vfo split = " << s << " VFO = " << rig_strvfo (v); #endif update_split (false); @@ -722,7 +746,7 @@ void HamlibTransceiver::poll () else if (-RIG_ENAVAIL == rc || -RIG_ENIMPL == rc) // Some rigs (Icom) don't have a way of reporting SPLIT mode { #if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS - qDebug ().nospace () << "HamlibTransceiver::poll rig_get_split_vfo can't do on this rig"; + qDebug () << "HamlibTransceiver::poll rig_get_split_vfo can't do on this rig"; #endif // just report how we see it based on prior commands diff --git a/HamlibTransceiver.hpp b/HamlibTransceiver.hpp index c8a5c0ba3..6ff7eafcc 100644 --- a/HamlibTransceiver.hpp +++ b/HamlibTransceiver.hpp @@ -43,9 +43,9 @@ class HamlibTransceiver final private: void do_start () override; void do_stop () override; - void do_frequency (Frequency) override; - void do_tx_frequency (Frequency, bool rationalise_mode) override; - void do_mode (MODE, bool rationalise) override; + void do_frequency (Frequency, MODE = UNK) override; + void do_tx_frequency (Frequency, bool rationalise_mode = true) override; + void do_mode (MODE, bool rationalise = true) override; void do_ptt (bool) override; void poll () override; diff --git a/OmniRigTransceiver.cpp b/OmniRigTransceiver.cpp index 33de89342..ce0c60630 100644 --- a/OmniRigTransceiver.cpp +++ b/OmniRigTransceiver.cpp @@ -632,12 +632,17 @@ void OmniRigTransceiver::do_ptt (bool on) } } -void OmniRigTransceiver::do_frequency (Frequency f) +void OmniRigTransceiver::do_frequency (Frequency f, MODE m) { #if WSJT_TRACE_CAT qDebug () << "OmniRigTransceiver::do_frequency:" << f << state (); #endif + if (UNK != m) + { + do_mode (m, false); + } + if (OmniRig::PM_FREQ & writable_params_) { rig_->SetFreq (f); diff --git a/OmniRigTransceiver.hpp b/OmniRigTransceiver.hpp index 19c203a9e..729543c8a 100644 --- a/OmniRigTransceiver.hpp +++ b/OmniRigTransceiver.hpp @@ -35,7 +35,7 @@ public: void do_start () override; void do_stop () override; - void do_frequency (Frequency) override; + void do_frequency (Frequency, MODE = UNK) override; void do_tx_frequency (Frequency, bool rationalise_mode) override; void do_mode (MODE, bool rationalise) override; void do_ptt (bool on) override; diff --git a/PollingTransceiver.cpp b/PollingTransceiver.cpp index 7e5131ee5..8d4acadc8 100644 --- a/PollingTransceiver.cpp +++ b/PollingTransceiver.cpp @@ -106,17 +106,18 @@ void PollingTransceiver::do_post_stop () m_->stop_timer (); } -void PollingTransceiver::do_post_frequency (Frequency f) +void PollingTransceiver::do_post_frequency (Frequency f, MODE m) { - if (m_->next_state_.frequency () != f) + if (m_->next_state_.frequency () != f || m_->next_state_.mode () != m) { // update expected state with new frequency and set poll count m_->next_state_.frequency (f); + m_->next_state_.mode (m); m_->retries_ = polls_to_stabilize; } } -void PollingTransceiver::do_post_tx_frequency (Frequency f) +void PollingTransceiver::do_post_tx_frequency (Frequency f, bool /* rationalize */) { if (m_->next_state_.tx_frequency () != f) { @@ -128,7 +129,7 @@ void PollingTransceiver::do_post_tx_frequency (Frequency f) } } -void PollingTransceiver::do_post_mode (MODE m) +void PollingTransceiver::do_post_mode (MODE m, bool /*rationalize_mode*/) { if (m_->next_state_.mode () != m) { diff --git a/PollingTransceiver.hpp b/PollingTransceiver.hpp index c8d7a6c32..0abec495b 100644 --- a/PollingTransceiver.hpp +++ b/PollingTransceiver.hpp @@ -41,7 +41,7 @@ public: ~PollingTransceiver (); protected: - void do_sync (bool /* force_signal */) override final; + void do_sync (bool force_signal) override final; // Sub-classes implement this and fetch what they can from the rig // in a non-intrusive manner. @@ -49,9 +49,9 @@ protected: void do_post_start () override final; void do_post_stop () override final; - void do_post_frequency (Frequency) override final; - void do_post_tx_frequency (Frequency) override final; - void do_post_mode (MODE) override final; + void do_post_frequency (Frequency, MODE = UNK) override final; + void do_post_tx_frequency (Frequency, bool rationalize = true) override final; + void do_post_mode (MODE, bool rationalize = true) override final; bool do_pre_update () override final; private: diff --git a/Transceiver.hpp b/Transceiver.hpp index b30150552..2048a3998 100644 --- a/Transceiver.hpp +++ b/Transceiver.hpp @@ -126,7 +126,7 @@ public: Q_SIGNAL void finished () const; // Set frequency in Hertz. - Q_SLOT virtual void frequency (Frequency) noexcept = 0; + Q_SLOT virtual void frequency (Frequency, MODE = UNK) noexcept = 0; // Setting a non-zero TX frequency means split operation, the value // zero means simplex operation. diff --git a/TransceiverBase.cpp b/TransceiverBase.cpp index 738ad7024..77c7f0e88 100644 --- a/TransceiverBase.cpp +++ b/TransceiverBase.cpp @@ -102,15 +102,15 @@ void TransceiverBase::stop () noexcept } } -void TransceiverBase::frequency (Frequency f) noexcept +void TransceiverBase::frequency (Frequency f, MODE m) noexcept { QString message; try { if (m_->state_.online ()) { - do_frequency (f); - do_post_frequency (f); + do_frequency (f, m); + do_post_frequency (f, m); } } catch (std::exception const& e) @@ -135,7 +135,7 @@ void TransceiverBase::tx_frequency (Frequency tx, bool rationalise_mode) noexcep if (m_->state_.online ()) { do_tx_frequency (tx, rationalise_mode); - do_post_tx_frequency (tx); + do_post_tx_frequency (tx, rationalise_mode); } } catch (std::exception const& e) @@ -160,7 +160,7 @@ void TransceiverBase::mode (MODE m, bool rationalise) noexcept if (m_->state_.online ()) { do_mode (m, rationalise); - do_post_mode (m); + do_post_mode (m, rationalise); } } catch (std::exception const& e) diff --git a/TransceiverBase.hpp b/TransceiverBase.hpp index fbf151a6c..d42df9a0f 100644 --- a/TransceiverBase.hpp +++ b/TransceiverBase.hpp @@ -71,7 +71,7 @@ public: // void start () noexcept override final; void stop () noexcept override final; - void frequency (Frequency rx) noexcept override final; + void frequency (Frequency rx, MODE = UNK) noexcept override final; void tx_frequency (Frequency tx, bool rationalise_mode) noexcept override final; void mode (MODE, bool rationalise) noexcept override final; void ptt (bool) noexcept override final; @@ -97,17 +97,17 @@ protected: virtual void do_stop () = 0; virtual void do_post_stop () {} - virtual void do_frequency (Frequency rx) = 0; - virtual void do_post_frequency (Frequency) {} + virtual void do_frequency (Frequency rx, MODE = UNK) = 0; + virtual void do_post_frequency (Frequency, MODE = UNK) {} virtual void do_tx_frequency (Frequency tx = 0, bool rationalise_mode = true) = 0; - virtual void do_post_tx_frequency (Frequency) {} + virtual void do_post_tx_frequency (Frequency, bool /* rationalise_mode */ = true) {} virtual void do_mode (MODE, bool rationalise = true) = 0; - virtual void do_post_mode (MODE) {} + virtual void do_post_mode (MODE, bool /* rationalise */ = true) {} virtual void do_ptt (bool = true) = 0; - virtual void do_post_ptt (bool) {} + virtual void do_post_ptt (bool = true) {} virtual void do_sync (bool force_signal = false) = 0; diff --git a/contrib/Commander TCPIP Mesages.pdf b/contrib/Commander TCPIP Mesages.pdf index ca7b42e50..1c7e6a8ca 100644 Binary files a/contrib/Commander TCPIP Mesages.pdf and b/contrib/Commander TCPIP Mesages.pdf differ diff --git a/mainwindow.cpp b/mainwindow.cpp index e86c5999a..ab81687eb 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -431,8 +431,7 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme ui->labDialFreq->setStyleSheet("QLabel { background-color : black; color : yellow; }"); m_config.transceiver_online (true); - qsy (m_lastMonitoredFrequency); - monitor (!m_config.monitor_off_at_startup ()); + on_monitorButton_clicked (!m_config.monitor_off_at_startup ()); #if !WSJT_ENABLE_EXPERIMENTAL_FEATURES ui->actionJT9W_1->setEnabled (false); @@ -678,12 +677,13 @@ void MainWindow::on_monitorButton_clicked (bool checked) auto prior = m_monitoring; monitor (checked); - if (!prior) + if (checked && !prior) { m_diskData = false; // no longer reading WAV files // put rig back where it was when last in control Q_EMIT m_config.transceiver_frequency (m_lastMonitoredFrequency); + qsy (m_lastMonitoredFrequency); setXIT (ui->TxFreqSpinBox->value ()); } @@ -1504,6 +1504,7 @@ void MainWindow::guiUpdate() if(g_iptt==0 and ((bTxTime and fTR<0.4) or m_tune )) { icw[0]=m_ncw; g_iptt = 1; + setXIT (ui->TxFreqSpinBox->value ()); // ensure correct offset Q_EMIT m_config.transceiver_ptt (true); ptt1Timer->start(200); //Sequencer delay } @@ -2877,10 +2878,7 @@ void MainWindow::handle_transceiver_failure (QString reason) { ui->readFreq->setStyleSheet("QPushButton{background-color: red;" "border-width: 0px; border-radius: 5px;}"); - - m_btxok=false; - m_repeatMsg=0; - + on_stopTxButton_clicked (); rigFailure ("Rig Control Error", reason); }