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 "KENWOOD.h"
22 #include "support.h"
23 
selectA()24 void KENWOOD::selectA()
25 {
26 	cmd = "FR0;";
27 	sendCommand(cmd);
28 	showresp(WARN, ASC, "Rx on A", cmd, "");
29 	if (!split) {
30 		cmd = "FT0;";
31 		sendCommand(cmd);
32 		showresp(WARN, ASC, "Tx on A", cmd, "");
33 	} else {
34 		cmd = "FT1;";
35 		sendCommand(cmd);
36 		showresp(WARN, ASC, "Tx on B", cmd, "");
37 	}
38 }
39 
selectB()40 void KENWOOD::selectB()
41 {
42 	cmd = "FR1;";
43 	sendCommand(cmd);
44 	showresp(WARN, ASC, "Rx on B", cmd, "");
45 	if (!split) {
46 		cmd = "FT1;";
47 		sendCommand(cmd);
48 		showresp(WARN, ASC, "Tx on B", cmd, "");
49 	} else {
50 		cmd = "FT0;";
51 		sendCommand(cmd);
52 		showresp(WARN, ASC, "Tx on A", cmd, "");
53 	}
54 }
55 
set_split(bool val)56 void KENWOOD::set_split(bool val)
57 {
58 	split = val;
59 
60 	if (useB) {
61 		if (val) {
62 			cmd = "FR1;FT0;";
63 			sendCommand(cmd);
64 			showresp(WARN, ASC, "Rx on B, Tx on A", cmd, "");
65 		} else {
66 			cmd = "FR1;FT1;";
67 			sendCommand(cmd);
68 			showresp(WARN, ASC, "Rx on B, Tx on B", cmd, "");
69 		}
70 	} else {
71 		if (val) {
72 			cmd = "FR0;FT1;";
73 			sendCommand(cmd);
74 			showresp(WARN, ASC, "Rx on A, Tx on B", cmd, "");
75 		} else {
76 			cmd = "FR0;FT0;";
77 			sendCommand(cmd);
78 			showresp(WARN, ASC, "Rx on A, Tx on A", cmd, "");
79 		}
80 	}
81 }
82 
83 /*
84 ========================================================================
85 	frequency & mode data are contained in the IF; response
86 		IFaaaaaaaaaaaXXXXXbbbbbcdXeefghjklmmX;
87 		12345678901234567890123456789012345678
88 		01234567890123456789012345678901234567 byte #
89 		          1         2         3
90 		                            ^ position 28
91 		where:
92 			aaaaaaaaaaa => decimal value of vfo frequency
93 			bbbbb => rit/xit frequency
94 			c => rit off/on
95 			d => xit off/on
96 			e => memory channel
97 			f => tx/rx
98 			g => mode
99 			h => function
100 			j => scan off/on
101 			k => split off /on
102 			l => tone off /on
103 			m => tone number
104 			X => unused characters
105 
106 ========================================================================
107 */
108 
get_split()109 int KENWOOD::get_split()
110 {
111 	cmd = "IF;";
112 	int ret = wait_char(';', 38, 100, "get split", ASC);
113 	gett("split");
114 	if (ret < 38) return 0;
115 	return (replybuff[32] == '1');
116 }
117 
check()118 bool KENWOOD::check()
119 {
120 	cmd = "FA;";
121 	int ret = wait_char(';', 14, 100, "check", ASC);
122 	gett("check");
123 	if (ret < 14) return false;
124 	return true;
125 }
126 
get_vfoA()127 unsigned long int KENWOOD::get_vfoA ()
128 {
129 	cmd = "FA;";
130 	if (wait_char(';', 14, 100, "get vfo A", ASC) == 14) {
131 		size_t p = replystr.rfind("FA");
132 		if (p != string::npos) {
133 			int f = 0;
134 			for (size_t n = 2; n < 13; n++)
135 				f = f*10 + replystr[p+n] - '0';
136 			A.freq = f;
137 		}
138 	}
139 	gett("vfoA");
140 	return A.freq;
141 }
142 
set_vfoA(unsigned long int freq)143 void KENWOOD::set_vfoA (unsigned long int freq)
144 {
145 	A.freq = freq;
146 	cmd = "FA00000000000;";
147 	for (int i = 12; i > 1; i--) {
148 		cmd[i] += freq % 10;
149 		freq /= 10;
150 	}
151 	sendCommand(cmd);
152 	showresp(WARN, ASC, "set vfo A", cmd, "");
153 	sett("vfoA");
154 }
155 
get_vfoB()156 unsigned long int KENWOOD::get_vfoB ()
157 {
158 	cmd = "FB;";
159 	if (wait_char(';', 14, 100, "get vfo B", ASC) == 14) {
160 		size_t p = replystr.rfind("FB");
161 		if (p != string::npos) {
162 			int f = 0;
163 			for (size_t n = 2; n < 13; n++)
164 				f = f*10 + replystr[p+n] - '0';
165 			B.freq = f;
166 		}
167 	}
168 	gett("vfoB");
169 	return B.freq;
170 }
171 
set_vfoB(unsigned long int freq)172 void KENWOOD::set_vfoB (unsigned long int freq)
173 {
174 	B.freq = freq;
175 	cmd = "FB00000000000;";
176 	for (int i = 12; i > 1; i--) {
177 		cmd[i] += freq % 10;
178 		freq /= 10;
179 	}
180 	sendCommand(cmd);
181 	showresp(WARN, ASC, "set vfo B", cmd, "");
182 	sett("vfoB");
183 }
184 
185 /*
186 ========================================================================
187 	frequency & mode data are contained in the IF; response
188 		IFaaaaaaaaaaaXXXXXbbbbbcdXeefghjklmmX;
189 		12345678901234567890123456789012345678
190 		01234567890123456789012345678901234567 byte #
191 		          1         2         3
192 		                            ^ position 28
193 		where:
194 			aaaaaaaaaaa => decimal value of vfo frequency
195 			bbbbb => rit/xit frequency
196 			c => rit off/on
197 			d => xit off/on
198 			e => memory channel
199 			f => tx/rx
200 			g => mode
201 			h => function
202 			j => scan off/on
203 			k => split off /on
204 			l => tone off /on
205 			m => tone number
206 			X => unused characters
207 
208 ========================================================================
209 */
210 
get_PTT()211 int KENWOOD::get_PTT()
212 {
213 	cmd = "IF;";
214 	int ret = wait_char(';', 38, 100, "get VFO", ASC);
215 	if (ret < 38) return ptt_;
216 	ptt_ = (replybuff[28] == '1');
217 	gett("PTT");
218 	return ptt_;
219 }
220 
221 // Tranceiver PTT on/off
set_PTT_control(int val)222 void KENWOOD::set_PTT_control(int val)
223 {
224 	if (val) cmd = "TX;";
225 	else	 cmd = "RX;";
226 	sendCommand(cmd);
227 	showresp(WARN, ASC, "set PTT", cmd, "");
228 	sett("PTT");
229 }
230 
tune_rig(int val)231 void KENWOOD::tune_rig(int val)
232 {
233 //	cmd = "AC111;";
234 //	       | |||______ start tuner = 1
235 //	       | ||_______ set TX hold = 1
236 //	       | |________ set RX hold = 1
237 //	       |__________ tune transceiver command prefix
238 	if (tuning()) return;
239 	switch (val) {
240 		case 0:
241 			cmd = "AC000;"; break;
242 		case 1:
243 			cmd = "AC110;"; break;
244 		case 2: default:
245 			cmd = "AC111;"; break;
246 	}
247 	sendCommand(cmd);
248 	showresp(WARN, ASC, "tune_rig", cmd, "");
249 	sett("tune_run");
250 }
251 
tuning()252 bool KENWOOD::tuning()
253 {
254 	cmd = "AC;";
255 	if (wait_char(';', 6, 100, "tuning?", ASC) == 6) {
256 		if (replystr[4] == '1') return true;
257 	}
258 	return false;
259 }
260 
get_tune()261 int KENWOOD::get_tune()
262 {
263 	cmd = "AC;";
264 	if (wait_char(';', 6, 100, "tuning?", ASC) == 6) {
265 		size_t p = replystr.rfind("AC");
266 		if (p != std::string::npos) {
267 			return (replystr[p+4] - '0');
268 		}
269 	}
270 	gett("get_tune");
271 	return 0;
272 }
273 
274 // Volume control return 0 ... 100
get_volume_control()275 int KENWOOD::get_volume_control()
276 {
277 	int volctrl = 0;
278 	cmd = "AG0;";
279 	if (wait_char(';', 7, 100, "get vol", ASC) == 7) {
280 		size_t p = replystr.rfind("AG");
281 		if (p != string::npos) {
282 			volctrl = fm_decimal(replystr.substr(p+3),3);
283 			volctrl = (int)(volctrl / 2.55);
284 		}
285 	}
286 	gett("volume");
287 	return volctrl;
288 }
289 
set_volume_control(int val)290 void KENWOOD::set_volume_control(int val)
291 {
292 	int ivol = (int)(val * 2.55);
293 	cmd = "AG0";
294 	cmd.append(to_decimal(ivol, 3)).append(";");
295 	sendCommand(cmd);
296 	showresp(WARN, ASC, "set vol", cmd, "");
297 	sett("volume");
298 }
299 
select_swr()300 void  KENWOOD::select_swr()
301 {
302 	cmd = "RM1;";
303 	sendCommand(cmd);
304 	showresp(WARN, ASC, "select SWR", cmd, "");
305 	sett("select SWR");
306 }
307 
select_alc()308 void  KENWOOD::select_alc()
309 {
310 	cmd = "RM3;";
311 	sendCommand(cmd);
312 	showresp(WARN, ASC, "select ALC", cmd, "");
313 	sett("select ALC");
314 }
315 
set_rf_gain(int val)316 void KENWOOD::set_rf_gain(int val)
317 {
318 	cmd = "RG";
319 	cmd.append(to_decimal(val * 255 / 100, 3)).append(";");
320 	sendCommand(cmd);
321 	showresp(WARN, ASC, "set rf gain", cmd, "");
322 	sett("RFgain");
323 }
324 
get_rf_gain()325 int  KENWOOD::get_rf_gain()
326 {
327 	cmd = "RG;";
328 	int rfg = 100;
329 	if (wait_char(';', 6, 100, "get rf gain", ASC) == 6) {
330 		size_t p = replystr.rfind("RG");
331 		if (p != string::npos)
332 			rfg = fm_decimal(replystr.substr(p+2) ,3) * 100 / 255;
333 	}
334 	gett("RFgain");
335 	return rfg;
336 }
337 
get_rf_min_max_step(int & min,int & max,int & step)338 void KENWOOD::get_rf_min_max_step(int &min, int &max, int &step)
339 {
340 	min = 0;
341 	max = 100;
342 	step = 1;
343 }
344 
345 // val 0 .. 100
set_mic_gain(int val)346 void KENWOOD::set_mic_gain(int val)
347 {
348 	cmd = "MG";
349 	cmd.append(to_decimal(val,3)).append(";");
350 	sendCommand(cmd);
351 	showresp(WARN, ASC, "set mic", cmd, "");
352 	sett("MICgain");
353 }
354 
get_mic_gain()355 int KENWOOD::get_mic_gain()
356 {
357 	int mgain = 0;
358 	cmd = "MG;";
359 	if (wait_char(';', 6, 100, "get mic", ASC) == 6) {
360 		size_t p = replystr.rfind("MG");
361 		if (p != string::npos) {
362 			mgain = fm_decimal(replystr.substr(p+2), 3);
363 		}
364 	}
365 	gett("MICgain");
366 	return mgain;
367 }
368 
get_mic_min_max_step(int & min,int & max,int & step)369 void KENWOOD::get_mic_min_max_step(int &min, int &max, int &step)
370 {
371 	min = 0;
372 	max = 100;
373 	step = 1;
374 }
375 
set_noise(bool b)376 void KENWOOD::set_noise(bool b)
377 {
378 	if (b)
379 		cmd = "NB1;";
380 	else
381 		cmd = "NB0;";
382 	sendCommand(cmd);
383 	showresp(WARN, ASC, "set NB", cmd, "");
384 	sett("setNB");
385 }
386 
get_noise()387 int KENWOOD::get_noise()
388 {
389 	int response = 1;
390 	cmd = "NB;";
391 	if (wait_char(';', 4, 100, "get Noise Blanker", ASC) == 4) {
392 		size_t p = replystr.rfind("NB");
393 		if (p == string::npos) response = 0;
394 		if (replystr[p+2] == '0') response = 0;
395 	}
396 	gett("Noise");
397 	return response;
398 }
399 
set_squelch(int val)400 void KENWOOD::set_squelch(int val)
401 {
402 	cmd = "SQ0";
403 	cmd.append(to_decimal(abs(val),3)).append(";");
404 	sendCommand(cmd,0);
405 	showresp(WARN, ASC, "set squelch", cmd, "");
406 	sett("Squelch");
407 }
408 
get_squelch()409 int  KENWOOD::get_squelch()
410 {
411 	int val = 0;
412 	cmd = "SQ0;";
413 	if (wait_char(';', 7, 100, "get squelch", ASC) >= 7) {
414 		size_t p = replystr.rfind("SQ0");
415 		if (p == string::npos) return val;
416 		replystr[p + 6] = 0;
417 		val = atoi(&replystr[p + 3]);
418 	}
419 	gett("Squelch");
420 	return val;
421 }
422 
get_squelch_min_max_step(int & min,int & max,int & step)423 void KENWOOD::get_squelch_min_max_step(int &min, int &max, int &step)
424 {
425 	min = 0; max = 255; step = 1;
426 }
427 
428 //======================================================================
429 // IF shift only available if the transceiver is in the CW mode
430 // step size is 50 Hz
431 //======================================================================
432 
set_if_shift(int val)433 void KENWOOD::set_if_shift(int val)
434 {
435 	if (active_mode == CW || active_mode == CWR) { // cw modes
436 		progStatus.shift_val = val;
437 		cmd = "IS ";
438 		cmd.append(to_decimal(abs(val),4)).append(";");
439 		sendCommand(cmd,0);
440 		showresp(WARN, ASC, "set IF shift", cmd, "");
441 		sett("IF shift");
442 	}
443 }
444 
get_if_shift(int & val)445 bool KENWOOD::get_if_shift(int &val)
446 {
447 	bool response = false;
448 	if (active_mode == CW || active_mode == CWR) { // cw modes
449 		cmd = "IS;";
450 		if (wait_char(';', 8, 100, "get IF shift", ASC) == 8) {
451 			size_t p = replystr.rfind("IS");
452 			if (p != string::npos) {
453 				val = fm_decimal(replystr.substr(p+3), 4);
454 			} else
455 				val = progStatus.shift_val;
456 			response = true;
457 		}
458 	}
459 	val = progStatus.shift_val;
460 	gett("IF shift");
461 	return response;
462 }
463 
get_if_min_max_step(int & min,int & max,int & step)464 void KENWOOD::get_if_min_max_step(int &min, int &max, int &step)
465 {
466 }
467