1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2014
3 // David Freese, W1HKJ
4 //
5 // This file is part of flrig.
6 //
7 // flrig is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // flrig is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // aunsigned long int with this program. If not, see <http://www.gnu.org/licenses/>.
19 // ----------------------------------------------------------------------------
20
21 #include "TS480SAT.h"
22 #include "support.h"
23
24 static const char TS480SATname_[] = "TS-480SAT";
25
26 static const char *TS480SATmodes_[] = {
27 "LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "FSK-R", NULL};
28 static const char TS480SAT_mode_chr[] = { '1', '2', '3', '4', '5', '6', '7', '9' };
29 static const char TS480SAT_mode_type[] = { 'L', 'U', 'U', 'U', 'U', 'L', 'L', 'U' };
30
31 static const char *TS480SAT_empty[] = { "N/A", NULL };
32 static int TS480SAT_bw_vals[] = {1, WVALS_LIMIT};
33
34 // SL command is lo cut when menu 045 OFF
35 static const char *TS480SAT_SL[] = {
36 "0", "50", "100", "200", "300",
37 "400", "500", "600", "700", "800",
38 "900", "1000", NULL };
39 static const char *TS480SAT_SL_tooltip = "lo cut";
40 static const char *TS480SAT_btn_SL_label = "L";
41
42 // SH command is hi cut when menu 045 OFF
43 static const char *TS480SAT_SH[] = {
44 "1000", "1200", "1400", "1600", "1800",
45 "2000", "2200", "2400", "2600", "2800",
46 "3000", "3400", "4000", "5000", NULL };
47 static int TS480SAT_HI_bw_vals[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,WVALS_LIMIT};
48
49 static const char *TS480SAT_SH_tooltip = "hi cut";
50 static const char *TS480SAT_btn_SH_label = "H";
51
52 // SL command is width when menu 045 ON
53 static const char *TS480SAT_dataW[] = {
54 "50", "100", "250", "500", "1000", "1500", "2400", NULL };
55 static int TS480SAT_data_bw_vals[] = {1,2,3,4,5,6,7, WVALS_LIMIT};
56
57 static const char *TS480SAT_dataW_tooltip = "width";
58 static const char *TS480SAT_dataW_label = "W";
59
60 // SH command is center when menu 045 ON
61 static const char *TS480SAT_dataC[] = {
62 "1000", "1500", "2210", NULL };
63 static const char *TS480SAT_dataC_tooltip = "center";
64 static const char *TS480SAT_dataC_label = "C";
65
66 static const char *TS480SAT_AM_SL[] = {
67 "10", "100", "200", "500",
68 NULL };
69
70 static const char *TS480SAT_AM_SH[] = {
71 "2500", "3000", "4000", "5000",
72 NULL };
73 //static int TS480SAT_AM_bw_vals[] = {1,2,3,4,WVALS_LIMIT};
74
75 static const char *TS480SAT_CWwidths[] = {
76 "50", "80", "100", "150", "200",
77 "300", "400", "500", "600", "1000",
78 "2000", NULL};
79 static int TS480SAT_CW_bw_vals[] = {1,2,3,4,5,6,7,8,9,10,11,WVALS_LIMIT};
80
81 static const char *TS480SAT_CWbw[] = {
82 "FW0050;", "FW0080;", "FW0100;", "FW0150;", "FW0200;",
83 "FW0300;", "FW0400;", "FW0500;", "FW0600;", "FW1000;",
84 "FW2000;" };
85
86 static const char *TS480SAT_FSKwidths[] = {
87 "250", "500", "1000", "1500", NULL};
88 static int TS480SAT_FSK_bw_vals[] = { 1,2,3,4,WVALS_LIMIT};
89
90 static const char *TS480SAT_FSKbw[] = {
91 "FW0250;", "FW0500;", "FW1000;", "FW1500;" };
92
93 static int agcval = 1;
94 static bool fm_mode = false;
95
96 static GUI rig_widgets[]= {
97 { (Fl_Widget *)btnVol, 2, 125, 50 }, // 0
98 { (Fl_Widget *)sldrVOLUME, 54, 125, 156 }, // 1
99 { (Fl_Widget *)sldrRFGAIN, 54, 145, 156 }, // 2
100 { (Fl_Widget *)btnIFsh, 214, 105, 50 }, // 3
101 { (Fl_Widget *)sldrIFSHIFT, 266, 105, 156 }, // 4
102 { (Fl_Widget *)btnDataPort, 214, 125, 50 }, // 5
103 { (Fl_Widget *)sldrSQUELCH, 266, 125, 156 }, // 6
104 { (Fl_Widget *)sldrMICGAIN, 266, 145, 156 }, // 7
105 { (Fl_Widget *)sldrPOWER, 54, 165, 368 }, // 8
106 { (Fl_Widget *)NULL, 0, 0, 0 }
107 };
108
109 static string menu012 = "EX01200004";
110
initialize()111 void RIG_TS480SAT::initialize()
112 {
113 rig_widgets[0].W = btnVol;
114 rig_widgets[1].W = sldrVOLUME;
115 rig_widgets[2].W = sldrRFGAIN;
116 rig_widgets[3].W = btnIFsh;
117 rig_widgets[4].W = sldrIFSHIFT;
118 rig_widgets[5].W = btnDataPort;
119 rig_widgets[6].W = sldrSQUELCH;
120 rig_widgets[7].W = sldrMICGAIN;
121 rig_widgets[8].W = sldrPOWER;
122
123 check_menu_45();
124
125 menu012.clear();
126 cmd = "EX0120000;"; // read menu 012 state
127 //might return something like EX01200004;
128 gett("read menu 12");
129
130 if (wait_char(';', 11, 100, "read ex 012", ASC) == 11)
131 menu012 = replystr;
132
133 cmd = "EX01200000;";
134 sendCommand(cmd);
135 sett("set menu 12");
136 };
137
RIG_TS480SAT()138 RIG_TS480SAT::RIG_TS480SAT() {
139 // base class values
140 name_ = TS480SATname_;
141 modes_ = TS480SATmodes_;
142 _mode_type = TS480SAT_mode_type;
143 bandwidths_ = TS480SAT_empty;
144 bw_vals_ = TS480SAT_bw_vals;
145
146 dsp_SL = TS480SAT_SL;
147 SL_tooltip = TS480SAT_SL_tooltip;
148 SL_label = TS480SAT_btn_SL_label;
149
150 dsp_SH = TS480SAT_SH;
151 SH_tooltip = TS480SAT_SH_tooltip;
152 SH_label = TS480SAT_btn_SH_label;
153
154 widgets = rig_widgets;
155
156 comm_baudrate = BR57600;
157 stopbits = 1;
158 comm_retries = 2;
159 comm_wait = 5;
160 comm_timeout = 50;
161 comm_rtscts = true;
162 comm_rtsplus = false;
163 comm_dtrplus = false;
164 comm_catptt = true;
165 comm_rtsptt = false;
166 comm_dtrptt = false;
167 B.imode = A.imode = 1;
168 B.iBW = A.iBW = 0x8A03;
169 B.freq = A.freq = 14070000;
170
171 can_change_alt_vfo = true;
172
173 has_extras = true;
174
175 has_noise_reduction =
176 has_noise_reduction_control =
177 has_auto_notch =
178 has_noise_control =
179 has_sql_control =
180
181 has_split = true;
182 has_split_AB = true;
183 has_data_port = true;
184 has_micgain_control = true;
185 has_ifshift_control = true;
186 has_rf_control = true;
187 has_agc_control = true;
188 has_swr_control = true;
189 has_alc_control = true;
190 has_power_out = true;
191 has_dsp_controls = true;
192 has_smeter = true;
193 has_attenuator_control = true;
194 has_preamp_control = true;
195 has_mode_control = true;
196 has_bandwidth_control = true;
197 has_volume_control = true;
198 has_power_control = true;
199 has_tune_control = true;
200 has_ptt_control = true;
201
202 precision = 1;
203 ndigits = 8;
204
205 _noise_reduction_level = 0;
206 _nrval1 = 2;
207 _nrval2 = 4;
208 }
209
get_bwname_(int n,int md)210 const char * RIG_TS480SAT::get_bwname_(int n, int md)
211 {
212 static char bwname[20];
213 if (n > 256) {
214 int hi = (n >> 8) & 0x7F;
215 int lo = n & 0xFF;
216 snprintf(bwname, sizeof(bwname), "%s/%s",
217 (md == 0 || md == 1 || md == 3) ? dsp_SL[lo] : TS480SAT_AM_SL[lo],
218 (md == 0 || md == 1 || md == 3) ? dsp_SH[hi] : TS480SAT_AM_SH[hi] );
219 } else {
220 snprintf(bwname, sizeof(bwname), "%s",
221 (md == 2 || md == 6) ? TS480SAT_CWwidths[n] : TS480SAT_FSKwidths[n]);
222 }
223 return bwname;
224 }
225
check_menu_45()226 void RIG_TS480SAT::check_menu_45()
227 {
228 // read current switch 45 setting
229 menu_45 = false;
230 cmd = "EX0450000;";
231 if (wait_char(';', 11, 100, "Check menu item 45", ASC) >= 11) {
232 size_t p = replystr.rfind("EX045");
233 if (p != string::npos)
234 menu_45 = (replystr[p+9] == '1');
235 }
236
237 if (menu_45) {
238 dsp_SL = TS480SAT_dataW;
239 SL_tooltip = TS480SAT_dataW_tooltip;
240 SL_label = TS480SAT_dataW_label;
241 dsp_SH = TS480SAT_dataC;
242 SH_tooltip = TS480SAT_dataC_tooltip;
243 SH_label = TS480SAT_dataC_label;
244 B.iBW = A.iBW = 0x8106;
245 } else {
246 dsp_SL = TS480SAT_SL;
247 SL_tooltip = TS480SAT_SL_tooltip;
248 SL_label = TS480SAT_btn_SL_label;
249 dsp_SH = TS480SAT_SH;
250 SH_tooltip = TS480SAT_SH_tooltip;
251 SH_label = TS480SAT_btn_SH_label;
252 B.iBW = A.iBW = 0x8A03;
253 }
254 gett("check menu 45");
255 }
256
shutdown()257 void RIG_TS480SAT::shutdown()
258 {
259 // restore state of xcvr beeps
260 if (menu012.empty()) return;
261 cmd = menu012;
262 sendCommand(cmd);
263 sett("shutdown, restore menu 12");
264 }
265
266 // SM cmd 0 ... 100 (rig values 0 ... 15)
get_smeter()267 int RIG_TS480SAT::get_smeter()
268 {
269 int mtr = 0;
270 cmd = "SM0;";
271 if (wait_char(';', 8, 100, "get Smeter", ASC) < 8) return 0;
272
273 size_t p = replystr.rfind("SM");
274 if (p != string::npos)
275 mtr = 5 * atoi(&replystr[p + 3]);
276 gett("get smeter");
277 return mtr;
278 }
279
280 struct pwrpair {int mtr; float pwr;};
281
282 static pwrpair pwrtbl[] = {
283 {0, 0.0},
284 {2, 5.0},
285 {4, 10.0},
286 {7, 25.0},
287 {11, 50.0},
288 {16, 100.0},
289 {20, 200.0} };
290
get_power_out()291 int RIG_TS480SAT::get_power_out()
292 {
293 int mtr = 0;
294 cmd = "SM0;";
295 if (wait_char(';', 8, 100, "get power", ASC) < 8) return mtr;
296
297 size_t p = replystr.rfind("SM");
298 if (p != string::npos) {
299 mtr = atoi(&replystr[p + 3]);
300 size_t i = 0; // outside of the if/else for scope reasons
301 if (mtr < 0) mtr = 0;
302 else if (mtr > 20) mtr = 20;
303 else while(mtr > pwrtbl[i].mtr) i++;
304
305 mtr = (int)ceil(pwrtbl[i].pwr +
306 (pwrtbl[i+1].pwr - pwrtbl[i].pwr)*(mtr - pwrtbl[i].mtr)/(pwrtbl[i+1].mtr - pwrtbl[i].mtr));
307 if (mtr > 200) mtr = 200;
308 }
309 gett("power out");
310 return mtr;
311 }
312
313 // RM cmd 0 ... 100 (rig values 0 ... 8)
314 // User report of RM; command using Send Cmd tab
315 // RM10000;RM20000;RM30000;
316 // RM1nnnn; => SWR
317 // RM2nnnn; => COMP
318 // RM3nnnn; => ALC
319
get_swr()320 int RIG_TS480SAT::get_swr()
321 {
322 int mtr = 0;
323 cmd = "RM;";
324 if (wait_char(';', 8, 100, "get SWR/ALC", ASC) < 8) return (int)mtr;
325
326 size_t p = replystr.rfind("RM1");
327 if (p != string::npos)
328 mtr = 66 * atoi(&replystr[p+3]) / 10;
329 p = replystr.rfind("RM3");
330 if (p != string::npos)
331 alc = 66 * atoi(&replystr[p+3]) / 10;
332 else
333 alc = 0;
334 swralc_polled = true;
335 gett("swr");
336 return mtr;
337 }
338
get_alc(void)339 int RIG_TS480SAT::get_alc(void)
340 {
341 if (!swralc_polled) get_swr();
342 swralc_polled = false;
343 return alc;
344 }
345
set_widths(int val)346 int RIG_TS480SAT::set_widths(int val)
347 {
348 int bw;
349 if (val == 0 || val == 1 || val == 3) {
350 if (menu_45) {
351 bw = 0x8106; // 1500 Hz 2400 wide
352 dsp_SL = TS480SAT_dataW;
353 SL_tooltip = TS480SAT_dataW_tooltip;
354 SL_label = TS480SAT_dataW_label;
355 dsp_SH = TS480SAT_dataC;
356 SH_tooltip = TS480SAT_dataC_tooltip;
357 SH_label = TS480SAT_dataC_label;
358 bandwidths_ = TS480SAT_dataW;
359 bw_vals_ = TS480SAT_data_bw_vals;
360 } else {
361 bw = 0x8A03; // 200 ... 3000 Hz
362 dsp_SL = TS480SAT_SL;
363 SL_tooltip = TS480SAT_SL_tooltip;
364 SL_label = TS480SAT_btn_SL_label;
365 dsp_SH = TS480SAT_SH;
366 SH_tooltip = TS480SAT_SH_tooltip;
367 SH_label = TS480SAT_btn_SH_label;
368 bandwidths_ = TS480SAT_SH;
369 bw_vals_ = TS480SAT_HI_bw_vals;
370 }
371 } else if (val == 2 || val == 6) {
372 bandwidths_ = TS480SAT_CWwidths;
373 bw_vals_ = TS480SAT_CW_bw_vals;
374 dsp_SL = TS480SAT_empty;
375 dsp_SH = TS480SAT_empty;
376 bw = 7;
377 } else if (val == 5 || val == 7) {
378 bandwidths_ = TS480SAT_FSKwidths;
379 bw_vals_ = TS480SAT_FSK_bw_vals;
380 dsp_SL = TS480SAT_empty;
381 dsp_SH = TS480SAT_empty;
382 bw = 1;
383 } else { // val == 4 ==> AM
384 bandwidths_ = TS480SAT_empty;
385 bw_vals_ = TS480SAT_bw_vals;
386 dsp_SL = TS480SAT_AM_SL;
387 dsp_SH = TS480SAT_AM_SH;
388 bw = 0x8201;
389 }
390 return bw;
391 }
392
bwtable(int m)393 const char **RIG_TS480SAT::bwtable(int m)
394 {
395 if (m == 0 || m == 1 || m == 3)
396 return TS480SAT_empty;
397 else if (m == 2 || m == 6)
398 return TS480SAT_CWwidths;
399 else if (m == 5 || m == 7)
400 return TS480SAT_FSKwidths;
401 //else AM m == 4
402 return TS480SAT_empty;
403 }
404
lotable(int m)405 const char **RIG_TS480SAT::lotable(int m)
406 {
407 if (m == 0 || m == 1 || m == 3)
408 return TS480SAT_SL;
409 else if (m == 2 || m == 6)
410 return NULL;
411 else if (m == 5 || m == 7)
412 return NULL;
413 return TS480SAT_AM_SL;
414 }
415
hitable(int m)416 const char **RIG_TS480SAT::hitable(int m)
417 {
418 if (m == 0 || m == 1 || m == 3)
419 return TS480SAT_SH;
420 else if (m == 2 || m == 6)
421 return NULL;
422 else if (m == 5 || m == 7)
423 return NULL;
424 return TS480SAT_AM_SH;
425 }
426
set_modeA(int val)427 void RIG_TS480SAT::set_modeA(int val)
428 {
429 if (val == 3) fm_mode = true;
430 else fm_mode = false;
431 A.imode = val;
432 cmd = "MD";
433 cmd += TS480SAT_mode_chr[val];
434 cmd += ';';
435 sendCommand(cmd);
436 showresp(WARN, ASC, "set mode", cmd, "");
437 A.iBW = set_widths(val);
438 sett("set mode A");
439 }
440
get_modeA()441 int RIG_TS480SAT::get_modeA()
442 {
443 cmd = "MD;";
444 if (wait_char(';', 4, 100, "get modeA", ASC) < 4) return A.imode;
445
446 size_t p = replystr.rfind("MD");
447 if (p != string::npos && (p + 2 < replystr.length())) {
448 int md = replystr[p+2];
449 md = md - '1';
450 if (md == 8) md = 7;
451 A.imode = md;
452 A.iBW = set_widths(A.imode);
453 }
454 if (A.imode == 3) fm_mode = true;
455 else fm_mode = false;
456 gett("mode A");
457 return A.imode;
458 }
459
set_modeB(int val)460 void RIG_TS480SAT::set_modeB(int val)
461 {
462 if (val == 3) fm_mode = true;
463 else fm_mode = false;
464 B.imode = val;
465 cmd = "MD";
466 cmd += TS480SAT_mode_chr[val];
467 cmd += ';';
468 sendCommand(cmd);
469 showresp(WARN, ASC, "set mode B", cmd, "");
470 B.iBW = set_widths(val);
471 sett("mode B");
472 }
473
get_modeB()474 int RIG_TS480SAT::get_modeB()
475 {
476 cmd = "MD;";
477 if (wait_char(';', 4, 100, "get modeB", ASC) < 4) return B.imode;
478
479 size_t p = replystr.rfind("MD");
480 if (p != string::npos && (p + 2 < replystr.length())) {
481 int md = replystr[p+2];
482 md = md - '1';
483 if (md == 8) md = 7;
484 B.imode = md;
485 B.iBW = set_widths(B.imode);
486 }
487 if (B.imode == 3) fm_mode = true;
488 else fm_mode = false;
489 gett("mode B");
490 return B.imode;
491 }
492
get_modetype(int n)493 int RIG_TS480SAT::get_modetype(int n)
494 {
495 return _mode_type[n];
496 }
497
set_bwA(int val)498 void RIG_TS480SAT::set_bwA(int val)
499 {
500 if (A.imode == 0 || A.imode == 1 || A.imode == 3 || A.imode == 4) {
501 if (val < 256) return;
502 A.iBW = val;
503 cmd = "SL";
504 cmd.append(to_decimal(A.iBW & 0xFF, 2)).append(";");
505 sendCommand(cmd);
506 showresp(WARN, ASC, SL_tooltip, cmd, "");
507 cmd = "SH";
508 cmd.append(to_decimal(((A.iBW >> 8) & 0x7F), 2)).append(";");
509 sendCommand(cmd);
510 showresp(WARN, ASC, SH_tooltip, cmd, "");
511 sett("bw A");
512 }
513 if (val > 256) return;
514 else if (A.imode == 2 || A.imode == 6) {
515 A.iBW = val;
516 cmd = TS480SAT_CWbw[A.iBW];
517 sendCommand(cmd);
518 showresp(WARN, ASC, "set CW bw", cmd, "");
519 sett("bw A");
520 }else if (A.imode == 5 || A.imode == 7) {
521 A.iBW = val;
522 cmd = TS480SAT_FSKbw[A.iBW];
523 sendCommand(cmd);
524 showresp(WARN, ASC, "set FSK bw", cmd, "");
525 sett("bw A");
526 }
527 }
528
get_bwA()529 int RIG_TS480SAT::get_bwA()
530 {
531 int i = 0;
532 size_t p;
533
534 bool menu45 = menu_45;
535
536 check_menu_45();
537 if (menu45 != menu_45)
538 Fl::awake(updateBandwidthControl);
539
540 if (A.imode == 0 || A.imode == 1 || A.imode == 3 || A.imode == 4) {
541 int lo = A.iBW & 0xFF, hi = (A.iBW >> 8) & 0x7F;
542 cmd = "SL;";
543 if (wait_char(';', 5, 100, "get SL", ASC) == 5) {
544 p = replystr.rfind("SL");
545 if (p != string::npos)
546 lo = fm_decimal(replystr.substr(p+2), 2);
547 }
548 cmd = "SH;";
549 if (wait_char(';', 5, 100, "get SH", ASC) == 5) {
550 p = replystr.rfind("SH");
551 if (p != string::npos)
552 hi = fm_decimal(replystr.substr(p+2), 2);
553 A.iBW = ((hi << 8) | (lo & 0xFF)) | 0x8000;
554 }
555 } else if (A.imode == 2 || A.imode == 6) {
556 cmd = "FW;";
557 if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
558 p = replystr.rfind("FW");
559 if (p != string::npos) {
560 for (i = 0; i < 11; i++)
561 if (replystr.find(TS480SAT_CWbw[i]) == p)
562 break;
563 if (i == 11) i = 10;
564 A.iBW = i;
565 }
566 }
567 } else if (A.imode == 5 || A.imode == 7) {
568 cmd = "FW;";
569 if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
570 p = replystr.rfind("FW");
571 if (p != string::npos) {
572 for (i = 0; i < 4; i++)
573 if (replystr.find(TS480SAT_FSKbw[i]) == p)
574 break;
575 if (i == 4) i = 3;
576 A.iBW = i;
577 }
578 }
579 }
580 gett("get bw A");
581 return A.iBW;
582 }
583
set_bwB(int val)584 void RIG_TS480SAT::set_bwB(int val)
585 {
586 if (B.imode == 0 || B.imode == 1 || B.imode == 3 || B.imode == 4) {
587 if (val < 256) return;
588 B.iBW = val;
589 cmd = "SL";
590 cmd.append(to_decimal(B.iBW & 0xFF, 2)).append(";");
591 sendCommand(cmd);
592 showresp(WARN, ASC, SL_tooltip, cmd, "");
593 cmd = "SH";
594 cmd.append(to_decimal(((B.iBW >> 8) & 0x7F), 2)).append(";");
595 sendCommand(cmd);
596 showresp(WARN, ASC, SH_tooltip, cmd, "");
597 sett("bw B");
598 }
599 if (val > 256) return;
600 else if (B.imode == 2 || B.imode == 6) { // CW
601 B.iBW = val;
602 cmd = TS480SAT_CWbw[B.iBW];
603 sendCommand(cmd);
604 showresp(WARN, ASC, "set CW bw", cmd, "");
605 sett("bw B");
606 }else if (B.imode == 5 || B.imode == 7) {
607 B.iBW = val;
608 cmd = TS480SAT_FSKbw[B.iBW];
609 sendCommand(cmd);
610 showresp(WARN, ASC, "set FSK bw", cmd, "");
611 sett("bw B");
612 }
613 }
614
get_bwB()615 int RIG_TS480SAT::get_bwB()
616 {
617 int i = 0;
618 size_t p;
619 bool menu45 = menu_45;
620
621 check_menu_45();
622 if (menu45 != menu_45)
623 Fl::awake(updateBandwidthControl);
624
625 if (B.imode == 0 || B.imode == 1 || B.imode == 3 || B.imode == 4) {
626 int lo = B.iBW & 0xFF, hi = (B.iBW >> 8) & 0x7F;
627 cmd = "SL;";
628 if (wait_char(';', 5, 100, "get SL", ASC) == 5) {
629 p = replystr.rfind("SL");
630 if (p != string::npos)
631 lo = fm_decimal(replystr.substr(p+2), 2);
632 }
633 cmd = "SH;";
634 if (wait_char(';', 5, 100, "get SH", ASC) == 5) {
635 p = replystr.rfind("SH");
636 if (p != string::npos)
637 hi = fm_decimal(replystr.substr(p+2), 2);
638 B.iBW = ((hi << 8) | (lo & 0xFF)) | 0x8000;
639 }
640 } else if (B.imode == 2 || B.imode == 6) {
641 cmd = "FW;";
642 if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
643 p = replystr.rfind("FW");
644 if (p != string::npos) {
645 for (i = 0; i < 11; i++)
646 if (replystr.find(TS480SAT_CWbw[i]) == p)
647 break;
648 if (i == 11) i = 10;
649 B.iBW = i;
650 }
651 }
652 } else if (B.imode == 5 || B.imode == 7) {
653 cmd = "FW;";
654 if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
655 p = replystr.rfind("FW");
656 if (p != string::npos) {
657 for (i = 0; i < 4; i++)
658 if (replystr.find(TS480SAT_FSKbw[i]) == p)
659 break;
660 if (i == 4) i = 3;
661 B.iBW = i;
662 }
663 }
664 }
665 gett("bw B");
666 return B.iBW;
667 }
668
adjust_bandwidth(int val)669 int RIG_TS480SAT::adjust_bandwidth(int val)
670 {
671 int bw = 0;
672 if (val == 0 || val == 1 || val == 3)
673 bw = 0x8A03;
674 else if (val == 4)
675 bw = 0x8201;
676 else if (val == 2 || val == 6)
677 bw = 7;
678 else if (val == 5 || val == 7)
679 bw = 1;
680 return bw;
681 }
682
def_bandwidth(int val)683 int RIG_TS480SAT::def_bandwidth(int val)
684 {
685 return adjust_bandwidth(val);
686 }
687
set_power_control(double val)688 void RIG_TS480SAT::set_power_control(double val)
689 {
690 cmd = "PC";
691 char szval[4];
692 if (modeA == 4 && val > 25) val = 25; // AM mode limitation
693 snprintf(szval, sizeof(szval), "%03d", (int)val);
694 cmd += szval;
695 cmd += ';';
696 LOG_WARN("%s", cmd.c_str());
697 sendCommand(cmd);
698 sett("power control");
699 }
700
get_power_control()701 int RIG_TS480SAT::get_power_control()
702 {
703 int val = progStatus.power_level;
704 cmd = "PC;";
705 if (wait_char(';', 6, 100, "get Power control", ASC) < 6) return val;
706
707 size_t p = replystr.rfind("PC");
708 if (p == string::npos) return val;
709
710 val = atoi(&replystr[p + 2]);
711 gett("power control");
712 return val;
713 }
714
set_attenuator(int val)715 void RIG_TS480SAT::set_attenuator(int val)
716 {
717 if (val) cmd = "RA01;";
718 else cmd = "RA00;";
719 LOG_WARN("%s", cmd.c_str());
720 sendCommand(cmd);
721 sett("attenuator");
722 }
723
get_attenuator()724 int RIG_TS480SAT::get_attenuator()
725 {
726 cmd = "RA;";
727 if (wait_char(';', 7, 100, "get attenuator", ASC) < 7) return progStatus.attenuator;
728
729 size_t p = replystr.rfind("RA");
730 gett("attenuator");
731 if (p == string::npos) return progStatus.attenuator;
732 if (replystr[p+3] == '1') return 1;
733 return 0;
734 }
735
set_preamp(int val)736 void RIG_TS480SAT::set_preamp(int val)
737 {
738 if (val) cmd = "PA1;";
739 else cmd = "PA0;";
740 LOG_WARN("%s", cmd.c_str());
741 sendCommand(cmd);
742 sett("preamp");
743 }
744
get_preamp()745 int RIG_TS480SAT::get_preamp()
746 {
747 cmd = "PA;";
748 if (wait_char(';', 5, 100, "get preamp", ASC) < 5) return progStatus.preamp;
749
750 size_t p = replystr.rfind("PA");
751 gett("preamp");
752 if (p == string::npos) return progStatus.preamp;
753 if (replystr[p+2] == '1') return 1;
754 return 0;
755 }
756
set_if_shift(int val)757 void RIG_TS480SAT::set_if_shift(int val)
758 {
759 cmd = "IS+";
760 if (val < 0) cmd[2] = '-';
761 cmd.append(to_decimal(abs(val),4)).append(";");
762 sendCommand(cmd);
763 showresp(WARN, ASC, "set IF shift", cmd, "");
764 sett("if shift");
765 }
766
get_if_shift(int & val)767 bool RIG_TS480SAT::get_if_shift(int &val)
768 {
769 cmd = "IS;";
770 if (wait_char(';', 8, 100, "get IF shift", ASC) == 8) {
771 size_t p = replystr.rfind("IS");
772 gett("if shift");
773 if (p != string::npos) {
774 val = fm_decimal(replystr.substr(p+3), 4);
775 if (replystr[p+2] == '-') val *= -1;
776 return (val != 0);
777 }
778 }
779 val = progStatus.shift_val;
780 return progStatus.shift;
781 }
782
get_if_min_max_step(int & min,int & max,int & step)783 void RIG_TS480SAT::get_if_min_max_step(int &min, int &max, int &step)
784 {
785 if_shift_min = min = -1100;
786 if_shift_max = max = 1100;
787 if_shift_step = step = 10;
788 if_shift_mid = 0;
789 }
790
791 // Noise Reduction (TS2000.cxx) NR1 only works; no NR2 and don' no why
set_noise_reduction(int val)792 void RIG_TS480SAT::set_noise_reduction(int val)
793 {
794 if (val == -1) {
795 return;
796 }
797 _noise_reduction_level = val;
798 if (_noise_reduction_level == 0) {
799 nr_label("NR", false);
800 } else if (_noise_reduction_level == 1) {
801 nr_label("NR1", true);
802 } else if (_noise_reduction_level == 2) {
803 nr_label("NR2", true);
804 }
805 cmd.assign("NR");
806 cmd += '0' + _noise_reduction_level;
807 cmd += ';';
808 sendCommand (cmd);
809 showresp(WARN, ASC, "SET noise reduction", cmd, "");
810 sett("noise reduction");
811 }
812
get_noise_reduction()813 int RIG_TS480SAT::get_noise_reduction()
814 {
815 cmd = rsp = "NR";
816 cmd.append(";");
817 if (wait_char(';', 4, 100, "GET noise reduction", ASC) == 4) {
818 size_t p = replystr.rfind(rsp);
819 if (p == string::npos) return _noise_reduction_level;
820 _noise_reduction_level = replystr[p+2] - '0';
821 }
822
823 if (_noise_reduction_level == 1) {
824 nr_label("NR1", true);
825 } else if (_noise_reduction_level == 2) {
826 nr_label("NR2", true);
827 } else {
828 nr_label("NR", false);
829 }
830 gett("noise reduction");
831 return _noise_reduction_level;
832 }
833
set_noise_reduction_val(int val)834 void RIG_TS480SAT::set_noise_reduction_val(int val)
835 {
836 if (_noise_reduction_level == 0) return;
837 if (_noise_reduction_level == 1) _nrval1 = val;
838 else _nrval2 = val;
839
840 cmd.assign("RL").append(to_decimal(val, 2)).append(";");
841 sendCommand(cmd);
842 showresp(WARN, ASC, "SET_noise_reduction_val", cmd, "");
843 sett("nr value");
844 }
845
get_noise_reduction_val()846 int RIG_TS480SAT::get_noise_reduction_val()
847 {
848 int nrval = 0;
849 if (_noise_reduction_level == 0) return 0;
850 int val = progStatus.noise_reduction_val;
851 cmd = rsp = "RL";
852 cmd.append(";");
853 if (wait_char(';', 5, 100, "GET noise reduction val", ASC) == 5) {
854 size_t p = replystr.rfind(rsp);
855 if (p == string::npos) {
856 nrval = (_noise_reduction_level == 1 ? _nrval1 : _nrval2);
857 return nrval;
858 }
859 val = atoi(&replystr[p+2]);
860 }
861
862 if (_noise_reduction_level == 1) _nrval1 = val;
863 else _nrval2 = val;
864 gett("nr value");
865 return val;
866 }
867
get_agc()868 int RIG_TS480SAT::get_agc()
869 {
870 cmd = "GT;";
871 wait_char(';', 6, 100, "GET agc val", ASC);
872 size_t p = replystr.rfind("GT");
873 gett("agc");
874 if (p == string::npos) return agcval;
875 if (replystr[4] == ' ') return 0;
876 agcval = replystr[4] - '0' + 1; // '0' == off, '1' = fast, '2' = slow
877
878 return agcval;
879 }
880
incr_agc()881 int RIG_TS480SAT::incr_agc()
882 {
883 if (fm_mode) return 0;
884 agcval++;
885 if (agcval == 4) agcval = 1;
886 cmd.assign("GT00");
887 cmd += (agcval + '0' - 1);
888 cmd += ";";
889 sendCommand(cmd);
890 showresp(WARN, ASC, "SET agc", cmd, replystr);
891 sett("increment agc");
892 return agcval;
893 }
894
895
896 static const char *agcstrs[] = {"FM", "AGC", "FST", "SLO"};
agc_label()897 const char *RIG_TS480SAT::agc_label()
898 {
899 if (fm_mode) return agcstrs[0];
900 return agcstrs[agcval];
901 }
902
agc_val()903 int RIG_TS480SAT::agc_val()
904 {
905 if (fm_mode) return 0;
906 return agcval;
907 }
908
909 // Auto Notch, beat canceller (TS2000.cxx) BC1 only, not BC2
set_auto_notch(int v)910 void RIG_TS480SAT::set_auto_notch(int v)
911 {
912 cmd = v ? "BC1;" : "BC0;";
913 sendCommand(cmd);
914 showresp(WARN, ASC, "set auto notch", cmd, "");
915 sett("auto notch");
916 }
917
get_auto_notch()918 int RIG_TS480SAT::get_auto_notch()
919 {
920 cmd = "BC;";
921 if (wait_char(';', 4, 100, "get auto notch", ASC) == 4) {
922 int anotch = 0;
923 size_t p = replystr.rfind("BC");
924 gett("auto notch");
925 if (p != string::npos) {
926 anotch = (replystr[p+2] == '1');
927 return anotch;
928 }
929 }
930 return 0;
931 }
932
933 // Noise Blanker (TS2000.cxx)
set_noise(bool b)934 void RIG_TS480SAT::set_noise(bool b)
935 {
936 if (b)
937 cmd = "NB1;";
938 else
939 cmd = "NB0;";
940 sendCommand(cmd);
941 showresp(WARN, ASC, "set NB", cmd, "");
942 sett("noise");
943 }
944
get_noise()945 int RIG_TS480SAT::get_noise()
946 {
947 cmd = "NB;";
948 if (wait_char(';', 4, 100, "get Noise Blanker", ASC) == 4) {
949 size_t p = replystr.rfind("NB");
950 gett("noise");
951 if (p == string::npos) return 0;
952 if (replystr[p+2] == '0') return 0;
953 }
954 return 1;
955 }
956
957 // Tranceiver PTT on/off
set_PTT_control(int val)958 void RIG_TS480SAT::set_PTT_control(int val)
959 {
960 if (val) {
961 if (progStatus.data_port) cmd = "TX1;"; // DTS transmission using ANI input
962 else cmd = "TX0;"; // mic input
963 } else cmd = "RX;";
964 sendCommand(cmd);
965 showresp(WARN, ASC, "set PTT", cmd, "");
966 sett("ptt");
967 }
968
get_PTT()969 int RIG_TS480SAT::get_PTT()
970 {
971 cmd = "IF;";
972 int ret = wait_char(';', 38, 100, "get VFO", ASC);
973 gett("ptt");
974 if (ret < 38) return ptt_;
975 ptt_ = (replybuff[28] == '1');
976 return ptt_;
977 }
978
set_rf_gain(int val)979 void RIG_TS480SAT::set_rf_gain(int val)
980 {
981 cmd = "RG";
982 cmd.append(to_decimal(val,3)).append(";");
983 sendCommand(cmd);
984 showresp(WARN, ASC, "set rf gain", cmd, "");
985 sett("rf gain");
986 }
987
get_rf_gain()988 int RIG_TS480SAT::get_rf_gain()
989 {
990 int val = progStatus.rfgain;
991 cmd = "RG;";
992 if (wait_char(';', 6, 100, "get rf gain", ASC) < 6) return val;
993
994 size_t p = replystr.rfind("RG");
995 if (p != string::npos)
996 val = fm_decimal(replystr.substr(p+2), 3);
997 gett("rf gain");
998 return val;
999 }
1000
get_rf_min_max_step(int & min,int & max,int & step)1001 void RIG_TS480SAT::get_rf_min_max_step(int &min, int &max, int &step)
1002 {
1003 min = 0; max = 100; step = 1;
1004 }
1005
1006 /*
1007 void RIG_TS480SAT::selectA()
1008 {
1009 cmd = "FR0;FT0;";
1010 sendCommand(cmd);
1011 showresp(WARN, ASC, "Rx on A, Tx on A", cmd, "");
1012 }
1013
1014 void RIG_TS480SAT::selectB()
1015 {
1016 cmd = "FR1;FT1;";
1017 sendCommand(cmd);
1018 showresp(WARN, ASC, "Rx on B, Tx on B", cmd, "");
1019 }
1020
1021 void RIG_TS480SAT::set_split(bool val)
1022 {
1023 split = val;
1024 if (useB) {
1025 if (val) {
1026 cmd = "FR1;FT0;";
1027 sendCommand(cmd);
1028 showresp(WARN, ASC, "Rx on B, Tx on A", cmd, "");
1029 } else {
1030 cmd = "FR1;FT1;";
1031 sendCommand(cmd);
1032 showresp(WARN, ASC, "Rx on B, Tx on B", cmd, "");
1033 }
1034 } else {
1035 if (val) {
1036 cmd = "FR0;FT1;";
1037 sendCommand(cmd);
1038 showresp(WARN, ASC, "Rx on A, Tx on B", cmd, "");
1039 } else {
1040 cmd = "FR0;FT0;";
1041 sendCommand(cmd);
1042 showresp(WARN, ASC, "Rx on A, Tx on A", cmd, "");
1043 }
1044 }
1045 }
1046
1047 bool RIG_TS480SAT::can_split()
1048 {
1049 return true;
1050 }
1051
1052 int RIG_TS480SAT::get_split()
1053 {
1054 size_t p;
1055 int split = 0;
1056 char rx = 0, tx = 0;
1057 // tx vfo
1058 cmd = rsp = "FT";
1059 cmd.append(";");
1060 if (wait_char(';', 4, 100, "get split tx vfo", ASC) == 4) {
1061 p = replystr.rfind(rsp);
1062 if (p == string::npos) return split;
1063 tx = replystr[p+2];
1064 }
1065 // rx vfo
1066 cmd = rsp = "FR";
1067 cmd.append(";");
1068 if (wait_char(';', 4, 100, "get split rx vfo", ASC) == 4) {
1069 p = replystr.rfind(rsp);
1070 if (p == string::npos) return split;
1071 rx = replystr[p+2];
1072 // split test
1073 split = (tx == '1' ? 2 : 0) + (rx == '1' ? 1 : 0);
1074 }
1075
1076 return split;
1077 }
1078
1079 unsigned long int RIG_TS480SAT::get_vfoA ()
1080 {
1081 cmd = "FA;";
1082 if (wait_char(';', 14, 100, "get vfo A", ASC) < 14) return A.freq;
1083
1084 size_t p = replystr.rfind("FA");
1085 if (p != string::npos && (p + 12 < replystr.length())) {
1086 int f = 0;
1087 for (size_t n = 2; n < 13; n++)
1088 f = f*10 + replystr[p+n] - '0';
1089 A.freq = f;
1090 }
1091 return A.freq;
1092 }
1093
1094 void RIG_TS480SAT::set_vfoA (unsigned long int freq)
1095 {
1096 A.freq = freq;
1097 cmd = "FA00000000000;";
1098 for (int i = 12; i > 1; i--) {
1099 cmd[i] += freq % 10;
1100 freq /= 10;
1101 }
1102 sendCommand(cmd);
1103 showresp(WARN, ASC, "set vfo A", cmd, "");
1104 }
1105
1106 unsigned long int RIG_TS480SAT::get_vfoB ()
1107 {
1108 cmd = "FB;";
1109 if (wait_char(';', 14, 100, "get vfo B", ASC) < 14) return B.freq;
1110
1111 size_t p = replystr.rfind("FB");
1112 if (p != string::npos && (p + 12 < replystr.length())) {
1113 int f = 0;
1114 for (size_t n = 2; n < 13; n++)
1115 f = f*10 + replystr[p+n] - '0';
1116 B.freq = f;
1117 }
1118 return B.freq;
1119 }
1120
1121 void RIG_TS480SAT::set_vfoB (unsigned long int freq)
1122 {
1123 B.freq = freq;
1124 cmd = "FB00000000000;";
1125 for (int i = 12; i > 1; i--) {
1126 cmd[i] += freq % 10;
1127 freq /= 10;
1128 }
1129 sendCommand(cmd);
1130 showresp(WARN, ASC, "set vfo B", cmd, "");
1131 }
1132
1133 // Squelch (TS990.cxx)
1134 void RIG_TS480SAT::set_squelch(int val)
1135 {
1136 cmd = "SQ0";
1137 cmd.append(to_decimal(abs(val),3)).append(";");
1138 sendCommand(cmd);
1139 showresp(INFO, ASC, "set squelch", cmd, "");
1140 }
1141
1142 int RIG_TS480SAT::get_squelch()
1143 {
1144 int val = 0;
1145 cmd = "SQ0;";
1146 if (wait_char(';', 7, 20, "get squelch", ASC) >= 7) {
1147 size_t p = replystr.rfind("SQ0");
1148 if (p == string::npos) return val;
1149 replystr[p + 6] = 0;
1150 val = atoi(&replystr[p + 3]);
1151 }
1152 return val;
1153 }
1154
1155 void RIG_TS480SAT::get_squelch_min_max_step(int &min, int &max, int &step)
1156 {
1157 min = 0; max = 255; step = 1;
1158 }
1159
1160 void RIG_TS480SAT::set_mic_gain(int val)
1161 {
1162 cmd = "MG";
1163 cmd.append(to_decimal(val,3)).append(";");
1164 sendCommand(cmd);
1165 showresp(WARN, ASC, "set mic gain", cmd, "");
1166 }
1167
1168 int RIG_TS480SAT::get_mic_gain()
1169 {
1170 int val = progStatus.mic_gain;
1171 cmd = "MG;";
1172 if (wait_char(';', 6, 100, "get mic gain", ASC) < 6) return val;
1173
1174 size_t p = replystr.rfind("MG");
1175 if (p != string::npos)
1176 val = fm_decimal(replystr.substr(p+2), 3);
1177 return val;
1178 }
1179
1180 void RIG_TS480SAT::get_mic_min_max_step(int &min, int &max, int &step)
1181 {
1182 min = 0; max = 100; step = 1;
1183 }
1184
1185
1186 void RIG_TS480SAT::set_volume_control(int val)
1187 {
1188 cmd = "AG";
1189 char szval[5];
1190 snprintf(szval, sizeof(szval), "%04d", val * 255 / 100);
1191 cmd += szval;
1192 cmd += ';';
1193 LOG_WARN("%s", cmd.c_str());
1194 sendCommand(cmd);
1195 }
1196
1197 int RIG_TS480SAT::get_volume_control()
1198 {
1199 int val = progStatus.volume;
1200 cmd = "AG0;";
1201 if (wait_char(';', 7, 100, "get vol", ASC) < 7) return val;
1202
1203 size_t p = replystr.rfind("AG");
1204 if (p == string::npos) return val;
1205 replystr[p + 6] = 0;
1206 val = atoi(&replystr[p + 3]);
1207 val = val * 100 / 255;
1208 return val;
1209 }
1210
1211 void RIG_TS480SAT::tune_rig()
1212 {
1213 cmd = "AC111;";
1214 LOG_WARN("%s", cmd.c_str());
1215 sendCommand(cmd);
1216 }
1217
1218 */
1219