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 "IC706MKIIG.h"
22 
23 //=============================================================================
24 // IC-706MKIIG
25 //
26 
27 // optional filter strings
28 // "EMPTY", "NARR", "NORM", "WIDE", "MED",
29 // "FL-101", "FL-232", "FL-100", "FL-223", "FL-272", "FL-103", "FL-94"
30 
31 const char IC706MKIIGname_[] = "IC-706MKIIG";
32 const char *IC706MKIIGmodes_[] = { "LSB", "USB", "AM", "CW", "RTTY", "FM", "WFM", NULL};
33 
34 enum {
35 	LSB706, USB706, AM706, CW706, RTTY706, FM706, WFM706 };
36 
37 const char IC706MKIIG_mode_type[] =
38 	{ 'L', 'U', 'U', 'L', 'L', 'U', 'U'};
39 const char *IC706MKIIG_ssb_cw_rtty_bws[] = { "WIDE", "NORMAL", "NARROW", NULL};
40 static int IC706MKIIG_vals_ssb_cw_rtty_bws[] = { 1, 2, 3, WVALS_LIMIT };
41 const char *IC706MKIIG_am_fm_bws[] = { "NORMAL", "NARROW", NULL};
42 static int IC706MKIIG_vals_am_fm_bws[] = { 1, 2, WVALS_LIMIT };
43 const char *IC706MKIIG_wfm_bws[] = { "FIXED", NULL};
44 static int IC706MKIIG_vals_wfm_bws[] = { 1, WVALS_LIMIT};
45 
RIG_IC706MKIIG()46 RIG_IC706MKIIG::RIG_IC706MKIIG() {
47 	name_ = IC706MKIIGname_;
48 	modes_ = IC706MKIIGmodes_;
49 	bandwidths_ = IC706MKIIG_ssb_cw_rtty_bws;
50 	bw_vals_ = IC706MKIIG_vals_ssb_cw_rtty_bws;
51 	_mode_type = IC706MKIIG_mode_type;
52 	comm_baudrate = BR19200;
53 	stopbits = 1;
54 	comm_retries = 2;
55 	comm_wait = 5;
56 	comm_timeout = 50;
57 	comm_echo = true;
58 	comm_rtscts = false;
59 	comm_rtsplus = true;
60 	comm_dtrplus = true;
61 	comm_catptt = false;
62 	comm_rtsptt = false;
63 	comm_dtrptt = false;
64 	def_freq = freqA = freqB = A.freq = B.imode = 14070000;
65 	def_mode = modeA = modeB = A.imode = B.imode = 1;
66 	def_bw = bwA = bwB = A.iBW = B.iBW = 0;
67 	filter_nbr = 0;
68 
69 	has_mode_control = true;
70 	has_bandwidth_control = true;
71 
72 //	has_split = true;
73 	has_smeter = true;
74 	has_mode_control = true;
75 	has_attenuator_control = true;
76 
77 	defaultCIV = 0x58;
78 	adjustCIV(defaultCIV);
79 
80 	precision = 1;
81 	ndigits = 9;
82 
83 };
84 
85 //=============================================================================
86 
initialize()87 void RIG_IC706MKIIG::initialize()
88 {
89 	if (progStatus.use706filters) {
90 		if (!progStatus.ssb_cw_wide.empty())   IC706MKIIG_ssb_cw_rtty_bws[0] = progStatus.ssb_cw_wide.c_str();
91 		if (!progStatus.ssb_cw_normal.empty()) IC706MKIIG_ssb_cw_rtty_bws[1] = progStatus.ssb_cw_normal.c_str();
92 		if (!progStatus.ssb_cw_narrow.empty()) IC706MKIIG_ssb_cw_rtty_bws[2] = progStatus.ssb_cw_narrow.c_str();
93 	} else {
94 		IC706MKIIG_ssb_cw_rtty_bws[0] = "FIXED";
95 		IC706MKIIG_ssb_cw_rtty_bws[1] = NULL;
96 	  IC706MKIIG_vals_ssb_cw_rtty_bws[0] = 1;
97 	  IC706MKIIG_vals_ssb_cw_rtty_bws[1] = WVALS_LIMIT;
98 	}
99 }
100 
selectA()101 void RIG_IC706MKIIG::selectA()
102 {
103 	cmd = pre_to;
104 	cmd += '\x07';
105 	cmd += '\x00';
106 	cmd.append(post);
107 	waitFB("select A");
108 }
109 
selectB()110 void RIG_IC706MKIIG::selectB()
111 {
112 	cmd = pre_to;
113 	cmd += '\x07';
114 	cmd += '\x01';
115 	cmd.append(post);
116 	waitFB("select B");
117 }
118 
check()119 bool RIG_IC706MKIIG::check ()
120 {
121 	string resp = pre_fm;
122 	resp += '\x03';
123 	cmd = pre_to;
124 	cmd += '\x03';
125 	cmd.append( post );
126 	bool ok = waitFOR(11, "check vfo");
127 	rig_trace(2, "check()", str2hex(replystr.c_str(), replystr.length()));
128 	return ok;
129 }
130 
get_vfoA()131 unsigned long int RIG_IC706MKIIG::get_vfoA ()
132 {
133 	if (useB) return A.freq;
134 	cmd = pre_to;
135 	cmd += '\x03';
136 	cmd.append( post );
137 	string resp = pre_fm;
138 	resp += '\x03';
139 	if (waitFOR(11, "get vfo A")) {
140 		size_t p = replystr.rfind(resp);
141 		if (p != string::npos) {
142 			if (replystr[p+5] == -1)
143 				A.freq = 0;
144 			else
145 				A.freq = fm_bcd_be(replystr.substr(p+5), 10);
146 		}
147 	}
148 	return A.freq;
149 }
150 
set_vfoA(unsigned long int freq)151 void RIG_IC706MKIIG::set_vfoA (unsigned long int freq)
152 {
153 	A.freq = freq;
154 	cmd = pre_to;
155 	cmd += '\x05';
156 	cmd.append( to_bcd_be( freq, 10 ) );
157 	cmd.append( post );
158 	waitFB("set vfo A");
159 }
160 
get_vfoB()161 unsigned long int RIG_IC706MKIIG::get_vfoB ()
162 {
163 	if (!useB) return B.freq;
164 	cmd = pre_to;
165 	cmd += '\x03';
166 	cmd.append( post );
167 	string resp = pre_fm;
168 	resp += '\x03';
169 	if (waitFOR(11, "get vfo B")) {
170 		size_t p = replystr.rfind(resp);
171 		if (p != string::npos) {
172 			if (replystr[p+5] == -1)
173 				A.freq = 0;
174 			else
175 				B.freq = fm_bcd_be(replystr.substr(p+5), 10);
176 		}
177 	}
178 	return B.freq;
179 }
180 
set_vfoB(unsigned long int freq)181 void RIG_IC706MKIIG::set_vfoB (unsigned long int freq)
182 {
183 	B.freq = freq;
184 	cmd = pre_to;
185 	cmd += '\x05';
186 	cmd.append( to_bcd_be( freq, 10 ) );
187 	cmd.append( post );
188 	waitFB("set vfo B");
189 }
190 
191 //void RIG_IC706MKIIG::set_split(bool b)
192 //{
193 //	cmd = pre_to;
194 //	cmd += 0x0F;
195 //	cmd += b ? 0x01 : 0x00;
196 //	cmd.append( post );
197 //	waitFB("set split");
198 //}
199 
200 // When wide or normal operation is available,
201 //   add “00” for wide operation or
202 //       “01” for normal operation;
203 // When normal or narrow operation is available,
204 //   add “00” for normal operation or
205 //       “01” for narrow operation;
206 // When wide, normal and narrow operation is available,
207 //   add “00” for wide operation,
208 //       “01” for normal operation
209 //   and “02” for narrow
210 
set_modeA(int val)211 void RIG_IC706MKIIG::set_modeA(int val)
212 {
213 	modeA = val;
214 	cmd = pre_to;
215 	cmd += 0x06;
216 	cmd += val;
217 	switch (val) {
218 		case AM706: case FM706:
219 		   cmd += IC706MKIIG_vals_am_fm_bws[filter_nbr];
220 			break;
221 		case WFM706:
222 		   cmd += IC706MKIIG_vals_wfm_bws[filter_nbr];
223 			break;
224 		case LSB706: case USB706: case CW706: case RTTY706: default:
225 		  if (progStatus.use706filters) {
226 			  cmd += IC706MKIIG_vals_ssb_cw_rtty_bws[filter_nbr];
227 		 } else { // No filters
228 			cmd += 0x01;
229 		 }
230 			break;
231 	}
232 	cmd.append( post );
233 	waitFB("set mode A");
234 }
235 
get_modeA()236 int RIG_IC706MKIIG::get_modeA()
237 {
238 	cmd = pre_to;
239 	cmd += 0x04;
240 	cmd.append(post);
241 	string resp = pre_fm;
242 	resp += 0x04;
243 	if (waitFOR(8, "get mode A")) {
244 		size_t p = replystr.rfind(resp);
245 		if (p != string::npos) {
246 			modeA = replystr[p+5];
247 			filter_nbr = replystr[p+6] - 1;
248 		}
249 	}
250 	return modeA;
251 }
252 
get_modetype(int n)253 int RIG_IC706MKIIG::get_modetype(int n)
254 {
255 	return _mode_type[n];
256 }
257 
set_bwA(int val)258 void RIG_IC706MKIIG::set_bwA(int val)
259 {
260 	filter_nbr = val;
261 	set_modeA(modeA);
262 }
263 
get_bwA()264 int RIG_IC706MKIIG::get_bwA()
265 {
266 	return filter_nbr;
267 }
268 
adjust_bandwidth(int m)269 int RIG_IC706MKIIG::adjust_bandwidth(int m)
270 {
271 	switch (m) {
272 		case LSB706: case USB706: case CW706: case RTTY706:
273 			bandwidths_ = IC706MKIIG_ssb_cw_rtty_bws;
274 			bw_vals_ = IC706MKIIG_vals_ssb_cw_rtty_bws;
275 			return 1;
276 			break;
277 		case AM706: case FM706:
278 			bandwidths_ = IC706MKIIG_am_fm_bws;
279 			bw_vals_ = IC706MKIIG_vals_am_fm_bws;
280 			return 0;
281 			break;
282 		case WFM706:
283 			bandwidths_ = IC706MKIIG_wfm_bws;
284 			bw_vals_ = IC706MKIIG_vals_wfm_bws;
285 			return 0;
286 			break;
287 		default:
288 			bandwidths_ = IC706MKIIG_ssb_cw_rtty_bws;
289 			bw_vals_ = IC706MKIIG_vals_ssb_cw_rtty_bws;
290 			return 1;
291 			break;
292 	}
293 	return 0;
294 }
295 
def_bandwidth(int m)296 int RIG_IC706MKIIG::def_bandwidth(int m)
297 {
298 	switch (m) {
299 		default:
300 		case LSB706: case USB706: case CW706: case RTTY706:
301 			return 1;
302 			break;
303 		case AM706: case FM706:
304 			return 0;
305 			break;
306 		case WFM706:
307 			return 0;
308 			break;
309 	}
310 	return 1;
311 }
312 
bwtable(int m)313 const char **RIG_IC706MKIIG::bwtable(int m)
314 {
315 	switch (m) {
316 		case LSB706: case USB706: case CW706: case RTTY706:
317 			return IC706MKIIG_ssb_cw_rtty_bws;
318 			break;
319 		case AM706: case FM706:
320 			return IC706MKIIG_am_fm_bws;
321 			break;
322 		case WFM706:
323 			return IC706MKIIG_wfm_bws;
324 			break;
325 		default:
326 			return IC706MKIIG_ssb_cw_rtty_bws;
327 			break;
328 	}
329 }
330 
set_attenuator(int val)331 void RIG_IC706MKIIG::set_attenuator(int val)
332 {
333 	cmd = pre_to;
334 	cmd += '\x11';
335 	cmd += val ? '\x20' : '\x00';
336 	cmd.append( post );
337 	waitFB("set att");
338 }
339 
get_smeter()340 int RIG_IC706MKIIG::get_smeter()
341 {
342 	cmd = pre_to;
343 	cmd.append("\x15\x02");
344 	cmd.append( post );
345 	string resp = pre_fm;
346 	resp.append("\x15\x02");
347 	if (waitFOR(9, "get smeter")) { // SHOULD BE 10 bytes
348 		size_t p = replystr.rfind(resp);
349 		if (p != string::npos)
350 			return (int)ceil(fm_bcd(replystr.substr(p+6), 3) / 2.55);
351 	}
352 	return -1;
353 }
354