Set split mode before and after setting Tx frequency

Also cleaned up duplicate trace output.

Using the  DX Lab  Suite Commander  CAT interface  with rigs  like the
TS-2000  requires  that  split  mode  be set  after  changing  the  Tx
frequency. This  is because  setting teh  Tx frequency  disables split
mode.

With some Icom rigs  the rig must be in split  mode before setting the
Tx frequency otherwise the Tx frequency change will not be honoured.

To fix  this the sequence set-split,  set-tx-frequency, set-split must
always be used to change the Tx frequency.

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.

Ensure split Tx frequency agrees with UI before transmitting

Ensure split works on Yaesu via Hamlib without breaking others

Also improved class HamlibTransceiver debug trace messages.

Merged r4776-r4779 from wsjtx-1.4 branch.



git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@4780 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2014-12-06 20:23:29 +00:00
parent d41bbee263
commit 4300b45e6a
18 changed files with 254 additions and 165 deletions

View File

@ -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<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_.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<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.
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<TransceiverFactory::SplitMode> (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
{

View File

@ -2,6 +2,7 @@
#include <QTcpSocket>
#include <QRegularExpression>
#include <QLocale>
#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 ("<command:10>CmdSetFreq<parameters:23><xcvrfreq:10>" + 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 = ("<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);
}
@ -134,46 +143,30 @@ void DXLabSuiteCommanderTransceiver::do_tx_frequency (Frequency tx, bool /* rati
if (tx)
{
simple_command ("<command:8>CmdSplit<parameters:7><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 ("<command:12>CmdSetTxFreq<parameters:23><xcvrfreq:10>" + QString ("%L1").arg (tx / 1e3 + 1e-4, 10, 'f', 3).toLocal8Bit ());
auto f_string = frequency_to_string (tx);
auto params = ("<xcvrfreq:%1>" + f_string + "<SuppressDual:1>Y").arg (f_string.size ());
simple_command (("<command:11>CmdQSXSplit<parameters:%1>" + params).arg (params.size ()));
}
else
{
simple_command ("<command:8>CmdSplit<parameters:8><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 ("<command:10>CmdSetMode<parameters:%1><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 ("<command:8>CmdSplit<parameters:8><1:3>off");
simple_command ("<command:8>CmdSplit<parameters:7><1:2>on");
}
simple_command (("<command:10>CmdSetMode<parameters:%1>" + 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 ("<command:10>CmdGetFreq<parameters:0>", quiet);
if (0 == reply.indexOf ("<CmdFreq:"))
{
// remove thousands separator and DP - relies of n.nnn kHz
// format so we can do uint conversion
reply = reply.mid (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 ("<command:12>CmdGetTXFreq<parameters:0>", quiet);
if (0 == reply.indexOf ("<CmdTXFreq:"))
{
// remove thousands separator and DP - relies of n.nnn kHz format so we ca do uint conversion
auto text = reply.mid (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;
}

View File

@ -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<TransceiverBase> wrapped_;
bool use_for_ptt_;
QString server_;
QTcpSocket * commander_;
QLocale locale_;
};
#endif

View File

@ -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

View File

@ -32,7 +32,7 @@ public:
explicit EmulateSplitTransceiver (std::unique_ptr<Transceiver> 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;

View File

@ -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_)
{

View File

@ -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.

View File

@ -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, vfo_t>
{
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<vfo_t, vfo_t>
}
#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, &current_mode, &current_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, &current_mode, &current_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, &current_mode, &current_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

View File

@ -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;

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

View File

@ -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;

View File

@ -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)
{

View File

@ -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:

View File

@ -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.

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;
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)

View File

@ -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;

Binary file not shown.

View File

@ -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);
}