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 "rigbase.h"
22 #include "util.h"
23 #include "debug.h"
24 #include "rig_io.h"
25 #include "support.h"
26
27
28 const char *szNORIG = "NONE";
29 const char *szNOMODES[] = {"LSB", "USB", NULL};
30 const char *szNOBWS[] = {"NONE", NULL};
31 const char *szDSPLO[] = {"NONE", NULL};
32 const char *szDSPHI[] = {"NONE", NULL};
33 const char *szdsptooltip = "dsp tooltip";
34 const char *szbtnlabel = " ";
35 const int ibw_val = -1;
36
37 static GUI basewidgets[] = { {NULL, 0, 0} };
38
rigbase()39 rigbase::rigbase()
40 {
41 IDstr = "";
42 name_ = szNORIG;
43 modes_ = szNOMODES;
44 bandwidths_ = szNOBWS;
45 dsp_SL = szDSPLO;
46 SL_tooltip = szdsptooltip;
47 SL_label = szbtnlabel;
48 dsp_SH = szDSPHI;
49 SH_tooltip = szdsptooltip;
50 SH_label = szbtnlabel;
51 bw_vals_ = &ibw_val;
52
53 widgets = basewidgets;
54
55 serloop_timing = 200; // msec, 5x / second
56
57 stopbits = 2;
58
59 CIV = 0;
60 defaultCIV = 0;
61 USBaudio = false;
62
63 has_xcvr_auto_on_off =
64 comm_echo =
65 has_vfo_adj =
66 has_rit =
67 has_xit =
68 has_bfo =
69 has_power_control =
70 has_volume_control =
71 has_mode_control =
72 has_bandwidth_control =
73 has_dsp_controls =
74 has_micgain_control =
75 has_mic_line_control =
76 has_auto_notch =
77 has_notch_control =
78 has_noise_control =
79 has_noise_reduction_control =
80 has_noise_reduction =
81 has_attenuator_control =
82 has_preamp_control =
83 has_ifshift_control =
84 has_pbt_controls =
85 has_FILTER =
86 has_ptt_control =
87 has_tune_control =
88 has_swr_control =
89 has_alc_control =
90 has_agc_control =
91 has_rf_control =
92 has_sql_control =
93 has_data_port =
94 restore_mbw =
95
96 has_extras =
97 has_nb_level =
98 has_agc_level =
99 has_cw_wpm =
100 has_cw_vol =
101 has_cw_spot =
102 has_cw_spot_tone =
103 has_cw_qsk =
104 has_cw_break_in =
105 has_cw_delay =
106 has_cw_weight =
107 has_cw_keyer =
108 has_vox_onoff =
109 has_vox_gain =
110 has_vox_anti =
111 has_vox_hang =
112 has_vox_on_dataport =
113 has_compression =
114 has_compON =
115 use_line_in =
116 has_bpf_center =
117 has_special =
118 has_ext_tuner =
119 has_smeter =
120 has_power_out =
121 has_line_out =
122 // has_split =
123 has_split_AB =
124 has_band_selection =
125 has_get_info =
126 has_getvfoAorB =
127 ICOMrig = false;
128 ICOMmainsub = false;
129
130 has_a2b = false;
131 has_vfoAB = false;
132
133 data_type = BINARY;
134
135 A.freq = 14070000L;
136 A.imode = 1;
137 A.iBW = 0;
138 B.freq = 14070000L;
139 B.imode = 1;
140 B.iBW = 0;
141 inuse = onA;
142 precision = 1;
143 ndigits = 9;
144 can_change_alt_vfo = false;
145
146 freqA = 14070000L;
147 modeA = 1;
148 bwA = 0;
149 freqB = 14070000L;
150 modeB = 1;
151 bwB = 0;
152
153 def_freq = 14070000L;
154 def_mode = 1;
155 def_bw = 0;
156 bpf_center = 0;
157 pbt = 0;
158
159 ptt_ = tune_ = 0;
160
161 rTONE = tTONE = 8;
162
163 max_power = 100;
164
165 active_mode = 0; // wbx
166
167 if_shift_min = -1500;
168 if_shift_max = 1500;
169 if_shift_step = 10;
170 if_shift_mid = 0;
171
172 atten_level = 0;
173 preamp_level = 0;
174 }
175
to_bcd_be(unsigned long int freq,int len)176 string rigbase::to_bcd_be(unsigned long int freq, int len)
177 {
178 unsigned char a;
179 int numchars = len / 2;
180 string bcd = "";
181 if (len & 1) numchars ++;
182 for (int i = 0; i < numchars; i++) {
183 a = 0;
184 a |= freq % 10;
185 freq /= 10;
186 a |= (freq % 10)<<4;
187 freq /= 10;
188 bcd += a;
189 }
190 return bcd;
191 }
192
to_bcd(unsigned long int freq,int len)193 string rigbase::to_bcd(unsigned long int freq, int len)
194 {
195 string bcd_be = to_bcd_be(freq, len);
196 string bcd = "";
197 int bcdlen = bcd_be.size();
198 for (int i = bcdlen - 1; i >= 0; i--)
199 bcd += bcd_be[i];
200 return bcd;
201 }
202
fm_bcd(string bcd,int len)203 unsigned long int rigbase::fm_bcd (string bcd, int len)
204 {
205 int i;
206 unsigned long int f = 0;
207 int numchars = len/2;
208 if (len & 1) numchars ++;
209 for (i = 0; i < numchars; i++) {
210 f *=10;
211 f += (bcd[i] >> 4) & 0x0F;
212 f *= 10;
213 f += bcd[i] & 0x0F;
214 }
215 return f;
216 }
217
218
fm_bcd_be(string bcd,int len)219 unsigned long int rigbase::fm_bcd_be(string bcd, int len)
220 {
221 char temp;
222 int numchars = len/2;
223 if (len & 1) numchars++;
224 for (int i = 0; i < numchars / 2; i++) {
225 temp = bcd[i];
226 bcd[i] = bcd[numchars -1 - i];
227 bcd[numchars -1 - i] = temp;
228 }
229 return fm_bcd(bcd, len);
230 }
231
to_binary_be(unsigned long int freq,int len)232 string rigbase::to_binary_be(unsigned long int freq, int len)
233 {
234 static string bin = "";
235 for (int i = 0; i < len; i++) {
236 bin += freq & 0xFF;
237 freq >>= 8;
238 }
239 return bin;
240 }
241
to_binary(unsigned long int freq,int len)242 string rigbase::to_binary(unsigned long int freq, int len)
243 {
244 static string bin = "";
245 string bin_be = to_binary_be(freq, len);
246 int binlen = bin_be.size();
247 for (int i = binlen - 1; i >= 0; i--)
248 bin += bin_be[i];
249 return bin;
250 }
251
fm_binary(string binary,int len)252 unsigned long int rigbase::fm_binary(string binary, int len)
253 {
254 int i;
255 unsigned long int f = 0;
256 for (i = 0; i < len; i++) {
257 f *= 256;
258 f += (unsigned char)binary[i];
259 }
260 return f;
261 }
262
fm_binary_be(string binary_be,int len)263 unsigned long int rigbase::fm_binary_be(string binary_be, int len)
264 {
265 unsigned char temp;
266 int numchars = len/2;
267 if (len & 1) numchars++;
268 for (int i = 0; i < numchars / 2; i++) {
269 temp = binary_be[i];
270 binary_be[i] = binary_be[numchars -1 - i];
271 binary_be[numchars -1 - i] = temp;
272 }
273 return fm_binary(binary_be, len);
274 }
275
to_decimal_be(unsigned long int d,int len)276 string rigbase::to_decimal_be(unsigned long int d, int len)
277 {
278 static string sdec_be;
279 sdec_be.clear();
280 for (int i = 0; i < len; i++) {
281 sdec_be += (char)((d % 10) + '0');
282 d /= 10;
283 }
284 return sdec_be;
285 }
286
to_decimal(unsigned long int d,int len)287 string rigbase::to_decimal(unsigned long int d, int len)
288 {
289 static string sdec;
290 sdec.clear();
291 string sdec_be = to_decimal_be(d, len);
292 int bcdlen = sdec_be.size();
293 for (int i = bcdlen - 1; i >= 0; i--)
294 sdec += sdec_be[i];
295 return sdec;
296 }
297
fm_decimal(string decimal,int len)298 unsigned long int rigbase::fm_decimal(string decimal, int len)
299 {
300 unsigned long int d = 0;
301 for (int i = 0; i < len; i++) {
302 d *= 10;
303 d += decimal[i] - '0';
304 }
305 return d;
306 }
307
fm_decimal_be(string decimal_be,int len)308 unsigned long int rigbase::fm_decimal_be(string decimal_be, int len)
309 {
310 unsigned char temp;
311 int numchars = len/2;
312 if (len & 1) numchars++;
313 for (int i = 0; i < numchars / 2; i++) {
314 temp = decimal_be[i];
315 decimal_be[i] = decimal_be[numchars -1 - i];
316 decimal_be[numchars -1 - i] = temp;
317 }
318 return fm_decimal(decimal_be, len);
319 }
320
321 //======================================================================
322 // translation 0..255 <==> 0..100
323 // for Icom controls
324 //======================================================================
325
326 static int set100[] =
327 { 0, 3, 6, 8, 11, 13, 16, 18, 21, 23,
328 26, 29, 31, 34, 36, 39, 41, 44, 46, 49,
329 51, 54, 57, 59, 62, 64, 67, 69, 72, 74,
330 77, 80, 82, 85, 87, 90, 92, 95, 97,100,
331 102,105,108,110,113,115,118,120,123,125,
332 128,131,133,136,138,141,143,146,148,151,
333 153,156,159,161,164,166,169,171,174,176,
334 179,182,184,187,189,192,194,197,199,202,
335 204,207,210,212,215,217,220,222,225,227,
336 230,233,235,238,240,243,245,248,250,253,255};
337
bcd255(int val)338 string rigbase::bcd255(int val)
339 {
340 return to_bcd(set100[(int)(val)], 3);
341 }
342
num100(string bcd)343 int rigbase::num100(string bcd)
344 {
345 int val = fm_bcd(bcd, 3);
346 for (int n = 0; n < 101; n++) {
347 if (set100[n] > val) return n - 1;
348 if (set100[n] == val) return n;
349 }
350 return 0;
351 }
352
hexval(int hex)353 int rigbase::hexval(int hex)
354 {
355 int val = 0;
356 val += 10 * ((hex >> 4) & 0x0F);
357 val += hex & 0x0F;
358 return val;
359 }
360
hex2val(string hexstr)361 int rigbase::hex2val(string hexstr)
362 {
363 return 100 * hexval(hexstr[0]) + hexval(hexstr[1]);
364 }
365
366
367 //======================================================================
368
waitN(size_t n,int timeout,const char * sz,int pr)369 int rigbase::waitN(size_t n, int timeout, const char *sz, int pr)
370 {
371 guard_lock reply_lock(&mutex_replystr);
372
373 char sztemp[50];
374 string returned = "";
375 string tosend = cmd;
376 int cnt = 0;
377 int waited = 0;
378 size_t num = n + cmd.length();
379 int delay = num * 11000.0 / RigSerial->Baud() +
380 progStatus.use_tcpip ? progStatus.tcpip_ping_delay : 0;
381
382 replystr.clear();
383 RigSerial->FlushBuffer();
384
385 if(!progStatus.use_tcpip && !RigSerial->IsOpen()) {
386 snprintf(sztemp, sizeof(sztemp), "TEST %s", sz);
387 showresp(WARN, pr, sztemp, tosend, replystr);
388 return 0;
389 }
390
391 sendCommand(tosend, 0);
392 MilliSleep(delay);
393
394 returned = "";
395 for ( cnt = 0; cnt < timeout / 10; cnt++) {
396 readResponse();
397 returned.append(respstr);
398 if (returned.length() >= n) {
399 replystr = returned;
400 waited = cnt * 10 + delay;
401 snprintf(sztemp, sizeof(sztemp), "%s OK %d ms", sz, waited);
402 showresp(WARN, pr, sztemp, cmd, returned);
403 return replystr.length();
404 }
405 MilliSleep(10);
406 Fl::awake();
407 }
408
409 replystr = returned;
410 waited = timeout + delay;
411 snprintf(sztemp, sizeof(sztemp), "%s failed %d ms", sz, waited);
412 showresp(ERR, pr, sztemp, cmd, returned);
413 return 0;
414 }
415
wait_char(int ch,size_t n,int timeout,const char * sz,int pr)416 int rigbase::wait_char(int ch, size_t n, int timeout, const char *sz, int pr)
417 {
418 guard_lock reply_lock(&mutex_replystr);
419
420 char sztemp[50];
421 string returned = "";
422 string tosend = cmd;
423 int cnt = 0;
424 int waited = 0;
425 size_t num = n + cmd.length();
426
427 int delay = num * 11000.0 / RigSerial->Baud() +
428 progStatus.use_tcpip ? progStatus.tcpip_ping_delay : 0;
429
430 replystr.clear();
431 RigSerial->FlushBuffer();
432
433 if(!progStatus.use_tcpip && !RigSerial->IsOpen()) {
434 snprintf(sztemp, sizeof(sztemp), "TEST %s", sz);
435 showresp(DEBUG, pr, sztemp, tosend, replystr);
436 return 0;
437 }
438
439 sendCommand(tosend, 0);
440 MilliSleep(delay);
441
442 returned = "";
443 for ( cnt = 0; cnt < timeout / 10; cnt++) {
444 readResponse();
445 returned.append(respstr);
446 if (returned.find(ch) != string::npos) {
447 replystr = returned;
448 waited = cnt * 10 + delay;
449 snprintf(sztemp, sizeof(sztemp), "%s OK %d ms", sz, waited);
450 showresp(DEBUG, pr, sztemp, cmd, returned);
451 return replystr.length();
452 }
453 MilliSleep(10);
454 Fl::awake();
455 }
456
457 replystr = returned;
458 waited = timeout + delay;
459 snprintf(sztemp, sizeof(sztemp), "%s failed %d ms", sz, waited);
460 showresp(ERR, pr, sztemp, cmd, returned);
461 return 0;
462 }
463
464 // Yaesu transceiver - wait for response to identifier request
465 // return boolean state of response
466 // ID - for most
467 // AI - for FTdx9000
468 // wait - wait nnn milliseconds before declaring transceiver DOA
469 // default 200 msec
470 // retry - number of retries, default
id_OK(string ID,int wait)471 bool rigbase::id_OK(string ID, int wait)
472 {
473 guard_lock reply_lock(&mutex_replystr);
474
475 string returned;
476 for (int n = 0; n < progStatus.comm_retries; n++) {
477 sendCommand(string(ID).append(";", 0));
478 returned = "";
479 for (int cnt = 0; cnt < wait / 10; cnt++) {
480 readResponse();
481 returned.append(respstr);
482 if (returned.find(ID)) {
483 replystr = returned;
484 return true;
485 }
486 MilliSleep(10);
487 Fl::awake();
488 }
489 }
490 replystr.clear();
491 return false;
492 }
493
sendOK(string cmd)494 void rigbase::sendOK(string cmd)
495 {
496 if (IDstr.empty()) {
497 sendCommand(cmd,0);
498 return;
499 }
500 if (id_OK(IDstr, 100))
501 sendCommand(cmd, 0);
502 }
503
set_split(bool val)504 void rigbase::set_split(bool val)
505 {
506 split = val;
507 }
508
get_split()509 int rigbase::get_split()
510 {
511 return split;
512 }
513
514 char bcdval[100] = {
515 '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09',
516 '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19',
517 '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', '\x28', '\x29',
518 '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39',
519 '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', '\x48', '\x49',
520 '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', '\x58', '\x59',
521 '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', '\x69',
522 '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', '\x78', '\x79',
523 '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', '\x88', '\x89',
524 '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', '\x98', '\x99'
525 };
526