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