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 "config.h"
22 
23 #include "TS590SG.h"
24 #include "support.h"
25 
26 static const char TS590SGname_[] = "TS-590SG";
27 
28 static const char *TS590SGmodes_[] = {
29 "LSB", "USB",  "CW", "FM", "AM", "FSK", "CW-R", "FSK-R",
30 "LSB-D", "USB-D", "FM-D", NULL};
31 
32 static const char TS590SG_mode_chr[] =  {
33 '1', '2', '3', '4', '5', '6', '7', '9',
34 '1', '2', '4' };
35 static const char TS590SG_mode_type[] = {
36 'L', 'U', 'U', 'U', 'U', 'L', 'L', 'U',
37 'L', 'U', 'U' };
38 
39 //----------------------------------------------------------------------
40 static const char *TS590SG_empty[] = { "N/A", NULL };
41 
42 //----------------------------------------------------------------------
43 static int DEF_SL_SH = 0x8A03;
44 static const char *TS590SG_SSB_SL[] = {
45   "0",   "50", "100", "200", "300",
46 "400",  "500", "600", "700", "800",
47 "900", "1000", NULL };
48 
49 static const char *TS590SG_CAT_ssb_SL[] = {
50 "SL00;", "SL01;", "SL02;", "SL03;", "SL04;",
51 "SL05;", "SL06;", "SL07;", "SL08;", "SL09;",
52 "SL10;", "SL11;", NULL };
53 static const char *TS590SG_SSB_SL_tooltip = "lo cut";
54 static const char *TS590SG_SSB_btn_SL_label = "L";
55 
56 static const char *TS590SG_SSB_SH[] = {
57 "1000", "1200", "1400", "1600", "1800",
58 "2000", "2200", "2400", "2600", "2800",
59 "3000", "3400", "4000", "5000", NULL };
60 
61 static const char *TS590SG_CAT_ssb_SH[] = {
62 "SH00;", "SH01;", "SH02;", "SH03;", "SH04;",
63 "SH05;", "SH06;", "SH07;", "SH08;", "SH09;",
64 "SH10;", "SH11;", "SH12;", "SH13;", NULL };
65 static const char *TS590SG_SSB_SH_tooltip = "hi cut";
66 static const char *TS590SG_SSB_btn_SH_label = "H";
67 
68 //----------------------------------------------------------------------
69 static int DEF_width_shift = 0x8D05;
70 static const char *TS590SG_DATA_width[] = {
71   "50",   "80",  "100",  "150", "200",
72  "250",  "300",  "400",  "500", "600",
73 "1000", "1500", "2000", "2500",  NULL };
74 
75 static const char *TS590SG_CAT_data_width[] = {
76 "SL00;", "SL01;", "SL02;", "SL03;", "SL04;",
77 "SL05;", "SL06;", "SL07;", "SL08;", "SL09;",
78 "SL10;", "SL11;", "SL12;", "SL13;", NULL };
79 static const char *TS590SG_DATA_W_tooltip = "width";
80 static const char *TS590SG_DATA_W_btn_label = "W";
81 
82 static const char *TS590SG_DATA_shift[] = {
83 "1000", "1100", "1200", "1300", "1400",
84 "1500", "1600", "1700", "1800", "1900",
85 "2000", "2100", "2210", NULL };
86 
87 static const char *TS590SG_CAT_data_shift[] = {
88 "SH00;", "SH01;", "SH02;", "SH03;", "SH04;",
89 "SH05;", "SH06;", "SH07;", "SH08;", "SH09;",
90 "SH10;", "SH11;", "SH12;", NULL };
91 static const char *TS590SG_DATA_S_tooltip = "shift";
92 static const char *TS590SG_DATA_S_btn_label = "S";
93 
94 //----------------------------------------------------------------------
95 static int DEF_am = 0x8201;
96 static const char *TS590SG_AM_SL[] = {
97 "10", "100", "200", "500", NULL };
98 
99 static const char *TS590SG_CAT_am_SL[] = {
100 "SL00;", "SL01;", "SL02;", "SL03;", NULL};
101 static const char *TS590SG_AM_SL_tooltip = "lo cut";
102 static const char *TS590SG_AM_btn_SL_label = "L";
103 
104 static const char *TS590SG_AM_SH[] = {
105 "2500", "3000", "4000", "5000", NULL };
106 
107 static const char *TS590SG_CAT_am_SH[] = {
108 "SH00;", "SH01;", "SH02;", "SH03;", NULL};
109 static const char *TS590SG_AM_SH_tooltip = "hi cut";
110 static const char *TS590SG_AM_btn_SH_label = "H";
111 
112 //----------------------------------------------------------------------
113 static int  DEF_cw = 7;
114 static const char *TS590SG_CWwidths[] = {
115   "50",   "80",  "100",  "150", "200",
116  "250",  "300",  "400",  "500", "600",
117 "1000", "1500", "2000", "2500",  NULL};
118 
119 static const char *TS590SG_CWbw[] = {
120 "FW0050;", "FW0080;", "FW0100;", "FW0150;", "FW0200;",
121 "FW0250;", "FW0300;", "FW0400;", "FW0500;", "FW0600;",
122 "FW1000;", "FW1500;", "FW2000;", "FW2500;", NULL};
123 
124 //----------------------------------------------------------------------
125 static int  DEF_fsk = 1;
126 static const char *TS590SG_FSKwidths[] = {
127 "250", "500", "1000", "1500", NULL};
128 
129 static const char *TS590SG_FSKbw[] = {
130 "FW0250;", "FW0500;", "FW1000;", "FW1500;", NULL };
131 
132 //----------------------------------------------------------------------
133 
134 static GUI rig_widgets[]= {
135 	{ (Fl_Widget *)btnVol,        2, 125,  50 }, // 0
136 	{ (Fl_Widget *)sldrVOLUME,   54, 125, 156 }, // 1
137 	{ (Fl_Widget *)sldrRFGAIN,   54, 145, 156 }, // 2
138 	{ (Fl_Widget *)btnNR,         2, 165,  50 }, // 3
139 	{ (Fl_Widget *)sldrNR,       54, 165, 156 }, // 4
140 	{ (Fl_Widget *)sldrPOWER,    54, 185, 368 }, // 5
141 	{ (Fl_Widget *)btnIFsh,     214, 105,  50 }, // 6
142 	{ (Fl_Widget *)sldrIFSHIFT, 266, 105, 156 }, // 7
143 	{ (Fl_Widget *)btnNotch,    214, 125,  50 }, // 8
144 	{ (Fl_Widget *)sldrNOTCH,   266, 125, 156 }, // 9
145 	{ (Fl_Widget *)sldrSQUELCH, 266, 145, 156 }, // 10
146 	{ (Fl_Widget *)sldrMICGAIN, 266, 165, 156 }, // 11
147 	{ (Fl_Widget *)NULL,          0,   0,   0 }
148 };
149 
150 static string menu005;
151 
initialize()152 void RIG_TS590SG::initialize()
153 {
154 	rig_widgets[0].W = btnVol;
155 	rig_widgets[1].W = sldrVOLUME;
156 	rig_widgets[2].W = sldrRFGAIN;
157 	rig_widgets[3].W = btnNR;
158 	rig_widgets[4].W = sldrNR;
159 	rig_widgets[5].W = sldrPOWER;
160 	rig_widgets[6].W = btnIFsh;
161 	rig_widgets[7].W = sldrIFSHIFT;
162 	rig_widgets[8].W = btnNotch;
163 	rig_widgets[9].W = sldrNOTCH;
164 	rig_widgets[10].W = sldrSQUELCH;
165 	rig_widgets[11].W = sldrMICGAIN;
166 
167 //	cmd = "EX0050000;";
168 //	if (wait_char(';', 11, 100, "read ex 003", ASC) == 11)
169 //		menu005 = replystr;
170 //	cmd = "EX005000000;";
171 //	sendCommand(cmd);
172 
173 	cmd = "AC000;"; sendCommand(cmd);
174 	selectA();
175 	get_preamp();
176 	get_attenuator();
177 }
178 
shutdown()179 void RIG_TS590SG::shutdown()
180 {
181 // restore state of xcvr beeps
182 //	cmd = menu005;
183 //	sendCommand(cmd);
184 }
185 
186 
RIG_TS590SG()187 RIG_TS590SG::RIG_TS590SG() {
188 
189 	name_ = TS590SGname_;
190 	modes_ = TS590SGmodes_;
191 	bandwidths_ = TS590SG_SSB_SH;
192 
193 	dsp_SL     = TS590SG_SSB_SL;
194 	SL_tooltip = TS590SG_SSB_SL_tooltip;
195 	SL_label   = TS590SG_SSB_btn_SL_label;
196 
197 	dsp_SH     = TS590SG_SSB_SH;
198 	SH_tooltip = TS590SG_SSB_SH_tooltip;
199 	SH_label   = TS590SG_SSB_btn_SH_label;
200 
201 	widgets = rig_widgets;
202 
203 	comm_baudrate = BR115200;
204 	stopbits = 1;
205 	comm_retries = 2;
206 	comm_wait = 5;
207 	comm_timeout = 50;
208 	comm_rtscts = true;
209 	comm_rtsplus = false;
210 	comm_dtrplus = false;
211 	comm_catptt = true;
212 	comm_rtsptt = false;
213 	comm_dtrptt = false;
214 
215 	B.imode = A.imode = USB;
216 	B.iBW = A.iBW = DEF_SL_SH;
217 	B.freq = A.freq = 14070000;
218 	can_change_alt_vfo = true;
219 
220 	nb_level = 2;
221 
222 	has_micgain_control =
223 	has_ifshift_control = false;
224 
225 	has_auto_notch =
226 	has_notch_control =
227 	has_sql_control =
228 	has_swr_control =
229 	has_noise_reduction =
230 	has_noise_reduction_control =
231 	has_alc_control =
232 	has_dsp_controls =
233 	has_smeter =
234 	has_power_out =
235 	has_split =
236 	has_split_AB =
237 	has_noise_control =
238 	has_micgain_control =
239 	has_rf_control =
240 	has_volume_control =
241 	has_power_control =
242 	has_tune_control =
243 	has_attenuator_control =
244 	has_preamp_control =
245 	has_mode_control =
246 	has_bandwidth_control =
247 	has_ifshift_control =
248 	has_ptt_control = true;
249 
250 	rxtxa = true;
251 
252 	precision = 1;
253 	ndigits = 8;
254 
255 	att_level = 0;
256 	preamp_level = 0;
257 	noise_reduction_level = 0;
258 }
259 
get_bwname_(int n,int md)260 const char * RIG_TS590SG::get_bwname_(int n, int md)
261 {
262 	static char bwname[20];
263 	if (n > 256) {
264 		int hi = (n >> 8) & 0x7F;
265 		int lo = n & 0xFF;
266 		snprintf(bwname, sizeof(bwname), "%s/%s",
267 			(md == LSB || md == USB || md == FM) ? TS590SG_SSB_SL[lo] :
268 			(md == AM) ? TS590SG_AM_SL[lo] :
269 			TS590SG_DATA_width[lo],
270 			(md == LSB || md == USB || md == FM) ? TS590SG_SSB_SH[hi] :
271 			(md == AM) ? TS590SG_AM_SH[hi] :
272 			TS590SG_DATA_shift[hi] );
273 	} else {
274 		snprintf(bwname, sizeof(bwname), "%s",
275 			(md == CW || md == CWR) ? TS590SG_CWwidths[n] : TS590SG_FSKwidths[n]);
276 	}
277 	return bwname;
278 }
279 
get_smeter()280 int RIG_TS590SG::get_smeter()
281 {
282 	int mtr = 0;
283 	cmd = "SM0;";
284 	if (wait_char(';', 8, 100, "get", ASC) < 8) return 0;
285 
286 	size_t p = replystr.find("SM0");
287 	if (p == string::npos) return 0;
288 
289 	replystr[p + 7] = 0;
290 	mtr = atoi(&replystr[p + 3]);
291 	mtr *= 50;
292 	mtr /= 15;
293 	if (mtr > 100) mtr = 100;
294 	return mtr;
295 }
296 
get_power_out()297 int RIG_TS590SG::get_power_out()
298 {
299 	int mtr = 0;
300 	cmd = "SM0;";
301 	if (wait_char(';', 8, 100, "get power", ASC) < 8) return mtr;
302 
303 	size_t p = replystr.rfind("SM0");
304 	if (p == string::npos) return mtr;
305 
306 	mtr = atoi(&replystr[p + 3]);
307 	mtr *= 50;
308 	mtr /= 18;
309 	if (mtr > 100) mtr = 100;
310 
311 	return mtr;
312 }
313 
314 // Transceiver power level
set_power_control(double val)315 void RIG_TS590SG::set_power_control(double val)
316 {
317 	int ival = (int)val;
318 	cmd = "PC000;";
319 	for (int i = 4; i > 1; i--) {
320 		cmd[i] += ival % 10;
321 		ival /= 10;
322 	}
323 	sendCommand(cmd, 0);
324 }
325 
get_power_control()326 int RIG_TS590SG::get_power_control()
327 {
328 	cmd = "PC;";
329 	if (wait_char(';', 6, 100, "get pwr ctrl", ASC) < 6) return 0;
330 
331 	size_t p = replystr.rfind("PC");
332 	if (p == string::npos) return 0;
333 	int mtr = 0;
334 	replystr[p + 5] = 0;
335 	mtr = atoi(&replystr[p + 2]);
336 	return mtr;
337 }
338 
set_attenuator(int val)339 void RIG_TS590SG::set_attenuator(int val)
340 {
341 	att_level = val;
342 	if (val) cmd = "RA01;";
343 	else     cmd = "RA00;";
344 	sendCommand(cmd, 0);
345 }
346 
get_attenuator()347 int RIG_TS590SG::get_attenuator()
348 {
349 	cmd = "RA;";
350 	if (wait_char(';', 7, 100, "get att", ASC) < 7) return 0;
351 
352 	size_t p = replystr.rfind("RA");
353 	if (p == string::npos) return 0;
354 
355 	if (replystr[p + 2] == '0' &&
356 		replystr[p + 3] == '0')
357 		att_level = 0;
358 	else
359 		att_level = 1;
360 
361 	return att_level;
362 }
363 
set_preamp(int val)364 void RIG_TS590SG::set_preamp(int val)
365 {
366 	preamp_level = val;
367 	if (val) cmd = "PA1;";
368 	else     cmd = "PA0;";
369 	sendCommand(cmd, 0);
370 }
371 
get_preamp()372 int RIG_TS590SG::get_preamp()
373 {
374 	cmd = "PA;";
375 	if (wait_char(';', 5, 100, "get preamp", ASC) < 5) return 0;
376 
377 	size_t p = replystr.rfind("PA");
378 	if (p == string::npos) return 0;
379 
380 	if (replystr[p  + 2] == '1')
381 		preamp_level = 1;
382 	else
383 		preamp_level = 0;
384 	return preamp_level;
385 }
386 
387 //======================================================================
388 // mode commands
389 //======================================================================
390 
set_modeA(int val)391 void RIG_TS590SG::set_modeA(int val)
392 {
393 	active_mode = A.imode = val;
394 	cmd = "MD";
395 	cmd += TS590SG_mode_chr[val];
396 	cmd += ';';
397 	sendCommand(cmd, 0);
398 	showresp(ERR, ASC, "set mode A", cmd, "");
399 	if ( val == LSBD || val == USBD || val == FMD) {
400 		data_mode = true;
401 		cmd = "DA1;";
402 		sendCommand(cmd, 0);
403 		showresp(WARN, ASC, "set data A", cmd, "");
404 	} else if (val == LSB || val == USB || val == FM) {
405 		data_mode = false;
406 		cmd = "DA0;";
407 		sendCommand(cmd, 0);
408 		showresp(WARN, ASC, "set data A", cmd, "");
409 	}
410 	set_widths(val);
411 }
412 
get_modeA()413 int RIG_TS590SG::get_modeA()
414 {
415 	int md = A.imode;
416 	cmd = "MD;";
417 	if (wait_char(';', 4, 100, "get mode A", ASC) < 4) return A.imode;
418 
419 	size_t p = replystr.rfind("MD");
420 	if (p == string::npos) return A.imode;
421 
422 	switch (replystr[p + 2]) {
423 		case '1' : md = LSB; break;
424 		case '2' : md = USB; break;
425 		case '3' : md = CW; break;
426 		case '4' : md = FM; break;
427 		case '5' : md = AM; break;
428 		case '6' : md = FSK; break;
429 		case '7' : md = CWR; break;
430 		case '9' : md = FSKR; break;
431 		default : md = A.imode;
432 	}
433 
434 	if (md == LSB || md == USB || md == FM) {
435 		cmd = "DA;";
436 		if (wait_char(';', 4, 100, "get data A", ASC) < 4) return A.imode;
437 
438 		p = replystr.rfind("DA");
439 		if (p == string::npos) return A.imode;
440 		if (replystr[p + 2] == '1') {
441 			data_mode = true;
442 			if (md == LSB) md = LSBD;
443 			else if (md == USB) md = USBD;
444 			else if (md == FM) md = FMD;
445 		}
446 	}
447 	if (md != A.imode) {
448 		active_mode = A.imode = md;
449 		set_widths(md);
450 	}
451 	return A.imode;
452 }
453 
set_modeB(int val)454 void RIG_TS590SG::set_modeB(int val)
455 {
456 	active_mode = B.imode = val;
457 	cmd = "MD";
458 	cmd += TS590SG_mode_chr[val];
459 	cmd += ';';
460 	sendCommand(cmd, 0);
461 	showresp(WARN, ASC, "set mode B", cmd, "");
462 	if ( val == LSBD || val == USBD || val == FMD) {
463 		data_mode = true;
464 		cmd = "DA1;";
465 		sendCommand(cmd, 0);
466 		showresp(WARN, ASC, "set data B", cmd, "");
467 	} else if (val == LSB || val == USB || val == FM) {
468 		cmd = "DA0;";
469 		sendCommand(cmd, 0);
470 		showresp(WARN, ASC, "set data B", cmd, "");
471 	}
472 	set_widths(val);
473 }
474 
get_modeB()475 int RIG_TS590SG::get_modeB()
476 {
477 	int md = B.imode;
478 	cmd = "MD;";
479 	if (wait_char(';', 4, 100, "get mode B", ASC) < 4) return B.imode;
480 
481 	size_t p = replystr.rfind("MD");
482 	if (p == string::npos) return B.imode;
483 
484 	switch (replystr[p + 2]) {
485 		case '1' : md = LSB; break;
486 		case '2' : md = USB; break;
487 		case '3' : md = CW; break;
488 		case '4' : md = FM; break;
489 		case '5' : md = AM; break;
490 		case '6' : md = FSK; break;
491 		case '7' : md = CWR; break;
492 		case '9' : md = FSKR; break;
493 		default : md = B.imode;
494 	}
495 
496 	if (md == LSB || md == USB || md == FM) {
497 		cmd = "DA;";
498 		if (wait_char(';', 4, 100, "get dat B", ASC) < 4) return B.imode;
499 
500 		p = replystr.rfind("DA");
501 		if (p == string::npos) return B.imode;
502 		if (replystr[p + 2] == '1') {
503 			data_mode = true;
504 			if (md == LSB) md = LSBD;
505 			else if (md == USB) md = USBD;
506 			else if (md == FM) md = FMD;
507 		}
508 	}
509 	if (md != B.imode) {
510 		active_mode = B.imode = md;
511 		set_widths(md);
512 	}
513 	return B.imode;
514 }
515 
516 //======================================================================
517 // Bandpass filter commands
518 //======================================================================
519 
set_widths(int val)520 int RIG_TS590SG::set_widths(int val)
521 {
522 	int bw = 0;
523 	if (val == LSB || val == USB || val == FM || val == FMD) {
524 		bandwidths_ = TS590SG_SSB_SH;
525 		dsp_SL = TS590SG_SSB_SL;
526 		dsp_SH = TS590SG_SSB_SH;
527 		SL_tooltip = TS590SG_SSB_SL_tooltip;
528 		SL_label   = TS590SG_SSB_btn_SL_label;
529 		SH_tooltip = TS590SG_SSB_SH_tooltip;
530 		SH_label   = TS590SG_SSB_btn_SH_label;
531 		bw = DEF_SL_SH; // 200 lower, 3000 upper
532 	} else if (val == CW || val == CWR) {
533 		bandwidths_ = TS590SG_CWwidths;
534 		dsp_SL = TS590SG_empty;
535 		dsp_SH = TS590SG_empty;
536 		bw = DEF_cw;
537 	} else if (val == FSK || val == FSKR) {
538 		bandwidths_ = TS590SG_FSKwidths;
539 		dsp_SL = TS590SG_empty;
540 		dsp_SH = TS590SG_empty;
541 		bw = 1;
542 	} else if (val == AM) { // val == 4 ==> AM
543 		bandwidths_ = TS590SG_AM_SH;
544 		dsp_SL = TS590SG_AM_SL;
545 		dsp_SH = TS590SG_AM_SH;
546 		SL_tooltip = TS590SG_AM_SL_tooltip;
547 		SL_label   = TS590SG_AM_btn_SL_label;
548 		SH_tooltip = TS590SG_AM_SH_tooltip;
549 		SH_label   = TS590SG_AM_btn_SH_label;
550 		bw = DEF_am;
551 	} else if (val == LSBD || val == USBD) {
552 		bandwidths_ = TS590SG_DATA_width;
553 
554 		dsp_SL = TS590SG_DATA_shift;
555 		SL_tooltip = TS590SG_DATA_S_tooltip;
556 		SL_label   = TS590SG_DATA_S_btn_label;
557 
558 		dsp_SH = TS590SG_DATA_width;
559 		SH_tooltip = TS590SG_DATA_W_tooltip;
560 		SH_label   = TS590SG_DATA_W_btn_label;
561 		bw = DEF_width_shift;
562 	}
563 	return bw;
564 }
565 
bwtable(int m)566 const char **RIG_TS590SG::bwtable(int m)
567 {
568 	if (m == LSB || m == USB || m == FM || m == FMD)
569 		return TS590SG_SSB_SH;
570 	else if (m == CW || m == CWR)
571 		return TS590SG_CWwidths;
572 	else if (m == FSK || m == FSKR)
573 		return TS590SG_FSKwidths;
574 	else if (m == AM)
575 		return TS590SG_AM_SH;
576 	else
577 		return TS590SG_DATA_width;
578 }
579 
lotable(int m)580 const char **RIG_TS590SG::lotable(int m)
581 {
582 	if (m == LSB || m == USB || m == FM || m == FMD)
583 		return TS590SG_SSB_SL;
584 	else if (m == AM)
585 		return TS590SG_AM_SL;
586 	else if (m == LSBD || m == USBD)
587 		return TS590SG_DATA_shift;
588 // CW CWR FSK FSKR
589 	return NULL;
590 }
591 
hitable(int m)592 const char **RIG_TS590SG::hitable(int m)
593 {
594 	if (m == LSB || m == USB || m == FM || m == FMD)
595 		return TS590SG_SSB_SH;
596 	else if (m == AM)
597 		return TS590SG_AM_SH;
598 	else if (m == LSBD || m == USBD)
599 		return TS590SG_DATA_width;
600 // CW CWR FSK FSKR
601 	return NULL;
602 }
603 
adjust_bandwidth(int val)604 int RIG_TS590SG::adjust_bandwidth(int val)
605 {
606 	if (val == LSB || val == USB || val == FM || val == FMD)
607 		return DEF_SL_SH;
608 	else if (val == LSBD || val == USBD)
609 		return DEF_width_shift;
610 	else if (val == CW || val == CWR)
611 		return DEF_cw;
612 	else if (val == FSK || val == FSKR)
613 		return DEF_fsk;
614 //	else if (val == AM)
615 	return DEF_am;
616 }
617 
def_bandwidth(int val)618 int RIG_TS590SG::def_bandwidth(int val)
619 {
620 	return adjust_bandwidth(val);
621 }
622 
set_bwA(int val)623 void RIG_TS590SG::set_bwA(int val)
624 {
625 // LSB, USB, FM, FM-D
626 	if (A.imode == LSB || A.imode == USB || A.imode == FM || A.imode == FMD) {
627 		if (val < 256) return;
628 		A.iBW = val;
629 		cmd = TS590SG_CAT_ssb_SL[A.iBW & 0x7F];
630 		sendCommand(cmd,0);
631 		showresp(WARN, ASC, "set lower", cmd, "");
632 		cmd = TS590SG_CAT_ssb_SH[(A.iBW >> 8) & 0x7F];
633 		sendCommand(cmd,0);
634 		showresp(WARN, ASC, "set upper", cmd, "");
635 		return;
636 	}
637 // LSB-D, USB-D
638 	if (A.imode == LSBD || A.imode == USBD) {
639 		if (val < 256) return;
640 		A.iBW = val;
641 		cmd = TS590SG_CAT_data_shift[A.iBW & 0x7F];
642 		sendCommand(cmd,0);
643 		showresp(WARN, ASC, "set shift", cmd, "");
644 		cmd = TS590SG_CAT_data_width[(A.iBW >> 8) & 0x7F];
645 		sendCommand(cmd,0);
646 		showresp(WARN, ASC, "set width", cmd, "");
647 		return;
648 	}
649 // AM
650 	if (A.imode == AM) {
651 		if (val < 256) return;
652 		A.iBW = val;
653 		cmd = TS590SG_CAT_am_SL[A.iBW & 0x7F];
654 		sendCommand(cmd,0);
655 		showresp(WARN, ASC, "set lower", cmd, "");
656 		cmd = TS590SG_CAT_am_SH[(A.iBW >> 8) & 0x7F];
657 		sendCommand(cmd,0);
658 		showresp(WARN, ASC, "set upper", cmd, "");
659 		return;
660 	}
661 	if (val > 256) return;
662 // CW
663 	if (A.imode == CW || A.imode == CWR) {
664 		A.iBW = val;
665 		cmd = TS590SG_CWbw[A.iBW];
666 		sendCommand(cmd,0);
667 		showresp(WARN, ASC, "set CW bw", cmd, "");
668 		return;
669 	}
670 // FSK
671 	if (A.imode == FSK || A.imode == FSKR) {
672 		A.iBW = val;
673 		cmd = TS590SG_FSKbw[A.iBW];
674 		sendCommand(cmd,0);
675 		showresp(WARN, ASC, "set FSK bw", cmd, "");
676 		return;
677 	}
678 }
679 
set_bwB(int val)680 void RIG_TS590SG::set_bwB(int val)
681 {
682 	if (B.imode == LSB || B.imode == USB || B.imode == FM || B.imode == FMD) {
683 		if (val < 256) return;
684 		B.iBW = val;
685 		cmd = TS590SG_CAT_ssb_SL[B.iBW & 0x7F];
686 		sendCommand(cmd,0);
687 		showresp(WARN, ASC, "set lower", cmd, "");
688 		cmd = TS590SG_CAT_ssb_SH[(B.iBW >> 8) & 0x7F];
689 		sendCommand(cmd,0);
690 		showresp(WARN, ASC, "set upper", cmd, "");
691 		return;
692 	}
693 	if (B.imode == LSBD || B.imode == USBD) { // SSB data mode
694 		if (val < 256) return;
695 		B.iBW = val;
696 		cmd = TS590SG_CAT_data_shift[B.iBW  & 0x7F];
697 		sendCommand(cmd,0);
698 		showresp(WARN, ASC, "set shift", cmd, "");
699 		cmd = TS590SG_CAT_data_width[(B.iBW >> 8) & 0x7F];
700 		sendCommand(cmd,0);
701 		showresp(WARN, ASC, "set width", cmd, "");
702 		return;
703 	}
704 	if (B.imode == AM) {
705 		if (val < 256) return;
706 		B.iBW = val;
707 		cmd = TS590SG_AM_SL[B.iBW & 0x7F];
708 		sendCommand(cmd,0);
709 		showresp(WARN, ASC, "set lower", cmd, "");
710 		cmd = TS590SG_AM_SH[(B.iBW >> 8) & 0x7F];
711 		sendCommand(cmd,0);
712 		showresp(WARN, ASC, "set upper", cmd, "");
713 		return;
714 	}
715 
716 	if (val > 256) return;
717 	if (B.imode == CW || B.imode == CWR) {
718 		B.iBW = val;
719 		cmd = TS590SG_CWbw[B.iBW];
720 		sendCommand(cmd,0);
721 		showresp(WARN, ASC, "set CW bw", cmd, "");
722 		return;
723 	}
724 
725 	if (B.imode == FSK || B.imode == FSKR) {
726 		B.iBW = val;
727 		cmd = TS590SG_FSKbw[B.iBW];
728 		sendCommand(cmd,0);
729 		showresp(WARN, ASC, "set FSK bw", cmd, "");
730 		return;
731 	}
732 }
733 
get_bwA()734 int RIG_TS590SG::get_bwA()
735 {
736 	int i = 0, lo = 0, hi = 0;
737 	size_t p;
738 	switch (A.imode) {
739 	case CW: case CWR:
740 		A.iBW = DEF_cw;
741 		cmd = "FW;";
742 		if (wait_char(';', 7, 100, "get CW width", ASC) == 7) {
743 			p = replystr.rfind("FW");
744 			if (p != string::npos) {
745 				for (i = 0; i < 14; i++)
746 					if (replystr.find(TS590SG_CWbw[i]) == p)
747 						break;
748 				if (i == 14) i = 13;
749 				A.iBW = i;
750 			}
751 		}
752 		break;
753 	case FSK: case FSKR:
754 		A.iBW = DEF_fsk;
755 		cmd = "FW;";
756 		if (wait_char(';', 7, 100, "get FSK width", ASC) == 7 ) {
757 			p = replystr.rfind("FW");
758 			if (p != string::npos) {
759 				for (i = 0; i < 4; i++)
760 					if (replystr.find(TS590SG_FSKbw[i]) == p)
761 						break;
762 				if (i == 4) i = 3;
763 				A.iBW = i;
764 			}
765 		}
766 		break;
767 	case LSB: case USB: case FM:
768 		A.iBW = DEF_SL_SH;
769 		lo = A.iBW & 0x7F;
770 		hi = (A.iBW >> 8) & 0x7F;
771 		cmd = "SL;";
772 		if (wait_char(';', 5, 100, "get lower", ASC) == 5) {
773 			p = replystr.rfind("SL");
774 			if (p == string::npos) break;
775 			lo = fm_decimal(replystr.substr(2), 2);
776 			cmd = "SH;";
777 			if (wait_char(';', 5, 100, "get upper", ASC) == 5) {
778 				p = replystr.rfind("SH");
779 				if (p == string::npos) break;
780 				hi = fm_decimal(replystr.substr(2), 2);
781 				A.iBW = ((hi << 8) | (lo & 0x7F)) | 0x8000;
782 			}
783 		}
784 		break;
785 	case LSBD: case USBD: case FMD:
786 		A.iBW = DEF_width_shift;
787 		lo = A.iBW & 0x7F;
788 		hi = (A.iBW >> 8) & 0x7F;
789 		cmd = "SL;";
790 		if (wait_char(';', 5, 100, "get width", ASC) == 5) {
791 			p = replystr.rfind("SL");
792 			if (p == string::npos) break;
793 			hi = fm_decimal(replystr.substr(2), 2);
794 			cmd = "SH;";
795 			if (wait_char(';', 5, 100, "get shift", ASC) == 5) {
796 				p = replystr.rfind("SH");
797 				if (p == string::npos) break;
798 				lo = fm_decimal(replystr.substr(2), 2);
799 				A.iBW = ((hi << 8) | (lo & 0x7F)) | 0x8000;
800 			}
801 		}
802 		break;
803 	}
804 	return A.iBW;
805 }
806 
get_bwB()807 int RIG_TS590SG::get_bwB()
808 {
809 	int i = 0, lo = 0, hi = 0;
810 	size_t p;
811 	switch (B.imode) {
812 	case CW: case CWR:
813 		B.iBW = DEF_cw;
814 		cmd = "FW;";
815 		if (wait_char(';', 7, 100, "get CW width", ASC) == 7) {
816 			p = replystr.rfind("FW");
817 			if (p != string::npos) {
818 				for (i = 0; i < 14; i++)
819 					if (replystr.find(TS590SG_CWbw[i]) == p)
820 						break;
821 				if (i == 14) i = 13;
822 				B.iBW = i;
823 			}
824 		}
825 		break;
826 	case FSK: case FSKR:
827 		B.iBW = DEF_fsk;
828 		cmd = "FW;";
829 		if (wait_char(';', 7, 100, "get FSK width", ASC) == 7) {
830 			p = replystr.rfind("FW");
831 			if (p != string::npos) {
832 				for (i = 0; i < 4; i++)
833 					if (replystr.find(TS590SG_FSKbw[i]) == p)
834 						break;
835 				if (i == 4) i = 3;
836 				B.iBW = i;
837 			}
838 		}
839 		break;
840 	case LSB: case USB: case FM:
841 		B.iBW = DEF_SL_SH;
842 		lo = B.iBW & 0xFF;
843 		hi = (B.iBW >> 8) & 0x7F;
844 		cmd = "SL;";
845 		if (wait_char(';', 5, 100, "get lower", ASC) == 5) {
846 			p = replystr.rfind("SL");
847 			if (p == string::npos) break;
848 			lo = fm_decimal(replystr.substr(2), 2);
849 			cmd = "SH;";
850 			if (wait_char(';', 5, 100, "get upper", ASC) == 5) {
851 				p = replystr.rfind("SH");
852 				if (p == string::npos) break;
853 				hi = fm_decimal(replystr.substr(2), 2);
854 				B.iBW = ((hi << 8) | (lo & 0x7F)) | 0x8000;
855 			}
856 		}
857 		break;
858 	case LSBD: case USBD: case FMD:
859 		B.iBW = DEF_width_shift;
860 		lo = B.iBW & 0x7F;
861 		hi = (B.iBW >> 8) & 0x7F;
862 		cmd = "SL;";
863 		if (wait_char(';', 5, 100, "get width", ASC) == 5) {
864 			p = replystr.rfind("SL");
865 			if (p == string::npos) break;
866 			hi = fm_decimal(replystr.substr(2), 2);
867 			cmd = "SH;";
868 			if (wait_char(';', 5, 100, "get shift", ASC) == 5 ) {
869 				p = replystr.rfind("SH");
870 				if (p == string::npos) break;
871 				lo = fm_decimal(replystr.substr(2), 2);
872 				B.iBW = ((hi << 8) | (lo & 0xFF)) | 0x8000;
873 			}
874 		}
875 		break;
876 	}
877 	return B.iBW;
878 }
879 
get_modetype(int n)880 int RIG_TS590SG::get_modetype(int n)
881 {
882 	return TS590SG_mode_type[n];
883 }
884 
885 //======================================================================
886 // IF shift command only available if the transceiver is in the CW mode
887 // step size is 50 Hz
888 //======================================================================
set_if_shift(int val)889 void RIG_TS590SG::set_if_shift(int val)
890 {
891 	if (active_mode == CW || active_mode == CWR) { // cw modes
892 		progStatus.shift_val = val;
893 		cmd = "IS ";
894 		cmd.append(to_decimal(abs(val),4)).append(";");
895 		sendCommand(cmd,0);
896 		showresp(WARN, ASC, "set IF shift", cmd, "");
897 	}
898 }
899 
get_if_shift(int & val)900 bool RIG_TS590SG::get_if_shift(int &val)
901 {
902 	if (active_mode == CW || active_mode == CWR) { // cw modes
903 		cmd = "IS;";
904 		if (wait_char(';', 8, 100, "get IF shift", ASC) == 8) {
905 			size_t p = replystr.rfind("IS");
906 			if (p != string::npos) {
907 				val = fm_decimal(replystr.substr(p+3), 4);
908 			} else
909 				val = progStatus.shift_val;
910 			return true;
911 		}
912 	}
913 	val = progStatus.shift_val;
914 	return false;
915 }
916 
get_if_min_max_step(int & min,int & max,int & step)917 void RIG_TS590SG::get_if_min_max_step(int &min, int &max, int &step)
918 {
919 	if_shift_min = min = 300;
920 	if_shift_max = max = 1000;
921 	if_shift_step = step = 50;
922 	if_shift_mid = 800;
923 }
924 
set_noise_reduction(int val)925 void RIG_TS590SG::set_noise_reduction(int val)
926 {
927 	if (val == -1) {
928 		if (noise_reduction_level == 1) {
929 			nr_label("NR1", true);
930 		} else if (noise_reduction_level == 2) {
931 			nr_label("NR2", true);
932 		}
933 		return;
934 	}
935 	if (noise_reduction_level == 0) {
936 		noise_reduction_level = 1;
937 		nr_label("NR1", true);
938 	} else if (noise_reduction_level == 1) {
939 		noise_reduction_level = 2;
940 		nr_label("NR2", true);
941 	} else if (noise_reduction_level == 2) {
942 		noise_reduction_level = 0;
943 		nr_label("NR", false);
944 	}
945 	cmd.assign("NR");
946 	cmd += '0' + noise_reduction_level;
947 	sendCommand (cmd);
948 	showresp(WARN, ASC, "SET noise reduction", cmd, "");
949 }
950 
get_noise_reduction()951 int  RIG_TS590SG::get_noise_reduction()
952 {
953 	cmd = rsp = "NR";
954 	cmd.append(";");
955 	if (wait_char(';', 4, 100, "GET noise reduction", ASC) == 4 ) {
956 		size_t p = replystr.rfind(rsp);
957 		if (p == string::npos) return noise_reduction_level;
958 		noise_reduction_level = replystr[p+2] - '0';
959 
960 		if (noise_reduction_level == 1) {
961 			nr_label("NR1", true);
962 		} else if (noise_reduction_level == 2) {
963 			nr_label("NR2", true);
964 		} else {
965 			nr_label("NR", false);
966 		}
967 	}
968 
969 	return noise_reduction_level;
970 }
971 
set_noise_reduction_val(int val)972 void RIG_TS590SG::set_noise_reduction_val(int val)
973 {
974 	cmd.assign("RL").append(to_decimal(val, 2)).append(";");
975 	sendCommand(cmd);
976 	showresp(WARN, ASC, "SET_noise_reduction_val", cmd, "");
977 }
978 
get_noise_reduction_val()979 int  RIG_TS590SG::get_noise_reduction_val()
980 {
981 	if (noise_reduction_level == 0) return 0;
982 	int val = 1;
983 	cmd = rsp = "RL";
984 	cmd.append(";");
985 	if (wait_char(';', 5, 100, "GET noise reduction val", ASC) == 5) {
986 		size_t p = replystr.rfind(rsp);
987 		if (p == string::npos) return progStatus.noise_reduction_val;
988 		val = atoi(&replystr[p+2]);
989 	}
990 	return val;
991 }
992 
set_auto_notch(int v)993 void RIG_TS590SG::set_auto_notch(int v)
994 {
995 	cmd.assign("NT").append(v ? "1" : "0" ).append("0;");
996 	sendCommand(cmd);
997 	showresp(WARN, ASC, "SET Auto Notch", cmd, "");
998 }
999 
get_auto_notch()1000 int  RIG_TS590SG::get_auto_notch()
1001 {
1002 	cmd = "NT;";
1003 	if (wait_char(';', 5, 100, "get auto notch", ASC) == 5) {
1004 		size_t p = replystr.rfind("NT");
1005 		if (p == string::npos) return 0;
1006 		if (replystr[p+2] == '1') return 1;
1007 	}
1008 	return 0;
1009 }
1010 
set_notch(bool on,int val)1011 void RIG_TS590SG::set_notch(bool on, int val)
1012 {
1013 	if (on) {
1014 		cmd.assign("NT20;");
1015 		sendCommand(cmd);
1016 		showresp(WARN, ASC, "Set notch ON", cmd, "");
1017 		int bp = (int)((val - 300.0) * 128.0 / 2700.0);
1018 		cmd.assign("BP").append(to_decimal(bp, 3)).append(";");
1019 		sendCommand(cmd);
1020 		showresp(WARN, ASC, "set notch freq", cmd, "");
1021 	} else {
1022 		cmd.assign("NT00;");
1023 		sendCommand(cmd);
1024 		showresp(WARN, ASC, "Set notch OFF", cmd, "");
1025 	}
1026 }
1027 
get_notch(int & val)1028 bool  RIG_TS590SG::get_notch(int &val)
1029 {
1030 	val = 300;
1031 	cmd = "NT;";
1032 	if (wait_char(';', 5, 100, "get notch state", ASC) == 5) {
1033 		size_t p = replystr.rfind("NT");
1034 		if (p == string::npos)
1035 			return 0;
1036 		if (replystr[p+2] == '2') {
1037 			cmd.assign("BP;");
1038 			if (wait_char(';', 6, 100, "get notch freq", ASC) == 6) {
1039 				size_t p = replystr.rfind("BP");
1040 				if (p != string::npos)
1041 					val = (int)((atoi(&replystr[p+2]) * 2700.0 / 128.0) + 300.0);
1042 				return 1;
1043 			}
1044 		}
1045 	}
1046 	return 0;
1047 }
1048 
get_notch_min_max_step(int & min,int & max,int & step)1049 void RIG_TS590SG::get_notch_min_max_step(int &min, int &max, int &step)
1050 {
1051 	min = 300;
1052 	max = 3000;
1053 	step = 20;
1054 }
1055 
set_noise(bool val)1056 void RIG_TS590SG::set_noise(bool val)
1057 {
1058 	if (nb_level == 0) {
1059 		nb_level = 1;
1060 		nb_label("NB 1", true);
1061 	} else if (nb_level == 1) {
1062 		nb_level = 2;
1063 		nb_label("NB 2", true);
1064 	} else if (nb_level == 2) {
1065 		nb_level = 3;
1066 		nb_label("NB 3", true);
1067 	} else if (nb_level == 3) {
1068 		nb_level = 0;
1069 		nb_label("NB", false);
1070 	}
1071 	cmd = "NB0;";
1072 	cmd[2] += nb_level;
1073 	LOG_INFO("%s", cmd.c_str());
1074 	sendCommand(cmd, 0);
1075 }
1076 
get_noise()1077 int RIG_TS590SG::get_noise()
1078 {
1079 	cmd = "NB;";
1080 	if (wait_char(';', 4, 100, "get Noise Blanker", ASC) == 4) {
1081 		size_t p = replystr.rfind("NB");
1082 		if (p == string::npos) return 0;
1083 		if (replystr[p+2] == '0') return 0;
1084 		nb_level = replystr[p+2] - '0';
1085 		if (nb_level == 0) {
1086 			nb_label("NB", false);
1087 		} else if (nb_level == 1) {
1088 			nb_label("NB 1", true);
1089 		} else if (nb_level == 2) {
1090 			nb_label("NB 2", true);
1091 		} else if (nb_level == 3) {
1092 			nb_label("NB 3", true);
1093 		}
1094 	}
1095 	return nb_level;
1096 }
1097 
set_rf_gain(int val)1098 void RIG_TS590SG::set_rf_gain(int val)
1099 {
1100 	cmd = "RG000;";
1101 	int rfval = 255 - val;
1102 	for (int i = 4; i > 1; i--) {
1103 		cmd[i] = rfval % 10 + '0';
1104 		rfval /= 10;
1105 	}
1106 	sendCommand(cmd);
1107 	showresp(WARN, ASC, "SET rfgain", cmd, "");
1108 }
1109 
get_rf_gain()1110 int  RIG_TS590SG::get_rf_gain()
1111 {
1112 	int rfval = 0;
1113 	cmd = rsp = "RG";
1114 	cmd += ';';
1115 	if (wait_char(';', 6, 100, "get rfgain", ASC) == 6) {
1116 		size_t p = replystr.rfind(rsp);
1117 		if (p == string::npos) return progStatus.rfgain;
1118 		for (int i = 2; i < 5; i++) {
1119 			rfval *= 10;
1120 			rfval += replystr[p+i] - '0';
1121 		}
1122 	}
1123 	return 255 - rfval;
1124 }
1125 
get_rf_min_max_step(int & min,int & max,int & step)1126 void RIG_TS590SG::get_rf_min_max_step(int &min, int &max, int &step)
1127 {
1128 	min = 0;
1129 	max = 255;
1130 	step = 1;
1131 }
1132 
get_PTT()1133 int RIG_TS590SG::get_PTT()
1134 {
1135 	cmd = "IF;";
1136 	int ret = wait_char(';', 38, 100, "get VFO", ASC);
1137 	if (ret < 38) return ptt_;
1138 	ptt_ = (replybuff[28] == '1');
1139 	return ptt_;
1140 }
1141 
1142 // Tranceiver PTT on/off
set_PTT_control(int val)1143 void RIG_TS590SG::set_PTT_control(int val)
1144 {
1145 	if (val) {
1146 		if (data_mode)
1147 			cmd = "TX1;";
1148 		else
1149 			cmd = "TX0;";
1150 	} else
1151 		cmd = "RX;";
1152 	sendCommand(cmd, 0);
1153 }
1154 
1155 /*
1156 void RIG_TS590SG::selectA()
1157 {
1158 	cmd = "FR0;";
1159 	sendCommand(cmd, 0);
1160 	showresp(WARN, ASC, "Rx A", cmd, "");
1161 	cmd = "FT0;";
1162 	sendCommand(cmd, 0);
1163 	showresp(WARN, ASC, "Tx A", cmd, "");
1164 	rxtxa = true;
1165 }
1166 
1167 void RIG_TS590SG::selectB()
1168 {
1169 	cmd = "FR1;";
1170 	sendCommand(cmd, 0);
1171 	showresp(WARN, ASC, "Rx B", cmd, "");
1172 	cmd = "FT1;";
1173 	sendCommand(cmd, 0);
1174 	showresp(WARN, ASC, "Tx B", cmd, "");
1175 	rxtxa = false;
1176 }
1177 
1178 void RIG_TS590SG::set_split(bool val)
1179 {
1180 	split = val;
1181 	if (useB) {
1182 		if (val) {
1183 			cmd = "FR1;FT0;";
1184 			sendCommand(cmd);
1185 			showresp(WARN, ASC, "Rx on B, Tx on A", cmd, "");
1186 		} else {
1187 			cmd = "FR1;FT1;";
1188 			sendCommand(cmd);
1189 			showresp(WARN, ASC, "Rx on B, Tx on B", cmd, "");
1190 		}
1191 	} else {
1192 		if (val) {
1193 			cmd = "FR0;FT1;";
1194 			sendCommand(cmd);
1195 			showresp(WARN, ASC, "Rx on A, Tx on B", cmd, "");
1196 		} else {
1197 			cmd = "FR0;FT0;";
1198 			sendCommand(cmd);
1199 			showresp(WARN, ASC, "Rx on A, Tx on A", cmd, "");
1200 		}
1201 	}
1202 }
1203 
1204 int RIG_TS590SG::get_split()
1205 {
1206 	size_t p;
1207 	int split = 0;
1208 	char rx = 0, tx = 0;
1209 // tx vfo
1210 	cmd = rsp = "FT";
1211 	cmd.append(";");
1212 	if (wait_char(';', 4, 100, "get split tx vfo", ASC) == 4) {
1213 		p = replystr.rfind(rsp);
1214 		if (p == string::npos) return split;
1215 		tx = replystr[p+2];
1216 	}
1217 // rx vfo
1218 	cmd = rsp = "FR";
1219 	cmd.append(";");
1220 	if (wait_char(';', 4, 100, "get split rx vfo", ASC) == 4) {
1221 		p = replystr.rfind(rsp);
1222 		if (p == string::npos) return split;
1223 		rx = replystr[p+2];
1224 // split test
1225 		split = (tx == '1' ? 2 : 0) + (rx == '1' ? 1 : 0);
1226 	}
1227 
1228 	return split;
1229 }
1230 
1231 unsigned long int RIG_TS590SG::get_vfoA ()
1232 {
1233 	cmd = "FA;";
1234 	if (wait_char(';', 14, 100, "get vfoA", ASC) < 14) return A.freq;
1235 
1236 	size_t p = replystr.rfind("FA");
1237 	if (p == string::npos) return A.freq;
1238 
1239 	unsigned long int f = 0L;
1240 	unsigned long int mul = 1L;
1241 	for (size_t n = 12; n > 1; n--) {
1242 		f += (replystr[p + n] - '0') * mul;
1243 		mul *= 10;
1244 	}
1245 	A.freq = f;
1246 	return A.freq;
1247 }
1248 
1249 void RIG_TS590SG::set_vfoA (unsigned long int freq)
1250 {
1251 	A.freq = freq;
1252 	cmd = "FA00000000000;";
1253 	for (int i = 12; i > 1; i--) {
1254 		cmd[i] += freq % 10;
1255 		freq /= 10;
1256 	}
1257 	sendCommand(cmd, 0);
1258 	showresp(WARN, ASC, "set vfo A", cmd, "");
1259 }
1260 
1261 unsigned long int RIG_TS590SG::get_vfoB ()
1262 {
1263 	cmd = "FB;";
1264 	if (wait_char(';', 14, 100, "get vfoB", ASC) < 14) return B.freq;
1265 
1266 	size_t p = replystr.rfind("FB");
1267 	if (p == string::npos) return B.freq;
1268 
1269 	unsigned long int f = 0L;
1270 	unsigned long int mul = 1L;
1271 	for (size_t n = 12; n > 1; n--) {
1272 		f += (replystr[p + n] - '0') * mul;
1273 		mul *= 10;
1274 	}
1275 	B.freq = f;
1276 
1277 	return B.freq;
1278 }
1279 
1280 void RIG_TS590SG::set_vfoB (unsigned long int freq)
1281 {
1282 	B.freq = freq;
1283 	cmd = "FB00000000000;";
1284 	for (int i = 12; i > 1; i--) {
1285 		cmd[i] += freq % 10;
1286 		freq /= 10;
1287 	}
1288 	sendCommand(cmd, 0);
1289 	showresp(WARN, ASC, "set vfo B", cmd, "");
1290 }
1291 
1292 void RIG_TS590SG::tune_rig()
1293 {
1294 	cmd = "AC111;";
1295 	sendCommand(cmd, 0);
1296 }
1297 
1298 // Volume control return 0 ... 100
1299 int RIG_TS590SG::get_volume_control()
1300 {
1301 	cmd = "AG0;";
1302 	if (wait_char(';', 7, 100, "get vol ctrl", ASC) < 7) return 0;
1303 
1304 	size_t p = replystr.rfind("AG");
1305 	if (p == string::npos) return 0;
1306 
1307 	replystr[p + 6] = 0;
1308 	int val = atoi(&replystr[p + 3]);
1309 	return (int)(val / 2.55);
1310 }
1311 
1312 void RIG_TS590SG::set_volume_control(int val)
1313 {
1314 	int ivol = (int)(val * 2.55);
1315 	cmd = "AG0000;";
1316 	for (int i = 5; i > 2; i--) {
1317 		cmd[i] += ivol % 10;
1318 		ivol /= 10;
1319 	}
1320 	sendCommand(cmd, 0);
1321 }
1322 
1323 //static bool read_alc = false;
1324 //static int alc_val = 0;
1325 
1326 int RIG_TS590SG::get_swr(void)
1327 {
1328 	int mtr = 0;
1329 
1330 	cmd = "RM1;";
1331 	sendCommand(cmd, 0);
1332 	showresp(WARN, ASC, "SWR meter", cmd, "");
1333 
1334 	cmd = "RM;";
1335 	if (wait_char(';', 8, 100, "get swr", ASC) < 8) return 0;
1336 
1337 	size_t p = replystr.find("RM1");
1338 	if (p == string::npos) return 0;
1339 
1340 	replystr[p + 7] = 0;
1341 	mtr = atoi(&replystr[p + 3]);
1342 	mtr *= 100;
1343 	mtr /= 30;
1344 	if (mtr > 100) mtr = 100;
1345 
1346 	return mtr;
1347 }
1348 
1349 int RIG_TS590SG::get_alc(void)
1350 {
1351 	cmd = "RM3;";
1352 	sendCommand(cmd, 0);
1353 	showresp(WARN, ASC, "ALC meter", cmd, "");
1354 
1355 	cmd = "RM;";
1356 	if (wait_char(';', 8, 100, "get alc", ASC) < 8) return 0;
1357 
1358 	size_t p = replystr.find("RM3");
1359 	if (p == string::npos) return 0;
1360 
1361 	replystr[p + 7] = 0;
1362 	int alc_val = atoi(&replystr[p + 3]);
1363 	alc_val *= 100;
1364 	alc_val /= 30;
1365 	if (alc_val > 100) alc_val = 100;
1366 	return alc_val;
1367 }
1368 
1369 // val 0 .. 100
1370 void RIG_TS590SG::set_mic_gain(int val)
1371 {
1372 	cmd = "MG000;";
1373 	for (int i = 3; i > 0; i--) {
1374 		cmd[1+i] += val % 10;
1375 		val /= 10;
1376 	}
1377 	sendCommand(cmd, 0);
1378 }
1379 
1380 int RIG_TS590SG::get_mic_gain()
1381 {
1382 	int val = 0;
1383 	cmd = "MG;";
1384 	if (wait_char(';', 6, 100, "get mic ctrl", ASC) >= 6) {
1385 		size_t p = replystr.rfind("MG");
1386 		if (p == string::npos) return val;
1387 		replystr[p + 5] = 0;
1388 		val = atoi(&replystr[p + 2]);
1389 	}
1390 	return val;
1391 }
1392 
1393 void RIG_TS590SG::get_mic_min_max_step(int &min, int &max, int &step)
1394 {
1395 	min = 0;
1396 	max = 100;
1397 	step = 1;
1398 }
1399 
1400 void RIG_TS590SG::set_squelch(int val)
1401 {
1402 	cmd = "SQ0";
1403 	cmd.append(to_decimal(abs(val),3)).append(";");
1404 	sendCommand(cmd,0);
1405 	showresp(WARN, ASC, "set squelch", cmd, "");
1406 }
1407 
1408 int  RIG_TS590SG::get_squelch()
1409 {
1410 	int val = 0;
1411 	cmd = "SQ0;";
1412 	if (wait_char(';', 7, 100, "get squelch", ASC) >= 7) {
1413 		size_t p = replystr.rfind("SQ0");
1414 		if (p == string::npos) return val;
1415 		replystr[p + 6] = 0;
1416 		val = atoi(&replystr[p + 3]);
1417 	}
1418 	return val;
1419 }
1420 
1421 void RIG_TS590SG::get_squelch_min_max_step(int &min, int &max, int &step)
1422 {
1423 	min = 0; max = 255; step = 1;
1424 }
1425 
1426 */
1427