mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-25 05:38:46 -05:00
424ed88645
V12.2.6 of teh DX Lab Suite Commander finally has a way to suppress mode rationalization when setting the split Tx frequency. This now means that we can now honor the radio setting to not change the rig modulation mode. This should help with a number of rigs that require different modes on teh Tx and Rx VFOs for optimal wide band digital operation. This will also help with some rig and interface combinations that lock up or otherwise misbehave when setting the Tx VFO mode at certain times with respect to other rig control commands. This change also improves mode setting in general hopefully closing a few corner case issues when starting up and when transmitting for the first time in a session. Included is the latest DX Lab Suite Commander TCP/IP commands documentation correct for v12.2.6. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7030 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
272 lines
6.4 KiB
C++
272 lines
6.4 KiB
C++
#include "TransceiverBase.hpp"
|
|
|
|
#include <exception>
|
|
|
|
#include <QString>
|
|
#include <QTimer>
|
|
#include <QThread>
|
|
#include <QDebug>
|
|
|
|
#include "moc_TransceiverBase.cpp"
|
|
|
|
namespace
|
|
{
|
|
auto const unexpected = TransceiverBase::tr ("Unexpected rig error");
|
|
}
|
|
|
|
void TransceiverBase::start (unsigned sequence_number) noexcept
|
|
{
|
|
QString message;
|
|
try
|
|
{
|
|
may_update u {this, true};
|
|
shutdown ();
|
|
startup ();
|
|
last_sequence_number_ = sequence_number;
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
message = e.what ();
|
|
}
|
|
catch (...)
|
|
{
|
|
message = unexpected;
|
|
}
|
|
if (!message.isEmpty ())
|
|
{
|
|
offline (message);
|
|
}
|
|
}
|
|
|
|
void TransceiverBase::set (TransceiverState const& s,
|
|
unsigned sequence_number) noexcept
|
|
{
|
|
TRACE_CAT ("TransceiverBase", "#:" << sequence_number << s);
|
|
|
|
QString message;
|
|
try
|
|
{
|
|
may_update u {this, true};
|
|
bool was_online {requested_.online ()};
|
|
if (!s.online () && was_online)
|
|
{
|
|
shutdown ();
|
|
}
|
|
else if (s.online () && !was_online)
|
|
{
|
|
shutdown ();
|
|
startup ();
|
|
}
|
|
if (requested_.online ())
|
|
{
|
|
bool ptt_on {false};
|
|
bool ptt_off {false};
|
|
if (s.ptt () != requested_.ptt ())
|
|
{
|
|
ptt_on = s.ptt ();
|
|
ptt_off = !s.ptt ();
|
|
}
|
|
if (ptt_off)
|
|
{
|
|
do_ptt (false);
|
|
do_post_ptt (false);
|
|
QThread::msleep (100); // some rigs cannot process CAT
|
|
// commands while switching from
|
|
// Tx to Rx
|
|
}
|
|
if (s.frequency () // ignore bogus zero frequencies
|
|
&& ((s.frequency () != requested_.frequency () // and QSY
|
|
|| (s.mode () != UNK && s.mode () != requested_.mode ())) // or mode change
|
|
|| ptt_off)) // or just returned to rx
|
|
{
|
|
do_frequency (s.frequency (), s.mode (), ptt_off);
|
|
do_post_frequency (s.frequency (), s.mode ());
|
|
|
|
// record what actually changed
|
|
requested_.frequency (actual_.frequency ());
|
|
requested_.mode (actual_.mode ());
|
|
}
|
|
if (!s.tx_frequency () || s.tx_frequency () > 10000) // ignore bogus startup values
|
|
{
|
|
if ((s.tx_frequency () != requested_.tx_frequency () // and QSY
|
|
|| (s.mode () != UNK && s.mode () != requested_.mode ())) // or mode change
|
|
// || s.split () != requested_.split ())) // or split change
|
|
|| (s.tx_frequency () && ptt_on)) // or about to tx split
|
|
{
|
|
do_tx_frequency (s.tx_frequency (), s.mode (), ptt_on);
|
|
do_post_tx_frequency (s.tx_frequency (), s.mode ());
|
|
|
|
// record what actually changed
|
|
requested_.tx_frequency (actual_.tx_frequency ());
|
|
requested_.split (actual_.split ());
|
|
}
|
|
}
|
|
if (ptt_on)
|
|
{
|
|
do_ptt (true);
|
|
do_post_ptt (true);
|
|
QThread::msleep (100); // some rigs cannot process CAT
|
|
// commands while switching from
|
|
// Rx to Tx
|
|
}
|
|
|
|
// record what actually changed
|
|
requested_.ptt (actual_.ptt ());
|
|
}
|
|
last_sequence_number_ = sequence_number;
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
message = e.what ();
|
|
}
|
|
catch (...)
|
|
{
|
|
message = unexpected;
|
|
}
|
|
if (!message.isEmpty ())
|
|
{
|
|
offline (message);
|
|
}
|
|
}
|
|
|
|
void TransceiverBase::startup ()
|
|
{
|
|
Q_EMIT resolution (do_start ());
|
|
do_post_start ();
|
|
actual_.online (true);
|
|
requested_.online (true);
|
|
}
|
|
|
|
void TransceiverBase::shutdown ()
|
|
{
|
|
may_update u {this};
|
|
if (requested_.online ())
|
|
{
|
|
try
|
|
{
|
|
// try and ensure PTT isn't left set
|
|
do_ptt (false);
|
|
do_post_ptt (false);
|
|
if (requested_.split ())
|
|
{
|
|
// try and reset split mode
|
|
do_tx_frequency (0, UNK, true);
|
|
do_post_tx_frequency (0, UNK);
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
// don't care about exceptions
|
|
}
|
|
}
|
|
do_stop ();
|
|
do_post_stop ();
|
|
actual_.online (false);
|
|
requested_.online (false);
|
|
}
|
|
|
|
void TransceiverBase::stop () noexcept
|
|
{
|
|
QString message;
|
|
try
|
|
{
|
|
shutdown ();
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
message = e.what ();
|
|
}
|
|
catch (...)
|
|
{
|
|
message = unexpected;
|
|
}
|
|
if (!message.isEmpty ())
|
|
{
|
|
offline (message);
|
|
}
|
|
else
|
|
{
|
|
Q_EMIT finished ();
|
|
}
|
|
}
|
|
|
|
void TransceiverBase::update_rx_frequency (Frequency rx)
|
|
{
|
|
actual_.frequency (rx);
|
|
requested_.frequency (rx); // track rig changes
|
|
}
|
|
|
|
void TransceiverBase::update_other_frequency (Frequency tx)
|
|
{
|
|
actual_.tx_frequency (tx);
|
|
}
|
|
|
|
void TransceiverBase::update_split (bool state)
|
|
{
|
|
actual_.split (state);
|
|
}
|
|
|
|
void TransceiverBase::update_mode (MODE m)
|
|
{
|
|
actual_.mode (m);
|
|
}
|
|
|
|
void TransceiverBase::update_PTT (bool state)
|
|
{
|
|
actual_.ptt (state);
|
|
}
|
|
|
|
bool TransceiverBase::maybe_low_resolution (Radio::Frequency low_res,
|
|
Radio::Frequency high_res)
|
|
{
|
|
if (resolution_ != Resolution::truncate
|
|
&& low_res == (high_res + 5) / 10 * 10) // rounded to 10's
|
|
{
|
|
resolution_ = Resolution::round;
|
|
return true;
|
|
}
|
|
if (resolution_ != Resolution::round
|
|
&& low_res == high_res / 10 * 10) // truncated to 10's
|
|
{
|
|
resolution_ = Resolution::truncate;
|
|
return true;
|
|
}
|
|
|
|
if (resolution_ != Resolution::truncate
|
|
&& low_res == (high_res + 50) / 100 * 100) // rounded to 100's
|
|
{
|
|
resolution_ = Resolution::round;
|
|
return true;
|
|
}
|
|
if (resolution_ != Resolution::round
|
|
&& low_res == high_res / 100 * 100) // truncated to 100's
|
|
{
|
|
resolution_ = Resolution::truncate;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void TransceiverBase::update_complete (bool force_signal)
|
|
{
|
|
if ((do_pre_update () && actual_ != last_) || force_signal)
|
|
{
|
|
Q_EMIT update (actual_, last_sequence_number_);
|
|
last_ = actual_;
|
|
}
|
|
}
|
|
|
|
void TransceiverBase::offline (QString const& reason)
|
|
{
|
|
Q_EMIT failure (reason);
|
|
try
|
|
{
|
|
shutdown ();
|
|
}
|
|
catch (...)
|
|
{
|
|
// don't care
|
|
}
|
|
}
|