1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2017
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 <sstream>
22 #include "FT891.h"
23 #include "debug.h"
24 #include "support.h"
25 #include "trace.h"
26
27 #define FL891_WAIT_TIME 200
28
29 enum mFT891 {
30 mLSB, mUSB, mCW, mFM, mAM, mTTYL, mCWR, mDATAL, mTTYU, mFMN, mDATAU, mAMN };
31 // 0 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 // mode index
32
33 static const char FT891name_[] = "FT-891";
34
35 static const char *FT891modes_[] = {
36 "LSB", "USB", "CW-U", "FM", "AM", "RTTY-L", "CW-L", "DATA-L", "RTTY-U", "FM-N", "DATA-U", "AM-N", NULL};
37
38 static const char FT891_mode_chr[] = {
39 '1', '2', '3', '4', '5', '6', '7', '8', '9', 'B', 'C', 'D' };
40
41 static const char FT891_mode_type[] = {
42 'L', 'U', 'U', 'U', 'U', 'L', 'L', 'L', 'U', 'U', 'U', 'U' };
43
44 static const int FT891_def_bw[] = {
45 17, 17, 5, 0, 0, 10, 5, 16, 10, 0, 16, 0 };
46 // mLSB, mUSB, mCW, mFM, mAM, mTTYL, mCWR, mDATAL, mTTYU, mFMN, mDATAU, mAMN
47
48 static const char *FT891_widths_SSB[] = {
49 "200", "400", "600", "850", "1100", "1350", "1500", "1650", "1800", "1950",
50 "2100", "2200", "2300", "2400", "2500", "2600", "2700", "2800", "2900", "3000",
51 "3200", NULL };
52
53 static int FT891_wvals_SSB[] = {
54 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
55 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
56 21, WVALS_LIMIT};
57
58 static const char *FT891_widths_SSBD[] = {
59 "50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
60 "800", "1200", "1400", "1700", "2000", "2400", "3000", NULL };
61
62 static int FT891_wvals_SSBD[] = {
63 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
64 11, 12, 13, 14, 15, 16, 17, WVALS_LIMIT};
65
66 static const char *FT891_widths_CW[] = {
67 "50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
68 "800", "1200", "1400", "1700", "2000", "2400", "3000", NULL };
69
70 static int FT891_wvals_CW[] = {
71 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
72 11, 12, 13, 14, 15, 16, 17, WVALS_LIMIT};
73
74 // Single bandwidth modes
75 static const char *FT891_widths_AMFMnar[] = { "NARR", NULL };
76 static const char *FT891_widths_AMFMnorm[] = { "NORM", NULL };
77
78 static const int FT891_wvals_AMFM[] = { 0, WVALS_LIMIT };
79
80 static const int FT891_wvals_NN[] = {0, 1, WVALS_LIMIT};
81
82 static GUI rig_widgets[]= {
83 { (Fl_Widget *)btnVol, 2, 125, 50 },
84 { (Fl_Widget *)sldrVOLUME, 54, 125, 156 },
85 { (Fl_Widget *)sldrRFGAIN, 54, 145, 156 },
86 { (Fl_Widget *)btnIFsh, 214, 105, 50 },
87 { (Fl_Widget *)sldrIFSHIFT, 266, 105, 156 },
88 { (Fl_Widget *)btnNotch, 214, 125, 50 },
89 { (Fl_Widget *)sldrNOTCH, 266, 125, 156 },
90 { (Fl_Widget *)sldrMICGAIN, 266, 145, 156 },
91 { (Fl_Widget *)sldrPOWER, 266, 165, 156 },
92 { (Fl_Widget *)btnNR, 2, 165, 50 },
93 { (Fl_Widget *)sldrNR, 54, 165, 156 },
94 { (Fl_Widget *)NULL, 0, 0, 0 }
95 };
96
RIG_FT891()97 RIG_FT891::RIG_FT891() {
98 // base class values
99 IDstr = "ID";
100 name_ = FT891name_;
101 modes_ = FT891modes_;
102 bandwidths_ = FT891_widths_SSB;
103 bw_vals_ = FT891_wvals_SSB;
104
105 widgets = rig_widgets;
106
107 comm_baudrate = BR38400;
108 stopbits = 1;
109 comm_retries = 2;
110 comm_wait = 5;
111 comm_timeout = 50;
112 comm_rtscts = true;
113 comm_rtsplus = false;
114 comm_dtrplus = false;
115 comm_catptt = true;
116 comm_rtsptt = false;
117 comm_dtrptt = false;
118
119 A.imode = B.imode = modeB = modeA = def_mode = 1;
120 A.iBW = B.iBW = bwA = bwB = def_bw = 12;
121 A.freq = B.freq = freqA = freqB = def_freq = 14070000;
122
123 has_compression =
124 has_compON =
125 has_a2b =
126 has_ext_tuner =
127 has_xcvr_auto_on_off =
128 // has_split =
129 // has_split_AB =
130 has_noise_reduction =
131 has_noise_reduction_control =
132 has_extras =
133 has_vox_onoff =
134 has_vox_gain =
135 has_vox_anti =
136 has_vox_hang =
137 has_vox_on_dataport =
138
139 // has_vfo_adj =
140
141 has_cw_wpm =
142 has_cw_keyer =
143 // has_cw_vol =
144 has_cw_spot =
145 has_cw_spot_tone =
146 has_cw_qsk =
147 has_cw_weight =
148
149 has_band_selection =
150
151 can_change_alt_vfo =
152 has_smeter =
153 has_alc_control =
154 has_swr_control =
155 has_power_out =
156 has_power_control =
157 has_volume_control =
158 has_rf_control =
159 has_sql_control =
160 has_micgain_control =
161 has_mode_control =
162 has_nb_level =
163 has_noise_control =
164 has_bandwidth_control =
165 has_notch_control =
166 has_auto_notch =
167 has_attenuator_control =
168 has_preamp_control =
169 has_ifshift_control =
170 has_ptt_control =
171 has_tune_control = true;
172
173 // derived specific
174 atten_level = 1;
175 preamp_level = 1;
176 notch_on = false;
177 m_60m_indx = 0;
178
179 precision = 1;
180 ndigits = 9;
181
182 }
183
initialize()184 void RIG_FT891::initialize()
185 {
186 rig_widgets[0].W = btnVol;
187 rig_widgets[1].W = sldrVOLUME;
188 rig_widgets[2].W = sldrRFGAIN;
189 rig_widgets[3].W = btnIFsh;
190 rig_widgets[4].W = sldrIFSHIFT;
191 rig_widgets[5].W = btnNotch;
192 rig_widgets[6].W = sldrNOTCH;
193 rig_widgets[7].W = sldrMICGAIN;
194 rig_widgets[8].W = sldrPOWER;
195 rig_widgets[9].W = btnNR;
196 rig_widgets[10].W = sldrNR;
197
198 // set progStatus defaults
199 if (progStatus.notch_val < 10) progStatus.notch_val = 1500;
200 if (progStatus.noise_reduction_val < 1) progStatus.noise_reduction_val = 1;
201 if (progStatus.power_level < 5) progStatus.power_level = 5;
202 // first-time-thru, or reset
203 if (progStatus.cw_qsk < 15) {
204 progStatus.cw_qsk = 15;
205 progStatus.cw_spot_tone = 700;
206 progStatus.cw_weight = 3.0;
207 progStatus.cw_wpm = 18;
208 progStatus.vox_on_dataport = false;
209 progStatus.vox_gain = 50;
210 progStatus.vox_anti = 50;
211 progStatus.vox_hang = 500;
212 }
213 // Disable Auto Information mode
214 sendCommand("AI0;");
215
216 op_yaesu_select60->deactivate();
217
218 }
219
post_initialize()220 void RIG_FT891::post_initialize()
221 {
222 }
223
check()224 bool RIG_FT891::check ()
225 {
226 cmd = rsp = "FA";
227 cmd += ';';
228 int ret = wait_char(';',12, FL891_WAIT_TIME, "check", ASC);
229 if (ret >= 12) return true;
230 return false;
231 }
232
get_vfoA()233 unsigned long int RIG_FT891::get_vfoA ()
234 {
235 // When VFOA is 'selected', radio has it actively loaded in FA, otherwise
236 // it is in FB
237 if (rigbase::isOnA()) {
238 cmd = rsp = "FA";
239 } else {
240 cmd = rsp = "FB";
241 }
242 cmd += ';';
243
244 wait_char(';',12, FL891_WAIT_TIME, "get vfo A", ASC);
245
246 get_trace(4, "get_vfoA():\n", cmd.c_str(), "\n", replystr.c_str());
247
248 size_t p = replystr.rfind(rsp);
249 if (p == string::npos) return freqA;
250 p += 2;
251 int f = 0;
252 for (int n = 0; n < ndigits; n++)
253 f = f * 10 + replystr[p + n] - '0';
254 freqA = f;
255 return freqA;
256 }
257
set_vfoA(unsigned long int freq)258 void RIG_FT891::set_vfoA (unsigned long int freq)
259 {
260 freqA = freq;
261
262 // When VFOA is 'selected', radio has it actively loaded in FA, otherwise
263 // it is in FB
264 if (rigbase::isOnA()) {
265 cmd = "FA000000000;";
266 } else {
267 cmd = "FB000000000;";
268 }
269
270 for (int i = 0; i < ndigits; i++) {
271 cmd[ndigits + 1 - i] += freq % 10;
272 freq /= 10;
273 }
274
275 sendCommand(cmd);
276 showresp(WARN, ASC, "SET vfo A", cmd, replystr);
277
278 set_trace(4, "set_vfoA():\n", cmd.c_str(), "\n", replystr.c_str());
279
280 }
281
get_vfoB()282 unsigned long int RIG_FT891::get_vfoB ()
283 {
284 // When VFOB is 'selected', radio has it actively loaded in FA, otherwise
285 // it is in FB
286 if (rigbase::isOnB()) {
287 cmd = rsp = "FA";
288 } else {
289 cmd = rsp = "FB";
290 }
291 cmd += ';';
292 wait_char(';',12, FL891_WAIT_TIME, "get vfo B", ASC);
293
294 get_trace(4, "get_vfoB():\n", cmd.c_str(), "\n", replystr.c_str());
295
296 size_t p = replystr.rfind(rsp);
297 if (p == string::npos) return freqB;
298 p += 2;
299 int f = 0;
300 for (int n = 0; n < ndigits; n++)
301 f = f * 10 + replystr[p + n] - '0';
302 freqB = f;
303 return freqB;
304 }
305
306
set_vfoB(unsigned long int freq)307 void RIG_FT891::set_vfoB (unsigned long int freq)
308 {
309 freqB = freq;
310
311 // When VFOB is 'selected', radio has it actively loaded in FA, otherwise
312 // it is in FB
313 if (rigbase::isOnB()) {
314 cmd = "FA000000000;";
315 } else {
316 cmd = "FB000000000;";
317 }
318
319 for (int i = 0; i < ndigits; i++) {
320 cmd[ndigits + 1 - i] += freq % 10;
321 freq /= 10;
322 }
323
324 sendCommand(cmd);
325 showresp(WARN, ASC, "SET vfo B", cmd, replystr);
326
327 set_trace(4, "set_vfoB():\n", cmd.c_str(), "\n", replystr.c_str());
328 }
329
selectA()330 void RIG_FT891::selectA()
331 {
332 if (rigbase::isOnA()) return;
333 rigbase::selectA();
334
335 cmd = "SV;";
336
337 sendCommand(cmd);
338 showresp(WARN, ASC, "select A", cmd, replystr);
339
340 get_trace(4, "selectA():\n", cmd.c_str(), "\n", replystr.c_str());
341 }
342
selectB()343 void RIG_FT891::selectB()
344 {
345 if (rigbase::isOnB()) return;
346 rigbase::selectB();
347
348 cmd = "SV;";
349
350 sendCommand(cmd);
351 showresp(WARN, ASC, "select B", cmd, replystr);
352
353 set_trace(4, "selectB():\n", cmd.c_str(), "\n", replystr.c_str());
354 }
355
356
A2B()357 void RIG_FT891::A2B()
358 {
359 cmd = "AB;";
360
361 sendCommand(cmd);
362 showresp(WARN, ASC, "vfo A->B", cmd, replystr);
363
364 set_trace(4, "A2B():\n", cmd.c_str(), "\n", replystr.c_str());
365 }
366
B2A()367 void RIG_FT891::B2A()
368 {
369 cmd = "BA;";
370
371 sendCommand(cmd);
372 showresp(WARN, ASC, "vfo B->A", cmd, replystr);
373
374 set_trace(4, "B2A():\n", cmd.c_str(), "\n", replystr.c_str());
375 }
376
swapAB()377 void RIG_FT891::swapAB()
378 {
379 rigbase::swapAB();
380
381 cmd = "SV;";
382
383 sendCommand(cmd);
384 showresp(WARN, ASC, "vfo A<>B", cmd, replystr);
385
386 set_trace(4, "swapAB():\n", cmd.c_str(), "\n", replystr.c_str());
387 }
388
get_smeter()389 int RIG_FT891::get_smeter()
390 {
391 cmd = rsp = "SM0";
392 cmd += ';';
393 wait_char(';',7, FL891_WAIT_TIME, "get smeter", ASC);
394
395 size_t p = replystr.rfind(rsp);
396 if (p == string::npos) return 0;
397 if (p + 6 >= replystr.length()) return 0;
398 int mtr = atoi(&replystr[p+3]);
399 mtr = mtr / 2.56;
400 return mtr;
401 }
402
get_swr()403 int RIG_FT891::get_swr()
404 {
405 cmd = rsp = "RM6";
406 cmd += ';';
407 wait_char(';',7, FL891_WAIT_TIME, "get swr", ASC);
408
409 size_t p = replystr.rfind(rsp);
410 if (p == string::npos) return 0;
411 if (p + 6 >= replystr.length()) return 0;
412 int mtr = atoi(&replystr[p+3]);
413 return (int)ceil(mtr / 2.56);
414 }
415
get_alc()416 int RIG_FT891::get_alc()
417 {
418 cmd = rsp = "RM4";
419 cmd += ';';
420 wait_char(';',7, FL891_WAIT_TIME, "get alc", ASC);
421
422 size_t p = replystr.rfind(rsp);
423 if (p == string::npos) return 0;
424 if (p + 6 >= replystr.length()) return 0;
425 int mtr = atoi(&replystr[p+3]);
426 return (int)ceil(mtr / 2.56);
427 }
428
get_power_out()429 int RIG_FT891::get_power_out()
430 {
431 cmd = rsp = "RM5";
432 sendCommand(cmd.append(";"));
433 wait_char(';',7, FL891_WAIT_TIME, "get pout", ASC);
434
435 size_t p = replystr.rfind(rsp);
436 if (p == string::npos) return 0;
437 if (p + 6 >= replystr.length()) return 0;
438
439 // this needs to be measured and adjusted
440 int mtr = atoi(&replystr[p+3]);
441 return (int)ceil(mtr / 2.56);
442 }
443
444 // Transceiver power level
get_power_control()445 int RIG_FT891::get_power_control()
446 {
447 cmd = rsp = "PC";
448 cmd += ';';
449 wait_char(';',6, FL891_WAIT_TIME, "get power", ASC);
450
451 size_t p = replystr.rfind(rsp);
452 if (p == string::npos) return progStatus.power_level;
453 if (p + 5 >= replystr.length()) return progStatus.power_level;
454
455 int mtr = atoi(&replystr[p+2]);
456 return mtr;
457 }
458
set_power_control(double val)459 void RIG_FT891::set_power_control(double val)
460 {
461 int ival = (int)val;
462 cmd = "PC000;";
463 for (int i = 4; i > 1; i--) {
464 cmd[i] += ival % 10;
465 ival /= 10;
466 }
467
468 sendCommand(cmd);
469 showresp(WARN, ASC, "SET power", cmd, replystr);
470
471 set_trace(4, "set_power_control():\n", cmd.c_str(), "\n", replystr.c_str());
472
473 }
474
475 // Volume control return 0 ... 100
get_volume_control()476 int RIG_FT891::get_volume_control()
477 {
478 cmd = rsp = "AG0";
479 cmd += ';';
480 wait_char(';',7, FL891_WAIT_TIME, "get vol", ASC);
481
482 size_t p = replystr.rfind(rsp);
483 if (p == string::npos) return progStatus.volume;
484 if (p + 6 >= replystr.length()) return progStatus.volume;
485 int val = round(atoi(&replystr[p+3]) / 2.55);
486 if (val > 100) val = 100;
487 return ceil(val);
488 }
489
set_volume_control(int val)490 void RIG_FT891::set_volume_control(int val)
491 {
492 int ivol = (int)(val * 2.55);
493 cmd = "AG0000;";
494 for (int i = 5; i > 2; i--) {
495 cmd[i] += ivol % 10;
496 ivol /= 10;
497 }
498
499 sendCommand(cmd);
500 showresp(WARN, ASC, "SET vol", cmd, replystr);
501
502 set_trace(4, "set_volume_control():\n", cmd.c_str(), "\n", replystr.c_str());
503 }
504
505 // Tranceiver PTT on/off
set_PTT_control(int val)506 void RIG_FT891::set_PTT_control(int val)
507 {
508 cmd = val ? "TX1;" : "TX0;";
509
510 sendCommand(cmd);
511 showresp(WARN, ASC, "SET PTT", cmd, replystr);
512 ptt_ = val;
513
514 set_trace(4, "set_ptt_control():\n", cmd.c_str(), "\n", replystr.c_str());
515 }
516
get_PTT()517 int RIG_FT891::get_PTT()
518 {
519 cmd = "TX;";
520 rsp = "TX";
521 waitN(4, 100, "get PTT", ASC);
522
523 size_t p = replystr.rfind(rsp);
524 if (p == string::npos) return ptt_;
525 ptt_ = (replystr[p+2] != '0' ? 1 : 0);
526
527 get_trace(4, "get_ptt():\n", cmd.c_str(), "\n", replystr.c_str());
528
529 return ptt_;
530 }
531
532
533 // internal or external tune mode
tune_rig(int)534 void RIG_FT891::tune_rig(int)
535 {
536 cmd = "AC012;";
537 sendCommand(cmd);
538 showresp(WARN, ASC, "tune rig", cmd, replystr);
539 set_trace(4, "tune_rig():\n", cmd.c_str(), "\n", replystr.c_str());
540 }
541
get_tune()542 int RIG_FT891::get_tune()
543 {
544 cmd = rsp = "AC";
545 cmd += ';';
546 waitN(5, 100, "get tune", ASC);
547
548 rig_trace(2, "get_tuner status()", replystr.c_str());
549
550 size_t p = replystr.rfind(rsp);
551 if (p == string::npos) return 0;
552 int val = replystr[p+4] - '0';
553 return !(val < 2);
554 }
555
set_attenuator(int val)556 void RIG_FT891::set_attenuator(int val)
557 {
558 if (val) cmd = "RA01;";
559 else cmd = "RA00;";
560 sendCommand(cmd);
561 showresp(WARN, ASC, "SET att", cmd, replystr);
562 }
563
get_attenuator()564 int RIG_FT891::get_attenuator()
565 {
566 cmd = rsp = "RA0";
567 cmd += ';';
568 wait_char(';',5, FL891_WAIT_TIME, "get att", ASC);
569
570 size_t p = replystr.rfind(rsp);
571 if (p == string::npos) return progStatus.attenuator;
572 if (p + 3 >= replystr.length()) return progStatus.attenuator;
573 atten_level = replystr[p+3] - '0';
574
575 return atten_level;
576 }
577
set_preamp(int val)578 void RIG_FT891::set_preamp(int val)
579 {
580 if (val) cmd = "PA01;";
581 else cmd = "PA00;";
582 if (val) {
583 preamp_label("AMP", true);
584 } else {
585 preamp_label("IPO", false);
586 }
587 preamp_level = val;
588
589 sendCommand (cmd);
590 showresp(WARN, ASC, "SET preamp", cmd, replystr);
591 }
592
get_preamp()593 int RIG_FT891::get_preamp()
594 {
595 cmd = rsp = "PA0";
596 cmd += ';';
597 wait_char(';',5, FL891_WAIT_TIME, "get pre", ASC);
598
599 size_t p = replystr.rfind(rsp);
600 if (p != string::npos)
601 preamp_level = replystr[p+3] - '0';
602
603 if (preamp_level == 1) {
604 preamp_label("Amp", true);
605 } else {
606 preamp_label("IPO", false);
607 }
608
609 return preamp_level;
610 }
611
adjust_bandwidth(int val)612 int RIG_FT891::adjust_bandwidth(int val)
613 {
614 switch (val) {
615 case mCW :
616 case mCWR :
617 case mTTYL :
618 case mTTYU :
619 bandwidths_ = FT891_widths_CW;
620 bw_vals_ = FT891_wvals_CW;
621 break;
622 case mFM :
623 case mAM :
624 bandwidths_ = FT891_widths_AMFMnorm;
625 bw_vals_ = FT891_wvals_AMFM;
626 break;
627 case mFMN :
628 case mAMN :
629 bandwidths_ = FT891_widths_AMFMnar;
630 bw_vals_ = FT891_wvals_AMFM;
631 break;
632 case mDATAL :
633 case mDATAU :
634 bandwidths_ = FT891_widths_SSBD;
635 bw_vals_ = FT891_wvals_SSBD;
636 break;
637 default:
638 bandwidths_ = FT891_widths_SSB;
639 bw_vals_ = FT891_wvals_SSB;
640 }
641 return FT891_def_bw[val];
642 }
643
def_bandwidth(int val)644 int RIG_FT891::def_bandwidth(int val)
645 {
646 return FT891_def_bw[val];
647 }
648
bwtable(int n)649 const char ** RIG_FT891::bwtable(int n)
650 {
651 switch (n) {
652 case mFM :
653 case mAM : return FT891_widths_AMFMnorm;
654 case mFMN :
655 case mAMN : return FT891_widths_AMFMnar;
656 case mCW :
657 case mCWR :
658 case mTTYL :
659 case mTTYU : return FT891_widths_CW;
660 case mDATAL :
661 case mDATAU : return FT891_widths_SSBD;
662 default : break;
663 }
664 return FT891_widths_SSB;
665 }
666
set_sideband(int md)667 void RIG_FT891::set_sideband(int md)
668 {
669 switch (md) {
670 case mLSB: case mUSB:
671 cmd = "EX1107";
672 cmd += (md == mLSB ? '1' : '0');
673 cmd += ';';
674 sendCommand(cmd);
675 showresp(WARN, ASC, "SET SSB sideband", cmd, replystr);
676 set_trace(4, "SET SSB sideband:\n", cmd.c_str(), "\n", replystr.c_str());
677 break;
678 case mCW: case mCWR:
679 cmd = "EX0707";
680 cmd += (md == mCWR ? '1' : '0');
681 cmd += ';';
682 sendCommand(cmd);
683 showresp(WARN, ASC, "SET CW sideband", cmd, replystr);
684 set_trace(4, "SET CW sideband:\n", cmd.c_str(), "\n", replystr.c_str());
685 break;
686 case mTTYL: case mTTYU:
687 cmd = "EX1011";
688 cmd += (md == mTTYL ? '1' : '0');
689 cmd += ';';
690 sendCommand(cmd);
691 showresp(WARN, ASC, "SET TTY sideband", cmd, replystr);
692 set_trace(4, "SET TTY sideband:\n", cmd.c_str(), "\n", replystr.c_str());
693 break;
694 case mDATAL: case mDATAU:
695 cmd = "EX0812";
696 cmd += (md == mDATAL ? '1' : '0');
697 cmd += ';';
698 sendCommand(cmd);
699 showresp(WARN, ASC, "SET DATA sideband", cmd, replystr);
700 set_trace(4, "SET DATA sideband:\n", cmd.c_str(), "\n", replystr.c_str());
701 break;
702 default: return;
703 }
704 return;
705 }
706
get_sideband(int md)707 int RIG_FT891::get_sideband(int md)
708 {
709 size_t p;
710 switch (md) {
711 case mLSB: case mUSB:
712 cmd = "EX1107;";
713 wait_char(';', 8, FL891_WAIT_TIME, "GET SSB sideband", ASC);
714 p = replystr.find("EX");
715 if (p != string::npos)
716 return replystr[p+6] - '0';
717 break;
718 case mCW: case mCWR:
719 cmd = "EX0707;";
720 wait_char(';', 8, FL891_WAIT_TIME, "GET CW sideband", ASC);
721 p = replystr.find("EX");
722 if (p != string::npos)
723 return replystr[p+6] - '0';
724 break;
725 case mTTYL: case mTTYU:
726 cmd = "EX1011;";
727 wait_char(';', 8, FL891_WAIT_TIME, "GET TTY sideband", ASC);
728 p = replystr.find("EX");
729 if (p != string::npos)
730 return replystr[p+6] - '0';
731 break;
732 case mDATAL: case mDATAU:
733 cmd = "EX0812;";
734 wait_char(';', 8, FL891_WAIT_TIME, "GET DATA sideband", ASC);
735 p = replystr.find("EX");
736 if (p != string::npos)
737 return replystr[p+6] - '0';
738 break;
739 default: return 1;
740 }
741 return 1;
742 }
743
set_modeA(int val)744 void RIG_FT891::set_modeA(int val)
745 {
746 modeA = val;
747
748 if (!rigbase::isOnA()) {
749 LOG_WARN("set_modeA, but on B. Call selectA() first.");
750 return;
751 }
752
753 adjust_bandwidth(modeA);
754
755 cmd = "MD0";
756 cmd += FT891_mode_chr[val];
757 cmd += ';';
758
759 sendCommand(cmd);
760 showresp(WARN, ASC, "SET mode A", cmd, replystr);
761
762 set_trace(4, "set_modeA():\n", cmd.c_str(), "\n", replystr.c_str());
763
764 // set_sideband(val);
765 }
766
get_modeA()767 int RIG_FT891::get_modeA()
768 {
769 if (!rigbase::isOnA()) {
770 //LOG_WARN("get_modeA, but on B. Call selectA() first.");
771 return modeA;
772 }
773
774 cmd = rsp = "MD0";
775 cmd += ';';
776 wait_char(';',5, FL891_WAIT_TIME, "get mode A", ASC);
777
778 size_t p = replystr.rfind(rsp);
779 if (p != string::npos) {
780 if (p + 3 < replystr.length()) {
781 int md = 0;
782 switch (replystr[p+3]) {
783 case '1': case '2': md = (get_sideband(mLSB) ? mLSB : mUSB); break;
784 case '3': case '7': md = (get_sideband(mCW) ? mCWR : mCW); break;
785 case '6': case '9': md = (get_sideband(mTTYU) ? mTTYL : mTTYU); break;
786 case '8': case 'C': md = (get_sideband(mDATAU) ? mDATAL : mDATAU); break;
787 case '4': md = mFM; break;
788 case '5': md = mAM; break;
789 case 'B': md = mFMN; break;
790 case 'D': md = mAMN; break;
791 }
792 modeA = md;
793 }
794 }
795
796 adjust_bandwidth(modeA);
797
798 get_trace(4, "get_modeA():\n", cmd.c_str(), "\n", replystr.c_str());
799
800 return modeA;
801 }
802
set_modeB(int val)803 void RIG_FT891::set_modeB(int val)
804 {
805 modeB = val;
806
807 if (!rigbase::isOnB()) {
808 LOG_WARN("set_modeB, but on A. Call selectB() first.");
809 return;
810 }
811
812 adjust_bandwidth(modeB);
813
814 cmd = "MD0";
815 cmd += FT891_mode_chr[val];
816 cmd += ';';
817
818 sendCommand(cmd);
819 showresp(WARN, ASC, "SET mode B", cmd, replystr);
820
821 set_trace(4, "set_modeB():\n", cmd.c_str(), "\n", replystr.c_str());
822
823 // set_sideband(val);
824 }
825
get_modeB()826 int RIG_FT891::get_modeB()
827 {
828 if (!rigbase::isOnB()) {
829 //LOG_WARN("set_modeB, but on A. Call selectB() first.");
830 return modeB;
831 }
832
833 cmd = rsp = "MD0";
834 cmd += ';';
835 wait_char(';',5, FL891_WAIT_TIME, "get mode B", ASC);
836
837 size_t p = replystr.rfind(rsp);
838 if (p != string::npos) {
839 if (p + 3 < replystr.length()) {
840 int md = 0;
841 switch (replystr[p+3]) {
842 case '1': case '2': md = (get_sideband(mLSB) ? mLSB : mUSB); break;
843 case '3': case '7': md = (get_sideband(mCW) ? mCWR : mCW); break;
844 case '6': case '9': md = (get_sideband(mTTYU) ? mTTYL : mTTYU); break;
845 case '8': case 'C': md = (get_sideband(mDATAU) ? mDATAL : mDATAU); break;
846 case '4': md = mFM; break;
847 case '5': md = mAM; break;
848 case 'B': md = mFMN; break;
849 case 'D': md = mAMN; break;
850 }
851 modeB = md;
852 }
853 }
854
855 adjust_bandwidth(modeB);
856
857 get_trace(4, "get_modeB():\n", cmd.c_str(), "\n", replystr.c_str());
858
859 return modeB;
860 }
861
set_bwA(int val)862 void RIG_FT891::set_bwA(int val)
863 {
864 bwA = val;
865
866 if (!rigbase::isOnA()) {
867 LOG_WARN("set_bwA, but on B. Call selectA() first.");
868 return;
869 }
870
871 int bw_indx = bw_vals_[val];
872
873 if (modeA == mFM || modeA == mAM || modeA == mFMN || modeA == mAMN) return;
874 cmd = "NA00;";
875 if ((((modeA == mLSB || modeA == mUSB) && val < 8)) ||
876 ((modeA == mCW || modeA == mCWR ||
877 modeA == mTTYL || modeA == mTTYU ||
878 modeA == mDATAL || modeA == mDATAU) && val < 9) )
879 cmd = "NA01;";
880
881 cmd.append("SH01");
882 cmd += '0' + bw_indx / 10;
883 cmd += '0' + bw_indx % 10;
884 cmd += ';';
885
886 sendCommand(cmd);
887 showresp(WARN, ASC, "SET bw A", cmd, replystr);
888
889 set_trace(4, "set_bwA():\n", cmd.c_str(), "\n", replystr.c_str());
890 }
891
get_bwA()892 int RIG_FT891::get_bwA()
893 {
894 size_t p;
895 if (!rigbase::isOnA()) {
896 //LOG_WARN("get_bwA, but on B. Call selectA() first.");
897 return bwA;
898 }
899
900 if (modeA == mFM || modeA == mAM || modeA == mFMN || modeA == mAMN) {
901 bwA = 0;
902 return bwA;
903 }
904
905 cmd = rsp = "SH0";
906 cmd += ';';
907
908 wait_char(';',7, FL891_WAIT_TIME, "get bw A", ASC);
909
910 get_trace(4, "get_bwA():\n", cmd.c_str(), "\n", replystr.c_str());
911
912 p = replystr.rfind(rsp);
913 if (p == string::npos) return bwA;
914 if (p + 6 >= replystr.length()) return bwA;
915
916 replystr[p+6] = 0;
917 int bw_idx = fm_decimal(replystr.substr(p+4), 2);
918 const int *idx = bw_vals_;
919 int i = 0;
920 while (*idx != WVALS_LIMIT) {
921 if (*idx == bw_idx) break;
922 idx++;
923 i++;
924 }
925 if (*idx == WVALS_LIMIT) i--;
926 bwA = i;
927
928 return bwA;
929 }
930
set_bwB(int val)931 void RIG_FT891::set_bwB(int val)
932 {
933 bwB = val;
934
935 if (!rigbase::isOnB()) {
936 LOG_WARN("set_bwB, but on A. Call selectB() first.");
937 return;
938 }
939
940 int bw_indx = bw_vals_[val];
941
942 if (modeB == mFM || modeB == mAM || modeB == mFMN || modeB == mAMN) return;
943 cmd = "NA00;";
944 if ((((modeB == mLSB || modeB == mUSB) && val < 8)) ||
945 ((modeB == mCW || modeB == mCWR ||
946 modeB == mTTYL || modeB == mTTYU ||
947 modeB == mDATAL || modeB == mDATAU) && val < 9) )
948 cmd = "NA01;";
949
950 cmd.append("SH01");
951 cmd += '0' + bw_indx / 10;
952 cmd += '0' + bw_indx % 10;
953 cmd += ';';
954
955 sendCommand(cmd);
956 showresp(WARN, ASC, "SET bw B", cmd, replystr);
957
958 set_trace(4, "set_bwB():\n", cmd.c_str(), "\n", replystr.c_str());
959
960 }
961
get_bwB()962 int RIG_FT891::get_bwB()
963 {
964 size_t p;
965 if (!rigbase::isOnB()) {
966 //LOG_WARN("get_bwB, but on A. Call selectB() first.");
967 return bwB;
968 }
969
970 if (modeB == mFM || modeB == mAM || modeB == mFMN || modeB == mAMN) {
971 bwB = 0;
972 return bwB;
973 }
974 cmd = rsp = "SH0";
975 cmd += ';';
976 wait_char(';',7, FL891_WAIT_TIME, "get bw B", ASC);
977
978 get_trace(4, "get_bwB():\n", cmd.c_str(), "\n", replystr.c_str());
979
980 p = replystr.rfind(rsp);
981 if (p == string::npos) return bwB;
982 if (p + 6 >= replystr.length()) return bwB;
983
984 replystr[p+6] = 0;
985 int bw_idx = fm_decimal(replystr.substr(p+4), 2);
986 const int *idx = bw_vals_;
987 int i = 0;
988 while (*idx != WVALS_LIMIT) {
989 if (*idx == bw_idx) break;
990 idx++;
991 i++;
992 }
993 if (*idx == WVALS_LIMIT) i--;
994 bwB = i;
995 return bwB;
996 }
997
get_modetype(int n)998 int RIG_FT891::get_modetype(int n)
999 {
1000 return FT891_mode_type[n];
1001 }
1002
set_if_shift(int val)1003 void RIG_FT891::set_if_shift(int val)
1004 {
1005 cmd = "IS01+0000;";
1006 if (val == 0) cmd[3] = '0';
1007 if (val < 0) cmd[4] = '-';
1008 val = abs(val);
1009 for (int i = 4; i > 0; i--) {
1010 cmd[4+i] += val % 10;
1011 val /= 10;
1012 }
1013 sendCommand(cmd);
1014 showresp(WARN, ASC, "SET if shift", cmd, replystr);
1015 }
1016
get_if_shift(int & val)1017 bool RIG_FT891::get_if_shift(int &val)
1018 {
1019 cmd = rsp = "IS0";
1020 cmd += ';';
1021 wait_char(';',10, FL891_WAIT_TIME, "get if shift", ASC);
1022
1023 size_t p = replystr.rfind(rsp);
1024 val = progStatus.shift_val;
1025 if (p == string::npos) return progStatus.shift;
1026 val = atoi(&replystr[p+5]);
1027 if (replystr[p+4] == '-') val = -val;
1028 return (replystr[3] == '1');
1029 }
1030
1031 // P1 0: (Fixed)
1032 // P2 0: Manual NOTCH �ON/OFF�
1033 // 1: Manual NOTCH LEVEL
1034 // P3 if P2=0
1035 // 000: �OFF�
1036 // 001: �ON�
1037 // if P2=1
1038 // 001 - 320 (NOTCH Frequency : x 10 Hz )
1039
set_notch(bool on,int val)1040 void RIG_FT891::set_notch(bool on, int val)
1041 {
1042 // set notch frequency
1043 if (on) {
1044 cmd = "BP00001;";
1045 sendCommand(cmd);
1046 showresp(WARN, ASC, "SET notch on", cmd, replystr);
1047 cmd = "BP01000;";
1048 if (val % 10 >= 5) val += 10;
1049 val /= 10;
1050 for (int i = 3; i > 0; i--) {
1051 cmd[3 + i] += val % 10;
1052 val /=10;
1053 }
1054 sendCommand(cmd);
1055 showresp(WARN, ASC, "SET notch val", cmd, replystr);
1056 return;
1057 }
1058
1059 // set notch off
1060 cmd = "BP00000;";
1061 sendCommand(cmd);
1062 showresp(WARN, ASC, "SET notch off", cmd, replystr);
1063 }
1064
get_notch(int & val)1065 bool RIG_FT891::get_notch(int &val)
1066 {
1067 bool ison = false;
1068 cmd = rsp = "BP00";
1069 cmd += ';';
1070 wait_char(';',8, FL891_WAIT_TIME, "get notch on/off", ASC);
1071
1072 size_t p = replystr.rfind(rsp);
1073 if (p == string::npos) return ison;
1074
1075 if (replystr[p+6] == '1') { // manual notch enabled
1076 ison = true;
1077 val = progStatus.notch_val;
1078 cmd = rsp = "BP01";
1079 cmd += ';';
1080 wait_char(';',8, FL891_WAIT_TIME, "get notch val", ASC);
1081 p = replystr.rfind(rsp);
1082 if (p == string::npos)
1083 val = 10;
1084 else
1085 val = fm_decimal(replystr.substr(p+4), 3) * 10;
1086 }
1087 return ison;
1088 }
1089
set_auto_notch(int v)1090 void RIG_FT891::set_auto_notch(int v)
1091 {
1092 cmd.assign("BC0").append(v ? "1" : "0" ).append(";");
1093 sendCommand(cmd);
1094 showresp(WARN, ASC, "SET DNF Auto Notch Filter", cmd, replystr);
1095 }
1096
get_auto_notch()1097 int RIG_FT891::get_auto_notch()
1098 {
1099 cmd = "BC0;";
1100 wait_char(';',5, FL891_WAIT_TIME, "get auto notch", ASC);
1101 size_t p = replystr.rfind("BC0");
1102 if (p == string::npos) return 0;
1103 if (replystr[p+3] == '1') return 1;
1104 return 0;
1105 }
1106
set_noise(bool b)1107 void RIG_FT891::set_noise(bool b)
1108 {
1109 if (b) cmd = "NR01;";
1110 else cmd = "NR00;";
1111 sendCommand (cmd);
1112 showresp(WARN, ASC, "SET NR", cmd, replystr);
1113 }
1114
get_noise()1115 int RIG_FT891::get_noise()
1116 {
1117 cmd = "NR0;";
1118 wait_char(';',5, FL891_WAIT_TIME, "get NR", ASC);
1119
1120 size_t p = replystr.rfind("NR0");
1121 if (p == string::npos) return 0;
1122 return replystr[p+3] - '0';
1123 }
1124
set_nb_level(int val)1125 void RIG_FT891::set_nb_level(int val)
1126 {
1127 cmd = "RL000;";
1128 for (int i = 4; i > 2; i--) {
1129 cmd[i] += val % 10;
1130 val /= 10;
1131 }
1132 sendCommand(cmd);
1133 showresp(WARN, ASC, "set RL level", cmd, replystr);
1134 }
1135
get_nb_level()1136 int RIG_FT891::get_nb_level()
1137 {
1138 cmd = "RL0;";
1139 wait_char(';', 7, FL891_WAIT_TIME, "get RL level", ASC);
1140 size_t p = replystr.rfind("RL0");
1141 if (p == string::npos) return 0;
1142
1143 int val = atoi(&replystr[p+3]);
1144 return val;
1145 }
1146
set_noise_reduction(int val)1147 void RIG_FT891::set_noise_reduction(int val)
1148 {
1149 if (val) cmd = "NB01;";
1150 else cmd = "NB00;";
1151 sendCommand (cmd);
1152 showresp(WARN, ASC, "Set NB on/off", cmd, replystr);
1153 }
1154
get_noise_reduction()1155 int RIG_FT891::get_noise_reduction()
1156 {
1157 cmd = "NB0;";
1158 wait_char(';', 5, FL891_WAIT_TIME, "get NB", ASC);
1159
1160 size_t p = replystr.rfind("NB0");
1161 if (p == string::npos) return 0;
1162 return replystr[p+3] - '0';
1163 }
1164
set_noise_reduction_val(int val)1165 void RIG_FT891::set_noise_reduction_val(int val)
1166 {
1167 cmd = "NL0000;";
1168 for (int i = 5; i > 2; i--) {
1169 cmd[i] += val % 10;
1170 val /= 10;
1171 }
1172 sendCommand(cmd);
1173 showresp(WARN, ASC, "set NB level", cmd, replystr);
1174 }
1175
get_noise_reduction_val()1176 int RIG_FT891::get_noise_reduction_val()
1177 {
1178 cmd = "NL0;";
1179 wait_char(';', 7, FL891_WAIT_TIME, "get NB level", ASC);
1180 size_t p = replystr.rfind("NL0");
1181 if (p == string::npos) return 0;
1182
1183 int val = atoi(&replystr[p+3]);
1184 return val;
1185 }
1186
1187 // val 0 .. 100
set_mic_gain(int val)1188 void RIG_FT891::set_mic_gain(int val)
1189 {
1190 cmd = "MG000;";
1191 for (int i = 4; i > 1; i--) {
1192 cmd[i] = val % 10 + '0';
1193 val /= 10;
1194 }
1195 sendCommand(cmd);
1196 showresp(WARN, ASC, "SET mic", cmd, replystr);
1197 }
1198
get_mic_gain()1199 int RIG_FT891::get_mic_gain()
1200 {
1201 cmd = rsp = "MG";
1202 cmd += ';';
1203 wait_char(';',6, FL891_WAIT_TIME, "get mic", ASC);
1204
1205 size_t p = replystr.rfind(rsp);
1206 if (p == string::npos) return progStatus.mic_gain;
1207 int val = atoi(&replystr[p+2]);
1208 if (val > 100) val = 100;
1209 return ceil(val);
1210 }
1211
set_rf_gain(int val)1212 void RIG_FT891::set_rf_gain(int val)
1213 {
1214 cmd = "RG0000;";
1215 for (int i = 5; i > 2; i--) {
1216 cmd[i] = val % 10 + '0';
1217 val /= 10;
1218 }
1219
1220 sendCommand(cmd);
1221 showresp(WARN, ASC, "SET rfgain", cmd, replystr);
1222
1223 set_trace(4, "set_rf_gain():\n", cmd.c_str(), "\n", replystr.c_str());
1224
1225 }
1226
get_rf_gain()1227 int RIG_FT891::get_rf_gain()
1228 {
1229 int rfval = 0;
1230 cmd = rsp = "RG0";
1231 cmd += ';';
1232 wait_char(';',7, FL891_WAIT_TIME, "get rfgain", ASC);
1233
1234 get_trace(4, "get_rf_gain():\n", cmd.c_str(), "\n", replystr.c_str());
1235
1236 size_t p = replystr.rfind(rsp);
1237 if (p == string::npos) return progStatus.rfgain;
1238 for (int i = 3; i < 6; i++) {
1239 rfval *= 10;
1240 rfval += replystr[p+i] - '0';
1241 }
1242 return ceil(rfval);
1243 }
1244
set_squelch(int val)1245 void RIG_FT891::set_squelch(int val)
1246 {
1247 cmd = "SQ0000;";
1248 for (int i = 5; i > 2; i--) {
1249 cmd[i] = val % 10 + '0';
1250 val /= 10;
1251 }
1252
1253 sendCommand(cmd);
1254 showresp(WARN, ASC, "SET squelch", cmd, replystr);
1255
1256 set_trace(4, "set_squelch():\n", cmd.c_str(), "\n", replystr.c_str());
1257
1258 }
1259
get_squelch()1260 int RIG_FT891::get_squelch()
1261 {
1262 int rfval = 0;
1263 cmd = rsp = "SQ0";
1264 cmd += ';';
1265 wait_char(';',7, FL891_WAIT_TIME, "get squelch", ASC);
1266
1267 get_trace(4, "get_squelch():\n", cmd.c_str(), "\n", replystr.c_str());
1268
1269 size_t p = replystr.rfind(rsp);
1270 if (p == string::npos) return progStatus.rfgain;
1271 for (int i = 3; i < 6; i++) {
1272 rfval *= 10;
1273 rfval += replystr[p+i] - '0';
1274 }
1275 return ceil(rfval);
1276 }
1277
1278
1279 // NEED
1280 // bool RIG_FT891::get_vox_onoff()
1281
1282 // EX1616 VOX SELECT 0: MIC 1: DATA
1283 // EX1617 VOX GAIN 0 - 100 (P2= 000 - 100)
1284 // VG VOX GAIN 0 - 100 (P2= 000 - 100)
1285 // EX1618 VOX DELAY 30 - 3000 msec (P2= 0030 - 3000) (10 msec/step)
1286 // EX1619 ANTI VOX GAIN 0 - 100 (P2= 000 - 100)
1287
1288 // EX1620 DATA VOX GAIN 0 - 100 (P2= 000 - 100)
1289 // EX1621 DATA VOX DELAY 30 - 3000 msec (P2= 0030 - 3000)
1290 // EX1622 ANTI DVOX GAIN 0 - 100 (P2= 000 - 100)
1291
set_vox_onoff()1292 void RIG_FT891::set_vox_onoff()
1293 {
1294 cmd = "VX0;";
1295 if (progStatus.vox_onoff) cmd[2] = '1';
1296 sendCommand(cmd);
1297 showresp(WARN, ASC, "SET vox", cmd, replystr);
1298 }
1299
set_vox_gain()1300 void RIG_FT891::set_vox_gain()
1301 {
1302 if (progStatus.vox_on_dataport)
1303 cmd = "EX1620";
1304 else
1305 cmd = "VG";
1306 cmd.append(to_decimal(progStatus.vox_gain, 3)).append(";");
1307 sendCommand(cmd);
1308 showresp(WARN, ASC, "SET vox gain", cmd, replystr);
1309 }
1310
set_vox_anti()1311 void RIG_FT891::set_vox_anti()
1312 {
1313 if (progStatus.vox_on_dataport)
1314 cmd = "EX1622";
1315 else
1316 cmd = "EX1619";
1317 cmd.append(to_decimal(progStatus.vox_anti, 3)).append(";");
1318 sendCommand(cmd);
1319 showresp(WARN, ASC, "SET anti-vox", cmd, replystr);
1320 }
1321
set_vox_hang()1322 void RIG_FT891::set_vox_hang()
1323 {
1324 if (progStatus.vox_on_dataport)
1325 cmd = "EX1621";
1326 else
1327 cmd = "VD";
1328 cmd.append(to_decimal(progStatus.vox_hang, 4)).append(";");
1329 sendCommand(cmd);
1330 showresp(WARN, ASC, "SET vox delay", cmd, replystr);
1331 }
1332
set_vox_on_dataport()1333 void RIG_FT891::set_vox_on_dataport()
1334 {
1335 cmd = "EX16160;";
1336 if (progStatus.vox_on_dataport) cmd[6] = '1';
1337 sendCommand(cmd);
1338 showresp(WARN, ASC, "SET vox on data port", cmd, replystr);
1339 }
1340
set_cw_wpm()1341 void RIG_FT891::set_cw_wpm()
1342 {
1343 cmd = "KS";
1344 if (progStatus.cw_wpm > 60) progStatus.cw_wpm = 60;
1345 if (progStatus.cw_wpm < 4) progStatus.cw_wpm = 4;
1346 cmd.append(to_decimal(progStatus.cw_wpm, 3)).append(";");
1347 sendCommand(cmd);
1348 showresp(WARN, ASC, "SET cw wpm", cmd, replystr);
1349 }
1350
enable_keyer()1351 void RIG_FT891::enable_keyer()
1352 {
1353 if (progStatus.enable_keyer)
1354 cmd = "KR1;";
1355 else
1356 cmd = "KR0;";
1357 sendCommand(cmd);
1358 showresp(WARN, ASC, "SET keyer on/off", cmd, replystr);
1359 }
1360
set_cw_spot()1361 bool RIG_FT891::set_cw_spot()
1362 {
1363 if (vfo->imode == mCW || vfo->imode == mCWR) {
1364 cmd = "CS0;";
1365 if (progStatus.spot_onoff) cmd[2] = '1';
1366 sendCommand(cmd);
1367 showresp(WARN, ASC, "SET spot on/off", cmd, replystr);
1368 return true;
1369 } else
1370 return false;
1371 }
1372
set_cw_weight()1373 void RIG_FT891::set_cw_weight()
1374 {
1375 int n = round(progStatus.cw_weight * 10);
1376 cmd.assign("EX0403").append(to_decimal(n, 2)).append(";");
1377 sendCommand(cmd);
1378 showresp(WARN, ASC, "SET cw weight", cmd, replystr);
1379 }
1380
set_cw_qsk()1381 void RIG_FT891::set_cw_qsk()
1382 {
1383 int n = progStatus.cw_qsk / 5 - 3;
1384 cmd.assign("EX0713").append(to_decimal(n, 1)).append(";");
1385 sendCommand(cmd);
1386 showresp(WARN, ASC, "SET cw qsk", cmd, replystr);
1387 }
1388
1389 // 00: 300 Hz to 75: 1050 Hz (10Hz steps)
set_cw_spot_tone()1390 void RIG_FT891::set_cw_spot_tone()
1391 {
1392 int n = progStatus.cw_spot_tone / 10 - 30;
1393 if (n < 0) n = 0;
1394 if (n > 75) n = 75;
1395 cmd.assign("KP").append(to_decimal(n, 2)).append(";");
1396 sendCommand(cmd);
1397 showresp(WARN, ASC, "SET cw tone", cmd, replystr);
1398 }
1399
set_xcvr_auto_on()1400 void RIG_FT891::set_xcvr_auto_on()
1401 {
1402 if (!progStatus.xcvr_auto_on) return;
1403
1404 cmd = rsp = "PS";
1405 cmd.append(";");
1406 wait_char(';',4, FL891_WAIT_TIME, "Test: Is Rig ON", ASC);
1407 size_t p = replystr.rfind(rsp);
1408 if (p == string::npos) { // rig is off, power on
1409 cmd = "PS1;";
1410 sendCommand(cmd);
1411 // wake up time for initialization
1412 for (int i = 0; i < 1500; i += 100) {
1413 MilliSleep(100);
1414 update_progress(100 * i / 6000);
1415 Fl::awake();
1416 }
1417 for (int i = 1500; i < 3000; i += 100) {
1418 MilliSleep(100);
1419 update_progress(100 * i / 6000);
1420 Fl::awake();
1421 }
1422 sendCommand(cmd);
1423 for (int i = 3000; i < 6000; i += 100) {
1424 MilliSleep(100);
1425 update_progress(100 * i / 6000);
1426 Fl::awake();
1427 }
1428 }
1429 }
1430
set_xcvr_auto_off()1431 void RIG_FT891::set_xcvr_auto_off()
1432 {
1433 if (!progStatus.xcvr_auto_off) return;
1434
1435 cmd = "PS0;";
1436 sendCommand(cmd);
1437 showresp(WARN, ASC, "SET xcvr auto on/off", cmd, replystr);
1438 }
1439
set_compression(int on,int val)1440 void RIG_FT891::set_compression(int on, int val)
1441 {
1442 cmd = "PL";
1443 cmd.append(to_decimal(val, 3)).append(";");
1444 sendCommand(cmd);
1445 showresp(WARN, ASC, "set Comp PL", cmd, replystr);
1446
1447 // Can only send PR command in SSB mode. Other modes will cause 891 to
1448 // return ?; in response to sending this
1449 int curMode = rigbase::isOnA() ? modeA : modeB;
1450 if ( curMode == mLSB || curMode == mUSB ) {
1451 if (on)
1452 cmd = "PR01;";
1453 else
1454 cmd = "PR00;";
1455 set_trace(2, "set Comp", cmd.c_str());
1456 sendCommand(cmd);
1457 showresp(WARN, ASC, "set Comp", cmd, replystr);
1458 }
1459 }
1460
get_compression(int & on,int & val)1461 void RIG_FT891::get_compression(int &on, int &val)
1462 {
1463 on = 0; val = 0;
1464
1465 cmd = rsp = "PL";
1466 cmd += ';';
1467 wait_char(';',6, FL891_WAIT_TIME, "get Comp PL", ASC);
1468
1469 size_t p = replystr.rfind(rsp);
1470 if (p == string::npos) return;
1471 val = atoi(&replystr[p+2]);
1472 if (val > 100) val = 100;
1473 val = ceil(val);
1474
1475 // Can only send PR command in SSB mode. Other modes will cause 891 to
1476 // return ?; in response to sending this
1477 int curMode = rigbase::isOnA() ? modeA : modeB;
1478 if ( curMode == mLSB || curMode == mUSB ) {
1479 cmd = "PR0;";
1480 wait_char(';', 7, FL891_WAIT_TIME, "get PR level", ASC);
1481 size_t p = replystr.rfind("PR0");
1482 if (p == string::npos) return;
1483
1484 on = replystr[p+3] - '0';
1485 }
1486
1487 stringstream s;
1488 s << "get_compression: " << (on ? "ON" : "OFF") << "(" << on << "), comp PL=" << val;
1489 get_trace(1, s.str().c_str());
1490 }
1491
1492
get_band_selection(int v)1493 void RIG_FT891::get_band_selection(int v)
1494 {
1495 if (v < 3) v = v - 1;
1496 cmd.assign("BS").append(to_decimal(v, 2)).append(";");
1497 sendCommand(cmd);
1498 showresp(WARN, ASC, "Select Band Stacks", cmd, replystr);
1499 set_trace(2, "get band", cmd.c_str());
1500 }
1501
1502