Support for new DX Lab Suite Commander TCP/IP commands

Dave AA6YQ has added two new commands to the Commander server to allow
more reliable control.

Requires DX Lab Suite Commander 11.1.4 or later.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx-1.4@4777 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2014-12-06 20:19:37 +00:00
parent 9860a6651b
commit 9fae7720c5
18 changed files with 209 additions and 137 deletions

View File

@ -262,7 +262,7 @@ private:
void initialise_models (); void initialise_models ();
bool open_rig (); bool open_rig ();
bool set_mode (); //bool set_mode ();
void close_rig (); void close_rig ();
void enumerate_rigs (); void enumerate_rigs ();
void set_rig_invariants (); void set_rig_invariants ();
@ -328,7 +328,7 @@ private:
// typenames used as arguments must match registered type names :( // typenames used as arguments must match registered type names :(
Q_SIGNAL void stop_transceiver () const; 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 tx_frequency (Frequency tx, bool rationalize_mode) const;
Q_SIGNAL void mode (Transceiver::MODE, bool rationalize) const; Q_SIGNAL void mode (Transceiver::MODE, bool rationalize) const;
Q_SIGNAL void ptt (bool) const; Q_SIGNAL void ptt (bool) const;
@ -390,7 +390,20 @@ private:
bool rig_changed_; bool rig_changed_;
TransceiverState cached_rig_state_; TransceiverState cached_rig_state_;
bool ptt_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_; 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_; bool enforce_mode_and_split_;
FrequencyDelta transceiver_offset_; FrequencyDelta transceiver_offset_;
@ -516,6 +529,7 @@ void Configuration::transceiver_tx_frequency (Frequency f)
#endif #endif
m_->setup_split_ = true; m_->setup_split_ = true;
m_->required_tx_frequency_ = f;
m_->transceiver_tx_frequency (f); m_->transceiver_tx_frequency (f);
} }
@ -545,6 +559,7 @@ void Configuration::sync_transceiver (bool force_signal, bool enforce_mode_and_s
m_->enforce_mode_and_split_ = enforce_mode_and_split; m_->enforce_mode_and_split_ = enforce_mode_and_split;
m_->setup_split_ = enforce_mode_and_split; m_->setup_split_ = enforce_mode_and_split;
m_->required_tx_frequency_ = 0;
m_->sync_transceiver (force_signal); m_->sync_transceiver (force_signal);
} }
@ -588,6 +603,7 @@ Configuration::impl::impl (Configuration * self, QString const& instance_key, QS
, rig_changed_ {false} , rig_changed_ {false}
, ptt_state_ {false} , ptt_state_ {false}
, setup_split_ {false} , setup_split_ {false}
, required_tx_frequency_ {0}
, enforce_mode_and_split_ {false} , enforce_mode_and_split_ {false}
, transceiver_offset_ {0} , transceiver_offset_ {0}
, default_audio_input_device_selected_ {false} , default_audio_input_device_selected_ {false}
@ -1604,6 +1620,7 @@ void Configuration::impl::on_CAT_poll_interval_spin_box_valueChanged (int /* val
void Configuration::impl::on_split_mode_button_group_buttonClicked (int /* id */) void Configuration::impl::on_split_mode_button_group_buttonClicked (int /* id */)
{ {
setup_split_ = true; setup_split_ = true;
required_tx_frequency_ = 0;
} }
void Configuration::impl::on_test_CAT_push_button_clicked () void Configuration::impl::on_test_CAT_push_button_clicked ()
@ -1857,51 +1874,61 @@ bool Configuration::impl::open_rig ()
void Configuration::impl::transceiver_frequency (Frequency f) void Configuration::impl::transceiver_frequency (Frequency f)
{ {
if (set_mode () || cached_rig_state_.frequency () != f) Transceiver::MODE mode {Transceiver::UNK};
switch (static_cast<DataMode> (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_.frequency (f);
cached_rig_state_.mode (mode);
// lookup offset // lookup offset
transceiver_offset_ = stations_.offset (f); transceiver_offset_ = stations_.offset (f);
Q_EMIT frequency (f + transceiver_offset_); Q_EMIT frequency (f + transceiver_offset_, mode);
} }
} }
bool Configuration::impl::set_mode () // bool Configuration::impl::set_mode ()
{ // {
// Some rigs change frequency when switching between some modes so // // Some rigs change frequency when switching between some modes so
// we need to check if we change mode and not elide the frequency // // we need to check if we change mode and not elide the frequency
// setting in the same as the cached frequency. // // setting in the same as the cached frequency.
bool mode_changed {false}; // bool mode_changed {false};
auto data_mode = static_cast<DataMode> (ui_->TX_mode_button_group->checkedId ()); // auto data_mode = static_cast<DataMode> (ui_->TX_mode_button_group->checkedId ());
// Set mode if we are responsible for it. // // Set mode if we are responsible for it.
if (data_mode_USB == data_mode && cached_rig_state_.mode () != Transceiver::USB) // if (data_mode_USB == data_mode && cached_rig_state_.mode () != Transceiver::USB)
{ // {
if (Transceiver::USB != cached_rig_state_.mode ()) // if (Transceiver::USB != cached_rig_state_.mode ())
{ // {
cached_rig_state_.mode (Transceiver::USB); // cached_rig_state_.mode (Transceiver::USB);
Q_EMIT mode (Transceiver::USB, cached_rig_state_.split () && data_mode_none != data_mode_); // Q_EMIT mode (Transceiver::USB, cached_rig_state_.split () && data_mode_none != data_mode_);
mode_changed = true; // mode_changed = true;
} // }
} // }
if (data_mode_data == data_mode && cached_rig_state_.mode () != Transceiver::DIG_U) // if (data_mode_data == data_mode && cached_rig_state_.mode () != Transceiver::DIG_U)
{ // {
if (Transceiver::DIG_U != cached_rig_state_.mode ()) // if (Transceiver::DIG_U != cached_rig_state_.mode ())
{ // {
cached_rig_state_.mode (Transceiver::DIG_U); // cached_rig_state_.mode (Transceiver::DIG_U);
Q_EMIT mode (Transceiver::DIG_U, cached_rig_state_.split () && data_mode_none != data_mode_); // Q_EMIT mode (Transceiver::DIG_U, cached_rig_state_.split () && data_mode_none != data_mode_);
mode_changed = true; // mode_changed = true;
} // }
} // }
return mode_changed; // return mode_changed;
} // }
void Configuration::impl::transceiver_tx_frequency (Frequency f) 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_.tx_frequency (f);
cached_rig_state_.split (f); cached_rig_state_.split (f);
@ -1932,7 +1959,7 @@ void Configuration::impl::transceiver_mode (MODE m)
void Configuration::impl::transceiver_ptt (bool on) void Configuration::impl::transceiver_ptt (bool on)
{ {
set_mode (); // set_mode ();
cached_rig_state_.ptt (on); cached_rig_state_.ptt (on);
@ -1966,7 +1993,7 @@ void Configuration::impl::handle_transceiver_update (TransceiverState state)
|| TransceiverFactory::PTT_method_DTR == ptt_method || TransceiverFactory::PTT_method_DTR == ptt_method
|| TransceiverFactory::PTT_method_RTS == ptt_method); || TransceiverFactory::PTT_method_RTS == ptt_method);
set_mode (); // set_mode ();
// Follow the setup choice. // Follow the setup choice.
split_mode_selected = static_cast<TransceiverFactory::SplitMode> (ui_->split_mode_button_group->checkedId ()); split_mode_selected = static_cast<TransceiverFactory::SplitMode> (ui_->split_mode_button_group->checkedId ());
@ -1993,22 +2020,24 @@ void Configuration::impl::handle_transceiver_update (TransceiverState state)
// ui_->split_mode_button_group->button (split_mode)->setChecked (true); // ui_->split_mode_button_group->button (split_mode)->setChecked (true);
// split_mode_selected = split_mode; // split_mode_selected = split_mode;
setup_split_ = true; 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. Changing WSJT-X settings for you."));
Q_EMIT self_->transceiver_failure (tr ("Rig split mode setting not consistent with WSJT-X settings.")); 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 // One time rig setup split
if (setup_split_ && cached_rig_state_.split () != state.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; setup_split_ = false;
required_tx_frequency_ = 0;
} }
else else
{ {

View File

@ -2,6 +2,7 @@
#include <QTcpSocket> #include <QTcpSocket>
#include <QRegularExpression> #include <QRegularExpression>
#include <QLocale>
#include "NetworkServerLookup.hpp" #include "NetworkServerLookup.hpp"
@ -110,19 +111,27 @@ void DXLabSuiteCommanderTransceiver::do_ptt (bool on)
} }
update_PTT (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 #if WSJT_TRACE_CAT
qDebug () << "DXLabSuiteCommanderTransceiver::do_frequency:" << f << state (); qDebug () << "DXLabSuiteCommanderTransceiver::do_frequency:" << f << state ();
#endif #endif
// number is localised auto f_string = frequency_to_string (f);
// avoid floating point translation errors by adding a small number (0.1Hz) if (UNK != m)
simple_command ("<command:10>CmdSetFreq<parameters:23><xcvrfreq:10>" + QString ("%L1").arg (f / 1e3 + 1e-4, 10, 'f', 3).toLocal8Bit ()); {
auto m_string = map_mode (m);
auto params = ("<xcvrfreq:%1>" + f_string + "<xcvrmode:%2>" + m_string + "<preservesplitanddual:1>Y").arg (f_string.size ()).arg (m_string.size ());
simple_command (("<command:14>CmdSetFreqMode<parameters:%1>" + params).arg (params.size ()));
update_mode (m);
}
else
{
auto params = ("<xcvrfreq:%1>" + f_string).arg (f_string.size ());
simple_command (("<command:10>CmdSetFreq<parameters:%1>" + params).arg (params.size ()));
}
update_rx_frequency (f); update_rx_frequency (f);
} }
@ -134,50 +143,30 @@ void DXLabSuiteCommanderTransceiver::do_tx_frequency (Frequency tx, bool /* rati
if (tx) if (tx)
{ {
simple_command ("<command:8>CmdSplit<parameters:7><1:2>on"); auto f_string = frequency_to_string (tx);
auto params = ("<xcvrfreq:%1>" + f_string + "<SuppressDual:1>Y").arg (f_string.size ());
// number is localised simple_command (("<command:11>CmdQSXSplit<parameters:%1>" + params).arg (params.size ()));
// 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 ("<command:12>CmdSetTxFreq<parameters:23><xcvrfreq:10>" + QString ("%L1").arg (tx / 1e3 + 1e-4, 10, 'f', 3).toLocal8Bit ());
// set split again because on some rigs CmdSetTxFreq clears
// split mode
simple_command ("<command:8>CmdSplit<parameters:7><1:2>on");
update_split (true);
} }
else else
{ {
simple_command ("<command:8>CmdSplit<parameters:8><1:3>off"); simple_command ("<command:8>CmdSplit<parameters:8><1:3>off");
} }
update_split (tx);
update_other_frequency (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 #if WSJT_TRACE_CAT
qDebug () << "DXLabSuiteCommanderTransceiver::do_mode:" << mode << state (); qDebug () << "DXLabSuiteCommanderTransceiver::do_mode:" << m << state ();
#endif #endif
auto mapped = map_mode (mode); auto m_string = map_mode (m);
simple_command ((QString ("<command:10>CmdSetMode<parameters:%1><1:%2>").arg (5 + mapped.size ()).arg (mapped.size ()) + mapped).toLocal8Bit ()); auto params = ("<1:%1>" + m_string).arg (m_string.size ());
if (state ().split ()) simple_command (("<command:10>CmdSetMode<parameters:%1>" + params).arg (params.size ()));
{
// this toggle ensures that the TX VFO mode is the same as the RX VFO
simple_command ("<command:8>CmdSplit<parameters:8><1:3>off");
simple_command ("<command:8>CmdSplit<parameters:7><1:2>on");
}
do_frequency (state ().frequency ()); // gets Commander synchronized update_mode (m);
// setting TX frequency rationalises the mode on Icoms so get current and set
poll ();
} }
void DXLabSuiteCommanderTransceiver::poll () void DXLabSuiteCommanderTransceiver::poll ()
@ -191,14 +180,14 @@ void DXLabSuiteCommanderTransceiver::poll ()
auto reply = command_with_reply ("<command:10>CmdGetFreq<parameters:0>", quiet); auto reply = command_with_reply ("<command:10>CmdGetFreq<parameters:0>", quiet);
if (0 == reply.indexOf ("<CmdFreq:")) if (0 == reply.indexOf ("<CmdFreq:"))
{ {
// remove thousands separator and DP - relies of n.nnn kHz auto f = string_to_frequency (reply.mid (reply.indexOf ('>') + 1));
// format so we can do uint conversion if (f)
reply = reply.mid (reply.indexOf ('>') + 1).replace (",", "").replace (".", "");
if (!state ().ptt ()) // Commander is not reliable on frequency
// polls while transmitting
{ {
update_rx_frequency (reply.toUInt ()); if (!state ().ptt ()) // Commander is not reliable on frequency
// polls while transmitting
{
update_rx_frequency (f);
}
} }
} }
else else
@ -215,11 +204,14 @@ void DXLabSuiteCommanderTransceiver::poll ()
reply = command_with_reply ("<command:12>CmdGetTXFreq<parameters:0>", quiet); reply = command_with_reply ("<command:12>CmdGetTXFreq<parameters:0>", quiet);
if (0 == reply.indexOf ("<CmdTXFreq:")) if (0 == reply.indexOf ("<CmdTXFreq:"))
{ {
// remove thousands separator and DP - relies of n.nnn kHz format so we ca do uint conversion auto f = string_to_frequency (reply.mid (reply.indexOf ('>') + 1));
auto text = reply.mid (reply.indexOf ('>') + 1).replace (",", "").replace (".", ""); if (f)
if ("000" != text)
{ {
update_other_frequency (text.toUInt ()); if (!state ().ptt ()) // Commander is not reliable on frequency
// polls while transmitting
{
update_other_frequency (f);
}
} }
} }
else else
@ -327,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_); Q_ASSERT (commander_);
@ -348,7 +340,7 @@ 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_); Q_ASSERT (commander_);
@ -360,7 +352,7 @@ QByteArray DXLabSuiteCommanderTransceiver::command_with_reply (QByteArray const&
throw error { throw error {
tr ("DX Lab Suite Commander failed to send command \"%1\": %2\n") tr ("DX Lab Suite Commander failed to send command \"%1\": %2\n")
.arg (cmd.constData ()) .arg (cmd)
.arg (commander_->errorString ()) .arg (commander_->errorString ())
}; };
} }
@ -380,7 +372,7 @@ QByteArray DXLabSuiteCommanderTransceiver::command_with_reply (QByteArray const&
throw error { throw error {
tr ("DX Lab Suite Commander send command \"%1\" read reply failed: %2\n") tr ("DX Lab Suite Commander send command \"%1\" read reply failed: %2\n")
.arg (cmd.constData ()) .arg (cmd)
.arg (commander_->errorString ()) .arg (commander_->errorString ())
}; };
} }
@ -394,11 +386,16 @@ QByteArray DXLabSuiteCommanderTransceiver::command_with_reply (QByteArray const&
throw error { throw error {
tr ("DX Lab Suite Commander retries exhausted sending command \"%1\"") tr ("DX Lab Suite Commander retries exhausted sending command \"%1\"")
.arg (cmd.constData ()) .arg (cmd)
}; };
} }
auto result = commander_->readAll (); auto result = commander_->readAll ();
// qDebug () << "result: " << result;
// for (int i = 0; i < result.size (); ++i)
// {
// qDebug () << i << ":" << hex << int (result[i]);
// }
if (!no_debug) if (!no_debug)
{ {
@ -407,11 +404,12 @@ QByteArray DXLabSuiteCommanderTransceiver::command_with_reply (QByteArray const&
#endif #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 to_send = data.constData ();
auto length = data.size (); auto length = data.size ();
@ -428,3 +426,31 @@ bool DXLabSuiteCommanderTransceiver::write_to_port (QByteArray const& data)
} }
return true; 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;
}

View File

@ -8,6 +8,7 @@
class QTcpSocket; class QTcpSocket;
class QByteArray; class QByteArray;
class QString;
// //
// DX Lab Suite Commander Interface // DX Lab Suite Commander Interface
@ -32,7 +33,7 @@ public:
protected: protected:
void do_start () override; void do_start () override;
void do_stop () 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_tx_frequency (Frequency, bool rationalise_mode) override;
void do_mode (MODE, bool rationalise) override; void do_mode (MODE, bool rationalise) override;
void do_ptt (bool on) override; void do_ptt (bool on) override;
@ -40,14 +41,17 @@ protected:
void poll () override; void poll () override;
private: private:
void simple_command (QByteArray const&, bool no_debug = false); void simple_command (QString const&, bool no_debug = false);
QByteArray command_with_reply (QByteArray const&, bool no_debug = false); QString command_with_reply (QString const&, bool no_debug = false);
bool write_to_port (QByteArray const&); bool write_to_port (QString const&);
QString frequency_to_string (Frequency) const;
Frequency string_to_frequency (QString) const;
std::unique_ptr<TransceiverBase> wrapped_; std::unique_ptr<TransceiverBase> wrapped_;
bool use_for_ptt_; bool use_for_ptt_;
QString server_; QString server_;
QTcpSocket * commander_; QTcpSocket * commander_;
QLocale locale_;
}; };
#endif #endif

View File

@ -20,17 +20,17 @@ void EmulateSplitTransceiver::start () noexcept
wrapped_->tx_frequency (0, false); wrapped_->tx_frequency (0, false);
} }
void EmulateSplitTransceiver::frequency (Frequency rx) noexcept void EmulateSplitTransceiver::frequency (Frequency rx, MODE m) noexcept
{ {
#if WSJT_TRACE_CAT #if WSJT_TRACE_CAT
qDebug () << "EmulateSplitTransceiver::frequency:" << rx; qDebug () << "EmulateSplitTransceiver::frequency:" << rx << "mode:" << m;
#endif #endif
// Save frequency parameters. // Save frequency parameters.
frequency_[0] = rx; frequency_[0] = rx;
// Set active frequency. // Set active frequency.
wrapped_->frequency (rx); wrapped_->frequency (rx, m);
} }
void EmulateSplitTransceiver::tx_frequency (Frequency tx, bool /* rationalise_mode */) noexcept void EmulateSplitTransceiver::tx_frequency (Frequency tx, bool /* rationalise_mode */) noexcept

