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 #include <iostream>
21 #include <sstream>
22
23 #include "IC7200.h"
24 #include "support.h"
25 #include "trace.h"
26
27 //=============================================================================
28 // IC-7200
29
30 const char IC7200name_[] = "IC-7200";
31
32 // these are only defined in this file
33 // undef'd at end of file
34 #define NUM_FILTERS 3
35 #define NUM_MODES 9
36
37 enum {
38 LSB7200, USB7200, AM7200,
39 CW7200, RTTY7200,
40 CWR7200, RTTYR7200,
41 LSBD7200, USBD7200 };
42
43 static int mode_filterA[NUM_MODES] = {1,1,1,1,1,1,1,1,1};
44 static int mode_filterB[NUM_MODES] = {1,1,1,1,1,1,1,1,1};
45
46 static int mode_bwA[NUM_MODES] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,};
47 static int mode_bwB[NUM_MODES] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,};
48
49 static const char *szfilter[NUM_FILTERS] = {"W", "M", "N"};
50
51 const char *IC7200modes_[] = {
52 "LSB", "USB", "AM", "CW", "RTTY", "CW-R", "RTTY-R",
53 "LSB-D", "USB-D", NULL};
54
55 const char mdval[] = { 0, 1, 2, 3, 4, 7, 8, 0, 1};
56
57 static char IC7200_mode_type[] = {
58 'L', 'U', 'U', 'L', 'L', 'U', 'U',
59 'L', 'U' };
60
61 const char *IC7200_SSBwidths[] = {
62 "50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
63 "600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500",
64 "1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500",
65 "2600", "2700", "2800", "2900", "3000", "3100", "3200", "3300", "3400", "3500",
66 "3600",
67 NULL};
68 static int IC7200_bw_vals_SSB[] = {
69 1, 2, 3, 4, 5, 6, 7, 8, 9,10,
70 11,12,13,14,15,16,17,18,19,20,
71 21,22,23,24,25,26,27,28,29,30,
72 31,32,33,34,35,36,37,38,39,40,
73 41, WVALS_LIMIT};
74
75 const char *IC7200_RTTYwidths[] = {
76 "50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
77 "600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500",
78 "1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500",
79 "2600", "2700",
80 NULL};
81 static int IC7200_bw_vals_RTTY[] = {
82 1, 2, 3, 4, 5, 6, 7, 8, 9,10,
83 11,12,13,14,15,16,17,18,19,20,
84 21,22,23,24,25,26,27,28,29,30,
85 31,32, WVALS_LIMIT};
86
87 const char *IC7200_AMwidths[] = {
88 "200", "400", "600", "800", "1000", "1200", "1400", "1600", "1800", "2000",
89 "2200", "2400", "2600", "2800", "3000", "3200", "3400", "3600", "3800", "4000",
90 "4200", "4400", "4600", "4800", "5000", "5200", "5400", "5600", "5800", "5000",
91 "6200", "6400", "6600", "6800", "7000", "7200", "7400", "7600", "7800", "8000",
92 NULL};
93 static int IC7200_bw_vals_AM[] = {
94 1, 2, 3, 4, 5, 6, 7, 8, 9,10,
95 11,12,13,14,15,16,17,18,19,20,
96 21,22,23,24,25,26,27,28,29,30,
97 31,32,33,34,35,36,37,38,39,40,
98 WVALS_LIMIT};
99
100 //======================================================================
101 // IC7200 unique commands
102 //======================================================================
103
104 static GUI IC7200_widgets[]= {
105 { (Fl_Widget *)btnVol, 2, 125, 50 }, //0
106 { (Fl_Widget *)sldrVOLUME, 54, 125, 156 }, //1
107 { (Fl_Widget *)btnAGC, 2, 145, 50 }, //2
108 { (Fl_Widget *)sldrRFGAIN, 54, 145, 156 }, //3
109 { (Fl_Widget *)sldrSQUELCH, 54, 165, 156 }, //4
110 { (Fl_Widget *)btnNR, 2, 185, 50 }, //5
111 { (Fl_Widget *)sldrNR, 54, 185, 156 }, //6
112 { (Fl_Widget *)btnLOCK, 214, 105, 50 }, //7
113 { (Fl_Widget *)sldrINNER, 266, 105, 156 }, //8
114 { (Fl_Widget *)btnCLRPBT, 214, 125, 50 }, //9
115 { (Fl_Widget *)sldrOUTER, 266, 125, 156 }, //10
116 { (Fl_Widget *)btnNotch, 214, 145, 50 }, //11
117 { (Fl_Widget *)sldrNOTCH, 266, 145, 156 }, //12
118 { (Fl_Widget *)sldrMICGAIN, 266, 165, 156 }, //13
119 { (Fl_Widget *)sldrPOWER, 266, 185, 156 }, //14
120 { (Fl_Widget *)NULL, 0, 0, 0 }
121 };
122
initialize()123 void RIG_IC7200::initialize()
124 {
125 IC7200_widgets[0].W = btnVol;
126 IC7200_widgets[1].W = sldrVOLUME;
127 IC7200_widgets[2].W = btnAGC;
128 IC7200_widgets[3].W = sldrRFGAIN;
129 IC7200_widgets[4].W = sldrSQUELCH;
130 IC7200_widgets[5].W = btnNR;
131 IC7200_widgets[6].W = sldrNR;
132 IC7200_widgets[7].W = btnLOCK;
133 IC7200_widgets[8].W = sldrINNER;
134 IC7200_widgets[9].W = btnCLRPBT;
135 IC7200_widgets[10].W = sldrOUTER;
136 IC7200_widgets[11].W = btnNotch;
137 IC7200_widgets[12].W = sldrNOTCH;
138 IC7200_widgets[13].W = sldrMICGAIN;
139 IC7200_widgets[14].W = sldrPOWER;
140
141 btn_icom_select_11->deactivate();
142 btn_icom_select_12->deactivate();
143 btn_icom_select_13->deactivate();
144
145 choice_rTONE->deactivate();
146 choice_tTONE->deactivate();
147 }
148
RIG_IC7200()149 RIG_IC7200::RIG_IC7200() {
150 name_ = IC7200name_;
151 modes_ = IC7200modes_;
152 _mode_type = IC7200_mode_type;
153 bandwidths_ = IC7200_SSBwidths;
154 bw_vals_ = IC7200_bw_vals_SSB;
155 widgets = IC7200_widgets;
156
157 comm_baudrate = BR9600;
158 stopbits = 1;
159 comm_retries = 2;
160 comm_wait = 5;
161 comm_timeout = 50;
162 comm_echo = true;
163 comm_rtscts = false;
164 comm_rtsplus = true;
165 comm_dtrplus = true;
166 comm_catptt = true;
167 comm_rtsptt = false;
168 comm_dtrptt = false;
169
170 def_freq = A.freq = 14070000;
171 def_mode = A.imode = 1;
172 def_bw = A.iBW = 32;
173
174 B.freq = 7070000;
175 B.imode = 1;
176 B.iBW = 32;
177
178 has_extras = true;
179 has_smeter = true;
180 has_power_out = true;
181 has_swr_control = true;
182 has_alc_control = true;
183 has_agc_control = true;
184 has_sql_control = true;
185 has_power_control = true;
186 has_volume_control = true;
187 has_mode_control = true;
188 has_bandwidth_control = true;
189 has_micgain_control = true;
190 has_attenuator_control = true;
191 has_preamp_control = true;
192 has_noise_control = true;
193 has_nb_level = true;
194 has_noise_reduction = true;
195 has_noise_reduction_control = true;
196 has_auto_notch = true;
197 has_notch_control = true;
198 has_pbt_controls = true;
199 has_FILTER = true;
200 has_rf_control = true;
201 has_compON = true;
202 has_compression = true;
203 has_vox_onoff = true;
204 has_ptt_control = true;
205 has_tune_control = true;
206 has_split_AB = true;
207 has_vfo_adj = true;
208 has_a2b = true;
209
210 has_band_selection = true;
211
212 has_cw_wpm = true;
213 has_cw_spot_tone = true;
214 has_cw_qsk = true;
215 has_cw_break_in = true;
216
217 defaultCIV = 0x76;
218 adjustCIV(defaultCIV);
219
220 precision = 1;
221 ndigits = 8;
222
223 CW_sense = 0; // normal
224 };
225
minmax(int min,int max,int & val)226 static inline void minmax(int min, int max, int &val)
227 {
228 if (val > max) val = max;
229 if (val < min) val = min;
230 }
231
232 //======================================================================
233
selectA()234 void RIG_IC7200::selectA()
235 {
236 cmd = pre_to;
237 cmd += '\x07';
238 cmd += '\x00';
239 cmd.append(post);
240 set_trace(2, "selectA()", str2hex(cmd.c_str(), cmd.length()));
241 waitFB("select A");
242 inuse = onA;
243 }
244
selectB()245 void RIG_IC7200::selectB()
246 {
247 cmd = pre_to;
248 cmd += '\x07';
249 cmd += '\x01';
250 cmd.append(post);
251 set_trace(2, "selectB()", str2hex(cmd.c_str(), cmd.length()));
252 waitFB("select B");
253 inuse = onB;
254 }
255
check()256 bool RIG_IC7200::check ()
257 {
258 string resp = pre_fm;
259 resp += '\x03';
260 cmd = pre_to;
261 cmd += '\x03';
262 cmd.append( post );
263 bool ok = waitFOR(11, "check vfo");
264 get_trace(2, "check()", str2hex(replystr.c_str(), replystr.length()));
265 return ok;
266 }
267
get_vfoA()268 unsigned long int RIG_IC7200::get_vfoA ()
269 {
270 if (useB) return A.freq;
271 string resp = pre_fm;
272 resp += '\x03';
273 cmd = pre_to;
274 cmd += '\x03';
275 cmd.append( post );
276 if (waitFOR(11, "get vfo A")) {
277 size_t p = replystr.rfind(resp);
278 if (p != string::npos) {
279 if (replystr[p+5] == -1)
280 A.freq = 0;
281 else
282 A.freq = fm_bcd_be(replystr.substr(p+5), 10);
283 }
284 }
285 get_trace(2, "get_vfoA()", str2hex(replystr.c_str(), replystr.length()));
286 return A.freq;
287 }
288
set_vfoA(unsigned long int freq)289 void RIG_IC7200::set_vfoA (unsigned long int freq)
290 {
291 A.freq = freq;
292 cmd = pre_to;
293 cmd += '\x05';
294 cmd.append( to_bcd_be( freq, 10 ) );
295 cmd.append( post );
296 set_trace(2, "set_vfoA()", str2hex(cmd.c_str(), cmd.length()));
297 waitFB("set vfo A");
298 }
299
get_vfoB()300 unsigned long int RIG_IC7200::get_vfoB ()
301 {
302 if (!useB) return B.freq;
303 string resp = pre_fm;
304 resp += '\x03';
305 cmd = pre_to;
306 cmd += '\x03';
307 cmd.append( post );
308 if (waitFOR(11, "get vfo B")) {
309 size_t p = replystr.rfind(resp);
310 if (p != string::npos) {
311 if (replystr[p+5] == -1)
312 A.freq = 0;
313 else
314 B.freq = fm_bcd_be(replystr.substr(p+5), 10);
315 }
316 }
317 get_trace(2, "get_vfoB()", str2hex(replystr.c_str(), replystr.length()));
318 return B.freq;
319 }
320
set_vfoB(unsigned long int freq)321 void RIG_IC7200::set_vfoB (unsigned long int freq)
322 {
323 B.freq = freq;
324 cmd = pre_to;
325 cmd += '\x05';
326 cmd.append( to_bcd_be( freq, 10 ) );
327 cmd.append( post );
328 set_trace(2, "set_vfoB()", str2hex(cmd.c_str(), cmd.length()));
329 waitFB("set vfo B");
330 }
331
can_split()332 bool RIG_IC7200::can_split()
333 {
334 return true;
335 }
336
set_split(bool val)337 void RIG_IC7200::set_split(bool val)
338 {
339 split = val;
340 cmd = pre_to;
341 cmd += 0x0F;
342 cmd += val ? 0x01 : 0x00;
343 cmd.append(post);
344 waitFB(val ? "set split ON" : "set split OFF");
345 set_trace(2, "set_split()", str2hex(cmd.c_str(), cmd.length()));
346 }
347
348 // 7200 does not respond to get split CAT command
get_split()349 int RIG_IC7200::get_split()
350 {
351 return split;
352 }
353
354 // Tranceiver PTT on/off
set_PTT_control(int val)355 void RIG_IC7200::set_PTT_control(int val)
356 {
357 cmd = pre_to;
358 cmd += '\x1c';
359 cmd += '\x00';
360 cmd += (val ? '\x01' : '\x00');
361 cmd.append( post );
362 if (val)
363 waitFB("set ptt ON");
364 else
365 waitFB("set ptt OFF");
366 ptt_ = val;
367 set_trace(2, "set_PTT()", str2hex(cmd.c_str(), cmd.length()));
368 }
369
get_PTT()370 int RIG_IC7200::get_PTT()
371 {
372 cmd = pre_to;
373 cmd += '\x1c'; cmd += '\x00';
374 string resp = pre_fm;
375 resp += '\x1c'; resp += '\x00';
376 cmd.append(post);
377 if (waitFOR(8, "get PTT")) {
378 size_t p = replystr.rfind(resp);
379 if (p != string::npos)
380 ptt_ = replystr[p + 6];
381 }
382 get_trace(2, "get_PTT()", str2hex(replystr.c_str(), replystr.length()));
383 return ptt_;
384 }
385
386 // Volume control val 0 ... 100
set_volume_control(int val)387 void RIG_IC7200::set_volume_control(int val)
388 {
389 cmd = pre_to;
390 cmd.append("\x14\x01");
391 cmd.append(bcd255(val));
392 cmd.append( post );
393 waitFB("set vol");
394 set_trace(2, "set_volume_control()", str2hex(cmd.c_str(), cmd.length()));
395 }
396
get_volume_control()397 int RIG_IC7200::get_volume_control()
398 {
399 int val = progStatus.volume;
400 string cstr = "\x14\x01";
401 string resp = pre_fm;
402 resp.append(cstr);
403 cmd = pre_to;
404 cmd.append(cstr);
405 cmd.append( post );
406 if (waitFOR(9, "get vol")) {
407 size_t p = replystr.rfind(resp);
408 if (p != string::npos)
409 val = num100(replystr.substr(p+6));
410 }
411 get_trace(2, "get_volume_control()", str2hex(replystr.c_str(), replystr.length()));
412 return val;
413 }
414
get_vol_min_max_step(int & min,int & max,int & step)415 void RIG_IC7200::get_vol_min_max_step(int &min, int &max, int &step)
416 {
417 min = 0; max = 100; step = 1;
418 }
419
get_smeter()420 int RIG_IC7200::get_smeter()
421 {
422 string cstr = "\x15\x02";
423 string resp = pre_fm;
424 resp.append(cstr);
425 cmd = pre_to;
426 cmd.append(cstr);
427 cmd.append( post );
428 int mtr= -1;
429 if (waitFOR(9, "get smeter")) {
430 size_t p = replystr.rfind(resp);
431 if (p != string::npos) {
432 mtr = fm_bcd(replystr.substr(p+6), 3);
433 mtr = (int)ceil(mtr /2.55);
434 if (mtr > 100) mtr = 100;
435 }
436 }
437 get_trace(2, "get_smeter()", str2hex(replystr.c_str(), replystr.length()));
438 return mtr;
439 }
440
441 struct pwrpair {int mtr; float pwr;};
442
443 static pwrpair pwrtbl[] = {
444 {0, 0.0},
445 {40, 10.0},
446 {76, 20.0},
447 {92, 25.0},
448 {103, 30.0},
449 {124, 40.0},
450 {143, 50.0},
451 {183, 75.0},
452 {213, 100.0},
453 {255, 140.0} };
454
get_power_out(void)455 int RIG_IC7200::get_power_out(void)
456 {
457 string cstr = "\x15\x11";
458 string resp = pre_fm;
459 resp.append(cstr);
460 cmd = pre_to;
461 cmd.append(cstr);
462 cmd.append( post );
463 int mtr= 0;
464 if (waitFOR(9, "get power out")) {
465 size_t p = replystr.rfind(resp);
466 if (p != string::npos) {
467 mtr = fm_bcd(replystr.substr(p+6), 3);
468 size_t i = 0;
469 for (i = 0; i < sizeof(pwrtbl) / sizeof(pwrpair) - 1; i++)
470 if (mtr >= pwrtbl[i].mtr && mtr < pwrtbl[i+1].mtr)
471 break;
472 if (mtr < 0) mtr = 0;
473 if (mtr > 255) mtr = 255;
474 mtr = (int)ceil(pwrtbl[i].pwr +
475 (pwrtbl[i+1].pwr - pwrtbl[i].pwr)*(mtr - pwrtbl[i].mtr)/(pwrtbl[i+1].mtr - pwrtbl[i].mtr));
476
477 if (mtr > 100) mtr = 100;
478 }
479 }
480 get_trace(2, "get_power_out()", str2hex(replystr.c_str(), replystr.length()));
481 return mtr;
482 }
483
get_swr(void)484 int RIG_IC7200::get_swr(void)
485 {
486 string cstr = "\x15\x12";
487 string resp = pre_fm;
488 resp.append(cstr);
489 cmd = pre_to;
490 cmd.append(cstr);
491 cmd.append( post );
492 int mtr= -1;
493 if (waitFOR(9, "get swr")) {
494 size_t p = replystr.rfind(resp);
495 if (p != string::npos) {
496 mtr = fm_bcd(replystr.substr(p+6), 3);
497 mtr = (int)ceil(mtr /2.55);
498 if (mtr > 100) mtr = 100;
499 }
500 }
501 get_trace(2, "get_swr()", str2hex(replystr.c_str(), replystr.length()));
502 return mtr;
503 }
504
get_alc(void)505 int RIG_IC7200::get_alc(void)
506 {
507 string cstr = "\x15\x13";
508 string resp = pre_fm;
509 resp.append(cstr);
510 cmd = pre_to;
511 cmd.append(cstr);
512 cmd.append( post );
513 int mtr= -1;
514 if (waitFOR(9, "get alc")) {
515 size_t p = replystr.rfind(resp);
516 if (p != string::npos) {
517 mtr = fm_bcd(replystr.substr(p+6), 3);
518 mtr = (int)ceil(mtr /2.55);
519 if (mtr > 100) mtr = 100;
520 }
521 }
522 get_trace(2, "get_alc()", str2hex(replystr.c_str(), replystr.length()));
523 return mtr;
524 }
525
set_noise(bool val)526 void RIG_IC7200::set_noise(bool val)
527 {
528 cmd = pre_to;
529 cmd.append("\x16\x22");
530 cmd += val ? 1 : 0;
531 cmd.append(post);
532 waitFB("set noise");
533 set_trace(2, "set_noise()", str2hex(cmd.c_str(), cmd.length()));
534 }
535
get_noise()536 int RIG_IC7200::get_noise()
537 {
538 int val = progStatus.noise;
539 string cstr = "\x16\x22";
540 string resp = pre_fm;
541 resp.append(cstr);
542 cmd = pre_to;
543 cmd.append(cstr);
544 cmd.append(post);
545 if (waitFOR(8, "get noise")) {
546 size_t p = replystr.rfind(resp);
547 if (p != string::npos) {
548 val = replystr[p+6];
549 }
550 }
551 get_trace(2, "get_noise()", str2hex(replystr.c_str(), replystr.length()));
552 return val;
553 }
554
set_nb_level(int val)555 void RIG_IC7200::set_nb_level(int val)
556 {
557 cmd = pre_to;
558 cmd.append("\x14\x12");
559 cmd.append(bcd255(val));
560 cmd.append( post );
561 waitFB("set NB level");
562 set_trace(2, "set_nb_level()", str2hex(cmd.c_str(), cmd.length()));
563 }
564
get_nb_level()565 int RIG_IC7200::get_nb_level()
566 {
567 int val = progStatus.nb_level;
568 string cstr = "\x14\x12";
569 string resp = pre_fm;
570 resp.append(cstr);
571 cmd = pre_to;
572 cmd.append(cstr);
573 cmd.append(post);
574 if (waitFOR(9, "get NB level")) {
575 size_t p = replystr.rfind(resp);
576 if (p != string::npos)
577 val = num100(replystr.substr(p+6));
578 }
579 get_trace(2, "get_nb_level()", str2hex(replystr.c_str(), replystr.length()));
580 return val;
581 }
582
set_noise_reduction(int val)583 void RIG_IC7200::set_noise_reduction(int val)
584 {
585 cmd = pre_to;
586 cmd.append("\x16\x40");
587 cmd += val ? 1 : 0;
588 cmd.append(post);
589 waitFB("set NR");
590 set_trace(2, "set_noise_reduction()", str2hex(cmd.c_str(), cmd.length()));
591 }
592
get_noise_reduction()593 int RIG_IC7200::get_noise_reduction()
594 {
595 string cstr = "\x16\x40";
596 string resp = pre_fm;
597 resp.append(cstr);
598 cmd = pre_to;
599 cmd.append(cstr);
600 cmd.append(post);
601 if (waitFOR(8, "get NR")) {
602 size_t p = replystr.rfind(resp);
603 if (p != string::npos)
604 return (replystr[p+6] ? 1 : 0);
605 }
606 get_trace(2, "get_noise_reduction()", str2hex(replystr.c_str(), replystr.length()));
607 return progStatus.noise_reduction;
608 }
609
610 // 0 < val < 100
set_noise_reduction_val(int val)611 void RIG_IC7200::set_noise_reduction_val(int val)
612 {
613 cmd = pre_to;
614 cmd.append("\x14\x06");
615 val = val * 16 + 8;
616 cmd.append(to_bcd(val, 3));
617 cmd.append(post);
618 waitFB("set NRval");
619 set_trace(2, "set_noise_reduction_val()", str2hex(cmd.c_str(), cmd.length()));
620 }
621
get_noise_reduction_val()622 int RIG_IC7200::get_noise_reduction_val()
623 {
624 int val = progStatus.noise_reduction_val;
625 string cstr = "\x14\x06";
626 string resp = pre_fm;
627 resp.append(cstr);
628 cmd = pre_to;
629 cmd.append(cstr);
630 cmd.append(post);
631 if (waitFOR(9, "get NRval")) {
632 size_t p = replystr.rfind(resp);
633 if (p != string::npos) {
634 val = fm_bcd(replystr.substr(p+6), 3);
635 val = (val - 8) / 16;
636 }
637 }
638 get_trace(2, "get_nr_val()", str2hex(replystr.c_str(), replystr.length()));
639 return val;
640 }
641
set_attenuator(int val)642 void RIG_IC7200::set_attenuator(int val)
643 {
644 if (val) {
645 atten_label("20 dB", true);
646 atten_level = 1;
647 set_preamp(0);
648 } else {
649 atten_label("ATT", false);
650 atten_level = 0;
651 }
652
653 cmd = pre_to;
654 cmd += '\x11';
655 cmd += atten_level ? '\x20' : '\x00';
656 cmd.append( post );
657 waitFB("set att");
658 set_trace(2, "set_attenuator()", str2hex(cmd.c_str(), cmd.length()));
659 }
660
next_attenuator()661 int RIG_IC7200::next_attenuator()
662 {
663 if (atten_level) return 0;
664 return 1;
665 }
666
get_attenuator()667 int RIG_IC7200::get_attenuator()
668 {
669 cmd = pre_to;
670 cmd += '\x11';
671 cmd.append( post );
672 string resp = pre_fm;
673 resp += '\x11';
674 if (waitFOR(7, "get ATT")) {
675 get_trace(2, "get_ATT()", str2hex(replystr.c_str(), replystr.length()));
676 size_t p = replystr.rfind(resp);
677 if (p != string::npos) {
678 if (!replystr[p+5]) {
679 atten_label("ATT", false);
680 atten_level = 0;
681 return 0;
682 } else {
683 atten_label("20 dB", true);
684 atten_level = 1;
685 return 1;
686 }
687 }
688 }
689 return 0;
690 }
691
next_preamp()692 int RIG_IC7200::next_preamp()
693 {
694 if (preamp_level)
695 return 0;
696 return 1;
697 }
698
set_preamp(int val)699 void RIG_IC7200::set_preamp(int val)
700 {
701 if (val) {
702 preamp_label("Pre ON", true);
703 preamp_level = 1;
704 if (atten_level == 1) {
705 atten_label("ATT", false);
706 atten_level = 0;
707 }
708 } else {
709 preamp_label("Pre", false);
710 preamp_level = 0;
711 }
712
713 cmd = pre_to;
714 cmd += '\x16';
715 cmd += '\x02';
716 cmd += preamp_level ? 0x01 : 0x00;
717 cmd.append( post );
718 waitFB("set Pre");
719 set_trace(2, "set_preamp()", str2hex(cmd.c_str(), cmd.length()));
720 }
721
get_preamp()722 int RIG_IC7200::get_preamp()
723 {
724 string cstr = "\x16\x02";
725 string resp = pre_fm;
726 resp.append(cstr);
727 cmd = pre_to;
728 cmd.append(cstr);
729 cmd.append( post );
730 if (waitFOR(8, "get Pre")) {
731 get_trace(2, "get_preamp()", str2hex(replystr.c_str(), replystr.length()));
732 size_t p = replystr.rfind(resp);
733 if (p != string::npos) {
734 if (replystr[p+6] == 0x01) {
735 preamp_label("Pre ON", true);
736 preamp_level = 1;
737 // progStatus.preamp = true;
738 } else {
739 preamp_label("Pre", false);
740 preamp_level = 0;
741 // progStatus.preamp = false;
742 }
743 }
744 }
745 return preamp_level; //progStatus.preamp;
746 }
747
set_rf_gain(int val)748 void RIG_IC7200::set_rf_gain(int val)
749 {
750 cmd = pre_to;
751 cmd.append("\x14\x02");
752 cmd.append(bcd255(val));
753 cmd.append( post );
754 waitFB("set RF");
755 set_trace(2, "set_rf_gain()", str2hex(cmd.c_str(), cmd.length()));
756 }
757
get_rf_gain()758 int RIG_IC7200::get_rf_gain()
759 {
760 int val = progStatus.rfgain;
761 string cstr = "\x14\x02";
762 string resp = pre_fm;
763 cmd = pre_to;
764 cmd.append(cstr).append(post);
765 resp.append(cstr);
766 if (waitFOR(9, "get RF")) {
767 size_t p = replystr.rfind(resp);
768 if (p != string::npos)
769 val = num100(replystr.substr(p + 6));
770 }
771 get_trace(2, "get_rf_gain()", str2hex(replystr.c_str(), replystr.length()));
772 return val;
773 }
774
set_squelch(int val)775 void RIG_IC7200::set_squelch(int val)
776 {
777 cmd = pre_to;
778 cmd.append("\x14\x03");
779 cmd.append(bcd255(val));
780 cmd.append( post );
781 waitFB("set Sqlch");
782 set_trace(2, "set_squelch()", str2hex(cmd.c_str(), cmd.length()));
783 }
784
get_squelch()785 int RIG_IC7200::get_squelch()
786 {
787 int val = progStatus.squelch;
788 string cstr = "\x14\x03";
789 string resp = pre_fm;
790 resp.append(cstr);
791 cmd = pre_to;
792 cmd.append(cstr);
793 cmd.append(post);
794 if (waitFOR(9, "get squelch")) {
795 size_t p = replystr.rfind(resp);
796 if (p != string::npos)
797 val = num100(replystr.substr(p+6));
798 }
799 get_trace(2, "get_squelch()", str2hex(replystr.c_str(), replystr.length()));
800 return val;
801 }
802
set_power_control(double val)803 void RIG_IC7200::set_power_control(double val)
804 {
805 cmd = pre_to;
806 cmd.append("\x14\x0A");
807 cmd.append(bcd255(val));
808 cmd.append( post );
809 waitFB("set power");
810 set_trace(2, "set_power_control()", str2hex(cmd.c_str(), cmd.length()));
811 }
812
get_power_control()813 int RIG_IC7200::get_power_control()
814 {
815 string cstr = "\x14\x0A";
816 string resp = pre_fm;
817 cmd = pre_to;
818 cmd.append(cstr).append(post);
819 resp.append(cstr);
820 int val = progStatus.power_level;
821 string retstr = "ret str";
822 if (waitFOR(9, "get power")) {
823 size_t p = replystr.rfind(resp);
824 if (p != string::npos) {
825 val = num100(replystr.substr(p+6));
826 retstr = str2hex(replystr.substr(p).c_str(), 9);
827 }
828 }
829 get_trace(2, "get_power_control()", str2hex(replystr.c_str(), replystr.length()));
830 return val;
831 }
832
get_mic_gain_min_max_step(int & min,int & max,int & step)833 void RIG_IC7200::get_mic_gain_min_max_step(int &min, int &max, int &step)
834 {
835 min = 0;
836 max = 100;
837 step = 1;
838 }
839
get_mic_gain()840 int RIG_IC7200::get_mic_gain()
841 {
842 string cstr = "\x14\x0B";
843 string resp = pre_fm;
844 resp.append(cstr);
845 cmd = pre_to;
846 cmd.append(cstr);
847 cmd.append(post);
848 if (waitFOR(9, "get mic")) {
849 size_t p = replystr.rfind(resp);
850 if (p != string::npos) {
851 return num100(replystr.substr(p + 6));
852 }
853 }
854 get_trace(2, "get_mic_gain()", str2hex(replystr.c_str(), replystr.length()));
855 return 0;
856 }
857
set_mic_gain(int val)858 void RIG_IC7200::set_mic_gain(int val)
859 {
860 cmd = pre_to;
861 cmd.append("\x14\x0B");
862 cmd.append(bcd255(val));
863 cmd.append(post);
864 waitFB("set mic");
865 set_trace(2, "set_mic_gain()", str2hex(cmd.c_str(), cmd.length()));
866 }
867
get_modeA()868 int RIG_IC7200::get_modeA()
869 {
870 int md = A.imode;
871 size_t p = 0;
872
873 string resp = pre_fm;
874 resp += '\x04';
875 cmd = pre_to;
876 cmd += '\x04';
877 cmd.append(post);
878
879 if (waitFOR(8, "get mode A")) {
880 p = replystr.rfind(resp);
881 if (p != string::npos) {
882 if (replystr[p+5] == -1) { md = A.filter = 0; }
883 else {
884 md = replystr[p + 5];
885 if (md > 6) md -= 2;
886 A.filter = replystr[p+6];
887 }
888 }
889 }
890 get_trace(2, "get_modeA()", str2hex(replystr.c_str(), replystr.length()));
891
892 cmd = pre_to;
893 cmd += "\x1A\x04";
894 cmd.append(post);
895 resp = pre_fm;
896 resp += "\x1A\x04";
897 if (waitFOR(9, "data mode?")) {
898 p = replystr.rfind(resp);
899 if (p != string::npos) {
900 if ((replystr[p+6] & 0x01) == 0x01) {
901 if (md == 0) md = 7;
902 if (md == 1) md = 8;
903 }
904 }
905 }
906 if (A.filter > 0 && A.filter < 4)
907 mode_filterA[A.imode] = A.filter;
908
909 get_trace(2, "get_data_modeA()", str2hex(replystr.c_str(), replystr.length()));
910 get_trace(4, "mode_filterA[", IC7200modes_[md], "] = ", szfilter[A.filter-1]);
911
912 if (A.imode == CW7200 || A.imode == CWR7200) {
913 cmd.assign(pre_to).append("\x1A\x03\x37").append(post);
914 resp.assign(pre_fm).append("\x1A\x03\x37");
915 if (waitFOR(9, "get CW sideband")) {
916 p = replystr.rfind(resp);
917 CW_sense = replystr[p + 7];
918 if (CW_sense) IC7200_mode_type[A.imode] = 'U';
919 else IC7200_mode_type[A.imode] = 'L';
920 }
921 }
922
923 return (A.imode = md);
924 }
925
set_modeA(int val)926 void RIG_IC7200::set_modeA(int val)
927 {
928 A.imode = val;
929
930 cmd = pre_to;
931 cmd += '\x06';
932 cmd += mdval[A.imode];
933 cmd += mode_filterA[A.imode];
934 cmd.append( post );
935
936 waitFB("set mode A, default filter");
937
938 set_trace(4, "set mode A[", IC7200modes_[A.imode], "] ", str2hex(replystr.c_str(), replystr.length()));
939
940 if (val < 7) return;
941
942 cmd = pre_to;
943 cmd += '\x1A'; cmd += '\x04';
944 cmd += '\x01';
945 cmd += mode_filterA[A.imode];
946 cmd.append( post);
947 waitFB("set data mode A");
948
949 set_trace(2, "set_data_modeA()", str2hex(replystr.c_str(), replystr.length()));
950 }
951
get_modeB()952 int RIG_IC7200::get_modeB()
953 {
954 int md = B.imode;
955 size_t p = 0;
956
957 cmd = pre_to;
958 cmd += '\x04';
959 cmd.append(post);
960 string resp = pre_fm;
961 resp += '\x04';
962 if (waitFOR(8, "get mode B")) {
963 p = replystr.rfind(resp);
964 if (p != string::npos) {
965 if (replystr[p+5] == -1) { md = B.filter = 0; }
966 else {
967 md = replystr[p+5];
968 if (md > 6) md -= 2;
969 B.filter = replystr[p+6];
970 }
971 }
972 }
973 get_trace(2, "get_modeB()", str2hex(replystr.c_str(), replystr.length()));
974
975 cmd = pre_to;
976 cmd += "\x1A\x04";
977 cmd.append(post);
978 resp = pre_fm;
979 resp += "\x1A\x04";
980 if (waitFOR(9, "get data B")) {
981 p = replystr.rfind(resp);
982 if (p != string::npos) {
983 if ((replystr[p+6] & 0x01) == 0x01) {
984 if (md == 0) md = 7;
985 if (md == 1) md = 8;
986 }
987 }
988 }
989 if (B.filter > 0 && B.filter < 4)
990 mode_filterB[B.imode] = B.filter;
991
992 get_trace(2, "get_data_modeB()", str2hex(replystr.c_str(), replystr.length()));
993 get_trace(4, "mode_filterB[", IC7200modes_[md], "] = ", szfilter[B.filter-1]);
994
995 if (B.imode == CW7200 || B.imode == CWR7200) {
996 cmd.assign(pre_to).append("\x1A\x03\x37").append(post);
997 resp.assign(pre_fm).append("\x1A\x03\x37");
998 if (waitFOR(9, "get CW sideband")) {
999 p = replystr.rfind(resp);
1000 CW_sense = replystr[p + 7];
1001 if (CW_sense) IC7200_mode_type[B.imode] = 'U';
1002 else IC7200_mode_type[B.imode] = 'L';
1003 }
1004 }
1005
1006 return (B.imode = md);
1007 }
1008
set_modeB(int val)1009 void RIG_IC7200::set_modeB(int val)
1010 {
1011 B.imode = val;
1012
1013 cmd = pre_to;
1014 cmd += '\x06';
1015 cmd += mdval[B.imode];
1016 cmd += mode_filterB[B.imode];
1017 cmd.append( post );
1018 waitFB("set mode B, default filter");
1019
1020 set_trace(4, "set mode B[", IC7200modes_[B.imode], "] ", str2hex(replystr.c_str(), replystr.length()));
1021
1022 if (val < 7) return;
1023
1024 cmd = pre_to;
1025 cmd += '\x1A'; cmd += '\x04';
1026 cmd += '\x01';
1027 cmd += mode_filterB[B.imode];
1028 cmd.append( post);
1029 waitFB("set data mode B");
1030
1031 set_trace(2, "set data mode B ", str2hex(replystr.c_str(), replystr.length()));
1032
1033 }
1034
get_modetype(int n)1035 int RIG_IC7200::get_modetype(int n)
1036 {
1037 return _mode_type[n];
1038 }
1039
get_FILT(int mode)1040 int RIG_IC7200::get_FILT(int mode)
1041 {
1042 if (useB) return mode_filterB[mode];
1043 return mode_filterA[mode];
1044 }
1045
set_FILT(int filter)1046 void RIG_IC7200::set_FILT(int filter)
1047 {
1048 if (filter < 1 || filter > 3)
1049 return;
1050
1051 if (useB) {
1052 B.filter = filter;
1053 mode_filterB[B.imode] = filter;
1054
1055 cmd = pre_to;
1056 cmd += '\x06';
1057 cmd += mdval[B.imode];
1058 cmd += filter;
1059 cmd.append( post );
1060
1061 waitFB("set mode/filter B");
1062 set_trace(2, "set mode/filter B", str2hex(replystr.c_str(), replystr.length()));
1063
1064 if (B.imode < 7) return;
1065
1066 cmd = pre_to;
1067 cmd += '\x1A'; cmd += '\x04';
1068 cmd += '\x01';
1069 cmd += filter;
1070 cmd.append( post);
1071 waitFB("set data mode/filter B");
1072 set_trace(2, "set data mode/filter B", str2hex(replystr.c_str(), replystr.length()));
1073
1074 } else {
1075 A.filter = filter;
1076 mode_filterA[A.imode] = filter;
1077
1078 cmd = pre_to;
1079 cmd += '\x06';
1080 cmd += mdval[A.imode];
1081 cmd += filter;
1082 cmd.append( post );
1083 waitFB("set filter A ");
1084 set_trace(2, "set filter A", str2hex(replystr.c_str(), replystr.length()));
1085
1086 if (A.imode < 7) return;
1087
1088 cmd = pre_to;
1089 cmd += '\x1A'; cmd += '\x04';
1090 cmd += '\x01';
1091 cmd += mode_filterA[A.imode];
1092 cmd.append( post);
1093 waitFB("set data filter A");
1094 set_trace(2, "set data filter A", str2hex(replystr.c_str(), replystr.length()));
1095 }
1096
1097 }
1098
FILT(int val)1099 const char *RIG_IC7200::FILT(int val)
1100 {
1101 if (val < 1) val = 1;
1102 if (val > 3) val = 3;
1103 return(szfilter[val - 1]);
1104 }
1105
nextFILT()1106 const char *RIG_IC7200::nextFILT()
1107 {
1108 int val = A.filter;
1109 if (useB) val = B.filter;
1110 val++;
1111 if (val > 3) val = 1;
1112 set_FILT(val);
1113 return szfilter[val - 1];
1114 }
1115
set_FILTERS(std::string s)1116 void RIG_IC7200::set_FILTERS(std::string s)
1117 {
1118 stringstream strm;
1119 strm << s;
1120 for (int i = 0; i < NUM_MODES; i++)
1121 strm >> mode_filterA[i];
1122 for (int i = 0; i < NUM_MODES; i++)
1123 strm >> mode_filterB[i];
1124 for (int i = 0; i < NUM_MODES; i++) {
1125 if (mode_filterA[i] < 1) mode_filterA[i] = 1;
1126 if (mode_filterA[i] > 3) mode_filterA[i] = 3;
1127 if (mode_filterB[i] < 1) mode_filterB[i] = 1;
1128 if (mode_filterB[i] > 3) mode_filterB[i] = 3;
1129 }
1130 }
1131
get_FILTERS()1132 std::string RIG_IC7200::get_FILTERS()
1133 {
1134 for (int i = 0; i < NUM_MODES; i++) {
1135 if (mode_filterA[i] < 1) mode_filterA[i] = 1;
1136 if (mode_filterA[i] > 3) mode_filterA[i] = 3;
1137 if (mode_filterB[i] < 1) mode_filterB[i] = 1;
1138 if (mode_filterB[i] > 3) mode_filterB[i] = 3;
1139 }
1140 stringstream s;
1141 for (int i = 0; i < NUM_MODES; i++)
1142 s << mode_filterA[i] << " ";
1143 for (int i = 0; i < NUM_MODES; i++)
1144 s << mode_filterB[i] << " ";
1145 return s.str();
1146 }
1147
get_BANDWIDTHS()1148 std::string RIG_IC7200::get_BANDWIDTHS()
1149 {
1150 stringstream s;
1151 for (int i = 0; i < NUM_MODES; i++)
1152 s << mode_bwA[i] << " ";
1153 for (int i = 0; i < NUM_MODES; i++)
1154 s << mode_bwB[i] << " ";
1155 return s.str();
1156 }
1157
set_BANDWIDTHS(std::string s)1158 void RIG_IC7200::set_BANDWIDTHS(std::string s)
1159 {
1160 stringstream strm;
1161 strm << s;
1162 for (int i = 0; i < NUM_MODES; i++)
1163 strm >> mode_bwA[i];
1164 for (int i = 0; i < NUM_MODES; i++)
1165 strm >> mode_bwB[i];
1166 }
1167
adjust_bandwidth(int m)1168 int RIG_IC7200::adjust_bandwidth(int m)
1169 {
1170 switch (m) {
1171 case 2: // AM
1172 bandwidths_ = IC7200_AMwidths;
1173 bw_vals_ = IC7200_bw_vals_AM;
1174 bwA = 30;
1175 break;
1176 case 3:
1177 case 5: // CW
1178 bandwidths_ = IC7200_SSBwidths;
1179 bw_vals_ = IC7200_bw_vals_SSB;
1180 bwA = 14;
1181 break;
1182 case 4:
1183 case 6: // RTTY
1184 bandwidths_ = IC7200_RTTYwidths;
1185 bw_vals_ = IC7200_bw_vals_RTTY;
1186 bwA = 28;
1187 break;
1188 case 0:
1189 case 1:
1190 case 7:
1191 case 8:
1192 default: // SSB
1193 bandwidths_ = IC7200_SSBwidths;
1194 bw_vals_ = IC7200_bw_vals_SSB;
1195 bwA = 32;
1196 }
1197 return bwA;
1198 }
1199
def_bandwidth(int m)1200 int RIG_IC7200::def_bandwidth(int m)
1201 {
1202 int bw = adjust_bandwidth(m);
1203 if (useB) {
1204 if (mode_bwB[m] == -1)
1205 mode_bwB[m] = bw;
1206 return mode_bwB[m];
1207 }
1208 if (mode_bwA[m] == -1)
1209 mode_bwA[m] = bw;
1210 return mode_bwA[m];
1211 }
1212
bwtable(int m)1213 const char ** RIG_IC7200::bwtable(int m)
1214 {
1215 switch (m) {
1216 case 2: // AM
1217 return IC7200_AMwidths;
1218 break;
1219 case 3:
1220 case 5: // CW
1221 return IC7200_SSBwidths;
1222 break;
1223 case 4:
1224 case 6: // RTTY
1225 return IC7200_RTTYwidths;
1226 break;
1227 case 0:
1228 case 1:
1229 case 7:
1230 case 8:
1231 default: // SSB
1232 return IC7200_SSBwidths;
1233 }
1234 return IC7200_SSBwidths;
1235 }
1236
set_bwA(int val)1237 void RIG_IC7200::set_bwA(int val)
1238 {
1239 A.iBW = val;
1240 cmd = pre_to;
1241 cmd.append("\x1A\x02");
1242 cmd.append(to_bcd(val, 2));
1243 cmd.append( post );
1244 waitFB("set BW A");
1245 mode_bwA[A.imode] = val;
1246 set_trace(4, "set_bwA() ", bwtable(A.imode)[val], ": ", str2hex(replystr.c_str(), replystr.length()));
1247 }
1248
get_bwA()1249 int RIG_IC7200::get_bwA()
1250 {
1251 cmd = pre_to;
1252 cmd += "\x1A\x02";
1253 cmd.append( post );
1254 string resp = pre_fm;
1255 resp += "\x1A\x02";
1256 int bwval = A.iBW;
1257 if (waitFOR(8, "get BW A")) {
1258 size_t p = replystr.rfind(resp);
1259 if (p != string::npos)
1260 bwval = (fm_bcd(replystr.substr(p+6),2));
1261 }
1262 if (bwval != A.iBW) {
1263 A.iBW = bwval;
1264 }
1265 get_trace(2, "get_bwA()", str2hex(replystr.c_str(), replystr.length()));
1266
1267 mode_bwA[A.imode] = A.iBW;
1268
1269 return A.iBW;
1270 }
1271
set_bwB(int val)1272 void RIG_IC7200::set_bwB(int val)
1273 {
1274 B.iBW = val;
1275 cmd = pre_to;
1276 cmd.append("\x1A\x02");
1277 cmd.append(to_bcd(val, 2));
1278 cmd.append( post );
1279 waitFB("set BW B");
1280 mode_bwB[B.imode] = val;
1281 set_trace(4, "set_bwB() ", bwtable(B.imode)[val], ": ", str2hex(replystr.c_str(), replystr.length()));
1282 }
1283
get_bwB()1284 int RIG_IC7200::get_bwB()
1285 {
1286 cmd = pre_to;
1287 cmd += "\x1A\x02";
1288 cmd.append( post );
1289 string resp = pre_fm;
1290 resp += "\x1A\x02";
1291 int bwval = B.iBW;
1292 if (waitFOR(8, "get BW B")) {
1293 size_t p = replystr.rfind(resp);
1294 if (p != string::npos)
1295 bwval = (fm_bcd(replystr.substr(p+6),2));
1296 }
1297 if (bwval != B.iBW) {
1298 B.iBW = bwval;
1299 }
1300 get_trace(2, "get_bwB()", str2hex(replystr.c_str(), replystr.length()));
1301 mode_bwB[B.imode] = B.iBW;
1302 return B.iBW;
1303 }
1304
set_auto_notch(int val)1305 void RIG_IC7200::set_auto_notch(int val)
1306 {
1307 cmd = pre_to;
1308 cmd += '\x16';
1309 cmd += '\x41';
1310 cmd += (unsigned char)val;
1311 cmd.append( post );
1312 waitFB("set AN");
1313 set_trace(2, "set_auto_notch()", str2hex(cmd.c_str(), cmd.length()));
1314 }
1315
get_auto_notch()1316 int RIG_IC7200::get_auto_notch()
1317 {
1318 string cstr = "\x16\x41";
1319 string resp = pre_fm;
1320 resp.append(cstr);
1321 cmd = pre_to;
1322 cmd.append(cstr);
1323 cmd.append( post );
1324 if (waitFOR(8, "get AN")) {
1325 get_trace(2, "get_auto_notch()", str2hex(replystr.c_str(), replystr.length()));
1326 size_t p = replystr.rfind(resp);
1327 if (p != string::npos) {
1328 if (replystr[p+6] == 0x01) {
1329 auto_notch_label("AN", true);
1330 return true;
1331 } else {
1332 auto_notch_label("AN", false);
1333 return false;
1334 }
1335 }
1336 }
1337 return progStatus.auto_notch;
1338 }
1339
1340 static int comp_level[] = {11,34,58,81,104,128,151,174,197,221,244};
set_compression(int on,int val)1341 void RIG_IC7200::set_compression(int on, int val)
1342 {
1343 cmd = pre_to;
1344 cmd.append("\x16\x44");
1345 if (on) cmd += '\x01';
1346 else cmd += '\x00';
1347 cmd.append(post);
1348 waitFB("set Comp ON/OFF");
1349 set_trace(2, "set_compression_on_off()", str2hex(cmd.c_str(), cmd.length()));
1350
1351 if (val < 0) return;
1352 if (val > 10) return;
1353
1354 cmd.assign(pre_to).append("\x14\x0E");
1355 cmd.append(to_bcd(comp_level[val], 3));
1356 cmd.append( post );
1357 waitFB("set comp");
1358 set_trace(2, "set_compression_level()", str2hex(cmd.c_str(), cmd.length()));
1359 }
1360
get_compression(int & on,int & val)1361 void RIG_IC7200::get_compression(int &on, int &val)
1362 {
1363 std::string resp;
1364
1365 cmd.assign(pre_to).append("\x16\x44").append(post);
1366
1367 resp.assign(pre_fm).append("\x16\x44");
1368
1369 if (waitFOR(8, "get comp on/off")) {
1370 get_trace(2, "get_comp_on_off()", str2hex(replystr.c_str(), replystr.length()));
1371 size_t p = replystr.find(resp);
1372 if (p != string::npos)
1373 on = (replystr[p+6] == 0x01);
1374 }
1375
1376 cmd.assign(pre_to).append("\x14\x0E").append(post);
1377 resp.assign(pre_fm).append("\x14\x0E");
1378
1379 if (waitFOR(9, "get comp level")) {
1380 get_trace(2, "get_comp_level()", str2hex(replystr.c_str(), replystr.length()));
1381 size_t p = replystr.find(resp);
1382 int level = 0;
1383 if (p != string::npos) {
1384 level = fm_bcd(replystr.substr(p+6), 3);
1385 for (val = 0; val < 11; val++)
1386 if (level <= comp_level[val]) break;
1387 }
1388 }
1389 }
1390
set_vox_onoff()1391 void RIG_IC7200::set_vox_onoff()
1392 {
1393 if (progStatus.vox_onoff) {
1394 cmd = pre_to;
1395 cmd.append("\x16\x46");
1396 cmd += '\x01';
1397 cmd.append(post);
1398 waitFB("set Vox ON");
1399 } else {
1400 cmd = pre_to;
1401 cmd.append("\x16\x46");
1402 cmd += '\x00';
1403 cmd.append(post);
1404 waitFB("set Vox OFF");
1405 }
1406 set_trace(2, "set_vox_on_off()", str2hex(cmd.c_str(), cmd.length()));
1407 }
1408
set_notch(bool on,int freq)1409 void RIG_IC7200::set_notch(bool on, int freq)
1410 {
1411 int hexval;
1412 switch (vfo->imode) {
1413 default: case USB7200: case USBD7200: case RTTYR7200:
1414 hexval = freq - 1500;
1415 break;
1416 case LSB7200: case LSBD7200: case RTTY7200:
1417 hexval = 1500 - freq;
1418 break;
1419 case CW7200:
1420 if (CW_sense)
1421 hexval = freq - progStatus.cw_spot_tone;
1422 else
1423 hexval = progStatus.cw_spot_tone - freq;
1424 break;
1425 case CWR7200:
1426 if (CW_sense)
1427 hexval = progStatus.cw_spot_tone - freq;
1428 else
1429 hexval = freq - progStatus.cw_spot_tone;
1430 break;
1431 }
1432
1433 hexval /= 20;
1434 hexval += 128;
1435 if (hexval < 0) hexval = 0;
1436 if (hexval > 255) hexval = 255;
1437
1438 cmd = pre_to;
1439 cmd.append("\x16\x48");
1440 cmd += on ? '\x01' : '\x00';
1441 cmd.append(post);
1442 waitFB("set notch");
1443
1444 cmd = pre_to;
1445 cmd.append("\x14\x0D");
1446 cmd.append(to_bcd(hexval,3));
1447 cmd.append(post);
1448 waitFB("set notch val");
1449 }
1450
get_notch(int & val)1451 bool RIG_IC7200::get_notch(int &val)
1452 {
1453 bool on = false;
1454 val = 1500;
1455
1456 string cstr = "\x16\x48";
1457 string resp = pre_fm;
1458 resp.append(cstr);
1459 cmd = pre_to;
1460 cmd.append(cstr);
1461 cmd.append( post );
1462 if (waitFOR(8, "get notch")) {
1463 size_t p = replystr.rfind(resp);
1464 if (p != string::npos)
1465 on = replystr[p + 6];
1466 cmd = pre_to;
1467 resp = pre_fm;
1468 cstr = "\x14\x0D";
1469 cmd.append(cstr);
1470 resp.append(cstr);
1471 cmd.append(post);
1472 if (waitFOR(9, "notch val")) {
1473 size_t p = replystr.rfind(resp);
1474 if (p != string::npos) {
1475 val = (int)ceil(fm_bcd(replystr.substr(p+6),3));
1476 val -= 128;
1477 val *= 20;
1478 switch (vfo->imode) {
1479 default: case USB7200: case USBD7200: case RTTYR7200:
1480 val = 1500 + val;
1481 break;
1482 case LSB: case LSBD7200: case RTTY7200:
1483 val = 1500 - val;
1484 break;
1485 case CW7200:
1486 if (CW_sense)
1487 val = progStatus.cw_spot_tone + val;
1488 else
1489 val = progStatus.cw_spot_tone - val;
1490 break;
1491 case CWR7200:
1492 if (CW_sense)
1493 val = progStatus.cw_spot_tone - val;
1494 else
1495 val = progStatus.cw_spot_tone + val;
1496 break;
1497 }
1498 }
1499 }
1500 }
1501 return on;
1502 }
1503
get_notch_min_max_step(int & min,int & max,int & step)1504 void RIG_IC7200::get_notch_min_max_step(int &min, int &max, int &step)
1505 {
1506 switch (vfo->imode) {
1507 default:
1508 case USB7200: case USBD7200: case RTTYR7200:
1509 case LSB7200: case LSBD7200: case RTTY7200:
1510 min = 0; max = 3000; step = 20; break;
1511 case CW7200: case CWR7200:
1512 min = progStatus.cw_spot_tone - 500;
1513 max = progStatus.cw_spot_tone + 500;
1514 step = 20;
1515 break;
1516 }
1517 }
1518
1519 static int agcval = 0;
get_agc()1520 int RIG_IC7200::get_agc()
1521 {
1522 cmd = pre_to;
1523 cmd.append("\x16\x12");
1524 cmd.append(post);
1525 if (waitFOR(8, "get AGC")) {
1526 size_t p = replystr.find(pre_fm);
1527 if (p == string::npos) return agcval;
1528 return (agcval = replystr[p+6]); // 1 = off, 2 = FAST, 3 = SLOW
1529 }
1530 get_trace(2, "get_agc()", str2hex(replystr.c_str(), replystr.length()));
1531 return agcval;
1532 }
1533
incr_agc()1534 int RIG_IC7200::incr_agc()
1535 {
1536 agcval++;
1537 if (agcval == 3) agcval = 0;
1538 cmd = pre_to;
1539 cmd.append("\x16\x12");
1540 cmd += agcval;
1541 cmd.append(post);
1542 waitFB("set AGC");
1543 return agcval;
1544 }
1545
1546
1547 static const char *agcstrs[] = {"AGC", "FST", "SLO"};
agc_label()1548 const char *RIG_IC7200::agc_label()
1549 {
1550 return agcstrs[agcval];
1551 }
1552
agc_val()1553 int RIG_IC7200::agc_val()
1554 {
1555 return (agcval);
1556 }
1557
set_if_shift(int val)1558 void RIG_IC7200::set_if_shift(int val)
1559 {
1560 int shift;
1561 sh_ = val;
1562 if (val == 0) sh_on_ = false;
1563 else sh_on_ = true;
1564
1565 shift = 128 + val * 128 / 50;
1566 if (shift < 0) shift = 0;
1567 if (shift > 255) shift = 255;
1568
1569 cmd = pre_to;
1570 cmd.append("\x14\x07");
1571 cmd.append(to_bcd(shift, 3));
1572 cmd.append(post);
1573 waitFB("set IF on/off");
1574 set_trace(2, "set_if_shift_on_off()", str2hex(cmd.c_str(), cmd.length()));
1575
1576 cmd = pre_to;
1577 cmd.append("\x14\x08");
1578 cmd.append(to_bcd(shift, 3));
1579 cmd.append(post);
1580 waitFB("set IF val");
1581 set_trace(2, "set_if_shift_val()", str2hex(cmd.c_str(), cmd.length()));
1582 }
1583
get_if_shift(int & val)1584 bool RIG_IC7200::get_if_shift(int &val) {
1585 val = sh_;
1586 return sh_on_;
1587 }
1588
get_if_min_max_step(int & min,int & max,int & step)1589 void RIG_IC7200::get_if_min_max_step(int &min, int &max, int &step)
1590 {
1591 min = -50;
1592 max = +50;
1593 step = 1;
1594 }
1595
set_pbt_inner(int val)1596 void RIG_IC7200::set_pbt_inner(int val)
1597 {
1598 int shift = 128 + val * 128 / 50;
1599 if (shift < 0) shift = 0;
1600 if (shift > 255) shift = 255;
1601
1602 cmd = pre_to;
1603 cmd.append("\x14\x07");
1604 cmd.append(to_bcd(shift, 3));
1605 cmd.append(post);
1606 waitFB("set PBT inner");
1607 set_trace(2, "set_PBT_inner()", str2hex(cmd.c_str(), cmd.length()));
1608 }
1609
set_pbt_outer(int val)1610 void RIG_IC7200::set_pbt_outer(int val)
1611 {
1612 int shift = 128 + val * 128 / 50;
1613 if (shift < 0) shift = 0;
1614 if (shift > 255) shift = 255;
1615
1616 cmd = pre_to;
1617 cmd.append("\x14\x08");
1618 cmd.append(to_bcd(shift, 3));
1619 cmd.append(post);
1620 waitFB("set PBT outer");
1621 set_trace(2, "set_PBT_outer()", str2hex(cmd.c_str(), cmd.length()));
1622 }
1623
get_pbt_inner()1624 int RIG_IC7200::get_pbt_inner()
1625 {
1626 int val = 0;
1627 string cstr = "\x14\x07";
1628 string resp = pre_fm;
1629 resp.append(cstr);
1630 cmd = pre_to;
1631 cmd.append(cstr);
1632 cmd.append( post );
1633 if (waitFOR(9, "get pbt inner")) {
1634 size_t p = replystr.rfind(resp);
1635 if (p != string::npos) {
1636 val = num100(replystr.substr(p+6));
1637 val -= 50;
1638 }
1639 }
1640 get_trace(2, "get_pbt_inner()", str2hex(replystr.c_str(), replystr.length()));
1641 return val;
1642 }
1643
get_pbt_outer()1644 int RIG_IC7200::get_pbt_outer()
1645 {
1646 int val = 0;
1647 string cstr = "\x14\x08";
1648 string resp = pre_fm;
1649 resp.append(cstr);
1650 cmd = pre_to;
1651 cmd.append(cstr);
1652 cmd.append( post );
1653 if (waitFOR(9, "get pbt outer")) {
1654 size_t p = replystr.rfind(resp);
1655 if (p != string::npos) {
1656 val = num100(replystr.substr(p+6));
1657 val -= 50;
1658 }
1659 }
1660 get_trace(2, "get_pbt_outer()", str2hex(replystr.c_str(), replystr.length()));
1661 return val;
1662 }
1663
1664 // CW methods
1665
get_cw_wpm_min_max(int & min,int & max)1666 void RIG_IC7200::get_cw_wpm_min_max(int &min, int &max)
1667 {
1668 min = 6; max = 48;
1669 }
1670
set_cw_wpm()1671 void RIG_IC7200::set_cw_wpm()
1672 {
1673 int iwpm = round((progStatus.cw_wpm - 6) * 255 / 42 + 0.5);
1674 minmax(0, 255, iwpm);
1675
1676 cmd.assign(pre_to).append("\x14\x0C");
1677 cmd.append(to_bcd(iwpm, 3));
1678 cmd.append( post );
1679 waitFB("SET cw wpm");
1680 set_trace(2, "set_cw_wpm()", str2hex(cmd.c_str(), cmd.length()));
1681 }
1682
set_break_in()1683 void RIG_IC7200::set_break_in()
1684 {
1685 // 16 47 00 break-in off
1686 // 16 47 01 break-in semi
1687 // 16 47 02 break-in full
1688
1689 cmd.assign(pre_to).append("\x16\x47");
1690
1691 switch (progStatus.break_in) {
1692 case 2: cmd += '\x02'; break_in_label("FULL"); break;
1693 case 1: cmd += '\x01'; break_in_label("SEMI"); break;
1694 case 0:
1695 default: cmd += '\x00'; break_in_label("BK-IN");
1696 }
1697 cmd.append(post);
1698 waitFB("SET break-in");
1699 set_trace(2, "set_break_in()", str2hex(cmd.c_str(), cmd.length()));
1700 }
1701
get_cw_qsk_min_max_step(double & min,double & max,double & step)1702 void RIG_IC7200::get_cw_qsk_min_max_step(double &min, double &max, double &step)
1703 {
1704 min = 2.0; max = 13.0; step = 0.1;
1705 }
1706
set_cw_qsk()1707 void RIG_IC7200::set_cw_qsk()
1708 {
1709 int qsk = round ((progStatus.cw_qsk - 2.0) * 255.0 / 11.0 + 0.5);
1710 minmax(0, 255, qsk);
1711
1712 cmd.assign(pre_to).append("\x14\x0F");
1713 cmd.append(to_bcd(qsk, 3));
1714 cmd.append(post);
1715 waitFB("Set cw qsk delay");
1716 set_trace(2, "set_cw_qsk()", str2hex(cmd.c_str(), cmd.length()));
1717 }
1718
get_cw_spot_tone_min_max_step(int & min,int & max,int & step)1719 void RIG_IC7200::get_cw_spot_tone_min_max_step(int &min, int &max, int &step)
1720 {
1721 min = 300; max = 900; step = 5;
1722 }
1723
set_cw_spot_tone()1724 void RIG_IC7200::set_cw_spot_tone()
1725 {
1726 cmd.assign(pre_to).append("\x14\x09"); // values 0=300Hz 255=900Hz
1727 int n = round((progStatus.cw_spot_tone - 300) * 255.0 / 600.0 + 0.5);
1728 minmax(0, 255, n);
1729
1730 cmd.append(to_bcd(n, 3));
1731 cmd.append( post );
1732 waitFB("SET cw spot tone");
1733 set_trace(2, "set_cw_spot_tone()", str2hex(cmd.c_str(), cmd.length()));
1734 }
1735
set_cw_vol()1736 void RIG_IC7200::set_cw_vol()
1737 {
1738 cmd.assign(pre_to);
1739 cmd.append("\x1A\x03\x06");
1740 cmd.append(to_bcd((int)(progStatus.cw_vol * 2.55), 3));
1741 cmd.append( post );
1742 waitFB("SET cw sidetone volume");
1743 set_trace(2, "set_cw_vol()", str2hex(cmd.c_str(), cmd.length()));
1744 }
1745
setVfoAdj(double v)1746 void RIG_IC7200::setVfoAdj(double v)
1747 {
1748 vfo_ = v;
1749 cmd.assign(pre_to);
1750 cmd.append("\x1A\x03\x49");
1751 cmd.append(bcd255(int(v)));
1752 cmd.append(post);
1753 waitFB("SET vfo adjust");
1754 set_trace(2, "set_vfo_adj()", str2hex(cmd.c_str(), cmd.length()));
1755 }
1756
getVfoAdj()1757 double RIG_IC7200::getVfoAdj()
1758 {
1759 cmd.assign(pre_to);
1760 cmd.append("\x1A\x03\x49");
1761 cmd.append(post);
1762
1763 if (waitFOR(10, "get vfo adj")) {
1764 size_t p = replystr.find(pre_fm);
1765 if (p != string::npos) {
1766 vfo_ = num100(replystr.substr(p+7));
1767 }
1768 }
1769 get_trace(2, "get_vfo_adj()", str2hex(replystr.c_str(), replystr.length()));
1770 return vfo_;
1771 }
1772
get_band_selection(int v)1773 void RIG_IC7200::get_band_selection(int v)
1774 {
1775 cmd.assign(pre_to);
1776 cmd.append("\x1A\x01");
1777 cmd += to_bcd_be( v, 2 );
1778 cmd += '\x01';
1779 cmd.append( post );
1780
1781 if (waitFOR(17, "get band")) {
1782 std::string ans = replystr;
1783 size_t p = ans.rfind(pre_fm);
1784 if (p != string::npos) {
1785 unsigned long int bandfreq = fm_bcd_be(ans.substr(p+8, 5), 10);
1786 int bandmode = ans[p+13];
1787 int bandfilter = ans[p+14];
1788 int banddata = ans[p+15] & 0x10;
1789 if ((bandmode == 0 || bandmode == 1) && banddata) bandmode += 7;
1790 if (useB) {
1791 set_vfoB(bandfreq);
1792 set_modeB(bandmode);
1793 set_FILT(bandfilter);
1794 } else {
1795 set_vfoA(bandfreq);
1796 set_modeA(bandmode);
1797 set_FILT(bandfilter);
1798 }
1799 get_trace(2, "get_band", str2hex(ans.substr(p).c_str(), ans.substr(p).length()));
1800 }
1801 }
1802 }
1803
set_band_selection(int v)1804 void RIG_IC7200::set_band_selection(int v)
1805 {
1806 unsigned long int freq = (useB ? B.freq : A.freq);
1807 int mode = (useB ? B.imode : A.imode);
1808 int fil = (useB ? B.filter : A.filter);
1809
1810 cmd.assign(pre_to);
1811 cmd.append("\x1A\x01");
1812 cmd += to_bcd_be( v, 2 );
1813 cmd += '\x01';
1814 cmd.append( to_bcd_be( freq, 10 ) );
1815 cmd += mdval[mode];
1816 cmd += fil;
1817 if (mode >= 7)
1818 cmd += '\x10';
1819 else
1820 cmd += '\x00';
1821 cmd.append(post);
1822 waitFB("set band");
1823 set_trace(2, "SET", str2hex(cmd.c_str(), cmd.length()));
1824
1825 cmd.assign(pre_to);
1826 cmd.append("\x1A\x01");
1827 cmd += to_bcd_be( v, 2 );
1828 cmd += '\x01';
1829 cmd.append( post );
1830
1831 waitFOR(17, "get band stack");
1832 get_trace(2, "get_band_stack", str2hex(replystr.c_str(), replystr.length()));
1833 }
1834
1835