flrig-1.3.49/ 0000775 0001750 0001750 00000000000 13606710477 007731 5 0000000 0000000 flrig-1.3.49/src/ 0000775 0001750 0001750 00000000000 13606710477 010520 5 0000000 0000000 flrig-1.3.49/src/support/ 0000775 0001750 0001750 00000000000 13606710477 012234 5 0000000 0000000 flrig-1.3.49/src/support/ptt.cxx 0000644 0001750 0001750 00000004111 13605621006 013466 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "threads.h"
#include "ptt.h"
#include "debug.h"
#include "rig_io.h"
#include "rig.h"
#include "support.h"
using namespace std;
// used for transceivers with a single vfo, called only by rigPTT
static XCVR_STATE fake_vfo;
static void showfreq(void *)
{
FreqDispA->value(vfoA.freq);
}
static void fake_split(int on)
{
if (on) {
fake_vfo = vfoA;
vfoA.freq = vfoB.freq;
selrig->set_vfoA(vfoA.freq);
Fl::awake(showfreq);
} else {
vfoA = fake_vfo;
selrig->set_vfoA(vfoA.freq);
Fl::awake(showfreq);
}
}
// add fake rit to this function and to set_vfoA ??
void rigPTT(bool on)
{
if (on && progStatus.split && !selrig->can_split())
fake_split(on);
if (progStatus.comm_catptt) {
selrig->set_PTT_control(on);
} else if (progStatus.comm_dtrptt || progStatus.comm_rtsptt)
RigSerial->SetPTT(on);
else if (SepSerial->IsOpen() && (progStatus.sep_dtrptt || progStatus.sep_rtsptt) )
SepSerial->SetPTT(on);
else
LOG_ERROR("No PTT i/o connected");
if (!on && progStatus.split && !selrig->can_split())
fake_split(on);
}
flrig-1.3.49/src/support/socket_io.cxx 0000644 0001750 0001750 00000017156 13605621006 014653 0000000 0000000 // socket_io.cxx
//
// Author: Dave Freese, W1HKJ
// Stelios Bounanos, M0GLD
//
// ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "config.h"
#include "status.h"
#include "debug.h"
#include "util.h"
#include "gettext.h"
#include "rigpanel.h"
#include "socket_io.h"
#include "socket.h"
#include
#include
#include
#ifdef WIN32
# include
#else
# include
#endif
using namespace std;
Socket *tcpip = (Socket *)0;
Address *remote_addr = (Address *)0;
static bool exit_socket_loop = false;
static string rxbuffer;
pthread_t *rcv_socket_thread = 0;
pthread_mutex_t mutex_rcv_socket = PTHREAD_MUTEX_INITIALIZER;
static void log_level(int level, string s, string data)
{
time_t now;
time(&now);
struct tm *local = localtime(&now);
char sztm[20];
strftime(sztm, sizeof(sztm), "%H:%M:%S", local);
string s1;
s1 = selrig->data_type == BINARY ? str2hex(data.c_str(), data.length()) : data;
if (selrig->data_type == STRING) {
s1 = data;
size_t p;
while((p = s1.find('\r')) != string::npos)
s1.replace(p, 1, "");
while((p = s1.find('\n')) != string::npos)
s1.replace(p, 1, "");
} else
s1 = str2hex(data.c_str(), data.length());
switch (level) {
case QUIET:
LOG_QUIET("%s: %s : %s", sztm, s.c_str(), s1.c_str());
break;
case ERR:
LOG_ERROR("%s: %s : %s", sztm, s.c_str(), s1.c_str());
break;
case WARN:
LOG_WARN("%s: %s : %s", sztm, s.c_str(), s1.c_str());
break;
case INFO:
LOG_INFO("%s: %s : %s", sztm, s.c_str(), s1.c_str());
break;
default:
LOG_DEBUG("%s: %s : %s", sztm, s.c_str(), s1.c_str());
}
}
void *rcv_socket_loop(void *)
{
for (;;) {
MilliSleep(50);
{ guard_lock socket_lock(&mutex_rcv_socket);
if (exit_socket_loop) break;
if (tcpip && tcpip->fd() != -1) {
try {
tcpip->recv(rxbuffer);
box_tcpip_connect->color(FL_GREEN);
box_tcpip_connect->redraw();
box_xcvr_connect->color(FL_GREEN);
box_xcvr_connect->redraw();
tcpip_menu_box->color(FL_GREEN);
tcpip_menu_box->redraw();
} catch (const SocketException& e) {
LOG_ERROR("Error %d, %s", e.error(), e.what());
box_tcpip_connect->color(FL_YELLOW);
box_tcpip_connect->redraw();
box_xcvr_connect->color(FL_YELLOW);
box_xcvr_connect->redraw();
tcpip_menu_box->color(FL_YELLOW);
tcpip_menu_box->redraw();
}
}
} // end guard_lock
}
exit_socket_loop = false;
return NULL;
}
void connect_to_remote()
{
try {
if (remote_addr) delete remote_addr;
remote_addr = new Address(progStatus.tcpip_addr.c_str(), progStatus.tcpip_port.c_str());
LOG_QUIET("Created new remote_addr @ %p", remote_addr);
if (!tcpip) {
guard_lock socket_lock(&mutex_rcv_socket);
tcpip = new Socket(*remote_addr);
LOG_QUIET("Created new socket @ %p", tcpip);
tcpip->set_timeout(0.001);
tcpip->connect();
tcpip->set_nonblocking(true);
LOG_QUIET("Connected to %d", tcpip->fd());
tcpip_box->show();
box_tcpip_connect->color(FL_GREEN);
box_tcpip_connect->redraw();
box_xcvr_connect->color(FL_GREEN);
box_xcvr_connect->redraw();
tcpip_menu_box->color(FL_GREEN);
tcpip_menu_box->redraw();
}
if (tcpip->fd() == -1) {
guard_lock socket_lock(&mutex_rcv_socket);
try {
tcpip->connect(*remote_addr);
tcpip->set_nonblocking(true);
LOG_QUIET("Connected to %d", tcpip->fd());
tcpip_box->show();
box_tcpip_connect->color(FL_GREEN);
box_tcpip_connect->redraw();
box_xcvr_connect->color(FL_GREEN);
box_xcvr_connect->redraw();
tcpip_menu_box->color(FL_GREEN);
tcpip_menu_box->redraw();
} catch (const SocketException & e) {
LOG_ERROR("Error: %d, %s", e.error(), e.what());
delete remote_addr;
remote_addr = 0;
delete tcpip;
tcpip = 0;
box_tcpip_connect->color(FL_LIGHT1);
box_tcpip_connect->redraw();
box_xcvr_connect->color(FL_LIGHT1);
box_xcvr_connect->redraw();
tcpip_menu_box->color(FL_LIGHT1);
tcpip_menu_box->redraw();
throw e;
}
}
if (!rcv_socket_thread) {
rcv_socket_thread = new pthread_t;
if (pthread_create(rcv_socket_thread, NULL, rcv_socket_loop, NULL)) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
LOG_QUIET("%s", "Socket receive thread started");
}
}
catch (const SocketException& e) {
LOG_ERROR("Error: %d, %s", e.error(), e.what());
delete remote_addr;
remote_addr = 0;
LOG_ERROR("Deleted remote address");
delete tcpip;
tcpip = 0;
LOG_ERROR("Deleted tcpip socket");
throw e;
}
return;
}
void disconnect_from_remote()
{
if (!tcpip || tcpip->fd() == -1) return;
{
guard_lock socket_lock(&mutex_rcv_socket);
tcpip->close();
delete tcpip;
tcpip = 0;
LOG_QUIET("%s", "Deleted tcpip socket instance");
delete remote_addr;
remote_addr = 0;
LOG_QUIET("%s", "Deleted socket address instance");
exit_socket_loop = true;
}
pthread_join(*rcv_socket_thread, NULL);
rcv_socket_thread = NULL;
LOG_QUIET("%s", "Exited from socket read thread");
box_tcpip_connect->color(FL_LIGHT1);
box_tcpip_connect->redraw();
box_xcvr_connect->color(FL_LIGHT1);
box_xcvr_connect->redraw();
tcpip_menu_box->color(FL_LIGHT1);
tcpip_menu_box->redraw();
}
int retry_after = 0;
int drop_count = 0;
void send_to_remote(string cmd_string, int pace)
{
if (retry_after > 0) {
retry_after -= progStatus.serloop_timing;
if (retry_after < 0) retry_after = 0;
return;
}
if (!tcpip || tcpip->fd() == -1) {
try {
connect_to_remote();
} catch (...) {
LOG_QUIET("Retry connect in %d seconds", progStatus.tcpip_reconnect_after);
retry_after = 1000 * progStatus.tcpip_reconnect_after;
return;
}
}
try {
guard_lock send_lock(&mutex_rcv_socket);
size_t len = cmd_string.length();
for (size_t i = 0; i < len; i += 8)
tcpip->send(&cmd_string[i], len - i > 8 ? 8 : len - i);
log_level(WARN, "send to remote", cmd_string);
drop_count = 0;
} catch (const SocketException& e) {
LOG_ERROR("Error: %d, %s", e.error(), e.what());
drop_count++;
if (drop_count == progStatus.tcpip_drops_allowed) {
disconnect_from_remote();
drop_count = 0;
}
}
return;
}
int read_from_remote(string &str)
{
if (!tcpip || tcpip->fd() == -1) return 0;
guard_lock socket_lock(&mutex_rcv_socket);
str = rxbuffer;
rxbuffer.clear();
if (!str.empty())
log_level(WARN, "receive from remote", str);
else
log_level(WARN, "receive from remote", "no data");
return str.length();
}
flrig-1.3.49/src/support/dialogs.cxx 0000664 0001750 0001750 00000104331 13605621006 014310 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef __WIN32__
#include
#include
#include
#include
#include
#endif
#include "dialogs.h"
#include "rigs.h"
#include "util.h"
#include "debug.h"
#include "serial.h"
#include "support.h"
#include "rigpanel.h"
#include "rigbase.h"
#include "font_browser.h"
#include "ui.h"
#include "status.h"
#include "rig.h"
#include "socket_io.h"
#include "rigpanel.h"
#include "gettext.h"
using namespace std;
Fl_Double_Window *dlgDisplayConfig = NULL;
Fl_Double_Window *dlgXcvrConfig = NULL;
Fl_Double_Window *dlgMemoryDialog = NULL;
Fl_Double_Window *dlgControls = NULL;
Font_Browser *fntbrowser = NULL;
Fl_Color flrig_def_color(int);
//======================================================================
// test comm ports
//======================================================================
void clear_combos()
{
selectCommPort->clear();
selectAuxPort->clear();
selectSepPTTPort->clear();
selectCommPort->add("NONE");
selectAuxPort->add("NONE");
selectSepPTTPort->add("NONE");
}
void add_combos(char *port)
{
selectCommPort->add(port);
selectAuxPort->add(port);
selectSepPTTPort->add(port);
}
void set_combo_value()
{
selectCommPort->value(progStatus.xcvr_serial_port.c_str());
selectAuxPort->value(progStatus.aux_serial_port.c_str());
selectSepPTTPort->value(progStatus.sep_serial_port.c_str());
}
//======================================================================
// WIN32 init_port_combos
//======================================================================
#ifdef __WIN32__
static bool open_serial(const char* dev)
{
bool ret = false;
HANDLE fd = CreateFile(dev, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (fd != INVALID_HANDLE_VALUE) {
CloseHandle(fd);
ret = true;
}
return ret;
}
# define TTY_MAX 255
void init_port_combos()
{
clear_combos();
char ttyname[21];
const char tty_fmt[] = "//./COM%u";
for (unsigned j = 0; j < TTY_MAX; j++) {
snprintf(ttyname, sizeof(ttyname), tty_fmt, j);
if (!open_serial(ttyname))
continue;
snprintf(ttyname, sizeof(ttyname), "COM%u", j);
LOG_WARN("Found serial port %s", ttyname);
add_combos(ttyname);
}
set_combo_value();
}
#endif //__WIN32__
//======================================================================
// Linux init_port_combos
//======================================================================
#ifdef __linux__
#ifndef PATH_MAX
# define PATH_MAX 1024
#endif
# define TTY_MAX 8
void init_port_combos()
{
struct stat st;
char ttyname[PATH_MAX + 1];
bool ret = false;
DIR* sys = NULL;
char cwd[PATH_MAX] = { '.', '\0' };
clear_combos();
LOG_QUIET("%s","Search for serial ports");
glob_t gbuf;
glob("/dev/serial/by-id/*", 0, NULL, &gbuf);
for (size_t j = 0; j < gbuf.gl_pathc; j++) {
if ( !(stat(gbuf.gl_pathv[j], &st) == 0 && S_ISCHR(st.st_mode)) ||
strstr(gbuf.gl_pathv[j], "modem") )
continue;
LOG_QUIET("Found serial port %s", gbuf.gl_pathv[j]);
add_combos(gbuf.gl_pathv[j]);
}
globfree(&gbuf);
glob("/dev/tty*", 0, NULL, &gbuf);
for (size_t j = 0; j < gbuf.gl_pathc; j++) {
if ( !(stat(gbuf.gl_pathv[j], &st) == 0 && S_ISCHR(st.st_mode)) ||
strstr(gbuf.gl_pathv[j], "modem") )
continue;
std::cout << "Serial port: " << gbuf.gl_pathv[j] << std::endl;
LOG_QUIET("Found serial port %s", gbuf.gl_pathv[j]);
add_combos(gbuf.gl_pathv[j]);
}
globfree(&gbuf);
if (getcwd(cwd, sizeof(cwd)) == NULL) goto out;
if (chdir("/sys/class/tty") == -1) goto check_cuse;
if ((sys = opendir(".")) == NULL) goto check_cuse;
ssize_t len;
struct dirent* dp;
LOG_QUIET("%s", "Searching /sys/class/tty/");
while ((dp = readdir(sys))) {
# ifdef _DIRENT_HAVE_D_TYPE
if (dp->d_type != DT_LNK)
continue;
# endif
if ((len = readlink(dp->d_name, ttyname, sizeof(ttyname)-1)) == -1)
continue;
ttyname[len] = '\0';
if (!strstr(ttyname, "/devices/virtual/")) {
snprintf(ttyname, sizeof(ttyname), "/dev/%s", dp->d_name);
if (stat(ttyname, &st) == -1 || !S_ISCHR(st.st_mode))
continue;
LOG_QUIET("Found serial port %s", ttyname);
add_combos(ttyname);
ret = true;
}
}
check_cuse:
if (sys) {
closedir(sys);
sys = NULL;
}
if (chdir("/sys/class/cuse") == -1) goto out;
if ((sys = opendir(".")) == NULL) goto out;
LOG_QUIET("%s", "Searching /sys/class/cuse/");
while ((dp = readdir(sys))) {
# ifdef _DIRENT_HAVE_D_TYPE
if (dp->d_type != DT_LNK)
continue;
# endif
if ((len = readlink(dp->d_name, ttyname, sizeof(ttyname)-1)) == -1)
continue;
ttyname[len] = '\0';
if (strstr(ttyname, "/devices/virtual/") && !strncmp(dp->d_name, "mhuxd", 5)) {
char *name = strdup(dp->d_name);
if(!name)
continue;
char *p = strchr(name, '!');
if(p)
*p = '/';
snprintf(ttyname, sizeof(ttyname), "/dev/%s", name);
free(name);
if (stat(ttyname, &st) == -1 || !S_ISCHR(st.st_mode))
continue;
LOG_QUIET("Found serial port %s", ttyname);
add_combos(ttyname);
ret = true;
}
}
out:
std::string tty_virtual = HomeDir;
tty_virtual.append("vdev");
LOG_QUIET("Searching %s", tty_virtual.c_str());
tty_virtual.append("/ttyS%u");
for (unsigned j = 0; j < TTY_MAX; j++) {
snprintf(ttyname, sizeof(ttyname), tty_virtual.c_str(), j);
if ( !(stat(ttyname, &st) == 0 && S_ISCHR(st.st_mode)) )
continue;
LOG_QUIET("Found serial port %s", ttyname);
add_combos(ttyname);
}
if (sys) closedir(sys);
if (chdir(cwd) == -1) return;
if (ret) { // do we need to fall back to the probe code below?
set_combo_value();
return;
}
const char* tty_fmt[] = {
"/dev/ttyS%u",
"/dev/ttyUSB%u",
"/dev/usb/ttyUSB%u"
};
LOG_QUIET("%s", "Serial port discovery via 'stat'");
for (size_t i = 0; i < sizeof(tty_fmt)/sizeof(*tty_fmt); i++) {
for (unsigned j = 0; j < TTY_MAX; j++) {
snprintf(ttyname, sizeof(ttyname), tty_fmt[i], j);
if ( !(stat(ttyname, &st) == 0 && S_ISCHR(st.st_mode)) )
continue;
LOG_WARN("Found serial port %s", ttyname);
add_combos(ttyname);
}
}
set_combo_value();
}
#endif // __linux__
//======================================================================
// APPLE init_port_combos
//======================================================================
#ifdef __APPLE__
#ifndef PATH_MAX
# define PATH_MAX 1024
#endif
void init_port_combos()
{
clear_combos();
struct stat st;
const char* tty_fmt[] = {
// "/dev/cu.*",
"/dev/tty.*"
};
glob_t gbuf;
for (size_t i = 0; i < sizeof(tty_fmt)/sizeof(*tty_fmt); i++) {
glob(tty_fmt[i], 0, NULL, &gbuf);
for (size_t j = 0; j < gbuf.gl_pathc; j++) {
if ( !(stat(gbuf.gl_pathv[j], &st) == 0 && S_ISCHR(st.st_mode)) ||
strstr(gbuf.gl_pathv[j], "modem") )
continue;
LOG_WARN("Found serial port %s", gbuf.gl_pathv[j]);
add_combos(gbuf.gl_pathv[j]);
}
globfree(&gbuf);
}
set_combo_value();
}
#endif //__APPLE__
//======================================================================
// FreeBSD init_port_combos
//======================================================================
#ifdef __FreeBSD__
#ifndef PATH_MAX
# define PATH_MAX 1024
#endif
# define TTY_MAX 8
void init_port_combos()
{
int retval;
struct stat st;
char ttyname[PATH_MAX + 1];
const char* tty_fmt[] = {
"/dev/ttyd%u"
};
clear_combos();
for (size_t i = 0; i < sizeof(tty_fmt)/sizeof(*tty_fmt); i++) {
for (unsigned j = 0; j < TTY_MAX; j++) {
snprintf(ttyname, sizeof(ttyname), tty_fmt[i], j);
if ( !(stat(ttyname, &st) == 0 && S_ISCHR(st.st_mode)) )
continue;
LOG_WARN("Found serial port %s", ttyname);
add_combos(ttyname);
}
}
}
#endif //__FreeBSD__
void cbCIVdefault()
{
char hexstr[8];
int picked = selectRig->index();
rigbase *srig = rigs[picked];
snprintf(hexstr, sizeof(hexstr), "0x%02X", srig->defaultCIV);
txtCIV->value(hexstr);
progStatus.CIV = srig->defaultCIV;
srig->adjustCIV(progStatus.CIV);
}
void cbCIV()
{
int picked = selectRig->index();
int adr = 0;
rigbase *srig = rigs[picked];
sscanf(txtCIV->value(), "0x%2X", &adr);
progStatus.CIV = adr;
srig->adjustCIV(progStatus.CIV);
}
void cbUSBaudio()
{
progStatus.USBaudio = btnUSBaudio->value();
}
void configXcvr()
{
selectCommPort->value(progStatus.xcvr_serial_port.c_str());
selectAuxPort->value(progStatus.aux_serial_port.c_str());
selectSepPTTPort->value(progStatus.sep_serial_port.c_str());
if (selrig->CIV) {
char hexstr[8];
snprintf(hexstr, sizeof(hexstr), "0x%02X", selrig->CIV);
txtCIV->value(hexstr);
txtCIV->activate();
btnCIVdefault->activate();
if (xcvr_name == rig_IC7200.name_ ||
xcvr_name == rig_IC7300.name_ ||
xcvr_name == rig_IC7600.name_ ) {
btnUSBaudio->value(progStatus.USBaudio);
btnUSBaudio->activate();
} else
btnUSBaudio->deactivate();
} else {
txtCIV->value("");
txtCIV->deactivate();
btnCIVdefault->deactivate();
btnUSBaudio->value(0);
btnUSBaudio->deactivate();
}
select_tab(_("Xcvr"));
}
void open_poll_tab()
{
select_tab(_("Poll"));
}
void open_trace_tab()
{
select_tab(_("Trace"));
}
void open_commands_tab()
{
select_tab(_("Cmds"));
}
void open_restore_tab()
{
select_tab(_("Restore"));
}
void open_send_command_tab()
{
select_tab(_("Send"));
}
void open_tcpip_tab()
{
select_tab(_("TCPIP"));
}
void open_ptt_tab()
{
select_tab(_("PTT"));
}
void open_aux_tab()
{
select_tab(_("Aux"));
}
void createXcvrDialog()
{
dlgXcvrConfig = XcvrDialog();
init_port_combos();
mnuBaudrate->clear();
for (int i = 0; szBaudRates[i] != NULL; i++)
mnuBaudrate->add(szBaudRates[i]);
cbo_tt550_agc_level->add("slow");
cbo_tt550_agc_level->add("med");
cbo_tt550_agc_level->add("fast");
cbo_tt550_agc_level->index(progStatus.tt550_agc_level);
cbo_tt550_nb_level->add("NONE");
cbo_tt550_nb_level->add("1");
cbo_tt550_nb_level->add("2");
cbo_tt550_nb_level->add("3");
cbo_tt550_nb_level->add("4");
cbo_tt550_nb_level->add("5");
cbo_tt550_nb_level->add("6");
cbo_tt550_nb_level->add("7");
cbo_tt550_nb_level->index(progStatus.tt550_nb_level);
initRigCombo();
}
// Frequency display font / colors
Fl_Font selfont;
void cbFreqControlFontBrowser(Fl_Widget*, void*) {
selfont = fntbrowser->fontNumber();
lblTest->labelfont(selfont);
dlgDisplayConfig->redraw();
fntbrowser->hide();
}
void cbPrefFont()
{
fntbrowser->fontNumber(progStatus.fontnbr);
fntbrowser->fontFilter(Font_Browser::FIXED_WIDTH);
fntbrowser->fontFilter(Font_Browser::ALL_TYPES);
fntbrowser->callback(cbFreqControlFontBrowser);
fntbrowser->show();
}
uchar fg_red, fg_green, fg_blue;
uchar bg_red, bg_green, bg_blue;
uchar smeterRed, smeterGreen, smeterBlue;
uchar peakRed, peakGreen, peakBlue;
uchar pwrRed, pwrGreen, pwrBlue;
uchar swrRed, swrGreen, swrBlue;
Fl_Color bgclr;
Fl_Color fgclr;
Fl_Color fgsys;
static uchar fg_sys_red, fg_sys_green, fg_sys_blue;
Fl_Color bgsys;
static uchar bg_sys_red, bg_sys_green, bg_sys_blue;
Fl_Color bg2sys;
static uchar bg2_sys_red, bg2_sys_green, bg2_sys_blue;
Fl_Color bg_slider;
static uchar bg_slider_red, bg_slider_green, bg_slider_blue;
Fl_Color btn_slider;
static uchar btn_slider_red, btn_slider_green, btn_slider_blue;
Fl_Color btn_lt_color;
static uchar btn_lt_color_red, btn_lt_color_green, btn_lt_color_blue;
void cb_lighted_button()
{
uchar r = btn_lt_color_red, g = btn_lt_color_green, b = btn_lt_color_blue;
if (fl_color_chooser("Foreground color", r, g, b)) {
btn_lt_color_red = r; btn_lt_color_green = g; btn_lt_color_blue = b;
btn_lt_color = fl_rgb_color(r, g, b);
btn_lighted->selection_color(btn_lt_color);
btn_lighted->value(1);
btn_lighted->redraw();
}
}
void cb_lighted_default()
{
btn_lt_color = flrig_def_color(FL_YELLOW);
btn_lt_color_red = ((btn_lt_color >> 24) & 0xFF);
btn_lt_color_green = ((btn_lt_color >> 16) & 0xFF);
btn_lt_color_blue = ((btn_lt_color >> 8) & 0xFF);
btn_lighted->selection_color(btn_lt_color);
btn_lighted->value(1);
btn_lighted->redraw();
}
void cb_change_hrd_button()
{
progStatus.hrd_buttons = !progStatus.hrd_buttons;
FreqDispA->set_hrd(progStatus.hrd_buttons);
FreqDispB->set_hrd(progStatus.hrd_buttons);
}
void set_sliders_when()
{
if (sldrSQUELCH)
sldrSQUELCH->when(progStatus.sliders_button);
if (sldrMICGAIN)
sldrMICGAIN->when(progStatus.sliders_button);
if (sldrIFSHIFT)
sldrIFSHIFT->when(progStatus.sliders_button);
if (sldrNR)
sldrNR->when(progStatus.sliders_button);
if (sldrNOTCH)
sldrNOTCH->when(progStatus.sliders_button);
if (sldrRFGAIN)
sldrRFGAIN->when(progStatus.sliders_button);
if (sldrINNER)
sldrINNER->when(progStatus.sliders_button);
if (sldrOUTER)
sldrOUTER->when(progStatus.sliders_button);
if (sldrPOWER)
sldrPOWER->when(progStatus.sliders_button);
if (sldrVOLUME)
sldrVOLUME->when(progStatus.sliders_button);
if (ic7610_digi_sel_val)
ic7610_digi_sel_val->when(progStatus.sliders_button);
if (sldr_nb_level)
sldr_nb_level->when(progStatus.sliders_button);
}
void cb_change_sliders_button()
{
if (progStatus.sliders_button == FL_WHEN_CHANGED)
progStatus.sliders_button = FL_WHEN_RELEASE;
else
progStatus.sliders_button = FL_WHEN_CHANGED;
set_sliders_when();
}
void cb_slider_defaults()
{
bg_slider_red = 232;
bg_slider_green = 255;
bg_slider_blue = 232;
btn_slider_red = 0;
btn_slider_green = 0;
btn_slider_blue = 128;
bg_slider = fl_rgb_color( 232, 255, 232);
btn_slider = fl_rgb_color( 0, 0, 128);
sldrColors->color(bg_slider);
sldrColors->selection_color(btn_slider);
sldrColors->redraw();
}
void cb_slider_background()
{
uchar r = bg_slider_red, g = bg_slider_green, b = bg_slider_blue;
if (fl_color_chooser("Foreground color", r, g, b)) {
bg_slider_red = r; bg_slider_green = g; bg_slider_blue = b;
bg_slider = fl_rgb_color(r, g, b);
sldrColors->color(bg_slider);
sldrColors->selection_color(btn_slider);
sldrColors->redraw();
}
}
void cb_slider_select()
{
uchar r = btn_slider_red, g = btn_slider_green, b = btn_slider_blue;
if (fl_color_chooser("Foreground color", r, g, b)) {
btn_slider_red = r; btn_slider_green = g; btn_slider_blue = b;
btn_slider = fl_rgb_color(r, g, b);
sldrColors->color(bg_slider);
sldrColors->selection_color(btn_slider);
sldrColors->redraw();
}
}
void cb_sys_defaults()
{
bgsys = flrig_def_color(FL_BACKGROUND_COLOR);
bg_sys_red = ((bgsys >> 24) & 0xFF);
bg_sys_green = ((bgsys >> 16) & 0xFF);
bg_sys_blue = ((bgsys >> 8) & 0xFF);
bg2sys = flrig_def_color(FL_BACKGROUND2_COLOR);
bg2_sys_red = ((bg2sys) >> 24 & 0xFF);
bg2_sys_green = ((bg2sys) >> 16 & 0xFF);
bg2_sys_blue = ((bg2sys) >> 8 & 0xFF);
fgsys = flrig_def_color(FL_FOREGROUND_COLOR);
fg_sys_red = (fgsys >> 24) & 0xFF;
fg_sys_green = (fgsys >> 16) & 0xFF;
fg_sys_blue = (fgsys >> 8) & 0xFF;
Fl::background(bg_sys_red, bg_sys_green, bg_sys_blue);
Fl::background2(bg2_sys_red, bg2_sys_green, bg2_sys_blue);
Fl::foreground(fg_sys_red, fg_sys_green, fg_sys_blue);
dlgDisplayConfig->redraw();
mainwindow->redraw();
}
void cb_sys_foreground()
{
uchar r = fg_sys_red, g = fg_sys_green, b = fg_sys_blue;
if (fl_color_chooser("Foreground color", r, g, b)) {
fg_sys_red = r; fg_sys_green = g; fg_sys_blue = b;
fgsys = fl_rgb_color(r, g, b);
Fl::foreground(r, g, b);
dlgDisplayConfig->redraw();
mainwindow->redraw();
}
}
void cb_sys_background()
{
uchar r = bg_sys_red, g = bg_sys_green, b = bg_sys_blue;
if (fl_color_chooser("Background color", r, g, b)) {
bg_sys_red = r; bg_sys_green = g; bg_sys_blue = b;
bgsys = fl_rgb_color(r, g, b);
Fl::background(r, g, b);
dlgDisplayConfig->redraw();
mainwindow->redraw();
}
}
void cb_sys_background2()
{
uchar r = bg2_sys_red, g = bg2_sys_green, b = bg2_sys_blue;
if (fl_color_chooser("Background2 color", r, g, b)) {
bg2_sys_red = r; bg2_sys_green = g; bg2_sys_blue = b;
bg2sys = fl_rgb_color(r, g, b);
Fl::background2(r, g, b);
dlgDisplayConfig->redraw();
mainwindow->redraw();
}
}
void cbBacklightColor()
{
uchar r = bg_red, g = bg_green, b = bg_blue;
if (fl_color_chooser("Background color", r, g, b)) {
bg_red = r; bg_green = g; bg_blue = b;
bgclr = fl_rgb_color(r, g, b);
lblTest->color(bgclr);
sldrRcvSignalColor->color( fl_rgb_color (smeterRed, smeterGreen, smeterBlue), bgclr );
sldrPWRcolor->color(fl_rgb_color (pwrRed, pwrGreen, pwrBlue), bgclr);
sldrSWRcolor->color(fl_rgb_color (swrRed, swrGreen, swrBlue), bgclr);
scaleSmeterColor->color(bgclr);
scalePWRcolor->color(bgclr);
scaleSWRcolor->color(bgclr);
grpMeterColor->color(bgclr);
dlgDisplayConfig->redraw();
}
}
void cbPrefForeground()
{
uchar r = fg_red, g = fg_green, b = fg_blue;
if (fl_color_chooser("Foreground color", r, g, b)) {
fg_red = r; fg_green = g; fg_blue = b;
fgclr = fl_rgb_color(r, g, b);
lblTest->labelcolor(fgclr);
scaleSmeterColor->labelcolor(fgclr);
scalePWRcolor->labelcolor(fgclr);
scaleSWRcolor->labelcolor(fgclr);
grpMeterColor->labelcolor(fgclr);
dlgDisplayConfig->redraw();
}
}
void default_meters()
{
Fl_Color c;
bg_red = 232; bg_green = 255; bg_blue = 232;
bgclr = fl_rgb_color( bg_red, bg_green, bg_blue);
lblTest->color(bgclr);
sldrRcvSignalColor->color( fl_rgb_color (smeterRed, smeterGreen, smeterBlue), bgclr );
sldrPWRcolor->color(fl_rgb_color (pwrRed, pwrGreen, pwrBlue), bgclr);
sldrSWRcolor->color(fl_rgb_color (swrRed, swrGreen, swrBlue), bgclr);
scaleSmeterColor->color(bgclr);
scalePWRcolor->color(bgclr);
scaleSWRcolor->color(bgclr);
grpMeterColor->color(bgclr);
fg_red = 0; fg_green = 0; fg_blue = 0;
fgclr = (Fl_Color)0;
lblTest->labelcolor(fgclr);
scaleSmeterColor->labelcolor(fgclr);
scalePWRcolor->labelcolor(fgclr);
scaleSWRcolor->labelcolor(fgclr);
grpMeterColor->labelcolor(fgclr);
smeterRed = 0; smeterGreen = 180; smeterBlue = 0;
c = fl_rgb_color (smeterRed, smeterGreen, smeterBlue);
sldrRcvSignalColor->color(c, bgclr );
peakRed = 255; peakGreen = 0; peakBlue = 0;
c = fl_rgb_color( peakRed, peakGreen, peakBlue );
sldrRcvSignalColor->PeakColor(c);
sldrPWRcolor->PeakColor(c);
sldrSWRcolor->PeakColor(c);
pwrRed = 180; pwrGreen = 0; pwrBlue = 0;
c = fl_rgb_color( pwrRed, pwrGreen, pwrBlue );
sldrPWRcolor->color(c, bgclr);
swrRed = 148; swrGreen = 0; swrBlue = 148;
c = fl_rgb_color(swrRed, swrGreen, swrBlue);
sldrSWRcolor->color(c, bgclr);
dlgDisplayConfig->redraw();
}
void cbSMeterColor()
{
uchar r = smeterRed, g = smeterGreen, b = smeterBlue;
if (fl_color_chooser("S Meter color", r, g, b)) {
smeterRed = r; smeterGreen = g; smeterBlue = b;
sldrRcvSignalColor->color(
fl_rgb_color (r, g, b),
bgclr );
dlgDisplayConfig->redraw();
}
}
void cbPeakMeterColor()
{
uchar r = peakRed, g = peakGreen, b = peakBlue;
if (fl_color_chooser("Peak value color", r, g, b)) {
peakRed = r; peakGreen = g; peakBlue = b;
sldrRcvSignalColor->PeakColor(fl_rgb_color (r, g, b));
sldrPWRcolor->PeakColor(fl_rgb_color (r, g, b));
sldrSWRcolor->PeakColor(fl_rgb_color (r, g, b));
dlgDisplayConfig->redraw();
}
}
void cbPwrMeterColor()
{
uchar r = pwrRed, g = pwrGreen, b = pwrBlue;
if (fl_color_chooser("Power color", r, g, b)) {
pwrRed = r; pwrGreen = g; pwrBlue = b;
sldrPWRcolor->color(
fl_rgb_color (r, g, b),
bgclr );
dlgDisplayConfig->redraw();
}
}
void cbSWRMeterColor()
{
uchar r = swrRed, g = swrGreen, b = swrBlue;
if (fl_color_chooser("Power color", r, g, b)) {
swrRed = r; swrGreen = g; swrBlue = b;
sldrSWRcolor->color(
fl_rgb_color (swrRed, swrGreen, swrBlue),
bgclr );
dlgDisplayConfig->redraw();
}
}
void setColors()
{
progStatus.swrRed = swrRed;
progStatus.swrGreen = swrGreen;
progStatus.swrBlue = swrBlue;
progStatus.pwrRed = pwrRed;
progStatus.pwrGreen = pwrGreen;
progStatus.pwrBlue = pwrBlue;
progStatus.smeterRed = smeterRed;
progStatus.smeterGreen = smeterGreen;
progStatus.smeterBlue = smeterBlue;
progStatus.peakRed = peakRed;
progStatus.peakGreen = peakGreen;
progStatus.peakBlue = peakBlue;
progStatus.fg_red = fg_red;
progStatus.fg_green = fg_green;
progStatus.fg_blue = fg_blue;
progStatus.bg_red = bg_red;
progStatus.bg_green = bg_green;
progStatus.bg_blue = bg_blue;
progStatus.fontnbr = selfont;
FreqDispA->font(selfont);
FreqDispB->font(selfont);
progStatus.fg_sys_red = fg_sys_red;
progStatus.fg_sys_green = fg_sys_green;
progStatus.fg_sys_blue = fg_sys_blue;
progStatus.bg_sys_red = bg_sys_red;
progStatus.bg_sys_green = bg_sys_green;
progStatus.bg_sys_blue = bg_sys_blue;
progStatus.bg2_sys_red = bg2_sys_red;
progStatus.bg2_sys_green = bg2_sys_green;
progStatus.bg2_sys_blue = bg2_sys_blue;
progStatus.slider_red = bg_slider_red;
progStatus.slider_green = bg_slider_green;
progStatus.slider_blue = bg_slider_blue;
progStatus.slider_btn_red = btn_slider_red;
progStatus.slider_btn_green = btn_slider_green;
progStatus.slider_btn_blue = btn_slider_blue;
progStatus.lighted_btn_red = btn_lt_color_red;
progStatus.lighted_btn_green = btn_lt_color_green;
progStatus.lighted_btn_blue = btn_lt_color_blue;
if (useB) {
FreqDispB->SetONOFFCOLOR( fl_rgb_color(fg_red, fg_green, fg_blue), bgclr);
FreqDispA->SetONOFFCOLOR(
fl_rgb_color(fg_red, fg_green, fg_blue),
fl_color_average(bgclr, FL_BLACK, 0.87));
} else {
FreqDispA->SetONOFFCOLOR( fl_rgb_color(fg_red, fg_green, fg_blue), bgclr);
FreqDispB->SetONOFFCOLOR(
fl_rgb_color(fg_red, fg_green, fg_blue),
fl_color_average(bgclr, FL_BLACK, 0.87));
}
grpMeters->color(bgclr);
meter_fill_box->color(bgclr);
scaleSmeter->color(bgclr);
scaleSmeter->labelcolor(fgclr);
scalePower->color(bgclr);
scalePower->labelcolor(fgclr);
btnALC_SWR->color(bgclr);
btnALC_SWR->labelcolor(fgclr);
btnALC_SWR->redraw();
sldrFwdPwr->color(fl_rgb_color (pwrRed, pwrGreen, pwrBlue), bgclr);
sldrFwdPwr->PeakColor(fl_rgb_color(peakRed, peakGreen, peakBlue));
sldrRcvSignal->color(fl_rgb_color (smeterRed, smeterGreen, smeterBlue), bgclr);
sldrRcvSignal->PeakColor(fl_rgb_color(peakRed, peakGreen, peakBlue));
sldrALC->color(fl_rgb_color (swrRed, swrGreen, swrBlue), bgclr);
sldrALC->PeakColor(fl_rgb_color(peakRed, peakGreen, peakBlue));
sldrSWR->color(fl_rgb_color (swrRed, swrGreen, swrBlue), bgclr);
sldrSWR->PeakColor(fl_rgb_color(peakRed, peakGreen, peakBlue));
grpMeters->redraw();
if (btnVol) btnVol->selection_color(btn_lt_color);
if (btnNR) btnNR->selection_color(btn_lt_color);
if (btnIFsh) btnIFsh->selection_color(btn_lt_color);
if (btnNotch) btnNotch->selection_color(btn_lt_color);
if (btnA) btnA->selection_color(btn_lt_color);
if (btnB) btnB->selection_color(btn_lt_color);
if (btnSplit) btnSplit->selection_color(btn_lt_color);
if (btnAttenuator) btnAttenuator->selection_color(btn_lt_color);
if (btnPreamp) btnPreamp->selection_color(btn_lt_color);
if (btnNOISE) btnNOISE->selection_color(btn_lt_color);
if (btnAutoNotch) btnAutoNotch->selection_color(btn_lt_color);
if (btnTune) btnTune->selection_color(btn_lt_color);
if (btnPTT) btnPTT->selection_color(btn_lt_color);
if (btnLOCK) btnLOCK->selection_color(btn_lt_color);
if (btnAuxRTS) btnAuxRTS->selection_color(btn_lt_color);
if (btnAuxDTR) btnAuxDTR->selection_color(btn_lt_color);
if (btnSpot) btnSpot->selection_color(btn_lt_color);
if (btn_vox) btn_vox->selection_color(btn_lt_color);
if (btnCompON) btnCompON->selection_color(btn_lt_color);
// if (btnSpecial) btnSpecial->selection_color(btn_lt_color);
if (btn_tt550_vox) btn_tt550_vox->selection_color(btn_lt_color);
if (btn_tt550_CompON) btn_tt550_CompON->selection_color(btn_lt_color);
if (sldrVOLUME) sldrVOLUME->color(bg_slider);
if (sldrVOLUME) sldrVOLUME->selection_color(btn_slider);
if (sldrRFGAIN) sldrRFGAIN->color(bg_slider);
if (sldrRFGAIN) sldrRFGAIN->selection_color(btn_slider);
if (sldrSQUELCH) sldrSQUELCH->color(bg_slider);
if (sldrSQUELCH) sldrSQUELCH->selection_color(btn_slider);
if (sldrNR) sldrNR->color(bg_slider);
if (sldrNR) sldrNR->selection_color(btn_slider);
if (sldrIFSHIFT) sldrIFSHIFT->color(bg_slider);
if (sldrIFSHIFT) sldrIFSHIFT->selection_color(btn_slider);
if (sldrINNER) sldrINNER->color(bg_slider);
if (sldrINNER) sldrINNER->selection_color(btn_slider);
if (sldrOUTER) sldrOUTER->color(bg_slider);
if (sldrOUTER) sldrOUTER->selection_color(btn_slider);
if (sldrNOTCH) sldrNOTCH->color(bg_slider);
if (sldrNOTCH) sldrNOTCH->selection_color(btn_slider);
if (sldrMICGAIN) sldrMICGAIN->color(bg_slider);
if (sldrMICGAIN) sldrMICGAIN->selection_color(btn_slider);
if (sldrPOWER) sldrPOWER->color(bg_slider);
if (sldrPOWER) sldrPOWER->selection_color(btn_slider);
if (spnrPOWER) spnrPOWER->color(bg_slider);
if (spnrVOLUME) spnrVOLUME->color(bg_slider);
// if (spnrPOWER) spnrPOWER->selection_color(btn_slider);
mainwindow->redraw();
}
void cb_reset_display_dialog()
{
cb_sys_defaults();
cb_lighted_default();
cb_slider_defaults();
default_meters();
setColors();
}
void cbOkDisplayDialog()
{
setColors();
dlgDisplayConfig->hide();
}
void cbCancelDisplayDialog()
{
dlgDisplayConfig->hide();
}
void setDisplayColors()
{
if (dlgDisplayConfig == NULL)
return;
swrRed = progStatus.swrRed;
swrGreen = progStatus.swrGreen;
swrBlue = progStatus.swrBlue;
pwrRed = progStatus.pwrRed;
pwrGreen = progStatus.pwrGreen;
pwrBlue = progStatus.pwrBlue;
smeterRed = progStatus.smeterRed;
smeterGreen = progStatus.smeterGreen;
smeterBlue = progStatus.smeterBlue;
peakRed = progStatus.peakRed;
peakGreen = progStatus.peakGreen;
peakBlue = progStatus.peakBlue;
fg_red = progStatus.fg_red;
fg_green = progStatus.fg_green;
fg_blue = progStatus.fg_blue;
bg_red = progStatus.bg_red;
bg_green = progStatus.bg_green;
bg_blue = progStatus.bg_blue;
bgclr = fl_rgb_color(bg_red, bg_green, bg_blue);
fgclr = fl_rgb_color(fg_red, fg_green, fg_blue);
fg_sys_red = progStatus.fg_sys_red;
fg_sys_green = progStatus.fg_sys_green;
fg_sys_blue = progStatus.fg_sys_blue;
bg_sys_red = progStatus.bg_sys_red;
bg_sys_green = progStatus.bg_sys_green;
bg_sys_blue = progStatus.bg_sys_blue;
bg2_sys_red = progStatus.bg2_sys_red;
bg2_sys_green = progStatus.bg2_sys_green;
bg2_sys_blue = progStatus.bg2_sys_blue;
bg_slider_red = progStatus.slider_red;
bg_slider_green = progStatus.slider_green;
bg_slider_blue = progStatus.slider_blue;
btn_slider_red = progStatus.slider_btn_red;
btn_slider_green = progStatus.slider_btn_green;
btn_slider_blue = progStatus.slider_btn_blue;
sldrColors->color(fl_rgb_color(bg_slider_red, bg_slider_green, bg_slider_blue));
sldrColors->selection_color(fl_rgb_color(btn_slider_red, btn_slider_green, btn_slider_blue));
btn_lt_color_red = progStatus.lighted_btn_red;
btn_lt_color_green = progStatus.lighted_btn_green;
btn_lt_color_blue = progStatus.lighted_btn_blue;
lblTest->labelcolor(fl_rgb_color(fg_red, fg_green, fg_blue));
lblTest->color(bgclr);
scaleSmeterColor->color(bgclr);
scaleSmeterColor->labelcolor(fgclr);
scalePWRcolor->color(bgclr);
scalePWRcolor->labelcolor(fgclr);
scaleSWRcolor->color(bgclr);
scaleSWRcolor->labelcolor(fgclr);
grpMeterColor->color(bgclr);
grpMeterColor->labelcolor(fgclr);
sldrRcvSignalColor->color(
fl_rgb_color (smeterRed, smeterGreen, smeterBlue),
bgclr );
sldrPWRcolor->color(
fl_rgb_color (pwrRed, pwrGreen, pwrBlue),
bgclr );
sldrSWRcolor->color(
fl_rgb_color (swrRed, swrGreen, swrBlue),
bgclr );
sldrRcvSignalColor->minimum(0);
sldrRcvSignalColor->maximum(100);
sldrRcvSignalColor->value(25);
sldrPWRcolor->minimum(0);
sldrPWRcolor->maximum(100);
sldrPWRcolor->value(25);
sldrSWRcolor->minimum(0);
sldrSWRcolor->maximum(100);
sldrSWRcolor->value(25);
btn_lt_color = fl_rgb_color( btn_lt_color_red, btn_lt_color_green, btn_lt_color_blue);
btn_slider = fl_rgb_color( btn_slider_red, btn_slider_green, btn_slider_blue);
bg_slider = fl_rgb_color(bg_slider_red, bg_slider_green, bg_slider_blue);
btn_lighted->value(1);
btn_lighted->selection_color(btn_lt_color);
sldrColors->color(bg_slider);
sldrColors->selection_color(btn_slider);
mnuScheme->value(mnuScheme->find_item(progStatus.ui_scheme.c_str()));
dlgDisplayConfig->show();
}
void cbCloseMemory()
{
dlgMemoryDialog->hide();
}
void openMemoryDialog()
{
if (dlgMemoryDialog == NULL)
return;
dlgMemoryDialog->show();
}
void show_controls()
{
int wh = mainwindow->h();
int ww = mainwindow->w();
switch (progStatus.UIsize) {
case wide_ui :
if (mainwindow->h() > WIDE_MAINH) {
btn_show_controls->label("@-22->");
btn_show_controls->redraw_label();
grpTABS->hide();
mainwindow->size(mainwindow->w(), WIDE_MAINH);
mainwindow->size_range(735, WIDE_MAINH, 0, WIDE_MAINH);
} else {
wh += grpTABS->h();
btn_show_controls->label("@-28->");
btn_show_controls->redraw_label();
grpTABS->show();
grpTABS->resize(0, wh - grpTABS->h(), ww, grpTABS->h());
mainwindow->size(ww, wh);
mainwindow->size_range(735, wh, 0, wh);
}
mainwindow->redraw();
break;
case touch_ui :
if (selrig->name_ == rig_TT550.name_) {
tabs550->show();
tabsGeneric->hide();
} else {
tabs550->hide();
tabsGeneric->show();
}
tabs550->redraw();
tabsGeneric->redraw();
mainwindow->redraw();
break;
case small_ui :
if (selrig->name_ == rig_TT550.name_) {
tabsGeneric->hide();
tabs550->show();
} else {
tabs550->hide();
tabsGeneric->show();
}
if (tabs_dialog->visible())
tabs_dialog->hide();
else {
tabs_dialog->position(mainwindow->x(), mainwindow->y() + mainwindow->h() + 26);
tabs_dialog->show();
}
break;
default :
break;
}
}
// a replica of the default color map used by Fltk
static unsigned flrig_cmap[256] = {
0x00000000,
0xff000000,
0x00ff0000,
0xffff0000,
0x0000ff00,
0xff00ff00,
0x00ffff00,
0xffffff00,
0x55555500,
0xc6717100,
0x71c67100,
0x8e8e3800,
0x7171c600,
0x8e388e00,
0x388e8e00,
0x00008000,
0xa8a89800,
0xe8e8d800,
0x68685800,
0x98a8a800,
0xd8e8e800,
0x58686800,
0x9c9ca800,
0xdcdce800,
0x5c5c6800,
0x9ca89c00,
0xdce8dc00,
0x5c685c00,
0x90909000,
0xc0c0c000,
0x50505000,
0xa0a0a000,
0x00000000,
0x0d0d0d00,
0x1a1a1a00,
0x26262600,
0x31313100,
0x3d3d3d00,
0x48484800,
0x55555500,
0x5f5f5f00,
0x6a6a6a00,
0x75757500,
0x80808000,
0x8a8a8a00,
0x95959500,
0xa0a0a000,
0xaaaaaa00,
0xb5b5b500,
0xc0c0c000,
0xcbcbcb00,
0xd5d5d500,
0xe0e0e000,
0xeaeaea00,
0xf5f5f500,
0xffffff00,
0x00000000,
0x00240000,
0x00480000,
0x006d0000,
0x00910000,
0x00b60000,
0x00da0000,
0x00ff0000,
0x3f000000,
0x3f240000,
0x3f480000,
0x3f6d0000,
0x3f910000,
0x3fb60000,
0x3fda0000,
0x3fff0000,
0x7f000000,
0x7f240000,
0x7f480000,
0x7f6d0000,
0x7f910000,
0x7fb60000,
0x7fda0000,
0x7fff0000,
0xbf000000,
0xbf240000,
0xbf480000,
0xbf6d0000,
0xbf910000,
0xbfb60000,
0xbfda0000,
0xbfff0000,
0xff000000,
0xff240000,
0xff480000,
0xff6d0000,
0xff910000,
0xffb60000,
0xffda0000,
0xffff0000,
0x00003f00,
0x00243f00,
0x00483f00,
0x006d3f00,
0x00913f00,
0x00b63f00,
0x00da3f00,
0x00ff3f00,
0x3f003f00,
0x3f243f00,
0x3f483f00,
0x3f6d3f00,
0x3f913f00,
0x3fb63f00,
0x3fda3f00,
0x3fff3f00,
0x7f003f00,
0x7f243f00,
0x7f483f00,
0x7f6d3f00,
0x7f913f00,
0x7fb63f00,
0x7fda3f00,
0x7fff3f00,
0xbf003f00,
0xbf243f00,
0xbf483f00,
0xbf6d3f00,
0xbf913f00,
0xbfb63f00,
0xbfda3f00,
0xbfff3f00,
0xff003f00,
0xff243f00,
0xff483f00,
0xff6d3f00,
0xff913f00,
0xffb63f00,
0xffda3f00,
0xffff3f00,
0x00007f00,
0x00247f00,
0x00487f00,
0x006d7f00,
0x00917f00,
0x00b67f00,
0x00da7f00,
0x00ff7f00,
0x3f007f00,
0x3f247f00,
0x3f487f00,
0x3f6d7f00,
0x3f917f00,
0x3fb67f00,
0x3fda7f00,
0x3fff7f00,
0x7f007f00,
0x7f247f00,
0x7f487f00,
0x7f6d7f00,
0x7f917f00,
0x7fb67f00,
0x7fda7f00,
0x7fff7f00,
0xbf007f00,
0xbf247f00,
0xbf487f00,
0xbf6d7f00,
0xbf917f00,
0xbfb67f00,
0xbfda7f00,
0xbfff7f00,
0xff007f00,
0xff247f00,
0xff487f00,
0xff6d7f00,
0xff917f00,
0xffb67f00,
0xffda7f00,
0xffff7f00,
0x0000bf00,
0x0024bf00,
0x0048bf00,
0x006dbf00,
0x0091bf00,
0x00b6bf00,
0x00dabf00,
0x00ffbf00,
0x3f00bf00,
0x3f24bf00,
0x3f48bf00,
0x3f6dbf00,
0x3f91bf00,
0x3fb6bf00,
0x3fdabf00,
0x3fffbf00,
0x7f00bf00,
0x7f24bf00,
0x7f48bf00,
0x7f6dbf00,
0x7f91bf00,
0x7fb6bf00,
0x7fdabf00,
0x7fffbf00,
0xbf00bf00,
0xbf24bf00,
0xbf48bf00,
0xbf6dbf00,
0xbf91bf00,
0xbfb6bf00,
0xbfdabf00,
0xbfffbf00,
0xff00bf00,
0xff24bf00,
0xff48bf00,
0xff6dbf00,
0xff91bf00,
0xffb6bf00,
0xffdabf00,
0xffffbf00,
0x0000ff00,
0x0024ff00,
0x0048ff00,
0x006dff00,
0x0091ff00,
0x00b6ff00,
0x00daff00,
0x00ffff00,
0x3f00ff00,
0x3f24ff00,
0x3f48ff00,
0x3f6dff00,
0x3f91ff00,
0x3fb6ff00,
0x3fdaff00,
0x3fffff00,
0x7f00ff00,
0x7f24ff00,
0x7f48ff00,
0x7f6dff00,
0x7f91ff00,
0x7fb6ff00,
0x7fdaff00,
0x7fffff00,
0xbf00ff00,
0xbf24ff00,
0xbf48ff00,
0xbf6dff00,
0xbf91ff00,
0xbfb6ff00,
0xbfdaff00,
0xbfffff00,
0xff00ff00,
0xff24ff00,
0xff48ff00,
0xff6dff00,
0xff91ff00,
0xffb6ff00,
0xffdaff00,
0xffffff00
};
Fl_Color flrig_def_color(int n)
{
if ( n > 255 ) n = 255;
if (n < 0) n = 0;
return (Fl_Color)flrig_cmap[n];
}
void cb_send_command(string command, Fl_Output *resp)
{
if (command.empty()) return;
bool usehex = false;
if (command.empty()) return;
string cmd = "";
if (command.find("x") != string::npos) { // hex strings
size_t p = 0;
usehex = true;
unsigned int val;
while (( p = command.find("x", p)) != string::npos) {
sscanf(&command[p+1], "%x", &val);
cmd += (unsigned char) val;
p += 3;
}
} else
cmd = command;
if (resp) {
resp->value("");
resp->redraw();
}
// lock out polling loops until done
guard_lock lock1(&mutex_srvc_reqs);
guard_lock lock2(&mutex_serial);
sendCommand(cmd, 0);//cmd.length());
set_trace(2, "command: ", command.c_str());
waitResponse(100);
std::string retstr = usehex ?
str2hex(respstr.c_str(), respstr.length()) :
respstr;
set_trace(2, "response: ", retstr.c_str());
if (resp) {
resp->value(retstr.c_str());
resp->redraw();
}
}
flrig-1.3.49/src/support/support.cxx 0000664 0001750 0001750 00000473416 13605621006 014417 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "icons.h"
#include "support.h"
#include "debug.h"
#include "gettext.h"
#include "rig_io.h"
#include "dialogs.h"
#include "rigbase.h"
#include "ptt.h"
#include "socket_io.h"
#include "ui.h"
#include "tod_clock.h"
#include "rig.h"
#include "rigs.h"
#include "K3_ui.h"
#include "KX3_ui.h"
#include "rigpanel.h"
#include "tod_clock.h"
#include "trace.h"
void initTabs();
using namespace std;
rigbase *selrig = rigs[0];
extern bool test;
bool flrig_abort = false;
int freqval = 0;
XCVR_STATE vfoA = XCVR_STATE(14070000, 0, 0, UI);
XCVR_STATE vfoB = XCVR_STATE(7070000, 0, 0, UI);
XCVR_STATE *vfo = &vfoA;
//XCVR_STATE xmlvfo = XCVR_STATE(14070000, 0, 0, UI);
XCVR_STATE xcvr_vfoA, xcvr_vfoB;
enum {VOL, MIC, PWR, SQL, IFSH, NOTCH, RFGAIN, NR, NB };
queue srvc_reqs;
bool useB = false;
bool changed_vfo = false;
const char **old_bws = NULL;
// Add alpha-tag to XCVR_STATE;
struct ATAG_XCVR_STATE {
long freq;
int imode;
int iBW;
int src;
char alpha_tag[ATAGSIZE];
};
ATAG_XCVR_STATE oplist[LISTSIZE];
int numinlist = 0;
vector rigmodes_;
vector rigbws_;
Cserial *RigSerial;
Cserial *AuxSerial;
Cserial *SepSerial;
bool using_buttons = false;
enum { SWR_IMAGE, ALC_IMAGE };
int meter_image = SWR_IMAGE;
bool xcvr_initialized = false;
//======================================================================
// slider change processing
//======================================================================
int inhibit_nb_level = 0;
int inhibit_volume = 0;
int inhibit_pbt = 0;
int inhibit_shift = 0;
int inhibit_nr = 0;
int inhibit_notch = 0;
int inhibit_power = 0;
int inhibit_mic = 0;
int inhibit_rfgain = 0;
int inhibit_squelch = 0;
struct SLIDER {
enum {NOTCH, SHIFT, INNER, OUTER, LOCK, VOLUME, MIC, POWER, SQUELCH, RFGAIN, NB_LEVEL, NR, NR_VAL};
int fnc;
int val;
};
queue sliders;
pthread_mutex_t mutex_sliders = PTHREAD_MUTEX_INITIALIZER;
void process_sliders()
{
SLIDER slider;
int val;
while (!sliders.empty()) {
{
guard_lock slock(&mutex_sliders);
slider = sliders.front();
sliders.pop();
while (!sliders.empty() && (slider.fnc == sliders.front().fnc)) {
slider = sliders.front();
sliders.pop();
}
}
val = slider.val;
if (inhibit_pbt == 1) inhibit_pbt = 0;
switch (slider.fnc) {
case SLIDER::NOTCH :
selrig->set_notch(progStatus.notch, val);
if (inhibit_notch == 1) inhibit_notch = 0;
break;
case SLIDER::SHIFT :
selrig->set_if_shift(val);
if (inhibit_shift == 1) inhibit_shift = 0;
break;
case SLIDER::INNER :
selrig->set_pbt_inner(val);
break;
case SLIDER::OUTER :
selrig->set_pbt_outer(val);
break;
case SLIDER::LOCK :
selrig->set_pbt_inner(val);
selrig->set_pbt_outer(val);
break;
case SLIDER::VOLUME :
selrig->set_volume_control(val);
if (inhibit_volume == 1) inhibit_volume = 0;
break;
case SLIDER::MIC :
selrig->set_mic_gain(val);
if (inhibit_mic == 1) inhibit_mic = 0;
break;
case SLIDER::POWER :
selrig->set_power_control(val);
if (inhibit_power) {
stringstream str;
str << "SLIDER::POWER inhibit_power=" << inhibit_power;
trace(1, str.str().c_str());
}
if (inhibit_power == 1) inhibit_power = 0;
break;
case SLIDER::SQUELCH :
selrig->set_squelch(val);
if (inhibit_squelch == 1) inhibit_squelch = 0;
break;
case SLIDER::RFGAIN :
selrig->set_rf_gain(val);
if (inhibit_rfgain == 1) inhibit_rfgain = 0;
break;
case SLIDER::NB_LEVEL :
selrig->set_nb_level(val);
if (inhibit_nb_level == 1) inhibit_nb_level = 0;
break;
case SLIDER::NR :
selrig->set_noise_reduction(val);
break;
case SLIDER::NR_VAL :
selrig->set_noise_reduction_val(val);
if (inhibit_nr == 1) inhibit_nr = 0;
break;
default: break;
}
}
}
//======================================================================
// loop for serial i/o thread
// runs continuously until program is closed
// only accesses the serial port if it has been successfully opened
//======================================================================
bool bypass_serial_thread_loop = true;
bool run_serial_thread = true;
bool PTT = false;
int powerlevel = 0;
string printXCVR_STATE(XCVR_STATE &data)
{
stringstream str;
const char **bwt = selrig->bwtable(data.imode);
const char **dsplo = selrig->lotable(data.imode);
const char **dsphi = selrig->hitable(data.imode);
str << data.freq << ", ";
str <<
(selrig->modes_ ? selrig->modes_[data.imode] : "modes n/a");
if (data.iBW > 256 && selrig->has_dsp_controls) {
str << ", " <<
(dsplo ? dsplo[data.iBW & 0x7F] : "??");
} else if (bwt) {
str << ", " << bwt[data.iBW];
} else
str << ", n/a";
if (data.iBW > 256 && selrig->has_dsp_controls) {
str << ", " <<
(dsphi ? dsphi[(data.iBW >> 8) & 0x7F] : "??");
}
return str.str();
}
string print_ab()
{
std::string s;
s.assign("VFO-A: ");
s.append(printXCVR_STATE(vfoA));
s.append("; VFO-B: ");
s.append(printXCVR_STATE(vfoB));
return s;
}
char *print(XCVR_STATE &data)
{
static char str[1024];
const char **bwt = selrig->bwtable(data.imode);
const char **dsplo = selrig->lotable(data.imode);
const char **dsphi = selrig->hitable(data.imode);
snprintf(
str, sizeof(str),
"\
Data Source: %s\n\
freq ........... %ld\n\
mode ........... %d [%s]\n\
filter ......... %s\n\
bwt index ...... %2d, [%s] [%s]\n\
split .......... %4d, power_control . %4d, volume_control %4d\n\
attenuator ..... %4d, preamp ........ %4d, rf gain ....... %4d\n\
if_shift ....... %4d, shift val ..... %4d\n\
auto notch ..... %4d, notch ......... %4d, notch value ... %4d\n\
noise .......... %4d, nr ............ %4d, nr val ........ %4d\n\
mic gain ....... %4d, agc level ..... %4d, squelch ....... %4d\n\
compression .... %4d, compON ........ %4d",
data.src == XML ? "XML" : data.src == UI ? "UI" :
data.src == SRVR ? "SRVR" : "RIG",
data.freq,
data.imode,
selrig->modes_ ? selrig->modes_[data.imode] : "modes n/a",
selrig->has_FILTER ? selrig->FILT(selrig->get_FILT(data.imode)) : "n/a",
data.iBW,
(data.iBW > 256 && selrig->has_dsp_controls) ?
(dsplo ? dsplo[data.iBW & 0x7F] : "??") : (bwt ? bwt[data.iBW] : "n/a"),
(data.iBW > 256 && selrig->has_dsp_controls) ?
(dsphi ? dsphi[(data.iBW >> 8) & 0x7F] : "??") : "",
data.split,
data.power_control,
data.volume_control,
data.attenuator,
data.preamp,
data.rf_gain,
data.if_shift,
data.shift_val,
data.auto_notch,
data.notch,
data.notch_val,
data.noise,
data.nr,
data.nr_val,
data.mic_gain,
data.agc_level,
data.squelch,
data.compression,
data.compON
);
return str;
}
// the following functions are ONLY CALLED by the serial loop
// read any data stream sent by transceiver
// support for the K3 and KX3 read of VFO, MODE and BW are
// in the K3_ui and KX3_ui source files
void read_info()
{
trace(1,"read_info()");
selrig->get_info();
}
// read current vfo frequency
void read_vfo()
{
// transceiver changed ?
trace(1,"read_vfo()");
long freq;
if (!useB) { // vfo-A
trace(2, "vfoA active", "get vfo A");
freq = selrig->get_vfoA();
if (freq != vfoA.freq) {
vfoA.freq = freq;
Fl::awake(setFreqDispA, (void *)vfoA.freq);
vfo = &vfoA;
}
if ( selrig->twovfos() ) {
trace(2, "vfoA active", "get vfo B");
freq = selrig->get_vfoB();
if (freq != vfoB.freq) {
vfoB.freq = freq;
Fl::awake(setFreqDispB, (void *)vfoB.freq);
}
}
} else { // vfo-B
trace(2, "vfoB active", "get vfo B");
freq = selrig->get_vfoB();
if (freq != vfoB.freq) {
vfoB.freq = freq;
Fl::awake(setFreqDispB, (void *)vfoB.freq);
vfo = &vfoB;
}
if ( selrig->twovfos() ) {
trace(2, "vfoB active", "get vfo A");
freq = selrig->get_vfoA();
if (freq != vfoA.freq) {
vfoA.freq = freq;
Fl::awake(setFreqDispA, (void *)vfoA.freq);
}
}
}
}
void updateUI(void *)
{
setModeControl(NULL);
setBWControl(NULL);
updateBandwidthControl(NULL);
highlight_vfo(NULL);
}
void update_vfoAorB(void *d)
{
if (xcvr_name == rig_FT817.name_) {
trace(1,"FT817, update_vfoAorB()");
if (useB) {
vfoB.src = RIG;
vfoB.freq = selrig->get_vfoB();
vfoB.imode = selrig->get_modeB();
vfoB.iBW = selrig->get_bwB();
} else {
vfoA.src = RIG;
vfoA.freq = selrig->get_vfoA();
vfoA.imode = selrig->get_modeA();
vfoA.iBW = selrig->get_bwA();
}
return;
}
updateUI((void*)0);
}
void read_vfoAorB()
{
int val;
if (selrig->has_getvfoAorB) {
{
trace(1,"read_vfoAorB()");
val = selrig->get_vfoAorB();
if (val == -1) val = 0;
}
if (val != useB) {
useB = val;
Fl::awake(update_vfoAorB, reinterpret_cast(val));
MilliSleep(50);
}
}
}
void setModeControl(void *)
{
opMODE->index(vfo->imode);
// enables/disables the IF shift control, depending on the mode.
// the IF Shift function, is ONLY valid in CW modes, with the 870S.
if (xcvr_name == rig_TS870S.name_) {
if (vfo->imode == RIG_TS870S::tsCW || vfo->imode == RIG_TS870S::tsCWR) {
btnIFsh->activate();
if (sldrIFSHIFT) sldrIFSHIFT->activate();
if (spnrIFSHIFT) spnrIFSHIFT->activate();
} else {
btnIFsh->deactivate();
if (sldrIFSHIFT) sldrIFSHIFT->deactivate();
if (spnrIFSHIFT) spnrIFSHIFT->deactivate();
}
}
}
void setFILTER(void *)
{
if (selrig->has_FILTER) {
if (useB)
btnFILT->label(selrig->FILT(vfoB.filter));
else
btnFILT->label(selrig->FILT(vfoA.filter));
btnFILT->redraw_label();
trace(3, "Filter", (useB ? "B" : "A"), btnFILT->label());
}
}
// mode and bandwidth
void read_mode()
{
int nu_mode;
int nu_BW;
if (!useB) {
trace(2, "read_mode", "vfoA active");
nu_mode = selrig->get_modeA();
vfoA.filter = selrig->get_FILT(nu_mode);
if (nu_mode != vfoA.imode) {
{
vfoA.imode = vfo->imode = nu_mode;
selrig->adjust_bandwidth(vfo->imode);
nu_BW = selrig->get_bwA();
vfoA.iBW = vfo->iBW = nu_BW;
}
Fl::awake(setModeControl);
set_bandwidth_control();
}
Fl::awake(setFILTER);
if (selrig->can_change_alt_vfo) {
vfoB.imode = selrig->get_modeB();
vfoB.filter = selrig->get_FILT(vfoB.imode);
}
} else {
trace(2, "read_mode", "vfoB active");
nu_mode = selrig->get_modeB();
vfoB.filter = selrig->get_FILT(nu_mode);
if (nu_mode != vfoB.imode) {
{
vfoB.imode = vfo->imode = nu_mode;
selrig->adjust_bandwidth(vfo->imode);
nu_BW = selrig->get_bwB();
vfoB.iBW = vfo->iBW = nu_BW;
}
Fl::awake(setModeControl);
set_bandwidth_control();
}
Fl::awake(setFILTER);
if (selrig->can_change_alt_vfo) {
vfoA.imode = selrig->get_modeA();
vfoA.filter = selrig->get_FILT(vfoA.imode);
}
}
}
void setBWControl(void *)
{
if (selrig->has_dsp_controls) {
if (opDSP_lo->isbusy() || opDSP_hi->isbusy())
return;
if (vfo->iBW > 256) {
opBW->index(0);
opBW->hide();
if (opDSP_lo->visible()) {
opDSP_hi->index((vfo->iBW >> 8) & 0x7F);
opDSP_hi->hide();
opDSP_lo->index(vfo->iBW & 0xFF);
opDSP_lo->show();
} else {
opDSP_hi->index((vfo->iBW >> 8) & 0x7F);
opDSP_lo->index(vfo->iBW & 0xFF);
opDSP_lo->hide();
opDSP_hi->show();
}
btnDSP->label(selrig->SL_label);
btnDSP->redraw_label();
btnDSP->show();
} else {
opDSP_lo->index(0);
opDSP_hi->index(0);
opDSP_lo->hide();
opDSP_hi->hide();
btnDSP->hide();
opBW->index(vfo->iBW);
opBW->show();
}
}
else {
if (opBW->isbusy())
return;
opDSP_lo->hide();
opDSP_hi->hide();
btnDSP->hide();
opBW->index(vfo->iBW);
opBW->show();
}
}
void read_bandwidth()
{
trace(1,"read_bandwidth()");
int nu_BW;
if (!useB) {
trace(2, "vfoA active", "get_bwA()");
nu_BW = selrig->get_bwA();
if (nu_BW != vfoA.iBW) {
stringstream s;
s << "Bandwidth A change. nu_BW=" << nu_BW << ", vfoA.iBW=" << vfoA.iBW << ", vfo->iBW=" << vfo->iBW;
trace(1, s.str().c_str());
vfoA.iBW = vfo->iBW = nu_BW;
// Fl::awake(setBWControl);
}
} else {
trace(2, "vfoB active", "get_bwB()");
nu_BW = selrig->get_bwB();
if (nu_BW != vfoB.iBW) {
stringstream s;
s << "Bandwidth B change. nu_BW=" << nu_BW << ", vfoB.iBW=" << vfoB.iBW << ", vfo->iBW=" << vfo->iBW;
trace(1, s.str().c_str());
vfoB.iBW = vfo->iBW = nu_BW;
// Fl::awake(setBWControl);
}
}
Fl::awake(setBWControl);
}
// read current signal level
int mval = 0;
void read_smeter()
{
if (!selrig->has_smeter) return;
int sig;
{
trace(1,"read_smeter()");
sig = selrig->get_smeter();
}
if (sig == -1) return;
mval = sig;
Fl::awake(updateSmeter, reinterpret_cast(sig));
}
int tunerval = 0;
void update_UI_TUNER(void *)
{
btn_tune_on_off->value(tunerval);
btn_tune_on_off->redraw();
}
void read_tuner()
{
tunerval = selrig->get_tune();
if (tunerval != btn_tune_on_off->value()) {
stringstream s;
s << "tuner state: " << tunerval;
trace(1, s.str().c_str());
Fl::awake(update_UI_TUNER);
}
}
// read power out
void read_power_out()
{
if (!selrig->has_power_out) return;
int sig;
{
trace(1,"read_power_out()");
sig = selrig->get_power_out();
}
if (sig == -1) return;
mval = sig;
Fl::awake(updateFwdPwr, reinterpret_cast(sig));
}
// read swr
void read_swr()
{
if ((meter_image != SWR_IMAGE) ||
!selrig->has_swr_control) return;
int sig;
{
trace(1,"read_swr()");
sig = selrig->get_swr();
}
if (sig > -1)
Fl::awake(updateSWR, reinterpret_cast(sig));
}
// alc
void read_alc()
{
if ((meter_image != ALC_IMAGE) ||
!selrig->has_alc_control) return;
int sig;
{
trace(1,"read_alc()");
sig = selrig->get_alc();
}
if (sig > -1)
Fl::awake(updateALC, reinterpret_cast(sig));
}
// notch
void update_auto_notch(void *d)
{
btnAutoNotch->value(progStatus.auto_notch);
}
void read_auto_notch()
{
int val;
if (!selrig->has_auto_notch) return;
{
trace(1,"read_auto_notch()");
val = selrig->get_auto_notch();
}
if (val != progStatus.auto_notch) {
progStatus.auto_notch = vfo->auto_notch = val;
Fl::awake(update_auto_notch, (void*)0);
}
}
// NOISE blanker
void update_noise(void *d)
{
btnNOISE->value(progStatus.noise);
sldr_nb_level->value(progStatus.nb_level);
}
void read_noise()
{
int on = 0, val = 0;
if (inhibit_nb_level) return;
{
trace(1,"read_noise()");
on = selrig->get_noise();
val = selrig->get_nb_level();
}
if ((on != progStatus.noise) || (val != progStatus.nb_level)) {
vfo->noise = progStatus.noise = on;
vfo->nb_level = progStatus.nb_level = val;
Fl::awake(update_noise, (void*)0);
}
}
// compression
void update_compression(void *d)
{
if (btnCompON) btnCompON->value(progStatus.compON);
if (spnr_compression) spnr_compression->value(progStatus.compression);
}
void read_compression()
{
int on = progStatus.compON;
int val = progStatus.compression;
if (selrig->has_compression || selrig->has_compON) {
{
trace(1,"read_compression()");
selrig->get_compression( on, val );
}
if (on != progStatus.compON || val != progStatus.compression) {
vfo->compression = progStatus.compression = val;
vfo->compON = progStatus.compON = on;
Fl::awake(update_compression, (void*)0);
}
}
}
// preamp - attenuator
void update_preamp(void *d)
{
btnPreamp->value(progStatus.preamp);
}
void update_attenuator(void *d)
{
btnAttenuator->value(progStatus.attenuator);
}
void read_preamp_att()
{
int val;
if (selrig->has_preamp_control) {
{
trace(1,"read_preamp_att() 1");
val = selrig->get_preamp();
}
if (val != progStatus.preamp || val != vfo->preamp || (btnPreamp && val != btnPreamp->value())) {
vfo->preamp = progStatus.preamp = val;
Fl::awake(update_preamp, (void*)0);
}
}
if (selrig->has_attenuator_control) {
{
trace(1,"read_preamp_att() 2");
val = selrig->get_attenuator();
}
if (val != progStatus.attenuator || val != vfo->attenuator || (btnAttenuator && val != btnAttenuator->value())) {
vfo->attenuator = progStatus.attenuator = val;
Fl::awake(update_attenuator, (void*)0);
}
}
}
// split
void update_split(void *d)
{
/*
if (xcvr_name == rig_yaesu.name_ || xcvr_name == rig_FTdx1200.name_ ||
xcvr_name == rig_TS480SAT.name_ || xcvr_name == rig_TS480HX.name_ ||
xcvr_name == rig_TS590S.name_ || xcvr_name == rig_TS590SG.name_ ||
xcvr_name == rig_TS890S.name_ ||
xcvr_name == rig_TS2000.name_ || xcvr_name == rig_TS990.name_) {
switch (progStatus.split) {
case 0: btnSplit->value(0);
useB = false;
highlight_vfo(NULL);
break;
case 1: btnSplit->value(1);
useB = true;
highlight_vfo(NULL);
break;
case 2: btnSplit->value(1);
useB = false;
highlight_vfo(NULL);
break;
case 3: btnSplit->value(0);
useB = true;
highlight_vfo(NULL);
break;
}
} else
*/
btnSplit->value(progStatus.split);
btnSplit->redraw();
}
void read_split()
{
int val = progStatus.split;
if (selrig->has_split) {
val = selrig->get_split();
vfo->split = progStatus.split = val;
Fl::awake(update_split, (void*)0);
ostringstream s;
s << "read_split() " << (val ? "ON" : "OFF");
trace(1, s.str().c_str());
} else {
vfo->split = progStatus.split;
}
}
// volume
void update_volume(void *d)
{
long *nr = (long *)d;
if (spnrVOLUME) spnrVOLUME->value(progStatus.volume);
if (spnrVOLUME) spnrVOLUME->activate();
sldrVOLUME->value(progStatus.volume); // Set slider to last known value
sldrVOLUME->activate(); // activate it
if (*nr) btnVol->value(1); // Button Lit
else btnVol->value(0); // Button Dark.
}
long nlzero = 0L;
long nlone = 1L;
void read_volume()
{
if (inhibit_volume) return;
if (!selrig->has_volume_control) return;
int vol;
{
trace(1,"read_volume()");
vol = selrig->get_volume_control();
}
if (vol != progStatus.volume) {
if (vol <= 1 && !btnVol->value()) return;
progStatus.volume = vol;
if (vol <= 1 && btnVol->value())
Fl::awake(update_volume, (void*)&nlzero);
else
Fl::awake(update_volume, (void*)&nlone);
}
}
// ifshift
void update_ifshift(void *d)
{
btnIFsh->value(progStatus.shift);
if (sldrIFSHIFT) sldrIFSHIFT->value(progStatus.shift_val);
if (spnrIFSHIFT) spnrIFSHIFT->value(progStatus.shift_val);
}
void update_pbt(void *)
{
if (sldrINNER) sldrINNER->value(progStatus.pbt_inner);
if (sldrOUTER) sldrOUTER->value(progStatus.pbt_outer);
}
void read_pbt()
{
if (inhibit_pbt) {
inhibit_pbt = 0;
return;
}
progStatus.pbt_inner = selrig->get_pbt_inner();
progStatus.pbt_outer = selrig->get_pbt_outer();
Fl::awake(update_pbt, (void*)0);
}
void read_ifshift()
{
int on = 0;
int val = 0;
if (selrig->has_pbt_controls)
return read_pbt();
if (inhibit_shift) return;
if (!selrig->has_ifshift_control) return;
{
trace(1,"read_if_shift()");
on = selrig->get_if_shift(val);
}
if ((on != progStatus.shift) || (val != progStatus.shift_val)) {
vfo->if_shift = progStatus.shift = on;
vfo->shift_val = progStatus.shift_val = val;
Fl::awake(update_ifshift, (void*)0);
}
}
// noise reduction
void update_nr(void *d)
{
btnNR->value(progStatus.noise_reduction);
if (sldrNR) sldrNR->value(progStatus.noise_reduction_val);
if (spnrNR) spnrNR->value(progStatus.noise_reduction_val);
}
void read_nr()
{
int on = 0;
int val = 0;
if (inhibit_nr) return;
if (!selrig->has_noise_reduction) return;
{
trace(1,"read_nr()");
on = selrig->get_noise_reduction();
val = selrig->get_noise_reduction_val();
}
if ((on != progStatus.noise_reduction) || (val != progStatus.noise_reduction_val)) {
vfo->nr = progStatus.noise_reduction = on;
vfo->nr_val = progStatus.noise_reduction_val = val;
Fl::awake(update_nr, (void*)0);
}
}
// manual notch
void update_notch(void *d)
{
btnNotch->value(progStatus.notch);
if (sldrNOTCH) sldrNOTCH->value(progStatus.notch_val);
if (spnrNOTCH) spnrNOTCH->value(progStatus.notch_val);
}
void read_notch()
{
int on = progStatus.notch;
int val = progStatus.notch_val;
if (inhibit_notch) return;
if (!selrig->has_notch_control) return;
{
trace(1,"read_notch()");
on = selrig->get_notch(val);
}
if ((on != progStatus.notch) || (val != progStatus.notch_val)) {
vfo->notch_val = progStatus.notch_val = val;
vfo->notch = progStatus.notch = on;
Fl::awake(update_notch, (void*)0);
}
}
// power_control
void update_power_control(void *d)
{
set_power_controlImage(progStatus.power_level);
if (sldrPOWER) sldrPOWER->value(progStatus.power_level);
if (spnrPOWER) spnrPOWER->value(progStatus.power_level);
if (xcvr_name == rig_K2.name_) {
double min, max, step;
selrig->get_pc_min_max_step(min, max, step);
if (sldrPOWER) sldrPOWER->minimum(min);
if (sldrPOWER) sldrPOWER->maximum(max);
if (sldrPOWER) sldrPOWER->step(step);
if (sldrPOWER) sldrPOWER->redraw();
if (spnrPOWER) spnrPOWER->minimum(min);
if (spnrPOWER) spnrPOWER->maximum(max);
if (spnrPOWER) spnrPOWER->step(step);
if (spnrPOWER) spnrPOWER->redraw();
}
}
void read_power_control()
{
int val;
if (inhibit_power) return;
if (!selrig->has_power_control) return;
{
trace(1,"read_power_control()");
val = selrig->get_power_control();
}
if (val != progStatus.power_level || val != vfo->power_control || (sldrPOWER && val != sldrPOWER->value()) ) {
stringstream s;
s << "read_power_control(), UPDATE progStatus.power_level=" << progStatus.power_level << ", vfo->power_control=" << vfo->power_control << ", radio power=" << val << ", sldrPOWER->value()=" << (sldrPOWER ? sldrPOWER->value() : -1);
trace(1, s.str().c_str());
vfo->power_control = progStatus.power_level = val;
Fl::awake(update_power_control, (void*)0);
}
//else
//{
// stringstream s;
// s << "read_power_control(), CURRENT progStatus.power_level=" << progStatus.power_level << ", vfo->power_control=" << vfo->power_control << ", read power=" << val << ", sldrPOWER->value()=" << (sldrPOWER ? sldrPOWER->value() : -1);
// trace(1, s.str().c_str());
//}
}
// mic gain
void update_mic_gain(void *d)
{
if (sldrMICGAIN) sldrMICGAIN->value(progStatus.mic_gain);
if (spnrMICGAIN) spnrMICGAIN->value(progStatus.mic_gain);
}
void read_mic_gain()
{
int val;
if (inhibit_mic) return;
if (!selrig->has_micgain_control) return;
{
trace(1,"read_mic_gain()");
val = selrig->get_mic_gain();
}
if (val != progStatus.mic_gain || val != vfo->mic_gain || (sldrMICGAIN && val != sldrMICGAIN->value())) {
vfo->mic_gain = progStatus.mic_gain = val;
Fl::awake(update_mic_gain, (void*)0);
}
}
void read_agc()
{
int val;
if (!selrig->has_agc_control) return;
trace(1,"read_agc()");
val = selrig->get_agc();
if (val != progStatus.agc_level) {
vfo->agc_level = progStatus.agc_level = val;
Fl::awake(setAGC);
}
}
// rf gain
void update_rfgain(void *d)
{
if (sldrRFGAIN) sldrRFGAIN->value(progStatus.rfgain);
if (spnrRFGAIN) spnrRFGAIN->value(progStatus.rfgain);
}
void read_rfgain()
{
int val;
if (inhibit_rfgain) return;
if (selrig->has_rf_control) {
trace(1,"read_rfgain");
val = selrig->get_rf_gain();
if (val != progStatus.rfgain) {
progStatus.rfgain = val;
Fl::awake(update_rfgain, (void*)0);
}
}
read_agc();
}
// squelch
void update_squelch(void *d)
{
if (sldrSQUELCH) sldrSQUELCH->value(progStatus.squelch);
if (spnrSQUELCH) spnrSQUELCH->value(progStatus.squelch);
}
void read_squelch()
{
int val;
if (inhibit_squelch) return;
if (!selrig->has_sql_control) return;
{
trace(1,"read_squelch()");
val = selrig->get_squelch();
}
if (val != progStatus.squelch || val != vfo->squelch || (sldrSQUELCH && val != sldrSQUELCH->value())) {
vfo->squelch = progStatus.squelch = val;
Fl::awake(update_squelch, (void*)0);
}
}
struct POLL_PAIR {
int *poll;
void (*pollfunc)();
};
POLL_PAIR RX_poll_pairs[] = {
{&progStatus.poll_vfoAorB, read_vfoAorB},
{&progStatus.poll_frequency, read_vfo},
{&progStatus.poll_mode, read_mode},
{&progStatus.poll_bandwidth, read_bandwidth},
{&progStatus.poll_smeter, read_smeter},
{&progStatus.poll_smeter, read_tuner},
{&progStatus.poll_volume, read_volume},
{&progStatus.poll_auto_notch, read_auto_notch},
{&progStatus.poll_notch, read_notch},
{&progStatus.poll_ifshift, read_ifshift},
{&progStatus.poll_power_control, read_power_control},
{&progStatus.poll_pre_att, read_preamp_att},
{&progStatus.poll_micgain, read_mic_gain},
{&progStatus.poll_squelch, read_squelch},
{&progStatus.poll_rfgain, read_rfgain},
{&progStatus.poll_split, read_split},
{&progStatus.poll_nr, read_nr},
{&progStatus.poll_noise, read_noise},
{&progStatus.poll_compression, read_compression},
{NULL, NULL}
};
POLL_PAIR TX_poll_pairs[] = {
{&progStatus.poll_pout, read_power_out},
{&progStatus.poll_swr, read_swr},
{&progStatus.poll_alc, read_alc},
{&progStatus.poll_split, read_split},
{NULL, NULL}
};
POLL_PAIR *poll_parameters;
static bool resetrcv = true;
static bool resetxmt = true;
// On the Yaesu FT-891, the mode must be set before VFO, since mode
// changes can shift frequency.
//
// For example, might set freq to 7123.000, but then change mode from USB
// to DATA-U. This mode shift would change the VFO to 7123.700, instead
// of the desired 7123.000.
//
// Setting VFO after the mode change will prevent this type of frequency
// shifting.
void yaesu891UpdateA(XCVR_STATE * newVfo)
{
selrig->set_modeA(newVfo->imode);
selrig->set_vfoA(newVfo->freq);
selrig->set_bwA(newVfo->iBW);
}
void yaesu891UpdateB(XCVR_STATE * newVfo)
{
selrig->set_modeB(newVfo->imode);
selrig->set_vfoB(newVfo->freq);
selrig->set_bwB(newVfo->iBW);
}
void serviceQUE()
{
guard_lock que_lock(&mutex_srvc_reqs, "serviceQUE");
guard_lock serial(&mutex_serial);
queue pending; // creates an empty queue
VFOQUEUE nuvals;
while (!srvc_reqs.empty()) {
{
nuvals = srvc_reqs.front();
srvc_reqs.pop();
}
if (nuvals.change == ON || nuvals.change == OFF) { // PTT processing
if (selrig->ICOMmainsub && useB) { // disallowed operation
Fl::awake(update_UI_PTT);
return;
}
PTT = (nuvals.change == ON);
if (nuvals.change == ON) trace(1,"ptt ON");
else trace(1,"ptt OFF");
rigPTT(PTT);
int get = selrig->get_PTT();
int cnt = 0;
while ((get != PTT) && (cnt++ < 100)) {
MilliSleep(10);
get = selrig->get_PTT();
}
{
stringstream s;
s << "ptt returned " << get << " in " << cnt * 10 << " msec";
trace(1, s.str().c_str());
Fl::awake(update_UI_PTT);
}
continue;
}
if (PTT) {
if ((nuvals.vfo.iBW != 255) ||
(nuvals.vfo.imode != -1)) {
pending.push(nuvals);
continue; // while (!srvc_reqs.empty())
}
}
switch (nuvals.change) {
case vX:
if (useB)
serviceB(nuvals.vfo);
else
serviceA(nuvals.vfo);
break;
case vA:
serviceA(nuvals.vfo);
break;
case vB:
serviceB(nuvals.vfo);
break;
case sA: // select A
{
useB = false;
selrig->selectA();
vfo = &vfoA;
if (selrig->name_ == rig_FT891.name_) {
// Restore mode, then freq and bandwidth after select
yaesu891UpdateA(&vfoA);
}
trace(2, "case sA ", printXCVR_STATE(vfoA).c_str());
rig_trace(2, "case sA ", printXCVR_STATE(vfoA).c_str());
Fl::awake(updateUI);
}
break;
case sB: // select B
{
useB = true;
selrig->selectB();
vfo = &vfoB;
if (selrig->name_ == rig_FT891.name_) {
// Restore mode, then freq and bandwidth after select
yaesu891UpdateB(&vfoB);
}
trace(2, "case sB ", printXCVR_STATE(vfoB).c_str());
rig_trace(2, "case sB ", printXCVR_STATE(vfoB).c_str());
Fl::awake(updateUI);
}
break;
case sON: case sOFF:
{
int on = 0;
if (nuvals.change == sON) on = 1;
trace(1, (on ? "split ON" : "split OFF"));
rig_trace(2, "case sB ", printXCVR_STATE(vfoB).c_str());
if (selrig->can_split() || selrig->has_split_AB) {
selrig->set_split(on);
progStatus.split = on;
Fl::awake(update_split, (void *)0);
if (selrig->ICOMmainsub) {
useB = false;
selrig->selectA();
vfo = &vfoA;
}
}
}
break;
case SWAP:
trace(1, "execute swapab()");
rig_trace(1, "execute swapab()");
execute_swapAB();
break;
case A2B:
trace(1, "execute A2B()");
rig_trace(1, "execute A2B()");
execute_A2B();
break;
default:
trace(2, "default ", printXCVR_STATE(nuvals.vfo).c_str());
if (useB) serviceB(nuvals.vfo);
else serviceA(nuvals.vfo);
break;
}
}
{
while (!srvc_reqs.empty()) {
pending.push(srvc_reqs.front());
srvc_reqs.pop();
}
while (!pending.empty()) {
srvc_reqs.push(pending.front());
pending.pop();
}
}
Fl::awake(updateUI);
}
void find_bandwidth(XCVR_STATE &nuvals)
{
if (nuvals.iBW == 255) return;
if (!selrig->has_bandwidth_control) {
nuvals.iBW = 255;
return;
}
if (nuvals.iBW > 65536) {
nuvals.iBW /= 256;
nuvals.iBW /= 256;
int i = 0;
while ( selrig->bandwidths_[i] &&
atol(selrig->bandwidths_[i]) < nuvals.iBW) {
i++;
}
if (!selrig->bandwidths_[i]) i--;
nuvals.iBW = i;
}
}
void serviceA(XCVR_STATE nuvals)
{
if (nuvals.freq == 0) nuvals.freq = vfoA.freq;
if (nuvals.imode == -1) nuvals.imode = vfoA.imode;
// find_bandwidth(nuvals);
if (nuvals.iBW == 255) nuvals.iBW = vfoA.iBW;
if (useB) {
if (selrig->can_change_alt_vfo) {
trace(2, "B active, set alt vfo A", printXCVR_STATE(nuvals).c_str());
rig_trace(2, "B active, set alt vfo A", printXCVR_STATE(nuvals).c_str());
if (vfoA.imode != nuvals.imode) {
if (selrig->name_ == rig_FT891.name_) {
// Mode change on ft891 requires mode first, so set all values
yaesu891UpdateA(&nuvals);
vfoA = nuvals;
} else {
selrig->set_modeA(nuvals.imode);
}
}
if (vfoA.iBW != nuvals.iBW)
selrig->set_bwA(nuvals.iBW);
if (vfoA.freq != nuvals.freq)
selrig->set_vfoA(nuvals.freq);
vfoA = nuvals;
} else if (xcvr_name != rig_TT550.name_) {
trace(2, "B active, set vfo A", printXCVR_STATE(nuvals).c_str());
rig_trace(2, "B active, set vfo A", printXCVR_STATE(nuvals).c_str());
useB = false;
selrig->selectA();
if (vfoA.imode != nuvals.imode)
selrig->set_modeA(nuvals.imode);
if (vfoA.iBW != nuvals.iBW)
selrig->set_bwA(nuvals.iBW);
if (vfoA.freq != nuvals.freq)
selrig->set_vfoA(nuvals.freq);
useB = true;
selrig->selectB();
vfoA = nuvals;
}
Fl::awake(setFreqDispA, (void *)nuvals.freq);
return;
}
trace(2, "service VFO A", printXCVR_STATE(nuvals).c_str());
if ((nuvals.imode != -1) && (vfoA.imode != nuvals.imode)) {
if (selrig->name_ == rig_FT891.name_) {
// Mode change on ft891 can change frequency, so set all values
yaesu891UpdateA(&nuvals);
vfoA = nuvals;
set_bandwidth_control();
} else {
std::string m1, m2;
m1 = selrig->modes_[nuvals.imode];
m2 = selrig->modes_[vfoA.imode];
selrig->set_modeA(vfoA.imode = nuvals.imode);
set_bandwidth_control();
selrig->set_bwA(vfoA.iBW);
if (m1.find("CW") != std::string::npos ||
m2.find("CW") != std::string::npos)
vfoA.freq = nuvals.freq = selrig->get_vfoA();
}
}
if (vfoA.iBW != nuvals.iBW) {
selrig->set_bwA(vfoA.iBW = nuvals.iBW);
}
if (vfoA.freq != nuvals.freq) {
trace(1, "change vfoA frequency");
selrig->set_vfoA(vfoA.freq = nuvals.freq);
}
vfo = &vfoA;
Fl::awake(setFreqDispA, (void *)vfoA.freq);
// Fl::awake(updateUI); // may be redundant
}
void serviceB(XCVR_STATE nuvals)
{
if (nuvals.freq == 0) nuvals.freq = vfoB.freq;
if (nuvals.imode == -1) nuvals.imode = vfoB.imode;
if (nuvals.iBW == 255) nuvals.iBW = vfoB.iBW;
if (!useB) {
if (selrig->can_change_alt_vfo) {
trace(2, "A active, set alt vfo B", printXCVR_STATE(nuvals).c_str());
if (vfoB.imode != nuvals.imode) {
if (selrig->name_ == rig_FT891.name_) {
// Mode change on ft891 requires mode first, so set all values
yaesu891UpdateB(&nuvals);
vfoB = nuvals;
} else {
selrig->set_modeB(nuvals.imode);
}
}
if (vfoB.iBW != nuvals.iBW)
selrig->set_bwB(nuvals.iBW);
if (vfoB.freq != nuvals.freq)
selrig->set_vfoB(nuvals.freq);
vfoB = nuvals;
} else if (xcvr_name != rig_TT550.name_) {
trace(2, "A active, set vfo B", printXCVR_STATE(nuvals).c_str());
useB = true;
selrig->selectB();
if (vfoB.imode != nuvals.imode)
selrig->set_modeB(nuvals.imode);
if (vfoB.iBW != nuvals.iBW)
selrig->set_bwB(nuvals.iBW);
if (vfoB.freq != nuvals.freq)
selrig->set_vfoB(nuvals.freq);
useB = false;
selrig->selectA();
vfoB = nuvals;
}
Fl::awake(setFreqDispB, (void *)nuvals.freq);
return;
}
trace(2, "service VFO B", printXCVR_STATE(nuvals).c_str());
if ((nuvals.imode != -1) && (vfoB.imode != nuvals.imode)) {
std::string m1, m2;
m1 = selrig->modes_[nuvals.imode];
m2 = selrig->modes_[vfoB.imode];
selrig->set_modeB(vfoB.imode = nuvals.imode);
set_bandwidth_control();
selrig->set_bwB(vfoB.iBW);
if (m1.find("CW") != std::string::npos ||
m2.find("CW") != std::string::npos)
vfoB.freq = nuvals.freq = selrig->get_vfoB();
}
if (vfoB.iBW != nuvals.iBW) {
selrig->set_bwB(vfoB.iBW = nuvals.iBW);
}
if (vfoB.freq != nuvals.freq)
selrig->set_vfoB(vfoB.freq = nuvals.freq);
vfo = &vfoB;
Fl::awake(setFreqDispB, (void *)vfoB.freq);
}
bool close_rig = false;
void * serial_thread_loop(void *d)
{
static int loopcount = progStatus.serloop_timing / 10;
static int poll_nbr = 0;
for(;;) {
if (!run_serial_thread) break;
MilliSleep(10);
if (bypass_serial_thread_loop) {
goto serial_bypass_loop;
}
if (close_rig) {
trace(1, "serial_thread_loop: close_rig");
return NULL;
}
//send any freq/mode/bw changes in the queu
process_sliders();
if (!srvc_reqs.empty())
serviceQUE();
if (!PTT) {
if (resetrcv) {
Fl::awake(zeroXmtMeters, 0);
resetrcv = false;
loopcount = progStatus.serloop_timing / 10;
poll_nbr = 0;
}
resetxmt = true;
if (--loopcount <= 0) {
loopcount = progStatus.serloop_timing / 10;
poll_nbr++;
if (xcvr_name == rig_K3.name_) {
read_K3();
}
else if (xcvr_name == rig_KX3.name_) {
read_KX3();
}
if ((xcvr_name == rig_K2.name_) ||
(selrig->has_get_info &&
(progStatus.poll_frequency ||
progStatus.poll_mode ||
progStatus.poll_bandwidth) ) )
read_info();
if (bypass_serial_thread_loop) {
trace(1, "bypass serial thread loop");
goto serial_bypass_loop;// continue;
}
poll_parameters = &RX_poll_pairs[0];
while (poll_parameters->poll) {
// need to put thread asleep to allow other threads
// access to serial mutex
MilliSleep(1);
if (!srvc_reqs.empty()) goto serial_bypass_loop;//break;
if (PTT) {
trace(1, "PTT detected");
goto serial_bypass_loop;//break;
}
if (bypass_serial_thread_loop) {
trace(1, "bypass_serial_thread_loop");
goto serial_bypass_loop;//break;
}
if (*(poll_parameters->poll) && !(poll_nbr % *(poll_parameters->poll))) {
guard_lock serial_lock(&mutex_serial);
(poll_parameters->pollfunc)();
}
poll_parameters++;
}
}
} else {
if (resetxmt) {
Fl::awake(updateSmeter, (void *)(0));
resetxmt = false;
loopcount = progStatus.serloop_timing / 10;
poll_nbr = 0;
}
resetrcv = true;
if (!srvc_reqs.empty()) goto serial_bypass_loop;
if (--loopcount <= 0) {
loopcount = progStatus.serloop_timing / 10;
poll_nbr++;
poll_parameters = &TX_poll_pairs[0];
while (poll_parameters->poll) {
MilliSleep(1);
if (!srvc_reqs.empty()) goto serial_bypass_loop;
if (!PTT) {
trace(1, "!PTT detected");
goto serial_bypass_loop;
}
if (*(poll_parameters->poll) && !(poll_nbr % *(poll_parameters->poll))) {
guard_lock serial_lock(&mutex_serial);
(poll_parameters->pollfunc)();
}
poll_parameters++;
}
}
}
serial_bypass_loop: ;
}
return NULL;
}
//=============================================================================
void setBW()
{
XCVR_STATE fm = *vfo;
fm.src = UI;
fm.iBW = opBW->index();
guard_lock que_lock( &mutex_srvc_reqs, "setBW" );
srvc_reqs.push( VFOQUEUE((useB ? vB : vA), fm));
}
void setDSP()
{
XCVR_STATE fm = *vfo;
fm.src = UI;
fm.iBW = ((opDSP_hi->index() << 8) | 0x8000) | (opDSP_lo->index() & 0xFF) ;
guard_lock que_lock( & mutex_srvc_reqs, "setDSP" );
srvc_reqs.push ( VFOQUEUE((useB ? vB : vA), fm));
}
void selectDSP()
{
if (btnDSP->label()[0] == selrig->SL_label[0]) {
btnDSP->label(selrig->SH_label);
btnDSP->redraw_label();
opDSP_hi->show();
opDSP_lo->hide();
} else {
btnDSP->label(selrig->SL_label);
btnDSP->redraw_label();
opDSP_lo->show();
opDSP_hi->hide();
}
}
void selectFILT()
{
guard_lock lock(&mutex_serial);
btnFILT->label(selrig->nextFILT());
btnFILT->redraw_label();
}
// set_bandwidth_control updates iBW and then posts the call for
// the UI thread to updateBandwidthControl
// changes to the UI cannot come from any thread other than the
// main FL thread! Doing otherwise can cause what appears to be
// random program crashes.
void set_bandwidth_control()
{
if (!selrig->has_bandwidth_control) return;
vfo->iBW = selrig->def_bandwidth(vfo->imode);
if (vfo->iBW < 256) {
int i = 0;
while (selrig->bandwidths_[i]) i++;
i--;
if (vfo->iBW > i) vfo->iBW = selrig->def_bandwidth(vfo->imode);
}
useB ? vfoB.iBW = vfo->iBW : vfoA.iBW = vfo->iBW;
Fl::awake(updateBandwidthControl);
}
void updateBandwidthControl(void *d)
{
if (selrig->has_bandwidth_control) {
if (selrig->adjust_bandwidth(vfo->imode) != -1) {
opBW->clear();
rigbws_.clear();
for (int i = 0; selrig->bandwidths_[i] != NULL; i++) {
rigbws_.push_back(selrig->bandwidths_[i]);
opBW->add(selrig->bandwidths_[i]);
}
if (selrig->has_dsp_controls) {
opDSP_lo->clear();
opDSP_hi->clear();
for (int i = 0; selrig->dsp_SL[i] != NULL; i++)
opDSP_lo->add(selrig->dsp_SL[i]);
for (int i = 0; selrig->dsp_SH[i] != NULL; i++)
opDSP_hi->add(selrig->dsp_SH[i]);
if (vfo->iBW > 256) {
opBW->index(0);
opBW->hide();
opBW->hide();
opDSP_lo->index(vfo->iBW & 0xFF);
opDSP_lo->hide();
opDSP_hi->index((vfo->iBW >> 8) & 0x7F);
btnDSP->label(selrig->SL_label);
opDSP_lo->show();
btnDSP->show();
btnFILT->hide();
} else {
opDSP_lo->hide();
opDSP_hi->hide();
btnDSP->hide();
btnFILT->hide();
opBW->index(vfo->iBW);
opBW->show();
}
} else { // no DSP control so update BW control, hide DSP
opDSP_lo->hide();
opDSP_hi->hide();
btnDSP->hide();
opBW->index(vfo->iBW);
if (selrig->has_FILTER) {
btnFILT->show();
btnFILT->label(
selrig->FILT(
useB ? vfoB.filter : vfoA.filter));
btnFILT->redraw_label();
opBW->resize(opDSP_lo->x(), opDSP_lo->y(), opDSP_lo->w(), opDSP_lo->h());
opBW->redraw();
}
opBW->show();
}
// Allow BW to receive rig updates as value is changed there, without needing
// to click the dropdown first
opBW->isbusy(false);
}
} else { // no BW, no DSP controls
opBW->index(0);
opBW->hide();
btnFILT->hide();
opDSP_lo->index(0);
opDSP_hi->index(0);
btnDSP->hide();
opDSP_lo->hide();
opDSP_hi->hide();
}
}
void setMode()
{
XCVR_STATE fm = *vfo;
fm.imode = opMODE->index();
fm.iBW = selrig->def_bandwidth(fm.imode);
fm.src = UI;
if (selrig->has_FILTER) {
fm.filter = selrig->get_FILT(fm.imode);
if (useB) fm.filter = selrig->get_FILT(fm.imode);
}
guard_lock que_lock( &mutex_srvc_reqs, "setMode" );
srvc_reqs.push(VFOQUEUE( (useB ? vB : vA), fm));
}
void sortList() {
if (!numinlist) return;
ATAG_XCVR_STATE temp;
for (int i = 0; i < numinlist - 1; i++)
for (int j = i + 1; j < numinlist; j++)
if (oplist[i].freq > oplist[j].freq) {
temp = oplist[i];
oplist[i] = oplist[j];
oplist[j] = temp;
}
}
void clearList() {
if (!numinlist) return;
for (int i = 0; i < LISTSIZE; i++) {
oplist[i].freq = 0;
oplist[i].imode = USB;
oplist[i].iBW = 0;
memset(oplist[i].alpha_tag, 0, ATAGSIZE);
}
FreqSelect->clear();
numinlist = 0;
inAlphaTag->value("");
}
void updateSelect() {
char szline[80 + ATAGSIZE];
char szatag[ATAGSIZE];
int i;
FreqSelect->clear();
if (!numinlist) return;
sortList();
// stripe lines
int bg1, bg2, bg_clr;
bg1 = FL_WHITE; bg2 = FL_LIGHT2;
for (int n = 0; n < numinlist; n++) {
memset(szline, 0, sizeof(szline));
memset(szatag, 0, sizeof(szatag));
for (i = 0; i < ATAGSIZE - 1; i++) {
szatag[i] = oplist[n].alpha_tag[i];
if (szatag[i] == 0) szatag[i] = ' ';
}
bg_clr = (n % 2) ? bg1 : bg2;
snprintf(szline, sizeof(szline),
"@B%d@r%.3f\t@B%d@r%s\t@B%d@r%s\t@B%d@r%s", bg_clr,
oplist[n].freq / 1000.0, bg_clr,
selrig->get_bwname_(oplist[n].iBW, oplist[n].imode), bg_clr,
selrig->get_modename_(oplist[n].imode), bg_clr,
szatag );
FreqSelect->add (szline);
}
inAlphaTag->value("");
}
void addtoList(int val, int imode, int iBW) {
if (numinlist < LISTSIZE) {
oplist[numinlist].imode = imode;
oplist[numinlist].freq = val;
oplist[numinlist].iBW = iBW;
memset(oplist[numinlist].alpha_tag, 0, ATAGSIZE);
numinlist++;
}
}
void readFile() {
ifstream iList(defFileName.c_str());
if (!iList) {
fl_message ("Could not open %s", defFileName.c_str());
return;
}
clearList();
int i = 0, mode, bw;
long freq;
while (!iList.eof()) {
freq = 0L; mode = -1;
iList >> freq >> mode >> bw;
if (freq && (mode > -1)) {
oplist[i].freq = freq;
oplist[i].imode = mode;
oplist[i].iBW = (bw == -1 ? 0 : bw);
memset(oplist[i].alpha_tag, 0, ATAGSIZE);
i++;
}
}
iList.close();
numinlist = i;
updateSelect();
}
void readTagFile() {
ifstream iList(defFileName.c_str());
if (!iList) {
fl_message ("Could not open %s", defFileName.c_str());
return;
}
clearList();
int i = 0, mode, bw;
long freq;
string atag;
char ca[ATAGSIZE + 60];
while (!iList.eof()) {
freq = 0L; mode = -1;
atag.clear();
memset(ca, 0, sizeof(ca));
iList >> freq >> mode >> bw;
iList.getline(ca, sizeof(ca) - 1);
atag = ca;
if (freq && (mode > -1)) {
oplist[i].freq = freq;
oplist[i].imode = mode;
oplist[i].iBW = (bw == -1 ? 0 : bw);
// trim leading, trailing spaces and double quotes
atag = lt_trim(atag);
snprintf(oplist[i].alpha_tag, ATAGSIZE, "%s", atag.c_str());
i++;
}
}
iList.close();
numinlist = i;
updateSelect();
}
void buildlist() {
string tmpFN, orgFN;
// check for new Memory-Alpha-Tag file
defFileName = RigHomeDir;
defFileName.append(selrig->name_);
defFileName.append(".mat");
FILE *fh = fopen(defFileName.c_str(), "r");
if (fh != NULL) {
fclose (fh);
readTagFile();
return;
}
// else only read original file to make new MAT file
orgFN = RigHomeDir;
orgFN.append(selrig->name_);
orgFN.append(".arv");
fh = fopen(orgFN.c_str(), "r");
if (fh != NULL) {
fclose (fh);
tmpFN = defFileName;
defFileName = orgFN;
readFile();
defFileName = tmpFN;
return;
}
clearList();
}
// flrig front panel changed
int movFreqA() {
XCVR_STATE nuvfo = vfoA;
nuvfo.freq = FreqDispA->value();
nuvfo.src = UI;
guard_lock que_lock(&mutex_srvc_reqs, "movFreqA");
srvc_reqs.push(VFOQUEUE(vA, nuvfo));
return 1;
}
int movFreqB() {
XCVR_STATE nuvfo = vfoB;
nuvfo.freq = FreqDispB->value();
nuvfo.src = UI;
guard_lock que_lock(&mutex_srvc_reqs, "movFreqB");
srvc_reqs.push(VFOQUEUE(vB, nuvfo));
return 1;
}
void execute_swapAB()
{
if (selrig->canswap()) {
selrig->swapAB();
if (selrig->ICOMmainsub) {
XCVR_STATE temp = vfoA;
vfoA = vfoB;
vfoB = temp;
selrig->selectA();
vfo = &vfoA;
useB = false;
} else if (selrig->ICOMrig) {
if (useB) {
useB = false;
selrig->selectA();
vfo = &vfoA;
} else {
useB = true;
selrig->selectB();
vfo = &vfoB;
}
} else if (selrig->name_ == rig_FT891.name_) {
// No need for extra select, as swapAB accomplishes this
if (useB) {
useB = false;
vfo = &vfoA;
// Restore mode, then frequency and bandwidth after swap.
yaesu891UpdateA(&vfoA);
}
else {
useB = true;
vfo = &vfoB;
// Restore mode, then frequency and bandwidth after swap.
yaesu891UpdateB(&vfoB);
}
} else {
XCVR_STATE temp = vfoB;
vfoB = vfoA;
vfoA = temp;
if (useB) {
selrig->selectB();
vfo = &vfoB;
} else {
selrig->selectA();
vfo = &vfoA;
}
}
} else {
if (useB) {
XCVR_STATE vfotemp = vfoA;
selrig->selectA();
vfoA = vfoB;
selrig->set_vfoA(vfoA.freq);
selrig->set_modeA(vfoA.imode);
selrig->set_bwA(vfoA.iBW);
selrig->selectB();
vfoB = vfotemp;
selrig->set_vfoB(vfoB.freq);
selrig->set_modeB(vfoB.imode);
selrig->set_bwB(vfoB.iBW);
vfo = &vfoB;
} else {
XCVR_STATE vfotemp = vfoB;
selrig->selectB();
vfoB = vfoA;
selrig->set_vfoB(vfoB.freq);
selrig->set_modeB(vfoB.imode);
selrig->set_bwB(vfoB.iBW);
selrig->selectA();
vfoA = vfotemp;
selrig->set_vfoA(vfoA.freq);
selrig->set_modeA(vfoA.imode);
selrig->set_bwA(vfoA.iBW);
vfo = &vfoA;
}
}
Fl::awake(updateUI);
}
void cbAswapB()
{
guard_lock lock(&mutex_srvc_reqs, "cbAswapB");
if (Fl::event_button() == FL_RIGHT_MOUSE) {
VFOQUEUE xcvr;
xcvr.change = A2B;
trace(1, "cb Active->Inactive vfo");
srvc_reqs.push(xcvr);
} else {
VFOQUEUE xcvr;
xcvr.change = SWAP;
trace(1, "cb SWAP");
srvc_reqs.push(xcvr);
}
}
void execute_A2B()
{
if (xcvr_name == rig_K3.name_) {
K3_A2B();
} else if (xcvr_name == rig_KX3.name_) {
KX3_A2B();
} else if (xcvr_name == rig_K2.name_) {
trace(1,"cbA2B() 1");
vfoB = vfoA;
selrig->set_vfoB(vfoB.freq);
FreqDispB->value(vfoB.freq);
}
if (selrig->ICOMmainsub) {
useB = false;
selrig->selectA();
selrig->A2B();
vfoB = vfoA;
vfo = &vfoA;
} else if (selrig->has_a2b) {
trace(1,"cbA2B() 2");
selrig->A2B();
if (useB) {
vfoA = vfoB;
FreqDispA->value(vfoA.freq);
} else {
vfoB = vfoA;
FreqDispB->value(vfoB.freq);
}
} else {
if (useB) {
vfoA = vfoB;
if (selrig->name_ == rig_FT891.name_) {
yaesu891UpdateA(&vfoA);
} else {
selrig->set_vfoA(vfoA.freq);
selrig->set_modeA(vfoA.imode);
selrig->set_bwA(vfoA.iBW);
}
FreqDispA->value(vfoA.freq);
} else {
vfoB = vfoA;
if (selrig->name_ == rig_FT891.name_) {
yaesu891UpdateB(&vfoB);
} else {
selrig->set_vfoB(vfoB.freq);
selrig->set_modeB(vfoB.imode);
selrig->set_bwB(vfoB.iBW);
}
FreqDispB->value(vfoB.freq);
}
}
Fl::awake(updateUI);
}
void highlight_vfo(void *d)
{
Fl_Color norm_fg = fl_rgb_color(progStatus.fg_red, progStatus.fg_green, progStatus.fg_blue);
Fl_Color norm_bg = fl_rgb_color(progStatus.bg_red, progStatus.bg_green, progStatus.bg_blue);
Fl_Color dim_bg = fl_color_average( norm_bg, FL_BLACK, 0.75);
FreqDispA->value(vfoA.freq);
FreqDispB->value(vfoB.freq);
if (useB) {
FreqDispA->SetONOFFCOLOR( norm_fg, dim_bg );
FreqDispB->SetONOFFCOLOR( norm_fg, norm_bg );
btnA->value(0);
btnB->value(1);
} else {
FreqDispA->SetONOFFCOLOR( norm_fg, norm_bg );
FreqDispB->SetONOFFCOLOR( norm_fg, dim_bg);
btnA->value(1);
btnB->value(0);
}
FreqDispA->redraw();
FreqDispB->redraw();
btnA->redraw();
btnB->redraw();
Fl::check();
}
void cb_set_split(int val)
{
progStatus.split = val;
VFOQUEUE xcvr_split;
if (val) xcvr_split.change = sON;
else xcvr_split.change = sOFF;
trace(1, (val ? "cb_set_split(ON)" : "cb_set_split(OFF)"));
srvc_reqs.push(xcvr_split);
}
void cb_selectA()
{
guard_lock que_lock( &mutex_srvc_reqs, "cb_selectA");
srvc_reqs.push (VFOQUEUE(sA, vfoA));
return;
}
void cb_selectB()
{
guard_lock que_lock( &mutex_srvc_reqs, "cb_selectB");
srvc_reqs.push (VFOQUEUE(sB, vfoB));
return;
}
void setLower()
{
}
void setUpper()
{
}
void selectFreq() {
long n = FreqSelect->value();
if (!n) return;
n--;
XCVR_STATE fm;
fm.freq = oplist[n].freq;
fm.imode = oplist[n].imode;
fm.iBW = oplist[n].iBW;
fm.src = UI;
if (!useB) {
FreqDispA->value(fm.freq);
guard_lock que_lock(&mutex_srvc_reqs, "selectFreq on A");
srvc_reqs.push(VFOQUEUE(vA, fm));
} else {
FreqDispB->value(fm.freq);
guard_lock que_lock(&mutex_srvc_reqs, "selectFreq on B");
srvc_reqs.push(VFOQUEUE(vB, fm));
}
}
void select_and_close()
{
switch (Fl::event_button()) {
case FL_LEFT_MOUSE:
if (FreqSelect->value() > 0)
inAlphaTag->value(oplist[FreqSelect->value() - 1].alpha_tag);
if (Fl::event_clicks()) { // double click
selectFreq();
cbCloseMemory();
}
break;
case FL_RIGHT_MOUSE:
if (FreqSelect->value() > 0)
inAlphaTag->value(oplist[FreqSelect->value() - 1].alpha_tag);
selectFreq();
break;
default:
break;
}
// update Alpha Tag field when keyboard scrolling
switch (Fl::event_key()) {
case FL_Up:
case FL_Down:
if (FreqSelect->value() > 0)
inAlphaTag->value(oplist[FreqSelect->value() - 1].alpha_tag);
break;
default:
break;
}
}
void delFreq() {
if (FreqSelect->value()) {
long n = FreqSelect->value() - 1;
for (int i = n; i < numinlist; i ++)
oplist[i] = oplist[i+1];
if (numinlist) {
oplist[numinlist - 1].imode = USB;
oplist[numinlist - 1].freq = 0;
oplist[numinlist - 1].iBW = 0;
memset(oplist[numinlist - 1].alpha_tag, 0, ATAGSIZE);
numinlist--;
}
updateSelect();
}
}
void addFreq() {
if (useB) {
long freq = FreqDispB->value();
if (!freq) return;
int mode = opMODE->index();
int bw;
if (btnDSP->visible())
bw = ((opDSP_hi->index() << 8) | 0x8000) | (opDSP_lo->index() & 0xFF) ;
else
bw = opBW->index();
for (int n = 0; n < numinlist; n++)
if (freq == oplist[n].freq && mode == oplist[n].imode) {
oplist[n].iBW = bw;
updateSelect(); // update list
return;
}
addtoList(freq, mode, bw);
updateSelect();
FreqDispB->visual_beep();
} else {
long freq = FreqDispA->value();
if (!freq) return;
int mode = opMODE->index();
int bw;
if (btnDSP->visible())
bw = ((opDSP_hi->index() << 8) | 0x8000) | (opDSP_lo->index() & 0xFF) ;
else
bw = opBW->index();
for (int n = 0; n < numinlist; n++)
if (freq == oplist[n].freq && mode == oplist[n].imode) {
oplist[n].iBW = bw;
updateSelect(); // update list
return;
}
addtoList(freq, mode, bw);
updateSelect();
FreqDispA->visual_beep();
}
}
void cbRIT()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cbRIT()");
if (selrig->has_rit)
selrig->setRit((int)cntRIT->value());
}
void cbXIT()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cbXIT()");
selrig->setXit((int)cntXIT->value());
}
void cbBFO()
{
if (selrig->has_bfo) {
guard_lock serial_lock(&mutex_serial);
trace(1, "cbBFO()");
selrig->setBfo((int)cntBFO->value());
}
}
void cbAttenuator()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cbAttenuator()");
progStatus.attenuator = selrig->next_attenuator();
selrig->set_attenuator(progStatus.attenuator);
}
void setAttControl(void *d)
{
int val = (long)d;
btnAttenuator->value(val);
}
void cbPreamp()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cbPreamp()");
progStatus.preamp = selrig->next_preamp();
selrig->set_preamp(progStatus.preamp);
}
void setPreampControl(void *d)
{
int val = (long)d;
btnPreamp->value(val);
}
void cbAN()
{
progStatus.auto_notch = btnAutoNotch->value();
guard_lock serial_lock(&mutex_serial);
trace(1, "cbAN()");
selrig->set_auto_notch(progStatus.auto_notch);
}
void cbbtnNotch()
{
if (!selrig->has_notch_control) return;
guard_lock serial_lock(&mutex_serial);
trace(1, "cbbtnNotch()");
int btn, cnt = 0;
btn = btnNotch->value();
progStatus.notch = btn;
selrig->set_notch(btn, progStatus.notch_val);
MilliSleep(progStatus.comm_wait);
int on, val = progStatus.notch_val;
on = selrig->get_notch(val);
while ((on != btn) && (cnt++ < 10)) {
MilliSleep(progStatus.comm_wait);
on = selrig->get_notch(val);
Fl::awake();
}
}
void setNotch()
{
if (!selrig->has_notch_control) return;
trace(1, "setNotch()");
int ev = Fl::event();
if (ev == FL_DRAG || ev == FL_PUSH || ev == FL_MOUSEWHEEL)
inhibit_notch = 2;
else if (ev == FL_RELEASE || ev == FL_LEAVE)
inhibit_notch = 1;
int set = 0;
if (sldrNOTCH) {
set = sldrNOTCH->value();
} else {
set = spnrNOTCH->value();
}
progStatus.notch_val = set;
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::NOTCH;
slider.val = set;
sliders.push(slider);
}
// called from xml_io thread
// xcvr updated in xml_io / xml_server code
// this only updates the dialog controls
void setNotchControl(void *d)
{
if (sldrNOTCH) sldrNOTCH->value(progStatus.notch_val);
if (spnrNOTCH) spnrNOTCH->value(progStatus.notch_val);
btnNotch->value(progStatus.notch);
}
void adjust_if_shift_control(void *d)
{
if (sldrIFSHIFT) sldrIFSHIFT->minimum(selrig->if_shift_min);
if (sldrIFSHIFT) sldrIFSHIFT->maximum(selrig->if_shift_max);
if (sldrIFSHIFT) sldrIFSHIFT->step(selrig->if_shift_step);
if (sldrIFSHIFT) sldrIFSHIFT->value(selrig->if_shift_mid);
if (sldrIFSHIFT) sldrIFSHIFT->redraw();
if (spnrIFSHIFT) spnrIFSHIFT->minimum(selrig->if_shift_min);
if (spnrIFSHIFT) spnrIFSHIFT->maximum(selrig->if_shift_max);
if (spnrIFSHIFT) spnrIFSHIFT->step(selrig->if_shift_step);
if (spnrIFSHIFT) spnrIFSHIFT->value(selrig->if_shift_mid);
if (spnrIFSHIFT) spnrIFSHIFT->redraw();
btnIFsh->value(0);
btnIFsh->redraw();
}
void setIFshiftButton(void *d)
{
bool b = (bool)d;
if (b && !btnIFsh->value()) {
btnIFsh->value(1);
}
else if (!b && btnIFsh->value()) {
btnIFsh->value(0);
if (sldrIFSHIFT) sldrIFSHIFT->value( selrig->if_shift_mid );
if (spnrIFSHIFT) spnrIFSHIFT->value( selrig->if_shift_mid );
}
}
void setIFshiftControl(void *d)
{
int val = (long)d;
if (sldrIFSHIFT) {
if (sldrIFSHIFT->value() != val)
sldrIFSHIFT->value(val);
}
if (spnrIFSHIFT) {
if (spnrIFSHIFT->value() != val)
spnrIFSHIFT->value(val);
}
btnIFsh->value( val != selrig->if_shift_mid );
}
void setIFshift()
{
trace(1, "setIFshift()");
int ev = Fl::event();
if (ev == FL_DRAG || ev == FL_PUSH || ev == FL_MOUSEWHEEL)
inhibit_shift = 2;
else if (ev == FL_RELEASE || ev == FL_LEAVE)
inhibit_shift = 1;
int btn = 0, set = 0;
btn = btnIFsh->value();
progStatus.shift = btn;
if (sldrIFSHIFT) {
set = sldrIFSHIFT->value();
} else if (spnrIFSHIFT) {
set = spnrIFSHIFT->value();
}
progStatus.shift_val = set;
if (xcvr_name == rig_TS990.name_) {
guard_lock lckser(&mutex_serial);
if (progStatus.shift)
selrig->set_monitor(1);
else
selrig->set_monitor(0);
}
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::SHIFT;
slider.val = set;
sliders.push(slider);
}
void cbIFsh()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "setIFsh()");
int btn, set, cnt = 0;
if (sldrIFSHIFT) {
set = sldrIFSHIFT->value();
btn = btnIFsh->value();
} else {
set = spnrIFSHIFT->value();
btn = btnIFsh->value();
}
if (btn == 0) set = 0;
selrig->set_if_shift(set);
MilliSleep(progStatus.comm_wait);
int val, on;
on = selrig->get_if_shift(val);
while ((on != btn) && (cnt++ < 10)) {
MilliSleep(progStatus.comm_wait);
on = selrig->get_if_shift(val);
Fl::awake();
}
}
void setLOCK()
{
progStatus.pbt_lock = btnLOCK->value();
if (progStatus.pbt_lock) {
guard_lock serial_lock(&mutex_serial);
progStatus.pbt_outer = progStatus.pbt_inner;
sldrOUTER->value(progStatus.pbt_outer);
selrig->set_pbt_outer(progStatus.pbt_outer);
sldrOUTER->redraw();
}
}
void setINNER()
{
if (progStatus.pbt_lock) {
sldrOUTER->value(sldrINNER->value());
sldrOUTER->redraw();
}
int ev = Fl::event();
if (ev == FL_DRAG || ev == FL_PUSH || ev == FL_MOUSEWHEEL)
inhibit_pbt = 2;
else if (ev == FL_RELEASE || ev == FL_LEAVE)
inhibit_pbt = 1;
progStatus.pbt_inner = sldrINNER->value();
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::INNER;
if (progStatus.pbt_lock) slider.fnc = SLIDER::LOCK;
slider.val = progStatus.pbt_inner;
sliders.push(slider);
}
void setOUTER()
{
if (progStatus.pbt_lock) {
sldrINNER->value(sldrOUTER->value());
sldrINNER->redraw();
}
int ev = Fl::event();
if (ev == FL_DRAG || ev == FL_PUSH || ev == FL_MOUSEWHEEL)
inhibit_pbt = 2;
else if (ev == FL_RELEASE || ev == FL_LEAVE)
inhibit_pbt = 1;
progStatus.pbt_outer = sldrOUTER->value();
if (progStatus.pbt_lock) {
progStatus.pbt_inner = progStatus.pbt_outer;
sldrINNER->value(progStatus.pbt_outer);
sldrINNER->redraw();
}
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::OUTER;
if (progStatus.pbt_lock) slider.fnc = SLIDER::LOCK;
slider.val = progStatus.pbt_outer;
sliders.push(slider);
}
void setCLRPBT()
{
progStatus.pbt_inner = progStatus.pbt_outer = 0;
sldrOUTER->value(0);
sldrOUTER->redraw();
sldrINNER->value(0);
sldrINNER->redraw();
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::INNER;
slider.val = 0;
sliders.push(slider);
slider.fnc = SLIDER::OUTER;
sliders.push(slider);
}
//----------------------------------------------------------------------
// these only apply to the IC7610
//----------------------------------------------------------------------
void digi_sel_on_off()
{
selrig->set_digi_sel(progStatus.digi_sel_on_off);
}
void set_ic7610_digi_sel_on_off(void *)
{
ic7610digi_sel_on_off->value(progStatus.digi_sel_on_off);
}
void digi_sel_val()
{
selrig->set_digi_val(progStatus.digi_sel_val);
}
void set_ic7610_digi_sel_val(void *)
{
ic7610_digi_sel_val->value(progStatus.digi_sel_val);
}
void dual_watch()
{
selrig->set_dual_watch(progStatus.dual_watch);
}
void set_ic7610_dual_watch(void *)
{
}
void index_att()
{
selrig->set_index_att(progStatus.index_ic7610att);
}
void set_ic7610_index_att(void *)
{
ic7610att->index(progStatus.index_ic7610att);
}
//----------------------------------------------------------------------
void cbEventLog()
{
debug::show();
}
void setVolume()
{
trace(1, "setVolume()");
int ev = Fl::event();
if (ev == FL_DRAG || ev == FL_PUSH || ev == FL_MOUSEWHEEL)
inhibit_volume = 2;
else if (ev == FL_RELEASE || ev == FL_LEAVE)
inhibit_volume = 1;
int set;
if (spnrVOLUME) set = spnrVOLUME->value();
else set = sldrVOLUME->value();
progStatus.volume = set;
SLIDER sldr;
sldr.fnc = SLIDER::VOLUME;
sldr.val = set;
guard_lock lcksldr(&mutex_sliders);
sliders.push(sldr);
}
void setVolumeControl(void* d)
{
guard_lock serial_lock(&mutex_serial);
trace(1, "setMicGainControl()");
if (sldrVOLUME) sldrVOLUME->value(progStatus.volume);
if (spnrVOLUME) spnrVOLUME->value(progStatus.volume);
}
void cbMute()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cbMute()");
int set = 0, get, cnt = 0;
if (btnVol->value() == 0) {
if (spnrVOLUME) spnrVOLUME->deactivate();
if (sldrVOLUME) sldrVOLUME->deactivate();
} else {
if (spnrVOLUME) {
spnrVOLUME->activate();
set = spnrVOLUME->value();
}
if (sldrVOLUME) {
sldrVOLUME->activate();
set = sldrVOLUME->value();
}
}
selrig->set_volume_control(set);
MilliSleep(progStatus.comm_wait);
get = selrig->get_volume_control();
while (get != set && cnt++ < 10) {
MilliSleep(progStatus.comm_wait);
get = selrig->get_volume_control();
Fl::awake();
}
progStatus.volume = set;
}
void setMicGain()
{
Fl_Event evt = (Fl_Event)Fl::event();;
if (evt == FL_DRAG)
inhibit_mic = 2;
else
inhibit_mic = 1;
stringstream str;
str << "setMicGain(), evt=" << evt << ", inhibit_mic=" << inhibit_mic;
trace(1, str.str().c_str());
int set = 0;
if (sldrMICGAIN) set = sldrMICGAIN->value();
if (spnrMICGAIN) set = spnrMICGAIN->value();
progStatus.mic_gain = set;
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::MIC;
slider.val = set;
sliders.push(slider);
}
void setMicGainControl(void* d)
{
guard_lock serial_lock(&mutex_serial);
trace(1, "setMicGainControl()");
if (sldrMICGAIN) sldrMICGAIN->value(progStatus.mic_gain);
if (spnrMICGAIN) spnrMICGAIN->value(progStatus.mic_gain);
}
static int img = -1;
void set_power_controlImage(double pwr)
{
if (progStatus.pwr_scale == 0 || (progStatus.pwr_scale == 5 && pwr <= 5.0)) {
if (img != 1) {
img = 1;
scalePower->image(image_p5);
sldrFwdPwr->maximum(5.0);
sldrFwdPwr->minimum(0.0);
scalePower->redraw();
}
}
else if (progStatus.pwr_scale == 1 || (progStatus.pwr_scale == 5 && pwr <= 25.0)) {
if (img != 2) {
img = 2;
scalePower->image(image_p25);
sldrFwdPwr->maximum(25.0);
sldrFwdPwr->minimum(0.0);
scalePower->redraw();
}
}
else if (progStatus.pwr_scale == 2 || (progStatus.pwr_scale == 5 && pwr <= 50.0)) {
if (img != 3) {
img = 3;
scalePower->image(image_p50);
sldrFwdPwr->maximum(50.0);
sldrFwdPwr->minimum(0.0);
scalePower->redraw();
}
}
else if (progStatus.pwr_scale == 3 || (progStatus.pwr_scale == 5 && pwr <= 100.0)) {
if (img != 4) {
img = 4;
scalePower->image(image_p100);
sldrFwdPwr->maximum(100.0);
sldrFwdPwr->minimum(0.0);
scalePower->redraw();
}
}
else if (progStatus.pwr_scale == 4 || (pwr > 100.0)) {
if (img != 5) {
img = 5;
scalePower->image(image_p200);
sldrFwdPwr->maximum(200.0);
sldrFwdPwr->minimum(0.0);
scalePower->redraw();
}
}
return;
}
void setPower()
{
Fl_Event evt = (Fl_Event)Fl::event();;
if (evt == FL_DRAG) {
inhibit_power = 2;
} else {
inhibit_power = 1;
}
stringstream str;
str << "setPower(), evt=" << evt << ", inhibit_power=" << inhibit_power;
trace(1, str.str().c_str());
int set = 0;
if (spnrPOWER) set = progStatus.power_level = spnrPOWER->value();
if (sldrPOWER) set = progStatus.power_level = sldrPOWER->value();
if (xcvr_name == rig_K2.name_) {
double min, max, step;
selrig->get_pc_min_max_step(min, max, step);
if (spnrPOWER) spnrPOWER->minimum(min);
if (spnrPOWER) spnrPOWER->maximum(max);
if (spnrPOWER) spnrPOWER->step(step);
if (spnrPOWER) spnrPOWER->value(progStatus.power_level);
if (spnrPOWER) spnrPOWER->redraw();
if (sldrPOWER) sldrPOWER->minimum(min);
if (sldrPOWER) sldrPOWER->maximum(max);
if (sldrPOWER) sldrPOWER->step(step);
if (sldrPOWER) sldrPOWER->value(progStatus.power_level);
if (sldrPOWER) sldrPOWER->redraw();
}
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::POWER;
slider.val = set;
sliders.push(slider);
}
void cbTune()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cbTune()");
selrig->tune_rig(2);
}
void cb_tune_on_off()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_tune_on_off()");
selrig->tune_rig(btn_tune_on_off->value());
}
void cbPTT()
{
setPTT(reinterpret_cast(btnPTT->value()));
}
void setSQUELCH()
{
trace(1, "setSQUELCH()");
int ev = Fl::event();
if (ev == FL_DRAG || ev == FL_PUSH || ev == FL_MOUSEWHEEL)
inhibit_squelch = 2;
else if (ev == FL_RELEASE || ev == FL_LEAVE)
inhibit_squelch = 1;
int set = 0;
if (sldrSQUELCH) set = sldrSQUELCH->value();
if (spnrSQUELCH) set = spnrSQUELCH->value();
progStatus.squelch = set;
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::SQUELCH;
slider.val = set;
sliders.push(slider);
}
int agcwas = 0;
void redrawAGC()
{
const char *lbl = selrig->agc_label();
int val = progStatus.agc_level;
btnAGC->label(lbl);
btnAGC->redraw_label();
int rignbr = 0;
if (xcvr_name == rig_IC7200.name_) rignbr = 1;
if (xcvr_name == rig_IC7300.name_) rignbr = 2;
if (rignbr) {
if (val == 0) btnAGC->selection_color(FL_BACKGROUND_COLOR); // off
if (val == 1) btnAGC->selection_color(
rignbr == 1 ? FL_GREEN : FL_RED); // fast
if (val == 2) btnAGC->selection_color(
rignbr == 1 ? FL_RED : FL_YELLOW); // med / slow
if (val == 3) btnAGC->selection_color(FL_GREEN); // slow
btnAGC->value(val > 0);
} else {
if (val == 0)
btnAGC->value(0);
else
btnAGC->value(1);
}
if (agcwas != val) {
agcwas = val;
}
btnAGC->redraw();
}
void setAGC(void *)
{
if (!selrig->has_agc_control) return;
redrawAGC();
}
void cbAGC()
{
if (!selrig->has_agc_control) return;
guard_lock serial_lock(&mutex_serial);
trace(1, "cbAGC()");
progStatus.agc_level = selrig->incr_agc();
redrawAGC();
}
void setRFGAIN()
{
trace(1, "setRFGAIN()");
int ev = Fl::event();
if (ev == FL_DRAG || ev == FL_PUSH || ev == FL_MOUSEWHEEL)
inhibit_rfgain = 2;
else if (ev == FL_RELEASE || ev == FL_LEAVE)
inhibit_rfgain = 1;
int set = 0;
if (spnrRFGAIN) set = spnrRFGAIN->value();
if (sldrRFGAIN) set = sldrRFGAIN->value();
progStatus.rfgain = set;
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::RFGAIN;
slider.val = set;
sliders.push(slider);
}
void setRFGAINControl(void* d)
{
guard_lock serial_lock(&mutex_serial);
trace(1, "setRFGAINControl()");
if (sldrRFGAIN) sldrRFGAIN->value(progStatus.rfgain);
if (spnrRFGAIN) spnrRFGAIN->value(progStatus.rfgain);
}
void updateALC(void * d)
{
if (meter_image != ALC_IMAGE) return;
double data = (long)d;
sldrRcvSignal->hide();
sldrSWR->hide();
sldrALC->show();
sldrALC->value(data);
sldrALC->redraw();
}
void updateSWR(void * d)
{
if (meter_image != SWR_IMAGE) return;
double data = (long)d;
if (selrig->has_swr_control) {
sldrRcvSignal->hide();
sldrALC->hide();
sldrSWR->show();
}
sldrSWR->value(data);
sldrSWR->redraw();
}
void updateFwdPwr(void *d)
{
double power = (long)d;
if (!sldrFwdPwr->visible()) {
sldrFwdPwr->show();
}
if (xcvr_name == rig_FT817.name_) power /= 10;
if (xcvr_name == rig_KX3.name_ && selrig->power_10x()) power /= 10;
sldrFwdPwr->value(power);
sldrFwdPwr->redraw();
if (selrig->has_power_control)
set_power_controlImage(power);
}
void updateSquelch(void *d)
{
if (sldrSQUELCH) sldrSQUELCH->value((long)d);
if (sldrSQUELCH) sldrSQUELCH->redraw();
if (spnrSQUELCH) spnrSQUELCH->value((long)d);
if (spnrSQUELCH) spnrSQUELCH->redraw();
}
void updateRFgain(void *d)
{
if (spnrRFGAIN) {
spnrRFGAIN->value((long)d);
spnrRFGAIN->redraw();
}
if (sldrRFGAIN) {
sldrRFGAIN->value((long)d);
sldrRFGAIN->redraw();
}
}
void zeroXmtMeters(void *d)
{
sldrFwdPwr->clear();
sldrALC->clear();
sldrSWR->clear();
updateFwdPwr(0);
updateALC(0);
updateSWR(0);
}
void setFreqDispA(void *d)
{
long f = (long)d;
FreqDispA->value(f);
FreqDispA->redraw();
}
void setFreqDispB(void *d)
{
long f = (long)d;
FreqDispB->value(f);
FreqDispB->redraw();
}
void updateSmeter(void *d) // 0 to 100;
{
double smeter = (long)d;
if (!sldrRcvSignal->visible()) {
sldrRcvSignal->show();
sldrFwdPwr->hide();
sldrALC->hide();
sldrSWR->hide();
}
sldrRcvSignal->value(smeter);
sldrRcvSignal->redraw();
}
void saveFreqList()
{
string atag;
if (!numinlist) {
remove(defFileName.c_str());
return;
}
ofstream oList(defFileName.c_str());
if (!oList) {
fl_message ("Could not write to %s", defFileName.c_str());
return;
}
for (int i = 0; i < numinlist; i++) {
atag = oplist[i].alpha_tag;
oList << oplist[i].freq << " " << oplist[i].imode << " " << oplist[i].iBW << " \"" << atag.c_str() << "\"" << endl;
}
oList.close();
}
void setPTT( void *d)
{
guard_lock que_lock(&mutex_srvc_reqs, "setPTT");
int set = (long)d;
VFOQUEUE xcvrptt;
if (set) xcvrptt.change = ON;
else xcvrptt.change = OFF;
srvc_reqs.push(xcvrptt);
}
void update_progress(int val)
{
progress->value(val);
Fl::check();
}
void restore_rig_vals_(XCVR_STATE &xcvrvfo)
{
if (progStatus.restore_pre_att) {
selrig->set_attenuator(xcvrvfo.attenuator);
selrig->set_preamp(xcvrvfo.preamp);
}
update_progress(progress->value() + 5);
if (progStatus.restore_auto_notch)
selrig->set_auto_notch(xcvrvfo.auto_notch);
if (progStatus.restore_split)
selrig->set_split(xcvrvfo.split);
update_progress(progress->value() + 5);
if (progStatus.restore_power_control)
selrig->set_power_control(xcvrvfo.power_control);
if (progStatus.restore_volume)
selrig->set_volume_control(xcvrvfo.volume_control);
update_progress(progress->value() + 5);
if (progStatus.restore_if_shift)
selrig->set_if_shift(xcvrvfo.if_shift);
update_progress(progress->value() + 5);
if (progStatus.restore_notch)
selrig->set_notch(xcvrvfo.notch, xcvrvfo.notch_val);
if (progStatus.restore_noise)
selrig->set_noise(xcvrvfo.noise);
update_progress(progress->value() + 5);
if (progStatus.restore_nr) {
selrig->set_noise_reduction(xcvrvfo.nr);
selrig->set_noise_reduction_val(xcvrvfo.nr_val);
}
update_progress(progress->value() + 5);
if (progStatus.restore_mic_gain)
selrig->set_mic_gain(xcvrvfo.mic_gain);
update_progress(progress->value() + 5);
if (progStatus.restore_squelch)
selrig->set_squelch(xcvrvfo.squelch);
update_progress(progress->value() + 5);
if (progStatus.restore_rf_gain)
selrig->set_rf_gain(xcvrvfo.rf_gain);
update_progress(progress->value() + 5);
if (progStatus.restore_comp_on_off && progStatus.restore_comp_level)
selrig->set_compression(xcvrvfo.compON, xcvrvfo.compression);
else if (progStatus.restore_comp_on_off)
selrig->set_compression(xcvrvfo.compON, progStatus.compression);
else if (progStatus.restore_comp_level)
selrig->set_compression(progStatus.compON, xcvrvfo.compression);
update_progress(progress->value() + 5);
}
void restore_rig_vals()
{
if (progStatus.start_stop_trace) ss_trace(true);
update_progress(0);
guard_lock serial_lock(&mutex_serial);
trace(1, "restore_rig_vals()");
if (!useB) {
useB = true;
selrig->selectB();
}
if (progStatus.restore_mode) {
selrig->set_modeB(xcvr_vfoB.imode);
selrig->set_FILT(xcvr_vfoB.filter);
}
if (progStatus.restore_frequency)
selrig->set_vfoB(xcvr_vfoB.freq);
if (progStatus.restore_bandwidth)
selrig->set_bwB(xcvr_vfoB.iBW);
restore_rig_vals_(xcvr_vfoB);
trace(2, "Restored xcvr B:\n", print(xcvr_vfoB));
useB = false;
selrig->selectA();
if (progStatus.restore_mode) {
selrig->set_modeA(xcvr_vfoA.imode);
selrig->set_FILT(xcvr_vfoA.filter);
}
if (progStatus.restore_frequency)
selrig->set_vfoA(xcvr_vfoA.freq);
if (progStatus.restore_bandwidth)
selrig->set_bwA(xcvr_vfoA.iBW);
restore_rig_vals_(xcvr_vfoA);
trace(2, "Restored xcvr A:\n", print(xcvr_vfoA));
if (progStatus.start_stop_trace) ss_trace(false);
}
void read_rig_vals_(XCVR_STATE &xcvrvfo)
{
if (selrig->has_preamp_control)
xcvrvfo.preamp = selrig->get_preamp();
if (selrig->has_attenuator_control)
xcvrvfo.attenuator = selrig->get_attenuator();
if (selrig->has_preamp_control || selrig->has_attenuator_control)
btnRestorePreAtt->activate();
else
btnRestorePreAtt->deactivate();
if (selrig->has_auto_notch) {
btnRestoreAutoNotch->activate();
if (progStatus.restore_auto_notch && selrig->has_auto_notch)
xcvrvfo.auto_notch = selrig->get_auto_notch();
} else btnRestoreAutoNotch->deactivate();
if (selrig->has_split) {
btnRestoreSplit->activate();
if (progStatus.restore_split && selrig->has_split)
xcvrvfo.split = selrig->get_split();
} else
btnRestoreSplit->deactivate();
update_progress(progress->value() + 4);
if (selrig->has_power_control) {
btnRestorePowerControl->activate();
if (progStatus.restore_power_control)
xcvrvfo.power_control = selrig->get_power_control();
} else
btnRestorePowerControl->deactivate();
if (selrig->has_volume_control) {
btnRestoreVolume->activate();
if (progStatus.restore_volume)
xcvrvfo.volume_control = selrig->get_volume_control();
} else
btnRestoreVolume->deactivate();
if (selrig->has_ifshift_control) {
btnRestoreIFshift->activate();
if (progStatus.restore_if_shift)
selrig->get_if_shift(xcvrvfo.if_shift);
} else
btnRestoreIFshift->deactivate();
update_progress(progress->value() + 4);
if (selrig->has_notch_control) {
btnRestoreNotch->activate();
if (progStatus.restore_notch)
xcvrvfo.notch = selrig->get_notch(xcvrvfo.notch_val);
} else
btnRestoreNotch->deactivate();
if (selrig->has_noise_control) {
btnRestoreNoise->activate();
if (progStatus.restore_noise)
xcvrvfo.noise = selrig->get_noise();
} else
btnRestoreNoise->deactivate();
update_progress(progress->value() + 4);
if (selrig->has_noise_reduction_control) {
btnRestoreNR->activate();
if (progStatus.restore_nr) {
xcvrvfo.nr = selrig->get_noise_reduction();
xcvrvfo.nr_val = selrig->get_noise_reduction_val();
}
} else
btnRestoreNR->deactivate();
if (selrig->has_micgain_control) {
btnRestoreMicGain->activate();
if (progStatus.restore_mic_gain)
xcvrvfo.mic_gain = selrig->get_mic_gain();
} else
btnRestoreMicGain->deactivate();
if (selrig->has_sql_control) {
btnRestoreSquelch->activate();
if (progStatus.restore_squelch)
xcvrvfo.squelch = selrig->get_squelch();
} else
btnRestoreSquelch->deactivate();
update_progress(progress->value() + 4);
if (selrig->has_rf_control) {
btnRestoreRfGain->activate();
if (progStatus.restore_rf_gain)
xcvrvfo.rf_gain = selrig->get_rf_gain();
} else
btnRestoreRfGain->deactivate();
if (selrig->has_compression || selrig->has_compON) {
selrig->get_compression( xcvrvfo.compON, xcvrvfo.compression );
if (selrig->has_compON)
btnRestoreCompOnOff->activate();
else
btnRestoreCompOnOff->deactivate();
if (selrig->has_compression)
btnRestoreCompLevel->activate();
else
btnRestoreCompLevel->deactivate();
} else {
btnRestoreCompOnOff->deactivate();
btnRestoreCompLevel->deactivate();
}
update_progress(progress->value() + 4);
}
void read_vfoA_vals()
{
trace(1, "read_vfoA_vals()");
update_progress(progress->value() + 4);
if (selrig->has_get_info)
selrig->get_info();
trace(1, "read vfoA()");
xcvr_vfoA.freq = selrig->get_vfoA();
update_progress(progress->value() + 4);
trace(1, "read modeA()");
xcvr_vfoA.imode = selrig->get_modeA();
update_progress(progress->value() + 4);
trace(1, "get bwA()");
xcvr_vfoA.iBW = selrig->get_bwA();
update_progress(progress->value() + 4);
trace(1, "get FILT(A)");
xcvr_vfoA.filter = selrig->get_FILT(xcvr_vfoA.imode);
trace(1, "read_rig_vals()");
read_rig_vals_(xcvr_vfoA);
trace(2, "Read xcvr A:\n", print(xcvr_vfoA));
}
void read_vfoB_vals()
{
trace(1, "read_vfoB_vals()");
update_progress(progress->value() + 4);
if (selrig->has_get_info)
selrig->get_info();
trace(1, "read vfoB()");
xcvr_vfoB.freq = selrig->get_vfoB();
update_progress(progress->value() + 4);
trace(1, "read modeB()");
xcvr_vfoB.imode = selrig->get_modeB();
update_progress(progress->value() + 4);
trace(1, "get bwB()");
xcvr_vfoB.iBW = selrig->get_bwB();
update_progress(progress->value() + 4);
trace(1, "get FILT(B)");
xcvr_vfoB.filter = selrig->get_FILT(xcvr_vfoB.imode);
trace(1, "read_rig_vals()");
read_rig_vals_(xcvr_vfoB);
trace(2, "Read xcvr B:\n", print(xcvr_vfoB));
}
void read_rig_vals()
{
if (progStatus.start_stop_trace) ss_trace(true);
if (selrig->has_mode_control)
btnRestoreMode->activate();
else
btnRestoreMode->deactivate();
if (selrig->has_bandwidth_control)
btnRestoreBandwidth->activate();
else
btnRestoreBandwidth->deactivate();
// no guard_lock ... this function called from within a guard_lock block
trace(1, "read_rig_vals()");
update_progress(0);
if (selrig->name_ == rig_FT891.name_) {
// The FT-891 loses width WDH on A/B changes. It also starts
// with VFOA active, so no selectA() before reading VFOA values.
useB = false;
read_vfoA_vals();
useB = true;
selrig->selectB(); // first select call
read_vfoB_vals();
// Restore VFOA mode, then freq and bandwidth
useB = false;
selrig->selectA(); // second select call
yaesu891UpdateA(&xcvr_vfoA);
} else {
useB = true;
selrig->selectB(); // first select call to FT897D
read_vfoB_vals();
useB = false;
selrig->selectA(); // second select call
read_vfoA_vals();
}
//std::cout << "xcvr_vfoA.freq " << xcvr_vfoA.freq << std::endl;
//std::cout << "xcvr_vfoB.freq " << xcvr_vfoB.freq << std::endl;
if (selrig->has_agc_control) {
progStatus.agc_level = selrig->get_agc();
redrawAGC();
}
if (selrig->has_FILTER)
selrig->set_FILTERS(progStatus.filters);
selrig->set_BANDWIDTHS(progStatus.bandwidths);
if (progStatus.start_stop_trace) ss_trace(false);
}
void close_UI()
{
{
guard_lock serial_lock(&mutex_serial);
trace(1, "close_UI()");
run_serial_thread = false;
}
pthread_join(*serial_thread, NULL);
// xcvr auto off
if (selrig->has_xcvr_auto_on_off && progStatus.xcvr_auto_off)
selrig->set_xcvr_auto_off();
// close down the serial port
RigSerial->ClosePort();
if (dlgDisplayConfig && dlgDisplayConfig->visible())
dlgDisplayConfig->hide();
if (dlgXcvrConfig && dlgXcvrConfig->visible())
dlgXcvrConfig->hide();
if (dlgMemoryDialog && dlgMemoryDialog->visible())
dlgMemoryDialog->hide();
debug::stop();
mainwindow->hide();
}
void closeRig()
{
trace(1, "closeRig()");
if (xcvr_initialized) {
restore_rig_vals();
selrig->shutdown();
}
close_rig = false;
}
void cbExit()
{
main_group->hide();
main_group->redraw();
grpInitializing->size(mainwindow->w(), mainwindow->h() - grpInitializing->y());
grpInitializing->show();
grpInitializing->redraw();
progress->label("Closing");
progress->redraw_label();
progress->position(grpInitializing->w()/4, grpInitializing->y() + grpInitializing->h()/2);
update_progress(0);
progStatus.freq_A = vfoA.freq;
progStatus.imode_A = vfoA.imode;
progStatus.iBW_A = vfoA.iBW;
progStatus.freq_B = vfoB.freq;
progStatus.imode_B = vfoB.imode;
progStatus.iBW_B = vfoB.iBW;
if (selrig->has_FILTER)
progStatus.filters = selrig->get_FILTERS();
progStatus.spkr_on = btnVol->value();
saveFreqList();
if (spnrPOWER) progStatus.power_level = spnrPOWER->value();
if (spnrVOLUME) progStatus.volume = spnrVOLUME->value();
if (spnrRFGAIN) progStatus.rfgain = spnrRFGAIN->value();
if (spnrMICGAIN) progStatus.mic_gain = spnrMICGAIN->value();
if (spnrNOTCH) progStatus.notch_val = spnrNOTCH->value();
if (spnrIFSHIFT) progStatus.shift_val = spnrIFSHIFT->value();
if (spnrNR) progStatus.noise_reduction_val = spnrNR->value();
if (sldrPOWER) progStatus.power_level = sldrPOWER->value();
if (sldrVOLUME) progStatus.volume = sldrVOLUME->value();
if (sldrRFGAIN) progStatus.rfgain = sldrRFGAIN->value();
if (sldrMICGAIN) progStatus.mic_gain = sldrMICGAIN->value();
if (sldrNOTCH) progStatus.notch_val = sldrNOTCH->value();
if (sldrIFSHIFT) progStatus.shift_val = sldrIFSHIFT->value();
if (sldrNR) progStatus.noise_reduction_val = sldrNR->value();
progStatus.notch = btnNotch->value();
progStatus.shift = btnIFsh->value();
progStatus.noise_reduction = btnNR->value();
progStatus.noise = btnNOISE->value();
progStatus.attenuator = btnAttenuator->value();
progStatus.preamp = btnPreamp->value();
progStatus.auto_notch = btnAutoNotch->value();
progStatus.bandwidths = selrig->get_BANDWIDTHS();
progStatus.saveLastState();
closeRig();
{
guard_lock serial_lock(&mutex_serial);
trace(1, "shutdown serial thread");
close_rig = true;
}
close_UI();
if (tracewindow) tracewindow->hide();
if (tabs_dialog) tabs_dialog->hide();
}
void cbALC_SWR()
{
if (!selrig->has_alc_control) return;
if (meter_image == SWR_IMAGE) {
btnALC_SWR->image(image_alc);
meter_image = ALC_IMAGE;
sldrALC->show();
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cbALC_SWR() 1");
selrig->select_alc();
}
} else {
btnALC_SWR->image(image_swr);
meter_image = SWR_IMAGE;
sldrSWR->show();
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cbALC_SWR() 2");
selrig->select_swr();
}
}
btnALC_SWR->redraw();
}
void update_UI_PTT(void *d)
{
btnPTT->value(PTT);
if (!PTT) {
btnALC_SWR->hide();
scaleSmeter->show();
sldrRcvSignal->clear();
} else {
btnALC_SWR->show();
scaleSmeter->hide();
sldrFwdPwr->clear();
sldrALC->clear();
sldrSWR->clear();
}
}
void adjust_small_ui()
{
int y = 0;
mainwindow->resize( mainwindow->x(), mainwindow->y(), SMALL_MAINW, SMALL_MAINH);
btnVol->hide();
sldrVOLUME->hide();
sldrRFGAIN->hide();
btnIFsh->hide();
sldrIFSHIFT->hide();
btnLOCK->hide();
btnCLRPBT->hide();
sldrINNER->hide();
btnCLRPBT->hide();
sldrOUTER->hide();
btnNotch->hide();
sldrNOTCH->hide();
sldrMICGAIN->hide();
btnPOWER->hide();
sldrPOWER->hide();
btnPOWER->hide();
sldrSQUELCH->hide();
btnNR->hide();
sldrNR->hide();
btnNOISE->hide();
btnAGC->hide();
sldrRFGAIN->redraw_label();
if (progStatus.schema == 1 && selrig->widgets[0].W != NULL) {
int i = 0;
while (selrig->widgets[i].W != NULL) {
selrig->widgets[i].W->resize(
selrig->widgets[i].x, selrig->widgets[i].y,
selrig->widgets[i].w, selrig->widgets[i].W->h() );
selrig->widgets[i].W->show();
selrig->widgets[i].W->redraw();
if (selrig->widgets[i].y > y) y = selrig->widgets[i].y;
i++;
}
if (selrig->has_data_port) {
sldrMICGAIN->label("");
sldrMICGAIN->redraw_label();
}
if (selrig->has_power_control) {
btnPOWER->resize( sldrPOWER->x() - 52, sldrPOWER->y(), 50, 18 );
btnPOWER->redraw();
btnPOWER->show();
}
if (mnuSchema) mnuSchema->set();
} else {
if (mnuSchema) mnuSchema->clear();
y = cntRIT->y() + 2;
if (selrig->has_volume_control) {
y += 20;
btnVol->position( 2, y);
btnVol->show();
btnVol->redraw();
sldrVOLUME->resize( 54, y, 368, 18 );
sldrVOLUME->show();
sldrVOLUME->redraw();
}
if (selrig->has_rf_control) {
y += 20;
sldrRFGAIN->resize( 54, y, 368, 18 );
sldrRFGAIN->show();
sldrRFGAIN->redraw();
}
if (selrig->has_sql_control) {
y += 20;
sldrSQUELCH->resize( 54, y, 368, 18 );
sldrSQUELCH->show();
sldrSQUELCH->redraw();
}
if (selrig->has_noise_reduction_control) {
y += 20;
btnNR->position( 2, y);
btnNR->show();
btnNR->redraw();
sldrNR->resize( 54, y, 368, 18 );
sldrNR->show();
sldrNR->redraw();
if (xcvr_name == rig_TT599.name_) btnNR->deactivate();
}
if (selrig->has_pbt_controls) {
y += 20;
btnLOCK->position( 2, y);
btnLOCK->show();
btnLOCK->redraw();
sldrINNER->resize( 54, y, 368, 18 );
sldrINNER->show();
sldrINNER->redraw();
y += 20;
btnCLRPBT->position( 2, y);
btnCLRPBT->show();
btnCLRPBT->redraw();
sldrOUTER->resize( 54, y, 368, 18);
sldrOUTER->show();
sldrOUTER->redraw();
}
if (selrig->has_ifshift_control) {
y += 20;
btnIFsh->position( 2, y);
btnIFsh->show();
btnIFsh->redraw();
sldrIFSHIFT->resize( 54, y, 368, 18 );
sldrIFSHIFT->show();
sldrIFSHIFT->redraw();
}
if (selrig->has_notch_control) {
y += 20;
btnNotch->position( 2, y);
btnNotch->show();
btnNotch->redraw();
sldrNOTCH->resize( 54, y, 368, 18 );
sldrNOTCH->show();
sldrNOTCH->redraw();
}
if (selrig->has_micgain_control || selrig->has_data_port) {
if (selrig->has_micgain_control) {
y += 20;
sldrMICGAIN->resize( 54, y, 368, 18 );
sldrMICGAIN->show();
sldrMICGAIN->redraw();
if (selrig->has_data_port) {
sldrMICGAIN->label("");
sldrMICGAIN->redraw_label();
btnDataPort->position( 2, y);
btnDataPort->show();
btnDataPort->redraw();
}
} else if (selrig->has_data_port) {
btnDataPort->position( 214, 105);
btnDataPort->show();
btnDataPort->redraw();
}
}
if (selrig->has_power_control) {
y += 20;
sldrPOWER->resize( 54, y, 368, 18 );
sldrPOWER->show();
sldrPOWER->redraw();
btnPOWER->resize( 2, y, 50, 18 );
btnPOWER->show();
}
}
y += 20;
btn_show_controls->position( btn_show_controls->x(), y );
btnAttenuator->position( btnAttenuator->x(), y);
btnAttenuator->redraw();
btnPreamp->position( btnPreamp->x(), y);
btnPreamp->redraw();
btnNOISE->position( btnNOISE->x(), y);
btnNOISE->show();
btnNOISE->redraw();
btnAutoNotch->position( btnAutoNotch->x(), y);
btnAutoNotch->redraw();
btnTune->position( btnTune->x(), y);
btnTune->redraw();
btn_tune_on_off->position( btn_tune_on_off->x(), y);
btn_tune_on_off->redraw();
if (selrig->has_agc_control) {
btnAGC->show();
sldrRFGAIN->label("");
sldrRFGAIN->redraw_label();
} else {
btnAGC->hide();
sldrRFGAIN->label(_("RF"));
sldrRFGAIN->redraw_label();
}
if (xcvr_name == rig_FT1000MP.name_) {
y -= 20;
btnTune->position( btnTune->x(), y);
btnTune->redraw();
btn_tune_on_off->position( btn_tune_on_off->x(), y);
btn_tune_on_off->redraw();
btnAutoNotch->position( btnAutoNotch->x(), y);
btnAutoNotch->redraw();
btnPTT->position( btnPTT->x(), y);
btnPTT->redraw();
}
if (xcvr_name == rig_FT100D.name_ ||
xcvr_name == rig_FT767.name_ ||
xcvr_name == rig_FT817.name_ ||
xcvr_name == rig_FT847.name_ ||
xcvr_name == rig_FT857D.name_ ||
xcvr_name == rig_FT890.name_ ||
xcvr_name == rig_FT897D.name_ ||
xcvr_name == rig_FT920.name_ ) {
y -= 20;
btnPTT->position( mainwindow->w() - btnPTT->w() - btn_show_controls->w() - 10, y);
btnPTT->redraw();
btn_show_controls->position( btnPTT->x() + btnPTT->w() + 5, y );
btn_show_controls->redraw();
}
int use_AuxPort = (progStatus.aux_serial_port != "NONE");
if (use_AuxPort) {
btnPTT->resize(btnPTT->x(), y, btnPTT->w(), 38);
btnPTT->redraw();
y += 20;
boxControl->position(boxControl->x(), y);
btnAuxRTS->position(btnAuxRTS->x(), y);
btnAuxDTR->position(btnAuxDTR->x(), y);
btnAuxRTS->value(progStatus.aux_rts);
btnAuxDTR->value(progStatus.aux_dtr);
boxControl->show();
btnAuxRTS->show();
btnAuxDTR->show();
} else {
boxControl->hide();
btnAuxRTS->hide();
btnAuxDTR->hide();
btnPTT->resize(btnPTT->x(), y, btnPTT->w(), 18);
btnPTT->redraw();
}
btn_show_controls->label("@-22->");
btn_show_controls->redraw_label();
y += 20;
btn_show_controls->show();
mainwindow->init_sizes();
mainwindow->size( mainwindow->w(), y);
if (progStatus.tooltips) {
Fl_Tooltip::enable(1);
if (mnuTooltips) mnuTooltips->set();
} else {
if (mnuTooltips) mnuTooltips->clear();
Fl_Tooltip::enable(0);
}
mainwindow->redraw();
if (tabs_dialog && tabs_dialog->visible())
tabs_dialog->position(mainwindow->x(), mainwindow->y() + mainwindow->h() + 26);
}
void adjust_wide_ui()
{
mainwindow->resize( mainwindow->x(), mainwindow->y(), mainwindow->w(), WIDE_MAINH);
mainwindow->redraw();
btnVol->show();
sldrVOLUME->show();
sldrRFGAIN->show();
if (selrig->has_ifshift_control) {
btnIFsh->show();
sldrIFSHIFT->show();
}
if (selrig->has_pbt_controls) {
btnLOCK->show();
btnLOCK->value(progStatus.pbt_lock);
btnCLRPBT->show();
sldrINNER->show();
sldrOUTER->show();
sldrINNER->value(progStatus.pbt_inner);
sldrOUTER->value(progStatus.pbt_outer);
}
btnNotch->show();
sldrNOTCH->show();
sldrMICGAIN->show();
sldrPOWER->show();
btnPOWER->hide();
sldrSQUELCH->show();
btnNR->show();
sldrNR->show();
btnAGC->hide();
btnDataPort->hide();
sldrRFGAIN->redraw_label();
if (!selrig->has_micgain_control)
sldrMICGAIN->deactivate();
if (!selrig->has_noise_reduction)
btnNR->deactivate();
if (!selrig->has_noise_reduction_control)
sldrNR->deactivate();
if (xcvr_name == rig_TT550.name_) {
tabs550->show();
tabsGeneric->hide();
} else {
tabs550->hide();
tabsGeneric->remove(genericAux);
if (progStatus.aux_serial_port != "NONE" || selrig->has_data_port) {
if (progStatus.aux_serial_port != "NONE") {
btnAuxRTS->activate();
btnAuxDTR->activate();
} else {
btnAuxRTS->deactivate();
btnAuxDTR->deactivate();
}
if (selrig->has_data_port)
btnDataPort->show();
else
btnDataPort->hide();
tabsGeneric->add(genericAux);
}
tabsGeneric->remove(genericRXB);
if (selrig->has_rit || selrig->has_xit || selrig->has_bfo)
tabsGeneric->add(genericRXB);
tabsGeneric->show();
if (selrig->has_agc_control) {
btnAGC->show();
sldrRFGAIN->label("");
sldrRFGAIN->redraw_label();
} else {
btnAGC->hide();
sldrRFGAIN->label(_("RF"));
sldrRFGAIN->redraw_label();
}
if (selrig->has_power_control) {
btnPOWER->resize(sldrPOWER->x() - 52, sldrPOWER->y(), 50, 18);
btnPOWER->show();
}
else {
sldrPOWER->deactivate();
}
}
if (progStatus.tooltips) {
Fl_Tooltip::enable(1);
if (mnuTooltips) mnuTooltips->set();
} else {
if (mnuTooltips) mnuTooltips->clear();
Fl_Tooltip::enable(0);
}
mainwindow->redraw();
}
void adjust_touch_ui()
{
mainwindow->resize( mainwindow->x(), mainwindow->y(), mainwindow->w(), TOUCH_MAINH);
mainwindow->redraw();
if (spnrPOWER) spnrPOWER->show();
if (sldrPOWER) sldrPOWER->show();
btnVol->show();
if (spnrVOLUME) spnrVOLUME->show();
if (sldrVOLUME) sldrVOLUME->show();
if (spnrRFGAIN) spnrRFGAIN->show();
if (sldrRFGAIN) sldrRFGAIN->show();
btnIFsh->show();
if (spnrIFSHIFT) spnrIFSHIFT->show();
if (sldrIFSHIFT) sldrIFSHIFT->show();
btnNotch->show();
if (spnrNOTCH) spnrNOTCH->show();
if (sldrNOTCH) sldrNOTCH->show();
if (spnrMICGAIN) spnrMICGAIN->show();
if (sldrMICGAIN) sldrMICGAIN->show();
if (spnrSQUELCH) spnrSQUELCH->show();
if (sldrSQUELCH) sldrSQUELCH->show();
if (selrig->has_agc_control) {
btnAGC->show();
sldrRFGAIN->label("");
sldrRFGAIN->redraw_label();
} else {
btnAGC->hide();
sldrRFGAIN->label(_("RF"));
sldrRFGAIN->redraw_label();
}
btnNR->show();
if (spnrNR) spnrNR->show();
if (sldrNR) sldrNR->show();
if (xcvr_name == rig_TT550.name_) {
tabs550->show();
tabsGeneric->hide();
} else {
tabs550->hide();
tabsGeneric->remove(genericAux);
if (progStatus.aux_serial_port != "NONE" || selrig->has_data_port) {
//std::cout << "has data port\n";
if (progStatus.aux_serial_port != "NONE") {
btnAuxRTS->activate();
btnAuxDTR->activate();
} else {
btnAuxRTS->deactivate();
btnAuxDTR->deactivate();
}
if (selrig->has_data_port)
btnDataPort->activate();
else
btnDataPort->deactivate();
tabsGeneric->add(genericAux);
}
tabsGeneric->remove(genericRXB);
if (selrig->has_rit || selrig->has_xit || selrig->has_bfo)
tabsGeneric->add(genericRXB);
tabsGeneric->show();
}
if (progStatus.tooltips) {
Fl_Tooltip::enable(1);
if (mnuTooltips) mnuTooltips->set();
} else {
if (mnuTooltips) mnuTooltips->clear();
Fl_Tooltip::enable(0);
}
mainwindow->init_sizes();
mainwindow->size_range(WIDE_MAINW, WIDE_MAINH, 0, WIDE_MAINH);
mainwindow->redraw();
}
void adjust_control_positions()
{
switch (progStatus.UIsize) {
case small_ui :
adjust_small_ui();
break;
case wide_ui :
adjust_wide_ui();
break;
case touch_ui :
default :
adjust_touch_ui();
break;
}
FreqDispA->set_hrd(progStatus.hrd_buttons);
FreqDispB->set_hrd(progStatus.hrd_buttons);
if (selrig->name_ == rig_FT891.name_) {
// Default FT891 to only send slider updates to rig once slider
// is released. This avoids a condition where once slider is
// released, the slider value no longer tracks changes from
// controls on the rig.
progStatus.sliders_button = FL_WHEN_RELEASE;
chk_sliders_button->value(false);
}
set_sliders_when();
}
void initTabs()
{
if (xcvr_name == rig_TT550.name_) {
spnr_tt550_line_out->value(progStatus.tt550_line_out);
cbo_tt550_agc_level->index(progStatus.tt550_agc_level);
spnr_tt550_cw_wpm->value(progStatus.tt550_cw_wpm);
spnr_tt550_cw_vol->value(progStatus.tt550_cw_vol);
spnr_tt550_cw_spot->value(progStatus.tt550_cw_spot);
spnr_tt550_cw_weight->value(progStatus.tt550_cw_weight);
spnr_tt550_cw_qsk->value(progStatus.tt550_cw_qsk);
btn_tt550_enable_keyer->value(progStatus.tt550_enable_keyer);
btn_tt550_vox->value(progStatus.tt550_vox_onoff);
spnr_tt550_vox_gain->value(progStatus.tt550_vox_gain);
spnr_tt550_anti_vox->value(progStatus.tt550_vox_anti);
spnr_tt550_vox_hang->value(progStatus.tt550_vox_hang);
btn_tt550_CompON->value(progStatus.tt550_compON);
spnr_tt550_compression->value(progStatus.tt550_compression);
spnr_tt550_mon_vol->value(progStatus.tt550_mon_vol);
btn_tt550_enable_xmtr->value(progStatus.tt550_enable_xmtr);
btn_tt550_enable_tloop->value(progStatus.tt550_enable_tloop);
btn_tt550_tuner_bypass->value(progStatus.tt550_tuner_bypass);
btn_tt550_use_xmt_bw->value(progStatus.tt550_use_xmt_bw);
sel_tt550_encoder_step->value(progStatus.tt550_encoder_step);
spnr_tt550_encoder_sensitivity->value(progStatus.tt550_encoder_sensitivity);
sel_tt550_F1_func->value(progStatus.tt550_F1_func);
sel_tt550_F2_func->value(progStatus.tt550_F2_func);
sel_tt550_F3_func->value(progStatus.tt550_F3_func);
progStatus.use_rig_data = false;
op_tt550_XmtBW->clear();
for (int i = 0; TT550_xmt_widths[i] != NULL; i++) {
op_tt550_XmtBW->add(TT550_xmt_widths[i]);
}
op_tt550_XmtBW->activate();
op_tt550_XmtBW->index(progStatus.tt550_xmt_bw);
poll_smeter->activate(); poll_smeter->value(progStatus.poll_smeter);
poll_pout->activate(); poll_pout->value(progStatus.poll_pout);
poll_swr->activate(); poll_swr->value(progStatus.poll_swr);
poll_alc->activate(); poll_alc->value(progStatus.poll_alc);
poll_frequency->deactivate(); poll_frequency->value(0);
poll_mode->deactivate(); poll_mode->value(0);
poll_bandwidth->deactivate(); poll_bandwidth->value(0);
poll_volume->deactivate(); poll_volume->value(0);
poll_notch->deactivate(); poll_notch->value(0);
poll_auto_notch->deactivate(); poll_auto_notch->value(0);
poll_ifshift->deactivate(); poll_ifshift->value(0);
poll_power_control->deactivate(); poll_power_control->value(0);
poll_pre_att->deactivate(); poll_pre_att->value(0);
poll_squelch->deactivate(); poll_squelch->value(0);
poll_micgain->deactivate(); poll_micgain->value(0);
poll_rfgain->deactivate(); poll_rfgain->value(0);
poll_split->deactivate(); poll_split->value(0);
poll_nr->deactivate(); poll_nr->value(0);
poll_noise->deactivate(); poll_noise->value(0);
poll_all->deactivate(); poll_all->value(0);
if (progStatus.tt550_at11_inline) {
tt550_AT_inline->value(1);
tt550_AT_inline->label("Inline");
tt550_AT_inline->redraw_label();
selrig->at11_autotune();
} else {
tt550_AT_inline->value(0);
tt550_AT_inline->label("Bypassed");
tt550_AT_inline->redraw_label();
selrig->at11_bypass();
}
if (progStatus.tt550_at11_hiZ) {
selrig->at11_hiZ();
tt550_AT_Z->value(1);
} else{
selrig->at11_loZ();
tt550_AT_Z->value(0);
}
} else {
hidden_tabs->add(tab_yaesu_bands);
hidden_tabs->add(tab_FT8n_bands);
hidden_tabs->add(tab_FT8n_CTCSS);
hidden_tabs->add(tab_icom_bands);
hidden_tabs->add(genericCW);
hidden_tabs->add(genericQSK);
hidden_tabs->add(genericVOX);
hidden_tabs->add(genericSpeech);
hidden_tabs->add(genericRx);
hidden_tabs->add(genericMisc);
hidden_tabs->add(genericUser_1);
hidden_tabs->add(genericUser_2);
hidden_tabs->add(tab7610);
if (selrig->has_band_selection) {
if (selrig->ICOMrig) {
tabsGeneric->add(tab_icom_bands);
tab_icom_bands->redraw();
} else if (selrig->name_ == rig_FT857D.name_ || selrig->name_ == rig_FT897D.name_) {
tabsGeneric->add(tab_FT8n_bands);
tabsGeneric->add(tab_FT8n_CTCSS);
tab_FT8n_bands->redraw();
tab_FT8n_CTCSS->redraw();
} else {
tabsGeneric->add(tab_yaesu_bands);
tab_yaesu_bands->redraw();
}
}
if (selrig->has_cw_wpm ||
selrig->has_cw_weight ||
selrig->has_cw_keyer ||
selrig->has_cw_spot ||
selrig->has_cw_spot_tone ) {
if (selrig->has_cw_wpm) {
int min, max;
selrig->get_cw_wpm_min_max(min, max);
spnr_cw_wpm->minimum(min);
spnr_cw_wpm->maximum(max);
spnr_cw_wpm->value(progStatus.cw_wpm);
spnr_cw_wpm->show();
} else
spnr_cw_wpm->hide();
if (selrig->has_cw_weight) {
double min, max, step;
selrig->get_cw_weight_min_max_step( min, max, step );
spnr_cw_weight->minimum(min);
spnr_cw_weight->maximum(max);
spnr_cw_weight->step(step);
spnr_cw_weight->value(progStatus.cw_weight);
spnr_cw_weight->show();
} else
spnr_cw_weight->hide();
if (selrig->has_cw_keyer) {
btn_enable_keyer->show();
btn_enable_keyer->value(progStatus.enable_keyer);
selrig->enable_keyer();
}
else
btn_enable_keyer->hide();
if (selrig->has_cw_spot) {
btnSpot->value(progStatus.cw_spot);
selrig->set_cw_spot();
btnSpot->show();
} else
btnSpot->hide();
if (selrig->has_cw_spot_tone) {
spnr_cw_spot_tone->show();
int min, max, step;
selrig->get_cw_spot_tone_min_max_step(min, max, step);
spnr_cw_spot_tone->minimum(min);
spnr_cw_spot_tone->maximum(max);
spnr_cw_spot_tone->step(step);
spnr_cw_spot_tone->value(progStatus.cw_spot_tone);
selrig->set_cw_spot_tone();
} else
spnr_cw_spot_tone->hide();
tabsGeneric->add(genericCW);
genericCW->redraw();
}
if (selrig->has_cw_qsk) {
tabsGeneric->add(genericQSK);
btnBreakIn->show();
spnr_cw_delay->show();
if (selrig->has_cw_qsk) {
double min, max, step;
selrig->get_cw_qsk_min_max_step(min, max, step);
spnr_cw_qsk->minimum(min);
spnr_cw_qsk->maximum(max);
spnr_cw_qsk->step(step);
spnr_cw_qsk->value(progStatus.cw_qsk);
spnr_cw_qsk->show();
} else
spnr_cw_qsk->hide();
}
if (selrig->has_vox_onoff ||
selrig->has_vox_gain ||
selrig->has_vox_hang ||
selrig->has_vox_on_dataport) {
if (selrig->has_vox_onoff) {
btn_vox->value(progStatus.vox_onoff);
btn_vox->show();
selrig->set_vox_onoff();
} else btn_vox->hide();
if (selrig->has_vox_gain) {
int min, max, step;
selrig->get_vox_gain_min_max_step(min, max, step);
spnr_vox_gain->minimum(min);
spnr_vox_gain->maximum(max);
spnr_vox_gain->step(step);
spnr_vox_gain->value(progStatus.vox_gain);
spnr_vox_gain->show();
selrig->set_vox_gain();
} else spnr_vox_gain->hide();
if (selrig->has_vox_anti) {
int min, max, step;
selrig->get_vox_anti_min_max_step(min, max, step);
spnr_anti_vox->minimum(min);
spnr_anti_vox->maximum(max);
spnr_anti_vox->step(step);
spnr_anti_vox->value(progStatus.vox_anti);
spnr_anti_vox->show();
selrig->set_vox_anti();
} else spnr_anti_vox->hide();
if (selrig->has_vox_hang) {
int min, max, step;
selrig->get_vox_hang_min_max_step(min, max, step);
spnr_vox_hang->minimum(min);
spnr_vox_hang->maximum(max);
spnr_vox_hang->step(step);
spnr_vox_hang->value(progStatus.vox_hang);
spnr_vox_hang->show();
selrig->set_vox_hang();
} else spnr_vox_hang->hide();
if (selrig->has_vox_on_dataport) {
btn_vox_on_dataport->value(progStatus.vox_on_dataport);
btn_vox_on_dataport->show();
selrig->set_vox_on_dataport();
} else btn_vox_on_dataport->hide();
tabsGeneric->add(genericVOX);
genericVOX->redraw();
}
if (selrig->has_compON ||
selrig->has_compression ) {
if (selrig->has_compON) {
btnCompON->show();
btnCompON->value(progStatus.compON);
} else
btnCompON->hide();
if (selrig->has_compression) {
int min, max, step;
selrig->get_comp_min_max_step(min, max, step);
spnr_compression->minimum(min);
spnr_compression->maximum(max);
spnr_compression->step(step);
spnr_compression->show();
spnr_compression->value(progStatus.compression);
selrig->set_compression(progStatus.compON, progStatus.compression);
} else
spnr_compression->hide();
tabsGeneric->add(genericSpeech);
genericSpeech->redraw();
}
if (selrig->has_nb_level ||
selrig->has_bpf_center ) {
if (selrig->has_nb_level)
sldr_nb_level->show();
else
sldr_nb_level->hide();
if (selrig->has_bpf_center) {
spnr_bpf_center->value(progStatus.bpf_center);
spnr_bpf_center->show();
btn_use_bpf_center->show();
} else {
spnr_bpf_center->hide();
btn_use_bpf_center->hide();
}
tabsGeneric->add(genericRx);
genericRx->redraw();
}
if (selrig->has_vfo_adj ||
selrig->has_line_out ||
selrig->has_xcvr_auto_on_off ) {
if (selrig->has_vfo_adj) {
int min, max, step;
selrig->get_vfoadj_min_max_step(min, max, step);
spnr_vfo_adj->minimum(min);
spnr_vfo_adj->maximum(max);
spnr_vfo_adj->step(step);
progStatus.vfo_adj = selrig->getVfoAdj();
spnr_vfo_adj->value(progStatus.vfo_adj);
spnr_vfo_adj->show();
} else
spnr_vfo_adj->hide();
if (selrig->has_line_out)
spnr_line_out->show();
else
spnr_line_out->hide();
if (selrig->has_xcvr_auto_on_off) {
btn_xcvr_auto_on->value(progStatus.xcvr_auto_on);
btn_xcvr_auto_off->value(progStatus.xcvr_auto_off);
btn_xcvr_auto_on->show();
btn_xcvr_auto_off->show();
} else {
btn_xcvr_auto_on->hide();
btn_xcvr_auto_off->hide();
}
tabsGeneric->add(genericMisc);
genericMisc->redraw();
}
tabsGeneric->add(genericUser_1);
tabsGeneric->add(genericUser_2);
genericUser_1->redraw();
genericUser_2->redraw();
if (selrig->name_ == rig_IC7610.name_) {
tabsGeneric->add(tab7610);
tab7610->redraw();
btnAttenuator->hide();
}
tabsGeneric->redraw();
poll_frequency->activate(); poll_frequency->value(progStatus.poll_frequency);
poll_mode->activate(); poll_mode->value(progStatus.poll_mode);
poll_bandwidth->activate(); poll_bandwidth->value(progStatus.poll_bandwidth);
poll_smeter->activate(); poll_smeter->value(progStatus.poll_smeter);
poll_pout->activate(); poll_pout->value(progStatus.poll_pout);
poll_swr->activate(); poll_swr->value(progStatus.poll_swr);
poll_alc->activate(); poll_alc->value(progStatus.poll_alc);
poll_volume->activate(); poll_volume->value(progStatus.poll_volume);
poll_notch->activate(); poll_notch->value(progStatus.poll_notch);
poll_auto_notch->activate(); poll_auto_notch->value(progStatus.poll_auto_notch);
poll_ifshift->activate(); poll_ifshift->value(progStatus.poll_ifshift);
poll_power_control->activate(); poll_power_control->value(progStatus.poll_power_control);
poll_pre_att->activate(); poll_pre_att->value(progStatus.poll_pre_att);
poll_squelch->activate(); poll_squelch->value(progStatus.poll_squelch);
poll_micgain->activate(); poll_micgain->value(progStatus.poll_micgain);
poll_rfgain->activate(); poll_rfgain->value(progStatus.poll_rfgain);
poll_split->activate(); poll_split->value(progStatus.poll_split);
poll_noise->activate(); poll_noise->value(progStatus.poll_noise);
poll_nr->activate(); poll_nr->value(progStatus.poll_nr);
poll_compression->activate(); poll_compression->value(progStatus.poll_compression);
if (!selrig->has_bandwidth_control) { poll_bandwidth->deactivate(); poll_bandwidth->value(0); }
if (!selrig->has_smeter) { poll_smeter->deactivate(); poll_smeter->value(0); }
if (!selrig->has_power_out) { poll_pout->deactivate(); poll_pout->value(0); }
if (!selrig->has_swr_control) { poll_swr->deactivate(); poll_swr->value(0); }
if (!selrig->has_alc_control) { poll_alc->deactivate(); poll_alc->value(0); }
if (!selrig->has_volume_control) { poll_volume->deactivate(); poll_volume->value(0); }
if (!selrig->has_notch_control) { poll_notch->deactivate(); poll_notch->value(0); }
if (!selrig->has_auto_notch ||
xcvr_name == rig_FT1000MP.name_ )
{ poll_auto_notch->deactivate(); poll_auto_notch->value(0); }
if (!selrig->has_ifshift_control &&
!selrig->has_pbt_controls) { poll_ifshift->deactivate(); poll_ifshift->value(0); }
if (selrig->has_pbt_controls) {
poll_ifshift->label("pbt");
poll_ifshift->redraw_label();
}
if (!selrig->has_power_control) { poll_power_control->deactivate(); poll_power_control->value(0); }
if (!selrig->has_preamp_control && !selrig->has_attenuator_control)
{ poll_pre_att->deactivate(); poll_pre_att->value(0); }
if (!selrig->has_sql_control) { poll_squelch->deactivate(); poll_squelch->value(0); }
if (!selrig->has_micgain_control) { poll_micgain->deactivate(); poll_micgain->value(0); }
if (!selrig->has_rf_control) { poll_rfgain->deactivate(); poll_rfgain->value(0); }
if (!selrig->has_split) { poll_split->deactivate(); poll_split->value(0); }
if (!selrig->has_noise_control) {poll_noise->deactivate(); poll_noise->value(0);}
if (!selrig->has_noise_reduction) {poll_nr->deactivate(); poll_nr->value(0);}
if (!selrig->has_compression) { poll_compression->deactivate(); poll_compression->value(0); }
}
}
void init_TT550()
{
useB = false;
selrig->selectA();
vfoB.freq = progStatus.freq_B;
vfoB.imode = progStatus.imode_B;
vfoB.iBW = progStatus.iBW_B;
FreqDispB->value(vfoB.freq);
selrig->set_vfoB(vfoB.freq);
selrig->set_modeB(vfoB.imode);
selrig->set_bwB(vfoB.iBW);
vfoA.freq = progStatus.freq_A;
vfoA.imode = progStatus.imode_A;
vfoA.iBW = progStatus.iBW_A;
FreqDispA->value( vfoA.freq );
selrig->set_vfoA(vfoA.freq);
selrig->set_modeA(vfoA.imode);
vfo = &vfoA;
if (vfoA.iBW == -1) vfoA.iBW = selrig->def_bandwidth(vfoA.imode);
selrig->set_bwA(vfoA.iBW);
rigmodes_.clear();
opMODE->clear();
for (int i = 0; selrig->modes_[i] != NULL; i++) {
rigmodes_.push_back(selrig->modes_[i]);
opMODE->add(selrig->modes_[i]);
}
opMODE->activate();
opMODE->index(vfoA.imode);
rigbws_.clear();
opBW->show();
opBW->clear();
old_bws = selrig->bandwidths_;
for (int i = 0; selrig->bandwidths_[i] != NULL; i++) {
rigbws_.push_back(selrig->bandwidths_[i]);
opBW->add(selrig->bandwidths_[i]);
}
opBW->activate();
opBW->index(vfoA.iBW);
spnr_tt550_vfo_adj->value(progStatus.vfo_adj);
btnPreamp->label("Spot");
btnPreamp->value(progStatus.tt550_spot_onoff);
switch (progStatus.UIsize) {
case small_ui :
btnPreamp->show();
break;
case wide_ui : case touch_ui : default :
btnPreamp->activate();
}
}
void init_generic_rig()
{
if (progStatus.CIV > 0)
selrig->adjustCIV(progStatus.CIV);
if (selrig->has_getvfoAorB) {
int ret = selrig->get_vfoAorB();
int retry = 10;
while (ret == -1 && retry--) {
MilliSleep(50);
ret = selrig->get_vfoAorB();
}
if (ret == -1) ret = 0;
useB = ret;
read_rig_vals();
if (progStatus.use_rig_data) {
vfoA = xcvr_vfoA;
vfoB = xcvr_vfoB;
}
if (useB) {
selrig->selectB();
vfo = &vfoB;
} else {
vfo = &vfoA;
}
}
else {
read_rig_vals();
if (progStatus.use_rig_data) {
vfoA = xcvr_vfoA;
vfoB = xcvr_vfoB;
}
}
progStatus.compON = xcvr_vfoA.compON;
progStatus.compression = xcvr_vfoA.compression;
vfo = &vfoA;
rigmodes_.clear();
opMODE->clear();
if (selrig->has_mode_control) {
for (int i = 0; selrig->modes_[i] != NULL; i++) {
rigmodes_.push_back(selrig->modes_[i]);
opMODE->add(selrig->modes_[i]);
}
opMODE->activate();
opMODE->index(progStatus.imode_A);
} else {
opMODE->add(" ");
opMODE->index(0);
opMODE->deactivate();
}
rigbws_.clear();
opBW->show();
opBW->clear();
if (selrig->has_bandwidth_control) {
old_bws = selrig->bandwidths_;
for (int i = 0; selrig->bandwidths_[i] != NULL; i++) {
rigbws_.push_back(selrig->bandwidths_[i]);
opBW->add(selrig->bandwidths_[i]);
}
opBW->activate();
if (progStatus.iBW_A == -1) progStatus.iBW_A = selrig->def_bandwidth(vfoA.imode);
if (progStatus.iBW_B == -1) progStatus.iBW_B = selrig->def_bandwidth(vfoB.imode);
opBW->index(progStatus.iBW_A);
} else {
opBW->add(" ");
opBW->index(0);
opBW->deactivate();
}
}
void init_rit()
{
if (selrig->has_rit) {
int min, max, step;
selrig->get_RIT_min_max_step(min, max, step);
cntRIT->minimum(min);
cntRIT->maximum(max);
cntRIT->step(step);
switch (progStatus.UIsize) {
case small_ui :
cntRIT->show();
break;
case wide_ui : case touch_ui : default :
cntRIT->activate();
}
cntRIT->value(progStatus.rit_freq);
} else {
switch (progStatus.UIsize) {
case small_ui :
cntRIT->hide();
break;
case wide_ui: case touch_ui : default :
cntRIT->deactivate();
}
}
}
void init_xit()
{
if (selrig->has_xit) {
int min, max, step;
selrig->get_XIT_min_max_step(min, max, step);
cntXIT->minimum(min);
cntXIT->maximum(max);
cntXIT->step(step);
cntXIT->value(progStatus.xit_freq);
switch (progStatus.UIsize) {
case small_ui :
cntXIT->show();
break;
case wide_ui : case touch_ui : default :
cntXIT->activate();
}
} else {
switch (progStatus.UIsize) {
case small_ui :
cntXIT->hide();
case wide_ui : case touch_ui : default :
cntXIT->deactivate();
}
}
}
void init_bfo()
{
if (selrig->has_bfo) {
int min, max, step;
selrig->get_BFO_min_max_step(min, max, step);
cntBFO->minimum(min);
cntBFO->maximum(max);
cntBFO->step(step);
cntBFO->value(progStatus.bfo_freq);
switch (progStatus.UIsize) {
case small_ui :
cntBFO->show();
break;
case wide_ui : case touch_ui : default :
cntBFO->activate();
}
} else {
switch (progStatus.UIsize) {
case small_ui :
cntBFO->hide();
break;
case wide_ui : case touch_ui : default :
cntBFO->deactivate();
}
}
}
void init_dsp_controls()
{
if (selrig->has_dsp_controls) {
opDSP_lo->clear();
opDSP_hi->clear();
btnDSP->label(selrig->SL_label);
btnDSP->redraw_label();
for (int i = 0; selrig->dsp_SL[i] != NULL; i++)
opDSP_lo->add(selrig->dsp_SL[i]);
opDSP_lo->tooltip(selrig->SL_tooltip);
for (int i = 0; selrig->dsp_SH[i] != NULL; i++)
opDSP_hi->add(selrig->dsp_SH[i]);
opDSP_hi->tooltip(selrig->SH_tooltip);
if (vfo->iBW > 256) {
opDSP_lo->index(vfo->iBW & 0xFF);
opDSP_hi->index((vfo->iBW >> 8) & 0x7F);
btnDSP->show();
opDSP_hi->show();
opDSP_lo->hide();
opBW->hide();
opBW->index(0);
btnFILT->hide();
} else {
opDSP_lo->index(0);
opDSP_hi->index(0);
btnDSP->hide();
opDSP_lo->hide();
opDSP_hi->hide();
btnFILT->hide();
opBW->show();
}
} else if (selrig->has_FILTER) {
btnDSP->hide();
opDSP_lo->hide();
opDSP_hi->hide();
btnFILT->show();
opBW->resize(opDSP_lo->x(), opDSP_lo->y(), opDSP_lo->w(), opDSP_lo->h());
opBW->redraw();
opBW->show();
} else {
btnDSP->hide();
opDSP_lo->hide();
opDSP_hi->hide();
btnFILT->hide();
opBW->show();
}
}
void init_volume_control()
{
if (selrig->has_volume_control) {
int min, max, step;
selrig->get_vol_min_max_step(min, max, step);
if (spnrVOLUME) {
spnrVOLUME->minimum(min);
spnrVOLUME->maximum(max);
spnrVOLUME->step(step);
spnrVOLUME->redraw();
spnrVOLUME->activate();
}
if (sldrVOLUME) {
sldrVOLUME->minimum(min);
sldrVOLUME->maximum(max);
sldrVOLUME->step(step);
sldrVOLUME->redraw();
sldrVOLUME->activate();
}
switch (progStatus.UIsize) {
case small_ui :
btnVol->show();
if (sldrVOLUME) sldrVOLUME->show();
if (spnrVOLUME) spnrVOLUME->show();
break;
case wide_ui : case touch_ui : default :
btnVol->activate();
if (sldrVOLUME) sldrVOLUME->activate();
if (spnrVOLUME) spnrVOLUME->activate();
}
} else {
switch (progStatus.UIsize) {
case small_ui :
btnVol->hide();
if (sldrVOLUME) sldrVOLUME->hide();
if (spnrVOLUME) spnrVOLUME->hide();
break;
case wide_ui : case touch_ui : default :
btnVol->deactivate();
if (sldrVOLUME) sldrVOLUME->deactivate();
if (spnrVOLUME) spnrVOLUME->deactivate();
}
}
}
void set_init_volume_control()
{
if (!selrig->has_volume_control)
return;
if (progStatus.use_rig_data) {
progStatus.volume = selrig->get_volume_control();
if (sldrVOLUME) sldrVOLUME->value(progStatus.volume);
if (sldrVOLUME) sldrVOLUME->activate();
btnVol->value(1);
if (spnrVOLUME) spnrVOLUME->value(progStatus.volume);
if (spnrVOLUME) spnrVOLUME->activate();
sldrVOLUME->activate();
} else {
if (sldrVOLUME) sldrVOLUME->value(progStatus.volume);
if (spnrVOLUME) spnrVOLUME->value(progStatus.volume);
if (progStatus.spkr_on == 0) {
btnVol->value(0);
if (sldrVOLUME) sldrVOLUME->deactivate();
if (spnrVOLUME) spnrVOLUME->deactivate();
selrig->set_volume_control(0);
} else {
btnVol->value(1);
if (sldrVOLUME) sldrVOLUME->activate();
if (spnrVOLUME) spnrVOLUME->activate();
selrig->set_volume_control(progStatus.volume);
}
}
}
void init_rf_control()
{
if (selrig->has_rf_control) {
int min, max, step;
selrig->get_rf_min_max_step(min, max, step);
if (sldrRFGAIN) sldrRFGAIN->minimum(min);
if (sldrRFGAIN) sldrRFGAIN->maximum(max);
if (sldrRFGAIN) sldrRFGAIN->step(step);
if (sldrRFGAIN) sldrRFGAIN->redraw();
if (spnrRFGAIN) spnrRFGAIN->minimum(min);
if (spnrRFGAIN) spnrRFGAIN->maximum(max);
if (spnrRFGAIN) spnrRFGAIN->step(step);
if (spnrRFGAIN) spnrRFGAIN->redraw();
switch (progStatus.UIsize) {
case small_ui :
if (sldrRFGAIN) sldrRFGAIN->show();
if (spnrRFGAIN) spnrRFGAIN->show();
break;
case wide_ui : case touch_ui : default :
if (sldrRFGAIN) sldrRFGAIN->activate();
if (spnrRFGAIN) spnrRFGAIN->activate();
}
} else {
switch (progStatus.UIsize) {
case small_ui :
if (sldrRFGAIN) sldrRFGAIN->hide();
if (spnrRFGAIN) spnrRFGAIN->hide();
break;
case wide_ui : case touch_ui : default :
if (sldrRFGAIN) sldrRFGAIN->deactivate();
if (spnrRFGAIN) spnrRFGAIN->deactivate();
}
}
if (selrig->name_ == rig_ICF8101.name_) {
if (sldrRFGAIN) sldrRFGAIN->deactivate();
if (spnrRFGAIN) spnrRFGAIN->deactivate();
}
}
void set_init_rf_gain()
{
if (!selrig->has_rf_control)
return;
if (progStatus.use_rig_data) {
progStatus.rfgain = selrig->get_rf_gain();
if (sldrRFGAIN) sldrRFGAIN->value(progStatus.rfgain);
if (spnrRFGAIN) spnrRFGAIN->value(progStatus.rfgain);
} else {
if (sldrRFGAIN) sldrRFGAIN->value(progStatus.rfgain);
if (spnrRFGAIN) spnrRFGAIN->value(progStatus.rfgain);
selrig->set_rf_gain(progStatus.rfgain);
}
}
void init_sql_control()
{
if (selrig->has_sql_control) {
int min, max, step;
selrig->get_squelch_min_max_step(min, max, step);
if (sldrSQUELCH) sldrSQUELCH->minimum(min);
if (sldrSQUELCH) sldrSQUELCH->maximum(max);
if (sldrSQUELCH) sldrSQUELCH->step(step);
if (sldrSQUELCH) sldrSQUELCH->redraw();
if (spnrSQUELCH) spnrSQUELCH->minimum(min);
if (spnrSQUELCH) spnrSQUELCH->maximum(max);
if (spnrSQUELCH) spnrSQUELCH->step(step);
if (spnrSQUELCH) spnrSQUELCH->redraw();
switch (progStatus.UIsize) {
case small_ui :
if (sldrSQUELCH) sldrSQUELCH->show();
if (spnrSQUELCH) spnrSQUELCH->show();
break;
case wide_ui : case touch_ui : default:
if (sldrSQUELCH) sldrSQUELCH->activate();
if (spnrSQUELCH) spnrSQUELCH->activate();
}
} else {
switch (progStatus.UIsize) {
case small_ui :
if (sldrSQUELCH) sldrSQUELCH->hide();
if (spnrSQUELCH) spnrSQUELCH->hide();
break;
case wide_ui : case touch_ui : default :
if (sldrSQUELCH) sldrSQUELCH->deactivate();
if (spnrSQUELCH) spnrSQUELCH->deactivate();
}
}
}
void set_init_sql_control()
{
if (!selrig->has_sql_control)
return;
if (progStatus.use_rig_data) {
progStatus.squelch = selrig->get_squelch();
if (sldrSQUELCH) sldrSQUELCH->value(progStatus.squelch);
if (spnrSQUELCH) spnrSQUELCH->value(progStatus.squelch);
} else {
if (sldrSQUELCH) sldrSQUELCH->value(progStatus.squelch);
if (spnrSQUELCH) spnrSQUELCH->value(progStatus.squelch);
selrig->set_squelch(progStatus.squelch);
}
}
void set_init_noise_reduction_control()
{
if (!selrig->has_noise_reduction_control)
return;
if (progStatus.use_rig_data) {
progStatus.noise_reduction = selrig->get_noise_reduction();
progStatus.noise_reduction_val = selrig->get_noise_reduction_val();
btnNR->value(progStatus.noise_reduction);
if (sldrNR) sldrNR->value(progStatus.noise_reduction_val);
if (spnrNR) spnrNR->value(progStatus.noise_reduction_val);
if (selrig->name_ == rig_FT891.name_) {
// On the FT-891, the usual definitions of NB and NR buttons
// as defined in FLRIG are reversed. Relabel them to match
// what the user sees in the radio screens, and handle the
// mapping to appropriate cat controls in the FT891.xx class.
btnNR->label("NB");
btnNR->tooltip(_("Noise Blanker On/Off"));
}
} else {
btnNR->value(progStatus.noise_reduction);
if (sldrNR) sldrNR->value(progStatus.noise_reduction_val);
if (spnrNR) spnrNR->value(progStatus.noise_reduction_val);
selrig->set_noise_reduction(progStatus.noise_reduction);
selrig->set_noise_reduction_val(progStatus.noise_reduction_val);
}
}
void init_noise_reduction_control()
{
if (selrig->has_noise_reduction_control) {
int min, max, step;
selrig->get_nr_min_max_step(min, max, step);
if (sldrNR) sldrNR->minimum(min);
if (sldrNR) sldrNR->maximum(max);
if (sldrNR) sldrNR->step(step);
if (sldrNR) sldrNR->redraw();
if (spnrNR) spnrNR->minimum(min);
if (spnrNR) spnrNR->maximum(max);
if (spnrNR) spnrNR->step(step);
if (spnrNR) spnrNR->redraw();
if (selrig->name_ == rig_FT891.name_) {
// On the FT-891, the usual definitions of NB and NR buttons
// as defined in FLRIG are reversed. Relabel them to match
// what the user sees in the radio screens, and handle the
// mapping to appropriate cat controls in the FT891.xx class.
sldrNR->tooltip(_("Adjust noise blanker"));
}
switch (progStatus.UIsize) {
case small_ui :
btnNR->show();
if (sldrNR) sldrNR->show();
if (spnrNR) spnrNR->show();
break;
case wide_ui : case touch_ui : default:
btnNR->show();
if (sldrNR) sldrNR->show();//activate();
if (spnrNR) spnrNR->show();//activate();
break;
}
} else {
switch (progStatus.UIsize) {
case small_ui :
btnNR->hide();
if (sldrNR) sldrNR->hide();
if (spnrNR) sldrNR->hide();
break;
case wide_ui : case touch_ui : default :
btnNR->hide();//deactivate();
if (sldrNR) sldrNR->hide();//deactivate();
if (spnrNR) spnrNR->hide();//deactivate();
break;
}
}
}
void set_init_if_shift_control()
{
if (!selrig->has_ifshift_control)
return;
if (progStatus.use_rig_data) {
progStatus.shift = selrig->get_if_shift(progStatus.shift_val);
btnIFsh->value(progStatus.shift);
if (sldrIFSHIFT) sldrIFSHIFT->value(progStatus.shift_val);
if (spnrIFSHIFT) spnrIFSHIFT->value(progStatus.shift_val);
} else {
if (progStatus.shift) {
btnIFsh->value(1);
if (sldrIFSHIFT) sldrIFSHIFT->value(progStatus.shift_val);
if (spnrIFSHIFT) spnrIFSHIFT->value(progStatus.shift_val);
selrig->set_if_shift(progStatus.shift_val);
} else {
btnIFsh->value(0);
if (sldrIFSHIFT) sldrIFSHIFT->value(selrig->if_shift_mid);
if (spnrIFSHIFT) spnrIFSHIFT->value(selrig->if_shift_mid);
selrig->set_if_shift(selrig->if_shift_mid);
}
}
}
void init_if_shift_control()
{
if (btnLOCK) btnLOCK->hide();
if (btnCLRPBT) btnCLRPBT->hide();
if (sldrINNER) sldrINNER->hide();
if (sldrOUTER) sldrOUTER->hide();
if (btnIFsh) btnIFsh->hide();
if (sldrIFSHIFT) sldrIFSHIFT->hide();
if (spnrIFSHIFT) spnrIFSHIFT->hide();
if (selrig->has_ifshift_control) {
btnIFsh->show();
sldrIFSHIFT->show();
if (spnrIFSHIFT) spnrIFSHIFT->show();
int min, max, step;
selrig->get_if_min_max_step(min, max, step);
if (sldrIFSHIFT) sldrIFSHIFT->minimum(min);
if (sldrIFSHIFT) sldrIFSHIFT->maximum(max);
if (sldrIFSHIFT) sldrIFSHIFT->step(step);
if (sldrIFSHIFT) sldrIFSHIFT->redraw();
if (spnrIFSHIFT) spnrIFSHIFT->minimum(min);
if (spnrIFSHIFT) spnrIFSHIFT->maximum(max);
if (spnrIFSHIFT) spnrIFSHIFT->step(step);
if (spnrIFSHIFT) spnrIFSHIFT->redraw();
switch (progStatus.UIsize) {
case small_ui :
btnIFsh->show();
if (sldrIFSHIFT) sldrIFSHIFT->show();
if (spnrIFSHIFT) spnrIFSHIFT->show();
break;
case wide_ui : case touch_ui : default :
btnIFsh->activate();
if (sldrIFSHIFT) sldrIFSHIFT->activate();
if (spnrIFSHIFT) spnrIFSHIFT->activate();
break;
}
} else {
switch (progStatus.UIsize) {
case small_ui :
btnIFsh->hide();
if (sldrIFSHIFT) sldrIFSHIFT->hide();
if (spnrIFSHIFT) spnrIFSHIFT->hide();
break;
case wide_ui : case touch_ui : default :
btnIFsh->deactivate();
if (sldrIFSHIFT) sldrIFSHIFT->deactivate();
if (spnrIFSHIFT) spnrIFSHIFT->deactivate();
break;
}
}
if (selrig->has_pbt_controls) {
btnLOCK->show();
btnLOCK->value(progStatus.pbt_lock);
btnCLRPBT->show();
sldrINNER->show();
sldrOUTER->show();
sldrINNER->value(progStatus.pbt_inner);
sldrOUTER->value(progStatus.pbt_outer);
}
if (xcvr_name == rig_TS870S.name_) {
if (progStatus.imode_A == RIG_TS870S::tsCW ||
progStatus.imode_A == RIG_TS870S::tsCWR) {
btnIFsh->activate();
if (sldrIFSHIFT) sldrIFSHIFT->activate();
if (spnrIFSHIFT) spnrIFSHIFT->activate();
} else {
btnIFsh->deactivate();
if (sldrIFSHIFT) sldrIFSHIFT->deactivate();
if (spnrIFSHIFT) spnrIFSHIFT->deactivate();
}
}
}
void init_notch_control()
{
if (selrig->has_notch_control) {
int min, max, step;
selrig->get_notch_min_max_step(min, max, step);
if (sldrNOTCH) sldrNOTCH->minimum(min);
if (sldrNOTCH) sldrNOTCH->maximum(max);
if (sldrNOTCH) sldrNOTCH->step(step);
if (sldrNOTCH) sldrNOTCH->redraw();
if (spnrNOTCH) spnrNOTCH->minimum(min);
if (spnrNOTCH) spnrNOTCH->maximum(max);
if (spnrNOTCH) spnrNOTCH->step(step);
if (spnrNOTCH) spnrNOTCH->redraw();
switch (progStatus.UIsize) {
case small_ui :
btnNotch->show();
if (sldrNOTCH) sldrNOTCH->show();
if (spnrNOTCH) spnrNOTCH->show();
break;
case wide_ui : case touch_ui : default :
btnNotch->activate();
if (sldrNOTCH) sldrNOTCH->activate();
if (spnrNOTCH) spnrNOTCH->activate();
break;
}
} else {
switch (progStatus.UIsize) {
case small_ui :
btnNotch->hide();
if (sldrNOTCH) sldrNOTCH->hide();
if (spnrNOTCH) spnrNOTCH->hide();
break;
case wide_ui : case touch_ui : default :
btnNotch->deactivate();
if (sldrNOTCH) sldrNOTCH->deactivate();
if (spnrNOTCH) spnrNOTCH->deactivate();
break;
}
}
}
void set_init_notch_control()
{
if (selrig->has_notch_control) {
if (progStatus.use_rig_data) {
progStatus.notch = selrig->get_notch(progStatus.notch_val);
btnNotch->value(progStatus.notch);
if (sldrNOTCH) sldrNOTCH->value(progStatus.notch_val);
if (spnrNOTCH) spnrNOTCH->value(progStatus.notch_val);
} else {
btnNotch->value(progStatus.notch);
if (sldrNOTCH) sldrNOTCH->value(progStatus.notch_val);
if (spnrNOTCH) spnrNOTCH->value(progStatus.notch_val);
selrig->set_notch(progStatus.notch, progStatus.notch_val);
}
}
}
void init_micgain_control()
{
if (selrig->has_micgain_control || selrig->has_data_port) {
if (selrig->has_micgain_control) {
int min = 0, max = 0, step = 0;
selrig->get_mic_min_max_step(min, max, step);
if (sldrMICGAIN) sldrMICGAIN->minimum(min);
if (sldrMICGAIN) sldrMICGAIN->maximum(max);
if (sldrMICGAIN) sldrMICGAIN->step(step);
if (spnrMICGAIN) spnrMICGAIN->minimum(min);
if (spnrMICGAIN) spnrMICGAIN->maximum(max);
if (spnrMICGAIN) spnrMICGAIN->step(step);
switch (progStatus.UIsize) {
case small_ui :
if (sldrMICGAIN) sldrMICGAIN->show();
if (spnrMICGAIN) spnrMICGAIN->show();
break;
case wide_ui : case touch_ui : default :
if (sldrMICGAIN) sldrMICGAIN->activate();
if (spnrMICGAIN) spnrMICGAIN->activate();
break;
}
} else {
if (sldrMICGAIN) sldrMICGAIN->deactivate();
if (spnrMICGAIN) spnrMICGAIN->deactivate();
}
} else {
switch (progStatus.UIsize) {
case small_ui :
if (sldrMICGAIN) sldrMICGAIN->hide();
if (spnrMICGAIN) spnrMICGAIN->hide();
break;
case wide_ui : case touch_ui : default :
if (sldrMICGAIN) sldrMICGAIN->deactivate();
if (spnrMICGAIN) spnrMICGAIN->deactivate();
}
}
}
void set_init_micgain_control()
{
int min, max, step;
if (selrig->has_micgain_control) {
if (progStatus.use_rig_data)
progStatus.mic_gain = selrig->get_mic_gain();
else
selrig->set_mic_gain(progStatus.mic_gain);
selrig->get_mic_min_max_step(min, max, step);
if (sldrMICGAIN) {
sldrMICGAIN->minimum(min);
sldrMICGAIN->maximum(max);
sldrMICGAIN->step(step);
sldrMICGAIN->value(progStatus.mic_gain);
sldrMICGAIN->activate();
}
if (spnrMICGAIN) {
spnrMICGAIN->minimum(min);
spnrMICGAIN->maximum(max);
spnrMICGAIN->step(step);
spnrMICGAIN->value(progStatus.mic_gain);
spnrMICGAIN->activate();
}
} else {
if (sldrMICGAIN) sldrMICGAIN->deactivate();
if (spnrMICGAIN) sldrMICGAIN->deactivate();
}
}
void init_power_control()
{
double min, max, step;
if (selrig->has_power_control) {
if (progStatus.use_rig_data)
progStatus.power_level = selrig->get_power_control();
else
selrig->set_power_control(progStatus.power_level);
sldrPOWER->activate();
selrig->get_pc_min_max_step(min, max, step);
if (sldrPOWER) sldrPOWER->minimum(min);
if (sldrPOWER) sldrPOWER->maximum(max);
if (sldrPOWER) sldrPOWER->step(step);
if (sldrPOWER) sldrPOWER->value(progStatus.power_level);
if (sldrPOWER) sldrPOWER->show();
if (sldrPOWER) sldrPOWER->redraw();
if (spnrPOWER) spnrPOWER->minimum(min);
if (spnrPOWER) spnrPOWER->maximum(max);
if (spnrPOWER) spnrPOWER->step(step);
if (spnrPOWER) spnrPOWER->value(progStatus.power_level);
if (spnrPOWER) spnrPOWER->show();
if (spnrPOWER) spnrPOWER->redraw();
} else {
if (sldrPOWER) sldrPOWER->deactivate();
if (spnrPOWER) spnrPOWER->deactivate();
}
}
void set_init_power_control()
{
if (selrig->has_power_control) {
if (progStatus.use_rig_data)
progStatus.power_level = selrig->get_power_control();
else
selrig->set_power_control(progStatus.power_level);
}
set_power_controlImage(progStatus.power_level);
}
void init_attenuator_control()
{
if (selrig->has_attenuator_control) {
if (selrig->name_ == rig_FT891.name_) {
btnAttenuator->label("ATT");
btnAttenuator->redraw_label();
}
switch (progStatus.UIsize) {
case small_ui :
btnAttenuator->show();
break;
case wide_ui : case touch_ui : default :
btnAttenuator->activate();
}
} else {
switch (progStatus.UIsize) {
case small_ui :
btnAttenuator->hide();
break;
case wide_ui : case touch_ui : default :
btnAttenuator->deactivate();
}
}
}
void set_init_attenuator_control()
{
if (selrig->has_attenuator_control) {
if (!progStatus.use_rig_data)
selrig->set_attenuator(progStatus.attenuator);
}
}
void init_agc_control()
{
if (selrig->has_agc_control) {
btnAGC->show();
sldrRFGAIN->label("");
sldrRFGAIN->redraw_label();
} else {
btnAGC->hide();
sldrRFGAIN->label(_("RF"));
sldrRFGAIN->redraw_label();
}
}
void init_preamp_control()
{
if (selrig->has_preamp_control) {
if (selrig->name_ == rig_FT891.name_) {
btnPreamp->label("IPO");
btnPreamp->redraw_label();
}
switch (progStatus.UIsize) {
case small_ui :
btnPreamp->show();
break;
case wide_ui : case touch_ui : default :
btnPreamp->activate();
}
} else {
switch (progStatus.UIsize) {
case small_ui :
btnPreamp->hide();
break;
case wide_ui : case touch_ui : default :
btnPreamp->deactivate();
}
}
}
void set_init_preamp_control()
{
if (selrig->has_preamp_control) {
if (!progStatus.use_rig_data)
selrig->set_preamp(progStatus.preamp);
}
}
void init_noise_control()
{
int min, max, step;
if (selrig->has_noise_control) {
if (xcvr_name == rig_TS990.name_) {
btnNOISE->label("AGC"); //Set TS990 AGC Label
btnNR->label("NR1"); //Set TS990 NR Button
}
if (selrig->name_ == rig_FT891.name_) {
// On the FT-891, the usual definitions of NB and NR buttons
// as defined in FLRIG are reversed. Relabel them to match
// what the user sees in the radio screens, and handle the
// mapping to appropriate cat controls in the FT891.xx class.
btnNOISE->label("DNR");
btnNOISE->tooltip(_("DSP Noise Reduction On/Off. See RX tab for DNR level."));
}
btnNOISE->show();
btnNOISE->activate();
}
else {
btnNOISE->hide();
btnNOISE->deactivate();
}
if (selrig->has_nb_level) {
selrig->get_nb_min_max_step(min, max, step);
sldr_nb_level->minimum(min);
sldr_nb_level->maximum(max);
sldr_nb_level->step(step);
sldr_nb_level->value(progStatus.nb_level);
if (selrig->name_ == rig_FT891.name_) {
// On the FT-891, the usual definitions of NB and NR buttons
// as defined in FLRIG are reversed. Relabel them to match
// what the user sees in the radio screens, and handle the
// mapping to appropriate cat controls in the FT891.xx class.
sldr_nb_level->label("DNR level");
sldr_nb_level->tooltip(_("Adjust DSP Noise Reduction level"));
}
sldr_nb_level->activate();
sldr_nb_level->redraw();
} else
sldr_nb_level->deactivate();
}
void set_init_noise_control()
{
if (selrig->has_noise_control) {
if (progStatus.use_rig_data)
progStatus.noise = selrig->get_noise();
else
selrig->set_noise(progStatus.noise);
btnNOISE->value(progStatus.noise);
btnNOISE->show();
btnNOISE->activate();
}
}
void init_tune_control()
{
if (selrig->has_tune_control) {
switch (progStatus.UIsize) {
case small_ui :
btnTune->show();
btn_tune_on_off->show();
break;
case wide_ui : case touch_ui : default :
btnTune->activate();
btn_tune_on_off->activate();
}
} else {
switch (progStatus.UIsize) {
case small_ui :
btnTune->hide();
btn_tune_on_off->hide();
break;
case wide_ui : case touch_ui : default :
btnTune->deactivate();
btn_tune_on_off->deactivate();
}
}
}
void init_ptt_control()
{
if (selrig->has_ptt_control ||
progStatus.comm_dtrptt || progStatus.comm_rtsptt ||
progStatus.sep_dtrptt || progStatus.sep_rtsptt) {
btnPTT->activate();
} else {
btnPTT->deactivate();
}
}
void init_auto_notch()
{
if (selrig->has_auto_notch) {
if (xcvr_name == rig_RAY152.name_) {
btnAutoNotch->label("AGC");
btnAutoNotch->tooltip("AGC on/off");
} else if (xcvr_name == rig_FT1000MP.name_) {
btnAutoNotch->label("Tuner");
btnAutoNotch->tooltip("Tuner on/off");
} else if (xcvr_name == rig_FT891.name_) {
btnAutoNotch->label("DNF");
btnAutoNotch->tooltip("DSP Auto notch filter on/off");
} else {
btnAutoNotch->label("AN");
btnAutoNotch->tooltip("Auto notch on/off");
}
switch (progStatus.UIsize) {
case small_ui :
btnAutoNotch->show();
break;
case wide_ui : case touch_ui : default :
btnAutoNotch->activate();
}
} else {
switch (progStatus.UIsize) {
case small_ui :
btnAutoNotch->hide();
break;
case wide_ui : case touch_ui : default :
btnAutoNotch->deactivate();
}
}
}
void set_init_auto_notch()
{
if (selrig->has_auto_notch) {
if (progStatus.use_rig_data)
progStatus.auto_notch = selrig->get_auto_notch();
else
selrig->set_auto_notch(progStatus.auto_notch);
btnAutoNotch->value(progStatus.auto_notch);
}
}
void init_swr_control()
{
if (selrig->has_swr_control)
btnALC_SWR->activate();
else {
btnALC_SWR->deactivate();
}
}
void set_init_compression_control()
{
if (selrig->has_compON || selrig->has_compression) {
selrig->set_compression(progStatus.compON, progStatus.compression);
if (selrig->name_ == rig_FT891.name_) {
// On the FT-891, compression is called PRC, under function
// menu FUNCTION-1. Set the button to match for consistency.
btnCompON->label("PRC");
btnCompON->tooltip("Set speech processor for SSB modes on/off.");
}
}
}
void init_special_controls()
{
if (selrig->has_special)
btnSpecial->show();
else
btnSpecial->hide();
}
void init_external_tuner()
{
if (selrig->has_ext_tuner)
btn_ext_tuner->show();
else
btn_ext_tuner->hide();
}
void init_CIV()
{
if (selrig->CIV) {
char hexstr[8];
snprintf(hexstr, sizeof(hexstr), "0x%02X", selrig->CIV);
txtCIV->value(hexstr);
txtCIV->activate();
btnCIVdefault->activate();
if (selrig->name_ == rig_IC7200.name_ ||
selrig->name_ == rig_IC7300.name_ ||
selrig->name_ == rig_IC7600.name_ ||
selrig->name_ == rig_IC7800.name_ ) {
btnUSBaudio->value(progStatus.USBaudio = true);
btnUSBaudio->activate();
} else
btnUSBaudio->deactivate();
} else {
txtCIV->value("");
txtCIV->deactivate();
btnCIVdefault->deactivate();
btnUSBaudio->value(false);
btnUSBaudio->deactivate();
}
}
void init_VFOs()
{
if (selrig->name_ == rig_TT550.name_) return;
if (selrig->name_ == rig_FT817.name_) {
FreqDispA->value(vfoA.freq);
FreqDispB->value(vfoB.freq);
updateBandwidthControl();
highlight_vfo(NULL);
useB = false;
return;
}
if (!progStatus.use_rig_data) {
vfoB.freq = progStatus.freq_B;
vfoB.imode = progStatus.imode_B;
vfoB.iBW = progStatus.iBW_B;
//std::cout << "use Status data, vfoB.freq " << vfoB.freq << std::endl;
if (vfoB.iBW == -1)
vfoB.iBW = selrig->def_bandwidth(vfoB.imode);
useB = true;
selrig->selectB();
selrig->set_modeB(vfoB.imode);
selrig->set_bwB(vfoB.iBW);
selrig->set_vfoB(vfoB.freq);
FreqDispB->value(vfoB.freq);
update_progress(progress->value() + 4);
trace(2, "init_VFOs() vfoB ", printXCVR_STATE(vfoB).c_str());
vfoA.freq = progStatus.freq_A;
vfoA.imode = progStatus.imode_A;
vfoA.iBW = progStatus.iBW_A;
if (vfoA.iBW == -1)
vfoA.iBW = selrig->def_bandwidth(vfoA.imode);
useB = false;
selrig->selectA();
selrig->set_modeA(vfoA.imode);
selrig->set_bwA(vfoA.iBW);
selrig->set_vfoA(vfoA.freq);
FreqDispA->value( vfoA.freq );
//std::cout << "use Status data, vfoA.freq " << vfoA.freq << std::endl;
update_progress(progress->value() + 4);
vfo = &vfoA;
updateBandwidthControl();
highlight_vfo((void *)0);
trace(2, "init_VFOs() vfoA ", printXCVR_STATE(vfoA).c_str());
}
else {
// Capture VFOA mode and bandwidth, since it will be lost in VFO switch
if (selrig->name_ == rig_FT891.name_) {
useB = false;
vfoA.freq = selrig->get_vfoA();
update_progress(progress->value() + 4);
vfoA.imode = selrig->get_modeA();
update_progress(progress->value() + 4);
vfoA.iBW = selrig->get_bwA();
update_progress(progress->value() + 4);
FreqDispA->value(vfoA.freq);
trace(2, "A: ", printXCVR_STATE(vfoA).c_str());
useB = true;
selrig->selectB(); // third select call
vfoB.freq = selrig->get_vfoB();
update_progress(progress->value() + 4);
vfoB.imode = selrig->get_modeB();
update_progress(progress->value() + 4);
vfoB.iBW = selrig->get_bwB();
update_progress(progress->value() + 4);
FreqDispB->value(vfoB.freq);
trace(2, "B: ", printXCVR_STATE(vfoB).c_str());
// Restore radio VFOA mode, then freq and bandwidth
useB = false;
selrig->selectA(); // fourth select call
yaesu891UpdateA(&vfoA);
} else {
vfoB = xcvr_vfoB;
vfoA = xcvr_vfoA;
//std::cout << "use rig data, vfoA.freq " << vfoA.freq << std::endl;
//std::cout << "use rig data, vfoB.freq " << vfoB.freq << std::endl;
FreqDispB->value(vfoB.freq);
FreqDispA->value(vfoA.freq);
}
vfo = &vfoA;
setModeControl((void *)0);
update_progress(progress->value() + 4);
updateBandwidthControl();
update_progress(progress->value() + 4);
highlight_vfo((void *)0);
}
selrig->set_split(0); // initialization set split call
}
void init_IC7300_special()
{
if (selrig->name_ == rig_IC7300.name_) {
selrig->enable_break_in();
redrawAGC();
}
}
void init_TS990_special()
{
if (xcvr_name == rig_TS990.name_) { // Setup TS990 Mon Button
btnIFsh->label("MON");
}
}
void init_K3_KX3_special()
{
if (xcvr_name == rig_K3.name_) {
btnB->hide();
btnA->hide();
btn_KX3_swapAB->hide();
btn_K3_swapAB->show();
} else if (xcvr_name == rig_KX3.name_) {
btnB->hide();
btnA->hide();
btn_K3_swapAB->hide();
btn_KX3_swapAB->show();
} else {
btn_K3_swapAB->hide();
btn_KX3_swapAB->hide();
btnB->show();
btnA->show();
}
}
void initRig()
{
xcvr_initialized = false;
if (tabs_dialog && tabs_dialog->visible()) tabs_dialog->hide();
grpInitializing->show();
main_group->hide();
mainwindow->redraw();
flrig_abort = false;
sldrRcvSignal->aging(progStatus.rx_peak);
sldrRcvSignal->avg(progStatus.rx_avg);
sldrFwdPwr->aging(progStatus.pwr_peak);
sldrFwdPwr->avg(progStatus.pwr_avg);
if (progStatus.use_tcpip) {
try {
connect_to_remote();
} catch (...) {
grpInitializing->hide();
main_group->show();
mainwindow->redraw();
return;
}
}
// disable the serial thread
{
guard_lock gl_serial(&mutex_serial);
trace(1, "init_rig()");
// Xcvr Auto Power on as soon as possible
if (selrig->has_xcvr_auto_on_off && progStatus.xcvr_auto_on)
selrig->set_xcvr_auto_on();
init_special_controls();
init_external_tuner();
init_rit();
init_xit();
init_bfo();
init_dsp_controls();
init_volume_control();
init_rf_control();
init_sql_control();
init_noise_reduction_control();
init_if_shift_control();
init_notch_control();
init_micgain_control();
init_power_control();
init_attenuator_control();
init_agc_control();
init_preamp_control();
init_noise_control();
init_tune_control();
init_ptt_control();
init_auto_notch();
init_swr_control();
selrig->initialize();
if (progStatus.xcvr_serial_port != "NONE") {
if (!selrig->check()) goto failed;
if (flrig_abort) goto failed;
}
FreqDispA->set_precision(selrig->precision);
FreqDispA->set_ndigits(selrig->ndigits);
FreqDispB->set_precision(selrig->precision);
FreqDispB->set_ndigits(selrig->ndigits);
FreqDispB->set_precision(selrig->precision);
FreqDispB->set_ndigits(selrig->ndigits);
FreqDispB->set_precision(selrig->precision);
FreqDispB->set_ndigits(selrig->ndigits);
if (xcvr_name == rig_TT550.name_)
init_TT550();
else
init_generic_rig();
set_init_volume_control();
set_init_rf_gain();
set_init_sql_control();
set_init_noise_reduction_control();
set_init_if_shift_control();
set_init_micgain_control();
set_init_power_control();
set_init_attenuator_control();
set_init_preamp_control();
set_init_noise_control();
set_init_auto_notch();
set_init_notch_control();
set_init_compression_control();
initTabs();
buildlist();
init_CIV();
init_VFOs();
selrig->post_initialize();
init_IC7300_special();
init_TS990_special();
init_K3_KX3_special();
btnAswapB->show();
} // enable the serial thread
bypass_serial_thread_loop = false;
grpInitializing->hide();
adjust_control_positions();
main_group->show();
mainwindow->redraw();
mainwindow->damage();
Fl::flush();
// Fl::check();
xcvr_initialized = true;
return;
failed:
xcvr_initialized = false;
adjust_control_positions();
grpInitializing->hide();
main_group->show();
mainwindow->redraw();
bypass_serial_thread_loop = true;
fl_alert2(_("\
Transceiver not responding!\n\n\
Check serial (COM) port connection\n\
Open menu Config/Setup/Transceiver\n\
Press 'Ser Port' button, reselect port\n\
Press 'Init' button."));
return;
}
void init_title()
{
title = PACKAGE;
title += " ";
title.append(selrig->name_);
mainwindow->label(title.c_str());
}
void initConfigDialog()
{
int picked = selectRig->index();
rigbase *srig = rigs[picked];
xcvr_name = srig->name_;
if (!progStatus.loadXcvrState(xcvr_name) ) {
selectCommPort->index(0);
mnuBaudrate->index( srig->comm_baudrate );
btnOneStopBit->value( srig->stopbits == 1 );
btnTwoStopBit->value( srig->stopbits == 2 );
cntRigCatRetries->value( srig->comm_retries );
cntRigCatTimeout->value( srig->comm_timeout );
cntRigCatWait->value( srig->comm_wait );
btnRigCatEcho->value( srig->comm_echo );
btncatptt->value( srig->comm_catptt );
btnrtsptt->value( srig->comm_rtsptt );
btndtrptt->value( srig->comm_dtrptt );
chkrtscts->value( srig->comm_rtscts );
btnrtsplus->value( srig->comm_rtsplus );
btndtrplus->value( srig->comm_dtrplus );
if (selrig->CIV) {
char hexstr[8];
snprintf(hexstr, sizeof(hexstr), "0x%02X", srig->CIV);
txtCIV->value(hexstr);
txtCIV->activate();
btnCIVdefault->activate();
if (xcvr_name == rig_IC7200.name_ ||
xcvr_name == rig_IC7300.name_ ||
xcvr_name == rig_IC7600.name_ ||
xcvr_name == rig_IC7800.name_) {
btnUSBaudio->value(progStatus.USBaudio = true);
btnUSBaudio->activate();
} else
btnUSBaudio->deactivate();
} else {
txtCIV->value("");
txtCIV->deactivate();
btnCIVdefault->deactivate();
btnUSBaudio->value(false);
btnUSBaudio->deactivate();
}
} else {
initStatusConfigDialog();
trace(1, progStatus.info().c_str());
}
}
void initStatusConfigDialog()
{
if (progStatus.CIV) selrig->adjustCIV(progStatus.CIV);
selectRig->value(xcvr_name.c_str());
mnuBaudrate->index( progStatus.comm_baudrate );
selectCommPort->value( progStatus.xcvr_serial_port.c_str() );
selectAuxPort->value( progStatus.aux_serial_port.c_str() );
selectSepPTTPort->value( progStatus.sep_serial_port.c_str() );
btnOneStopBit->value( progStatus.stopbits == 1 );
btnTwoStopBit->value( progStatus.stopbits == 2 );
cntRigCatRetries->value( progStatus.comm_retries );
cntRigCatTimeout->value( progStatus.comm_timeout );
cntRigCatWait->value( progStatus.comm_wait );
btnRigCatEcho->value( progStatus.comm_echo );
btncatptt->value( progStatus.comm_catptt );
btnrtsptt->value( progStatus.comm_rtsptt );
btndtrptt->value( progStatus.comm_dtrptt );
chkrtscts->value( progStatus.comm_rtscts );
btnrtsplus->value( progStatus.comm_rtsplus );
btndtrplus->value( progStatus.comm_dtrplus );
btnSepDTRplus->value(progStatus.sep_dtrplus);
btnSepDTRptt->value(progStatus.sep_dtrptt);
btnSepRTSplus->value(progStatus.sep_rtsplus);
btnSepRTSptt->value(progStatus.sep_rtsptt);
if (progStatus.use_tcpip) {
box_xcvr_connect->color(FL_BACKGROUND2_COLOR);
box_xcvr_connect->redraw();
} else {
if (!startXcvrSerial()) {
if (progStatus.xcvr_serial_port.compare("NONE") == 0) {
LOG_WARN("No comm port ... test mode");
} else {
fl_alert2("\
Cannot open %s!\n\n\
Check serial (COM) port connection\n\
Open menu Config/Setup/Transceiver\n\
Press 'Ser Port' button, reselect port\n\
Press 'Init' button.", progStatus.xcvr_serial_port.c_str());
LOG_WARN("Cannot open %s", progStatus.xcvr_serial_port.c_str());
progStatus.xcvr_serial_port = "NONE";
selectCommPort->value(progStatus.xcvr_serial_port.c_str());
}
box_xcvr_connect->color(FL_BACKGROUND2_COLOR);
box_xcvr_connect->redraw();
} else {
selectCommPort->value(progStatus.xcvr_serial_port.c_str());
box_xcvr_connect->color(FL_GREEN);
box_xcvr_connect->redraw();
}
if (!startAuxSerial()) {
if (progStatus.aux_serial_port.compare("NONE") != 0) {
LOG_WARN("Cannot open %s", progStatus.aux_serial_port.c_str());
progStatus.aux_serial_port = "NONE";
selectAuxPort->value(progStatus.aux_serial_port.c_str());
}
}
if (!startSepSerial()) {
if (progStatus.sep_serial_port.compare("NONE") != 0) {
LOG_WARN("Cannot open %s", progStatus.sep_serial_port.c_str());
progStatus.sep_serial_port = "NONE";
selectSepPTTPort->value(progStatus.sep_serial_port.c_str());
}
}
}
init_title();
initRig();
}
void initRigCombo()
{
selectRig->clear();
int i = 0;
while (rigs[i] != NULL)
selectRig->add(rigs[i++]->name_.c_str());
selectRig->index(0);
}
//----------------------------------------------------------------------
// button label and label state changes
// Note that an additional level of service request is made to insure
// that the main thread is actually changing the widget
// noise reduction
static std::string nr_label_;
static bool nr_state_;
void do_nr_label(void *)
{
btnNR->value(nr_state_ ? 1 : 0);
btnNR->label(nr_label_.c_str());
btnNR->redraw_label();
}
void nr_label(const char *l, bool on = false)
{
nr_label_ = l;
nr_state_ = on;
Fl::awake(do_nr_label);
}
// noise blanker
static std::string nb_label_;
static bool nb_state_;
void do_nb_label(void *)
{
btnNOISE->value(nb_state_ ? 1 : 0);
btnNOISE->label(nb_label_.c_str());
btnNOISE->redraw_label();
}
void nb_label(const char * l, bool on = false)
{
nb_label_ = l;
nb_state_ = on;
Fl::awake(do_nb_label);
}
// preamp label
static std::string preamp_label_;
static bool preamp_state_;
void do_preamp_label(void *)
{
btnPreamp->value(preamp_state_ ? 1 : 0);
btnPreamp->label(preamp_label_.c_str());
btnPreamp->redraw_label();
}
void preamp_label(const char * l, bool on = false)
{
preamp_label_ = l;
preamp_state_ = on;
Fl::awake(do_preamp_label);
}
// atten label
static std::string atten_label_;
static bool atten_state_;
void do_atten_label(void *)
{
btnAttenuator->value(atten_state_ ? 1 : 0);
btnAttenuator->label(atten_label_.c_str());
btnAttenuator->redraw_label();
}
void atten_label(const char * l, bool on = false)
{
atten_label_ = l;
atten_state_ = on;
Fl::awake(do_atten_label);
}
// break-in label
static std::string bkin_label_;
void do_bkin_label(void *)
{
btnBreakIn->label(bkin_label_.c_str());
btnBreakIn->redraw_label();
}
void break_in_label(const char *l)
{
bkin_label_ = l;
Fl::awake(do_bkin_label);
}
// autonotch label
static std::string auto_notch_label_;
static bool auto_notch_state_;
void do_auto_notch_label(void *)
{
btnAutoNotch->value(auto_notch_state_ ? 1 : 0);
btnAutoNotch->label(auto_notch_label_.c_str());
btnAutoNotch->redraw_label();
}
void auto_notch_label(const char * l, bool on = false)
{
auto_notch_label_ = l;
auto_notch_state_ = on;
Fl::awake(do_auto_notch_label);
}
void cbAuxPort()
{
AuxSerial->setRTS(progStatus.aux_rts);
AuxSerial->setDTR(progStatus.aux_dtr);
}
void cb_agc_level()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_agc_level()");
selrig->set_agc_level();
}
void cb_cw_wpm()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_cw_wpm()");
selrig->set_cw_wpm();
}
void cb_cw_vol()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_cw_vol()");
selrig->set_cw_vol();
}
void cb_cw_spot()
{
int ret;
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_cw_spot()");
ret = selrig->set_cw_spot();
if (!ret) btnSpot->value(0);
}
void cb_cw_spot_tone()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_cw_spot_tone()");
selrig->set_cw_spot_tone();
}
void cb_vox_gain()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_vox_gain()");
selrig->set_vox_gain();
}
void cb_vox_anti()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_vox_anti()");
selrig->set_vox_anti();
}
void cb_vox_hang()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_vox_hang()");
selrig->set_vox_hang();
}
void cb_vox_onoff()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_vox_onoff()");
selrig->set_vox_onoff();
}
void cb_vox_on_dataport()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_dataport()");
selrig->set_vox_on_dataport();
}
void cb_compression()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_compression");
selrig->set_compression(progStatus.compON, progStatus.compression);
}
void cb_auto_notch()
{
progStatus.auto_notch = btnAutoNotch->value();
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_autonotch()");
selrig->set_auto_notch(progStatus.auto_notch);
}
void cb_vfo_adj()
{
if (xcvr_name == rig_TT550.name_)
progStatus.vfo_adj = spnr_tt550_vfo_adj->value();
else
progStatus.vfo_adj = spnr_vfo_adj->value();
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_vfo_adj()");
selrig->setVfoAdj(progStatus.vfo_adj);
}
void cb_line_out()
{
}
void cb_bpf_center()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_bpf_center()");
selrig->set_if_shift(selrig->pbt);
}
void cb_special()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_special()");
selrig->set_special(btnSpecial->value());
}
void cbNoise()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cbNoise()");
int btn, get, cnt = 0;
btn = progStatus.noise = btnNOISE->value();
selrig->set_noise(btn);
MilliSleep(progStatus.comm_wait);
get = selrig->get_noise();
while ((get != btn) && (cnt++ < 10)) {
MilliSleep(progStatus.comm_wait);
get = selrig->get_noise();
Fl::awake();
}
}
void cb_nb_level()
{
if (!selrig->has_nb_level) return;
int set = 0;
trace(1, "cb_nb_level()");
int ev = Fl::event();
if (ev == FL_DRAG || ev == FL_PUSH || ev == FL_MOUSEWHEEL)
inhibit_nb_level = 2;
else if (ev == FL_RELEASE || ev == FL_LEAVE)
inhibit_nb_level = 1;
set = sldr_nb_level->value();
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::NB_LEVEL;
slider.val = set;
sliders.push(slider);
}
void cbNR()
{
if (!selrig->has_noise_reduction_control) return;
guard_lock serial_lock(&mutex_serial);
trace(1, "cbNR()");
int btn = 0, set = 0, get, cnt = 0;
if (sldrNR) {
set = sldrNR->value();
btn = btnNR->value();
}
if (spnrNR) {
set = spnrNR->value();
btn = btnNR->value();
}
if (xcvr_name == rig_TS2000.name_) {
if (btn != -1) { // pia
if (selrig->noise_reduction_level() == 0) {
selrig->set_noise_reduction(1);
selrig->set_noise_reduction_val(selrig->nrval1());
progStatus.noise_reduction = 1;
progStatus.noise_reduction_val = selrig->nrval1();
} else if (selrig->currmode() != RIG_TS2000::FM &&
selrig->noise_reduction_level() == 1) {
selrig->set_noise_reduction(2);
selrig->set_noise_reduction_val(selrig->nrval2());
progStatus.noise_reduction = 2;
progStatus.noise_reduction_val = selrig->nrval2();
} else
selrig->set_noise_reduction(0);
} else {
progStatus.noise_reduction_val = set;
selrig->set_noise_reduction_val(set);
}
} else { // not TS2000
progStatus.noise_reduction = btn;
selrig->set_noise_reduction(btn);
MilliSleep(progStatus.comm_wait);
get = selrig->get_noise_reduction();
while ((get != btn) && (cnt++ < 10)) {
MilliSleep(progStatus.comm_wait);
get = selrig->get_noise_reduction();
Fl::awake();
}
progStatus.noise_reduction_val = set;
selrig->set_noise_reduction_val(set);
MilliSleep(progStatus.comm_wait);
get = selrig->get_noise_reduction_val();
cnt = 0;
while ((get != set) && (cnt++ < 10)) {
MilliSleep(progStatus.comm_wait);
get = selrig->get_noise_reduction_val();
Fl::awake();
}
}
}
void setNR()
{
if (!selrig->has_noise_reduction_control) return;
trace(1, "setNR()");
int btn = 0, set = 0;
int ev = Fl::event();
if (ev == FL_DRAG || ev == FL_PUSH || ev == FL_MOUSEWHEEL)
inhibit_nr = 2;
else if (ev == FL_RELEASE || ev == FL_LEAVE)
inhibit_nr = 1;
if (xcvr_name == rig_TS2000.name_ ||
xcvr_name == rig_TS590S.name_ ||
xcvr_name == rig_TS590SG.name_ ||
xcvr_name == rig_TS890S.name_ ||
xcvr_name == rig_TS990.name_) {
if (sldrNR) {
set = sldrNR->value();
btn = -1;
}
if (spnrNR) {
set = spnrNR->value();
btn = -1;
}
} else {
if (sldrNR) {
set = sldrNR->value();
btn = btnNR->value();
}
if (spnrNR) {
set = spnrNR->value();
btn = btnNR->value();
}
}
guard_lock lcksldr(&mutex_sliders);
SLIDER slider;
slider.fnc = SLIDER::NR;
slider.val = btn;
sliders.push(slider);
slider.fnc = SLIDER::NR_VAL;
slider.val = set;
sliders.push(slider);
}
void cb_spot()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_spot()");
selrig->set_cw_spot();
}
void cb_enable_keyer()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_enable_keyer()");
selrig->enable_keyer();
}
void cb_enable_break_in()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_enable_break_in()");
selrig->enable_break_in();
}
void cb_cw_weight()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_cw_weight()");
selrig->set_cw_weight();
}
void cb_cw_qsk()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_cw_qsk()");
selrig->set_cw_qsk();
}
void cb_cw_delay()
{
guard_lock serial_lock(&mutex_serial);
trace(1, "cb_cw_delay()");
selrig->set_cw_delay();
}
void set_band(int band)
{
switch (band) {
case 1: progStatus.f160 = vfo->freq;
progStatus.m160 = vfo->imode;
progStatus.txT_160 = choice_FT8n_tTONE->value();
progStatus.rxT_160 = choice_FT8n_rTONE->value();
progStatus.offset_160 = FMoffset->index();
progStatus.oF_160 = FMoff_freq->value();
break; // 160 meters
case 2: progStatus.f80 = vfo->freq;
progStatus.m80 = vfo->imode;
progStatus.txT_80 = choice_FT8n_tTONE->value();
progStatus.rxT_80 = choice_FT8n_rTONE->value();
progStatus.offset_80 = FMoffset->index();
progStatus.oF_80 = FMoff_freq->value();
break; // 80 meters
case 3: progStatus.f40 = vfo->freq;
progStatus.m40 = vfo->imode;
progStatus.txT_40 = choice_FT8n_tTONE->value();
progStatus.rxT_40 = choice_FT8n_rTONE->value();
progStatus.offset_40 = FMoffset->index();
progStatus.oF_40 = FMoff_freq->value();
break; // 40 meters
case 4: progStatus.f30 = vfo->freq;
progStatus.m30 = vfo->imode;
progStatus.txT_30 = choice_FT8n_tTONE->value();
progStatus.rxT_30 = choice_FT8n_rTONE->value();
progStatus.offset_30 = FMoffset->index();
progStatus.oF_30 = FMoff_freq->value();
break; // 30 meters
case 5: progStatus.f20 = vfo->freq;
progStatus.m20 = vfo->imode;
progStatus.txT_20 = choice_FT8n_tTONE->value();
progStatus.rxT_20 = choice_FT8n_rTONE->value();
progStatus.offset_20 = FMoffset->index();
progStatus.oF_20 = FMoff_freq->value();
break; // 20 meters
case 6: progStatus.f17 = vfo->freq;
progStatus.m17 = vfo->imode;
progStatus.txT_17 = choice_FT8n_tTONE->value();
progStatus.rxT_17 = choice_FT8n_rTONE->value();
progStatus.offset_17 = FMoffset->index();
progStatus.oF_17 = FMoff_freq->value();
break; // 17 meters
case 7: progStatus.f15 = vfo->freq;
progStatus.m15 = vfo->imode;
progStatus.txT_15 = choice_FT8n_tTONE->value();
progStatus.rxT_15 = choice_FT8n_rTONE->value();
progStatus.offset_15 = FMoffset->index();
progStatus.oF_15 = FMoff_freq->value();
break; // 15 meters
case 8: progStatus.f12 = vfo->freq;
progStatus.m12 = vfo->imode;
progStatus.txT_12 = choice_FT8n_tTONE->value();
progStatus.rxT_12 = choice_FT8n_rTONE->value();
progStatus.offset_12 = FMoffset->index();
progStatus.oF_12 = FMoff_freq->value();
break; // 12 meters
case 9: progStatus.f10 = vfo->freq;
progStatus.m10 = vfo->imode;
progStatus.txT_10 = choice_FT8n_tTONE->value();
progStatus.rxT_10 = choice_FT8n_rTONE->value();
progStatus.offset_10 = FMoffset->index();
progStatus.oF_10 = FMoff_freq->value();
break; // 10 meters
case 10:progStatus.f6 = vfo->freq;
progStatus.m6 = vfo->imode;
progStatus.txT_6 = choice_FT8n_tTONE->value();
progStatus.rxT_6 = choice_FT8n_rTONE->value();
progStatus.offset_6 = FMoffset->index();
progStatus.oF_6 = FMoff_freq->value();
break; // 6 meters
case 11:progStatus.f2 = vfo->freq;
progStatus.m2 = vfo->imode;
progStatus.txT_2 = choice_FT8n_tTONE->value();
progStatus.rxT_2 = choice_FT8n_rTONE->value();
progStatus.offset_2 = FMoffset->index();
progStatus.oF_2 = FMoff_freq->value();
break; // 2 meters
case 12:progStatus.f70 = vfo->freq;
progStatus.m70 = vfo->imode;
progStatus.txT_70 = choice_FT8n_tTONE->value();
progStatus.rxT_70 = choice_FT8n_rTONE->value();
progStatus.offset_70 = FMoffset->index();
progStatus.oF_70 = FMoff_freq->value();
break; // 70 cent'
}
}
void updateCTCSS(int band)
{
switch (band) {
case 1: choice_FT8n_tTONE->value(progStatus.txT_160);
choice_FT8n_rTONE->value(progStatus.txT_160);
FMoffset->index(progStatus.offset_160);
FMoff_freq->value(progStatus.oF_160 );
break; // 160 meters
case 2: choice_FT8n_tTONE->value(progStatus.txT_80);
choice_FT8n_rTONE->value(progStatus.txT_80);
FMoffset->index(progStatus.offset_80);
FMoff_freq->value(progStatus.oF_80 );
break; // 80 meters
case 3: choice_FT8n_tTONE->value(progStatus.txT_40);
choice_FT8n_rTONE->value(progStatus.txT_40);
FMoffset->index(progStatus.offset_40);
FMoff_freq->value(progStatus.oF_40 );
break; // 40 meters
case 4: choice_FT8n_tTONE->value(progStatus.txT_30);
choice_FT8n_rTONE->value(progStatus.txT_30);
FMoffset->index(progStatus.offset_30);
FMoff_freq->value(progStatus.oF_30 );
break; // 30 meters
case 5: choice_FT8n_tTONE->value(progStatus.txT_20);
choice_FT8n_rTONE->value(progStatus.txT_20);
FMoffset->index(progStatus.offset_20);
FMoff_freq->value(progStatus.oF_20 );
break; // 20 meters
case 6: choice_FT8n_tTONE->value(progStatus.txT_17);
choice_FT8n_rTONE->value(progStatus.txT_17);
FMoffset->index(progStatus.offset_17);
FMoff_freq->value(progStatus.oF_17 );
break; // 17 meters
case 7: choice_FT8n_tTONE->value(progStatus.txT_15);
choice_FT8n_rTONE->value(progStatus.txT_15);
FMoffset->index(progStatus.offset_15);
FMoff_freq->value(progStatus.oF_15 );
break; // 15 meters
case 8: choice_FT8n_tTONE->value(progStatus.txT_12);
choice_FT8n_rTONE->value(progStatus.txT_12);
FMoffset->index(progStatus.offset_12);
FMoff_freq->value(progStatus.oF_12 );
break; // 12 meters
case 9: choice_FT8n_tTONE->value(progStatus.txT_10);
choice_FT8n_rTONE->value(progStatus.txT_10);
FMoffset->index(progStatus.offset_10);
FMoff_freq->value(progStatus.oF_10 );
break; // 10 meters
case 10:choice_FT8n_tTONE->value(progStatus.txT_6);
choice_FT8n_rTONE->value(progStatus.txT_6);
FMoffset->index(progStatus.offset_6);
FMoff_freq->value(progStatus.oF_6 );
break; // 6 meters
case 11:choice_FT8n_tTONE->value(progStatus.txT_2);
choice_FT8n_rTONE->value(progStatus.txT_2);
FMoffset->index(progStatus.offset_2);
FMoff_freq->value(progStatus.oF_2 );
break; // 2 meters
case 12:choice_FT8n_tTONE->value(progStatus.txT_70);
choice_FT8n_rTONE->value(progStatus.txT_70);
FMoffset->index(progStatus.offset_70);
FMoff_freq->value(progStatus.oF_70 );
progStatus.m70 = vfo->imode;
break; // 70 cent'
}
}
void cbBandSelect(int band)
{
guard_lock gl_serial(&mutex_serial);
if (xcvr_name == rig_FT857D.name_ || xcvr_name == rig_FT897D.name_ ) {
if (Fl::event_button() == FL_LEFT_MOUSE) {
selrig->set_band_selection(band);
updateCTCSS(band);
if (band > 8) { // 10, 6, 2, 70
int tTONE = PL_tones[choice_FT8n_tTONE->value()];
int rTONE = PL_tones[choice_FT8n_rTONE->value()];
selrig->set_tones(tTONE, rTONE);
selrig->set_offset(FMoffset->index(), FMoff_freq->value());
}
} else if (Fl::event_button() == FL_RIGHT_MOUSE)
set_band(band);
return;
}
if (Fl::event_button() == FL_RIGHT_MOUSE) {
selrig->rTONE = choice_rTONE->value();
selrig->tTONE = choice_tTONE->value();
selrig->set_band_selection(band);
return;
}
selrig->get_band_selection(band);
// get freqmdbw
if (!useB) {
vfoA.freq = selrig->get_vfoA();
if (selrig->has_mode_control)
vfoA.imode = selrig->get_modeA();
if (selrig->has_bandwidth_control) {
selrig->adjust_bandwidth(vfoA.imode);
vfoA.iBW = selrig->get_bwA();
}
vfo = &vfoA;
} else {
vfoB.freq = selrig->get_vfoB();
if (selrig->has_mode_control)
vfoB.imode = selrig->get_modeB();
if (selrig->has_bandwidth_control) {
selrig->adjust_bandwidth(vfoB.imode);
vfoB.iBW = selrig->get_bwB();
}
vfo = &vfoB;
}
// local display freqmdbw
if (selrig->has_mode_control) {
setModeControl(NULL);
}
if (selrig->has_bandwidth_control) {
set_bandwidth_control();
setBWControl(NULL);
}
if (!useB) { FreqDispA->value(vfo->freq); FreqDispA->redraw(); }
else { FreqDispB->value(vfo->freq); FreqDispB->redraw(); }
if (selrig->CIV && (selrig->name_ != rig_IC7200.name_)) {
choice_tTONE->value(selrig->tTONE);
choice_tTONE->redraw();
choice_rTONE->value(selrig->rTONE);
choice_rTONE->redraw();
}
}
void enable_yaesu_bandselect(int btn_num, bool enable)
{
switch (btn_num) {
case 1:
case 9:
break;
case 10: // 6m
if (enable) btn_yaesu_select_10->show();
else btn_yaesu_select_10->hide();
break;
case 11: // GEN
if (enable) btn_yaesu_select_11->show();
else btn_yaesu_select_11->hide();
break;
case 13:
if (enable) op_yaesu_select60->show();
else op_yaesu_select60->hide();
break;
default:
break;
}
}
// trim leading and trailing whitspace and double quote
const string lt_trim(const string& pString, const string& pWhitespace)
{
size_t beginStr, endStr, range;
beginStr = pString.find_first_not_of(pWhitespace);
if (beginStr == string::npos) return ""; // no content
endStr = pString.find_last_not_of(pWhitespace);
range = endStr - beginStr + 1;
return pString.substr(beginStr, range);
}
void editAlphaTag()
{
int indx;
string atag;
if (FreqSelect->value() < 1) {
inAlphaTag->value("");
return; // no memory selected
}
indx = FreqSelect->value() - 1;
atag = inAlphaTag->value();
// delete leading, trailing spaces
atag = lt_trim(atag);
memset(oplist[indx].alpha_tag, 0, ATAGSIZE);
snprintf(oplist[indx].alpha_tag, ATAGSIZE, "%s", atag.c_str());
// update browser list
updateSelect();
FreqSelect->value(indx + 1);
inAlphaTag->value(oplist[indx].alpha_tag);
}
flrig-1.3.49/src/support/debug.cxx 0000644 0001750 0001750 00000012706 13605621006 013756 0000000 0000000 // ----------------------------------------------------------------------------
// debug.cxx
//
// Copyright (C) 2014
// Stelios Bounanos, M0GLD
// David Freese, W1HKJ
//
// This file is part of fldigi.
//
// fldigi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "debug.h"
#include "icons.h"
#include "gettext.h"
#include "rig.h"
#include "tod_clock.h"
#include "threads.h"
#include "support.h"
#include "trace.h"
using namespace std;
#define MAX_LINES 65536
pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
static FILE* wfile;
static FILE* rfile;
static int rfd;
static bool tty;
static Fl_Double_Window* window = (Fl_Double_Window *)0;
static Fl_Browser* btext = (Fl_Browser *)0;
static string buffer;
debug* debug::inst = 0;
//debug::level_e debug::level = debug::ERROR_LEVEL;
debug::level_e debug::level = debug::INFO_LEVEL;
uint32_t debug::mask = ~0u;
const char* prefix[] = { _("Quiet"), _("Error"), _("Warning"), _("Info"), _("Debug") };
static void slider_cb(Fl_Widget* w, void*);
static void clear_cb(Fl_Widget *w, void*);
void debug::start(const char* filename)
{
if (debug::inst)
return;
inst = new debug(filename);
window = new Fl_Double_Window(600, 256, _("Event log"));
int pad = 2;
Fl_Slider* slider = new Fl_Slider(pad, pad, 128, 20, prefix[level]);
slider->tooltip(_("Change log level"));
slider->align(FL_ALIGN_RIGHT);
slider->type(FL_HOR_NICE_SLIDER);
slider->range(0.0, LOG_NLEVELS - 1);
slider->step(1.0);
slider->value(level);
slider->callback(slider_cb);
Fl_Button* clearbtn = new Fl_Button(window->w() - 60, pad, 60, 20, "clear");
clearbtn->callback(clear_cb);
btext = new Fl_Browser(pad, slider->h()+pad, window->w()-2*pad, window->h()-slider->h()-2*pad, 0);
window->resizable(btext);
buffer.clear();
window->end();
}
void debug::stop(void)
{
guard_lock dlock(&debug_mutex);
delete inst;
inst = 0;
btext = 0;
if (window) {
delete window;
window = 0;
}
}
static char fmt[1024];
static char sztemp[8096];
static string estr = "";
void debug::log(level_e level, const char* func, const char* srcf, int line, const char* format, ...)
{
if (!inst) return;
if (level > debug::level) return;
snprintf(fmt, sizeof(fmt), "%c: %s: %s\n", *prefix[level], func, format);
va_list args;
va_start(args, format);
vsnprintf(sztemp, sizeof(sztemp), fmt, args);
// guard_lock dlock(&debug_mutex);
estr.append(sztemp);
if (progStatus.debugtrace) trace(1, sztemp);
fprintf(wfile, "[%s] %s", ztime(), sztemp);
va_end(args);
fflush(wfile);
Fl::awake(sync_text, 0);
}
void debug::slog(level_e level, const char* func, const char* srcf, int line, const char* format, ...)
{
if (!inst) return;
if (level > debug::level) return;
snprintf(fmt, sizeof(fmt), "%c:%s\n", *prefix[level], format);
va_list args;
va_start(args, format);
vsnprintf(sztemp, sizeof(sztemp), fmt, args);
// guard_lock dlock(&debug_mutex);
estr.append(sztemp);
if (progStatus.debugtrace) trace(1, sztemp);
fprintf(wfile, "[%s] %s", ztime(), sztemp);
va_end(args);
fflush(wfile);
Fl::awake(sync_text, 0);
}
void debug::elog(const char* func, const char* srcf, int line, const char* text)
{
log(ERROR_LEVEL, func, srcf, line, "%s: %s", text, strerror(errno));
}
void debug::show(void)
{
window->show();
}
void debug::sync_text(void* arg)
{
guard_lock dlock(&debug_mutex);
if (inst == 0 || btext == 0) return;
size_t p0 = 0, p1 = estr.find('\n');
std::string insrt;
while (p1 != string::npos) {
insrt = estr.substr(p0, p1-p0);
btext->insert(1, insrt.c_str());
buffer.append(insrt.append("\n"));
p0 = p1 + 1;
p1 = estr.find('\n', p0);
}
estr = "";
}
debug::debug(const char* filename)
{
if ((wfile = fopen(filename, "w")) == NULL)
throw strerror(errno);
setvbuf(wfile, (char*)NULL, _IOLBF, 0);
set_cloexec(fileno(wfile), 1);
if ((rfile = fopen(filename, "r")) == NULL)
throw strerror(errno);
rfd = fileno(rfile);
set_cloexec(rfd, 1);
#ifndef __WIN32__
int f;
if ((f = fcntl(rfd, F_GETFL)) == -1)
throw strerror(errno);
if (fcntl(rfd, F_SETFL, f | O_NONBLOCK) == -1)
throw strerror(errno);
#endif
tty = isatty(fileno(stderr));
}
debug::~debug()
{
if (window) {
delete window;
window = 0;
}
fclose(wfile);
fclose(rfile);
}
static void slider_cb(Fl_Widget* w, void*)
{
debug::level = (debug::level_e)((Fl_Slider*)w)->value();
w->label(prefix[debug::level]);
w->parent()->redraw();
}
static void clear_cb(Fl_Widget* w, void*)
{
if (!btext) return;
btext->clear();
buffer.clear();
}
flrig-1.3.49/src/support/trace.cxx 0000664 0001750 0001750 00000014174 13605621006 013771 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "icons.h"
#include "support.h"
#include "debug.h"
#include "gettext.h"
#include "rig_io.h"
#include "dialogs.h"
#include "rigbase.h"
#include "ptt.h"
#include "socket_io.h"
#include "ui.h"
#include "tod_clock.h"
#include "trace.h"
#include "rig.h"
#include "rigs.h"
#include "K3_ui.h"
#include "KX3_ui.h"
#include "rigpanel.h"
#include "tod_clock.h"
using namespace std;
Fl_Double_Window* tracewindow = (Fl_Double_Window *)0;
Fl_Text_Display* tracedisplay = (Fl_Text_Display *)0;
Fl_Text_Buffer* tracebuffer = (Fl_Text_Buffer*)0;
Fl_Button* btn_cleartrace = (Fl_Button*)0;
vector tracestrings;
static void cb_cleartrace(Fl_Button *, void *)
{
tracedisplay->buffer()->text("");
}
static void make_trace_window() {
tracewindow = new Fl_Double_Window(600, 300, _("Trace log"));
tracedisplay = new Fl_Text_Display(0, 0, 600, 270);
tracebuffer = new Fl_Text_Buffer;
tracedisplay->buffer(tracebuffer);
tracedisplay->textfont(FL_SCREEN);
btn_cleartrace = new Fl_Button(515, 275, 80, 20, _("Clear"));
btn_cleartrace->callback((Fl_Callback *)cb_cleartrace);
tracewindow->resizable(tracedisplay);
}
static void update_tracetext(void *)
{
guard_lock tt(&mutex_trace);
for (size_t n = 0; n < tracestrings.size(); n++)
tracedisplay->insert(tracestrings[n].c_str());
tracestrings.clear();
}
static void tracefile(std::string s)
{
string trace_fname = RigHomeDir;
trace_fname.append("trace.txt");
ofstream tfile(trace_fname.c_str(), ios::app);
if (tfile)
tfile << s;
tfile.close();
}
void trace(int n, ...) // all args of type const char *
{
if (!tracewindow) make_trace_window();
if (!progStatus.trace) return;
if (!n) return;
stringstream s;
va_list vl;
va_start(vl, n);
s << ztime() << " : " << va_arg(vl, const char *);
for (int i = 1; i < n; i++)
s << " " << va_arg(vl, const char *);
va_end(vl);
s << "\n";
tracefile(s.str());
guard_lock tt(&mutex_trace);
tracestrings.push_back(s.str());
Fl::awake(update_tracetext);
}
void xml_trace(int n, ...) // all args of type const char *
{
if (!tracewindow) make_trace_window();
if (!progStatus.xmltrace) return;
if (!n) return;
stringstream s;
va_list vl;
va_start(vl, n);
s << ztime() << " : " << va_arg(vl, const char *);
for (int i = 1; i < n; i++)
s << " " << va_arg(vl, const char *);
va_end(vl);
s << "\n";
tracefile(s.str());
guard_lock tt(&mutex_trace);
tracestrings.push_back(s.str());
Fl::awake(update_tracetext);
}
void rig_trace(int n, ...) // all args of type const char *
{
if (!tracewindow) make_trace_window();
if (!progStatus.rigtrace) return;
if (!n) return;
stringstream s;
va_list vl;
va_start(vl, n);
s << ztime() << " : " << va_arg(vl, const char *);
for (int i = 1; i < n; i++)
s << " " << va_arg(vl, const char *);
va_end(vl);
s << "\n";
tracefile(s.str());
guard_lock tt(&mutex_trace);
tracestrings.push_back(s.str());
Fl::awake(update_tracetext);
}
void set_trace(int n, ...) // all args of type const char *
{
if (!tracewindow) make_trace_window();
if (!progStatus.settrace) return;
if (!n) return;
stringstream s;
va_list vl;
va_start(vl, n);
s << ztime() << " : " << va_arg(vl, const char *);
for (int i = 1; i < n; i++)
s << " " << va_arg(vl, const char *);
va_end(vl);
s << "\n";
tracefile(s.str());
guard_lock tt(&mutex_trace);
tracestrings.push_back(s.str());
Fl::awake(update_tracetext);
}
void get_trace(int n, ...) // all args of type const char *
{
if (!tracewindow) make_trace_window();
if (!progStatus.gettrace) return;
if (!n) return;
stringstream s;
va_list vl;
va_start(vl, n);
s << ztime() << " : " << va_arg(vl, const char *);
for (int i = 1; i < n; i++)
s << " " << va_arg(vl, const char *);
va_end(vl);
s << "\n";
tracefile(s.str());
guard_lock tt(&mutex_trace);
tracestrings.push_back(s.str());
Fl::awake(update_tracetext);
}
void rpc_trace(int n, ...) // all args of type const char *
{
if (!tracewindow) make_trace_window();
if (!progStatus.rpctrace) return;
if (!n) return;
stringstream s;
va_list vl;
va_start(vl, n);
s << ztime() << " : " << va_arg(vl, const char *);
for (int i = 1; i < n; i++)
s << " " << va_arg(vl, const char *);
va_end(vl);
std::string str = s.str();
size_t p = str.find("\r\n");
while (p != std::string::npos) {
str.replace(p, 2, "\n");
p = str.find("\r\n");
}
p = str.find("\r");
while (p != std::string::npos) {
str.replace(p, 1, "\n");
p = str.find("\r");
}
p = str.find("\t");
while (p != std::string::npos) {
str.erase(p, 1);
p = str.find("\t");
}
int indent = 0;
p = str.find("<");
while (p != std::string::npos) {
if (str[p+1] != '/') {
str.insert(p, "\n");
str.insert(p+1, indent, ' ');
indent += 2;
} else {
str.insert(p, "\n");
indent -= 2;
str.insert(p+1, indent, ' ');
}
if (indent < 0) indent = 0;
p = str.find(">", p);
p = str.find("<", p);
}
p = str.find("\n\n");
while (p != std::string::npos) {
str.erase(p,1);
p = str.find("\n\n");
}
if (str[str.length()-1] != '\n') str += '\n';
tracefile(str);
guard_lock tt(&mutex_trace);
tracestrings.push_back(str);
Fl::awake(update_tracetext);
}
flrig-1.3.49/src/support/rig_io.cxx 0000664 0001750 0001750 00000023236 13605621006 014142 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include
#include
#include "rig.h"
#include "support.h"
#include "util.h"
#include "debug.h"
#include "status.h"
#include "rigbase.h"
#include "rig_io.h"
#include "icons.h"
#include "tod_clock.h"
#include "socket_io.h"
using namespace std;
extern bool test;
const char *nuline = "\n";
static int iBaudRates[] = { 300, 600, 1200, 2400, 4800, 9600,
19200, 38400, 57600, 115200, 230400, 460800 };
const char *szBaudRates[] = { "300", "600", "1200", "2400", "4800", "9600",
"19200", "38400", "57600", "115200", "230400", "460800", NULL };
int BaudRate(int n)
{
if (n > (int)sizeof(iBaudRates)) return 1200;
return (iBaudRates[n]);
}
bool startXcvrSerial()
{
debug::level_e level = debug::level;
debug::level = debug::DEBUG_LEVEL;
bypass_serial_thread_loop = true;
// setup commands for serial port
if (progStatus.xcvr_serial_port == "NONE") {
bypass_serial_thread_loop = false;
return false;
}
RigSerial->Device(progStatus.xcvr_serial_port);
RigSerial->Baud(BaudRate(progStatus.comm_baudrate));
RigSerial->Stopbits(progStatus.stopbits);
RigSerial->Retries(progStatus.comm_retries);
RigSerial->Timeout(progStatus.comm_timeout);
RigSerial->RTSptt(progStatus.comm_rtsptt);
RigSerial->DTRptt(progStatus.comm_dtrptt);
RigSerial->RTSCTS(progStatus.comm_rtscts);
RigSerial->RTS(progStatus.comm_rtsplus);
RigSerial->DTR(progStatus.comm_dtrplus);
if (!RigSerial->OpenPort()) {
LOG_ERROR("Cannot access %s", progStatus.xcvr_serial_port.c_str());
return false;
} else {
LOG_DEBUG("\n\
Serial port:\n\
Port : %s\n\
Baud : %d\n\
Stopbits : %d\n\
Retries : %d\n\
Timeout : %d\n\
Loop : %d\n\
RTSCTS : %d\n\
CATptt : %d\n\
RTSptt : %d\n\
DTRptt : %d\n\
RTS+ : %d\n\
DTR+ : %d\n",
progStatus.xcvr_serial_port.c_str(),
progStatus.comm_baudrate,
progStatus.stopbits,
progStatus.comm_retries,
progStatus.comm_timeout,
progStatus.serloop_timing,
progStatus.comm_rtscts,
progStatus.comm_catptt,
progStatus.comm_rtsptt,
progStatus.comm_dtrptt,
progStatus.comm_rtsplus,
progStatus.comm_dtrplus );
}
RigSerial->FlushBuffer();
debug::level = level;
return true;
}
bool startAuxSerial()
{
if (progStatus.aux_serial_port == "NONE") return false;
AuxSerial->Device(progStatus.aux_serial_port);
AuxSerial->Baud(BaudRate(progStatus.comm_baudrate));
AuxSerial->Stopbits(progStatus.stopbits);
AuxSerial->Retries(progStatus.comm_retries);
AuxSerial->Timeout(progStatus.comm_timeout);
if (!AuxSerial->OpenPort()) {
LOG_ERROR("Cannot access %s", progStatus.aux_serial_port.c_str());
return false;
}
return true;
}
bool startSepSerial()
{
if (progStatus.sep_serial_port == "NONE") return false;
SepSerial->Device(progStatus.sep_serial_port);
SepSerial->Baud(BaudRate(progStatus.comm_baudrate));
SepSerial->RTSCTS(false);
SepSerial->RTS(progStatus.sep_rtsplus);
SepSerial->RTSptt(progStatus.sep_rtsptt);
SepSerial->DTR(progStatus.sep_dtrplus);
SepSerial->DTRptt(progStatus.sep_dtrptt);
if (!SepSerial->OpenPort()) {
LOG_ERROR("Cannot access %s", progStatus.sep_serial_port.c_str());
return false;
}
return true;
}
// TODO: Review for thread safety.
// Tried adding mutex, but deadlocks startup
// progress dialog:
// guard_lock reply_lock(&mutex_replystr);
//
void assignReplyStr(string val)
{
selrig->replystr = val;
}
char replybuff[RXBUFFSIZE+1];
//string replystr;
string respstr;
int readResponse()
{
int numread = 0;
respstr.clear();
memset(replybuff, 0, RXBUFFSIZE + 1);
if (progStatus.use_tcpip)
numread = read_from_remote(respstr);
else {
numread = RigSerial->ReadBuffer(replybuff, RXBUFFSIZE);
for (int i = 0; i < numread; respstr += replybuff[i++]);
}
if (numread)
LOG_DEBUG("rsp:%3d, %s", numread, str2hex(respstr.c_str(), respstr.length()));
return numread;
}
int sendCommand (string s, int nread, int wait)
{
int numwrite = (int)s.size();
// TODO: Review for thread safety
//
// Clear command before sending, to keep the logs sensical. Otherwise it looks like
// reply was from this command, when it really was from a previous command.
assignReplyStr("");
if (progStatus.use_tcpip) {
readResponse();
send_to_remote(s, progStatus.byte_interval);
int timeout =
progStatus.comm_wait + progStatus.tcpip_ping_delay +
(int)((nread + progStatus.comm_echo ? numwrite : 0)*11000.0/RigSerial->Baud() );
while (timeout > 0) {
if (timeout > 10) MilliSleep(10);
else MilliSleep(timeout);
timeout -= 10;
Fl::awake();
}
if (nread == 0) return 0;
return readResponse();
}
if (RigSerial->IsOpen() == false) {
return 0;
}
LOG_DEBUG("cmd:%3d, %s", (int)s.length(), str2hex(s.data(), s.length()));
RigSerial->FlushBuffer();
RigSerial->WriteBuffer(s.c_str(), numwrite);
int timeout = progStatus.comm_wait +
(int)((nread + progStatus.comm_echo ? numwrite : 0)*11000.0/RigSerial->Baud());
timeout += wait;
while (timeout > 0) {
if (timeout > 10) MilliSleep(10);
else MilliSleep(timeout);
timeout -= 10;
Fl::awake();
}
if (nread == 0) return 0;
return readResponse();
}
static int waitcount = 0;
static bool timeout_alert = false;
static char sztimeout_alert[200];
static void show_timeout(void *)
{
fl_alert2("%s",sztimeout_alert);
}
bool waitCommand(
string command,
int nread,
string info,
int msec,
char term,
int how,
int level )
{
guard_lock reply_lock(&mutex_replystr);
int numwrite = (int)command.length();
if (nread == 0)
LOG_DEBUG("cmd:%3d, %s", numwrite, how == ASC ? command.c_str() : str2hex(command.data(), numwrite));
if (progStatus.use_tcpip) {
send_to_remote(command, progStatus.byte_interval);
if (nread == 0) return 0;
} else {
if (RigSerial->IsOpen() == false) {
LOG_DEBUG("cmd: %s", how == ASC ? command.c_str() : str2hex(command.data(), command.length()));
waitcount = 0;
return 0;
}
RigSerial->FlushBuffer();
// replystr.clear();
RigSerial->WriteBuffer(command.c_str(), numwrite);
if (nread == 0) {
waitcount = 0;
return 0;
}
}
int tod_start = zmsec();
// minimimum time to wait for a response
int timeout = (int)((nread + progStatus.comm_echo ? numwrite : 0)*11000.0/RigSerial->Baud()
+ progStatus.use_tcpip ? progStatus.tcpip_ping_delay : 0);
while (timeout > 0) {
if (timeout > 10) MilliSleep(10);
else MilliSleep(timeout);
timeout -= 10;
Fl::awake();
}
// additional wait for xcvr processing
string returned = "";
static char sztemp[100];
int waited = 0;
while (waited < msec) {
if (readResponse())
returned.append(respstr);
if ( ((int)returned.length() >= nread) ||
(returned.find(term) != string::npos) ) {
assignReplyStr(returned);
waited = zmsec() - tod_start;
snprintf(sztemp, sizeof(sztemp), "%s rcvd in %d msec", info.c_str(), waited);
showresp(level, how, sztemp, command, returned);
waitcount = 0;
return true;
}
waited += 10;
MilliSleep(10);
Fl::awake();
}
waitcount++;
assignReplyStr(returned);
waited = zmsec() - tod_start;
snprintf(sztemp, sizeof(sztemp), "%s TIMED OUT in %d ms", command.c_str(), waited);
showresp(ERR, HEX, sztemp, command, returned);
if (waitcount > 4 && !timeout_alert) {
timeout_alert = true;
snprintf(sztimeout_alert, sizeof(sztimeout_alert),
"Serial i/o failure\n%s TIME OUT in %d ms",
command.c_str(), waited);
Fl::awake(show_timeout);
}
return false;
}
int waitResponse(int timeout)
{
int n = 0;
if (!progStatus.use_tcpip && RigSerial->IsOpen() == false)
return 0;
MilliSleep(10);
if (!(n = readResponse()))
while (timeout > 0) {
if (timeout > 10) MilliSleep(10);
else MilliSleep(timeout);
timeout -= 10;
Fl::awake();
}
return n;
}
void showresp(int level, int how, string s, string tx, string rx)
{
time_t now;
time(&now);
struct tm *local = localtime(&now);
char sztm[20];
strftime(sztm, sizeof(sztm), "%H:%M:%S", local);
string s1 = how == HEX ? str2hex(tx.c_str(), tx.length()) : tx;
string s2 = how == HEX ? str2hex(rx.c_str(), rx.length()) : rx;
if (how == ASC) {
size_t p;
while((p = s1.find('\r')) != string::npos)
s1.replace(p, 1, "");
while((p = s1.find('\n')) != string::npos)
s1.replace(p, 1, "");
while((p = s2.find('\r')) != string::npos)
s2.replace(p, 1, "");
while((p = s2.find('\n')) != string::npos)
s2.replace(p, 1, "");
}
switch (level) {
case QUIET:
SLOG_QUIET("%s: %10s\ncmd %s\nans %s", sztm, s.c_str(), s1.c_str(), s2.c_str());
break;
case ERR:
SLOG_ERROR("%s: %10s\ncmd %s\nans %s", sztm, s.c_str(), s1.c_str(), s2.c_str());
break;
case INFO:
SLOG_INFO("%s: %10s\ncmd %s\nans %s", sztm, s.c_str(), s1.c_str(), s2.c_str());
break;
case DEBUG:
SLOG_DEBUG("%s: %10s\ncmd %s\nans %s", sztm, s.c_str(), s1.c_str(), s2.c_str());
break;
case WARN:
default:
SLOG_WARN("%s: %10s\ncmd %s\nans %s", sztm, s.c_str(), s1.c_str(), s2.c_str());
break;
}
}
flrig-1.3.49/src/support/mingw.c 0000644 0001750 0001750 00000017233 13472116063 013435 0000000 0000000 // ----------------------------------------------------------------------------
// mingw.c
//
// The following routines were copied from git-1.6.1.2/compat/mingw.c:
// git_vsnprintf git_snprintf sleep mingw_getcwd mingw_getenv mingw_rename
//
// The uname routine was adapted from libgw32c 0.4.
//
// The rest:
// Copyright (C) 2009
// Stelios Bounanos, M0GLD
// ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include
#include "compat.h"
#include "util.h"
/* default mode for stdin, stdout and stderr */
unsigned int _CRT_fmode = _O_BINARY;
/******************************************************************************/
#if SNPRINTF_RETURNS_BOGUS
/*
* The size parameter specifies the available space, i.e. includes
* the trailing NUL byte; but Windows's vsnprintf expects the
* number of characters to write without the trailing NUL.
*/
#define SNPRINTF_SIZE_CORR 1
#undef vsnprintf
int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
{
char *s;
int ret = -1;
if (maxsize > 0) {
ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
if (ret == maxsize-1)
ret = -1;
/* Windows does not NUL-terminate if result fills buffer */
str[maxsize-1] = 0;
}
if (ret != -1)
return ret;
s = NULL;
if (maxsize < 128)
maxsize = 128;
while (ret == -1) {
maxsize *= 4;
str = (char *)realloc(s, maxsize);
if (! str)
break;
s = str;
ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
if (ret == maxsize-1)
ret = -1;
}
free(s);
return ret;
}
int git_snprintf(char *str, size_t maxsize, const char *format, ...)
{
va_list ap;
int ret;
va_start(ap, format);
ret = git_vsnprintf(str, maxsize, format, ap);
va_end(ap);
return ret;
}
#endif /* SNPRINTF_RETURNS_BOGUS */
unsigned sleep(unsigned seconds)
{
Sleep(seconds*1000);
return 0;
}
#undef getcwd
char *mingw_getcwd(char *pointer, int len)
{
int i;
char *ret = getcwd(pointer, len);
if (!ret)
return ret;
for (i = 0; pointer[i]; i++)
if (pointer[i] == '\\')
pointer[i] = '/';
return ret;
}
#undef getenv
char *mingw_getenv(const char *name)
{
char *result = getenv(name);
if (!result && !strcmp(name, "TMPDIR")) {
/* on Windows it is TMP and TEMP */
result = getenv("TMP");
if (!result)
result = getenv("TEMP");
}
return result;
}
#undef rename
int mingw_rename(const char *pold, const char *pnew)
{
DWORD attrs;
/*
* Try native rename() first to get errno right.
* It is based on MoveFile(), which cannot overwrite existing files.
*/
if (!rename(pold, pnew))
return 0;
if (errno != EEXIST)
return -1;
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
return 0;
/* TODO: translate more errors */
if (GetLastError() == ERROR_ACCESS_DENIED &&
(attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) {
if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
errno = EISDIR;
return -1;
}
if ((attrs & FILE_ATTRIBUTE_READONLY) &&
SetFileAttributes(pnew, attrs & ~FILE_ATTRIBUTE_READONLY)) {
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
return 0;
/* revert file attributes on failure */
SetFileAttributes(pnew, attrs);
}
}
errno = EACCES;
return -1;
}
/******************************************************************************/
__attribute__((constructor))
static void wsa_init(void)
{
WSADATA wsa;
static int wsa_init_ = 0;
if (wsa_init_)
return;
if (WSAStartup(MAKEWORD(2, 2), &wsa)) {
fprintf(stderr, "unable to initialize winsock: error %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
atexit((void(*)(void)) WSACleanup);
wsa_init_ = 1;
}
int socketpair(int family, int type, int protocol, int *sv)
{
struct sockaddr_in addr;
SOCKET sfd;
int err, len = sizeof(addr);
if (sv == NULL || family != AF_INET || type != SOCK_STREAM || protocol) {
WSASetLastError(WSAEINVAL);
return SOCKET_ERROR;
}
sv[0] = sv[1] = INVALID_SOCKET;
if ((sfd = socket(family, type, 0)) == INVALID_SOCKET)
return SOCKET_ERROR;
memset(&addr, 0, sizeof(addr));
addr.sin_family = family;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = 0; /* any port */
if ((err = bind(sfd, (const struct sockaddr*)&addr, sizeof(addr))) == SOCKET_ERROR) {
err = WSAGetLastError();
closesocket(sfd);
WSASetLastError(err);
return SOCKET_ERROR;
}
if ((err = getsockname(sfd, (struct sockaddr*)&addr, &len)) == SOCKET_ERROR) {
err = WSAGetLastError();
closesocket(sfd);
WSASetLastError(err);
return SOCKET_ERROR;
}
do {
if (listen(sfd, 1) == SOCKET_ERROR)
break;
if ((sv[0] = WSASocket(family, type, 0, NULL, 0, 0)) == INVALID_SOCKET)
break;
if (connect(sv[0], (const struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
break;
if ((sv[1] = accept(sfd, NULL, NULL)) == INVALID_SOCKET)
break;
closesocket(sfd);
return 0;
} while (0);
/* error */
err = WSAGetLastError();
closesocket(sfd);
closesocket(sv[0]);
closesocket(sv[1]);
WSASetLastError(err);
return SOCKET_ERROR;
}
/******************************************************************************/
int nanosleep(const struct timespec *req, struct timespec *rem)
{
if (unlikely(req->tv_nsec < 0 || req->tv_nsec < 0L || req->tv_nsec > 999999999L)) {
errno = EINVAL;
return -1;
}
Sleep(req->tv_sec * 1000 + req->tv_nsec / 1000000L);
if (unlikely(rem)) {
rem->tv_sec = 0;
rem->tv_nsec = 0L;
}
return 0;
}
/*
BOOL GetOsInfo(LPSTR OsName, LPSTR Release, LPSTR Version);
BOOL GetMachInfo(LPSTR MachineName, LPSTR ProcessorName);
int uname(struct utsname *name)
{
char processor[1024];
if (name == NULL) {
errno = EINVAL;
return -1;
}
if (gethostname(name->nodename, sizeof(name->nodename)) < 0) {
name->nodename[0] = '\0';
errno = ENOSYS;
return -1;
}
if (!GetOsInfo(name->sysname, name->release, name->version)) {
strncpy (name->sysname, "win32", sizeof (name->sysname));
strncpy (name->release, "unknown", sizeof (name->release));
strncpy (name->version, "unknown", sizeof (name->version));
}
// "windows32" is as yet the only universal windows description allowed
// by config.guess and config.sub
strncpy(name->sysname, "windows32", sizeof (name->sysname));
if (!GetMachInfo(name->machine, processor))
strncpy(name->machine, "i386", sizeof (name->machine));
return 0;
}
int getrusage(int who, struct rusage *usage)
{
FILETIME ct, et, kt, ut;
ULARGE_INTEGER uli;
if (who != RUSAGE_SELF) {
errno = EINVAL;
return -1;
}
if (!usage) {
errno = EFAULT;
return -1;
}
if (!GetProcessTimes(GetCurrentProcess(), &ct, &et, &kt, &ut)) {
errno = ENOENT;
return -1;
}
// FILETIMEs use 100-ns units
memcpy(&uli, &kt, sizeof(FILETIME));
usage->ru_stime.tv_sec = uli.QuadPart / 10000000L;
usage->ru_stime.tv_usec = uli.QuadPart % 10000000L;
memcpy(&uli, &ut, sizeof(FILETIME));
usage->ru_utime.tv_sec = uli.QuadPart / 10000000L;
usage->ru_utime.tv_usec = uli.QuadPart % 10000000L;
return 0;
}
*/
flrig-1.3.49/src/support/util.cxx 0000664 0001750 0001750 00000013776 13605621006 013657 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include "util.h"
#ifdef __MINGW32__
# include "compat.h"
#endif
/* Return the smallest power of 2 not less than n */
uint32_t ceil2(uint32_t n)
{
--n;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return n + 1;
}
/* Return the largest power of 2 not greater than n */
uint32_t floor2(uint32_t n)
{
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return n - (n >> 1);
}
#include
unsigned long ver2int(const char* version)
{
unsigned long v;
char* p;
v = (unsigned long)(strtod(version, &p) * 1e7 + 0.5);
while (*p)
v += *p++;
return v;
}
/*
#if !HAVE_STRCASESTR
# include
// from git 1.6.1.2 compat/strcasestr.c
char *strcasestr(const char *haystack, const char *needle)
{
int nlen = strlen(needle);
int hlen = strlen(haystack) - nlen + 1;
int i;
for (i = 0; i < hlen; i++) {
int j;
for (j = 0; j < nlen; j++) {
unsigned char c1 = haystack[i+j];
unsigned char c2 = needle[j];
if (toupper(c1) != toupper(c2))
goto next;
}
return (char *) haystack + i;
next: ;
}
return NULL;
}
#endif // !HAVE_STRCASESTR
*/
#if !HAVE_STRLCPY
// from git 1.6.1.2 compat/strcasestr.c
size_t strlcpy(char *dest, const char *src, size_t size)
{
size_t ret = strlen(src);
if (size) {
size_t len = (ret >= size) ? size - 1 : ret;
memcpy(dest, src, len);
dest[len] = '\0';
}
return ret;
}
#endif // !HAVE_STRLCPY
#ifdef __WIN32__
int set_cloexec(int fd, unsigned char v) { return 0; }
#else
# include
# include
int set_cloexec(int fd, unsigned char v)
{
int f = fcntl(fd, F_GETFD);
return f == -1 ? f : fcntl(fd, F_SETFD, (v ? f | FD_CLOEXEC : f & ~FD_CLOEXEC));
}
#endif // __WIN32__
int set_nonblock(int fd, unsigned char v)
{
#ifndef __WIN32__
int f = fcntl(fd, F_GETFL);
return f == -1 ? f : fcntl(fd, F_SETFL, (v ? f | O_NONBLOCK : f & ~O_NONBLOCK));
#else // __WIN32__
u_long v_ = (u_long)v;
errno = 0;
if (ioctlsocket(fd, FIONBIO, &v_) == SOCKET_ERROR) {
errno = WSAGetLastError();
return -1;
}
else
return 0;
#endif // __WIN32__
}
#ifndef __WIN32__
# include
# include
# include
# include
#endif
int set_nodelay(int fd, unsigned char v)
{
int val = v;
return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&val, sizeof(val));
}
#ifdef __WIN32__
# include
int get_bufsize(int fd, int dir, int* len)
{
int optlen = sizeof(*len);
#else
int get_bufsize(int fd, int dir, int* len)
{
socklen_t optlen = sizeof(*len);
#endif
return getsockopt(fd, SOL_SOCKET, (dir == 0 ? SO_RCVBUF : SO_SNDBUF),
(char*)len, &optlen);
}
int set_bufsize(int fd, int dir, int len)
{
return setsockopt(fd, SOL_SOCKET, (dir == 0 ? SO_RCVBUF : SO_SNDBUF),
(const char*)&len, sizeof(len));
}
#ifndef __WIN32__
#include
#include
#ifndef NSIG
# define NSIG 64
#endif
static size_t nsig = 0;
static struct sigaction* sigact = 0;
static pthread_mutex_t sigmutex = PTHREAD_MUTEX_INITIALIZER;
#endif
void save_signals(void)
{
#ifndef __WIN32__
pthread_mutex_lock(&sigmutex);
if (!sigact)
sigact = new struct sigaction[NSIG];
for (nsig = 1; nsig <= NSIG; nsig++)
if (sigaction(nsig, NULL, &sigact[nsig-1]) == -1)
break;
pthread_mutex_unlock(&sigmutex);
#endif
}
void restore_signals(void)
{
#ifndef __WIN32__
pthread_mutex_lock(&sigmutex);
for (size_t i = 1; i <= nsig; i++)
sigaction(i, &sigact[i-1], NULL);
delete [] sigact;
sigact = 0;
nsig = 0;
pthread_mutex_unlock(&sigmutex);
#endif
}
uint32_t simple_hash_data(const unsigned char* buf, size_t len, uint32_t code)
{
for (size_t i = 0; i < len; i++)
code = ((code << 4) | (code >> (32 - 4))) ^ (uint32_t)buf[i];
return code;
}
uint32_t simple_hash_str(const unsigned char* str, uint32_t code)
{
while (*str)
code = ((code << 4) | (code >> (32 - 4))) ^ (uint32_t)*str++;
return code;
}
#include
#include
static const char hexsym[] = "0123456789ABCDEF";
static std::vector* hexbuf;
const char* str2hex(const unsigned char* str, size_t len)
{
if (unlikely(len == 0))
return "";
if (unlikely(!hexbuf)) {
hexbuf = new std::vector;
hexbuf->reserve(192);
}
if (unlikely(hexbuf->size() < len * 3))
hexbuf->resize(len * 3);
char* p = &(*hexbuf)[0];
size_t i;
for (i = 0; i < len; i++) {
*p++ = hexsym[str[i] >> 4];
*p++ = hexsym[str[i] & 0xF];
*p++ = ' ';
}
*(p - 1) = '\0';
return &(*hexbuf)[0];
}
const char* str2hex(const char* str, size_t len)
{
return str2hex((const unsigned char*)str, len ? len : strlen(str));
}
static std::vector* binbuf;
const char* uint2bin(unsigned u, size_t len)
{
if (unlikely(len == 0))
len = sizeof(u) * CHAR_BIT;
if (unlikely(!binbuf)) {
binbuf = new std::vector;
binbuf->reserve(sizeof(u) * CHAR_BIT);
}
if (unlikely(binbuf->size() < len + 1))
binbuf->resize(len + 1);
for (size_t i = 0; i < len; i++) {
(*binbuf)[len - i - 1] = '0' + (u & 1);
u >>= 1;
}
(*binbuf)[len] = '\0';
return &(*binbuf)[0];
}
void MilliSleep(long msecs)
{
struct timespec tv;
tv.tv_sec = msecs / 1000;
tv.tv_nsec = (msecs - tv.tv_sec * 1000) * 1000000L;
nanosleep(&tv, NULL);
}
flrig-1.3.49/src/support/serial.cxx 0000644 0001750 0001750 00000062412 13605621006 014146 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include "serial.h"
#include "debug.h"
#include "rig.h"
LOG_FILE_SOURCE(debug::LOG_RIGCONTROL);
#if SERIAL_DEBUG
FILE *serlog = 0;
#endif
#ifndef __WIN32__
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
Cserial::Cserial() {
device = "/dev/ttyS0";
baud = 1200;
timeout = 50; //msec
retries = 5;
rts = dtr = false;
rtsptt = dtrptt = false;
rtscts = false;
status = 0;
stopbits = 2;
fd = -1;
}
Cserial::~Cserial() {
ClosePort();
}
///////////////////////////////////////////////////////
// Function name : Cserial::OpenPort
// Description : Opens the port specified by strPortName
// Return type : bool
// Argument : c_string strPortName
///////////////////////////////////////////////////////
bool Cserial::CheckPort(string dev) {
int testfd = open( dev.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if (testfd < 0)
return false;
close(fd);
return true;
}
///////////////////////////////////////////////////////
// Function name : Cserial::OpenPort
// Description : Opens the port specified by strPortName
// Return type : bool
// Argument : c_string strPortName
///////////////////////////////////////////////////////
bool Cserial::OpenPort() {
if ((fd = open( device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY )) < 0)
return false;
#if SERIAL_DEBUG
fprintf(serlog,"%s opened\n", device.c_str());
#endif
// save current port settings
tcflush (fd, TCIFLUSH);
tcgetattr (fd, &oldtio);
newtio = oldtio;
// 8 data bits
newtio.c_cflag &= ~CSIZE;
newtio.c_cflag |= CS8;
// enable receiver, set local mode
newtio.c_cflag |= (CLOCAL | CREAD);
// no parity
newtio.c_cflag &= ~PARENB;
if (stopbits == 1)
// 1 stop bit
newtio.c_cflag &= ~CSTOPB;
else
// 2 stop bit
newtio.c_cflag |= CSTOPB;
if (rtscts)
// h/w handshake
newtio.c_cflag |= CRTSCTS;
else
// no h/w handshake
newtio.c_cflag &= ~CRTSCTS;
// raw input
newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// raw output
newtio.c_oflag &= ~OPOST;
// software flow control disabled
newtio.c_iflag &= ~IXON;
// do not translate CR to NL
newtio.c_iflag &= ~ICRNL;
switch(baud) {
case 300:
speed = B300;
break;
case 1200:
speed = B1200;
break;
case 2400:
speed = B2400;
break;
case 4800:
speed = B4800;
break;
case 9600:
speed = B9600;
break;
case 19200:
speed = B19200;
break;
case 38400:
speed = B38400;
break;
case 57600:
speed = B57600;
break;
case 115200:
speed = B115200;
break;
default:
speed = B1200;
}
cfsetispeed(&newtio, speed);
cfsetospeed(&newtio, speed);
tcsetattr (fd, TCSANOW, &newtio);
ioctl(fd, TIOCMGET, &status);
origstatus = status;
if (dtr)
status |= TIOCM_DTR; // set the DTR bit
else
status &= ~TIOCM_DTR; // clear the DTR bit
if (rtscts == false) { // rts OK for ptt if RTSCTS not used
if (rts)
status |= TIOCM_RTS; // set the RTS bit
else
status &= ~TIOCM_RTS; // clear the RTS bit
}
ioctl(fd, TIOCMSET, &status);
FlushBuffer();
return true;
}
///////////////////////////////////////////////////////
// Function name : Cserial::setPTT
// Return type : void
///////////////////////////////////////////////////////
void Cserial::SetPTT(bool ON)
{
if (fd < 0) {
#if SERIAL_DEBUG
fprintf(serlog, "ptt fd < 0\n");
#endif
LOG_ERROR("ptt fd < 0");
return;
}
if (dtrptt || rtsptt) {
ioctl(fd, TIOCMGET, &status);
if (ON) { // ptt enabled
if (dtrptt && dtr) status &= ~TIOCM_DTR; // toggle low
if (dtrptt && !dtr) status |= TIOCM_DTR; // toggle high
if (!rtscts) {
if (rtsptt && rts) status &= ~TIOCM_RTS; // toggle low
if (rtsptt && !rts) status |= TIOCM_RTS; // toggle high
}
} else { // ptt disabled
if (dtrptt && dtr) status |= TIOCM_DTR; // toggle high
if (dtrptt && !dtr) status &= ~TIOCM_DTR; // toggle low
if (!rtscts) {
if (rtsptt && rts) status |= TIOCM_RTS; // toggle high
if (rtsptt && !rts) status &= ~TIOCM_RTS; // toggle low
}
}
LOG_INFO("PTT %d, DTRptt %d, DTR %d, RTSptt %d, RTS %d, RTSCTS %d, status %2X",
ON, dtrptt, dtr, rtsptt, rts, rtscts, status);
#if SERIAL_DEBUG
fprintf(serlog,"PTT %d, DTRptt %d, DTR %d, RTSptt %d, RTS %d, RTSCTS %d, status %2X\n",
ON, dtrptt, dtr, rtsptt, rts, rtscts, status);
#endif
ioctl(fd, TIOCMSET, &status);
}
// LOG_DEBUG("No ptt specified");
}
void Cserial::setRTS(bool b)
{
if (fd < 0)
return;
ioctl(fd, TIOCMGET, &status);
if (b == true)
status |= TIOCM_RTS; // toggle high
else
status &= ~TIOCM_RTS; // toggle low
ioctl(fd, TIOCMSET, &status);
}
void Cserial::setDTR(bool b)
{
if (fd < 0)
return;
ioctl(fd, TIOCMGET, &status);
if (b == true)
status |= TIOCM_DTR; // toggle high
else
status &= ~TIOCM_DTR; // toggle low
ioctl(fd, TIOCMSET, &status);
}
///////////////////////////////////////////////////////
// Function name : Cserial::ClosePort
// Description : Closes the Port
// Return type : void
///////////////////////////////////////////////////////
void Cserial::ClosePort()
{
if (fd < 0) return;
int myfd = fd;
fd = -1;
// Some serial drivers force RTS and DTR high immediately upon
// opening the port, so our origstatus will indicate those bits
// high (though the lines weren't actually high before we opened).
// But then when we "restore" RTS and DTR from origstatus here
// it can result in PTT activation upon program exit! To avoid
// this possibility, we ignore the apparentl initial settings, and
// instead force RTS and DTR low before closing the port. (Just
// omitting the ioctl(TIOCMSET) would also resolve the problem).
// Kamal Mostafa
origstatus &= ~(TIOCM_RTS|TIOCM_DTR);
ioctl(myfd, TIOCMSET, &origstatus);
tcsetattr (myfd, TCSANOW, &oldtio);
close(myfd);
fd = -1;
return;
}
bool Cserial::IOselect ()
{
fd_set rfds;
struct timeval tv;
int retval;
FD_ZERO (&rfds);
FD_SET (fd, &rfds);
tv.tv_sec = timeout/1000;
tv.tv_usec = (timeout % 1000) * 1000;
retval = select (FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, &tv);
if (retval <= 0) // no response from serial port or error returned
return false;
return true;
}
///////////////////////////////////////////////////////
// Function name : Cserial::ReadBuffer
// Description : Reads upto nchars from the selected port
// Return type : # characters received
// Argument : pointer to buffer; # chars to read
///////////////////////////////////////////////////////
int Cserial::ReadBuffer (char *buf, int nchars)
{
if (fd < 0) return 0;
int retnum, nread = 0;
while (nchars > 0) {
if (!IOselect()) {
return nread;
}
retnum = read (fd, (char *)(buf + nread), nchars);
if (retnum < 0)
return 0;//nread;
if (retnum == 0)
return nread;
nread += retnum;
nchars -= retnum;
}
return nread;
}
///////////////////////////////////////////////////////
// Function name : Cserial::WriteBuffer
// Description : Writes a string to the selected port
// Return type : bool
// Argument : BYTE by
///////////////////////////////////////////////////////
int Cserial::WriteBuffer(const char *buff, int n)
{
if (fd < 0) return 0;
int ret = write (fd, buff, n);
return ret;
}
///////////////////////////////////////////////////////
// Function name : Cserial::WriteByte
// Description : Writes a Byte to the selected port
// Return type : bool
// Argument : BYTE by
///////////////////////////////////////////////////////
bool Cserial::WriteByte(char by)
{
if (fd < 0) return false;
static char buff[2];
buff[0] = by; buff[1] = 0;
return (write(fd, buff, 1) == 1);
}
///////////////////////////////////////////////////////
// Function name : Cserial::FlushBuffer
// Description : flushes the pending rx chars
// Return type : void
///////////////////////////////////////////////////////
void Cserial::FlushBuffer()
{
if (fd < 0)
return;
tcflush (fd, TCIFLUSH);
}
//=============================================================================
// WIN32 serial implementation
//=============================================================================
#else // __WIN32__
using namespace std;
///////////////////////////////////////////////////////
// Function name : Cserial::CheckPort
// Description : Checks the port specified by strPortName
// Return type : bool
// Argument : c_string strPortName
///////////////////////////////////////////////////////
bool Cserial::CheckPort(string dev) {
static HANDLE hTest;
string COMportname = "//./";
COMportname.append(dev);
hTest = CreateFile(COMportname.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);
if(hTest == INVALID_HANDLE_VALUE) return false;
CloseHandle(hTest);
return true;
}
///////////////////////////////////////////////////////
// Function name : Cserial::OpenPort
// Description : Opens the port specified by strPortName
// Return type : bool
// Argument : CString strPortName
///////////////////////////////////////////////////////
bool Cserial::OpenPort()
{
if (device.empty()) return false;
string COMportname = "//./";
COMportname.append(device);
hComm = CreateFile(COMportname.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);
LOG_ERROR("Open Comm port %s ; hComm = %d", COMportname.c_str(), (int)hComm);
#if SERIAL_DEBUG
fl_alert("Open Comm port %s ; hComm = %d", COMportname.c_str(), (int)hComm);
fprintf(serlog, "Open Comm port %s ; hComm = %d\n", COMportname.c_str(), (int)hComm);
#endif
if (hComm == INVALID_HANDLE_VALUE) return false;
ConfigurePort( baud, 8, false, NOPARITY, stopbits);
FlushBuffer();
return true;
}
///////////////////////////////////////////////////////
// Function name : Cserial::ClosePort
// Description : Closes the Port
// Return type : void
///////////////////////////////////////////////////////
void Cserial::ClosePort()
{
if (hComm != INVALID_HANDLE_VALUE) {
bPortReady = SetCommTimeouts (hComm, &CommTimeoutsSaved);
CloseHandle(hComm);
}
hComm = INVALID_HANDLE_VALUE;
return;
}
bool Cserial::IsOpen()
{
if (hComm == INVALID_HANDLE_VALUE) return false;
return true;
}
///////////////////////////////////////////////////////
// Function name : Cserial::GetBytesRead
// Description :
// Return type : DWORD
///////////////////////////////////////////////////////
DWORD Cserial::GetBytesRead()
{
return nBytesRead;
}
///////////////////////////////////////////////////////
// Function name : Cserial::GetBytesWritten
// Description : returns total number of bytes written to port
// Return type : DWORD
///////////////////////////////////////////////////////
DWORD Cserial::GetBytesWritten()
{
return nBytesWritten;
}
///////////////////////////////////////////////////////
// Function name : Cserial::ReadByte
// Description : Reads a byte from the selected port
// Return type : bool
// Argument : BYTE& by
///////////////////////////////////////////////////////
bool Cserial::ReadByte(char & by)
{
static BYTE byResByte[1024];
static DWORD dwBytesTxD=0;
if (hComm == INVALID_HANDLE_VALUE) return false;
if (ReadFile (hComm, &byResByte[0], 1, &dwBytesTxD, 0)) {
if (dwBytesTxD == 1) {
by = (UCHAR)byResByte[0];
return true;
}
}
by = 0;
return false;
}
int Cserial::ReadData (char *buf, int nchars)
{
DWORD dwRead = 0;
if (!ReadFile(hComm, buf, nchars, &dwRead, NULL))
return 0;
return (int) dwRead;
}
int Cserial::ReadChars (char *buf, int nchars, int msec)
{
if (msec) Sleep(msec);
return ReadData (buf, nchars);
}
void Cserial::FlushBuffer()
{
#define TX_CLEAR 0x0004L
#define RX_CLEAR 0x0008L
if (hComm == INVALID_HANDLE_VALUE) return;
PurgeComm(hComm, RX_CLEAR);
}
///////////////////////////////////////////////////////
// Function name : Cserial::WriteByte
// Description : Writes a Byte to teh selected port
// Return type : bool
// Argument : BYTE by
///////////////////////////////////////////////////////
bool Cserial::WriteByte(char by)
{
if (hComm == INVALID_HANDLE_VALUE) return false;
nBytesWritten = 0;
if (WriteFile(hComm,&by,1,&nBytesWritten,NULL)==0) return false;
return true;
}
///////////////////////////////////////////////////////
// Function name : Cserial::WriteBuffer
// Description : Writes a string to the selected port
// Return type : bool
// Argument : BYTE by
///////////////////////////////////////////////////////
int Cserial::WriteBuffer(const char *buff, int n)
{
if (hComm == INVALID_HANDLE_VALUE) return 0;
WriteFile (hComm, buff, n, &nBytesWritten, NULL);
return nBytesWritten;
}
///////////////////////////////////////////////////////
// Function name : Cserial::SetCommunicationTimeouts
// Description : Sets the timeout for the selected port
// Return type : bool
// Argument : DWORD ReadIntervalTimeout
// Argument : DWORD ReadTotalTimeoutMultiplier
// Argument : DWORD ReadTotalTimeoutConstant
// Argument : DWORD WriteTotalTimeoutMultiplier
// Argument : DWORD WriteTotalTimeoutConstant
///////////////////////////////////////////////////////
bool Cserial::SetCommunicationTimeouts(
DWORD ReadIntervalTimeout, // msec
DWORD ReadTotalTimeoutMultiplier,
DWORD ReadTotalTimeoutConstant,
DWORD WriteTotalTimeoutMultiplier,
DWORD WriteTotalTimeoutConstant
)
{
if((bPortReady = GetCommTimeouts (hComm, &CommTimeoutsSaved))==0) {
return false;
}
LOG_ERROR("\n\
Read Interval Timeout............... %ld\n\
Read Total Timeout Multiplier....... %ld\n\
Read Total Timeout Constant Timeout. %ld\n\
Write Total Timeout Constant........ %ld\n\
Write Total Timeout Multiplier...... %ld",
CommTimeoutsSaved.ReadIntervalTimeout,
CommTimeoutsSaved.ReadTotalTimeoutMultiplier,
CommTimeoutsSaved.ReadTotalTimeoutConstant,
CommTimeoutsSaved.WriteTotalTimeoutConstant,
CommTimeoutsSaved.WriteTotalTimeoutMultiplier);
#if SERIAL_DEBUG
fprintf(serlog, "\
Read Interval Timeout............... %ld\n\
Read Total Timeout Multiplier....... %ld\n\
Read Total Timeout Constant Timeout. %ld\n\
Write Total Timeout Constant........ %ld\n\
Write Total Timeout Multiplier...... %ld\n",
CommTimeoutsSaved.ReadIntervalTimeout,
CommTimeoutsSaved.ReadTotalTimeoutMultiplier,
CommTimeoutsSaved.ReadTotalTimeoutConstant,
CommTimeoutsSaved.WriteTotalTimeoutConstant,
CommTimeoutsSaved.WriteTotalTimeoutMultiplier);
#endif
CommTimeouts.ReadIntervalTimeout = ReadIntervalTimeout;
CommTimeouts.ReadTotalTimeoutMultiplier = ReadTotalTimeoutMultiplier;
CommTimeouts.ReadTotalTimeoutConstant = ReadTotalTimeoutConstant;
CommTimeouts.WriteTotalTimeoutConstant = WriteTotalTimeoutConstant;
CommTimeouts.WriteTotalTimeoutMultiplier = WriteTotalTimeoutMultiplier;
bPortReady = SetCommTimeouts (hComm, &CommTimeouts);
if(bPortReady ==0) {
CloseHandle(hComm);
return false;
}
return true;
}
/*
* Remarks
*
* WriteTotalTimeoutMultiplier
*
* The multiplier used to calculate the total time-out period for write
* operations, in milliseconds. For each write operation, this value is
* multiplied by the number of bytes to be written.
*
* WriteTotalTimeoutConstant
*
* A constant used to calculate the total time-out period for write operations,
* in milliseconds. For each write operation, this value is added to the product
* of the WriteTotalTimeoutMultiplier member and the number of bytes to be
* written.
*
* A value of zero for both the WriteTotalTimeoutMultiplier and
* WriteTotalTimeoutConstant members indicates that total time-outs are not
* used for write operations.
*
*
* If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier to
* MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than zero and
* less than MAXDWORD, one of the following occurs when the ReadFile function
* is called:
*
* If there are any bytes in the input buffer, ReadFile returns immediately
* with the bytes in the buffer.
*
* If there are no bytes in the input buffer, ReadFile waits until a byte
* arrives and then returns immediately.
*
* *********************************************************************
*
* If no bytes arrive within the time specified by ReadTotalTimeoutConstant,
* ReadFile times out.
*
* ReadIntervalTimeout
*
* The maximum time allowed to elapse between the arrival of two bytes on the
* communications line, in milliseconds. During a ReadFile operation, the time
* period begins when the first byte is received. If the interval between the
* arrival of any two bytes exceeds this amount, the ReadFile operation is
* completed and any buffered data is returned. A value of zero indicates that
* interval time-outs are not used.
*
* A value of MAXDWORD, combined with zero values for both the
* ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies
* that the read operation is to return immediately with the bytes that have
* already been received, even if no bytes have been received.
*
* ReadTotalTimeoutMultiplier
*
* The multiplier used to calculate the total time-out period for read
* operations, in milliseconds. For each read operation, this value is
* multiplied by the requested number of bytes to be read.
*
* ReadTotalTimeoutConstant
*
* A constant used to calculate the total time-out period for read operations,
* in milliseconds. For each read operation, this value is added to the product
* of the ReadTotalTimeoutMultiplier member and the requested number of bytes.
*
* A value of zero for both the ReadTotalTimeoutMultiplier and
* ReadTotalTimeoutConstant members indicates that total time-outs are not
* used for read operations.
*
*/
bool Cserial::SetCommTimeout() {
return SetCommunicationTimeouts (
0, // Read Interval Timeout
0, // Read Total Timeout Multiplier
50, // Read Total Timeout Constant
50, // Write Total Timeout Constant
0 // Write Total Timeout Multiplier
);
// CommTimeouts.ReadIntervalTimeout = 50;
// CommTimeouts.ReadTotalTimeoutConstant = 50;
// CommTimeouts.ReadTotalTimeoutMultiplier=10;
// CommTimeouts.WriteTotalTimeoutMultiplier=10;
// CommTimeouts.WriteTotalTimeoutConstant = 50;
}
///////////////////////////////////////////////////////
// Function name : ConfigurePort
// Description : Configures the Port
// Return type : bool
// Argument : DWORD BaudRate
// Argument : BYTE ByteSize
// Argument : DWORD fParity
// Argument : BYTE Parity
// Argument : BYTE StopBits
///////////////////////////////////////////////////////
bool Cserial::ConfigurePort(
DWORD BaudRate,
BYTE ByteSize,
DWORD dwParity,
BYTE Parity,
BYTE StopBits)
{
if (hComm == INVALID_HANDLE_VALUE) return false;
// memset(dcb, 0, sizeof(dcb));
dcb.DCBlength = sizeof(dcb);
if((bPortReady = GetCommState(hComm, &dcb)) == 0) {
LOG_ERROR("GetCommState Error on %s", device.c_str());
#if SERIAL_DEBUG
fl_alert("GetCommState Error on %s", device.c_str());
fprintf(serlog, "GetCommState Error on %s\n", device.c_str());
#endif
CloseHandle(hComm);
return false;
}
#if SERIAL_DEBUG
fprintf(serlog, "\
\n\
Get Comm State:\n\
DCB.DCBlength %d\n\
DCB.Baudrate %d\n\
DCB.ByteSize %d\n\
DCB.Parity %d\n\
DCB.StopBits %d\n\
DCB.Binary %d\n\
DCB.fDtrControl %d\n\
DCB.fRtsControl %d\n\
DCB.fDsrSensitivity %d\n\
DCB.fParity %d\n\
DCB.fOutX %d\n\
DCB.fInX %d\n\
DCB.fNull %d\n\
DCB.XonChar %d\n\
DCB.XoffChar %d\n\
DCB.fAbortOnError %d\n\
DCB.fOutxCtsFlow %d\n\
DCB.fOutxDsrFlow %d\n",
(int)dcb.DCBlength,
(int)dcb.BaudRate,
(int)dcb.ByteSize,
(int)dcb.Parity,
(int)dcb.StopBits,
(int)dcb.fBinary,
(int)dcb.fDtrControl,
(int)dcb.fRtsControl,
(int)dcb.fDsrSensitivity,
(int)dcb.fParity,
(int)dcb.fOutX,
(int)dcb.fInX,
(int)dcb.fNull,
(int)dcb.XonChar,
(int)dcb.XoffChar,
(int)dcb.fAbortOnError,
(int)dcb.fOutxCtsFlow,
(int)dcb.fOutxDsrFlow);
#endif
dcb.DCBlength = sizeof (dcb);
dcb.BaudRate = BaudRate;
dcb.ByteSize = ByteSize;
dcb.Parity = Parity ;
if (dcb.StopBits) // corrects a driver malfunction in the Yaesu SCU-17
dcb.StopBits = (StopBits == 1 ? ONESTOPBIT : TWOSTOPBITS);
dcb.fBinary = true;
dcb.fDsrSensitivity = false;
dcb.fParity = false;
dcb.fOutX = false;
dcb.fInX = false;
dcb.fNull = false;
dcb.fAbortOnError = false;
dcb.fOutxCtsFlow = false;
dcb.fOutxDsrFlow = false;
dcb.fErrorChar = false;
//PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx
if (dtr)
dcb.fDtrControl = DTR_CONTROL_ENABLE;
else
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = false;
if (rtscts) dcb.fRtsControl = RTS_CONTROL_ENABLE;
else {
if (rts)
dcb.fRtsControl = RTS_CONTROL_ENABLE;
else
dcb.fRtsControl = RTS_CONTROL_DISABLE;
}
#if SERIAL_DEBUG
fprintf(serlog, "\
\n\
Set Comm State:\n\
DCB.DCBlength %d\n\
DCB.Baudrate %d\n\
DCB.ByteSize %d\n\
DCB.Parity %d\n\
DCB.StopBits %d\n\
DCB.Binary %d\n\
DCB.fDtrControl %d\n\
DCB.fRtsControl %d\n\
DCB.fDsrSensitivity %d\n\
DCB.fParity %d\n\
DCB.fOutX %d\n\
DCB.fInX %d\n\
DCB.fNull %d\n\
DCB.XonChar %d\n\
DCB.XoffChar %d\n\
DCB.fAbortOnError %d\n\
DCB.fOutxCtsFlow %d\n\
DCB.fOutxDsrFlow %d\n",
(int)dcb.DCBlength,
(int)dcb.BaudRate,
(int)dcb.ByteSize,
(int)dcb.Parity,
(int)dcb.StopBits,
(int)dcb.fBinary,
(int)dcb.fDtrControl,
(int)dcb.fRtsControl,
(int)dcb.fDsrSensitivity,
(int)dcb.fParity,
(int)dcb.fOutX,
(int)dcb.fInX,
(int)dcb.fNull,
(int)dcb.XonChar,
(int)dcb.XoffChar,
(int)dcb.fAbortOnError,
(int)dcb.fOutxCtsFlow,
(int)dcb.fOutxDsrFlow);
#endif
bPortReady = SetCommState(hComm, &dcb);
// if(bPortReady == 0) {
#if SERIAL_DEBUG
long err = GetLastError();
fl_alert("SetCommState handle %d, returned %d\nError = %d", (int)hComm, bPortReady, (int)err);
fprintf(serlog, "SetCommState handle %d, returned %d, error = %d\n", (int)hComm, bPortReady, (int)err);
#endif
if (bPortReady == 0) {
CloseHandle(hComm);
return false;
}
return SetCommTimeout();
}
///////////////////////////////////////////////////////
// Function name : Cserial::setPTT
// Return type : void
///////////////////////////////////////////////////////
void Cserial::SetPTT(bool ON)
{
if (hComm == INVALID_HANDLE_VALUE) {
#if SERIAL_DEBUG
fl_alert("SetPTT failed, invalid handle");
fprintf(serlog, "SetPTT failed, invalid handle\n");
#endif
return;
}
if ( !(dtrptt || rtsptt) )
return;
if (ON) {
if (dtrptt && dtr)
dcb.fDtrControl = DTR_CONTROL_DISABLE;
if (dtrptt && !dtr)
dcb.fDtrControl = DTR_CONTROL_ENABLE;
if (!rtscts) {
if (rtsptt && rts)
dcb.fRtsControl = RTS_CONTROL_DISABLE;
if (rtsptt && !rts)
dcb.fRtsControl = RTS_CONTROL_ENABLE;
}
} else {
if (dtrptt && dtr)
dcb.fDtrControl = DTR_CONTROL_ENABLE;
if (dtrptt && !dtr)
dcb.fDtrControl = DTR_CONTROL_DISABLE;
if (!rtscts) {
if (rtsptt && rts)
dcb.fRtsControl = RTS_CONTROL_ENABLE;
if (rtsptt && !rts)
dcb.fRtsControl = RTS_CONTROL_DISABLE;
}
}
LOG_ERROR("PTT %d, DTRptt %d, DTR %d, RTSptt %d, RTS %d, RTSCTS %d, %2x %2x",
ON, dtrptt, dtr, rtsptt, rts, rtscts,
static_cast(dcb.fDtrControl),
static_cast(dcb.fRtsControl) );
#if SERIAL_DEBUG
fprintf(serlog, "\
PTT %d, DTRptt %d, DTR %d, RTSptt %d, RTS %d, RTSCTS %d, DtrControl %2x, RtsControl %2x\n",
ON, dtrptt, dtr, rtsptt, rts, rtscts,
static_cast(dcb.fDtrControl),
static_cast(dcb.fRtsControl) );
#endif
SetCommState(hComm, &dcb);
}
void Cserial::setRTS(bool b)
{
if (hComm == INVALID_HANDLE_VALUE) return;
if (b == true)
dcb.fRtsControl = RTS_CONTROL_ENABLE;
else
dcb.fRtsControl = RTS_CONTROL_DISABLE;
#if SERIAL_DEBUG
int retval = SetCommState(hComm, &dcb);
fprintf(serlog, "\
Set RTS %d, DtrControl %2x, RtsControl %2x ==> %d\n",
b,
static_cast(dcb.fDtrControl),
static_cast(dcb.fRtsControl),
retval );
return;
#endif
SetCommState(hComm, &dcb);
}
void Cserial::setDTR(bool b)
{
if (hComm == INVALID_HANDLE_VALUE) return;
if (b == true)
dcb.fDtrControl = DTR_CONTROL_ENABLE;
else
dcb.fDtrControl = DTR_CONTROL_DISABLE;
#if SERIAL_DEBUG
int retval = SetCommState(hComm, &dcb);
fprintf(serlog, "\
Set DTR %d, DtrControl %2x, RtsControl %2x ==> %d\n",
b,
static_cast(dcb.fDtrControl),
static_cast(dcb.fRtsControl),
retval );
return;
#endif
SetCommState(hComm, &dcb);
}
Cserial::Cserial() {
rts = dtr = false;
rtsptt = dtrptt = false;
rtscts = false;
baud = CBR_9600;
stopbits = 2;
hComm = 0;
}
Cserial::Cserial( std::string portname) {
device = portname;
Cserial();
}
Cserial::~Cserial() {
ClosePort();
}
#endif
flrig-1.3.49/src/support/timeops.cxx 0000664 0001750 0001750 00000012565 13605621006 014355 0000000 0000000 // ----------------------------------------------------------------------------
// timeops.cxx
//
// Copyright (C) 2017
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// fldigi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include "timeops.h"
#ifdef __MINGW32__
# include "compat.h"
# include "util.h"
#else
# include "util.h"
#endif
#if !HAVE_CLOCK_GETTIME
# ifdef __APPLE__
# include
# define CLOCK_REALTIME 0
# define CLOCK_MONOTONIC 6
# endif
# if TIME_WITH_SYS_TIME
# include
# endif
# include
int clock_gettime(clock_id_t clock_id, struct timespec* tp)
{
if (clock_id == CLOCK_REALTIME) {
struct timeval t;
if (unlikely(gettimeofday(&t, NULL) != 0))
return -1;
tp->tv_sec = t.tv_sec;
tp->tv_nsec = t.tv_usec * 1000;
}
else if (clock_id == CLOCK_MONOTONIC) {
#if defined(__WOE32__)
int msec = GetTickCount();
tp->tv_sec = msec / 1000;
tp->tv_nsec = (msec % 1000) * 1000000;
#elif defined(__APPLE__)
static mach_timebase_info_data_t info = { 0, 0 };
if (unlikely(info.denom == 0))
mach_timebase_info(&info);
uint64_t t = mach_absolute_time() * info.numer / info.denom;
tp->tv_sec = t / 1000000000;
tp->tv_nsec = t % 1000000000;
#endif
}
else {
errno = EINVAL;
return -1;
}
return 0;
}
#endif // !HAVE_CLOCK_GETTIME
struct timespec operator+(const struct timespec &t0, const double &t)
{
struct timespec r;
r.tv_sec = t0.tv_sec + static_cast(t);
r.tv_nsec = t0.tv_nsec + static_cast((t - static_cast(t)) * 1e9);
if (r.tv_nsec > 1000000000) {
r.tv_nsec -= 1000000000;
r.tv_sec++;
}
return r;
}
struct timespec operator-(const struct timespec &t0, const struct timespec &t1)
{
struct timespec r = t0;
if (r.tv_nsec < t1.tv_nsec) {
--r.tv_sec;
r.tv_nsec += 1000000000L;
}
r.tv_sec -= t1.tv_sec;
r.tv_nsec -= t1.tv_nsec;
return r;
}
struct timespec& operator-=(struct timespec &t0, const struct timespec &t1)
{
if (t0.tv_nsec < t1.tv_nsec) {
--t0.tv_sec;
t0.tv_nsec += 1000000000L;
}
t0.tv_sec -= t1.tv_sec;
t0.tv_nsec -= t1.tv_nsec;
return t0;
}
bool operator>(const struct timespec &t0, const struct timespec &t1)
{
if (t0.tv_sec == t1.tv_sec)
return t0.tv_nsec > t1.tv_nsec;
else if (t0.tv_sec > t1.tv_sec)
return true;
else
return false;
}
bool operator==(const struct timespec &t0, const struct timespec &t1)
{
return t0.tv_sec == t1.tv_sec && t0.tv_nsec == t1.tv_nsec;
}
struct timeval operator+(const struct timeval &t0, const double &t)
{
struct timeval r;
r.tv_sec = t0.tv_sec + static_cast(t);
r.tv_usec = t0.tv_usec + static_cast((t - static_cast(t)) * 1e9);
if (r.tv_usec > 1000000) {
r.tv_usec -= 1000000;
r.tv_sec++;
}
return r;
}
struct timeval operator-(const struct timeval &t0, const struct timeval &t1)
{
struct timeval r = t0;
if (r.tv_usec < t1.tv_usec) {
--r.tv_sec;
r.tv_usec += 1000000;
}
r.tv_sec -= t1.tv_sec;
r.tv_usec -= t1.tv_usec;
return r;
}
struct timeval& operator-=(struct timeval &t0, const struct timeval &t1)
{
if (t0.tv_usec < t1.tv_usec) {
--t0.tv_sec;
t0.tv_usec += 1000000L;
}
t0.tv_sec -= t1.tv_sec;
t0.tv_usec -= t1.tv_usec;
return t0;
}
bool operator>(const struct timeval &t0, const struct timeval &t1)
{
if (t0.tv_sec == t1.tv_sec)
return t0.tv_usec > t1.tv_usec;
else if (t0.tv_sec > t1.tv_sec)
return true;
else
return false;
}
bool operator==(const struct timeval &t0, const struct timeval &t1)
{
return t0.tv_sec == t1.tv_sec && t0.tv_usec == t1.tv_usec;
}
#ifndef HAVE_GMTIME_R
#include
#include "threads.h"
static pthread_mutex_t gmtime_r_mutex = PTHREAD_MUTEX_INITIALIZER;
struct tm *gmtime_r(const time_t *_Time, struct tm *_Tm)
{
pthread_mutex_lock (&gmtime_r_mutex);
struct tm *p = gmtime(_Time);
if (p && _Tm) memcpy (_Tm, p, sizeof (struct tm));
pthread_mutex_unlock (&gmtime_r_mutex);
return p;
}
static pthread_mutex_t gmtime_local_mutex = PTHREAD_MUTEX_INITIALIZER;
struct tm *localtime_r(const time_t *_Time,struct tm *_Tm)
{
pthread_mutex_lock (&gmtime_local_mutex);
struct tm *p = localtime(_Time);
if (p && _Tm) memcpy (_Tm, p, sizeof (struct tm));
pthread_mutex_unlock (&gmtime_local_mutex);
return p;
}
#endif
flrig-1.3.49/src/support/status.cxx 0000664 0001750 0001750 00000160515 13605621006 014217 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include "status.h"
#include "util.h"
#include "rig.h"
#include "rigs.h"
#include "support.h"
#include "config.h"
#include "rigpanel.h"
#include "ui.h"
#include "debug.h"
#include "IC706MKIIG.h"
string xcvr_name = "NONE";
int current_ui_size = -1;
status progStatus = {
50, // int mainX;
50, // int mainY;
735, // int mainW;
150, // int mainH;
small_ui, // UISIZE, UIsize;
false, // UIchanged;
"NONE", // string xcvr_serial_port;
0, // int comm_baudrate;
2, // int stopbits;
2, // int comm_retries;
5, // int comm_wait;
50, // int comm_timeout;
false, // bool comm_echo;
false, // bool comm_catptt;
false, // bool comm_rtsptt;
false, // bool comm_dtrptt;
false, // bool comm_rtscts;
false, // bool comm_rtsplus;
false, // bool comm_dtrplus;
200, // int serloop_timing;
0, // int byte_interval;
"NONE", // string aux_serial_port;
false, // bool aux_SCU_17;
false, // bool aux_rts;
false, // bool aux_dtr;
"NONE", // string sep_serial_port;
false, // bool sep_rtsptt;
false, // bool sep_dtrptt;
false, // bool sep_rtsplus;
false, // bool sep_dtrplus;
false, // bool sep_SCU_17;
0, // int CIV;
false, // bool USBaudio;
1, // bool poll_smeter;
1, // bool poll_frequency;
1, // bool poll_mode;
1, // bool poll_bandwidth;
1, // bool poll_volume;
1, // bool poll_auto_notch;
1, // bool poll_notch;
1, // bool poll_ifshift;
1, // bool poll_power_control;
1, // bool poll_pre_att;
1, // bool poll_micgain;
1, // bool poll_squelch;
1, // bool poll_rfgain;
1, // bool poll_pout;
1, // bool poll_swr;
1, // bool poll_alc;
1, // bool poll_split;
1, // bool poll_noise;
1, // bool poll_nr;
1, // int poll_vfoAorB;
1, // poll_meters;
1, // poll_ops;
1, // poll_compression;
4, // int poll_all;
-1, // int iBW_A;
1, // int imode_A;
14070000, // long freq_A;
-1, // int iBW_B;
1, // int imode_B;
7070000, // long freq_B;
"", // std::string filters;
"", // std::string bandwidths;
true, // bool use_rig_data;
false, // bool spkr_on;
20, // int volume;
0, // int power_level;
10, // int mic_gain;
false, // bool notch;
0, // int notch_val;
false, // bool shift;
0, // int shift_val;
0, // bool pbt_lock;
0, // int pbt_inner;
0, // int pbt_outer;
100, // int rfgain;
10, // int squelch;
0, // int schema;
true, // bool hrd_buttons
FL_WHEN_CHANGED, // int sliders_button
0, // int line_out;
false, // bool data_port;
1, // int agc_level;
18, // int cw_wpm;
3.0, // double cw_weight;
0, // int cw_vol;
0, // int cw_spot;
false, // bool spot_onoff;
700, // int cw_spot_tone;
false, // bool enable_keyer;
0, // bool break_in;
15, // double cw_qsk;
200, // double cw_delay;
false, // int vox_onoff;
10, // int vox_gain;
10, // int vox_anti;
100, // int vox_hang; FT950 default
true, // bool vox_on_dataport;
0, // int compression;
false, // bool compON;
0, // bool noise_reduction;
0, // int noise_reduction_val;
0, // int nb_level;
false, // bool noise;
0, // int attenuator
0, // int preamp;
0, // int auto_notch;
0, // int split;
0, // int no_txqsy
5, // int rx_avg;
5, // int rx_peak;
5, // int pwr_avg;
5, // int pwr_peak;
4, // int pwr_scale ==> Autoselect
// ic7610 special controls
false, // bool digi_sel_on_off;
0, // int digi_sel_val;
6, // int ic7610att;
0, // bool dual_watch;
//ft950 reversed RF gain values
false, // bool ft950_rg_reverse
true, // bool restore_frequency;
true, // bool restore_mode;
true, // bool restore_bandwidth;
true, // bool restore_volume;
true, // bool restore_mic_gain;
true, // bool restore_rf_gain;
true, // bool restore_power_control;
true, // bool restore_if_shift;
true, // bool restore_notch;
true, // bool restore_auto_notch;
true, // bool restore_noise;
true, // bool restore_squelch;
true, // bool restore_split;
true, // bool restore_pre_att;
true, // bool restore_nr;
true, // bool restore_comp_on_off;
true, // bool restore_comp_level;
//tt550 controls
80, // tt550_line_out;
1, // tt550_agc_level;
24, // tt550_cw_wpm;
1.0, // tt550_cw_weight;
10, // tt550_cw_vol;
10, // tt550_cw_spot;
false, // tt550_cw_spot_onoff;
20, // tt550_cw_qsk;
false, // tt550_enable_keyer;
false, // tt550_vox_onoff;
0, // tt550_vox_gain;
0, // tt550_vox_anti;
0, // tt550_vox_hang;
0, // tt550_mon_vol;
0, // tt550_squelch_level;
0, // tt550_compression;
1, // tt550_nb_level;
false, // tt550_bool compON;
false, // tt550_tuner_bypass;
true, // tt550_enable_xmtr;
false, // tt550_enable_tloop;
true, // tt550_use_line_in;
14, // tt550_xmt_bw;
false, // tt550_use_xmt_bw;
25, // tt550_AM_level;
0, // tt550_encoder_step;
1, // tt550_encoder_sensitivity;
2000, // tt550_keypad_timeout;
0, // tt550_F1_func;
0, // tt550_F2_func;
0, // tt550_F3_func;
5, // tt550_Nsamples;
true, // tt550_at11_inline;
true, // tt550_at11_hiZ;
// =========================
0.0, // vfo_adj;
600, // bfo_freq;
0, // rit_freq;
0, // xit_freq;
1500, // bpf_center;
true, // use_bpf_center;
// =========================
// IC706MKIIG filters
false, // bool use706filters
"EMPTY", // string ssb_cw_wide;
"NORMAL", // string ssb_cw_normal;
"EMPTY", // string ssb_cw_narrow;
// optional filter strings
// "EMPTY", "NARR", "NORM", "WIDE", "MED",
// "FL-101", "FL-232", "FL-100", "FL-223", "FL-103"
// =========================
"cmd 1", // string label1;
"", // string command1;
"cmd 2", // string label2;
"", // string command2;
"cmd 3", // string label3;
"", // string command3;
"cmd 4", // string label4;
"", // string command4;
"cmd 5", // string label5;
"", // string command5;
"cmd 6", // string label6;
"", // string command6;
"cmd 7", // string label7;
"", // string command7;
"cmd 8", // string label8;
"", // string command8;
"cmd 9", // string label9;
"", // string command9;
"cmd 10", // string label10;
"", // string command10;
"cmd 11", // string label11;
"", // string command11;
"cmd 12", // string label12;
"", // string command12;
"cmd 13", // string label13;
"", // string command13;
"cmd 14", // string label14;
"", // string command14;
"cmd 15", // string label15;
"", // string command15;
"cmd 16", // string label16;
"", // string command16;
// =========================
232, // int bg_red;
255, // int bg_green;
232, // int bg_blue;
0, // int fg_red;
0, // int fg_green;
0, // int fg_blue;
148, // int swrRed;
0, // int swrGreen;
148, // int swrBlue;
180, // int pwrRed;
0, // int pwrGreen;
0, // int pwrBlue;
0, // int smeterRed;
180, // int smeterGreen;
0, //int smeterBlue;
255, // int peakRed;
0, // int peakGreen;
0, // int peakBlue;
0, // int fg_sys_red;
0, // int fg_sys_green;
0, // int fg_sys_blue;
0xc0, // int bg_sys_red;
0xc0, // int bg_sys_green;
0xc0, // int bg_sys_blue;
255, // int bg2_sys_red;
255, // int bg2_sys_green;
255, // int bg2_sys_blue;
232, // int slider_red;
255, // int slider_green;
232, // int slider_blue;
0, // int slider_btn_red;
0, // int slider_btn_green;
128, // int slider_btn_blue;
255, // int lighted_btn_red;
255, // int lighted_btn_green;
0, // int lighted_btn_blue;
FL_COURIER, // Fl_Font fontnbr;
false, // bool tooltips;
"gtk+", // string ui_scheme
// "7362", // string server_port
// "127.0.0.1",// string server_address
"4001", // string tcpip_port
"127.0.0.1",// string tcpip_address
50, // int tcpip_ping_delay
10, // int tcpip_reconnect_after in seconds
10, // int tcpip_drops_allowed;
false, // bool use_tcpip
false, // bool xcvr auto on
false, // bool xcvr auto off
false, // bool external_tuner
false, // bool trace;
false, // bool rigtrace;
false, // bool gettrace;
false, // bool settrace;
false, // bool debugtrace;
false, // bool xmltrace;
false, // bool rpctrace;
false, // bool start_stop_trace;
0, // int rpc_level;
// bands; defaults for FT857 / FT897
// frequency, mode, txCTCSS, rxCTCSS, offset, offset_freq;
1805000L, 6, 0, 0, 0, 600, // f160
3580000L, 6, 0, 0, 0, 600, // f80 meters
7070000L, 6, 0, 0, 0, 600, // f40 meters
10140000L, 6, 0, 0, 0, 600, // f30 meters
14070000L, 6, 0, 0, 0, 600, // f20 meters
18100000L, 6, 0, 0, 0, 600, // f17 meters
21070000L, 6, 0, 0, 0, 600, // f15 meters
24920000L, 6, 0, 0, 0, 600, // f12 meters
28070000L, 6, 0, 0, 0, 600, // f10 meters
50070000L, 6, 0, 0, 0, 600, // f6 meters
144070000L, 6, 0, 0, 0, 600, // f2 meters
432100000L, 6, 0, 0, 0, 600 // f70 cent'
};
void status::saveLastState()
{
xcvr_name = selrig->name_;
Fl_Preferences xcvrpref(RigHomeDir.c_str(), "w1hkj.com", PACKAGE_TARNAME);
xcvrpref.set("xcvr_name", xcvr_name.c_str());
xcvrpref.set("xml_port", xmlport);
int mX = mainwindow->x();
int mY = mainwindow->y();
int mW = mainwindow->w();
int mH = mainwindow->h();
if (mX >= 0 && mX >= 0) {
mainX = mX;
mainY = mY;
if (UIsize != small_ui) { mainW = mW; mainH = mH; }
}
Fl_Preferences spref(RigHomeDir.c_str(), "w1hkj.com", xcvr_name.c_str());
spref.set("version", PACKAGE_VERSION);
spref.set("mainx", mainX);
spref.set("mainy", mainY);
spref.set("mainw", mainW);
spref.set("mainh", mainH);
spref.set("uisize", UIsize);
spref.set("xcvr_serial_port", xcvr_serial_port.c_str());
spref.set("comm_baudrate", comm_baudrate);
spref.set("comm_stopbits", stopbits);
spref.set("comm_retries", comm_retries);
spref.set("comm_wait", comm_wait);
spref.set("comm_timeout", comm_timeout);
spref.set("serloop_timing", serloop_timing);
spref.set("byte_interval", byte_interval);
spref.set("comm_echo", comm_echo);
spref.set("ptt_via_cat", comm_catptt);
spref.set("ptt_via_rts", comm_rtsptt);
spref.set("ptt_via_dtr", comm_dtrptt);
spref.set("rts_cts_flow", comm_rtscts);
spref.set("rts_plus", comm_rtsplus);
spref.set("dtr_plus", comm_dtrplus);
spref.set("civadr", CIV);
spref.set("usbaudio", USBaudio);
spref.set("aux_serial_port", aux_serial_port.c_str());
spref.set("aux_rts", aux_rts);
spref.set("aux_dtr", aux_dtr);
spref.set("sep_serial_port", sep_serial_port.c_str());
spref.set("sep_rtsptt", sep_rtsptt);
spref.set("sep_dtrptt", sep_dtrptt);
spref.set("sep_rtsplus", sep_rtsplus);
spref.set("set_dtrplus", sep_dtrplus);
spref.set("poll_smeter", poll_smeter);
spref.set("poll_frequency", poll_frequency);
spref.set("poll_mode", poll_mode);
spref.set("poll_bandwidth", poll_bandwidth);
spref.set("poll_volume", poll_volume);
spref.set("poll_auto_notch", poll_auto_notch);
spref.set("poll_notch", poll_notch);
spref.set("poll_ifshift", poll_ifshift);
spref.set("poll_power_control", poll_power_control);
spref.set("poll_pre_att", poll_pre_att);
spref.set("poll_micgain", poll_micgain);
spref.set("poll_squelch", poll_squelch);
spref.set("poll_rfgain", poll_rfgain);
spref.set("poll_pout", poll_pout);
spref.set("poll_swr", poll_swr);
spref.set("poll_alc", poll_alc);
spref.set("poll_split", poll_split);
spref.set("poll_noise", poll_noise);
spref.set("poll_nr", poll_nr);
spref.set("poll_compression", poll_compression);
spref.set("poll_all", poll_all);
spref.set("bw_A", iBW_A);
spref.set("mode_A", imode_A);
spref.set("freq_A", freq_A);
spref.set("bw_B", iBW_B);
spref.set("mode_B", imode_B);
spref.set("freq_B", freq_B);
spref.set("filters", filters.c_str());
spref.set("bandwidths", bandwidths.c_str());
spref.set("use_rig_data", use_rig_data);
// spref.set("restore_rig_data", restore_rig_data);
spref.set("restore_frequency", restore_frequency);
spref.set("restore_mode", restore_mode);
spref.set("restore_bandwidth", restore_bandwidth);
spref.set("restore_volume", restore_volume);
spref.set("restore_mic_gain", restore_mic_gain);
spref.set("restore_rf_gain", restore_rf_gain);
spref.set("restore_power_control", restore_power_control);
spref.set("restore_if_shift", restore_if_shift);
spref.set("restore_notch", restore_notch);
spref.set("restore_auto_notch", restore_auto_notch);
spref.set("restore_noise", restore_noise);
spref.set("restore_squelch", restore_squelch);
spref.set("restore_split", restore_split);
spref.set("restore_pre_att", restore_pre_att);
spref.set("restore_nr", restore_nr);
spref.set("restore_comp_on_off", restore_comp_on_off);
spref.set("restore_comp_level", restore_comp_level);
spref.set("bool_spkr_on", spkr_on);
spref.set("int_volume", volume);
spref.set("dbl_power", power_level);
spref.set("int_mic", mic_gain);
spref.set("bool_notch", notch);
spref.set("int_notch", notch_val);
spref.set("bool_shift", shift);
spref.set("int_shift", shift_val);
spref.set("pbt_lock", pbt_lock);
spref.set("pbt_inner", pbt_inner);
spref.set("pbt_outer", pbt_outer);
spref.set("rfgain", rfgain);
spref.set("squelch", squelch);
spref.set("no_txqsy", no_txqsy);
spref.set("schema", schema);
spref.set("rx_avg", rx_avg);
spref.set("rx_peak", rx_peak);
spref.set("pwr_avg", pwr_avg);
spref.set("pwr_peak", pwr_peak);
spref.set("pwr_scale", pwr_scale);
spref.set("digi_sel_on_off", digi_sel_on_off);
spref.set("digi_sel_val", digi_sel_val);
spref.set("dual_watch", dual_watch);
spref.set("ic7610att", index_ic7610att);
spref.set("ft950_rg_reverse", ft950_rg_reverse);
if (selrig->name_ == rig_TT550.name_) {
spref.set("tt550_line_out", tt550_line_out);
spref.set("tt550_agc_level", tt550_agc_level);
spref.set("tt550_cw_wpm", tt550_cw_wpm);
spref.set("tt550_cw_weight", tt550_cw_weight);
spref.set("tt550_cw_vol", tt550_cw_vol);
spref.set("tt550_cw_spot", tt550_cw_spot);
spref.set("tt550_spot_onoff", tt550_spot_onoff);
spref.set("tt550_cw_qsk", tt550_cw_qsk);
spref.set("tt550_enable_keyer", tt550_enable_keyer);
spref.set("cw_delay", cw_delay);
spref.set("tt550_vox_onoff", tt550_vox_onoff);
spref.set("tt550_vox_gain", tt550_vox_gain);
spref.set("tt550_vox_anti", tt550_vox_anti);
spref.set("tt550_vox_hang", tt550_vox_hang);
spref.set("tt550_mon_vol", tt550_mon_vol);
spref.set("tt550_squelch_level", tt550_squelch_level);
spref.set("tt550_compression", tt550_compression);
spref.set("tt550_nb_level", tt550_nb_level);
spref.set("tt550_compON", tt550_compON);
spref.set("tt550_tuner_bypass", tt550_tuner_bypass);
spref.set("tt550_enable_xmtr", tt550_enable_xmtr);
spref.set("tt550_enable_tloop", tt550_enable_tloop);
spref.set("tt550_xmt_bw", tt550_xmt_bw);
spref.set("tt550_use_xmt_bw", tt550_use_xmt_bw);
spref.set("tt550_AM_level", tt550_AM_level);
spref.set("tt550_use_line_in", tt550_use_line_in);
spref.set("tt550_encoder_step", tt550_encoder_step);
spref.set("tt550_encoder_sensitivity", tt550_encoder_sensitivity);
spref.set("tt550_keypad_timeout", tt550_keypad_timeout);
spref.set("tt550_F1_func", tt550_F1_func);
spref.set("tt550_F2_func", tt550_F2_func);
spref.set("tt550_F3_func", tt550_F3_func);
spref.set("tt550_Nsamples", tt550_Nsamples);
spref.set("tt550_at11_inline", tt550_at11_inline);
spref.set("tt550_at11_hiZ", tt550_at11_hiZ);
} else {
spref.set("line_out", line_out);
spref.set("data_port", data_port);
spref.set("vox_on_dataport", vox_on_dataport);
spref.set("agc_level", agc_level);
spref.set("cw_wpm", cw_wpm);
spref.set("cw_weight", cw_weight);
spref.set("cw_vol", cw_vol);
spref.set("cw_spot", cw_spot);
spref.set("spot_onoff", spot_onoff);
spref.set("cw_spot_tone", cw_spot_tone);
spref.set("cw_qsk", cw_qsk);
spref.set("cw_delay", cw_delay);
spref.set("enable_keyer", enable_keyer);
spref.set("break_in", break_in);
spref.set("vox_onoff", vox_onoff);
spref.set("vox_gain", vox_gain);
spref.set("vox_anti", vox_anti);
spref.set("vox_hang", vox_hang);
spref.set("compression", compression);
spref.set("compON", compON);
}
spref.set("noise_reduction", noise_reduction);
spref.set("noise_red_val", noise_reduction_val);
spref.set("nb_level", nb_level);
spref.set("bool_noise", noise);
spref.set("int_preamp", preamp);
spref.set("int_att", attenuator);
spref.set("vfo_adj", vfo_adj);
spref.set("bfo_freq", bfo_freq);
spref.set("rit_freq", rit_freq);
spref.set("xit_freq", xit_freq);
spref.set("bpf_center", bpf_center);
spref.set("use_bpf_center", use_bpf_center);
if (selrig->name_ == IC706MKIIGname_) {
spref.set("use706filters", use706filters);
spref.set("Set_IC706MKIIG_filter_names", "");
spref.set("IC706MKIIG_filter_names_1", \
"EMPTY,NARR,NORM,WIDE,MED" );
spref.set("IC706MKIIG_filter_names_2", \
"FL-101,FL-232,FL-100,FL-223,FL-103" );
spref.set("ssb_cw_wide", ssb_cw_wide.c_str());
spref.set("ssb_cw_normal", ssb_cw_normal.c_str());
spref.set("ssb_cw_narrow", ssb_cw_narrow.c_str());
selrig->initialize();
}
spref.set("label1", label1.c_str());
spref.set("command1", command1.c_str());
spref.set("label2", label2.c_str());
spref.set("command2", command2.c_str());
spref.set("label3", label3.c_str());
spref.set("command3", command3.c_str());
spref.set("label4", label4.c_str());
spref.set("command4", command4.c_str());
spref.set("label5", label5.c_str());
spref.set("command5", command5.c_str());
spref.set("label6", label6.c_str());
spref.set("command6", command6.c_str());
spref.set("label7", label7.c_str());
spref.set("command7", command7.c_str());
spref.set("label8", label8.c_str());
spref.set("command8", command8.c_str());
spref.set("label9", label9.c_str());
spref.set("command9", command9.c_str());
spref.set("label10", label10.c_str());
spref.set("command10", command10.c_str());
spref.set("label11", label11.c_str());
spref.set("command11", command11.c_str());
spref.set("label12", label12.c_str());
spref.set("command12", command12.c_str());
spref.set("label13", label13.c_str());
spref.set("command13", command13.c_str());
spref.set("label14", label14.c_str());
spref.set("command14", command14.c_str());
spref.set("label15", label15.c_str());
spref.set("command15", command15.c_str());
spref.set("label16", label16.c_str());
spref.set("command16", command16.c_str());
spref.set("fg_red", fg_red);
spref.set("fg_green", fg_green);
spref.set("fg_blue", fg_blue);
spref.set("bg_red", bg_red);
spref.set("bg_green", bg_green);
spref.set("bg_blue", bg_blue);
spref.set("smeter_red", smeterRed);
spref.set("smeter_green", smeterGreen);
spref.set("smeter_blue", smeterBlue);
spref.set("power_red", pwrRed);
spref.set("power_green", pwrGreen);
spref.set("power_blue", pwrBlue);
spref.set("swr_red", swrRed);
spref.set("swr_green", swrGreen);
spref.set("swr_blue", swrBlue);
spref.set("peak_red", peakRed);
spref.set("peak_green", peakGreen);
spref.set("peak_blue", peakBlue);
spref.set("fg_sys_red", fg_sys_red);
spref.set("fg_sys_green", fg_sys_green);
spref.set("fg_sys_blue", fg_sys_blue);
spref.set("bg_sys_red", bg_sys_red);
spref.set("bg_sys_green", bg_sys_green);
spref.set("bg_sys_blue", bg_sys_blue);
spref.set("bg2_sys_red", bg2_sys_red);
spref.set("bg2_sys_green", bg2_sys_green);
spref.set("bg2_sys_blue", bg2_sys_blue);
spref.set("slider_red", slider_red);
spref.set("slider_green", slider_green);
spref.set("slider_blue", slider_blue);
spref.set("slider_btn_red", slider_btn_red);
spref.set("slider_btn_green", slider_btn_green);
spref.set("slider_btn_blue", slider_btn_blue);
spref.set("lighted_btn_red", lighted_btn_red);
spref.set("lighted_btn_green", lighted_btn_green);
spref.set("lighted_btn_blue", lighted_btn_blue);
spref.set("fontnbr", fontnbr);
spref.set("tooltips", tooltips);
spref.set("ui_scheme", ui_scheme.c_str());
// spref.set("server_port", server_port.c_str());
// spref.set("server_addr", server_addr.c_str());
spref.set("tcpip_port", tcpip_port.c_str());
spref.set("tcpip_addr", tcpip_addr.c_str());
spref.set("tcpip_ping_delay", tcpip_ping_delay);
spref.set("tcpip_tcpip_reconnect_after", tcpip_reconnect_after);
spref.set("tcpip_drops_allowed", tcpip_drops_allowed);
spref.set("use_tcpip", use_tcpip);
spref.set("xcvr_auto_on", xcvr_auto_on);
spref.set("xcvr_auto_off", xcvr_auto_off);
spref.set("external_tuner", external_tuner);
spref.set("trace", trace);
spref.set("rigtrace", rigtrace);
spref.set("gettrace", gettrace);
spref.set("settrace", settrace);
spref.set("debugtrace", debugtrace);
spref.set("xmltrace", xmltrace);
spref.set("rpctrace", rpctrace);
spref.set("startstoptrace", start_stop_trace);
spref.set("rpc_level", rpc_level);
spref.set("f160", f160); spref.set("m160", m160);
spref.set("txT160", txT_160); spref.set("rxT160", rxT_160);
spref.set("offset_160", offset_160); spref.set("oF_160", oF_160);
spref.set("f80", f80); spref.set("m80", m80);
spref.set("txT80", txT_80); spref.set("rxT80", rxT_80);
spref.set("offset_80", offset_80); spref.set("oF_80", oF_80);
spref.set("f40", f40); spref.set("m40", m40);
spref.set("txT40", txT_40); spref.set("rxT40", rxT_40);
spref.set("offset_40", offset_40); spref.set("oF_40", oF_40);
spref.set("f30", f30); spref.set("m30", m30);
spref.set("txT30", txT_30); spref.set("rxT30", rxT_30);
spref.set("offset_30", offset_30); spref.set("oF_30", oF_30);
spref.set("f20", f20); spref.set("m20", m20);
spref.set("txT20", txT_20); spref.set("rxT20", rxT_20);
spref.set("offset_20", offset_20); spref.set("oF_20", oF_20);
spref.set("f17", f17); spref.set("m17", m17);
spref.set("txT17", txT_17); spref.set("rxT17", rxT_17);
spref.set("offset_17", offset_17); spref.set("oF_17", oF_17);
spref.set("f15", f15); spref.set("m15", m15);
spref.set("txT15", txT_15); spref.set("rxT15", rxT_15);
spref.set("offset_15", offset_15); spref.set("oF_15", oF_15);
spref.set("f12", f12); spref.set("m12", m12);
spref.set("txT12", txT_12); spref.set("rxT12", rxT_12);
spref.set("offset_12", offset_12); spref.set("oF_12", oF_12);
spref.set("f10", f10); spref.set("m10", m10);
spref.set("txT10", txT_10); spref.set("rxT10", rxT_10);
spref.set("offset_10", offset_10); spref.set("oF_10", oF_10);
spref.set("f6", f6); spref.set("m6", m6);
spref.set("txT6", txT_6); spref.set("rxT_6", rxT_6);
spref.set("offset_6", offset_6); spref.set("oF_6", oF_6);
spref.set("f2", f2); spref.set("m2", m2);
spref.set("txT2", txT_2); spref.set("rxT2", rxT_2);
spref.set("offset_2", offset_2); spref.set("oF_2", oF_2);
spref.set("f70", f70); spref.set("m70", m70);
spref.set("txT70", txT_70); spref.set("rxT70", rxT_70);
spref.set("offset_70", offset_70); spref.set("oF_70", oF_70);
spref.set("hrd_buttons", hrd_buttons);
spref.set("sliders_button", sliders_button);
}
bool status::loadXcvrState(string xcvr)
{
Fl_Preferences spref(RigHomeDir.c_str(), "w1hkj.com", xcvr.c_str());
if (spref.entryExists("version")) {
int i;
char defbuffer[500];
spref.get("mainx", mainX, mainX);
spref.get("mainy", mainY, mainY);
spref.get("mainw", mainW, mainW);
spref.get("mainh", mainH, mainH);
spref.get("uisize", UIsize, UIsize);
if (current_ui_size != -1) {
UIsize = current_ui_size;
}
current_ui_size = UIsize;
if (UIsize == wide_ui) {
if (mainW < WIDE_MAINW) mainW = WIDE_MAINW;
}
if (UIsize == touch_ui) {
if (mainW < TOUCH_MAINW) mainW = TOUCH_MAINW;
}
spref.get("xcvr_serial_port", defbuffer, "NONE", 499);
xcvr_serial_port = defbuffer;
if (xcvr_serial_port.find("tty") == 0)
xcvr_serial_port.insert(0, "/dev/");
i = 0;
selrig = rigs[i];
while (rigs[i] != NULL) {
if (xcvr == rigs[i]->name_) {
selrig = rigs[i];
break;
}
i++;
}
spref.get("comm_baudrate", comm_baudrate, comm_baudrate);
spref.get("comm_stopbits", stopbits, stopbits);
spref.get("comm_retries", comm_retries, comm_retries);
spref.get("comm_wait", comm_wait, comm_wait);
spref.get("comm_timeout", comm_timeout, comm_timeout);
spref.get("serloop_timing", serloop_timing, serloop_timing);
if (serloop_timing < 10) serloop_timing = 10; // minimum loop delay of 10 msec
spref.get("byte_interval", byte_interval, byte_interval);
if (spref.get("comm_echo", i, i)) comm_echo = i;
if (spref.get("ptt_via_cat", i, i)) comm_catptt = i;
if (spref.get("ptt_via_rts", i, i)) comm_rtsptt = i;
if (spref.get("ptt_via_dtr", i, i)) comm_dtrptt = i;
if (spref.get("rts_cts_flow", i, i)) comm_rtscts = i;
if (spref.get("rts_plus", i, i)) comm_rtsplus = i;
if (spref.get("dtr_plus", i, i)) comm_dtrplus = i;
spref.get("civadr", CIV, CIV);
if (spref.get("usbaudio", i, i)) USBaudio = i;
spref.get("aux_serial_port", defbuffer, "NONE", 499);
aux_serial_port = defbuffer;
if (spref.get("aux_rts", i, i)) aux_rts = i;
if (spref.get("aux_dtr", i, i)) aux_dtr = i;
spref.get("sep_serial_port", defbuffer, "NONE", 499);
sep_serial_port = defbuffer;
if (spref.get("sep_rtsptt", i, i)) sep_rtsptt = i;
if (spref.get("sep_dtrptt", i, i)) sep_dtrptt = i;
if (spref.get("sep_rtsplus", i, i)) sep_rtsplus = i;
if (spref.get("sep_dtrplus", i, i)) sep_dtrplus = i;
spref.get("poll_smeter", poll_smeter, poll_smeter);
spref.get("poll_frequency", poll_frequency, poll_frequency);
spref.get("poll_mode", poll_mode, poll_mode);
spref.get("poll_bandwidth", poll_bandwidth, poll_bandwidth);
spref.get("poll_volume", poll_volume, poll_volume);
spref.get("poll_auto_notch", poll_auto_notch, poll_auto_notch);
spref.get("poll_notch", poll_notch, poll_notch);
spref.get("poll_ifshift", poll_ifshift, poll_ifshift);
spref.get("poll_power_control", poll_power_control, poll_power_control);
spref.get("poll_pre_att", poll_pre_att, poll_pre_att);
spref.get("poll_micgain", poll_micgain, poll_micgain);
spref.get("poll_squelch", poll_squelch, poll_squelch);
spref.get("poll_rfgain", poll_rfgain, poll_rfgain);
spref.get("poll_pout", poll_pout, poll_pout);
spref.get("poll_swr", poll_swr, poll_swr);
spref.get("poll_alc", poll_alc, poll_alc);
spref.get("poll_split", poll_split, poll_split);
spref.get("poll_noise", poll_noise, poll_noise);
spref.get("poll_nr", poll_nr, poll_nr);
spref.get("poll_compression", poll_compression, poll_compression);
spref.get("poll_all", poll_all, poll_all);
spref.get("bw_A", iBW_A, iBW_A);
spref.get("mode_A", imode_A, imode_A);
spref.get("freq_A", freq_A, freq_A);
spref.get("bw_B", iBW_B, iBW_B);
spref.get("mode_B", imode_B, imode_B);
spref.get("freq_B", freq_B, freq_B);
spref.get("filters", defbuffer, "", 499);
filters = defbuffer;
spref.get("bandwidths", defbuffer, "", 499);
bandwidths = defbuffer;
if (spref.get("use_rig_data", i, i)) use_rig_data = i;
// if (spref.get("restore_rig_data", i, i)) restore_rig_data = i;
if (spref.get("restore_frequency", i, i)) restore_frequency = i;
if (spref.get("restore_mode", i, i)) restore_mode = i;
if (spref.get("restore_bandwidth", i, i)) restore_bandwidth = i;
if (spref.get("restore_volume", i, i)) restore_volume = i;
if (spref.get("restore_mic_gain", i, i)) restore_mic_gain = i;
if (spref.get("restore_rf_gain", i, i)) restore_rf_gain = i;
if (spref.get("restore_power_control", i, i)) restore_power_control = i;
if (spref.get("restore_if_shift", i, i)) restore_if_shift = i;
if (spref.get("restore_notch", i, i)) restore_notch = i;
if (spref.get("restore_auto_notch", i, i)) restore_auto_notch = i;
if (spref.get("restore_noise", i, i)) restore_noise = i;
if (spref.get("restore_squelch", i, i)) restore_squelch = i;
if (spref.get("restore_split", i, i)) restore_split = i;
if (spref.get("restore_pre_att", i, i)) restore_pre_att = i;
if (spref.get("restore_nr", i, i)) restore_nr = i;
if (spref.get("restore_comp_on_off", i, i)) restore_comp_on_off = i;
if (spref.get("restore_comp_level", i, i)) restore_comp_level = i;
if (spref.get("bool_spkr_on", i, i)) spkr_on = i;
spref.get("int_volume", volume, volume);
spref.get("dbl_power", power_level, power_level);
spref.get("int_mic", mic_gain, mic_gain);
if (spref.get("bool_notch", i, i)) notch = i;
spref.get("int_notch", notch_val, notch_val);
if (spref.get("bool_shift", i, i)) shift = i;
spref.get("int_shift", shift_val, shift_val);
if (spref.get("pbt_lock", i, pbt_lock)) pbt_lock = i;
if (spref.get("pbt_inner", i, pbt_inner)) pbt_inner = i;
if (spref.get("pbt_outer", i, pbt_outer)) pbt_outer = i;
spref.get("rfgain", rfgain, rfgain);
spref.get("squelch", squelch, squelch);
spref.get("no_txqsy", no_txqsy, no_txqsy);
spref.get("schema", schema, schema);
spref.get("rx_avg", rx_avg, rx_avg);
spref.get("rx_peak", rx_peak, rx_peak);
spref.get("pwr_avg", pwr_avg, pwr_avg);
spref.get("pwr_peak", pwr_peak, pwr_peak);
spref.get("pwr_scale", pwr_scale, pwr_scale);
if (spref.get("digi_sel_on_off", i, i)) digi_sel_on_off = i;
spref.get("digi_sel_val", digi_sel_val, digi_sel_val);
if (spref.get("dual_watch", i, i)) dual_watch = i;
spref.get("ic7610att", index_ic7610att, index_ic7610att);
if (spref.get("ft950_rg_reverse", i, i)) ft950_rg_reverse = i;
if (selrig->name_ == rig_TT550.name_) {
spref.get("tt550_line_out", tt550_line_out, tt550_line_out);
spref.get("tt550_agc_level", tt550_agc_level, tt550_agc_level);
spref.get("tt550_cw_wpm", tt550_cw_wpm, tt550_cw_wpm);
spref.get("tt550_cw_weight", tt550_cw_weight, tt550_cw_weight);
spref.get("tt550_cw_vol", tt550_cw_vol, tt550_cw_vol);
spref.get("tt550_cw_spot", tt550_cw_spot, tt550_cw_spot);
if (spref.get("tt550_spot_onoff", i, i)) tt550_spot_onoff = i;
spref.get("tt550_cw_qsk", tt550_cw_qsk, tt550_cw_qsk);
if (spref.get("tt550_enable_keyer", i, i)) tt550_enable_keyer = i;
if (spref.get("break_in", i, i)) break_in = i;
if (spref.get("vox_onoff", i, i)) vox_onoff = i;
if (spref.get("tt550_vox_onoff", i, i)) tt550_vox_onoff = i;
spref.get("tt550_vox_gain", tt550_vox_gain, tt550_vox_gain);
spref.get("tt550_vox_anti", tt550_vox_anti, tt550_vox_anti);
spref.get("tt550_vox_hang", tt550_vox_hang, tt550_vox_hang);
spref.get("tt550_mon_vol", tt550_mon_vol, tt550_mon_vol);
spref.get("tt550_squelch_level", tt550_squelch_level, tt550_squelch_level);
spref.get("tt550_compression", tt550_compression, tt550_compression);
spref.get("tt550_nb_level", tt550_nb_level, tt550_nb_level);
if (spref.get("tt550_compON", i, i)) tt550_compON = i;
if (spref.get("tt550_tuner_bypass", i, i)) tt550_tuner_bypass = i;
if (spref.get("tt550_enable_xmtr", i, i)) tt550_enable_xmtr = i;
if (spref.get("tt550_enable_tloop", i, i)) tt550_enable_tloop = i;
spref.get("tt550_xmt_bw", tt550_xmt_bw, tt550_xmt_bw);
if (spref.get("tt550_use_xmt_bw", i, i)) tt550_use_xmt_bw = i;
if (spref.get("tt550_use_line_in", i, i)) tt550_use_line_in = i;
spref.get("tt550_AM_level", tt550_AM_level, tt550_AM_level);
spref.get("tt550_encoder_step", tt550_encoder_step, tt550_encoder_step);
spref.get("tt550_encoder_sensitivity", tt550_encoder_sensitivity, tt550_encoder_sensitivity);
spref.get("tt550_keypad_timeout", tt550_keypad_timeout, tt550_keypad_timeout);
spref.get("tt550_F1_func", tt550_F1_func, tt550_F1_func);
spref.get("tt550_F2_func", tt550_F2_func, tt550_F2_func);
spref.get("tt550_F3_func", tt550_F3_func, tt550_F3_func);
spref.get("tt550_Nsamples", tt550_Nsamples, tt550_Nsamples);
spref.get("tt550_at11_inline", i, tt550_at11_inline); tt550_at11_inline = i;
spref.get("tt550_at11_hiZ", i, tt550_at11_hiZ); tt550_at11_hiZ = i;
}
else {
spref.get("line_out", line_out, line_out);
spref.get("data_port", i, data_port); data_port = i;
spref.get("vox_on_dataport", i, vox_on_dataport); vox_on_dataport = i;
spref.get("agc_level", agc_level, agc_level);
spref.get("cw_wpm", cw_wpm, cw_wpm);
spref.get("cw_weight", cw_weight, cw_weight);
spref.get("cw_vol", cw_vol, cw_vol);
spref.get("cw_spot", cw_spot, cw_spot);
if (spref.get("spot_onoff", i, i)) spot_onoff = i;
spref.get("cw_spot_tone", cw_spot_tone, cw_spot_tone);
spref.get("cw_qsk", cw_qsk, cw_qsk);
spref.get("(cw_delay", cw_delay, cw_delay);
if (spref.get("enable_keyer", i, i)) enable_keyer = i;
if (spref.get("break_in", i, i)) break_in = i;
if (spref.get("vox_onoff", i, i)) vox_onoff = i;
spref.get("vox_gain", vox_gain, vox_gain);
spref.get("vox_anti", vox_anti, vox_anti);
spref.get("vox_hang", vox_hang, vox_hang);
spref.get("compression", compression, compression);
if (spref.get("compON", i, i)) compON = i;
}
if (spref.get("noise_reduction", i, i)) noise_reduction = i;
spref.get("noise_red_val", noise_reduction_val, noise_reduction_val);
if (spref.get("bool_noise", i, i)) noise = i;
spref.get("nb_level", nb_level, nb_level);
spref.get("int_preamp", preamp, preamp);
spref.get("int_att", attenuator, attenuator);
spref.get("compression", compression, compression);
if (spref.get("compON", i, i)) compON = i;
spref.get("vfo_adj", vfo_adj, vfo_adj);
spref.get("bfo_freq", bfo_freq, bfo_freq);
spref.get("rit_freq", rit_freq, rit_freq);
spref.get("xit_freq", xit_freq, xit_freq);
spref.get("bpf_center", bpf_center, bpf_center);
spref.get("use_bpf_center", i, i); use_bpf_center = i;
if (spref.get("use706filters", i, i)) use706filters = i;
spref.get("ssb_cw_wide", defbuffer, ssb_cw_wide.c_str(), 499);
ssb_cw_wide = defbuffer;
spref.get("ssb_cw_normal", defbuffer, ssb_cw_normal.c_str(), 499);
ssb_cw_normal = defbuffer;
spref.get("ssb_cw_narrow", defbuffer, ssb_cw_narrow.c_str(), 499);
ssb_cw_narrow = defbuffer;
spref.get("label1", defbuffer, label1.c_str(), 499);
label1 = defbuffer;
spref.get("command1", defbuffer, command1.c_str(), 499);
command1 = defbuffer;
spref.get("label2", defbuffer, label2.c_str(), 499);
label2 = defbuffer;
spref.get("command2", defbuffer, command2.c_str(), 499);
command2 = defbuffer;
spref.get("label3", defbuffer, label3.c_str(), 499);
label3 = defbuffer;
spref.get("command3", defbuffer, command3.c_str(), 499);
command3 = defbuffer;
spref.get("label4", defbuffer, label4.c_str(), 499);
label4 = defbuffer;
spref.get("command4", defbuffer, command4.c_str(), 499);
command4 = defbuffer;
spref.get("label5", defbuffer, label5.c_str(), 499);
label5 = defbuffer;
spref.get("command5", defbuffer, command5.c_str(), 499);
command5 = defbuffer;
spref.get("label6", defbuffer, label6.c_str(), 499);
label6 = defbuffer;
spref.get("command6", defbuffer, command6.c_str(), 499);
command6 = defbuffer;
spref.get("label7", defbuffer, label7.c_str(), 499);
label7 = defbuffer;
spref.get("command7", defbuffer, command7.c_str(), 499);
command7 = defbuffer;
spref.get("label8", defbuffer, label8.c_str(), 499);
label8 = defbuffer;
spref.get("command8", defbuffer, command8.c_str(), 499);
command8 = defbuffer;
spref.get("label9", defbuffer, label9.c_str(), 499);
label9 = defbuffer;
spref.get("command9", defbuffer, command9.c_str(), 499);
command9 = defbuffer;
spref.get("label10", defbuffer, label10.c_str(), 499);
label10 = defbuffer;
spref.get("command10", defbuffer, command10.c_str(), 499);
command10 = defbuffer;
spref.get("label11", defbuffer, label11.c_str(), 499);
label11 = defbuffer;
spref.get("command11", defbuffer, command11.c_str(), 499);
command11 = defbuffer;
spref.get("label12", defbuffer, label12.c_str(), 499);
label12 = defbuffer;
spref.get("command12", defbuffer, command12.c_str(), 499);
command12 = defbuffer;
spref.get("label13", defbuffer, label13.c_str(), 499);
label13 = defbuffer;
spref.get("command13", defbuffer, command13.c_str(), 499);
command13 = defbuffer;
spref.get("label14", defbuffer, label14.c_str(), 499);
label14 = defbuffer;
spref.get("command14", defbuffer, command14.c_str(), 499);
command14 = defbuffer;
spref.get("label15", defbuffer, label15.c_str(), 499);
label15 = defbuffer;
spref.get("command15", defbuffer, command15.c_str(), 499);
command15 = defbuffer;
spref.get("label16", defbuffer, label16.c_str(), 499);
label16 = defbuffer;
spref.get("command16", defbuffer, command16.c_str(), 499);
command16 = defbuffer;
spref.get("fg_red", fg_red, fg_red);
spref.get("fg_green", fg_green, fg_green);
spref.get("fg_blue", fg_blue, fg_blue);
spref.get("bg_red", bg_red, bg_red);
spref.get("bg_green", bg_green, bg_green);
spref.get("bg_blue", bg_blue, bg_blue);
spref.get("smeter_red", smeterRed, smeterRed);
spref.get("smeter_green", smeterGreen, smeterGreen);
spref.get("smeter_blue", smeterBlue, smeterBlue);
spref.get("power_red", pwrRed, pwrRed);
spref.get("power_green", pwrGreen, pwrGreen);
spref.get("power_blue", pwrBlue, pwrBlue);
spref.get("swr_red", swrRed, swrRed);
spref.get("swr_green", swrGreen, swrGreen);
spref.get("swr_blue", swrBlue, swrBlue);
spref.get("peak_red", peakRed, peakRed);
spref.get("peak_green", peakGreen, peakGreen);
spref.get("peak_blue", peakBlue, peakBlue);
spref.get("fg_sys_red", fg_sys_red, fg_sys_red);
spref.get("fg_sys_green", fg_sys_green, fg_sys_green);
spref.get("fg_sys_blue", fg_sys_blue, fg_sys_blue);
spref.get("bg_sys_red", bg_sys_red, bg_sys_red);
spref.get("bg_sys_green", bg_sys_green, bg_sys_green);
spref.get("bg_sys_blue", bg_sys_blue, bg_sys_blue);
spref.get("bg2_sys_red", bg2_sys_red, bg2_sys_red);
spref.get("bg2_sys_green", bg2_sys_green, bg2_sys_green);
spref.get("bg2_sys_blue", bg2_sys_blue, bg2_sys_blue);
spref.get("slider_red", slider_red, slider_red);
spref.get("slider_green", slider_green, slider_green);
spref.get("slider_blue", slider_blue, slider_blue);
spref.get("slider_btn_red", slider_btn_red, slider_btn_red);
spref.get("slider_btn_green", slider_btn_green, slider_btn_green);
spref.get("slider_btn_blue", slider_btn_blue, slider_btn_blue);
spref.get("lighted_btn_red", lighted_btn_red, lighted_btn_red);
spref.get("lighted_btn_green", lighted_btn_green, lighted_btn_green);
spref.get("lighted_btn_blue", lighted_btn_blue, lighted_btn_blue);
i = (int)fontnbr;
spref.get("fontnbr", i, i); fontnbr = (Fl_Font)i;
i = 0;
if (spref.get("tooltips", i, i)) tooltips = i;
spref.get("ui_scheme", defbuffer, "gtk+", 499);
ui_scheme = defbuffer;
// spref.get("server_port", defbuffer, "7362", 499);
// server_port = defbuffer;
// spref.get("server_addr", defbuffer, "127.0.0.1", 499);
// server_addr = defbuffer;
spref.get("tcpip_port", defbuffer, "4001", 499);
tcpip_port = defbuffer;
spref.get("tcpip_addr", defbuffer, "127.0.0.1", 499);
tcpip_addr = defbuffer;
spref.get("tcpip_ping_delay", tcpip_ping_delay, tcpip_ping_delay);
spref.get("tcpip_tcpip_reconnect_after", tcpip_reconnect_after, tcpip_reconnect_after);
spref.get("tcpip_drops_allowed", tcpip_drops_allowed, tcpip_drops_allowed);
if (spref.get("use_tcpip", i, i)) use_tcpip = i;
if (spref.get("xcvr_auto_on", i, i)) xcvr_auto_on = i;
if (spref.get("xcvr_auto_off", i, i)) xcvr_auto_off = i;
if (spref.get("external_tuner", i,i)) external_tuner = i;
if (spref.get("trace", i, trace)) trace = i;
if (spref.get("rigtrace", i, rigtrace)) rigtrace = i;
if (spref.get("gettrace", i, gettrace)) gettrace = i;
if (spref.get("settrace", i, settrace)) settrace = i;
if (spref.get("debugtrace", i, debugtrace)) debugtrace = i;
if (spref.get("xmltrace", i, xmltrace)) xmltrace = i;
if (spref.get("startstoptrace", i, start_stop_trace)) start_stop_trace = i;
if (spref.get("rpctrace", i, rpctrace)) rpctrace = i;
spref.get("rpc_level", rpc_level, rpc_level);
spref.get("f160", f160, f160); spref.get("m160", m160, m160);
spref.get("txT160", txT_160, txT_160); spref.get("rxT160", rxT_160, rxT_160);
spref.get("offset_160", offset_160, offset_160); spref.get("oF_160", oF_160, oF_160);
spref.get("f80", f80, f80); spref.get("m80", m80, m80);
spref.get("txT80", txT_80, txT_80); spref.get("rxT80", rxT_80, rxT_80);
spref.get("offset_80", offset_80, offset_80); spref.get("oF_80", oF_80, oF_80);
spref.get("f40", f40, f40); spref.get("m40", m40, m40);
spref.get("txT40", txT_40, txT_40); spref.get("rxT40", rxT_40, rxT_40);
spref.get("offset_40", offset_40, offset_40); spref.get("oF_40", oF_40, oF_40);
spref.get("f30", f30, f30); spref.get("m30", m30, m30);
spref.get("txT30", txT_30, txT_30); spref.get("rxT30", rxT_30, rxT_30);
spref.get("offset_30", offset_30, offset_30); spref.get("oF_30", oF_30, oF_30);
spref.get("f20", f20, f20); spref.get("m20", m20, m20);
spref.get("txT20", txT_20, txT_20); spref.get("rxT20", rxT_20, rxT_20);
spref.get("offset_20", offset_20, offset_20); spref.get("oF_20", oF_20, oF_20);
spref.get("f17", f17, f17); spref.get("m17", m17, m17);
spref.get("txT17", txT_17, txT_17); spref.get("rxT17", rxT_17, rxT_17);
spref.get("offset_17", offset_17, offset_17); spref.get("oF_17", oF_17, oF_17);
spref.get("f15", f15, f15); spref.get("m15", m15, m15);
spref.get("txT15", txT_15, txT_15); spref.get("rxT15", rxT_15, rxT_15);
spref.get("offset_15", offset_15, offset_15); spref.get("oF_15", oF_15, oF_15);
spref.get("f12", f12, f12); spref.get("m12", m12, m12);
spref.get("txT12", txT_12, txT_12); spref.get("rxT12", rxT_12, rxT_12);
spref.get("offset_12", offset_12, offset_12); spref.get("oF_12", oF_12, oF_12);
spref.get("f10", f10, f10); spref.get("m10", m10, m10);
spref.get("txT10", txT_10, txT_10); spref.get("rxT10", rxT_10, rxT_10);
spref.get("offset_10", offset_10, offset_10); spref.get("oF_10", oF_10, oF_10);
spref.get("f6", f6, f6); spref.get("m6", m6, m6);
spref.get("txT6", txT_6, txT_6); spref.get("rxT6", rxT_6, rxT_6);
spref.get("offset_6", offset_6, offset_6); spref.get("oF_6", oF_6, oF_6);
spref.get("f2", f2, f2); spref.get("m2", m2, m2);
spref.get("txT2", txT_2, txT_2); spref.get("rxT2", rxT_2, rxT_2);
spref.get("offset_2", offset_2, offset_2); spref.get("oF_2", oF_2, oF_2);
spref.get("f70", f70, f70); spref.get("m70", m70, m70);
spref.get("txT70", txT_70, txT_70); spref.get("rxT70", rxT_70, rxT_70);
spref.get("offset_70", offset_70, offset_70); spref.get("oF_70", oF_70, oF_70);
if (spref.get("hrd_buttons", i, i)) hrd_buttons = i;
spref.get("sliders_button", sliders_button, sliders_button);
return true;
}
return false;
}
void status::loadLastState()
{
Fl_Preferences xcvrpref(RigHomeDir.c_str(), "w1hkj.com", PACKAGE_TARNAME);
if (xcvrpref.entryExists("xcvr_name")) {
char defbuffer[200];
xcvrpref.get("xcvr_name", defbuffer, "NONE", 499);
xcvr_name = defbuffer;
// for backward compatability
} else if (xcvrpref.entryExists("last_xcvr_used")) {
char defbuffer[200];
xcvrpref.get("last_xcvr_used", defbuffer, "NONE", 499);
xcvr_name = defbuffer;
}
xcvrpref.get("xml_port", xmlport, xmlport);
loadXcvrState(xcvr_name);
}
void status::UI_laststate()
{
Fl_Color bgclr = fl_rgb_color(bg_red, bg_green, bg_blue);
Fl_Color fgclr = fl_rgb_color(fg_red, fg_green, fg_blue);
Fl::background( bg_sys_red, bg_sys_green, bg_sys_blue);
Fl::background2( bg2_sys_red, bg2_sys_green, bg2_sys_blue);
Fl::foreground( fg_sys_red, fg_sys_green, fg_sys_blue);
FreqDispA->SetONOFFCOLOR( fgclr, bgclr );
FreqDispA->font(fontnbr);
FreqDispB->SetONOFFCOLOR( fgclr, fl_color_average(bgclr, FL_BLACK, 0.87));
FreqDispB->font(fontnbr);
scaleSmeter->color(bgclr);
scaleSmeter->labelcolor(fgclr);
scalePower->color(bgclr);
scalePower->labelcolor(fgclr);
btnALC_SWR->color(bgclr);
btnALC_SWR->labelcolor(fgclr);
sldrFwdPwr->color(fl_rgb_color (pwrRed, pwrGreen, pwrBlue), bgclr);
sldrFwdPwr->PeakColor(fl_rgb_color(peakRed, peakGreen, peakBlue));
sldrRcvSignal->color(fl_rgb_color (smeterRed, smeterGreen, smeterBlue), bgclr);
sldrRcvSignal->PeakColor(fl_rgb_color(peakRed, peakGreen, peakBlue));
sldrALC->color(fl_rgb_color (swrRed, swrGreen, swrBlue), bgclr);
sldrALC->PeakColor(fl_rgb_color(peakRed, peakGreen, peakBlue));
sldrSWR->color(fl_rgb_color (swrRed, swrGreen, swrBlue), bgclr);
sldrSWR->PeakColor(fl_rgb_color(peakRed, peakGreen, peakBlue));
if (UIsize != small_ui)
meter_fill_box->color(bgclr);
grpMeters->color(bgclr);
grpMeters->labelcolor(fgclr);
Fl_Color btn_lt_color = fl_rgb_color(lighted_btn_red, lighted_btn_green, lighted_btn_blue);
if (btnVol) btnVol->selection_color(btn_lt_color);
if (btnNR) btnNR->selection_color(btn_lt_color);
if (btnIFsh) btnIFsh->selection_color(btn_lt_color);
if (btnNotch) btnNotch->selection_color(btn_lt_color);
if (btnA) btnA->selection_color(btn_lt_color);
if (btnB) btnB->selection_color(btn_lt_color);
if (btnSplit) btnSplit->selection_color(btn_lt_color);
if (btnAttenuator) btnAttenuator->selection_color(btn_lt_color);
if (btnPreamp) btnPreamp->selection_color(btn_lt_color);
if (btnNOISE) btnNOISE->selection_color(btn_lt_color);
if (btnAutoNotch) btnAutoNotch->selection_color(btn_lt_color);
if (btnTune) btnTune->selection_color(btn_lt_color);
if (btnPTT) btnPTT->selection_color(btn_lt_color);
if (btnLOCK) btnLOCK->selection_color(btn_lt_color);
if (btnAuxRTS) btnAuxRTS->selection_color(btn_lt_color);
if (btnAuxDTR) btnAuxDTR->selection_color(btn_lt_color);
if (btnSpot) btnSpot->selection_color(btn_lt_color);
if (btn_vox) btn_vox->selection_color(btn_lt_color);
if (btnCompON) btnCompON->selection_color(btn_lt_color);
if (btnSpecial) btnSpecial->selection_color(btn_lt_color);
if (btn_tt550_vox) btn_tt550_vox->selection_color(btn_lt_color);
if (btn_tt550_CompON) btn_tt550_CompON->selection_color(btn_lt_color);
if (btnAGC) btnAGC->selection_color(btn_lt_color);
Fl_Color bg_slider = fl_rgb_color(slider_red, slider_green, slider_blue);
Fl_Color btn_slider = fl_rgb_color(slider_btn_red, slider_btn_green, slider_btn_blue);
if (sldrVOLUME) sldrVOLUME->color(bg_slider);
if (sldrVOLUME) sldrVOLUME->selection_color(btn_slider);
if (sldrRFGAIN) sldrRFGAIN->color(bg_slider);
if (sldrRFGAIN) sldrRFGAIN->selection_color(btn_slider);
if (sldrSQUELCH) sldrSQUELCH->color(bg_slider);
if (sldrSQUELCH) sldrSQUELCH->selection_color(btn_slider);
if (sldrNR) sldrNR->color(bg_slider);
if (sldrNR) sldrNR->selection_color(btn_slider);
if (sldrIFSHIFT) sldrIFSHIFT->color(bg_slider);
if (sldrIFSHIFT) sldrIFSHIFT->selection_color(btn_slider);
if (sldrINNER) sldrINNER->color(bg_slider);
if (sldrINNER) sldrINNER->selection_color(btn_slider);
if (sldrOUTER) sldrOUTER->color(bg_slider);
if (sldrOUTER) sldrOUTER->selection_color(btn_slider);
if (sldrNOTCH) sldrNOTCH->color(bg_slider);
if (sldrNOTCH) sldrNOTCH->selection_color(btn_slider);
if (sldrMICGAIN) sldrMICGAIN->color(bg_slider);
if (sldrMICGAIN) sldrMICGAIN->selection_color(btn_slider);
if (sldrPOWER) sldrPOWER->color(bg_slider);
if (sldrPOWER) sldrPOWER->selection_color(btn_slider);
if (ic7610_digi_sel_val) {
ic7610_digi_sel_val->color(bg_slider);
ic7610_digi_sel_val->selection_color(btn_slider);
}
if (sldr_nb_level) {
sldr_nb_level->color(bg_slider);
sldr_nb_level->selection_color(btn_slider);
}
if (spnrPOWER) spnrPOWER->color(bg_slider);
if (spnrPOWER) spnrPOWER->selection_color(btn_slider);
if (spnrVOLUME) spnrVOLUME->color(bg_slider);
if (spnrVOLUME) spnrVOLUME->selection_color(btn_slider);
if (spnrRFGAIN) spnrRFGAIN->color(bg_slider);
if (spnrRFGAIN) spnrRFGAIN->selection_color(btn_slider);
if (spnrSQUELCH) spnrSQUELCH->color(bg_slider);
if (spnrSQUELCH) spnrSQUELCH->selection_color(btn_slider);
if (spnrNR) spnrNR->color(bg_slider);
if (spnrNR) spnrNR->selection_color(btn_slider);
if (spnrIFSHIFT) spnrIFSHIFT->color(bg_slider);
if (spnrIFSHIFT) spnrIFSHIFT->selection_color(btn_slider);
if (spnrNOTCH) spnrNOTCH->color(bg_slider);
if (spnrNOTCH) spnrNOTCH->selection_color(btn_slider);
if (spnrMICGAIN) spnrMICGAIN->color(bg_slider);
if (spnrMICGAIN) spnrMICGAIN->selection_color(btn_slider);
btnUser1->label(label1.c_str()); btnUser1->redraw_label();
btnUser2->label(label2.c_str()); btnUser2->redraw_label();
btnUser3->label(label3.c_str()); btnUser3->redraw_label();
btnUser4->label(label4.c_str()); btnUser4->redraw_label();
btnUser5->label(label5.c_str()); btnUser5->redraw_label();
btnUser6->label(label6.c_str()); btnUser6->redraw_label();
btnUser7->label(label7.c_str()); btnUser7->redraw_label();
btnUser8->label(label8.c_str()); btnUser8->redraw_label();
btnUser9->label(label9.c_str()); btnUser9->redraw_label();
btnUser10->label(label10.c_str()); btnUser10->redraw_label();
btnUser11->label(label11.c_str()); btnUser11->redraw_label();
btnUser12->label(label12.c_str()); btnUser12->redraw_label();
btnUser13->label(label13.c_str()); btnUser13->redraw_label();
btnUser14->label(label14.c_str()); btnUser14->redraw_label();
btnUser15->label(label15.c_str()); btnUser15->redraw_label();
btnUser16->label(label16.c_str()); btnUser16->redraw_label();
Fl::scheme(ui_scheme.c_str());
}
string status::info()
{
stringstream info;
info << "status::info()\n============== Prefs File Contents =============\n\n";
info << "xcvr_serial_port : " << xcvr_serial_port << "\n";
info << "comm_baudrate : " << comm_baudrate << "\n";
info << "comm_stopbits : " << stopbits << "\n";
info << "comm_retries : " << comm_retries << "\n";
info << "comm_wait : " << comm_wait << "\n";
info << "comm_timeout : " << comm_timeout << "\n";
info << "serloop_timing : " << serloop_timing << "\n";
info << "byte_interval : " << byte_interval << "\n";
info << "\n";
info << "comm_echo : " << comm_echo << "\n";
info << "ptt_via_cat : " << comm_catptt << "\n";
info << "ptt_via_rts : " << comm_rtsptt << "\n";
info << "ptt_via_dtr : " << comm_dtrptt << "\n";
info << "rts_cts_flow : " << comm_rtscts << "\n";
info << "rts_plus : " << comm_rtsplus << "\n";
info << "dtr_plus : " << comm_dtrplus << "\n";
info << "civadr : " << CIV << "\n";
info << "usbaudio : " << USBaudio << "\n";
info << "\n";
info << "aux_serial_port : " << aux_serial_port.c_str() << "\n";
info << "aux_rts : " << aux_rts << "\n";
info << "aux_dtr : " << aux_dtr << "\n";
info << "\n";
info << "sep_serial_port : " << sep_serial_port.c_str() << "\n";
info << "sep_rtsptt : " << sep_rtsptt << "\n";
info << "sep_dtrptt : " << sep_dtrptt << "\n";
info << "sep_rtsplus : " << sep_rtsplus << "\n";
info << "set_dtrplus : " << sep_dtrplus << "\n";
info << "\n";
info << "poll_smeter : " << poll_smeter << "\n";
info << "poll_frequency : " << poll_frequency << "\n";
info << "poll_mode : " << poll_mode << "\n";
info << "poll_bandwidth : " << poll_bandwidth << "\n";
info << "poll_volume : " << poll_volume << "\n";
info << "poll_auto_notch : " << poll_auto_notch << "\n";
info << "poll_notch : " << poll_notch << "\n";
info << "poll_ifshift : " << poll_ifshift << "\n";
info << "poll_power_control : " << poll_power_control << "\n";
info << "poll_pre_att : " << poll_pre_att << "\n";
info << "poll_micgain : " << poll_micgain << "\n";
info << "poll_squelch : " << poll_squelch << "\n";
info << "poll_rfgain : " << poll_rfgain << "\n";
info << "poll_pout : " << poll_pout << "\n";
info << "poll_swr : " << poll_swr << "\n";
info << "poll_alc : " << poll_alc << "\n";
info << "poll_split : " << poll_split << "\n";
info << "poll_noise : " << poll_noise << "\n";
info << "poll_nr : " << poll_nr << "\n";
info << "poll_all : " << poll_all << "\n";
info << "\n";
info << "freq_A : " << freq_A << "\n";
info << "mode_A : " << imode_A << "\n";
info << "bw_A : " << iBW_A << "\n";
info << "\n";
info << "freq_B : " << freq_B << "\n";
info << "mode_B : " << imode_B << "\n";
info << "bw_B : " << iBW_B << "\n";
info << "\n";
info << "filters : " << filters << "\n";
info << "\n";
info << "use_rig_data : " << use_rig_data << "\n";
// info << "restore_rig_data : " << restore_rig_data << "\n";
info << "\n";
info << "bool_spkr_on : " << spkr_on << "\n";
info << "int_volume : " << volume << "\n";
info << "dbl_power : " << power_level << "\n";
info << "int_mic : " << mic_gain << "\n";
info << "bool_notch : " << notch << "\n";
info << "int_notch : " << notch_val << "\n";
info << "bool_shift : " << shift << "\n";
info << "int_shift : " << shift_val << "\n";
info << "rfgain : " << rfgain << "\n";
info << "squelch : " << squelch << "\n";
info << "\n";
info << "schema : " << schema << "\n";
info << "\n";
info << "rx_avg : " << rx_avg << "\n";
info << "rx_peak : " << rx_peak << "\n";
info << "pwr_avg : " << pwr_avg << "\n";
info << "pwr_peak : " << pwr_peak << "\n";
info << "pwr_scale : " << pwr_scale << "\n";
info << "\n";
info << "line_out : " << line_out << "\n";
info << "data_port : " << data_port << "\n";
info << "vox_on_dataport : " << vox_on_dataport << "\n";
info << "agc_level : " << agc_level << "\n";
info << "cw_wpm : " << cw_wpm << "\n";
info << "cw_weight : " << cw_weight << "\n";
info << "cw_vol : " << cw_vol << "\n";
info << "cw_spot : " << cw_spot << "\n";
info << "spot_onoff : " << spot_onoff << "\n";
info << "cw_spot_tone : " << cw_spot_tone << "\n";
info << "cw_qsk : " << cw_qsk << "\n";
info << "(cw_delay : " << cw_delay << "\n";
info << "enable_keyer : " << enable_keyer << "\n";
info << "break_in : " << break_in << "\n";
info << "vox_onoff : " << vox_onoff << "\n";
info << "vox_gain : " << vox_gain << "\n";
info << "vox_anti : " << vox_anti << "\n";
info << "vox_hang : " << vox_hang << "\n";
info << "compression : " << compression << "\n";
info << "compON : " << compON << "\n";
info << "\n";
info << "label 1 : " << label1 << "\n";
info << "command 1 : " << command1 << "\n";
info << "label 2 : " << label1 << "\n";
info << "command 2 : " << command1 << "\n";
info << "label 3 : " << label1 << "\n";
info << "command 3 : " << command1 << "\n";
info << "label 4 : " << label1 << "\n";
info << "command 4 : " << command1 << "\n";
info << "label 5 : " << label1 << "\n";
info << "command 5 : " << command1 << "\n";
info << "label 6 : " << label1 << "\n";
info << "command 6 : " << command1 << "\n";
info << "label 7 : " << label1 << "\n";
info << "command 7 : " << command1 << "\n";
info << "label 8 : " << label1 << "\n";
info << "command 8 : " << command1 << "\n";
info << "label 9 : " << label9 << "\n";
info << "command 9 : " << command9 << "\n";
info << "label 10 : " << label10 << "\n";
info << "command 10 : " << command10 << "\n";
info << "label 11 : " << label11 << "\n";
info << "command 11 : " << command11 << "\n";
info << "label 12 : " << label12 << "\n";
info << "command 12 : " << command12 << "\n";
info << "label 13 : " << label13 << "\n";
info << "command 13 : " << command13 << "\n";
info << "label 14 : " << label14 << "\n";
info << "command 14 : " << command14 << "\n";
info << "label 15 : " << label15 << "\n";
info << "command 15 : " << command15 << "\n";
info << "label 16 : " << label16 << "\n";
info << "command 16 : " << command16 << "\n";
return info.str();
}
static bool strace;
static bool srigtrace;
static bool ssettrace;
static bool sgettrace;
void ss_trace(bool on) {
if (on) {
strace = progStatus.trace;
srigtrace = progStatus.rigtrace;
ssettrace = progStatus.settrace;
sgettrace = progStatus.gettrace;
progStatus.trace =
progStatus.rigtrace =
progStatus.settrace =
progStatus.gettrace = true;
} else {
progStatus.trace = strace;
progStatus.rigtrace = srigtrace;
progStatus.settrace = ssettrace;
progStatus.gettrace = sgettrace;
}
}
flrig-1.3.49/src/support/socket.cxx 0000644 0001750 0001750 00000044600 13605621006 014156 0000000 0000000 // ----------------------------------------------------------------------------
// socket.cxx
//
// Copyright (C) 2008-2009
// Stelios Bounanos, M0GLD
// ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#ifndef __MINGW32__
# include
# include
# include
# include
# include
# include
#else
# include "compat.h"
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "debug.h"
#include "socket.h"
#if HAVE_GETADDRINFO && !defined(AI_NUMERICSERV)
# define AI_NUMERICSERV 0
#endif
using namespace std;
//
// utility functions
//
#if HAVE_GETADDRINFO
static void copy_addrinfo(struct addrinfo** info, const struct addrinfo* src)
{
struct addrinfo* p = *info;
for (const struct addrinfo* rp = src; rp; rp = rp->ai_next) {
if (p) {
p->ai_next = new struct addrinfo;
p = p->ai_next;
}
else {
p = new struct addrinfo;
if (!*info)
*info = p;
}
p->ai_flags = rp->ai_flags;
p->ai_family = rp->ai_family;
p->ai_socktype = rp->ai_socktype;
p->ai_protocol = rp->ai_protocol;
p->ai_addrlen = rp->ai_addrlen;
if (rp->ai_addr) {
p->ai_addr = reinterpret_cast(new struct sockaddr_storage);
memcpy(p->ai_addr, rp->ai_addr, rp->ai_addrlen);
}
else
p->ai_addr = NULL;
if (rp->ai_canonname)
p->ai_canonname = strdup(rp->ai_canonname);
else
p->ai_canonname = NULL;
p->ai_next = NULL;
}
}
static void free_addrinfo(struct addrinfo* ai)
{
for (struct addrinfo *next, *p = ai; p; p = next) {
next = p->ai_next;
delete reinterpret_cast(p->ai_addr);
free(p->ai_canonname);
delete p;
}
}
#else
static void copy_charpp(char*** dst, const char* const* src)
{
if (src == NULL) {
*dst = NULL;
return;
}
size_t n = 0;
for (const char* const* s = src; *s; s++)
n++;
*dst = new char*[n+1];
for (size_t i = 0; i < n; i++)
(*dst)[i] = strdup(src[i]);
(*dst)[n] = NULL;
}
static void copy_hostent(struct hostent* dst, const struct hostent* src)
{
if (src->h_name)
dst->h_name = strdup(src->h_name);
else
dst->h_name = NULL;
copy_charpp(&dst->h_aliases, src->h_aliases);
dst->h_length = src->h_length;
if (src->h_addr_list) {
size_t n = 0;
for (const char* const* p = src->h_addr_list; *p; p++)
n++;
dst->h_addr_list = new char*[n+1];
for (size_t i = 0; i < n; i++) {
dst->h_addr_list[i] = new char[src->h_length];
memcpy(dst->h_addr_list[i], src->h_addr_list[i], src->h_length);
}
dst->h_addr_list[n] = NULL;
}
else
dst->h_addr_list = NULL;
}
static void copy_servent(struct servent* dst, const struct servent* src)
{
if (src->s_name)
dst->s_name = strdup(src->s_name);
else
dst->s_name = NULL;
copy_charpp(&dst->s_aliases, src->s_aliases);
dst->s_port = src->s_port;
if (src->s_proto)
dst->s_proto = strdup(src->s_proto);
else
dst->s_proto = NULL;
}
static void free_charpp(char** pp)
{
if (!pp)
return;
for (char** p = pp; *p; p++)
free(*p);
delete [] pp;
}
static void free_hostent(struct hostent* hp)
{
free(const_cast(hp->h_name));
free_charpp(hp->h_aliases);
if (hp->h_addr_list) {
for (char** p = hp->h_addr_list; *p; p++)
delete [] *p;
delete [] hp->h_addr_list;
}
}
static void free_servent(struct servent* sp)
{
free(const_cast(sp->s_name));
free_charpp(sp->s_aliases);
free(sp->s_proto);
}
#endif // HAVE_GETADDRINFO
//
// Address class
//
Address::Address(const char* host, int port, const char* proto_name)
: node(host), copied(false)
{
#if HAVE_GETADDRINFO
info = NULL;
#else
memset(&host_entry, 0, sizeof(host_entry));
memset(&service_entry, 0, sizeof(service_entry));
#endif
if (node.empty() && port == 0)
return;
ostringstream s;
s << port;
service = s.str();
lookup(proto_name);
}
Address::Address(const char* host, const char* port_name, const char* proto_name)
: node(host), service(port_name), copied(false)
{
#if HAVE_GETADDRINFO
info = NULL;
#else
memset(&host_entry, 0, sizeof(host_entry));
memset(&service_entry, 0, sizeof(service_entry));
#endif
lookup(proto_name);
}
Address::Address(const Address& addr)
{
#if HAVE_GETADDRINFO
info = NULL;
#else
memset(&host_entry, 0, sizeof(host_entry));
memset(&service_entry, 0, sizeof(service_entry));
#endif
*this = addr;
}
Address::~Address()
{
#if HAVE_GETADDRINFO
if (info) {
if (!copied)
freeaddrinfo(info);
else
free_addrinfo(info);
}
#else
free_hostent(&host_entry);
free_servent(&service_entry);
#endif
}
Address& Address::operator=(const Address& rhs)
{
if (this == &rhs)
return *this;
node = rhs.node;
service = rhs.service;
#if HAVE_GETADDRINFO
if (info) {
if (!copied)
freeaddrinfo(info);
else
free_addrinfo(info);
}
copy_addrinfo(&info, rhs.info);
#else
free_hostent(&host_entry);
free_servent(&service_entry);
copy_hostent(&host_entry, &rhs.host_entry);
copy_servent(&service_entry, &rhs.service_entry);
addr.ai_protocol = rhs.addr.ai_protocol;
addr.ai_socktype = rhs.addr.ai_socktype;
#endif
copied = true;
return *this;
}
void Address::lookup(const char* proto_name)
{
int proto;
if (!strcasecmp(proto_name, "tcp"))
proto = IPPROTO_TCP;
else if (!strcasecmp(proto_name, "udp"))
proto = IPPROTO_UDP;
else {
throw SocketException("Bad protocol name");
}
#if HAVE_GETADDRINFO
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
# ifdef AI_ADDRCONFIG
hints.ai_flags = AI_ADDRCONFIG;
# endif
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = (proto == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM);
if (service.find_first_not_of("0123456789") == string::npos)
hints.ai_flags |= AI_NUMERICSERV;
int r;
if ((r = getaddrinfo(node.empty() ? NULL : node.c_str(), service.c_str(), &hints, &info)) < 0) {
string errstr = "getaddrinfo: ";
errstr.append(node).append(" : ").append(service);
throw SocketException(r, errstr.c_str());
}
#else // use gethostbyname etc.
memset(&host_entry, 0, sizeof(host_entry));
memset(&service_entry, 0, sizeof(service_entry));
if (node.empty())
node = "0.0.0.0";
struct hostent* hp;
if ((hp = gethostbyname(node.c_str())) == NULL) {
#ifdef __WIN32__
string errstr = "gethostbyname: ";
errstr.append(node).append(" not found");
throw SocketException(0, errstr.c_str());
#else
throw SocketException(hstrerror(HOST_NOT_FOUND));
#endif
}
copy_hostent(&host_entry, hp);
int port;
struct servent* sp;
if ((sp = getservbyname(service.c_str(), NULL)) == NULL) {
// if a service name string could not be looked up by name, it must be numeric
if (service.find_first_not_of("0123456789") != string::npos) {
throw SocketException("Unknown service name");
}
port = htons(atoi(service.c_str()));
sp = getservbyport(port, NULL);
}
if (!sp)
service_entry.s_port = port;
else
copy_servent(&service_entry, sp);
memset(&addr, 0, sizeof(addr));
addr.ai_protocol = proto;
addr.ai_socktype = (proto == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM);
#endif
}
///
/// Returns the number of addresses available for
/// the node and service
///
size_t Address::size(void) const
{
size_t n = 0;
#if HAVE_GETADDRINFO
if (!info)
return 0;
for (struct addrinfo* p = info; p; p = p->ai_next)
n++;
#else
if (!host_entry.h_addr_list)
return 0;
for (char** p = host_entry.h_addr_list; *p; p++)
n++;
#endif
return n;
}
///
/// Returns an address from the list of those available
/// for the node and service
///
const addr_info_t* Address::get(size_t n) const
{
#if HAVE_GETADDRINFO
if (!info)
return NULL;
struct addrinfo* p = info;
for (size_t i = 0; i < n; i++)
p = p->ai_next;
LOG_DEBUG("Found address %s", get_str(p).c_str());
return p;
#else
if (!host_entry.h_addr_list)
return NULL;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr = *(struct in_addr*)host_entry.h_addr_list[n];
saddr.sin_port = service_entry.s_port;
addr.ai_family = saddr.sin_family;
addr.ai_addrlen = sizeof(saddr);
addr.ai_addr = (struct sockaddr*)&saddr;
LOG_DEBUG("Found address %s", get_str(&addr).c_str());
return &addr;
#endif
}
///
/// Returns the string representation of an address
///
string Address::get_str(const addr_info_t* addr)
{
if (!addr)
return "";
#if HAVE_GETADDRINFO
char host[NI_MAXHOST], port[NI_MAXSERV];
memset(host, 0, sizeof(host));
if (getnameinfo(addr->ai_addr, sizeof(struct sockaddr_storage),
host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV) == 0)
return string("[").append(host).append("]:").append(port);
else
return "";
#else
char* host, port[8];
host = inet_ntoa(((struct sockaddr_in*)addr->ai_addr)->sin_addr);
snprintf(port, sizeof(port), "%u", htons(((struct sockaddr_in*)addr->ai_addr)->sin_port));
return string("[").append(host).append("]:").append(port);
#endif
}
//
// Socket class
//
/// Constructs a Socket object and associates the address addr with it.
/// This address will be used by subsequent calls to the bind() or connect()
/// methods
///
/// @param addr An Address object
///
Socket::Socket(const Address& addr)
{
buffer = new char[BUFSIZ];
memset(&timeout, 0, sizeof(timeout));
anum = 0;
autoclose = true;
open(addr);
set_nonblocking(false);
}
/// Constructs a Socket object from a file descriptor
///
/// @param fd A file descriptor
///
Socket::Socket(int fd)
: sockfd(fd)
{
buffer = new char[BUFSIZ];
anum = 0;
memset(&timeout, 0, sizeof(timeout));
if (sockfd == -1)
return;
#ifndef __MINGW32__
int r = fcntl(sockfd, F_GETFL);
if (r == -1)
throw SocketException(errno, "fcntl");
nonblocking = r & O_NONBLOCK;
#else
set_nonblocking(false);
#endif
autoclose = true;
}
///
/// Constructs a Socket object by copying another instance
///
Socket::Socket(const Socket& s)
: sockfd(s.sockfd), address(s.address), anum(s.anum),
nonblocking(s.nonblocking), autoclose(true)
{
buffer = new char[BUFSIZ];
ainfo = address.get(anum);
memcpy(&timeout, &s.timeout, sizeof(timeout));
s.set_autoclose(false);
}
Socket::~Socket()
{
delete [] buffer;
if (autoclose)
close();
}
Socket& Socket::operator=(const Socket& rhs)
{
if (this == &rhs)
return *this;
sockfd = rhs.sockfd;
address = rhs.address;
anum = rhs.anum;
ainfo = address.get(anum);
memcpy(&timeout, &rhs.timeout, sizeof(timeout));
nonblocking = rhs.nonblocking;
autoclose = rhs.autoclose;
rhs.set_autoclose(false);
return *this;
}
///
/// Associates the Socket with an address
///
/// This address will be used by subsequent calls to the bind() or connect
/// methods.
///
/// @params addr An address object
///
void Socket::open(const Address& addr)
{
address = addr;
size_t n = address.size();
for (anum = 0; anum < n; anum++) {
ainfo = address.get(anum);
LOG_DEBUG("Trying %s", address.get_str(ainfo).c_str());
if ((sockfd = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol)) != -1)
break;
}
if (sockfd == -1)
throw SocketException(errno, "socket");
set_close_on_exec(true);
}
///
/// Shuts down the socket
///
void Socket::close(void)
{
::close(sockfd);
sockfd = -1;
}
///
/// Waits for the socket file descriptor to become ready for I/O
///
/// @params dir Specifies the I/O direction. 0 is input, 1 is output.
///
/// @return True if the file descriptor became ready within the timeout
/// period, false otherwise. @see Socket::set_timeout
bool Socket::wait(int dir)
{
fd_set fdset;
FD_ZERO(&fdset);
FD_SET((unsigned)sockfd, &fdset);
struct timeval t = { timeout.tv_sec, timeout.tv_usec };
int r;
if (dir == 0)
r = select(sockfd + 1, &fdset, NULL, NULL, &t);
else if (dir == 1)
r = select(sockfd + 1, NULL, &fdset, NULL, &t);
else
throw SocketException(EINVAL, "Socket::wait");
if (r == -1)
throw SocketException(errno, "select");
return r;
}
///
/// Binds the socket to the address associated with the object
/// @see Socket::open
///
void Socket::bind(void)
{
int r = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&r, sizeof(r)) == -1)
perror("setsockopt SO_REUSEADDR");
if (::bind(sockfd, ainfo->ai_addr, ainfo->ai_addrlen) == -1)
throw SocketException(errno, "bind");
}
///
/// Calls listen(2) on the socket file desriptor
///
/// The socket must already have been bound to an address via a call to the bind
/// method.
///
/// @params backlog The maximum number of pending connections (default SOMAXCONN)
///
void Socket::listen(int backlog)
{
if (::listen(sockfd, backlog) == -1)
throw SocketException(errno, "listen");
}
///
/// Accepts a connection
///
/// The socket must already have been bound to an address via a call to the bind
/// method.
///
/// @return A Socket instance for the accepted connection
///
Socket Socket::accept(void)
{
listen();
// wait for fd to become readable
if (nonblocking && (timeout.tv_sec > 0 || timeout.tv_usec > 0))
if (!wait(0))
throw SocketException(ETIMEDOUT, "select");
int r;
if ((r = ::accept(sockfd, NULL, 0)) == -1)
throw SocketException(errno, "accept");
set_close_on_exec(true, r);
return Socket(r);
}
///
/// Accepts a single connection and then closes the listening socket
/// @see Socket::accept
///
/// @return A Socket instance for the accepted connection
///
Socket Socket::accept1(void)
{
bind();
Socket s = accept();
close();
s.set_close_on_exec(true);
return s;
}
///
/// Connects the socket to the address that is associated with the object
///
void Socket::connect(void)
{
LOG_DEBUG("Connecting to %s", address.get_str(ainfo).c_str());
if (::connect(sockfd, ainfo->ai_addr, ainfo->ai_addrlen) == -1)
throw SocketException(errno, "connect");
}
///
/// Connects the socket to an address
///
/// @param addr The address to connect to
///
void Socket::connect(const Address& addr)
{
close();
open(addr);
connect();
}
///
/// Sends a buffer
///
/// @param buf
/// @param len
///
/// @return The amount of data that was sent. This may be less than len
/// if the socket is non-blocking.
///
size_t Socket::send(const void* buf, size_t len)
{
// if we have a nonblocking socket and a nonzero timeout,
// wait for fd to become writeable
if (nonblocking && (timeout.tv_sec > 0 || timeout.tv_usec > 0))
if (!wait(1))
return 0;
ssize_t r = ::send(sockfd, (const char*)buf, len, 0);
if (r == 0)
shutdown(sockfd, SHUT_WR);
else if (r == -1) {
if (errno != EAGAIN)
throw SocketException(errno, "send");
r = 0;
}
return r;
}
///
/// Sends a string
///
/// @param buf
///
/// @return The amount of data that was sent. This may be less than len
/// if the socket is non-blocking.
///
size_t Socket::send(const string& buf)
{
return send(buf.data(), buf.length());
}
///
/// Receives data into a buffer
///
/// @arg buf
/// @arg len The maximum number of bytes to write to buf.
///
/// @return The amount of data that was received. This may be less than len
/// if the socket is non-blocking.
size_t Socket::recv(void* buf, size_t len)
{
// if we have a nonblocking socket and a nonzero timeout,
// wait for fd to become writeable
if (nonblocking && (timeout.tv_sec > 0 || timeout.tv_usec > 0))
if (!wait(0)) {
return 0;
}
ssize_t r = ::recv(sockfd, (char*)buf, len, 0);
if (r == 0) {
shutdown(sockfd, SHUT_RD);
} else if (r == -1) {
if (errno != EAGAIN)
throw SocketException(errno, "recv");
r = 0;
}
return r;
}
///
/// Receives all available data and appends it to a string.
///
/// @arg buf
///
/// @return The amount of data that was received.
///
size_t Socket::recv(string& buf)
{
size_t n = 0;
ssize_t r;
while ((r = recv(buffer, BUFSIZ)) > 0) {
buf.reserve(buf.length() + r);
buf.append(buffer, r);
n += r;
}
return n;
}
///
/// Retrieves the socket's receive or send buffer size
///
/// @param dir Specifies the I/O direction. 0 is input, 1 is output.
///
int Socket::get_bufsize(int dir)
{
int len;
if (::get_bufsize(sockfd, dir, &len) == -1)
throw SocketException(errno, "get_bufsize");
return len;
}
///
/// Sets the socket's receive or send buffer size
///
/// @param dir Specifies the I/O direction. 0 is input, 1 is output.
/// @param len Specifies the new buffer size
///
void Socket::set_bufsize(int dir, int len)
{
if (::set_bufsize(sockfd, dir, len) == -1)
throw SocketException(errno, "set_bufsize");
}
///
/// Sets the socket's blocking mode
///
/// @param v If true, the socket is set to non-blocking
///
void Socket::set_nonblocking(bool v)
{
if (set_nonblock(sockfd, v) == -1)
throw SocketException(errno, "set_nonblock");
nonblocking = v;
}
///
/// Enables the use of Nagle's algorithm for the socket
///
/// @param v If true, Nagle's algorithm is disabled.
///
void Socket::set_nodelay(bool v)
{
if (::set_nodelay(sockfd, v) == -1)
throw SocketException(errno, "set_nodelay");
}
///
/// Sets the timeout associated with non-blocking operations
///
/// @param t
///
void Socket::set_timeout(const struct timeval& t)
{
timeout.tv_sec = t.tv_sec;
timeout.tv_usec = t.tv_usec;
}
void Socket::set_timeout(double t)
{
timeout.tv_sec = (time_t)floor(t);
timeout.tv_usec = (suseconds_t)((t - timeout.tv_sec) * 1e6);
}
///
/// Sets the socket's autoclose mode.
///
/// If autoclose is disabled, the socket file descriptor will not be closed when
/// the Socket object is destructed.
///
/// @param v If true, the socket will be closed by the destructor
///
void Socket::set_autoclose(bool v) const
{
autoclose = v;
}
///
/// Sets the socket's close-on-exec flag
///
void Socket::set_close_on_exec(bool v, int fd)
{
if (fd == -1)
fd = sockfd;
if (set_cloexec(fd, v) == -1)
throw SocketException(errno, "set_cloexec");
}
///
/// Returns the Socket's file descriptor.
///
/// The descriptor should only be used for reading and writing.
///
/// @return the socket file descriptor
///
int Socket::fd(void)
{
return sockfd;
}
flrig-1.3.49/src/support/tod_clock.cxx 0000644 0001750 0001750 00000003421 13605621006 014623 0000000 0000000 // =====================================================================
//
// TOD_clock.cxx
//
// Copyright (C) 2017
// Dave Freese, W1HKJ
//
// This file is part of flrig
//
// Fldigi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with fldigi. If not, see .
// =====================================================================
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "util.h"
#include "debug.h"
//#include "status.h"
#include "icons.h"
#include "tod_clock.h"
#include "timeops.h"
using namespace std;
static int _zmsec = 0;
static int _zsec = 0;
static int _zmin = 0;
static int _zhr = 0;
void ztimer()
{
struct tm tm;
time_t t_temp;
struct timeval tv;
gettimeofday(&tv, NULL);
t_temp=(time_t)tv.tv_sec;
gmtime_r(&t_temp, &tm);
_zmsec = (tv.tv_usec/1000) % 1000;
_zsec = tm.tm_sec;
_zmin = tm.tm_min;
_zhr = tm.tm_hour;
}
int zmsec(void)
{
ztimer();
return _zmsec;
}
char exttime[13];
char *ztime()
{
ztimer();
snprintf(exttime, sizeof(exttime),
"%02d:%02d:%02d.%03d",
_zhr, _zmin, _zsec, _zmsec);
return exttime;
}
flrig-1.3.49/src/support/threads.cxx 0000644 0001750 0001750 00000006176 13605621006 014326 0000000 0000000 // ----------------------------------------------------------------------------
// threads.cxx
//
// Copyright (C) 2014
// Stelios Bounanos, M0GLD
// David Freese, W1HKJ
//
// This file is part of fldigi.
//
// fldigi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include "threads.h"
#include "support.h"
/// This ensures that a mutex is always unlocked when leaving a function or block.
extern pthread_mutex_t mutex_replystr;
extern pthread_mutex_t command_mutex;
extern pthread_mutex_t mutex_vfoque;
extern pthread_mutex_t mutex_serial;
extern pthread_mutex_t debug_mutex;
extern pthread_mutex_t mutex_rcv_socket;
extern pthread_mutex_t mutex_ptt;
extern pthread_mutex_t mutex_srvc_reqs;
extern pthread_mutex_t mutex_trace;
// Change to 1 to observe guard lock/unlock processing on stdout
//#define DEBUG_GUARD_LOCK 0
//guard_lock::guard_lock(pthread_mutex_t* m, int h) : mutex(m), how(h) {
//char szlock[100];
// pthread_mutex_lock(mutex);
// snprintf(szlock, sizeof(szlock), "lock %s : %d", name(mutex), how);
// how = h
// if (how >= 100)
// trace(1, szlock);
// if (how != 0 && DEBUG_GUARD_LOCK)
// printf("%s", szlock);
//}
//guard_lock::~guard_lock(void) {
//char szunlock[100];
// snprintf(szunlock, sizeof(szunlock), "unlock %s : %d\n", name(mutex), how);
// if (how >= 100)
// trace(1, szunlock);
// if (how != 0 && DEBUG_GUARD_LOCK)
// printf("%s", szunlock);
// pthread_mutex_unlock(mutex);
//}
guard_lock::guard_lock(pthread_mutex_t* m, std::string h) : mutex(m) {
pthread_mutex_lock(mutex);
if (!h.empty()) {
how = h;
std::string szlock;
szlock.assign("lock ").append(name(mutex)).append(" : ").append(how);
trace(1, szlock.c_str());
}
}
guard_lock::~guard_lock(void) {
if (!how.empty()) {
std::string szlock;
szlock.assign("unlock ").append(name(mutex)).append(" : ").append(how).append("\n");
trace(1, szlock.c_str());
}
pthread_mutex_unlock(mutex);
}
const char * guard_lock::name(pthread_mutex_t *m) {
if (m == &mutex_replystr) return "mutex_replystr";
if (m == &command_mutex) return "command_mutex";
if (m == &mutex_replystr) return "mutex_replystr";
if (m == &mutex_vfoque) return "mutex_vfoque";
if (m == &mutex_serial) return "mutex_serial";
if (m == &debug_mutex) return "debug_mutex";
if (m == &mutex_rcv_socket) return "mutex_rcv_socket";
if (m == &mutex_ptt) return "mutex_ptt";
if (m == &mutex_srvc_reqs) return "mutex_service_requests";
if (m == &mutex_trace) return "mutex_trace";
return "";
}
flrig-1.3.49/src/main.cxx 0000664 0001750 0001750 00000034466 13474456325 012127 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include "config.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef WIN32
# include "flrigrc.h"
# include "compat.h"
# define dirent fl_dirent_no_thanks
#endif
#include
#ifdef __MINGW32__
# if FLRIG_FLTK_API_MAJOR == 1 && FLRIG_FLTK_API_MINOR < 3
# undef dirent
# include
# endif
#else
# include
#endif
#include
#include
#include
//#include "images/flrig.xpm"
#include "support.h"
#include "dialogs.h"
#include "rig.h"
#include "status.h"
#include "debug.h"
#include "util.h"
#include "gettext.h"
#include "xml_server.h"
//#include "xml_io.h"
#include "serial.h"
#include "ui.h"
#include "icons.h"
#include "flrig_icon.cxx"
int parse_args(int argc, char **argv, int& idx);
Fl_Double_Window *mainwindow = (Fl_Double_Window *)0;
Fl_Double_Window *tabs_dialog = (Fl_Double_Window *)0;
string HomeDir;
string RigHomeDir;
string TempDir;
string defFileName;
string title;
pthread_t *serial_thread = 0;
pthread_t *digi_thread = 0;
pthread_mutex_t mutex_serial = PTHREAD_MUTEX_INITIALIZER;
//pthread_mutex_t mutex_xmlrpc = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_vfoque = PTHREAD_MUTEX_INITIALIZER;
//pthread_mutex_t mutex_vfoque = PTHREAD_MUTEX_INITIALIZER;
//pthread_mutex_t mutex_vfoque = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_ptt = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_replystr = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_srvc_reqs = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_trace = PTHREAD_MUTEX_INITIALIZER;
int use_trace = 0;
bool EXPAND_CONTROLS = false;
int xmlport = 12345;
//----------------------------------------------------------------------
void about()
{
string msg = "\
%s\n\
Version %s\n\
copyright W1HKJ \n\
Developer: Dave, W1HKJ";
fl_message(msg.c_str(), PACKAGE_TARNAME, PACKAGE_VERSION);
}
void visit_URL(void* arg)
{
const char* url = reinterpret_cast(arg);
#ifndef __WOE32__
const char* browsers[] = {
# ifdef __APPLE__
getenv("FLDIGI_BROWSER"), // valid for any OS - set by user
"open" // OS X
# else
"fl-xdg-open", // Puppy Linux
"xdg-open", // other Unix-Linux distros
getenv("FLDIGI_BROWSER"), // force use of spec'd browser
getenv("BROWSER"), // most Linux distributions
"sensible-browser",
"firefox",
"mozilla" // must be something out there!
# endif
};
switch (fork()) {
case 0:
# ifndef NDEBUG
unsetenv("MALLOC_CHECK_");
unsetenv("MALLOC_PERTURB_");
# endif
for (size_t i = 0; i < sizeof(browsers)/sizeof(browsers[0]); i++)
if (browsers[i])
execlp(browsers[i], browsers[i], url, (char*)0);
exit(EXIT_FAILURE);
case -1:
fl_alert(_("Could not run a web browser:\n%s\n\n"
"Open this URL manually:\n%s"),
strerror(errno), url);
}
#else
// gurgle... gurgle... HOWL
// "The return value is cast as an HINSTANCE for backward
// compatibility with 16-bit Windows applications. It is
// not a true HINSTANCE, however. The only thing that can
// be done with the returned HINSTANCE is to cast it to an
// int and compare it with the value 32 or one of the error
// codes below." (Error codes omitted to preserve sanity).
if ((int)ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL) <= 32)
fl_alert(_("Could not open url:\n%s\n"), url);
#endif
}
//----------------------------------------------------------------------
extern void saveFreqList();
void showEvents(void *)
{
debug::show();
}
#if defined(__WIN32__) && defined(PTW32_STATIC_LIB)
static void ptw32_cleanup(void)
{
(void)pthread_win32_process_detach_np();
}
void ptw32_init(void)
{
(void)pthread_win32_process_attach_np();
atexit(ptw32_cleanup);
}
#endif // __WIN32__
#define KNAME "Flrig"
#if !defined(__WIN32__) && !defined(__APPLE__)
Pixmap Rig_icon_pixmap;
void make_pixmap(Pixmap *xpm, const char **data)
{
Fl_Window w(0,0, KNAME);
w.xclass(KNAME);
w.show();
w.make_current();
Fl_Pixmap icon(data);
int maxd = (icon.w() > icon.h()) ? icon.w() : icon.h();
*xpm = fl_create_offscreen(maxd, maxd);
fl_begin_offscreen(*xpm);
fl_color(FL_BACKGROUND_COLOR);
fl_rectf(0, 0, maxd, maxd);
icon.draw(maxd - icon.w(), maxd - icon.h());
fl_end_offscreen();
}
#endif
static void checkdirectories(void)
{
struct {
string& dir;
const char* suffix;
void (*new_dir_func)(void);
} dirs[] = {
{ RigHomeDir, 0, 0 }
};
int r;
for (size_t i = 0; i < sizeof(dirs)/sizeof(*dirs); i++) {
if (dirs[i].suffix)
dirs[i].dir.assign(RigHomeDir).append(dirs[i].suffix).append("/");
if ((r = mkdir(dirs[i].dir.c_str(), 0777)) == -1 && errno != EEXIST) {
cerr << _("Could not make directory") << ' ' << dirs[i].dir
<< ": " << strerror(errno) << '\n';
exit(EXIT_FAILURE);
}
else if (r == 0 && dirs[i].new_dir_func)
dirs[i].new_dir_func();
}
}
void exit_main(Fl_Widget *w)
{
if (Fl::event_key() == FL_Escape)
return;
cbExit();
}
void expand_controls(void*)
{
show_controls();
}
void close_controls(void*)
{
switch (progStatus.UIsize) {
case wide_ui :
if (EXPAND_CONTROLS && selrig->has_extras) return;
btn_show_controls->label("@-22->");
btn_show_controls->redraw_label();
grpTABS->hide();
mainwindow->resizable(grpTABS);
mainwindow->size(progStatus.mainW, 150);
mainwindow->size_range(735, 150, 0, 150);
break;
case small_ui :
if (tabs_dialog && tabs_dialog->visible()) tabs_dialog->hide();
// if (EXPAND_CONTROLS && selrig->has_extras)
// Fl::add_timeout(1.0, expand_controls);
break;
case touch_ui :
default :
break;
}
}
void startup(void*)
{
initStatusConfigDialog();
switch (progStatus.UIsize) {
case touch_ui :
mainwindow->size(progStatus.mainW, TOUCH_MAINH);
mainwindow->size_range(TOUCH_MAINW, TOUCH_MAINH, 0, TOUCH_MAINH);
mainwindow->redraw();
break;
case wide_ui :
if (EXPAND_CONTROLS && selrig->has_extras) return;
btn_show_controls->label("@-22->");
btn_show_controls->redraw_label();
grpTABS->hide();
mainwindow->resizable(grpTABS);
mainwindow->size(progStatus.mainW, WIDE_MAINH);
mainwindow->size_range(735, WIDE_MAINH, 0, WIDE_MAINH);
mainwindow->redraw();
case small_ui :
default :
// if (EXPAND_CONTROLS && selrig->has_extras)
// show_controls();
break;
}
}
void rotate_log(std::string filename)
{
const int n = 5; // rename existing log files to keep up to 5 old versions
ostringstream oldfn, newfn;
ostringstream::streampos p;
oldfn << filename << '.';
newfn << filename << '.';
p = oldfn.tellp();
for (int i = n - 1; i > 0; i--) {
oldfn.seekp(p);
newfn.seekp(p);
oldfn << i;
newfn << i + 1;
rename(oldfn.str().c_str(), newfn.str().c_str());
}
rename(filename.c_str(), oldfn.str().c_str());
}
void flrig_terminate() {
std::cerr << "terminating" << std::endl;
fl_message("Closing flrig");
cbExit();
}
int main (int argc, char *argv[])
{
std::set_terminate(flrig_terminate);
int arg_idx;
HomeDir.clear();
RigHomeDir.clear();
Fl::args(argc, argv, arg_idx, parse_args);
Fl::set_fonts(0);
char dirbuf[FL_PATH_MAX + 1];
string appdir = argv[0];
size_t p;
#ifdef __WIN32__
p = appdir.rfind("flrig.exe");
if (p != string::npos) appdir.erase(p);
p = appdir.find("FL_APPS\\");
if (p != string::npos) {
HomeDir.assign(appdir.substr(0, p + 8));
RigHomeDir.assign(HomeDir).append("flrig.files\\");
} else if (RigHomeDir.empty()) {
fl_filename_expand(dirbuf, sizeof(dirbuf) -1, "$USERPROFILE/");
HomeDir = dirbuf;
RigHomeDir.assign(HomeDir).append("flrig.files\\");
}
#else
p = appdir.rfind("flrig");
if (p != std::string::npos)
appdir.erase(p);
p = appdir.find("FL_APPS/");
if (p != string::npos)
RigHomeDir = appdir.substr(0, p + 8);
if (RigHomeDir.empty()) {
fl_filename_expand(dirbuf, FL_PATH_MAX, "$HOME/");
HomeDir = dirbuf;
}
DIR *isdir = 0;
string test_dir;
test_dir.assign(HomeDir).append("flrig.files/");
isdir = opendir(test_dir.c_str());
if (isdir) {
RigHomeDir = test_dir;
closedir(isdir);
} else if (RigHomeDir.empty()) {
RigHomeDir.assign(HomeDir).append(".flrig/");
}
#endif
checkdirectories();
#if SERIAL_DEBUG
extern FILE *serlog;
std::string serlogname = RigHomeDir;
serlogname.append("serlog.txt");
serlog = fopen(serlogname.c_str(), "w");
#endif
RigSerial = new Cserial;
SepSerial = new Cserial;
AuxSerial = new Cserial;
try {
std::string fname = RigHomeDir;
fname.append("debug_log.txt");
rotate_log(fname);
debug::start(fname.c_str());
time_t t = time(NULL);
LOG(debug::INFO_LEVEL, debug::LOG_OTHER, _("%s log started on %s"), PACKAGE_STRING, ctime(&t));
string trace_fname = RigHomeDir;
trace_fname.append("trace.txt");
rotate_log(trace_fname);
}
catch (const char* error) {
cerr << error << '\n';
debug::stop();
exit(1);
}
progStatus.loadLastState();
if (use_trace) progStatus.trace = true;
switch (progStatus.UIsize) {
case touch_ui :
mainwindow = touch_rig_window();
break;
case small_ui :
mainwindow = Small_rig_window();
tabs_dialog = tabs_window();
tabs_dialog->hide();
break;
case wide_ui :
default :
mainwindow = Wide_rig_window();
}
mainwindow->callback(exit_main);
progStatus.UI_laststate();
fntbrowser = new Font_Browser;
dlgMemoryDialog = Memory_Dialog();
dlgDisplayConfig = DisplayDialog();
Fl::lock();
#if defined(__WIN32__) && defined(PTW32_STATIC_LIB)
ptw32_init();
#endif
bypass_serial_thread_loop = true;
serial_thread = new pthread_t;
if (pthread_create(serial_thread, NULL, serial_thread_loop, NULL)) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
start_server(xmlport);
createXcvrDialog();
btnALC_SWR->image(image_swr);
sldrRcvSignal->clear();
sldrFwdPwr->clear();
sldrALC->clear();
sldrSWR->clear();
switch (progStatus.UIsize) {
case small_ui :
mainwindow->resize(
progStatus.mainX, progStatus.mainY,
mainwindow->w(), 150);//mainwindow->h());
grpInitializing->size(mainwindow->w(), mainwindow->h() - grpInitializing->y());
grpInitializing->redraw();
progress->position(progress->x(), grpInitializing->y() + grpInitializing->h()/2);
progress->redraw();
break;
case wide_ui :
mainwindow->resize(
progStatus.mainX, progStatus.mainY,
progStatus.mainW, btnVol->y() + btnVol->h() + 2);
break;
case touch_ui :
mainwindow->resize(
progStatus.mainX, progStatus.mainY,
progStatus.mainW, TOUCH_MAINH);
default :
break;
}
mainwindow->xclass(KNAME);
#if defined(__WOE32__)
# ifndef IDI_ICON
# define IDI_ICON 101
# endif
mainwindow->icon((char*)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON)));
mainwindow->show (argc, argv);
#elif !defined(__APPLE__)
make_pixmap(&Rig_icon_pixmap, flrig_icon);
mainwindow->icon((char *)Rig_icon_pixmap);
mainwindow->show(argc, argv);
#else
mainwindow->show(argc, argv);
#endif
if (progStatus.UIsize != touch_ui) {
btn_show_controls->label("@-28->");
btn_show_controls->redraw_label();
}
Fl::add_timeout(0.5, startup);
return Fl::run();
}
void cl_print(std::string cl)
{
Fl_Double_Window clwin(50,50,600,500, "Command line text");
Fl_Text_Display cldisplay(2,2,596,496);
Fl_Text_Buffer clbuff;
cldisplay.buffer(&clbuff);
cldisplay.textfont(FL_COURIER);
cldisplay.insert(cl.c_str());
clwin.end();
clwin.resizable(cldisplay);
clwin.show();
while (clwin.visible()) {
Fl::wait();
MilliSleep(50);
}
}
void cb_xml_help(Fl_Menu_*, void*)
{
cl_print(print_xmlhelp());
}
int parse_args(int argc, char **argv, int& idx)
{
std::string helpstr =
"Usage: \n\
--help this help text\n\
--version\n\
--config-dir [fully qualified pathname to ]\n\
--debug-level N (0..4)\n\
--trace\n\
--xml-help\n\
--xml-trace\n\
--exp (expand menu tab controls)";
if (strcasecmp("--help", argv[idx]) == 0) {
#ifdef __WIN32__
fl_alert2("%s", helpstr.c_str());
#else
std::cout << helpstr << std::endl;
#endif
exit(0);
}
if (strcasecmp("--version", argv[idx]) == 0) {
std::string ver = "Version: ";
ver.append(VERSION).append("\n");
std::cout << ver;
exit (0);
}
if (strcasecmp("--trace", argv[idx]) == 0) {
use_trace = true;
idx++;
return 1;
}
if (strcasecmp("--xml-help", argv[idx]) == 0) {
std::cout << print_xmlhelp();
exit(0);
}
if (strcasecmp("--debug-level", argv[idx]) == 0) {
string level = argv[idx + 1];
switch (level[0]) {
case '0': debug::level = debug::QUIET_LEVEL; break;
case '1': debug::level = debug::ERROR_LEVEL; break;
case '2': debug::level = debug::WARN_LEVEL; break;
case '3': debug::level = debug::INFO_LEVEL; break;
case '4': debug::level = debug::DEBUG_LEVEL; break;
default : debug::level = debug::WARN_LEVEL;
}
idx += 2;
return 1;
}
if (strcasecmp("--config-dir", argv[idx]) == 0) {
RigHomeDir = argv[idx + 1];
if (RigHomeDir[RigHomeDir.length()-1] != '/')
RigHomeDir += '/';
idx += 2;
return 1;
}
if (strcasecmp("--exp", argv[idx]) == 0) {
EXPAND_CONTROLS = true;
idx++;
return 1;
}
# ifdef __APPLE__
if (strncasecmp("-psn", argv[idx], 4) == 0) {
idx++;
return 1;
}
#endif
fl_alert2("Unknown command line parameter: \"%s\"\n\n%s", argv[idx], helpstr.c_str());
exit(0);
return 0;
}
flrig-1.3.49/src/Makefile.am 0000664 0001750 0001750 00000021342 13603755231 012470 0000000 0000000 # Copyright (c) 2008 Dave Freese, W1HKJ (w1hkj AT w1hkj DOT com)
bin_PROGRAMS = flrig
MINGW32_SRC = \
flrig-rc.rc \
include/flrigrc.h \
support/mingw.c \
include/compat.h \
include/compat-mingw.h
# Build the xmlrpcpp source if libflxmlrpc is not found
XMLRPCPP_SRC = \
xmlrpcpp/XmlRpcBase64.h \
xmlrpcpp/XmlRpcClient.cpp \
xmlrpcpp/XmlRpcClient.h \
xmlrpcpp/XmlRpcDispatch.cpp \
xmlrpcpp/XmlRpcDispatch.h \
xmlrpcpp/XmlRpcException.h \
xmlrpcpp/XmlRpc.h \
xmlrpcpp/XmlRpcMutex.cpp \
xmlrpcpp/XmlRpcMutex.h \
xmlrpcpp/XmlRpcServerConnection.cpp \
xmlrpcpp/XmlRpcServerConnection.h \
xmlrpcpp/XmlRpcServer.cpp \
xmlrpcpp/XmlRpcServer.h \
xmlrpcpp/XmlRpcServerMethod.cpp \
xmlrpcpp/XmlRpcServerMethod.h \
xmlrpcpp/XmlRpcSocket.cpp \
xmlrpcpp/XmlRpcSocket.h \
xmlrpcpp/XmlRpcSource.cpp \
xmlrpcpp/XmlRpcSource.h \
xmlrpcpp/XmlRpcUtil.cpp \
xmlrpcpp/XmlRpcUtil.h \
xmlrpcpp/XmlRpcValue.cpp \
xmlrpcpp/XmlRpcValue.h
# We distribute these but do not always compile them
EXTRA_flrig_SOURCES = $(FLRIG_WIN32_RES_SRC) $(MINGW32_SRC) $(XMLRPCPP_SRC)
flrig_SOURCES =
if !ENABLE_FLXMLRPC
flrig_SOURCES += $(XMLRPCPP_SRC)
flrig_CPPFLAGS = @FLRIG_BUILD_CPPFLAGS@
flrig_CXXFLAGS = @FLRIG_BUILD_CXXFLAGS@
flrig_CFLAGS = $(flrig_CXXFLAGS)
flrig_LDFLAGS = @FLRIG_BUILD_LDFLAGS@
flrig_LDADD = @FLRIG_BUILD_LDADD@
else
flrig_CPPFLAGS = @FLRIG_BUILD_CPPFLAGS@ @FLXMLRPC_CFLAGS@
flrig_CXXFLAGS = @FLRIG_BUILD_CXXFLAGS@ @FLXMLRPC_CFLAGS@
flrig_CFLAGS = $(flrig_CXXFLAGS)
flrig_LDFLAGS = @FLRIG_BUILD_LDFLAGS@ @FLXMLRPC_LIBS@
flrig_LDADD = @FLRIG_BUILD_LDADD@
endif
if MINGW32
if HAVE_WINDRES
flrig_SOURCES += $(MINGW32_SRC)
endif
endif
########################################################################
FLRIG_VERSION_MAJOR = @FLRIG_VERSION_MAJOR@
FLRIG_VERSION_MINOR = @FLRIG_VERSION_MINOR@
FLRIG_VERSION_PATCH = @FLRIG_VERSION_PATCH@
FLRIG_VERSION = @FLRIG_VERSION@
.EXPORT_ALL_VARIABLES: nsisinst appbundle
# Sources that are generated,
BUILT_SOURCES =
# not distributed,
nodist_flrig_SOURCES = $(BUILT_SOURCES)
# and deleted by the clean targets
CLEANFILES = $(BUILT_SOURCES)
CLEAN_LOCAL =
if MINGW32
if HAVE_WINDRES
.rc.o:
$(WINDRES) -I$(srcdir)/include -I$(srcdir)/../data/win32 $< -O coff $@
endif
endif
install-data-local:
if test -f $(srcdir)/../data/flrig.xpm; then \
$(mkinstalldirs) $(DESTDIR)/$(datadir)/pixmaps; \
$(INSTALL_DATA) $(srcdir)/../data/flrig.xpm $(DESTDIR)/$(datadir)/pixmaps; \
fi
if test -f $(srcdir)/../data/flrig.desktop; then \
$(mkinstalldirs) $(DESTDIR)/$(datadir)/applications; \
$(INSTALL_DATA) $(srcdir)/../data/flrig.desktop $(DESTDIR)/$(datadir)/applications; \
fi
uninstall-local:
rm -f $(DESTDIR)/$(datadir)/pixmaps/flrig.xpm
rm -f $(DESTDIR)/$(datadir)/applications/flrig.desktop
INSTALLER_FILE = flrig-$(FLRIG_VERSION)_setup.exe
APPBUNDLE=flrig-$(FLRIG_VERSION)
APPBUNDLE_NOLIBS=$(APPBUNDLE)-nolibs
if HAVE_NSIS
nsisinst: $(bin_PROGRAMS)
sh $(srcdir)/../scripts/mknsisinst.sh "$(srcdir)/../data" .
CLEANFILES += $(INSTALLER_FILE)
endif
if DARWIN
appbundle: $(bin_PROGRAMS)
sh $(srcdir)/../scripts/mkappbundle.sh "$(srcdir)/../data" .
CLEAN_LOCAL += $(APPBUNDLE_NOLIBS) $(APPBUNDLE) $(APPBUNDLE)*.dmg
endif
clean-local:
-rm -rf $(CLEAN_LOCAL)
# Sources that we build. It is OK to have headers here.
flrig_SOURCES += \
graphics/pixmaps.cxx \
graphics/icons.cxx \
graphics/images.cxx \
main.cxx \
rigs/rigbase.cxx \
rigs/rigs.cxx \
rigs/AOR5K.cxx \
rigs/FT100D.cxx \
rigs/FT450.cxx \
rigs/FT450D.cxx \
rigs/FT747.cxx \
rigs/FT767.cxx \
rigs/FT817.cxx \
rigs/FT847.cxx \
rigs/FT857D.cxx \
rigs/FT890.cxx \
rigs/FT891.cxx \
rigs/FT900.cxx \
rigs/FT920.cxx \
rigs/FT950.cxx \
rigs/FT990.cxx \
rigs/FT990a.cxx \
rigs/FT991.cxx \
rigs/FT991A.cxx \
rigs/FT1000.cxx \
rigs/FT1000MP.cxx \
rigs/FT2000.cxx \
rigs/FTdx101D.cxx \
rigs/FTdx1200.cxx \
rigs/FTdx3000.cxx \
rigs/FT5000.cxx \
rigs/FTdx9000.cxx \
rigs/ICbase.cxx \
rigs/IC703.cxx \
rigs/IC706MKIIG.cxx \
rigs/IC718.cxx \
rigs/IC728.cxx \
rigs/IC735.cxx \
rigs/IC746.cxx \
rigs/IC756.cxx \
rigs/IC756PRO2.cxx \
rigs/IC756PRO3.cxx \
rigs/IC910.cxx \
rigs/IC7000.cxx \
rigs/IC7100.cxx \
rigs/IC7200.cxx \
rigs/IC7300.cxx \
rigs/IC7410.cxx \
rigs/IC7600.cxx \
rigs/IC7610.cxx \
rigs/IC7800.cxx \
rigs/IC7851.cxx \
rigs/IC9100.cxx \
rigs/IC9700.cxx \
rigs/IC7700.cxx \
rigs/ICF8101.cxx \
rigs/KENWOOD.cxx \
rigs/K2.cxx \
rigs/K3.cxx \
rigs/KX3.cxx \
rigs/PCR1000.cxx \
rigs/RAY152.cxx \
rigs/TS140.cxx \
rigs/TS450S.cxx \
rigs/TS480HX.cxx \
rigs/TS480SAT.cxx \
rigs/TS570.cxx \
rigs/TS590S.cxx \
rigs/TS590SG.cxx \
rigs/TS790.cxx \
rigs/TS850.cxx \
rigs/TS870S.cxx \
rigs/TS890S.cxx \
rigs/TS940S.cxx \
rigs/TS950.cxx \
rigs/TS990.cxx \
rigs/TS2000.cxx \
rigs/TT516.cxx \
rigs/DELTA-II.cxx \
rigs/TT538.cxx \
rigs/TT550.cxx \
rigs/TT563.cxx \
rigs/TT566.cxx \
rigs/TT588.cxx \
rigs/TT599.cxx \
support/debug.cxx \
support/dialogs.cxx \
support/ptt.cxx \
support/rig_io.cxx \
support/serial.cxx \
support/socket.cxx \
support/socket_io.cxx \
support/status.cxx \
support/support.cxx \
support/threads.cxx \
support/timeops.cxx \
support/trace.cxx \
support/util.cxx \
UI/K3_ui.cxx \
UI/KX3_ui.cxx \
UI/rigpanel.cxx \
widgets/combo.cxx \
widgets/Fl_SigBar.cxx \
widgets/flinput2.cxx \
widgets/flslider2.cxx \
widgets/font_browser.cxx \
widgets/FreqControl.cxx \
widgets/pl_tones.cxx \
widgets/ValueSlider.cxx \
widgets/hspinner.cxx \
support/tod_clock.cxx \
server/xml_server.cxx
# Additional source files that are distributed
EXTRA_DIST = \
config.h \
flrig_icon.cxx \
UI/ui_bitmaps.cxx \
UI/ui_wide.cxx \
UI/ui_small.cxx \
UI/ui_touch.cxx \
UI/ui_setup.cxx \
UI/ui_memory.cxx \
UI/xcvr_setup.cxx \
UI/meters_setup.cxx \
UI/power_meter_setup.cxx \
include/combo.h \
include/debug.h \
include/dialogs.h \
include/fileselect.h \
include/font_browser.h \
include/flrigrc.h \
include/flinput2.h \
include/icons.h \
include/KENWOOD.h \
include/pixmaps.h \
include/flslider2.h \
include/Fl_SigBar.h \
include/FreqControl.h \
include/hspinner.h \
include/AOR5K.h \
include/FT100D.h \
include/FT450.h \
include/FT450D.h \
include/FT747.h \
include/FT767.h \
include/FT817.h \
include/FT847.h \
include/FT857D.h \
include/FT920.h \
include/FT890.h \
include/FT891.h \
include/FT900.h \
include/FT950.h \
include/FT990.h \
include/FT990a.h \
include/FT991.h \
include/FT991A.h \
include/FT1000.h \
include/FT1000MP.h \
include/FT2000.h \
include/FTdx101D.h \
include/FTdx1200.h \
include/FTdx3000.h \
include/FT5000.h \
include/FTdx9000.h \
include/generic.h \
include/gettext.h \
include/ICbase.h \
include/IC703.h \
include/IC706MKIIG.h \
include/IC718.h \
include/IC728.h \
include/IC735.h \
include/IC746.h \
include/IC756.h \
include/IC756PRO2.h \
include/IC756PRO3.h \
include/IC910.h \
include/IC7000.h \
include/IC7100.h \
include/IC7410.h \
include/IC7200.h \
include/IC7300.h \
include/IC7600.h \
include/IC7610.h \
include/IC7700.h \
include/IC7800.h \
include/IC7851.h \
include/IC9100.h \
include/IC9700.h \
include/ICF8101.h \
include/images.h \
include/K2.h \
include/K3.h \
include/K3_ui.h \
include/KX3.h \
include/KX3_ui.h \
include/PCR1000.h \
include/RAY152.h \
include/mingw.h \
include/pl_tones.h \
include/ptt.h \
include/rig.h \
include/rigs.h \
include/rigbase.h \
include/rig_io.h \
include/rigpanel.h \
include/serial.h \
include/socket.h \
include/socket_io.h \
include/status.h \
include/support.h \
include/threads.h \
include/trace.h \
include/TS140.h \
include/TS450S.h \
include/TS480HX.h \
include/TS480SAT.h \
include/TS570.h \
include/TS590S.h \
include/TS590SG.h \
include/TS790.h \
include/TS850.h \
include/TS870S.h \
include/TS890S.h \
include/TS940S.h \
include/TS950.h \
include/TS990.h \
include/TS2000.h \
include/TT516.h \
include/DELTA-II.h \
include/TT538.h \
include/TT550.h \
include/TT563.h \
include/TT566.h \
include/TT588.h \
include/TT599.h \
include/timeops.h \
include/tod_clock.h \
include/ui.h \
include/util.h \
include/ValueSlider.h \
include/xml_server.h \
images/alc.xbm \
images/P5.xbm \
images/P25.xbm \
images/P50.xbm \
images/P100.xbm \
images/P200.xbm \
images/P200log.xbm \
images/S60.xbm \
images/SWR.xbm
# Additional non-source files that are distributed
# Additional source files that support non-Linux cross compilation
EXTRA_DIST += \
$(srcdir)/../data/flrig.desktop \
$(srcdir)/../data/flrig.xpm \
$(srcdir)/../data/win32/fl_app.nsi \
$(srcdir)/../data/win32/flrig.ico \
$(srcdir)/../scripts/mknsisinst.sh \
$(srcdir)/../scripts/buildmxe.sh \
$(srcdir)/../scripts/builddist.sh \
$(srcdir)/../data/mac/Info.plist.in \
$(srcdir)/../data/mac/flrig.icns \
$(srcdir)/../scripts/mkappbundle.sh \
$(FLRIG_WIN32_SRC) \
$(FLRIG_FL_SRC)
flrig-1.3.49/src/rigs/ 0000775 0001750 0001750 00000000000 13606710477 011464 5 0000000 0000000 flrig-1.3.49/src/rigs/FT747.cxx 0000644 0001750 0001750 00000011356 13472116065 012701 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include "debug.h"
#include "util.h"
#include "FT747.h"
static const char FT747name_[] = "FT-747";
static const char *FT747modes_[] = {
"LSB", "USB", "CW", "CWN", "AMW", "AMN", "FMW", "FMN", NULL};
static const char FT747_mode_type[] = { 'L', 'U', 'U', 'U', 'U', 'U', 'U', 'U' };
RIG_FT747::RIG_FT747() {
// base class values
name_ = FT747name_;
modes_ = FT747modes_;
comm_baudrate = BR4800;
stopbits = 2;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_rtscts = false;
comm_rtsplus = false;
comm_dtrplus = true;
comm_catptt = false;
comm_rtsptt = false;
comm_dtrptt = false;
modeA = 1;
bwA = 0;
has_split = true;
has_split_AB = true;
has_get_info = true;
has_ptt_control = true;
has_mode_control = true;
precision = 10;
ndigits = 8;
};
void RIG_FT747::init_cmd()
{
cmd = "00000";
for (size_t i = 0; i < 5; i++) cmd[i] = 0;
}
void RIG_FT747::selectA()
{
init_cmd();
cmd[4] = 0x05;
sendCommand(cmd);
showresp(INFO, HEX, "select A", cmd, replystr);
}
void RIG_FT747::selectB()
{
init_cmd();
cmd[3] = 0x01;
cmd[4] = 0x05;
sendCommand(cmd);
showresp(INFO, HEX, "select B", cmd, replystr);
}
void RIG_FT747::set_split(bool val)
{
split = val;
init_cmd();
cmd[3] = val ? 0x01 : 0x00;
cmd[4] = 0x01;
sendCommand(cmd);
if (val)
showresp(INFO, HEX, "set split ON", cmd, replystr);
else
showresp(INFO, HEX, "set split OFF", cmd, replystr);
}
bool RIG_FT747::check()
{
init_cmd();
cmd[3] = 0x01;
cmd[4] = 0xFA;
int ret = waitN(28, 100, "check", HEX);
if (ret >= 28) return true;
return false;
}
bool RIG_FT747::get_info()
{
long int afreq = A.freq, bfreq = B.freq;
int amode = A.imode;
init_cmd();
cmd[4] = 0x10;
int ret = waitN(28, 100, "get info", HEX);
showresp(DEBUG, HEX, "get info", cmd, replystr);
if (ret >= 28) {
// GET FREQUENCY bytes ARE NOT the same as SET FREQUENCY bytes
// returned values are packed BCD
// | 00 00 | f2 f3 | f4 f5 | f6 f7 | f8 f9 | where
// f2 - 10's of MHz
// f3 - MHz
// ... f9 - Hz
// | 00 00 | 01 04 | 02 05 | 00 00 | 00 00 | = 14.250.000 Hz
afreq = fm_bcd(replystr.substr(9), 8);
bfreq = fm_bcd(replystr.substr(16), 8);
int md = replystr[22];
switch (md) {
case 0x01 : amode = 6; // FMW
break;
case 0x81 : amode = 7; // FMN
break;
case 0x02 : amode = 4; // AMW
break;
case 0x82 : amode = 5; // AMN
break;
case 0x04 : amode = 2; // CW
break;
case 0x84 : amode = 3; // CWN
break;
case 0x08 : amode = 1; // USB
break;
case 0x10 : amode = 0; // LSB
break;
}
A.freq = afreq;
A.imode = amode;
B.freq = bfreq;
B.imode = amode;
return true;
}
A.freq = afreq;
A.imode = amode;
B.freq = bfreq;
B.imode = amode;
return false;
}
long RIG_FT747::get_vfoA ()
{
return A.freq;
}
void RIG_FT747::set_vfoA (long freq)
{
A.freq = freq;
freq /=10; // 747 does not support 1 Hz resolution
cmd = to_bcd_be(freq, 8);
cmd += 0x0A; // SET FREQUENCY
SLOG_INFO("cmd: %s", str2hex(cmd.c_str(), cmd.length()));
sendCommand(cmd);
}
int RIG_FT747::get_modeA()
{
return A.imode;
}
void RIG_FT747::set_modeA(int val)
{
A.imode = val;
init_cmd();
cmd[3] = val;
cmd[4] = 0x0C; // MODESEL
SLOG_INFO("cmd: %s", str2hex(cmd.c_str(), cmd.length()));
sendCommand(cmd);
}
long RIG_FT747::get_vfoB ()
{
return B.freq;
}
void RIG_FT747::set_vfoB (long freq)
{
B.freq = freq;
freq /=10;
cmd = to_bcd_be(freq, 8);
cmd += 0x0A; // SET FREQUENCY
SLOG_INFO("cmd: %s", str2hex(cmd.c_str(), cmd.length()));
sendCommand(cmd);
}
int RIG_FT747::get_modeB()
{
return B.imode;
}
void RIG_FT747::set_modeB(int val)
{
B.imode = val;
init_cmd();
cmd[3] = val;
cmd[4] = 0x0C; // MODESEL
SLOG_INFO("cmd: %s", str2hex(cmd.c_str(), cmd.length()));
sendCommand(cmd);
}
void RIG_FT747::set_PTT_control(int val)
{
init_cmd();
cmd[3] = val ? 0x01 : 0x00;
cmd[4] = 0x0F;
sendCommand(cmd);
ptt_ = val;
}
flrig-1.3.49/src/rigs/IC746.cxx 0000664 0001750 0001750 00000100741 13523520365 012660 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include "IC746.h"
//=============================================================================
// IC-746, IC746PRO
//=============================================================================
const char IC746name_[] = "IC-746";
const char *IC746modes_[] = {
"LSB", "USB", "AM", "CW", "RTTY", "FM", "CW-R", "RTTY-R", NULL};
// mode values are 0, 1, 2, 3, 4, 5, 7, 8
const char IC746_mode_type[] =
{ 'L', 'U', 'U', 'U', 'L', 'U', 'L', 'U'};
const char *IC746_widths[] = { "NORM", "NARR", NULL};
static int IC746_bw_vals[] = { 1, 2, WVALS_LIMIT};
static GUI IC746_widgetsdgets[]= {
{ (Fl_Widget *)btnVol, 2, 125, 50 }, //0
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 }, //1
{ (Fl_Widget *)btnAGC, 2, 145, 50 }, //2
{ (Fl_Widget *)sldrRFGAIN, 54, 145, 156 }, //3
{ (Fl_Widget *)sldrSQUELCH, 54, 165, 156 }, //4
{ (Fl_Widget *)btnNR, 2, 185, 50 }, //5
{ (Fl_Widget *)sldrNR, 54, 185, 156 }, //6
{ (Fl_Widget *)btnLOCK, 214, 105, 50 }, //7
{ (Fl_Widget *)sldrINNER, 266, 105, 156 }, //8
{ (Fl_Widget *)btnCLRPBT, 214, 125, 50 }, //9
{ (Fl_Widget *)sldrOUTER, 266, 125, 156 }, //10
{ (Fl_Widget *)btnNotch, 214, 145, 50 }, //11
{ (Fl_Widget *)sldrNOTCH, 266, 145, 156 }, //12
{ (Fl_Widget *)sldrMICGAIN, 266, 165, 156 }, //13
{ (Fl_Widget *)sldrPOWER, 266, 185, 156 }, //14
{ (Fl_Widget *)NULL, 0, 0, 0 }
};
void RIG_IC746::initialize()
{
IC746_widgetsdgets[0].W = btnVol;
IC746_widgetsdgets[1].W = sldrVOLUME;
IC746_widgetsdgets[2].W = btnAGC;
IC746_widgetsdgets[3].W = sldrRFGAIN;
IC746_widgetsdgets[4].W = sldrSQUELCH;
IC746_widgetsdgets[5].W = btnNR;
IC746_widgetsdgets[6].W = sldrNR;
IC746_widgetsdgets[7].W = btnLOCK;
IC746_widgetsdgets[8].W = sldrINNER;
IC746_widgetsdgets[9].W = btnCLRPBT;
IC746_widgetsdgets[10].W = sldrOUTER;
IC746_widgetsdgets[11].W = btnNotch;
IC746_widgetsdgets[12].W = sldrNOTCH;
IC746_widgetsdgets[13].W = sldrMICGAIN;
IC746_widgetsdgets[14].W = sldrPOWER;
}
RIG_IC746::RIG_IC746() {
defaultCIV = 0x56;
name_ = IC746name_;
modes_ = IC746modes_;
bandwidths_ = IC746_widths;
bw_vals_ = IC746_bw_vals;
_mode_type = IC746_mode_type;
widgets = IC746_widgetsdgets;
comm_baudrate = BR9600;
stopbits = 1;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_echo = true;
comm_rtscts = false;
comm_rtsplus = true;
comm_dtrplus = true;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
def_freq = freqB = freqA = B.freq = A.freq = 14070000L;
def_mode = modeB = modeA = B.imode = A.imode = 1;
def_bw = bwB = bwA = B.iBW = A.iBW = 0;
filter_nbr = 0;
ICvol = 0;
has_bandwidth_control =
has_smeter =
has_power_control =
has_volume_control =
has_mode_control =
has_micgain_control =
has_notch_control =
has_attenuator_control =
has_preamp_control =
has_pbt_controls = true;
has_ptt_control =
has_tune_control =
has_noise_control =
has_noise_reduction =
has_noise_reduction_control =
has_rf_control =
has_sql_control =
has_split =
restore_mbw = true;
has_extras = true;
precision = 1;
ndigits = 9;
};
void RIG_IC746::selectA()
{
cmd = pre_to;
cmd += '\x07';
cmd += '\x00';
cmd.append(post);
waitFB("sel A");
}
void RIG_IC746::selectB()
{
cmd = pre_to;
cmd += '\x07';
cmd += '\x01';
cmd.append(post);
waitFB("sel B");
}
bool RIG_IC746::check ()
{
string resp = pre_fm;
resp += '\x03';
cmd = pre_to;
cmd += '\x03';
cmd.append( post );
bool ok = waitFOR(11, "check vfo");
rig_trace(2, "check()", str2hex(replystr.c_str(), replystr.length()));
return ok;
}
long RIG_IC746::get_vfoA ()
{
if (useB) return A.freq;
string cstr = "\x03";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(11, "get vfo A")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
A.freq = fm_bcd_be(replystr.substr(p+5), 10);
}
return A.freq;
}
void RIG_IC746::set_vfoA (long freq)
{
A.freq = freq;
cmd = pre_to;
cmd += '\x05';
cmd.append( to_bcd_be( freq, 10 ) );
cmd.append( post );
waitFB("set vfo A");
}
long RIG_IC746::get_vfoB ()
{
if (!useB) return B.freq;
string cstr = "\x03";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(11, "get vfo B")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
B.freq = fm_bcd_be(replystr.substr(p+5), 10);
}
return B.freq;
}
void RIG_IC746::set_vfoB (long freq)
{
B.freq = freq;
cmd = pre_to;
cmd += '\x05';
cmd.append( to_bcd_be( freq, 10 ) );
cmd.append( post );
waitFB("set vfo B");
}
int RIG_IC746::get_smeter()
{
string cstr = "\x15\x02";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get smeter")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (int)ceil(fm_bcd(replystr.substr(p+6), 3) / 2.55);
}
return 0;
}
// Volume control val 0 ... 100
void RIG_IC746::set_volume_control(int val)
{
ICvol = (int)(val);
cmd = pre_to;
cmd.append("\x14\x01");
cmd.append(to_bcd(ICvol, 3));
cmd.append( post );
waitFB("set vol");
}
int RIG_IC746::get_volume_control()
{
string cstr = "\x14\x01";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get vol")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (int)ceil(fm_bcd(replystr.substr(p+6),3));
}
return 0;
}
void RIG_IC746::get_vol_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 255; step = 1;
}
// Tranceiver PTT on/off
void RIG_IC746::set_PTT_control(int val)
{
cmd = pre_to;
cmd += '\x1c';
cmd += '\x00';
cmd += (unsigned char) val;
cmd.append( post );
waitFB("set ptt");
ptt_ = val;
}
int RIG_IC746::get_PTT()
{
cmd = pre_to;
cmd += '\x1c'; cmd += '\x00';
string resp = pre_fm;
resp += '\x1c'; resp += '\x00';
cmd.append(post);
if (waitFOR(8, "get PTT")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
ptt_ = replystr[p + 6];
}
return ptt_;
}
void RIG_IC746::set_attenuator(int val)
{
cmd = pre_to;
cmd += '\x11';
cmd += val ? 0x20 : 0x00;
cmd.append( post );
waitFB("set att");
if (!val) {
preamp_level--;
if (preamp_level < 0) preamp_level = 2;
set_preamp(1);
}
}
int RIG_IC746::get_attenuator()
{
string cstr = "\x11";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(7, "get att")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (replystr[p+5] ? 1 : 0);
}
return 0;
}
int RIG_IC746::next_preamp()
{
switch(preamp_level) {
case 0: return 1;
case 1: return 2;
case 2: return 0;
}
return 0;
}
void RIG_IC746::set_preamp(int val)
{
preamp_level = val;
if (preamp_level == 1)
preamp_label("Pre 1", true);
else if (preamp_level == 2)
preamp_label("Pre 2", true);
else if (preamp_level == 0)
preamp_label("Pre", false);
cmd = pre_to;
cmd += '\x16';
cmd += '\x02';
cmd += (unsigned char) preamp_level;
cmd.append( post );
waitFB("set preamp");
}
int RIG_IC746::get_preamp()
{
string cstr = "\x16\x02";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get preamp")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
if (replystr[p+6] == 0x01) {
preamp_label("Pre 1", true);
preamp_level = 1;
} else if (replystr[p+6] == 0x02) {
preamp_label("Pre 2", true);
preamp_level = 2;
} else {
preamp_label("Pre", false);
preamp_level = 0;
}
}
}
return preamp_level;
}
// changed noise blanker to noise reduction
void RIG_IC746::set_noise(bool val)
{
cmd = pre_to;
cmd.append("\x16\x22");
cmd += val ? 1 : 0;
cmd.append(post);
waitFB("set noise");
}
int RIG_IC746::get_noise()
{
string cstr = "\x16\x22";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get noise")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (replystr[p+6] ? 1 : 0);
}
return 0;
}
void RIG_IC746::set_noise_reduction(int val)
{
cmd = pre_to;
cmd.append("\x16\x40");
cmd += val ? 1 : 0;
cmd.append(post);
waitFB("set NR");
}
int RIG_IC746::get_noise_reduction()
{
string cstr = "\x16\x40";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get NR")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (replystr[p+6] ? 1 : 0);
}
return 0;
}
// 0 < val < 100
void RIG_IC746::set_noise_reduction_val(int val)
{
cmd = pre_to;
cmd.append("\x14\x06");
cmd.append(to_bcd(val * 255 / 100, 3));
cmd.append(post);
waitFB("set NR val");
}
int RIG_IC746::get_noise_reduction_val()
{
string cstr = "\x14\x06";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get NR val")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (int)ceil(fm_bcd(replystr.substr(p+6),3) / 2.55);
}
return 0;
}
void RIG_IC746::set_modeA(int val)
{
A.imode = val;
cmd = pre_to;
cmd += '\x06';
cmd += val > 5 ? val + 1 : val;
cmd += filter_nbr + 1; // filter #
cmd.append( post );
waitFB("set mode A");
}
int RIG_IC746::get_modeA()
{
string cstr = "\x04";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get mode A")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
A.imode = replystr[p+5];
if (A.imode > 6) A.imode--;
filter_nbr = replystr[p+6] - 1;
}
}
return A.imode;
}
void RIG_IC746::set_bwA(int val)
{
filter_nbr = val;
set_modeA(A.imode);
}
int RIG_IC746::get_bwA()
{
return filter_nbr;
}
void RIG_IC746::set_modeB(int val)
{
B.imode = val;
cmd = pre_to;
cmd += '\x06';
cmd += val > 5 ? val + 1 : val;
cmd += filter_nbr + 1; // filter
cmd.append( post );
waitFB("set mode B");
}
int RIG_IC746::get_modeB()
{
string cstr = "\x04";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get mode B")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
B.imode = replystr[p+5];
if (B.imode > 6) B.imode--;
filter_nbr = replystr[p+6] - 1;
}
}
return B.imode;
}
void RIG_IC746::set_bwB(int val)
{
filter_nbr = val;
set_modeB(B.imode);
}
int RIG_IC746::get_bwB()
{
return filter_nbr;
}
int RIG_IC746::get_modetype(int n)
{
return _mode_type[n];
}
void RIG_IC746::set_mic_gain(int val)
{
val = (int)(val * 255 / 100);
cmd = pre_to;
cmd.append("\x14\x0B");
cmd.append(to_bcd(val,3));
cmd.append(post);
waitFB("set mic");
}
void RIG_IC746::get_mic_gain_min_max_step(int &min, int &max, int &step)
{
min = 0;
max = 100;
step = 1;
}
void RIG_IC746::set_if_shift(int val)
{
int shift;
sh_ = val;
if (val == 0) sh_on_ = false;
else sh_on_ = true;
shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x07");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set IF on/off");
cmd = pre_to;
cmd.append("\x14\x08");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set IF val");
}
void RIG_IC746::get_if_min_max_step(int &min, int &max, int &step)
{
min = -50;
max = +50;
step = 1;
}
void RIG_IC746::set_pbt_inner(int val)
{
int shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x07");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set PBT inner");
}
void RIG_IC746::set_pbt_outer(int val)
{
int shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x08");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set PBT outer");
}
int RIG_IC746::get_pbt_inner()
{
int val = 0;
string cstr = "\x14\x07";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get pbt inner")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = num100(replystr.substr(p+6));
val -= 50;
}
}
rig_trace(2, "get_pbt_inner()", str2hex(replystr.c_str(), replystr.length()));
return val;
}
int RIG_IC746::get_pbt_outer()
{
int val = 0;
string cstr = "\x14\x08";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get pbt inner")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = num100(replystr.substr(p+6));
val -= 50;
}
}
rig_trace(2, "get_pbt_outer()", str2hex(replystr.c_str(), replystr.length()));
return val;
}
int ICsql = 0;
void RIG_IC746::set_squelch(int val)
{
ICsql = (int)(val * 255 / 100);
cmd = pre_to;
cmd.append("\x14\x03");
cmd.append(to_bcd(ICsql, 3));
cmd.append( post );
waitFB("set sql");
}
int ICrfg = 0;
void RIG_IC746::set_rf_gain(int val)
{
ICrfg = (int)(val * 255 / 100);
cmd = pre_to;
cmd.append("\x14\x02");
cmd.append(to_bcd(ICrfg, 3));
cmd.append( post );
waitFB("set rf gain");
}
void RIG_IC746::set_power_control(double val)
{
cmd = pre_to;
cmd.append("\x14\x0A");
cmd.append(to_bcd((int)(val * 255 / 100), 3));
cmd.append( post );
waitFB("set power");
}
void RIG_IC746::set_split(bool val)
{
split = val;
cmd = pre_to;
cmd += 0x0F;
cmd += val ? 0x10 : 0x00;
cmd.append(post);
waitFB("set split");
}
int RIG_IC746::get_split()
{
return split;
}
//=============================================================================
// 746PRO
const char IC746PROname_[] = "IC-746PRO";
const char *IC746PROmodes_[] = {
"LSB", "USB", "AM", "CW", "RTTY", "FM", "CW-R", "RTTY-R",
"D-LSB", "D-USB", "D-FM", NULL};
const char IC746PRO_mode_type[] =
{ 'L', 'U', 'U', 'U', 'L', 'U', 'L', 'U',
'L', 'U', 'U' };
const char *IC746PRO_SSBwidths[] = {
"50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
"600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500",
"1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500",
"2600", "2700", "2800", "2900", "3000", "3100", "3200", "3300", "3400", "3500",
"3600",
NULL};
static int IC746PRO_bw_vals_SSB[] = {
1, 2, 3, 4, 5, 6, 7, 8, 9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,39,40,
41, WVALS_LIMIT};
const char *IC746PRO_RTTYwidths[] = {
"50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
"600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500",
"1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500",
"2600", "2700",
NULL};
static int IC746PRO_bw_vals_RTTY[] = {
1, 2, 3, 4, 5, 6, 7, 8, 9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,
31,32, WVALS_LIMIT};
const char *IC746PRO_AMFMwidths[] = { "FILT-1", "FILT-2", "FILT-3", NULL };
static int IC746PRO_bw_vals_AMFM[] = {
1,2,3,WVALS_LIMIT};
void RIG_IC746PRO::initialize()
{
IC746_widgetsdgets[0].W = btnVol;
IC746_widgetsdgets[1].W = sldrVOLUME;
IC746_widgetsdgets[2].W = btnAGC;
IC746_widgetsdgets[3].W = sldrRFGAIN;
IC746_widgetsdgets[4].W = sldrSQUELCH;
IC746_widgetsdgets[5].W = btnNR;
IC746_widgetsdgets[6].W = sldrNR;
IC746_widgetsdgets[7].W = btnLOCK;
IC746_widgetsdgets[8].W = sldrINNER;
IC746_widgetsdgets[9].W = btnCLRPBT;
IC746_widgetsdgets[10].W = sldrOUTER;
IC746_widgetsdgets[11].W = btnNotch;
IC746_widgetsdgets[12].W = sldrNOTCH;
IC746_widgetsdgets[13].W = sldrMICGAIN;
IC746_widgetsdgets[14].W = sldrPOWER;
btn_icom_select_11->activate();
btn_icom_select_12->deactivate();
btn_icom_select_13->deactivate();
choice_rTONE->activate();
choice_tTONE->activate();
}
RIG_IC746PRO::RIG_IC746PRO() {
defaultCIV = 0x66;
name_ = IC746PROname_;
modes_ = IC746PROmodes_;
bandwidths_ = IC746PRO_SSBwidths;
bw_vals_ = IC746PRO_bw_vals_SSB;
_mode_type = IC746PRO_mode_type;
atten_level = 1;
preamp_level = 2;
def_mode = modeB = modeA = B.imode = A.imode = 1;
def_bw = bwB = bwA = B.iBW = A.iBW = 34;
def_freq = freqB = freqA = B.freq = A.freq = 14070000L;
has_smeter =
has_power_control =
has_volume_control =
has_mode_control =
has_bandwidth_control =
has_micgain_control =
has_notch_control =
has_attenuator_control =
has_preamp_control =
has_pbt_controls = true;
has_ptt_control =
has_tune_control =
has_noise_control =
has_noise_reduction =
has_noise_reduction_control =
has_rf_control =
has_sql_control =
has_split =
restore_mbw = true;
has_swr_control =
has_alc_control =
has_power_out = true;
has_extras = true;
has_band_selection = true;
adjustCIV(defaultCIV);
};
void RIG_IC746PRO::set_modeA(int val)
{
A.imode = val;
bool datamode = false;
switch (val) {
case 10 : val = 5; datamode = true; break;
case 9 : val = 1; datamode = true; break;
case 8 : val = 0; datamode = true; break;
case 7 : val = 8; break;
case 6 : val = 7; break;
default: break;
}
cmd = pre_to;
cmd += '\x06';
cmd += val;
cmd += filter_nbr + 1; // filter 1 ... 3
cmd.append( post );
waitFB("set mode A");
if (datamode) { // LSB / USB ==> use DATA mode
cmd = pre_to;
cmd.append("\x1A\x06\x01");
cmd.append(post);
waitFB("data mode");
}
}
int RIG_IC746PRO::get_modeA()
{
int md;
string cstr = "\x04";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get mode A")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
md = replystr[p+5];
if (md > 6) md--;
filter_nbr = replystr[p+6] - 1;
cstr = "\x1A\x06";
resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "data ?")) {
p = replystr.rfind(resp);
if (p != string::npos) {
if (replystr[p+6]) {
switch (md) {
case 0 : md = 8; break;
case 1 : md = 9; break;
case 5 : md = 10; break;
default : break;
}
}
}
}
A.imode = md;
}
}
return A.imode;
}
void RIG_IC746PRO::set_modeB(int val)
{
B.imode = val;
bool datamode = false;
switch (val) {
case 10 : val = 5; datamode = true; break;
case 9 : val = 1; datamode = true; break;
case 8 : val = 0; datamode = true; break;
case 7 : val = 8; break;
case 6 : val = 7; break;
default: break;
}
cmd = pre_to;
cmd += '\x06';
cmd += val;
cmd += filter_nbr + 1;
cmd.append( post );
waitFB("set mode B");
if (datamode) { // LSB / USB ==> use DATA mode
cmd = pre_to;
cmd.append("\x1A\x06\x01");
cmd.append(post);
waitFB("data mode");
}
}
int RIG_IC746PRO::get_modeB()
{
int md;
string cstr = "\x04";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get mode B")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
md = replystr[p+5];
if (md > 6) md--;
filter_nbr = replystr[p+6] - 1; // this is the filter #; not the bandwidth
cstr = "\x1A\x06";
resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "data ?")) {
p = replystr.rfind(resp);
if (p != string::npos) {
if (replystr[p+6]) {
switch (md) {
case 0 : md = 8; break;
case 1 : md = 9; break;
case 5 : md = 10; break;
default : break;
}
}
}
}
B.imode = md;
}
}
return B.imode;
}
int RIG_IC746PRO::adjust_bandwidth(int m)
{
if (m == 0 || m == 1 || m == 8 || m == 9) { //SSB
bandwidths_ = IC746PRO_SSBwidths;
bw_vals_ = IC746PRO_bw_vals_SSB;
return (32);
}
if (m == 3 || m == 6) { //CW
bandwidths_ = IC746PRO_SSBwidths;
bw_vals_ = IC746PRO_bw_vals_SSB;
return (14);
}
if (m == 4 || m == 7) { //RTTY
bandwidths_ = IC746PRO_RTTYwidths;
bw_vals_ = IC746PRO_bw_vals_RTTY;
return (28);
}
bandwidths_ = IC746PRO_AMFMwidths;
bw_vals_ = IC746PRO_bw_vals_AMFM;
return (0);
}
int RIG_IC746PRO::def_bandwidth(int m)
{
if (m == 0 || m == 1 || m == 8 || m == 9) { //SSB
return (32);
}
if (m == 3 || m == 6) { //CW
return (14);
}
if (m == 4 || m == 7) { //RTTY
return (28);
}
bandwidths_ = IC746PRO_AMFMwidths;
return (0);
}
const char **RIG_IC746PRO::bwtable(int m)
{
if (m == 0 || m == 1 || m == 8 || m == 9) //SSB
return IC746PRO_SSBwidths;
if (m == 3 || m == 6) //CW
return IC746PRO_SSBwidths;
if (m == 4 || m == 7) //RTTY
return IC746PRO_RTTYwidths;
return IC746PRO_AMFMwidths;
}
int RIG_IC746PRO::get_swr()
{
string cstr = "\x15\x12";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get swr")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (int)ceil(fm_bcd(replystr.substr(p + 6),3) / 2.55 );
}
return -1;
}
int RIG_IC746PRO::get_alc()
{
string cstr = "\x15\x13";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get alc")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (int)ceil(fm_bcd(replystr.substr(p + 6),3) / 2.55 );
}
return -1;
}
// Transceiver power level return power in watts
int RIG_IC746PRO::get_power_out()
{
string cstr = "\x15\x11";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get power")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (int)ceil(fm_bcd(replystr.substr(p + 6),3) / 2.55 );
}
return -1;
}
void RIG_IC746PRO::set_bwA(int val)
{
// if (bandwidths_ == IC746PRO_AMFMwidths) {
// filter_nbr = val;
// set_modeA(A.imode);
// return;
// }
A.iBW = val;
cmd = pre_to;
cmd.append("\x1A\x03");
cmd.append(to_bcd(A.iBW,2));
cmd.append( post );
waitFB("set bw A");
}
int RIG_IC746PRO::get_bwA()
{
string cstr = "\x1A\x03";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(8, "get bw A")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
A.iBW = (int)ceil(fm_bcd(replystr.substr(p + 6), 2));
}
return A.iBW;
}
void RIG_IC746PRO::set_bwB(int val)
{
// if (bandwidths_ == IC746PRO_AMFMwidths) {
// filter_nbr = val;
// set_modeA(A.imode);
// return;
// }
B.iBW = val;
cmd = pre_to;
cmd.append("\x1A\x03");
cmd.append(to_bcd(B.iBW,2));
cmd.append( post );
waitFB("set bw B");
}
int RIG_IC746PRO::get_bwB()
{
string cstr = "\x1A\x03";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(8, "get bw B")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
B.iBW = (int)(fm_bcd(replystr.substr(p + 6), 2));
}
return B.iBW;
}
int RIG_IC746PRO::get_attenuator()
{
string cstr = "\x11";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(7, "get att")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (replystr[p+5] ? 1 : 0);
}
return 0;
}
void RIG_IC746PRO::set_attenuator(int val)
{
int cmdval = val ? 0x20 : 0x00;
cmd = pre_to;
cmd += '\x11';
cmd += cmdval;
cmd.append( post );
waitFB("set att");
}
bool IC_notchon = false;
void RIG_IC746PRO::set_notch(bool on, int val)
{
int notch = (int)(val/20.0 + 128);
if (notch > 256) notch = 255;
if (on != IC_notchon) {
cmd = pre_to;
cmd.append("\x16\x48");
cmd += on ? '\x01' : '\x00';
cmd.append(post);
waitFB("set notch");
IC_notchon = on;
}
if (on) {
cmd = pre_to;
cmd.append("\x14\x0D");
cmd.append(to_bcd(notch,3));
cmd.append(post);
waitFB("set notch val");
}
}
bool RIG_IC746PRO::get_notch(int &val)
{
bool on = false;
val = 0;
string cstr = "\x16\x48";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(8, "get notch")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
on = replystr[p + 6] ? 1 : 0;
cmd = pre_to;
resp = pre_fm;
cstr = "\x14\x0D";
cmd.append(cstr);
resp.append(cstr);
cmd.append(post);
if (waitFOR(9, "get notch val")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = 20*ceil(fm_bcd(replystr.substr(p + 6),3) - 128);
}
}
return on;
}
void RIG_IC746PRO::get_notch_min_max_step(int &min, int &max, int &step)
{
min = -1280;
max = 1280;
step = 20;
}
void RIG_IC746PRO::set_rf_gain(int val)
{
int ICrfg = val * 255 / 100;
cmd = pre_to;
cmd.append("\x14\x02");
cmd.append(to_bcd(ICrfg, 3));
cmd.append( post );
waitFB("set rf gain");
}
int RIG_IC746PRO::get_rf_gain()
{
string cstr = "\x14\x02";
string resp = pre_fm;
cmd = pre_to;
cmd.append(cstr).append(post);
resp.append(cstr);
if (waitFOR(9, "get rfgain")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (int)ceil(fm_bcd(replystr.substr(p + 6),3) / 2.55);
}
return progStatus.rfgain;
}
void RIG_IC746PRO::set_squelch(int val)
{
int IC746PROsql = val * 255 / 100;
cmd = pre_to;
cmd.append("\x14\x03");
cmd.append(to_bcd(IC746PROsql, 3));
cmd.append( post );
waitFB("set sql");
}
int RIG_IC746PRO::get_squelch()
{
string cstr = "\x14\x03";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get sql")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (int)ceil(fm_bcd(replystr.substr(p+6), 3) / 2.55);
}
return progStatus.squelch;
}
void RIG_IC746PRO::set_power_control(double val)
{
cmd = pre_to;
cmd.append("\x14\x0A");
cmd.append(to_bcd((int)(val * 2.55), 3));
cmd.append( post );
waitFB("set power");
}
int RIG_IC746PRO::get_power_control()
{
string cstr = "\x14\x0A";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr).append(post);
if (waitFOR(9, "get power")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (int)ceil(fm_bcd(replystr.substr(p + 6),3) / 2.55);
}
return progStatus.power_level;
}
void RIG_IC746PRO::set_preamp(int val)
{
if (preamp_level == 0) {
preamp_level = 1;
preamp_label("Pre 1", true);
} else if (preamp_level == 1) {
preamp_level = 2;
preamp_label("Pre 2", true);
} else if (preamp_level == 2) {
preamp_level = 0;
preamp_label("Pre", false);
}
cmd = pre_to;
cmd += '\x16';
cmd += '\x02';
cmd += (unsigned char) preamp_level;
cmd.append( post );
waitFB("set preamp");
}
int RIG_IC746PRO::get_preamp()
{
string cstr = "\x16\x02";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(8, "get preamp")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
if (replystr[p+6] == 0x01) {
preamp_label("Pre 1", true);
preamp_level = 1;
} else if (replystr[p+6] == 0x02) {
preamp_label("Pre 2", true);
preamp_level = 2;
} else {
preamp_label("Pre", false);
preamp_level = 0;
}
}
}
return preamp_level;
}
int RIG_IC746PRO::get_mic_gain()
{
string cstr = "\x14\x0B";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get mic")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (int)ceil(fm_bcd(replystr.substr(p+6),3) / 2.55);
}
return 0;
}
void RIG_IC746PRO::set_mic_gain(int val)
{
val = (int)(val * 2.55);
cmd = pre_to;
cmd.append("\x14\x0B");
cmd.append(to_bcd(val,3));
cmd.append(post);
waitFB("set mic");
}
void RIG_IC746PRO::get_mic_gain_min_max_step(int &min, int &max, int &step)
{
min = 0;
max = 100;
step = 1;
}
void RIG_IC746PRO::set_if_shift(int val)
{
int shift;
sh_ = val;
if (val == 0) sh_on_ = false;
else sh_on_ = true;
shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x07");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set IF on/off");
cmd = pre_to;
cmd.append("\x14\x08");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set IF val");
}
void RIG_IC746PRO::get_if_min_max_step(int &min, int &max, int &step)
{
min = -50;
max = +50;
step = 1;
}
void RIG_IC746PRO::set_pbt_inner(int val)
{
int shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x07");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set PBT inner");
}
void RIG_IC746PRO::set_pbt_outer(int val)
{
int shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x08");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set PBT outer");
}
int RIG_IC746PRO::get_pbt_inner()
{
int val = 0;
string cstr = "\x14\x07";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get pbt inner")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = num100(replystr.substr(p+6));
val -= 50;
}
}
rig_trace(2, "get_pbt_inner()", str2hex(replystr.c_str(), replystr.length()));
return val;
}
int RIG_IC746PRO::get_pbt_outer()
{
int val = 0;
string cstr = "\x14\x08";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get pbt inner")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = num100(replystr.substr(p+6));
val -= 50;
}
}
rig_trace(2, "get_pbt_outer()", str2hex(replystr.c_str(), replystr.length()));
return val;
}
void RIG_IC746PRO::set_split(bool val)
{
split = val;
cmd = pre_to;
cmd += 0x0F;
cmd += val ? 0x01 : 0x00;
cmd.append(post);
waitFB(val ? "set split ON" : "set split OFF");
}
int RIG_IC746PRO::get_split()
{
return split;
}
// Read/Write band stack registers
//
// Read 23 bytes
//
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// FE FE nn E0 1A 01 bd rn f5 f4 f3 f2 f1 mo fi fg t1 t2 t3 r1 r2 r3 FD
// Write 23 bytes
//
// FE FE E0 nn 1A 01 bd rn f5 f4 f3 f2 f1 mo fi fg t1 t2 t3 r1 r2 r3 FD
//
// nn - CI-V address
// bd - band selection 1/2/3
// rn - register number 1/2/3
// f5..f1 - frequency BCD reverse
// mo - mode
// fi - filter #
// fg flags: x01 use Tx tone, x02 use Rx tone, x10 data mode
// t1..t3 - tx tone BCD fwd
// r1..r3 - rx tone BCD fwd
//
// FE FE E0 94 1A 01 06 01 70 99 08 18 00 01 03 10 00 08 85 00 08 85 FD
//
// band 6; freq 0018,089,970; USB; data mode; t 88.5; r 88.5
void RIG_IC746PRO::get_band_selection(int v)
{
cmd.assign(pre_to);
cmd.append("\x1A\x01");
cmd += to_bcd_be( v, 2 );
cmd += '\x01';
cmd.append( post );
if (waitFOR(23, "get band stack")) {
set_trace(2, "get band stack", str2hex(replystr.c_str(), replystr.length()));
size_t p = replystr.rfind(pre_fm);
if (p != string::npos) {
long int bandfreq = fm_bcd_be(replystr.substr(p+8, 5), 10);
int bandmode = replystr[p+13];
int bandfilter = replystr[p+14];
int banddata = replystr[p+15] & 0x10;
if ((bandmode == 0 || bandmode == 1) && banddata) bandmode += 7;
int tone = fm_bcd(replystr.substr(p+16, 3), 6);
size_t index = 0;
for (index = 0; index < sizeof(PL_tones) / sizeof(*PL_tones); index++)
if (tone == PL_tones[index]) break;
tTONE = index;
tone = fm_bcd(replystr.substr(p+19, 3), 6);
for (index = 0; index < sizeof(PL_tones) / sizeof(*PL_tones); index++)
if (tone == PL_tones[index]) break;
rTONE = index;
if (useB) {
set_vfoB(bandfreq);
set_modeB(bandmode);
set_FILT(bandfilter);
} else {
set_vfoA(bandfreq);
set_modeA(bandmode);
set_FILT(bandfilter);
}
}
} else
set_trace(2, "get band stack", str2hex(replystr.c_str(), replystr.length()));
}
void RIG_IC746PRO::set_band_selection(int v)
{
long freq = (useB ? B.freq : A.freq);
int fil = (useB ? filB : filA);
int mode = (useB ? B.imode : A.imode);
cmd.assign(pre_to);
cmd.append("\x1A\x01");
cmd += to_bcd_be( v, 2 );
cmd += '\x01';
cmd.append( to_bcd_be( freq, 10 ) );
cmd += mode;
cmd += fil;
if (mode >= 7)
cmd += '\x10';
else
cmd += '\x00';
cmd.append(to_bcd(PL_tones[tTONE], 6));
cmd.append(to_bcd(PL_tones[rTONE], 6));
cmd.append(post);
waitFB("set_band_selection");
set_trace(2, "set_band_selection()", str2hex(replystr.c_str(), replystr.length()));
cmd.assign(pre_to);
cmd.append("\x1A\x01");
cmd += to_bcd_be( v, 2 );
cmd += '\x01';
cmd.append( post );
waitFOR(23, "get band stack");
}
flrig-1.3.49/src/rigs/TS480HX.cxx 0000644 0001750 0001750 00000065710 13472116065 013153 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include "TS480HX.h"
#include "support.h"
static const char TS480HXname_[] = "TS-480HX";
static const char *TS480HXmodes_[] = {
"LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "FSK-R", NULL};
static const char TS480HX_mode_chr[] = { '1', '2', '3', '4', '5', '6', '7', '9' };
static const char TS480HX_mode_type[] = { 'L', 'U', 'U', 'U', 'U', 'L', 'L', 'U' };
static const char *TS480HX_empty[] = { "N/A", NULL };
static int TS480HX_bw_vals[] = {1, WVALS_LIMIT};
// SL command is lo cut when menu 045 OFF
static const char *TS480HX_SL[] = {
"0", "50", "100", "200", "300",
"400", "500", "600", "700", "800",
"900", "1000", NULL };
static const char *TS480HX_SL_tooltip = "lo cut";
static const char *TS480HX_btn_SL_label = "L";
// SH command is hi cut when menu 045 OFF
static const char *TS480HX_SH[] = {
"1000", "1200", "1400", "1600", "1800",
"2000", "2200", "2400", "2600", "2800",
"3000", "3400", "4000", "5000", NULL };
static int TS480HX_HI_bw_vals[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,WVALS_LIMIT};
static const char *TS480HX_SH_tooltip = "hi cut";
static const char *TS480HX_btn_SH_label = "H";
// SL command is width when menu 045 ON
static const char *TS480HX_dataW[] = {
"50", "100", "250", "500", "1000", "1500", "2400", NULL };
static int TS480HX_data_bw_vals[] = {1,2,3,4,5,6,7, WVALS_LIMIT};
static const char *TS480HX_dataW_tooltip = "width";
static const char *TS480HX_dataW_label = "W";
// SH command is center when menu 045 ON
static const char *TS480HX_dataC[] = {
"1000", "1500", "2210", NULL };
static const char *TS480HX_dataC_tooltip = "center";
static const char *TS480HX_dataC_label = "C";
static const char *TS480HX_AM_SL[] = {
"10", "100", "200", "500",
NULL };
static const char *TS480HX_AM_SH[] = {
"2500", "3000", "4000", "5000",
NULL };
//static int TS480HX_AM_bw_vals[] = {1,2,3,4,WVALS_LIMIT};
static const char *TS480HX_CWwidths[] = {
"50", "80", "100", "150", "200",
"300", "400", "500", "600", "1000",
"2000", NULL};
static int TS480HX_CW_bw_vals[] = {1,2,3,4,5,6,7,8,9,10,11,WVALS_LIMIT};
static const char *TS480HX_CWbw[] = {
"FW0050;", "FW0080;", "FW0100;", "FW0150;", "FW0200;",
"FW0300;", "FW0400;", "FW0500;", "FW0600;", "FW1000;",
"FW2000;" };
static const char *TS480HX_FSKwidths[] = {
"250", "500", "1000", "1500", NULL};
static int TS480HX_FSK_bw_vals[] = { 1,2,3,4,WVALS_LIMIT};
static const char *TS480HX_FSKbw[] = {
"FW0250;", "FW0500;", "FW1000;", "FW1500;" };
static int agcval = 1;
static bool fm_mode = false;
static GUI rig_widgets[]= {
{ (Fl_Widget *)btnVol, 2, 125, 50 }, // 0
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 }, // 1
{ (Fl_Widget *)sldrRFGAIN, 54, 145, 156 }, // 2
{ (Fl_Widget *)btnIFsh, 214, 105, 50 }, // 3
{ (Fl_Widget *)sldrIFSHIFT, 266, 105, 156 }, // 4
{ (Fl_Widget *)btnDataPort, 214, 125, 50 }, // 5
{ (Fl_Widget *)sldrSQUELCH, 266, 125, 156 }, // 6
{ (Fl_Widget *)sldrMICGAIN, 266, 145, 156 }, // 7
{ (Fl_Widget *)sldrPOWER, 54, 165, 368 }, // 8
{ (Fl_Widget *)NULL, 0, 0, 0 }
};
static string menu012 = "EX01200004";
void RIG_TS480HX::initialize()
{
rig_widgets[0].W = btnVol;
rig_widgets[1].W = sldrVOLUME;
rig_widgets[2].W = sldrRFGAIN;
rig_widgets[3].W = btnIFsh;
rig_widgets[4].W = sldrIFSHIFT;
rig_widgets[5].W = btnDataPort;
rig_widgets[6].W = sldrSQUELCH;
rig_widgets[7].W = sldrMICGAIN;
rig_widgets[8].W = sldrPOWER;
check_menu_45();
menu012.clear();
cmd = "EX0120000;"; // read menu 012 state
//might return something like EX01200004;
if (wait_char(';', 11, 100, "read ex 012", ASC) == 11)
menu012 = replystr;
cmd = "EX01200000;";
sendCommand(cmd);
}
RIG_TS480HX::RIG_TS480HX() {
// base class values
name_ = TS480HXname_;
modes_ = TS480HXmodes_;
_mode_type = TS480HX_mode_type;
bandwidths_ = TS480HX_empty;
bw_vals_ = TS480HX_bw_vals;
dsp_SL = TS480HX_SL;
SL_tooltip = TS480HX_SL_tooltip;
SL_label = TS480HX_btn_SL_label;
dsp_SH = TS480HX_SH;
SH_tooltip = TS480HX_SH_tooltip;
SH_label = TS480HX_btn_SH_label;
widgets = rig_widgets;
comm_baudrate = BR57600;
stopbits = 1;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_rtscts = true;
comm_rtsplus = false;
comm_dtrplus = false;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
B.imode = A.imode = 1;
B.iBW = A.iBW = 0x8A03;
B.freq = A.freq = 14070000;
can_change_alt_vfo = true;
has_extras = true;
has_noise_reduction =
has_noise_reduction_control =
has_auto_notch =
has_noise_control =
has_sql_control =
has_split = true;
has_split_AB = true;
has_data_port = true;
has_micgain_control = true;
has_ifshift_control = true;
has_rf_control = true;
has_agc_control = true;
has_swr_control = true;
has_alc_control = true;
has_power_out = true;
has_dsp_controls = true;
has_smeter = true;
has_attenuator_control = true;
has_preamp_control = true;
has_mode_control = true;
has_bandwidth_control = true;
has_volume_control = true;
has_power_control = true;
has_tune_control = true;
has_ptt_control = true;
precision = 1;
ndigits = 8;
_noise_reduction_level = 0;
_nrval1 = 2;
_nrval2 = 4;
}
const char * RIG_TS480HX::get_bwname_(int n, int md)
{
static char bwname[20];
if (n > 256) {
int hi = (n >> 8) & 0x7F;
int lo = n & 0xFF;
snprintf(bwname, sizeof(bwname), "%s/%s",
(md == 0 || md == 1 || md == 3) ? dsp_SL[lo] : TS480HX_AM_SL[lo],
(md == 0 || md == 1 || md == 3) ? dsp_SH[hi] : TS480HX_AM_SH[hi] );
} else {
snprintf(bwname, sizeof(bwname), "%s",
(md == 2 || md == 6) ? TS480HX_CWwidths[n] : TS480HX_FSKwidths[n]);
}
return bwname;
}
void RIG_TS480HX::check_menu_45()
{
// read current switch 45 setting
menu_45 = false;
cmd = "EX0450000;";
if (wait_char(';', 11, 100, "Check menu item 45", ASC) >= 11) {
size_t p = replystr.rfind("EX045");
if (p != string::npos)
menu_45 = (replystr[p+9] == '1');
}
if (menu_45) {
dsp_SL = TS480HX_dataW;
SL_tooltip = TS480HX_dataW_tooltip;
SL_label = TS480HX_dataW_label;
dsp_SH = TS480HX_dataC;
SH_tooltip = TS480HX_dataC_tooltip;
SH_label = TS480HX_dataC_label;
B.iBW = A.iBW = 0x8106;
} else {
dsp_SL = TS480HX_SL;
SL_tooltip = TS480HX_SL_tooltip;
SL_label = TS480HX_btn_SL_label;
dsp_SH = TS480HX_SH;
SH_tooltip = TS480HX_SH_tooltip;
SH_label = TS480HX_btn_SH_label;
B.iBW = A.iBW = 0x8A03;
}
}
void RIG_TS480HX::shutdown()
{
// restore state of xcvr beeps
if (menu012.empty()) return;
cmd = menu012;
sendCommand(cmd);
}
// SM cmd 0 ... 100 (rig values 0 ... 15)
int RIG_TS480HX::get_smeter()
{
int mtr = 0;
cmd = "SM0;";
if (wait_char(';', 8, 100, "get Smeter", ASC) < 8) return 0;
size_t p = replystr.rfind("SM");
if (p != string::npos)
mtr = 5 * atoi(&replystr[p + 3]);
return mtr;
}
struct pwrpair {int mtr; float pwr;};
static pwrpair pwrtbl[] = {
{0, 0.0},
{2, 5.0},
{4, 10.0},
{7, 25.0},
{11, 50.0},
{16, 100.0},
{20, 200.0} };
int RIG_TS480HX::get_power_out()
{
int mtr = 0;
cmd = "SM0;";
if (wait_char(';', 8, 100, "get power", ASC) < 8) return mtr;
size_t p = replystr.rfind("SM");
if (p != string::npos) {
mtr = atoi(&replystr[p + 3]);
size_t i = 0;
for (i = 0; i < sizeof(pwrtbl) / sizeof(pwrpair) - 1; i++)
if (mtr >= pwrtbl[i].mtr && mtr < pwrtbl[i+1].mtr)
break;
if (mtr < 0) mtr = 0;
if (mtr > 20) mtr = 20;
mtr = (int)ceil(pwrtbl[i].pwr +
(pwrtbl[i+1].pwr - pwrtbl[i].pwr)*(mtr - pwrtbl[i].mtr)/(pwrtbl[i+1].mtr - pwrtbl[i].mtr));
if (mtr > 200) mtr = 200;
}
return mtr;
}
// RM cmd 0 ... 100 (rig values 0 ... 8)
// User report of RM; command using Send Cmd tab
// RM10000;RM20000;RM30000;
// RM1nnnn; => SWR
// RM2nnnn; => COMP
// RM3nnnn; => ALC
int RIG_TS480HX::get_swr()
{
int mtr = 0;
cmd = "RM;";
if (wait_char(';', 8, 100, "get SWR/ALC", ASC) < 8) return (int)mtr;
size_t p = replystr.rfind("RM1");
if (p != string::npos)
mtr = 66 * atoi(&replystr[p + 3]) / 10;
p = replystr.rfind("RM3");
if (p != string::npos)
alc = 66 * atoi(&replystr[p+3]) / 10;
else
alc = 0;
swralc_polled = true;
return mtr;
}
int RIG_TS480HX::get_alc(void)
{
if (!swralc_polled) get_swr();
swralc_polled = false;
return alc;
}
int RIG_TS480HX::set_widths(int val)
{
int bw;
if (val == 0 || val == 1 || val == 3) {
if (menu_45) {
bw = 0x8106; // 1500 Hz 2400 wide
dsp_SL = TS480HX_dataW;
SL_tooltip = TS480HX_dataW_tooltip;
SL_label = TS480HX_dataW_label;
dsp_SH = TS480HX_dataC;
SH_tooltip = TS480HX_dataC_tooltip;
SH_label = TS480HX_dataC_label;
bandwidths_ = TS480HX_dataW;
bw_vals_ = TS480HX_data_bw_vals;
} else {
bw = 0x8A03; // 200 ... 3000 Hz
dsp_SL = TS480HX_SL;
SL_tooltip = TS480HX_SL_tooltip;
SL_label = TS480HX_btn_SL_label;
dsp_SH = TS480HX_SH;
SH_tooltip = TS480HX_SH_tooltip;
SH_label = TS480HX_btn_SH_label;
bandwidths_ = TS480HX_SH;
bw_vals_ = TS480HX_HI_bw_vals;
}
} else if (val == 2 || val == 6) {
bandwidths_ = TS480HX_CWwidths;
bw_vals_ = TS480HX_CW_bw_vals;
dsp_SL = TS480HX_empty;
dsp_SH = TS480HX_empty;
bw = 7;
} else if (val == 5 || val == 7) {
bandwidths_ = TS480HX_FSKwidths;
bw_vals_ = TS480HX_FSK_bw_vals;
dsp_SL = TS480HX_empty;
dsp_SH = TS480HX_empty;
bw = 1;
} else { // val == 4 ==> AM
bandwidths_ = TS480HX_empty;
bw_vals_ = TS480HX_bw_vals;
dsp_SL = TS480HX_AM_SL;
dsp_SH = TS480HX_AM_SH;
bw = 0x8201;
}
return bw;
}
const char **RIG_TS480HX::bwtable(int m)
{
if (m == 0 || m == 1 || m == 3)
return TS480HX_empty;
else if (m == 2 || m == 6)
return TS480HX_CWwidths;
else if (m == 5 || m == 7)
return TS480HX_FSKwidths;
//else AM m == 4
return TS480HX_empty;
}
const char **RIG_TS480HX::lotable(int m)
{
if (m == 0 || m == 1 || m == 3)
return TS480HX_SL;
else if (m == 2 || m == 6)
return NULL;
else if (m == 5 || m == 7)
return NULL;
return TS480HX_AM_SL;
}
const char **RIG_TS480HX::hitable(int m)
{
if (m == 0 || m == 1 || m == 3)
return TS480HX_SH;
else if (m == 2 || m == 6)
return NULL;
else if (m == 5 || m == 7)
return NULL;
return TS480HX_AM_SH;
}
void RIG_TS480HX::set_modeA(int val)
{
if (val == 3) fm_mode = true;
else fm_mode = false;
A.imode = val;
cmd = "MD";
cmd += TS480HX_mode_chr[val];
cmd += ';';
sendCommand(cmd);
showresp(WARN, ASC, "set mode", cmd, "");
A.iBW = set_widths(val);
}
int RIG_TS480HX::get_modeA()
{
cmd = "MD;";
if (wait_char(';', 4, 100, "get modeA", ASC) < 4) return A.imode;
size_t p = replystr.rfind("MD");
if (p != string::npos && (p + 2 < replystr.length())) {
int md = replystr[p+2];
md = md - '1';
if (md == 8) md = 7;
A.imode = md;
A.iBW = set_widths(A.imode);
}
if (A.imode == 3) fm_mode = true;
else fm_mode = false;
return A.imode;
}
void RIG_TS480HX::set_modeB(int val)
{
if (val == 3) fm_mode = true;
else fm_mode = false;
B.imode = val;
cmd = "MD";
cmd += TS480HX_mode_chr[val];
cmd += ';';
sendCommand(cmd);
showresp(WARN, ASC, "set mode B", cmd, "");
B.iBW = set_widths(val);
}
int RIG_TS480HX::get_modeB()
{
cmd = "MD;";
if (wait_char(';', 4, 100, "get modeB", ASC) < 4) return B.imode;
size_t p = replystr.rfind("MD");
if (p != string::npos && (p + 2 < replystr.length())) {
int md = replystr[p+2];
md = md - '1';
if (md == 8) md = 7;
B.imode = md;
B.iBW = set_widths(B.imode);
}
if (B.imode == 3) fm_mode = true;
else fm_mode = false;
return B.imode;
}
int RIG_TS480HX::get_modetype(int n)
{
return _mode_type[n];
}
void RIG_TS480HX::set_bwA(int val)
{
if (A.imode == 0 || A.imode == 1 || A.imode == 3 || A.imode == 4) {
if (val < 256) return;
A.iBW = val;
cmd = "SL";
cmd.append(to_decimal(A.iBW & 0xFF, 2)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, SL_tooltip, cmd, "");
cmd = "SH";
cmd.append(to_decimal(((A.iBW >> 8) & 0x7F), 2)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, SH_tooltip, cmd, "");
}
if (val > 256) return;
else if (A.imode == 2 || A.imode == 6) {
A.iBW = val;
cmd = TS480HX_CWbw[A.iBW];
sendCommand(cmd);
showresp(WARN, ASC, "set CW bw", cmd, "");
}else if (A.imode == 5 || A.imode == 7) {
A.iBW = val;
cmd = TS480HX_FSKbw[A.iBW];
sendCommand(cmd);
showresp(WARN, ASC, "set FSK bw", cmd, "");
}
}
int RIG_TS480HX::get_bwA()
{
int i = 0;
size_t p;
bool menu45 = menu_45;
check_menu_45();
if (menu45 != menu_45)
Fl::awake(updateBandwidthControl);
if (A.imode == 0 || A.imode == 1 || A.imode == 3 || A.imode == 4) {
int lo = A.iBW & 0xFF, hi = (A.iBW >> 8) & 0x7F;
cmd = "SL;";
if (wait_char(';', 5, 100, "get SL", ASC) == 5) {
p = replystr.rfind("SL");
if (p != string::npos)
lo = fm_decimal(replystr.substr(p+2), 2);
}
cmd = "SH;";
if (wait_char(';', 5, 100, "get SH", ASC) == 5) {
p = replystr.rfind("SH");
if (p != string::npos)
hi = fm_decimal(replystr.substr(p+2), 2);
A.iBW = ((hi << 8) | (lo & 0xFF)) | 0x8000;
}
} else if (A.imode == 2 || A.imode == 6) {
cmd = "FW;";
if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
p = replystr.rfind("FW");
if (p != string::npos) {
for (i = 0; i < 11; i++)
if (replystr.find(TS480HX_CWbw[i]) == p)
break;
if (i == 11) i = 10;
A.iBW = i;
}
}
} else if (A.imode == 5 || A.imode == 7) {
cmd = "FW;";
if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
p = replystr.rfind("FW");
if (p != string::npos) {
for (i = 0; i < 4; i++)
if (replystr.find(TS480HX_FSKbw[i]) == p)
break;
if (i == 4) i = 3;
A.iBW = i;
}
}
}
return A.iBW;
}
void RIG_TS480HX::set_bwB(int val)
{
if (B.imode == 0 || B.imode == 1 || B.imode == 3 || B.imode == 4) {
if (val < 256) return;
B.iBW = val;
cmd = "SL";
cmd.append(to_decimal(B.iBW & 0xFF, 2)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, SL_tooltip, cmd, "");
cmd = "SH";
cmd.append(to_decimal(((B.iBW >> 8) & 0x7F), 2)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, SH_tooltip, cmd, "");
}
if (val > 256) return;
else if (B.imode == 2 || B.imode == 6) { // CW
B.iBW = val;
cmd = TS480HX_CWbw[B.iBW];
sendCommand(cmd);
showresp(WARN, ASC, "set CW bw", cmd, "");
}else if (B.imode == 5 || B.imode == 7) {
B.iBW = val;
cmd = TS480HX_FSKbw[B.iBW];
sendCommand(cmd);
showresp(WARN, ASC, "set FSK bw", cmd, "");
}
}
int RIG_TS480HX::get_bwB()
{
int i = 0;
size_t p;
bool menu45 = menu_45;
check_menu_45();
if (menu45 != menu_45)
Fl::awake(updateBandwidthControl);
if (B.imode == 0 || B.imode == 1 || B.imode == 3 || B.imode == 4) {
int lo = B.iBW & 0xFF, hi = (B.iBW >> 8) & 0x7F;
cmd = "SL;";
if (wait_char(';', 5, 100, "get SL", ASC) == 5) {
p = replystr.rfind("SL");
if (p != string::npos)
lo = fm_decimal(replystr.substr(p+2), 2);
}
cmd = "SH;";
if (wait_char(';', 5, 100, "get SH", ASC) == 5) {
p = replystr.rfind("SH");
if (p != string::npos)
hi = fm_decimal(replystr.substr(p+2), 2);
B.iBW = ((hi << 8) | (lo & 0xFF)) | 0x8000;
}
} else if (B.imode == 2 || B.imode == 6) {
cmd = "FW;";
if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
p = replystr.rfind("FW");
if (p != string::npos) {
for (i = 0; i < 11; i++)
if (replystr.find(TS480HX_CWbw[i]) == p)
break;
if (i == 11) i = 10;
B.iBW = i;
}
}
} else if (B.imode == 5 || B.imode == 7) {
cmd = "FW;";
if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
p = replystr.rfind("FW");
if (p != string::npos) {
for (i = 0; i < 4; i++)
if (replystr.find(TS480HX_FSKbw[i]) == p)
break;
if (i == 4) i = 3;
B.iBW = i;
}
}
}
return B.iBW;
}
int RIG_TS480HX::adjust_bandwidth(int val)
{
int bw = 0;
if (val == 0 || val == 1 || val == 3)
bw = 0x8A03;
else if (val == 4)
bw = 0x8201;
else if (val == 2 || val == 6)
bw = 7;
else if (val == 5 || val == 7)
bw = 1;
return bw;
}
int RIG_TS480HX::def_bandwidth(int val)
{
return adjust_bandwidth(val);
}
void RIG_TS480HX::set_power_control(double val)
{
cmd = "PC";
char szval[4];
if (modeA == 4 && val > 50) val = 50; // AM mode limitation
snprintf(szval, sizeof(szval), "%03d", (int)val);
cmd += szval;
cmd += ';';
LOG_WARN("%s", cmd.c_str());
sendCommand(cmd);
}
int RIG_TS480HX::get_power_control()
{
int val = progStatus.power_level;
cmd = "PC;";
if (wait_char(';', 6, 100, "get Power control", ASC) < 6) return val;
size_t p = replystr.rfind("PC");
if (p == string::npos) return val;
val = atoi(&replystr[p + 2]);
return val;
}
void RIG_TS480HX::set_attenuator(int val)
{
if (val) cmd = "RA01;";
else cmd = "RA00;";
LOG_WARN("%s", cmd.c_str());
sendCommand(cmd);
}
int RIG_TS480HX::get_attenuator()
{
cmd = "RA;";
if (wait_char(';', 7, 100, "get attenuator", ASC) < 7) return progStatus.attenuator;
size_t p = replystr.rfind("RA");
if (p == string::npos) return progStatus.attenuator;
if (replystr[p+3] == '1') return 1;
return 0;
}
void RIG_TS480HX::set_preamp(int val)
{
if (val) cmd = "PA1;";
else cmd = "PA0;";
LOG_WARN("%s", cmd.c_str());
sendCommand(cmd);
}
int RIG_TS480HX::get_preamp()
{
cmd = "PA;";
if (wait_char(';', 5, 100, "get preamp", ASC) < 5) return progStatus.preamp;
size_t p = replystr.rfind("PA");
if (p == string::npos) return progStatus.preamp;
if (replystr[p+2] == '1') return 1;
return 0;
}
void RIG_TS480HX::set_if_shift(int val)
{
cmd = "IS+";
if (val < 0) cmd[2] = '-';
cmd.append(to_decimal(abs(val),4)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, "set IF shift", cmd, "");
}
bool RIG_TS480HX::get_if_shift(int &val)
{
cmd = "IS;";
if (wait_char(';', 8, 100, "get IF shift", ASC) == 8) {
size_t p = replystr.rfind("IS");
if (p != string::npos) {
val = fm_decimal(replystr.substr(p+3), 4);
if (replystr[p+2] == '-') val *= -1;
return (val != 0);
}
}
val = progStatus.shift_val;
return progStatus.shift;
}
void RIG_TS480HX::get_if_min_max_step(int &min, int &max, int &step)
{
if_shift_min = min = -1100;
if_shift_max = max = 1100;
if_shift_step = step = 10;
if_shift_mid = 0;
}
// Noise Reduction (TS2000.cxx) NR1 only works; no NR2 and don' no why
void RIG_TS480HX::set_noise_reduction(int val)
{
if (val == -1) {
return;
}
_noise_reduction_level = val;
if (_noise_reduction_level == 0) {
nr_label("NR", false);
} else if (_noise_reduction_level == 1) {
nr_label("NR1", true);
} else if (_noise_reduction_level == 2) {
nr_label("NR2", true);
}
cmd.assign("NR");
cmd += '0' + _noise_reduction_level;
cmd += ';';
sendCommand (cmd);
showresp(WARN, ASC, "SET noise reduction", cmd, "");
}
int RIG_TS480HX::get_noise_reduction()
{
cmd = rsp = "NR";
cmd.append(";");
if (wait_char(';', 4, 100, "GET noise reduction", ASC) == 4) {
size_t p = replystr.rfind(rsp);
if (p == string::npos) return _noise_reduction_level;
_noise_reduction_level = replystr[p+2] - '0';
}
if (_noise_reduction_level == 1) {
nr_label("NR1", true);
} else if (_noise_reduction_level == 2) {
nr_label("NR2", true);
} else {
nr_label("NR", false);
}
return _noise_reduction_level;
}
void RIG_TS480HX::set_noise_reduction_val(int val)
{
if (_noise_reduction_level == 0) return;
if (_noise_reduction_level == 1) _nrval1 = val;
else _nrval2 = val;
cmd.assign("RL").append(to_decimal(val, 2)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, "SET_noise_reduction_val", cmd, "");
}
int RIG_TS480HX::get_noise_reduction_val()
{
int nrval = 0;
if (_noise_reduction_level == 0) return 0;
int val = progStatus.noise_reduction_val;
cmd = rsp = "RL";
cmd.append(";");
if (wait_char(';', 5, 100, "GET noise reduction val", ASC) == 5) {
size_t p = replystr.rfind(rsp);
if (p == string::npos) {
nrval = (_noise_reduction_level == 1 ? _nrval1 : _nrval2);
return nrval;
}
val = atoi(&replystr[p+2]);
}
if (_noise_reduction_level == 1) _nrval1 = val;
else _nrval2 = val;
return val;
}
int RIG_TS480HX::get_agc()
{
cmd = "GT;";
wait_char(';', 6, 100, "GET agc val", ASC);
size_t p = replystr.rfind("GT");
if (p == string::npos) return agcval;
if (replystr[4] == ' ') return 0;
agcval = replystr[4] - '0' + 1; // '0' == off, '1' = fast, '2' = slow
return agcval;
}
int RIG_TS480HX::incr_agc()
{
if (fm_mode) return 0;
agcval++;
if (agcval == 4) agcval = 1;
cmd.assign("GT00");
cmd += (agcval + '0' - 1);
cmd += ";";
sendCommand(cmd);
showresp(WARN, ASC, "SET agc", cmd, replystr);
return agcval;
}
static const char *agcstrs[] = {"FM", "AGC", "FST", "SLO"};
const char *RIG_TS480HX::agc_label()
{
if (fm_mode) return agcstrs[0];
return agcstrs[agcval];
}
int RIG_TS480HX::agc_val()
{
if (fm_mode) return 0;
return agcval;
}
// Auto Notch, beat canceller (TS2000.cxx) BC1 only, not BC2
void RIG_TS480HX::set_auto_notch(int v)
{
cmd = v ? "BC1;" : "BC0;";
sendCommand(cmd);
showresp(WARN, ASC, "set auto notch", cmd, "");
}
int RIG_TS480HX::get_auto_notch()
{
cmd = "BC;";
if (wait_char(';', 4, 100, "get auto notch", ASC) == 4) {
int anotch = 0;
size_t p = replystr.rfind("BC");
if (p != string::npos) {
anotch = (replystr[p+2] == '1');
return anotch;
}
}
return 0;
}
// Noise Blanker (TS2000.cxx)
void RIG_TS480HX::set_noise(bool b)
{
if (b)
cmd = "NB1;";
else
cmd = "NB0;";
sendCommand(cmd);
showresp(WARN, ASC, "set NB", cmd, "");
}
int RIG_TS480HX::get_noise()
{
cmd = "NB;";
if (wait_char(';', 4, 100, "get Noise Blanker", ASC) == 4) {
size_t p = replystr.rfind("NB");
if (p == string::npos) return 0;
if (replystr[p+2] == '0') return 0;
}
return 1;
}
// Tranceiver PTT on/off
void RIG_TS480HX::set_PTT_control(int val)
{
if (val) {
if (progStatus.data_port) cmd = "TX1;"; // DTS transmission using ANI input
else cmd = "TX0;"; // mic input
} else cmd = "RX;";
sendCommand(cmd);
showresp(WARN, ASC, "set PTT", cmd, "");
}
int RIG_TS480HX::get_PTT()
{
cmd = "IF;";
int ret = wait_char(';', 38, 100, "get VFO", ASC);
if (ret < 38) return ptt_;
ptt_ = (replybuff[28] == '1');
return ptt_;
}
void RIG_TS480HX::set_rf_gain(int val)
{
cmd = "RG";
cmd.append(to_decimal(val,3)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, "set rf gain", cmd, "");
}
int RIG_TS480HX::get_rf_gain()
{
int val = progStatus.rfgain;
cmd = "RG;";
if (wait_char(';', 6, 100, "get rf gain", ASC) < 6) return val;
size_t p = replystr.rfind("RG");
if (p != string::npos)
val = fm_decimal(replystr.substr(p+2), 3);
return val;
}
void RIG_TS480HX::get_rf_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 100; step = 1;
}
/*
void RIG_TS480HX::selectA()
{
cmd = "FR0;FT0;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on A, Tx on A", cmd, "");
}
void RIG_TS480HX::selectB()
{
cmd = "FR1;FT1;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on B, Tx on B", cmd, "");
}
void RIG_TS480HX::set_split(bool val)
{
split = val;
if (useB) {
if (val) {
cmd = "FR1;FT0;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on B, Tx on A", cmd, "");
} else {
cmd = "FR1;FT1;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on B, Tx on B", cmd, "");
}
} else {
if (val) {
cmd = "FR0;FT1;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on A, Tx on B", cmd, "");
} else {
cmd = "FR0;FT0;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on A, Tx on A", cmd, "");
}
}
}
bool RIG_TS480HX::can_split()
{
return true;
}
int RIG_TS480HX::get_split()
{
size_t p;
int split = 0;
char rx = 0, tx = 0;
// tx vfo
cmd = rsp = "FT";
cmd.append(";");
if (wait_char(';', 4, 100, "get split tx vfo", ASC) == 4) {
p = replystr.rfind(rsp);
if (p == string::npos) return split;
tx = replystr[p+2];
}
// rx vfo
cmd = rsp = "FR";
cmd.append(";");
if (wait_char(';', 4, 100, "get split rx vfo", ASC) == 4) {
p = replystr.rfind(rsp);
if (p == string::npos) return split;
rx = replystr[p+2];
// split test
split = (tx == '1' ? 2 : 0) + (rx == '1' ? 1 : 0);
}
return split;
}
long RIG_TS480HX::get_vfoA ()
{
cmd = "FA;";
if (wait_char(';', 14, 100, "get vfo A", ASC) < 14) return A.freq;
size_t p = replystr.rfind("FA");
if (p != string::npos && (p + 12 < replystr.length())) {
int f = 0;
for (size_t n = 2; n < 13; n++)
f = f*10 + replystr[p+n] - '0';
A.freq = f;
}
return A.freq;
}
void RIG_TS480HX::set_vfoA (long freq)
{
A.freq = freq;
cmd = "FA00000000000;";
for (int i = 12; i > 1; i--) {
cmd[i] += freq % 10;
freq /= 10;
}
sendCommand(cmd);
showresp(WARN, ASC, "set vfo A", cmd, "");
}
long RIG_TS480HX::get_vfoB ()
{
cmd = "FB;";
if (wait_char(';', 14, 100, "get vfo B", ASC) < 14) return B.freq;
size_t p = replystr.rfind("FB");
if (p != string::npos && (p + 12 < replystr.length())) {
int f = 0;
for (size_t n = 2; n < 13; n++)
f = f*10 + replystr[p+n] - '0';
B.freq = f;
}
return B.freq;
}
void RIG_TS480HX::set_vfoB (long freq)
{
B.freq = freq;
cmd = "FB00000000000;";
for (int i = 12; i > 1; i--) {
cmd[i] += freq % 10;
freq /= 10;
}
sendCommand(cmd);
showresp(WARN, ASC, "set vfo B", cmd, "");
}
// Squelch (TS990.cxx)
void RIG_TS480HX::set_squelch(int val)
{
cmd = "SQ0";
cmd.append(to_decimal(abs(val),3)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "set squelch", cmd, "");
}
int RIG_TS480HX::get_squelch()
{
int val = 0;
cmd = "SQ0;";
if (wait_char(';', 7, 20, "get squelch", ASC) >= 7) {
size_t p = replystr.rfind("SQ0");
if (p == string::npos) return val;
replystr[p + 6] = 0;
val = atoi(&replystr[p + 3]);
}
return val;
}
void RIG_TS480HX::get_squelch_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 255; step = 1;
}
void RIG_TS480HX::set_mic_gain(int val)
{
cmd = "MG";
cmd.append(to_decimal(val,3)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, "set mic gain", cmd, "");
}
int RIG_TS480HX::get_mic_gain()
{
int val = progStatus.mic_gain;
cmd = "MG;";
if (wait_char(';', 6, 100, "get mic gain", ASC) < 6) return val;
size_t p = replystr.rfind("MG");
if (p != string::npos)
val = fm_decimal(replystr.substr(p+2), 3);
return val;
}
void RIG_TS480HX::get_mic_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 100; step = 1;
}
void RIG_TS480HX::set_volume_control(int val)
{
cmd = "AG";
char szval[5];
snprintf(szval, sizeof(szval), "%04d", val * 255 / 100);
cmd += szval;
cmd += ';';
LOG_WARN("%s", cmd.c_str());
sendCommand(cmd);
}
int RIG_TS480HX::get_volume_control()
{
int val = progStatus.volume;
cmd = "AG0;";
if (wait_char(';', 7, 100, "get vol", ASC) < 7) return val;
size_t p = replystr.rfind("AG");
if (p == string::npos) return val;
replystr[p + 6] = 0;
val = atoi(&replystr[p + 3]);
val = val * 100 / 255;
return val;
}
void RIG_TS480HX::tune_rig()
{
cmd = "AC111;";
LOG_WARN("%s", cmd.c_str());
sendCommand(cmd);
}
*/
flrig-1.3.49/src/rigs/AOR5K.cxx 0000644 0001750 0001750 00000026314 13472116064 012746 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
// AOR 5000 driver based on several other drivers as examples.
// Written 05/2017 by Mario Lorenz, dl5mlo@amsat-dl.org
#include "AOR5K.h"
#include "status.h"
const char AOR5Kname_[] = "AOR-5000";
const char *AOR5Kmodes_[] =
{ "FM", "AM", "LSB", "USB", "CW", "SAM", "SAL", "SAH", NULL};
const char modenbr[] =
{ '0', '1', '2', '3', '4', '5', '6', '7' };
static const char AOR5K_mode_type[] =
{ 'U', 'U', 'L', 'U', 'U', 'U', 'U', 'L' };
static const char *AOR5K_IF_widths[] = {
"500", "3000", "6000", "15000", "40000", "110000", "220000", NULL};
static int AOR5K_IF_bw_vals[] = {
0, 1, 2, 3, 4, 5, 6, WVALS_LIMIT};
static int def_mode_width[] = { 3, 2, 1, 1, 0, 1, 1, 1 };
static const char *AOR5K_SL_label = "HPF";
static const char *AOR5K_SL[] = { "50", "200", "300", "400", NULL };
static const char *AOR5K_SH_label = "LPF";
static const char *AOR5K_SH[] = { "3000", "4000", "6000", "12000", NULL };
static GUI aor5k_widgets[]= {
{ (Fl_Widget *)btnVol, 2, 125, 50 },
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 },
// { (Fl_Widget *)btnAGC, 2, 145, 50 },
// { (Fl_Widget *)sldrSQUELCH, 266, 125, 156 },
// { (Fl_Widget *)btnNotch, 214, 145, 50 },
// { (Fl_Widget *)sldrNOTCH, 266, 145, 156 },
{ (Fl_Widget *)NULL, 0, 0, 0 }
};
RIG_AOR5K::RIG_AOR5K() {
// base class values
name_ = AOR5Kname_;
modes_ = AOR5Kmodes_;
bandwidths_ = AOR5K_IF_widths;
bw_vals_ = AOR5K_IF_bw_vals;
dsp_SL = AOR5K_SL;
SL_tooltip = AOR5K_SL_label;
SL_label = AOR5K_SL_label;
dsp_SH = AOR5K_SH;
SH_tooltip = AOR5K_SH_label;
SH_label = AOR5K_SH_label;
comm_baudrate = BR9600;
widgets = aor5k_widgets;
stopbits = 2;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_rtscts = false;
comm_rtsplus = false;
comm_dtrplus = false;
comm_catptt = false;
comm_rtsptt = false;
comm_dtrptt = false;
def_freq = freqA = freqB = 14070000;
def_mode = modeA = modeB = 1;
def_bw = bwA = bwB = 1;
has_volume_control =
has_mode_control =
has_bandwidth_control =
has_noise_control =
has_attenuator_control =
has_agc_control =
has_smeter =
has_agc_level =
has_vfoAB =
can_change_alt_vfo =
has_dsp_controls =
true;
has_notch_control =
has_sql_control =
has_xcvr_auto_on_off =
has_a2b =
has_b2a =
has_vfo_adj =
has_rit =
has_xit =
has_bfo =
has_power_control =
has_micgain_control =
has_mic_line_control =
has_auto_notch =
has_noise_reduction_control =
has_noise_reduction =
has_preamp_control =
has_ifshift_control =
has_ptt_control =
has_tune_control =
has_swr_control =
has_alc_control =
has_rf_control =
has_power_out =
has_split =
has_split_AB =
has_data_port =
has_getvfoAorB =
has_extras =
has_nb_level =
has_cw_wpm =
has_cw_vol =
has_cw_spot =
has_cw_spot_tone =
has_cw_qsk =
has_cw_break_in =
has_cw_delay =
has_cw_weight =
has_cw_keyer =
has_vox_onoff =
has_vox_gain =
has_vox_anti =
has_vox_hang =
has_vox_on_dataport =
has_compression =
has_compON =
use_line_in =
has_bpf_center =
has_special =
has_ext_tuner =
has_band_selection = false;
precision = 1;
ndigits = 10;
atten_level = 0;
agcval = 0;
}
int RIG_AOR5K::adjust_bandwidth(int m)
{
return def_mode_width[m];
}
int RIG_AOR5K::def_bandwidth(int m)
{
return def_mode_width[m];
}
#define AOR5K_WAIT_TIME 800
extern int report_level;
void RIG_AOR5K::initialize()
{
debug::level = debug::INFO_LEVEL;
LOG_INFO("AOR5K");
aor5k_widgets[0].W = btnVol;
aor5k_widgets[1].W = sldrVOLUME;
// aor5k_widgets[2].W = btnAGC;
// aor5k_widgets[3].W = sldrSQUELCH;
// aor5k_widgets[4].W = btnNotch;
// aor5k_widgets[5].W = sldrNOTCH;
// aor5k_widgets[6].W = sldrPOWER;
report_level = INFO;
// cmd = "AI0;"; // disable auto-info
// sendCommand(cmd);
// showresp(INFO, ASC, "disable auto-info", cmd, replystr);
get_vfoA();
get_modeA();
get_bwA();
get_vfoB();
get_modeB();
get_bwB();
set_split(false); // normal ops
}
void RIG_AOR5K::shutdown()
{
}
void RIG_AOR5K::selectA() {
cmd = "VE\r";
wait_char('\r', 1, AOR5K_WAIT_TIME, "Select VFO A", ASC);
}
void RIG_AOR5K::selectB() {
cmd = "VB\r";
wait_char('\r', 1, AOR5K_WAIT_TIME, "Select VFO B", ASC);
}
bool RIG_AOR5K::check()
{
cmd = "RX\r";
int ret = wait_char('\r', 34, AOR5K_WAIT_TIME, "get vfo A", ASC);
if (ret < 34) return false;
return true;
}
long RIG_AOR5K::get_vfoA ()
{
cmd = "RX\r";
int ret = wait_char('\r', 34, AOR5K_WAIT_TIME, "get vfo A", ASC);
if (ret < 34) return freqA;
size_t p = replystr.rfind("RF");
if (p == string::npos) return freqA;
if (p < 3) return freqA;
if (replystr[p-2] =='E') {
// VFO A is active. Instead of A we use E
long f = 0;
for (size_t n = 2; n < 12; n++)
f = f*10 + replystr[p + n] - '0';
freqA = f;
}
return freqA;
}
void RIG_AOR5K::set_vfoA (long freq)
{
freqA = freq;
cmd = "VE0000000000\r";
for (int i = 11; i > 1; i--) {
cmd[i] += freq % 10;
freq /= 10;
}
wait_char('\r', 1, AOR5K_WAIT_TIME, "set VFO A", ASC);
}
long RIG_AOR5K::get_vfoB ()
{
cmd = "RX\r";
int ret = wait_char('\r', 34, AOR5K_WAIT_TIME, "get vfo B", ASC);
if (ret < 34) return freqB;
size_t p = replystr.rfind("RF");
if (p == string::npos) return freqB;
if (p < 3) return freqB;
if (replystr[p-2] == 'B') {
// VFO B active
long f = 0;
for (size_t n = 2; n < 12; n++)
f = f*10 + replystr[p + n] - '0';
freqB = f;
}
return freqB;
}
void RIG_AOR5K::set_vfoB (long freq)
{
freqB = freq;
cmd = "VB0000000000\r";
for (int i = 11; i > 1; i--) {
cmd[i] += freq % 10;
freq /= 10;
}
wait_char('\r', 1, AOR5K_WAIT_TIME, "set VFO B", ASC);
}
// Volume control
void RIG_AOR5K::set_volume_control(int val)
{
cmd = "VL000\r";
for (int i = 4; i > 1; i--) {
cmd[i] += val % 10;
val /= 10;
}
wait_char('\r', 1, AOR5K_WAIT_TIME, "set Vol", ASC);
}
int RIG_AOR5K::get_volume_control()
{
cmd = "VL\r";
int ret = wait_char('\r', 5, AOR5K_WAIT_TIME, "get volume", ASC);
if (ret < 5) return progStatus.volume;
size_t p = replystr.rfind("VL");
if (p == string::npos) return 0;
replystr[p + 5] = 0;
int v = atoi(&replystr[p + 2]);
return v;
}
void RIG_AOR5K::get_vol_min_max_step(int &min, int &max, int &step) {
min = 0; max = 255; step = 1;
}
void RIG_AOR5K::set_modeA(int val)
{
modeA = val;
cmd = "MD0\r";
cmd[2] = modenbr[val];
wait_char('\r', 1, AOR5K_WAIT_TIME, "set mode A", ASC);
//sendCommand(cmd);
//showresp(INFO, ASC, "set mode A", cmd, replystr);
//cmd="RX\r";
}
int RIG_AOR5K::get_modeA()
{
cmd = "MD\r";
int ret = wait_char('\r', 4, AOR5K_WAIT_TIME, "get mode A", ASC);
if (ret < 4) return modeA;
size_t p = replystr.rfind("MD");
if (p == string::npos) return modeA;
int md = replystr[p + 2] - '0';
if (md > 8) md=0;
return (modeA = md);
}
void RIG_AOR5K::set_modeB(int val)
{
modeB = val;
set_modeA(val); // Fake ModeB -- mode setting is not per VFO
}
int RIG_AOR5K::get_modeB()
{
// Fake ModeB
return (modeB = get_modeA());
}
int RIG_AOR5K::get_modetype(int n)
{
return AOR5K_mode_type[n];
}
int RIG_AOR5K::next_attenuator()
{
switch (atten_level) {
case 0: return 1;
case 1: return 2;
case 2: return 22;
case 22: return 0;
}
return 0;
}
void RIG_AOR5K::set_attenuator(int val)
{
atten_level = val;
switch (atten_level) {
case 1:
cmd = "AT1\r";
atten_label("10 dB", true);
break;
case 2:
cmd = "AT2\r";
atten_label("20 dB", true);
break;
case 22:
cmd = "ATF\r";
atten_label("AUTO", true);
break;
case 0:
default:
cmd = "AT0\r";
atten_label("0 dB", false);
break;
}
wait_char('\r', 1, AOR5K_WAIT_TIME, "set BW A", ASC);
}
int RIG_AOR5K::get_attenuator()
{
cmd = "AT\r";
int ret = wait_char('\r', 4, AOR5K_WAIT_TIME, "get ATT", ASC);
if (ret < 4) return atten_level;
size_t p = replystr.rfind("AT");
if (p == string::npos) return atten_level;
if (replystr[p+2] == '1')
atten_level = 22;
else atten_level = replystr[p + 3] - '0';
switch (atten_level) {
case 0: atten_label("0 dB", false); break;
case 1: atten_label("10 dB", true); break;
case 2: atten_label("20 dB", true); break;
case 22: atten_label("AUTO", true); break;
}
return atten_level;
}
//SM $ (S-meter Read; GET only)
int RIG_AOR5K::get_smeter()
{
cmd = "LM\r";
int ret = wait_char('\r', 7, AOR5K_WAIT_TIME, "get Smeter", ASC);
if (ret < 6) return 0;
size_t p = replystr.rfind("LM");
if (p == string::npos) return 0;
replystr[p+5] ='\0';
int mtr = strtoul(&replystr[p+3], NULL, 16); // encoded in hex. S-Meter mapping TBD
return int(floor(float(mtr)/2.55)); // 0...100 is legal range
}
void RIG_AOR5K::set_noise(bool on)
{
if (on)
cmd = "NB1\r";
else
cmd = "NB0\r";
wait_char('\r', 1, AOR5K_WAIT_TIME, "set Noise Blanker", ASC);
}
int RIG_AOR5K::get_noise()
{
cmd = "NB\r";
int ret = wait_char('\r', 4, AOR5K_WAIT_TIME, "get Noise Blanker", ASC);
if (ret < 4) return progStatus.noise;
size_t p = replystr.rfind("NB");
if (p == string::npos) return progStatus.noise;
return (replystr[p+2] == '1' ? 1 : 0);
}
// FW $ (Filter Bandwidth and Number; GET/SET)
// K3 Extended SET/RSP format (K31): FWxxxx; where xxxx is 0-9999, the bandwidth
// in 10-Hz units. May be quantized and/or range limited based on the present
// operating mode.
void RIG_AOR5K::set_bwA(int val)
{
cmd = "BW0\r";
bwA = val;
cmd[2] = '0' + val;
wait_char('\r', 4, AOR5K_WAIT_TIME, "set BW A", ASC);
}
int RIG_AOR5K::get_bwA()
{
cmd = "BW\r";
int ret = wait_char('\r', 4, AOR5K_WAIT_TIME, "get bandwidth A", ASC);
if (ret < 4) return bwA;
size_t p = replystr.rfind("BW");
if (p == string::npos) return bwA;
return (bwA = replystr[p+2] - '0');
}
void RIG_AOR5K::set_bwB(int val)
{
bwB = val;
set_bwA(val);
}
int RIG_AOR5K::get_bwB()
{
return (bwB = get_bwA());
}
int RIG_AOR5K::get_agc() {
cmd = "AC\r";
int ret = wait_char('\r', 4, AOR5K_WAIT_TIME, "get AGC", ASC);
if (ret < 4) return agcval;
size_t p = replystr.rfind("AC");
if (p == string::npos) return agcval;
int agci = replystr[p+2] - '0';
switch (agci) {
case 0: agcval = 1; break;
case 1: agcval = 2; break;
case 2: agcval = 3 ; break;
case 22: agcval = 0; break;
}
return agcval;
}
int RIG_AOR5K::incr_agc() {
agcval++;
if (agcval >= 4) agcval = 0;
switch(agcval) {
case 0: cmd = "ACF\r"; break;
case 1: cmd = "AC0\r"; break;
case 2: cmd = "AC1\r"; break;
case 3: cmd = "AC2\r"; break;
}
wait_char('\r', 1, AOR5K_WAIT_TIME, "set AGC", ASC);
return agcval;
}
static const char *agcstrs[] = {"AGC", "AGF" , "AGM", "AGS"};
const char* RIG_AOR5K::agc_label() {
return agcstrs[agcval];
}
int RIG_AOR5K::agc_val() {
return agcval;
}
flrig-1.3.49/src/rigs/IC728.cxx 0000644 0001750 0001750 00000004700 13472116064 012654 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include "IC728.h"
//=============================================================================
// IC-728
//
const char IC728name_[] = "IC-728";
const char *IC728modes_[] = { "LSB", "USB", "AM", "CW", "RTTY", "FM", NULL};
const char *IC728_widths[] = { "NARR", "WIDE", NULL};
static int IC728_bw_vals[] = {1,2, WVALS_LIMIT};
RIG_IC728::RIG_IC728() {
name_ = IC728name_;
modes_ = IC728modes_;
bandwidths_ = IC728_widths;
bw_vals_ = IC728_bw_vals;
comm_baudrate = BR1200;
stopbits = 2;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_echo = true;
comm_rtscts = false;
comm_rtsplus = true;
comm_dtrplus = true;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
modeA = 1;
bwA = 0;
defaultCIV = 0x38;
adjustCIV(defaultCIV);
precision = 10;
ndigits = 7;
};
//=============================================================================
bool RIG_IC728::check ()
{
string resp = pre_fm;
resp += '\x03';
cmd = pre_to;
cmd += '\x03';
cmd.append( post );
bool ok = waitFOR(10, "check vfo");
rig_trace(2, "check()", str2hex(replystr.c_str(), replystr.length()));
return ok;
}
long RIG_IC728::get_vfoA ()
{
string cstr = "\x03";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(10, "get vfo A")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
freqA = fm_bcd_be(replystr.substr(p+5), 8);
}
return freqA;
}
void RIG_IC728::set_vfoA (long freq)
{
freqA = freq;
cmd = pre_to;
cmd += '\x05';
cmd.append( to_bcd_be( freq, 8 ) );
cmd.append( post );
waitFB("set vfo A");
}
flrig-1.3.49/src/rigs/PCR1000.cxx 0000644 0001750 0001750 00000110432 13472116065 013046 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
/*
* Driver for PCR-1000 April 2012, Brian Miezejewski, k5hfi
* patched 1/23/2017, Dave, G0WBX
*/
/* Todo:
*
* 1) Need on/off button to turn the radio on and off?
* 2) Up the baud rate to 37800 after connect
* 3) Support for fast mode.
* 4) Scan support for scanning between a frequency pair
* 5) Scan support for scanning a list of frequencies stored in flrig.
* 6) Implement band scope.
* 7) BFO support?
*
*/
/* Notes:
* The Icom PCR-1000 differs for most of the other rigs controlled by flrig in
* that settings do not change at the rig, they are all controlled by flrig. There is
* no reason to poll for frequency, volume, mode, etc., they simply can't change on their own.
* On the other hand, things like s-meter reading do change, but the PCR-1000 will send these
* with no poll needed when the receiver is in "fast" mode.
*
* Note that while the PCR-1000 does not have a second VFO, we have virtualized a second
* vfo in the PCR-1000 flrig implementation. Each VFO stores its frequency, mode, and bandwidth.
* The XCVR_STATE variable is used to store the VFO states.
*/
#include "config.h"
#include "PCR1000.h"
#include "support.h"
//----------------------------------------------------------------------
inline string str(string s)
{
size_t p;
while((p = s.find('\r')) != string::npos)
s.replace(p, 1, "");
while((p = s.find('\n')) != string::npos)
s.replace(p, 1, "");
return s;
}
#define strace(s, s1) set_trace(3, s, str(s1).c_str(), str(replystr).c_str());
#define gtrace(s, s1) get_trace(3, s, str(s1).c_str(), str(replystr).c_str());
//----------------------------------------------------------------------
const char RIG_PCR1000::name[] = "PCR-1000";
// mode array Index Values :- 0 1 2 3 4 5
const char *RIG_PCR1000::modes[] = { "LSB", "USB", "AM", "CW", "NFM", "WFM", NULL};
const char RIG_PCR1000::mode_chr[] = { '0', '1', '2', '3', '5', '6' };
const char RIG_PCR1000::mode_type[] = { 'L', 'U', 'U', 'U', 'U', 'U' };
// band width array Index Values :- 0 1 2 3 4
const char *RIG_PCR1000::band_widths[] = { "2.8k","6k","15k","50k","230k",NULL};
static int PCR1000_bw_vals[] = {1,2,3,4,5,WVALS_LIMIT};
//----------------------------------------------------------------------
// Array used for the conversion of hex values to a character string
const char RIG_PCR1000::hex_chars[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ;
//----------------------------------------------------------------------
char RIG_PCR1000::volume_command[] = "J40XX\r\n" ;
char RIG_PCR1000::squelch_command[] = "J41XX\r\n" ;
char RIG_PCR1000::if_shift_command[] = "J43XX\r\n" ;
const char RIG_PCR1000::noise_off_command[] = "J4600\r\n" ;
const char RIG_PCR1000::noise_on_command[] = "J4601\r\n" ;
const char RIG_PCR1000::att_off_command[] = "J4700\r\n" ;
const char RIG_PCR1000::att_on_command[] = "J4701\r\n" ;
char RIG_PCR1000::check_power_command[] = "H1?" ;
char RIG_PCR1000::power_on_command[] = "H101\r\n" ;
char RIG_PCR1000::power_off_command[] = "H100\r\n" ;
const char RIG_PCR1000::get_smeter_command[] = "I1?" ;
//----------------------------------------------------------------------
//----------------------------------------------------------------------
static GUI rig_widgets[]= {
{ (Fl_Widget *)btnVol, 2, 125, 50 },
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 },
{ (Fl_Widget *)NULL, 0, 0, 0 }
};
//----------------------------------------------------------------------
/*
* A PCR-1000 will start issuing repeating H100 to indicate its status as
* off as soon as you connect to it. It will start at 9600-n-1 and uses rts/cts for
* transaction control.
*/
void RIG_PCR1000::initialize()
{
rig_widgets[0].W = btnVol;
rig_widgets[1].W = sldrVOLUME;
modes_ = modes;
bandwidths_ = band_widths;
bw_vals_ = PCR1000_bw_vals;
selectA();
// Lets see if the radio is turned on.
sendCommand(check_power_command,6);
showresp(WARN, ASC, "Check Power", check_power_command , replystr);
gtrace("Check Power", check_power_command);
// If the radio is turned off, turn it on.
if (replystr.rfind("H100") != std::string::npos) {
sendCommand(power_on_command,6);
showresp(WARN, ASC, "Power ON", power_on_command , replystr);
strace("Power ON", power_on_command);
}
// Set the radio with the default values
set_volume_control(current_volume) ;
set_squelch(sql);
set_if_shift(if_shift); // mid = off // wbx
}
bool RIG_PCR1000::check()
{
return true;
}
//----------------------------------------------------------------------
RIG_PCR1000::RIG_PCR1000() : current_vfo(A) {
// current_vfo = A ;
name_ = name;
modes_ = modes;
bandwidths_ = band_widths;
widgets = rig_widgets;
comm_baudrate = BR9600;
stopbits = 1;
comm_retries = 2;
comm_wait = 50;
comm_timeout = 50;
comm_rtscts = true;
comm_rtsplus = false;
comm_dtrplus = false;
comm_catptt = false;
comm_rtsptt = false;
comm_dtrptt = false;
// Defaults.
A.imode = 1;
A.freq = 14070000L;
A.iBW = 0 ;
B.imode = 1;
B.freq = 14070000L;
B.iBW = 0 ;
sql = 127 ; // Set squelch to a reasonable value
if_shift = 0 ; // IF shift off
attenuator = 0 ; // Attenuator is set to off
noise = 0 ; // Noise blanker to off
current_volume = 25 ; // Set volume to make at least a little noise, otherwise there is no
// indication when the radio is switched on.
has_micgain_control =
has_notch_control =
has_swr_control = false;
has_smeter =
has_bandwidth_control =
has_volume_control =
has_mode_control =
has_sql_control =
has_noise_control =
has_attenuator_control =
has_ifshift_control = true;
precision = 10 ;
ndigits = 9 ;
}
//----------------------------------------------------------------------
void RIG_PCR1000::shutdown() {
// Turn off the radio
sendCommand(power_off_command,6);
strace("Power OFF", power_off_command);
showresp(WARN, ASC, "Power OFF", power_off_command , replystr);
}
//----------------------------------------------------------------------
/*
* Set the frequency in the current mode command
*/
void RIG_PCR1000::setFreqModeBW(XCVR_STATE &freqMode) {
RIG_PCR1000::freq_cmd myComm = {
{'K','0'},
{'0','0','0','7','2','0','0','0','0','0'},
{'0','0'},
{'0','0'},
{'0','0','\r','\n','\0'}
} ;
// Set the mode
myComm.mode[1] = mode_chr[ freqMode.imode ] ;
// Set the frequency in the selected mode command
long freq = freqMode.freq ;
for( int pos = 9 ; pos >= 0 ; pos--,freq /= 10 ) {
myComm.frequency[pos] = '0'+(freq%10) ;
}
// Set the band width
myComm.band_width[1] = '0'+ freqMode.iBW ;
// printf("Freq:%s",myComm.command);
sendCommand(myComm.command,5);
showresp(WARN, ASC, "set vfo", myComm.command, replystr);
strace("set vfo", myComm.command);
}
//----------------------------------------------------------------------
/*
* The PCR-1000 cannot change its frequency so it is always whatever we last set it to
*/
//----------------------------------------------------------------------
void RIG_PCR1000::set_vfoA (long freq)
{
freqA = A.freq = freq;
setFreqModeBW(A) ;
}
long RIG_PCR1000::get_vfoA ()
{
return A.freq;
}
//----------------------------------------------------------------------
void RIG_PCR1000::set_vfoB (long freq)
{
freqB = B.freq = freq;
setFreqModeBW(B) ;
}
long RIG_PCR1000::get_vfoB ()
{
return B.freq;
}
//======================================================================
// Some utility functions
//======================================================================
/*
* This method converts a character to its hex values, i.e.
* '0' = 0
* '5' = 5
* 'A' = 10
*
*/
int RIG_PCR1000::hexTo(const char c) const {
return ( c <= '9') ? c - '0' : c - 'A' + 10 ;
}
/*
* This method sets the value of ival into the first 2 characters in cptr, i.e.
* 17 is converted to "11"
* 37 is converted to "25"
*
*/
void RIG_PCR1000::set2Hex(int ival, char *cptr) {
cptr[0] = hex_chars[ival / 16] ;
cptr[1] = hex_chars[ival % 16] ;
}
//----------------------------------------------------------------------
int RIG_PCR1000::get_smeter() { // returns 0-100
int ret = sendCommand(get_smeter_command,6) ;
showresp(WARN, ASC, "S meter", get_smeter_command, replystr);
gtrace("S meter", get_smeter_command);
ret = hexTo(replystr.c_str()[3]) * 16 + hexTo(replystr.c_str()[4]) ;
return (int)((float)ret * ( 100.0 / 255.0 ) ) ;
}
//----------------------------------------------------------------------
// Volume control return (rig sends back 0 .. 255)
int RIG_PCR1000::get_volume_control()
{
return current_volume ;
}
//----------------------------------------------------------------------
void RIG_PCR1000::set_volume_control(int val) // 0 .. 100
{
current_volume = val ;
int ival = (int)(val * 2.55); // 0 .. 255
set2Hex( ival, &(volume_command[3])) ;
sendCommand(volume_command, 5);
showresp(WARN, ASC, "set volume", volume_command, replystr);
strace("set volume", volume_command);
}
//======================================================================
// Band width commands
//======================================================================
void RIG_PCR1000::set_bwA(int val) {
A.iBW = bwA = val;
setFreqModeBW(A);
}
int RIG_PCR1000::get_bwA() {
return A.iBW ;
}
void RIG_PCR1000::set_bwB(int val) {
B.iBW = bwB = val;
setFreqModeBW(B);
}
int RIG_PCR1000::get_bwB() {
return B.iBW ;
}
//======================================================================
// mode commands
//======================================================================
void RIG_PCR1000::set_modeA(int val)
{
modeA = A.imode = val ;
setFreqModeBW(A);
}
//----------------------------------------------------------------------
int RIG_PCR1000::get_modeA()
{
return A.imode;
}
//----------------------------------------------------------------------
void RIG_PCR1000::set_modeB(int val)
{
modeB = B.imode = val ;
setFreqModeBW(B);
}
//----------------------------------------------------------------------
int RIG_PCR1000::get_modeB()
{
return B.imode;
}
//----------------------------------------------------------------------
int RIG_PCR1000::get_modetype(int n)
{
return mode_type[n];
}
//======================================================================
// mode commands
//======================================================================
//----------------------------------------------------------------------
void RIG_PCR1000::selectA() {
current_vfo = A ;
}
//----------------------------------------------------------------------
void RIG_PCR1000::selectB() {
current_vfo = B ;
}
//----------------------------------------------------------------------
void RIG_PCR1000::A2B() {
B.freq = A.freq ;
B.iBW = A.iBW ;
B.imode = A.imode ;
B.src = A.src ;
}
//----------------------------------------------------------------------
void RIG_PCR1000::swapAB() {
XCVR_STATE T ;
T.freq = B.freq ;
T.iBW = B.iBW ;
T.imode = B.imode ;
T.src = B.src ;
B.freq = A.freq ;
B.iBW = A.iBW ;
B.imode = A.imode ;
B.src = A.src ;
A.freq = T.freq ;
A.iBW = T.iBW ;
A.imode = T.imode ;
A.src = T.src ;
}
//======================================================================
// Squelch commands
//======================================================================
//----------------------------------------------------------------------
void RIG_PCR1000::set_squelch(int val) {
sql = val ;
set2Hex( val, &(squelch_command[3])) ;
sendCommand(squelch_command, 5);
showresp(WARN, ASC, "Set Squelch", squelch_command, replystr);
strace("set squelch", squelch_command);
}
int RIG_PCR1000::get_squelch() {
return sql ;
}
//======================================================================
// IF shift commands
//======================================================================
//----------------------------------------------------------------------
/*
* Since the PCR1000 IF shift shifts in 10 hertz increments we display and store
+ * the actual shift. Just divide by 10 and add 80 before its set.
*
* The "and add 80" above is decimal, it should be in Hex, so that's 128 Decimal
* The showresp text lable was wrong too, it's been corrected.
*
*/
void RIG_PCR1000::set_if_shift(int val) {
if_shift = val ;
set2Hex( val/10 + 128, &(if_shift_command[3])) ;
sendCommand(if_shift_command, 5);
showresp(WARN, ASC, "IF Shift", if_shift_command, replystr);
strace("if shift", if_shift_command);
}
bool RIG_PCR1000::get_if_shift(int &val) {
val = if_shift ;
return (if_shift == if_shift_mid)?false:true ;
}
//======================================================================
// Attenuator commands
//======================================================================
//----------------------------------------------------------------------
void RIG_PCR1000::set_attenuator(int val) {
if( val != attenuator ) {
if( val ) {
// Turn att on
sendCommand(att_on_command, 5);
showresp(WARN, ASC, "Set Attenuator ON", att_on_command, replystr); // wbx
strace("set att ON", att_on_command);
attenuator = 1 ;
} else {
// Turn att off
sendCommand(att_off_command, 5);
showresp(WARN, ASC, "Set Attenuator OFF", att_off_command, replystr); // wbx
strace("set att OFF", att_off_command);
attenuator = 0 ;
}
}
}
int RIG_PCR1000::get_attenuator() {
return attenuator ;
}
//======================================================================
// Noise reduction commands (Doesn't do much on PCR-1000 :-( )
//======================================================================
//----------------------------------------------------------------------
void RIG_PCR1000::set_noise(bool on) {
if( on ) {
// Turn on
sendCommand(noise_on_command, 5);
showresp(WARN, ASC, "Noise Reduction ON", noise_on_command, replystr);
strace("nr ON", noise_on_command);
noise = 1 ;
} else {
// Turn off
sendCommand(noise_off_command, 5);
showresp(WARN, ASC, "Noise Reduction OFF", noise_off_command, replystr);
strace("nr OFF", noise_off_command);
noise = 0 ;
}
}
int RIG_PCR1000::get_noise() {
return noise ;
}
//======================================================================
// Command structures for the PCR1000
//
// From http://www.gm4jjj.co.uk/PCR1000.html
//======================================================================
/*
PCR1000 Command List
The ICOM PCR1000 Computer Controlled Radio Command Protocol has not been
published by ICOM, however I have compiled this list from various sources.
Warning: I take no responsibility for the accuracy of any of the following,
you use it at your own risk! - Make sure you have a backup of your EEPROM
before trying any experimentation!
Updated 10 JAN 2002
All commands are sent is ASCII in the format: Command + CR + LF
CR = chr$(13)
LF = chr$(10)
EXCEPT when in AUTOUPDATE mode (see G3xx command), when NO CR + LF
IS REQUIRED after the Command
Note that no G0XX is returned in autoupdate mode
Some responses from the PCR1000 have an added character at the end
of the response string. It is usually a duplicate of the last
character of the string and can be discarded. (A bug, I suppose)
DTR and RTS set high by software.
When radio is first turned on, the software send the following commands:
initial boot up at 9600 Baud.
H101 Turn Radio ON
G105 Set Baud rate to 38400 Baud
G300 Set Autoupdate to OFF
H1? Is radio still ON? Responds H100 for OFF, H101 for ON
H101 Radio ON command
G4? Possible Inquire Firmware Revision? US and UK version
returns G410
G301 Auto Update ON
GE? Inquire Country/Region returns GE09 in FCC USA version
and GE02 in EUR/AUS version
GD? Is DSP Installed?
Returns GD00 if NO, GD01 if Yes
K00857937500050200 Set Frequency and mode and filter
J4100 Set Squelch
J5100 See Tone Squelch
J5000 Set VSC off
J4380 Set IF Shift to mid range
J4500 Set AGC OFF
J4600 Set Noise Blanker OFF
J4700 Set Attenuator OFF
J4A80 Not known
LD82000 Set Tracking Filter to Automatic
J8001J8101J8200J8301 DSP Packet. See DSP commands below
J4000 Set Volume
ME0000120050100012500 Set Bandscope ON to +- 200 Khz and 12.5 Khz step
' This is returned when Bandscope first turned ON
NE100000000000000000000000000000000000
NE110000000000000000000000000000000000
NE120000000000000000000000000000000000
NE130000000000000000000000000000000000
NE140000000000000000000000000000000000
NE150000000000000000000000000000000000
NE160000000000000000000000000000000000
NE170000000000000000000000000000000000
NE190000000000000000000000000000000000
NE1A0000000000000000000000000000000000
NE1B0000000000000000000000000000000000
NE1C0000000000000000000000000000000000
NE1D0000000000000000000000000000000000
NE1E0000000000000000000000000000000000
NE1F0000000000000000000000000000000000
___________________________________________________
Command Status:
G0xx
where xx = 00 when command is Good, 01 when command is Bad
Signal Update:
G3xx
00 = off (Program needs to Poll status) See I1? to I3? below
01 = on (Radio sends Status when a parameter changes) See Ix? commands
02 = binary mode (Update off)
03 = binary mode (Update on)
Inquire signal information. These commands can be Polled or are
returned as a packet if Autoupdate is ON (See G301) and one of the
values changes.
I0? Squelch Status returns 04 = Closed, 07 = Open
I1? Signal Strength returns 00 to FF
I2? Signal Centering returns 00 = Low, 80 = Centered, FF = High
I3? DTMF Tone
returns I300 if NO DTMF tone present
returns I31 + ASCII digit 0 to F (* = E, # = F)
Alive:
H1? Is radio alive? Radio responds H101 (on) or H100 (off)
Volume:
J40xx xx Range 00 to FF
Squelch:
J41xx xx Range 00 to FF
IF Shift:
J43xx xx Range 00 to FF
AGC:
J45xx xx = 01 for ON, 00 for OFF
NB:
J46xx xx = 01 for ON, 00 for OFF
Attenuator:
J47xx xx = 01 for ON, 00 for OFF
VSC:
J50xx xx = 01 for ON, 00 for OFF
T Squelch on = J51tt (tt=tone , 01=67Hz, 33=254.1Hz)
T Squelch off = J5100
Frequency: K0GMMMKKKHHHmmff00
where K0 G MMM KKK HHH mm ff 00
G=GHz
MMM=MHz
KKK=KHz
HHH=Hz
mm = mode
ff = Filter
00 = Padding Bytes (always there)
Mode Settings:
00 = LSB
01 = USB
02 = AM
03 = CW
04 = Not used or Unknown
05 = NFM
06 = WFM
Filter Settings:
00 = 3 Khz (actually 2.8 Khz) (CW USB LSB AM)
01 = 6 Khz (CW USB LSB AM NFM)
02 = 15 Khz (AM NFM)
03 = 50 Khz (AM NFM WFM)
04 = 230 Khz (WFM)
Radio Replies
I0xx Squelch Status xx=04 Closed, 07 Open
I1ss ss is Signal Strength 00 to FF
I200 Signal Frequency < Display Frequency
I280 Signal Frequency = Display Frequency
I2FF Signal Frequency > Display Frequency
I300 No DTMF Present
I31t t is DTMF tone (* = E, # = F)
Baud Rate
G1xx
where xx is:
00 = 300
01 = 1200
02 = 4800
03 = 9600
04 = 19200
05 = 38400
Signal Update
G3xx
00 = off (Program needs to inquire signal strength, DTMF tone, Center, etc)
01 = on (Radio sends signal strength, DTMF tone, etc as needed)
02 = binary mode (Update off)
03 = binary mode (Update on)
__________________________________________________________
Icom PCR1000 Band Scope commands.
The basic command to turn the bandscope function On is:
ME0000120050100012500 + CR + LF
The command breaks down this way:
ME00001 20050100012500
ME00001 is the preamble. It's always the same.
ME00001 20 050100012500
20 is the number of samples. It must be a 2 digit HEX number
represented in ASCII. Add leading 0 if necessary. Calculate
this number by dividing the Scope Bandwidth by the step size. For
example in the +- 200 Khz span the total bandwidth is 400 Khz. If the
step size is 12.5 khz then 400/12.5 is 32 or 20 Hex. If you get a non
integer answer for the initial division then increment the sample
number by 1 or 2 (sample should be an EVEN number). You can
arbitrarily set the sample higher(SLIGHTLY) to allow the display to
be moved inward from the edges of the scope display.
ME0000120 05 0100012500
05 is a sample rate value that determines how fast the
scope is swept and in the Icom software is either 05 or 28. This is
interpreted as a hex number and must be 2 digits. The practical values
for this runs from 01 (very fast and resource intensive) to about
70 (very slow and nearly useless). Putting 00 here locks the PCR1000
and software up. In the Icom software the number of samples
determine this value. Sample numbers above 10 hex use 05 and those
10 Hex or lower use 28 Hex.
ME000012005 01 00012500
01 This is the On/Off characters. If they are 00 then
the bandscope is OFF. If they are 01 the bandscope is ON
ME00001200501 00 012500
00 is a padding value and must be there.
ME0000120050100 012500
012500 is the step size expressed in HERTZ. It must
be 6 digits long, padded with LEADING ZEROS. Examples are 001000 for
1000 hertz (1 Khz), 030000 for 30 Khz and 100000 for 100 Khz. The
bandscope accepts values down to at least 10 hertz but the Icom
software displays a LIMIT warning at 1 Khz and at 100 Khz.
The Band Scope commands appear to be insensitive to mode and bandwidth
except for the fact that it doesn't work in USB, LSB or CW. It has
been hypothesized that the product detector circuitry is used by the
Band Scope.
Typical Band Scope Commands:
ME00001C8050100001000 +- 100 Khz @ 1 Khz
ME0000164050100001000 +- 50
ME0000132050100001000 +- 25
ME00001A0050100002500 +- 200 Khz @ 2.5 Khz
ME0000150050100002500 +- 100
ME0000128050100002500 +- 50
ME0000114050100002500 +- 25
ME0000150050100005000 +- 200 Khz @ 5.0 Khz
ME0000128050100005000 +- 100
ME0000114050100005000 +- 50
ME000010A280100005000 +- 25
ME0000140050100006250 +- 200 Khz @ 6.25 Khz
ME0000120050100006250 +- 100
ME0000110280100006250 +- 50
ME0000108280100006250 +- 25
ME000012E050100009000 +- 200 Khz @ 9.0 Khz
ME0000118050100009000 +- 100
ME000010C280100009000 +- 50
ME0000106280100009000 +- 25
ME0000128050100010000 +- 200 Khz @ 10.0 Khz
ME0000114050100010000 +- 100
ME000010A280100010000 +- 50
ME0000106280100010000 +- 25
ME0000120050100012500 +- 200 Khz @ 12.5 Khz
ME0000110280100012500 +- 100
ME0000110280100012500 +- 50
ME0000108280100012500 +- 25
ME0000114050100020000 +- 200 Khz @ 20.0 Khz
ME000010A280100020000 +- 100
ME0000106280100020000 +- 50
ME0000104280100020000 +- 25
ME0000110280100025000 +- 200 Khz @ 25.0 Khz
ME0000108280100025000 +- 100
ME0000104280100025000 +- 50
ME0000100280100025000 +- 25
ME000010E280100030000 +- 200 Khz @ 30.0 Khz
ME0000108280100030000 +- 100
ME0000104280100030000 +- 50
ME0000100280100030000 +- 25
ME0000108280100050000 +- 200 Khz @ 50.0 Khz
ME0000104280100050000 +- 100
ME0000100280100050000 +- 50 Note 00 sample size This is invalid!
ME0000104280100100000 +- 200 Khz @ 100.0 Khz
ME0000100280100100000 +- 100 Invalid
ME0000100280100100000 +- 50 Invalid
**********************************************************************
The data is returned in 37 byte packets. The packets begin with the
Letters NE1 followed by the 2 digit hex packet number. The Packet
numbers run from 00 to F0 (must be 2 digits). Typical packet numbers
would be NE100, NE170, NE180 and NE1F0.
These numbers are followed by 32 bytes that contain signal level
information for EACH sample (16 per packet).
Each byte is a hex number (in ascii) that can run from 00 to FF. The
bytes in packet NE180 represent the first 16 samples UP from the
displayed frequency in ascending order. The bytes in packet NE170
represent the 16 samples BELOW the displayed frequency in descending
order. For example the following:
NE18020202020202020202020202020202020
NE1 80 20202020202020202020202020202020
NE1 is the fixed preamble
NE1 80 20202020202020202020202020202020
80 is the packet number
NE180 20 202020202020202020202020202020
20 is the sample signal level (20 Hex) at the displayed frequency
NE18020 20 2020202020202020202020202020
This is the next sample level UP from the displayed freq
The next 14 values represent the next 14 sample levels. If less samples
are needed, the higher sample levels are set to 00. If more then 16
sanple levels are needed Up from the center freq, then the next packet
NE190 hold the values.
For the following:
NE17000000000000000001111111111111111
NE1 7000000000000000001111111111111111
NE1 is the fixed preamble
NE1 70 00000000000000001111111111111111
70 is the packet number. Packet 70 is the first packet BELOW the
center frequency.
NE170000000000000000011111111111111 11
11 This is the first sample level
BELOW the center frequency.
NE1700000000000000000111111111111 11 11
11 This is the next LOWER sample
level and so on. In this example, only 16 (10 Hex) samples were
specified. 8 samples are provided here below center freq and the
corresponding 8 above center freq would be in the NE180 packet.
If more then the 32 samples that can be displayed with NE170 and NE180
were specified then additional packets would be sent. For example if
48(decimal) samples were specified then the following packets would be
returned: NE160 would have 8 samples (in the UPPER 8)
NE170 would have 16 samples
NE180 would have 16 samples
NE190 would have 8 samples (in the LOWER 8)
Note that they are sent in ascending order from NE160 to NE190.
A rough indication of the number of packets needed for a given sample
size is (Number of samples)/16 plus 1. If the number is ODD then add
1 more packet.
Sample in order sent (This is a continous string):
NE1600000000000000000000030180FA61F14
NE1701F2B0C0F7E030C2B85088E080F2B4314
NE1801B8E181830085FEC6603083001143003
NE19001030101012701000000000000000000
When Band Scope is first turned ON or is turned OFF, ALL 16 packets
are returned with ALL samples set to 00.
___________________________________________________________
The DSP commands below have to be sent as a packet
followed by a Cr + Lf
sample packet
J8001J8101J820FJ8301
| | is always there and never changes
J8001J8101J820FJ8301
| | DSP ON J8100 is DSP Off
J8001J8101J820FJ8301
| | ANR on and set to max would be J8200 if off
J8001J8101J820FJ8301
| | Notch turned ON J8301 turns notch ON
With this in mind here is the DSP Command Set:
On startup the software sends GD?
Returns GD00 if NO DSP installed
Returns GD01 if DSP Installed
Autoupdate must be ON (send G301 + cr + lf):
J8001 Always the same
J81xx where xx is 00 if DSP is OFF and 01 if ON
J82xx This is the ANR function (Automatic Noise Reduction)
xx is 00 if ANR is OFF. If ON, xx varies from 01 to 0F
when you turn a knob on the new DSP Popup panel.
J83xx is the Automatic Notch filter. xx is 00 if notch
is OFF and 01 if ON.
The following data is written to the PCR1000.ini file.
DSPON with either 0 or 1 for Off/On
DSPANF with either 0 or 1 for Off/On
DSPNR with either 0 or 1 for Off/On
DSPNRLEVEL with value 0 to 15 for Noise Reduction level
----------------------------------------------------------
COUNTRY/REGION Table
GE? (Returns contents of Address 7E of the EEPROM)
JAPAN 00
USA 01
EUR/AUS 02
FRA 03
DEN 04
CAN 05
GENE1 06
GENE2 07
FCC JPN 08
FCC USA 09
FCC EUR/AUS 0A
FCC FRA 0B
FCC DEN 0C
FCC CAN 0D
FCC GENE1 0E
FCC GENE2 OF
TRACKING FILTER
LD820x xx=00 automatic tracking, Range 01 to FF manual setting of filter
EEPROM UNLOCKING
Don't play with these unless you have a verified backup of your own PCR-1000 EEPROM contents
You need to unlock the protection even to READ the EEPROM contents.
The Unlock Codes are:
GC01
GCF0
Note the response to both the above commands is G001
Read Command:
LD0xx? xx= eeprom address 00 to 7F
Replies LD0xxyy yy = data in location xx
Write Command:
LD0xxyy xx = address yy = data to write
Replies G000 if OK
To put protection back on again turn the PCR-1000 off and on again.
Use the software command H100 or the switch.
The baud rate will then return to 9600.
Average Values
Use these if you have a corrupted EEPROM and no backup
Crash Pattern
This is what the PCR-1000 produces if it crashes and corrupts the EEPROM
EEPROM Locations (DATA IN DECIMAL)
ADDRESS AVERAGE CRASHED COMMENTS
(HEX) (DEC) (DEC)
00 0 0 RESERVED
01 0 0 RESERVED
02 82 82 CHECK PATTERN
03 88 88 CHECK PATTERN
04 99 128 REFERENCE XTAL SHIFT (CENTRE =128)
05 0 0 RESERVED
06 0 0 RESERVED
07 0 0 RESERVED
08 63 0 FM LEVEL S0 REF-VOLT
09 79 48 FM LEVEL S3 REF-VOLT
0A 95 80 FM LEVEL S5 REF-VOLT
0B 117 112 FM LEVEL S7 REF-VOLT
0C 140 144 FM LEVEL S9 REF-VOLT
0D 166 176 FM LEVEL S9+20 REF-VOLT
0E 188 208 FM LEVEL S9+40 REF-VOLT
0F 210 240 FM LEVEL S9+60 REF-VOLT
10 54 0 WFM LEVEL S0 REF-VOLT
11 67 48 WFM LEVEL S3 REF-VOLT
12 80 80 WFM LEVEL S5 REF-VOLT
13 103 112 WFM LEVEL S7 REF-VOLT
14 126 144 WFM LEVEL S9 REF-VOLT
15 152 176 WFM LEVEL S9+20 REF-VOLT
16 177 208 WFM LEVEL S9+40 REF-VOLT
17 199 240 WFM LEVEL S9+60 REF-VOLT
18 21 0 SCOPE LEVEL S0 REF-VOLT
19 39 48 SCOPE LEVEL S3 REF-VOLT
1A 45 80 SCOPE LEVEL S5 REF-VOLT
1B 55 112 SCOPE LEVEL S7 REF-VOLT
1C 57 144 SCOPE LEVEL S9 REF-VOLT
1D 61 176 SCOPE LEVEL S9+20 REF-VOLT
1E 64 208 SCOPE LEVEL S9+40 REF-VOLT
1F 67 240 SCOPE LEVEL S9+60 REF-VOLT
20 21 115 FM CENTERMETER LOW
21 57 46 FM CENTERMETER HIGH
22 115 115 RESERVED
23 146 146 RESERVED
24 11 166 FM NOISESQL THRESHOLD LEVEL
25 11 36 FM NOISESQL TIGHT LEVEL
26 2 0 FM NOISESQL SETTING T2
27 4 0 FM NOISESQL SETTING T3
28 0 0 RESERVED
29 0 0 RESERVED
2A 96 96 CTCSS-DET JUDGEMENT LEVEL (CLOSE)
2B 160 160 CTCSS-DET JUDGEMENT LEVEL (OPEN)
2C 98 144 BPF0 LEVEL S9 REFERENCE
2D 137 144 BPF1 LEVEL S9 REFERENCE
2E 111 144 BPF2 LEVEL S9 REFERENCE
2F 106 144 BPF3 LEVEL S9 REFERENCE
30 125 144 BPF4 LEVEL S9 REFERENCE 50.02MHZ
31 130 144 BPF4 LEVEL S9 REFERENCE 58.28MHZ
32 129 144 BPF4 LEVEL S9 REFERENCE 58.32MHZ
33 135 144 BPF4 LEVEL S9 REFERENCE 88.02MHZ
34 138 144 BPF4 LEVEL S9 REFERENCE 108.28MHZ
35 138 144 BPF4 LEVEL S9 REFERENCE 108.32MHZ
36 141 144 BPF4 LEVEL S9 REFERENCE 130.02MHZ
37 140 144 BPF4 LEVEL S9 REFERENCE 149.98MHZ
38 118 144 BPF5 LEVEL S9 REFERENCE 150.02MHZ
39 122 144 BPF5 LEVEL S9 REFERENCE 183.28MHZ
3A 121 144 BPF5 LEVEL S9 REFERENCE 183.32MHZ
3B 122 144 BPF5 LEVEL S9 REFERENCE 216.02MHZ
3C 119 144 BPF5 LEVEL S9 REFERENCE 265.68MHZ
3D 117 144 BPF5 LEVEL S9 REFERENCE 265.72MHZ
3E 117 144 BPF5 LEVEL S9 REFERENCE 300.02MHZ
3F 110 144 BPF5 LEVEL S9 REFERENCE 349.98HZ
40 124 144 BPF6 LEVEL S9 REFERENCE 350.02HZ
41 123 144 BPF6 LEVEL S9 REFERENCE 383.28MHZ
42 123 144 BPF6 LEVEL S9 REFERENCE 383.32MHZ
43 125 144 BPF6 LEVEL S9 REFERENCE 433.32MHZ
44 123 144 BPF6 LEVEL S9 REFERENCE 483.28MHZ
45 123 144 BPF6 LEVEL S9 REFERENCE 483.32MHZ
46 121 144 BPF6 LEVEL S9 REFERENCE 558.32MHZ
47 119 144 BPF6 LEVEL S9 REFERENCE 633.28MHZ
48 119 144 BPF6 LEVEL S9 REFERENCE 633.32MHZ
49 116 144 BPF6 LEVEL S9 REFERENCE 699.98MHZ
4A 103 144 BPF7 LEVEL S9 REFERENCE 700.02MHZ
4B 107 144 BPF7 LEVEL S9 REFERENCE 750.02MHZ
4C 110 144 BPF7 LEVEL S9 REFERENCE 799.98MHZ
4D 110 144 BPF7 LEVEL S9 REFERENCE 800.02MHZ
4E 120 144 BPF7 LEVEL S9 REFERENCE 916.68MHZ
4F 119 144 BPF7 LEVEL S9 REFERENCE 916.72MHZ
50 123 144 BPF7 LEVEL S9 REFERENCE 1016.68MHZ
51 122 144 BPF7 LEVEL S9 REFERENCE 1016.72MHZ
52 112 144 BPF7 LEVEL S9 REFERENCE 1166.68MHZ
53 111 144 BPF7 LEVEL S9 REFERENCE 1166.72MHZ
54 110 144 BPF7 LEVEL S9 REFERENCE 1299.98MHZ
55 0 0 RESERVED
56 0 0 RESERVED
57 0 0 RESERVED
58 35 128 BPF4 TUNING PEAK-POINT 50.02MHZ
59 35 128 BPF4 TUNING PEAK-POINT 58.28MHZ
5A 117 128 BPF4 TUNING PEAK-POINT 58.32MHZ
5B 110 128 BPF4 TUNING PEAK-POINT 88.02MHZ
5C 114 128 BPF4 TUNING PEAK-POINT 108.28MHZ
5D 188 128 BPF4 TUNING PEAK-POINT 108.32MHZ
5E 191 128 BPF4 TUNING PEAK-POINT 130.02MHZ
5F 204 128 BPF4 TUNING PEAK-POINT 149.98MHZ
60 70 128 BPF5 TUNING PEAK-POINT 150.02MHZ
61 43 128 BPF5 TUNING PEAK-POINT 183.28MHZ
62 118 128 BPF5 TUNING PEAK-POINT 183.32MHZ
63 101 28 BPF5 TUNING PEAK-POINT 216.02MHZ
64 92 128 BPF5 TUNING PEAK-POINT 265.68MHZ
65 180 128 BPF5 TUNING PEAK-POINT 265.72MHZ
66 173 128 BPF5 TUNING PEAK-POINT 300.02MHZ
67 177 128 BPF5 TUNING PEAK-POINT 349.98MHZ
68 46 128 BPF6 TUNING PEAK-POINT 350.02MHZ
69 32 128 BPF6 TUNING PEAK-POINT 383.28MHZ
6A 113 128 BPF6 TUNING PEAK-POINT 383.32MHZ
6B 95 128 BPF6 TUNING PEAK-POINT 433.32MHZ
6C 83 128 BPF6 TUNING PEAK-POINT 483.28MHZ
6D 156 128 BPF6 TUNING PEAK-POINT 483.32MHZ
6E 132 128 BPF6 TUNING PEAK-POINT 558.32MHZ
6F 112 128 BPF6 TUNING PEAK-POINT 633.28MHZ
70 187 128 BPF6 TUNING PEAK-POINT 633.32MHZ
71 185 128 BPF6 TUNING PEAK-POINT 699.98MHZ
72 75 128 BPF7 TUNING PEAK-POINT 700.02MHZ
73 66 128 BPF7 TUNING PEAK-POINT 750.02MHZ
74 57 128 BPF7 TUNING PEAK-POINT 799.98MHZ
75 146 128 BPF7 TUNING PEAK-POINT 800.02MHZ
76 79 128 BPF7 TUNING PEAK-POINT 916.68MHZ
77 160 128 BPF7 TUNING PEAK-POINT 916.72MHZ
78 122 128 BPF7 TUNING PEAK-POINT 1016.68MHZ
79 194 128 BPF7 TUNING PEAK-POINT 1016.72MHZ
7A 127 128 BPF7 TUNING PEAK-POINT 1166.68MHZ
7B 202 128 BPF7 TUNING PEAK-POINT 1166.72MHZ
7C 170 128 BPF7 TUNING PEAK-POINT 1299.98MHZ
7D 0 0 RESERVED
7E * 7 COUNTRY/REGION (*See Table of values)
7F 2 7 RESERVED
Unknowns
---------
Still looking for the purpose of the following PCR commands:-
LE20050
LE20040
Above used by icom in their EEPROM routines in their software for setting up
the radio and also some third party software I have seen. Is this understood or
is it just being copied?
GCD0
GE07
H800 * see below
LD840?
LD846?
LD84A? * see below
LD842 * see below
LD844 * see below
LD848
LD860
LD862
G4? returns G410
J4A80
If anyone fill in the gaps that would be great!
Update:- Some more info has come in! - Thanks to the guys on the PCR-1000 list.
There are some questions about the following commands:
LD840? (always 0)
LD842? (current signal strength)
LD844? (centering info?)
LD846? (usually 0x60)
LD848? (always 0)
LD84A? (old LD842?)
LD84C? (always 0)
LD84E? (always 0)
LD860? (always 0)
LD862? (always 0)
LD864? (always 0)
LD842? returns the current signal strength level, same as for I1?
LD84A? returns the previous signal strength. I believe this is what the radio uses to determine if the signal strength level has changed (as you probably noticed, it only kicks out a new I1xx message in G301 mode when the signal strength changes).
LD844? returns something relevant to frequency. If I set the PCR-1000 to 144.35, NBFM, 6Khz filter, and set my HT for 144.35 Mhz, when I transmit on the HT, this value goes to 0x25. Moving the HT to 144.355 causes the value to increase to a nominal 0x37, and moving the HT to 144.345 causes the value to decrease to a nominal 0x15. Interesting relationship between these values: 0x37 - 0x25 = 0x12, and 0x25 - 0x15 = 0x10. This is 18 decimal and 16 decimal respectively. Two pretty close numbers for shifting +/- 5Khz. I expect this register has something to do with the centering information.
I'm not completely sure about this, but every document except 1 has the auto tracking register mis-coded. It's generally listed as LD8200 to turn off, and LD8201 to set to manual. It's actually LD82000 (note three 0's) to turn off, and can be varied from LD82001 to LD820FF. I don't know exactly what the tracking thingie does, but it has a pronounced affect turning it off or on. - Editor's note this has now been corrected in this document, it is the tracking of the RF stage with frequency I believe.
There's also a mention of H800 in the documents. H8 will accept values from 00 to FF, and has an odd effect on the audio. Values greater than or equal to 0x81 cause a very brief (100ms or so) drop out on the audio. Values 0x80 and below don't do this. Interestingly enough, when G301 is in effect, changing H8 causes an H9 message to be output. H9 can be read with the H9? command. I've only seen 0x00, 0x01, and 0x10 be reported back.
The following command sequence seems to have something to do with squelch and signal strength. H800; J4180; H881; H9? (reports H901), J4100. Now the squelch should be open, but isn't. Setting H800 will open the squelch again. Now do H8FF; H9? Audio opens, and H9? reports H910. Curious. All my experimenting is in NBFM mode, so perhaps some of these other registers come into play in other modes.
Something else that's not mentioned in any of the documentation is that when G301 mode is on, commands don't generate a response unless they're interrogative (i.e. GD? or H1?).
*/
flrig-1.3.49/src/rigs/FT767.cxx 0000644 0001750 0001750 00000004640 13472116065 012701 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include "FT767.h"
static const char FT767name_[] = "FT-767";
static const char *FT767modes_[] = {
"LSB", "USB", "CW", "AM", "FM", "FSK", NULL};
static const char FT767_mode_type[] = { 'L', 'U', 'U', 'U', 'U', 'U' };
RIG_FT767::RIG_FT767() {
// base class values
name_ = FT767name_;
modes_ = FT767modes_;
comm_baudrate = BR4800;
stopbits = 2;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_rtscts = false;
comm_rtsplus = false;
comm_dtrplus = true;
comm_catptt = false;
comm_rtsptt = false;
comm_dtrptt = false;
modeA = 1;
bwA = 0;
has_mode_control = true;
precision = 10;
ndigits = 8;
};
void RIG_FT767::init_cmd()
{
cmd = "00000";
for (size_t i = 0; i < 5; i++) cmd[i] = 0;
}
bool RIG_FT767::check()
{
init_cmd();
cmd[4] = 0x01; // CHECK command
int ret = waitN(20, 100, "check", HEX);
if (ret >= 20) return true;
return false;
}
long RIG_FT767::get_vfoA ()
{
init_cmd();
cmd[4] = 0x01; // CHECK command
int ret = waitN(20, 100, "get vfoA", HEX);
if (ret < 20) return freqA;
freqA = fm_bcd(replystr.substr(14), 8) * 10; // VFO-A in positions 14-17
modeA = replystr[19];
return freqA;
}
void RIG_FT767::set_vfoA (long freq)
{
freqA = freq;
freq /=10; // 767 does not support 1 Hz resolution
cmd = to_bcd(freq, 8);
cmd += 0x08; // SET FREQUENCY
sendCommand(cmd);
}
int RIG_FT767::get_modeA()
{
return modeA;
}
void RIG_FT767::set_modeA(int val)
{
modeA = val;
init_cmd();
cmd[3] = 0x10 + val; // 0x10 = LSB ... 0x15 = FSK
cmd[4] = 0x0A; // MODESEL
sendCommand(cmd);
}
flrig-1.3.49/src/rigs/FT990.cxx 0000644 0001750 0001750 00000016270 13472116065 012701 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include "FT990.h"
#include "rig.h"
static const char FT990name_[] = "FT-990";
static const char *FT990modes_[] =
{ "LSB", "USB", "CW2.4", "CW500",
"AM6.0", "AM2.4", "FM",
"RTTY(L)", "RTTY(U)", "PKT(L)", "PKT(FM)", NULL};
static const int FT990_def_bw[] = {
0, 0, 0, 2,
4, 0, 0,
0, 0, 0, 0 };
static const int FT990_mode_val[] = {
0, 1, 2, 3,
4, 5, 6,
8, 9, 10, 11 };
static const char FT990_mode_type[] = {
'L', 'U', 'L', 'L',
'U', 'U', 'U',
'L', 'U', 'L', 'U' };
static const char *FT990widths_[] =
{ "2400", "2000", "500", "250", "6000", NULL};
static int FT990_bw_vals[] = {
1,2,3,4,5,WVALS_LIMIT};
static const int FT990_bw_val[] =
{ 0, 1, 2, 3, 4 };
RIG_FT990::RIG_FT990() {
name_ = FT990name_;
modes_ = FT990modes_;
bandwidths_ = FT990widths_;
bw_vals_ = FT990_bw_vals;
comm_baudrate = BR4800;
stopbits = 2;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 100;
comm_rtscts = false;
comm_rtsplus = false;
comm_dtrplus = true;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
afreq = bfreq = A.freq = B.freq = 14070000;
amode = bmode = A.imode = B.imode = 1;
aBW = bBW = A.iBW = B.iBW = 2;
precision = 10;
ndigits = 9;
has_split = has_split_AB =
has_get_info =
has_smeter =
has_power_out =
has_swr_control =
has_mode_control =
has_bandwidth_control =
has_ptt_control = true;
}
int RIG_FT990::adjust_bandwidth(int m)
{
if (m == 0 || m == 1 || m == 5) return 2;
if (m == 2 || m == 3 ) return 1;
if (m == 4 || m == 6 || m == 7) return 3;
return 2;
}
void RIG_FT990::init_cmd()
{
cmd = "00000";
for (size_t i = 0; i < 5; i++) cmd[i] = 0;
replystr.clear();
}
void RIG_FT990::initialize()
{
}
void RIG_FT990::selectA()
{
init_cmd();
cmd[4] = 0x05;
sendCommand(cmd);
showresp(WARN, HEX, "select A", cmd, replystr);
}
void RIG_FT990::selectB()
{
init_cmd();
cmd[3] = 0x01;
cmd[4] = 0x05;
sendCommand(cmd);
showresp(WARN, HEX, "select B", cmd, replystr);
}
void RIG_FT990::set_split(bool val)
{
split = val;
init_cmd();
cmd[3] = val ? 0x01 : 0x00;
cmd[4] = 0x01;
sendCommand(cmd);
if (val)
showresp(WARN, HEX, "set split ON", cmd, replystr);
else
showresp(WARN, HEX, "set split OFF", cmd, replystr);
}
bool RIG_FT990::check()
{
init_cmd();
cmd[3] = 0x00;
cmd[4] = 0xFA;
int ret = waitN(5, 100, "check");
if (ret >= 5) return true;
return false;
}
bool RIG_FT990::get_info()
{
bool memmode = false, vfobmode = false;
int pfreq, pmode, pbw;
init_cmd();
cmd[3] = 0x00;
cmd[4] = 0xFA;
int ret = waitN(5, 100, "Read flags");
if (ret >= 5) {
size_t p = ret - 5;
memmode = ((replystr[p+1] & 0x10) == 0x10);
vfobmode = ((replystr[p] & 0x02) == 0x02);
if (memmode) return false;
if (vfobmode && !useB) {
useB = true;
Fl::awake(highlight_vfo, (void *)0);
} else if (!vfobmode && useB) {
useB = false;
Fl::awake(highlight_vfo, (void *)0);
}
}
init_cmd();
cmd[4] = 0x10; // update info
cmd[0] = 0x02; // 1 16 byte sequences for current VFO / MEM
ret = waitN(16, 100, "Read info");
if (ret >= 16) {
size_t p = ret - 16;
// current VFO / MEM
pfreq = 0;
for (size_t n = 1; n < 5; n++)
pfreq = pfreq * 256 + (unsigned char)replystr[p + n];
pfreq = pfreq * 1.25; // 100D resolution is 1.25 Hz / bit for read
int rmode = replystr[p + 7] & 0x07;
switch (rmode) {
case 0 : pmode = 0; break; // LSB
case 1 : pmode = 1; break; // USB
case 2 : pmode = 2; break; // CW
case 3 : pmode = 5; break; // AM
case 4 : pmode = 6; break; // FM
case 5 : pmode = 8; break; // RTTY
case 6 : pmode = 9; break; // PKT
default : pmode = 1; break;
}
int rpbw = replystr[p + 8];
pbw = rpbw & 0x05;
if (pbw > 4) pbw = 4;
if ((rpbw & 0x80) == 0x80) {
if (pmode == 10) pmode = 11;
if (pmode == 8) pmode = 9;
}
if (pmode == 6) pbw = 0;
if (useB) {
B.freq = pfreq; B.imode = pmode; B.iBW = pbw;
} else {
A.freq = pfreq; A.imode = pmode; A.iBW = pbw;
}
LOG_WARN("Vfo %c = %d, BW %s", vfobmode ? 'B' : 'A', pfreq, FT990widths_[pbw]);
return true;
}
return false;
}
long RIG_FT990::get_vfoA ()
{
return A.freq;
}
void RIG_FT990::set_vfoA (long freq)
{
A.freq = freq;
freq /=10; // 100D does not support 1 Hz resolution
cmd = to_bcd_be(freq, 8);
cmd += 0x0A;
sendCommand(cmd);
showresp(WARN, HEX, "set freq A", cmd, replystr);
}
int RIG_FT990::get_modeA()
{
return A.imode;
}
void RIG_FT990::set_modeA(int val)
{
A.imode = val;
init_cmd();
cmd[3] = FT990_mode_val[val];
cmd[4] = 0x0C;
sendCommand(cmd);
showresp(WARN, HEX, "set mode A", cmd, replystr);
}
void RIG_FT990::set_bwA (int val)
{
A.iBW = val;
init_cmd();
cmd[3] = FT990_bw_val[val];
cmd[4] = 0x8C;
sendCommand(cmd);
showresp(WARN, HEX, "set BW A", cmd, replystr);
}
int RIG_FT990::get_bwA()
{
return A.iBW;
}
long RIG_FT990::get_vfoB()
{
return B.freq;
}
void RIG_FT990::set_vfoB(long freq)
{
B.freq = freq;
freq /=10;
cmd = to_bcd_be(freq, 8);
cmd += 0x0A;
sendCommand(cmd);
showresp(WARN, HEX, "set freq B", cmd, replystr);
}
void RIG_FT990::set_modeB(int val)
{
B.imode = val;
init_cmd();
cmd[3] = FT990_mode_val[val];
cmd[4] = 0x0C;
sendCommand(cmd);
showresp(WARN, HEX, "set mode B", cmd, replystr);
}
int RIG_FT990::get_modeB()
{
return B.imode;
}
void RIG_FT990::set_bwB(int val)
{
B.iBW = val;
init_cmd();
cmd[3] = FT990_bw_val[val];
cmd[4] = 0x8C;
sendCommand(cmd);
showresp(WARN, HEX, "set bw B", cmd, replystr);
}
int RIG_FT990::get_bwB()
{
return B.iBW;
}
int RIG_FT990::def_bandwidth(int m)
{
return FT990_def_bw[m];
}
// Tranceiver PTT on/off
void RIG_FT990::set_PTT_control(int val)
{
init_cmd();
if (val) cmd[3] = 1;
cmd[4] = 0x0F;
sendCommand(cmd);
if (val)
showresp(WARN, HEX, "set PTT ON", cmd, replystr);
else
showresp(WARN, HEX, "set PTT OFF", cmd, replystr);
ptt_ = val;
}
int RIG_FT990::get_smeter()
{
init_cmd();
cmd[4] = 0xF7;
int ret = waitN(5, 100, "S-meter");
if (ret < 5) return 0;
int sval = (unsigned char)replybuff[0];
if (sval < 90) sval = 90;
if (sval > 200) sval = 200;
if (sval < 120) sval = 250 - 5 * sval / 3;
else sval = 125 - 5 * sval / 8;
return sval;
}
int RIG_FT990::get_swr()
{
return 0;
}
int RIG_FT990::get_power_out()
{
init_cmd();
cmd[4] = 0xF7;
int ret = waitN(5, 100, "Power out");
if (ret < 5) return 0;
int sval = (unsigned char)replybuff[0];
if (sval < 90) sval = 90;
if (sval > 200) sval = 200;
if (sval < 120) sval = 250 - 5 * sval / 3;
else sval = 125 - 5 * sval / 8;
return sval;
}
flrig-1.3.49/src/rigs/FT847.cxx 0000644 0001750 0001750 00000011526 13472116065 012701 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include "FT847.h"
#include "rig.h"
static const char FT847name_[] = "FT-847";
static const char *FT847modes_[] =
{ "LSB", "USB", "CW", "CW-R", "AM", "FM", "CW-N", "CW-NR", "AM-N", "FM-N", NULL};
static const int FT847_mode_val[] =
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x08, 0x82, 0x83, 0x84, 0x88 };
static const char FT847_mode_type[] =
{ 'L', 'U', 'L', 'U', 'U', 'U', 'L', 'U', 'U', 'U' };
//static const int FT847_def_bw[] = { 2, 2, 1, 1, 3, 2, 2, 3 };
//static const char *FT847widths_[] = { "300", "500", "2400", "6000", NULL};
//static const int FT847_bw_val[] = { 0, 1, 2, 3 };
static const int sm[] = {0,2,4,6,8,11,14,16,19,22,25,28,31,34,37,40,
43,45,47,50,54,58,62,66,70,74,78,82,86,90,95,100};
static const int po[] = {0,2,3,4,5,6,7,8,9,10,11,12,14,16,18,20,
23,26,30,34,39,44,50,56,62,69,76,84,92,100,109,120};
RIG_FT847::RIG_FT847() {
name_ = FT847name_;
modes_ = FT847modes_;
// bandwidths_ = FT847widths_;
comm_baudrate = BR9600;
stopbits = 2;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_rtscts = false;
comm_rtsplus = false;
comm_dtrplus = true;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
afreq = A.freq = B.freq = 14070000;
amode = A.imode = B.imode = 1;
precision = 10;
ndigits = 8;
has_smeter =
has_power_out =
has_get_info =
// has_bandwidth_control =
has_mode_control =
has_ptt_control = true;
}
void RIG_FT847::init_cmd()
{
cmd = "00000";
for (size_t i = 0; i < 5; i++) cmd[i] = 0;
}
void RIG_FT847::initialize()
{
init_cmd();
sendCommand(cmd, 0); // CAT on
cmd[4] = 0x8E; // satellite mode off
replystr.clear();
sendCommand(cmd);
showresp(WARN, HEX, "init", cmd, replystr);
}
bool RIG_FT847::get_info()
{
int ret = 0, i = 0;
init_cmd();
cmd[4] = 0x03;
ret = waitN(5, 100, "get info", HEX);
if (ret >= 5) {
afreq = fm_bcd(replystr.substr(ret - 5), 8)*10;
amode = replystr[ret - 1];
for (i = 0; i < 10; i++) if (FT847_mode_val[i] == amode) break;
if (i == 10) i = 1;
amode = i;
return true;
}
return false;
}
bool RIG_FT847::check ()
{
init_cmd();
cmd[4] = 0x03;
int ret = waitN(5, 100, "check", HEX);
if (ret >= 5) return true;
return false;
}
long RIG_FT847::get_vfoA ()
{
if (useB) return A.freq;
if (get_info()) {
A.freq = afreq;
A.imode = amode;
A.iBW = aBW;
}
return A.freq;
}
void RIG_FT847::set_vfoA (long freq)
{
A.freq = freq;
freq /=10; // 847 does not support 1 Hz resolution
cmd = to_bcd(freq, 8);
cmd += 0x01;
replystr.clear();
sendCommand(cmd);
showresp(WARN, HEX, "set vfo A", cmd, replystr);
}
int RIG_FT847::get_modeA()
{
return A.imode;
}
void RIG_FT847::set_modeA(int val)
{
A.imode = val;
init_cmd();
cmd[0] = FT847_mode_val[val];
cmd[4] = 0x07;
replystr.clear();
sendCommand(cmd);
showresp(WARN, HEX, "set mode A", cmd, replystr);
}
long RIG_FT847::get_vfoB()
{
if (!useB) return B.freq;
if (get_info()) {
B.freq = afreq;
B.imode = amode;
B.iBW = aBW;
}
return B.freq;
}
void RIG_FT847::set_vfoB(long freq)
{
B.freq = freq;
freq /=10; // 847 does not support 1 Hz resolution
cmd = to_bcd(freq, 8);
cmd += 0x01;
replystr.clear();
sendCommand(cmd);
showresp(WARN, HEX, "set vfo B", cmd, replystr);
}
void RIG_FT847::set_modeB(int val)
{
B.imode = val;
init_cmd();
cmd[0] = FT847_mode_val[val];
cmd[4] = 0x07;
replystr.clear();
sendCommand(cmd);
showresp(WARN, HEX, "set mode B", cmd, replystr);
}
int RIG_FT847::get_modeB()
{
return B.imode;
}
// Tranceiver PTT on/off
void RIG_FT847::set_PTT_control(int val)
{
init_cmd();
if (val) cmd[4] = 0x08;
else cmd[4] = 0x88;
replystr.clear();
sendCommand(cmd);
showresp(WARN, HEX, "set PTT", cmd, replystr);
ptt_ = val;
}
int RIG_FT847::get_smeter()
{
init_cmd();
cmd[4] = 0xE7;
int sval = 0;
int ret = waitN(1, 100, "get smeter", HEX);
if (ret >= 1)
sval = sm[(replystr[ret - 1] & 0x1F)];
return sval;
}
int RIG_FT847::get_power_out()
{
init_cmd();
cmd[4] = 0xF7;
fwdpwr = 0;
int ret = waitN(1, 100, "get power", HEX);
if (ret >= 1)
fwdpwr = po[(replystr[ret - 1] & 0x1F)];
return fwdpwr;
}
flrig-1.3.49/src/rigs/IC7600.cxx 0000664 0001750 0001750 00000100424 13521157767 012744 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include "IC7600.h"
bool IC7600_DEBUG = true;
//=============================================================================
// IC-7600
const char IC7600name_[] = "IC-7600";
const char *IC7600modes_[] = {
"LSB", "USB", "AM", "CW", "RTTY", "FM", "CW-R", "RTTY-R", "PSK", "PSK-R",
"LSB-D1", "LSB-D2", "LSB-D3",
"USB-D1", "USB-D2", "USB-D3", NULL};
const char IC7600_mode_type[] = {
'L', 'U', 'U', 'U', 'L', 'U', 'L', 'U', 'U', 'L',
'L', 'L', 'L',
'U', 'U', 'U' };
const char IC7600_mode_nbr[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x12, 0x13,
0x00, 0x00, 0x00,
0x01, 0x01, 0x01 };
const char *IC7600_ssb_bws[] = {
"50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
"600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500",
"1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500",
"2600", "2700", "2800", "2900", "3000", "3100", "3200", "3300", "3400", "3500",
"3600", NULL };
static int IC7600_bw_vals_SSB[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36,37,38,39,
40, WVALS_LIMIT};
const char *IC7600_rtty_bws[] = {
"50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
"600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500",
"1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500",
"2600", "2700", NULL };
static int IC7600_bw_vals_RTTY[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31, WVALS_LIMIT};
const char *IC7600_am_bws[] = {
"200", "400", "600", "800", "1000", "1200", "1400", "1600", "1800", "2000",
"2200", "2400", "2600", "2800", "3000", "3200", "3400", "3600", "3800", "4000",
"4200", "4400", "4600", "4800", "5000", "5200", "5400", "5600", "5800", "6000",
"6200", "6400", "6600", "6800", "7000", "7600", "7400", "7600", "7800", "8000",
"8200", "8400", "8600", "8800", "9000", "9200", "9400", "9600", "9800", "10000", NULL };
static int IC7600_bw_vals_AM[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36,37,38,39,
40,41,42,43,44,45,46,47,48,49
WVALS_LIMIT};
const char *IC7600_fm_bws[] = { "FIXED", NULL };
static int IC7600_bw_vals_FM[] = { 1, WVALS_LIMIT};
static GUI IC7600_widgets[]= {
{ (Fl_Widget *)btnVol, 2, 125, 50 }, //0
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 }, //1
{ (Fl_Widget *)btnAGC, 2, 145, 50 }, //2
{ (Fl_Widget *)sldrRFGAIN, 54, 145, 156 }, //3
{ (Fl_Widget *)sldrSQUELCH, 54, 165, 156 }, //4
{ (Fl_Widget *)btnNR, 2, 185, 50 }, //5
{ (Fl_Widget *)sldrNR, 54, 185, 156 }, //6
{ (Fl_Widget *)btnLOCK, 214, 105, 50 }, //7
{ (Fl_Widget *)sldrINNER, 266, 105, 156 }, //8
{ (Fl_Widget *)btnCLRPBT, 214, 125, 50 }, //9
{ (Fl_Widget *)sldrOUTER, 266, 125, 156 }, //10
{ (Fl_Widget *)btnNotch, 214, 145, 50 }, //11
{ (Fl_Widget *)sldrNOTCH, 266, 145, 156 }, //12
{ (Fl_Widget *)sldrMICGAIN, 266, 165, 156 }, //13
{ (Fl_Widget *)sldrPOWER, 266, 185, 156 }, //14
{ (Fl_Widget *)NULL, 0, 0, 0 }
};
void RIG_IC7600::initialize()
{
IC7600_widgets[0].W = btnVol;
IC7600_widgets[1].W = sldrVOLUME;
IC7600_widgets[2].W = btnAGC;
IC7600_widgets[3].W = sldrRFGAIN;
IC7600_widgets[4].W = sldrSQUELCH;
IC7600_widgets[5].W = btnNR;
IC7600_widgets[6].W = sldrNR;
IC7600_widgets[7].W = btnLOCK;
IC7600_widgets[8].W = sldrINNER;
IC7600_widgets[9].W = btnCLRPBT;
IC7600_widgets[10].W = sldrOUTER;
IC7600_widgets[11].W = btnNotch;
IC7600_widgets[12].W = sldrNOTCH;
IC7600_widgets[13].W = sldrMICGAIN;
IC7600_widgets[14].W = sldrPOWER;
btn_icom_select_11->deactivate();
btn_icom_select_12->deactivate();
btn_icom_select_13->deactivate();
choice_rTONE->activate();
choice_tTONE->activate();
}
RIG_IC7600::RIG_IC7600() {
defaultCIV = 0x7A;
adjustCIV(defaultCIV);
name_ = IC7600name_;
modes_ = IC7600modes_;
bandwidths_ = IC7600_ssb_bws;
bw_vals_ = IC7600_bw_vals_SSB;
_mode_type = IC7600_mode_type;
widgets = IC7600_widgets;
def_freq = A.freq = 14070000;
def_mode = A.imode = 13;
def_bw = A.iBW = 34;
B.freq = 7070000;
B.imode = 13;
B.iBW = 34;
has_extras = true;
has_cw_wpm = true;
has_cw_spot_tone = true;
has_cw_qsk = true;
has_vox_onoff = true;
has_vox_gain = true;
has_vox_anti = true;
has_vox_hang = true;
has_compON = true;
has_compression = true;
has_split = true;
has_split_AB = true;
has_micgain_control = true;
has_bandwidth_control = true;
has_smeter = true;
has_power_out =
has_swr_control =
has_alc_control =
has_sql_control = true;
has_power_control = true;
has_volume_control = true;
has_mode_control = true;
has_attenuator_control = true;
has_preamp_control = true;
has_noise_control = true;
has_noise_reduction = true;
has_noise_reduction_control = true;
has_auto_notch = true;
has_notch_control = true;
has_pbt_controls = true;
has_FILTER = true;
has_rf_control = true;
has_ptt_control = true;
has_tune_control = true;
ICOMmainsub = true;
has_band_selection = true;
precision = 1;
ndigits = 8;
filA = filB = 1;
};
//======================================================================
// IC7600 unique commands
//======================================================================
static inline void minmax(int min, int max, int &val)
{
if (val > max) val = max;
if (val < min) val = min;
}
void RIG_IC7600::selectA()
{
cmd.assign(pre_to).append("\x07\xD0").append(post);
waitFB("select A");
}
void RIG_IC7600::selectB()
{
cmd.assign(pre_to).append("\x07\xD1").append(post);
waitFB("select B");
}
bool RIG_IC7600::check ()
{
string resp = pre_fm;
resp += '\x03';
cmd = pre_to;
cmd += '\x03';
cmd.append( post );
bool ok = waitFOR(11, "check vfo");
rig_trace(2, "check()", str2hex(replystr.c_str(), replystr.length()));
return ok;
}
long RIG_IC7600::get_vfoA ()
{
if (useB) return A.freq;
string resp;
cmd.assign(pre_to).append("\x03").append( post );
if (waitFOR(11, "get vfo A")) {
resp.assign(pre_fm).append("\x03");
size_t p = replystr.rfind(resp);
if (p != string::npos)
A.freq = fm_bcd_be(replystr.substr(p+5), 10);
}
return A.freq;
}
void RIG_IC7600::set_vfoA (long freq)
{
A.freq = freq;
cmd.assign(pre_to).append("\x05");
cmd.append( to_bcd_be( freq, 10 ) );
cmd.append( post );
waitFB("set vfo A");
}
long RIG_IC7600::get_vfoB ()
{
if (!useB) return B.freq;
string resp = pre_fm;
cmd.assign(pre_to).append("\x03").append(post);
if (waitFOR(11, "get vfo B")) {
resp.assign(pre_fm).append("\x03");
size_t p = replystr.rfind(resp);
if (p != string::npos)
B.freq = fm_bcd_be(replystr.substr(p+5), 10);
}
return B.freq;
}
void RIG_IC7600::set_vfoB (long freq)
{
B.freq = freq;
cmd.assign(pre_to).append("\x05");
cmd.append( to_bcd_be( freq, 10 ) );
cmd.append( post );
waitFB("set vfo B");
}
bool RIG_IC7600::can_split()
{
return true;
}
void RIG_IC7600::set_split(bool val)
{
split = val;
cmd = pre_to;
cmd += 0x0F;
cmd += val ? 0x01 : 0x00;
cmd.append(post);
waitFB(val ? "set split ON" : "set split OFF");
}
int RIG_IC7600::get_split()
{
int read_split = 0;
cmd.assign(pre_to);
cmd.append("\x0F");
cmd.append( post );
if (waitFOR(7, "get split")) {
string resp = pre_fm;
resp.append("\x0F");
size_t p = replystr.find(resp);
if (p != string::npos)
read_split = replystr[p+5];
if (read_split != 0xFA) // fail byte
split = read_split;
}
return split;
}
void RIG_IC7600::set_modeA(int val)
{
A.imode = val;
cmd = pre_to;
cmd += '\x06';
cmd += IC7600_mode_nbr[val];
cmd += filA;
cmd.append( post );
waitFB("set modeA");
// digital set / clear
if (val >= 10) {
cmd = pre_to;
cmd.append("\x1A\x06");
switch (val) {
case 10 : case 13 : cmd.append("\x01\x01"); break;
case 11 : case 14 : cmd.append("\x02\x01"); break;
case 12 : case 15 : cmd.append("\x03\x01"); break;
}
cmd.append( post);
waitFB("set digital mode ON/OFF");
}
}
static const char *szfilter[] = {"1", "2", "3"};
int RIG_IC7600::get_modeA()
{
int md = 0;
string resp;
size_t p;
cmd.assign(pre_to).append("\x04").append(post);
if (waitFOR(8, "get mode A")) {
resp.assign(pre_fm).append("\x04");
p = replystr.rfind(resp);
if (p == string::npos) return A.imode;
for (md = 0; md < 10; md++) {
if (replystr[p+5] == IC7600_mode_nbr[md]) {
A.imode = md;
}
}
filA = replystr[p+6];
if (A.imode < 2) {
cmd.assign(pre_to).append("\x1A\x06").append(post);
if (waitFOR(9, "data mode?")) {
resp.assign(pre_fm).append("\x1A\x06");
p = replystr.rfind(resp);
if (p == string::npos) return A.imode;
int dmode = replystr[p+6];
if(dmode != 0) {
if (A.imode == 0) A.imode = 9 + dmode;
else if (A.imode == 1) A.imode = 12 + dmode;
}
}
}
}
if (A.imode > 15) A.imode = 0;
return A.imode;
}
void RIG_IC7600::set_modeB(int val)
{
B.imode = val;
cmd.assign(pre_to).append("\x06");
cmd += IC7600_mode_nbr[val];
cmd += filB;
cmd.append( post );
waitFB("set modeB");
// digital set / clear
if (val >= 10) {
cmd = pre_to;
cmd.append("\x1A\x06");
switch (val) {
case 10 : case 13 : cmd.append("\x01\x01"); break;
case 11 : case 14 : cmd.append("\x02\x01"); break;
case 12 : case 15 : cmd.append("\x03\x01"); break;
}
cmd.append( post);
waitFB("set digital mode ON/OFF");
}
}
int RIG_IC7600::get_modeB()
{
int md = 0;
string resp;
size_t p;
cmd.assign(pre_to).append("\x04").append(post);
if (waitFOR(8, "get mode B")) {
resp.assign(pre_fm).append("\x04");
p = replystr.rfind(resp);
if (p == string::npos) return B.imode;
for (md = 0; md < 10; md++) if (replystr[p+5] == IC7600_mode_nbr[md]) break;
if (md == 10) md = 0;
B.imode = md;
filB = replystr[p+6];
if (B.imode < 2) {
cmd.assign(pre_to).append("\x1A\x06").append(post);
if (waitFOR(9, "data mode?")) {
resp.assign(pre_fm).append("\x1A\x06");
p = replystr.rfind(resp);
if (p == string::npos) return B.imode;
int dmode = replystr[p+6];
if(dmode != 0) {
if (B.imode == 0) B.imode = 9 + dmode;
else if (B.imode == 1) B.imode = 12 + dmode;
}
}
}
}
if (B.imode > 15) B.imode = 0;
return B.imode;
}
int RIG_IC7600::get_bwA()
{
if (A.imode == 5) return 0;
cmd = pre_to;
cmd.append("\x1a\x03");
cmd.append(post);
if (waitFOR(8, "get_bwA")) {
string resp = pre_fm;
resp.append("\x1A\x02");
size_t p = replystr.find(resp);
if (p != string::npos)
A.iBW = fm_bcd(replystr.substr(p+6), 2);
}
return A.iBW;
}
void RIG_IC7600::set_bwA(int val)
{
A.iBW = val;
if (A.imode == 5) return;
cmd = pre_to;
cmd.append("\x1a\x03");
cmd.append(to_bcd(A.iBW, 2));
cmd.append(post);
waitFB("set bwA");
}
int RIG_IC7600::get_bwB()
{
if (B.imode == 5) return 0;
cmd = pre_to;
cmd.append("\x1a\x03");
cmd.append(post);
if (waitFOR(8, "get_bwB")) {
string resp = pre_fm;
resp.append("\x1A\x02");
size_t p = replystr.find(resp);
if (p != string::npos)
B.iBW = fm_bcd(replystr.substr(p+6), 2);
}
return B.iBW;
}
void RIG_IC7600::set_bwB(int val)
{
B.iBW = val;
if (B.imode == 5) return;
cmd = pre_to;
cmd.append("\x1a\x03");
cmd.append(to_bcd(A.iBW, 2));
cmd.append(post);
waitFB("set bwB");
}
int RIG_IC7600::adjust_bandwidth(int m)
{
int bw = 0;
switch (m) {
case 2: // AM
bandwidths_ = IC7600_am_bws;
bw_vals_ = IC7600_bw_vals_AM;
bw = 19;
break;
case 5: // FM
bandwidths_ = IC7600_fm_bws;
bw_vals_ = IC7600_bw_vals_FM;
bw = 0;
break;
case 4: case 7: // RTTY
bandwidths_ = IC7600_rtty_bws;
bw_vals_ = IC7600_bw_vals_RTTY;
bw = 12;
break;
case 3: case 6: // CW
bandwidths_ = IC7600_ssb_bws;
bw_vals_ = IC7600_bw_vals_SSB;
bw = 12;
break;
case 8: case 9: // PKT
bandwidths_ = IC7600_ssb_bws;
bw_vals_ = IC7600_bw_vals_SSB;
bw = 34;
break;
case 0: case 1: // SSB
case 10: case 11 : case 12 :
case 13: case 14 : case 15 :
default:
bandwidths_ = IC7600_ssb_bws;
bw_vals_ = IC7600_bw_vals_SSB;
bw = 34;
}
return bw;
}
const char ** RIG_IC7600::bwtable(int m)
{
const char **table;
switch (m) {
case 2: // AM
table = IC7600_am_bws;
break;
case 5: // FM
table = IC7600_fm_bws;
break;
case 4: case 7: // RTTY
table = IC7600_rtty_bws;
break;
case 3: case 6: // CW
case 8: case 9: // PKT
case 0: case 1: // SSB
case 10: case 11 : case 12 :
case 13: case 14 : case 15 :
default:
table = IC7600_ssb_bws;
}
return table;
}
int RIG_IC7600::def_bandwidth(int m)
{
int bw = 0;
switch (m) {
case 2: // AM
bw = 19;
break;
case 5: // FM
bw = 0;
break;
case 4: case 7: // RTTY
bw = 12;
break;
case 3: case 6: // CW
bw = 12;
break;
case 8: case 9: // PKT
bw = 34;
break;
case 0: case 1: // SSB
case 10: case 11 : case 12 :
case 13: case 14 : case 15 :
default:
bw = 34;
}
return bw;
}
int RIG_IC7600::get_mic_gain()
{
int val = 0;
string cstr = "\x14\x0B";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get mic")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = (int)ceil(fm_bcd(replystr.substr(p+6),3) / 2.55);
}
minmax(0,100,val);
return val;
}
void RIG_IC7600::set_mic_gain(int v)
{
int ICvol = (int)(v * 255 / 100);
minmax(0, 255, ICvol);
if (!progStatus.USBaudio) {
cmd = pre_to;
cmd.append("\x14\x0B");
cmd.append(to_bcd(ICvol, 3));
cmd.append( post );
} else {
cmd = pre_to;
cmd += '\x1A'; cmd += '\x05';
cmd += '\x00'; cmd += '\x29';
cmd.append(to_bcd(ICvol, 3));
cmd.append( post );
}
waitFB("set mic gain");
}
void RIG_IC7600::get_mic_gain_min_max_step(int &min, int &max, int &step)
{
min = 0;
max = 100;
step = 1;
}
// alh added ++++++++++++++++++++++++++++
void RIG_IC7600::set_compression(int on, int val)
{
if (on) {
cmd.assign(pre_to).append("\x14\x0E");
cmd.append(to_bcd(val * 255 / 100, 3));
cmd.append( post );
waitFB("set comp");
cmd = pre_to;
cmd.append("\x16\x44");
cmd += '\x01';
cmd.append(post);
waitFB("set Comp ON");
} else{
cmd.assign(pre_to).append("\x16\x44");
cmd += '\x00';
cmd.append(post);
waitFB("set Comp OFF");
}
}
void RIG_IC7600::set_vox_onoff()
{
if (progStatus.vox_onoff) {
cmd.assign(pre_to).append("\x16\x46\x01");
cmd.append( post );
waitFB("set vox ON");
} else {
cmd.assign(pre_to).append("\x16\x46");
cmd += '\x00'; // ALH
cmd.append( post );
waitFB("set vox OFF");
}
}
void RIG_IC7600::set_vox_gain()
{
cmd.assign(pre_to).append("\x1A\x05"); // ALH values 0-255
cmd +='\x01';
cmd +='\x65';
cmd.append(to_bcd((int)(progStatus.vox_gain * 2.55), 3));
cmd.append( post );
waitFB("SET vox gain");
}
void RIG_IC7600::set_vox_anti()
{
cmd.assign(pre_to).append("\x1A\x05"); //ALH values 0-255
cmd +='\x01';
cmd +='\x66';
cmd.append(to_bcd((int)(progStatus.vox_anti * 2.55), 3));
cmd.append( post );
waitFB("SET anti-vox");
}
void RIG_IC7600::set_vox_hang()
{
cmd.assign(pre_to).append("\x1A\x05"); //ALH values 00-20 = 0.0 - 2.0 sec
cmd +='\x01'; // ALH
cmd +='\x67'; // ALH
cmd.append(to_bcd((int)(progStatus.vox_hang / 10 ), 2));
cmd.append( post );
waitFB("SET vox hang");
}
// CW controls
void RIG_IC7600::set_cw_wpm()
{
cmd.assign(pre_to).append("\x14\x0C"); // values 0-255
cmd.append(to_bcd(round((progStatus.cw_wpm - 6) * 255 / (60 - 6)), 3));
cmd.append( post );
waitFB("SET cw wpm");
}
void RIG_IC7600::set_cw_qsk()
{
int n = round(progStatus.cw_qsk * 10); // values 0-255
cmd.assign(pre_to).append("\x14\x0F");
cmd.append(to_bcd(n, 3));
cmd.append(post);
waitFB("Set cw qsk delay");
}
void RIG_IC7600::set_cw_spot_tone()
{
cmd.assign(pre_to).append("\x14\x09"); // values 0=300Hz 255=900Hz
int n = round((progStatus.cw_spot_tone - 300) * 255.0 / 600.0);
if (n > 255) n = 255;
if (n < 0) n = 0;
cmd.append(to_bcd(n, 3));
cmd.append( post );
waitFB("SET cw spot tone");
}
void RIG_IC7600::set_cw_vol()
{
cmd.assign(pre_to);
cmd.append("\x1A\x05");
cmd += '\x00';
cmd += '\x24'; // ALH / DF
cmd.append(to_bcd((int)(progStatus.cw_vol * 2.55), 3));
cmd.append( post );
waitFB("SET cw sidetone volume");
}
// Tranceiver PTT on/off
void RIG_IC7600::set_PTT_control(int val)
{
cmd = pre_to;
cmd += '\x1c';
cmd += '\x00';
cmd += (unsigned char) val;
cmd.append( post );
waitFB("set ptt");
ptt_ = val;
}
int RIG_IC7600::get_PTT()
{
cmd = pre_to;
cmd += '\x1c'; cmd += '\x00';
string resp = pre_fm;
resp += '\x1c'; resp += '\x00';
cmd.append(post);
if (waitFOR(8, "get PTT")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
ptt_ = replystr[p + 6];
}
return ptt_;
}
// Volume control val 0 ... 100
void RIG_IC7600::set_volume_control(int val)
{
int ICvol = (int)(val * 255 / 100);
minmax(0, 255, ICvol);
cmd = pre_to;
cmd.append("\x14\x01");
cmd.append(to_bcd(ICvol, 3));
cmd.append( post );
waitFB("set vol");
}
/*
I:12:20:22: get vol ans in 0 ms, OK
cmd FE FE 7A E0 14 01 FD
ans FE FE 7A E0 14 01 FD
FE FE E0 7A 14 01 00 65 FD
0 1 2 3 4 5 6 7 8
*/
int RIG_IC7600::get_volume_control()
{
int val = 0;
string cstr = "\x14\x01";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get vol")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = (int)ceil(fm_bcd(replystr.substr(p + 6),3) * 100 / 255);
}
minmax(0, 100, val);
progStatus.volume = val;
return (progStatus.volume);
}
void RIG_IC7600::get_vol_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 100; step = 1;
}
void RIG_IC7600::set_power_control(double value)
{
int val = (int)(value * 255 / 100);
minmax(0, 255, val);
cmd = pre_to;
cmd.append("\x14\x0A");
cmd.append(to_bcd(val, 3));
cmd.append( post );
waitFB("set power");
}
int RIG_IC7600::get_power_control()
{
int val = progStatus.power_level;
string cstr = "\x14\x0A";
string resp = pre_fm;
cmd = pre_to;
cmd.append(cstr).append(post);
resp.append(cstr);
if (waitFOR(9, "get power")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = (int)ceil(fm_bcd(replystr.substr(p + 6),3) * 100 / 255);
}
minmax(0, 100, val);
progStatus.power_level = val;
return (progStatus.power_level);
}
void RIG_IC7600::get_pc_min_max_step(double &min, double &max, double &step)
{
min = 2; max = 100; step = 1;
}
int RIG_IC7600::get_smeter()
{
string cstr = "\x15\x02";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
int mtr= -1;
if (waitFOR(9, "get smeter")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
mtr = fm_bcd(replystr.substr(p+6), 3);
mtr = (int)ceil(mtr /2.41);
if (mtr > 100) mtr = 100;
}
}
return mtr;
}
int RIG_IC7600::get_power_out(void)
{
string cstr = "\x15\x11";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
int mtr= -1;
if (waitFOR(9, "get power out")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
mtr = fm_bcd(replystr.substr(p+6), 3);
mtr = (int)ceil(mtr /2.13);
if (mtr > 100) mtr = 100;
}
}
return mtr;
}
int RIG_IC7600::get_swr(void)
{
string cstr = "\x15\x12";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
int mtr= -1;
if (waitFOR(9, "get swr")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
mtr = fm_bcd(replystr.substr(p+6), 3);
mtr = (int)ceil(mtr /2.55);
if (mtr > 100) mtr = 100;
}
}
return mtr;
}
int RIG_IC7600::get_alc(void)
{
string cstr = "\x15\x13";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
int mtr= -1;
if (waitFOR(9, "get alc")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
mtr = fm_bcd(replystr.substr(p+6), 3);
mtr = (int)ceil(mtr /1.2);
if (mtr > 100) mtr = 100;
}
}
return mtr;
}
void RIG_IC7600::set_rf_gain(int val)
{
int ICrfg = (int)(val * 255 / 100);
minmax(0, 255, ICrfg);
cmd = pre_to;
cmd.append("\x14\x02");
cmd.append(to_bcd(ICrfg, 3));
cmd.append( post );
waitFB("set RF");
}
int RIG_IC7600::get_rf_gain()
{
int val = progStatus.rfgain;
string cstr = "\x14\x02";
string resp = pre_fm;
cmd = pre_to;
cmd.append(cstr).append(post);
resp.append(cstr);
if (waitFOR(9, "get RF")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = (int)(fm_bcd(replystr.substr(p + 6),3) * 100 / 255);
}
minmax(0, 100, val);
progStatus.rfgain = val;
return (progStatus.rfgain);
}
void RIG_IC7600::get_rf_min_max_step(double &min, double &max, double &step)
{
min = 0; max = 100; step = 1;
}
int RIG_IC7600::next_preamp()
{
switch (preamp_level) {
case 0: return 1;
case 1: return 2;
case 2: return 0;
}
return 0;
}
void RIG_IC7600::set_preamp(int val)
{
cmd = pre_to;
cmd += '\x16';
cmd += '\x02';
if (preamp_level == 1) {
preamp_label("Amp 1", true);
} else if (preamp_level == 2) {
preamp_label("Amp 2", true);
} else if (preamp_level == 0) {
preamp_label("OFF", false);
}
cmd += (unsigned char)preamp_level;
cmd.append( post );
waitFB("set Pre");
}
int RIG_IC7600::get_preamp()
{
preamp_level = progStatus.preamp;
string cstr = "\x16\x02";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(8, "get Pre")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
preamp_level = replystr[p+6];
if (preamp_level == 1) {
preamp_label("Amp 1", true);
} else if (preamp_level == 2) {
preamp_label("Amp 2", true);
} else {
preamp_label("OFF", false);
preamp_level = 0;
}
}
}
return preamp_level;
}
int RIG_IC7600::next_attenuator()
{
switch (atten_level) {
case 0x00: return 0x06;
case 0x06: return 0x12;
case 0x12: return 0x18;
case 0x18: return 0x00;
}
return 0;
}
void RIG_IC7600::set_attenuator(int val)
{
atten_level = val;
if (atten_level == 0x06) {
atten_label("6 dB", true);
} else if (atten_level == 0x12) {
atten_label("12 dB", true);
} else if (atten_level == 0x18) {
atten_label("18 dB", true);
} else if (atten_level == 0x00) {
atten_label("ATT", false);
}
cmd = pre_to;
cmd += '\x11';
cmd += atten_level;
cmd.append( post );
waitFB("set att");
}
int RIG_IC7600::get_attenuator()
{
cmd = pre_to;
string resp = pre_fm;
cmd += '\x11';
resp += '\x11';
cmd.append( post );
if (waitFOR(7, "get ATT")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
atten_level = replystr[p+5];
if (atten_level == 0x06) {
atten_label("6 dB", true);
} else if (atten_level == 0x12) {
atten_label("12 dB", true);
} else if (atten_level == 0x18) {
atten_label("18 dB", true);
} else {
atten_level = 0x00;
atten_label("ATT", false);
}
}
return atten_level;
}
void RIG_IC7600::set_noise(bool val)
{
cmd = pre_to;
cmd.append("\x16\x22");
cmd += val ? 1 : 0;
cmd.append(post);
waitFB("set noise");
}
/*
I:12:06:50: get noise ans in 0 ms, OK
cmd FE FE 7A E0 16 22 FD
ans FE FE 7A E0 16 22 FD FE FE E0 7A 16 22 00 FD
*/
int RIG_IC7600::get_noise()
{
string cstr = "\x16\x22";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get noise")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (replystr[p+6] ? 1 : 0);
}
return progStatus.noise;
}
void RIG_IC7600::set_noise_reduction(int val)
{
cmd = pre_to;
cmd.append("\x16\x40");
cmd += val ? 1 : 0;
cmd.append(post);
waitFB("set NR");
}
int RIG_IC7600::get_noise_reduction()
{
string cstr = "\x16\x40";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get NR")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (replystr[p+6] ? 1 : 0);
}
return progStatus.noise_reduction;
}
/*
I:12:06:50: get NR ans in 0 ms, OK
cmd FE FE 7A E0 16 40 FD
ans FE FE 7A E0 16 40 FD
FE FE E0 7A 16 40 01 FD
0 1 2 3 4 5 6 7
I:12:06:50: get NRval ans in 0 ms, OK
cmd FE FE 7A E0 14 06 FD
ans FE FE 7A E0 14 06 FD
FE FE E0 7A 14 06 00 24 FD
0 1 2 3 4 5 6 7 8
*/
void RIG_IC7600::set_noise_reduction_val(int val)
{
cmd = pre_to;
cmd.append("\x14\x06");
cmd.append(to_bcd(val * 255 / 100, 3));
cmd.append(post);
waitFB("set NRval");
}
int RIG_IC7600::get_noise_reduction_val()
{
int val = progStatus.noise_reduction_val;
string cstr = "\x14\x06";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get NRval")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = (int)ceil(fm_bcd(replystr.substr(p+6),3) * 100 / 255);
}
minmax(0, 100, val);
return val;
}
void RIG_IC7600::set_squelch(int val)
{
int ICsql = (int)(val * 255 / 100);
minmax(0, 255, ICsql);
cmd = pre_to;
cmd.append("\x14\x03");
cmd.append(to_bcd(ICsql, 3));
cmd.append( post );
waitFB("set Sqlch");
}
int RIG_IC7600::get_squelch()
{
int val = progStatus.squelch;
string cstr = "\x14\x03";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get squelch")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = (int)ceil(fm_bcd(replystr.substr(p+6), 3) * 100 / 255);
}
minmax(0, 100, val);
progStatus.squelch = val;
return (progStatus.squelch);
}
void RIG_IC7600::set_auto_notch(int val)
{
cmd = pre_to;
cmd += '\x16';
cmd += '\x41';
cmd += (unsigned char)val;
cmd.append( post );
waitFB("set AN");
}
int RIG_IC7600::get_auto_notch()
{
string cstr = "\x16\x41";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(8, "get AN")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
if (replystr[p+6] == 0x01) {
auto_notch_label("AN", true);
return true;
} else {
auto_notch_label("AN", false);
return false;
}
}
}
return progStatus.auto_notch;
}
static bool IC7600_notchon = false;
void RIG_IC7600::set_notch(bool on, int val)
{
int notch = val / 20 + 53;
minmax(0, 255, notch);
if (on != IC7600_notchon) {
cmd = pre_to;
cmd.append("\x16\x48");
cmd += on ? '\x01' : '\x00';
cmd.append(post);
waitFB("set notch");
IC7600_notchon = on;
}
if (on) {
cmd = pre_to;
cmd.append("\x14\x0D");
cmd.append(to_bcd(notch,3));
cmd.append(post);
waitFB("set notch val");
}
}
bool RIG_IC7600::get_notch(int &val)
{
bool on = false;
val = 0;
string cstr = "\x16\x48";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(8, "get notch")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
on = replystr[p + 6] ? 1 : 0;
cmd = pre_to;
resp = pre_fm;
cstr = "\x14\x0D";
cmd.append(cstr);
resp.append(cstr);
cmd.append(post);
if (waitFOR(9, "get notch val")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = fm_bcd(replystr.substr(p+6),3);
val = (val - 53) * 20;
if (val < 0) val = 0;
if (val > 4040) val = 4040;
}
}
}
return (IC7600_notchon = on);
}
void RIG_IC7600::get_notch_min_max_step(int &min, int &max, int &step)
{
min = 0;
max = 4040;
step = 20;
}
void RIG_IC7600::set_pbt_inner(int val)
{
int shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x07");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set PBT inner");
}
void RIG_IC7600::set_pbt_outer(int val)
{
int shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x08");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set PBT outer");
}
int RIG_IC7600::get_pbt_inner()
{
int val = 0;
string cstr = "\x14\x07";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get pbt inner")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = num100(replystr.substr(p+6));
val -= 50;
}
}
rig_trace(2, "get_pbt_inner()", str2hex(replystr.c_str(), replystr.length()));
return val;
}
int RIG_IC7600::get_pbt_outer()
{
int val = 0;
string cstr = "\x14\x08";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get pbt inner")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = num100(replystr.substr(p+6));
val -= 50;
}
}
rig_trace(2, "get_pbt_outer()", str2hex(replystr.c_str(), replystr.length()));
return val;
}
const char *RIG_IC7600::FILT(int &val)
{
if (useB) {
if (filB < 0) filB = 0;
if (filB > 3) filB = 3;
val = filB;
return(szfilter[filB - 1]);
}
else {
if (filA < 0) filA = 0;
if (filA > 3) filA = 3;
val = filA;
return (szfilter[filA - 1]);
}
}
const char *RIG_IC7600::nextFILT()
{
if (useB) {
filB++;
if (filB > 3) filB = 1;
set_modeB(B.imode);
return(szfilter[filB - 1]);
} else {
filA++;
if (filA > 3) filA = 1;
set_modeA(A.imode);
return(szfilter[filA - 1]);
}
}
// Read/Write band stack registers
//
// Read 23 bytes
//
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// FE FE nn E0 1A 01 bd rn f5 f4 f3 f2 f1 mo fi fg t1 t2 t3 r1 r2 r3 FD
// Write 23 bytes
//
// FE FE E0 nn 1A 01 bd rn f5 f4 f3 f2 f1 mo fi fg t1 t2 t3 r1 r2 r3 FD
//
// nn - CI-V address
// bd - band selection 1/2/3
// rn - register number 1/2/3
// f5..f1 - frequency BCD reverse
// mo - mode
// fi - filter #
// fg flags: x01 use Tx tone, x02 use Rx tone, x10 data mode
// t1..t3 - tx tone BCD fwd
// r1..r3 - rx tone BCD fwd
//
// FE FE E0 94 1A 01 06 01 70 99 08 18 00 01 03 10 00 08 85 00 08 85 FD
//
// band 6; freq 0018,089,970; USB; data mode; t 88.5; r 88.5
void RIG_IC7600::get_band_selection(int v)
{
cmd.assign(pre_to);
cmd.append("\x1A\x01");
cmd += to_bcd_be( v, 2 );
cmd += '\x01';
cmd.append( post );
if (waitFOR(23, "get band stack")) {
set_trace(2, "get band stack", str2hex(replystr.c_str(), replystr.length()));
size_t p = replystr.rfind(pre_fm);
if (p != string::npos) {
long int bandfreq = fm_bcd_be(replystr.substr(p+8, 5), 10);
int bandmode = replystr[p+13];
int bandfilter = replystr[p+14];
int banddata = replystr[p+15] & 0x10;
int tone = fm_bcd(replystr.substr(p+16, 3), 6);
size_t index = 0;
for (index = 0; index < sizeof(PL_tones) / sizeof(*PL_tones); index++)
if (tone == PL_tones[index]) break;
tTONE = index;
tone = fm_bcd(replystr.substr(p+19, 3), 6);
for (index = 0; index < sizeof(PL_tones) / sizeof(*PL_tones); index++)
if (tone == PL_tones[index]) break;
rTONE = index;
if ((bandmode == 0) && banddata)
bandmode = ((banddata == 0x10) ? 10 :
(banddata == 0x20) ? 11 :
(banddata == 0x30) ? 12 : 0);
if ((bandmode == 1) && banddata)
bandmode = ((banddata == 0x10) ? 13 :
(banddata == 0x20) ? 14 :
(banddata == 0x30) ? 15 : 0);
if (useB) {
set_vfoB(bandfreq);
set_modeB(bandmode);
set_FILT(bandfilter);
} else {
set_vfoA(bandfreq);
set_modeA(bandmode);
set_FILT(bandfilter);
}
}
} else
set_trace(2, "get band stack", str2hex(replystr.c_str(), replystr.length()));
}
void RIG_IC7600::set_band_selection(int v)
{
long freq = (useB ? B.freq : A.freq);
int fil = (useB ? filB : filA);
int mode = (useB ? B.imode : A.imode);
cmd.assign(pre_to);
cmd.append("\x1A\x01");
cmd += to_bcd_be( v, 2 );
cmd += '\x01';
cmd.append( to_bcd_be( freq, 10 ) );
cmd += mode;
cmd += fil;
if (mode >= 9)
cmd += '\x10';
else
cmd += '\x00';
cmd.append(to_bcd(PL_tones[tTONE], 6));
cmd.append(to_bcd(PL_tones[rTONE], 6));
cmd.append(post);
waitFB("set_band_selection");
set_trace(2, "set_band_selection()", str2hex(replystr.c_str(), replystr.length()));
cmd.assign(pre_to);
cmd.append("\x1A\x01");
cmd += to_bcd_be( v, 2 );
cmd += '\x01';
cmd.append( post );
waitFOR(23, "get band stack");
}
flrig-1.3.49/src/rigs/TS480SAT.cxx 0000644 0001750 0001750 00000067615 13472116065 013271 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include "TS480SAT.h"
#include "support.h"
static const char TS480SATname_[] = "TS-480SAT";
static const char *TS480SATmodes_[] = {
"LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "FSK-R", NULL};
static const char TS480SAT_mode_chr[] = { '1', '2', '3', '4', '5', '6', '7', '9' };
static const char TS480SAT_mode_type[] = { 'L', 'U', 'U', 'U', 'U', 'L', 'L', 'U' };
static const char *TS480SAT_empty[] = { "N/A", NULL };
static int TS480SAT_bw_vals[] = {1, WVALS_LIMIT};
// SL command is lo cut when menu 045 OFF
static const char *TS480SAT_SL[] = {
"0", "50", "100", "200", "300",
"400", "500", "600", "700", "800",
"900", "1000", NULL };
static const char *TS480SAT_SL_tooltip = "lo cut";
static const char *TS480SAT_btn_SL_label = "L";
// SH command is hi cut when menu 045 OFF
static const char *TS480SAT_SH[] = {
"1000", "1200", "1400", "1600", "1800",
"2000", "2200", "2400", "2600", "2800",
"3000", "3400", "4000", "5000", NULL };
static int TS480SAT_HI_bw_vals[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,WVALS_LIMIT};
static const char *TS480SAT_SH_tooltip = "hi cut";
static const char *TS480SAT_btn_SH_label = "H";
// SL command is width when menu 045 ON
static const char *TS480SAT_dataW[] = {
"50", "100", "250", "500", "1000", "1500", "2400", NULL };
static int TS480SAT_data_bw_vals[] = {1,2,3,4,5,6,7, WVALS_LIMIT};
static const char *TS480SAT_dataW_tooltip = "width";
static const char *TS480SAT_dataW_label = "W";
// SH command is center when menu 045 ON
static const char *TS480SAT_dataC[] = {
"1000", "1500", "2210", NULL };
static const char *TS480SAT_dataC_tooltip = "center";
static const char *TS480SAT_dataC_label = "C";
static const char *TS480SAT_AM_SL[] = {
"10", "100", "200", "500",
NULL };
static const char *TS480SAT_AM_SH[] = {
"2500", "3000", "4000", "5000",
NULL };
//static int TS480SAT_AM_bw_vals[] = {1,2,3,4,WVALS_LIMIT};
static const char *TS480SAT_CWwidths[] = {
"50", "80", "100", "150", "200",
"300", "400", "500", "600", "1000",
"2000", NULL};
static int TS480SAT_CW_bw_vals[] = {1,2,3,4,5,6,7,8,9,10,11,WVALS_LIMIT};
static const char *TS480SAT_CWbw[] = {
"FW0050;", "FW0080;", "FW0100;", "FW0150;", "FW0200;",
"FW0300;", "FW0400;", "FW0500;", "FW0600;", "FW1000;",
"FW2000;" };
static const char *TS480SAT_FSKwidths[] = {
"250", "500", "1000", "1500", NULL};
static int TS480SAT_FSK_bw_vals[] = { 1,2,3,4,WVALS_LIMIT};
static const char *TS480SAT_FSKbw[] = {
"FW0250;", "FW0500;", "FW1000;", "FW1500;" };
static int agcval = 1;
static bool fm_mode = false;
static GUI rig_widgets[]= {
{ (Fl_Widget *)btnVol, 2, 125, 50 }, // 0
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 }, // 1
{ (Fl_Widget *)sldrRFGAIN, 54, 145, 156 }, // 2
{ (Fl_Widget *)btnIFsh, 214, 105, 50 }, // 3
{ (Fl_Widget *)sldrIFSHIFT, 266, 105, 156 }, // 4
{ (Fl_Widget *)btnDataPort, 214, 125, 50 }, // 5
{ (Fl_Widget *)sldrSQUELCH, 266, 125, 156 }, // 6
{ (Fl_Widget *)sldrMICGAIN, 266, 145, 156 }, // 7
{ (Fl_Widget *)sldrPOWER, 54, 165, 368 }, // 8
{ (Fl_Widget *)NULL, 0, 0, 0 }
};
static string menu012 = "EX01200004";
void RIG_TS480SAT::initialize()
{
rig_widgets[0].W = btnVol;
rig_widgets[1].W = sldrVOLUME;
rig_widgets[2].W = sldrRFGAIN;
rig_widgets[3].W = btnIFsh;
rig_widgets[4].W = sldrIFSHIFT;
rig_widgets[5].W = btnDataPort;
rig_widgets[6].W = sldrSQUELCH;
rig_widgets[7].W = sldrMICGAIN;
rig_widgets[8].W = sldrPOWER;
check_menu_45();
menu012.clear();
cmd = "EX0120000;"; // read menu 012 state
//might return something like EX01200004;
gett("read menu 12");
if (wait_char(';', 11, 100, "read ex 012", ASC) == 11)
menu012 = replystr;
cmd = "EX01200000;";
sendCommand(cmd);
sett("set menu 12");
};
RIG_TS480SAT::RIG_TS480SAT() {
// base class values
name_ = TS480SATname_;
modes_ = TS480SATmodes_;
_mode_type = TS480SAT_mode_type;
bandwidths_ = TS480SAT_empty;
bw_vals_ = TS480SAT_bw_vals;
dsp_SL = TS480SAT_SL;
SL_tooltip = TS480SAT_SL_tooltip;
SL_label = TS480SAT_btn_SL_label;
dsp_SH = TS480SAT_SH;
SH_tooltip = TS480SAT_SH_tooltip;
SH_label = TS480SAT_btn_SH_label;
widgets = rig_widgets;
comm_baudrate = BR57600;
stopbits = 1;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_rtscts = true;
comm_rtsplus = false;
comm_dtrplus = false;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
B.imode = A.imode = 1;
B.iBW = A.iBW = 0x8A03;
B.freq = A.freq = 14070000;
can_change_alt_vfo = true;
has_extras = true;
has_noise_reduction =
has_noise_reduction_control =
has_auto_notch =
has_noise_control =
has_sql_control =
has_split = true;
has_split_AB = true;
has_data_port = true;
has_micgain_control = true;
has_ifshift_control = true;
has_rf_control = true;
has_agc_control = true;
has_swr_control = true;
has_alc_control = true;
has_power_out = true;
has_dsp_controls = true;
has_smeter = true;
has_attenuator_control = true;
has_preamp_control = true;
has_mode_control = true;
has_bandwidth_control = true;
has_volume_control = true;
has_power_control = true;
has_tune_control = true;
has_ptt_control = true;
precision = 1;
ndigits = 8;
_noise_reduction_level = 0;
_nrval1 = 2;
_nrval2 = 4;
}
const char * RIG_TS480SAT::get_bwname_(int n, int md)
{
static char bwname[20];
if (n > 256) {
int hi = (n >> 8) & 0x7F;
int lo = n & 0xFF;
snprintf(bwname, sizeof(bwname), "%s/%s",
(md == 0 || md == 1 || md == 3) ? dsp_SL[lo] : TS480SAT_AM_SL[lo],
(md == 0 || md == 1 || md == 3) ? dsp_SH[hi] : TS480SAT_AM_SH[hi] );
} else {
snprintf(bwname, sizeof(bwname), "%s",
(md == 2 || md == 6) ? TS480SAT_CWwidths[n] : TS480SAT_FSKwidths[n]);
}
return bwname;
}
void RIG_TS480SAT::check_menu_45()
{
// read current switch 45 setting
menu_45 = false;
cmd = "EX0450000;";
if (wait_char(';', 11, 100, "Check menu item 45", ASC) >= 11) {
size_t p = replystr.rfind("EX045");
if (p != string::npos)
menu_45 = (replystr[p+9] == '1');
}
if (menu_45) {
dsp_SL = TS480SAT_dataW;
SL_tooltip = TS480SAT_dataW_tooltip;
SL_label = TS480SAT_dataW_label;
dsp_SH = TS480SAT_dataC;
SH_tooltip = TS480SAT_dataC_tooltip;
SH_label = TS480SAT_dataC_label;
B.iBW = A.iBW = 0x8106;
} else {
dsp_SL = TS480SAT_SL;
SL_tooltip = TS480SAT_SL_tooltip;
SL_label = TS480SAT_btn_SL_label;
dsp_SH = TS480SAT_SH;
SH_tooltip = TS480SAT_SH_tooltip;
SH_label = TS480SAT_btn_SH_label;
B.iBW = A.iBW = 0x8A03;
}
gett("check menu 45");
}
void RIG_TS480SAT::shutdown()
{
// restore state of xcvr beeps
if (menu012.empty()) return;
cmd = menu012;
sendCommand(cmd);
sett("shutdown, restore menu 12");
}
// SM cmd 0 ... 100 (rig values 0 ... 15)
int RIG_TS480SAT::get_smeter()
{
int mtr = 0;
cmd = "SM0;";
if (wait_char(';', 8, 100, "get Smeter", ASC) < 8) return 0;
size_t p = replystr.rfind("SM");
if (p != string::npos)
mtr = 5 * atoi(&replystr[p + 3]);
gett("get smeter");
return mtr;
}
struct pwrpair {int mtr; float pwr;};
static pwrpair pwrtbl[] = {
{0, 0.0},
{2, 5.0},
{4, 10.0},
{7, 25.0},
{11, 50.0},
{16, 100.0},
{20, 200.0} };
int RIG_TS480SAT::get_power_out()
{
int mtr = 0;
cmd = "SM0;";
if (wait_char(';', 8, 100, "get power", ASC) < 8) return mtr;
size_t p = replystr.rfind("SM");
if (p != string::npos) {
mtr = atoi(&replystr[p + 3]);
size_t i = 0;
for (i = 0; i < sizeof(pwrtbl) / sizeof(pwrpair) - 1; i++)
if (mtr >= pwrtbl[i].mtr && mtr < pwrtbl[i+1].mtr)
break;
if (mtr < 0) mtr = 0;
if (mtr > 20) mtr = 20;
mtr = (int)ceil(pwrtbl[i].pwr +
(pwrtbl[i+1].pwr - pwrtbl[i].pwr)*(mtr - pwrtbl[i].mtr)/(pwrtbl[i+1].mtr - pwrtbl[i].mtr));
if (mtr > 200) mtr = 200;
}
gett("power out");
return mtr;
}
// RM cmd 0 ... 100 (rig values 0 ... 8)
// User report of RM; command using Send Cmd tab
// RM10000;RM20000;RM30000;
// RM1nnnn; => SWR
// RM2nnnn; => COMP
// RM3nnnn; => ALC
int RIG_TS480SAT::get_swr()
{
int mtr = 0;
cmd = "RM;";
if (wait_char(';', 8, 100, "get SWR/ALC", ASC) < 8) return (int)mtr;
size_t p = replystr.rfind("RM1");
if (p != string::npos)
mtr = 66 * atoi(&replystr[p + 3]) / 10;
p = replystr.rfind("RM3");
if (p != string::npos)
alc = 66 * atoi(&replystr[p+3]) / 10;
else
alc = 0;
swralc_polled = true;
gett("swr");
return mtr;
}
int RIG_TS480SAT::get_alc(void)
{
if (!swralc_polled) get_swr();
swralc_polled = false;
return alc;
}
int RIG_TS480SAT::set_widths(int val)
{
int bw;
if (val == 0 || val == 1 || val == 3) {
if (menu_45) {
bw = 0x8106; // 1500 Hz 2400 wide
dsp_SL = TS480SAT_dataW;
SL_tooltip = TS480SAT_dataW_tooltip;
SL_label = TS480SAT_dataW_label;
dsp_SH = TS480SAT_dataC;
SH_tooltip = TS480SAT_dataC_tooltip;
SH_label = TS480SAT_dataC_label;
bandwidths_ = TS480SAT_dataW;
bw_vals_ = TS480SAT_data_bw_vals;
} else {
bw = 0x8A03; // 200 ... 3000 Hz
dsp_SL = TS480SAT_SL;
SL_tooltip = TS480SAT_SL_tooltip;
SL_label = TS480SAT_btn_SL_label;
dsp_SH = TS480SAT_SH;
SH_tooltip = TS480SAT_SH_tooltip;
SH_label = TS480SAT_btn_SH_label;
bandwidths_ = TS480SAT_SH;
bw_vals_ = TS480SAT_HI_bw_vals;
}
} else if (val == 2 || val == 6) {
bandwidths_ = TS480SAT_CWwidths;
bw_vals_ = TS480SAT_CW_bw_vals;
dsp_SL = TS480SAT_empty;
dsp_SH = TS480SAT_empty;
bw = 7;
} else if (val == 5 || val == 7) {
bandwidths_ = TS480SAT_FSKwidths;
bw_vals_ = TS480SAT_FSK_bw_vals;
dsp_SL = TS480SAT_empty;
dsp_SH = TS480SAT_empty;
bw = 1;
} else { // val == 4 ==> AM
bandwidths_ = TS480SAT_empty;
bw_vals_ = TS480SAT_bw_vals;
dsp_SL = TS480SAT_AM_SL;
dsp_SH = TS480SAT_AM_SH;
bw = 0x8201;
}
return bw;
}
const char **RIG_TS480SAT::bwtable(int m)
{
if (m == 0 || m == 1 || m == 3)
return TS480SAT_empty;
else if (m == 2 || m == 6)
return TS480SAT_CWwidths;
else if (m == 5 || m == 7)
return TS480SAT_FSKwidths;
//else AM m == 4
return TS480SAT_empty;
}
const char **RIG_TS480SAT::lotable(int m)
{
if (m == 0 || m == 1 || m == 3)
return TS480SAT_SL;
else if (m == 2 || m == 6)
return NULL;
else if (m == 5 || m == 7)
return NULL;
return TS480SAT_AM_SL;
}
const char **RIG_TS480SAT::hitable(int m)
{
if (m == 0 || m == 1 || m == 3)
return TS480SAT_SH;
else if (m == 2 || m == 6)
return NULL;
else if (m == 5 || m == 7)
return NULL;
return TS480SAT_AM_SH;
}
void RIG_TS480SAT::set_modeA(int val)
{
if (val == 3) fm_mode = true;
else fm_mode = false;
A.imode = val;
cmd = "MD";
cmd += TS480SAT_mode_chr[val];
cmd += ';';
sendCommand(cmd);
showresp(WARN, ASC, "set mode", cmd, "");
A.iBW = set_widths(val);
sett("set mode A");
}
int RIG_TS480SAT::get_modeA()
{
cmd = "MD;";
if (wait_char(';', 4, 100, "get modeA", ASC) < 4) return A.imode;
size_t p = replystr.rfind("MD");
if (p != string::npos && (p + 2 < replystr.length())) {
int md = replystr[p+2];
md = md - '1';
if (md == 8) md = 7;
A.imode = md;
A.iBW = set_widths(A.imode);
}
if (A.imode == 3) fm_mode = true;
else fm_mode = false;
gett("mode A");
return A.imode;
}
void RIG_TS480SAT::set_modeB(int val)
{
if (val == 3) fm_mode = true;
else fm_mode = false;
B.imode = val;
cmd = "MD";
cmd += TS480SAT_mode_chr[val];
cmd += ';';
sendCommand(cmd);
showresp(WARN, ASC, "set mode B", cmd, "");
B.iBW = set_widths(val);
sett("mode B");
}
int RIG_TS480SAT::get_modeB()
{
cmd = "MD;";
if (wait_char(';', 4, 100, "get modeB", ASC) < 4) return B.imode;
size_t p = replystr.rfind("MD");
if (p != string::npos && (p + 2 < replystr.length())) {
int md = replystr[p+2];
md = md - '1';
if (md == 8) md = 7;
B.imode = md;
B.iBW = set_widths(B.imode);
}
if (B.imode == 3) fm_mode = true;
else fm_mode = false;
gett("mode B");
return B.imode;
}
int RIG_TS480SAT::get_modetype(int n)
{
return _mode_type[n];
}
void RIG_TS480SAT::set_bwA(int val)
{
if (A.imode == 0 || A.imode == 1 || A.imode == 3 || A.imode == 4) {
if (val < 256) return;
A.iBW = val;
cmd = "SL";
cmd.append(to_decimal(A.iBW & 0xFF, 2)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, SL_tooltip, cmd, "");
cmd = "SH";
cmd.append(to_decimal(((A.iBW >> 8) & 0x7F), 2)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, SH_tooltip, cmd, "");
sett("bw A");
}
if (val > 256) return;
else if (A.imode == 2 || A.imode == 6) {
A.iBW = val;
cmd = TS480SAT_CWbw[A.iBW];
sendCommand(cmd);
showresp(WARN, ASC, "set CW bw", cmd, "");
sett("bw A");
}else if (A.imode == 5 || A.imode == 7) {
A.iBW = val;
cmd = TS480SAT_FSKbw[A.iBW];
sendCommand(cmd);
showresp(WARN, ASC, "set FSK bw", cmd, "");
sett("bw A");
}
}
int RIG_TS480SAT::get_bwA()
{
int i = 0;
size_t p;
bool menu45 = menu_45;
check_menu_45();
if (menu45 != menu_45)
Fl::awake(updateBandwidthControl);
if (A.imode == 0 || A.imode == 1 || A.imode == 3 || A.imode == 4) {
int lo = A.iBW & 0xFF, hi = (A.iBW >> 8) & 0x7F;
cmd = "SL;";
if (wait_char(';', 5, 100, "get SL", ASC) == 5) {
p = replystr.rfind("SL");
if (p != string::npos)
lo = fm_decimal(replystr.substr(p+2), 2);
}
cmd = "SH;";
if (wait_char(';', 5, 100, "get SH", ASC) == 5) {
p = replystr.rfind("SH");
if (p != string::npos)
hi = fm_decimal(replystr.substr(p+2), 2);
A.iBW = ((hi << 8) | (lo & 0xFF)) | 0x8000;
}
} else if (A.imode == 2 || A.imode == 6) {
cmd = "FW;";
if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
p = replystr.rfind("FW");
if (p != string::npos) {
for (i = 0; i < 11; i++)
if (replystr.find(TS480SAT_CWbw[i]) == p)
break;
if (i == 11) i = 10;
A.iBW = i;
}
}
} else if (A.imode == 5 || A.imode == 7) {
cmd = "FW;";
if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
p = replystr.rfind("FW");
if (p != string::npos) {
for (i = 0; i < 4; i++)
if (replystr.find(TS480SAT_FSKbw[i]) == p)
break;
if (i == 4) i = 3;
A.iBW = i;
}
}
}
gett("get bw A");
return A.iBW;
}
void RIG_TS480SAT::set_bwB(int val)
{
if (B.imode == 0 || B.imode == 1 || B.imode == 3 || B.imode == 4) {
if (val < 256) return;
B.iBW = val;
cmd = "SL";
cmd.append(to_decimal(B.iBW & 0xFF, 2)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, SL_tooltip, cmd, "");
cmd = "SH";
cmd.append(to_decimal(((B.iBW >> 8) & 0x7F), 2)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, SH_tooltip, cmd, "");
sett("bw B");
}
if (val > 256) return;
else if (B.imode == 2 || B.imode == 6) { // CW
B.iBW = val;
cmd = TS480SAT_CWbw[B.iBW];
sendCommand(cmd);
showresp(WARN, ASC, "set CW bw", cmd, "");
sett("bw B");
}else if (B.imode == 5 || B.imode == 7) {
B.iBW = val;
cmd = TS480SAT_FSKbw[B.iBW];
sendCommand(cmd);
showresp(WARN, ASC, "set FSK bw", cmd, "");
sett("bw B");
}
}
int RIG_TS480SAT::get_bwB()
{
int i = 0;
size_t p;
bool menu45 = menu_45;
check_menu_45();
if (menu45 != menu_45)
Fl::awake(updateBandwidthControl);
if (B.imode == 0 || B.imode == 1 || B.imode == 3 || B.imode == 4) {
int lo = B.iBW & 0xFF, hi = (B.iBW >> 8) & 0x7F;
cmd = "SL;";
if (wait_char(';', 5, 100, "get SL", ASC) == 5) {
p = replystr.rfind("SL");
if (p != string::npos)
lo = fm_decimal(replystr.substr(p+2), 2);
}
cmd = "SH;";
if (wait_char(';', 5, 100, "get SH", ASC) == 5) {
p = replystr.rfind("SH");
if (p != string::npos)
hi = fm_decimal(replystr.substr(p+2), 2);
B.iBW = ((hi << 8) | (lo & 0xFF)) | 0x8000;
}
} else if (B.imode == 2 || B.imode == 6) {
cmd = "FW;";
if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
p = replystr.rfind("FW");
if (p != string::npos) {
for (i = 0; i < 11; i++)
if (replystr.find(TS480SAT_CWbw[i]) == p)
break;
if (i == 11) i = 10;
B.iBW = i;
}
}
} else if (B.imode == 5 || B.imode == 7) {
cmd = "FW;";
if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
p = replystr.rfind("FW");
if (p != string::npos) {
for (i = 0; i < 4; i++)
if (replystr.find(TS480SAT_FSKbw[i]) == p)
break;
if (i == 4) i = 3;
B.iBW = i;
}
}
}
gett("bw B");
return B.iBW;
}
int RIG_TS480SAT::adjust_bandwidth(int val)
{
int bw = 0;
if (val == 0 || val == 1 || val == 3)
bw = 0x8A03;
else if (val == 4)
bw = 0x8201;
else if (val == 2 || val == 6)
bw = 7;
else if (val == 5 || val == 7)
bw = 1;
return bw;
}
int RIG_TS480SAT::def_bandwidth(int val)
{
return adjust_bandwidth(val);
}
void RIG_TS480SAT::set_power_control(double val)
{
cmd = "PC";
char szval[4];
if (modeA == 4 && val > 25) val = 25; // AM mode limitation
snprintf(szval, sizeof(szval), "%03d", (int)val);
cmd += szval;
cmd += ';';
LOG_WARN("%s", cmd.c_str());
sendCommand(cmd);
sett("power control");
}
int RIG_TS480SAT::get_power_control()
{
int val = progStatus.power_level;
cmd = "PC;";
if (wait_char(';', 6, 100, "get Power control", ASC) < 6) return val;
size_t p = replystr.rfind("PC");
if (p == string::npos) return val;
val = atoi(&replystr[p + 2]);
gett("power control");
return val;
}
void RIG_TS480SAT::set_attenuator(int val)
{
if (val) cmd = "RA01;";
else cmd = "RA00;";
LOG_WARN("%s", cmd.c_str());
sendCommand(cmd);
sett("attenuator");
}
int RIG_TS480SAT::get_attenuator()
{
cmd = "RA;";
if (wait_char(';', 7, 100, "get attenuator", ASC) < 7) return progStatus.attenuator;
size_t p = replystr.rfind("RA");
gett("attenuator");
if (p == string::npos) return progStatus.attenuator;
if (replystr[p+3] == '1') return 1;
return 0;
}
void RIG_TS480SAT::set_preamp(int val)
{
if (val) cmd = "PA1;";
else cmd = "PA0;";
LOG_WARN("%s", cmd.c_str());
sendCommand(cmd);
sett("preamp");
}
int RIG_TS480SAT::get_preamp()
{
cmd = "PA;";
if (wait_char(';', 5, 100, "get preamp", ASC) < 5) return progStatus.preamp;
size_t p = replystr.rfind("PA");
gett("preamp");
if (p == string::npos) return progStatus.preamp;
if (replystr[p+2] == '1') return 1;
return 0;
}
void RIG_TS480SAT::set_if_shift(int val)
{
cmd = "IS+";
if (val < 0) cmd[2] = '-';
cmd.append(to_decimal(abs(val),4)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, "set IF shift", cmd, "");
sett("if shift");
}
bool RIG_TS480SAT::get_if_shift(int &val)
{
cmd = "IS;";
if (wait_char(';', 8, 100, "get IF shift", ASC) == 8) {
size_t p = replystr.rfind("IS");
gett("if shift");
if (p != string::npos) {
val = fm_decimal(replystr.substr(p+3), 4);
if (replystr[p+2] == '-') val *= -1;
return (val != 0);
}
}
val = progStatus.shift_val;
return progStatus.shift;
}
void RIG_TS480SAT::get_if_min_max_step(int &min, int &max, int &step)
{
if_shift_min = min = -1100;
if_shift_max = max = 1100;
if_shift_step = step = 10;
if_shift_mid = 0;
}
// Noise Reduction (TS2000.cxx) NR1 only works; no NR2 and don' no why
void RIG_TS480SAT::set_noise_reduction(int val)
{
if (val == -1) {
return;
}
_noise_reduction_level = val;
if (_noise_reduction_level == 0) {
nr_label("NR", false);
} else if (_noise_reduction_level == 1) {
nr_label("NR1", true);
} else if (_noise_reduction_level == 2) {
nr_label("NR2", true);
}
cmd.assign("NR");
cmd += '0' + _noise_reduction_level;
cmd += ';';
sendCommand (cmd);
showresp(WARN, ASC, "SET noise reduction", cmd, "");
sett("noise reduction");
}
int RIG_TS480SAT::get_noise_reduction()
{
cmd = rsp = "NR";
cmd.append(";");
if (wait_char(';', 4, 100, "GET noise reduction", ASC) == 4) {
size_t p = replystr.rfind(rsp);
if (p == string::npos) return _noise_reduction_level;
_noise_reduction_level = replystr[p+2] - '0';
}
if (_noise_reduction_level == 1) {
nr_label("NR1", true);
} else if (_noise_reduction_level == 2) {
nr_label("NR2", true);
} else {
nr_label("NR", false);
}
gett("noise reduction");
return _noise_reduction_level;
}
void RIG_TS480SAT::set_noise_reduction_val(int val)
{
if (_noise_reduction_level == 0) return;
if (_noise_reduction_level == 1) _nrval1 = val;
else _nrval2 = val;
cmd.assign("RL").append(to_decimal(val, 2)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, "SET_noise_reduction_val", cmd, "");
sett("nr value");
}
int RIG_TS480SAT::get_noise_reduction_val()
{
int nrval = 0;
if (_noise_reduction_level == 0) return 0;
int val = progStatus.noise_reduction_val;
cmd = rsp = "RL";
cmd.append(";");
if (wait_char(';', 5, 100, "GET noise reduction val", ASC) == 5) {
size_t p = replystr.rfind(rsp);
if (p == string::npos) {
nrval = (_noise_reduction_level == 1 ? _nrval1 : _nrval2);
return nrval;
}
val = atoi(&replystr[p+2]);
}
if (_noise_reduction_level == 1) _nrval1 = val;
else _nrval2 = val;
gett("nr value");
return val;
}
int RIG_TS480SAT::get_agc()
{
cmd = "GT;";
wait_char(';', 6, 100, "GET agc val", ASC);
size_t p = replystr.rfind("GT");
gett("agc");
if (p == string::npos) return agcval;
if (replystr[4] == ' ') return 0;
agcval = replystr[4] - '0' + 1; // '0' == off, '1' = fast, '2' = slow
return agcval;
}
int RIG_TS480SAT::incr_agc()
{
if (fm_mode) return 0;
agcval++;
if (agcval == 4) agcval = 1;
cmd.assign("GT00");
cmd += (agcval + '0' - 1);
cmd += ";";
sendCommand(cmd);
showresp(WARN, ASC, "SET agc", cmd, replystr);
sett("increment agc");
return agcval;
}
static const char *agcstrs[] = {"FM", "AGC", "FST", "SLO"};
const char *RIG_TS480SAT::agc_label()
{
if (fm_mode) return agcstrs[0];
return agcstrs[agcval];
}
int RIG_TS480SAT::agc_val()
{
if (fm_mode) return 0;
return agcval;
}
// Auto Notch, beat canceller (TS2000.cxx) BC1 only, not BC2
void RIG_TS480SAT::set_auto_notch(int v)
{
cmd = v ? "BC1;" : "BC0;";
sendCommand(cmd);
showresp(WARN, ASC, "set auto notch", cmd, "");
sett("auto notch");
}
int RIG_TS480SAT::get_auto_notch()
{
cmd = "BC;";
if (wait_char(';', 4, 100, "get auto notch", ASC) == 4) {
int anotch = 0;
size_t p = replystr.rfind("BC");
gett("auto notch");
if (p != string::npos) {
anotch = (replystr[p+2] == '1');
return anotch;
}
}
return 0;
}
// Noise Blanker (TS2000.cxx)
void RIG_TS480SAT::set_noise(bool b)
{
if (b)
cmd = "NB1;";
else
cmd = "NB0;";
sendCommand(cmd);
showresp(WARN, ASC, "set NB", cmd, "");
sett("noise");
}
int RIG_TS480SAT::get_noise()
{
cmd = "NB;";
if (wait_char(';', 4, 100, "get Noise Blanker", ASC) == 4) {
size_t p = replystr.rfind("NB");
gett("noise");
if (p == string::npos) return 0;
if (replystr[p+2] == '0') return 0;
}
return 1;
}
// Tranceiver PTT on/off
void RIG_TS480SAT::set_PTT_control(int val)
{
if (val) {
if (progStatus.data_port) cmd = "TX1;"; // DTS transmission using ANI input
else cmd = "TX0;"; // mic input
} else cmd = "RX;";
sendCommand(cmd);
showresp(WARN, ASC, "set PTT", cmd, "");
sett("ptt");
}
int RIG_TS480SAT::get_PTT()
{
cmd = "IF;";
int ret = wait_char(';', 38, 100, "get VFO", ASC);
gett("ptt");
if (ret < 38) return ptt_;
ptt_ = (replybuff[28] == '1');
return ptt_;
}
void RIG_TS480SAT::set_rf_gain(int val)
{
cmd = "RG";
cmd.append(to_decimal(val,3)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, "set rf gain", cmd, "");
sett("rf gain");
}
int RIG_TS480SAT::get_rf_gain()
{
int val = progStatus.rfgain;
cmd = "RG;";
if (wait_char(';', 6, 100, "get rf gain", ASC) < 6) return val;
size_t p = replystr.rfind("RG");
if (p != string::npos)
val = fm_decimal(replystr.substr(p+2), 3);
gett("rf gain");
return val;
}
void RIG_TS480SAT::get_rf_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 100; step = 1;
}
/*
void RIG_TS480SAT::selectA()
{
cmd = "FR0;FT0;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on A, Tx on A", cmd, "");
}
void RIG_TS480SAT::selectB()
{
cmd = "FR1;FT1;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on B, Tx on B", cmd, "");
}
void RIG_TS480SAT::set_split(bool val)
{
split = val;
if (useB) {
if (val) {
cmd = "FR1;FT0;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on B, Tx on A", cmd, "");
} else {
cmd = "FR1;FT1;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on B, Tx on B", cmd, "");
}
} else {
if (val) {
cmd = "FR0;FT1;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on A, Tx on B", cmd, "");
} else {
cmd = "FR0;FT0;";
sendCommand(cmd);
showresp(WARN, ASC, "Rx on A, Tx on A", cmd, "");
}
}
}
bool RIG_TS480SAT::can_split()
{
return true;
}
int RIG_TS480SAT::get_split()
{
size_t p;
int split = 0;
char rx = 0, tx = 0;
// tx vfo
cmd = rsp = "FT";
cmd.append(";");
if (wait_char(';', 4, 100, "get split tx vfo", ASC) == 4) {
p = replystr.rfind(rsp);
if (p == string::npos) return split;
tx = replystr[p+2];
}
// rx vfo
cmd = rsp = "FR";
cmd.append(";");
if (wait_char(';', 4, 100, "get split rx vfo", ASC) == 4) {
p = replystr.rfind(rsp);
if (p == string::npos) return split;
rx = replystr[p+2];
// split test
split = (tx == '1' ? 2 : 0) + (rx == '1' ? 1 : 0);
}
return split;
}
long RIG_TS480SAT::get_vfoA ()
{
cmd = "FA;";
if (wait_char(';', 14, 100, "get vfo A", ASC) < 14) return A.freq;
size_t p = replystr.rfind("FA");
if (p != string::npos && (p + 12 < replystr.length())) {
int f = 0;
for (size_t n = 2; n < 13; n++)
f = f*10 + replystr[p+n] - '0';
A.freq = f;
}
return A.freq;
}
void RIG_TS480SAT::set_vfoA (long freq)
{
A.freq = freq;
cmd = "FA00000000000;";
for (int i = 12; i > 1; i--) {
cmd[i] += freq % 10;
freq /= 10;
}
sendCommand(cmd);
showresp(WARN, ASC, "set vfo A", cmd, "");
}
long RIG_TS480SAT::get_vfoB ()
{
cmd = "FB;";
if (wait_char(';', 14, 100, "get vfo B", ASC) < 14) return B.freq;
size_t p = replystr.rfind("FB");
if (p != string::npos && (p + 12 < replystr.length())) {
int f = 0;
for (size_t n = 2; n < 13; n++)
f = f*10 + replystr[p+n] - '0';
B.freq = f;
}
return B.freq;
}
void RIG_TS480SAT::set_vfoB (long freq)
{
B.freq = freq;
cmd = "FB00000000000;";
for (int i = 12; i > 1; i--) {
cmd[i] += freq % 10;
freq /= 10;
}
sendCommand(cmd);
showresp(WARN, ASC, "set vfo B", cmd, "");
}
// Squelch (TS990.cxx)
void RIG_TS480SAT::set_squelch(int val)
{
cmd = "SQ0";
cmd.append(to_decimal(abs(val),3)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "set squelch", cmd, "");
}
int RIG_TS480SAT::get_squelch()
{
int val = 0;
cmd = "SQ0;";
if (wait_char(';', 7, 20, "get squelch", ASC) >= 7) {
size_t p = replystr.rfind("SQ0");
if (p == string::npos) return val;
replystr[p + 6] = 0;
val = atoi(&replystr[p + 3]);
}
return val;
}
void RIG_TS480SAT::get_squelch_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 255; step = 1;
}
void RIG_TS480SAT::set_mic_gain(int val)
{
cmd = "MG";
cmd.append(to_decimal(val,3)).append(";");
sendCommand(cmd);
showresp(WARN, ASC, "set mic gain", cmd, "");
}
int RIG_TS480SAT::get_mic_gain()
{
int val = progStatus.mic_gain;
cmd = "MG;";
if (wait_char(';', 6, 100, "get mic gain", ASC) < 6) return val;
size_t p = replystr.rfind("MG");
if (p != string::npos)
val = fm_decimal(replystr.substr(p+2), 3);
return val;
}
void RIG_TS480SAT::get_mic_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 100; step = 1;
}
void RIG_TS480SAT::set_volume_control(int val)
{
cmd = "AG";
char szval[5];
snprintf(szval, sizeof(szval), "%04d", val * 255 / 100);
cmd += szval;
cmd += ';';
LOG_WARN("%s", cmd.c_str());
sendCommand(cmd);
}
int RIG_TS480SAT::get_volume_control()
{
int val = progStatus.volume;
cmd = "AG0;";
if (wait_char(';', 7, 100, "get vol", ASC) < 7) return val;
size_t p = replystr.rfind("AG");
if (p == string::npos) return val;
replystr[p + 6] = 0;
val = atoi(&replystr[p + 3]);
val = val * 100 / 255;
return val;
}
void RIG_TS480SAT::tune_rig()
{
cmd = "AC111;";
LOG_WARN("%s", cmd.c_str());
sendCommand(cmd);
}
*/
flrig-1.3.49/src/rigs/TT588.cxx 0000644 0001750 0001750 00000040401 13472116065 012713 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
// Fernando M. Maresca,
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
/*
* Note for anyone wishing to expand on the command set.
*
* A rejected command is responded to by a three character sequence "Zy\r".
* where the y is the letter of the command in error
* you need to check for that response
*
*/
#include "TT588.h"
#include "support.h"
#include "math.h"
#include "debug.h"
// fer, debugging purpose
#include
#include
static const char TT588name_[] = "Omni-VII";
//static const char *TT588modes_[] = { "D-USB", "USB", "LSB", "CW", "AM", "FM", NULL}
//static const char TT588mode_chr[] = { '1', '1', '2', '3', '0', '4' };
//static const char TT588mode_type[] = { 'U', 'U', 'L', 'L', 'U', 'U' };
static const char *TT588modes_[] = {
"AM", "USB", "LSB", "CWU", "FM", "CWL", "FSK", NULL};
static const char TT588mode_chr[] = { '0', '1', '2', '3', '4', '5', '6' };
static const char TT588mode_type[] = { 'U', 'U', 'L', 'U', 'U', 'L', 'L' };
// filter # is 37 - index
static const char *TT588_widths[] = {
"200", "250", "300", "350", "400", "450", "500", "600", "700", "800",
"900", "1000", "1200", "1400", "1600", "1800", "2000", "2200", "2400", "2500",
"2600", "2800", "3000", "3200", "3400", "3600", "3800", "4000", "4500", "5000",
"5500", "6000", "6500", "7000", "7500", "8000", "9000", "12000", NULL};
static int TT588_bw_vals[] = {
1, 2, 3, 4, 5, 6, 7, 8, 9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,
WVALS_LIMIT};
static const int TT588_numeric_widths[] = {
200, 250, 300, 350, 400, 450, 500, 600, 700, 800,
900, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2500,
2600, 2800, 3000, 3200, 3400, 3600, 3800, 4000, 4500, 5000,
5500, 6000, 6500, 7000, 7500, 8000, 9000, 12000, 0};
static char TT588setFREQA[] = "*Annnn\r";
static char TT588setFREQB[] = "*Bnnnn\r";
//static char TT588setAGC[] = "*Gn\r";
static char TT588setSQLCH[] = "*Hc\r";
static char TT588setRF[] = "*Ic\r";
static char TT588setATT[] = "*Jc\r";
static char TT588setNB[] = "*Knar\r";
static char TT588setMODE[] = "*Mnn\r";
static char TT588setSPLIT[] = "*Nn\r";
static char TT588setPBT[] = "*Pxx\r";
static char TT588setVOL[] = "*Un\r";
static char TT588setBW[] = "*Wx\r";
// these C1* and C2* commands are for ethernet only
//static char TT588setPOWER[] = "*C1Xn\r";
//static char TT588setPREAMP[] = "*C1Zn\r";
//static char TT588getPOWER[] = "?C1X\r";
//static char TT588getPREAMP[] = "?C1Z\r";
// set pout is not available under serial interface
//static char TT588setPOWER[] = "*C1Xn\r";
// F command gets fwd and ref power
//static char TT588getFWDPWR[] = "?F\r";
static char TT588getPOWER[] = "?F\r";
static char TT588getFREQA[] = "?A\r";
static char TT588getFREQB[] = "?B\r";
//static char TT588getAGC[] = "?G\r";
static char TT588getSQLCH[] = "?H\r";
static char TT588getRF[] = "?I\r";
static char TT588getATT[] = "?J\r";
static char TT588getNB[] = "?K\r";
static char TT588getMODE[] = "?M\r";
static char TT588getSPLIT[] = "?N\r";
static char TT588getPBT[] = "?P\r";
static char TT588getSMETER[] = "?S\r";
static char TT588getVOL[] = "?U\r";
static char TT588getBW[] = "?W\r";
//static char TT588getFWDPWR[] = "?F\r";
//static char TT588getREFPWR[] = "?R\r";
static char TT588setXMT[] = "*Tnn\r";
static GUI tt588_widgets[]= {
{ (Fl_Widget *)btnVol, 2, 125, 50 },
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 },
{ (Fl_Widget *)sldrRFGAIN, 54, 145, 156 },
{ (Fl_Widget *)sldrMICGAIN, 266, 125, 156 },
{ (Fl_Widget *)sldrSQUELCH, 266, 145, 156 },
{ (Fl_Widget *)NULL, 0, 0, 0 }
};
RIG_TT588::RIG_TT588() {
// base class values
name_ = TT588name_;
modes_ = TT588modes_;
bandwidths_ = TT588_widths;
bw_vals_ = TT588_bw_vals;
widgets = tt588_widgets;
comm_baudrate = BR57600;
stopbits = 1;
comm_retries = 2;
comm_wait = 20;
comm_timeout = 50;
comm_echo = false;
comm_rtscts = true;
comm_rtsplus = false;
comm_dtrplus = true;
comm_catptt = true;// false;
comm_rtsptt = false;
comm_dtrptt = false;
serloop_timing = 200;
def_mode = modeB = modeA = A.imode = B.iBW = 1;
def_bw = bwB = bwA = A.iBW = B.iBW = 15;
def_freq = freqB = freqA = A.freq = B.freq = 14070000;
max_power = 100;
pbt = 0;
VfoAdj = progStatus.vfo_adj;
vfo_corr = 0;
atten_level = 0;
nb_ = 0;
an_ = 0;
has_preamp_control =
has_bpf_center =
has_power_control = // must be in REMOTE mode
has_micgain_control = // must be in REMOTE mode
has_tune_control =
has_vfo_adj = false;
can_change_alt_vfo =
// has_auto_notch =
// has_notch_control =
has_split =
has_split_AB =
has_smeter =
has_power_out =
has_swr_control =
has_volume_control =
has_rf_control =
has_attenuator_control =
has_ifshift_control =
has_sql_control =
has_ptt_control =
has_bandwidth_control =
has_noise_control =
has_mode_control = true;
precision = 1;
ndigits = 8;
}
void RIG_TT588::initialize()
{
tt588_widgets[0].W = btnVol;
tt588_widgets[1].W = sldrVOLUME;
tt588_widgets[2].W = sldrRFGAIN;
tt588_widgets[3].W = sldrMICGAIN;
tt588_widgets[4].W = sldrSQUELCH;
VfoAdj = progStatus.vfo_adj;
}
void RIG_TT588::shutdown()
{
set_if_shift(0);
}
bool RIG_TT588::check ()
{
cmd = TT588getFREQA;
int ret = waitN(6, 100, "check");
if (ret < 6) return false;
return true;
}
long RIG_TT588::get_vfoA ()
{
cmd = TT588getFREQA;
int ret = waitN(6, 100, "get vfo A");
if (ret >= 6) {
/*
whenever 41 is in the freq. value answered, we don't want to use that index
for an offset. (reproduce: freq. set around 21 MHz, then drag
the wf to change freq. up and down.)
*/
size_t p = replystr.rfind("A");
if (p != string::npos) {
int f = 0;
for (size_t n = 1; n < 5; n++)
f = f*256 + (unsigned char)replystr[n];
freqA = f;
}
}
return (long)(freqA - vfo_corr);
}
void RIG_TT588::set_vfoA (long freq)
{
freqA = freq;
vfo_corr = (freq / 1e6) * VfoAdj + 0.5;
long xfreq = freqA + vfo_corr;
cmd = TT588setFREQA;
cmd[5] = xfreq & 0xff; xfreq = xfreq >> 8;
cmd[4] = xfreq & 0xff; xfreq = xfreq >> 8;
cmd[3] = xfreq & 0xff; xfreq = xfreq >> 8;
cmd[2] = xfreq & 0xff;
sendCommand(cmd);
showresp(WARN, HEX, "set vfo A", cmd, replystr);
return ;
}
long RIG_TT588::get_vfoB()
{
cmd = TT588getFREQB;
int ret = waitN(6, 100, "get vfo B");
if (ret >= 6) {
size_t p = replystr.rfind("B");
if (p != string::npos) {
int f = 0;
for (size_t n = 1; n < 5; n++)
f = f*256 + (unsigned char)replystr[n];
freqB = f;
}
}
return (long)(freqB - vfo_corr);
}
void RIG_TT588::set_vfoB (long freq)
{
freqB = freq;
vfo_corr = (freq / 1e6) * VfoAdj + 0.5;
long xfreq = freqB + vfo_corr;
cmd = TT588setFREQB;
cmd[5] = xfreq & 0xff; xfreq = xfreq >> 8;
cmd[4] = xfreq & 0xff; xfreq = xfreq >> 8;
cmd[3] = xfreq & 0xff; xfreq = xfreq >> 8;
cmd[2] = xfreq & 0xff;
sendCommand(cmd);
showresp(WARN, HEX, "set vfo B", cmd, replystr);
return ;
}
void RIG_TT588::setVfoAdj(double v)
{
VfoAdj = v;
}
void RIG_TT588::set_modeA(int val)
{
modeA = val;
cmd = TT588setMODE;
cmd[2] = TT588mode_chr[modeA];
cmd[3] = TT588mode_chr[modeB];
sendCommand(cmd);
showresp(WARN, HEX, "set mode A", cmd, replystr);
}
void RIG_TT588::set_modeB(int val)
{
modeB = val;
cmd = TT588setMODE;
cmd[2] = TT588mode_chr[modeA];
cmd[3] = TT588mode_chr[modeB];
sendCommand(cmd);
showresp(WARN, HEX, "set mode B", cmd, replystr);
}
int RIG_TT588::get_modeA()
{
cmd = TT588getMODE;
int ret = waitN(4, 100, "get mode A");
if (ret < 4) return modeA;
size_t p = replystr.rfind("M");
if (p == string::npos) return modeA;
modeA = replystr[p + 1] - '0';
return modeA;
}
int RIG_TT588::get_modeB()
{
cmd = TT588getMODE;
int ret = waitN(4, 100, "get mode B");
if (ret < 4) return modeB;
size_t p = replystr.rfind("M");
if (p == string::npos) return modeB;
modeB = replystr[p + 2] - '0';
return modeB;
}
int RIG_TT588::get_modetype(int n)
{
return TT588mode_type[n];
}
void RIG_TT588::set_bwA(int val)
{
bwA = val;
cmd = TT588setBW;
cmd[2] = 37 - val;
sendCommand(cmd);
showresp(WARN, HEX, "set BW A", cmd, replystr);
set_if_shift(pbt);
}
void RIG_TT588::set_bwB(int val)
{
bwB = val;
cmd = TT588setBW;
cmd[2] = 37 - val;
sendCommand(cmd);
showresp(WARN, HEX, "set BW B", cmd, replystr);
set_if_shift(pbt);
}
int RIG_TT588::get_bwA()
{
cmd = TT588getBW;
int ret = waitN(3, 100, "get BW A");
if (ret < 3) return 37 - bwA;
size_t p = replystr.rfind("W");
if (p == string::npos) return 37 - bwA;
bwA = (int)(replystr[p + 1] & 0x7F);
return 37 - bwA;
}
int RIG_TT588::get_bwB()
{
cmd = TT588getBW;
int ret = waitN(3, 100, "get BW B");
if (ret < 3) return 37 - bwB;
size_t p = replystr.rfind("W");
if (p == string::npos) return 37 - bwB;
bwB = (int)(replystr[p + 1] & 0x7F);
return 37 - bwB;
}
int RIG_TT588::adjust_bandwidth(int m)
{
if (m == 0) return 35; // AM
if (m == 1 || m == 2) return 22; // LSB-USB
if (m == 3 || m == 5) return 9;
if (m == 6) return 0;
if (m == 4) return 25;
return 22;
}
int RIG_TT588::def_bandwidth(int m)
{
return adjust_bandwidth(m);
}
void RIG_TT588::set_if_shift(int val)
{
pbt = val;
cmd = TT588setPBT;
short int si = val;
int bpval = progStatus.bpf_center - 200 - TT588_numeric_widths[bwA]/2;
if ((modeA == 1 || modeA == 2) && progStatus.use_bpf_center)
si += (bpval > 0 ? bpval : 0);
cmd[2] = (si & 0xff00) >> 8;
cmd[3] = (si & 0xff);
sendCommand(cmd);
showresp(WARN, HEX, "set pbt", cmd, replystr);
}
bool RIG_TT588::get_if_shift(int &val)
{
cmd = TT588getPBT;
int ret = waitN(4, 100, "get pbt");
val = pbt;
if (ret >= 4) {
size_t p = replystr.rfind("P");
if (p != string::npos) {
val = ((replystr[p + 1] & 0xFF) << 8) | (replystr[p+2] & 0xFF);
if (val > 0x7FFF) val -= 0x10000;
}
}
return (val == 0 ? false : true);
}
void RIG_TT588::get_if_min_max_step(int &min, int &max, int &step)
{
min = -2500;
max = 2500;
step = 10;
}
int RIG_TT588::next_attenuator()
{
switch (atten_level) {
case 0: return 1;
case 1: return 2;
case 2: return 3;
case 3: return 0;
}
return 0;
}
void RIG_TT588::set_attenuator(int val)
{
atten_level = val;
cmd = TT588setATT;
cmd[2] = '0' + atten_level;
switch (atten_level) {
case 0: atten_label("0 dB", false); break;
case 1: atten_label("6 dB", true); break;
case 2: atten_label("12 dB", true); break;
case 3: atten_label("18 dB", true); break;
}
sendCommand(cmd);
showresp(WARN, HEX, "set att", cmd, replystr);
}
int RIG_TT588::get_attenuator()
{
cmd = TT588getATT;
int ret = waitN(3, 100, "get att");
int val = atten_level;
if (ret >= 3) {
size_t p = replystr.rfind("J");
if (p != string::npos) val = (replystr[p + 1] - '0');
}
if (atten_level != val) atten_level = val;
switch (atten_level) {
case 0: atten_label("0 dB", false); break;
case 1: atten_label("6 dB", true); break;
case 2: atten_label("12 dB", true); break;
case 3: atten_label("18 dB", true); break;
}
return atten_level;
}
int RIG_TT588::get_smeter()
{
int sval = 0;
float fval = 0;
cmd = TT588getSMETER;
int ret = waitN(6, 100, "get smeter");
if (ret < 6) return sval;
size_t p = replystr.rfind("S");
if (p == string::npos) return sval;
sscanf(&replystr[p + 1], "%4x", &sval);
fval = sval/256.0;
sval = (int)(fval * 100.0 / 18.0);
if (sval > 100) sval = 100;
return sval;
}
int RIG_TT588::get_volume_control()
{
cmd = TT588getVOL;
int ret = waitN(3, 100, "get vol");
if (ret < 3) return progStatus.volume;
size_t p = replystr.rfind("U");
if (p == string::npos) return progStatus.volume;
return (int)((replystr[p + 1] & 0x7F) / 1.27);
}
void RIG_TT588::set_volume_control(int vol)
{
cmd = TT588setVOL;
cmd[2] = 0x7F & (int)(vol * 1.27);
sendCommand(cmd);
showresp(WARN, HEX, "set vol", cmd, replystr);
}
void RIG_TT588::set_rf_gain(int val)
{
cmd = TT588setRF;
cmd[2] = 0x7F & (int)(val * 1.27);
sendCommand(cmd);
showresp(WARN, HEX, "set rfgain", cmd, replystr);
}
int RIG_TT588::get_rf_gain()
{
cmd = TT588getRF;
int ret = waitN(3, 100, "get rfgain");
if (ret < 3) return 100;
size_t p = replystr.rfind("I");
if (p == string::npos) return 100;
return (int)((replystr[p+1] & 0x7F) / 1.27);
}
// Tranceiver PTT on/off
void RIG_TT588::set_PTT_control(int val)
{
cmd = TT588setXMT;
if (val) {
cmd[2] = 0x04;
cmd[3] = 0;
} else {
cmd[2] = 0;
cmd[3] = 0;
}
sendCommand(cmd);
showresp(WARN, HEX, "set PTT", cmd, replystr);
}
int RIG_TT588::get_power_out()
{
cmd = TT588getPOWER;
int ret = waitN(4, 100, "get pout");
if (ret < 4) return 0;
size_t p = replystr.rfind("F");
if (p == string::npos) return 0;
fwdpwr = replystr[p + 1] & 0x7F;
refpwr = replystr[p + 2] & 0x7F;
// it looks like it never returns reflected power < 1
refpwr -= 1;
fwdv = sqrtf(fwdpwr);
refv = sqrtf(refpwr);
return fwdpwr;
}
int RIG_TT588::get_swr()
{
float swr = (fwdv + refv)/(fwdv - refv) ;
swr -= 1;
swr *= 25.0;
if (swr < 0) swr = 0;
if (swr > 100) swr = 100;
return (int)swr;
}
void RIG_TT588::set_squelch(int val)
{
cmd = TT588setSQLCH;
cmd[2] = (unsigned char)(val * 1.27);
sendCommand(cmd);
showresp(WARN, HEX, "set sql", cmd, replystr);
}
int RIG_TT588::get_squelch()
{
cmd = TT588getSQLCH;
int ret = waitN(3, 100, "get sql");
if (ret < 3) return 0;
size_t p = replystr.rfind("H");
if (p == string::npos) return 0;
return (int)((replystr[p+1] & 0x7F) / 1.27);
}
void RIG_TT588::set_noise(bool val)
{
static char nblabel[] = "NB ";
nb_++;
if (nb_ == 8) nb_ = 0;
nblabel[2] = '0' + nb_;
nb_label(nblabel, nb_ ? true : false);
cmd = TT588setNB;
cmd[2] = (unsigned char)nb_;
cmd[3] = 0;
cmd[4] = (unsigned char)an_;
sendCommand(cmd);
showresp(WARN, HEX, "set NB", cmd, replystr);
}
int RIG_TT588::get_noise()
{
cmd = TT588getNB;
int ret = waitN(5, 100, "get NB");
if (ret < 5) return nb_;
size_t p = replystr.rfind("K");
if (p == string::npos) return nb_;
int val = replystr[p+1];
if (nb_ != val) nb_ = val;
static char nblabel[] = "NB ";
nblabel[2] = '0' + nb_;
nb_label(nblabel, nb_ ? true : false);
return nb_;
}
/*
void RIG_TT588::set_auto_notch(int val)
{
static char anlabel[] = "AN ";
an_++;
if (an_ == 10) an_ = 0;
anlabel[2] = '0' + an_;
auto_notch_label(anlabel, an_ > 0 ? true : false);
cmd = TT588setNB;
cmd[2] = (unsigned char)nb_;
cmd[3] = 0;
cmd[4] = (unsigned char)an_;
sendCommand(cmd);
}
int RIG_TT588::get_auto_notch()
{
cmd = TT588getNB;
int ret = sendCommand(cmd);
showresp(WARN, HEX, "get AN", cmd, replystr);
int val = an_;
if (ret >= 5) {
size_t p = replystr.rfind("K");
if (p != string::npos) val = replystr[p+3];
}
if (an_ != val) an_ = val;
static char anlabel[] = "AN ";
anlabel[2] = '0' + an_;
auto_notch_label(anlabel, an_ ? true : false);
return an_;
}
*/
void RIG_TT588::set_split(bool val)
{
cmd = TT588setSPLIT;
cmd[2] = val == true ? 1 : 0;
sendCommand(cmd);
showresp(WARN, HEX, "set split", cmd, replystr);
}
int RIG_TT588::get_split()
{
cmd = TT588getSPLIT;
int ret = waitN(3, 100, "get split");
if (ret == 3)
return (replystr[1] == 0x01);
return false;
}
/*
int RIG_TT588::get_power_control(void)
{
cmd = TT588getPOWER;
int ret = waitN(7, 100, "get pc");
if (ret == 7) {
int pc = replystr[3] & 0x7F;
return (int)ceil(pc / 1.27);
}
return 0;
}
void RIG_TT588::set_power_control(double val)
{
cmd = TT588setPOWER;
cmd[4] = ((int)(val * 1.27) & 0x7f);
sendCommand(cmd);
showresp(WARN, HEX, "set pc", cmd, replystr);
}
int RIG_TT588::get_preamp()
{
cmd = TT588getPREAMP;
int ret = waitN(5, 100, "get preamp");
if (ret == 5)
return replystr[3];
return 0;
}
void RIG_TT588::set_preamp(int val)
{
cmd = TT588setPREAMP;
cmd[4] = (val == 0 ? 0 : 1);
sendCommand(cmd);
showresp(WARN, HEX, "set preamp", cmd, replystr);
}
*/
flrig-1.3.49/src/rigs/TT563.cxx 0000644 0001750 0001750 00000015363 13472116065 012715 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include "TT563.h"
//=============================================================================
// TT-563
const char RIG_TT563name_[] = "OMNI-VI";
const char *RIG_TT563modes_[] = {
"LSB", "USB", "AM", "CW", "RTTY", "FM", NULL};
static const char RIG_TT563_mode_type[] = {'L', 'U', 'U', 'U', 'L', 'U'};
const char *RIG_TT563widths[] = { "NARR", "WIDE", NULL};
static int TT563_bw_vals[] = {1, 2, WVALS_LIMIT};
RIG_TT563::RIG_TT563() {
name_ = RIG_TT563name_;
modes_ = RIG_TT563modes_;
bandwidths_ = RIG_TT563widths;
bw_vals_ = TT563_bw_vals;
comm_baudrate = BR9600;
stopbits = 1;
comm_retries = 2;
comm_wait = 10;
comm_timeout = 50;
comm_echo = true;
comm_rtscts = false;
comm_rtsplus = true;
comm_dtrplus = true;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
def_freq = A.freq = 14070000;
def_mode = A.imode = 1;
def_bw = A.iBW = 1;
B.freq = 7070000;
B.imode = 1;
B.iBW = 1;
has_mode_control = true;
has_ptt_control = true;
has_a2b = true;
has_getvfoAorB = true;
has_split_AB = true;
defaultCIV = 0x04;
adjustCIV(defaultCIV);
precision = 10;
ndigits = 7;
};
void RIG_TT563::selectA()
{
cmd = pre_to;
cmd += '\x07';
cmd += '\x00';
cmd.append(post);
set_trace(2, "selectA()", str2hex(cmd.c_str(), cmd.length()));
waitFB("select A");
inuse = onA;
}
void RIG_TT563::selectB()
{
cmd = pre_to;
cmd += '\x07';
cmd += '\x01';
cmd.append(post);
set_trace(2, "selectB()", str2hex(cmd.c_str(), cmd.length()));
waitFB("select B");
inuse = onB;
}
void RIG_TT563::swapAB()
{
cmd = pre_to;
cmd += 0x07;
cmd += 0xB0;
cmd.append(post);
set_trace(2, "swapAB()", str2hex(cmd.c_str(), cmd.length()));
waitFB("swapAB()");
}
void RIG_TT563::A2B()
{
cmd = pre_to;
cmd += 0x07;
cmd += 0xA0;
cmd.append(post);
set_trace(2, "A2B()", str2hex(cmd.c_str(), cmd.length()));
waitFB("A2B()");
}
bool RIG_TT563::can_split()
{
return true;
}
void RIG_TT563::set_split(bool val)
{
split = val;
cmd = pre_to;
cmd += 0x0F;
cmd += val ? 0x01 : 0x00;
cmd.append(post);
waitFB(val ? "set_split(ON)" : "set_split(OFF)");
set_trace(2,
(val ? "set_split(ON)" : "set_split(OFF)"),
str2hex(replystr.c_str(), replystr.length()));
}
// 7200 does not respond to get split CAT command
int RIG_TT563::get_split()
{
return split;
}
bool RIG_TT563::check ()
{
string resp = pre_fm;
resp += '\x03';
cmd = pre_to;
cmd += '\x03';
cmd.append( post );
bool ok = waitFOR(11, "check vfo");
get_trace(2, "check()", str2hex(replystr.c_str(), replystr.length()));
return ok;
}
long RIG_TT563::get_vfoA ()
{
if (useB) return A.freq;
string resp = pre_fm;
resp += '\x03';
cmd = pre_to;
cmd += '\x03';
cmd.append( post );
if (waitFOR(11, "get vfo A")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
A.freq = fm_bcd_be(replystr.substr(p+5), 10);
}
get_trace(2, "get_vfoA()", str2hex(replystr.c_str(), replystr.length()));
return A.freq;
}
void RIG_TT563::set_vfoA (long freq)
{
A.freq = freq;
cmd = pre_to;
cmd += '\x05';
cmd.append( to_bcd_be( freq, 10 ) );
cmd.append( post );
set_trace(2, "set_vfoA()", str2hex(cmd.c_str(), cmd.length()));
waitFB("set vfo A");
}
long RIG_TT563::get_vfoB ()
{
if (!useB) return B.freq;
string resp = pre_fm;
resp += '\x03';
cmd = pre_to;
cmd += '\x03';
cmd.append( post );
if (waitFOR(11, "get vfo B")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
B.freq = fm_bcd_be(replystr.substr(p+5), 10);
}
get_trace(2, "get_vfoB()", str2hex(replystr.c_str(), replystr.length()));
return B.freq;
}
void RIG_TT563::set_vfoB (long freq)
{
B.freq = freq;
cmd = pre_to;
cmd += '\x05';
cmd.append( to_bcd_be( freq, 10 ) );
cmd.append( post );
set_trace(2, "set_vfoB()", str2hex(cmd.c_str(), cmd.length()));
waitFB("set vfo B");
}
int RIG_TT563::get_vfoAorB()
{
int ret = useB;
cmd = pre_to;
cmd += '\x17';
cmd.append(post);
string resp = pre_fm;
resp += '\x17';
if (waitFOR(6, "get_PTT()")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
ret = ((replystr[p+4] & 0x02) == 0x02);
}
}
get_trace(2, "get_vfoAorB()", str2hex(replystr.c_str(), replystr.length()));
return ret;
}
void RIG_TT563::set_PTT_control(int val)
{
cmd = pre_to;
cmd += '\x16';
cmd += val ? '\x01' : '\x02';
cmd.append( post );
sendCommand(cmd);
set_trace(2, "set_PTT_control()", str2hex(cmd.c_str(), cmd.length()));
waitFB("set_PTT_control()");
}
int RIG_TT563::get_PTT()
{
int ret = false;
cmd = pre_to;
cmd += '\x17';
cmd.append(post);
string resp = pre_fm;
resp += '\x17';
if (waitFOR(6, "get_PTT()")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
ret = ((replystr[p+4] & 0x04) == 0x04);
}
}
get_trace(2, "get_PTT()", str2hex(replystr.c_str(), replystr.length()));
return ret;
}
void RIG_TT563::set_modeA(int md)
{
A.imode = md;
cmd = pre_to;
cmd += '\x06';
cmd += A.imode;
cmd.append(post);
sendCommand(cmd);
set_trace(2, "set_modeA()", str2hex(cmd.c_str(), cmd.length()));
waitFB("set_modeA()");
}
int RIG_TT563::get_modeA()
{
cmd = pre_to;
cmd += '\x04';
cmd.append(post);
string resp = pre_fm;
resp += '\x04';
if (waitFOR(7, "get modeA")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
A.imode = replystr[p+5];
}
}
get_trace(2, "get_modeA()", str2hex(replystr.c_str(), replystr.length()));
return A.imode;
}
void RIG_TT563::set_modeB(int md)
{
B.imode = md;
cmd = pre_to;
cmd += '\x06';
cmd += B.imode;
cmd.append(post);
sendCommand(cmd);
set_trace(2, "set_modeB()", str2hex(cmd.c_str(), cmd.length()));
waitFB("set_modeB()");
}
int RIG_TT563::get_modeB()
{
cmd = pre_to;
cmd += '\x04';
cmd.append(post);
string resp = pre_fm;
resp += '\x04';
if (waitFOR(7, "get mode")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
B.imode = replystr[p+5];
}
}
get_trace(2, "get_modeB()", str2hex(replystr.c_str(), replystr.length()));
return B.imode;
}
int RIG_TT563::get_modetype(int n)
{
return RIG_TT563_mode_type[n];
}
flrig-1.3.49/src/rigs/IC7300.cxx 0000664 0001750 0001750 00000121763 13501240707 012733 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
// Modified: January 2017
// Andy Stewart, KB1OIQ
// Updated: June 2018
// Cliff Scott, AE5ZA
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include
#include "IC7300.h"
#include "support.h"
#include "trace.h"
//=============================================================================
// IC-7300
#define isett(s) set_trace(2, s, str2hex(replystr.c_str(), replystr.length()));
#define igett(s) get_trace(2, s, str2hex(replystr.c_str(), replystr.length()));
const char IC7300name_[] = "IC-7300";
// these are only defined in this file
// undef'd at end of file
#define NUM_FILTERS 3
#define NUM_MODES 12
static int mode_filterA[NUM_MODES] = {1,1,1,1,1,1,1,1,1,1,1,1};
static int mode_filterB[NUM_MODES] = {1,1,1,1,1,1,1,1,1,1,1,1};
static int mode_bwA[NUM_MODES] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
static int mode_bwB[NUM_MODES] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
static const char *szfilter[NUM_FILTERS] = {"1", "2", "3"};
enum {
m73LSB, m73USB, m73AM, m73FM, m73CW, m73CWR, m73RTTY, m73RTTYR,
m73LSBD, m73USBD, m73AMD, m73FMD
};
const char *IC7300modes_[] = {
"LSB", "USB", "AM", "FM", "CW", "CW-R", "RTTY", "RTTY-R",
"LSB-D", "USB-D", "AM-D", "FM-D", NULL};
const char IC7300_mode_type[] = {
'L', 'U', 'U', 'U', 'L', 'U', 'L', 'U',
'L', 'U', 'U', 'U' };
const char IC7300_mode_nbr[] = {
0x00, 0x01, 0x02, 0x05, 0x03, 0x07, 0x04, 0x08,
0x00, 0x01, 0x02, 0x05 };
const char *IC7300_ssb_bws[] = {
"50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
"600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500",
"1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500",
"2600", "2700", "2800", "2900", "3000", "3100", "3200", "3300", "3400", "3500",
"3600", NULL };
static int IC7300_bw_vals_SSB[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36,37,38,39,
40, WVALS_LIMIT};
const char *IC7300_rtty_bws[] = {
"50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
"600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500",
"1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500",
"2600", "2700", NULL };
static int IC7300_bw_vals_RTTY[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31, WVALS_LIMIT};
const char *IC7300_am_bws[] = {
"200", "400", "600", "800", "1000", "1200", "1400", "1600", "1800", "2000",
"2200", "2400", "2600", "2800", "3000", "3200", "3400", "3600", "3800", "4000",
"4200", "4400", "4600", "4800", "5000", "5200", "5400", "5600", "5800", "6000",
"6200", "6400", "6600", "6800", "7000", "7300", "7400", "7300", "7800", "8000",
"8200", "8400", "8600", "8800", "9000", "9200", "9400", "9600", "9800", "10000", NULL };
static int IC7300_bw_vals_AM[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36,37,38,39,
40,41,42,43,44,45,46,47,48,49
WVALS_LIMIT};
const char *IC7300_fm_bws[] = { "FIXED", NULL };
static int IC7300_bw_vals_FM[] = { 1, WVALS_LIMIT};
static GUI IC7300_widgets[]= {
{ (Fl_Widget *)btnVol, 2, 125, 50 }, //0
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 }, //1
{ (Fl_Widget *)btnAGC, 2, 145, 50 }, //2
{ (Fl_Widget *)sldrRFGAIN, 54, 145, 156 }, //3
{ (Fl_Widget *)sldrSQUELCH, 54, 165, 156 }, //4
{ (Fl_Widget *)btnNR, 2, 185, 50 }, //5
{ (Fl_Widget *)sldrNR, 54, 185, 156 }, //6
{ (Fl_Widget *)btnLOCK, 214, 105, 50 }, //7
{ (Fl_Widget *)sldrINNER, 266, 105, 156 }, //8
{ (Fl_Widget *)btnCLRPBT, 214, 125, 50 }, //9
{ (Fl_Widget *)sldrOUTER, 266, 125, 156 }, //10
{ (Fl_Widget *)btnNotch, 214, 145, 50 }, //11
{ (Fl_Widget *)sldrNOTCH, 266, 145, 156 }, //12
{ (Fl_Widget *)sldrMICGAIN, 266, 165, 156 }, //13
{ (Fl_Widget *)sldrPOWER, 266, 185, 156 }, //14
{ (Fl_Widget *)NULL, 0, 0, 0 }
};
void RIG_IC7300::initialize()
{
IC7300_widgets[0].W = btnVol;
IC7300_widgets[1].W = sldrVOLUME;
IC7300_widgets[2].W = btnAGC;
IC7300_widgets[3].W = sldrRFGAIN;
IC7300_widgets[4].W = sldrSQUELCH;
IC7300_widgets[5].W = btnNR;
IC7300_widgets[6].W = sldrNR;
IC7300_widgets[7].W = btnLOCK;
IC7300_widgets[8].W = sldrINNER;
IC7300_widgets[9].W = btnCLRPBT;
IC7300_widgets[10].W = sldrOUTER;
IC7300_widgets[11].W = btnNotch;
IC7300_widgets[12].W = sldrNOTCH;
IC7300_widgets[13].W = sldrMICGAIN;
IC7300_widgets[14].W = sldrPOWER;
btn_icom_select_11->deactivate();
btn_icom_select_12->deactivate();
btn_icom_select_13->deactivate();
choice_rTONE->activate();
choice_tTONE->activate();
}
RIG_IC7300::RIG_IC7300() {
defaultCIV = 0x94;
adjustCIV(defaultCIV);
name_ = IC7300name_;
modes_ = IC7300modes_;
bandwidths_ = IC7300_ssb_bws;
bw_vals_ = IC7300_bw_vals_SSB;
_mode_type = IC7300_mode_type;
comm_baudrate = BR19200;
stopbits = 1;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_echo = true;
comm_rtscts = false;
comm_rtsplus = true;
comm_dtrplus = true;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
widgets = IC7300_widgets;
def_freq = A.freq = 14070000;
def_mode = A.imode = 9;
def_bw = A.iBW = 34;
B.freq = 7070000;
B.imode = 9;
B.iBW = 34;
has_extras = true;
has_cw_wpm = true;
has_cw_spot_tone = true;
has_cw_qsk = true;
has_cw_break_in = true;
has_vox_onoff = true;
has_vox_gain = true;
has_vox_anti = true;
has_vox_hang = true;
has_compON = true;
has_compression = true;
has_split = true;
has_split_AB = true;
has_micgain_control = true;
has_bandwidth_control = true;
has_smeter = true;
has_power_out = true;
has_swr_control = true;
has_alc_control = true;
has_sql_control = true;
has_agc_control = true;
has_power_control = true;
has_volume_control = true;
has_mode_control = true;
has_attenuator_control = true;
has_preamp_control = true;
has_noise_control = true;
has_nb_level = true;
has_noise_reduction = true;
has_noise_reduction_control = true;
has_auto_notch = true;
has_notch_control = true;
has_pbt_controls = true;
has_FILTER = true;
has_rf_control = true;
has_ptt_control = true;
has_tune_control = true;
has_band_selection = true;
precision = 1;
ndigits = 8;
has_vfo_adj = true;
can_change_alt_vfo = true;
has_a2b = true;
};
static inline void minmax(int min, int max, int &val)
{
if (val > max) val = max;
if (val < min) val = min;
}
void RIG_IC7300::selectA()
{
cmd.assign(pre_to).append("\x07");
cmd += '\x00';
cmd.append(post);
waitFB("select A");
isett("selectA");
}
void RIG_IC7300::selectB()
{
cmd.assign(pre_to).append("\x07");
cmd += '\x01';
cmd.append(post);
waitFB("select B");
isett("selectB");
}
//======================================================================
// IC7300 unique commands
//======================================================================
void RIG_IC7300::swapAB()
{
cmd = pre_to;
cmd += 0x07; cmd += 0xB0;
cmd.append(post);
waitFB("Exchange vfos");
get_modeA(); // get mode to update the filter A / B usage
get_modeB();
}
bool RIG_IC7300::check ()
{
string resp = pre_fm;
resp += '\x03';
cmd = pre_to;
cmd += '\x03';
cmd.append( post );
bool ok = waitFOR(11, "check vfo");
isett("check vfo");
return ok;
}
long RIG_IC7300::get_vfoA ()
{
string resp;
cmd.assign(pre_to).append("\x25");
resp.assign(pre_fm).append("\x25");
if (useB) {
cmd += '\x01';
resp += '\x01';
} else {
cmd += '\x00';
resp += '\x00';
}
cmd.append(post);
if (waitFOR(12, "get vfo A")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
A.freq = fm_bcd_be(replystr.substr(p+6), 10);
}
igett("get_vfoA");
return A.freq;
}
void RIG_IC7300::set_vfoA (long freq)
{
A.freq = freq;
cmd.assign(pre_to).append("\x25");
if (useB) cmd += '\x01';
else cmd += '\x00';
cmd.append( to_bcd_be( freq, 10) );
cmd.append( post );
waitFB("set vfo A");
isett("set_vfoA");
}
long RIG_IC7300::get_vfoB ()
{
string resp;
cmd.assign(pre_to).append("\x25");
resp.assign(pre_fm).append("\x25");
if (useB) {
cmd += '\x00';
resp += '\x00';
} else {
cmd += '\x01';
resp += '\x01';
}
cmd.append(post);
if (waitFOR(12, "get vfo B")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
B.freq = fm_bcd_be(replystr.substr(p+6), 10);
}
igett("get_vfoB");
return B.freq;
}
void RIG_IC7300::set_vfoB (long freq)
{
B.freq = freq;
cmd.assign(pre_to).append("\x25");
if (useB) cmd += '\x00';
else cmd += '\x01';
cmd.append( to_bcd_be( freq, 10 ) );
cmd.append( post );
waitFB("set vfo B");
isett("set_vfoB");
}
// expecting
// 0 1 2 3 4 5 6 7 8 9
// FE FE E0 94 26 NN NN NN NN FD
// | | | |
// | | | |__filter setting, 01, 02, 03
// | | |_____data mode, 00 - off, 01 - on
// | |________Mode 00 - LSB
// | 01 - USB
// | 02 - AM
// | 03 - CW
// | 04 - RTTY
// | 05 - FM
// | 07 - CW-R
// | 08 - RTTY-R
// |___________selected vfo, 00 - active, 01 - inactive
int RIG_IC7300::get_modeA()
{
int md = 0;
size_t p;
string resp;
cmd.assign(pre_to).append("\x26");
resp.assign(pre_fm).append("\x26");
if (useB)
cmd += '\x01';
else
cmd += '\x00';
cmd.append(post);
if (waitFOR(10, "get mode A")) {
p = replystr.rfind(resp);
if (p == string::npos)
goto end_wait_modeA;
for (md = 0; md < m73LSBD; md++) {
if (replystr[p+6] == IC7300_mode_nbr[md]) {
A.imode = md;
if (replystr[p+7] == 0x01 && A.imode < 4)
A.imode += 8;
if (A.imode > 11)
A.imode = 1;
break;
}
}
A.filter = replystr[p+8];
if (A.filter > 0 && A.filter < 4)
mode_filterA[A.imode] = A.filter;
}
get_trace(4, "get mode A[", IC7300modes_[A.imode], "] ", str2hex(replystr.c_str(), replystr.length()));
end_wait_modeA:
return A.imode;
}
// LSB USB AM CW RTTY FM CW-R RTTY-R LSB-D USB-D
// 0 1 2 3 4 5 6 7 8 9
void RIG_IC7300::set_modeA(int val)
{
A.imode = val;
cmd.assign(pre_to);
cmd += '\x26';
if (useB)
cmd += '\x01'; // unselected vfo
else
cmd += '\x00'; // selected vfo
cmd += IC7300_mode_nbr[A.imode]; // operating mode
if (A.imode >= m73LSBD)
cmd += '\x01'; // data mode
else
cmd += '\x00';
cmd += mode_filterA[A.imode]; // filter
cmd.append( post );
waitFB("set mode A");
set_trace(4, "set mode A[", IC7300modes_[A.imode], "] ", str2hex(replystr.c_str(), replystr.length()));
}
int RIG_IC7300::get_modeB()
{
int md = 0;
size_t p;
string resp;
cmd.assign(pre_to).append("\x26");
resp.assign(pre_fm).append("\x26");
if (useB)
cmd += '\x00'; // active vfo
else
cmd += '\x01'; // inactive vfo
cmd.append(post);
if (waitFOR(10, "get mode B")) {
p = replystr.rfind(resp);
if (p == string::npos)
goto end_wait_modeB;
for (md = 0; md < m73LSBD; md++) {
if (replystr[p+6] == IC7300_mode_nbr[md]) {
B.imode = md;
if (replystr[p+7] == 0x01 && B.imode < 4)
B.imode += 8;
if (B.imode > 11)
B.imode = 1;
break;
}
}
B.filter = replystr[p+8];
}
get_trace(4, "get mode B[", IC7300modes_[B.imode], "] ", str2hex(replystr.c_str(), replystr.length()));
if (B.filter > 0 && B.filter < 4)
mode_filterB[B.imode] = B.filter;
end_wait_modeB:
return B.imode;
}
void RIG_IC7300::set_modeB(int val)
{
B.imode = val;
cmd.assign(pre_to);
cmd += '\x26';
if (useB)
cmd += '\x00'; // selected vfo
else
cmd += '\x01'; // unselected vfo
cmd += IC7300_mode_nbr[B.imode]; // operating mode
if (B.imode >= m73LSBD)
cmd += '\x01'; // data mode
else
cmd += '\x00';
cmd += mode_filterB[B.imode]; // filter
cmd.append( post );
waitFB("set mode B");
set_trace(4, "set mode B[", IC7300modes_[B.imode], "] ", str2hex(replystr.c_str(), replystr.length()));
}
int RIG_IC7300::get_FILT(int mode)
{
if (useB) return mode_filterB[mode];
return mode_filterA[mode];
}
void RIG_IC7300::set_FILT(int filter)
{
if (filter < 1 || filter > 3)
return;
if (useB) {
B.filter = filter;
mode_filterB[B.imode] = filter;
cmd.assign(pre_to);
cmd += '\x26';
cmd += '\x00'; // selected vfo
cmd += IC7300_mode_nbr[B.imode]; // operating mode
if (B.imode >= m73LSBD) cmd += '\x01'; // data mode
else cmd += '\x00';
cmd += filter; // filter
cmd.append( post );
waitFB("set mode/filter B");
set_trace(4, "set mode/filter B[", IC7300modes_[B.imode], "] ", str2hex(replystr.c_str(), replystr.length()));
} else {
A.filter = filter;
mode_filterA[A.imode] = filter;
cmd.assign(pre_to);
cmd += '\x26';
cmd += '\x00'; // selected vfo
cmd += IC7300_mode_nbr[A.imode]; // operating mode
if (A.imode >= m73LSBD) cmd += '\x01'; // data mode
else cmd += '\x00';
cmd += filter; // filter
cmd.append( post );
waitFB("set mode/filter A");
set_trace(4, "set mode/filter A[", IC7300modes_[A.imode], "] ", str2hex(replystr.c_str(), replystr.length()));
}
}
const char *RIG_IC7300::FILT(int val)
{
if (val < 1) val = 1;
if (val > 3) val = 3;
return(szfilter[val - 1]);
}
const char * RIG_IC7300::nextFILT()
{
int val = A.filter;
if (useB) val = B.filter;
val++;
if (val > 3) val = 1;
set_FILT(val);
return szfilter[val - 1];
}
void RIG_IC7300::set_FILTERS(std::string s)
{
stringstream strm;
strm << s;
for (int i = 0; i < NUM_MODES; i++)
strm >> mode_filterA[i];
for (int i = 0; i < NUM_MODES; i++)
strm >> mode_filterB[i];
for (int i = 0; i < NUM_MODES; i++) {
if (mode_filterA[i] < 1) mode_filterA[i] = 1;
if (mode_filterA[i] > 3) mode_filterA[i] = 3;
if (mode_filterB[i] < 1) mode_filterB[i] = 1;
if (mode_filterB[i] > 3) mode_filterB[i] = 3;
}
}
std::string RIG_IC7300::get_FILTERS()
{
stringstream s;
for (int i = 0; i < NUM_MODES; i++) {
if (mode_filterA[i] < 1) mode_filterA[i] = 1;
if (mode_filterA[i] > 3) mode_filterA[i] = 3;
if (mode_filterB[i] < 1) mode_filterB[i] = 1;
if (mode_filterB[i] > 3) mode_filterB[i] = 3;
}
for (int i = 0; i < NUM_MODES; i++)
s << mode_filterA[i] << " ";
for (int i = 0; i < NUM_MODES; i++)
s << mode_filterB[i] << " ";
return s.str();
}
std::string RIG_IC7300::get_BANDWIDTHS()
{
stringstream s;
for (int i = 0; i < NUM_MODES; i++)
s << mode_bwA[i] << " ";
for (int i = 0; i < NUM_MODES; i++)
s << mode_bwB[i] << " ";
return s.str();
}
void RIG_IC7300::set_BANDWIDTHS(std::string s)
{
stringstream strm;
strm << s;
for (int i = 0; i < NUM_MODES; i++)
strm >> mode_bwA[i];
for (int i = 0; i < NUM_MODES; i++)
strm >> mode_bwB[i];
}
bool RIG_IC7300::can_split()
{
return true;
}
void RIG_IC7300::set_split(bool val)
{
split = val;
cmd = pre_to;
cmd += 0x0F;
cmd += val ? 0x01 : 0x00;
cmd.append(post);
waitFB(val ? "set split ON" : "set split OFF");
isett("set_split");
}
int RIG_IC7300::get_split()
{
int read_split = 0;
cmd.assign(pre_to);
cmd.append("\x0F");
cmd.append( post );
if (waitFOR(7, "get split")) {
string resp = pre_fm;
resp.append("\x0F");
size_t p = replystr.find(resp);
if (p != string::npos)
read_split = replystr[p+5];
if (read_split != 0xFA) // fail byte
split = read_split;
}
igett("get_split");
return split;
}
int RIG_IC7300::get_bwA()
{
if (A.imode == 3 || A.imode == 11) return 0; // FM, FM-D
if (useB) selectA();
cmd = pre_to;
cmd.append("\x1a\x03");
cmd.append(post);
int bwval = A.iBW;
if (waitFOR(8, "get_bwA")) {
string resp = pre_fm;
resp.append("\x1A\x03");
size_t p = replystr.find(resp);
if (p != string::npos)
bwval = fm_bcd(replystr.substr(p+6), 2);
}
if (bwval != A.iBW) {
A.iBW = bwval;
mode_bwA[A.imode] = bwval;
}
if (useB) selectB();
igett("get_bwA");
return A.iBW;
}
void RIG_IC7300::set_bwA(int val)
{
if (A.imode == 3 || A.imode == 11) return; // FM, FM-D
A.iBW = val;
if (useB) selectA();
cmd = pre_to;
cmd.append("\x1a\x03");
cmd.append(to_bcd(A.iBW, 2));
cmd.append(post);
waitFB("set bwA");
mode_bwA[A.imode] = val;
isett("set_bwA");
if (useB) selectB();
}
int RIG_IC7300::get_bwB()
{
if (B.imode == 3 || B.imode == 11) return 0; // FM, FM-D
if (!useB) selectB();
cmd = pre_to;
cmd.append("\x1a\x03");
cmd.append(post);
int bwval = B.iBW;
if (waitFOR(8, "get_bwB")) {
string resp = pre_fm;
resp.append("\x1A\x03");
size_t p = replystr.find(resp);
if (p != string::npos)
bwval = fm_bcd(replystr.substr(p+6), 2);
}
if (bwval != B.iBW) {
B.iBW = bwval;
mode_bwB[B.imode] = bwval;
}
if (!useB) selectA();
igett("get_bwB");
return B.iBW;
}
void RIG_IC7300::set_bwB(int val)
{
if (B.imode == 3 || B.imode == 11) return; // FM, FM-D
B.iBW = val;
if (!useB) selectB();
cmd = pre_to;
cmd.append("\x1a\x03");
cmd.append(to_bcd(B.iBW, 2));
cmd.append(post);
waitFB("set bwB");
mode_bwB[B.imode] = val;
isett("set_bwB");
if (!useB) selectA();
}
// LSB USB AM FM CW CW-R RTTY RTTY-R LSB-D USB-D AM-D FM-D
// 0 1 2 3 4 5 6 7 8 9 10 11
int RIG_IC7300::adjust_bandwidth(int m)
{
int bw = 0;
switch (m) {
case 2: case 10: // AM, AM-D
bandwidths_ = IC7300_am_bws;
bw_vals_ = IC7300_bw_vals_AM;
bw = 19;
break;
case 3: case 11: // FM, FM-D
bandwidths_ = IC7300_fm_bws;
bw_vals_ = IC7300_bw_vals_FM;
bw = 0;
break;
case 6: case 7: // RTTY, RTTY-R
bandwidths_ = IC7300_rtty_bws;
bw_vals_ = IC7300_bw_vals_RTTY;
bw = 12;
break;
case 4: case 5: // CW, CW -R
bandwidths_ = IC7300_ssb_bws;
bw_vals_ = IC7300_bw_vals_SSB;
bw = 12;
break;
case 0: case 1: // LSB, USB
case 8: case 9: // LSB-D, USB-D
default:
bandwidths_ = IC7300_ssb_bws;
bw_vals_ = IC7300_bw_vals_SSB;
bw = 34;
}
return bw;
}
const char ** RIG_IC7300::bwtable(int m)
{
const char **table;
switch (m) {
case 2: case 10: // AM, AM-D
table = IC7300_am_bws;
break;
case 3: case 11: // FM, FM-D
table = IC7300_fm_bws;
break;
case 6: case 7: // RTTY, RTTY-R
table = IC7300_rtty_bws;
break;
case 4: case 5: // CW, CW -R
case 0: case 1: // LSB, USB
case 8: case 9: // LSB-D, USB-D
default:
table = IC7300_ssb_bws;
}
return table;
}
int RIG_IC7300::def_bandwidth(int m)
{
int bw = adjust_bandwidth(m);
if (useB) {
if (mode_bwB[m] == -1)
mode_bwB[m] = bw;
return mode_bwB[m];
}
if (mode_bwA[m] == -1)
mode_bwA[m] = bw;
return mode_bwA[m];
}
int RIG_IC7300::get_mic_gain()
{
int val = 0;
string cstr = "\x14\x0B";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get mic")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = num100(replystr.substr(p + 6));
}
return val;
}
void RIG_IC7300::set_mic_gain(int val)
{
cmd = pre_to;
cmd.append("\x14\x0B");
cmd.append(bcd255(val));
cmd.append( post );
waitFB("set mic gain");
}
void RIG_IC7300::get_mic_gain_min_max_step(int &min, int &max, int &step)
{
min = 0;
max = 100;
step = 1;
}
static int comp_level[] = {11,34,58,81,104,128,151,174,197,221,244};
void RIG_IC7300::set_compression(int on, int val)
{
cmd = pre_to;
cmd.append("\x16\x44");
if (on) cmd += '\x01';
else cmd += '\x00';
cmd.append(post);
waitFB("set Comp ON/OFF");
if (val < 0) return;
if (val > 10) return;
cmd.assign(pre_to).append("\x14\x0E");
cmd.append(to_bcd(comp_level[val], 3));
cmd.append( post );
waitFB("set comp");
}
void RIG_IC7300::get_compression(int &on, int &val)
{
std::string resp;
cmd.assign(pre_to).append("\x16\x44").append(post);
resp.assign(pre_fm).append("\x16\x44");
if (waitFOR(8, "get comp on/off")) {
size_t p = replystr.find(resp);
if (p != string::npos)
on = (replystr[p+6] == 0x01);
}
cmd.assign(pre_to).append("\x14\x0E").append(post);
resp.assign(pre_fm).append("\x14\x0E");
if (waitFOR(9, "get comp level")) {
size_t p = replystr.find(resp);
int level = 0;
if (p != string::npos) {
level = fm_bcd(replystr.substr(p+6), 3);
for (val = 0; val < 11; val++)
if (level <= comp_level[val]) break;
}
}
}
void RIG_IC7300::set_vox_onoff()
{
if (progStatus.vox_onoff) {
cmd.assign(pre_to).append("\x16\x46\x01");
cmd.append( post );
waitFB("set vox ON");
} else {
cmd.assign(pre_to).append("\x16\x46");
cmd += '\x00';
cmd.append( post );
waitFB("set vox OFF");
}
}
// Xcvr values range 0...255 step 1
void RIG_IC7300::get_vox_gain_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 100; step = 1;
}
void RIG_IC7300::set_vox_gain()
{
int vox_gain = round((progStatus.vox_gain * 255 / 100 + 0.5));
minmax(0, 255, vox_gain);
cmd.assign(pre_to).append("\x14\x16");
cmd.append(to_bcd(vox_gain, 3));
cmd.append( post );
waitFB("SET vox gain");
}
// Xcvr values range 0...255 step 1
void RIG_IC7300::get_vox_anti_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 100; step = 1;
}
void RIG_IC7300::set_vox_anti()
{
int vox_anti = round((progStatus.vox_anti * 255 / 100 + 0.5));
minmax(0, 255, vox_anti);
cmd.assign(pre_to).append("\x14\x17");
cmd.append(to_bcd(vox_anti, 3));
cmd.append( post );
waitFB("SET anti-vox");
}
// VOX hang 0.0 - 2.0, step 0.1
// Xcvr values 0..20 step 1
void RIG_IC7300::get_vox_hang_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 20; step = 1;
}
void RIG_IC7300::set_vox_hang()
{
cmd.assign(pre_to).append("\x1A\x05\x01\x91");
cmd.append(to_bcd(progStatus.vox_hang, 2));
cmd.append( post );
waitFB("SET vox hang");
}
//----------------------------------------------------------------------
// CW controls
void RIG_IC7300::get_cw_wpm_min_max(int &min, int &max)
{
min = 6; max = 48;
}
void RIG_IC7300::set_cw_wpm()
{
int iwpm = round((progStatus.cw_wpm - 6) * 255 / 42 + 0.5);
minmax(0, 255, iwpm);
cmd.assign(pre_to).append("\x14\x0C");
cmd.append(to_bcd(iwpm, 3));
cmd.append( post );
waitFB("SET cw wpm");
}
void RIG_IC7300::enable_break_in()
{
// 16 47 00 break-in off
// 16 47 01 break-in semi
// 16 47 02 break-in full
cmd.assign(pre_to).append("\x16\x47");
switch (progStatus.break_in) {
case 2: cmd += '\x02'; break_in_label("FULL"); break;
case 1: cmd += '\x01'; break_in_label("SEMI"); break;
case 0:
default: cmd += '\x00'; break_in_label("BK-IN");
}
cmd.append(post);
waitFB("SET break-in");
}
void RIG_IC7300::get_cw_qsk_min_max_step(double &min, double &max, double &step)
{
min = 2.0; max = 13.0; step = 0.1;
}
void RIG_IC7300::set_cw_qsk()
{
int qsk = round ((progStatus.cw_qsk - 2.0) * 255.0 / 11.0 + 0.5);
minmax(0, 255, qsk);
cmd.assign(pre_to).append("\x14\x0F");
cmd.append(to_bcd(qsk, 3));
cmd.append(post);
waitFB("Set cw qsk delay");
}
void RIG_IC7300::get_cw_spot_tone_min_max_step(int &min, int &max, int &step)
{
min = 300; max = 900; step = 5;
}
void RIG_IC7300::set_cw_spot_tone()
{
cmd.assign(pre_to).append("\x14\x09"); // values 0=300Hz 255=900Hz
int n = round((progStatus.cw_spot_tone - 300) * 255.0 / 600.0 + 0.5);
minmax(0, 255, n);
cmd.append(to_bcd(n, 3));
cmd.append( post );
waitFB("SET cw spot tone");
}
void RIG_IC7300::set_cw_vol()
{
cmd.assign(pre_to);
cmd.append("\x1A\x05");
cmd += '\x00';
cmd += '\x24';
cmd.append(to_bcd((int)(progStatus.cw_vol * 2.55), 3));
cmd.append( post );
waitFB("SET cw sidetone volume");
}
// Tranceiver PTT on/off
void RIG_IC7300::set_PTT_control(int val)
{
cmd = pre_to;
cmd += '\x1c';
cmd += '\x00';
cmd += (unsigned char) val;
cmd.append( post );
waitFB("set ptt");
ptt_ = val;
}
int RIG_IC7300::get_PTT()
{
cmd = pre_to;
cmd += '\x1c'; cmd += '\x00';
string resp = pre_fm;
resp += '\x1c'; resp += '\x00';
cmd.append(post);
if (waitFOR(8, "get PTT")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
ptt_ = replystr[p + 6];
}
return ptt_;
}
// Volume control val 0 ... 100
void RIG_IC7300::set_volume_control(int val)
{
cmd = pre_to;
cmd.append("\x14\x01");
cmd.append(bcd255(val));
cmd.append( post );
waitFB("set vol");
}
/*
I:12:20:22: get vol ans in 0 ms, OK
cmd FE FE 7A E0 14 01 FD
ans FE FE 7A E0 14 01 FD
FE FE E0 7A 14 01 00 65 FD
0 1 2 3 4 5 6 7 8
*/
int RIG_IC7300::get_volume_control()
{
int val = 0;
string cstr = "\x14\x01";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get vol")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = num100(replystr.substr(p + 6));
}
return (val);
}
void RIG_IC7300::get_vol_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 100; step = 1;
}
void RIG_IC7300::set_power_control(double val)
{
cmd = pre_to;
cmd.append("\x14\x0A");
cmd.append(bcd255(val));
cmd.append( post );
waitFB("set power");
}
int RIG_IC7300::get_power_control()
{
int val = progStatus.power_level;
string cstr = "\x14\x0A";
string resp = pre_fm;
cmd = pre_to;
cmd.append(cstr).append(post);
resp.append(cstr);
if (waitFOR(9, "get power")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = num100(replystr.substr(p+6));
}
return val;
}
void RIG_IC7300::get_pc_min_max_step(double &min, double &max, double &step)
{
min = 2; max = 100; step = 1;
}
int RIG_IC7300::get_smeter()
{
string cstr = "\x15\x02";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
int mtr= -1;
if (waitFOR(9, "get smeter")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
mtr = fm_bcd(replystr.substr(p+6), 3);
mtr = (int)ceil(mtr /2.41);
if (mtr > 100) mtr = 100;
}
}
return mtr;
}
struct pwrpair {int mtr; float pwr;};
static pwrpair pwrtbl[] = {
{0, 0.0},
{21, 5.0},
{43,10.0},
{65, 15.0},
{83, 20.0},
{95, 25.0},
{105, 30.0},
{114, 35.0},
{124, 40.0},
{143, 50.0},
{183, 75.0},
{213, 100.0},
{255, 120.0 } };
int RIG_IC7300::get_power_out(void)
{
string cstr = "\x15\x11";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
int mtr= 0;
if (waitFOR(9, "get power out")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
mtr = fm_bcd(replystr.substr(p+6), 3);
size_t i = 0;
for (i = 0; i < sizeof(pwrtbl) / sizeof(pwrpair) - 1; i++)
if (mtr >= pwrtbl[i].mtr && mtr < pwrtbl[i+1].mtr)
break;
if (mtr < 0) mtr = 0;
if (mtr > 255) mtr = 255;
mtr = (int)ceil(pwrtbl[i].pwr +
(pwrtbl[i+1].pwr - pwrtbl[i].pwr)*(mtr - pwrtbl[i].mtr)/(pwrtbl[i+1].mtr - pwrtbl[i].mtr));
if (mtr > 100) mtr = 100;
}
}
return mtr;
}
struct swrpair {int mtr; float swr;};
// Table entries below correspond to SWR readings of 1.1, 1.5, 2.0, 2.5, 3.0 and infinity.
// Values are also tweaked to fit the display of the SWR meter.
static swrpair swrtbl[] = {
{0, 0.0},
{48, 10.5},
{80, 23.0},
{103, 35.0},
{120, 48.0},
{255, 100.0 } };
int RIG_IC7300::get_swr(void)
{
string cstr = "\x15\x12";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
int mtr= -1;
if (waitFOR(9, "get swr")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
mtr = fm_bcd(replystr.substr(p+6), 3);
size_t i = 0;
for (i = 0; i < sizeof(swrtbl) / sizeof(swrpair) - 1; i++)
if (mtr >= swrtbl[i].mtr && mtr < swrtbl[i+1].mtr)
break;
if (mtr < 0) mtr = 0;
if (mtr > 255) mtr = 255;
mtr = (int)ceil(swrtbl[i].swr +
(swrtbl[i+1].swr - swrtbl[i].swr)*(mtr - swrtbl[i].mtr)/(swrtbl[i+1].mtr - swrtbl[i].mtr));
if (mtr > 100) mtr = 100;
}
}
return mtr;
}
int RIG_IC7300::get_alc(void)
{
string cstr = "\x15\x13";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
int mtr= -1;
if (waitFOR(9, "get alc")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
mtr = fm_bcd(replystr.substr(p+6), 3);
mtr = (int)ceil(mtr /1.2);
if (mtr > 100) mtr = 100;
}
}
return mtr;
}
void RIG_IC7300::set_rf_gain(int val)
{
cmd = pre_to;
cmd.append("\x14\x02");
cmd.append(bcd255(val));
cmd.append( post );
waitFB("set RF");
}
int RIG_IC7300::get_rf_gain()
{
int val = progStatus.rfgain;
string cstr = "\x14\x02";
string resp = pre_fm;
cmd = pre_to;
cmd.append(cstr).append(post);
resp.append(cstr);
if (waitFOR(9, "get RF")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = num100(replystr.substr(p + 6));
}
return val;
}
void RIG_IC7300::get_rf_min_max_step(double &min, double &max, double &step)
{
min = 0; max = 100; step = 1;
}
int RIG_IC7300::next_preamp()
{
if (atten_level == 1)
return preamp_level;
switch (preamp_level) {
case 0: return 1;
case 1: return 2;
case 2: return 0;
}
return 0;
}
void RIG_IC7300::set_preamp(int val)
{
if (val) {
atten_level = 0;
atten_label("ATT", false);
}
cmd = pre_to;
cmd += '\x16';
cmd += '\x02';
preamp_level = val;
switch (val) {
case 1:
preamp_label("Amp 1", true);
break;
case 2:
preamp_label("Amp 2", true);
break;
case 0:
default:
preamp_label("PRE", false);
}
cmd += (unsigned char)preamp_level;
cmd.append( post );
waitFB( (preamp_level == 0) ? "set Preamp OFF" :
(preamp_level == 1) ? "set Preamp Level 1" :
"set Preamp Level 2");
}
int RIG_IC7300::get_preamp()
{
string cstr = "\x16\x02";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(8, "get Preamp Level")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
preamp_level = replystr[p+6];
if (preamp_level == 1) {
preamp_label("Amp 1", true);
} else if (preamp_level == 2) {
preamp_label("Amp 2", true);
} else {
preamp_label("PRE", false);
preamp_level = 0;
}
}
}
return preamp_level;
}
void RIG_IC7300::set_attenuator(int val)
{
if (val) {
atten_label("20 dB", true);
atten_level = 1;
preamp_label("PRE", false);
} else {
atten_level = 0;
atten_label("ATT", false);
}
cmd = pre_to;
cmd += '\x11';
cmd += atten_level ? '\x20' : '\x00';
cmd.append( post );
waitFB("set att");
}
int RIG_IC7300::next_attenuator()
{
if (atten_level) return 0;
return 1;
}
int RIG_IC7300::get_attenuator()
{
cmd = pre_to;
cmd += '\x11';
cmd.append( post );
string resp = pre_fm;
resp += '\x11';
if (waitFOR(7, "get ATT")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
if (replystr[p+5] == 0x20) {
atten_label("20 dB", true);
atten_level = 1;
return 1;
} else {
atten_label("ATT", false);
atten_level = 0;
return 0;
}
}
}
return 0;
}
void RIG_IC7300::set_noise(bool val)
{
cmd = pre_to;
cmd.append("\x16\x22");
cmd += val ? 1 : 0;
cmd.append(post);
waitFB("set noise");
}
int RIG_IC7300::get_noise()
{
int val = progStatus.noise;
string cstr = "\x16\x22";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get noise")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = replystr[p+6];
}
}
return val;
}
void RIG_IC7300::set_nb_level(int val)
{
cmd = pre_to;
cmd.append("\x14\x12");
cmd.append(bcd255(val));
cmd.append( post );
waitFB("set NB level");
}
int RIG_IC7300::get_nb_level()
{
int val = progStatus.nb_level;
string cstr = "\x14\x12";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get NB level")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = num100(replystr.substr(p+6));
}
return val;
}
void RIG_IC7300::set_noise_reduction(int val)
{
cmd = pre_to;
cmd.append("\x16\x40");
cmd += val ? 1 : 0;
cmd.append(post);
waitFB("set NR");
}
int RIG_IC7300::get_noise_reduction()
{
string cstr = "\x16\x40";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(8, "get NR")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
return (replystr[p+6] ? 1 : 0);
}
return progStatus.noise_reduction;
}
/*
I:12:06:50: get NR ans in 0 ms, OK
cmd FE FE 7A E0 16 40 FD
ans FE FE 7A E0 16 40 FD
FE FE E0 7A 16 40 01 FD
0 1 2 3 4 5 6 7
I:12:06:50: get NRval ans in 0 ms, OK
cmd FE FE 7A E0 14 06 FD
ans FE FE 7A E0 14 06 FD
FE FE E0 7A 14 06 00 24 FD
0 1 2 3 4 5 6 7 8
*/
void RIG_IC7300::set_noise_reduction_val(int val)
{
cmd = pre_to;
cmd.append("\x14\x06");
val *= 16;
val += 8;
cmd.append(to_bcd(val, 3));
cmd.append(post);
waitFB("set NRval");
}
int RIG_IC7300::get_noise_reduction_val()
{
int val = progStatus.noise_reduction_val;
string cstr = "\x14\x06";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get NRval")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = fm_bcd(replystr.substr(p+6),3);
val -= 8;
val /= 16;
}
}
return val;
}
void RIG_IC7300::set_squelch(int val)
{
cmd = pre_to;
cmd.append("\x14\x03");
cmd.append(bcd255(val));
cmd.append( post );
waitFB("set Sqlch");
}
int RIG_IC7300::get_squelch()
{
int val = progStatus.squelch;
string cstr = "\x14\x03";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append(post);
if (waitFOR(9, "get squelch")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
val = num100(replystr.substr(p+6));
}
return val;
}
void RIG_IC7300::set_auto_notch(int val)
{
cmd = pre_to;
cmd += '\x16';
cmd += '\x41';
cmd += (unsigned char)val;
cmd.append( post );
waitFB("set AN");
}
int RIG_IC7300::get_auto_notch()
{
string cstr = "\x16\x41";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(8, "get AN")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
if (replystr[p+6] == 0x01) {
auto_notch_label("AN", true);
return true;
} else {
auto_notch_label("AN", false);
return false;
}
}
}
return progStatus.auto_notch;
}
static bool IC7300_notchon = false;
void RIG_IC7300::set_notch(bool on, int val)
{
int notch = val / 20 + 53;
minmax(0, 255, notch);
if (on != IC7300_notchon) {
cmd = pre_to;
cmd.append("\x16\x48");
cmd += on ? '\x01' : '\x00';
cmd.append(post);
waitFB("set notch");
IC7300_notchon = on;
}
cmd = pre_to;
cmd.append("\x14\x0D");
cmd.append(to_bcd(notch,3));
cmd.append(post);
waitFB("set notch val");
}
bool RIG_IC7300::get_notch(int &val)
{
bool on = false;
string cstr = "\x16\x48";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(8, "get notch")) {
size_t p = replystr.rfind(resp);
if (p != string::npos)
on = replystr[p + 6] ? 1 : 0;
cmd = pre_to;
resp = pre_fm;
cstr = "\x14\x0D";
cmd.append(cstr);
resp.append(cstr);
cmd.append(post);
if (waitFOR(9, "get notch val")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = fm_bcd(replystr.substr(p+6),3);
val = (val - 53) * 20;
if (val < 0) val = 0;
if (val > 4040) val = 4040;
}
}
}
return (IC7300_notchon = on);
}
void RIG_IC7300::get_notch_min_max_step(int &min, int &max, int &step)
{
min = 0;
max = 4040;
step = 20;
}
static int agcval = 3;
int RIG_IC7300::get_agc()
{
cmd = pre_to;
cmd.append("\x16\x12");
cmd.append(post);
if (waitFOR(8, "get AGC")) {
size_t p = replystr.find(pre_fm);
if (p != string::npos)
agcval = replystr[p+6]; // 1 == off, 2 = FAST, 3 = MED, 4 = SLOW
}
return agcval;
}
int RIG_IC7300::incr_agc()
{
agcval++;
if (agcval == 4) agcval = 1;
cmd = pre_to;
cmd.append("\x16\x12");
cmd += agcval;
cmd.append(post);
waitFB("set AGC");
return agcval;
}
static const char *agcstrs[] = {"AGC", "FST", "MED", "SLO"};
const char *RIG_IC7300::agc_label()
{
return agcstrs[agcval];
}
int RIG_IC7300::agc_val()
{
return (agcval);
}
void RIG_IC7300::set_if_shift(int val)
{
int shift;
sh_ = val;
if (val == 0) sh_on_ = false;
else sh_on_ = true;
shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x07");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set IF on/off");
cmd = pre_to;
cmd.append("\x14\x08");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
waitFB("set IF val");
}
bool RIG_IC7300::get_if_shift(int &val) {
val = sh_;
return sh_on_;
}
void RIG_IC7300::get_if_min_max_step(int &min, int &max, int &step)
{
min = -50;
max = +50;
step = 1;
}
void RIG_IC7300::set_pbt_inner(int val)
{
int shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x07");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
set_trace(4, "set_pbt_inner(", val, ") ", str2hex(cmd.c_str(), cmd.length()));
waitFB("set PBT inner");
}
void RIG_IC7300::set_pbt_outer(int val)
{
int shift = 128 + val * 128 / 50;
if (shift < 0) shift = 0;
if (shift > 255) shift = 255;
cmd = pre_to;
cmd.append("\x14\x08");
cmd.append(to_bcd(shift, 3));
cmd.append(post);
set_trace(4, "set_pbt_outer(", val, ") ", str2hex(cmd.c_str(), cmd.length()));
waitFB("set PBT outer");
}
int RIG_IC7300::get_pbt_inner()
{
int val = 0;
string cstr = "\x14\x07";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get pbt inner")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = num100(replystr.substr(p+6));
val -= 50;
}
}
igett("get_pbt_inner");
return val;
}
int RIG_IC7300::get_pbt_outer()
{
int val = 0;
string cstr = "\x14\x08";
string resp = pre_fm;
resp.append(cstr);
cmd = pre_to;
cmd.append(cstr);
cmd.append( post );
if (waitFOR(9, "get pbt inner")) {
size_t p = replystr.rfind(resp);
if (p != string::npos) {
val = num100(replystr.substr(p+6));
val -= 50;
}
}
igett("get_pbt_outer");
return val;
}
void RIG_IC7300::setVfoAdj(double v)
{
vfo_ = v;
cmd.assign(pre_to);
cmd.append("\x1A\x05");
cmd += '\x00';
cmd += '\x58';
cmd.append(bcd255(int(v)));
cmd.append(post);
waitFB("SET vfo adjust");
}
double RIG_IC7300::getVfoAdj()
{
cmd.assign(pre_to);
cmd.append("\x1A\x05");
cmd += '\x00';
cmd += '\x58';
cmd.append(post);
if (waitFOR(11, "get vfo adj")) {
size_t p = replystr.find(pre_fm);
if (p != string::npos) {
vfo_ = num100(replystr.substr(p+8));
}
}
return vfo_;
}
// Read/Write band stack registers
//
// Read 23 bytes
//
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// FE FE nn E0 1A 01 bd rn f5 f4 f3 f2 f1 mo fi fg t1 t2 t3 r1 r2 r3 FD
// Write 23 bytes
//
// FE FE E0 nn 1A 01 bd rn f5 f4 f3 f2 f1 mo fi fg t1 t2 t3 r1 r2 r3 FD
//
// nn - CI-V address
// bd - band selection 1/2/3
// rn - register number 1/2/3
// f5..f1 - frequency BCD reverse
// mo - mode
// fi - filter #
// fg flags: x01 use Tx tone, x02 use Rx tone, x10 data mode
// t1..t3 - tx tone BCD fwd
// r1..r3 - rx tone BCD fwd
//
// FE FE E0 94 1A 01 06 01 70 99 08 18 00 01 03 10 00 08 85 00 08 85 FD
//
// band 6; freq 0018,089,970; USB; data mode; t 88.5; r 88.5
void RIG_IC7300::get_band_selection(int v)
{
cmd.assign(pre_to);
cmd.append("\x1A\x01");
cmd += to_bcd_be( v, 2 );
cmd += '\x01';
cmd.append( post );
if (waitFOR(23, "get band stack")) {
igett("get band stack");
size_t p = replystr.rfind(pre_fm);
if (p != string::npos) {
long int bandfreq = fm_bcd_be(replystr.substr(p+8, 5), 10);
int bandmode = replystr[p+13];
int bandfilter = replystr[p+14];
int banddata = replystr[p+15] & 0x10;
if ((bandmode < 4) && banddata) bandmode += 8;
int tone = fm_bcd(replystr.substr(p+16, 3), 6);
size_t index = 0;
for (index = 0; index < sizeof(PL_tones) / sizeof(*PL_tones); index++)
if (tone == PL_tones[index]) break;
tTONE = index;
tone = fm_bcd(replystr.substr(p+19, 3), 6);
for (index = 0; index < sizeof(PL_tones) / sizeof(*PL_tones); index++)
if (tone == PL_tones[index]) break;
rTONE = index;
if (useB) {
set_vfoB(bandfreq);
set_modeB(bandmode);
set_FILT(bandfilter);
} else {
set_vfoA(bandfreq);
set_modeA(bandmode);
set_FILT(bandfilter);
}
}
} else
igett("get band stack");
}
void RIG_IC7300::set_band_selection(int v)
{
long freq = (useB ? B.freq : A.freq);
int fil = (useB ? B.filter : A.filter);
int mode = (useB ? B.imode : A.imode);
cmd.assign(pre_to);
cmd.append("\x1A\x01");
cmd += to_bcd_be( v, 2 );
cmd += '\x01';
cmd.append( to_bcd_be( freq, 10 ) );
cmd += IC7300_mode_nbr[mode];
cmd += fil;
if (mode >= 7)
cmd += '\x10';
else
cmd += '\x00';
cmd.append(to_bcd(PL_tones[tTONE], 6));
cmd.append(to_bcd(PL_tones[rTONE], 6));
cmd.append(post);
waitFB("set_band_selection");
isett("set_band_selection");
cmd.assign(pre_to);
cmd.append("\x1A\x01");
cmd += to_bcd_be( v, 2 );
cmd += '\x01';
cmd.append( post );
waitFOR(23, "get band stack");
}
flrig-1.3.49/src/rigs/FT900.cxx 0000644 0001750 0001750 00000020345 13472116065 012666 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// 2015-10-04 adapted from FT890.cxx by Ernst F. Schroeder DJ7HS
// the FT-900 has two vfos and can work split
// but it cannot change the (hidden) alternate vfo
// 2015-12-03 1st stable version DJ7HS
// 2016-04-03 call get_info() within get_vfoA and get_vfoB DJ7HS
// 2017-06-16 changes in support.cxx made adaptations necessary DJ7HS
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include "FT900.h"
#include "status.h"
const char FT900name_[] = "FT-900";
const char *FT900modes_[] = {
"LSB", "USB", "CW", "CW-N", "AM", "AM-N", "FM", NULL};
static const int FT900_mode_val[] = { 0, 1, 2, 3, 4, 5, 6 };
static const char FT900_mode_type[] = { 'L', 'U', 'U', 'U', 'U', 'U', 'U' };
static const char *FT900widths_[] =
{ "wide", "narr", NULL};
static const int FT900_bw_val[] =
{ 0, 1 };
RIG_FT900::RIG_FT900() {
name_ = FT900name_;
modes_ = FT900modes_;
bandwidths_ = FT900widths_;
comm_baudrate = BR4800;
stopbits = 2;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_rtscts = false;
comm_rtsplus = false;
comm_dtrplus = false;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
afreq = bfreq = A.freq = B.freq = 14070000;
amode = bmode = A.imode = B.imode = 1;
aBW = bBW = A.iBW = B.iBW = 0;
precision = 10;
has_smeter =
has_power_out =
has_ptt_control =
has_split =
has_split_AB =
has_getvfoAorB =
has_get_info =
has_mode_control = true;
precision = 10;
ndigits = 7;
}
void RIG_FT900::initialize()
{
progStatus.poll_split = 1; // allow pollimg for split info
progStatus.poll_vfoAorB = 1; // allow pollimg for vfo info
}
void RIG_FT900::init_cmd()
{
cmd = "00000";
for (size_t i = 0; i < 5; i++) cmd[i] = 0;
}
void RIG_FT900::selectA()
{
init_cmd();
cmd[4] = 0x05;
sendCommand(cmd);
showresp(WARN, HEX, "select vfo A", cmd, replystr);
}
void RIG_FT900::selectB()
{
init_cmd();
cmd[3] = 0x01;
cmd[4] = 0x05;
sendCommand(cmd);
showresp(WARN, HEX, "select vfo B", cmd, replystr);
}
void RIG_FT900::set_split(bool val)
{
init_cmd();
cmd[3] = val ? 0x01 : 0x00;
cmd[4] = 0x01;
sendCommand(cmd);
if (val)
showresp(WARN, HEX, "set split ON", cmd, replystr);
else
showresp(WARN, HEX, "set split OFF", cmd, replystr);
}
int RIG_FT900::get_split()
{
return splitison;
}
int RIG_FT900::get_vfoAorB()
{
// get flags for vfoAorB and split
init_cmd();
cmd[4] = 0xFA;
int ret = waitN(5, 100, "get flags info", HEX);
// after this command the FT-900 replies with 3 bytes of flags and 2 bytes of dummy data
if (ret >= 5) {
size_t p = ret - 5;
int sp = replybuff[p];
splitison = (sp & 0x04) ? 1 : 0; // 1 if split is set
vfoAorB = (sp & 0x40) ? 1 : 0; // 0 if vfoA, 1 if vfoB is in use
return vfoAorB;
}
return -1; // -1 signals error
}
//void RIG_FT900::swapAB() // works with a simple trick
//{
// init_cmd();
// cmd[4] = 0x85; // copy active vfo to background vfo
// sendCommand(cmd);
// showresp(WARN, HEX, "copy active vfo to background vfo", cmd, replystr);
// if (!useB) {
// queA.push(vfoB);
// B = vfoA;
// } else {
// queB.push(vfoA);
// A = vfoB;
// }
//}
bool RIG_FT900::check()
{
init_cmd();
cmd[3] = 0x03;
cmd[4] = 0x10;
int ret = waitN(18, 100, "check", HEX);
if (ret >= 18) return true;
return false;
}
bool RIG_FT900::get_info()
{
// get the vfo, mode and bandwidth information
init_cmd();
cmd[3] = 0x03;
cmd[4] = 0x10;
// after this command the FT-900 replies with 2 x 9 bytes of data
// bytes 1..3 contain binary data for vfoA with 10 Hz resolution
// bytes 10..12 contain binary data for vfoB with 10 Hz resolution
// bytes 6 and 15 contain the mode and bytes 8 and 17 contain the bandwidth
int ret = waitN(18, 100, "get info", HEX);
if (ret >= 18) {
size_t p = ret - 18;
afreq = 0;
bfreq = 0;
for (size_t n = 1; n < 4; n++) {
afreq = afreq * 256 + (unsigned char)replybuff[p + n];
bfreq = bfreq * 256 + (unsigned char)replybuff[p + 9 + n];
}
afreq = afreq * 10.0;
bfreq = bfreq * 10.0;
aBW = 0; // normal BW
// mode data for vfoA is in byte 6
// bandwidth data is in byte 8
int md = replybuff[p + 6];
int bw = replybuff[p + 8];
switch (md) {
case 0 : // LSB
amode = 0;
break;
case 1 : // USB
amode = 1;
break;
case 2 : // CW
amode = (bw & 0x80) ? 3 : 2;
aBW = (bw & 0x80) ? 1 : 0;
break;
case 3 : // AM
amode = (bw & 0x40) ? 5 : 4;
aBW = (bw & 0x40) ? 1 : 0;
break;
case 4 : // FM
amode = 6;
break;
default :
amode = 1;
}
bBW = 0;
// mode data for vfoB is in byte 15
// bandwidth data is in byte 17
md = replybuff[p + 15];
bw = replybuff[p + 17];
switch (md) {
case 0 : // LSB
bmode = 0;
break;
case 1 : // USB
bmode = 1;
break;
case 2 : // CW
bmode = (bw & 0x80) ? 3 : 2;
bBW = (bw & 0x80) ? 1 : 0;
break;
case 3 : // AM
bmode = (bw & 0x40) ? 5 : 4;
bBW = (bw & 0x40) ? 1 : 0;
break;
case 4 : // FM
bmode = 6;
break;
default :
bmode = 1;
}
A.freq = afreq;
A.imode = amode;
A.iBW = aBW;
B.freq = bfreq;
B.imode = bmode;
B.iBW = bBW;
return true;
}
return false;
}
long RIG_FT900::get_vfoA ()
{
return A.freq;
}
void RIG_FT900::set_vfoA (long freq)
{
A.freq = freq;
freq /=10; // FT-900 does not support 1 Hz resolution
cmd = to_bcd_be(freq, 8);
cmd += 0x0A;
sendCommand(cmd);
showresp(WARN, HEX, "set vfo A", cmd, replystr);
}
int RIG_FT900::get_modeA()
{
return A.imode;
}
void RIG_FT900::set_modeA(int val)
{
A.imode = val;
init_cmd();
cmd[3] = FT900_mode_val[val];
cmd[4] = 0x0C;
sendCommand(cmd);
showresp(WARN, HEX, "set mode A", cmd, replystr);
}
long RIG_FT900::get_vfoB()
{
return B.freq;
}
void RIG_FT900::set_vfoB(long freq)
{
B.freq = freq;
freq /=10; // FT-900 does not support 1 Hz resolution
cmd = to_bcd_be(freq, 8);
cmd += 0x0A;
sendCommand(cmd);
showresp(WARN, HEX, "set vfo B", cmd, replystr);
}
void RIG_FT900::set_modeB(int val)
{
B.imode = val;
init_cmd();
cmd[3] = FT900_mode_val[val];
cmd[4] = 0x0C;
sendCommand(cmd);
showresp(WARN, HEX, "set mode B", cmd, replystr);
}
int RIG_FT900::get_modeB()
{
return B.imode;
}
// Transceiver PTT on/off
void RIG_FT900::set_PTT_control(int val)
{
// make sure no other vfo except either vfoA or vfoB is used for transmit
if (val) {
if (!useB) {
selectA();
} else {
selectB();
}
}
// make sure that in case of split the transmit mode is shown correctly
if (splitison) {
if (val) {
if (!useB) {
vfo = &vfoB;
} else {
vfo = &vfoA;
}
} else {
if (!useB) {
vfo = &vfoA;
} else {
vfo = &vfoB;
}
}
Fl::awake(setModeControl);
}
init_cmd();
if (val) cmd[3] = 1;
else cmd[3] = 0;
cmd[4] = 0x0F;
sendCommand(cmd, 0);
LOG_INFO("%s", str2hex(cmd.c_str(), 5));
ptt_ = val;
}
int RIG_FT900::get_smeter()
{
init_cmd();
cmd[4] = 0xF7;
int ret = waitN(5, 100, "get smeter", HEX);
if (ret < 5) return 0;
int sval = (unsigned char)(replybuff[ret - 2]);
sval = sval * 100 / 255;
return sval;
}
int RIG_FT900::get_power_out()
{
init_cmd();
cmd[4] = 0xF7;
int ret = waitN(5, 100, "get pwr out", HEX);
if (ret < 5) return 0;
int sval = (unsigned char)(replybuff[ret - 2]);
sval = sval * 100 / 255;
return sval;
}
flrig-1.3.49/src/rigs/TS990.cxx 0000664 0001750 0001750 00000240451 13556605525 012727 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
/*
* Copyright (c) 2014 Andy Burnett, G0HIX
*/
#include "config.h"
#include "TS990.h"
#include "support.h"
#include "debug.h"
#include
#include
void ts990debug(string s)
{
ofstream dbgfile;
if (s.empty())
dbgfile.open(string(RigHomeDir).append("ts990_debug.txt").c_str());
else
dbgfile.open(string(RigHomeDir).append("ts990_debug.txt").c_str(), ios::app);
dbgfile << s << std::endl;
dbgfile.close();
}
#define TS990_WAIT 50
static const char TS990name_[] = "TS-990";
static const char *TS990modes_[] = {
"LSB", "USB", "CW", "FM", "AM",
"FSK", "PSK", "CW-R", "FSK-R", "PSK-R",
"LSB-D1", "USB-D1", "FM-D1", "AM-D1",
"LSB-D2", "USB-D2", "FM-D2", "AM-D2",
"LSB-D3", "USB-D3", "FM-D3", "AM-D3", NULL};
static const char TS990_mode_chr[] = {
'1', '2', '3', '4', '5',
'6', 'A', '7', '9', 'B',
'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N' };
static const char TS990_mode_type[] = {
'L', 'U', 'U', 'U', 'U',
'U', 'U', 'L', 'U', 'U',
'L', 'U', 'U', 'U',
'L', 'U', 'U', 'U',
'L', 'U', 'U', 'U' };
//==============================================================================
static const char *TS990_empty[] = { "N/A", NULL };
//==============================================================================
// SSB - Width / Shift filters
//
// BW indicates 0x8000 & (shift << 8) & width
// Maximum assignable BW value 0x910C
// Default BW value 0x9005
//==============================================================================
static const char *TS990_filt_width[] = {
"50", "80", "100", "150", "200",
"250", "300", "400", "500", "600",
"1000", "1500", "2000", "2200", "2400",
"2600", "2800", "3000", NULL };
static int TS990_WIDTH_bw_vals[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,WVALS_LIMIT};
static const char *TS990_CAT_filt_width[] = {
"00;", "01;", "02;", "03;", "04;",
"05;", "06;", "07;", "08;", "09;",
"10;", "11;", "12;", "13;", "14;",
"15;", "16;", "17;", NULL };
static const char *TS990_filt_width_tooltip = "width";
static const char *TS990_filt_width_label = "W";
static const char *TS990_filt_shift[] = {
"1000", "1100", "1200", "1300", "1400",
"1500", "1600", "1700", "1800", "1900",
"2000", "2100", "2210", NULL };
static const char *TS990_CAT_filt_shift[] = {
"00;", "01;", "02;", "03;", "04;",
"05;", "06;", "07;", "08;", "09;",
"10;", "11;", "12;", NULL };
static const char *TS990_filt_shift_tooltip = "shift";
static const char *TS990_filt_shift_label = "S";
#define DEFAULT_SH_WI 0x8510 // SHIFT 1500, WIDTH 2800
#define DEFAULT_SH_WI_D1 0x850B // SHIFT 1500, WIDTH 3000
#define DEFAULT_SH_WI_D2 0x850A // SHIFT 1500, WIDTH 1000
#define DEFAULT_SH_WI_D3 0x8508 // SHIFT 1500, WIDTH 500
//==============================================================================
// SSB, FM, Other SL/SH cut filters
//
// BW indicates 0x8000 & (SH << 8) & SL
//==============================================================================
static const char *TS990_filt_SH[] = {
"1000", "1200", "1400", "1600", "1800",
"2000", "2200", "2400", "2600", "2800",
"3000", "3400", "4000", "5000", NULL };
static int TS990_HI_bw_vals[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,WVALS_LIMIT};
static const char *TS990_CAT_filt_SH[] = {
"00;", "01;", "02;", "03;", "04;",
"05;", "06;", "07;", "08;", "09;",
"10;", "11;", "12;", "13;", NULL };
static const char *TS990_filt_SH_tooltip = "hi cut";
static const char *TS990_filt_SH_label = "H";
static const char *TS990_filt_SL[] = {
"0", "50", "100", "200", "300",
"400", "500", "600", "700", "800",
"900", "1000", NULL };
static const char *TS990_CAT_filt_SL[] = {
"00;", "01;", "02;", "03;", "04;",
"05;", "06;", "07;", "08;", "09;",
"10;", "11;", NULL };
static const char *TS990_filt_SL_tooltip = "lo cut";
static const char *TS990_filt_SL_label = "L";
#define DEFAULT_HI_LO 0x8A03 // LO 200, HI 3000
#define DEFAULT_FM 0x8C05 // LO 400, HI 4000
#define DEFAULT_FM_D1 0x8903 // LO 200, HI 2800
#define DEFAULT_FM_D2 0x8707 // LO 600, HI 2400
#define DEFAULT_FM_D3 0x850B // LO 1000, HI 2000
//==============================================================================
// CW filters
//
// BW indicates 0x8000 & (width << 8) & shift
// Maximum assignable BW value 0x8D20
// Default BW value 0x8810 --> no shift, bandwidth = 500 Hz
//==============================================================================
static const char *TS990_CW_width[] = {
"50", "80", "100", "150", "200",
"250", "300", "400", "500", "600",
"1000", "1500", "2000", "2500", NULL };
static int TS990_CW_bw_vals[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,WVALS_LIMIT};
static const char *TS990_CAT_CW_width[] = {
"00;", "01;", "02;", "03;", "04;",
"05;", "06;", "07;", "08;", "09;",
"10;", "11;", "12;", "13;", NULL };
static const char *TS990_CW_W_tooltip = "width";
static const char *TS990_CW_W_btn_label = "W";
static const char *TS990_CW_shift[] = {
"-800", "-750", "-700", "-650", "-600",
"-550", "-500", "-450", "-400", "-350",
"-300", "-250", "-200", "-150", "-100",
"-50", "0", "50", "100", "150",
"200", "250", "300", "350", "400",
"450", "500", "550", "600", "650",
"700", "750", "800", NULL };
static const char *TS990_CAT_CW_shift[] = {
"00;", "01;", "02;", "03;", "04;",
"05;", "06;", "07;", "08;", "09;",
"10;", "11;", "12;", "13;", "14;",
"15;", "16;", "17;", "18;", "19;",
"20;", "21;", "22;", "23;", "24;",
"25;", "26;", "27;", "28;", "29;",
"30;", "31;", "32;", NULL };
static const char *TS990_CW_S_tooltip = "shift";
static const char *TS990_CW_S_btn_label = "S";
#define DEFAULT_CW 0x9008 // SHIFT 0, WIDTH 500
//==============================================================================
static const char *TS990_AM_SL[] = {
"0", "100", "200", "300", NULL };
static const char *TS990_CAT_AM_SL[] = {
"00;", "01;", "02;", "03;", NULL};
static const char *TS990_AM_SL_tooltip = "lo cut";
static const char *TS990_AM_btn_SL_label = "L";
static const char *TS990_AM_SH[] = {
"2500", "3000", "4000", "5000", NULL };
static int TS990_AM_HI_bw_vals[] = { 1,2,3,4,WVALS_LIMIT};
static const char *TS990_CAT_AM_SH[] = {
"00;", "01;", "02;", "03;", NULL};
static const char *TS990_AM_SH_tooltip = "hi cut";
static const char *TS990_AM_btn_SH_label = "H";
#define DEFAULT_AM 0x8102 // LO 100, HI 4000
#define DEFAULT_AM_D1 0x8202 // LO 200, HI 4000
#define DEFAULT_AM_D2 0x8201 // LO 200, HI 3000
#define DEFAULT_AM_D3 0x8200 // LO 200, HI 2500
//==============================================================================
static const char *TS990_FSK_filt[] = {
"250", "300", "400", "500", "1000", "1500", NULL};
static int TS990_FSK_bw_vals[] = {1,2,3,4,5,6,WVALS_LIMIT};
static const char *TS990_CAT_FSK_filt[] = {
"00;", "01;", "02;", "03;", "04;", "05;", NULL };
#define DEFAULT_FSK 0x03 // WIDTH 300
//==============================================================================
static const char *TS990_PSK_filt[] = {
"50", "80", "100", "150", "200",
"250", "300", "400", "500", "600",
"1000", "1500", NULL};
static int TS990_PSK_bw_vals[] = {1,2,3,4,5,6,7,8,9,10,11,12,WVALS_LIMIT};
static const char *TS990_CAT_PSK_filt[] = {
"00;", "01;", "02;", "03;", "04;",
"05;", "06;", "07;", "08;", "09;",
"10;", "11;", NULL };
#define DEFAULT_PSK 0x06 // WIDTH 300
//==============================================================================
static GUI rig_widgets[]= {
{ (Fl_Widget *)btnVol, 2, 125, 50 },
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 },
{ (Fl_Widget *)sldrRFGAIN, 54, 145, 156 },
{ (Fl_Widget *)btnIFsh, 214, 105, 50 },
{ (Fl_Widget *)sldrIFSHIFT, 266, 105, 156 },
{ (Fl_Widget *)btnNotch, 214, 125, 50 },
{ (Fl_Widget *)sldrNOTCH, 266, 125, 156 },
{ (Fl_Widget *)sldrMICGAIN, 266, 145, 156 },
{ (Fl_Widget *)sldrPOWER, 266, 165, 156 },
{ (Fl_Widget *)btnNR, 2, 165, 50 },
{ (Fl_Widget *)sldrNR, 54, 165, 156 },
{ (Fl_Widget *)NULL, 0, 0, 0 }
};
static string menu_0001;
void RIG_TS990::initialize()
{
ts990debug("");
ts990debug("initialize()");
rig_widgets[0].W = btnVol;
rig_widgets[1].W = sldrVOLUME;
rig_widgets[2].W = sldrRFGAIN;
rig_widgets[3].W = btnIFsh;
rig_widgets[4].W = sldrIFSHIFT;
rig_widgets[5].W = btnNotch;
rig_widgets[6].W = sldrNOTCH;
rig_widgets[7].W = sldrMICGAIN;
rig_widgets[8].W = sldrPOWER;
rig_widgets[9].W = btnNR;
rig_widgets[10].W = sldrNR;
cmd = "AC000;";
sendCommand(cmd);
cmd = "EX00100;";
if (wait_char(';', 11, 100, "read ex 00100", ASC) == 11)
menu_0001 = replystr;
cmd = "EX00100 00"; // turn off beeps
sendCommand(cmd);
read_menu_0607();
read_menu_0608();
set_menu_0607(false); // SSB uses lower/upper cutoff frequencies
set_menu_0608(true); // SSB data uses shift/width frequencies
A_default_SH_WI = DEFAULT_SH_WI;
A_default_SH_WI_D1 = DEFAULT_SH_WI_D1;
A_default_SH_WI_D2 = DEFAULT_SH_WI_D2;
A_default_SH_WI_D3 = DEFAULT_SH_WI_D3;
A_default_HI_LO = DEFAULT_HI_LO;
A_default_FM = DEFAULT_FM;
A_default_FM_D1 = DEFAULT_FM_D1;
A_default_FM_D2 = DEFAULT_FM_D2;
A_default_FM_D3 = DEFAULT_FM_D3;
A_default_CW = DEFAULT_CW;
A_default_AM = DEFAULT_AM;
A_default_AM_D1 = DEFAULT_AM_D1;
A_default_AM_D2 = DEFAULT_AM_D2;
A_default_AM_D3 = DEFAULT_AM_D3;
A_default_FSK = DEFAULT_FSK;
A_default_PSK = DEFAULT_PSK;
B_default_SH_WI = DEFAULT_SH_WI;
B_default_SH_WI_D1 = DEFAULT_SH_WI_D1;
B_default_SH_WI_D2 = DEFAULT_SH_WI_D2;
B_default_SH_WI_D3 = DEFAULT_SH_WI_D3;
B_default_HI_LO = DEFAULT_HI_LO;
B_default_FM = DEFAULT_FM;
B_default_FM_D1 = DEFAULT_FM_D1;
B_default_FM_D2 = DEFAULT_FM_D2;
B_default_FM_D3 = DEFAULT_FM_D3;
B_default_CW = DEFAULT_CW;
B_default_AM = DEFAULT_AM;
B_default_AM_D1 = DEFAULT_AM_D1;
B_default_AM_D2 = DEFAULT_AM_D2;
B_default_AM_D3 = DEFAULT_AM_D3;
B_default_FSK = DEFAULT_FSK;
B_default_PSK = DEFAULT_PSK;
selectA();
}
void RIG_TS990::shutdown()
{
set_menu_0607(save_menu_0607);
set_menu_0608(save_menu_0608);
cmd = menu_0001; // restore beep level
sendCommand(cmd);
}
//==============================================================================
RIG_TS990::RIG_TS990() {
name_ = TS990name_;
modes_ = TS990modes_;
B.freq = A.freq = 14107500;
A.imode = USB;
A.iBW = A_default_HI_LO;
B.imode = USB;
B.iBW = B_default_HI_LO;
bandwidths_ = TS990_filt_SH;
bw_vals_ = TS990_HI_bw_vals;
dsp_SL = TS990_filt_SL;
SL_tooltip = TS990_filt_SL_tooltip;
SL_label = TS990_filt_SL_label;
dsp_SH = TS990_filt_SH;
SH_tooltip = TS990_filt_SH_label;
SH_label = TS990_filt_SH_label;
widgets = rig_widgets;
comm_baudrate = BR115200;
stopbits = 1;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_rtscts = true;
comm_rtsplus = false;
comm_dtrplus = false;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
can_change_alt_vfo = true;
nb_level = 1;
has_auto_notch =
has_notch_control =
has_sql_control =
has_swr_control =
has_noise_reduction =
has_noise_reduction_control =
has_alc_control =
has_dsp_controls =
has_smeter =
has_power_out =
has_split =
has_split_AB =
has_noise_control =
has_micgain_control =
has_rf_control =
has_volume_control =
has_power_control =
has_tune_control =
has_attenuator_control =
has_preamp_control =
has_mode_control =
has_bandwidth_control =
has_ifshift_control =
has_ptt_control = true;
rxtxa = true;
precision = 1;
ndigits = 8;
}
//==============================================================================
void RIG_TS990::selectA()
{
ts990debug("selectA()");
cmd = "CB0;";
sendCommand(cmd);
showresp(INFO, ASC, "Main band", cmd, "");
rxtxa = true;
cmd = "MV00;";
sendCommand(cmd);
showresp(INFO, ASC, "Rx A, Tx A", cmd, "");
rxtxa = true;
}
void RIG_TS990::selectB()
{
ts990debug("selectB()");
cmd = "CB1;";
sendCommand(cmd);
showresp(INFO, ASC, "Sub band", cmd, "");
rxtxa = false;
cmd = "MV10;";
sendCommand(cmd);
showresp(INFO, ASC, "Rx B, Tx B", cmd, "");
rxtxa = false;
}
//==============================================================================
// Get Attenuator
// The TS990 actually has 4 attenuator settings.
// RA00; = Off, RA01; = 6dB, RA02; = 12dB, RA03; = 18dB
//==============================================================================
int RIG_TS990::next_attenuator()
{
ts990debug("next_attenuator()");
switch (atten_level) {
case 0: return 1;
case 1: return 2;
case 2: return 3;
case 3: return 0;
}
return 0;
}
void RIG_TS990::set_attenuator(int val)
{
ts990debug("set_attenuator(int val)");
atten_level = val;
if (useB) {
if (atten_level == 1) { // If attenuator level = 0 (off)
cmd = "RA11;"; // this is the command...
atten_label("Att 6", true); // show it in the button...
}
else if (atten_level == 2) { // If attenuator level = 1 (6dB)
cmd = "RA12;";
atten_label("Att 12", true);
} else if (atten_level == 3) { // if it's 12dB
cmd = "RA13;";
atten_label("Att 18", true);
} else if (atten_level == 0) { // If it's 18dB
cmd = "RA10;";
atten_label("Att", false);
}
sendCommand(cmd);
showresp(INFO, ASC, "set Att B", cmd, "");
} else {
if (atten_level == 1) {
cmd = "RA01;";
atten_label("Att 6", true);
}
else if (atten_level == 2) {
cmd = "RA02;";
atten_label("Att 12", true);
} else if (atten_level == 3) {
cmd = "RA03;";
atten_label("Att 18", true);
} else if (atten_level == 0) {
cmd = "RA00;";
atten_label("Att", false);
}
sendCommand(cmd);
showresp(INFO, ASC, "set Att A", cmd, "");
}
}
//==============================================================================
// Modified to read and show the actual radio setting, in the button.
//==============================================================================
int RIG_TS990::get_attenuator() {
ts990debug("get_attenuator()");
if (useB) {
cmd = "RA1;";
if (wait_char(';', 5, 100, "get Att B", ASC) < 5) return att_on;
size_t p = replystr.rfind("RA");
if (p == string::npos) return att_on;
if (replystr[p + 2] == '1' && replystr[p + 3] == '0') {
att_on = 0; // Attenuator is OFF
atten_level = 0; // remember it...
atten_label("Att", false); // show it...
} else if (replystr[p + 2] == '1' && replystr[p + 3] == '1') {
att_on = 1; // Attenuator is ON, 6dB
atten_level = 1; // remember the level
atten_label("Att 6", true); // show it...
} else if (replystr[p + 2] == '1' && replystr[p + 3] == '2') {
att_on = 1; // .. still ON, 12dB
atten_level = 2; // remember this level
atten_label("Att 12", true); // show it.
} else if (replystr[p + 2] == '1' && replystr[p + 3] == '3') {
att_on = 1; // .. still ON 18dB
atten_level = 3; // remember...
atten_label("Att 18", true); // show this too..
}
} else {
cmd = "RA0;";
if (wait_char(';', 5, 100, "get Att B", ASC) < 5) return att_on;
size_t p = replystr.rfind("RA");
if (p == string::npos) return att_on;
if (replystr[p + 2] == '0' && replystr[p + 3] == '0') {
att_on = 0;
atten_level = 0;
atten_label("Att", false);
} else if (replystr[p + 2] == '0' && replystr[p + 3] == '1') {
att_on = 1;
atten_level = 1;
atten_label("Att 6", true);
} else if (replystr[p + 2] == '0' && replystr[p + 3] == '2') {
att_on = 1;
atten_level = 2;
atten_label("Att 12", true);
} else if (replystr[p + 2] == '0' && replystr[p + 3] == '3') {
att_on = 1;
atten_level = 3;
atten_label("Att 18", true);
}
}
return att_on;
}
//==============================================================================
//Get PreAmp
//==============================================================================
int RIG_TS990::next_preamp()
{
ts990debug("next_preamp()");
if (preamp_level) return 0;
return 1;
}
void RIG_TS990::set_preamp(int val)
{
ts990debug("set_preamp(int val)");
if (useB) {
preamp_level = val;
if (val) cmd = "PA11;";
else cmd = "PA10;";
sendCommand(cmd);
} else {
preamp_level = val;
if (val) cmd = "PA01;";
else cmd = "PA00;";
sendCommand(cmd);
}
showresp(INFO, ASC, "set preamp", cmd, "");
}
int RIG_TS990::get_preamp()
{
ts990debug("get_preamp()");
if (useB) {
cmd = "PA1;";
if (wait_char(';', 5, TS990_WAIT, "get preamp", ASC) < 5) return 0;
size_t p = replystr.rfind("PA");
if (p == string::npos) return 0;
if (replystr[p + 3] == '1')
preamp_level = 1;
else
preamp_level = 0;
} else {
cmd = "PA0;";
if (wait_char(';', 5, TS990_WAIT, "get preamp", ASC) < 5) return 0;
size_t p = replystr.rfind("PA");
if (p == string::npos) return 0;
if (replystr[p + 3] == '1')
preamp_level = 1;
else
preamp_level = 0;
}
return preamp_level;
}
//==============================================================================
void RIG_TS990::set_split(bool val)
{
ts990debug("set_split(bool val)");
split = val;
if (useB) {
if (val) {
cmd = "MV10;TB0;";
sendCommand(cmd);
showresp(INFO, ASC, "Rx on B, Tx on A", cmd, "");
} else {
cmd = "MV10;TB1;";
sendCommand(cmd);
showresp(INFO, ASC, "Rx on B, Tx on B", cmd, "");
}
} else {
if (val) {
cmd = "MV00;TB1;";
sendCommand(cmd);
showresp(INFO, ASC, "Rx on A, Tx on B", cmd, "");
} else {
cmd = "MV00;TB0;";
sendCommand(cmd);
showresp(INFO, ASC, "Rx on A, Tx on A", cmd, "");
}
}
}
int RIG_TS990::get_split()
{
ts990debug("get_split()");
size_t p;
int split = 0;
char rx = 0, tx = 0;
// tx vfo
cmd = rsp = "TB";
cmd.append(";");
if (wait_char(';', 4, TS990_WAIT, "get split tx vfo", ASC) == 4) {
p = replystr.rfind(rsp);
if (p == string::npos) return split;
tx = replystr[p+2];
}
// rx vfo
cmd = rsp = "CB";
cmd.append(";");
if (wait_char(';', 4, TS990_WAIT, "get split rx vfo", ASC) == 4) {
p = replystr.rfind(rsp);
if (p == string::npos) return split;
rx = replystr[p+2];
//split test
split = (tx == '1' ? 2 : 0) + (rx == '1' ? 1 : 0);
}
return split;
}
//==============================================================================
const char * RIG_TS990::get_bwname_(int n, int md)
{
ts990debug("get_bwname_(int n, int md)");
static char bwname[20];
if (n > 256) {
int SH = (n >> 8) & 0x7F;
int SL = n & 0x7F;
snprintf(bwname, sizeof(bwname), "%s/%s",
(md == LSB || md == USB || md == FM) ? TS990_filt_SL[SL] :
(md == AM || md == AMD1 || md == AMD2 || md == AMD3) ? TS990_AM_SL[SL] :
(md == CW ||md == CWR) ? TS990_CAT_CW_width [SL]:
(md == FSK ||md == FSKR) ? TS990_FSK_filt [SL]:
(md == PSK ||md == PSKR) ? TS990_PSK_filt [SL]:
TS990_filt_shift[SL],
(md == LSB || md == USB || md == FM) ? TS990_filt_SH[SH] :
(md == AM || md == AMD1 || md == AMD2 || md == AMD3) ? TS990_AM_SH[SH] :
(md == CW ||md == CWR) ? TS990_CAT_CW_shift [SH]:
(md == FSK ||md == FSKR) ? TS990_FSK_filt [SH]:
(md == PSK ||md == PSKR) ? TS990_PSK_filt [SH]:
TS990_filt_width[SH] );
}
return bwname;
}
//==============================================================================
// Get/Set VFO for A and B
//==============================================================================
bool RIG_TS990::check ()
{
cmd = "FA;";
int ret = wait_char(';', 14, 100, "check", ASC);
if (ret < 14) return false;
return true;
}
long RIG_TS990::get_vfoA ()
{
ts990debug("get_vfoA()");
cmd = "FA;";
if (wait_char(';', 14, TS990_WAIT, "get vfoA", ASC) < 14) return A.freq;
size_t p = replystr.rfind("FA");
if (p == string::npos) return A.freq;
long f = 0L;
long mul = 1L;
for (size_t n = 12; n > 1; n--) {
f += (replystr[p + n] - '0') * mul;
mul *= 10;
}
A.freq = f;
return A.freq;
}
void RIG_TS990::set_vfoA (long freq)
{
ts990debug("set_vfoA(long freq)");
A.freq = freq;
cmd = "FA00000000000;";
for (int i = 12; i > 1; i--) {
cmd[i] += freq % 10;
freq /= 10;
}
sendCommand(cmd);
showresp(INFO, ASC, "set vfo A", cmd, "");
}
long RIG_TS990::get_vfoB ()
{
ts990debug("get_vfoB()");
cmd = "FB;";
if (wait_char(';', 14, TS990_WAIT, "get vfoB", ASC) < 14) return B.freq;
size_t p = replystr.rfind("FB");
if (p == string::npos) return B.freq;
long f = 0L;
long mul = 1L;
for (size_t n = 12; n > 1; n--) {
f += (replystr[p + n] - '0') * mul;
mul *= 10;
}
B.freq = f;
return B.freq;
}
void RIG_TS990::set_vfoB (long freq)
{
ts990debug("set_vfoB(long freq)");
B.freq = freq;
cmd = "FB00000000000;";
for (int i = 12; i > 1; i--) {
cmd[i] += freq % 10;
freq /= 10;
}
sendCommand(cmd);
showresp(INFO, ASC, "set vfo B", cmd, "");
}
//==============================================================================
// Smeter reading
//==============================================================================
// response SMbmmmm;
int RIG_TS990::get_smeter()
{
ts990debug("get_smeter()");
if (useB) cmd = "SM1;";
else cmd = "SM0;";
int mtr = 0;
if (wait_char(';', 8, TS990_WAIT, "get", ASC) < 8)
return 0;
size_t p = replystr.find("SM");
if (p == string::npos)
return 0;
mtr = fm_decimal(replystr.substr(p+3), 4);
mtr *= 10;
mtr /= 7;
return mtr;
}
//==============================================================================
// Power out reading
//==============================================================================
// response SMbmmmm;
int RIG_TS990::get_power_out()
{
ts990debug("get_power_out()");
static int meter[] =
{ 0, 7, 15, 23, 29, 34, 40, 46, 51, 58 };
static float val[] =
{ 0, 10, 25, 50, 75, 100, 125, 150, 175, 200 };
if (useB) cmd = "SM1;";
else cmd = "SM0;";
int mtr = 0;
if (wait_char(';', 8, TS990_WAIT, "get", ASC) < 8)
return 0;
size_t p = replystr.find("SM");
if (p == string::npos)
return 0;
mtr = fm_decimal(replystr.substr(p+3), 4);
int i = 0;
while (i < 9 && (mtr > meter[i])) i++;
float value = val[i] + (val[i+1] - val[i]) * (mtr - meter[i]) / (meter[i+1] - meter[i]);
return (int)value;
}
//==============================================================================
// SWR readings
//==============================================================================
// response RMbmmmm;
int RIG_TS990::get_swr(void)
{
ts990debug("get_swr(void)");
int mtr = 0;
cmd = "RM21;";
sendCommand(cmd);
showresp(INFO, ASC, "set SWR meter", cmd, "");
cmd = "RM;";
sendCommand(cmd);
if (wait_char(';', 8, TS990_WAIT, "get swr", ASC) < 8) return 0;
size_t p = replystr.find("RM2");
if (p == string::npos) return 0;
mtr = fm_decimal(replystr.substr(p+3), 4);
mtr *= 10;
mtr /= 7;
if (mtr > 100) mtr = 100;
return mtr;
}
//==============================================================================
// ALC readings
//==============================================================================
// response RMbmmmm;
int RIG_TS990::get_alc(void)
{
ts990debug("get_alc(void)");
cmd = "RM11;";
sendCommand(cmd);
showresp(INFO, ASC, "set ALC meter", cmd, "");
cmd = "RM;";
sendCommand(cmd);
if (wait_char(';', 8, TS990_WAIT, "get ALC", ASC) < 8) return 0;
size_t p = replystr.find("RM1");
if (p == string::npos) return 0;
int alc_val = fm_decimal(replystr.substr(p+3), 4);
alc_val *= 10;
alc_val /= 7;
if (alc_val > 100) alc_val = 100;
return alc_val;
}
//==============================================================================
// Transceiver power level
//==============================================================================
void RIG_TS990::set_power_control(double val)
{
ts990debug("set_poer_control(double val)");
int ival = (int)val;
cmd = "PC000;";
for (int i = 4; i > 1; i--) {
cmd[i] += ival % 10;
ival /= 10;
}
sendCommand(cmd);
}
//==============================================================================
// Power control setting
//==============================================================================
// response: PCppp;
int RIG_TS990::get_power_control()
{
ts990debug("get_power_control()");
cmd = "PC;";
if (wait_char(';', 6, TS990_WAIT, "get pwr ctrl", ASC) < 6) return 0;
size_t p = replystr.rfind("PC");
if (p == string::npos) return 0;
int mtr = 0;
replystr[p + 5] = 0;
mtr = fm_decimal(replystr.substr(p+2), 3);
return mtr;
}
//==============================================================================
// Volume control return 0 ... 100
//==============================================================================
// response AGbmmm;
int RIG_TS990::get_volume_control()
{
ts990debug("get_volume_control()");
if (useB) {
cmd = "AG1;";
if (wait_char(';', 7, TS990_WAIT, "get vol ctrl", ASC) < 7) return 0;
size_t p = replystr.rfind("AG");
if (p == string::npos) return 0;
replystr[p + 6] = 0;
int val = fm_decimal(replystr.substr(p+3), 3);
return (int)(val / 2.55);
} else {
cmd = "AG0;";
if (wait_char(';', 7, TS990_WAIT, "get vol ctrl", ASC) < 7) return 0;
size_t p = replystr.rfind("AG");
if (p == string::npos) return 0;
replystr[p + 6] = 0;
int val = fm_decimal(replystr.substr(p+3), 3);
return (int)(val / 2.55);
}
}
void RIG_TS990::set_volume_control(int val)
{
ts990debug("set_volume_control(int val)");
if (useB) {
int ivol = (int)(val * 2.55);
cmd = "AG1000;";
for (int i = 5; i > 2; i--) {
cmd[i] += ivol % 10;
ivol /= 10;
}
sendCommand(cmd);
} else {
int ivol = (int)(val * 2.55);
cmd = "AG0000;";
for (int i = 5; i > 2; i--) {
cmd[i] += ivol % 10;
ivol /= 10;
}
sendCommand(cmd);
}
}
//==============================================================================
// Tranceiver PTT on/off
//==============================================================================
void RIG_TS990::set_PTT_control(int val)
{
ts990debug("set_PTT_control(int val)");
if (val) {
if (data_mode)
cmd = "TX1;";
else
cmd = "TX0;";
} else
cmd = "RX;";
sendCommand(cmd);
ptt_ = val;
}
int RIG_TS990::get_PTT()
{
return ptt_;
}
//==============================================================================
// Transceiver Tune
//==============================================================================
void RIG_TS990::tune_rig()
{
ts990debug("tune_rig()");
cmd = "AC111;";
sendCommand(cmd);
}
//==============================================================================
// Mode A / B
//==============================================================================
void RIG_TS990::set_modeA(int val)
{
stringstream ss;
ss << "set_modeA(" << val << ") " << TS990modes_[val];
ts990debug(ss.str());
A.imode = val;
cmd = "OM0";
cmd += TS990_mode_chr[val];
cmd += ';';
sendCommand(cmd);
showresp(INFO, ASC, "set mode main band", cmd, "");
set_widths(val);
data_mode = (A.imode >= LSBD1);
}
int RIG_TS990::get_modeA()
{
int md = A.imode;
cmd = "OM0;";
if (wait_char(';', 5, TS990_WAIT, "get mode main band", ASC) < 5) return A.imode;
size_t p = replystr.rfind("OM");
if (p == string::npos) return A.imode;
switch (replystr[p + 3]) {
case '1' : md = LSB; break;
case '2' : md = USB; break;
case '3' : md = CW; break;
case '4' : md = FM; break;
case '5' : md = AM; break;
case '6' : md = FSK; break;
case '7' : md = CWR; break;
case '9' : md = FSKR; break;
case 'A' : md = PSK; break;
case 'B' : md = PSKR; break;
case 'C' : md = LSBD1; break;
case 'D' : md = USBD1; break;
case 'E' : md = FMD1; break;
case 'F' : md = AMD1; break;
case 'G' : md = LSBD2; break;
case 'H' : md = USBD2; break;
case 'I' : md = FMD2; break;
case 'J' : md = AMD2; break;
case 'K' : md = LSBD3; break;
case 'L' : md = USBD3; break;
case 'M' : md = FMD3; break;
case 'N' : md = AMD3; break;
default : md = A.imode;
}
ts990debug("get_modeA()");
if (md != A.imode) {
stringstream ss;
ss << "get_modeB(" << md << ") " << TS990modes_[md];
ts990debug(ss.str());
LOG_INFO("get mode A: %s", TS990modes_[md]);
A.imode = md;
set_widths(md);
}
data_mode = (A.imode >= LSBD1);
return A.imode;
}
void RIG_TS990::set_modeB(int val)
{
stringstream ss;
ss << "set_modeB(" << val << ") " << TS990modes_[val];
ts990debug(ss.str());
B.imode = val;
cmd = "OM1";
cmd += TS990_mode_chr[val];
cmd += ';';
sendCommand(cmd);
showresp(INFO, ASC, "set mode sub band", cmd, "");
set_widths(val);
data_mode = (B.imode >= LSBD1);
}
int RIG_TS990::get_modeB()
{
int md = B.imode;
cmd = "OM1;";
if (wait_char(';', 5, TS990_WAIT, "get mode sub band", ASC) < 5) return B.imode;
size_t p = replystr.rfind("OM");
if (p == string::npos) return B.imode;
switch (replystr[p + 3]) {
case '1' : md = LSB; break;
case '2' : md = USB; break;
case '3' : md = CW; break;
case '4' : md = FM; break;
case '5' : md = AM; break;
case '6' : md = FSK; break;
case '7' : md = CWR; break;
case '9' : md = FSKR; break;
case 'A' : md = PSK; break;
case 'B' : md = PSKR; break;
case 'C' : md = LSBD1; break;
case 'D' : md = USBD1; break;
case 'E' : md = FMD1; break;
case 'F' : md = AMD1; break;
case 'G' : md = LSBD2; break;
case 'H' : md = USBD2; break;
case 'I' : md = FMD2; break;
case 'J' : md = AMD2; break;
case 'K' : md = LSBD3; break;
case 'L' : md = USBD3; break;
case 'M' : md = FMD3; break;
case 'N' : md = AMD3; break;
default : md = B.imode;
}
ts990debug("get_modeb()");
if (md != B.imode) {
stringstream ss;
ss << "get_modeB(" << md << ") " << TS990modes_[md];
ts990debug(ss.str());
B.imode = md;
set_widths(md);
}
data_mode = (B.imode >= LSBD1);
return B.imode;
}
//==============================================================================
// Microphone gain
//==============================================================================
void RIG_TS990::set_mic_gain(int val)
{
ts990debug("set_mic_gain(int val)");
cmd = "MG000;";
val *= 255;
val /= 100;
for (int i = 3; i > 0; i--) {
cmd[1+i] += val % 10;
val /= 10;
}
sendCommand(cmd);
}
//==============================================================================
// Mic gain setting
//==============================================================================
// response MGggg;
int RIG_TS990::get_mic_gain()
{
ts990debug("get_mic_gain()");
int val = 0;
cmd = "MG;";
if (wait_char(';', 6, TS990_WAIT, "get mic ctrl", ASC) >= 6) {
size_t p = replystr.rfind("MG");
if (p == string::npos) return val;
replystr[p + 5] = 0;
val = fm_decimal(replystr.substr(p+2), 3);
val *= 100;
val /= 255;
}
return val;
}
void RIG_TS990::get_mic_min_max_step(int &min, int &max, int &step)
{
ts990debug("get_mic_max_step(int &min, int &max, int &step)");
min = 0;
max = 100;
step = 1;
}
//==============================================================================
// Read/Write SSB and Data Mode Filter Settings
//==============================================================================
void RIG_TS990::read_menu_0607()
{
ts990debug("read_menu_0607()");
save_menu_0607 = true;//false;
cmd = "EX00607;"; sendCommand(cmd);
if (wait_char(';', 12, TS990_WAIT, "Read menu 0607", ASC) >= 12) {
size_t p = replystr.rfind("EX00607");
if (p != string::npos)
save_menu_0607 = (replystr[p+10] == '1');
}
}
void RIG_TS990::read_menu_0608()
{
ts990debug("read_menu_0608()");
save_menu_0608 = true;//false;
cmd = "EX00608;"; sendCommand(cmd);
if (wait_char(';', 12, TS990_WAIT, "Read menu 0608", ASC) >= 12) {
size_t p = replystr.rfind("EX00608");
if (p != string::npos)
save_menu_0608 = (replystr[p+10] == '1');
}
}
void RIG_TS990::set_menu_0607(int val)
{
ts990debug("set_menu_0607()");
menu_0607 = val;
cmd = "EX00607 00";
cmd += menu_0607 ? "1" : "0";
cmd += ";";
sendCommand(cmd);
}
void RIG_TS990::set_menu_0608(int val)
{
ts990debug("set_menu_0608()");
menu_0608 = val;
cmd = "EX00608 00";
cmd += menu_0608 ? "1" : "0";
cmd += ";";
sendCommand(cmd);
}
//==============================================================================
// Bandpass filter commands
//==============================================================================
int RIG_TS990::set_widths(int val)
{
ts990debug("set_widths(int val)");
int bw = 0;
if (useB) bw = B.iBW;
else bw = A.iBW;
read_menu_0607();
read_menu_0608();
switch (val) {
case LSB: case USB:
if (menu_0607) {
bandwidths_ = TS990_filt_width;
bw_vals_ = TS990_WIDTH_bw_vals;
dsp_SL = TS990_filt_width;
SL_tooltip = TS990_filt_width_tooltip;
SL_label = TS990_filt_width_label;
dsp_SH = TS990_filt_shift;
SH_tooltip = TS990_filt_shift_tooltip;
SH_label = TS990_filt_shift_label;
} else {
bandwidths_ = TS990_filt_SH;
bw_vals_ = TS990_HI_bw_vals;
dsp_SL = TS990_filt_SL;
SL_tooltip = TS990_filt_SL_tooltip;
SL_label = TS990_filt_SL_label;
dsp_SH = TS990_filt_SH;
SH_tooltip = TS990_filt_SH_tooltip;
SH_label = TS990_filt_SH_label;
}
break;
case LSBD1: case LSBD2: case LSBD3:
case USBD1: case USBD2: case USBD3:
if (menu_0608) {
bandwidths_ = TS990_filt_width;
bw_vals_ = TS990_WIDTH_bw_vals;
dsp_SL = TS990_filt_width;
SL_tooltip = TS990_filt_width_tooltip;
SL_label = TS990_filt_width_label;
dsp_SH = TS990_filt_shift;
SH_tooltip = TS990_filt_shift_tooltip;
SH_label = TS990_filt_shift_label;
} else {
bandwidths_ = TS990_filt_SH;
bw_vals_ = TS990_HI_bw_vals;
dsp_SL = TS990_filt_SL;
SL_tooltip = TS990_filt_SL_tooltip;
SL_label = TS990_filt_SL_label;
dsp_SH = TS990_filt_SH;
SH_tooltip = TS990_filt_SH_tooltip;
SH_label = TS990_filt_SH_label;
}
break;
case CW: case CWR:
bandwidths_ = TS990_CW_width;
bw_vals_ = TS990_CW_bw_vals;
dsp_SL = TS990_CW_width;
SL_tooltip = TS990_CW_W_tooltip;
SL_label = TS990_CW_W_btn_label;
dsp_SH = TS990_CW_shift;
SH_tooltip = TS990_CW_S_tooltip;
SH_label = TS990_CW_S_btn_label;
break;
case FSK: case FSKR:
bandwidths_ = TS990_FSK_filt;
bw_vals_ = TS990_FSK_bw_vals;
dsp_SL = TS990_empty;
dsp_SH = TS990_empty;
break;
case PSK: case PSKR:
bandwidths_ = TS990_PSK_filt;
bw_vals_ = TS990_PSK_bw_vals;
dsp_SL = TS990_empty;
dsp_SH = TS990_empty;
break;
case AM: case AMD1: case AMD2: case AMD3:
bandwidths_ = TS990_AM_SH;
bw_vals_ = TS990_AM_HI_bw_vals;
dsp_SL = TS990_AM_SL;
dsp_SH = TS990_AM_SH;
SL_tooltip = TS990_AM_SL_tooltip;
SL_label = TS990_AM_btn_SL_label;
SH_tooltip = TS990_AM_SH_tooltip;
SH_label = TS990_AM_btn_SH_label;
break;
case FM: case FMD1: case FMD2: case FMD3:
bandwidths_ = TS990_filt_SH;
bw_vals_ = TS990_HI_bw_vals;
dsp_SL = TS990_filt_SL;
dsp_SH = TS990_filt_SH;
SL_tooltip = TS990_filt_SL_tooltip;
SL_label = TS990_filt_SL_label;
SH_tooltip = TS990_filt_SH_tooltip;
SH_label = TS990_filt_SH_label;
break;
}
return bw;
}
const char **RIG_TS990::bwtable(int m)
{
stringstream ss;
ss << "bwtable( " << m << " )";
ts990debug(ss.str());
const char **filter = TS990_filt_SH;
switch (m) {
case LSB: case USB:
if (menu_0607)
filter = TS990_filt_width;
else
filter = TS990_filt_SH;
break;
case FM: case FMD1: case FMD2: case FMD3:
filter = TS990_filt_SH;
break;
case LSBD1: case LSBD2: case LSBD3:
case USBD1: case USBD2: case USBD3:
if (menu_0608)
filter = TS990_filt_width;
else
filter = TS990_filt_SH;
break;
case AM: case AMD1: case AMD2: case AMD3:
filter = TS990_AM_SH;
break;
case CW: case CWR:
filter = TS990_CW_width;
break;
case FSK: case FSKR:
filter = TS990_FSK_filt;
break;
case PSK: case PSKR:
filter = TS990_PSK_filt;
break;
}
ss << "filter address: " << filter;
ts990debug(ss.str());
return filter;
}
const char **RIG_TS990::lotable(int m)
{
stringstream ss;
ss << "lotable( " << m << " )";
ts990debug(ss.str());
const char **filter = TS990_filt_SL;
switch (m) {
case LSB: case USB:
if (menu_0607)
filter = TS990_filt_width;
else
filter = TS990_filt_SL;
break;
case FM: case FMD1: case FMD2: case FMD3:
filter = TS990_filt_SL;
break;
case LSBD1: case LSBD2: case LSBD3:
case USBD1: case USBD2: case USBD3:
if (menu_0608)
filter = TS990_filt_width;
else
filter = TS990_filt_SL;
break;
case CW: case CWR:
filter = TS990_CW_width;
break;
case FSK: case FSKR:
filter = NULL;//TS990_FSK_filt;
break;
case PSK: case PSKR:
filter = NULL;//TS990_PSK_filt;
break;
case AM: case AMD1: case AMD2: case AMD3:
filter = TS990_AM_SL;
break;
}
ss << "filter address: " << filter;
ts990debug(ss.str());
return filter;
}
const char **RIG_TS990::hitable(int m)
{
stringstream ss;
ss << "hitable( " << m << " )";
ts990debug(ss.str());
const char **filter = TS990_filt_SH;
switch (m) {
case LSB: case USB:
if (menu_0607)
filter = TS990_filt_shift;
else
filter = TS990_filt_SH;
break;
case LSBD1: case LSBD2: case LSBD3:
case USBD1: case USBD2: case USBD3:
if (menu_0608)
filter = TS990_filt_shift;
else
filter = TS990_filt_SH;
break;
case CW: case CWR:
filter = TS990_CW_shift;
break;
case FM: case FMD1: case FMD2: case FMD3:
filter = TS990_filt_SH;
break;
case FSK: case FSKR:
filter = NULL;
break;
case PSK: case PSKR:
filter = NULL;
break;
case AM: case AMD1: case AMD2: case AMD3:
filter = TS990_AM_SH;
break;
}
ss << "filter address: " << filter;
ts990debug(ss.str());
return filter;
}
int RIG_TS990::adjust_bandwidth(int val)
{
stringstream ss;
ss << "adust_bandwidth( " << val << " )";
ts990debug(ss.str());
int retval = 0;
switch (val) {
case LSB: case USB:
if (useB)
retval = menu_0607 ? B_default_SH_WI : B_default_HI_LO;
else
retval = menu_0607 ? A_default_SH_WI : A_default_HI_LO;
break;
case LSBD1: case USBD1:
if (useB)
retval = menu_0608 ? B_default_SH_WI_D1 : B_default_HI_LO;
else
retval = menu_0608 ? A_default_SH_WI_D1 : A_default_HI_LO;
break;
case LSBD2: case USBD2:
if (useB)
retval = menu_0608 ? B_default_SH_WI_D2 : B_default_HI_LO;
else
retval = menu_0608 ? A_default_SH_WI_D2 : A_default_HI_LO;
break;
case LSBD3: case USBD3:
if (useB)
retval = menu_0608 ? B_default_SH_WI_D3 : B_default_HI_LO;
else
retval = menu_0608 ? A_default_SH_WI_D3 : A_default_HI_LO;
break;
case FM:
retval = (useB ? B_default_FM : A_default_FM);
break;
case FMD1:
retval = (useB ? B_default_FM_D1 : A_default_FM_D1);
break;
case FMD2:
retval = (useB ? B_default_FM_D2 : A_default_FM_D2);;
break;
case FMD3:
retval = (useB ? B_default_FM_D3 : A_default_FM_D3);
break;
case AM:
retval = (useB ? B_default_AM : A_default_AM);
break;
case AMD1:
retval = (useB ? B_default_AM_D1 : A_default_AM_D1);
break;
case AMD2:
retval = (useB ? B_default_AM_D2 : A_default_AM_D2);
break;
case AMD3:
retval = (useB ? B_default_AM_D3 : A_default_AM_D3);
break;
case CW: case CWR:
retval = (useB ? B_default_CW : A_default_CW);
break;
case FSK: case FSKR:
retval = (useB ? B_default_FSK : A_default_FSK);
break;
case PSK: case PSKR:
retval = (useB ? B_default_PSK : A_default_PSK);
break;
}
return retval;
}
int RIG_TS990::def_bandwidth(int val)
{
ts990debug("def_bandwidth(int val)");
read_menu_0607();
read_menu_0608();
return adjust_bandwidth(val);
}
void RIG_TS990::set_bwA(int val)
{
size_t SL = 0, SH = 0;
size_t sl = 0, sh = 0;
SL = val & 0x7F;
if (SL < 0) SL = 0;
SH = (val >> 8) & 0x7F;
if (SH < 0) SH = 0;
stringstream ss;
ss << "set_bwA( " << SH << "/" << SL << " )";
ts990debug(ss.str());
switch (A.imode) {
case LSB: case USB:
if (val < 256) break;
if (menu_0607) {
sl = sizeof(TS990_CAT_filt_width)/sizeof(*TS990_CAT_filt_width) - 1;
sh = sizeof(TS990_CAT_filt_shift)/sizeof(*TS990_CAT_filt_shift) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_filt_width[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set width", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_filt_shift[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set filter shift", cmd, "");
A.iBW = ((SH << 8) & SL) & 0x8000;
} else {
sh = sizeof(TS990_CAT_filt_SH)/sizeof(*TS990_CAT_filt_SH) - 1;
sl = sizeof(TS990_CAT_filt_SL)/sizeof(*TS990_CAT_filt_SL) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_filt_SL[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set filter lower cutoff", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_filt_SH[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set filter upper cutoff", cmd, "");
A.iBW = ((SH << 8) & SL) & 0x8000;
}
break;
case LSBD1: case LSBD2: case LSBD3:
case USBD1: case USBD2: case USBD3:
if (val < 256) break;
if (menu_0608) {
sl = sizeof(TS990_CAT_filt_width)/sizeof(*TS990_CAT_filt_width) - 1;
sh = sizeof(TS990_CAT_filt_shift)/sizeof(*TS990_CAT_filt_shift) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_filt_width[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set data width", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_filt_shift[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set data shift", cmd, "");
A.iBW = ((SH << 8) & SL) & 0x8000;
} else {
sh = sizeof(TS990_CAT_filt_SH)/sizeof(*TS990_CAT_filt_SH) - 1;
sl = sizeof(TS990_CAT_filt_SL)/sizeof(*TS990_CAT_filt_SL) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_filt_SL[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set data lower cutoff", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_filt_SH[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set data upper cutoff", cmd, "");
A.iBW = ((SH << 8) & SL) & 0x8000;
}
break;
case AM: case AMD1: case AMD2: case AMD3:
if (val < 256) break;
sh = sizeof(TS990_CAT_AM_SH) / sizeof(*TS990_CAT_AM_SH) - 1;
sl = sizeof(TS990_CAT_AM_SL) / sizeof(*TS990_CAT_AM_SL) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_AM_SL[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set AM lower", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_AM_SH[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set AM upper", cmd, "");
A.iBW = ((SH << 8) & SL) & 0x8000;
break;
case FM: case FMD1: case FMD2: case FMD3:
if (val < 256) break;
sh = sizeof(TS990_CAT_filt_SH) / sizeof(*TS990_CAT_filt_SH) - 1;
sl = sizeof(TS990_CAT_filt_SL) / sizeof(*TS990_CAT_filt_SL) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_filt_SL[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set FM lower", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_filt_SH[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set FM upper", cmd, "");
A.iBW = ((SH << 8) & SL) & 0x8000;
break;
case CW: case CWR:
if (val < 256) break;
sl = sizeof(TS990_CAT_CW_width) / sizeof(*TS990_CAT_CW_width) - 1;
sh = sizeof(TS990_CAT_CW_shift) / sizeof(*TS990_CAT_CW_shift) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_CW_width[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set cw width", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_CW_shift[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set cw shift", cmd, "");
A.iBW = ((SH << 8) & SL) & 0x8000;
break;
case FSK: case FSKR:
if (val > 256) break;
sl = sizeof(TS990_CAT_FSK_filt) / sizeof(*TS990_CAT_FSK_filt) - 1;
if (SL > sl) SL = sl;
cmd = "SL0";
cmd += TS990_CAT_FSK_filt[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set FSK bw", cmd, "");
A.iBW = SL;
break;
case PSK: case PSKR:
if (val > 256) break;
sl = sizeof(TS990_CAT_PSK_filt) / sizeof(*TS990_CAT_PSK_filt) - 1;
if (SL > sl) SL = sl;
cmd = "SL0";
cmd += TS990_CAT_PSK_filt[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set PSK bw", cmd, "");
A.iBW = SL;
break;
}
}
void RIG_TS990::set_bwB(int val)
{
size_t SL = 0, SH = 0;
size_t sl = 0, sh = 0;
SL = val & 0x7F;
if (SL < 0) SL = 0;
SH = (val >> 8) & 0x7F;
if (SH < 0) SH = 0;
stringstream ss;
ss << "set_bwB( " << SH << "/" << SL << " )";
ts990debug(ss.str());
switch (B.imode) {
case LSB: case USB:
if (val < 256) break;
if (menu_0607) {
sl = sizeof(TS990_CAT_filt_width)/sizeof(*TS990_CAT_filt_width) - 1;
sh = sizeof(TS990_CAT_filt_shift)/sizeof(*TS990_CAT_filt_shift) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_filt_width[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set width", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_filt_shift[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set filter shift", cmd, "");
B.iBW = ((SH << 8) & SL) & 0x8000;
} else {
sl = sizeof(TS990_CAT_filt_SL)/sizeof(*TS990_CAT_filt_SL) - 1;
sh = sizeof(TS990_CAT_filt_SH)/sizeof(*TS990_CAT_filt_SH) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_filt_SL[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set filter lower cutoff", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_filt_SH[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set filter upper cutoff", cmd, "");
B.iBW = ((SH << 8) & SL) & 0x8000;
}
break;
case LSBD1: case LSBD2: case LSBD3:
case USBD1: case USBD2: case USBD3:
if (val < 256) break;
if (menu_0608) {
sl = sizeof(TS990_CAT_filt_width)/sizeof(*TS990_CAT_filt_width) - 1;
sh = sizeof(TS990_CAT_filt_shift)/sizeof(*TS990_CAT_filt_shift) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_filt_width[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set data width", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_filt_shift[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set data shift", cmd, "");
B.iBW = ((SH << 8) & SL) & 0x8000;
} else {
sh = sizeof(TS990_CAT_filt_SH)/sizeof(*TS990_CAT_filt_SH) - 1;
sl = sizeof(TS990_CAT_filt_SL)/sizeof(*TS990_CAT_filt_SL) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_filt_SL[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set data lower cutoff", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_filt_SH[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set data upper cutoff", cmd, "");
B.iBW = ((SH << 8) & SL) & 0x8000;
}
break;
case AM: case AMD1: case AMD2: case AMD3:
if (val < 256) break;
sh = sizeof(TS990_CAT_AM_SH) / sizeof(*TS990_CAT_AM_SH) - 1;
sl = sizeof(TS990_CAT_AM_SL) / sizeof(*TS990_CAT_AM_SL) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_AM_SL[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set AM lower", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_AM_SH[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set AM upper", cmd, "");
B.iBW = ((SH << 8) & SL) & 0x8000;
break;
case FM: case FMD1: case FMD2: case FMD3:
if (val < 256) break;
sh = sizeof(TS990_CAT_filt_SH) / sizeof(*TS990_CAT_filt_SH) - 1;
sl = sizeof(TS990_CAT_filt_SL) / sizeof(*TS990_CAT_filt_SL) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_filt_SL[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set FM lower", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_filt_SH[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set FM upper", cmd, "");
B.iBW = ((SH << 8) & SL) & 0x8000;
break;
case CW: case CWR:
if (val < 256) break;
sl = sizeof(TS990_CAT_CW_width) / sizeof(*TS990_CAT_CW_width) - 1;
sh = sizeof(TS990_CAT_CW_shift) / sizeof(*TS990_CAT_CW_shift) - 1;
if (SL > sl) SL = sl;
if (SH > sh) SH = sh;
cmd = "SL0";
cmd += TS990_CAT_CW_width[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set cw width", cmd, "");
cmd = "SH0";
cmd += TS990_CAT_CW_shift[SH];
sendCommand(cmd);
showresp(INFO, ASC, "set cw shift", cmd, "");
B.iBW = ((SH << 8) & SL) & 0x8000;
break;
case FSK: case FSKR:
if (val > 256) break;
sl = sizeof(TS990_CAT_FSK_filt) / sizeof(*TS990_CAT_FSK_filt) - 1;
if (SL > sl) SL = sl;
cmd = "SL0";
cmd += TS990_CAT_FSK_filt[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set FSK bw", cmd, "");
B.iBW = SL;
break;
case PSK: case PSKR:
if (val > 256) break;
sl = sizeof(TS990_CAT_PSK_filt) / sizeof(*TS990_CAT_PSK_filt) - 1;
if (SL > sl) SL = sl;
cmd = "SL0";
cmd += TS990_CAT_PSK_filt[SL];
sendCommand(cmd);
showresp(INFO, ASC, "set PSK bw", cmd, "");
B.iBW = SL;
break;
}
}
//==============================================================================
// Bandwidth / Shift; Lower / Upper DSP settings
//==============================================================================
// response SLbbb; SHbbb;
int RIG_TS990::get_bwA()
{
size_t p;
int SL = 0, SH = 0;
read_menu_0607();
read_menu_0608();
switch (A.imode) {
case CW: case CWR:
A.iBW = A_default_CW;
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get CW width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get CW shift", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_CW = A.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
break;
case FSK: case FSKR:
A.iBW = A_default_FSK;
SL = A.iBW & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get FSK Width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
A_default_FSK = A.iBW = (SL & 0x7F);
}
break;
case PSK: case PSKR:
A.iBW = A_default_PSK;
SL = A.iBW & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get PSK Width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
A_default_PSK = A.iBW = (SL & 0x7F);
}
break;
case LSB: case USB:
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
if (menu_0607) {
A.iBW = A_default_SH_WI;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter shift", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_SH_WI = A.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
} else {
A.iBW = A_default_HI_LO;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get filter lower cutoff", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter upper cutoff", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_HI_LO = A.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
}
break;
case LSBD1: case USBD1:
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
if (menu_0608) {
A.iBW = A_default_SH_WI_D1;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter shift", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_SH_WI_D1 = A.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
} else {
A.iBW = A_default_HI_LO;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get filter lower cutoff", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter upper cutoff", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_HI_LO = A.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
}
break;
case LSBD2: case USBD2:
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
if (menu_0608) {
A.iBW = A_default_SH_WI_D2;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter shift", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_SH_WI_D2 = A.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
} else {
A.iBW = A_default_HI_LO;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get filter lower cutoff", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter upper cutoff", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_HI_LO = A.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
}
break;
case LSBD3: case USBD3:
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
if (menu_0608) {
A.iBW = A_default_SH_WI_D3;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter shift", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(3), 3);
A_default_SH_WI_D3 = A.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
} else {
A.iBW = A_default_HI_LO;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get filter lower cutoff", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter upper cutoff", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_HI_LO = A.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
}
break;
case AM:
A.iBW = A_default_AM;
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get AM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get AM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_AM = A.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case AMD1:
A.iBW = A_default_AM_D1;
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get AM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get AM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_AM_D1 = A.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case AMD2:
A.iBW = A_default_AM_D2;
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get AM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get AM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_AM_D2 = A.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case AMD3:
A.iBW = A_default_AM_D3;
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get AM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get AM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_AM_D3 = A.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case FM:
A.iBW = A_default_FM;
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get FM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get FM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_FM = A.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case FMD1:
A.iBW = A_default_FM_D1;
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get FM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get FM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_FM_D1 = A.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case FMD2 :
A.iBW = A_default_FM_D2;
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get FM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get FM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_FM_D2 = A.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case FMD3:
A.iBW = A_default_FM_D3;
SL = A.iBW & 0x7F;
SH = (A.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get FM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get FM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
A_default_FM_D3 = A.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
}
stringstream ss;
ss << "mode: " << TS990modes_[A.imode] << ", get_bwA( " << SH << "/" << SL << " )";
ts990debug(ss.str());
return A.iBW;
}
//==============================================================================
// Bandwidth / Shift; Lower / Upper DSP settings
//==============================================================================
// responses SHbbb; SLbbb;
int RIG_TS990::get_bwB()
{
size_t p;
int SL = 0, SH = 0;
read_menu_0607();
read_menu_0608();
switch (B.imode) {
case CW: case CWR:
B.iBW = B_default_CW;
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get CW width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get CW shift", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_CW = B.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
break;
case FSK: case FSKR:
B.iBW = B_default_FSK;
SL = B.iBW & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get FSK Width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
B_default_FSK = B.iBW = (SL & 0x7F);
}
break;
case PSK: case PSKR:
B.iBW = B_default_PSK;
SL = B.iBW & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get PSK Width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
B_default_PSK = B.iBW = (SL & 0x7F);
}
break;
case LSB: case USB:
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
if (menu_0607) {
B.iBW = B_default_SH_WI;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter shift", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_SH_WI = B.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
} else {
B.iBW = B_default_HI_LO;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get filter lower cutoff", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter upper cutoff", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_HI_LO = B.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
}
break;
case LSBD1: case USBD1:
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
if (menu_0608) {
B.iBW = B_default_SH_WI_D1;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter shift", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_SH_WI_D1 = B.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
} else {
B.iBW = B_default_HI_LO;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get filter lower cutoff", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter upper cutoff", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_HI_LO = B.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
}
break;
case LSBD2: case USBD2:
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
if (menu_0608) {
B.iBW = B_default_SH_WI_D2;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter shift", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_SH_WI_D2 = B.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
} else {
B.iBW = B_default_HI_LO;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get filter lower cutoff", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter upper cutoff", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_HI_LO = B.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
}
break;
case LSBD3: case USBD3:
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
if (menu_0608) {
B.iBW = B_default_SH_WI_D3;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get width", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter shift", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_SH_WI_D3 = B.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
} else {
B.iBW = B_default_HI_LO;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get filter lower cutoff", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get filter upper cutoff", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_HI_LO = B.iBW = ((SH << 8) | (SL & 0x7F )) | 0x8000;
}
}
}
break;
case AM:
B.iBW = B_default_AM;
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get AM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get AM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_AM = B.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case AMD1:
B.iBW = B_default_AM_D1;
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get AM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get AM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_AM_D1 = B.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case AMD2:
B.iBW = B_default_AM_D2;
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get AM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get AM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_AM_D2 = B.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case AMD3:
B.iBW = B_default_AM_D3;
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get AM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get AM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_AM_D3 = B.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case FM:
B.iBW = B_default_FM;
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get FM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get FM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_FM = B.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case FMD1:
B.iBW = B_default_FM_D1;
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get FM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get FM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_FM_D1 = B.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case FMD2 :
B.iBW = B_default_FM_D2;
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get FM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get FM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_FM_D2 = B.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
break;
case FMD3:
B.iBW = B_default_FM_D3;
SL = B.iBW & 0x7F;
SH = (B.iBW >> 8) & 0x7F;
cmd = "SL0;";
if (wait_char(';', 6, TS990_WAIT, "get FM lo", ASC) == 6) {
p = replystr.rfind("SL");
if (p == string::npos) break;
SL = fm_decimal(replystr.substr(2), 3);
cmd = "SH0;";
if (wait_char(';', 6, TS990_WAIT, "get FM hi", ASC) == 6) {
p = replystr.rfind("SH");
if (p == string::npos) break;
SH = fm_decimal(replystr.substr(2), 3);
B_default_FM_D3 = B.iBW = ((SH << 8) | (SL & 0x7F)) | 0x8000;
}
}
}
stringstream ss;
ss << "mode: " << TS990modes_[B.imode] << ", get_bwB( " << SH << "/" << SL << " )";
ts990debug(ss.str());
return B.iBW;
}
int RIG_TS990::get_modetype(int n)
{
ts990debug("get_modetype(int n)");
return TS990_mode_type[n];
}
void RIG_TS990::set_noise(bool val) //Now Setting AGC
{
ts990debug("set_noise(bool val)");
if (useB) {
if (nb_level == 2) {
nb_level = 3;
nb_label("AGC F", false);
cmd = "GC13;";
sendCommand(cmd);
} else if (nb_level == 3) {
nb_level = 1;
nb_label("AGC S", false);
cmd = "GC11;";
sendCommand(cmd);
} else if (nb_level == 1) {
nb_level = 2;
nb_label("AGC M", false);
cmd = "GC12;";
sendCommand(cmd);
}
} else {
if (nb_level == 2) {
nb_level = 3;
nb_label("AGC F", false);
cmd = "GC03;";
sendCommand(cmd);
} else if (nb_level == 3) {
nb_level = 1;
nb_label("AGC S", false);
cmd = "GC01;";
sendCommand(cmd);
} else if (nb_level == 1) {
nb_level = 2;
nb_label("AGC M", false);
cmd = "GC02;";
sendCommand(cmd);
}
}
}
//----------------------------------------------------------------------
int RIG_TS990::get_agc()
{
ts990debug("get_agc()");
int val = 0;
if (useB) {
cmd = "GC1;";
if (wait_char(';', 5, 100, "get AGC", ASC) < 5) return val;
size_t p = replystr.rfind("GC");
if (p == string::npos) return val;
if (replystr[p + 3] == '1' ) {
nb_label("AGC S", false);
} else if (replystr[p + 3] == '2' ) {
nb_label("AGC M", false);
} else if (replystr[p + 3] == '3' ) {
nb_label("AGC F", false);
}
} else {
cmd = "GC0;";
if (wait_char(';', 5, 100, "get AGC", ASC) < 5) return val;
size_t p = replystr.rfind("GC");
if (p == string::npos) return val;
if (replystr[p + 3] == '1' ) {
nb_label("AGC S", false);
} else if (replystr[p + 3] == '2' ) {
nb_label("AGC M", false);
} else if (replystr[p + 3] == '3' ) {
nb_label("AGC F", false);
}
}
return val;
}
//==============================================================================
void RIG_TS990::set_squelch(int val)
{
ts990debug("set_squelch(int val)");
val *= 255;
val /= 100;
if (useB) {
cmd = "SQ1";
cmd.append(to_decimal(abs(val),3)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "set squelch", cmd, "");
} else {
cmd = "SQ0";
cmd.append(to_decimal(abs(val),3)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "set squelch", cmd, "");
}
}
//response SQbmmm;
int RIG_TS990::get_squelch()
{
ts990debug("get_squelch()");
int val = 0;
if (useB) {
cmd = "SQ1;";
if (wait_char(';', 7, TS990_WAIT, "get squelch", ASC) >= 7) {
size_t p = replystr.rfind("SQ1");
if (p == string::npos) return val;
replystr[p + 6] = 0;
val = fm_decimal(replystr.substr(p+3), 3);
}
} else {
cmd = "SQ0;";
if (wait_char(';', 7, TS990_WAIT, "get squelch", ASC) >= 7) {
size_t p = replystr.rfind("SQ0");
if (p == string::npos) return val;
replystr[p + 6] = 0;
val = fm_decimal(replystr.substr(p+3), 3);
}
}
val *= 100;
val /= 255;
return val;
}
void RIG_TS990::get_squelch_min_max_step(int &min, int &max, int &step)
{
ts990debug("get_squelch_min_max_step(int &min, int &max, int &step)");
min = 0; max = 100; step = 1;
}
void RIG_TS990::set_rf_gain(int val)
{
ts990debug("set_rf_gain(int val)");
val *= 255;
val /= 100;
if (useB) {
cmd = "RG1";
cmd.append(to_decimal(val,3)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "set rf gain", cmd, "");
} else {
cmd = "RG0";
cmd.append(to_decimal(val,3)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "set rf gain", cmd, "");
}
}
//==============================================================================
// RF gain setting
//==============================================================================
// response RGbmmm;
int RIG_TS990::get_rf_gain()
{
ts990debug("get_rf_gain()");
int val = progStatus.rfgain;
if (useB) {
cmd = "RG1;";
if (wait_char(';', 7, TS990_WAIT, "get rf gain", ASC) < 7) return val;
size_t p = replystr.rfind("RG");
if (p != string::npos) {
val = fm_decimal(replystr.substr(p+3), 3);
val *= 100;
val /= 255;
}
} else {
cmd = "RG0;";
if (wait_char(';', 7, TS990_WAIT, "get rf gain", ASC) < 7) return val;
size_t p = replystr.rfind("RG");
if (p != string::npos) {
val = fm_decimal(replystr.substr(p+3), 3);
val *= 100;
val /= 255;
}
}
return val;
}
void RIG_TS990::get_rf_min_max_step(int &min, int &max, int &step)
{
ts990debug("get_rf_min_max_step(int &min, int &max, int &step)");
min = 0;
max = 100;
step = 1;
}
static bool nr_on = false;
void RIG_TS990::set_noise_reduction(int val)
{
ts990debug("set_noise_reduction(int val)");
if (useB) {
cmd.assign("NR1").append(val ? "1" : "0" ).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "SET noise reduction", cmd, "");
if (val) nr_on = true;
else nr_on = false;
} else {
cmd.assign("NR0").append(val ? "1" : "0" ).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "SET noise reduction", cmd, "");
if (val) nr_on = true;
else nr_on = false;
}
}
int RIG_TS990::get_noise_reduction()
{
ts990debug("get_noise_reduction()");
int val = 0;
if (useB) {
cmd = rsp = "NR1";
cmd.append(";");
if (wait_char(';', 5, TS990_WAIT, "GET noise reduction", ASC) < 5) return val;
size_t p = replystr.rfind(rsp);
if (p == string::npos) return val;
val = replystr[p+3] - '0';
if (val == 1) nr_on = true;
else nr_on = false;
return val;
} else {
cmd = rsp = "NR0";
cmd.append(";");
if (wait_char(';', 5, TS990_WAIT, "GET noise reduction", ASC) < 5) return val;
size_t p = replystr.rfind(rsp);
if (p == string::npos) return val;
val = replystr[p+3] - '0';
if (val == 1) nr_on = true;
else nr_on = false;
}
return val;
}
void RIG_TS990::set_noise_reduction_val(int val)
{
ts990debug("set_noise_reduction_val(int val)");
if (useB) {
cmd.assign("RL11").append(to_decimal(val, 2)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "SET_noise_reduction_val", cmd, "");
} else {
cmd.assign("RL10").append(to_decimal(val, 2)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "SET_noise_reduction_val", cmd, "");
}
}
//==============================================================================
// Noise reduction setting
//==============================================================================
// response RL1bmm; RL2bmm;
int RIG_TS990::get_noise_reduction_val()
{
ts990debug("get_noise_reduction_val()");
int val = 0;
if (useB) {
if (!nr_on) return val;
cmd = rsp = "RL11";
cmd.append(";");
if (wait_char(';', 7, TS990_WAIT, "GET noise reduction val", ASC) < 7) return val;
size_t p = replystr.rfind(rsp);
if (p == string::npos) return val;
val = fm_decimal(replystr.substr(p+4), 2);
} else {
if (!nr_on) return val;
cmd = rsp = "RL10";
cmd.append(";");
if (wait_char(';', 7, TS990_WAIT, "GET noise reduction val", ASC) < 7) return val;
size_t p = replystr.rfind(rsp);
if (p == string::npos) return val;
val = fm_decimal(replystr.substr(p+4), 2);
}
return val;
}
void RIG_TS990::set_auto_notch(int v)
{
ts990debug("set_auto_notch(int v)");
if (useB) {
cmd.assign("NT1").append(v ? "1" : "0" ).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "SET Auto Notch", cmd, "");
} else {
cmd.assign("NT0").append(v ? "1" : "0" ).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "SET Auto Notch", cmd, "");
}
}
int RIG_TS990::get_auto_notch()
{
ts990debug("get_auto_notch()");
int val = 0;
if (useB) {
cmd = "NT1;";
if (wait_char(';', 5, TS990_WAIT, "get auto notch", ASC) < 5) return val;
size_t p = replystr.rfind("NT");
if (p == string::npos) return val;
if (replystr[p+3] == '1') val = 1;
} else {
cmd = "NT0;";
if (wait_char(';', 5, TS990_WAIT, "get auto notch", ASC) < 5) return val;
size_t p = replystr.rfind("NT");
if (p == string::npos) return val;
if (replystr[p+3] == '1') val = 1;
}
return val;
}
void RIG_TS990::set_notch(bool on, int val)
{
ts990debug("set_notch(bool on, int val)");
if (useB) {
if (on) {
cmd.assign("NT12;");
sendCommand(cmd);
showresp(INFO, ASC, "Set notch ON", cmd, "");
int bp = (int)(val * 127.0 / 3000);
if (bp == 0) bp = 1;
cmd.assign("BP1").append(to_decimal(bp, 3)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "set notch freq", cmd, "");
} else {
cmd.assign("NT10;");
sendCommand(cmd);
showresp(INFO, ASC, "Set notch OFF", cmd, "");
}
} else {
if (on) {
cmd.assign("NT02;");
sendCommand(cmd);
showresp(INFO, ASC, "Set notch ON", cmd, "");
int bp = (int)(val * 127.0 / 3000);
if (bp == 0) bp = 1;
cmd.assign("BP0").append(to_decimal(bp, 3)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "set notch freq", cmd, "");
} else {
cmd.assign("NT00;");
sendCommand(cmd);
showresp(INFO, ASC, "Set notch OFF", cmd, "");
}
}
}
//==============================================================================
// Notch setting
//==============================================================================
// response NTbn; NTbn; BPbnnn;
bool RIG_TS990::get_notch(int &val)
{
ts990debug("get_notch(int &val)");
if (useB) {
cmd = "NT1;";
if (wait_char(';', 5, TS990_WAIT, "get notch state", ASC) < 5) return 0;
size_t p = replystr.rfind("NT");
if (p == string::npos)
return 0;
if (replystr[p+3] == '2') {
cmd.assign("BP1;");
if (wait_char(';', 7, TS990_WAIT, "get notch freq", ASC) < 7) return 0;
size_t p = replystr.rfind("BP1");
if (p != string::npos)
val = (int)(fm_decimal(replystr.substr(p+3), 3) * 3000 / 127.0);
return 1;
}
return 0;
} else {
cmd = "NT0;";
if (wait_char(';', 5, TS990_WAIT, "get notch state", ASC) < 5) return 0;
size_t p = replystr.rfind("NT");
if (p == string::npos)
return 0;
if (replystr[p+3] == '2') {
cmd.assign("BP0;");
if (wait_char(';', 7, TS990_WAIT, "get notch freq", ASC) < 7) return 0;
size_t p = replystr.rfind("BP0");
if (p != string::npos)
val = (int)(fm_decimal(replystr.substr(p+3), 3) * 3000.0 / 127.0);
return 1;
}
return 0;
}
return 0;
}
void RIG_TS990::get_notch_min_max_step(int &min, int &max, int &step)
{
ts990debug("get_notch_min_max_step(int &min, int &max, int &step)");
min = 20;
max = 3000;
step = 10;
}
//==============================================================================
// IF shift controls are used for TX monitoring
// MON button turns TX monitor on/off
// Slider controls TX monitor level
void RIG_TS990::set_if_shift(int val)
{
ts990debug("set_monitor_level(int val)");
progStatus.shift_val = val;
val *= 255;
val /= 100;
cmd = "ML";
cmd.append(to_decimal(val,3)).append(";");
sendCommand(cmd);
showresp(INFO, ASC, "set Mon Level", cmd, "");
}
//response MLsss;
bool RIG_TS990::get_if_shift(int &val)
{
ts990debug("get_monitor_level(int &val)");
cmd = "ML;";
if (wait_char(';', 6, TS990_WAIT, "get Mon Level", ASC) == 6) {
size_t p = replystr.rfind("ML");
if (p != string::npos) {
val = fm_decimal(&replystr[p+2], 3);
val *= 100;
val /= 100;
}
}
bool on = false;
cmd = "MO0;";
if (wait_char(';', 5, TS990_WAIT, "get Tx Mon on/off", ASC) == 5) {
size_t p = replystr.rfind("MO");
if (p != string::npos)
on = (replystr[p+3] == '1');
}
return on;
}
void RIG_TS990::get_if_min_max_step(int &min, int &max, int &step)
{
ts990debug("get_mon_min_max_step(int &min, int &max, int &step)");
if_shift_min = min = 0;
if_shift_max = max = 100;
if_shift_step = step = 1;
if_shift_mid = 10;
}
void RIG_TS990::set_monitor( bool b)
{
ts990debug("set_monitor( bool b)");
if (b) {
cmd = "MO01;";
sendCommand(cmd);
showresp(INFO, ASC, "set Tx Monitor ON", cmd, "");
} else {
cmd = "MO00;";
sendCommand(cmd);
showresp(INFO, ASC, "set Tx Monitor OFF", cmd, "");
}
}
flrig-1.3.49/src/rigs/KX3.cxx 0000664 0001750 0001750 00000053230 13515325633 012533 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2014
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include "KX3.h"
#include "status.h"
const char KX3name_[] = "KX3";
const char *KX3modes_[] =
{ "LSB", "USB", "CW", "FM", "AM", "DATA", "CW-R", "DATA-R", NULL};
const char modenbr[] =
{ '1', '2', '3', '4', '5', '6', '7', '9' };
static const char KX3_mode_type[] =
{ 'L', 'U', 'L', 'U', 'U', 'U', 'U', 'L' };
static const char *KX3_widths[] = {
"50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
"550", "600", "650", "700", "750", "800", "850", "900", "950", "1000",
"1100", "1200", "1300", "1400", "1500", "1600", "1700", "1800", "1900", "2000",
"2200", "2400", "2600", "2800", "3000", "3200", "3400", "3600", "4000", NULL};
static int KX3_bw_vals[] = {
1, 2, 3, 4, 5, 6, 7, 8, 9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38, 39,40, WVALS_LIMIT};
static int def_mode_width[] = { 34, 34, 15, 37, 37, 34, 15, 34 };
static GUI k3_widgets[]= {
{ (Fl_Widget *)btnVol, 2, 125, 50 },
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 },
{ (Fl_Widget *)sldrRFGAIN, 54, 145, 156 },
{ (Fl_Widget *)btnIFsh, 214, 105, 50 },
{ (Fl_Widget *)sldrIFSHIFT, 266, 105, 156 },
{ (Fl_Widget *)sldrMICGAIN, 266, 125, 156 },
{ (Fl_Widget *)sldrPOWER, 266, 145, 156 },
{ (Fl_Widget *)NULL, 0, 0, 0 }
};
RIG_KX3::RIG_KX3() {
// base class values
name_ = KX3name_;
modes_ = KX3modes_;
bandwidths_ = KX3_widths;
bw_vals_ = KX3_bw_vals;
comm_baudrate = BR38400;
widgets = k3_widgets;
stopbits = 1;
comm_retries = 2;
comm_wait = 5;
comm_timeout = 50;
comm_rtscts = false;
comm_rtsplus = false;
comm_dtrplus = false;
comm_catptt = true;
comm_rtsptt = false;
comm_dtrptt = false;
def_freq = freqA = freqB = 14070000;
def_mode = modeA = modeB = 1;
def_bw = bwA = bwB = 34;
can_change_alt_vfo =
has_split_AB =
has_micgain_control =
has_rf_control =
has_bandwidth_control =
has_power_control =
has_volume_control =
has_mode_control =
has_ptt_control =
has_noise_control =
has_attenuator_control =
has_smeter =
has_power_out =
has_split =
has_ifshift_control =
has_preamp_control = true;
has_notch_control =
has_tune_control =
has_swr_control = false;
if_shift_min = 400;
if_shift_max = 2600;
if_shift_step = 10;
if_shift_mid = 1500;
precision = 1;
ndigits = 8;
progStatus.rfgain = 250;
}
int RIG_KX3::adjust_bandwidth(int m)
{
return def_mode_width[m];
}
int RIG_KX3::def_bandwidth(int m)
{
return def_mode_width[m];
}
extern int report_level;
void RIG_KX3::initialize()
{
debug::level = debug::INFO_LEVEL;
LOG_INFO("KX3");
k3_widgets[0].W = btnVol;
k3_widgets[1].W = sldrVOLUME;
k3_widgets[2].W = sldrRFGAIN;
k3_widgets[3].W = btnIFsh;
k3_widgets[4].W = sldrIFSHIFT;
k3_widgets[5].W = sldrMICGAIN;
k3_widgets[6].W = sldrPOWER;
report_level = INFO;
cmd = "AI0;"; // disable auto-info
sendCommand(cmd);
showresp(INFO, ASC, "disable auto-info", cmd, replystr);
sett("disable auto info");
cmd = "K31;"; // KX3 extended mode
sendCommand(cmd);
showresp(INFO, ASC, "KX3 extended mode", cmd, replystr);
sett("KX3 extended mode");
get_vfoA();
get_modeA();
get_bwA();
get_vfoB();
get_modeB();
get_bwB();
set_split(false); // normal ops
}
void RIG_KX3::shutdown()
{
}
bool RIG_KX3::check ()
{
cmd = "FA;";
int ret = wait_char(';', 14, KX3_WAIT_TIME, "check", ASC);
gett("vfo check");
if (ret < 14) return false;
return true;
}
long RIG_KX3::get_vfoA ()
{
cmd = "FA;";
int ret = wait_char(';', 14, KX3_WAIT_TIME, "get vfo A", ASC);
gett("get vfoA");
if (ret < 14) return freqA;
size_t p = replystr.rfind("FA");
if (p == string::npos) return freqA;
long f = 0;
for (size_t n = 2; n < 13; n++)
f = f*10 + replystr[p + n] - '0';
freqA = f;
return freqA;
}
void RIG_KX3::set_vfoA (long freq)
{
freqA = freq;
cmd = "FA00000000000;";
for (int i = 12; i > 1; i--) {
cmd[i] += freq % 10;
freq /= 10;
}
sendCommand(cmd);
showresp(INFO, ASC, "set vfo A", cmd, replystr);
sett("set vfoA");
}
long RIG_KX3::get_vfoB ()
{
cmd = "FB;";
int ret = wait_char(';', 14, KX3_WAIT_TIME, "get vfo B", ASC);
gett("get vfoB");
if (ret < 14) return freqB;
size_t p = replystr.rfind("FB");
if (p == string::npos) return freqB;
long f = 0;
for (size_t n = 2; n < 13; n++)
f = f*10 + replystr[p + n] - '0';
freqB = f;
return freqB;
}
void RIG_KX3::set_vfoB (long freq)
{
if (split_on == false) {
LOG_INFO("split on");
return;
}
freqB = freq;
cmd = "FB00000000000;";
for (int i = 12; i > 1; i--) {
cmd[i] += freq % 10;
freq /= 10;
}
sendCommand(cmd);
showresp(INFO, ASC, "set vfo B", cmd, replystr);
sett("set vfoB");
}
// Volume control
void RIG_KX3::set_volume_control(int val)
{
int ivol = (int)(val * 2.55);
cmd = "AG000;";
for (int i = 4; i > 1; i--) {
cmd[i] += ivol % 10;
ivol /= 10;
}
sendCommand(cmd);
showresp(INFO, ASC, "set vol", cmd, replystr);
sett("set volume control");
}
int RIG_KX3::get_volume_control()
{
cmd = "AG;";
int ret = wait_char(';', 6, KX3_WAIT_TIME, "get volume", ASC);
gett("get volume control");
if (ret < 6) return progStatus.volume;
size_t p = replystr.rfind("AG");
if (p == string::npos) return 0;
replystr[p + 5] = 0;
int v = atoi(&replystr[p + 2]);
return (int)(v / 2.55);
}
void RIG_KX3::set_pbt_values(int val)
{
switch (val) {
case 0 :
case 1 :
case 3 :
case 4 :
if_shift_min = 400; if_shift_max = 2600;
if_shift_step = 10; if_shift_mid = 1500;
break;
case 2 :
case 6 :
if_shift_min = 300; if_shift_max = 1300;
if_shift_step = 10; if_shift_mid = 800;
break;
case 5 :
case 7 :
if_shift_min = 100; if_shift_max = 2100;
if_shift_step = 10; if_shift_mid = 1000;
break;
}
progStatus.shift_val = if_shift_mid;
Fl::awake(adjust_if_shift_control, (void *)0);
}
/*
* MD $ (Operating Mode; GET/SET)
* SET/RSP format: MDn; or MD$n;
* where n is
* 1 (LSB),
* 2 (USB),
* 3 (CW),
* 4 (FM),
* 5 (AM),
* 6 (DATA),
* 7 (CW-REV),
* 9 (DATA-REV).
* Notes:
* (1) K3 only: In Diversity Mode (accessed by holding SUB), sending MDn;
* sets both main and sub mode to n.
* (2) DATA and DATA-REV select the data sub-mode that was last in effect
* on the present band. (To read/set data sub-mode, use DT.)
* The norm/rev conditions for the K3’s data sub-modes are
* handled in two pairs at present:
* DATA A/PSK D, and
* AFSK A/FSK D.
* E.g., if the radio is set up for DATA A mode, alternating between
* MD6 and MD9 will cause both DATA A and PSK D to be set to the
* same normal/reverse condition.
* In K2 command modes 1 and 3 (K21 and K23), the RSP message converts
* modes 6 and 7 (DATA and DATA-REV) to modes 1 and 2 (LSB and USB).
* This may be useful with existing software applications that don't
* handle DATA modes correctly.
*/
/* The DT command needs to be included for get/set mode
*
* DT (DATA Sub-Mode; GET/SET)
* SET/RSP format: DTn; where n is the data sub-mode last used with VFO A,
* whether or not DATA mode is in effect:
* 0 (DATA A),
* 1 (AFSK A),
* 2 (FSK D),
* 3 (PSK D). See MD for data normal/reverse considerations.
* In Diversity Mode (K3 only, accessed by sending DV1 or via a long hold
* of SUB), sending DTn matches the sub receiver’s mode to the main receiver’s.
* Notes:
* (1) Use DT only when the transceiver is in DATA mode; otherwise,
* the returned value may not be valid.
* (2) In AI2/3 modes, changing the data sub-mode results in both FW
* and IS responses.
* (3) The present data sub-mode is also reported as part of the IF command,
* although this requires that K31 be in effect. Refer to the IF command
* for details.
*/
/* and last but not least, the IF command
*
* IF (Transceiver Information; GET only)
* RSP format: IF[f]*****+yyyyrx*00tmvspbd1*;
* where the fields are defined as follows:
* [f] Operating frequency, excluding any RIT/XIT offset
* (11 digits; see FA command format)
* * represents a space (BLANK, or ASCII 0x20)
* + either "+" or "-" (sign of RIT/XIT offset)
* yyyy RIT/XIT offset in Hz (range is -9999 to +9999 Hz when
* computer-controlled)
* r 1 if RIT is on, 0 if off
* x 1 if XIT is on, 0 if off
* t 1 if the K3 is in transmit mode, 0 if receive
* m operating mode (see MD command)
* v receive-mode VFO selection, 0 for VFO A, 1 for VFO B
* s 1 if scan is in progress, 0 otherwise
* p 1 if the transceiver is in split mode, 0 otherwise
* b Basic RSP format: always 0;
* K2 Extended RSP format (K22):
* 1 if present IF response is due to a band change; 0 otherwise
* d Basic RSP format: always 0;
* K3 Extended RSP format (K31):
* 1 DATA sub-mode, if applicable
* (0=DATA A, 1=AFSK A, 2= FSK D, 3=PSK D)
* The fixed-value fields (space, 0, and 1) are provided for syntactic
* compatibility with existing software.
*
* 01234567890123456789012345678901234567
* 0 1 2 3 7
* IF00014070000*****+yyyyrx*00tmvspbd1*;
* |---------| |
* vfo a/b split on = '1', off = '0'
* IF00014070000 -000000 0002000011 ; OFF
* IF00014070000 -000000 0002001011 ; ON
*/
void RIG_KX3::set_modeA(int val)
{
modeA = val;
cmd = "MD0;";
cmd[2] = modenbr[val];
sendCommand(cmd);
showresp(INFO, ASC, "set mode A", cmd, replystr);
set_pbt_values(val);
sett("set modeA");
}
int RIG_KX3::get_modeA()
{
cmd = "MD;";
int ret = wait_char(';', 4, KX3_WAIT_TIME, "get mode A", ASC);
gett("get modeA");
if (ret < 4) return modeA;
size_t p = replystr.rfind("MD");
if (p == string::npos) return modeA;
int md = replystr[p + 2] - '1';
if (md == 8) md--;
if (md != modeA) set_pbt_values(md);
return (modeA = md);
}
void RIG_KX3::set_modeB(int val)
{
if (split_on == false) {
LOG_INFO("split on");
return;
}
modeB = val;
cmd = "MD$0;";
cmd[3] = modenbr[val];
sendCommand(cmd);
showresp(INFO, ASC, "set mode B", cmd, replystr);
set_pbt_values(val);
sett("set modeB");
}
int RIG_KX3::get_modeB()
{
cmd = "MD$;";
int ret = wait_char(';', 4, KX3_WAIT_TIME, "get mode B", ASC);
gett("get modeB");
if (ret < 4) return modeB;
size_t p = replystr.rfind("MD$");
if (p == string::npos) return modeB;
int md = replystr[p + 3] - '1';
if (md == 8) md--;
if (md != modeB) set_pbt_values(md);
return (modeB = md);
}
int RIG_KX3::get_modetype(int n)
{
return KX3_mode_type[n];
}
void RIG_KX3::set_preamp(int val)
{
if (val) sendCommand("PA1;", 0);
else sendCommand("PA0;", 0);
sett("set preamp");
}
int RIG_KX3::get_preamp()
{
cmd = "PA;";
int ret = wait_char(';', 4, KX3_WAIT_TIME, "get preamp", ASC);
gett("get preamp");
if (ret < 4) return progStatus.preamp;
size_t p = replystr.rfind("PA");
if (p == string::npos) return 0;
return (replystr[p + 2] == '1' ? 1 : 0);
}
//
void RIG_KX3::set_attenuator(int val)
{
if (val) sendCommand("RA01;", 0);
else sendCommand("RA00;", 0);
sett("set attenuator");
}
int RIG_KX3::get_attenuator()
{
cmd = "RA;";
int ret = wait_char(';', 5, KX3_WAIT_TIME, "set ATT", ASC);
gett("get attenuator");
if (ret < 5) return progStatus.attenuator;
size_t p = replystr.rfind("RA");
if (p == string::npos) return 0;
return (replystr[p + 3] == '1' ? 1 : 0);
}
/*
* PC (Requested Power Output Level; GET/SET)
*
* Basic SET/RSP format: PCnnn; For the K3, nnn is 000-012 or 000-110 watts depending on the power range.
*
* If CONFIG:KXV3 is set to TEST or if a transverter band with low-level I/O is selected, then the unit
* is hundreds of a milliwatt, and the available range is 0.00-1.50 mW.
*
* This can be checked using the IC command, byte a, bit 4.
*
*/
void RIG_KX3::get_pc_min_max_step(double &min, double &max, double &step)
{
min = 0; max = 100; step = 1;
}
void RIG_KX3::set_power_control(double val)
{
int ival = val;
cmd = "PC000;";
for (int i = 4; i > 1; i--) {
cmd[i] += ival % 10;
ival /= 10;
}
sendCommand(cmd);
showresp(INFO, ASC, "set power ctrl", cmd, replystr);
sett("set power control");
}
int RIG_KX3::get_power_control()
{
cmd = "PC;";
int ret = wait_char(';', 6, KX3_WAIT_TIME, "get power level", ASC);
gett("get power control");
if (ret < 6) return progStatus.power_level;
size_t p = replystr.rfind("PC");
if (p == string::npos) return progStatus.power_level;
return fm_decimal(replystr.substr(p+2), 3);
}
/*
* PO ** (Actual Power Output Level; GET only; KX3 only)
*
* RSP format: PCnnn;
* where nnn is the power in tenths of a watt (QRP mode) or watts (QRO mode).
*
* Note: The QRO case only applies if the KXPA100 amplifier enabled via PA MODE=ON,
* is connected to the KX3 via the special control cable, and the PWR level is set
* to 11 W or higher. The reading is approximate, * as it is estimated from the
* KX3’s drive level. For a more accurate reading, use the KXPA100’s “^PF;†command.
*/
bool RIG_KX3::power_10x()
{
return power10x;
}
int RIG_KX3::get_power_out()
{
// test for KXPA100 presence
cmd = "^OP;";
int ret = 0;
size_t p = 0;
int mtr = 0;
ret = wait_char(';', 5, KX3_WAIT_TIME, "test KXPA", ASC);
gett("test KXPA");
if (ret >= 4) {
power10x = false;
if (replystr.find("^OP1;") != string::npos) {
cmd = "^PF;";
ret = wait_char(';', 8, KX3_WAIT_TIME, "get KXPA power out", ASC);
if (ret >= 8) {
p = replystr.rfind("^PF");
if (p == string::npos) return 0;
replystr[p + 7] = 0;
mtr = atoi(&replystr[p+3]);
if (mtr > 0) return mtr/10;
}
}
}
cmd = "PO;";
ret = wait_char(';', 6, KX3_WAIT_TIME, "get power out", ASC);
gett("get power out");
if (ret < 6) return 0;
p = replystr.rfind("PO");
if (p == string::npos) return 0;
replystr[p + 5] = 0;
mtr = atoi(&replystr[p + 2]);
power10x = true; // scales to 0 to 120 W
return mtr;
}
// Transceiver rf control
void RIG_KX3::set_rf_gain(int val)
{
int ival = val;
cmd = "RG000;";
for (int i = 4; i > 1; i--) {
cmd[i] += ival % 10;
ival /= 10;
}
sendCommand(cmd);
showresp(INFO, ASC, "set rfgain ctrl", cmd, replystr);
sett("set rf gain");
}
int RIG_KX3::get_rf_gain()
{
cmd = "RG;";
int ret = wait_char(';', 6, KX3_WAIT_TIME, "get RF gain", ASC);
gett("get rf gain");
if (ret < 6) return progStatus.rfgain;
size_t p = replystr.rfind("RG");
if (p == string::npos) return progStatus.rfgain;
replystr[p + 5] = 0;
int v = atoi(&replystr[p + 2]);
return v;
}
void RIG_KX3::get_rf_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 250; step = 1;
}
// Transceiver mic control
void RIG_KX3::set_mic_gain(int val)
{
int ival = (int)val;
cmd = "MG000;";
for (int i = 4; i > 1; i--) {
cmd[i] += ival % 10;
ival /= 10;
}
sendCommand(cmd);
showresp(INFO, ASC, "set mic ctrl", cmd, replystr);
sett("set mic gain");
}
int RIG_KX3::get_mic_gain()
{
cmd = "MG;";
int ret = wait_char(';', 6, KX3_WAIT_TIME, "get MIC gain", ASC);
gett("get mic gain");
if (ret < 6) return progStatus.mic_gain;
size_t p = replystr.rfind("MG");
if (p == string::npos) return progStatus.mic_gain;
replystr[p + 5] = 0;
int v = atoi(&replystr[p + 2]);
return v;
}
void RIG_KX3::get_mic_min_max_step(int &min, int &max, int &step)
{
min = 0; max = 60; step = 1;
}
// Tranceiver PTT on/off
void RIG_KX3::set_PTT_control(int val)
{
if (val) sendCommand("TX;", 0);
else sendCommand("RX;", 0);
ptt_ = val;
sett("set PTT");
}
// BG (Bargraph Read; GET only)
// RSP format: BGnn; where is 00 (no bars) through 10 (bar 10) if the
// bargraph is in DOT mode, and 12 (no bars) through 22 (all 10 bars) if
// the bargraph is in BAR mode. Reads the S-meter level on receive. Reads
// the power output level or ALC level on transmit, depending on the RF/ALC
// selection. Also see SM/SM$ command, which can read either main or sub RX
// S-meter level.
// SM SM$ (S-meter Read; GET only)
// Basic RSP format: SMnnnn; where nnnn is 0000-0015.
// S9=6; S9+20=9; S9+40=12; S9+60=15.
// KX3 Extended RSP format (KX31): nnnn is 0000-0021.
// S9=9; S9+20=13; S9+40=17; S9+60=21.
// This command can be used to obtain either the main (SM) or sub (SM$)
// S-meter readings. Returns 0000 in transmit mode. BG can be used to
// simply emulate the bar graph level, and applies to either RX or TX mode.
int RIG_KX3::get_smeter()
{
cmd = "SM;";
int ret = wait_char(';', 7, KX3_WAIT_TIME, "get Smeter", ASC);
gett("get smeter");
if (ret < 7) return 0;
size_t p = replystr.rfind("SM");
if (p == string::npos) return 0;
int mtr = fm_decimal(replystr.substr(p+2), 4);
if (mtr <= 6) mtr = (int) (50.0 * mtr / 6.0);
else mtr = (int)(50 + (mtr - 6.0) * 50.0 / 9.0);
return mtr;
}
void RIG_KX3::set_noise(bool on)
{
if (on) sendCommand("NB1;", 0);
else sendCommand("NB0;", 0);
sett("set noise blanker");
}
int RIG_KX3::get_noise()
{
cmd = "NB;";
int ret = wait_char(';', 4, KX3_WAIT_TIME, "get Noise Blanker", ASC);
gett("get noise blanker");
if (ret < 4) return progStatus.noise;
size_t p = replystr.rfind("NB");
if (p == string::npos) return progStatus.noise;
return (replystr[p+2] == '1' ? 1 : 0);
}
// BW $ (Filter Bandwidth and Number; GET/SET)
// KX3 Extended SET/RSP format (K31): BWxxxx; where xxxx is 0-9999, the bandwidth in 10-Hz units. May be
// quantized and/or range limited based on the present operating mode.
void RIG_KX3::set_bwA(int val)
{
cmd = "BW0000;";
bwA = val;
val = atoi(KX3_widths[val]);
val /= 10; cmd[5] += val % 10;
val /= 10; cmd[4] += val % 10;
val /= 10; cmd[3] += val % 10;
val /= 10; cmd[2] += val % 10;
sendCommand(cmd);
showresp(INFO, ASC, "set bw A", cmd, replystr);
sett("set bwA");
}
int RIG_KX3::get_bwA()
{
cmd = "BW;";
int ret = wait_char(';', 7, KX3_WAIT_TIME, "get bandwidth A", ASC);
gett("get bwA");
if (ret < 7) return bwA;
size_t p = replystr.rfind("FW");
if (p == string::npos) return bwA;
int bw = 0;
for (int i = 2; i < 6; i++) bw = bw * 10 + replystr[p+i] - '0';
bw *= 10;
for (bwA = 0; bwA < 36; bwA++)
if (bw <= atoi(KX3_widths[bwA])) break;
return bwA;
}
void RIG_KX3::set_bwB(int val)
{
if (split_on == false) {
LOG_INFO("split on");
return;
}
cmd = "BW$0000;";
bwA = val;
val = atoi(KX3_widths[val]);
val /= 10; cmd[6] += val % 10;
val /= 10; cmd[5] += val % 10;
val /= 10; cmd[4] += val % 10;
val /= 10; cmd[3] += val % 10;
sendCommand(cmd);
showresp(INFO, ASC, "set bw B", cmd, replystr);
sett("set bwB");
}
int RIG_KX3::get_bwB()
{
cmd = "BW$;";
int ret = wait_char(';', 8, KX3_WAIT_TIME, "get bandwidth B", ASC);
gett("get bwB");
if (ret < 8) return bwB;
size_t p = replystr.rfind("FW$");
if (p == string::npos) return bwB;
int bw = 0;
for (int i = 3; i < 7; i++) bw = bw * 10 + replystr[p+i] - '0';
bw *= 10;
for (bwB = 0; bwB < 36; bwB++)
if (bw <= atoi(KX3_widths[bwB])) break;
return bwB;
}
bool RIG_KX3::can_split()
{
return true;
}
void RIG_KX3::set_split(bool val)
{
if (val) {
cmd = "FT1;";
sendCommand(cmd);
showresp(INFO, ASC, "set split ON", cmd, replystr);
sett("set split ON");
} else {
cmd = "FR0;";
sendCommand(cmd);
showresp(INFO, ASC, "set split OFF", cmd, replystr);
sett("set split OFF");
}
split_on = val;
}
// 01234567890123456789012345678901234567
// 0 1 2 3 7
// IF00014070000*****+yyyyrx*00tmvspbd1*;
// |---------| |
// vfo a/b split on = '1', off = '0'
// IF00014070000 -000000 0002000011 ; OFF
// IF00014070000 -000000 0002001011 ; ON
int RIG_KX3::get_split()
{
cmd = "IF;";
int ret = wait_char(';', 38, KX3_WAIT_TIME, "get split", ASC);
gett("get split");
if (ret < 38) return split_on;
size_t p = replystr.rfind("IF");
if (p == string::npos) return split_on;
split_on = replystr[p+32] - '0';
return split_on;
}
void RIG_KX3::set_if_shift(int val)
{
cmd = "IS 0000;";
cmd[6] += val % 10; val /= 10;
cmd[5] += val % 10; val /= 10;
cmd[4] += val % 10; val /= 10;
cmd[3] += val % 10;
sendCommand(cmd);
showresp(INFO, ASC, "set if shift", cmd, replystr);
sett("set if shift");
}
bool RIG_KX3::get_if_shift(int &val)
{
cmd = "IS;";
int ret = wait_char(';', 8, KX3_WAIT_TIME, "get IF shift", ASC);
gett("get if shift");
val = progStatus.shift_val;
if (ret < 8) return progStatus.shift;
size_t p = replystr.rfind("IS ");
if (p == string::npos) return progStatus.shift;
sscanf(&replystr[p + 3], "%d", &progStatus.shift_val);
val = progStatus.shift_val;
if (val == if_shift_mid) progStatus.shift = false;
else progStatus.shift = true;
return progStatus.shift;
}
void RIG_KX3::get_if_min_max_step(int &min, int &max, int &step)
{
min = if_shift_min; max = if_shift_max; step = if_shift_step;
}
void RIG_KX3::get_if_mid()
{
cmd = "IS 9999;";
sendCommand(cmd);
waitResponse(500);
showresp(INFO, ASC, "center pbt", cmd, replystr);
sett("set center pbt");
cmd = "IS;";
int ret = wait_char(';', 8, KX3_WAIT_TIME, "get PBT center", ASC);
gett("get center pbt");
if (ret < 8) return;
size_t p = replystr.rfind("IS ");
if (p == string::npos) return;
sscanf(&replystr[p + 3], "%d", &if_shift_mid);
}
flrig-1.3.49/src/rigs/IC7610.cxx 0000664 0001750 0001750 00000142157 13501240707 012737 0000000 0000000 // ----------------------------------------------------------------------------
// Copyright (C) 2018
// David Freese, W1HKJ
//
// This file is part of flrig.
//
// flrig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// flrig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// ----------------------------------------------------------------------------
#include
#include