View File

@ -32,7 +32,7 @@ public:
explicit EmulateSplitTransceiver (std::unique_ptr<Transceiver> wrapped); explicit EmulateSplitTransceiver (std::unique_ptr<Transceiver> wrapped);
void start () noexcept override; 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 tx_frequency (Frequency, bool rationalise_mode) noexcept override;
void ptt (bool on) noexcept override; void ptt (bool on) noexcept override;

View File

@ -500,12 +500,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 #if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::do_frequency:" << f << "reversed:" << reversed_; qDebug () << "HRDTransceiver::do_frequency:" << f << "reversed:" << reversed_;
#endif #endif
if (UNK != m)
{
do_mode (m, false);
}
auto fo_string = QString::number (f); auto fo_string = QString::number (f);
if (vfo_count_ > 1 && reversed_) if (vfo_count_ > 1 && reversed_)
{ {

View File

@ -42,9 +42,9 @@ protected:
// Implement the TransceiverBase interface. // Implement the TransceiverBase interface.
void do_start () override; void do_start () override;
void do_stop () 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_tx_frequency (Frequency, bool rationalise_mode = true) override;
void do_mode (MODE, bool rationalise) override; void do_mode (MODE, bool rationalise = true) override;
void do_ptt (bool on) override; void do_ptt (bool on) override;
// Implement the PollingTransceiver interface. // Implement the PollingTransceiver interface.

View File

@ -470,12 +470,17 @@ auto HamlibTransceiver::get_vfos () const -> std::tuple<vfo_t, vfo_t>
return std::make_tuple (rx_vfo, tx_vfo); 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 #if WSJT_TRACE_CAT
qDebug () << "HamlibTransceiver::do_frequency:" << f << "reversed:" << reversed_; qDebug () << "HamlibTransceiver::do_frequency:" << f << "mode:" << m << "reversed:" << reversed_;
#endif #endif
if (UNK != m)
{
do_mode (m, false);
}
if (!is_dummy_) if (!is_dummy_)
{ {
error_check (rig_set_freq (rig_.data (), RIG_VFO_CURR, f), tr ("setting frequency")); error_check (rig_set_freq (rig_.data (), RIG_VFO_CURR, f), tr ("setting frequency"));

View File

@ -43,9 +43,9 @@ class HamlibTransceiver final
private: private:
void do_start () override; void do_start () override;
void do_stop () 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_tx_frequency (Frequency, bool rationalise_mode = true) override;
void do_mode (MODE, bool rationalise) override; void do_mode (MODE, bool rationalise = true) override;
void do_ptt (bool) override; void do_ptt (bool) override;
void poll () override; void poll () override;

View File

@ -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 #if WSJT_TRACE_CAT
qDebug () << "OmniRigTransceiver::do_frequency:" << f << state (); qDebug () << "OmniRigTransceiver::do_frequency:" << f << state ();
#endif #endif
if (UNK != m)
{
do_mode (m, false);
}
if (OmniRig::PM_FREQ & writable_params_) if (OmniRig::PM_FREQ & writable_params_)
{ {
rig_->SetFreq (f); rig_->SetFreq (f);

View File

@ -35,7 +35,7 @@ public:
void do_start () override; void do_start () override;
void do_stop () 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_tx_frequency (Frequency, bool rationalise_mode) override;
void do_mode (MODE, bool rationalise) override; void do_mode (MODE, bool rationalise) override;
void do_ptt (bool on) override; void do_ptt (bool on) override;

View File

@ -106,17 +106,18 @@ void PollingTransceiver::do_post_stop ()
m_->stop_timer (); 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 // update expected state with new frequency and set poll count
m_->next_state_.frequency (f); m_->next_state_.frequency (f);
m_->next_state_.mode (m);
m_->retries_ = polls_to_stabilize; 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) 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) if (m_->next_state_.mode () != m)
{ {

View File

@ -41,7 +41,7 @@ public:
~PollingTransceiver (); ~PollingTransceiver ();
protected: 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 // Sub-classes implement this and fetch what they can from the rig
// in a non-intrusive manner. // in a non-intrusive manner.
@ -49,9 +49,9 @@ protected:
void do_post_start () override final; void do_post_start () override final;
void do_post_stop () override final; void do_post_stop () override final;
void do_post_frequency (Frequency) override final; void do_post_frequency (Frequency, MODE = UNK) override final;
void do_post_tx_frequency (Frequency) override final; void do_post_tx_frequency (Frequency, bool rationalize = true) override final;
void do_post_mode (MODE) override final; void do_post_mode (MODE, bool rationalize = true) override final;
bool do_pre_update () override final; bool do_pre_update () override final;
private: private:

View File

@ -126,7 +126,7 @@ public:
Q_SIGNAL void finished () const; Q_SIGNAL void finished () const;
// Set frequency in Hertz. // 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 // Setting a non-zero TX frequency means split operation, the value
// zero means simplex operation. // zero means simplex operation.

View File

@ -102,15 +102,15 @@ void TransceiverBase::stop () noexcept
} }
} }
void TransceiverBase::frequency (Frequency f) noexcept void TransceiverBase::frequency (Frequency f, MODE m) noexcept
{ {
QString message; QString message;
try try
{ {
if (m_->state_.online ()) if (m_->state_.online ())
{ {
do_frequency (f); do_frequency (f, m);
do_post_frequency (f); do_post_frequency (f, m);
} }
} }
catch (std::exception const& e) catch (std::exception const& e)
@ -135,7 +135,7 @@ void TransceiverBase::tx_frequency (Frequency tx, bool rationalise_mode) noexcep
if (m_->state_.online ()) if (m_->state_.online ())
{ {
do_tx_frequency (tx, rationalise_mode); do_tx_frequency (tx, rationalise_mode);
do_post_tx_frequency (tx); do_post_tx_frequency (tx, rationalise_mode);
} }
} }
catch (std::exception const& e) catch (std::exception const& e)
@ -160,7 +160,7 @@ void TransceiverBase::mode (MODE m, bool rationalise) noexcept
if (m_->state_.online ()) if (m_->state_.online ())
{ {
do_mode (m, rationalise); do_mode (m, rationalise);
do_post_mode (m); do_post_mode (m, rationalise);
} }
} }
catch (std::exception const& e) catch (std::exception const& e)

