2
* TenTec Jupiter (TT538) drivers
6
* Copyright 2009, Dave Freese, W1HKJ
11
* Note for anyone wishing to expand on the command set.
13
* The Jupiter always sends a response and ends the response with a "G\r" to
14
* indicate that the command was accepted. A rejected command is responded to by a
15
* two character sequence "Z\r". You should always expect a maximum response equal
16
* to the number of data bytes plus two.
19
* A request for the present receiver filter bandwidth is the the string:
20
* "?W\r" which is 3 bytes in length
21
* The response from the Argonaut V will be:
22
* "Wn\rG\r" which is 5 bytes in length, where n is an unsigned char (byte)
23
* If the transceiver failed to receive the command correctly it will respond:
24
* "Z\r" ----> you need to check for that condition
32
static const char TT538name_[] = "TT-538";
34
//static const char *TT538modes_[] = { "D-USB", "USB", "LSB", "CW", "AM", "FM", NULL}
35
//static const char TT538mode_chr[] = { '1', '1', '2', '3', '0', '4' };
36
//static const char TT538mode_type[] = { 'U', 'U', 'L', 'L', 'U', 'U' };
37
static const char *TT538modes_[] = {
38
"AM", "USB", "LSB", "CW", "FM", NULL};
39
static const char TT538mode_chr[] = { '0', '1', '2', '3', '4' };
40
static const char TT538mode_type[] = { 'U', 'U', 'L', 'U', 'U' };
42
// filter # is 38 - index
43
static const char *TT538_widths[] = {
44
"150", "165", "180", "225", "260", "300", "330", "375", "450", "525",
45
"600", "675", "750", "900", "1050", "1200", "1350", "1500", "1650", "1800",
46
"1950", "2100", "2250", "2400", "2550", "2700", "2850", "3000", "3300", "3600",
47
"3900", "4200", "4500", "4800", "5100", "5400", "5700", "6000", "8000", NULL};
49
static const int TT538_numeric_widths[] = {
50
150, 165, 180, 225, 260, 300, 330, 375, 450, 525,
51
600, 675, 750, 900, 1050, 1200, 1350, 1500, 1650, 1800,
52
1950, 2100, 2250, 2400, 2550, 2700, 2850, 3000, 3300, 3600,
53
3900, 4200, 4500, 4800, 5100, 5400, 5700, 6000, 8000};
56
static char TT538setFREQA[] = "*Annnn\r";
57
//static char TT538setFREQB[] = "*Bnnnn\r";
58
//static char TT538setAGC[] = "*Gn\r";
59
//static char TT538setSQLCH[] = "*Hc\r";
60
static char TT538setRF[] = "*Ic\r";
61
static char TT538setATT[] = "*Jc\r";
62
//static char TT538setNB[] = "*Knar\r";
63
static char TT538setMODE[] = "*Mnn\r";
64
static char TT538setPBT[] = "*Pxx\r";
65
static char TT538setVOL[] = "*Un\r";
66
static char TT538setBW[] = "*Wx\r";
68
static char TT538getFREQA[] = "?A\r";
69
//static char TT538getFREQB[] = "?B\r";
70
//static char TT538getFWDPWR[] = "?F\r";
71
//static char TT538getAGC[] = "?G\r";
72
//static char TT538getSQLCH[] = "?H\r";
73
//static char TT538getRF[] = "?I\r";
74
static char TT538getATT[] = "?J\r";
75
//static char TT538getNB[] = "?K\r";
76
static char TT538getMODE[] = "?M\r";
77
static char TT538getPBT[] = "?P\r";
78
static char TT538getSMETER[] = "?S\r";
79
static char TT538getVOL[] = "?U\r";
80
static char TT538getBW[] = "?W\r";
82
//static char TT538getREFPWR[] = "?R\r";
83
//static char TT538setXMT[] = "#1\r";
84
//static char TT538setRCV[] = "#0\r";
86
static char TT538setXMT[] = "Q1\r";
87
static char TT538setRCV[] = "Q0\r";
89
static GUI rig_widgets[]= {
90
{ (Fl_Widget *)btnVol, 2, 125, 50 },
91
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 },
92
{ (Fl_Widget *)sldrRFGAIN, 266, 125, 156 },
93
{ (Fl_Widget *)btnIFsh, 214, 105, 50 },
94
{ (Fl_Widget *)sldrIFSHIFT, 266, 105, 156 },
95
{ (Fl_Widget *)NULL, 0, 0, 0 }
98
RIG_TT538::RIG_TT538() {
101
modes_ = TT538modes_;
102
bandwidths_ = TT538_widths;
104
widgets = rig_widgets;
106
comm_baudrate = BR57600;
112
comm_rtsplus = false;
114
comm_catptt = true;// false;
117
serloop_timing = 200;
119
def_mode = modeB = modeA = 1;
120
def_bw = bwB = bwA = 25;
121
def_freq = freqB = freqA = 14070000;
125
VfoAdj = progStatus.vfo_adj;
128
has_micgain_control =
132
has_noise_control = false;
140
has_attenuator_control =
141
has_ifshift_control =
143
has_bandwidth_control =
152
//static int corrA = 0, corrB = 0;
154
void RIG_TT538::checkresponse(string s)
156
if (RigSerial.IsOpen() == false)
158
string s1 = str2hex(cmd.c_str(), cmd.length());
159
string s2 = str2hex(replystr.c_str(), replystr.length());
160
LOG_ERROR("%s:\nsent %s\nreply %s\n", s.c_str(), s1.c_str(), s2.c_str());
163
void RIG_TT538::initialize()
165
rig_widgets[0].W = btnVol;
166
rig_widgets[1].W = sldrVOLUME;
167
rig_widgets[2].W = sldrRFGAIN;
168
rig_widgets[3].W = btnIFsh;
169
rig_widgets[4].W = sldrIFSHIFT;
171
VfoAdj = progStatus.vfo_adj;
172
fwdpwr = refpwr = 0.0;
175
void RIG_TT538::shutdown()
180
long RIG_TT538::get_vfoA ()
183
int ret = sendCommand(cmd);
184
if (ret < 6) return (long)(freqA / (1 + VfoAdj/1e6) + 0.5);
185
size_t p = replystr.rfind("A");
186
if (p == string::npos) return (long)(freqA / (1 + VfoAdj/1e6) + 0.5);
189
for (size_t n = 1; n < 5; n++)
190
f = f*256 + (unsigned char)replystr[p + n];
193
return (long)(freqA / (1 + VfoAdj/1e6) + 0.5);
196
void RIG_TT538::set_vfoA (long freq)
199
long xfreq = freqA * (1 + VfoAdj/1e6) + 0.5;
201
cmd[5] = xfreq & 0xff; xfreq = xfreq >> 8;
202
cmd[4] = xfreq & 0xff; xfreq = xfreq >> 8;
203
cmd[3] = xfreq & 0xff; xfreq = xfreq >> 8;
204
cmd[2] = xfreq & 0xff;
210
long RIG_TT538::get_vfoB ()
212
// cmd = TT538getFREQB;
214
int ret = sendCommand(cmd);
215
if (ret < 6) return (long)(freqB / (1 + VfoAdj/1e6) + 0.5);
216
size_t p = replystr.rfind("B");
217
if (p == string::npos) return (long)(freqB / (1 + VfoAdj/1e6) + 0.5);
220
for (size_t n = 1; n < 5; n++)
221
f = f*256 + (unsigned char)replystr[p + n];
224
return (long)(freqB / (1 + VfoAdj/1e6) + 0.5);
227
void RIG_TT538::set_vfoB (long freq)
230
long xfreq = freqB * (1 + VfoAdj/1e6) + 0.5;
231
// cmd = TT538setFREQB;
233
cmd[5] = xfreq & 0xff; xfreq = xfreq >> 8;
234
cmd[4] = xfreq & 0xff; xfreq = xfreq >> 8;
235
cmd[3] = xfreq & 0xff; xfreq = xfreq >> 8;
236
cmd[2] = xfreq & 0xff;
242
void RIG_TT538::setVfoAdj(double v)
247
void RIG_TT538::set_modeA(int val)
251
cmd[2] = TT538mode_chr[val];
256
int RIG_TT538::get_modeA()
259
int ret = sendCommand(cmd);
260
if (ret < 4) return modeA;
261
size_t p = replystr.rfind("M");
262
if (p == string::npos) return modeA;
263
modeA = replystr[p+1] - '0';
267
int RIG_TT538::get_modetype(int n)
269
return TT538mode_type[n];
272
void RIG_TT538::set_bwA(int val)
281
int RIG_TT538::get_bwA()
284
int ret = sendCommand(cmd);
285
if (ret < 3) return bwA;
286
size_t p = replystr.rfind("W");
287
if (p == string::npos) return bwA;
288
bwA = 38 - (unsigned char)replystr[p + 1];
292
int RIG_TT538::adjust_bandwidth(int m)
294
if (m == 0) return 37;
295
if (m == 1 || m == 2) return 27;
296
if (m == 3) return 10;
297
if (m == 4) return 27;
301
void RIG_TT538::set_if_shift(int val)
305
int bpval = progStatus.bpf_center - 200 - TT538_numeric_widths[bwA]/2;
307
if ((modeA == 1 || modeA == 2) && progStatus.use_bpf_center)
308
si += (bpval > 0 ? bpval : 0);
309
cmd[2] = (si & 0xff00) >> 8;
310
cmd[3] = (si & 0xff);
312
int ret = sendCommand(TT538getPBT);
314
size_t p = replystr.rfind("P");
315
if (p == string::npos) return;
316
if (replystr[p+1] != cmd[2] || replystr[p+2] != cmd[3]) {
321
bool RIG_TT538::get_if_shift(int &val)
324
// cmd = TT538getPBT;
325
// sendCommand(cmd, 0);
329
void RIG_TT538::get_if_min_max_step(int &min, int &max, int &step)
336
void RIG_TT538::set_attenuator(int val)
339
if (val) cmd[2] = '1';
345
int RIG_TT538::get_attenuator()
348
int ret = sendCommand(cmd);
349
if (ret < 3) return 0;
350
size_t p = replystr.rfind("J");
351
if (p == string::npos) return 0;
352
if (replystr[p+1] == '1')
357
int RIG_TT538::get_smeter()
360
cmd = TT538getSMETER;
361
int ret = sendCommand(cmd);
362
if (ret < 6) return 0;
363
size_t p = replystr.rfind("S");
364
if (p == string::npos) return 0;
368
sscanf(&replystr[p+1], "%4x", &sval);
371
return (int)(sig * 50.0 / 9.0);
374
static int gaintable[] = {
375
0, 2, 3, 4, 6, 7, 8, 9, 11, 12,
376
13, 14, 16, 17, 18, 19, 21, 22, 23, 24,
377
26, 27, 28, 30, 31, 32, 33, 35, 36, 37,
378
38, 40, 41, 42, 43, 45, 46, 47, 48, 50,
379
51, 52, 53, 55, 56, 57, 58, 60, 61, 62,
380
64, 65, 66, 68, 69, 70, 71, 72, 74, 75,
381
76, 77, 79, 80, 81, 82, 84, 85, 86, 88,
382
89, 90, 91, 92, 94, 95, 96, 98, 99, 100,
383
101, 103, 104, 105, 107, 108, 109, 110, 111, 113,
384
114, 115, 117, 118, 119, 120, 121, 123, 127, 125, 127 };
386
static int pot2val(int n)
389
for (i = 0; i < 100; i++)
390
if (gaintable[i] >= n) break;
394
static int val2pot(int n)
399
int RIG_TT538::get_volume_control()
402
int ret = sendCommand(cmd);
403
if (ret < 3) return 0;
404
size_t p = replystr.rfind("U");
405
if (p == string::npos) return 0;
407
return pot2val(replystr[p+1] & 0x7F);
410
void RIG_TT538::set_volume_control(int vol)
413
cmd[2] = val2pot(vol);
417
void RIG_TT538::set_rf_gain(int val)
420
cmd[2] = val2pot(val);
424
int RIG_TT538::get_rf_gain()
427
// sendCommand(cmd, 3, true);
430
// Jupiter does not reply with values as specified in the programmers manual
431
// Panel RF gain 0..50% replies with 80H..00H
432
// Panel RF gain 50..100% replies with 00H
435
// Tranceiver PTT on/off
436
void RIG_TT538::set_PTT_control(int val)
438
if (val) sendCommand(TT538setXMT);
439
else sendCommand(TT538setRCV);
442
int RIG_TT538::get_power_out()
444
int ret = sendCommand("?S\r"); // same as get smeter in receive
445
if (ret < 4) return fwdpwr;
446
size_t p = replystr.rfind("T");
447
if (p == string::npos) return fwdpwr;
449
fwdpwr = 0.8*fwdpwr + 0.2*(unsigned char)replystr[p+1];
450
refpwr = 0.8*refpwr + 0.2*(unsigned char)replystr[p+2];
452
LOG_INFO("%s // %4.1f : %4.1f", str2hex(replystr.c_str(), replystr.length()), fwdpwr, refpwr);
456
int RIG_TT538::get_swr()
459
if (fwdpwr == 0) return 0;
460
if (fwdpwr == refpwr) return 100;
461
nu = sqrt(refpwr / fwdpwr);
462
swr = (1 + nu) / (1 - nu) - 1.0;
464
if (swr < 0) swr = 0;
465
if (swr > 100) swr = 100;
466
LOG_INFO("swr %4.2f", swr);