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 "TS2000.h"
22 #include "support.h"
23
24 static const char TS2000name_[] = "TS-2000";
25
26 static const char *TS2000modes_[] = {
27 "LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "FSK-R", NULL};
28
29 static const char TS2000_mode_chr[] = { '1', '2', '3', '4', '5', '6', '7', '9' };
30 static const char TS2000_mode_type[] = { 'L', 'U', 'U', 'U', 'U', 'L', 'L', 'U' };
31
32 static const char *TS2000_empty[] = { "N/A", NULL };
33 //------------------------------------------------------------------------------
34 static const char *TS2000_SL[] = {
35 "0", "50", "100", "200", "300",
36 "400", "500", "600", "700", "800",
37 "900", "1000", NULL };
38 static const char *TS2000_CAT_SL[] = {
39 "SL00;", "SL01;", "SL02;", "SL03;", "SL04;",
40 "SL05;", "SL06;", "SL07;", "SL08;", "SL09;",
41 "SL10;", "SL11;" };
42 static const char *TS2000_SL_tooltip = "lo cut";
43 static const char *TS2000_SSB_btn_SL_label = "L";
44 //------------------------------------------------------------------------------
45 static const char *TS2000_SH[] = {
46 "1400", "1600", "1800", "2000", "2200",
47 "2400", "2600", "2800", "3000", "3400",
48 "4000", "5000", NULL };
49 static const char *TS2000_CAT_SH[] = {
50 "SH00;", "SH01;", "SH02;", "SH03;", "SH04;",
51 "SH05;", "SH06;", "SH07;", "SH08;", "SH09;",
52 "SH10;", "SH11;" };
53 static const char *TS2000_SH_tooltip = "hi cut";
54 static const char *TS2000_SSB_btn_SH_label = "H";
55 //------------------------------------------------------------------------------
56 static const char *TS2000_AM_SL[] = {
57 "0", "100", "200", "500", NULL };
58 static const char *TS2000_AM_SH[] = {
59 "2500", "3000", "4000", "5000" };
60 //------------------------------------------------------------------------------
61 static const char *TS2000_CWwidths[] = {
62 "50", "80", "100", "150", "200",
63 "300", "400", "500", "600", "1000",
64 "2000", NULL};
65 static const char *TS2000_CWbw[] = {
66 "FW0050;", "FW0080;", "FW0100;", "FW0150;", "FW0200;",
67 "FW0300;", "FW0400;", "FW0500;", "FW0600;", "FW1000;",
68 "FW2000;" };
69 //------------------------------------------------------------------------------
70 static const char *TS2000_FSKwidths[] = {
71 "250", "500", "1000", "1500", NULL};
72 static const char *TS2000_FSKbw[] = {
73 "FW0250;", "FW0500;", "FW1000;", "FW1500;" };
74 //------------------------------------------------------------------------------
75
76 static GUI rig_widgets[]= {
77 { (Fl_Widget *)btnVol, 2, 125, 50 }, // 0
78 { (Fl_Widget *)sldrVOLUME, 54, 125, 156 }, // 1
79 { (Fl_Widget *)sldrRFGAIN, 54, 145, 156 }, // 2
80 { (Fl_Widget *)btnIFsh, 214, 105, 50 }, // 3
81 { (Fl_Widget *)sldrIFSHIFT, 266, 105, 156 }, // 4
82 { (Fl_Widget *)btnNotch, 214, 125, 50 }, // 5
83 { (Fl_Widget *)sldrNOTCH, 266, 125, 156 }, // 6
84 { (Fl_Widget *)sldrSQUELCH, 266, 145, 156 }, // 7
85 { (Fl_Widget *)sldrMICGAIN, 266, 165, 156 }, // 8
86 { (Fl_Widget *)sldrPOWER, 54, 165, 368 }, // 9
87 { (Fl_Widget *)NULL, 0, 0, 0 }
88 };
89
90 // mid range on loudness
91 static string menu012 = "EX01200004";
92
initialize()93 void RIG_TS2000::initialize()
94 {
95 rig_widgets[0].W = btnVol;
96 rig_widgets[1].W = sldrVOLUME;
97 rig_widgets[2].W = sldrRFGAIN;
98 rig_widgets[3].W = btnIFsh;
99 rig_widgets[4].W = sldrIFSHIFT;
100 rig_widgets[5].W = btnNotch;
101 rig_widgets[6].W = sldrNOTCH;
102 rig_widgets[7].W = sldrSQUELCH;
103 rig_widgets[8].W = sldrMICGAIN;
104 rig_widgets[9].W = sldrPOWER;
105
106 menu012.clear();
107 cmd = "EX0120000;"; // read menu 012 state
108 //might return something like EX01200004;
109
110 if (wait_char(';', 11, 100, "read ex 012", ASC) == 11)
111 menu012 = replystr;
112
113 // disable beeps before resetting front panel display to SWR
114 cmd = "EX01200000;";
115 sendCommand(cmd);
116 sett("No beeps");
117 select_swr();
118
119 // restore state of xcvr beeps
120 // cmd = menu012;
121 // sendCommand(cmd);
122
123 // get current noise reduction values for NR1 and NR2
124 string current_nr;
125 cmd = "NR;";
126 if (wait_char(';', 4, 100, "read current NR", ASC) == 4)
127 current_nr = replystr;
128 if (current_nr == "?;") return;
129
130 cmd = "NR1;";
131 sendCommand(cmd);
132 gett("get NR");
133 cmd = "RL;";
134 if (wait_char(';', 5, 100, "GET noise reduction val", ASC) == 5) {
135 size_t p = replystr.rfind("RL");
136 if (p != string::npos)
137 _nrval1 = atoi(&replystr[p+2]);
138 }
139 cmd = "NR2;";
140 sendCommand(cmd);
141 gett("get NR value");
142
143 cmd = "RL;";
144 if (wait_char(';', 5, 100, "GET noise reduction val", ASC) == 5) {
145 size_t p = replystr.rfind("RL");
146 if (p != string::npos)
147 _nrval2 = atoi(&replystr[p+2]);
148 }
149
150 // restore xcvr setting for NR
151 cmd = current_nr;
152 sendCommand(cmd);
153 }
154
shutdown()155 void RIG_TS2000::shutdown()
156 {
157 // restore state of xcvr beeps
158 if (menu012.empty()) return;
159 cmd = menu012;
160 sendCommand(cmd);
161 sett("restore beeps");
162 }
163
164 static bool is_tuning = false;
165 static int skip_get = 2;
166
RIG_TS2000()167 RIG_TS2000::RIG_TS2000() {
168 // base class values
169 name_ = TS2000name_;
170 modes_ = TS2000modes_;
171 bandwidths_ = TS2000_empty;
172
173 dsp_SL = TS2000_SL;
174 SL_tooltip = TS2000_SL_tooltip;
175 SL_label = TS2000_SSB_btn_SL_label;
176
177 dsp_SH = TS2000_SH;
178 SH_tooltip = TS2000_SH_tooltip;
179 SH_label = TS2000_SSB_btn_SH_label;
180
181 widgets = rig_widgets;
182
183 comm_baudrate = BR4800;
184 stopbits = 2;
185 comm_retries = 2;
186 comm_wait = 5;
187 comm_timeout = 50;
188 comm_rtscts = true;
189 comm_rtsplus = false;
190 comm_dtrplus = false;
191 comm_catptt = true;
192 comm_rtsptt = false;
193 comm_dtrptt = false;
194 B.imode = A.imode = 1;
195 B.iBW = A.iBW = 0x8803;
196 B.freq = A.freq = 14070000;
197 can_change_alt_vfo = true;
198
199 has_power_out =
200 has_swr_control =
201 has_alc_control =
202 has_split =
203 has_split_AB =
204 has_dsp_controls =
205 has_rf_control =
206 has_notch_control =
207 has_auto_notch =
208 has_ifshift_control =
209 has_smeter =
210 has_noise_reduction =
211 has_noise_reduction_control =
212 has_noise_control =
213 has_micgain_control =
214 has_volume_control =
215 has_power_control =
216 has_tune_control =
217 has_attenuator_control =
218 has_preamp_control =
219 has_mode_control =
220 has_bandwidth_control =
221 has_sql_control =
222 has_ptt_control =
223 has_extras = true;
224
225 rxona = true;
226
227 precision = 1;
228 ndigits = 9;
229
230 att_level = 0;
231 preamp_level = 0;
232 _noise_reduction_level = 0;
233 _nrval1 = 2;
234 _nrval2 = 4;
235
236 is_tuning = false;
237 }
238
get_bwname_(int n,int md)239 const char * RIG_TS2000::get_bwname_(int n, int md)
240 {
241 static char bwname[20];
242 if (n > 256) {
243 int hi = (n >> 8) & 0x7F;
244 int lo = n & 0xFF;
245 snprintf(bwname, sizeof(bwname), "%s/%s",
246 (md == LSB || md == USB || md == FM) ? TS2000_SL[lo] : TS2000_AM_SL[lo],
247 (md == LSB || md == USB || md == FM) ? TS2000_SH[hi] : TS2000_AM_SH[hi] );
248 } else {
249 snprintf(bwname, sizeof(bwname), "%s",
250 (md == CW || md == CWR) ? TS2000_CWwidths[n] : TS2000_FSKwidths[n]);
251 }
252 return bwname;
253 }
254
get_smeter()255 int RIG_TS2000::get_smeter()
256 {
257 int smtr = 0;
258 if (rxona)
259 cmd = "SM0;";
260 else
261 cmd = "SM1;";
262 if (wait_char(';', 8, 100, "get smeter", ASC) == 8) {
263 size_t p = replystr.rfind("SM");
264 if (p != string::npos) {
265 smtr = fm_decimal(replystr.substr(p+3),4);
266 if (rxona)
267 smtr = (smtr * 100) / 30;
268 else
269 smtr = (smtr * 100) / 15;
270 }
271 }
272 gett("smeter");
273 return smtr;
274 }
275
276 // Transceiver power level
set_power_control(double val)277 void RIG_TS2000::set_power_control(double val)
278 {
279 int ival = (int)val;
280 cmd = "PC";
281 cmd.append(to_decimal(ival, 3)).append(";");
282 sendCommand(cmd);
283 showresp(WARN, ASC, "set pwr ctrl", cmd, "");
284 sett("pwr control");
285 }
286
get_power_out()287 int RIG_TS2000::get_power_out()
288 {
289 int poutmtr = 0;
290 cmd = "SM0;";
291 if (wait_char(';', 8, 100, "get power out", ASC) == 8) {
292 size_t p = replystr.rfind("SM0");
293 if (p != string::npos) {
294 poutmtr = fm_decimal(replystr.substr(p+3),4);
295 if (poutmtr <= 6) poutmtr = poutmtr * 2;
296 else if (poutmtr <= 11) poutmtr = 11 + (poutmtr - 6)*(26 - 11)/(11 - 6);
297 else if (poutmtr <= 18) poutmtr = 26 + (poutmtr - 11)*(50 - 26)/(18 - 11);
298 else poutmtr = 50 + (poutmtr - 18)*(100 - 50)/(27 - 18);
299 if (poutmtr > 100) poutmtr = 100;
300 }
301 }
302 gett("power out");
303 return poutmtr;
304 }
305
get_power_control()306 int RIG_TS2000::get_power_control()
307 {
308 int pctrl = 0;
309 cmd = "PC;";
310 if (wait_char(';', 6, 100, "get pout", ASC) == 6) {
311 size_t p = replystr.rfind("PC");
312 if (p != string::npos) {
313 pctrl = fm_decimal(replystr.substr(p+2), 3);
314 }
315 }
316 gett("power control");
317 return pctrl;
318 }
319
set_attenuator(int val)320 void RIG_TS2000::set_attenuator(int val)
321 {
322 att_level = val;
323 if (val) cmd = "RA01;";
324 else cmd = "RA00;";
325 sendCommand(cmd);
326 showresp(WARN, ASC, "set ATT", cmd, "");
327 sett("attenuator");
328 }
329
get_attenuator()330 int RIG_TS2000::get_attenuator()
331 {
332 cmd = "RA;";
333 if (wait_char(';', 7, 100, "get ATT", ASC) == 7) {
334 size_t p = replystr.rfind("RA");
335 if (p != string::npos && (p+3 < replystr.length())) {
336 if (replystr[p+2] == '0' && replystr[p+3] == '0')
337 att_level = 0;
338 else
339 att_level = 1;
340 }
341 }
342 gett("attenuator");
343 return att_level;
344 }
345
set_preamp(int val)346 void RIG_TS2000::set_preamp(int val)
347 {
348 preamp_level = val;
349 if (val) cmd = "PA1;";
350 else cmd = "PA0;";
351 sendCommand(cmd);
352 showresp(WARN, ASC, "set PRE", cmd, "");
353 sett("preamp");
354 }
355
get_preamp()356 int RIG_TS2000::get_preamp()
357 {
358 cmd = "PA;";
359 if (wait_char(';', 5, 100, "get PRE", ASC) == 5) {
360 size_t p = replystr.rfind("PA");
361 if (p != string::npos && (p+2 < replystr.length())) {
362 if (replystr[p+2] == '1')
363 preamp_level = 1;
364 else
365 preamp_level = 0;
366 }
367 }
368 gett("preamp");
369 return preamp_level;
370 }
371
set_widths(int val)372 int RIG_TS2000::set_widths(int val)
373 {
374 int bw;
375 switch (val) {
376 case LSB: case USB: case FM:
377 bandwidths_ = TS2000_SH;
378 dsp_SL = TS2000_SL;
379 SL_tooltip = TS2000_SL_tooltip;
380 SL_label = TS2000_SSB_btn_SL_label;
381 dsp_SH = TS2000_SH;
382 SH_tooltip = TS2000_SH_tooltip;
383 SH_label = TS2000_SSB_btn_SH_label;
384 if (val == FM) bw = 0x8A03; // 200 ... 4000 Hz
385 else bw = 0x8803; // 200 ... 3000 Hz
386 break;
387 case CW: case CWR:
388 bandwidths_ = TS2000_CWwidths;
389 dsp_SL = TS2000_empty;
390 dsp_SH = TS2000_empty;
391 bw = 7;
392 break;
393 case FSK: case FSKR:
394 bandwidths_ = TS2000_FSKwidths;
395 dsp_SL = TS2000_empty;
396 dsp_SH = TS2000_empty;
397 bw = 1;
398 break;
399 case AM: default:
400 bandwidths_ = TS2000_AM_SH;
401 dsp_SL = TS2000_AM_SL;
402 dsp_SH = TS2000_AM_SH;
403 bw = 0x8201;
404 break;
405 }
406 return bw;
407 }
408
bwtable(int val)409 const char **RIG_TS2000::bwtable(int val)
410 {
411 if (val == LSB || val == USB || val == FM)
412 return TS2000_SH;
413 else if (val == CW || val == CWR)
414 return TS2000_CWwidths;
415 else if (val == FSK || val == FSKR)
416 return TS2000_FSKwidths;
417 //else AM m == 4
418 return TS2000_AM_SH;
419 }
420
lotable(int val)421 const char **RIG_TS2000::lotable(int val)
422 {
423 if (val == LSB || val == USB || val == FM)
424 return TS2000_SL;
425 if (val == AM)
426 return TS2000_AM_SL;
427 return NULL;
428 }
429
hitable(int val)430 const char **RIG_TS2000::hitable(int val)
431 {
432 if (val == LSB || val == USB || val == FM)
433 return TS2000_SH;
434 if (val == AM)
435 return TS2000_AM_SH;
436 return NULL;
437 }
438
set_modeA(int val)439 void RIG_TS2000::set_modeA(int val)
440 {
441 if (val >= (int)(sizeof(TS2000_mode_chr)/sizeof(*TS2000_mode_chr))) return;
442 _currmode = A.imode = val;
443 cmd = "MD";
444 cmd += TS2000_mode_chr[val];
445 cmd += ';';
446 sendCommand(cmd);
447 showresp(WARN, ASC, "set mode", cmd, "");
448 sett("modeA");
449 A.iBW = set_widths(val);
450 }
451
get_modeA()452 int RIG_TS2000::get_modeA()
453 {
454 if (tuning()) return A.imode;
455 if (skip_get) {
456 skip_get--;
457 return A.imode;
458 }
459 cmd = "MD;";
460 if (wait_char(';', 4, 100, "get mode A", ASC) == 4) {
461 size_t p = replystr.rfind("MD");
462 if (p != string::npos) {
463 int md = replystr[p+2];
464 md = md - '1';
465 if (md == 8) md = 7;
466 A.imode = md;
467 A.iBW = set_widths(A.imode);
468 }
469 }
470 _currmode = A.imode;
471 gett("modeA");
472 return A.imode;
473 }
474
set_modeB(int val)475 void RIG_TS2000::set_modeB(int val)
476 {
477 if (val >= (int)(sizeof(TS2000_mode_chr)/sizeof(*TS2000_mode_chr))) return;
478 _currmode = B.imode = val;
479 cmd = "MD";
480 cmd += TS2000_mode_chr[val];
481 cmd += ';';
482 sendCommand(cmd);
483 showresp(WARN, ASC, "set mode B", cmd, "");
484 sett("modeB");
485 B.iBW = set_widths(val);
486 }
487
get_modeB()488 int RIG_TS2000::get_modeB()
489 {
490 if (tuning()) return B.imode;
491 if (skip_get) return B.imode;
492 cmd = "MD;";
493 if (wait_char(';', 4, 100, "get mode B", ASC) == 4) {
494 size_t p = replystr.rfind("MD");
495 if (p != string::npos) {
496 int md = replystr[p+2];
497 md = md - '1';
498 if (md == 8) md = 7;
499 B.imode = md;
500 B.iBW = set_widths(B.imode);
501 }
502 }
503 _currmode = B.imode;
504 gett("modeB");
505 return B.imode;
506 }
507
adjust_bandwidth(int val)508 int RIG_TS2000::adjust_bandwidth(int val)
509 {
510 int bw = 0;
511 if (val == LSB || val == USB)
512 bw = 0x8803;
513 else if (val == FM)
514 bw = 0x8A03;
515 else if (val == AM)
516 bw = 0x8301;
517 else if (val == CW || val == CWR)
518 bw = 7;
519 else if (val == FSK || val == FSKR)
520 bw = 1;
521 return bw;
522 }
523
def_bandwidth(int val)524 int RIG_TS2000::def_bandwidth(int val)
525 {
526 return adjust_bandwidth(val);
527 }
528
set_bwA(int val)529 void RIG_TS2000::set_bwA(int val)
530 {
531 if (A.imode == LSB || A.imode == USB || A.imode == FM || A.imode == AM) {
532 if (val < 256) return;
533 A.iBW = val;
534 cmd = "SL";
535 int index = A.iBW & 0x7F;
536 if (index >= (int)(sizeof(TS2000_CAT_SL)/sizeof(*TS2000_CAT_SL))) return;
537 cmd = TS2000_CAT_SL[index];
538 sendCommand(cmd);
539 showresp(WARN, ASC, "set lower", cmd, "");
540 sett("bwA lower");
541 cmd = "SH";
542 index = (A.iBW >> 8) & 0x7F;
543 if (index >= (int)(sizeof(TS2000_CAT_SH)/sizeof(*TS2000_CAT_SH))) return;
544 cmd = TS2000_CAT_SH[index];
545 sendCommand(cmd);
546 showresp(WARN, ASC, "set upper", cmd, "");
547 sett("bwA upper");
548 }
549 if (val > 256) return;
550 else if (A.imode == CW || A.imode == CWR) {
551 A.iBW = val;
552 int index = A.iBW & 0x7F;
553 if (index >= (int)(sizeof(TS2000_CWbw)/sizeof(*TS2000_CWbw))) return;
554 cmd = TS2000_CWbw[index];
555 sendCommand(cmd);
556 showresp(WARN, ASC, "set CW bw", cmd, "");
557 sett("CW bw");
558 }else if (A.imode == FSK || A.imode == FSKR) {
559 A.iBW = val;
560 int index = A.iBW & 0x7F;
561 if (index >= (int)(sizeof(TS2000_FSKbw)/sizeof(*TS2000_FSKbw))) return;
562 cmd = TS2000_FSKbw[index];
563 sendCommand(cmd);
564 showresp(WARN, ASC, "set FSK bw", cmd, "");
565 sett("FSK bw");
566 }
567 }
568
get_bwA()569 int RIG_TS2000::get_bwA()
570 {
571 if (tuning()) return A.iBW;
572 if (skip_get) return A.iBW;
573 size_t i = 0;
574 size_t p;
575 if (A.imode == LSB || A.imode == USB || A.imode == FM || A.imode == AM) {
576 int lo = A.iBW & 0xFF, hi = (A.iBW >> 8) & 0x7F;
577 cmd = "SL;";
578 if (wait_char(';', 5, 100, "get SL", ASC) == 5) {
579 p = replystr.rfind("SL");
580 if (p != string::npos)
581 lo = fm_decimal(replystr.substr(2), 2);
582 }
583 gett("bwA lower");
584 cmd = "SH;";
585 if (wait_char(';', 5, 100, "get SH", ASC) == 5) {
586 p = replystr.rfind("SH");
587 if (p != string::npos)
588 hi = fm_decimal(replystr.substr(2), 2);
589 A.iBW = ((hi << 8) | (lo & 0xFF)) | 0x8000;
590 }
591 gett("bwA upper");
592 } else if (A.imode == CW || A.imode == CWR) { // CW
593 cmd = "FW;";
594 if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
595 p = replystr.rfind("FW");
596 if (p != string::npos) {
597 for (i = 0; i < sizeof(TS2000_CWbw)/sizeof(*TS2000_CWbw); i++)
598 if (replystr.find(TS2000_CWbw[i]) == p)
599 break;
600 A.iBW = i;
601 }
602 }
603 gett("bwA CW");
604 } else if (A.imode == FSK || A.imode == FSKR) {
605 cmd = "FW;";
606 if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
607 p = replystr.rfind("FW");
608 if (p != string::npos) {
609 for (i = 0; i < sizeof(TS2000_FSKbw)/sizeof(*TS2000_FSKbw); i++)
610 if (replystr.find(TS2000_FSKbw[i]) == p)
611 break;
612 A.iBW = i;
613 }
614 }
615 gett("bwA FSK");
616 }
617 return A.iBW;
618 }
619
set_bwB(int val)620 void RIG_TS2000::set_bwB(int val)
621 {
622 if (B.imode == LSB || B.imode == USB || B.imode == FM || B.imode == AM) {
623 if (val < 256) return;
624 B.iBW = val;
625 cmd = "SL";
626 int index = B.iBW & 0x7F;
627 if (index >= (int)(sizeof(TS2000_CAT_SL)/sizeof(*TS2000_CAT_SL))) return;
628 cmd = TS2000_CAT_SL[index];
629 sendCommand(cmd);
630 showresp(WARN, ASC, "set lower", cmd, "");
631 sett("bwB lower");
632 cmd = "SH";
633 index = (B.iBW >> 8) & 0x7F;
634 if (index >= (int)(sizeof(TS2000_CAT_SH)/sizeof(*TS2000_CAT_SH))) return;
635 cmd = TS2000_CAT_SH[index];
636 sendCommand(cmd);
637 showresp(WARN, ASC, "set upper", cmd, "");
638 sett("bwB upper");
639 }
640 if (val > 256) return;
641 else if (B.imode == CW || B.imode == CWR) {
642 B.iBW = val;
643 int index = B.iBW & 0x7F;
644 if (index >= (int)(sizeof(TS2000_CWbw)/sizeof(*TS2000_CWbw))) return;
645 cmd = TS2000_CWbw[index];
646 sendCommand(cmd);
647 showresp(WARN, ASC, "set CW bw", cmd, "");
648 sett("bwB CW");
649 }else if (B.imode == FSK || B.imode == FSKR) {
650 B.iBW = val;
651 int index = B.iBW & 0x7F;
652 if (index >= (int)(sizeof(TS2000_FSKbw)/sizeof(*TS2000_FSKbw))) return;
653 cmd = TS2000_FSKbw[index];
654 sendCommand(cmd);
655 showresp(WARN, ASC, "set FSK bw", cmd, "");
656 sett("bwB FSK");
657 }
658 }
659
get_bwB()660 int RIG_TS2000::get_bwB()
661 {
662 if (tuning()) return B.iBW;
663 if (skip_get) return B.iBW;
664 size_t i = 0;
665 size_t p;
666 if (B.imode == LSB || B.imode == USB || B.imode == FM || B.imode == AM) {
667 int lo = B.iBW & 0xFF, hi = (B.iBW >> 8) & 0x7F;
668 cmd = "SL;";
669 if (wait_char(';', 5, 100, "get SL", ASC) == 5) {
670 p = replystr.rfind("SL");
671 if (p != string::npos)
672 lo = fm_decimal(replystr.substr(2), 2);
673 }
674 gett("bwB lower");
675 cmd = "SH;";
676 if (wait_char(';', 5, 100, "get SH", ASC) == 5) {
677 p = replystr.rfind("SH");
678 if (p != string::npos)
679 hi = fm_decimal(replystr.substr(2), 2);
680 B.iBW = ((hi << 8) | (lo & 0xFF)) | 0x8000;
681 }
682 gett("bwB upper");
683 } else if (B.imode == CW || B.imode == CWR) {
684 cmd = "FW;";
685 if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
686 p = replystr.rfind("FW");
687 if (p != string::npos) {
688 for (i = 0; i < sizeof(TS2000_CWbw)/sizeof(*TS2000_CWbw); i++)
689 if (replystr.find(TS2000_CWbw[i]) == p)
690 break;
691 B.iBW = i;
692 }
693 }
694 gett("bwB CW");
695 } else if (B.imode == FSK || B.imode == FSKR) {
696 cmd = "FW;";
697 if (wait_char(';', 7, 100, "get FW", ASC) == 7) {
698 p = replystr.rfind("FW");
699 if (p != string::npos) {
700 for (i = 0; i < sizeof(TS2000_FSKbw)/sizeof(*TS2000_FSKbw); i++)
701 if (replystr.find(TS2000_FSKbw[i]) == p)
702 break;
703 B.iBW = i;
704 }
705 }
706 gett("bwB FSK");
707 }
708 return B.iBW;
709 }
710
get_modetype(int n)711 int RIG_TS2000::get_modetype(int n)
712 {
713 if (n >= (int)(sizeof(TS2000_mode_type)/sizeof(*TS2000_mode_type))) return 0;
714 return TS2000_mode_type[n];
715 }
716
get_if_min_max_step(int & min,int & max,int & step)717 void RIG_TS2000::get_if_min_max_step(int &min, int &max, int &step)
718 {
719 if_shift_min = min = 400;
720 if_shift_max = max = 1000;
721 if_shift_step = step = 50;
722 if_shift_mid = 700;
723 }
724
set_notch(bool on,int val)725 void RIG_TS2000::set_notch(bool on, int val)
726 {
727 if (on) {
728 cmd = "BC2;"; // set manual notch
729 sendCommand(cmd);
730 showresp(WARN, ASC, "set notch on", cmd, "");
731 sett("notch ON");
732 cmd = "BP";
733 // val = round((val - 220) / 50);
734 val = round((val - 200) / 50);
735 cmd.append(to_decimal(val, 3)).append(";");
736 sendCommand(cmd);
737 showresp(WARN, ASC, "set notch val", cmd, "");
738 sett("notch val");
739 } else {
740 cmd = "BC0;"; // no notch action
741 sendCommand(cmd);
742 showresp(WARN, ASC, "set notch off", cmd, "");
743 sett("notch OFF");
744 }
745 }
746
get_notch(int & val)747 bool RIG_TS2000::get_notch(int &val)
748 {
749 bool ison = false;
750 cmd = "BC;";
751 if (wait_char(';', 4, 100, "get notch on/off", ASC) == 4) {
752 size_t p = replystr.rfind("BC");
753 if (p != string::npos) {
754 if (replystr[p+2] == '2') {
755 ison = true;
756 cmd = "BP;";
757 if (wait_char(';', 6, 100, "get notch val", ASC) == 6) {
758 gett("notch val");
759 p = replystr.rfind("BP");
760 if (p != string::npos)
761 val = 200 + 50 * fm_decimal(replystr.substr(p+2),3);
762 }
763 }
764 }
765 }
766 gett("notch on/off");
767 return (ison);
768 }
769
get_notch_min_max_step(int & min,int & max,int & step)770 void RIG_TS2000::get_notch_min_max_step(int &min, int &max, int &step)
771 {
772 min = 200;
773 max = 3350;
774 step = 50;
775 }
776
set_auto_notch(int v)777 void RIG_TS2000::set_auto_notch(int v)
778 {
779 cmd = v ? "NT1;" : "NT0;";
780 sendCommand(cmd);
781 showresp(WARN, ASC, "set auto notch", cmd, "");
782 sett("auto notch");
783 }
784
get_auto_notch()785 int RIG_TS2000::get_auto_notch()
786 {
787 int anotch = 0;
788 cmd = "NT;";
789 if (wait_char(';', 4, 100, "get auto notch", ASC) == 4) {
790 size_t p = replystr.rfind("NT");
791 if (p != string::npos) {
792 anotch = (replystr[p+2] == '1');
793 }
794 }
795 gett("auto notch");
796 return anotch;
797 }
798
set_noise_reduction(int val)799 void RIG_TS2000::set_noise_reduction(int val)
800 {
801 if (val == -1) {
802 return;
803 }
804 _noise_reduction_level = val;
805 if (_noise_reduction_level == 0) {
806 nr_label("NR", false);
807 } else if (_noise_reduction_level == 1) {
808 nr_label("NR1", true);
809 } else if (_noise_reduction_level == 2) {
810 nr_label("NR2", true);
811 }
812 cmd.assign("NR");
813 cmd += '0' + _noise_reduction_level;
814 cmd += ';';
815 sendCommand (cmd);
816 showresp(WARN, ASC, "SET noise reduction", cmd, "");
817 sett("noise reduction");
818 }
819
get_noise_reduction()820 int RIG_TS2000::get_noise_reduction()
821 {
822 cmd = rsp = "NR";
823 cmd.append(";");
824 if (wait_char(';', 4, 100, "GET noise reduction", ASC) == 4) {
825 size_t p = replystr.rfind(rsp);
826 if (p == string::npos) return _noise_reduction_level;
827 _noise_reduction_level = replystr[p+2] - '0';
828 }
829 if (replystr == "?;") {
830 _noise_reduction_level = 0;
831 return 0;
832 }
833
834 if (_noise_reduction_level == 1) {
835 nr_label("NR1", true);
836 } else if (_noise_reduction_level == 2) {
837 nr_label("NR2", true);
838 } else {
839 nr_label("NR", false);
840 }
841 gett("nr level");
842 return _noise_reduction_level;
843 }
844
set_noise_reduction_val(int val)845 void RIG_TS2000::set_noise_reduction_val(int val)
846 {
847 if (_noise_reduction_level == 0) return;
848 if (_noise_reduction_level == 1) _nrval1 = val;
849 else _nrval2 = val;
850
851 cmd.assign("RL").append(to_decimal(val, 2)).append(";");
852 sendCommand(cmd);
853 showresp(WARN, ASC, "SET_noise_reduction_val", cmd, "");
854 sett("noise reduction val");
855 }
856
get_noise_reduction_val()857 int RIG_TS2000::get_noise_reduction_val()
858 {
859 int nrval = 0;
860 if (_noise_reduction_level == 0) return 0;
861 int val = progStatus.noise_reduction_val;
862 cmd = rsp = "RL";
863 cmd.append(";");
864 if (wait_char(';', 5, 100, "GET noise reduction val", ASC) == 5) {
865 size_t p = replystr.rfind(rsp);
866 if (p == string::npos) {
867 nrval = (_noise_reduction_level == 1 ? _nrval1 : _nrval2);
868 return nrval;
869 }
870 val = atoi(&replystr[p+2]);
871 }
872 gett("noise reduction val");
873
874 if (_noise_reduction_level == 1) _nrval1 = val;
875 else _nrval2 = val;
876
877 return val;
878 }
879