View File

@ -71,7 +71,7 @@ public:
// //
void start () noexcept override final; void start () noexcept override final;
void stop () 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 tx_frequency (Frequency tx, bool rationalise_mode) noexcept override final;
void mode (MODE, bool rationalise) noexcept override final; void mode (MODE, bool rationalise) noexcept override final;
void ptt (bool) noexcept override final; void ptt (bool) noexcept override final;
@ -97,17 +97,17 @@ protected:
virtual void do_stop () = 0; virtual void do_stop () = 0;
virtual void do_post_stop () {} virtual void do_post_stop () {}
virtual void do_frequency (Frequency rx) = 0; virtual void do_frequency (Frequency rx, MODE = UNK) = 0;
virtual void do_post_frequency (Frequency) {} virtual void do_post_frequency (Frequency, MODE = UNK) {}
virtual void do_tx_frequency (Frequency tx = 0, bool rationalise_mode = true) = 0; 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_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_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; virtual void do_sync (bool force_signal = false) = 0;

Binary file not shown.

View File

@ -422,8 +422,7 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
ui->labDialFreq->setStyleSheet("QLabel { background-color : black; color : yellow; }"); ui->labDialFreq->setStyleSheet("QLabel { background-color : black; color : yellow; }");
m_config.transceiver_online (true); m_config.transceiver_online (true);
qsy (m_lastMonitoredFrequency); on_monitorButton_clicked (!m_config.monitor_off_at_startup ());
monitor (!m_config.monitor_off_at_startup ());
#if !WSJT_ENABLE_EXPERIMENTAL_FEATURES #if !WSJT_ENABLE_EXPERIMENTAL_FEATURES
ui->actionJT9W_1->setEnabled (false); ui->actionJT9W_1->setEnabled (false);
@ -666,12 +665,13 @@ void MainWindow::on_monitorButton_clicked (bool checked)
auto prior = m_monitoring; auto prior = m_monitoring;
monitor (checked); monitor (checked);
if (!prior) if (checked && !prior)
{ {
m_diskData = false; // no longer reading WAV files m_diskData = false; // no longer reading WAV files
// put rig back where it was when last in control // put rig back where it was when last in control
Q_EMIT m_config.transceiver_frequency (m_lastMonitoredFrequency); Q_EMIT m_config.transceiver_frequency (m_lastMonitoredFrequency);
qsy (m_lastMonitoredFrequency);
setXIT (ui->TxFreqSpinBox->value ()); setXIT (ui->TxFreqSpinBox->value ());
} }
@ -2857,10 +2857,7 @@ void MainWindow::handle_transceiver_failure (QString reason)
{ {
ui->readFreq->setStyleSheet("QPushButton{background-color: red;" ui->readFreq->setStyleSheet("QPushButton{background-color: red;"
"border-width: 0px; border-radius: 5px;}"); "border-width: 0px; border-radius: 5px;}");
on_stopTxButton_clicked ();
m_btxok=false;
m_repeatMsg=0;
rigFailure ("Rig Control Error", reason); rigFailure ("Rig Control Error", reason);
} }