6
* Copyright 2012, Dave Freese, W1HKJ
12
bool IC9100_DEBUG = true;
14
//=============================================================================
17
const char IC9100name_[] = "IC-9100";
19
const char *IC9100modes_[] = {
20
"LSB", "USB", "AM", "CW", "RTTY", "FM", "CW-R", "RTTY-R", "PSK", "PSK-R",
21
"LSB-D1", "LSB-D2", "LSB-D3",
22
"USB-D1", "USB-D2", "USB-D3", NULL};
24
const char IC9100_mode_type[] = {
25
'L', 'U', 'U', 'U', 'L', 'U', 'L', 'U', 'U', 'L',
29
const char IC9100_mode_nbr[] = {
30
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x12, 0x13,
34
const char *IC9100_ssb_bws[] = {
35
"50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
36
"600", "700", "800", "900",
37
"1000", "1100", "1200", "1300", "1400", "1500", "1600", "1700", "1800", "1900",
38
"2000", "2100", "2200", "2300", "2400", "2500", "2600", "2700", "2800", "2900",
39
"3000", "3100", "3200", "3300", "3400", "3500", "3600", NULL };
41
const char *IC9100_rtty_bws[] = {
42
"50", "100", "150", "200", "250", "300", "350", "400", "450", "500",
43
"600", "700", "800", "900",
44
"1000", "1100", "1200", "1300", "1400", "1500", "1600", "1700", "1800", "1900",
45
"2000", "2100", "2200", "2300", "2400", "2500", "2600", "2700", NULL };
47
const char *IC9100_am_bws[] = {
48
"200", "400", "600", "800", "1000", "1200", "1400", "1600", "1800", "2000",
49
"2200", "2400", "2600", "2800", "3000", "3200", "3400", "3600", "3800", "4000",
50
"4200", "4400", "4600", "4800", "5000", "5200", "5400", "5600", "5800", "6000",
51
"6200", "6400", "6600", "6800", "7000", "7200", "7400", "9100", "7800", "8000",
52
"8200", "8400", "8600", "8800", "9000", "9200", "9400", "9600", "9800", "10000", NULL };
54
const char *IC9100_fm_bws[] = {
57
static GUI IC9100_widgets[]= {
58
{ (Fl_Widget *)btnVol, 2, 125, 50 },
59
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 },
60
{ (Fl_Widget *)sldrRFGAIN, 54, 145, 156 },
61
{ (Fl_Widget *)sldrSQUELCH, 54, 165, 156 },
62
{ (Fl_Widget *)btnNR, 2, 185, 50 },
63
{ (Fl_Widget *)sldrNR, 54, 185, 156 },
64
{ (Fl_Widget *)btnIFsh, 214, 125, 50 },
65
{ (Fl_Widget *)sldrIFSHIFT, 266, 125, 156 },
66
{ (Fl_Widget *)btnNotch, 214, 145, 50 },
67
{ (Fl_Widget *)sldrNOTCH, 266, 145, 156 },
68
{ (Fl_Widget *)sldrMICGAIN, 266, 165, 156 },
69
{ (Fl_Widget *)sldrPOWER, 266, 185, 156 },
70
{ (Fl_Widget *)NULL, 0, 0, 0 }
73
RIG_IC9100::RIG_IC9100() {
76
modes_ = IC9100modes_;
77
bandwidths_ = IC9100_ssb_bws;
78
_mode_type = IC9100_mode_type;
79
adjustCIV(defaultCIV);
81
widgets = IC9100_widgets;
107
has_micgain_control =
108
has_bandwidth_control = true;
115
//======================================================================
116
// IC9100 unique commands
117
//======================================================================
119
void RIG_IC9100::initialize()
121
IC9100_widgets[0].W = btnVol;
122
IC9100_widgets[1].W = sldrVOLUME;
123
IC9100_widgets[2].W = sldrRFGAIN;
124
IC9100_widgets[3].W = sldrSQUELCH;
125
IC9100_widgets[4].W = btnNR;
126
IC9100_widgets[5].W = sldrNR;
127
IC9100_widgets[6].W = btnIFsh;
128
IC9100_widgets[7].W = sldrIFSHIFT;
129
IC9100_widgets[8].W = btnNotch;
130
IC9100_widgets[9].W = sldrNOTCH;
131
IC9100_widgets[10].W = sldrMICGAIN;
132
IC9100_widgets[11].W = sldrPOWER;
135
void RIG_IC9100::selectA()
141
sendICcommand(cmd, 6);
145
void RIG_IC9100::selectB()
151
sendICcommand(cmd, 6);
155
void RIG_IC9100::set_modeA(int val)
160
cmd += IC9100_mode_nbr[val];
163
LOG_INFO("%s", str2hex(cmd.data(), cmd.length()));
164
sendICcommand (cmd, 6);
166
// digital set / clear
169
cmd += '\x1A'; cmd += '\x06';
171
case 10 : case 13 : cmd += '\x01'; cmd += '\x01';break;
172
case 11 : case 14 : cmd += '\x02'; cmd += '\x01';break;
173
case 12 : case 15 : cmd += '\x03'; cmd += '\x01';break;
175
cmd += '\x00'; cmd += '\x00';
179
LOG_INFO("%s", str2hex(cmd.data(), cmd.length()));
180
sendICcommand (cmd, 6);
185
int RIG_IC9100::get_modeA()
191
if (sendICcommand (cmd, 8 )) {
192
for (md = 0; md < 10; md++) if (replystr[5] == IC9100_mode_nbr[md]) break;
193
if (md == 10) md = 0;
197
if (md == 0 || md == 1) {
199
cmd += '\x1A'; cmd += '\x06';
201
if (sendICcommand(cmd, 9)) {
202
if (replystr[6] > 0 && A.imode < 2) {
204
A.imode = 9 + A.imode * 3 + replystr[6];
211
void RIG_IC9100::set_modeB(int val)
216
cmd += IC9100_mode_nbr[val];
219
LOG_INFO("%s", str2hex(cmd.data(), cmd.length()));
220
sendICcommand (cmd, 6);
222
// digital set / clear
225
cmd += '\x1A'; cmd += '\x06';
227
case 10 : case 13 : cmd += '\x01'; cmd += '\x01';break;
228
case 11 : case 14 : cmd += '\x02'; cmd += '\x01';break;
229
case 12 : case 15 : cmd += '\x03'; cmd += '\x01';break;
231
cmd += '\x00'; cmd += '\x00';
235
LOG_INFO("%s", str2hex(cmd.data(), cmd.length()));
236
sendICcommand (cmd, 6);
241
int RIG_IC9100::get_modeB()
247
if (sendICcommand (cmd, 8 )) {
248
for (md = 0; md < 10; md++) if (replystr[5] == IC9100_mode_nbr[md]) break;
249
if (md == 10) md = 0;
253
if (md == 0 || md == 1) {
255
cmd += '\x1A'; cmd += '\x06';
257
if (sendICcommand(cmd, 9)) {
258
if (replystr[6] > 0 && B.imode < 2) {
260
B.imode = 9 + B.imode * 3 + replystr[6];
267
int RIG_IC9100::get_bwA()
269
if (A.imode == 5) return 0;
271
cmd.append("\x1a\x03");
273
if (sendICcommand (cmd, 8)) {
274
A.iBW = fm_bcd(&replystr[6], 2);
279
void RIG_IC9100::set_bwA(int val)
282
if (A.imode == 5) return;
284
cmd.append("\x1a\x03");
285
cmd.append(to_bcd(A.iBW, 2));
288
LOG_INFO("%s", str2hex(cmd.data(), cmd.length()));
289
sendICcommand (cmd, 6);
293
int RIG_IC9100::get_bwB()
295
if (B.imode == 5) return 0;
297
cmd.append("\x1a\x03");
299
if (sendICcommand (cmd, 8)) {
300
B.iBW = fm_bcd(&replystr[6], 2);
305
void RIG_IC9100::set_bwB(int val)
308
if (B.imode == 5) return;
310
cmd.append("\x1a\x03");
311
cmd.append(to_bcd(A.iBW, 2));
314
LOG_INFO("%s", str2hex(cmd.data(), cmd.length()));
315
sendICcommand (cmd, 6);
319
int RIG_IC9100::adjust_bandwidth(int m)
324
bandwidths_ = IC9100_am_bws;
328
bandwidths_ = IC9100_fm_bws;
331
case 4: case 7: // RTTY
332
bandwidths_ = IC9100_rtty_bws;
335
case 3: case 6: // CW
336
bandwidths_ = IC9100_ssb_bws;
339
case 8: case 9: // PKT
340
bandwidths_ = IC9100_ssb_bws;
343
case 0: case 1: // SSB
345
case 10: case 11 : case 12 :
346
case 13: case 14 : case 15 :
347
bandwidths_ = IC9100_ssb_bws;
353
int RIG_IC9100::def_bandwidth(int m)
363
case 4: case 7: // RTTY
366
case 3: case 6: // CW
369
case 8: case 9: // PKT
372
case 0: case 1: // SSB
373
case 10: case 11 : case 12 :
374
case 13: case 14 : case 15 :
381
void RIG_IC9100::set_mic_gain(int v)
383
ICvol = (int)(v * 255 / 100);
384
if (!progStatus.USBaudio) {
386
cmd.append("\x14\x0B");
387
cmd.append(to_bcd(ICvol, 3));
391
cmd += '\x1A'; cmd += '\x05';
392
cmd += '\x00'; cmd += '\x29';
393
cmd.append(to_bcd(ICvol, 3));
396
sendICcommand (cmd, 6);
399
LOG_WARN("%s", str2hex(cmd.data(), cmd.length()));
402
void RIG_IC9100::set_attenuator(int val)
405
if (atten_level == 0) {
407
atten_label("20 dB", true);
411
atten_label("Att", false);
418
sendICcommand(cmd,6);
421
LOG_INFO("%s", str2hex(cmd.data(), cmd.length()));
424
int RIG_IC9100::get_attenuator()
429
if (sendICcommand(cmd,6)) {
430
if (replystr[5] == 0x20) {
432
atten_label("20 dB", true);
435
atten_label("Att", false);
441
void RIG_IC9100::set_compression()
443
if (progStatus.compON) {
444
cmd.assign(pre_to).append("\x14\x0E");
445
cmd.append(to_bcd(progStatus.compression * 255 / 100, 3));
450
cmd.append("\x16\x44");
453
waitFB("set Comp ON");
456
cmd.assign(pre_to).append("\x16\x44");
459
waitFB("set Comp OFF");
463
void RIG_IC9100::set_vox_onoff()
465
cmd.assign(pre_to).append("\x16\x46");
466
if (progStatus.vox_onoff) {
469
waitFB("set vox ON");
473
waitFB("set vox OFF");
477
void RIG_IC9100::set_vox_gain()
479
cmd.assign(pre_to).append("\x1A\x05");
482
cmd.append(to_bcd((int)(progStatus.vox_gain * 2.55), 3));
484
waitFB("SET vox gain");
487
void RIG_IC9100::set_vox_anti()
489
cmd.assign(pre_to).append("\x1A\x05");
492
cmd.append(to_bcd((int)(progStatus.vox_anti * 2.55), 3));
494
waitFB("SET anti-vox");
497
void RIG_IC9100::set_vox_hang()
499
cmd.assign(pre_to).append("\x1A\x05"); //values 00-20 = 0.0 - 2.0 sec
502
cmd.append(to_bcd((int)(progStatus.vox_hang / 10 ), 2));
504
waitFB("SET vox hang");
507
// these need to be written and tested
508
void RIG_IC9100::get_vox_onoff()
512
void RIG_IC9100::get_vox_gain()
516
void RIG_IC9100::get_vox_anti()
520
void RIG_IC9100::get_vox_hang()
526
void RIG_IC9100::set_cw_wpm()
528
cmd.assign(pre_to).append("\x14\x0C"); // values 0-255
529
cmd.append(to_bcd(round((progStatus.cw_wpm - 6) * 255 / (60 - 6)), 3));
531
waitFB("SET cw wpm");
534
void RIG_IC9100::set_cw_qsk()
536
int n = round(progStatus.cw_qsk * 10); // values 0-255
537
cmd.assign(pre_to).append("\x14\x0F");
538
cmd.append(to_bcd(n, 3));
540
waitFB("Set cw qsk delay");
543
void RIG_IC9100::set_cw_spot_tone()
545
cmd.assign(pre_to).append("\x14\x09"); // values 0=300Hz 255=900Hz
546
int n = round((progStatus.cw_spot_tone - 300) * 255.0 / 600.0);
547
if (n > 255) n = 255;
549
cmd.append(to_bcd(n, 3));
551
waitFB("SET cw spot tone");
554
void RIG_IC9100::set_cw_vol()
557
cmd.append("\x1A\x05");
560
cmd.append(to_bcd((int)(progStatus.cw_vol * 2.55), 3));
562
waitFB("SET cw sidetone volume");
565
int RIG_IC9100::get_smeter()
567
string cstr = "\x15\x02";
568
string resp = pre_fm;
574
if (waitFOR(9, "get smeter")) {
575
size_t p = replystr.rfind(resp);
576
if (p != string::npos) {
577
mtr = fm_bcd(&replystr[p+6], 3);
578
mtr = (int)ceil(mtr /2.40);
579
if (mtr > 100) mtr = 100;
585
int RIG_IC9100::get_power_out()
587
string cstr = "\x15\x11";
588
string resp = pre_fm;
594
if (waitFOR(9, "get pout")) {
595
size_t p = replystr.rfind(resp);
596
if (p != string::npos) {
597
mtr = fm_bcd(&replystr[p+6], 3);
598
mtr = (int)ceil(mtr /2.15);
599
if (mtr > 100) mtr = 100;
605
int RIG_IC9100::get_swr()
607
string cstr = "\x15\x12";
608
string resp = pre_fm;
614
if (waitFOR(9, "get SWR")) {
615
size_t p = replystr.rfind(resp);
616
if (p != string::npos) {
617
mtr = fm_bcd(&replystr[p+6], 3);
618
mtr = (int)ceil(mtr /2.40);
619
if (mtr > 100) mtr = 100;
625
int RIG_IC9100::get_alc()
627
string cstr = "\x15\x13";
628
string resp = pre_fm;
634
if (waitFOR(9, "get alc")) {
635
size_t p = replystr.rfind(resp);
636
if (p != string::npos) {
637
mtr = fm_bcd(&replystr[p+6], 3);
638
mtr = (int)ceil(mtr /2.55);
639
if (mtr > 100) mtr = 100;
645
void RIG_IC9100::set_notch(bool on, int val)
647
int notch = (int)(val * 256.0 / 3000.0);
650
cmd.append("\x16\x48");
651
cmd += on ? '\x01' : '\x00';
656
cmd.append("\x14\x0D");
657
cmd.append(to_bcd(notch,3));
659
waitFB("set notch val");
663
bool RIG_IC9100::get_notch(int &val)
668
string cstr = "\x16\x48";
669
string resp = pre_fm;
674
if (waitFOR(8, "get notch")) {
675
size_t p = replystr.rfind(resp);
676
if (p != string::npos)
677
on = replystr[p + 6];
684
if (waitFOR(9, "notch val")) {
685
size_t p = replystr.rfind(resp);
686
if (p != string::npos)
687
val = (int)ceil(fm_bcd(&replystr[p+6],3) * 3000.0 / 255.0);
693
void RIG_IC9100::get_notch_min_max_step(int &min, int &max, int &step)
700
void RIG_IC9100::set_auto_notch(int val)
705
cmd += val ? 0x01 : 0x00;
710
int RIG_IC9100::get_auto_notch()
712
string cstr = "\x16\x41";
713
string resp = pre_fm;
718
if (waitFOR(8, "get AN")) {
719
size_t p = replystr.rfind(resp);
720
if (p != string::npos) {
721
if (replystr[p+6] == 0x01) {
722
auto_notch_label("AN", true);
725
auto_notch_label("AN", false);
730
return progStatus.auto_notch;
733
void RIG_IC9100::set_split(bool val)
737
cmd += val ? 0x01 : 0x00;
742
int RIG_IC9100::get_split()
744
LOG_WARN("%s", "get split - not implemented");
745
return progStatus.split;
750
string resp = pre_fm;
752
if (waitFOR(8, "get split")) {
753
size_t p = replystr.rfind(resp);
754
if (p != string::npos)
755
return (replystr[p+6] ? 1 : 0);