1 /*
2 * Hamlib CI-V backend - main file
3 * Copyright (c) 2000-2016 by Stephane Fillod
4 *
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 // cppcheck-suppress *
26 #include <stdio.h>
27 // cppcheck-suppress *
28 #include <stdlib.h>
29 // cppcheck-suppress *
30 #include <string.h> /* String function definitions */
31 // cppcheck-suppress *
32 #include <unistd.h> /* UNIX standard function definitions */
33 // cppcheck-suppress *
34 #include <math.h>
35
36 #include <hamlib/rig.h>
37 #include <serial.h>
38 #include <misc.h>
39 #include <cal.h>
40 #include <token.h>
41 #include <register.h>
42
43 #include "icom.h"
44 #include "icom_defs.h"
45 #include "frame.h"
46
47 static int set_vfo_curr(RIG *rig, vfo_t vfo, vfo_t curr_vfo);
48 static int icom_set_default_vfo(RIG *rig);
49 static int icom_get_spectrum_vfo(RIG *rig, vfo_t vfo);
50 static int icom_get_spectrum_edge_frequency_range(RIG *rig, vfo_t vfo,
51 int *range_id);
52
53 const cal_table_float_t icom_default_swr_cal =
54 {
55 5,
56 {
57 {0, 1.0f},
58 {48, 1.5f},
59 {80, 2.0f},
60 {120, 3.0f},
61 {240, 6.0f}
62 }
63 };
64
65 const cal_table_float_t icom_default_alc_cal =
66 {
67 2,
68 {
69 {0, 0.0f},
70 {120, 1.0f}
71 }
72 };
73
74 const cal_table_float_t icom_default_rfpower_meter_cal =
75 {
76 13,
77 {
78 { 0, 0.0f },
79 { 21, 5.0f },
80 { 43, 10.0f },
81 { 65, 15.0f },
82 { 83, 20.0f },
83 { 95, 25.0f },
84 { 105, 30.0f },
85 { 114, 35.0f },
86 { 124, 40.0f },
87 { 143, 50.0f },
88 { 183, 75.0f },
89 { 213, 100.0f },
90 { 255, 120.0f }
91 }
92 };
93
94 const cal_table_float_t icom_default_comp_meter_cal =
95 {
96 3,
97 {
98 {0, 0.0f},
99 {130, 15.0f},
100 {241, 30.0f}
101 }
102 };
103
104 const cal_table_float_t icom_default_vd_meter_cal =
105 {
106 3,
107 {
108 {0, 0.0f},
109 {13, 10.0f},
110 {241, 16.0f}
111 }
112 };
113
114 const cal_table_float_t icom_default_id_meter_cal =
115 {
116 4,
117 {
118 {0, 0.0f},
119 {97, 10.0f},
120 {146, 15.0f},
121 {241, 25.0f}
122 }
123 };
124
125 const struct ts_sc_list r8500_ts_sc_list[] =
126 {
127 {10, 0x00},
128 {50, 0x01},
129 {100, 0x02},
130 {kHz(1), 0x03},
131 {12500, 0x04},
132 {kHz(5), 0x05},
133 {kHz(9), 0x06},
134 {kHz(10), 0x07},
135 {12500, 0x08},
136 {kHz(20), 0x09},
137 {kHz(25), 0x10},
138 {kHz(100), 0x11},
139 {MHz(1), 0x12},
140 {0, 0x13}, /* programmable tuning step not supported */
141 {0, 0},
142 };
143
144 const struct ts_sc_list ic737_ts_sc_list[] =
145 {
146 {10, 0x00},
147 {kHz(1), 0x01},
148 {kHz(2), 0x02},
149 {kHz(3), 0x03},
150 {kHz(4), 0x04},
151 {kHz(5), 0x05},
152 {kHz(6), 0x06},
153 {kHz(7), 0x07},
154 {kHz(8), 0x08},
155 {kHz(9), 0x09},
156 {kHz(10), 0x10},
157 {0, 0},
158 };
159
160 const struct ts_sc_list r75_ts_sc_list[] =
161 {
162 {10, 0x00},
163 {100, 0x01},
164 {kHz(1), 0x02},
165 {kHz(5), 0x03},
166 {6250, 0x04},
167 {kHz(9), 0x05},
168 {kHz(10), 0x06},
169 {12500, 0x07},
170 {kHz(20), 0x08},
171 {kHz(25), 0x09},
172 {kHz(100), 0x10},
173 {MHz(1), 0x11},
174 {0, 0},
175 };
176
177 const struct ts_sc_list r7100_ts_sc_list[] =
178 {
179 {100, 0x00},
180 {kHz(1), 0x01},
181 {kHz(5), 0x02},
182 {kHz(10), 0x03},
183 {12500, 0x04},
184 {kHz(20), 0x05},
185 {kHz(25), 0x06},
186 {kHz(100), 0x07},
187 {0, 0},
188 };
189
190 const struct ts_sc_list r9000_ts_sc_list[] =
191 {
192 {10, 0x00},
193 {100, 0x01},
194 {kHz(1), 0x02},
195 {kHz(5), 0x03},
196 {kHz(9), 0x04},
197 {kHz(10), 0x05},
198 {12500, 0x06},
199 {kHz(20), 0x07},
200 {kHz(25), 0x08},
201 {kHz(100), 0x09},
202 {0, 0},
203 };
204
205 const struct ts_sc_list r9500_ts_sc_list[] =
206 {
207 {1, 0x00},
208 {10, 0x01},
209 {100, 0x02},
210 {kHz(1), 0x03},
211 {kHz(2.5), 0x04},
212 {kHz(5), 0x05},
213 {6250, 0x06},
214 {kHz(9), 0x07},
215 {kHz(10), 0x08},
216 {12500, 0x09},
217 {kHz(20), 0x10},
218 {kHz(25), 0x11},
219 {kHz(100), 0x12},
220 {MHz(1), 0x13},
221 {0, 0},
222 };
223
224 const struct ts_sc_list ic718_ts_sc_list[] =
225 {
226 {10, 0x00},
227 {kHz(1), 0x01},
228 {kHz(5), 0x01},
229 {kHz(9), 0x01},
230 {kHz(10), 0x04},
231 {kHz(100), 0x05},
232 {0, 0},
233 };
234
235 const struct ts_sc_list ic756_ts_sc_list[] =
236 {
237 {10, 0x00},
238 {kHz(1), 0x01},
239 {kHz(5), 0x02},
240 {kHz(9), 0x03},
241 {kHz(10), 0x04},
242 {0, 0},
243 };
244
245 const struct ts_sc_list ic756pro_ts_sc_list[] =
246 {
247 {10, 0x00}, /* 1 if step turned off */
248 {100, 0x01},
249 {kHz(1), 0x02},
250 {kHz(5), 0x03},
251 {kHz(9), 0x04},
252 {kHz(10), 0x05},
253 {kHz(12.5), 0x06},
254 {kHz(20), 0x07},
255 {kHz(25), 0x08},
256 {0, 0},
257 };
258
259 const struct ts_sc_list ic706_ts_sc_list[] =
260 {
261 {10, 0x00},
262 {100, 0x01},
263 {kHz(1), 0x02},
264 {kHz(5), 0x03},
265 {kHz(9), 0x04},
266 {kHz(10), 0x05},
267 {12500, 0x06},
268 {kHz(20), 0x07},
269 {kHz(25), 0x08},
270 {kHz(100), 0x09},
271 {0, 0},
272 };
273
274 const struct ts_sc_list ic7000_ts_sc_list[] =
275 {
276 {10, 0x00},
277 {100, 0x01},
278 {kHz(1), 0x02},
279 {kHz(5), 0x03},
280 {kHz(9), 0x04},
281 {kHz(10), 0x05},
282 {12500, 0x06},
283 {kHz(20), 0x07},
284 {kHz(25), 0x08},
285 {kHz(100), 0x09},
286 {MHz(1), 0x10},
287 {0, 0},
288 };
289
290 const struct ts_sc_list ic7100_ts_sc_list[] =
291 {
292 {10, 0x00},
293 {100, 0x01},
294 {kHz(1), 0x02},
295 {kHz(5), 0x03},
296 {kHz(6.25), 0x04},
297 {kHz(9), 0x05},
298 {kHz(10), 0x06},
299 {kHz(12.5), 0x07},
300 {kHz(20), 0x08},
301 {kHz(25), 0x09},
302 {kHz(50), 0x0A},
303 {kHz(100), 0x0B},
304 {MHz(1), 0x0C},
305 {0, 0x00},
306 };
307
308 const struct ts_sc_list ic7200_ts_sc_list[] =
309 {
310 {10, 0x00},
311 {100, 0x01},
312 {kHz(1), 0x02},
313 {kHz(5), 0x03},
314 {kHz(9), 0x04},
315 {kHz(10), 0x05},
316 {0, 0},
317 };
318
319 const struct ts_sc_list ic7300_ts_sc_list[] =
320 {
321 {1, 0x00}, /* Manual says "Send/read the tuning step OFF" */
322 {100, 0x01},
323 {kHz(1), 0x02},
324 {kHz(5), 0x03},
325 {kHz(9), 0x04},
326 {kHz(10), 0x05},
327 {kHz(12.5), 0x06},
328 {kHz(20), 0x07},
329 {kHz(25), 0x08},
330 {0, 0},
331 };
332
333 const struct ts_sc_list ic910_ts_sc_list[] =
334 {
335 {Hz(1), 0x00},
336 {Hz(10), 0x01},
337 {Hz(50), 0x02},
338 {Hz(100), 0x03},
339 {kHz(1), 0x04},
340 {kHz(5), 0x05},
341 {kHz(6.25), 0x06},
342 {kHz(10), 0x07},
343 {kHz(12.5), 0x08},
344 {kHz(20), 0x09},
345 {kHz(25), 0x10},
346 {kHz(100), 0x11},
347 {0, 0},
348 };
349
350 const struct ts_sc_list r8600_ts_sc_list[] =
351 {
352 {10, 0x00},
353 {100, 0x01},
354 {kHz(1), 0x02},
355 {kHz(2.5), 0x03},
356 {3125, 0x04},
357 {kHz(5), 0x05},
358 {6250, 0x06},
359 {8330, 0x07},
360 {kHz(9), 0x08},
361 {kHz(10), 0x09},
362 {kHz(12.5), 0x10},
363 {kHz(20), 0x11},
364 {kHz(25), 0x12},
365 {kHz(100), 0x13},
366 {0, 0x14}, /* programmable tuning step not supported */
367 {0, 0},
368 };
369
370 const struct ts_sc_list ic705_ts_sc_list[] =
371 {
372 {10, 0x00},
373 {100, 0x01},
374 {500, 0x02},
375 {kHz(1), 0x03},
376 {kHz(5), 0x04},
377 {kHz(6.25), 0x05},
378 {kHz(8.33), 0x06},
379 {kHz(9), 0x07},
380 {kHz(10), 0x08},
381 {kHz(12.5), 0x09},
382 {kHz(20), 0x10},
383 {kHz(25), 0x11},
384 {kHz(50), 0x12},
385 {kHz(100), 0x13},
386 {0, 0},
387 };
388
389 const struct ts_sc_list ic9700_ts_sc_list[] =
390 {
391 {10, 0x00},
392 {100, 0x01},
393 {500, 0x02},
394 {kHz(1), 0x03},
395 {kHz(5), 0x04},
396 {kHz(6.25), 0x05},
397 {kHz(10), 0x06},
398 {kHz(12.5), 0x07},
399 {kHz(20), 0x08},
400 {kHz(25), 0x09},
401 {kHz(50), 0x10},
402 {kHz(100), 0x11},
403 {0, 0},
404 };
405
406 /* rtty filter list for some DSP rigs ie PRO */
407 #define RTTY_FIL_NB 5
408 const pbwidth_t rtty_fil[] =
409 {
410 Hz(250),
411 Hz(300),
412 Hz(350),
413 Hz(500),
414 kHz(1),
415 0,
416 };
417
418 struct icom_addr
419 {
420 rig_model_t model;
421 unsigned char re_civ_addr;
422 };
423
424
425 #define TOK_CIVADDR TOKEN_BACKEND(1)
426 #define TOK_MODE731 TOKEN_BACKEND(2)
427 #define TOK_NOXCHG TOKEN_BACKEND(3)
428
429 const struct confparams icom_cfg_params[] =
430 {
431 {
432 TOK_CIVADDR, "civaddr", "CI-V address", "Transceiver's CI-V address",
433 "0", RIG_CONF_NUMERIC, {.n = {0, 0xff, 1}}
434 },
435 {
436 TOK_MODE731, "mode731", "CI-V 731 mode", "CI-V operating frequency "
437 "data length, needed for IC731 and IC735",
438 "0", RIG_CONF_CHECKBUTTON
439 },
440 {
441 TOK_NOXCHG, "no_xchg", "No VFO XCHG",
442 "Don't Use VFO XCHG to set other VFO mode and Frequency",
443 "0", RIG_CONF_CHECKBUTTON
444 },
445 {RIG_CONF_END, NULL,}
446 };
447
448 /*
449 * Lookup table for icom_get_ext_func
450 */
451 const struct confparams icom_ext_funcs[] =
452 {
453 { TOK_DIGI_SEL_FUNC, "digi_sel", "DIGI-SEL enable", "", "", RIG_CONF_CHECKBUTTON, {} },
454 { RIG_CONF_END, NULL, }
455 };
456
457 /*
458 * Lookup table for icom_get_ext_level
459 */
460 const struct confparams icom_ext_levels[] =
461 {
462 { TOK_DIGI_SEL_LEVEL, "digi_sel_level", "DIGI-SEL level", "", "", RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } } },
463 { TOK_DRIVE_GAIN, "drive_gain", "Drive gain", "", "", RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } } },
464 { TOK_SCOPE_MSS, "SPECTRUM_SELECT", "Spectrum Scope Main/Sub", "", "", RIG_CONF_COMBO, { .c = { .combostr = { "Main", "Sub", NULL } } } },
465 { TOK_SCOPE_SDS, "SPECTRUM_DUAL", "Spectrum Scope Single/Dual", "", "", RIG_CONF_COMBO, { .c = { .combostr = { "Single", "Dual", NULL } } } },
466 { TOK_SCOPE_EDG, "SPECTRUM_EDGE", "Spectrum Scope Edge", "Edge selection for fixed scope mode", "", RIG_CONF_COMBO, { .c = { .combostr = { "1", "2", "3", "4", NULL } } } },
467 { TOK_SCOPE_STX, "SPECTRUM_TX", "Spectrum Scope TX operation", "", "", RIG_CONF_CHECKBUTTON, {} },
468 { TOK_SCOPE_CFQ, "SPECTRUM_CENTER", "Spectrum Scope Center Frequency Type", "", "", RIG_CONF_COMBO, { .c = { .combostr = { "Filter center", "Carrier point center", "Carrier point center (Abs. Freq.)", NULL } } } },
469 { TOK_SCOPE_VBW, "SPECTRUM_VBW", "Spectrum Scope VBW", "Video Band Width", "", RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Wide", NULL } } } },
470 { TOK_SCOPE_RBW, "SPECTRUM_RBW", "Spectrum Scope RBW", "Resolution Band Width", "", RIG_CONF_COMBO, { .c = { .combostr = { "Wide", "Mid", "Narrow", NULL } } } },
471 { RIG_CONF_END, NULL, }
472 };
473
474 /*
475 * Lookup table for icom_get_ext_parm
476 */
477 const struct confparams icom_ext_parms[] =
478 {
479 { TOK_DSTAR_DSQL, "dsdsql", "D-STAR CSQL Status", "", "", RIG_CONF_CHECKBUTTON, {} },
480 { TOK_DSTAR_CALL_SIGN, "dscals", "D-STAR Call sign", "", "", RIG_CONF_BINARY, {} },
481 { TOK_DSTAR_MESSAGE, "dsrmes", "D-STAR Rx Message", "", "", RIG_CONF_STRING, {} },
482 { TOK_DSTAR_STATUS, "dsstat", "D-STAR Rx Status", "", "", RIG_CONF_BINARY, {} },
483 { TOK_DSTAR_GPS_DATA, "dsgpsd", "D-STAR GPS Data", "", "", RIG_CONF_BINARY, {} },
484 { TOK_DSTAR_GPS_MESS, "dsgpsm", "D-STAR GPS Message", "", "", RIG_CONF_STRING, {} },
485 { TOK_DSTAR_CODE, "dscode", "D-STAR CSQL Code", "", "", RIG_CONF_NUMERIC, {} },
486 { TOK_DSTAR_TX_DATA, "dstdat", "D-STAR Tx Data", "", "", RIG_CONF_BINARY, {} },
487 { TOK_DSTAR_MY_CS, "dsmycs", "D-STAR MY Call Sign", "", "", RIG_CONF_STRING, {} },
488 { TOK_DSTAR_TX_CS, "dstxcs", "D-STAR Tx Call Sign", "", "", RIG_CONF_BINARY, {} },
489 { TOK_DSTAR_TX_MESS, "dstmes", "D-STAR Tx Message", "", "", RIG_CONF_STRING, {} },
490 { RIG_CONF_END, NULL, }
491 };
492
493 /*
494 * Lookup table for icom_get_ext_* & icom_set_ext_* functions
495 */
496
497 const struct cmdparams icom_ext_cmd[] =
498 {
499 { {.t = TOK_DSTAR_DSQL}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSCSQL, SC_MOD_RW, 1, {0}, CMD_DAT_BOL, 1 },
500 { {.t = TOK_DSTAR_CALL_SIGN}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSCALS, SC_MOD_RW12, 2, {0}, CMD_DAT_BUF, 38 },
501 { {.t = TOK_DSTAR_MESSAGE}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSMESS, SC_MOD_RW12, 2, {0}, CMD_DAT_STR, 32 },
502 { {.t = TOK_DSTAR_STATUS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSRSTS, SC_MOD_RW12, 2, {0}, CMD_DAT_BUF, 1 },
503 { {.t = TOK_DSTAR_GPS_DATA}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSGPSD, SC_MOD_RW12, 2, {0}, CMD_DAT_BUF, 52 },
504 { {.t = TOK_DSTAR_GPS_MESS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSGPSM, SC_MOD_RW12, 2, {0}, CMD_DAT_STR, 52 },
505 { {.t = TOK_DSTAR_CODE}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSCSQL, SC_MOD_RW12, 2, {0}, CMD_DAT_FLT, 1 },
506 { {.t = TOK_DSTAR_TX_DATA}, CMD_PARAM_TYPE_TOKEN, C_CTL_DSD, S_DSD_DSTXDT, SC_MOD_RW, 1, {0}, CMD_DAT_BUF, 30 },
507 { {.t = TOK_DSTAR_MY_CS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DVT, S_DVT_DSMYCS, SC_MOD_RW, 1, {0}, CMD_DAT_STR, 12 },
508 { {.t = TOK_DSTAR_TX_CS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DVT, S_DVT_DSTXCS, SC_MOD_RW, 1, {0}, CMD_DAT_STR, 24 },
509 { {.t = TOK_DSTAR_TX_MESS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DVT, S_DVT_DSTXMS, SC_MOD_RW, 1, {0}, CMD_DAT_STR, 20 },
510 { {.t = TOK_DRIVE_GAIN}, CMD_PARAM_TYPE_TOKEN, C_CTL_LVL, S_LVL_DRIVE, SC_MOD_RW, 0, {0}, CMD_DAT_FLT, 2 },
511 { {.t = TOK_DIGI_SEL_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_FUNC, S_FUNC_DIGISEL, SC_MOD_RW, 0, {0}, CMD_DAT_BOL, 1 },
512 { {.t = TOK_DIGI_SEL_LEVEL}, CMD_PARAM_TYPE_TOKEN, C_CTL_LVL, S_LVL_DIGI, SC_MOD_RW, 0, {0}, CMD_DAT_FLT, 2 },
513 { {0} }
514 };
515
516 /*
517 * Please, if the default CI-V address of your rig is listed as UNKNOWN_ADDR,
518 * send the value to <fillods@users.sourceforge.net> for inclusion. Thanks --SF
519 */
520 static const struct icom_addr icom_addr_list[] =
521 {
522 {RIG_MODEL_IC703, 0x68},
523 {RIG_MODEL_IC706, 0x48},
524 {RIG_MODEL_IC706MKII, 0x4e},
525 {RIG_MODEL_IC706MKIIG, 0x58},
526 {RIG_MODEL_IC271, 0x20},
527 {RIG_MODEL_IC275, 0x10},
528 {RIG_MODEL_IC375, 0x12},
529 {RIG_MODEL_IC471, 0x22},
530 {RIG_MODEL_IC475, 0x14},
531 {RIG_MODEL_IC575, 0x16},
532 {RIG_MODEL_IC707, 0x3e},
533 {RIG_MODEL_IC725, 0x28},
534 {RIG_MODEL_IC726, 0x30},
535 {RIG_MODEL_IC728, 0x38},
536 {RIG_MODEL_IC729, 0x3a},
537 {RIG_MODEL_IC731, 0x02}, /* need confirmation */
538 {RIG_MODEL_IC735, 0x04},
539 {RIG_MODEL_IC736, 0x40},
540 {RIG_MODEL_IC7410, 0x80},
541 {RIG_MODEL_IC746, 0x56},
542 {RIG_MODEL_IC746PRO, 0x66},
543 {RIG_MODEL_IC737, 0x3c},
544 {RIG_MODEL_IC738, 0x44},
545 {RIG_MODEL_IC751, 0x1c},
546 {RIG_MODEL_IC751A, 0x1c},
547 {RIG_MODEL_IC756, 0x50},
548 {RIG_MODEL_IC756PRO, 0x5c},
549 {RIG_MODEL_IC756PROII, 0x64},
550 {RIG_MODEL_IC756PROIII, 0x6e},
551 {RIG_MODEL_IC7600, 0x7a},
552 {RIG_MODEL_IC761, 0x1e},
553 {RIG_MODEL_IC765, 0x2c},
554 {RIG_MODEL_IC775, 0x46},
555 {RIG_MODEL_IC7800, 0x6a},
556 {RIG_MODEL_IC785x, 0x8e},
557 {RIG_MODEL_IC781, 0x26},
558 {RIG_MODEL_IC820, 0x42},
559 {RIG_MODEL_IC821H, 0x4c},
560 {RIG_MODEL_IC910, 0x60},
561 {RIG_MODEL_IC9100, 0x7c},
562 {RIG_MODEL_IC9700, 0xa2},
563 {RIG_MODEL_IC970, 0x2e},
564 {RIG_MODEL_IC1271, 0x24},
565 {RIG_MODEL_IC1275, 0x18},
566 {RIG_MODEL_ICR10, 0x52},
567 {RIG_MODEL_ICR20, 0x6c},
568 {RIG_MODEL_ICR6, 0x7e},
569 {RIG_MODEL_ICR71, 0x1a},
570 {RIG_MODEL_ICR72, 0x32},
571 {RIG_MODEL_ICR75, 0x5a},
572 {RIG_MODEL_ICRX7, 0x78},
573 {RIG_MODEL_IC78, 0x62},
574 {RIG_MODEL_ICR7000, 0x08},
575 {RIG_MODEL_ICR7100, 0x34},
576 {RIG_MODEL_ICR8500, 0x4a},
577 {RIG_MODEL_ICR9000, 0x2a},
578 {RIG_MODEL_ICR9500, 0x72},
579 {RIG_MODEL_MINISCOUT, 0x94},
580 {RIG_MODEL_IC718, 0x5e},
581 {RIG_MODEL_OS535, 0x80}, /* same address as IC-7410 */
582 {RIG_MODEL_ICID1, 0x01},
583 {RIG_MODEL_IC7000, 0x70},
584 {RIG_MODEL_IC7100, 0x88},
585 {RIG_MODEL_IC7200, 0x76},
586 {RIG_MODEL_IC7610, 0x98},
587 {RIG_MODEL_IC7700, 0x74},
588 {RIG_MODEL_PERSEUS, 0xE1},
589 {RIG_MODEL_X108G, 0x70},
590 {RIG_MODEL_ICR8600, 0x96},
591 {RIG_MODEL_ICR30, 0x9c},
592 {RIG_MODEL_NONE, 0},
593 };
594
595 /*
596 * This is a generic icom_init function.
597 * You might want to define yours, so you can customize it for your rig
598 *
599 * Basically, it sets up *priv
600 * REM: serial port is already open (rig->state.rigport.fd)
601 */
icom_init(RIG * rig)602 int icom_init(RIG *rig)
603 {
604 struct icom_priv_data *priv;
605 struct icom_priv_caps *priv_caps;
606 struct rig_caps *caps;
607 int i;
608
609 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
610
611 if (!rig->caps)
612 {
613 RETURNFUNC(-RIG_EINVAL);
614 }
615
616 caps = rig->caps;
617
618 if (!caps->priv)
619 {
620 RETURNFUNC(-RIG_ECONF);
621 }
622
623 priv_caps = (struct icom_priv_caps *) caps->priv;
624
625
626 rig->state.priv = (struct icom_priv_data *) calloc(1,
627 sizeof(struct icom_priv_data));
628
629 if (!rig->state.priv)
630 {
631 /* whoops! memory shortage! */
632 RETURNFUNC(-RIG_ENOMEM);
633 }
634
635 priv = rig->state.priv;
636
637 priv->spectrum_scope_count = 0;
638
639 for (i = 0; caps->spectrum_scopes[i].name != NULL; i++)
640 {
641 priv->spectrum_scope_cache[i].spectrum_data = NULL;
642
643 if (priv_caps->spectrum_scope_caps.spectrum_line_length < 1)
644 {
645 rig_debug(RIG_DEBUG_ERR, "%s: no spectrum scope line length defined\n",
646 __func__);
647 RETURNFUNC(-RIG_ECONF);
648 }
649
650 priv->spectrum_scope_cache[i].spectrum_data = calloc(1,
651 priv_caps->spectrum_scope_caps.spectrum_line_length);
652
653 if (!priv->spectrum_scope_cache[i].spectrum_data)
654 {
655 RETURNFUNC(-RIG_ENOMEM);
656 }
657
658 priv->spectrum_scope_count++;
659 }
660
661 /* TODO: CI-V address should be customizable */
662
663 /*
664 * init the priv_data from static struct
665 * + override with preferences
666 */
667
668 priv->re_civ_addr = priv_caps->re_civ_addr;
669 priv->civ_731_mode = priv_caps->civ_731_mode;
670 priv->no_xchg = priv_caps->no_xchg;
671 priv->tx_vfo = RIG_VFO_NONE;
672 priv->rx_vfo = RIG_VFO_NONE;
673 rig->state.current_vfo = RIG_VFO_NONE;
674 priv->filter = RIG_PASSBAND_NOCHANGE;
675 priv->x25cmdfails = 0;
676 priv->x1cx03cmdfails = 0;
677
678 rig_debug(RIG_DEBUG_TRACE, "%s: done\n", __func__);
679
680 RETURNFUNC(RIG_OK);
681 }
682
683 /*
684 * ICOM Generic icom_cleanup routine
685 * the serial port is closed by the frontend
686 */
icom_cleanup(RIG * rig)687 int icom_cleanup(RIG *rig)
688 {
689 struct icom_priv_data *priv;
690 int i;
691
692 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
693
694 if (!rig)
695 {
696 RETURNFUNC(-RIG_EINVAL);
697 }
698
699 priv = rig->state.priv;
700
701 for (i = 0; rig->caps->spectrum_scopes[i].name != NULL; i++)
702 {
703 if (priv->spectrum_scope_cache[i].spectrum_data)
704 {
705 free(priv->spectrum_scope_cache[i].spectrum_data);
706 priv->spectrum_scope_cache[i].spectrum_data = NULL;
707 }
708 }
709
710 if (rig->state.priv)
711 {
712 free(rig->state.priv);
713 }
714
715 rig->state.priv = NULL;
716
717 RETURNFUNC(RIG_OK);
718 }
719
720 /**
721 * Returns 1 when USB ECHO is off
722 * Returns 0 when USB ECHO is on
723 * \return Returns < 0 when error occurs (e.g. timeout, nimple, navail)
724 */
icom_get_usb_echo_off(RIG * rig)725 int icom_get_usb_echo_off(RIG *rig)
726 {
727 int retval;
728 unsigned char ackbuf[MAXFRAMELEN];
729 int ack_len = sizeof(ackbuf);
730 struct rig_state *rs = &rig->state;
731 int retry_save = rs->rigport.retry;
732 struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv;
733
734
735 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
736
737 // reduce the retry here so it's quicker
738 rs->rigport.retry = 0;
739 // Check for echo on first by assuming echo is off and checking the answer
740 priv->serial_USB_echo_off = 1;
741
742 rig_debug(RIG_DEBUG_VERBOSE, "%s: retry temp set to %d\n", __func__,
743 rs->rigport.retry);
744
745 retval = icom_transaction(rig, C_RD_FREQ, -1, NULL, 0, ackbuf, &ack_len);
746
747 // if rig is not powered on we get no data and TIMEOUT
748 if (ack_len == 0 && retval == -RIG_ETIMEOUT) { RETURNFUNC(retval); }
749
750 rig_debug(RIG_DEBUG_VERBOSE, "%s: ack_len=%d\n", __func__, ack_len);
751
752 if (ack_len == 1) // then we got an echo of the cmd
753 {
754 struct rig_state *rs = &rig->state;
755 unsigned char buf[16];
756 priv->serial_USB_echo_off = 0;
757 rig_debug(RIG_DEBUG_VERBOSE, "%s: USB echo on detected\n", __func__);
758 // we should have a freq response so we'll read it and don't really care
759 // flushing doesn't always work as it depends on timing
760 read_icom_frame(&rs->rigport, buf, sizeof(buf));
761 }
762 else
763 {
764 rig_debug(RIG_DEBUG_VERBOSE, "%s: USB echo off detected\n", __func__);
765 }
766
767 rs->rigport.retry = retry_save;
768 RETURNFUNC(priv->serial_USB_echo_off);
769 }
770
771
772 /*
773 * ICOM rig open routine
774 * Detect echo state of USB serial port
775 */
776 int
icom_rig_open(RIG * rig)777 icom_rig_open(RIG *rig)
778 {
779 int retval = RIG_OK;
780 int satmode = 0;
781 struct rig_state *rs = &rig->state;
782 struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv;
783
784 ENTERFUNC;
785
786 rig_debug(RIG_DEBUG_VERBOSE, "%s: %s v%s\n", __func__, rig->caps->model_name,
787 rig->caps->version);
788 retval = icom_get_usb_echo_off(rig);
789
790 if (retval == RIG_OK) // then echo is on so let's try freq now
791 {
792 // some rigs like the IC7100 still echo when in standby
793 // so asking for freq now should timeout if such a rig
794 freq_t tfreq;
795 retval = rig_get_freq(rig, RIG_VFO_A, &tfreq);
796 }
797
798 if (retval != RIG_OK && priv->poweron == 0 && rs->auto_power_on)
799 {
800 // maybe we need power on?
801 rig_debug(RIG_DEBUG_VERBOSE, "%s trying power on\n", __func__);
802 retval = abs(rig_set_powerstat(rig, 1));
803
804 // this is only a fatal error if powerstat is implemented
805 // if not iplemented than we're at an error here
806 if (retval != RIG_OK && retval != RIG_ENIMPL && retval != RIG_ENAVAIL)
807 {
808 rig_debug(RIG_DEBUG_WARN, "%s: unexpected retval here: %s\n",
809 __func__, rigerror(retval));
810
811 rig_debug(RIG_DEBUG_WARN, "%s: rig_set_powerstat failed: =%s\n", __func__,
812 rigerror(retval));
813 RETURNFUNC(retval);
814 }
815
816 // Now that we're powered up let's try again
817 retval = icom_get_usb_echo_off(rig);
818
819 if (retval < 0)
820 {
821 rig_debug(RIG_DEBUG_ERR, "%s: Unable to determine USB echo status\n", __func__);
822 RETURNFUNC(retval);
823 }
824 }
825
826 icom_set_default_vfo(rig);
827 priv->poweron = 1;
828
829 if (rig->caps->has_get_func & RIG_FUNC_SATMODE)
830 {
831 // retval is important here -- used below
832 retval = rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode);
833 rig->state.cache.satmode = satmode;
834 rig_debug(RIG_DEBUG_VERBOSE, "%s: satmode=%d\n", __func__, satmode);
835
836 // RIG_OK return means this rig has satmode capabiltiy and Main/Sub VFOs
837 // Should we also set/force VFOA for Main&Sub here?
838 if (retval == RIG_OK && satmode)
839 {
840 priv->rx_vfo = RIG_VFO_MAIN;
841 priv->tx_vfo = RIG_VFO_SUB;
842 }
843 else if (retval == RIG_OK && !satmode)
844 {
845 priv->rx_vfo = RIG_VFO_MAIN;
846 priv->tx_vfo = RIG_VFO_MAIN;
847 }
848 }
849
850 #if 0 // do not do this here -- needs to be done when ranges are requested instead as this is very slow
851 icom_get_freq_range(rig); // try get to get rig range capability dyamically
852 #endif
853
854 RETURNFUNC(RIG_OK);
855 }
856
857 /*
858 * ICOM rig close routine
859 */
860 int
icom_rig_close(RIG * rig)861 icom_rig_close(RIG *rig)
862 {
863 int retval = RIG_OK;
864 // Nothing to do yet
865 struct rig_state *rs = &rig->state;
866 struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv;
867
868 rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
869
870 if (priv->poweron != 0 && rs->auto_power_off)
871 {
872 // maybe we need power off?
873 rig_debug(RIG_DEBUG_VERBOSE, "%s trying power off\n", __func__);
874 retval = abs(rig_set_powerstat(rig, 0));
875
876 // this is only a fatal error if powerstat is implemented
877 // if not iplemented than we're at an error here
878 if (retval != RIG_OK && retval != RIG_ENIMPL && retval != RIG_ENAVAIL)
879 {
880 rig_debug(RIG_DEBUG_WARN, "%s: unexpected retval here: %s\n",
881 __func__, rigerror(retval));
882
883 rig_debug(RIG_DEBUG_WARN, "%s: rig_set_powerstat failed: =%s\n", __func__,
884 rigerror(retval));
885 RETURNFUNC(retval);
886 }
887
888 }
889
890 RETURNFUNC(RIG_OK);
891 }
892
893 /*
894 * Set default when vfo == RIG_VFO_NONE
895 * Clients should be setting VFO as 1st things but some don't
896 * So they will get defaults of Main/VFOA as the selected VFO
897 * and we force that selection
898 */
icom_set_default_vfo(RIG * rig)899 static int icom_set_default_vfo(RIG *rig)
900 {
901 int retval;
902
903 rig_debug(RIG_DEBUG_TRACE, "%s: called, curr_vfo=%s\n", __func__,
904 rig_strvfo(rig->state.current_vfo));
905
906 if (VFO_HAS_MAIN_SUB_A_B_ONLY)
907 {
908 rig_debug(RIG_DEBUG_TRACE, "%s: setting default as MAIN/VFOA\n",
909 __func__);
910 TRACE;
911 retval = rig_set_vfo(rig, RIG_VFO_MAIN); // we'll default to Main in this case
912
913 if (retval != RIG_OK)
914 {
915 RETURNFUNC(retval);
916 }
917
918 TRACE;
919 retval = rig_set_vfo(rig, RIG_VFO_A); // we'll default to Main in this case
920
921 if (retval != RIG_OK)
922 {
923 RETURNFUNC(retval);
924 }
925
926 rig->state.current_vfo = RIG_VFO_MAIN;
927 RETURNFUNC(RIG_OK);
928 }
929
930 if (VFO_HAS_MAIN_SUB_ONLY)
931 {
932 rig_debug(RIG_DEBUG_TRACE, "%s: setting default as MAIN\n",
933 __func__);
934 TRACE;
935 retval = rig_set_vfo(rig, RIG_VFO_MAIN); // we'll default to Main in this case
936 rig->state.current_vfo = RIG_VFO_MAIN;
937 }
938 else if (VFO_HAS_A_B)
939 {
940 rig_debug(RIG_DEBUG_TRACE, "%s: setting default as VFOA\n",
941 __func__);
942 TRACE;
943 retval = RIG_OK;
944
945 if (rig->state.current_vfo != RIG_VFO_A)
946 {
947 retval = rig_set_vfo(rig,
948 RIG_VFO_A); // we'll default to VFOA for all others
949 rig->state.current_vfo = RIG_VFO_A;
950 }
951 }
952 else
953 {
954 // we don't have any VFO selection
955 rig_debug(RIG_DEBUG_TRACE, "%s: Unknown VFO setup so setting default as VFOA\n",
956 __func__);
957
958 rig->state.current_vfo = RIG_VFO_A;
959 retval = RIG_OK;
960 }
961
962 if (retval != RIG_OK)
963 {
964 RETURNFUNC(retval);
965 }
966
967 rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo now %s\n", __func__,
968 rig_strvfo(rig->state.current_vfo));
969
970 RETURNFUNC(RIG_OK);
971 }
972
973 // return true if band is changing from last set_freq
974 // Assumes rig is currently on the VFO being changed
975 // This handles the case case Main/Sub cannot be on the same band
icom_band_changing(RIG * rig,freq_t test_freq)976 int icom_band_changing(RIG *rig, freq_t test_freq)
977 {
978 freq_t curr_freq, freq1, freq2;
979 int retval;
980
981 // We should be sitting on the VFO we want to change so just get it's frequency
982 retval = rig_get_freq(rig, RIG_VFO_CURR, &curr_freq);
983
984 if (retval != RIG_OK)
985 {
986 rig_debug(RIG_DEBUG_ERR, "%s: rig_get_freq failed??\n", __func__);
987 RETURNFUNC(0); // I guess we need to say no change in this case
988 }
989
990 // Make our HF=0, 2M = 1, 70cm = 4, and 23cm=12
991 freq1 = floor(curr_freq / 1e8);
992 freq2 = floor(test_freq / 1e8);
993
994 rig_debug(RIG_DEBUG_TRACE, "%s: lastfreq=%.0f, thisfreq=%.0f\n", __func__,
995 freq1, freq2);
996
997 if (freq1 != freq2)
998 {
999 rig_debug(RIG_DEBUG_TRACE, "%s: Band change detected\n", __func__);
1000 RETURNFUNC(1);
1001 }
1002
1003 rig_debug(RIG_DEBUG_TRACE, "%s: Band change not detected\n", __func__);
1004 RETURNFUNC(0);
1005 }
1006
1007 /*
1008 * icom_set_freq
1009 * Assumes rig!=NULL, rig->state.priv!=NULL
1010 */
icom_set_freq(RIG * rig,vfo_t vfo,freq_t freq)1011 int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
1012 {
1013 struct icom_priv_data *priv;
1014 struct rig_state *rs;
1015 unsigned char freqbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN];
1016 int freq_len, ack_len = sizeof(ackbuf), retval;
1017 int cmd, subcmd;
1018 freq_t curr_freq;
1019
1020 rig_debug(RIG_DEBUG_VERBOSE, "%s called %s=%" PRIfreq "\n", __func__,
1021 rig_strvfo(vfo), freq);
1022 rs = &rig->state;
1023 priv = (struct icom_priv_data *) rs->priv;
1024
1025 if (rig->state.current_vfo == RIG_VFO_NONE)
1026 {
1027 icom_set_default_vfo(rig);
1028 }
1029
1030 if (vfo == RIG_VFO_CURR)
1031 {
1032 vfo = rig->state.current_vfo;
1033 rig_debug(RIG_DEBUG_TRACE, "%s: currVFO asked for so vfo set to %s\n", __func__,
1034 rig_strvfo(vfo));
1035 }
1036
1037 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ))
1038 {
1039 TRACE;
1040 rig_debug(RIG_DEBUG_TRACE, "%s: set_vfo_curr=%s\n", __func__,
1041 rig_strvfo(rig->state.current_vfo));
1042 retval = set_vfo_curr(rig, vfo, rig->state.current_vfo);
1043
1044 if (retval != RIG_OK)
1045 {
1046 RETURNFUNC(retval);
1047 }
1048 }
1049
1050 retval = rig_get_freq(rig, vfo, &curr_freq);
1051
1052 if (retval != RIG_OK)
1053 {
1054 RETURNFUNC(retval);
1055 }
1056
1057 freq_len = priv->civ_731_mode ? 4 : 5;
1058 /*
1059 * to_bcd requires nibble len
1060 */
1061 to_bcd(freqbuf, freq, freq_len * 2);
1062
1063 // mike
1064 if (rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ)
1065 {
1066 vfo_t vfo_unselected = RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B;
1067
1068 // if we are on the "other" vfo already then we have to allow for that
1069 if (rig->state.current_vfo & vfo_unselected)
1070 {
1071 TRACE;
1072 vfo_unselected = RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_SUB_A | RIG_VFO_MAIN_A;
1073 }
1074
1075 rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): vfo=%s, currvfo=%s\n", __func__, __LINE__,
1076 rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo));
1077 subcmd = 0x00;
1078
1079 // if we ask for unselected but we're not on unselected subcmd2 changes
1080 if ((vfo & vfo_unselected) && !(rig->state.current_vfo & vfo_unselected))
1081 {
1082 TRACE;
1083 subcmd = 0x01; // get unselected VFO
1084 }
1085
1086 cmd = 0x25;
1087 retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf,
1088 &ack_len);
1089 }
1090 else
1091 {
1092 cmd = C_SET_FREQ;
1093 subcmd = -1;
1094 retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf,
1095 &ack_len);
1096 }
1097
1098 hl_usleep(50 * 1000); // pause for transceive message and we'll flush it
1099
1100 if (retval != RIG_OK)
1101 {
1102 // We might have a failed command if we're changing bands
1103 // For example, IC9700 setting Sub=VHF when Main=VHF will fail
1104 // So we'll try a VFO swap and see if that helps things
1105 rig_debug(RIG_DEBUG_VERBOSE, "%s: special check for vfo swap\n", __func__);
1106
1107 if (icom_band_changing(rig, freq))
1108 {
1109 if (rig_has_vfo_op(rig, RIG_OP_XCHG))
1110 {
1111 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
1112 {
1113 rig_debug(RIG_DEBUG_ERR, "%s: vfo_op XCHG failed: %s\n", __func__,
1114 rigerror(retval));
1115 RETURNFUNC(retval);
1116 }
1117
1118 // Try the command again
1119 retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf,
1120 &ack_len);
1121
1122 // Swap back if we got an error otherwise we fall through for more processing
1123 if (retval != RIG_OK)
1124 {
1125 int retval2;
1126 rig_debug(RIG_DEBUG_ERR, "%s: 2nd set freq failed: %s\n", __func__,
1127 rigerror(retval));
1128
1129 if (RIG_OK != (retval2 = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
1130 {
1131 rig_debug(RIG_DEBUG_ERR, "%s: 2nd vfo_op XCHG failed: %s\n", __func__,
1132 rigerror(retval));
1133 RETURNFUNC(retval2);
1134 }
1135
1136 RETURNFUNC(retval);
1137 }
1138 }
1139 }
1140
1141 if (retval != RIG_OK)
1142 {
1143 rig_debug(RIG_DEBUG_ERR, "%s: set freq failed: %s\n", __func__,
1144 rigerror(retval));
1145 RETURNFUNC(retval);
1146 }
1147 }
1148
1149 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
1150 {
1151 // if we don't get ACK/NAK some serial corruption occurred
1152 // so we'll call it a timeout for retry purposes
1153 RETURNFUNC(-RIG_ETIMEOUT);
1154 }
1155
1156 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
1157 {
1158 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
1159 ackbuf[0], ack_len);
1160 RETURNFUNC(-RIG_ERJCTED);
1161 }
1162
1163 priv->curr_freq = freq;
1164
1165 switch (vfo)
1166 {
1167 case RIG_VFO_A: priv->vfoa_freq = freq; break;
1168
1169 case RIG_VFO_MAIN_A: priv->maina_freq = freq; break;
1170
1171 case RIG_VFO_SUB_A: priv->suba_freq = freq; break;
1172
1173 case RIG_VFO_B: priv->vfob_freq = freq; break;
1174
1175 case RIG_VFO_MAIN_B: priv->mainb_freq = freq;
1176
1177 case RIG_VFO_SUB_B: priv->subb_freq = freq;
1178
1179 case RIG_VFO_MAIN: priv->main_freq = freq; break;
1180
1181 case RIG_VFO_SUB: priv->sub_freq = freq; break;
1182
1183 case RIG_VFO_CURR: break;
1184
1185 default:
1186 rig_debug(RIG_DEBUG_ERR, "%s: unknown VFO? VFO=%s\n", __func__,
1187 rig_strvfo(vfo));
1188 }
1189
1190 RETURNFUNC(RIG_OK);
1191 }
1192
1193 /*
1194 * icom_get_freq
1195 * Assumes rig!=NULL, rig->state.priv!=NULL, freq!=NULL, Main=VFOA, Sub=VFOB
1196 * Note: old rig may return less than 4/5 bytes for get_freq
1197 */
icom_get_freq(RIG * rig,vfo_t vfo,freq_t * freq)1198 int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
1199 {
1200 struct icom_priv_data *priv;
1201 struct rig_state *rs;
1202 unsigned char freqbuf[MAXFRAMELEN];
1203 int freqbuf_offset = 1;
1204 unsigned char ackbuf[MAXFRAMELEN];
1205 int freq_len, retval = -RIG_EINTERNAL;
1206 int cmd, subcmd;
1207 int ack_len = sizeof(ackbuf);
1208 int civ_731_mode = 0; // even these rigs have 5-byte channels
1209 vfo_t vfo_save = rig->state.current_vfo;
1210
1211 rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s, curr_vfo=%s\n", __func__,
1212 rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo));
1213 rs = &rig->state;
1214 priv = (struct icom_priv_data *) rs->priv;
1215
1216 cmd = C_RD_FREQ;
1217 subcmd = -1;
1218
1219 if (vfo == RIG_VFO_MEM && (priv->civ_731_mode
1220 || rig->caps->rig_model == RIG_MODEL_IC706))
1221 {
1222 rig_debug(RIG_DEBUG_TRACE, "%s: VFO=MEM so turning off civ_731\n", __func__);
1223 civ_731_mode = 1;
1224 priv->civ_731_mode = 0;
1225
1226 }
1227
1228 // Pick the appropriate VFO when VFO_TX is requested
1229 if (vfo == RIG_VFO_TX)
1230 {
1231 if (priv->x1cx03cmdfails == 0) // we can try this command to avoid vfo swapping
1232 {
1233 cmd = 0x1c;
1234 subcmd = 0x03;
1235 retval = icom_transaction(rig, cmd, subcmd, NULL, 0, ackbuf,
1236 &ack_len);
1237
1238 if (retval == RIG_OK) // then we're done!!
1239 {
1240 *freq = from_bcd(&ackbuf[2], (priv->civ_731_mode ? 4 : 5) * 2);
1241 RETURNFUNC(retval);
1242 }
1243
1244 priv->x1cx03cmdfails = 1;
1245 }
1246
1247 rig_debug(RIG_DEBUG_TRACE, "%s: VFO_TX requested, vfo=%s\n", __func__,
1248 rig_strvfo(vfo));
1249
1250 if (priv->split_on)
1251 {
1252 vfo = (rig->state.vfo_list & RIG_VFO_B) ? RIG_VFO_B : RIG_VFO_SUB;
1253 }
1254 else
1255 {
1256 vfo = (rig->state.vfo_list & RIG_VFO_B) ? RIG_VFO_A : RIG_VFO_MAIN;
1257 }
1258 }
1259
1260 #if 0 // does not work with rigs without VFO_A
1261
1262 if (vfo == RIG_VFO_CURR)
1263 {
1264 vfo = rig->state.current_vfo;
1265
1266 if (vfo == RIG_VFO_NONE) { vfo = RIG_VFO_A; }
1267
1268 rig_debug(RIG_DEBUG_VERBOSE, "%s: CurrVFO changed to %s\n", __func__,
1269 rig_strvfo(vfo));
1270 }
1271
1272 #endif
1273
1274
1275
1276 #if 0
1277
1278 // Pick the appropriate VFO when VFO_RX or VFO_TX is requested
1279 if (vfo == RIG_VFO_RX && rig->state.current_vfo)
1280 {
1281 vfo = vfo_fixup(rig, vfo);
1282 rig_debug(RIG_DEBUG_TRACE, "%s: vfo_fixup vfo=%s\n", __func__, rig_strvfo(vfo));
1283 vfo = (rig->state.vfo_list & RIG_VFO_B) ? RIG_VFO_A : RIG_VFO_MAIN;
1284 rig_debug(RIG_DEBUG_ERR, "%s: VFO_RX requested, new vfo=%s\n", __func__,
1285 rig_strvfo(vfo));
1286 }
1287 else if (vfo == RIG_VFO_TX)
1288 {
1289 vfo = vfo_fixup(rig, vfo)
1290 rig_debug(RIG_DEBUG_TRACE, "%s: vfo_fixup vfo=%s\n", __func__, rig_strvfo(vfo));
1291
1292 if (rig->state.vfo_list == VFO_HAS_MAIN_SUB_A_B_ONLY)
1293 {
1294 vfo = RIG_VFO_A;
1295
1296 if (priv->split_on) { vfo = RIG_VFO_B; }
1297 else if (rig->state.cache.satmode) { vfo = RIG_VFO_SUB; }
1298 }
1299
1300 rig_debug(RIG_DEBUG_ERR, "%s: VFO_TX requested, new vfo=%s\n", __func__,
1301 rig_strvfo(vfo));
1302 }
1303
1304 #endif
1305
1306 rig_debug(RIG_DEBUG_VERBOSE, "%s: using vfo=%s\n", __func__,
1307 rig_strvfo(vfo));
1308
1309 if (rig->state.current_vfo == RIG_VFO_NONE)
1310 {
1311 // we default to VFOA/MAIN as appropriate
1312 vfo = (rig->state.vfo_list & RIG_VFO_B) ? RIG_VFO_A : RIG_VFO_MAIN;
1313 TRACE;
1314 retval = rig_set_vfo(rig, vfo);
1315
1316 if (retval != RIG_OK)
1317 {
1318 rig_debug(RIG_DEBUG_ERR, "%s: set_vfo failed? retval=%s\n", __func__,
1319 rigerror(retval));
1320 }
1321 }
1322
1323 // we'll use 0x25 command to get unselected frequency
1324 // we have to assume current_vfo is accurate to determine what "other" means
1325 if (priv->x25cmdfails == 0)
1326 {
1327 int cmd2 = 0x25;
1328 int subcmd2 = 0x00;
1329 vfo_t vfo_unselected = RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B;
1330
1331 // if we are on the "other" vfo already then we have to allow for that
1332 if (rig->state.current_vfo & vfo_unselected)
1333 {
1334 vfo_unselected = RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_SUB_A | RIG_VFO_MAIN_A;
1335 }
1336
1337 // if we ask for unselected but we're not on unselected subcmd2 changes
1338 if ((vfo & vfo_unselected) && !(rig->state.current_vfo & vfo_unselected))
1339 {
1340 subcmd2 = 0x01; // get unselected VFO
1341 }
1342
1343 retval = icom_transaction(rig, cmd2, subcmd2, NULL, 0, freqbuf, &freq_len);
1344
1345 if (retval != RIG_OK)
1346 {
1347 priv->x25cmdfails = 1;
1348 rig_debug(RIG_DEBUG_WARN,
1349 "%s: rig does not support 0x25 CI-V cmd\n", __func__);
1350 }
1351
1352 freq_len--; // 0x25 cmd is 1 byte longer than 0x03 cmd
1353 freqbuf_offset = 2;
1354 }
1355
1356 if (priv->x25cmdfails) // then we're doing this the hard way....swap+read
1357 {
1358 freqbuf_offset = 1;
1359 TRACE;
1360 retval = set_vfo_curr(rig, vfo, rig->state.current_vfo);
1361
1362 if (retval != RIG_OK)
1363 {
1364 if (vfo == RIG_VFO_MEM && civ_731_mode) { priv->civ_731_mode = 1; }
1365
1366 RETURNFUNC(retval);
1367 }
1368
1369 retval = icom_transaction(rig, cmd, subcmd, NULL, 0, freqbuf, &freq_len);
1370 TRACE;
1371 set_vfo_curr(rig, vfo_save, rig->state.current_vfo);
1372 }
1373
1374 #if 0
1375 else if (!priv->x25cmdfails
1376 && (vfo & (RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_MAIN_A | RIG_VFO_SUB_A)))
1377 {
1378 // we can use the 0x03 command for the default VFO
1379 retval = icom_transaction(rig, cmd, subcmd, NULL, 0, freqbuf, &freq_len);
1380 }
1381
1382 #endif
1383
1384 if (retval != RIG_OK)
1385 {
1386 if (vfo == RIG_VFO_MEM && civ_731_mode) { priv->civ_731_mode = 1; }
1387
1388 RETURNFUNC(retval);
1389 }
1390
1391 /*
1392 * freqbuf should contain Cn,Data area
1393 */
1394 freq_len--;
1395
1396 /*
1397 * is it a blank mem channel ?
1398 */
1399 if (freq_len == 1 && freqbuf[1] == 0xff)
1400 {
1401 *freq = RIG_FREQ_NONE;
1402
1403 if (vfo == RIG_VFO_MEM && civ_731_mode) { priv->civ_731_mode = 1; }
1404
1405 RETURNFUNC(RIG_OK);
1406 }
1407
1408 if (freq_len != 4 && freq_len != 5)
1409 {
1410 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n",
1411 __func__, freq_len);
1412
1413 if (vfo == RIG_VFO_MEM && civ_731_mode) { priv->civ_731_mode = 1; }
1414
1415 RETURNFUNC(-RIG_ERJCTED);
1416 }
1417
1418 if (freq_len != (priv->civ_731_mode ? 4 : 5))
1419 {
1420 rig_debug(RIG_DEBUG_WARN, "%s: freq len (%d) differs from expected\n",
1421 __func__, freq_len);
1422 }
1423
1424 /*
1425 * from_bcd requires nibble len
1426 */
1427 *freq = from_bcd(freqbuf + freqbuf_offset, freq_len * 2);
1428
1429 if (vfo == RIG_VFO_MEM && civ_731_mode) { priv->civ_731_mode = 1; }
1430
1431 switch (vfo)
1432 {
1433 case RIG_VFO_A: priv->vfoa_freq = *freq; break;
1434
1435 case RIG_VFO_MAIN_A: priv->maina_freq = *freq; break;
1436
1437 case RIG_VFO_SUB_A: priv->suba_freq = *freq; break;
1438
1439 case RIG_VFO_B: priv->vfob_freq = *freq; break;
1440
1441 case RIG_VFO_MAIN_B: priv->mainb_freq = *freq; break;
1442
1443 case RIG_VFO_SUB_B: priv->subb_freq = *freq; break;
1444
1445 case RIG_VFO_MAIN: priv->main_freq = *freq; break;
1446
1447 case RIG_VFO_SUB: priv->sub_freq = *freq; break;
1448
1449 case RIG_VFO_CURR: break;
1450
1451 default:
1452 rig_debug(RIG_DEBUG_ERR, "%s: unknown VFO? VFO=%s\n", __func__,
1453 rig_strvfo(vfo));
1454 }
1455
1456 rig_debug(RIG_DEBUG_VERBOSE, "%s exit vfo=%s, curr_vfo=%s\n", __func__,
1457 rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo));
1458 RETURNFUNC(RIG_OK);
1459 }
1460
icom_get_rit_new(RIG * rig,vfo_t vfo,shortfreq_t * ts)1461 int icom_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *ts)
1462 {
1463 unsigned char tsbuf[MAXFRAMELEN];
1464 int ts_len, retval;
1465
1466 retval =
1467 icom_transaction(rig, C_CTL_RIT, S_RIT_FREQ, NULL, 0, tsbuf, &ts_len);
1468
1469 if (retval != RIG_OK)
1470 {
1471 RETURNFUNC(retval);
1472 }
1473
1474 /*
1475 * tsbuf nibbles should contain 10,1,1000,100 hz digits and 00=+, 01=- bit
1476 */
1477 rig_debug(RIG_DEBUG_VERBOSE, "%s: ts_len=%d\n", __func__, ts_len);
1478
1479 if (ts_len != 5)
1480 {
1481 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ts_len);
1482 RETURNFUNC(-RIG_ERJCTED);
1483 }
1484
1485 *ts = (shortfreq_t) from_bcd(tsbuf + 2, 4);
1486
1487 if (tsbuf[4] != 0)
1488 {
1489 *ts *= -1;
1490 }
1491
1492 RETURNFUNC(RIG_OK);
1493 }
1494
1495 // The Icom rigs have only one register for both RIT and Delta TX
1496 // you can turn one or both on -- but both end up just being in sync.
icom_set_it_new(RIG * rig,vfo_t vfo,shortfreq_t ts,int set_xit)1497 static int icom_set_it_new(RIG *rig, vfo_t vfo, shortfreq_t ts, int set_xit)
1498 {
1499 unsigned char tsbuf[8];
1500 unsigned char ackbuf[16];
1501 int ack_len;
1502 int retval;
1503
1504 rig_debug(RIG_DEBUG_VERBOSE, "%s: ts=%d\n", __func__, (int) ts);
1505
1506 to_bcd(tsbuf, abs((int) ts), 4);
1507 // set sign bit
1508 tsbuf[2] = (ts < 0) ? 1 : 0;
1509
1510 retval = icom_transaction(rig, C_CTL_RIT, S_RIT_FREQ, tsbuf, 3, ackbuf,
1511 &ack_len);
1512
1513 if (retval != RIG_OK)
1514 {
1515 RETURNFUNC(retval);
1516 }
1517
1518 #if 0 // why is this here? We have another function to turn it on/off
1519
1520 if (ts == 0) // Turn off both RIT/XIT
1521 {
1522 if (rig->caps->has_get_func & RIG_FUNC_XIT)
1523 {
1524 rig_debug(RIG_DEBUG_TRACE, "%s: turning of XIT too\n", __func__);
1525 retval = icom_set_func(rig, vfo, RIG_FUNC_XIT, 0);
1526
1527 if (retval != RIG_OK)
1528 {
1529 RETURNFUNC(retval);
1530 }
1531 }
1532 else // some rigs don't have XIT like the 9700
1533 {
1534 rig_debug(RIG_DEBUG_TRACE,
1535 "%s: rig does not have xit command enabled\n", __func__);
1536 }
1537
1538 retval = icom_set_func(rig, vfo, RIG_FUNC_RIT, 0);
1539 }
1540 else
1541 {
1542 retval =
1543 icom_set_func(rig, vfo, set_xit ? RIG_FUNC_XIT : RIG_FUNC_RIT, 1);
1544 }
1545
1546 #endif
1547
1548 RETURNFUNC(retval);
1549 }
1550
icom_set_rit_new(RIG * rig,vfo_t vfo,shortfreq_t ts)1551 int icom_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t ts)
1552 {
1553 RETURNFUNC(icom_set_it_new(rig, vfo, ts, 0));
1554 }
1555
icom_set_xit_new(RIG * rig,vfo_t vfo,shortfreq_t ts)1556 int icom_set_xit_new(RIG *rig, vfo_t vfo, shortfreq_t ts)
1557 {
1558 RETURNFUNC(icom_set_it_new(rig, vfo, ts, 1));
1559 }
1560
1561 /* icom_get_dsp_flt
1562 returns the dsp filter width in hz or 0 if the command is not implemented or error.
1563 This allows the default parameters to be assigned from the get_mode routine if the command is not implemented.
1564 Assumes rig != null and the current mode is in mode.
1565
1566 Has been tested for IC-746pro, Should work on the all dsp rigs ie pro models.
1567 The 746 documentation says it has the get_if_filter, but doesn't give any decoding information ? Please test.
1568 */
1569
icom_get_dsp_flt(RIG * rig,rmode_t mode)1570 pbwidth_t icom_get_dsp_flt(RIG *rig, rmode_t mode)
1571 {
1572
1573 int retval, res_len, rfstatus;
1574 unsigned char resbuf[MAXFRAMELEN];
1575 value_t rfwidth;
1576 unsigned char fw_sub_cmd = RIG_MODEL_IC7200 == rig->caps->rig_model ? 0x02 :
1577 S_MEM_FILT_WDTH;
1578 struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv;
1579
1580 rig_debug(RIG_DEBUG_VERBOSE, "%s called, mode=%s\n", __func__,
1581 rig_strrmode(mode));
1582
1583 if (rig_has_get_func(rig, RIG_FUNC_RF)
1584 && (mode & (RIG_MODE_RTTY | RIG_MODE_RTTYR)))
1585 {
1586 if (!rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_RF, &rfstatus)
1587 && (rfstatus))
1588 {
1589 retval = rig_get_ext_parm(rig, TOK_RTTY_FLTR, &rfwidth);
1590
1591 if (retval != RIG_OK || rfwidth.i >= RTTY_FIL_NB)
1592 {
1593 return (0); /* use default */
1594 }
1595 else
1596 {
1597 return (rtty_fil[rfwidth.i]);
1598 }
1599 }
1600 }
1601
1602 if (RIG_MODEL_X108G == rig->caps->rig_model)
1603 {
1604 priv->no_1a_03_cmd = 1;
1605 }
1606
1607 if (priv->no_1a_03_cmd)
1608 {
1609 return (0);
1610 }
1611
1612 retval = icom_transaction(rig, C_CTL_MEM, fw_sub_cmd, 0, 0,
1613 resbuf, &res_len);
1614
1615 if (-RIG_ERJCTED == retval)
1616 {
1617 priv->no_1a_03_cmd = -1; /* do not keep asking */
1618 return (0);
1619 }
1620
1621 if (retval != RIG_OK)
1622 {
1623 rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), "
1624 "len=%d\n", __func__, resbuf[0], res_len);
1625 return (0); /* use default */
1626 }
1627
1628 if (res_len == 3 && resbuf[0] == C_CTL_MEM)
1629 {
1630 int i;
1631 i = (int) from_bcd(resbuf + 2, 2);
1632 rig_debug(RIG_DEBUG_TRACE, "%s: i=%d, [0]=%02x, [1]=%02x, [2]=%02x, [3]=%02x\n",
1633 __func__, i, resbuf[0], resbuf[1], resbuf[2], resbuf[3]);
1634
1635 if (mode & RIG_MODE_AM)
1636 {
1637 return ((i + 1) * 200); /* Ic_7800 */
1638 }
1639 else if (mode &
1640 (RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_RTTY |
1641 RIG_MODE_RTTYR | RIG_MODE_PKTUSB | RIG_MODE_PKTLSB))
1642 {
1643 rig_debug(RIG_DEBUG_TRACE, "%s: using width=%d\n", __func__, i);
1644 RETURNFUNC(i < 10 ? (i + 1) * 50 : (i - 4) * 100);
1645 }
1646 }
1647
1648 RETURNFUNC(0);
1649 }
1650
icom_set_dsp_flt(RIG * rig,rmode_t mode,pbwidth_t width)1651 int icom_set_dsp_flt(RIG *rig, rmode_t mode, pbwidth_t width)
1652 {
1653 int retval, rfstatus;
1654 unsigned char ackbuf[MAXFRAMELEN];
1655 unsigned char flt_ext;
1656 value_t rfwidth;
1657 int ack_len = sizeof(ackbuf), flt_idx;
1658 unsigned char fw_sub_cmd = RIG_MODEL_IC7200 == rig->caps->rig_model ? 0x02 :
1659 S_MEM_FILT_WDTH;
1660
1661 ENTERFUNC;
1662
1663 if (RIG_PASSBAND_NOCHANGE == width)
1664 {
1665 RETURNFUNC(RIG_OK);
1666 }
1667
1668 if (width == RIG_PASSBAND_NORMAL)
1669 {
1670 width = rig_passband_normal(rig, mode);
1671 }
1672
1673 if (rig_has_get_func(rig, RIG_FUNC_RF)
1674 && (mode & (RIG_MODE_RTTY | RIG_MODE_RTTYR)))
1675 {
1676 if (!rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_RF, &rfstatus)
1677 && (rfstatus))
1678 {
1679 int i;
1680
1681 for (i = 0; i < RTTY_FIL_NB; i++)
1682 {
1683 if (rtty_fil[i] == width)
1684 {
1685 rfwidth.i = i;
1686 RETURNFUNC(rig_set_ext_parm(rig, TOK_RTTY_FLTR, rfwidth));
1687 }
1688 }
1689
1690 /* not found */
1691 RETURNFUNC(-RIG_EINVAL);
1692 }
1693 }
1694
1695 if (mode & RIG_MODE_AM)
1696 {
1697 flt_idx = (width / 200) - 1; /* TBC: Ic_7800? */
1698 }
1699 else if (mode & (RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_RTTY |
1700 RIG_MODE_RTTYR))
1701 {
1702 if (width == 0)
1703 {
1704 width = 1;
1705 }
1706
1707 flt_idx =
1708 width <= 500 ? ((width + 49) / 50) - 1 : ((width + 99) / 100) + 4;
1709 }
1710 else
1711 {
1712 RETURNFUNC(RIG_OK);
1713 }
1714
1715 to_bcd(&flt_ext, flt_idx, 2);
1716
1717 retval = icom_transaction(rig, C_CTL_MEM, fw_sub_cmd, &flt_ext, 1,
1718 ackbuf, &ack_len);
1719
1720 if (retval != RIG_OK)
1721 {
1722 rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), "
1723 "len=%d\n", __func__, ackbuf[0], ack_len);
1724 RETURNFUNC(retval);
1725 }
1726
1727 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
1728 {
1729 rig_debug(RIG_DEBUG_ERR, "%s: command not supported ? (%#.2x), "
1730 "len=%d\n", __func__, ackbuf[0], ack_len);
1731 RETURNFUNC(retval);
1732 }
1733
1734 RETURNFUNC(RIG_OK);
1735 }
1736
icom_set_mode_x26(RIG * rig,vfo_t vfo,rmode_t mode,int datamode,int filter)1737 static int icom_set_mode_x26(RIG *rig, vfo_t vfo, rmode_t mode, int datamode,
1738 int filter)
1739 {
1740 struct icom_priv_data *priv = rig->state.priv;
1741 int retval;
1742 unsigned char buf[3];
1743
1744 ENTERFUNC;
1745
1746 if (priv->x26cmdfails) { RETURNFUNC(-RIG_ENAVAIL); }
1747
1748 int cmd2 = 0x26;
1749 int subcmd2 = 0x00;
1750 vfo_t vfo_unselected = RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B;
1751
1752 // if we are on the "other" vfo already then we have to allow for that
1753 if (rig->state.current_vfo & vfo_unselected)
1754 {
1755 vfo_unselected = RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_SUB_A | RIG_VFO_MAIN_A;
1756 }
1757
1758 // if we ask for unselected but we're not on unselected subcmd2 changes
1759 if ((vfo & vfo_unselected) && !(rig->state.current_vfo & vfo_unselected))
1760 {
1761 subcmd2 = 0x01; // get unselected VFO
1762 }
1763
1764 buf[0] = mode;
1765 buf[1] = datamode;
1766 // filter fixed to filter 1 due to IC7300 bug defaulting to filter 2 on mode changed -- yuck!!
1767 // buf[2] = filter // if Icom ever fixed this
1768 buf[2] = 1;
1769
1770 retval = icom_transaction(rig, cmd2, subcmd2, buf, 3, NULL, NULL);
1771
1772 if (retval != RIG_OK)
1773 {
1774 priv->x26cmdfails = 1;
1775 rig_debug(RIG_DEBUG_WARN,
1776 "%s: rig does not support 0x26 CI-V cmd\n", __func__);
1777 return -RIG_ENAVAIL;
1778 }
1779
1780 RETURNFUNC(RIG_OK);
1781 }
1782
1783 /*
1784 * icom_set_mode_with_data
1785 */
icom_set_mode_with_data(RIG * rig,vfo_t vfo,rmode_t mode,pbwidth_t width)1786 int icom_set_mode_with_data(RIG *rig, vfo_t vfo, rmode_t mode,
1787 pbwidth_t width)
1788 {
1789 int retval;
1790 unsigned char ackbuf[MAXFRAMELEN];
1791 int ack_len = sizeof(ackbuf);
1792 rmode_t icom_mode;
1793 rmode_t tmode;
1794 pbwidth_t twidth;
1795 //struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv;
1796 unsigned char dm_sub_cmd =
1797 rig->caps->rig_model == RIG_MODEL_IC7200 ? 0x04 : S_MEM_DATA_MODE;
1798 int filter_byte = rig->caps->rig_model == RIG_MODEL_IC7100
1799 || rig->caps->rig_model == RIG_MODEL_IC7200
1800 || rig->caps->rig_model == RIG_MODEL_IC7300
1801 || rig->caps->rig_model == RIG_MODEL_IC7600
1802 || rig->caps->rig_model == RIG_MODEL_IC7610
1803 || rig->caps->rig_model == RIG_MODEL_IC7700
1804 || rig->caps->rig_model == RIG_MODEL_IC7800
1805 || rig->caps->rig_model == RIG_MODEL_IC785x
1806 || rig->caps->rig_model == RIG_MODEL_IC9100
1807 || rig->caps->rig_model == RIG_MODEL_IC9700
1808 || rig->caps->rig_model == RIG_MODEL_IC705;
1809
1810 ENTERFUNC;
1811
1812 // if our current mode and width is not changing do nothing
1813 retval = rig_get_mode(rig, vfo, &tmode, &twidth);
1814
1815 if (retval != RIG_OK)
1816 {
1817 rig_debug(RIG_DEBUG_ERR, "%s: get_mode failed: %s\n", __func__,
1818 rigerror(retval));
1819 RETURNFUNC(retval);
1820 }
1821
1822 if (tmode == mode && width == RIG_PASSBAND_NOCHANGE)
1823 {
1824 rig_debug(RIG_DEBUG_TRACE, "%s: mode/width not changing\n", __func__);
1825 RETURNFUNC(RIG_OK);
1826 }
1827 // looks like we need to change it
1828
1829 switch (mode)
1830 {
1831
1832 case RIG_MODE_PKTUSB:
1833 // xFE xFE x6E xE0 x1A x06 x01 xFD switches mod input from MIC to ACC
1834 // This apparently works for IC-756ProIII but nobody has asked for it yet
1835 icom_mode = RIG_MODE_USB;
1836 break;
1837
1838 case RIG_MODE_PKTLSB:
1839 icom_mode = RIG_MODE_LSB;
1840 break;
1841
1842 case RIG_MODE_PKTFM:
1843 icom_mode = RIG_MODE_FM;
1844 break;
1845
1846 case RIG_MODE_PKTAM:
1847 icom_mode = RIG_MODE_AM;
1848 break;
1849
1850 default:
1851 icom_mode = mode;
1852 break;
1853 }
1854
1855 rig_debug(RIG_DEBUG_VERBOSE, "%s mode=%d, width=%d, curr_vfo=%s\n", __func__,
1856 (int)icom_mode,
1857 (int)width, rig_strvfo(rig->state.current_vfo));
1858
1859 // we only need to change base mode if we aren't using cmd 26 later
1860 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE))
1861 {
1862 retval = icom_set_mode(rig, vfo, icom_mode, width);
1863 }
1864 else
1865 {
1866 retval = RIG_OK;
1867 }
1868
1869 hl_usleep(50 * 1000); // pause for possible transceive message which we'll flush
1870
1871 if (RIG_OK == retval)
1872 {
1873 unsigned char datamode[2];
1874 unsigned char mode_icom; // Not used, we only need the width
1875 signed char width_icom;
1876
1877 TRACE;
1878
1879 switch (mode)
1880 {
1881 case RIG_MODE_PKTUSB:
1882 case RIG_MODE_PKTLSB:
1883 case RIG_MODE_PKTFM:
1884 case RIG_MODE_PKTAM:
1885 datamode[0] = 0x01;
1886 datamode[1] = 0x02; // default to filter 2
1887 break;
1888
1889 default:
1890 datamode[0] = 0x00;
1891 datamode[1] = 0x02; // default to filter 2
1892 break;
1893 }
1894
1895 rig2icom_mode(rig, vfo, mode, width, &mode_icom, &width_icom);
1896
1897 if (filter_byte) // then we need the filter width byte too
1898 {
1899 TRACE;
1900
1901 if (datamode[0] == 0) { datamode[1] = 0; } // the only good combo possible according to manual
1902
1903 rig_debug(RIG_DEBUG_TRACE, "%s(%d) mode_icom=%d, datamode[0]=%d, filter=%d\n",
1904 __func__, __LINE__, mode_icom, datamode[0], datamode[1]);
1905 retval = icom_set_mode_x26(rig, vfo, mode_icom, datamode[0], datamode[1]);
1906
1907 if (retval != RIG_OK)
1908 {
1909 retval =
1910 icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, datamode, 2, ackbuf, &ack_len);
1911 }
1912 }
1913 else
1914 {
1915 TRACE;
1916 retval =
1917 icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, datamode, 1, ackbuf, &ack_len);
1918 }
1919
1920 if (retval != RIG_OK)
1921 {
1922 rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), len=%d\n",
1923 __func__, ackbuf[0], ack_len);
1924 }
1925 else
1926 {
1927 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
1928 {
1929 rig_debug(RIG_DEBUG_ERR,
1930 "%s: command not supported ? (%#.2x), len=%d\n",
1931 __func__, ackbuf[0], ack_len);
1932 }
1933 }
1934 }
1935
1936 RETURNFUNC(retval);
1937 }
1938
1939 /*
1940 * icom_set_mode
1941 * Assumes rig!=NULL, rig->state.priv!=NULL
1942 */
icom_set_mode(RIG * rig,vfo_t vfo,rmode_t mode,pbwidth_t width)1943 int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
1944 {
1945 struct icom_priv_data *priv;
1946 const struct icom_priv_caps *priv_caps;
1947 const struct icom_priv_data *priv_data;
1948 struct rig_state *rs;
1949 unsigned char ackbuf[MAXFRAMELEN];
1950 unsigned char icmode;
1951 signed char icmode_ext;
1952 int ack_len = sizeof(ackbuf), retval, err;
1953 int swapvfos = 0;
1954
1955 rig_debug(RIG_DEBUG_VERBOSE,
1956 "%s called vfo=%s, mode=%s, width=%d, current_vfo=%s\n", __func__,
1957 rig_strvfo(vfo), rig_strrmode(mode), (int)width,
1958 rig_strvfo(rig->state.current_vfo));
1959 rs = &rig->state;
1960 priv = (struct icom_priv_data *) rs->priv;
1961
1962 priv_caps = (const struct icom_priv_caps *) rig->caps->priv;
1963 priv_data = (const struct icom_priv_data *) rig->state.priv;
1964
1965 if (priv_caps->r2i_mode != NULL) /* call priv code if defined */
1966 {
1967 err = priv_caps->r2i_mode(rig, vfo, mode, width, &icmode, &icmode_ext);
1968 }
1969 else /* else call default */
1970 {
1971 err = rig2icom_mode(rig, vfo, mode, width, &icmode, &icmode_ext);
1972 }
1973
1974 if (width == RIG_PASSBAND_NOCHANGE) { icmode_ext = priv_data->filter; }
1975
1976 if (err < 0)
1977 {
1978 rig_debug(RIG_DEBUG_ERR, "%s: Error on rig2icom err=%d\n", __func__, err);
1979 RETURNFUNC(err);
1980 }
1981
1982 rig_debug(RIG_DEBUG_VERBOSE, "%s: icmode=%d, icmode_ext=%d\n", __func__, icmode,
1983 icmode_ext);
1984
1985 /* IC-731, IC-735, IC-7000 don't support passband data */
1986 /* IC-726 & IC-475A/E also limited support - only on CW */
1987 /* TODO: G4WJS CW wide/narrow are possible with above two radios */
1988 if (priv->civ_731_mode || rig->caps->rig_model == RIG_MODEL_OS456
1989 || rig->caps->rig_model == RIG_MODEL_IC726
1990 || rig->caps->rig_model == RIG_MODEL_IC475
1991 || rig->caps->rig_model == RIG_MODEL_IC7000)
1992 {
1993 icmode_ext = -1;
1994 }
1995
1996 // some Icom rigs have seperate modes for VFOB/Sub
1997 // switching to VFOB should not matter for the other rigs
1998 // This needs to be improved for RIG_TARGETABLE_MODE rigs
1999 if ((vfo == RIG_VFO_B || vfo == RIG_VFO_SUB)
2000 && ((rig->state.current_vfo == RIG_VFO_A
2001 || rig->state.current_vfo == RIG_VFO_MAIN)
2002 || rig->state.current_vfo == RIG_VFO_CURR))
2003 {
2004 TRACE;
2005
2006 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE))
2007 {
2008 swapvfos = 1;
2009 rig_set_vfo(rig, RIG_VFO_B);
2010 }
2011 }
2012
2013 rig_debug(RIG_DEBUG_VERBOSE, "%s: #2 icmode=%d, icmode_ext=%d\n", __func__,
2014 icmode, icmode_ext);
2015 retval = icom_transaction(rig, C_SET_MODE, icmode,
2016 (unsigned char *) &icmode_ext,
2017 (icmode_ext == -1 ? 0 : 1), ackbuf, &ack_len);
2018
2019 if (swapvfos)
2020 {
2021 TRACE;
2022 rig_set_vfo(rig, RIG_VFO_A);
2023 }
2024
2025 if (retval != RIG_OK)
2026 {
2027 RETURNFUNC(retval);
2028 }
2029
2030 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
2031 {
2032 // if we don't get ACK/NAK some serial corruption occurred
2033 // so we'll call it a timeout for retry purposes
2034 RETURNFUNC(-RIG_ETIMEOUT);
2035 }
2036
2037 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
2038 {
2039 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
2040 ackbuf[0], ack_len);
2041 RETURNFUNC(-RIG_ERJCTED);
2042 }
2043
2044 /* DSP filter setting ($1A$03), but not supported by every rig,
2045 * and some models like IC910/Omni VI Plus have a different meaning for
2046 * this subcommand
2047 */
2048 if (rig->caps->rig_model == RIG_MODEL_IC7000)
2049 {
2050 icom_set_dsp_flt(rig, mode, width);
2051 }
2052
2053 RETURNFUNC(RIG_OK);
2054 }
2055
2056 /*
2057 * icom_get_mode_with_data
2058 *
2059 * newer Icom rigs support data mode with ACC-1 audio input and MIC muted
2060 */
icom_get_mode_with_data(RIG * rig,vfo_t vfo,rmode_t * mode,pbwidth_t * width)2061 int icom_get_mode_with_data(RIG *rig, vfo_t vfo, rmode_t *mode,
2062 pbwidth_t *width)
2063 {
2064 unsigned char databuf[MAXFRAMELEN];
2065 int data_len, retval;
2066 unsigned char dm_sub_cmd = RIG_MODEL_IC7200 == rig->caps->rig_model ? 0x04 :
2067 S_MEM_DATA_MODE;
2068 struct rig_state *rs;
2069 struct icom_priv_data *priv;
2070
2071 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2072
2073 rs = &rig->state;
2074 priv = (struct icom_priv_data *) rs->priv;
2075
2076 retval = icom_get_mode(rig, vfo, mode, width);
2077
2078 if (retval != RIG_OK)
2079 {
2080 RETURNFUNC(retval);
2081 }
2082
2083 rig_debug(RIG_DEBUG_VERBOSE, "%s mode=%d\n", __func__, (int)*mode);
2084
2085 switch (*mode)
2086 {
2087 case RIG_MODE_USB:
2088 case RIG_MODE_LSB:
2089 case RIG_MODE_AM:
2090 case RIG_MODE_FM:
2091
2092 /*
2093 * fetch data mode on/off
2094 */
2095 if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
2096 {
2097 // then we already got data mode so we fake the databuf answer
2098 databuf[2] = priv->datamode;
2099 data_len = 3;
2100 }
2101 else
2102 {
2103 retval =
2104 icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, 0, 0, databuf,
2105 &data_len);
2106
2107 if (retval != RIG_OK)
2108 {
2109 rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), len=%d\n",
2110 __func__, databuf[0], data_len);
2111 RETURNFUNC(-RIG_ERJCTED);
2112 }
2113 }
2114
2115 /*
2116 * databuf should contain Cn,Sc,D0[,D1]
2117 */
2118 data_len -= 2;
2119
2120 if (1 > data_len || data_len > 2)
2121 {
2122 /* manual says 1 byte answer
2123 but at least IC756 ProIII
2124 sends 2 - second byte
2125 appears to be same as
2126 second byte from 04 command
2127 which is filter preset
2128 number, whatever it is we
2129 ignore it */
2130 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__,
2131 data_len);
2132 RETURNFUNC(-RIG_ERJCTED);
2133 }
2134
2135 rig_debug(RIG_DEBUG_VERBOSE, "%s databuf[2]=%d, mode=%d\n", __func__,
2136 (int)databuf[2], (int)*mode);
2137
2138 if (databuf[2]) /* 0x01/0x02/0x03 -> data mode, 0x00 -> not data mode */
2139 {
2140 switch (*mode)
2141 {
2142 case RIG_MODE_USB:
2143 *mode = RIG_MODE_PKTUSB;
2144 break;
2145
2146 case RIG_MODE_LSB:
2147 *mode = RIG_MODE_PKTLSB;
2148 break;
2149
2150 case RIG_MODE_AM:
2151 *mode = RIG_MODE_PKTAM;
2152 break;
2153
2154 case RIG_MODE_FM:
2155 *mode = RIG_MODE_PKTFM;
2156 break;
2157
2158 default:
2159 break;
2160 }
2161 }
2162
2163 default:
2164 break;
2165 }
2166
2167 RETURNFUNC(retval);
2168 }
2169
2170 /*
2171 * icom_get_mode
2172 * Assumes rig!=NULL, rig->state.priv!=NULL, mode!=NULL, width!=NULL
2173 *
2174 * TODO: some IC781's, when sending mode info, in wide filter mode, no
2175 * width data is send along, making the frame 1 byte short.
2176 * (Thank to Mel, VE2DC for this info)
2177 */
icom_get_mode(RIG * rig,vfo_t vfo,rmode_t * mode,pbwidth_t * width)2178 int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
2179 {
2180 unsigned char modebuf[MAXFRAMELEN];
2181 const struct icom_priv_caps *priv_caps;
2182 struct icom_priv_data *priv_data;
2183 int mode_len, retval;
2184
2185 rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo));
2186 priv_caps = (const struct icom_priv_caps *) rig->caps->priv;
2187 priv_data = (struct icom_priv_data *) rig->state.priv;
2188
2189 *width = 0;
2190
2191 // IC7800 can set but not read with 0x26
2192 if ((rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
2193 && rig->caps->rig_model != RIG_MODEL_IC7800)
2194 {
2195 int vfosel = 0x00;
2196
2197 if (vfo & (RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B)) { vfosel = 0x01; }
2198
2199 // use cache for the non-selected VFO -- can't get it by VFO
2200 // this avoids vfo swapping but accurate answers for these rigs
2201 *width = rig->state.cache.widthMainB;
2202
2203 if (vfo == RIG_VFO_SUB_B) { *width = rig->state.cache.widthSubB; }
2204
2205 // then get non-selected VFO mode/width
2206 retval = icom_transaction(rig, 0x26, vfosel, NULL, 0, modebuf, &mode_len);
2207 rig_debug(RIG_DEBUG_TRACE,
2208 "%s: mode_len=%d, modebuf=%02x %02x %02x %02x %02x\n", __func__, mode_len,
2209 modebuf[0], modebuf[1], modebuf[2], modebuf[3], modebuf[4]);
2210 // mode_len=5, modebuf=26 01 01 01 01
2211 // last 3 bytes are mode, datamode, filter (1-3)
2212 priv_data->datamode = modebuf[3];
2213 priv_data->filter = modebuf[4];
2214 modebuf[1] = modebuf[2]; // copy mode to 2-byte format
2215 modebuf[2] = modebuf[4]; // copy filter to 2-byte format
2216 mode_len = 2;
2217 }
2218 else
2219 {
2220 retval = icom_transaction(rig, C_RD_MODE, -1, NULL, 0, modebuf, &mode_len);
2221 }
2222
2223 if (--mode_len == 3)
2224 {
2225 priv_data->filter = modebuf[2];
2226 rig_debug(RIG_DEBUG_TRACE,
2227 "%s: modebuf[0]=0x%02x, modebuf[1]=0x%02x, modebuf[2]=0x%02x, mode_len=%d, filter=%d\n",
2228 __func__, modebuf[0],
2229 modebuf[1], modebuf[2], mode_len, priv_data->filter);
2230 }
2231 else
2232 {
2233 rig_debug(RIG_DEBUG_TRACE,
2234 "%s: modebuf[0]=0x%02x, modebuf[1]=0x%02x, mode_len=%d\n", __func__, modebuf[0],
2235 modebuf[1], mode_len);
2236 }
2237
2238 if (retval != RIG_OK)
2239 {
2240 RETURNFUNC(retval);
2241 }
2242
2243 /*
2244 * modebuf should contain Cn,Data area
2245 */
2246 // when mode gets here it should be 2 or 1
2247 // mode_len--;
2248
2249 if (mode_len != 2 && mode_len != 1)
2250 {
2251 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n",
2252 __func__, mode_len);
2253 RETURNFUNC(-RIG_ERJCTED);
2254 }
2255
2256 if (priv_caps->i2r_mode != NULL) /* call priv code if defined */
2257 {
2258 priv_caps->i2r_mode(rig, modebuf[1],
2259 mode_len == 2 ? modebuf[2] : -1, mode, width);
2260 }
2261 else /* else call default */
2262 {
2263 icom2rig_mode(rig, modebuf[1],
2264 mode_len == 2 ? modebuf[2] : -1, mode, width);
2265 }
2266
2267 /* IC910H has different meaning of command 1A, subcommand 03. So do
2268 * not ask for DSP filter settings */
2269 /* Likewise, don't ask if we happen to be an Omni VI Plus */
2270 /* Likewise, don't ask if we happen to be an IC-R30 */
2271 /* Likewise, don't ask if we happen to be an IC-706* */
2272 if ((rig->caps->rig_model == RIG_MODEL_IC910) ||
2273 (rig->caps->rig_model == RIG_MODEL_OMNIVIP) ||
2274 (rig->caps->rig_model == RIG_MODEL_IC706) ||
2275 (rig->caps->rig_model == RIG_MODEL_IC706MKII) ||
2276 (rig->caps->rig_model == RIG_MODEL_IC706MKIIG) ||
2277 (rig->caps->rig_model == RIG_MODEL_ICR30))
2278 {
2279 RETURNFUNC(RIG_OK);
2280 }
2281
2282 /* Most rigs RETURNFUNC(1-wide, 2-normal,3-narrow
2283 * For DSP rigs these are presets, can be programmed for 30 - 41 bandwidths, depending on mode.
2284 * Lets check for dsp filters
2285 */
2286
2287 // if we already set width we won't update with except during set_vfo or set_mode
2288 // reason is we can't get width without swapping vfos -- yuck!!
2289 if (vfo & (RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_SUB_A | RIG_VFO_MAIN_A |
2290 RIG_VFO_CURR))
2291 {
2292 // then we get what was asked for
2293 if (vfo == RIG_VFO_NONE && rig->state.current_vfo == RIG_VFO_NONE)
2294 {
2295 rig_debug(RIG_DEBUG_TRACE, "%s(%d): forcing default VFO_A\n", __func__,
2296 __LINE__);
2297 TRACE;
2298 rig_set_vfo(rig, RIG_VFO_A); // force VFOA
2299 }
2300
2301 retval = icom_get_dsp_flt(rig, *mode);
2302 *width = retval;
2303
2304 if (retval == 0)
2305 {
2306 rig_debug(RIG_DEBUG_TRACE,
2307 "%s: vfo=%s returning mode=%s, width not available\n", __func__,
2308 rig_strvfo(vfo), rig_strrmode(*mode));
2309 }
2310 }
2311 else if (rig->state.cache.widthMainB == 0)
2312 {
2313 // we need to swap vfos to get the bandwidth -- yuck
2314 // so we read it once and will let set_mode and transceive capability (4.3 hamlib) update it
2315 vfo_t vfosave = rig->state.current_vfo;
2316
2317 if (vfosave != vfo)
2318 {
2319 // right now forcing VFOA/B arrangement -- reverse not supported yet
2320 // If VFOB width is ever different than VFOA
2321 // we need to figure out how to read VFOB without swapping VFOs
2322 //TRACE;
2323 //rig_set_vfo(rig, RIG_VFO_B);
2324 retval = icom_get_dsp_flt(rig, *mode);
2325 *width = retval;
2326
2327 if (*width == 0) { *width = rig->state.cache.widthMainA; } // we'll use VFOA's width
2328
2329 // dont' really care about cache time here
2330 // this is just to prevent vfo swapping while getting width
2331 rig->state.cache.widthMainB = retval;
2332 rig_debug(RIG_DEBUG_TRACE, "%s(%d): vfosave=%s, currvfo=%s\n", __func__,
2333 __LINE__, rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo));
2334 //TRACE;
2335 //rig_set_vfo(rig, RIG_VFO_A);
2336 rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s returning mode=%s, width=%d\n", __func__,
2337 rig_strvfo(vfo), rig_strrmode(*mode), (int)*width);
2338 }
2339 else
2340 {
2341 rig_debug(RIG_DEBUG_WARN,
2342 "%s: vfo arrangement not supported yet, vfo=%s, currvfo=%s\n", __func__,
2343 rig_strvfo(vfo), rig_strvfo(vfosave));
2344 }
2345 }
2346
2347
2348 RETURNFUNC(RIG_OK);
2349 }
2350
2351 #ifdef XXREMOVEDXX
2352 // not implemented yet
2353 /*
2354 * icom_get_vfo
2355 * The IC-9700 has introduced the ability to see MAIN/SUB selection
2356 * Maybe we'll see this in future ICOMs or firmware upgrades
2357 * Command 0x07 0XD2 -- but as of version 1.05 it doesn't work
2358 * We will, by default, force Main=VFOA and Sub=VFOB, and may want
2359 * an option to not force that behavior
2360 * Assumes rig!=NULL, rig->state.priv!=NULL
2361 */
icom_get_vfo(RIG * rig,vfo_t * vfo)2362 int icom_get_vfo(RIG *rig, vfo_t *vfo)
2363 {
2364 unsigned char ackbuf[MAXFRAMELEN];
2365 int ack_len = sizeof(ackbuf), retval;
2366 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2367
2368 retval = icom_transaction(rig, C_SET_VFO, S_SUB_SEL, NULL, 0,
2369 ackbuf, &ack_len);
2370
2371 if (retval != RIG_OK)
2372 {
2373 RETURNFUNC(retval);
2374 }
2375
2376 if (ack_len != 3)
2377 {
2378 rig_debug(RIG_DEBUG_ERR, "%s wrong frame len=%d\n", __func__, ack_len);
2379 RETURNFUNC(-RIG_ERJCTED);
2380 }
2381
2382 *vfo = ackbuf[2] == 0 ? RIG_VFO_A : RIG_VFO_B;
2383 RETURNFUNC(RIG_OK);
2384 }
2385 #endif
2386
2387 /*
2388 * icom_get_vfo
2389 * Assumes rig!=NULL, rig->state.priv!=NULL
2390 */
icom_set_vfo(RIG * rig,vfo_t vfo)2391 int icom_set_vfo(RIG *rig, vfo_t vfo)
2392 {
2393 unsigned char ackbuf[MAXFRAMELEN];
2394 int ack_len = sizeof(ackbuf), icvfo, retval;
2395 struct rig_state *rs = &rig->state;
2396 struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv;
2397
2398 rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo));
2399
2400 if (vfo == RIG_VFO_CURR)
2401 {
2402 rig_debug(RIG_DEBUG_TRACE, "%s: Asking for currVFO, currVFO=%s\n", __func__,
2403 rig_strvfo(rig->state.current_vfo));
2404 RETURNFUNC(RIG_OK);
2405 }
2406
2407 if (vfo == RIG_VFO_MAIN && VFO_HAS_A_B_ONLY)
2408 {
2409 vfo = RIG_VFO_A;
2410 rig_debug(RIG_DEBUG_TRACE,
2411 "%s: Rig does not have MAIN/SUB so Main changed to %s\n",
2412 __func__, rig_strvfo(vfo));
2413 }
2414 else if ((vfo == RIG_VFO_SUB) && (VFO_HAS_A_B_ONLY
2415 || (VFO_HAS_MAIN_SUB_A_B_ONLY && !priv->split_on && !rig->state.cache.satmode)))
2416 {
2417 // if rig doesn't have Main/Sub
2418 // or if rig has both Main/Sub and A/B -- e.g. 9700
2419 // and we dont' have split or satmode turned on
2420 // then we dont' use Sub -- instead we use Main/VFOB
2421 vfo = RIG_VFO_B;
2422 rig_debug(RIG_DEBUG_TRACE,
2423 "%s: Rig does not have MAIN/SUB so Sub changed to %s\n",
2424 __func__, rig_strvfo(vfo));
2425 }
2426 else if (vfo == RIG_VFO_TX)
2427 {
2428 rig_debug(RIG_DEBUG_TRACE, "%s: vfo line#%d vfo=%s\n", __func__, __LINE__,
2429 rig_strvfo(vfo));
2430 vfo = RIG_VFO_A;
2431
2432 if (VFO_HAS_A_B_ONLY && rig->state.cache.satmode) { vfo = RIG_VFO_B; }
2433 else if (VFO_HAS_MAIN_SUB_ONLY) { vfo = RIG_VFO_SUB; }
2434 else if (VFO_HAS_MAIN_SUB_A_B_ONLY && rig->state.cache.satmode) { vfo = RIG_VFO_SUB; }
2435 }
2436
2437 else if ((vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) && VFO_HAS_DUAL)
2438 {
2439 rig_debug(RIG_DEBUG_TRACE, "%s: vfo line#%d vfo=%s, split=%d\n", __func__,
2440 __LINE__, rig_strvfo(vfo), rig->state.cache.split);
2441 // If we're being asked for A/Main but we are a MainA/MainB rig change it
2442 vfo = RIG_VFO_MAIN;
2443
2444 if (rig->state.cache.split == RIG_SPLIT_ON && !rig->state.cache.satmode) { vfo = RIG_VFO_A; }
2445
2446 // Seems the IC821H reverses Main/Sub when in satmode
2447 if (rig->caps->rig_model == RIG_MODEL_IC821H && rig->state.cache.satmode) { vfo = RIG_VFO_SUB; }
2448 }
2449 else if ((vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) && VFO_HAS_DUAL)
2450 {
2451 rig_debug(RIG_DEBUG_TRACE, "%s: vfo line#%d vfo=%s\n", __func__, __LINE__,
2452 rig_strvfo(vfo));
2453 // If we're being asked for B/Sub but we are a MainA/MainB rig change it
2454 vfo = RIG_VFO_SUB;
2455
2456 // If we're in satmode for rigs like IC9700 we want the 2nd VFO
2457 if (rig->state.cache.satmode)
2458 {
2459 vfo = RIG_VFO_SUB_A;
2460 }
2461 else if (rig->state.cache.split == RIG_SPLIT_ON) { vfo = RIG_VFO_B; }
2462
2463 // Seems the IC821H reverses Main/Sub when in satmode
2464 if (rig->caps->rig_model == RIG_MODEL_IC821H && rig->state.cache.satmode) { vfo = RIG_VFO_MAIN; }
2465 }
2466 else if ((vfo == RIG_VFO_A || vfo == RIG_VFO_B) && !VFO_HAS_A_B
2467 && VFO_HAS_MAIN_SUB)
2468 {
2469 // If we're being asked for A/B but we are a Main/Sub rig change it
2470 vfo_t vfo_old = vfo;
2471 vfo = vfo == RIG_VFO_A ? RIG_VFO_MAIN : RIG_VFO_SUB;
2472 rig_debug(RIG_DEBUG_ERR, "%s: Rig does not have VFO A/B?\n", __func__);
2473 rig_debug(RIG_DEBUG_ERR, "%s: Mapping %s=%s\n", __func__, rig_strvfo(vfo_old),
2474 rig_strvfo(vfo));
2475 }
2476
2477
2478 if ((vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB) && !VFO_HAS_MAIN_SUB)
2479 {
2480 rig_debug(RIG_DEBUG_ERR, "%s: Rig does not have VFO Main/Sub?\n",
2481 __func__);
2482 RETURNFUNC(-RIG_EINVAL);
2483 }
2484
2485 if (vfo != rig->state.current_vfo)
2486 {
2487 rig_debug(RIG_DEBUG_TRACE, "%s: VFO changing from %s to %s\n", __func__,
2488 rig_strvfo(rig->state.current_vfo), rig_strvfo(vfo));
2489 priv->curr_freq = 0; // reset curr_freq so set_freq works 1st time
2490 }
2491
2492 rig_debug(RIG_DEBUG_TRACE, "%s: line#%d\n", __func__, __LINE__);
2493
2494 switch (vfo)
2495 {
2496 case RIG_VFO_A:
2497 icvfo = S_VFOA;
2498 break;
2499
2500 case RIG_VFO_B:
2501 icvfo = S_VFOB;
2502 break;
2503
2504 case RIG_VFO_MAIN:
2505 icvfo = S_MAIN;
2506 break;
2507
2508 case RIG_VFO_SUB:
2509 icvfo = S_SUB;
2510
2511 // If split is on these rigs can only split on Main/VFOB
2512 if (VFO_HAS_MAIN_SUB_A_B_ONLY && priv->split_on) { icvfo = S_VFOB; }
2513
2514 // If not split or satmode then we must want VFOB
2515 if (VFO_HAS_MAIN_SUB_A_B_ONLY && !priv->split_on && !rig->state.cache.satmode) { icvfo = S_VFOB; }
2516
2517 rig_debug(RIG_DEBUG_TRACE, "%s: Sub asked for, ended up with vfo=%s\n",
2518 __func__, icvfo == S_SUB ? "Sub" : "VFOB");
2519
2520 break;
2521
2522 case RIG_VFO_TX:
2523 icvfo = priv->split_on ? S_VFOB : S_VFOA;
2524 vfo = priv->split_on ? RIG_VFO_B : RIG_VFO_A;
2525 rig_debug(RIG_DEBUG_TRACE, "%s: RIG_VFO_TX changing vfo to %s\n", __func__,
2526 rig_strvfo(vfo));
2527 break;
2528
2529 case RIG_VFO_VFO:
2530 retval = icom_transaction(rig, C_SET_VFO, -1, NULL, 0,
2531 ackbuf, &ack_len);
2532
2533 if (retval != RIG_OK)
2534 {
2535 RETURNFUNC(retval);
2536 }
2537
2538 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
2539 {
2540 // if we don't get ACK/NAK some serial corruption occurred
2541 // so we'll call it a timeout for retry purposes
2542 RETURNFUNC(-RIG_ETIMEOUT);
2543 }
2544
2545 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
2546 {
2547 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
2548 ackbuf[0], ack_len);
2549 RETURNFUNC(-RIG_ERJCTED);
2550 }
2551
2552 rig->state.current_vfo = vfo;
2553 RETURNFUNC(RIG_OK);
2554
2555 case RIG_VFO_MEM:
2556 retval = icom_transaction(rig, C_SET_MEM, -1, NULL, 0,
2557 ackbuf, &ack_len);
2558
2559 if (retval != RIG_OK)
2560 {
2561 RETURNFUNC(retval);
2562 }
2563
2564 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
2565 {
2566 // if we don't get ACK/NAK some serial corruption occurred
2567 // so we'll call it a timeout for retry purposes
2568 RETURNFUNC(-RIG_ETIMEOUT);
2569 }
2570
2571 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
2572 {
2573 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
2574 ackbuf[0], ack_len);
2575 RETURNFUNC(-RIG_ERJCTED);
2576 }
2577
2578 rig->state.current_vfo = vfo;
2579 RETURNFUNC(RIG_OK);
2580
2581 case RIG_VFO_MAIN_A: // we need to select Main before setting VFO
2582 case RIG_VFO_MAIN_B:
2583 rig_debug(RIG_DEBUG_VERBOSE, "%s: MainA/B logic\n", __func__);
2584 retval = icom_transaction(rig, C_SET_VFO, S_MAIN, NULL, 0,
2585 ackbuf, &ack_len);
2586
2587 if (retval != RIG_OK)
2588 {
2589 RETURNFUNC(retval);
2590 }
2591
2592 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
2593 {
2594 // if we don't get ACK/NAK some serial corruption occurred
2595 // so we'll call it a timeout for retry purposes
2596 RETURNFUNC(-RIG_ETIMEOUT);
2597 }
2598
2599 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
2600 {
2601 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
2602 ackbuf[0], ack_len);
2603 RETURNFUNC(-RIG_ERJCTED);
2604 }
2605
2606 icvfo = vfo == RIG_VFO_MAIN_A ? S_VFOA : S_VFOB;
2607
2608 break;
2609
2610 case RIG_VFO_SUB_A: // we need to select Sub before setting VFO
2611 case RIG_VFO_SUB_B:
2612 rig_debug(RIG_DEBUG_VERBOSE, "%s: SubA/B logic\n", __func__);
2613 retval = icom_transaction(rig, C_SET_VFO, S_SUB, NULL, 0,
2614 ackbuf, &ack_len);
2615
2616 if (retval != RIG_OK)
2617 {
2618 RETURNFUNC(retval);
2619 }
2620
2621 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
2622 {
2623 // if we don't get ACK/NAK some serial corruption occurred
2624 // so we'll call it a timeout for retry purposes
2625 RETURNFUNC(-RIG_ETIMEOUT);
2626 }
2627
2628 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
2629 {
2630 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
2631 ackbuf[0], ack_len);
2632 RETURNFUNC(-RIG_ERJCTED);
2633 }
2634
2635 // If SUB_A then we'll assume we're done and probably not in sat mode
2636 // If rig has SUB_B active this may be a problem
2637 if (vfo == RIG_VFO_SUB_A) { return RIG_OK; }
2638
2639 icvfo = vfo == RIG_VFO_SUB_A ? S_VFOA : S_VFOB;
2640
2641 break;
2642
2643 default:
2644 rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__,
2645 rig_strvfo(vfo));
2646 RETURNFUNC(-RIG_EINVAL);
2647 }
2648
2649 rig_debug(RIG_DEBUG_TRACE, "%s: line#%d\n", __func__, __LINE__);
2650 retval = icom_transaction(rig, C_SET_VFO, icvfo, NULL, 0,
2651 ackbuf, &ack_len);
2652 rig_debug(RIG_DEBUG_TRACE, "%s: line#%d\n", __func__, __LINE__);
2653
2654 if (retval != RIG_OK)
2655 {
2656 RETURNFUNC(retval);
2657 }
2658
2659 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
2660 {
2661 // if we don't get ACK/NAK some serial corruption occurred
2662 // so we'll call it a timeout for retry purposes
2663 RETURNFUNC(-RIG_ETIMEOUT);
2664 }
2665
2666 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
2667 {
2668 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
2669 ackbuf[0], ack_len);
2670 RETURNFUNC(-RIG_ERJCTED);
2671 }
2672
2673 rig->state.current_vfo = vfo;
2674 rig_debug(RIG_DEBUG_TRACE, "%s: line#%d curr_vfo=%s\n", __func__, __LINE__,
2675 rig_strvfo(rig->state.current_vfo));
2676 RETURNFUNC(RIG_OK);
2677 }
2678
icom_set_cmd(RIG * rig,vfo_t vfo,struct cmdparams * par,value_t val)2679 int icom_set_cmd(RIG *rig, vfo_t vfo, struct cmdparams *par, value_t val)
2680 {
2681 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2682
2683 unsigned char cmdbuf[MAXFRAMELEN];
2684 int cmdlen = 0;
2685 unsigned char ackbuf[MAXFRAMELEN];
2686 int ack_len = 0;
2687
2688 if (!(par->submod & SC_MOD_WR)) { RETURNFUNC(-RIG_EINVAL); }
2689
2690 if ((par->submod & SC_MOD_RW12) == SC_MOD_RW12)
2691 {
2692 cmdbuf[0] = 0x01;
2693 cmdlen = 1;
2694 }
2695 else
2696 {
2697 cmdlen = par->sublen;
2698 memcpy(cmdbuf, par->subext, cmdlen);
2699 }
2700
2701 int wrd = val.i;
2702 int i;
2703
2704 switch (par->dattyp)
2705 {
2706 case CMD_DAT_WRD:
2707 for (i = 1; i <= par->datlen; i++)
2708 {
2709 cmdbuf[cmdlen + par->datlen - i] = wrd & 0xff;
2710 wrd >>= 8;
2711 }
2712
2713 break;
2714
2715 case CMD_DAT_BUF:
2716 memcpy(&cmdbuf[cmdlen], val.b.d, par->datlen);
2717 break;
2718
2719 case CMD_DAT_INT:
2720 case CMD_DAT_BOL:
2721 to_bcd_be(&cmdbuf[cmdlen], val.i, (par->datlen * 2));
2722 break;
2723
2724 case CMD_DAT_FLT:
2725 to_bcd_be(&cmdbuf[cmdlen], (int) val.f, (par->datlen * 2));
2726 break;
2727
2728 case CMD_DAT_LVL:
2729 to_bcd_be(&cmdbuf[cmdlen], (int)(val.f * 255.0), (par->datlen * 2));
2730 break;
2731
2732 case CMD_DAT_TIM: // returned as seconds since midnight
2733 to_bcd_be(&cmdbuf[cmdlen],
2734 ((((int)val.i / 3600) * 100) + (((int)val.i / 60) % 60)), (par->datlen * 2));
2735 break;
2736
2737 default:
2738 break;
2739 }
2740
2741 cmdlen += par->datlen;
2742 RETURNFUNC(icom_transaction(rig, par->command, par->subcmd, cmdbuf, cmdlen,
2743 ackbuf,
2744 &ack_len));
2745 }
2746
icom_get_cmd(RIG * rig,vfo_t vfo,struct cmdparams * par,value_t * val)2747 int icom_get_cmd(RIG *rig, vfo_t vfo, struct cmdparams *par, value_t *val)
2748 {
2749
2750 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2751
2752 unsigned char ssc = 0x02;
2753 unsigned char resbuf[MAXFRAMELEN];
2754 int reslen = sizeof(resbuf);
2755 int retval;
2756
2757 if (!(par->submod & SC_MOD_RD)) { RETURNFUNC(-RIG_EINVAL); }
2758
2759 if ((par->submod & SC_MOD_RW12) == SC_MOD_RW12)
2760 {
2761 retval = icom_get_raw_buf(rig, par->command, par->subcmd, 1, &ssc, &reslen,
2762 resbuf);
2763 }
2764 else
2765 {
2766 retval = icom_get_raw_buf(rig, par->command, par->subcmd,
2767 par->sublen, (unsigned char *)par->subext, &reslen, resbuf);
2768 }
2769
2770 if (retval != RIG_OK)
2771 {
2772 RETURNFUNC(retval);
2773 }
2774
2775 switch (par->dattyp)
2776 {
2777 case CMD_DAT_WRD:
2778 {
2779 int wrd = 0;
2780 int i;
2781
2782 for (i = 0; i < par->datlen; i++)
2783 {
2784 wrd = (wrd << 8) + resbuf[i];
2785 }
2786
2787 val->i = wrd;
2788 }
2789 break;
2790
2791 case CMD_DAT_STR:
2792 if (strlen(val->s) < reslen)
2793 {
2794 RETURNFUNC(-RIG_EINTERNAL);
2795 }
2796
2797 memcpy(val->s, resbuf, reslen);
2798 val->s[reslen] = 0;
2799 break;
2800
2801 case CMD_DAT_BUF:
2802 if (reslen > val->b.l)
2803 {
2804 RETURNFUNC(-RIG_EINTERNAL);
2805 }
2806
2807 memcpy(val->b.d, resbuf, reslen);
2808 val->b.l = reslen;
2809 break;
2810
2811 case CMD_DAT_INT:
2812 val->i = from_bcd_be(resbuf, (reslen * 2));
2813 break;
2814
2815 case CMD_DAT_FLT:
2816 val->f = (float) from_bcd_be(resbuf, (reslen * 2));
2817 break;
2818
2819 case CMD_DAT_LVL:
2820 val->f = (float) from_bcd_be(resbuf, (reslen * 2)) / 255.0;
2821 break;
2822
2823 case CMD_DAT_BOL:
2824 val->i = (from_bcd_be(resbuf, (reslen * 2)) == 0) ? 0 : 1;
2825 break;
2826
2827 case CMD_DAT_TIM:
2828 val->i = (from_bcd_be(resbuf, 2) * 3600) + (from_bcd_be(&resbuf[1], 2) * 60);
2829 break;
2830
2831 default:
2832 val->i = 0;
2833 break;
2834 }
2835
2836 RETURNFUNC(RIG_OK);
2837 }
2838
2839 /*
2840 * icom_set_level
2841 * Assumes rig!=NULL, rig->state.priv!=NULL
2842 */
icom_set_level(RIG * rig,vfo_t vfo,setting_t level,value_t val)2843 int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
2844 {
2845 struct rig_state *rs;
2846 unsigned char cmdbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN];
2847 int cmd_len, ack_len = sizeof(ackbuf);
2848 int lvl_cn, lvl_sc; /* Command Number, Subcommand */
2849 int icom_val;
2850 int i, retval;
2851 const struct icom_priv_caps *priv_caps =
2852 (const struct icom_priv_caps *) rig->caps->priv;
2853
2854 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2855
2856 const struct cmdparams *extcmds = priv_caps->extcmds;
2857
2858 for (i = 0; extcmds && extcmds[i].id.s != 0; i++)
2859 {
2860 if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_LEVEL && extcmds[i].id.s == level)
2861 {
2862 RETURNFUNC(icom_set_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], val));
2863 }
2864 }
2865
2866 rs = &rig->state;
2867
2868 /*
2869 * Many levels of float type are in [0.0..1.0] range
2870 */
2871 if (RIG_LEVEL_IS_FLOAT(level))
2872 {
2873 icom_val = val.f * 255;
2874 }
2875 else
2876 {
2877 icom_val = val.i;
2878 }
2879
2880 /* convert values to 0 .. 255 range */
2881 if (rig->caps->rig_model == RIG_MODEL_ICR75)
2882 {
2883 switch (level)
2884 {
2885 case RIG_LEVEL_NR:
2886 icom_val = val.f * 240;
2887 break;
2888
2889 case RIG_LEVEL_PBT_IN:
2890 case RIG_LEVEL_PBT_OUT:
2891 icom_val = (val.f / 10.0) + 128;
2892
2893 if (icom_val > 255)
2894 {
2895 icom_val = 255;
2896 }
2897
2898 break;
2899
2900 default:
2901 break;
2902 }
2903 }
2904
2905 switch (level)
2906 {
2907 case RIG_LEVEL_KEYSPD:
2908 if (val.i < 6)
2909 {
2910 icom_val = 6;
2911 }
2912 else if (val.i > 48)
2913 {
2914 icom_val = 48;
2915 }
2916
2917 icom_val = (int) lroundf(((float) icom_val - 6.0f) * (255.0f / 42.0f));
2918 break;
2919
2920 case RIG_LEVEL_CWPITCH:
2921 if (val.i < 300)
2922 {
2923 icom_val = 300;
2924 }
2925 else if (val.i >= 900)
2926 {
2927 icom_val = 900;
2928 }
2929
2930 icom_val = (int) lroundf(((float) icom_val - 300) * (255.0f / 600.0f));
2931 break;
2932
2933 default:
2934 break;
2935 }
2936
2937 /*
2938 * Most of the time, the data field is a 3 digit BCD,
2939 * but in *big endian* order: 0000..0255
2940 * (from_bcd is little endian)
2941 */
2942 cmd_len = 2;
2943 to_bcd_be(cmdbuf, (long long) icom_val, cmd_len * 2);
2944
2945 switch (level)
2946 {
2947 case RIG_LEVEL_PREAMP:
2948 lvl_cn = C_CTL_FUNC;
2949 lvl_sc = S_FUNC_PAMP;
2950 cmd_len = 1;
2951
2952 if (val.i == 0)
2953 {
2954 cmdbuf[0] = 0; /* 0=OFF */
2955 break;
2956 }
2957
2958 for (i = 0; i < HAMLIB_MAXDBLSTSIZ; i++)
2959 {
2960 if (rs->preamp[i] == val.i)
2961 {
2962 break;
2963 }
2964 }
2965
2966 if (i == HAMLIB_MAXDBLSTSIZ || rs->preamp[i] == 0)
2967 {
2968 rig_debug(RIG_DEBUG_ERR, "%s: unsupported preamp set_level %ddB\n",
2969 __func__, val.i);
2970 RETURNFUNC(-RIG_EINVAL);
2971 }
2972
2973 cmdbuf[0] = i + 1; /* 1=P.AMP1, 2=P.AMP2 */
2974 break;
2975
2976 case RIG_LEVEL_ATT:
2977 lvl_cn = C_CTL_ATT;
2978 /* attenuator level is dB, in BCD mode */
2979 lvl_sc = (val.i / 10) << 4 | (val.i % 10);
2980 cmd_len = 0;
2981 break;
2982
2983 case RIG_LEVEL_AF:
2984 lvl_cn = C_CTL_LVL;
2985 lvl_sc = S_LVL_AF;
2986 break;
2987
2988 case RIG_LEVEL_RF:
2989 lvl_cn = C_CTL_LVL;
2990 lvl_sc = S_LVL_RF;
2991 break;
2992
2993 case RIG_LEVEL_SQL:
2994 lvl_cn = C_CTL_LVL;
2995 lvl_sc = S_LVL_SQL;
2996 break;
2997
2998 case RIG_LEVEL_IF:
2999 lvl_cn = C_CTL_LVL;
3000 lvl_sc = S_LVL_IF;
3001 break;
3002
3003 case RIG_LEVEL_APF:
3004 lvl_cn = C_CTL_LVL;
3005 lvl_sc = S_LVL_APF;
3006 break;
3007
3008 case RIG_LEVEL_NR:
3009 lvl_cn = C_CTL_LVL;
3010 lvl_sc = S_LVL_NR;
3011 break;
3012
3013 case RIG_LEVEL_NB:
3014 lvl_cn = C_CTL_LVL;
3015 lvl_sc = S_LVL_NB;
3016 break;
3017
3018 case RIG_LEVEL_PBT_IN:
3019 lvl_cn = C_CTL_LVL;
3020 lvl_sc = S_LVL_PBTIN;
3021 break;
3022
3023 case RIG_LEVEL_PBT_OUT:
3024 lvl_cn = C_CTL_LVL;
3025 lvl_sc = S_LVL_PBTOUT;
3026 break;
3027
3028 case RIG_LEVEL_CWPITCH:
3029 lvl_cn = C_CTL_LVL;
3030 lvl_sc = S_LVL_CWPITCH;
3031
3032 /* use 'set mode' call for CWPITCH on IC-R75 */
3033 if (rig->caps->rig_model == RIG_MODEL_ICR75)
3034 {
3035 lvl_cn = C_CTL_MEM;
3036 lvl_sc = S_MEM_MODE_SLCT;
3037 cmd_len = 3;
3038 cmdbuf[0] = S_PRM_CWPITCH;
3039 to_bcd_be(cmdbuf + 1, (long long) icom_val, 4);
3040 }
3041
3042 break;
3043
3044 case RIG_LEVEL_RFPOWER:
3045 lvl_cn = C_CTL_LVL;
3046 lvl_sc = S_LVL_RFPOWER;
3047 break;
3048
3049 case RIG_LEVEL_MICGAIN:
3050 lvl_cn = C_CTL_LVL;
3051 lvl_sc = S_LVL_MICGAIN;
3052 break;
3053
3054 case RIG_LEVEL_KEYSPD:
3055 lvl_cn = C_CTL_LVL;
3056 lvl_sc = S_LVL_KEYSPD;
3057 break;
3058
3059 case RIG_LEVEL_NOTCHF_RAW:
3060 lvl_cn = C_CTL_LVL;
3061 lvl_sc = S_LVL_NOTCHF;
3062 break;
3063
3064 case RIG_LEVEL_COMP:
3065 lvl_cn = C_CTL_LVL;
3066 lvl_sc = S_LVL_COMP;
3067 break;
3068
3069 case RIG_LEVEL_AGC:
3070 lvl_cn = C_CTL_FUNC;
3071 lvl_sc = S_FUNC_AGC;
3072 cmd_len = 1;
3073
3074 if (priv_caps->agc_levels_present)
3075 {
3076 int found = 0;
3077
3078 for (i = 0;
3079 i <= RIG_AGC_LAST && priv_caps->agc_levels[i].level >= 0; i++)
3080 {
3081 if (priv_caps->agc_levels[i].level == val.i)
3082 {
3083 cmdbuf[0] = priv_caps->agc_levels[i].icom_level;
3084 found = 1;
3085 break;
3086 }
3087 }
3088
3089 if (!found)
3090 {
3091 RETURNFUNC(-RIG_EINVAL);
3092 }
3093 }
3094 else
3095 {
3096 // Legacy mapping that does not apply to all rigs
3097 switch (val.i)
3098 {
3099 case RIG_AGC_SLOW:
3100 cmdbuf[0] = D_AGC_SLOW;
3101 break;
3102
3103 case RIG_AGC_MEDIUM:
3104 cmdbuf[0] = D_AGC_MID;
3105 break;
3106
3107 case RIG_AGC_FAST:
3108 cmdbuf[0] = D_AGC_FAST;
3109 break;
3110
3111 case RIG_AGC_SUPERFAST:
3112 cmdbuf[0] = D_AGC_SUPERFAST;
3113 break;
3114
3115 default:
3116 rig_debug(RIG_DEBUG_ERR, "%s: unsupported LEVEL_AGC %d\n",
3117 __func__, val.i);
3118 RETURNFUNC(-RIG_EINVAL);
3119 }
3120 }
3121
3122 break;
3123
3124 case RIG_LEVEL_BKINDL:
3125 lvl_cn = C_CTL_LVL;
3126 lvl_sc = S_LVL_BKINDL;
3127 break;
3128
3129 case RIG_LEVEL_BALANCE:
3130 lvl_cn = C_CTL_LVL;
3131 lvl_sc = S_LVL_BALANCE;
3132 break;
3133
3134 case RIG_LEVEL_VOXGAIN:
3135 if (rig->caps->rig_model == RIG_MODEL_IC910)
3136 {
3137 /* IC-910H */
3138 lvl_cn = C_CTL_MEM;
3139 lvl_sc = S_MEM_VOXGAIN;
3140 }
3141 else
3142 {
3143 lvl_cn = C_CTL_LVL;
3144 lvl_sc = S_LVL_VOXGAIN;
3145 }
3146
3147 break;
3148
3149 case RIG_LEVEL_ANTIVOX:
3150 if (rig->caps->rig_model == RIG_MODEL_IC910)
3151 {
3152 /* IC-910H */
3153 lvl_cn = C_CTL_MEM;
3154 lvl_sc = S_MEM_ANTIVOX;
3155 }
3156 else
3157 {
3158 lvl_cn = C_CTL_LVL;
3159 lvl_sc = S_LVL_ANTIVOX;
3160 }
3161
3162 break;
3163
3164 case RIG_LEVEL_MONITOR_GAIN:
3165 lvl_cn = C_CTL_LVL;
3166 lvl_sc = S_LVL_MON;
3167 break;
3168
3169 case RIG_LEVEL_SPECTRUM_MODE:
3170 lvl_cn = C_CTL_SCP;
3171 lvl_sc = S_SCP_MOD;
3172 cmd_len = 2;
3173
3174 switch (val.i)
3175 {
3176 case RIG_SPECTRUM_MODE_CENTER:
3177 icom_val = SCOPE_MODE_CENTER;
3178 break;
3179
3180 case RIG_SPECTRUM_MODE_FIXED:
3181 icom_val = SCOPE_MODE_FIXED;
3182 break;
3183
3184 case RIG_SPECTRUM_MODE_CENTER_SCROLL:
3185 icom_val = SCOPE_MODE_SCROLL_C;
3186 break;
3187
3188 case RIG_SPECTRUM_MODE_FIXED_SCROLL:
3189 icom_val = SCOPE_MODE_SCROLL_F;
3190 break;
3191
3192 default:
3193 rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum mode %d\n", __func__, val.i);
3194 RETURNFUNC(-RIG_EINVAL);
3195 }
3196
3197 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
3198 cmdbuf[1] = icom_val;
3199 break;
3200
3201 case RIG_LEVEL_SPECTRUM_SPAN:
3202 lvl_cn = C_CTL_SCP;
3203 lvl_sc = S_SCP_SPN;
3204 cmd_len = 6;
3205
3206 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
3207 // Spectrum span is represented as a +/- value for Icom rigs
3208 to_bcd(cmdbuf + 1, val.i / 2, 5 * 2);
3209 break;
3210
3211 case RIG_LEVEL_SPECTRUM_SPEED:
3212 lvl_cn = C_CTL_SCP;
3213 lvl_sc = S_SCP_SWP;
3214 cmd_len = 2;
3215
3216 if (val.i < 0)
3217 {
3218 val.i = 0;
3219 }
3220 else if (val.i > 2)
3221 {
3222 val.i = 2;
3223 }
3224
3225 switch (val.i)
3226 {
3227 case 0:
3228 icom_val = SCOPE_SPEED_SLOW;
3229 break;
3230
3231 case 1:
3232 icom_val = SCOPE_SPEED_MID;
3233 break;
3234
3235 case 2:
3236 icom_val = SCOPE_SPEED_FAST;
3237 break;
3238 }
3239
3240 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
3241 cmdbuf[1] = icom_val;
3242 break;
3243
3244 case RIG_LEVEL_SPECTRUM_REF:
3245 {
3246 float icom_db = (roundf(val.f * 2.0f) / 2.0f) * 100.0f;
3247
3248 lvl_cn = C_CTL_SCP;
3249 lvl_sc = S_SCP_REF;
3250 cmd_len = 4;
3251
3252 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
3253
3254 // Spectrum reference level is represented at 0.01dB accuracy, but needs to be rounded to nearest 0.5dB
3255 to_bcd_be(cmdbuf + 1, abs((int) icom_db), 2 * 2);
3256
3257 // Sign
3258 cmdbuf[3] = (icom_db < 0) ? 1 : 0;
3259 break;
3260 }
3261
3262 case RIG_LEVEL_SPECTRUM_EDGE_LOW:
3263 case RIG_LEVEL_SPECTRUM_EDGE_HIGH:
3264 {
3265 int range_id;
3266 value_t edge_number_value;
3267 value_t opposite_edge_value;
3268 setting_t level_opposite_edge =
3269 (level == RIG_LEVEL_SPECTRUM_EDGE_LOW) ?
3270 RIG_LEVEL_SPECTRUM_EDGE_HIGH : RIG_LEVEL_SPECTRUM_EDGE_LOW;
3271
3272 lvl_cn = C_CTL_SCP;
3273 lvl_sc = S_SCP_FEF;
3274 cmd_len = 12;
3275
3276 // Modify the frequency range currently active
3277 retval = icom_get_spectrum_edge_frequency_range(rig, vfo, &range_id);
3278
3279 if (retval != RIG_OK)
3280 {
3281 rig_debug(RIG_DEBUG_ERR, "%s: error getting spectrum edge frequency range\n",
3282 __func__);
3283 RETURNFUNC(retval);
3284 }
3285
3286 // Modify the edge number currently active
3287 retval = icom_get_ext_level(rig, vfo, TOK_SCOPE_EDG, &edge_number_value);
3288
3289 if (retval != RIG_OK)
3290 {
3291 RETURNFUNC(retval);
3292 }
3293
3294 // Get the current opposite edge frequency
3295 retval = icom_get_level(rig, vfo, level_opposite_edge, &opposite_edge_value);
3296
3297 if (retval != RIG_OK)
3298 {
3299 RETURNFUNC(retval);
3300 }
3301
3302 to_bcd(cmdbuf, range_id, 1 * 2);
3303 to_bcd(cmdbuf + 1, edge_number_value.i + 1, 1 * 2);
3304
3305 if (level == RIG_LEVEL_SPECTRUM_EDGE_LOW)
3306 {
3307 to_bcd(cmdbuf + 2, val.i, 5 * 2);
3308 to_bcd(cmdbuf + 7, opposite_edge_value.i, 5 * 2);
3309 }
3310 else
3311 {
3312 to_bcd(cmdbuf + 2, opposite_edge_value.i, 5 * 2);
3313 to_bcd(cmdbuf + 7, val.i, 5 * 2);
3314 }
3315
3316 break;
3317 }
3318
3319 case RIG_LEVEL_SPECTRUM_ATT:
3320 lvl_cn = C_CTL_SCP;
3321 lvl_sc = S_SCP_ATT;
3322 cmd_len = 2;
3323
3324 for (i = 0; i < HAMLIB_MAXDBLSTSIZ; i++)
3325 {
3326 if (rig->caps->spectrum_attenuator[i] == val.i)
3327 {
3328 break;
3329 }
3330 }
3331
3332 if (val.i != 0 && (i == HAMLIB_MAXDBLSTSIZ
3333 || rig->caps->spectrum_attenuator[i] == 0))
3334 {
3335 rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum attenuator level %ddB\n",
3336 __func__, val.i);
3337 RETURNFUNC(-RIG_EINVAL);
3338 }
3339
3340 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
3341 to_bcd(cmdbuf + 1, val.i, 5 * 2);
3342 break;
3343
3344 default:
3345 rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__,
3346 rig_strlevel(level));
3347 RETURNFUNC(-RIG_EINVAL);
3348 }
3349
3350 retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, ackbuf,
3351 &ack_len);
3352
3353 if (retval != RIG_OK)
3354 {
3355 RETURNFUNC(retval);
3356 }
3357
3358 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
3359 {
3360 // if we don't get ACK/NAK some serial corruption occurred
3361 // so we'll call it a timeout for retry purposes
3362 RETURNFUNC(-RIG_ETIMEOUT);
3363 }
3364
3365 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
3366 {
3367 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
3368 ackbuf[0], ack_len);
3369 RETURNFUNC(-RIG_ERJCTED);
3370 }
3371
3372 RETURNFUNC(RIG_OK);
3373 }
3374
3375 /*
3376 * icom_get_level
3377 * Assumes rig!=NULL, rig->state.priv!=NULL, val!=NULL
3378 *
3379 */
icom_get_level(RIG * rig,vfo_t vfo,setting_t level,value_t * val)3380 int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
3381 {
3382 struct rig_state *rs;
3383 unsigned char cmdbuf[MAXFRAMELEN], respbuf[MAXFRAMELEN];
3384 int cmd_len, resp_len;
3385 int lvl_cn, lvl_sc; /* Command Number, Subcommand */
3386 int icom_val;
3387 int cmdhead;
3388 int retval;
3389 const struct icom_priv_caps *priv_caps =
3390 (const struct icom_priv_caps *) rig->caps->priv;
3391
3392 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
3393
3394 const struct cmdparams *extcmds = priv_caps->extcmds;
3395 int i;
3396
3397 for (i = 0; extcmds && extcmds[i].id.s != 0; i++)
3398 {
3399 rig_debug(RIG_DEBUG_TRACE, "%s: i=%d\n", __func__, i);
3400
3401 if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_LEVEL && extcmds[i].id.s == level)
3402 {
3403 RETURNFUNC(icom_get_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], val));
3404 }
3405 }
3406
3407 rig_debug(RIG_DEBUG_TRACE, "%s: no extcmd found\n", __func__);
3408
3409 rs = &rig->state;
3410
3411 cmd_len = 0;
3412
3413 switch (level)
3414 {
3415 case RIG_LEVEL_STRENGTH:
3416 case RIG_LEVEL_RAWSTR:
3417 lvl_cn = C_RD_SQSM;
3418 lvl_sc = S_SML;
3419 break;
3420
3421 case RIG_LEVEL_ALC:
3422 lvl_cn = C_RD_SQSM;
3423 lvl_sc = S_ALC;
3424 break;
3425
3426 case RIG_LEVEL_SWR:
3427 lvl_cn = C_RD_SQSM;
3428 lvl_sc = S_SWR;
3429 break;
3430
3431 case RIG_LEVEL_RFPOWER_METER:
3432 case RIG_LEVEL_RFPOWER_METER_WATTS:
3433 lvl_cn = C_RD_SQSM;
3434 lvl_sc = S_RFML;
3435 break;
3436
3437 case RIG_LEVEL_COMP_METER:
3438 lvl_cn = C_RD_SQSM;
3439 lvl_sc = S_CMP;
3440 break;
3441
3442 case RIG_LEVEL_VD_METER:
3443 lvl_cn = C_RD_SQSM;
3444 lvl_sc = S_VD;
3445 break;
3446
3447 case RIG_LEVEL_ID_METER:
3448 lvl_cn = C_RD_SQSM;
3449 lvl_sc = S_ID;
3450 break;
3451
3452 case RIG_LEVEL_PREAMP:
3453 lvl_cn = C_CTL_FUNC;
3454 lvl_sc = S_FUNC_PAMP;
3455 break;
3456
3457 case RIG_LEVEL_ATT:
3458 lvl_cn = C_CTL_ATT;
3459 lvl_sc = -1;
3460 break;
3461
3462 case RIG_LEVEL_AF:
3463 lvl_cn = C_CTL_LVL;
3464 lvl_sc = S_LVL_AF;
3465 break;
3466
3467 case RIG_LEVEL_RF:
3468 lvl_cn = C_CTL_LVL;
3469 lvl_sc = S_LVL_RF;
3470 break;
3471
3472 case RIG_LEVEL_SQL:
3473 lvl_cn = C_CTL_LVL;
3474 lvl_sc = S_LVL_SQL;
3475 break;
3476
3477 case RIG_LEVEL_IF:
3478 lvl_cn = C_CTL_LVL;
3479 lvl_sc = S_LVL_IF;
3480 break;
3481
3482 case RIG_LEVEL_APF:
3483 lvl_cn = C_CTL_LVL;
3484 lvl_sc = S_LVL_APF;
3485 break;
3486
3487 case RIG_LEVEL_NR:
3488 lvl_cn = C_CTL_LVL;
3489 lvl_sc = S_LVL_NR;
3490 break;
3491
3492 case RIG_LEVEL_NB:
3493 lvl_cn = C_CTL_LVL;
3494 lvl_sc = S_LVL_NB;
3495 break;
3496
3497 case RIG_LEVEL_PBT_IN:
3498 lvl_cn = C_CTL_LVL;
3499 lvl_sc = S_LVL_PBTIN;
3500 break;
3501
3502 case RIG_LEVEL_PBT_OUT:
3503 lvl_cn = C_CTL_LVL;
3504 lvl_sc = S_LVL_PBTOUT;
3505 break;
3506
3507 case RIG_LEVEL_CWPITCH:
3508 lvl_cn = C_CTL_LVL;
3509 lvl_sc = S_LVL_CWPITCH;
3510
3511 /* use 'set mode' call for CWPITCH on IC-R75 */
3512 if (rig->caps->rig_model == RIG_MODEL_ICR75)
3513 {
3514 lvl_cn = C_CTL_MEM;
3515 lvl_sc = S_MEM_MODE_SLCT;
3516 cmd_len = 1;
3517 cmdbuf[0] = S_PRM_CWPITCH;
3518 }
3519
3520 break;
3521
3522 case RIG_LEVEL_RFPOWER:
3523 lvl_cn = C_CTL_LVL;
3524 lvl_sc = S_LVL_RFPOWER;
3525 break;
3526
3527 case RIG_LEVEL_MICGAIN:
3528 lvl_cn = C_CTL_LVL;
3529 lvl_sc = S_LVL_MICGAIN;
3530 break;
3531
3532 case RIG_LEVEL_KEYSPD:
3533 lvl_cn = C_CTL_LVL;
3534 lvl_sc = S_LVL_KEYSPD;
3535 break;
3536
3537 case RIG_LEVEL_NOTCHF_RAW:
3538 lvl_cn = C_CTL_LVL;
3539 lvl_sc = S_LVL_NOTCHF;
3540 break;
3541
3542 case RIG_LEVEL_COMP:
3543 lvl_cn = C_CTL_LVL;
3544 lvl_sc = S_LVL_COMP;
3545 break;
3546
3547 case RIG_LEVEL_AGC:
3548 lvl_cn = C_CTL_FUNC;
3549 lvl_sc = S_FUNC_AGC;
3550 break;
3551
3552 case RIG_LEVEL_BKINDL:
3553 lvl_cn = C_CTL_LVL;
3554 lvl_sc = S_LVL_BKINDL;
3555 break;
3556
3557 case RIG_LEVEL_BALANCE:
3558 lvl_cn = C_CTL_LVL;
3559 lvl_sc = S_LVL_BALANCE;
3560 break;
3561
3562 case RIG_LEVEL_VOXGAIN: /* IC-910H */
3563 if (rig->caps->rig_model == RIG_MODEL_IC910)
3564 {
3565 /* IC-910H */
3566 lvl_cn = C_CTL_MEM;
3567 lvl_sc = S_MEM_VOXGAIN;
3568 }
3569 else
3570 {
3571 lvl_cn = C_CTL_LVL;
3572 lvl_sc = S_LVL_VOXGAIN;
3573 }
3574
3575 break;
3576
3577 case RIG_LEVEL_ANTIVOX:
3578 if (rig->caps->rig_model == RIG_MODEL_IC910)
3579 {
3580 /* IC-910H */
3581 lvl_cn = C_CTL_MEM;
3582 lvl_sc = S_MEM_ANTIVOX;
3583 }
3584 else
3585 {
3586 lvl_cn = C_CTL_LVL;
3587 lvl_sc = S_LVL_ANTIVOX;
3588 }
3589
3590 break;
3591
3592 case RIG_LEVEL_MONITOR_GAIN:
3593 lvl_cn = C_CTL_LVL;
3594 lvl_sc = S_LVL_MON;
3595 break;
3596
3597 case RIG_LEVEL_SPECTRUM_MODE:
3598 lvl_cn = C_CTL_SCP;
3599 lvl_sc = S_SCP_MOD;
3600 cmd_len = 1;
3601 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
3602 break;
3603
3604 case RIG_LEVEL_SPECTRUM_SPAN:
3605 lvl_cn = C_CTL_SCP;
3606 lvl_sc = S_SCP_SPN;
3607
3608 cmd_len = 1;
3609 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
3610 break;
3611
3612 case RIG_LEVEL_SPECTRUM_SPEED:
3613 lvl_cn = C_CTL_SCP;
3614 lvl_sc = S_SCP_SWP;
3615
3616 cmd_len = 1;
3617 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
3618 break;
3619
3620 case RIG_LEVEL_SPECTRUM_REF:
3621 lvl_cn = C_CTL_SCP;
3622 lvl_sc = S_SCP_REF;
3623
3624 cmd_len = 1;
3625 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
3626 break;
3627
3628 case RIG_LEVEL_SPECTRUM_EDGE_LOW:
3629 case RIG_LEVEL_SPECTRUM_EDGE_HIGH:
3630 {
3631 int range_id;
3632 value_t edge_number_value;
3633
3634 lvl_cn = C_CTL_SCP;
3635 lvl_sc = S_SCP_FEF;
3636 cmd_len = 2;
3637
3638 // Get the frequency range currently active
3639 retval = icom_get_spectrum_edge_frequency_range(rig, vfo, &range_id);
3640
3641 if (retval != RIG_OK)
3642 {
3643 rig_debug(RIG_DEBUG_ERR, "%s: error getting spectrum edge frequency range\n",
3644 __func__);
3645 RETURNFUNC(retval);
3646 }
3647
3648 // Get the edge number currently active
3649 retval = icom_get_ext_level(rig, vfo, TOK_SCOPE_EDG, &edge_number_value);
3650
3651 if (retval != RIG_OK)
3652 {
3653 RETURNFUNC(retval);
3654 }
3655
3656 to_bcd(cmdbuf, range_id, 1 * 2);
3657 to_bcd(cmdbuf + 1, edge_number_value.i + 1, 1 * 2);
3658 break;
3659 }
3660
3661 case RIG_LEVEL_SPECTRUM_ATT:
3662 lvl_cn = C_CTL_SCP;
3663 lvl_sc = S_SCP_ATT;
3664 cmd_len = 1;
3665
3666 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
3667 break;
3668
3669 default:
3670 rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s\n", __func__,
3671 rig_strlevel(level));
3672 RETURNFUNC(-RIG_EINVAL);
3673 }
3674
3675 /* use cmdbuf and cmd_len for 'set mode' subcommand */
3676 retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, respbuf,
3677 &resp_len);
3678
3679 if (retval != RIG_OK)
3680 {
3681 RETURNFUNC(retval);
3682 }
3683
3684 /*
3685 * strbuf should contain Cn,Sc,Data area
3686 */
3687 cmdhead = ((lvl_sc == -1) ? 1 : 2) + cmd_len;
3688 resp_len -= cmdhead;
3689
3690 if (respbuf[0] != lvl_cn)
3691 {
3692 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
3693 respbuf[0], resp_len);
3694 RETURNFUNC(-RIG_ERJCTED);
3695 }
3696
3697 /*
3698 * The result is a 3 digit BCD, but in *big endian* order: 0000..0255
3699 * (from_bcd is little endian)
3700 */
3701 icom_val = from_bcd_be(respbuf + cmdhead, resp_len * 2);
3702
3703 switch (level)
3704 {
3705 case RIG_LEVEL_STRENGTH:
3706 val->i = round(rig_raw2val(icom_val, &rig->caps->str_cal));
3707 break;
3708
3709 case RIG_LEVEL_RAWSTR:
3710 /* raw value */
3711 val->i = icom_val;
3712 break;
3713
3714 case RIG_LEVEL_AGC:
3715 if (priv_caps->agc_levels_present)
3716 {
3717 int found = 0;
3718
3719 for (i = 0;
3720 i <= RIG_AGC_LAST && priv_caps->agc_levels[i].level >= 0; i++)
3721 {
3722 if (priv_caps->agc_levels[i].icom_level == icom_val)
3723 {
3724 val->i = priv_caps->agc_levels[i].level;
3725 found = 1;
3726 break;
3727 }
3728 }
3729
3730 if (!found)
3731 {
3732 rig_debug(RIG_DEBUG_ERR, "%s: unexpected AGC 0x%02x\n", __func__,
3733 icom_val);
3734 RETURNFUNC(-RIG_EPROTO);
3735 }
3736 }
3737 else
3738 {
3739 switch (icom_val)
3740 {
3741 case D_AGC_SLOW:
3742 val->i = RIG_AGC_SLOW;
3743 break;
3744
3745 case D_AGC_MID:
3746 val->i = RIG_AGC_MEDIUM;
3747 break;
3748
3749 case D_AGC_FAST:
3750 val->i = RIG_AGC_FAST;
3751 break;
3752
3753 case D_AGC_SUPERFAST:
3754 val->i = RIG_AGC_SUPERFAST;
3755 break;
3756
3757 default:
3758 rig_debug(RIG_DEBUG_ERR, "%s: unexpected AGC 0x%02x\n", __func__,
3759 icom_val);
3760 RETURNFUNC(-RIG_EPROTO);
3761 }
3762 }
3763
3764 break;
3765
3766 case RIG_LEVEL_ALC:
3767 if (rig->caps->alc_cal.size == 0)
3768 {
3769 val->f = rig_raw2val_float(icom_val, &icom_default_alc_cal);
3770 }
3771 else
3772 {
3773 val->f = rig_raw2val_float(icom_val, &rig->caps->alc_cal);
3774 }
3775
3776 break;
3777
3778 case RIG_LEVEL_SWR:
3779 if (rig->caps->swr_cal.size == 0)
3780 {
3781 val->f = rig_raw2val_float(icom_val, &icom_default_swr_cal);
3782 }
3783 else
3784 {
3785 val->f = rig_raw2val_float(icom_val, &rig->caps->swr_cal);
3786 }
3787
3788 break;
3789
3790 case RIG_LEVEL_RFPOWER_METER:
3791
3792 // rig table in Watts needs to be divided by 100
3793 if (rig->caps->rfpower_meter_cal.size == 0)
3794 {
3795 val->f =
3796 rig_raw2val_float(icom_val, &icom_default_rfpower_meter_cal) * 0.01;
3797 }
3798 else
3799 {
3800 val->f =
3801 rig_raw2val_float(icom_val, &rig->caps->rfpower_meter_cal) * 0.01;
3802 }
3803
3804 break;
3805
3806 case RIG_LEVEL_RFPOWER_METER_WATTS:
3807
3808 // All Icom backends should be in Watts now
3809 if (rig->caps->rfpower_meter_cal.size == 0)
3810 {
3811 val->f =
3812 rig_raw2val_float(icom_val, &icom_default_rfpower_meter_cal);
3813 rig_debug(RIG_DEBUG_TRACE, "%s: using rig table to convert %d to %.01f\n",
3814 __func__, icom_val, val->f);
3815 }
3816 else
3817 {
3818 val->f =
3819 rig_raw2val_float(icom_val, &rig->caps->rfpower_meter_cal);
3820 rig_debug(RIG_DEBUG_TRACE,
3821 "%s: using default icom table to convert %d to %.01f\n", __func__, icom_val,
3822 val->f);
3823 }
3824
3825 break;
3826
3827 case RIG_LEVEL_COMP_METER:
3828 if (rig->caps->comp_meter_cal.size == 0)
3829 {
3830 val->f = rig_raw2val_float(icom_val, &icom_default_comp_meter_cal);
3831 }
3832 else
3833 {
3834 val->f = rig_raw2val_float(icom_val, &rig->caps->comp_meter_cal);
3835 }
3836
3837 break;
3838
3839 case RIG_LEVEL_VD_METER:
3840 if (rig->caps->vd_meter_cal.size == 0)
3841 {
3842 val->f = rig_raw2val_float(icom_val, &icom_default_vd_meter_cal);
3843 }
3844 else
3845 {
3846 val->f = rig_raw2val_float(icom_val, &rig->caps->vd_meter_cal);
3847 }
3848
3849 break;
3850
3851 case RIG_LEVEL_ID_METER:
3852 if (rig->caps->id_meter_cal.size == 0)
3853 {
3854 val->f = rig_raw2val_float(icom_val, &icom_default_id_meter_cal);
3855 }
3856 else
3857 {
3858 val->f = rig_raw2val_float(icom_val, &rig->caps->id_meter_cal);
3859 }
3860
3861 break;
3862
3863 case RIG_LEVEL_CWPITCH:
3864 val->i = (int) lroundf(300.0f + ((float) icom_val * 600.0f / 255.0f));
3865 break;
3866
3867 case RIG_LEVEL_KEYSPD:
3868 val->i = (int) lroundf((float) icom_val * (42.0f / 255.0f) + 6.0f);
3869 break;
3870
3871 case RIG_LEVEL_PREAMP:
3872 if (icom_val == 0)
3873 {
3874 val->i = 0;
3875 break;
3876 }
3877
3878 if (icom_val > HAMLIB_MAXDBLSTSIZ || rs->preamp[icom_val - 1] == 0)
3879 {
3880 rig_debug(RIG_DEBUG_ERR, "%s: unsupported preamp get_level %ddB\n",
3881 __func__, icom_val);
3882 RETURNFUNC(-RIG_EPROTO);
3883 }
3884
3885 val->i = rs->preamp[icom_val - 1];
3886 break;
3887
3888 case RIG_LEVEL_SPECTRUM_MODE:
3889 switch (icom_val)
3890 {
3891 case SCOPE_MODE_CENTER:
3892 val->i = RIG_SPECTRUM_MODE_CENTER;
3893 break;
3894
3895 case SCOPE_MODE_FIXED:
3896 val->i = RIG_SPECTRUM_MODE_FIXED;
3897 break;
3898
3899 case SCOPE_MODE_SCROLL_C:
3900 val->i = RIG_SPECTRUM_MODE_CENTER_SCROLL;
3901 break;
3902
3903 case SCOPE_MODE_SCROLL_F:
3904 val->i = RIG_SPECTRUM_MODE_FIXED_SCROLL;
3905 break;
3906
3907 default:
3908 rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum mode %d\n", __func__,
3909 icom_val);
3910 RETURNFUNC(-RIG_EINVAL);
3911 }
3912
3913 break;
3914
3915 case RIG_LEVEL_SPECTRUM_SPAN:
3916 icom_val = (int) from_bcd(respbuf + cmdhead, resp_len * 2);
3917 // Spectrum span is represented as a +/- value for Icom rigs
3918 val->i = icom_val * 2;
3919 break;
3920
3921 case RIG_LEVEL_SPECTRUM_SPEED:
3922 switch (icom_val)
3923 {
3924 case SCOPE_SPEED_SLOW:
3925 val->i = 0;
3926 break;
3927
3928 case SCOPE_SPEED_MID:
3929 val->i = 1;
3930 break;
3931
3932 case SCOPE_SPEED_FAST:
3933 val->i = 2;
3934 break;
3935
3936 default:
3937 rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum speed %d\n", __func__,
3938 icom_val);
3939 RETURNFUNC(-RIG_EINVAL);
3940 }
3941
3942 break;
3943
3944 case RIG_LEVEL_SPECTRUM_REF:
3945 {
3946 unsigned char *icom_ref = respbuf + cmdhead;
3947
3948 // Spectrum reference level is represented at 0.01dB accuracy, but is rounded to nearest 0.5dB
3949 float db = (float) from_bcd_be(icom_ref, 2 * 2) / 100.0f;
3950
3951 // Sign
3952 if (icom_ref[2] != 0)
3953 {
3954 db = -db;
3955 }
3956
3957 val->f = db;
3958 break;
3959 }
3960
3961 case RIG_LEVEL_SPECTRUM_EDGE_LOW:
3962 val->i = (int) from_bcd(respbuf + cmdhead, 5 * 2);
3963 break;
3964
3965 case RIG_LEVEL_SPECTRUM_EDGE_HIGH:
3966 val->i = (int) from_bcd(respbuf + cmdhead + 5, 5 * 2);
3967 break;
3968
3969 /* RIG_LEVEL_ATT/RIG_LEVEL_SPECTRUM_ATT: returned value is already an integer in dB (coded in BCD) */
3970 default:
3971 if (RIG_LEVEL_IS_FLOAT(level))
3972 {
3973 val->f = (float) icom_val / 255;
3974 }
3975 else
3976 {
3977 val->i = icom_val;
3978 }
3979 }
3980
3981 /* convert values from 0 .. 255 range */
3982 if (rig->caps->rig_model == RIG_MODEL_ICR75)
3983 {
3984 switch (level)
3985 {
3986 case RIG_LEVEL_NR:
3987 val->f = (float) icom_val / 240;
3988 break;
3989
3990 case RIG_LEVEL_PBT_IN:
3991 case RIG_LEVEL_PBT_OUT:
3992 if (icom_val == 255)
3993 {
3994 val->f = 1280.0;
3995 }
3996 else
3997 {
3998 val->f = (float)(icom_val - 128) * 10.0;
3999 }
4000
4001 break;
4002
4003 default:
4004 break;
4005 }
4006 }
4007
4008 rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, resp_len,
4009 icom_val, val->i, val->f);
4010
4011 RETURNFUNC(RIG_OK);
4012 }
4013
icom_set_ext_level(RIG * rig,vfo_t vfo,token_t token,value_t val)4014 int icom_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val)
4015 {
4016 const struct confparams *cfp = rig->caps->extlevels;
4017 unsigned char cmdbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN];
4018 int cmd_len, ack_len = sizeof(ackbuf);
4019 int lvl_cn, lvl_sc; /* Command Number, Subcommand */
4020 int i, retval;
4021
4022 rig_debug(RIG_DEBUG_VERBOSE, "%s called: token=%ld int=%d float=%f\n", __func__,
4023 token, val.i, val.f);
4024
4025 switch (token)
4026 {
4027 case TOK_SCOPE_MSS:
4028 if (val.i < 0 || val.i > 1)
4029 {
4030 RETURNFUNC(-RIG_EINVAL);
4031 }
4032
4033 lvl_cn = C_CTL_SCP;
4034 lvl_sc = S_SCP_MSS;
4035 cmd_len = 1;
4036 cmdbuf[0] = val.i;
4037 break;
4038
4039 case TOK_SCOPE_SDS:
4040 if (val.i < 0 || val.i > 1)
4041 {
4042 RETURNFUNC(-RIG_EINVAL);
4043 }
4044
4045 lvl_cn = C_CTL_SCP;
4046 lvl_sc = S_SCP_SDS;
4047 cmd_len = 1;
4048 cmdbuf[0] = val.i;
4049 break;
4050
4051 case TOK_SCOPE_STX:
4052
4053 // TODO: Should be a func?
4054 if (val.i < 0 || val.i > 1)
4055 {
4056 RETURNFUNC(-RIG_EINVAL);
4057 }
4058
4059 lvl_cn = C_CTL_SCP;
4060 lvl_sc = S_SCP_STX;
4061 cmd_len = 1;
4062 cmdbuf[0] = val.i;
4063 break;
4064
4065 case TOK_SCOPE_CFQ:
4066 if (val.i < 0 || val.i > 2)
4067 {
4068 RETURNFUNC(-RIG_EINVAL);
4069 }
4070
4071 lvl_cn = C_CTL_SCP;
4072 lvl_sc = S_SCP_CFQ;
4073 cmd_len = 1;
4074 cmdbuf[0] = val.i;
4075 break;
4076
4077 case TOK_SCOPE_EDG:
4078 if (val.i < 0 || val.i > 3)
4079 {
4080 RETURNFUNC(-RIG_EINVAL);
4081 }
4082
4083 lvl_cn = C_CTL_SCP;
4084 lvl_sc = S_SCP_EDG;
4085 cmd_len = 2;
4086 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
4087 cmdbuf[1] = val.i + 1;
4088 break;
4089
4090 case TOK_SCOPE_VBW:
4091 if (val.i < 0 || val.i > 1)
4092 {
4093 RETURNFUNC(-RIG_EINVAL);
4094 }
4095
4096 lvl_cn = C_CTL_SCP;
4097 lvl_sc = S_SCP_VBW;
4098 cmd_len = 2;
4099 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
4100 cmdbuf[1] = val.i;
4101 break;
4102
4103 case TOK_SCOPE_RBW:
4104 if (val.i < 0 || val.i > 2)
4105 {
4106 RETURNFUNC(-RIG_EINVAL);
4107 }
4108
4109 lvl_cn = C_CTL_SCP;
4110 lvl_sc = S_SCP_RBW;
4111 cmd_len = 2;
4112 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
4113 cmdbuf[1] = val.i;
4114 break;
4115
4116 default:
4117 cfp = (cfp == NULL) ? icom_ext_levels : cfp;
4118
4119 for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_levels);)
4120 {
4121 if (cfp[i].token == RIG_CONF_END)
4122 {
4123 cfp = icom_ext_levels;
4124 i = 0;
4125 }
4126 else if (cfp[i].token == token)
4127 {
4128 RETURNFUNC(icom_set_ext_cmd(rig, vfo, token, val));
4129 }
4130 else { i++; }
4131 }
4132
4133 rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_ext_level token: %ld\n", __func__,
4134 token);
4135 RETURNFUNC(-RIG_EINVAL);
4136 }
4137
4138 retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, ackbuf,
4139 &ack_len);
4140
4141 if (retval != RIG_OK)
4142 {
4143 RETURNFUNC(retval);
4144 }
4145
4146 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
4147 {
4148 // if we don't get ACK/NAK some serial corruption occurred
4149 // so we'll call it a timeout for retry purposes
4150 RETURNFUNC(-RIG_ETIMEOUT);
4151 }
4152
4153 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
4154 {
4155 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
4156 ackbuf[0], ack_len);
4157 RETURNFUNC(-RIG_ERJCTED);
4158 }
4159
4160 RETURNFUNC(RIG_OK);
4161 }
4162
icom_get_ext_level(RIG * rig,vfo_t vfo,token_t token,value_t * val)4163 int icom_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val)
4164 {
4165 const struct confparams *cfp = rig->caps->extlevels;
4166 unsigned char cmdbuf[MAXFRAMELEN], respbuf[MAXFRAMELEN];
4167 int cmd_len, resp_len;
4168 int lvl_cn, lvl_sc; /* Command Number, Subcommand */
4169 int icom_val;
4170 int cmdhead;
4171 int retval;
4172 int i;
4173
4174 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4175
4176 cmd_len = 0;
4177 lvl_sc = -1;
4178
4179 switch (token)
4180 {
4181 case TOK_SCOPE_MSS:
4182 lvl_cn = C_CTL_SCP;
4183 lvl_sc = S_SCP_MSS;
4184 break;
4185
4186 case TOK_SCOPE_SDS:
4187 lvl_cn = C_CTL_SCP;
4188 lvl_sc = S_SCP_SDS;
4189 break;
4190
4191 case TOK_SCOPE_STX:
4192 // TODO: Should be a func?
4193 lvl_cn = C_CTL_SCP;
4194 lvl_sc = S_SCP_STX;
4195 break;
4196
4197 case TOK_SCOPE_CFQ:
4198 lvl_cn = C_CTL_SCP;
4199 lvl_sc = S_SCP_CFQ;
4200 break;
4201
4202 case TOK_SCOPE_EDG:
4203 lvl_cn = C_CTL_SCP;
4204 lvl_sc = S_SCP_EDG;
4205 cmd_len = 1;
4206 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
4207 break;
4208
4209 case TOK_SCOPE_VBW:
4210 lvl_cn = C_CTL_SCP;
4211 lvl_sc = S_SCP_VBW;
4212 cmd_len = 1;
4213 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
4214 break;
4215
4216 case TOK_SCOPE_RBW:
4217 lvl_cn = C_CTL_SCP;
4218 lvl_sc = S_SCP_RBW;
4219 cmd_len = 1;
4220 cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo);
4221 break;
4222
4223 default:
4224 cfp = (cfp == NULL) ? icom_ext_levels : cfp;
4225
4226 for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_levels);)
4227 {
4228 if (cfp[i].token == RIG_CONF_END)
4229 {
4230 cfp = icom_ext_levels;
4231 i = 0;
4232 }
4233 else if (cfp[i].token == token)
4234 {
4235 RETURNFUNC(icom_get_ext_cmd(rig, vfo, token, val));
4236 }
4237 else { i++; }
4238 }
4239
4240 rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_ext_level token: %ld\n", __func__,
4241 token);
4242 RETURNFUNC(-RIG_EINVAL);
4243 }
4244
4245 /* use cmdbuf and cmd_len for 'set mode' subcommand */
4246 retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, respbuf,
4247 &resp_len);
4248
4249 if (retval != RIG_OK)
4250 {
4251 RETURNFUNC(retval);
4252 }
4253
4254 cmdhead = ((lvl_sc == -1) ? 1 : 2) + cmd_len;
4255 resp_len -= cmdhead;
4256
4257 if (respbuf[0] != lvl_cn)
4258 {
4259 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
4260 respbuf[0], resp_len);
4261 RETURNFUNC(-RIG_ERJCTED);
4262 }
4263
4264 icom_val = from_bcd_be(respbuf + cmdhead, resp_len * 2);
4265
4266 switch (token)
4267 {
4268 case TOK_SCOPE_EDG:
4269 val->i = icom_val - 1;
4270 break;
4271
4272 default:
4273 val->i = icom_val;
4274 break;
4275 }
4276
4277 rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, resp_len,
4278 icom_val, val->i, val->f);
4279
4280 RETURNFUNC(RIG_OK);
4281 }
4282
icom_set_ext_func(RIG * rig,vfo_t vfo,token_t token,int status)4283 int icom_set_ext_func(RIG *rig, vfo_t vfo, token_t token, int status)
4284 {
4285 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4286
4287 const struct confparams *cfp = rig->caps->extfuncs;
4288 cfp = (cfp == NULL) ? icom_ext_funcs : cfp;
4289 int i;
4290
4291 for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_funcs);)
4292 {
4293 if (cfp[i].token == RIG_CONF_END)
4294 {
4295 cfp = icom_ext_funcs;
4296 i = 0;
4297 }
4298 else if (cfp[i].token == token)
4299 {
4300 value_t value = { .i = status };
4301 RETURNFUNC(icom_set_ext_cmd(rig, vfo, token, value));
4302 }
4303 else { i++; }
4304 }
4305
4306 RETURNFUNC(-RIG_EINVAL);
4307 }
4308
icom_get_ext_func(RIG * rig,vfo_t vfo,token_t token,int * status)4309 int icom_get_ext_func(RIG *rig, vfo_t vfo, token_t token, int *status)
4310 {
4311 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4312
4313 const struct confparams *cfp = rig->caps->extfuncs;
4314 cfp = (cfp == NULL) ? icom_ext_funcs : cfp;
4315 int i;
4316
4317 for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_funcs);)
4318 {
4319 if (cfp[i].token == RIG_CONF_END)
4320 {
4321 cfp = icom_ext_funcs;
4322 i = 0;
4323 }
4324 else if (cfp[i].token == token)
4325 {
4326 value_t value;
4327 int result = icom_get_ext_cmd(rig, vfo, token, &value);
4328
4329 if (result == RIG_OK)
4330 {
4331 *status = value.i;
4332 }
4333
4334 RETURNFUNC(result);
4335 }
4336 else { i++; }
4337 }
4338
4339 RETURNFUNC(-RIG_EINVAL);
4340 }
4341
icom_set_ext_parm(RIG * rig,token_t token,value_t val)4342 int icom_set_ext_parm(RIG *rig, token_t token, value_t val)
4343 {
4344 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4345
4346 const struct confparams *cfp = rig->caps->extparms;
4347 cfp = (cfp == NULL) ? icom_ext_parms : cfp;
4348 int i;
4349
4350 for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_parms);)
4351 {
4352 if (cfp[i].token == RIG_CONF_END)
4353 {
4354 cfp = icom_ext_parms;
4355 i = 0;
4356 }
4357 else if (cfp[i].token == token)
4358 {
4359 RETURNFUNC(icom_set_ext_cmd(rig, RIG_VFO_NONE, token, val));
4360 }
4361 else { i++; }
4362 }
4363
4364 RETURNFUNC(-RIG_EINVAL);
4365 }
4366
icom_get_ext_parm(RIG * rig,token_t token,value_t * val)4367 int icom_get_ext_parm(RIG *rig, token_t token, value_t *val)
4368 {
4369 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4370
4371 const struct confparams *cfp = rig->caps->extparms;
4372 cfp = (cfp == NULL) ? icom_ext_parms : cfp;
4373 int i;
4374
4375 for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_parms);)
4376 {
4377 if (cfp[i].token == RIG_CONF_END)
4378 {
4379 cfp = icom_ext_parms;
4380 i = 0;
4381 }
4382 else if (cfp[i].token == token)
4383 {
4384 RETURNFUNC(icom_get_ext_cmd(rig, RIG_VFO_NONE, token, val));
4385 }
4386 else { i++; }
4387 }
4388
4389 RETURNFUNC(-RIG_EINVAL);
4390 }
4391
icom_get_ext_cmd(RIG * rig,vfo_t vfo,token_t token,value_t * val)4392 int icom_get_ext_cmd(RIG *rig, vfo_t vfo, token_t token, value_t *val)
4393 {
4394 int i;
4395
4396 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4397
4398 for (i = 0; rig->caps->ext_tokens
4399 && rig->caps->ext_tokens[i] != TOK_BACKEND_NONE; i++)
4400 {
4401 if (rig->caps->ext_tokens[i] == token)
4402 {
4403 const struct icom_priv_caps *priv = rig->caps->priv;
4404 const struct cmdparams *cmd = priv->extcmds ? priv->extcmds : icom_ext_cmd;
4405
4406 for (i = 0; (cmd[i].id.t != 0) || (cmd != icom_ext_cmd);)
4407 {
4408 if (cmd[i].id.t == 0)
4409 {
4410 cmd = icom_ext_cmd;
4411 i = 0;
4412 }
4413 else if (cmd[i].cmdparamtype == CMD_PARAM_TYPE_TOKEN && cmd[i].id.t == token)
4414 {
4415 RETURNFUNC(icom_get_cmd(rig, vfo, (struct cmdparams *)&cmd[i], val));
4416 }
4417 else { i++; }
4418 }
4419
4420 RETURNFUNC(-RIG_EINVAL);
4421 }
4422 }
4423
4424 RETURNFUNC(-RIG_EINVAL);
4425 }
4426
icom_set_ext_cmd(RIG * rig,vfo_t vfo,token_t token,value_t val)4427 int icom_set_ext_cmd(RIG *rig, vfo_t vfo, token_t token, value_t val)
4428 {
4429 int i;
4430
4431 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4432
4433 for (i = 0; rig->caps->ext_tokens
4434 && rig->caps->ext_tokens[i] != TOK_BACKEND_NONE; i++)
4435 {
4436 if (rig->caps->ext_tokens[i] == token)
4437 {
4438 const struct icom_priv_caps *priv = rig->caps->priv;
4439 const struct cmdparams *cmd = priv->extcmds ? priv->extcmds : icom_ext_cmd;
4440
4441 for (i = 0; (cmd[i].id.t != 0) || (cmd != icom_ext_cmd);)
4442 {
4443 if (cmd[i].id.t == 0)
4444 {
4445 cmd = icom_ext_cmd;
4446 i = 0;
4447 }
4448 else if (cmd->cmdparamtype == CMD_PARAM_TYPE_TOKEN && cmd[i].id.t == token)
4449 {
4450 RETURNFUNC(icom_set_cmd(rig, vfo, (struct cmdparams *)&cmd[i], val));
4451 }
4452 else { i++; }
4453 }
4454
4455 RETURNFUNC(-RIG_EINVAL);
4456 }
4457 }
4458
4459 RETURNFUNC(-RIG_EINVAL);
4460 }
4461
4462 /*
4463 * Assumes rig!=NULL, rig->state.priv!=NULL
4464 */
icom_set_conf(RIG * rig,token_t token,const char * val)4465 int icom_set_conf(RIG *rig, token_t token, const char *val)
4466 {
4467 struct icom_priv_data *priv;
4468 struct rig_state *rs;
4469
4470 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4471 rs = &rig->state;
4472 priv = (struct icom_priv_data *) rs->priv;
4473
4474 switch (token)
4475 {
4476 case TOK_CIVADDR:
4477 if (val[0] == '0' && val[1] == 'x')
4478 {
4479 priv->re_civ_addr = strtol(val, (char **) NULL, 16);
4480 }
4481 else
4482 {
4483 priv->re_civ_addr = atoi(val);
4484 }
4485
4486 break;
4487
4488 case TOK_MODE731:
4489 priv->civ_731_mode = atoi(val) ? 1 : 0;
4490 break;
4491
4492 case TOK_NOXCHG:
4493 priv->no_xchg = atoi(val) ? 1 : 0;
4494 break;
4495
4496 default:
4497 RETURNFUNC(-RIG_EINVAL);
4498 }
4499
4500 RETURNFUNC(RIG_OK);
4501 }
4502
4503 /*
4504 * assumes rig!=NULL,
4505 * Assumes rig!=NULL, rig->state.priv!=NULL
4506 * and val points to a buffer big enough to hold the conf value.
4507 */
icom_get_conf(RIG * rig,token_t token,char * val)4508 int icom_get_conf(RIG *rig, token_t token, char *val)
4509 {
4510 struct icom_priv_data *priv;
4511 struct rig_state *rs;
4512
4513 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4514 rs = &rig->state;
4515 priv = (struct icom_priv_data *) rs->priv;
4516
4517 switch (token)
4518 {
4519 case TOK_CIVADDR:
4520 sprintf(val, "%d", priv->re_civ_addr);
4521 break;
4522
4523 case TOK_MODE731: sprintf(val, "%d", priv->civ_731_mode);
4524 break;
4525
4526 case TOK_NOXCHG: sprintf(val, "%d", priv->no_xchg);
4527 break;
4528
4529 default: RETURNFUNC(-RIG_EINVAL);
4530 }
4531
4532 RETURNFUNC(RIG_OK);
4533 }
4534
4535
4536 /*
4537 * icom_set_ptt
4538 * Assumes rig!=NULL, rig->state.priv!=NULL
4539 */
icom_set_ptt(RIG * rig,vfo_t vfo,ptt_t ptt)4540 int icom_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt)
4541 {
4542 unsigned char ackbuf[MAXFRAMELEN], pttbuf[1];
4543 int ack_len = sizeof(ackbuf), retval;
4544
4545 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4546 pttbuf[0] = ptt == RIG_PTT_ON ? 1 : 0;
4547
4548 retval = icom_transaction(rig, C_CTL_PTT, S_PTT, pttbuf, 1,
4549 ackbuf, &ack_len);
4550
4551 if (retval != RIG_OK)
4552 {
4553 RETURNFUNC(retval);
4554 }
4555
4556 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
4557 {
4558 // if we don't get ACK/NAK some serial corruption occurred
4559 // so we'll call it a timeout for retry purposes
4560 RETURNFUNC(-RIG_ETIMEOUT);
4561 }
4562
4563 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
4564 {
4565 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
4566 ackbuf[0], ack_len);
4567 RETURNFUNC(-RIG_ERJCTED);
4568 }
4569
4570 RETURNFUNC(RIG_OK);
4571 }
4572
4573 /*
4574 * icom_get_ptt
4575 * Assumes rig!=NULL, rig->state.priv!=NULL, ptt!=NULL
4576 */
icom_get_ptt(RIG * rig,vfo_t vfo,ptt_t * ptt)4577 int icom_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
4578 {
4579 unsigned char pttbuf[MAXFRAMELEN];
4580 int ptt_len, retval;
4581
4582 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4583 retval = icom_transaction(rig, C_CTL_PTT, S_PTT, NULL, 0,
4584 pttbuf, &ptt_len);
4585
4586 if (retval != RIG_OK)
4587 {
4588 RETURNFUNC(retval);
4589 }
4590
4591 /*
4592 * pttbuf should contain Cn,Sc,Data area
4593 */
4594 ptt_len -= 2;
4595
4596 if (ptt_len != 1)
4597 {
4598 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n",
4599 __func__, ptt_len);
4600 RETURNFUNC(-RIG_ERJCTED);
4601 }
4602
4603 *ptt = pttbuf[2] == 1 ? RIG_PTT_ON : RIG_PTT_OFF;
4604
4605 RETURNFUNC(RIG_OK);
4606 }
4607
4608 /*
4609 * icom_get_dcd
4610 * Assumes rig!=NULL, rig->state.priv!=NULL, ptt!=NULL
4611 */
icom_get_dcd(RIG * rig,vfo_t vfo,dcd_t * dcd)4612 int icom_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd)
4613 {
4614 unsigned char dcdbuf[MAXFRAMELEN];
4615 int dcd_len, retval;
4616
4617 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4618 retval = icom_transaction(rig, C_RD_SQSM, S_SQL, NULL, 0,
4619 dcdbuf, &dcd_len);
4620
4621 if (retval != RIG_OK)
4622 {
4623 RETURNFUNC(retval);
4624 }
4625
4626 /*
4627 * dcdbuf should contain Cn,Data area
4628 */
4629 dcd_len -= 2;
4630
4631 if (dcd_len != 1)
4632 {
4633 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n",
4634 __func__, dcd_len);
4635 RETURNFUNC(-RIG_ERJCTED);
4636 }
4637
4638 /*
4639 * 0x00=sql closed, 0x01=sql open
4640 */
4641
4642 *dcd = dcdbuf[2] == 1 ? RIG_DCD_ON : RIG_DCD_OFF;
4643
4644 RETURNFUNC(RIG_OK);
4645 }
4646
4647 /*
4648 * icom_set_rptr_shift
4649 * Assumes rig!=NULL, rig->state.priv!=NULL
4650 */
icom_set_rptr_shift(RIG * rig,vfo_t vfo,rptr_shift_t rptr_shift)4651 int icom_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift)
4652 {
4653 unsigned char ackbuf[MAXFRAMELEN];
4654 int ack_len = sizeof(ackbuf), retval;
4655 int rptr_sc;
4656
4657 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4658
4659 switch (rptr_shift)
4660 {
4661 case RIG_RPT_SHIFT_NONE:
4662 rptr_sc = S_DUP_OFF; /* Simplex mode */
4663 break;
4664
4665 case RIG_RPT_SHIFT_MINUS:
4666 rptr_sc = S_DUP_M; /* Duplex - mode */
4667 break;
4668
4669 case RIG_RPT_SHIFT_PLUS:
4670 rptr_sc = S_DUP_P; /* Duplex + mode */
4671 break;
4672
4673 default:
4674 rig_debug(RIG_DEBUG_ERR, "%s: unsupported shift %d\n", __func__,
4675 rptr_shift);
4676 RETURNFUNC(-RIG_EINVAL);
4677 }
4678
4679 retval = icom_transaction(rig, C_CTL_SPLT, rptr_sc, NULL, 0,
4680 ackbuf, &ack_len);
4681
4682 if (retval != RIG_OK)
4683 {
4684 RETURNFUNC(retval);
4685 }
4686
4687 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
4688 {
4689 // if we don't get ACK/NAK some serial corruption occurred
4690 // so we'll call it a timeout for retry purposes
4691 RETURNFUNC(-RIG_ETIMEOUT);
4692 }
4693
4694 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
4695 {
4696 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
4697 ackbuf[0], ack_len);
4698 RETURNFUNC(-RIG_ERJCTED);
4699 }
4700
4701 RETURNFUNC(RIG_OK);
4702 }
4703
4704
4705 /*
4706 * icom_get_rptr_shift
4707 * Assumes rig!=NULL, rig->state.priv!=NULL, rptr_shift!=NULL
4708 * will not work for IC-746 Pro
4709 * NOTE: seems not to work (tested on IC-706MkIIG), please report --SF
4710 */
icom_get_rptr_shift(RIG * rig,vfo_t vfo,rptr_shift_t * rptr_shift)4711 int icom_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift)
4712 {
4713 unsigned char rptrbuf[MAXFRAMELEN];
4714 int rptr_len, retval;
4715
4716 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4717 retval = icom_transaction(rig, C_CTL_SPLT, -1, NULL, 0,
4718 rptrbuf, &rptr_len);
4719
4720 if (retval != RIG_OK)
4721 {
4722 RETURNFUNC(retval);
4723 }
4724
4725 /*
4726 * rptrbuf should contain Cn,Sc
4727 */
4728 rptr_len--;
4729
4730 if (rptr_len != 1)
4731 {
4732 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n",
4733 __func__, rptr_len);
4734 RETURNFUNC(-RIG_ERJCTED);
4735 }
4736
4737 switch (rptrbuf[1])
4738 {
4739 case S_DUP_OFF:
4740 case S_DUP_DD_RPS:
4741 *rptr_shift = RIG_RPT_SHIFT_NONE; /* Simplex mode */
4742 break;
4743
4744 case S_DUP_M:
4745 *rptr_shift = RIG_RPT_SHIFT_MINUS; /* Duplex - mode */
4746 break;
4747
4748 case S_DUP_P:
4749 *rptr_shift = RIG_RPT_SHIFT_PLUS; /* Duplex + mode */
4750 break;
4751
4752 // The same command indicates split state, which means simplex mode
4753 case S_SPLT_OFF:
4754 case S_SPLT_ON:
4755 *rptr_shift = RIG_RPT_SHIFT_NONE; /* Simplex mode */
4756 break;
4757
4758 default:
4759 rig_debug(RIG_DEBUG_ERR, "%s: unsupported shift %d\n", __func__,
4760 rptrbuf[1]);
4761 RETURNFUNC(-RIG_EPROTO);
4762 }
4763
4764 RETURNFUNC(RIG_OK);
4765 }
4766
4767 /*
4768 * icom_set_rptr_offs
4769 * Assumes rig!=NULL, rig->state.priv!=NULL
4770 */
icom_set_rptr_offs(RIG * rig,vfo_t vfo,shortfreq_t rptr_offs)4771 int icom_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs)
4772 {
4773 int offs_len;
4774 unsigned char offsbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN];
4775 int ack_len = sizeof(ackbuf), retval;
4776 const struct icom_priv_caps *priv_caps;
4777
4778 priv_caps = (const struct icom_priv_caps *) rig->caps->priv;
4779 offs_len = (priv_caps->offs_len) ? priv_caps->offs_len : OFFS_LEN;
4780
4781 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4782 /*
4783 * Icoms are using a 100Hz unit (at least on 706MKIIg) -- SF
4784 */
4785 to_bcd(offsbuf, rptr_offs / 100, offs_len * 2);
4786
4787 retval = icom_transaction(rig, C_SET_OFFS, -1, offsbuf, offs_len,
4788 ackbuf, &ack_len);
4789
4790 if (retval != RIG_OK)
4791 {
4792 RETURNFUNC(retval);
4793 }
4794
4795 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
4796 {
4797 // if we don't get ACK/NAK some serial corruption occurred
4798 // so we'll call it a timeout for retry purposes
4799 RETURNFUNC(-RIG_ETIMEOUT);
4800 }
4801
4802 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
4803 {
4804 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
4805 ackbuf[0], ack_len);
4806 RETURNFUNC(-RIG_ERJCTED);
4807 }
4808
4809 RETURNFUNC(RIG_OK);
4810 }
4811
4812
4813 /*
4814 * icom_get_rptr_offs
4815 * Assumes rig!=NULL, rig->state.priv!=NULL, rptr_offs!=NULL
4816 */
icom_get_rptr_offs(RIG * rig,vfo_t vfo,shortfreq_t * rptr_offs)4817 int icom_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs)
4818 {
4819 int offs_len;
4820 unsigned char offsbuf[MAXFRAMELEN];
4821 int buf_len, retval;
4822 const struct icom_priv_caps *priv_caps;
4823
4824 priv_caps = (const struct icom_priv_caps *) rig->caps->priv;
4825 offs_len = (priv_caps->offs_len) ? priv_caps->offs_len : OFFS_LEN;
4826
4827 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4828 retval = icom_transaction(rig, C_RD_OFFS, -1, NULL, 0, offsbuf, &buf_len);
4829
4830 if (retval != RIG_OK)
4831 {
4832 RETURNFUNC(retval);
4833 }
4834
4835 /*
4836 * offsbuf should contain Cn
4837 */
4838 buf_len--;
4839
4840 if (buf_len != offs_len)
4841 {
4842 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__,
4843 buf_len);
4844 RETURNFUNC(-RIG_ERJCTED);
4845 }
4846
4847 /*
4848 * Icoms are using a 100Hz unit (at least on 706MKIIg) -- SF
4849 */
4850 *rptr_offs = from_bcd(offsbuf + 1, buf_len * 2) * 100;
4851
4852 RETURNFUNC(RIG_OK);
4853 }
4854
4855 /*
4856 * Helper function to go back and forth split VFO
4857 */
icom_get_split_vfos(RIG * rig,vfo_t * rx_vfo,vfo_t * tx_vfo)4858 int icom_get_split_vfos(RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo)
4859 {
4860 struct icom_priv_data *priv;
4861 struct rig_state *rs;
4862
4863 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
4864
4865 rs = (struct rig_state *) &rig->state;
4866 priv = (struct icom_priv_data *) rs->priv;
4867
4868
4869 if (VFO_HAS_A_B_ONLY)
4870 {
4871 *rx_vfo = *tx_vfo = RIG_VFO_A;
4872
4873 if (priv->split_on)
4874 {
4875 *rx_vfo = RIG_VFO_A;
4876 *tx_vfo = RIG_VFO_B; /* rig doesn't enforce this but
4877 convention is needed here */
4878 }
4879
4880 rig_debug(RIG_DEBUG_TRACE, "%s: VFO_HAS_A_B_ONLY, split=%d, rx=%s, tx=%s\n",
4881 __func__,
4882 priv->split_on, rig_strvfo(*rx_vfo), rig_strvfo(*tx_vfo));
4883 }
4884 else if (VFO_HAS_MAIN_SUB_ONLY)
4885 {
4886 *rx_vfo = *tx_vfo = RIG_VFO_MAIN;
4887
4888 if (priv->split_on)
4889 {
4890 *rx_vfo = RIG_VFO_MAIN;
4891 *tx_vfo = RIG_VFO_SUB;
4892 }
4893
4894 rig_debug(RIG_DEBUG_TRACE,
4895 "%s: VFO_HAS_MAIN_SUB_ONLY, split=%d, rx=%s, tx=%s\n",
4896 __func__, priv->split_on, rig_strvfo(*rx_vfo), rig_strvfo(*tx_vfo));
4897 }
4898 else if (VFO_HAS_MAIN_SUB_A_B_ONLY)
4899 {
4900 int satmode = 0;
4901
4902 // e.g. IC9700 split on Main/Sub does not work
4903 // only Main VFOA/B and SubRx/MainTx split works
4904 if (rig->caps->has_get_func & RIG_FUNC_SATMODE)
4905 {
4906 // satmode defaults to 0 -- only call if we need to
4907 rig_get_func((RIG *)rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode);
4908 }
4909
4910 rig->state.cache.satmode = satmode;
4911
4912 // don't care about retval here...only care about satmode=1
4913 if (satmode)
4914 {
4915 *rx_vfo = priv->rx_vfo = RIG_VFO_MAIN;
4916 *tx_vfo = priv->tx_vfo = RIG_VFO_SUB;
4917 }
4918 else if (priv->split_on)
4919 {
4920 *rx_vfo = priv->rx_vfo = RIG_VFO_A;
4921 *tx_vfo = priv->tx_vfo = RIG_VFO_B;
4922 }
4923 else
4924 {
4925 *rx_vfo = priv->rx_vfo = RIG_VFO_A;
4926 *tx_vfo = priv->tx_vfo = RIG_VFO_A;
4927 }
4928
4929 rig_debug(RIG_DEBUG_TRACE,
4930 "%s: VFO_HAS_MAIN_SUB_A_B_ONLY, split=%d, rx=%s, tx=%s\n",
4931 __func__, priv->split_on, rig_strvfo(*rx_vfo), rig_strvfo(*tx_vfo));
4932 }
4933 else
4934 {
4935 rig_debug(RIG_DEBUG_ERR, "%s invalid vfo setup?\n", __func__);
4936 RETURNFUNC(-RIG_ENAVAIL);
4937 }
4938
4939 RETURNFUNC(RIG_OK);
4940 }
4941
4942 /*
4943 * icom_set_split_freq
4944 * Assumes rig!=NULL, rig->state.priv!=NULL,
4945 * icom_set_vfo,icom_set_freq works for this rig
4946 *
4947 * Assumes also that the current VFO is the rx VFO.
4948 */
icom_set_split_freq(RIG * rig,vfo_t vfo,freq_t tx_freq)4949 int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
4950 {
4951 int retval;
4952 vfo_t rx_vfo, tx_vfo;
4953 struct icom_priv_data *priv;
4954 struct rig_state *rs;
4955 unsigned char ackbuf[MAXFRAMELEN];
4956 int ack_len = sizeof(ackbuf);
4957
4958 rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s\n", __func__, rig_strvfo(vfo));
4959 rs = &rig->state;
4960 priv = (struct icom_priv_data *) rs->priv;
4961 rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s\n", __func__,
4962 rig_strvfo(rig->state.current_vfo));
4963
4964 rig_debug(RIG_DEBUG_VERBOSE, "%s: satmode=%d, subvfo=%s\n", __func__,
4965 rig->state.cache.satmode, rig_strvfo(priv->tx_vfo));
4966
4967 if (vfo == RIG_VFO_TX)
4968 {
4969 if (rig->state.cache.satmode) { vfo = RIG_VFO_SUB; }
4970 else { vfo = priv->tx_vfo; }
4971 }
4972
4973 rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo is now %s\n", __func__, rig_strvfo(vfo));
4974
4975 if (rig->state.cache.satmode && vfo == RIG_VFO_TX) { vfo = RIG_VFO_SUB; }
4976
4977 if (rig->state.current_vfo == RIG_VFO_NONE)
4978 {
4979 retval = icom_set_default_vfo(rig);
4980
4981 if (retval != RIG_OK)
4982 {
4983 rig_debug(RIG_DEBUG_ERR, "%s: set_default_vfo failed: %s\n", __func__,
4984 rigerror(retval));
4985 RETURNFUNC(retval);
4986 }
4987 }
4988
4989 #if 0
4990 TRACE;
4991 retval = set_vfo_curr(rig, RIG_VFO_TX, RIG_VFO_TX);
4992
4993 if (retval != RIG_OK)
4994 {
4995 rig_debug(RIG_DEBUG_ERR, "%s: set_default_vfo failed: %s\n", __func__,
4996 rigerror(retval));
4997 RETURNFUNC(retval);
4998 }
4999
5000 #endif
5001
5002 // If the rigs supports the 0x25 command we'll use it
5003 // This eliminates VFO swapping and improves split operations
5004 if (priv->x25cmdfails == 0)
5005 {
5006 int satmode = 0;
5007
5008 // retval not important here...only satmode=1 means anything
5009 if (rig->caps->has_get_func & RIG_FUNC_SATMODE)
5010 {
5011 rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode);
5012 }
5013
5014 rig->state.cache.satmode = satmode;
5015 rig_debug(RIG_DEBUG_VERBOSE, "%s: satmode=%d\n", __func__, satmode);
5016
5017 if (satmode == 0) // only worth trying if not in satmode
5018 {
5019 int cmd, subcmd, freq_len;
5020 unsigned char freqbuf[32];
5021 freq_len = priv->civ_731_mode ? 4 : 5;
5022 /*
5023 * to_bcd requires nibble len
5024 */
5025 to_bcd(freqbuf, tx_freq, freq_len * 2);
5026
5027 cmd = C_SEND_SEL_FREQ;
5028 subcmd = 0x01; // set the unselected vfo
5029
5030 // if we're already on the tx_vfo don't need the "other" vfo
5031 if (rig->state.current_vfo == rig->state.tx_vfo)
5032 {
5033 subcmd = 0x00;
5034 }
5035
5036 retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf,
5037 &ack_len);
5038
5039 if (retval == RIG_OK) // then we're done!!
5040 {
5041 RETURNFUNC(retval);
5042 }
5043 }
5044
5045 priv->x25cmdfails = 1;
5046 }
5047
5048
5049 if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG))
5050 {
5051 rig_debug(RIG_DEBUG_TRACE, "%s: Using XCHG to swap/set/swap\n", __func__);
5052
5053 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5054 {
5055 RETURNFUNC(retval);
5056 }
5057
5058 if (RIG_OK != (retval = icom_set_freq(rig, RIG_VFO_CURR, tx_freq)))
5059 {
5060 RETURNFUNC(retval);
5061 }
5062
5063 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5064 {
5065 RETURNFUNC(retval);
5066 }
5067
5068 RETURNFUNC(retval);
5069 }
5070
5071 /* In the case of rigs with an A/B VFO arrangement we assume the
5072 current VFO is VFO A and the split Tx VFO is always VFO B. These
5073 assumptions allow us to deal with the lack of VFO and split
5074 queries */
5075 if (VFO_HAS_A_B_ONLY
5076 && priv->split_on) /* broken if user changes split on rig :( */
5077 {
5078 /* VFO A/B style rigs swap VFO on split Tx so we need to disable
5079 split for certainty */
5080 if (RIG_OK !=
5081 (retval =
5082 icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf,
5083 &ack_len)))
5084 {
5085 RETURNFUNC(retval);
5086 }
5087
5088 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
5089 {
5090 // if we don't get ACK/NAK some serial corruption occurred
5091 // so we'll call it a timeout for retry purposes
5092 RETURNFUNC(-RIG_ETIMEOUT);
5093 }
5094
5095 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
5096 {
5097 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
5098 ackbuf[0], ack_len);
5099 RETURNFUNC(-RIG_ERJCTED);
5100 }
5101 }
5102
5103 if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo)))
5104 {
5105 RETURNFUNC(retval);
5106 }
5107
5108 rig_debug(RIG_DEBUG_TRACE, "%s: rx_vfo=%s, tx_vfo=%s\n", __func__,
5109 rig_strvfo(rx_vfo), rig_strvfo(tx_vfo));
5110
5111 TRACE;
5112
5113 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ)
5114 && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo)))
5115 {
5116 RETURNFUNC(retval);
5117 }
5118
5119 if (RIG_OK != (retval = rig_set_freq(rig, tx_vfo, tx_freq)))
5120 {
5121 RETURNFUNC(retval);
5122 }
5123
5124 TRACE;
5125
5126 if (VFO_HAS_MAIN_SUB_A_B_ONLY)
5127 {
5128 // Then we return the VFO to the rx_vfo
5129 rig_debug(RIG_DEBUG_TRACE, "%s: SATMODE split_on=%d rig so setting vfo to %s\n",
5130 __func__,
5131 priv->split_on, rig_strvfo(rx_vfo));
5132
5133 TRACE;
5134
5135 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ)
5136 && RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
5137 {
5138 RETURNFUNC(retval);
5139 }
5140 }
5141 else if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
5142 {
5143 TRACE;
5144 RETURNFUNC(retval);
5145 }
5146
5147 if (VFO_HAS_A_B_ONLY && priv->split_on)
5148 {
5149 /* Re-enable split */
5150 if (RIG_OK !=
5151 (retval =
5152 icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf,
5153 &ack_len)))
5154 {
5155 RETURNFUNC(retval);
5156 }
5157 }
5158
5159 // Update our internal freqs to match what we just did
5160 if (vfo == RIG_VFO_MAIN)
5161 {
5162 priv->main_freq = tx_freq;
5163 }
5164 else if (vfo == RIG_VFO_SUB)
5165 {
5166 priv->sub_freq = tx_freq;
5167 }
5168
5169 RETURNFUNC(retval);
5170 }
5171
5172 /*
5173 * icom_get_split_freq
5174 * Assumes rig!=NULL, rig->state.priv!=NULL, rx_freq!=NULL, tx_freq!=NULL
5175 * icom_set_vfo,icom_get_freq works for this rig
5176 */
icom_get_split_freq(RIG * rig,vfo_t vfo,freq_t * tx_freq)5177 int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
5178 {
5179 int retval;
5180 vfo_t rx_vfo, tx_vfo;
5181 struct icom_priv_data *priv;
5182 struct rig_state *rs;
5183 unsigned char ackbuf[MAXFRAMELEN];
5184 int ack_len = sizeof(ackbuf);
5185
5186 rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strvfo(vfo));
5187
5188 rs = &rig->state;
5189 priv = (struct icom_priv_data *) rs->priv;
5190 rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s\n", __func__,
5191 rig_strvfo(rig->state.current_vfo));
5192
5193
5194 if (rig->caps->rig_model == RIG_MODEL_IC910)
5195 {
5196 ptt_t ptt;
5197 rig_debug(RIG_DEBUG_VERBOSE, "%s: ic910#2\n", __func__);
5198 retval = rig_get_ptt(rig, RIG_VFO_CURR, &ptt);
5199
5200 if (retval != RIG_OK)
5201 {
5202 RETURNFUNC(retval);
5203 }
5204
5205 if (ptt)
5206 {
5207 rig_debug(RIG_DEBUG_TRACE, "%s: ptt is on so returning last known freq\n",
5208 __func__);
5209 *tx_freq = priv->vfob_freq;
5210 RETURNFUNC(RIG_OK);
5211 }
5212 }
5213
5214 rig_debug(RIG_DEBUG_VERBOSE, "%s curr_vfo=%s\n", __func__,
5215 rig_strvfo(rig->state.current_vfo));
5216
5217 if (rig->state.current_vfo == RIG_VFO_NONE)
5218 {
5219 icom_set_default_vfo(rig);
5220 }
5221
5222 // If the rigs supports the 0x25 command we'll use it
5223 // This eliminates VFO swapping and improves split operations
5224 // This does not work in satellite mode for the 9700
5225 if (priv->x25cmdfails == 0)
5226 {
5227 int cmd, subcmd;
5228 int satmode = 0;
5229
5230 // don't care about the retval here..only satmode=1 is important
5231 if (rig->caps->has_get_func & RIG_FUNC_SATMODE)
5232 {
5233 rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode);
5234 }
5235
5236 rig->state.cache.satmode = satmode;
5237 rig_debug(RIG_DEBUG_VERBOSE, "%s: satmode=%d\n", __func__, satmode);
5238
5239 if (satmode == 0) // only worth trying if not in satmode
5240 {
5241 if (priv->x25cmdfails == 0)
5242 {
5243 int retry_save = rs->rigport.retry;
5244 rs->rigport.retry = 0;
5245 cmd = C_SEND_SEL_FREQ;
5246 subcmd = 0x01; // get the unselected vfo
5247 retval = icom_transaction(rig, cmd, subcmd, NULL, 0, ackbuf,
5248 &ack_len);
5249
5250 rs->rigport.retry = retry_save;
5251
5252 if (retval == RIG_OK) // then we're done!!
5253 {
5254 *tx_freq = from_bcd(ackbuf + 2, (priv->civ_731_mode ? 4 : 5) * 2);
5255 RETURNFUNC(retval);
5256 }
5257
5258 priv->x25cmdfails = 1;
5259 }
5260 }
5261 else // we're in satmode so we try another command
5262 {
5263 if (priv->x1cx03cmdfails == 0)
5264 {
5265 cmd = 0x1c;
5266 subcmd = 0x03;
5267 retval = icom_transaction(rig, cmd, subcmd, NULL, 0, ackbuf,
5268 &ack_len);
5269
5270 if (retval == RIG_OK) // then we're done!!
5271 {
5272 *tx_freq = from_bcd(&ackbuf[2], (priv->civ_731_mode ? 4 : 5) * 2);
5273 RETURNFUNC(retval);
5274 }
5275
5276 priv->x1cx03cmdfails = 1;
5277 }
5278 }
5279
5280 }
5281
5282 /* This method works also in memory mode(RIG_VFO_MEM) */
5283 if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG))
5284 {
5285 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5286 {
5287 RETURNFUNC(retval);
5288 }
5289
5290 if (RIG_OK != (retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq)))
5291 {
5292 RETURNFUNC(retval);
5293 }
5294
5295 priv->vfob_freq = *tx_freq;
5296
5297 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5298 {
5299 RETURNFUNC(retval);
5300 }
5301
5302 RETURNFUNC(retval);
5303 }
5304
5305 /* In the case of rigs with an A/B VFO arrangement we assume the
5306 current VFO is VFO A and the split Tx VFO is always VFO B. These
5307 assumptions allow us to deal with the lack of VFO and split
5308 queries */
5309 if (VFO_HAS_A_B_ONLY
5310 && priv->split_on) /* broken if user changes split on rig :( */
5311 {
5312 /* VFO A/B style rigs swap VFO on split Tx so we need to disable
5313 split for certainty */
5314 if (RIG_OK !=
5315 (retval =
5316 icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf,
5317 &ack_len)))
5318 {
5319 RETURNFUNC(retval);
5320 }
5321
5322 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
5323 {
5324 // if we don't get ACK/NAK some serial corruption occurred
5325 // so we'll call it a timeout for retry purposes
5326 RETURNFUNC(-RIG_ETIMEOUT);
5327 }
5328
5329 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
5330 {
5331 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
5332 ackbuf[0], ack_len);
5333 RETURNFUNC(-RIG_ERJCTED);
5334 }
5335 }
5336
5337 if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo)))
5338 {
5339 RETURNFUNC(retval);
5340 }
5341
5342 TRACE;
5343
5344 if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo)))
5345 {
5346 RETURNFUNC(retval);
5347 }
5348
5349 if (RIG_OK != (retval = rig_get_freq(rig, tx_vfo, tx_freq)))
5350 {
5351 RETURNFUNC(retval);
5352 }
5353
5354 TRACE;
5355
5356 if (VFO_HAS_MAIN_SUB_A_B_ONLY)
5357 {
5358 // Then we return the VFO to where it was
5359 rig_debug(RIG_DEBUG_TRACE, "%s: SATMODE rig so returning vfo to %s\n", __func__,
5360 rig_strvfo(rx_vfo));
5361
5362 TRACE;
5363
5364 if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
5365 {
5366 RETURNFUNC(retval);
5367 }
5368 }
5369 else if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
5370 {
5371 TRACE;
5372 RETURNFUNC(retval);
5373 }
5374
5375 if (VFO_HAS_A_B_ONLY && priv->split_on)
5376 {
5377 /* Re-enable split */
5378 if (RIG_OK !=
5379 (retval =
5380 icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf,
5381 &ack_len)))
5382 {
5383 RETURNFUNC(retval);
5384 }
5385 }
5386
5387 priv->vfob_freq = *tx_freq;
5388 RETURNFUNC(retval);
5389 }
5390
5391 /*
5392 * icom_set_split_mode
5393 * Assumes rig!=NULL, rig->state.priv!=NULL,
5394 * icom_set_vfo,icom_set_mode works for this rig
5395 */
icom_set_split_mode(RIG * rig,vfo_t vfo,rmode_t tx_mode,pbwidth_t tx_width)5396 int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode,
5397 pbwidth_t tx_width)
5398 {
5399 int retval;
5400 vfo_t rx_vfo, tx_vfo;
5401 struct icom_priv_data *priv;
5402 struct rig_state *rs;
5403 unsigned char ackbuf[MAXFRAMELEN];
5404 int ack_len = sizeof(ackbuf);
5405
5406 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
5407 rs = &rig->state;
5408 priv = (struct icom_priv_data *) rs->priv;
5409
5410 /* This method works also in memory mode(RIG_VFO_MEM) */
5411 if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG))
5412 {
5413 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5414 {
5415 RETURNFUNC(retval);
5416 }
5417
5418 if (RIG_OK != (retval = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode,
5419 tx_width)))
5420 {
5421 RETURNFUNC(retval);
5422 }
5423
5424 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5425 {
5426 RETURNFUNC(retval);
5427 }
5428
5429 RETURNFUNC(retval);
5430 }
5431
5432 /* In the case of rigs with an A/B VFO arrangement we assume the
5433 current VFO is VFO A and the split Tx VFO is always VFO B. These
5434 assumptions allow us to deal with the lack of VFO and split
5435 queries */
5436 if (VFO_HAS_A_B_ONLY
5437 && priv->split_on) /* broken if user changes split on rig :( */
5438 {
5439 /* VFO A/B style rigs swap VFO on split Tx so we need to disable
5440 split for certainty */
5441 if (RIG_OK !=
5442 (retval =
5443 icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf,
5444 &ack_len)))
5445 {
5446 RETURNFUNC(retval);
5447 }
5448
5449 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
5450 {
5451 // if we don't get ACK/NAK some serial corruption occurred
5452 // so we'll call it a timeout for retry purposes
5453 RETURNFUNC(-RIG_ETIMEOUT);
5454 }
5455
5456 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
5457 {
5458 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
5459 ackbuf[0], ack_len);
5460 RETURNFUNC(-RIG_ERJCTED);
5461 }
5462 }
5463
5464 if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo)))
5465 {
5466 RETURNFUNC(retval);
5467 }
5468
5469 TRACE;
5470
5471 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
5472 && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo)))
5473 {
5474 RETURNFUNC(retval);
5475 }
5476
5477 if (RIG_OK != (retval = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode,
5478 tx_width)))
5479 {
5480 RETURNFUNC(retval);
5481 }
5482
5483 TRACE;
5484
5485 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
5486 && RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
5487 {
5488 RETURNFUNC(retval);
5489 }
5490
5491 if (VFO_HAS_A_B_ONLY && priv->split_on)
5492 {
5493 /* Re-enable split */
5494 if (RIG_OK !=
5495 (retval =
5496 icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf,
5497 &ack_len)))
5498 {
5499 RETURNFUNC(retval);
5500 }
5501 }
5502
5503 RETURNFUNC(retval);
5504 }
5505
5506 /*
5507 * icom_get_split_mode
5508 * Assumes rig!=NULL, rig->state.priv!=NULL,
5509 * rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL
5510 * icom_set_vfo,icom_get_mode works for this rig
5511 */
icom_get_split_mode(RIG * rig,vfo_t vfo,rmode_t * tx_mode,pbwidth_t * tx_width)5512 int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode,
5513 pbwidth_t *tx_width)
5514 {
5515 int retval;
5516 vfo_t rx_vfo, tx_vfo;
5517 struct icom_priv_data *priv;
5518 struct rig_state *rs;
5519 unsigned char ackbuf[MAXFRAMELEN];
5520 int ack_len = sizeof(ackbuf);
5521
5522 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
5523 rs = &rig->state;
5524 priv = (struct icom_priv_data *) rs->priv;
5525
5526 /* This method works also in memory mode(RIG_VFO_MEM) */
5527 if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG))
5528 {
5529 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5530 {
5531 RETURNFUNC(retval);
5532 }
5533
5534 if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode,
5535 tx_width)))
5536 {
5537 RETURNFUNC(retval);
5538 }
5539
5540 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5541 {
5542 RETURNFUNC(retval);
5543 }
5544
5545 RETURNFUNC(retval);
5546 }
5547
5548 /* In the case of rigs with an A/B VFO arrangement we assume the
5549 current VFO is VFO A and the split Tx VFO is always VFO B. These
5550 assumptions allow us to deal with the lack of VFO and split
5551 queries */
5552 if (VFO_HAS_A_B_ONLY
5553 && priv->split_on) /* broken if user changes split on rig :( */
5554 {
5555 /* VFO A/B style rigs swap VFO on split Tx so we need to disable
5556 split for certainty */
5557 if (RIG_OK !=
5558 (retval =
5559 icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf,
5560 &ack_len)))
5561 {
5562 RETURNFUNC(retval);
5563 }
5564
5565 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
5566 {
5567 // if we don't get ACK/NAK some serial corruption occurred
5568 // so we'll call it a timeout for retry purposes
5569 RETURNFUNC(-RIG_ETIMEOUT);
5570 }
5571
5572 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
5573 {
5574 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
5575 ackbuf[0], ack_len);
5576 RETURNFUNC(-RIG_ERJCTED);
5577 }
5578 }
5579
5580 if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo)))
5581 {
5582 RETURNFUNC(retval);
5583 }
5584
5585 TRACE;
5586
5587 if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo)))
5588 {
5589 RETURNFUNC(retval);
5590 }
5591
5592 if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode,
5593 tx_width)))
5594 {
5595 RETURNFUNC(retval);
5596 }
5597
5598 TRACE;
5599
5600 if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
5601 {
5602 RETURNFUNC(retval);
5603 }
5604
5605 if (VFO_HAS_A_B_ONLY && priv->split_on)
5606 {
5607 /* Re-enable split */
5608 if (RIG_OK !=
5609 (retval =
5610 icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf,
5611 &ack_len)))
5612 {
5613 RETURNFUNC(retval);
5614 }
5615 }
5616
5617 RETURNFUNC(retval);
5618 }
5619
5620 /*
5621 * icom_set_split_freq_mode
5622 * Assumes rig!=NULL, rig->state.priv!=NULL,
5623 * icom_set_vfo,icom_set_mode works for this rig
5624 */
icom_set_split_freq_mode(RIG * rig,vfo_t vfo,freq_t tx_freq,rmode_t tx_mode,pbwidth_t tx_width)5625 int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq,
5626 rmode_t tx_mode, pbwidth_t tx_width)
5627 {
5628 int retval;
5629 struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv;
5630 unsigned char ackbuf[MAXFRAMELEN];
5631 int ack_len = sizeof(ackbuf);
5632 vfo_t rx_vfo, tx_vfo;
5633 int split_assumed = 0;
5634
5635 rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__,
5636 rig_strvfo(vfo));
5637 rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s\n", __func__,
5638 rig_strvfo(rig->state.current_vfo));
5639
5640 // If the user is asking to set split on VFO_CURR we'll assume split mode
5641 // WSJT-X calls this function before turning on split mode
5642 if (vfo == RIG_VFO_CURR) { split_assumed = 1; }
5643
5644 if (rig->state.current_vfo == RIG_VFO_NONE)
5645 {
5646 icom_set_default_vfo(rig);
5647 }
5648
5649 /* This method works also in memory mode(RIG_VFO_MEM) */
5650 if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG))
5651 {
5652 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5653 {
5654 RETURNFUNC(retval);
5655 }
5656
5657 if (RIG_OK != (retval = rig_set_freq(rig, RIG_VFO_CURR, tx_freq)))
5658 {
5659 RETURNFUNC(retval);
5660 }
5661
5662 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
5663 && RIG_OK != (retval = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode,
5664 tx_width)))
5665 {
5666 RETURNFUNC(retval);
5667 }
5668
5669 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5670 {
5671 RETURNFUNC(retval);
5672 }
5673
5674 RETURNFUNC(retval);
5675 }
5676
5677 /* In the case of rigs with an A/B VFO arrangement we assume the
5678 current VFO is VFO A and the split Tx VFO is always VFO B. These
5679 assumptions allow us to deal with the lack of VFO and split
5680 queries */
5681 /* broken if user changes split on rig :( */
5682 if (VFO_HAS_A_B && (split_assumed || priv->split_on))
5683 {
5684 /* VFO A/B style rigs swap VFO on split Tx so we need to disable
5685 split for certainty */
5686 if (RIG_OK !=
5687 (retval =
5688 icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf,
5689 &ack_len)))
5690 {
5691 RETURNFUNC(retval);
5692 }
5693
5694 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
5695 {
5696 // if we don't get ACK/NAK some serial corruption occurred
5697 // so we'll call it a timeout for retry purposes
5698 RETURNFUNC(-RIG_ETIMEOUT);
5699 }
5700
5701 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
5702 {
5703 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
5704 ackbuf[0], ack_len);
5705 RETURNFUNC(-RIG_ERJCTED);
5706 }
5707 }
5708
5709 rig_debug(RIG_DEBUG_VERBOSE,
5710 "%s: before get_split_vfos rx_vfo=%s tx_vfo=%s\n", __func__,
5711 rig_strvfo(priv->rx_vfo), rig_strvfo(priv->tx_vfo));
5712
5713 if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo)))
5714 {
5715 RETURNFUNC(retval);
5716 }
5717
5718 // WSJT-X calls this function before setting split
5719 // So in this case we have to force the tx_vfo
5720 if (split_assumed && vfo == RIG_VFO_CURR)
5721 {
5722 rig_debug(RIG_DEBUG_TRACE, "%s: split_assumed so tx_vfo=%s\n", __func__,
5723 rig_strvfo(vfo));
5724 tx_vfo = VFO_HAS_A_B_ONLY ? RIG_VFO_B : RIG_VFO_SUB;
5725 }
5726
5727
5728 rig_debug(RIG_DEBUG_VERBOSE,
5729 "%s: after get_split_vfos rx_vfo=%s tx_vfo=%s\n", __func__,
5730 rig_strvfo(priv->rx_vfo), rig_strvfo(priv->tx_vfo));
5731
5732 // if not asking for RIG_VFO_CURR we'll use the requested VFO in the function call as tx_vfo
5733 if (!priv->split_on && vfo != RIG_VFO_CURR)
5734 {
5735 tx_vfo = vfo;
5736 rig_debug(RIG_DEBUG_TRACE, "%s: split not on so using requested vfo=%s\n",
5737 __func__, rig_strvfo(tx_vfo));
5738 }
5739
5740 TRACE;
5741
5742 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ)
5743 && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo)))
5744 {
5745 RETURNFUNC(retval);
5746 }
5747
5748 if (RIG_OK != (retval = rig_set_freq(rig, RIG_VFO_CURR, tx_freq)))
5749 {
5750 RETURNFUNC(retval);
5751 }
5752
5753 TRACE;
5754
5755 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
5756 && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo)))
5757 {
5758 RETURNFUNC(retval);
5759 }
5760
5761 if (RIG_OK != (retval = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode,
5762 tx_width)))
5763 {
5764 RETURNFUNC(retval);
5765 }
5766
5767 TRACE;
5768
5769 if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
5770 && RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
5771 {
5772 RETURNFUNC(retval);
5773 }
5774
5775 if (VFO_HAS_A_B && priv->split_on)
5776 {
5777 /* Re-enable split */
5778 if (RIG_OK !=
5779 (retval =
5780 icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf,
5781 &ack_len)))
5782 {
5783 RETURNFUNC(retval);
5784 }
5785 }
5786
5787 RETURNFUNC(retval);
5788 }
5789
5790 /*
5791 * icom_get_split_freq_mode
5792 * Assumes rig!=NULL, rig->state.priv!=NULL,
5793 * rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL
5794 * icom_set_vfo,icom_get_mode works for this rig
5795 */
icom_get_split_freq_mode(RIG * rig,vfo_t vfo,freq_t * tx_freq,rmode_t * tx_mode,pbwidth_t * tx_width)5796 int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq,
5797 rmode_t *tx_mode, pbwidth_t *tx_width)
5798 {
5799 int retval;
5800 vfo_t rx_vfo, tx_vfo;
5801 struct icom_priv_data *priv;
5802 struct rig_state *rs;
5803 unsigned char ackbuf[MAXFRAMELEN];
5804 int ack_len = sizeof(ackbuf);
5805
5806 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
5807 rs = &rig->state;
5808 priv = (struct icom_priv_data *) rs->priv;
5809
5810 /* This method works also in memory mode(RIG_VFO_MEM) */
5811 if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG))
5812 {
5813 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5814 {
5815 RETURNFUNC(retval);
5816 }
5817
5818 if (RIG_OK != (retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq)))
5819 {
5820 RETURNFUNC(retval);
5821 }
5822
5823 if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode,
5824 tx_width)))
5825 {
5826 RETURNFUNC(retval);
5827 }
5828
5829 if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG)))
5830 {
5831 RETURNFUNC(retval);
5832 }
5833
5834 RETURNFUNC(retval);
5835 }
5836
5837 /* In the case of rigs with an A/B VFO arrangement we assume the
5838 current VFO is VFO A and the split Tx VFO is always VFO B. These
5839 assumptions allow us to deal with the lack of VFO and split
5840 queries */
5841 if (VFO_HAS_A_B_ONLY
5842 && priv->split_on) /* broken if user changes split on rig :( */
5843 {
5844 /* VFO A/B style rigs swap VFO on split Tx so we need to disable
5845 split for certainty */
5846 if (RIG_OK !=
5847 (retval =
5848 icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf,
5849 &ack_len)))
5850 {
5851 RETURNFUNC(retval);
5852 }
5853
5854 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
5855 {
5856 // if we don't get ACK/NAK some serial corruption occurred
5857 // so we'll call it a timeout for retry purposes
5858 RETURNFUNC(-RIG_ETIMEOUT);
5859 }
5860
5861 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
5862 {
5863 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
5864 ackbuf[0], ack_len);
5865 RETURNFUNC(-RIG_ERJCTED);
5866 }
5867 }
5868
5869 if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo)))
5870 {
5871 RETURNFUNC(retval);
5872 }
5873
5874 TRACE;
5875
5876 if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo)))
5877 {
5878 RETURNFUNC(retval);
5879 }
5880
5881 if (RIG_OK != (retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq)))
5882 {
5883 RETURNFUNC(retval);
5884 }
5885
5886 if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode,
5887 tx_width)))
5888 {
5889 RETURNFUNC(retval);
5890 }
5891
5892 TRACE;
5893
5894 if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
5895 {
5896 RETURNFUNC(retval);
5897 }
5898
5899 if (VFO_HAS_A_B_ONLY && priv->split_on)
5900 {
5901 /* Re-enable split */
5902 if (RIG_OK !=
5903 (retval =
5904 icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf,
5905 &ack_len)))
5906 {
5907 RETURNFUNC(retval);
5908 }
5909 }
5910
5911 RETURNFUNC(retval);
5912 }
5913
5914
5915 /*
5916 * icom_set_split
5917 * Assumes rig!=NULL, rig->state.priv!=NULL
5918 */
icom_set_split_vfo(RIG * rig,vfo_t vfo,split_t split,vfo_t tx_vfo)5919 int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
5920 {
5921 struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv;
5922 unsigned char ackbuf[MAXFRAMELEN];
5923 int ack_len = sizeof(ackbuf), retval;
5924 int split_sc;
5925 //vfo_t vfo_final = RIG_VFO_NONE; // where does the VFO end up?
5926
5927 /* For Icom which VFO is active for this call is not important
5928 * S VFOA 1 VFOB -- RX on VFOA, TX on VFOB
5929 * S VFOB 1 VFOA -- RX on VFOB, TX on VFOA
5930 * S Main 1 Sub -- RX on Main, TX on Sub
5931 * S Sub 1 Main -- RX on Sub, TX on Main
5932 */
5933 rig_debug(RIG_DEBUG_VERBOSE,
5934 "%s called vfo='%s', split=%d, tx_vfo=%s, curr_vfo=%s\n", __func__,
5935 rig_strvfo(vfo), split, rig_strvfo(tx_vfo), rig_strvfo(rig->state.current_vfo));
5936
5937 // This should automatically switch between satmode on/off based on the requested split vfo
5938 if (rig->caps->has_get_func & RIG_FUNC_SATMODE)
5939 {
5940 if ((tx_vfo == RIG_VFO_SUB || tx_vfo == RIG_VFO_MAIN)
5941 && !rig->state.cache.satmode)
5942 {
5943 rig_debug(RIG_DEBUG_VERBOSE,
5944 "%s: VFO_SUB and satmode is off so turning satmode on\n",
5945 __func__);
5946 rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, 1);
5947 rig->state.cache.satmode = 1;
5948 priv->tx_vfo = RIG_VFO_SUB;
5949 }
5950 else if ((tx_vfo == RIG_VFO_A || tx_vfo == RIG_VFO_B)
5951 && rig->state.cache.satmode)
5952 {
5953 rig_debug(RIG_DEBUG_VERBOSE,
5954 "%s: VFO_B and satmode is on so turning satmode off\n",
5955 __func__);
5956 rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, 0);
5957 rig->state.cache.satmode = 0;
5958 priv->tx_vfo = RIG_VFO_B;
5959 }
5960 else if (tx_vfo == RIG_VFO_SUB && rig->state.cache.satmode && split == 1)
5961 {
5962 rig_debug(RIG_DEBUG_VERBOSE,
5963 "%s: rig in satmode so setting split on is redundant and will create error...returning OK\n",
5964 __func__);
5965 // we'll return OK anyways as this is a split mode
5966 // and gpredict wants to see the OK response here
5967 RETURNFUNC(RIG_OK); // we'll return OK anyways as this is a split mode
5968 }
5969 }
5970
5971 switch (split)
5972 {
5973 case RIG_SPLIT_OFF:
5974
5975 // if either VFOA or B is the vfo we set to VFOA when split is turned off
5976 if (tx_vfo == RIG_VFO_A || tx_vfo == RIG_VFO_B)
5977 {
5978 rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s\n", __func__,
5979 rig_strvfo(tx_vfo));
5980 priv->tx_vfo = RIG_VFO_A;
5981 //vfo_final = RIG_VFO_A; // do we need to switch back at all?
5982 }
5983 // otherwise if Main or Sub we set Main or VFOA as the current vfo
5984 else if (tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB)
5985 {
5986 rig_debug(RIG_DEBUG_TRACE, "%s: vfo is VFO_MAIN/SUB tx_vfo=%s\n",
5987 __func__, rig_strvfo(tx_vfo));
5988
5989 //rig_set_vfo(rig, RIG_VFO_MAIN);
5990 //vfo_final = RIG_VFO_MAIN; // do we need to switch back at all?
5991
5992 if (VFO_HAS_A_B_ONLY)
5993 {
5994 priv->tx_vfo = RIG_VFO_A;
5995 priv->rx_vfo = RIG_VFO_A;
5996 }
5997 else
5998 {
5999 priv->tx_vfo = RIG_VFO_MAIN;
6000 priv->rx_vfo = RIG_VFO_MAIN;
6001 }
6002 }
6003
6004 split_sc = S_SPLT_OFF;
6005 break;
6006
6007 case RIG_SPLIT_ON:
6008 split_sc = S_SPLT_ON;
6009 rig_debug(RIG_DEBUG_TRACE, "trace %s(%d)\n", __func__, __LINE__);
6010
6011 // the VFO adjusting here could probably be done in rig.c for all rigs
6012 /* If asking for Sub or Main on rig that doesn't have it map it */
6013 if (VFO_HAS_A_B_ONLY && ((tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB)
6014 || vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB))
6015 {
6016 rig_debug(RIG_DEBUG_TRACE, "%s: vfo clause 1\n", __func__);
6017
6018 if (tx_vfo == RIG_VFO_MAIN) { tx_vfo = RIG_VFO_A; vfo = RIG_VFO_B; }
6019 else if (tx_vfo == RIG_VFO_SUB) { tx_vfo = RIG_VFO_B; vfo = RIG_VFO_A; }
6020
6021 priv->tx_vfo = tx_vfo;
6022 priv->rx_vfo = vfo;
6023 }
6024
6025 /* ensure VFO A is Rx and VFO B is Tx as we assume that elsewhere */
6026 else if (VFO_HAS_A_B && (tx_vfo == RIG_VFO_A || tx_vfo == RIG_VFO_B))
6027 {
6028 rig_debug(RIG_DEBUG_TRACE, "%s: vfo clause 2\n", __func__);
6029 rig_debug(RIG_DEBUG_TRACE,
6030 "%s: rx_vfo to VFO_A, tx_vfo to VFO_B because tx_vfo=%s\n", __func__,
6031 rig_strvfo(tx_vfo));
6032
6033 if (tx_vfo == RIG_VFO_B)
6034 {
6035 priv->tx_vfo = RIG_VFO_B;
6036 priv->rx_vfo = vfo = RIG_VFO_A;
6037 }
6038 else
6039 {
6040 priv->tx_vfo = RIG_VFO_A;
6041 priv->rx_vfo = vfo = RIG_VFO_B;
6042 }
6043 }
6044 else if (VFO_HAS_MAIN_SUB_A_B_ONLY && (tx_vfo == RIG_VFO_MAIN
6045 || tx_vfo == RIG_VFO_SUB))
6046 {
6047 // do we need another case for tx_vfo = A/B ?
6048 rig_debug(RIG_DEBUG_TRACE, "%s: vfo clause 3\n", __func__);
6049 // if we're asking for split in this case we split Main on A/B
6050 priv->tx_vfo = RIG_VFO_SUB;
6051 priv->rx_vfo = RIG_VFO_MAIN;
6052 rig_debug(RIG_DEBUG_TRACE,
6053 "%s: tx=%s, rx=%s because tx_vfo=%s\n", __func__,
6054 rig_strvfo(priv->tx_vfo), rig_strvfo(priv->rx_vfo), rig_strvfo(tx_vfo));
6055 tx_vfo = RIG_VFO_SUB;
6056
6057 #if 0 // is this needed for satmode?
6058
6059 // make sure we're on Main/VFOA
6060 TRACE;
6061
6062 if (RIG_OK != (retval = icom_set_vfo(rig, RIG_VFO_MAIN)))
6063 {
6064 RETURNFUNC(retval);
6065 }
6066
6067 TRACE;
6068
6069 if (RIG_OK != (retval = icom_set_vfo(rig, RIG_VFO_A)))
6070 {
6071 RETURNFUNC(retval);
6072 }
6073
6074 #endif
6075 }
6076 else if (VFO_HAS_MAIN_SUB && (tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB))
6077 {
6078 rig_debug(RIG_DEBUG_TRACE, "%s: vfo clause 4\n", __func__);
6079 rig_debug(RIG_DEBUG_TRACE, "%s: set_vfo because tx_vfo=%s\n", __func__,
6080 rig_strvfo(tx_vfo));
6081
6082 #if 0 // do we need this for satmode?
6083
6084 TRACE;
6085
6086 if (RIG_OK != (retval = icom_set_vfo(rig, tx_vfo)))
6087 {
6088 RETURNFUNC(retval);
6089 }
6090
6091 #endif
6092
6093 priv->rx_vfo = vfo;
6094 priv->tx_vfo = tx_vfo;
6095 //vfo_final = RIG_VFO_MAIN;
6096
6097 split_sc = S_SPLT_ON;
6098 }
6099 else
6100 {
6101 rig_debug(RIG_DEBUG_ERR, "%s: split on vfo=%s not known\n", __func__,
6102 rig_strvfo(vfo));
6103 RETURNFUNC(-RIG_EINVAL);
6104 }
6105
6106 break;
6107
6108 default:
6109 rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %d", __func__, split);
6110 RETURNFUNC(-RIG_EINVAL);
6111 }
6112
6113 if (RIG_OK != (retval = icom_transaction(rig, C_CTL_SPLT, split_sc, NULL, 0,
6114 ackbuf, &ack_len)))
6115 {
6116 RETURNFUNC(retval);
6117 }
6118
6119 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
6120 {
6121 // if we don't get ACK/NAK some serial corruption occurred
6122 // so we'll call it a timeout for retry purposes
6123 RETURNFUNC(-RIG_ETIMEOUT);
6124 }
6125
6126 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
6127 {
6128 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
6129 ackbuf[0], ack_len);
6130 RETURNFUNC(-RIG_ERJCTED);
6131 }
6132
6133 priv->split_on = RIG_SPLIT_ON == split;
6134
6135 #if 0 // don't think we need this anymore -- 20210731
6136
6137 if (vfo_final != RIG_VFO_NONE && vfo_final != rig->state.current_vfo)
6138 {
6139 rig_debug(RIG_DEBUG_TRACE, "%s: vfo_final set %s\n", __func__,
6140 rig_strvfo(vfo_final));
6141 TRACE;
6142 retval = rig_set_vfo(rig, vfo_final);
6143
6144 if (retval != RIG_OK)
6145 {
6146 rig_debug(RIG_DEBUG_TRACE, "%s: vfo_final set failed? err=%s\n", __func__,
6147 rigerror(retval));
6148 }
6149 }
6150
6151 #endif
6152
6153 rig_debug(RIG_DEBUG_VERBOSE,
6154 "%s: vfo=%s curr_vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n",
6155 __func__, rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo),
6156 rig_strvfo(priv->rx_vfo),
6157 rig_strvfo(priv->tx_vfo), split);
6158 RETURNFUNC(RIG_OK);
6159 }
6160
6161 /*
6162 * icom_get_split_vfo
6163 * Assumes rig!=NULL, rig->state.priv!=NULL, split!=NULL
6164 *
6165 * Does not appear to be supported by any mode?
6166 * \sa icom_mem_get_split_vfo()
6167 */
icom_get_split_vfo(RIG * rig,vfo_t vfo,split_t * split,vfo_t * tx_vfo)6168 int icom_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo)
6169 {
6170 unsigned char splitbuf[MAXFRAMELEN];
6171 int split_len, retval, satmode = 0;
6172 struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv;
6173
6174 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
6175 retval = icom_transaction(rig, C_CTL_SPLT, -1, NULL, 0,
6176 splitbuf, &split_len);
6177
6178 if (retval != RIG_OK)
6179 {
6180 rig_debug(RIG_DEBUG_ERR, "%s: CTL_SPLT failed?\n", __func__);
6181 RETURNFUNC(retval);
6182 }
6183
6184 /*
6185 * splitbuf should contain Cn,Sc
6186 */
6187 split_len--;
6188
6189 if (split_len != 1)
6190 {
6191 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n",
6192 __func__, split_len);
6193 RETURNFUNC(-RIG_ERJCTED);
6194 }
6195
6196 switch (splitbuf[1])
6197 {
6198 case S_SPLT_OFF:
6199 *split = RIG_SPLIT_OFF;
6200 break;
6201
6202 case S_SPLT_ON:
6203 *split = RIG_SPLIT_ON;
6204 break;
6205
6206 // The same command indicates repeater shift state, which means that split is off
6207 case S_DUP_M:
6208 case S_DUP_P:
6209 case S_DUP_DD_RPS:
6210 *split = RIG_SPLIT_OFF;
6211 break;
6212
6213 default:
6214 rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %d", __func__,
6215 splitbuf[1]);
6216 RETURNFUNC(-RIG_EPROTO);
6217 }
6218
6219 if (rig->caps->has_get_func & RIG_FUNC_SATMODE)
6220 {
6221 rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode);
6222
6223 if (satmode != rig->state.cache.satmode)
6224 {
6225 rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): satmode changed to reset x25cmdfails\n",
6226 __func__, __LINE__);
6227 priv->x25cmdfails = satmode; // reset this so it tries again
6228 }
6229 }
6230
6231 rig->state.cache.satmode = satmode;
6232
6233 priv->split_on = RIG_SPLIT_ON == *split;
6234
6235 icom_get_split_vfos(rig, &priv->rx_vfo, &priv->tx_vfo);
6236
6237 *tx_vfo = priv->tx_vfo;
6238 rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n",
6239 __func__, rig_strvfo(vfo), rig_strvfo(priv->rx_vfo),
6240 rig_strvfo(priv->tx_vfo), *split);
6241 RETURNFUNC(RIG_OK);
6242 }
6243
6244
6245 /*
6246 * icom_mem_get_split_vfo
6247 * Assumes rig!=NULL, rig->state.priv!=NULL, split!=NULL
6248 */
icom_mem_get_split_vfo(RIG * rig,vfo_t vfo,split_t * split,vfo_t * tx_vfo)6249 int icom_mem_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split,
6250 vfo_t *tx_vfo)
6251 {
6252 int retval;
6253
6254 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
6255
6256 /* this hacks works only when in memory mode
6257 * I have no clue how to detect split in regular VFO mode
6258 */
6259 if (rig->state.current_vfo != RIG_VFO_MEM ||
6260 !rig_has_vfo_op(rig, RIG_OP_XCHG))
6261 {
6262 *split = rig->state.cache.split; // we set this but still return ENAVAIL
6263 RETURNFUNC(-RIG_ENAVAIL);
6264 }
6265
6266 retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
6267
6268 if (retval == RIG_OK)
6269 {
6270 *split = RIG_SPLIT_ON;
6271 /* get it back to normal */
6272 retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
6273
6274 if (retval != RIG_OK) { RETURNFUNC(retval); }
6275 }
6276 else if (retval == -RIG_ERJCTED)
6277 {
6278 *split = RIG_SPLIT_OFF;
6279 }
6280 else
6281 {
6282 /* this is really an error! */
6283 RETURNFUNC(retval);
6284 }
6285
6286 RETURNFUNC(RIG_OK);
6287 }
6288
6289 /*
6290 * icom_set_ts
6291 * Assumes rig!=NULL, rig->caps->priv!=NULL
6292 */
icom_set_ts(RIG * rig,vfo_t vfo,shortfreq_t ts)6293 int icom_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts)
6294 {
6295 const struct icom_priv_caps *priv_caps;
6296 unsigned char ackbuf[MAXFRAMELEN];
6297 int i, ack_len = sizeof(ackbuf), retval;
6298 int ts_sc = 0;
6299
6300 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
6301 priv_caps = (const struct icom_priv_caps *) rig->caps->priv;
6302
6303 for (i = 0; i < HAMLIB_TSLSTSIZ; i++)
6304 {
6305 if (priv_caps->ts_sc_list[i].ts == ts)
6306 {
6307 ts_sc = priv_caps->ts_sc_list[i].sc;
6308 break;
6309 }
6310 }
6311
6312 if (i >= HAMLIB_TSLSTSIZ)
6313 {
6314 RETURNFUNC(-RIG_EINVAL); /* not found, unsupported */
6315 }
6316
6317 retval = icom_transaction(rig, C_SET_TS, ts_sc, NULL, 0, ackbuf, &ack_len);
6318
6319 if (retval != RIG_OK)
6320 {
6321 RETURNFUNC(retval);
6322 }
6323
6324 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
6325 {
6326 // if we don't get ACK/NAK some serial corruption occurred
6327 // so we'll call it a timeout for retry purposes
6328 RETURNFUNC(-RIG_ETIMEOUT);
6329 }
6330
6331 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
6332 {
6333 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
6334 ackbuf[0], ack_len);
6335 RETURNFUNC(-RIG_ERJCTED);
6336 }
6337
6338 RETURNFUNC(RIG_OK);
6339 }
6340
6341 /*
6342 * icom_get_ts
6343 * Assumes rig!=NULL, rig->caps->priv!=NULL, ts!=NULL
6344 * NOTE: seems not to work (tested on IC-706MkIIG), please report --SF Not available on 746pro
6345 */
icom_get_ts(RIG * rig,vfo_t vfo,shortfreq_t * ts)6346 int icom_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts)
6347 {
6348 const struct icom_priv_caps *priv_caps;
6349 unsigned char tsbuf[MAXFRAMELEN];
6350 int ts_len, i, retval;
6351
6352 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
6353 priv_caps = (const struct icom_priv_caps *) rig->caps->priv;
6354
6355 retval = icom_transaction(rig, C_SET_TS, -1, NULL, 0, tsbuf, &ts_len);
6356
6357 if (retval != RIG_OK)
6358 {
6359 RETURNFUNC(retval);
6360 }
6361
6362 /*
6363 * tsbuf should contain Cn,Sc
6364 */
6365 ts_len--;
6366
6367 if (ts_len != 1)
6368 {
6369 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ts_len);
6370 RETURNFUNC(-RIG_ERJCTED);
6371 }
6372
6373 for (i = 0; i < HAMLIB_TSLSTSIZ; i++)
6374 {
6375 if (priv_caps->ts_sc_list[i].sc == tsbuf[1])
6376 {
6377 *ts = priv_caps->ts_sc_list[i].ts;
6378 break;
6379 }
6380 }
6381
6382 if (i >= HAMLIB_TSLSTSIZ)
6383 {
6384 RETURNFUNC(-RIG_EPROTO); /* not found, unsupported */
6385 }
6386
6387 RETURNFUNC(RIG_OK);
6388 }
6389
6390
6391 /*
6392 * icom_set_func
6393 * Assumes rig!=NULL, rig->state.priv!=NULL
6394 */
icom_set_func(RIG * rig,vfo_t vfo,setting_t func,int status)6395 int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
6396 {
6397 unsigned char fctbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN];
6398 int fct_len, ack_len, retval;
6399 int fct_cn, fct_sc; /* Command Number, Subcommand */
6400 struct rig_state *rs = &rig->state;
6401 struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv;
6402
6403 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
6404
6405 const struct icom_priv_caps *priv_caps = rig->caps->priv;
6406 const struct cmdparams *extcmds = priv_caps->extcmds;
6407 int i;
6408
6409 value_t value = { .i = status };
6410
6411 for (i = 0; extcmds && extcmds[i].id.s != 0; i++)
6412 {
6413 if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_FUNC && extcmds[i].id.s == func)
6414 {
6415 RETURNFUNC(icom_set_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], value));
6416 }
6417 }
6418
6419 fctbuf[0] = status ? 0x01 : 0x00;
6420 fct_len = 1;
6421
6422 switch (func)
6423 {
6424 case RIG_FUNC_NB:
6425 fct_cn = C_CTL_FUNC;
6426 fct_sc = S_FUNC_NB;
6427 break;
6428
6429 case RIG_FUNC_COMP: fct_cn = C_CTL_FUNC;
6430 fct_sc = S_FUNC_COMP;
6431 break;
6432
6433 case RIG_FUNC_VOX: fct_cn = C_CTL_FUNC;
6434 fct_sc = S_FUNC_VOX;
6435 break;
6436
6437 case RIG_FUNC_TONE: /* repeater tone */
6438 fct_cn = C_CTL_FUNC;
6439 fct_sc = S_FUNC_TONE;
6440 break;
6441
6442 case RIG_FUNC_TSQL: fct_cn = C_CTL_FUNC;
6443 fct_sc = S_FUNC_TSQL;
6444 break;
6445
6446 case RIG_FUNC_SBKIN: fct_cn = C_CTL_FUNC;
6447 fct_sc = S_FUNC_BKIN;
6448
6449 if (status != 0)
6450 {
6451 fctbuf[0] = 0x01;
6452 }
6453 else
6454 {
6455 fctbuf[0] = 0x00;
6456 }
6457
6458 break;
6459
6460 case RIG_FUNC_FBKIN:
6461 fct_cn = C_CTL_FUNC;
6462 fct_sc = S_FUNC_BKIN;
6463
6464 if (status != 0)
6465 {
6466 fctbuf[0] = 0x02;
6467 }
6468 else
6469 {
6470 fctbuf[0] = 0x00;
6471 }
6472
6473 break;
6474
6475 case RIG_FUNC_ANF:
6476 fct_cn = C_CTL_FUNC;
6477 fct_sc = S_FUNC_ANF;
6478 break;
6479
6480 case RIG_FUNC_NR:
6481 fct_cn = C_CTL_FUNC;
6482 fct_sc = S_FUNC_NR;
6483 break;
6484
6485 case RIG_FUNC_APF:
6486 fct_cn = C_CTL_FUNC;
6487 fct_sc = S_FUNC_APF;
6488 break;
6489
6490 case RIG_FUNC_MON:
6491 fct_cn = C_CTL_FUNC;
6492 fct_sc = S_FUNC_MON;
6493 break;
6494
6495 case RIG_FUNC_MN:
6496 fct_cn = C_CTL_FUNC;
6497 fct_sc = S_FUNC_MN;
6498 break;
6499
6500 case RIG_FUNC_RF:
6501 fct_cn = C_CTL_FUNC;
6502 fct_sc = S_FUNC_RF;
6503 break;
6504
6505 case RIG_FUNC_VSC:
6506 fct_cn = C_CTL_FUNC;
6507 fct_sc = S_FUNC_VSC;
6508 break;
6509
6510 case RIG_FUNC_LOCK:
6511 fct_cn = C_CTL_FUNC;
6512 fct_sc = S_FUNC_DIAL_LK;
6513 break;
6514
6515 case RIG_FUNC_AFC: /* IC-910H */
6516 fct_cn = C_CTL_FUNC;
6517 fct_sc = S_FUNC_AFC;
6518 break;
6519
6520 case RIG_FUNC_SCOPE:
6521 fct_cn = C_CTL_SCP;
6522 fct_sc = S_SCP_STS;
6523 fctbuf[0] = status;
6524 fct_len = 1;
6525 break;
6526
6527 case RIG_FUNC_SPECTRUM:
6528 fct_cn = C_CTL_SCP;
6529 fct_sc = S_SCP_DOP;
6530 fctbuf[0] = status;
6531 fct_len = 1;
6532 break;
6533
6534 case RIG_FUNC_SPECTRUM_HOLD:
6535 fct_cn = C_CTL_SCP;
6536 fct_sc = S_SCP_HLD;
6537
6538 fct_len = 2;
6539 fctbuf[0] = icom_get_spectrum_vfo(rig, vfo);
6540 fctbuf[1] = status;
6541 break;
6542
6543 case RIG_FUNC_RESUME: /* IC-910H & IC-746-Pro */
6544 fct_cn = C_CTL_SCAN;
6545 fct_sc = status ? S_SCAN_RSMON : S_SCAN_RSMOFF;
6546 fct_len = 0;
6547 break;
6548
6549 case RIG_FUNC_CSQL:
6550 fct_cn = C_CTL_FUNC;
6551 fct_sc = S_FUNC_CSQL;
6552 break;
6553
6554 case RIG_FUNC_DSQL:
6555 fct_cn = C_CTL_FUNC;
6556 fct_sc = S_FUNC_DSSQL;
6557
6558 if (status <= 2)
6559 {
6560 fctbuf[0] = status;
6561 }
6562 else
6563 {
6564 fctbuf[0] = 0;
6565 }
6566
6567 break;
6568
6569 case RIG_FUNC_AFLT:
6570 fct_cn = C_CTL_MEM;
6571 fct_sc = S_MEM_AFLT;
6572 break;
6573
6574 case RIG_FUNC_ANL:
6575 fct_cn = C_CTL_MEM;
6576 fct_sc = S_MEM_ANL;
6577 break;
6578
6579 case RIG_FUNC_AIP: /* IC-R8600 IP+ function, misusing AIP since RIG_FUNC_ word is full (32 bit) */
6580 fct_cn = C_CTL_MEM;
6581 fct_sc = S_FUNC_IPPLUS;
6582 break;
6583
6584 case RIG_FUNC_RIT:
6585 fct_cn = C_CTL_RIT;
6586 fct_sc = S_RIT;
6587 break;
6588
6589 case RIG_FUNC_XIT:
6590 fct_cn = C_CTL_RIT;
6591 fct_sc = S_XIT;
6592 break;
6593
6594 case RIG_FUNC_TUNER:
6595 fct_cn = C_CTL_PTT;
6596 fct_sc = S_ANT_TUN;
6597 break;
6598
6599 case RIG_FUNC_DUAL_WATCH:
6600 fct_cn = C_SET_VFO;
6601 fct_sc = S_DUAL;
6602 break;
6603
6604 case RIG_FUNC_SATMODE:
6605 if (rig->caps->rig_model == RIG_MODEL_IC910)
6606 {
6607 // Is the 910 the only one that uses this command?
6608 fct_cn = C_CTL_MEM;
6609 fct_sc = S_MEM_SATMODE910;
6610 }
6611 else
6612 {
6613 fct_cn = C_CTL_FUNC;
6614 fct_sc = S_MEM_SATMODE;
6615 }
6616
6617 priv->x25cmdfails =
6618 status; // we reset this to current status -- fails in SATMODE
6619 priv->x1cx03cmdfails = 0; // we reset this to try it again
6620 rig->state.cache.satmode = status;
6621
6622 break;
6623
6624
6625 default:
6626 rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__,
6627 rig_strfunc(func));
6628 RETURNFUNC(-RIG_EINVAL);
6629 }
6630
6631 retval = icom_transaction(rig, fct_cn, fct_sc, fctbuf, fct_len, ackbuf,
6632 &ack_len);
6633
6634 if (retval != RIG_OK)
6635 {
6636 RETURNFUNC(retval);
6637 }
6638
6639 if (ack_len != 1)
6640 {
6641 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ack_len);
6642 RETURNFUNC(-RIG_EPROTO);
6643 }
6644
6645 // turning satmode on/off can change the tx/rx vfos
6646 // when in satmode split=off always
6647 if (VFO_HAS_MAIN_SUB_A_B_ONLY)
6648 {
6649 vfo_t tx_vfo;
6650 split_t split;
6651
6652 // update split status
6653 retval = icom_get_split_vfo(rig, RIG_VFO_CURR, &split, &tx_vfo);
6654
6655 if (retval != RIG_OK) { RETURNFUNC(retval); }
6656
6657 priv->tx_vfo = RIG_VFO_A;
6658
6659 if (priv->split_on) // must have turned off satmode
6660 {
6661 priv->tx_vfo = RIG_VFO_B;
6662 }
6663 else if (status) // turned on satmode so tx is always Sub
6664 {
6665 priv->tx_vfo = RIG_VFO_SUB;
6666 }
6667 }
6668
6669 RETURNFUNC(RIG_OK);
6670 }
6671
6672 /*
6673 * icom_get_func
6674 * Assumes rig!=NULL, rig->state.priv!=NULL
6675 * FIXME: IC8500 and no-sc, any support?
6676 */
icom_get_func(RIG * rig,vfo_t vfo,setting_t func,int * status)6677 int icom_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status)
6678 {
6679 unsigned char ackbuf[MAXFRAMELEN];
6680 int ack_len = sizeof(ackbuf), retval;
6681 int fct_cn, fct_sc; /* Command Number, Subcommand */
6682 unsigned char fctbuf[MAXFRAMELEN];
6683 int fct_len = 0;
6684
6685 const struct icom_priv_caps *priv_caps = rig->caps->priv;
6686 const struct cmdparams *extcmds = priv_caps->extcmds;
6687 int i;
6688
6689 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
6690
6691 value_t value;
6692
6693 for (i = 0; extcmds && extcmds[i].id.s != 0; i++)
6694 {
6695 rig_debug(RIG_DEBUG_TRACE, "%s: i=%d\n", __func__, i);
6696
6697 if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_FUNC && extcmds[i].id.s == func)
6698 {
6699 int result = icom_get_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], &value);
6700
6701 if (result == RIG_OK)
6702 {
6703 *status = value.i;
6704 }
6705
6706 RETURNFUNC(result);
6707 }
6708 }
6709
6710 switch (func)
6711 {
6712 case RIG_FUNC_NB:
6713 fct_cn = C_CTL_FUNC;
6714 fct_sc = S_FUNC_NB;
6715 break;
6716
6717 case RIG_FUNC_COMP: fct_cn = C_CTL_FUNC;
6718 fct_sc = S_FUNC_COMP;
6719 break;
6720
6721 case RIG_FUNC_VOX: fct_cn = C_CTL_FUNC;
6722 fct_sc = S_FUNC_VOX;
6723 break;
6724
6725 case RIG_FUNC_TONE: /* repeater tone */
6726 fct_cn = C_CTL_FUNC;
6727 fct_sc = S_FUNC_TONE;
6728 break;
6729
6730 case RIG_FUNC_TSQL: fct_cn = C_CTL_FUNC;
6731 fct_sc = S_FUNC_TSQL;
6732 break;
6733
6734 case RIG_FUNC_SBKIN: /* returns 1 for semi and 2 for full adjusted below */
6735 case RIG_FUNC_FBKIN: fct_cn = C_CTL_FUNC;
6736 fct_sc = S_FUNC_BKIN;
6737 break;
6738
6739 case RIG_FUNC_ANF: fct_cn = C_CTL_FUNC;
6740 fct_sc = S_FUNC_ANF;
6741 break;
6742
6743 case RIG_FUNC_NR: fct_cn = C_CTL_FUNC;
6744 fct_sc = S_FUNC_NR;
6745 break;
6746
6747 case RIG_FUNC_APF: fct_cn = C_CTL_FUNC;
6748 fct_sc = S_FUNC_APF;
6749 break;
6750
6751 case RIG_FUNC_MON: fct_cn = C_CTL_FUNC;
6752 fct_sc = S_FUNC_MON;
6753 break;
6754
6755 case RIG_FUNC_MN: fct_cn = C_CTL_FUNC;
6756 fct_sc = S_FUNC_MN;
6757 break;
6758
6759 case RIG_FUNC_RF: fct_cn = C_CTL_FUNC;
6760 fct_sc = S_FUNC_RF;
6761 break;
6762
6763 case RIG_FUNC_VSC: fct_cn = C_CTL_FUNC;
6764 fct_sc = S_FUNC_VSC;
6765 break;
6766
6767 case RIG_FUNC_LOCK: fct_cn = C_CTL_FUNC;
6768 fct_sc = S_FUNC_DIAL_LK;
6769 break;
6770
6771 case RIG_FUNC_AFC: /* IC-910H */
6772 fct_cn = C_CTL_FUNC;
6773 fct_sc = S_FUNC_AFC;
6774 break;
6775
6776 case RIG_FUNC_SCOPE:
6777 fct_cn = C_CTL_SCP;
6778 fct_sc = S_SCP_STS;
6779 break;
6780
6781 case RIG_FUNC_SPECTRUM:
6782 fct_cn = C_CTL_SCP;
6783 fct_sc = S_SCP_DOP;
6784 break;
6785
6786 case RIG_FUNC_SPECTRUM_HOLD:
6787 fct_cn = C_CTL_SCP;
6788 fct_sc = S_SCP_HLD;
6789
6790 fctbuf[0] = icom_get_spectrum_vfo(rig, vfo);
6791 fct_len = 1;
6792 break;
6793
6794 case RIG_FUNC_AIP: /* IC-R8600 IP+ function, misusing AIP since RIG_FUNC_ word is full (32 bit) */
6795 fct_cn = C_CTL_MEM; /* 1a */
6796 fct_sc = S_FUNC_IPPLUS;
6797 break;
6798
6799 case RIG_FUNC_CSQL: fct_cn = C_CTL_FUNC;
6800 fct_sc = S_FUNC_CSQL;
6801 break;
6802
6803 case RIG_FUNC_DSQL: fct_cn = C_CTL_FUNC;
6804 fct_sc = S_FUNC_DSSQL;
6805 break;
6806
6807 case RIG_FUNC_AFLT: fct_cn = C_CTL_MEM;
6808 fct_sc = S_MEM_AFLT;
6809 break;
6810
6811 case RIG_FUNC_ANL: fct_cn = C_CTL_MEM;
6812 fct_sc = S_MEM_ANL;
6813 break;
6814
6815 case RIG_FUNC_RIT: fct_cn = C_CTL_RIT;
6816 fct_sc = S_RIT;
6817 break;
6818
6819 case RIG_FUNC_XIT: fct_cn = C_CTL_RIT;
6820 fct_sc = S_XIT;
6821 break;
6822
6823 case RIG_FUNC_TUNER: fct_cn = C_CTL_PTT;
6824 fct_sc = S_ANT_TUN;
6825 break;
6826
6827 case RIG_FUNC_DUAL_WATCH: fct_cn = C_SET_VFO;
6828 fct_sc = S_DUAL;
6829 break;
6830
6831 case RIG_FUNC_SATMODE:
6832 if (rig->caps->rig_model == RIG_MODEL_IC910)
6833 {
6834 // Is the 910 the only one that uses this command?
6835 fct_cn = C_CTL_MEM;
6836 fct_sc = S_MEM_SATMODE910;
6837 }
6838 else
6839 {
6840 fct_cn = C_CTL_FUNC;
6841 fct_sc = S_MEM_SATMODE;
6842 }
6843
6844 break;
6845
6846 default:
6847 rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s\n", __func__,
6848 rig_strfunc(func));
6849 RETURNFUNC(-RIG_EINVAL);
6850 }
6851
6852 retval = icom_transaction(rig, fct_cn, fct_sc, fctbuf, fct_len, ackbuf,
6853 &ack_len);
6854
6855 if (retval != RIG_OK)
6856 {
6857 RETURNFUNC(retval);
6858 }
6859
6860 if (ack_len != (3 + fct_len))
6861 {
6862 rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__,
6863 ack_len);
6864 RETURNFUNC(-RIG_EPROTO);
6865 }
6866
6867 if (func == RIG_FUNC_FBKIN)
6868 {
6869 *status = ackbuf[2] == 2 ? 1 : 0;
6870 }
6871 else if (func == RIG_FUNC_SATMODE)
6872 {
6873 struct rig_state *rs = &rig->state;
6874 struct icom_priv_data *priv = rs->priv;
6875
6876 *status = ackbuf[2 + fct_len];
6877
6878 // we'll reset this based on current status
6879 priv->x25cmdfails = *status;
6880 }
6881 else
6882 {
6883 *status = ackbuf[2 + fct_len];
6884 }
6885
6886 RETURNFUNC(RIG_OK);
6887 }
6888
6889 /*
6890 * icom_set_parm
6891 * Assumes rig!=NULL
6892 *
6893 * NOTE: Most of the parm commands are rig-specific.
6894 *
6895 * See the IC-7300 backend how to implement them for newer rigs that have 0x1A 0x05-based commands.
6896 *
6897 * For older rigs, see the IC-R75 backend where icom_set_raw()/icom_get_raw() are used.
6898 */
icom_set_parm(RIG * rig,setting_t parm,value_t val)6899 int icom_set_parm(RIG *rig, setting_t parm, value_t val)
6900 {
6901 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
6902
6903 int i;
6904 const struct icom_priv_caps *priv = rig->caps->priv;
6905 const struct cmdparams *extcmds = priv->extcmds;
6906
6907 for (i = 0; extcmds && extcmds[i].id.s != 0; i++)
6908 {
6909 if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_PARM && extcmds[i].id.s == parm)
6910 {
6911 RETURNFUNC(icom_set_cmd(rig, RIG_VFO_NONE, (struct cmdparams *)&extcmds[i],
6912 val));
6913 }
6914 }
6915
6916 switch (parm)
6917 {
6918 case RIG_PARM_ANN:
6919 {
6920 int ann_mode;
6921
6922 switch (val.i)
6923 {
6924 case RIG_ANN_OFF:
6925 ann_mode = S_ANN_ALL;
6926 break;
6927
6928 case RIG_ANN_FREQ:
6929 ann_mode = S_ANN_FREQ;
6930 break;
6931
6932 case RIG_ANN_RXMODE:
6933 ann_mode = S_ANN_MODE;
6934 break;
6935
6936 default:
6937 rig_debug(RIG_DEBUG_ERR, "%s: unsupported RIG_PARM_ANN %d\n",
6938 __func__, val.i);
6939 RETURNFUNC(-RIG_EINVAL);
6940 }
6941
6942 RETURNFUNC(icom_set_raw(rig, C_CTL_ANN, ann_mode, 0, NULL, 0, 0));
6943 }
6944
6945 default:
6946 rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_parm %s\n", __func__,
6947 rig_strparm(parm));
6948 RETURNFUNC(-RIG_EINVAL);
6949 }
6950 }
6951
6952 /*
6953 * icom_get_parm
6954 * Assumes rig!=NULL
6955 *
6956 * NOTE: Most of the parm commands are rig-specific.
6957 *
6958 * See the IC-7300 backend how to implement them for newer rigs that have 0x1A 0x05-based commands.
6959 *
6960 * For older rigs, see the IC-R75 backend where icom_set_raw()/icom_get_raw() are used.
6961 */
icom_get_parm(RIG * rig,setting_t parm,value_t * val)6962 int icom_get_parm(RIG *rig, setting_t parm, value_t *val)
6963 {
6964 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
6965
6966 const struct icom_priv_caps *priv = rig->caps->priv;
6967 const struct cmdparams *cmd = priv->extcmds;
6968 int i;
6969
6970 for (i = 0; cmd && cmd[i].id.s != 0; i++)
6971 {
6972 if (cmd[i].cmdparamtype == CMD_PARAM_TYPE_PARM && cmd[i].id.s == parm)
6973 {
6974 RETURNFUNC(icom_get_cmd(rig, RIG_VFO_NONE, (struct cmdparams *)&cmd[i], val));
6975 }
6976 }
6977
6978 switch (parm)
6979 {
6980 default:
6981 rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_parm %s", __func__,
6982 rig_strparm(parm));
6983 RETURNFUNC(-RIG_EINVAL);
6984 }
6985
6986 RETURNFUNC(RIG_OK);
6987 }
6988
6989 /*
6990 * icom_set_ctcss_tone
6991 * Assumes rig!=NULL, rig->state.priv!=NULL
6992 *
6993 * Works for 746 pro and should work for 756 xx and 7800
6994 */
icom_set_ctcss_tone(RIG * rig,vfo_t vfo,tone_t tone)6995 int icom_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone)
6996 {
6997 const struct rig_caps *caps;
6998 unsigned char tonebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN];
6999 int tone_len, ack_len = sizeof(ackbuf), retval;
7000
7001 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7002 caps = rig->caps;
7003
7004 if (caps->ctcss_list)
7005 {
7006 int i;
7007
7008 for (i = 0; caps->ctcss_list[i] != 0; i++)
7009 {
7010 if (caps->ctcss_list[i] == tone)
7011 {
7012 break;
7013 }
7014 }
7015
7016 if (caps->ctcss_list[i] != tone)
7017 {
7018 RETURNFUNC(-RIG_EINVAL);
7019 }
7020 }
7021
7022 /* Sent as frequency in tenth of Hz */
7023
7024 tone_len = 3;
7025 to_bcd_be(tonebuf, tone, tone_len * 2);
7026
7027 retval = icom_transaction(rig, C_SET_TONE, S_TONE_RPTR,
7028 tonebuf, tone_len, ackbuf, &ack_len);
7029
7030 if (retval != RIG_OK)
7031 {
7032 RETURNFUNC(retval);
7033 }
7034
7035 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
7036 {
7037 // if we don't get ACK/NAK some serial corruption occurred
7038 // so we'll call it a timeout for retry purposes
7039 RETURNFUNC(-RIG_ETIMEOUT);
7040 }
7041
7042 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
7043 {
7044 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7045 ackbuf[0], ack_len);
7046 RETURNFUNC(-RIG_ERJCTED);
7047 }
7048
7049 RETURNFUNC(RIG_OK);
7050 }
7051
7052 /*
7053 * icom_get_ctcss_tone
7054 * Assumes rig!=NULL, rig->state.priv!=NULL
7055 */
icom_get_ctcss_tone(RIG * rig,vfo_t vfo,tone_t * tone)7056 int icom_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone)
7057 {
7058 const struct rig_caps *caps;
7059 unsigned char tonebuf[MAXFRAMELEN];
7060 int tone_len, retval;
7061 int i;
7062
7063 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7064 caps = rig->caps;
7065
7066 retval = icom_transaction(rig, C_SET_TONE, S_TONE_RPTR, NULL, 0,
7067 tonebuf, &tone_len);
7068
7069 if (retval != RIG_OK)
7070 {
7071 RETURNFUNC(retval);
7072 }
7073
7074 /* cn,sc,data*3 */
7075 if (tone_len != 5)
7076 {
7077 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7078 tonebuf[0], tone_len);
7079 RETURNFUNC(-RIG_ERJCTED);
7080 }
7081
7082 tone_len -= 2;
7083 *tone = from_bcd_be(tonebuf + 2, tone_len * 2);
7084
7085 if (!caps->ctcss_list)
7086 {
7087 RETURNFUNC(RIG_OK);
7088 }
7089
7090 /* check this tone exists. That's better than nothing. */
7091 for (i = 0; caps->ctcss_list[i] != 0; i++)
7092 {
7093 if (caps->ctcss_list[i] == *tone)
7094 {
7095 RETURNFUNC(RIG_OK);
7096 }
7097 }
7098
7099 rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%#.2x)\n", __func__, tonebuf[2]);
7100 RETURNFUNC(-RIG_EPROTO);
7101 }
7102
7103 /*
7104 * icom_set_ctcss_sql
7105 * Assumes rig!=NULL, rig->state.priv!=NULL
7106 */
icom_set_ctcss_sql(RIG * rig,vfo_t vfo,tone_t tone)7107 int icom_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone)
7108 {
7109 const struct rig_caps *caps;
7110 unsigned char tonebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN];
7111 int tone_len, ack_len = sizeof(ackbuf), retval;
7112 int i;
7113
7114 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7115 caps = rig->caps;
7116
7117 for (i = 0; caps->ctcss_list[i] != 0; i++)
7118 {
7119 if (caps->ctcss_list[i] == tone)
7120 {
7121 break;
7122 }
7123 }
7124
7125 if (caps->ctcss_list[i] != tone)
7126 {
7127 RETURNFUNC(-RIG_EINVAL);
7128 }
7129
7130 /* Sent as frequency in tenth of Hz */
7131
7132 tone_len = 3;
7133 to_bcd_be(tonebuf, tone, tone_len * 2);
7134
7135 retval = icom_transaction(rig, C_SET_TONE, S_TONE_SQL,
7136 tonebuf, tone_len, ackbuf, &ack_len);
7137
7138 if (retval != RIG_OK)
7139 {
7140 RETURNFUNC(retval);
7141 }
7142
7143 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
7144 {
7145 // if we don't get ACK/NAK some serial corruption occurred
7146 // so we'll call it a timeout for retry purposes
7147 RETURNFUNC(-RIG_ETIMEOUT);
7148 }
7149
7150 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
7151 {
7152 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7153 ackbuf[0], ack_len);
7154 RETURNFUNC(-RIG_ERJCTED);
7155 }
7156
7157 RETURNFUNC(RIG_OK);
7158 }
7159
7160 /*
7161 * icom_get_ctcss_sql
7162 * Assumes rig!=NULL, rig->state.priv!=NULL
7163 */
icom_get_ctcss_sql(RIG * rig,vfo_t vfo,tone_t * tone)7164 int icom_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone)
7165 {
7166 const struct rig_caps *caps;
7167 unsigned char tonebuf[MAXFRAMELEN];
7168 int tone_len, retval;
7169 int i;
7170
7171 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7172 caps = rig->caps;
7173
7174 retval = icom_transaction(rig, C_SET_TONE, S_TONE_SQL, NULL, 0,
7175 tonebuf, &tone_len);
7176
7177 if (retval != RIG_OK)
7178 {
7179 RETURNFUNC(retval);
7180 }
7181
7182 if (tone_len != 5)
7183 {
7184 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7185 tonebuf[0], tone_len);
7186 RETURNFUNC(-RIG_ERJCTED);
7187 }
7188
7189 tone_len -= 2;
7190 *tone = from_bcd_be(tonebuf + 2, tone_len * 2);
7191
7192 /* check this tone exists. That's better than nothing. */
7193 for (i = 0; caps->ctcss_list[i] != 0; i++)
7194 {
7195 if (caps->ctcss_list[i] == *tone)
7196 {
7197 RETURNFUNC(RIG_OK);
7198 }
7199 }
7200
7201 rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%#.2x)\n", __func__, tonebuf[2]);
7202 RETURNFUNC(-RIG_EPROTO);
7203 }
7204
7205 /*
7206 * icom_set_dcs_code
7207 * Assumes rig!=NULL, rig->state.priv!=NULL
7208 */
icom_set_dcs_code(RIG * rig,vfo_t vfo,tone_t code)7209 int icom_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code)
7210 {
7211 const struct rig_caps *caps;
7212 unsigned char codebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN];
7213 int code_len, ack_len = sizeof(ackbuf), retval;
7214 int i;
7215
7216 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7217 caps = rig->caps;
7218
7219 for (i = 0; caps->dcs_list[i] != 0; i++)
7220 {
7221 if (caps->dcs_list[i] == code)
7222 {
7223 break;
7224 }
7225 }
7226
7227 if (caps->dcs_list[i] != code)
7228 {
7229 RETURNFUNC(-RIG_EINVAL);
7230 }
7231
7232 /* DCS Polarity ignored, by setting code_len to 3 it's foretval to 0 (= Tx:norm, Rx:norm). */
7233 code_len = 3;
7234 to_bcd_be(codebuf, code, code_len * 2);
7235
7236 retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS,
7237 codebuf, code_len, ackbuf, &ack_len);
7238
7239 if (retval != RIG_OK)
7240 {
7241 RETURNFUNC(retval);
7242 }
7243
7244 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
7245 {
7246 // if we don't get ACK/NAK some serial corruption occurred
7247 // so we'll call it a timeout for retry purposes
7248 RETURNFUNC(-RIG_ETIMEOUT);
7249 }
7250
7251 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
7252 {
7253 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7254 ackbuf[0], ack_len);
7255 RETURNFUNC(-RIG_ERJCTED);
7256 }
7257
7258 RETURNFUNC(RIG_OK);
7259 }
7260
7261 /*
7262 * icom_get_dcs_code
7263 * Assumes rig!=NULL, rig->state.priv!=NULL
7264 */
icom_get_dcs_code(RIG * rig,vfo_t vfo,tone_t * code)7265 int icom_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code)
7266 {
7267 const struct rig_caps *caps;
7268 unsigned char codebuf[MAXFRAMELEN];
7269 int code_len, retval;
7270 int i;
7271
7272 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7273 caps = rig->caps;
7274
7275 retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS, NULL, 0,
7276 codebuf, &code_len);
7277
7278 if (retval != RIG_OK)
7279 {
7280 RETURNFUNC(retval);
7281 }
7282
7283 /* cn,sc,data*3 */
7284 if (code_len != 5)
7285 {
7286 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7287 codebuf[0], code_len);
7288 RETURNFUNC(-RIG_ERJCTED);
7289 }
7290
7291 /* buf is cn,sc, polarity, code_lo, code_hi, so code bytes start at 3, len is 2
7292 polarity is not decoded yet, hard to do without breaking ABI
7293 */
7294
7295 code_len -= 3;
7296 *code = from_bcd_be(codebuf + 3, code_len * 2);
7297
7298 /* check this code exists. That's better than nothing. */
7299 for (i = 0; caps->dcs_list[i] != 0; i++)
7300 {
7301 if (caps->dcs_list[i] == *code)
7302 {
7303 RETURNFUNC(RIG_OK);
7304 }
7305 }
7306
7307 rig_debug(RIG_DEBUG_ERR, "%s: DTCS NG (%#.2x)\n", __func__, codebuf[2]);
7308 RETURNFUNC(-RIG_EPROTO);
7309 }
7310
7311 /*
7312 * icom_set_dcs_sql
7313 * Assumes rig!=NULL, rig->state.priv!=NULL
7314 */
icom_set_dcs_sql(RIG * rig,vfo_t vfo,tone_t code)7315 int icom_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code)
7316 {
7317 const struct rig_caps *caps;
7318 unsigned char codebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN];
7319 int code_len, ack_len = sizeof(ackbuf), retval;
7320 int i;
7321
7322 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7323 caps = rig->caps;
7324
7325 for (i = 0; caps->dcs_list[i] != 0; i++)
7326 {
7327 if (caps->dcs_list[i] == code)
7328 {
7329 break;
7330 }
7331 }
7332
7333 if (caps->dcs_list[i] != code)
7334 {
7335 RETURNFUNC(-RIG_EINVAL);
7336 }
7337
7338 /* DCS Polarity ignored, by setting code_len to 3 it's forced to 0 (= Tx:norm, Rx:norm). */
7339 code_len = 3;
7340 to_bcd_be(codebuf, code, code_len * 2);
7341
7342 retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS,
7343 codebuf, code_len, ackbuf, &ack_len);
7344
7345 if (retval != RIG_OK)
7346 {
7347 RETURNFUNC(retval);
7348 }
7349
7350 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
7351 {
7352 // if we don't get ACK/NAK some serial corruption occurred
7353 // so we'll call it a timeout for retry purposes
7354 RETURNFUNC(-RIG_ETIMEOUT);
7355 }
7356
7357 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
7358 {
7359 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7360 ackbuf[0], ack_len);
7361 RETURNFUNC(-RIG_ERJCTED);
7362 }
7363
7364 RETURNFUNC(RIG_OK);
7365 }
7366
7367 /*
7368 * icom_get_dcs_sql
7369 * Assumes rig!=NULL, rig->state.priv!=NULL
7370 */
icom_get_dcs_sql(RIG * rig,vfo_t vfo,tone_t * code)7371 int icom_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code)
7372 {
7373 const struct rig_caps *caps;
7374 unsigned char codebuf[MAXFRAMELEN];
7375 int code_len, retval;
7376 int i;
7377
7378 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7379 caps = rig->caps;
7380
7381 retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS, NULL, 0,
7382 codebuf, &code_len);
7383
7384 if (retval != RIG_OK)
7385 {
7386 RETURNFUNC(retval);
7387 }
7388
7389 /* cn,sc,data*3 */
7390 if (code_len != 5)
7391 {
7392 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7393 codebuf[0], code_len);
7394 RETURNFUNC(-RIG_ERJCTED);
7395 }
7396
7397 /* buf is cn,sc, polarity, code_lo, code_hi, so code bytes start at 3, len is 2
7398 polarity is not decoded yet, hard to do without breaking ABI
7399 */
7400
7401 code_len -= 3;
7402 *code = from_bcd_be(codebuf + 3, code_len * 2);
7403
7404 /* check this code exists. That's better than nothing. */
7405 for (i = 0; caps->dcs_list[i] != 0; i++)
7406 {
7407 if (caps->dcs_list[i] == *code)
7408 {
7409 RETURNFUNC(RIG_OK);
7410 }
7411 }
7412
7413 rig_debug(RIG_DEBUG_ERR, "%s: DTCS NG (%#.2x)\n", __func__, codebuf[2]);
7414 RETURNFUNC(-RIG_EPROTO);
7415 }
7416
7417 /*
7418 * icom_set_powerstat
7419 * Assumes rig!=NULL, rig->state.priv!=NULL
7420 */
icom_set_powerstat(RIG * rig,powerstat_t status)7421 int icom_set_powerstat(RIG *rig, powerstat_t status)
7422 {
7423 unsigned char ackbuf[200];
7424 int ack_len = sizeof(ackbuf), retval = RIG_OK;
7425 int pwr_sc;
7426 // so we'll do up to 175 for 115,200
7427 int fe_max = 175;
7428 unsigned char fe_buf[fe_max]; // for FE's to power up
7429 int i;
7430 int retry;
7431 struct rig_state *rs = &rig->state;
7432 struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv;
7433
7434 rig_debug(RIG_DEBUG_VERBOSE, "%s called status=%d\n", __func__,
7435 (int) status);
7436
7437 switch (status)
7438 {
7439 case RIG_POWER_ON:
7440
7441 sleep(1); // let serial bus idle for a while
7442 rig_debug(RIG_DEBUG_TRACE, "%s: PWR_ON failed, trying 0xfe's\n",
7443 __func__);
7444 // ic7300 manual says ~150 for 115,200
7445 // we'll just send a few more to be sure for all speeds
7446 memset(fe_buf, 0xfe, fe_max);
7447 // sending more than enough 0xfe's to wake up the rs232
7448 write_block(&rs->rigport, (char *) fe_buf, fe_max);
7449
7450 hl_usleep(100 * 1000);
7451 // we'll try 0x18 0x01 now -- should work on STBY rigs too
7452 pwr_sc = S_PWR_ON;
7453 fe_buf[0] = 0;
7454 retry = rs->rigport.retry;
7455 rs->rigport.retry = 0;
7456 priv->serial_USB_echo_off = 1;
7457 retval =
7458 icom_transaction(rig, C_SET_PWR, pwr_sc, NULL, 0, ackbuf, &ack_len);
7459 rs->rigport.retry = retry;
7460 // why was this sleep here? We'll try without it
7461 //hl_usleep(3000 * 1000); // give it 3 seconds to wake up
7462
7463 break;
7464
7465 default:
7466 pwr_sc = S_PWR_OFF;
7467 fe_buf[0] = 0;
7468 retry = rs->rigport.retry;
7469 rs->rigport.retry = 0;
7470 retval =
7471 icom_transaction(rig, C_SET_PWR, pwr_sc, NULL, 0, ackbuf, &ack_len);
7472 rs->rigport.retry = retry;
7473 }
7474
7475 i = 0;
7476 retry = 1;
7477
7478 if (status == RIG_POWER_ON) // wait for wakeup only
7479 {
7480
7481 for (i = 0; i < retry; ++i) // up to 10 attempts
7482 {
7483 freq_t freq;
7484 sleep(1);
7485 // need to see if echo is on or not first
7486 // until such time as rig is awake we don't know
7487 icom_get_usb_echo_off(rig);
7488
7489 // Use get_freq as all rigs should repond to this
7490 retval = rig_get_freq(rig, RIG_VFO_CURR, &freq);
7491
7492 if (retval == RIG_OK)
7493 {
7494 RETURNFUNC(retval);
7495 }
7496 else
7497 {
7498 rig_debug(RIG_DEBUG_TRACE, "%s: get_freq err=%s\n", __func__,
7499 rigerror(retval));
7500 }
7501
7502 rig_debug(RIG_DEBUG_TRACE, "%s: Wait %d of %d for get_powerstat\n",
7503 __func__, i + 1, retry);
7504 }
7505 }
7506
7507 if (i == retry)
7508 {
7509 rig_debug(RIG_DEBUG_TRACE, "%s: Wait failed for get_powerstat\n",
7510 __func__);
7511 retval = -RIG_ETIMEOUT;
7512 }
7513
7514 if (retval != RIG_OK)
7515 {
7516 rig_debug(RIG_DEBUG_TRACE, "%s: retval != RIG_OK, =%s\n", __func__,
7517 rigerror(retval));
7518 RETURNFUNC(retval);
7519 }
7520
7521 if (status == RIG_POWER_OFF && (ack_len != 1 || (ack_len >= 1
7522 && ackbuf[0] != ACK)))
7523 {
7524 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7525 ackbuf[0], ack_len);
7526 RETURNFUNC(-RIG_ERJCTED);
7527 }
7528
7529 RETURNFUNC(RIG_OK);
7530 }
7531
7532 /*
7533 * icom_get_powerstat
7534 * Assumes rig!=NULL, rig->state.priv!=NULL
7535 */
icom_get_powerstat(RIG * rig,powerstat_t * status)7536 int icom_get_powerstat(RIG *rig, powerstat_t *status)
7537 {
7538 unsigned char ackbuf[MAXFRAMELEN];
7539 int ack_len = sizeof(ackbuf), retval;
7540
7541 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7542
7543 /* r75 has no way to get power status, so fake it */
7544 if (rig->caps->rig_model == RIG_MODEL_ICR75)
7545 {
7546 /* getting the mode doesn't work if a memory is blank */
7547 /* so use one of the more innculous 'set mode' commands instead */
7548 int cmd_len = 1;
7549 unsigned char cmdbuf[MAXFRAMELEN];
7550 cmdbuf[0] = S_PRM_TIME;
7551 retval = icom_transaction(rig, C_CTL_MEM, S_MEM_MODE_SLCT,
7552 cmdbuf, cmd_len, ackbuf, &ack_len);
7553
7554 if (retval != RIG_OK)
7555 {
7556 RETURNFUNC(retval);
7557 }
7558
7559 *status = ((ack_len == 6) && (ackbuf[0] == C_CTL_MEM)) ?
7560 RIG_POWER_ON : RIG_POWER_OFF;
7561 }
7562 else
7563 {
7564 retval = icom_transaction(rig, C_SET_PWR, -1, NULL, 0,
7565 ackbuf, &ack_len);
7566
7567 if (retval != RIG_OK)
7568 {
7569 RETURNFUNC(retval);
7570 }
7571
7572 *status = ackbuf[1] == S_PWR_ON ? RIG_POWER_ON : RIG_POWER_OFF;
7573 }
7574
7575 RETURNFUNC(RIG_OK);
7576 }
7577
7578
7579 /*
7580 * icom_set_mem
7581 * Assumes rig!=NULL, rig->state.priv!=NULL
7582 */
icom_set_mem(RIG * rig,vfo_t vfo,int ch)7583 int icom_set_mem(RIG *rig, vfo_t vfo, int ch)
7584 {
7585 unsigned char membuf[2];
7586 unsigned char ackbuf[MAXFRAMELEN];
7587 int ack_len = sizeof(ackbuf), retval;
7588 int chan_len;
7589
7590 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7591 chan_len = ch < 100 ? 1 : 2;
7592
7593 to_bcd_be(membuf, ch, chan_len * 2);
7594 retval = icom_transaction(rig, C_SET_MEM, -1, membuf, chan_len,
7595 ackbuf, &ack_len);
7596
7597 if (retval != RIG_OK)
7598 {
7599 RETURNFUNC(retval);
7600 }
7601
7602 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
7603 {
7604 // if we don't get ACK/NAK some serial corruption occurred
7605 // so we'll call it a timeout for retry purposes
7606 RETURNFUNC(-RIG_ETIMEOUT);
7607 }
7608
7609 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
7610 {
7611 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7612 ackbuf[0], ack_len);
7613 RETURNFUNC(-RIG_ERJCTED);
7614 }
7615
7616 RETURNFUNC(RIG_OK);
7617 }
7618
7619 /*
7620 * icom_set_bank
7621 * Assumes rig!=NULL, rig->state.priv!=NULL
7622 */
icom_set_bank(RIG * rig,vfo_t vfo,int bank)7623 int icom_set_bank(RIG *rig, vfo_t vfo, int bank)
7624 {
7625 unsigned char bankbuf[2];
7626 unsigned char ackbuf[MAXFRAMELEN];
7627 int ack_len = sizeof(ackbuf), retval;
7628
7629 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7630 to_bcd_be(bankbuf, bank, BANK_NB_LEN * 2);
7631 retval = icom_transaction(rig, C_SET_MEM, S_BANK,
7632 bankbuf, CHAN_NB_LEN, ackbuf, &ack_len);
7633
7634 if (retval != RIG_OK)
7635 {
7636 RETURNFUNC(retval);
7637 }
7638
7639 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
7640 {
7641 // if we don't get ACK/NAK some serial corruption occurred
7642 // so we'll call it a timeout for retry purposes
7643 RETURNFUNC(-RIG_ETIMEOUT);
7644 }
7645
7646 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
7647 {
7648 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7649 ackbuf[0], ack_len);
7650 RETURNFUNC(-RIG_ERJCTED);
7651 }
7652
7653 RETURNFUNC(RIG_OK);
7654 }
7655
7656 /*
7657 * icom_set_ant
7658 * Assumes rig!=NULL, rig->state.priv!=NULL
7659 */
icom_set_ant(RIG * rig,vfo_t vfo,ant_t ant,value_t option)7660 int icom_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option)
7661 {
7662 unsigned char antopt[2];
7663 unsigned char ackbuf[MAXFRAMELEN];
7664 int ack_len = sizeof(ackbuf), retval, i_ant = 0;
7665 int antopt_len = 0;
7666 const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *)
7667 rig->caps->priv;
7668
7669 rig_debug(RIG_DEBUG_VERBOSE,
7670 "%s called, ant=0x%02x, option=%d, antack_len=%d\n", __func__, ant, option.i,
7671 priv_caps->antack_len);
7672
7673 // query the antennas once and find out how many we have
7674 if (ant >= rig_idx2setting(priv_caps->ant_count))
7675 {
7676 RETURNFUNC(-RIG_EINVAL);
7677 }
7678
7679 if (ant > RIG_ANT_4)
7680 {
7681 RETURNFUNC(-RIG_EDOM);
7682 }
7683
7684 switch (ant)
7685 {
7686 case RIG_ANT_1:
7687 i_ant = 0;
7688 break;
7689
7690 case RIG_ANT_2:
7691 i_ant = 1;
7692 break;
7693
7694 case RIG_ANT_3:
7695 i_ant = 2;
7696 break;
7697
7698 case RIG_ANT_4:
7699 i_ant = 3;
7700 break;
7701
7702 default:
7703 rig_debug(RIG_DEBUG_ERR, "%s: unsupported ant %#x", __func__, ant);
7704 RETURNFUNC(-RIG_EINVAL);
7705 }
7706
7707
7708 if (priv_caps->antack_len == 0) // we need to find out the antack_len
7709 {
7710 ant_t tmp_ant, ant_tx, ant_rx;
7711 int ant0 = 0;
7712 value_t tmp_option;
7713 retval = rig_get_ant(rig, vfo, ant0, &tmp_option, &tmp_ant, &ant_tx, &ant_rx);
7714
7715 if (retval != RIG_OK)
7716 {
7717 rig_debug(RIG_DEBUG_ERR, "%s: rig_get_ant error: %s \n", __func__,
7718 rigerror(retval));
7719 RETURNFUNC(retval);
7720 }
7721 }
7722
7723 // Some rigs have 3-byte ant cmd so there is an option to be set too
7724 if (priv_caps->antack_len == 3)
7725 {
7726 if (option.i != 0 && option.i != 1)
7727 {
7728 rig_debug(RIG_DEBUG_ERR, "%s: option.i != 0 or 1, ==%d?\n", __func__, option.i);
7729 RETURNFUNC(-RIG_EINVAL);
7730 }
7731
7732 antopt_len = 1;
7733 antopt[0] = option.i;
7734 // we have to set the rx option by itself apparently
7735 rig_debug(RIG_DEBUG_TRACE, "%s: setting antopt=%d\n", __func__, antopt[0]);
7736 retval = icom_transaction(rig, C_CTL_ANT, i_ant,
7737 antopt, antopt_len, ackbuf, &ack_len);
7738
7739 if (retval != RIG_OK)
7740 {
7741 RETURNFUNC(retval);
7742 }
7743
7744 rig_debug(RIG_DEBUG_TRACE,
7745 "%s: antack_len=%d so antopt_len=%d, antopt=0x%02x\n",
7746 __func__, priv_caps->antack_len, antopt_len, antopt[0]);
7747 }
7748 else if (priv_caps->antack_len == 2)
7749 {
7750 antopt_len = 0;
7751 rig_debug(RIG_DEBUG_TRACE, "%s: antack_len=%d so antopt_len=%d\n", __func__,
7752 priv_caps->antack_len, antopt_len);
7753 }
7754 else
7755 {
7756 rig_debug(RIG_DEBUG_TRACE, "%s: antack_len=%d so antopt_len=%d\n", __func__,
7757 priv_caps->antack_len, antopt_len);
7758 antopt_len = 0;
7759 rig_debug(RIG_DEBUG_ERR,
7760 "%s: rig does not have antenna select? antack_len=%d\n", __func__,
7761 priv_caps->antack_len);
7762 }
7763
7764 rig_debug(RIG_DEBUG_TRACE, "%s: i_ant=%d, antopt=0x%02x, antopt_len=%d\n",
7765 __func__, i_ant, antopt[0], antopt_len);
7766 retval = icom_transaction(rig, C_CTL_ANT, i_ant,
7767 antopt, antopt_len, ackbuf, &ack_len);
7768
7769 if (retval != RIG_OK)
7770 {
7771 RETURNFUNC(retval);
7772 }
7773
7774 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
7775 {
7776 // if we don't get ACK/NAK some serial corruption occurred
7777 // so we'll call it a timeout for retry purposes
7778 RETURNFUNC(-RIG_ETIMEOUT);
7779 }
7780
7781 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
7782 {
7783 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7784 ackbuf[0], ack_len);
7785 RETURNFUNC(-RIG_ERJCTED);
7786 }
7787
7788 RETURNFUNC(RIG_OK);
7789 }
7790
7791 /*
7792 * icom_get_ant
7793 * Assumes rig!=NULL, rig->state.priv!=NULL
7794 * only meaningful for HF
7795 */
icom_get_ant(RIG * rig,vfo_t vfo,ant_t ant,value_t * option,ant_t * ant_curr,ant_t * ant_tx,ant_t * ant_rx)7796 int icom_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option,
7797 ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx)
7798 {
7799 unsigned char ackbuf[MAXFRAMELEN];
7800 int ack_len = sizeof(ackbuf), retval;
7801 struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) rig->caps->priv;
7802
7803
7804 rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x\n", __func__, ant);
7805
7806 if (ant != RIG_ANT_CURR)
7807 {
7808 ant = rig_setting2idx(ant);
7809
7810 if (ant >= priv_caps->ant_count)
7811 {
7812 rig_debug(RIG_DEBUG_ERR, "%s: ant index=%u > ant_count=%d\n", __func__, ant,
7813 priv_caps->ant_count);
7814 RETURNFUNC(-RIG_EINVAL);
7815 }
7816 }
7817
7818 // Should be able to use just C_CTL_ANT for 1 or 2 antennas hopefully
7819 if (ant == RIG_ANT_CURR || priv_caps->ant_count <= 2)
7820 {
7821 retval = icom_transaction(rig, C_CTL_ANT, -1, NULL, 0, ackbuf, &ack_len);
7822 }
7823 else if (rig->caps->rig_model == RIG_MODEL_IC785x)
7824 {
7825 unsigned char buf[2];
7826 buf[0] = 0x03;
7827 buf[1] = 0x05 + ant;
7828 *ant_curr = ant;
7829 retval = icom_transaction(rig, C_CTL_MEM, 0x05, buf, sizeof(buf), ackbuf,
7830 &ack_len);
7831
7832 if (retval == RIG_OK)
7833 {
7834 option->i = ackbuf[4];
7835 RETURNFUNC(RIG_OK);
7836 }
7837 }
7838 else
7839 {
7840 rig_debug(RIG_DEBUG_ERR,
7841 "%s: asking for non-current antenna and ant_count==0?\n", __func__);
7842 rig_debug(RIG_DEBUG_ERR, "%s: need to implement ant control for this rig?\n",
7843 __func__);
7844 RETURNFUNC(-RIG_EINVAL);
7845 }
7846
7847 if (retval != RIG_OK)
7848 {
7849 RETURNFUNC(retval);
7850 }
7851
7852 // ack_len should be either 2 or 3
7853 // ant cmd format is one of
7854 // 0x12 0xaa
7855 // 0x12 0xaa 0xrr
7856 // Where aa is a zero-base antenna number and rr is a binary for rx only
7857
7858 if ((ack_len != 2 && ack_len != 3) || ackbuf[0] != C_CTL_ANT ||
7859 ackbuf[1] > 3)
7860 {
7861 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d, ant=%d\n", __func__,
7862 ackbuf[0], ack_len, ackbuf[1]);
7863 RETURNFUNC(-RIG_ERJCTED);
7864 }
7865
7866 rig_debug(RIG_DEBUG_ERR, "%s: ackbuf= 0x%02x 0x%02x 0x%02x\n", __func__,
7867 ackbuf[0], ackbuf[1], ackbuf[2]);
7868
7869 *ant_curr = *ant_tx = *ant_rx = rig_idx2setting(ackbuf[1]);
7870
7871 // Note: with IC756/IC-756Pro/IC-7800 and more, ackbuf[2] deals with [RX ANT]
7872 // Hopefully any ack_len=3 can fit in the option field
7873 if (ack_len == 3)
7874 {
7875 option->i = ackbuf[2];
7876 *ant_rx = rig_idx2setting(ackbuf[2]);
7877 }
7878
7879 RETURNFUNC(RIG_OK);
7880 }
7881
7882
7883 /*
7884 * icom_vfo_op, Mem/VFO operation
7885 * Assumes rig!=NULL, rig->state.priv!=NULL
7886 */
icom_vfo_op(RIG * rig,vfo_t vfo,vfo_op_t op)7887 int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op)
7888 {
7889 unsigned char mvbuf[MAXFRAMELEN];
7890 unsigned char ackbuf[MAXFRAMELEN];
7891 int mv_len = 0, ack_len = sizeof(ackbuf), retval;
7892 int mv_cn, mv_sc;
7893 int vfo_list;
7894
7895 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7896
7897 switch (op)
7898 {
7899 case RIG_OP_CPY:
7900 mv_cn = C_SET_VFO;
7901 vfo_list = rig->state.vfo_list;
7902
7903 if ((vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B))
7904 {
7905 mv_sc = S_BTOA;
7906 }
7907 else if ((vfo_list & (RIG_VFO_MAIN | RIG_VFO_SUB)) == (RIG_VFO_MAIN |
7908 RIG_VFO_SUB))
7909 {
7910 mv_sc = S_SUBTOMAIN;
7911 }
7912 else
7913 {
7914 RETURNFUNC(-RIG_ENAVAIL);
7915 }
7916
7917 break;
7918
7919 case RIG_OP_XCHG:
7920 mv_cn = C_SET_VFO;
7921 mv_sc = S_XCHNG;
7922 break;
7923
7924 case RIG_OP_FROM_VFO:
7925 mv_cn = C_WR_MEM;
7926 mv_sc = -1;
7927 break;
7928
7929 case RIG_OP_TO_VFO:
7930 mv_cn = C_MEM2VFO;
7931 mv_sc = -1;
7932 break;
7933
7934 case RIG_OP_MCL:
7935 mv_cn = C_CLR_MEM;
7936 mv_sc = -1;
7937 break;
7938
7939 case RIG_OP_TUNE:
7940 mv_cn = C_CTL_PTT;
7941 mv_sc = S_ANT_TUN;
7942 mvbuf[0] = 2;
7943 mv_len = 1;
7944 break;
7945
7946 default:
7947 rig_debug(RIG_DEBUG_ERR, "%s: unsupported mem/vfo op %#x", __func__,
7948 op);
7949 RETURNFUNC(-RIG_EINVAL);
7950 }
7951
7952 retval =
7953 icom_transaction(rig, mv_cn, mv_sc, mvbuf, mv_len, ackbuf, &ack_len);
7954
7955 if (retval != RIG_OK)
7956 {
7957 RETURNFUNC(retval);
7958 }
7959
7960 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
7961 {
7962 // if we don't get ACK/NAK some serial corruption occurred
7963 // so we'll call it a timeout for retry purposes
7964 RETURNFUNC(-RIG_ETIMEOUT);
7965 }
7966
7967 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
7968 {
7969 if (op != RIG_OP_XCHG)
7970 {
7971 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
7972 ackbuf[0], ack_len);
7973 }
7974
7975 RETURNFUNC(-RIG_ERJCTED);
7976 }
7977
7978 RETURNFUNC(RIG_OK);
7979 }
7980
7981 /*
7982 * icom_scan, scan operation
7983 * Assumes rig!=NULL, rig->state.priv!=NULL
7984 */
icom_scan(RIG * rig,vfo_t vfo,scan_t scan,int ch)7985 int icom_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch)
7986 {
7987 unsigned char scanbuf[MAXFRAMELEN];
7988 unsigned char ackbuf[MAXFRAMELEN];
7989 int scan_len, ack_len = sizeof(ackbuf), retval;
7990 int scan_cn, scan_sc;
7991
7992 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
7993 scan_len = 0;
7994 scan_cn = C_CTL_SCAN;
7995
7996 switch (scan)
7997 {
7998 case RIG_SCAN_STOP:
7999 scan_sc = S_SCAN_STOP;
8000 break;
8001
8002 case RIG_SCAN_MEM:
8003 TRACE;
8004 retval = rig_set_vfo(rig, RIG_VFO_MEM);
8005
8006 if (retval != RIG_OK)
8007 {
8008 RETURNFUNC(retval);
8009 }
8010
8011 /* Looks like all the IC-R* have this command,
8012 * but some old models don't have it.
8013 * Should be put in icom_priv_caps ?
8014 */
8015 if (rig->caps->rig_type == RIG_TYPE_RECEIVER)
8016 {
8017 scan_sc = S_SCAN_MEM2;
8018 }
8019 else
8020 {
8021 scan_sc = S_SCAN_START;
8022 }
8023
8024 break;
8025
8026 case RIG_SCAN_SLCT:
8027 TRACE;
8028 retval = rig_set_vfo(rig, RIG_VFO_MEM);
8029
8030 if (retval != RIG_OK)
8031 {
8032 RETURNFUNC(retval);
8033 }
8034
8035 scan_sc = S_SCAN_START;
8036 break;
8037
8038 case RIG_SCAN_PRIO:
8039 case RIG_SCAN_PROG:
8040 /* TODO: for SCAN_PROG, check this is an edge chan */
8041 /* BTW, I'm wondering if this is possible with CI-V */
8042 retval = icom_set_mem(rig, RIG_VFO_CURR, ch);
8043
8044 if (retval != RIG_OK)
8045 {
8046 RETURNFUNC(retval);
8047 }
8048
8049 TRACE;
8050 retval = rig_set_vfo(rig, RIG_VFO_VFO);
8051
8052 if (retval != RIG_OK)
8053 {
8054 RETURNFUNC(retval);
8055 }
8056
8057 scan_sc = S_SCAN_START;
8058 break;
8059
8060 case RIG_SCAN_DELTA:
8061 scan_sc = S_SCAN_DELTA; /* TODO: delta-f support */
8062 break;
8063
8064 default:
8065 rig_debug(RIG_DEBUG_ERR, "%s: unsupported scan %#x", __func__, scan);
8066 RETURNFUNC(-RIG_EINVAL);
8067 }
8068
8069 retval = icom_transaction(rig, scan_cn, scan_sc, scanbuf, scan_len,
8070 ackbuf, &ack_len);
8071
8072 if (retval != RIG_OK)
8073 {
8074 RETURNFUNC(retval);
8075 }
8076
8077 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
8078 {
8079 // if we don't get ACK/NAK some serial corruption occurred
8080 // so we'll call it a timeout for retry purposes
8081 RETURNFUNC(-RIG_ETIMEOUT);
8082 }
8083
8084 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
8085 {
8086 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
8087 ackbuf[0], ack_len);
8088 RETURNFUNC(-RIG_ERJCTED);
8089 }
8090
8091 RETURNFUNC(RIG_OK);
8092 }
8093
8094 /*
8095 * icom_send_morse
8096 * Assumes rig!=NULL, msg!=NULL
8097 */
icom_send_morse(RIG * rig,vfo_t vfo,const char * msg)8098 int icom_send_morse(RIG *rig, vfo_t vfo, const char *msg)
8099 {
8100 unsigned char ackbuf[MAXFRAMELEN];
8101 int ack_len = sizeof(ackbuf), retval;
8102 int len;
8103
8104 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8105 len = strlen(msg);
8106
8107 if (len > 30)
8108 {
8109 len = 30;
8110 }
8111
8112 rig_debug(RIG_DEBUG_TRACE, "%s: %s\n", __func__, msg);
8113
8114 retval = icom_transaction(rig, C_SND_CW, -1, (unsigned char *) msg, len,
8115 ackbuf, &ack_len);
8116
8117 if (retval != RIG_OK)
8118 {
8119 RETURNFUNC(retval);
8120 }
8121
8122 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
8123 {
8124 // if we don't get ACK/NAK some serial corruption occurred
8125 // so we'll call it a timeout for retry purposes
8126 RETURNFUNC(-RIG_ETIMEOUT);
8127 }
8128
8129 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
8130 {
8131 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
8132 ackbuf[0], ack_len);
8133 RETURNFUNC(-RIG_ERJCTED);
8134 }
8135
8136 RETURNFUNC(RIG_OK);
8137 }
8138
8139 /*
8140 * icom_stop_morse
8141 * Assumes rig!=NULL, msg!=NULL
8142 */
icom_stop_morse(RIG * rig,vfo_t vfo)8143 int icom_stop_morse(RIG *rig, vfo_t vfo)
8144 {
8145 unsigned char ackbuf[MAXFRAMELEN];
8146 unsigned char cmd[MAXFRAMELEN];
8147 int ack_len = sizeof(ackbuf), retval;
8148
8149 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8150
8151 cmd[0] = 0xff;
8152
8153 retval = icom_transaction(rig, C_SND_CW, -1, (unsigned char *) cmd, 1,
8154 ackbuf, &ack_len);
8155
8156 if (retval != RIG_OK)
8157 {
8158 RETURNFUNC(retval);
8159 }
8160
8161 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
8162 {
8163 // if we don't get ACK/NAK some serial corruption occurred
8164 // so we'll call it a timeout for retry purposes
8165 RETURNFUNC(-RIG_ETIMEOUT);
8166 }
8167
8168 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
8169 {
8170 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
8171 ackbuf[0], ack_len);
8172 RETURNFUNC(-RIG_ERJCTED);
8173 }
8174
8175 RETURNFUNC(RIG_OK);
8176 }
8177
icom_power2mW(RIG * rig,unsigned int * mwpower,float power,freq_t freq,rmode_t mode)8178 int icom_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq,
8179 rmode_t mode)
8180 {
8181 int rig_id;
8182
8183 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8184 rig_id = rig->caps->rig_model;
8185
8186 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8187
8188 switch (rig_id)
8189 {
8190 default:
8191 /* Normal 100 Watts */
8192 *mwpower = power * 100000;
8193 break;
8194 }
8195
8196 RETURNFUNC(RIG_OK);
8197 }
8198
icom_mW2power(RIG * rig,float * power,unsigned int mwpower,freq_t freq,rmode_t mode)8199 int icom_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq,
8200 rmode_t mode)
8201 {
8202 int rig_id;
8203
8204 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8205 rig_id = rig->caps->rig_model;
8206
8207 rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__,
8208 mwpower);
8209 rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %" PRIfreq " Hz\n",
8210 __func__, freq);
8211 rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__,
8212 rig_strrmode(mode));
8213
8214 if (mwpower > 100000)
8215 {
8216 RETURNFUNC(-RIG_EINVAL);
8217 }
8218
8219 switch (rig_id)
8220 {
8221 default: /* Default to a 100W radio */
8222 *power = ((float) mwpower / 100000);
8223 break;
8224 }
8225
8226 RETURNFUNC(RIG_OK);
8227 }
8228
icom_parse_spectrum_frame(RIG * rig,int length,const unsigned char * frame_data)8229 static int icom_parse_spectrum_frame(RIG *rig, int length,
8230 const unsigned char *frame_data)
8231 {
8232 struct rig_caps *caps = rig->caps;
8233 struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) caps->priv;
8234 struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv;
8235 struct icom_spectrum_scope_cache *cache;
8236
8237 int division = (int) from_bcd(frame_data + 1, 1 * 2);
8238 int max_division = (int) from_bcd(frame_data + 2, 1 * 2);
8239
8240 int spectrum_data_length_in_frame;
8241 const unsigned char *spectrum_data_start_in_frame;
8242
8243 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8244
8245 // The first byte indicates spectrum scope ID/VFO: 0 = Main, 1 = Sub
8246 int spectrum_id = frame_data[0];
8247
8248 if (spectrum_id < 0 || spectrum_id >= priv->spectrum_scope_count)
8249 {
8250 rig_debug(RIG_DEBUG_ERR, "%s: invalid spectrum scope ID from CI-V frame: %d\n",
8251 __func__, spectrum_id);
8252 RETURNFUNC(-RIG_EPROTO);
8253 }
8254
8255 cache = &priv->spectrum_scope_cache[spectrum_id];
8256
8257 if (division == 1)
8258 {
8259 int spectrum_scope_mode = frame_data[3];
8260 int out_of_range = frame_data[14];
8261
8262 cache->spectrum_mode = RIG_SPECTRUM_MODE_NONE;
8263
8264 switch (spectrum_scope_mode)
8265 {
8266 case SCOPE_MODE_CENTER:
8267 cache->spectrum_mode = RIG_SPECTRUM_MODE_CENTER;
8268 cache->spectrum_center_freq = (freq_t) from_bcd(frame_data + 4, 5 * 2);
8269 cache->spectrum_span_freq = (freq_t) from_bcd(frame_data + 9, 5 * 2) * 2;
8270 cache->spectrum_low_edge_freq = cache->spectrum_center_freq -
8271 cache->spectrum_span_freq / 2;
8272 cache->spectrum_high_edge_freq = cache->spectrum_center_freq +
8273 cache->spectrum_span_freq / 2;
8274 break;
8275
8276 case SCOPE_MODE_FIXED:
8277 cache->spectrum_mode = RIG_SPECTRUM_MODE_FIXED;
8278
8279 case SCOPE_MODE_SCROLL_C:
8280 if (cache->spectrum_mode == RIG_SPECTRUM_MODE_NONE)
8281 {
8282 cache->spectrum_mode = RIG_SPECTRUM_MODE_CENTER_SCROLL;
8283 }
8284
8285 case SCOPE_MODE_SCROLL_F:
8286 if (cache->spectrum_mode == RIG_SPECTRUM_MODE_NONE)
8287 {
8288 cache->spectrum_mode = RIG_SPECTRUM_MODE_FIXED_SCROLL;
8289 }
8290
8291 cache->spectrum_low_edge_freq = (freq_t) from_bcd(frame_data + 4, 5 * 2);
8292 cache->spectrum_high_edge_freq = (freq_t) from_bcd(frame_data + 9, 5 * 2);
8293 cache->spectrum_span_freq = (cache->spectrum_high_edge_freq -
8294 cache->spectrum_low_edge_freq);
8295 cache->spectrum_center_freq = cache->spectrum_high_edge_freq -
8296 cache->spectrum_span_freq / 2;
8297 break;
8298
8299 default:
8300 rig_debug(RIG_DEBUG_ERR, "%s: unknown Icom spectrum scope mode: %d\n", __func__,
8301 spectrum_scope_mode)
8302 RETURNFUNC(-RIG_EPROTO);
8303 }
8304
8305 spectrum_data_length_in_frame = length - 15;
8306 spectrum_data_start_in_frame = frame_data + 15;
8307
8308 memset(cache->spectrum_data, 0,
8309 priv_caps->spectrum_scope_caps.spectrum_line_length);
8310
8311 cache->spectrum_data_length = 0;
8312 cache->spectrum_metadata_valid = 1;
8313
8314 rig_debug(RIG_DEBUG_TRACE,
8315 "%s: Spectrum line start: id=%d division=%d max_division=%d mode=%d center=%.0f span=%.0f low_edge=%.0f high_edge=%.0f oor=%d data_length=%d\n",
8316 __func__, spectrum_id, division, max_division, spectrum_scope_mode,
8317 cache->spectrum_center_freq, cache->spectrum_span_freq,
8318 cache->spectrum_low_edge_freq, cache->spectrum_high_edge_freq, out_of_range,
8319 spectrum_data_length_in_frame);
8320 }
8321 else
8322 {
8323 spectrum_data_length_in_frame = length - 3;
8324 spectrum_data_start_in_frame = frame_data + 3;
8325 }
8326
8327 if (spectrum_data_length_in_frame > 0)
8328 {
8329 int frame_length = priv_caps->spectrum_scope_caps.single_frame_data_length;
8330 int data_frame_index = (max_division > 1) ? (division - 2) : (division - 1);
8331 int offset = data_frame_index * frame_length;
8332
8333 if (offset + spectrum_data_length_in_frame >
8334 priv_caps->spectrum_scope_caps.spectrum_line_length)
8335 {
8336 rig_debug(RIG_DEBUG_ERR,
8337 "%s: too much spectrum scope data received: %d bytes > %d bytes expected\n",
8338 __func__, offset + spectrum_data_length_in_frame,
8339 priv_caps->spectrum_scope_caps.spectrum_line_length);
8340 RETURNFUNC(-RIG_EPROTO);
8341 }
8342
8343 memcpy(cache->spectrum_data + offset, spectrum_data_start_in_frame,
8344 spectrum_data_length_in_frame);
8345 cache->spectrum_data_length = offset + spectrum_data_length_in_frame;
8346 }
8347
8348 if (cache->spectrum_metadata_valid && division == max_division)
8349 {
8350 struct rig_spectrum_line spectrum_line =
8351 {
8352 .data_level_min = priv_caps->spectrum_scope_caps.data_level_min,
8353 .data_level_max = priv_caps->spectrum_scope_caps.data_level_max,
8354 .signal_strength_min = priv_caps->spectrum_scope_caps.signal_strength_min,
8355 .signal_strength_max = priv_caps->spectrum_scope_caps.signal_strength_max,
8356 .spectrum_mode = cache->spectrum_mode,
8357 .center_freq = cache->spectrum_center_freq,
8358 .span_freq = cache->spectrum_span_freq,
8359 .low_edge_freq = cache->spectrum_low_edge_freq,
8360 .high_edge_freq = cache->spectrum_high_edge_freq,
8361 .spectrum_data_length = cache->spectrum_data_length,
8362 .spectrum_data = cache->spectrum_data,
8363 };
8364
8365 if (rig->callbacks.spectrum_event)
8366 {
8367 rig->callbacks.spectrum_event(rig, &spectrum_line, rig->callbacks.spectrum_arg);
8368 }
8369
8370 cache->spectrum_metadata_valid = 0;
8371 }
8372
8373 RETURNFUNC(RIG_OK);
8374 }
8375
icom_is_async_frame(RIG * rig,int frame_len,const unsigned char * frame)8376 int icom_is_async_frame(RIG *rig, int frame_len, const unsigned char *frame)
8377 {
8378 if (frame_len < ACKFRMLEN)
8379 {
8380 return 0;
8381 }
8382
8383 /* Spectrum scope data is not CI-V transceive data, but handled the same way as it is pushed by the rig */
8384 return frame[2] == BCASTID || (frame[2] == CTRLID && frame[4] == C_CTL_SCP
8385 && frame[5] == S_SCP_DAT);
8386 }
8387
icom_process_async_frame(RIG * rig,int frame_len,const unsigned char * frame)8388 int icom_process_async_frame(RIG *rig, int frame_len,
8389 const unsigned char *frame)
8390 {
8391 struct rig_state *rs = &rig->state;
8392 struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv;
8393 rmode_t mode;
8394 pbwidth_t width;
8395
8396 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8397
8398 /*
8399 * the first 2 bytes must be 0xfe
8400 * the 3rd one 0x00 since this is transceive mode
8401 * the 4rd one the emitter
8402 * then the command number
8403 * the rest is data
8404 * and don't forget one byte at the end for the EOM
8405 */
8406 switch (frame[4])
8407 {
8408 case C_SND_FREQ:
8409
8410 /*
8411 * TODO: the freq length might be less than 4 or 5 bytes
8412 * on older rigs!
8413 */
8414 if (rig->callbacks.freq_event)
8415 {
8416 freq_t freq;
8417 freq = from_bcd(frame + 5, (priv->civ_731_mode ? 4 : 5) * 2);
8418 RETURNFUNC(rig->callbacks.freq_event(rig, RIG_VFO_CURR, freq,
8419 rig->callbacks.freq_arg));
8420 }
8421 else
8422 {
8423 RETURNFUNC(-RIG_ENAVAIL);
8424 }
8425
8426 break;
8427
8428 case C_SND_MODE:
8429 if (rig->callbacks.mode_event)
8430 {
8431 icom2rig_mode(rig, frame[5], frame[6], &mode, &width);
8432 RETURNFUNC(rig->callbacks.mode_event(rig, RIG_VFO_CURR,
8433 mode, width, rig->callbacks.mode_arg));
8434 }
8435 else
8436 {
8437 RETURNFUNC(-RIG_ENAVAIL);
8438 }
8439
8440 break;
8441
8442 case C_CTL_SCP:
8443 if (frame[5] == S_SCP_DAT)
8444 {
8445 icom_parse_spectrum_frame(rig, frame_len - (6 + 1), frame + 6);
8446 }
8447
8448 break;
8449
8450 default:
8451 rig_debug(RIG_DEBUG_VERBOSE, "%s: transceive cmd unsupported %#2.2x\n",
8452 __func__, frame[4]);
8453 RETURNFUNC(-RIG_ENIMPL);
8454 }
8455
8456 RETURNFUNC(RIG_OK);
8457 }
8458
8459 /*
8460 * icom_decode is called by sa_sigio, when some asynchronous
8461 * data has been received from the rig
8462 */
icom_decode_event(RIG * rig)8463 int icom_decode_event(RIG *rig)
8464 {
8465 struct icom_priv_data *priv;
8466 struct rig_state *rs;
8467 unsigned char buf[MAXFRAMELEN];
8468 int retval, frm_len;
8469
8470 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8471
8472 rs = &rig->state;
8473 priv = (struct icom_priv_data *) rs->priv;
8474
8475 frm_len = read_icom_frame(&rs->rigport, buf, sizeof(buf));
8476
8477 if (frm_len == -RIG_ETIMEOUT)
8478 {
8479 rig_debug(RIG_DEBUG_VERBOSE,
8480 "%s: got a timeout before the first character\n", __func__);
8481 }
8482
8483 if (frm_len < 1)
8484 {
8485 RETURNFUNC(RIG_OK);
8486 }
8487
8488 retval = icom_frame_fix_preamble(frm_len, buf);
8489
8490 if (retval < 0)
8491 {
8492 RETURNFUNC(retval);
8493 }
8494
8495 frm_len = retval;
8496
8497 switch (buf[frm_len - 1])
8498 {
8499 case COL:
8500 rig_debug(RIG_DEBUG_VERBOSE, "%s: saw a collision\n", __func__);
8501 /* Collision */
8502 RETURNFUNC(-RIG_BUSBUSY);
8503
8504 case FI:
8505 /* Ok, normal frame */
8506 break;
8507
8508 default:
8509 /* Timeout after reading at least one character */
8510 /* Problem on ci-v bus? */
8511 RETURNFUNC(-RIG_EPROTO);
8512 }
8513
8514 if (!icom_is_async_frame(rig, frm_len, buf))
8515 {
8516 rig_debug(RIG_DEBUG_WARN, "%s: CI-V %#x called for %#x!\n", __func__,
8517 priv->re_civ_addr, buf[2]);
8518 }
8519
8520 RETURNFUNC(icom_process_async_frame(rig, frm_len, buf));
8521 }
8522
icom_set_raw(RIG * rig,int cmd,int subcmd,int subcmdbuflen,unsigned char * subcmdbuf,int val_bytes,int val)8523 int icom_set_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen,
8524 unsigned char *subcmdbuf, int val_bytes, int val)
8525 {
8526 unsigned char cmdbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN];
8527 int ack_len = sizeof(ackbuf);
8528 int cmdbuflen = subcmdbuflen;
8529 int retval;
8530
8531 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8532
8533 if (subcmdbuflen > 0)
8534 {
8535 if (subcmdbuf == NULL)
8536 {
8537 RETURNFUNC(-RIG_EINTERNAL);
8538 }
8539
8540 memcpy(cmdbuf, subcmdbuf, subcmdbuflen);
8541 }
8542
8543 if (val_bytes > 0)
8544 {
8545 to_bcd_be(cmdbuf + subcmdbuflen, (long long) val, val_bytes * 2);
8546 cmdbuflen += val_bytes;
8547 }
8548
8549 retval =
8550 icom_transaction(rig, cmd, subcmd, cmdbuf, cmdbuflen, ackbuf, &ack_len);
8551
8552 if (retval != RIG_OK)
8553 {
8554 RETURNFUNC(retval);
8555 }
8556
8557 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
8558 {
8559 // if we don't get ACK/NAK some serial corruption occurred
8560 // so we'll call it a timeout for retry purposes
8561 RETURNFUNC(-RIG_ETIMEOUT);
8562 }
8563
8564 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
8565 {
8566 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
8567 ackbuf[0], ack_len);
8568 RETURNFUNC(-RIG_ERJCTED);
8569 }
8570
8571 RETURNFUNC(RIG_OK);
8572 }
8573
icom_get_raw_buf(RIG * rig,int cmd,int subcmd,int subcmdbuflen,unsigned char * subcmdbuf,int * reslen,unsigned char * res)8574 int icom_get_raw_buf(RIG *rig, int cmd, int subcmd, int subcmdbuflen,
8575 unsigned char *subcmdbuf, int *reslen,
8576 unsigned char *res)
8577 {
8578 unsigned char ackbuf[MAXFRAMELEN];
8579 int ack_len = sizeof(ackbuf);
8580 int cmdhead = subcmdbuflen;
8581 int retval;
8582
8583 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8584
8585 retval =
8586 icom_transaction(rig, cmd, subcmd, subcmdbuf, subcmdbuflen, ackbuf,
8587 &ack_len);
8588
8589 if (retval != RIG_OK)
8590 {
8591 RETURNFUNC(retval);
8592 }
8593
8594 cmdhead += (subcmd == -1) ? 1 : 2;
8595 ack_len -= cmdhead;
8596
8597 rig_debug(RIG_DEBUG_TRACE, "%s: %d\n", __func__, ack_len);
8598
8599 if (*reslen < ack_len || res == NULL)
8600 {
8601 RETURNFUNC(-RIG_EINTERNAL);
8602 }
8603
8604 memcpy(res, ackbuf + cmdhead, ack_len);
8605 *reslen = ack_len;
8606
8607 RETURNFUNC(RIG_OK);
8608 }
8609
icom_get_raw(RIG * rig,int cmd,int subcmd,int subcmdbuflen,unsigned char * subcmdbuf,int * val)8610 int icom_get_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen,
8611 unsigned char *subcmdbuf, int *val)
8612 {
8613 unsigned char resbuf[MAXFRAMELEN];
8614 int reslen = sizeof(resbuf);
8615 int retval;
8616
8617 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8618
8619 retval =
8620 icom_get_raw_buf(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, &reslen,
8621 resbuf);
8622
8623 if (retval != RIG_OK)
8624 {
8625 RETURNFUNC(retval);
8626 }
8627
8628 * val = from_bcd_be(resbuf, reslen * 2);
8629
8630 rig_debug(RIG_DEBUG_TRACE, "%s: %d %d\n", __func__, reslen, *val);
8631
8632 RETURNFUNC(RIG_OK);
8633 }
8634
icom_set_level_raw(RIG * rig,setting_t level,int cmd,int subcmd,int subcmdbuflen,unsigned char * subcmdbuf,int val_bytes,value_t val)8635 int icom_set_level_raw(RIG *rig, setting_t level, int cmd, int subcmd,
8636 int subcmdbuflen, unsigned char *subcmdbuf,
8637 int val_bytes, value_t val)
8638 {
8639 int icom_val;
8640
8641 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8642
8643 if (RIG_LEVEL_IS_FLOAT(level))
8644 {
8645 icom_val = (int)(val.f * 255.0f);
8646 }
8647 else
8648 {
8649 icom_val = val.i;
8650 }
8651
8652 RETURNFUNC(icom_set_raw(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, val_bytes,
8653 icom_val));
8654 }
8655
icom_get_level_raw(RIG * rig,setting_t level,int cmd,int subcmd,int subcmdbuflen,unsigned char * subcmdbuf,value_t * val)8656 int icom_get_level_raw(RIG *rig, setting_t level, int cmd, int subcmd,
8657 int subcmdbuflen, unsigned char *subcmdbuf,
8658 value_t *val)
8659 {
8660 int icom_val;
8661 int retval;
8662
8663 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8664
8665 retval =
8666 icom_get_raw(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, &icom_val);
8667
8668 if (retval != RIG_OK)
8669 {
8670 RETURNFUNC(retval);
8671 }
8672
8673 if (RIG_LEVEL_IS_FLOAT(level))
8674 {
8675 val->f = (float) icom_val / 255.0f;
8676 }
8677 else
8678 {
8679 val->i = icom_val;
8680 }
8681
8682 RETURNFUNC(RIG_OK);
8683 }
8684
8685 /*
8686 * icom_send_voice_mem
8687 * Assumes rig!=NULL, rig->state.priv!=NULL
8688 */
icom_send_voice_mem(RIG * rig,vfo_t vfo,int ch)8689 int icom_send_voice_mem(RIG *rig, vfo_t vfo, int ch)
8690 {
8691 unsigned char chbuf[1];
8692 unsigned char ackbuf[MAXFRAMELEN];
8693 int ack_len = sizeof(ackbuf), retval;
8694
8695 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8696
8697 to_bcd_be(chbuf, ch, 2);
8698
8699 retval = icom_transaction(rig, C_SND_VOICE, 0, chbuf, 1,
8700 ackbuf, &ack_len);
8701
8702 if (retval != RIG_OK)
8703 {
8704 RETURNFUNC(retval);
8705 }
8706
8707 if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK))
8708 {
8709 // if we don't get ACK/NAK some serial corruption occurred
8710 // so we'll call it a timeout for retry purposes
8711 RETURNFUNC(-RIG_ETIMEOUT);
8712 }
8713
8714 if (ack_len != 1 || (ack_len >= 1 && ackbuf[0] != ACK))
8715 {
8716 rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__,
8717 ackbuf[0], ack_len);
8718 RETURNFUNC(-RIG_ERJCTED);
8719 }
8720
8721 RETURNFUNC(RIG_OK);
8722 }
8723
8724 /*
8725 * icom_get_freq_range
8726 * Assumes rig!=NULL, rig->state.priv!=NULL
8727 * Always returns RIG_OK
8728 */
icom_get_freq_range(RIG * rig)8729 int icom_get_freq_range(RIG *rig)
8730 {
8731 int nrange = 0;
8732 int i;
8733 int cmd, subcmd;
8734 int retval;
8735 unsigned char cmdbuf[MAXFRAMELEN];
8736 unsigned char ackbuf[MAXFRAMELEN];
8737 int ack_len = sizeof(ackbuf);
8738 // struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv;
8739 // int freq_len = priv->civ_731_mode ? 4 : 5;
8740 int freq_len = 5;
8741
8742 cmd = C_CTL_EDGE;
8743 subcmd = 0;
8744 retval = icom_transaction(rig, cmd, subcmd, NULL, 0, ackbuf, &ack_len);
8745
8746 if (retval != RIG_OK)
8747 {
8748 rig_debug(RIG_DEBUG_TRACE,
8749 "%s: rig does not have 0x1e command so skipping this check\n", __func__);
8750 RETURNFUNC(RIG_OK);
8751 }
8752
8753 rig_debug(RIG_DEBUG_TRACE, "%s: ackbuf[0]=%02x, ackbuf[1]=%02x\n", __func__,
8754 ackbuf[0], ackbuf[1]);
8755 nrange = from_bcd(&ackbuf[2], 2);
8756 rig_debug(RIG_DEBUG_TRACE, "%s: nrange=%d\n", __func__, nrange);
8757
8758 for (i = 1; i <= nrange; ++i)
8759 {
8760 cmd = C_CTL_EDGE;
8761 subcmd = 1;
8762 to_bcd(cmdbuf, i, 2);
8763 retval = icom_transaction(rig, cmd, subcmd, cmdbuf, 1, ackbuf,
8764 &ack_len);
8765
8766 if (retval == RIG_OK)
8767 {
8768 freq_t freqlo, freqhi;
8769 rig_debug(RIG_DEBUG_TRACE, "%s: ackbuf= %02x %02x %02x %02x...\n", __func__,
8770 ackbuf[0], ackbuf[1], ackbuf[2], ackbuf[3]);
8771 freqlo = from_bcd(&ackbuf[3], freq_len * 2);
8772 freqhi = from_bcd(&ackbuf[3 + freq_len + 1], freq_len * 2);
8773 rig_debug(RIG_DEBUG_TRACE, "%s: rig chan %d, low=%.0f, high=%.0f\n", __func__,
8774 i, freqlo, freqhi);
8775 }
8776 else
8777 {
8778 rig_debug(RIG_DEBUG_ERR, "%s: error from C_CTL_EDGE? err=%s\n", __func__,
8779 rigerror(retval));
8780 }
8781 }
8782
8783 // To be implemented
8784 // Automatically fill in the freq range for this rig if available
8785 rig_debug(RIG_DEBUG_TRACE, "%s: Hamlib ranges\n", __func__);
8786
8787 for (i = 0; i < HAMLIB_FRQRANGESIZ
8788 && !RIG_IS_FRNG_END(rig->caps->rx_range_list1[i]); i++)
8789 {
8790 rig_debug(RIG_DEBUG_TRACE, "%s: rig chan %d, low=%.0f, high=%.0f\n", __func__,
8791 i, (double)rig->caps->rx_range_list1[i].startf,
8792 (double)rig->caps->rx_range_list1[i].endf);
8793 }
8794
8795 RETURNFUNC(RIG_OK);
8796 }
8797
8798 // Sets rig vfo && rig->state.current_vfo to default VFOA, or current vfo, or the vfo requested
set_vfo_curr(RIG * rig,vfo_t vfo,vfo_t curr_vfo)8799 static int set_vfo_curr(RIG *rig, vfo_t vfo, vfo_t curr_vfo)
8800 {
8801 int retval;
8802 struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv;
8803
8804 rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, curr_vfo=%s\n", __func__,
8805 rig_strvfo(vfo), rig_strvfo(curr_vfo));
8806
8807 if (vfo == RIG_VFO_CURR)
8808 {
8809 rig_debug(RIG_DEBUG_TRACE, "%s: Asking for currVFO, currVFO=%s\n", __func__,
8810 rig_strvfo(rig->state.current_vfo));
8811 vfo = rig->state.current_vfo;
8812 RETURNFUNC(RIG_OK);
8813 }
8814
8815 if (vfo == RIG_VFO_MAIN && VFO_HAS_A_B_ONLY)
8816 {
8817 vfo = RIG_VFO_A;
8818 rig_debug(RIG_DEBUG_TRACE, "%s: Rig does not have MAIN/SUB so Main=%s\n",
8819 __func__, rig_strvfo(vfo));
8820 }
8821 else if (vfo == RIG_VFO_SUB && VFO_HAS_A_B_ONLY)
8822 {
8823 vfo = RIG_VFO_B;
8824 rig_debug(RIG_DEBUG_TRACE, "%s: Rig does not have MAIN/SUB so Sub=%s\n",
8825 __func__, rig_strvfo(vfo));
8826 }
8827
8828 /* This method works also in memory mode(RIG_VFO_MEM) */
8829 // first time we will set default to VFOA or Main as
8830 // So if you ask for frequency or such without setting VFO first you'll get Main/VFOA
8831 if (rig->state.current_vfo == RIG_VFO_NONE && vfo == RIG_VFO_CURR)
8832 {
8833 icom_set_default_vfo(rig);
8834 }
8835 // asking for vfo_curr so give it to them
8836 else if (rig->state.current_vfo != RIG_VFO_NONE && vfo == RIG_VFO_CURR)
8837 {
8838 rig_debug(RIG_DEBUG_TRACE, "%s: using curr_vfo=%s\n", __func__,
8839 rig_strvfo(rig->state.current_vfo));
8840 vfo = rig->state.current_vfo;
8841 }
8842 // only need to set vfo if it's changed
8843 else if (rig->state.current_vfo != vfo)
8844 {
8845 if (!(VFO_HAS_MAIN_SUB_A_B_ONLY && !priv->split_on && !rig->state.cache.satmode
8846 && vfo == RIG_VFO_SUB && rig->state.current_vfo == RIG_VFO_B))
8847 {
8848 rig_debug(RIG_DEBUG_TRACE, "%s: setting new vfo=%s\n", __func__,
8849 rig_strvfo(vfo));
8850 TRACE;
8851 retval = rig_set_vfo(rig, vfo);
8852
8853 if (retval != RIG_OK)
8854 {
8855 RETURNFUNC(retval);
8856 }
8857 }
8858 }
8859
8860 rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo now=%s\n", __func__,
8861 rig_strvfo(rig->state.current_vfo));
8862
8863 rig->state.current_vfo = vfo;
8864
8865 RETURNFUNC(RIG_OK);
8866 }
8867
icom_get_spectrum_vfo(RIG * rig,vfo_t vfo)8868 static int icom_get_spectrum_vfo(RIG *rig, vfo_t vfo)
8869 {
8870 if (rig->caps->targetable_vfo & RIG_TARGETABLE_SPECTRUM)
8871 {
8872 RETURNFUNC(ICOM_GET_VFO_NUMBER(vfo));
8873 }
8874
8875 RETURNFUNC(0);
8876 }
8877
icom_get_spectrum_edge_frequency_range(RIG * rig,vfo_t vfo,int * range_id)8878 static int icom_get_spectrum_edge_frequency_range(RIG *rig, vfo_t vfo,
8879 int *range_id)
8880 {
8881 freq_t freq;
8882 rmode_t mode;
8883 pbwidth_t width;
8884 int cache_ms_freq, cache_ms_mode, cache_ms_width;
8885 int i, retval;
8886 struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) rig->caps->priv;
8887
8888 retval = rig_get_cache(rig, vfo, &freq, &cache_ms_freq, &mode, &cache_ms_mode,
8889 &width, &cache_ms_width);
8890
8891 if (retval != RIG_OK)
8892 {
8893 RETURNFUNC(retval);
8894 }
8895
8896 // Get frequency if it is not cached or value is old
8897 if (freq == 0 || cache_ms_freq >= 1000)
8898 {
8899 retval = rig_get_freq(rig, vfo, &freq);
8900
8901 if (retval != RIG_OK)
8902 {
8903 RETURNFUNC(retval);
8904 }
8905 }
8906
8907 for (i = 0; i < ICOM_MAX_SPECTRUM_FREQ_RANGES; i++)
8908 {
8909 int id = priv_caps->spectrum_edge_frequency_ranges[i].range_id;
8910
8911 if (id < 1)
8912 {
8913 break;
8914 }
8915
8916 if (freq >= priv_caps->spectrum_edge_frequency_ranges[i].low_freq
8917 && freq < priv_caps->spectrum_edge_frequency_ranges[i].high_freq)
8918 {
8919 *range_id = id;
8920 RETURNFUNC(RIG_OK);
8921 }
8922 }
8923
8924 RETURNFUNC(-RIG_EINVAL);
8925 }
8926
8927 /*
8928 * init_icom is called by rig_probe_all (register.c)
8929 *
8930 * probe_icom reports all the devices on the CI-V bus.
8931 *
8932 * rig_model_t probeallrigs_icom(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data)
8933 */
DECLARE_PROBERIG_BACKEND(icom)8934 DECLARE_PROBERIG_BACKEND(icom)
8935 {
8936 unsigned char buf[MAXFRAMELEN], civ_addr, civ_id;
8937 int frm_len, i;
8938 rig_model_t model = RIG_MODEL_NONE;
8939 int rates[] = { 19200, 9600, 300, 0 };
8940 int rates_idx;
8941
8942 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
8943
8944 if (!port)
8945 {
8946 RETURNFUNC(RIG_MODEL_NONE);
8947 }
8948
8949 if (port->type.rig != RIG_PORT_SERIAL)
8950 {
8951 RETURNFUNC(RIG_MODEL_NONE);
8952 }
8953
8954 port->write_delay = port->post_write_delay = 0;
8955 port->retry = 1;
8956
8957 /*
8958 * try for all different baud rates
8959 */
8960 for (rates_idx = 0; rates[rates_idx]; rates_idx++)
8961 {
8962 int retval;
8963 port->parm.serial.rate = rates[rates_idx];
8964 port->timeout = 2 * 1000 / rates[rates_idx] + 40;
8965
8966 retval = serial_open(port);
8967
8968 if (retval != RIG_OK)
8969 {
8970 RETURNFUNC(RIG_MODEL_NONE);
8971 }
8972
8973 /*
8974 * try all possible addresses on the CI-V bus
8975 * FIXME: actually, old rigs do not support C_RD_TRXID cmd!
8976 * Try to be smart, and deduce model depending
8977 * on freq range, return address, and
8978 * available commands.
8979 */
8980 for (civ_addr = 0x01; civ_addr <= 0x7f; civ_addr++)
8981 {
8982
8983 frm_len = make_cmd_frame((char *) buf, civ_addr, CTRLID,
8984 C_RD_TRXID, S_RD_TRXID, NULL, 0);
8985
8986 rig_flush(port);
8987 write_block(port, (char *) buf, frm_len);
8988
8989 /* read out the bytes we just sent
8990 * TODO: check this is what we expect
8991 */
8992 read_icom_frame(port, buf, sizeof(buf));
8993
8994 /* this is the reply */
8995 frm_len = read_icom_frame(port, buf, sizeof(buf));
8996
8997 /* timeout.. nobody's there */
8998 if (frm_len <= 0)
8999 {
9000 continue;
9001 }
9002
9003 if (buf[7] != FI && buf[5] != FI)
9004 {
9005 /* protocol error, unexpected reply.
9006 * is this a CI-V device?
9007 */
9008 close(port->fd);
9009 RETURNFUNC(RIG_MODEL_NONE);
9010 }
9011 else if (buf[4] == NAK)
9012 {
9013 /*
9014 * this is an Icom, but it does not support transceiver ID
9015 * try to guess from the return address
9016 */
9017 civ_id = buf[3];
9018 }
9019 else
9020 {
9021 civ_id = buf[6];
9022 }
9023
9024 for (i = 0; icom_addr_list[i].model != RIG_MODEL_NONE; i++)
9025 {
9026 if (icom_addr_list[i].re_civ_addr == civ_id)
9027 {
9028 rig_debug(RIG_DEBUG_VERBOSE, "%s: found %#x at %#x\n",
9029 __func__, civ_id, buf[3]);
9030 model = icom_addr_list[i].model;
9031
9032 if (cfunc)
9033 {
9034 (*cfunc)(port, model, data);
9035 }
9036
9037 break;
9038 }
9039 }
9040
9041 /*
9042 * not found in known table....
9043 * update icom_addr_list[]!
9044 */
9045 if (icom_addr_list[i].model == RIG_MODEL_NONE)
9046 rig_debug(RIG_DEBUG_WARN, "%s: found unknown device "
9047 "with CI-V ID %#x, please report to Hamlib "
9048 "developers.\n", __func__, civ_id);
9049 }
9050
9051 /*
9052 * Try to identify OptoScan
9053 */
9054 for (civ_addr = 0x80; civ_addr <= 0x8f; civ_addr++)
9055 {
9056
9057 frm_len = make_cmd_frame((char *) buf, civ_addr, CTRLID,
9058 C_CTL_MISC, S_OPTO_RDID, NULL, 0);
9059
9060 rig_flush(port);
9061 write_block(port, (char *) buf, frm_len);
9062
9063 /* read out the bytes we just sent
9064 * TODO: check this is what we expect
9065 */
9066 read_icom_frame(port, buf, sizeof(buf));
9067
9068 /* this is the reply */
9069 frm_len = read_icom_frame(port, buf, sizeof(buf));
9070
9071 /* timeout.. nobody's there */
9072 if (frm_len <= 0)
9073 {
9074 continue;
9075 }
9076
9077 /* wrong protocol? */
9078 if (frm_len != 7 || buf[4] != C_CTL_MISC || buf[5] != S_OPTO_RDID)
9079 {
9080 continue;
9081 }
9082
9083 rig_debug(RIG_DEBUG_VERBOSE, "%s: "
9084 "found OptoScan%c%c%c, software version %d.%d, "
9085 "interface version %d.%d, at %#x\n",
9086 __func__,
9087 buf[2], buf[3], buf[4],
9088 buf[5] >> 4, buf[5] & 0xf,
9089 buf[6] >> 4, buf[6] & 0xf, civ_addr);
9090
9091 if (buf[6] == '5' && buf[7] == '3' && buf[8] == '5')
9092 {
9093 model = RIG_MODEL_OS535;
9094 }
9095 else if (buf[6] == '4' && buf[7] == '5' && buf[8] == '6')
9096 {
9097 model = RIG_MODEL_OS456;
9098 }
9099 else
9100 {
9101 continue;
9102 }
9103
9104 if (cfunc)
9105 {
9106 (*cfunc)(port, model, data);
9107 }
9108
9109 break;
9110 }
9111
9112 close(port->fd);
9113
9114 /*
9115 * Assumes all the rigs on the bus are running at same speed.
9116 * So if one at least has been found, none will be at lower speed.
9117 */
9118 if (model != RIG_MODEL_NONE)
9119 {
9120 RETURNFUNC(model);
9121 }
9122 }
9123
9124 RETURNFUNC(model);
9125 }
9126
9127 /*
9128 * initrigs_icom is called by rig_backend_load
9129 */
DECLARE_INITRIG_BACKEND(icom)9130 DECLARE_INITRIG_BACKEND(icom)
9131 {
9132 rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__);
9133
9134 rig_register(&ic703_caps);
9135 rig_register(&ic705_caps);
9136 rig_register(&ic706_caps);
9137 rig_register(&ic706mkii_caps);
9138 rig_register(&ic706mkiig_caps);
9139 rig_register(&ic718_caps);
9140 rig_register(&ic725_caps);
9141 rig_register(&ic726_caps);
9142 rig_register(&ic735_caps);
9143 rig_register(&ic736_caps);
9144 rig_register(&ic737_caps);
9145 rig_register(&ic738_caps);
9146 rig_register(&ic7410_caps);
9147 rig_register(&ic746_caps);
9148 rig_register(&ic746pro_caps);
9149 rig_register(&ic751_caps);
9150 rig_register(&ic761_caps);
9151 rig_register(&ic775_caps);
9152 rig_register(&ic756_caps);
9153 rig_register(&ic756pro_caps);
9154 rig_register(&ic756pro2_caps);
9155 rig_register(&ic756pro3_caps);
9156 rig_register(&ic7600_caps);
9157 rig_register(&ic765_caps);
9158 rig_register(&ic7700_caps);
9159 rig_register(&ic78_caps);
9160 rig_register(&ic7800_caps);
9161 rig_register(&ic785x_caps);
9162 rig_register(&ic7000_caps);
9163 rig_register(&ic7100_caps);
9164 rig_register(&ic7200_caps);
9165 rig_register(&ic7300_caps);
9166 rig_register(&ic7610_caps);
9167 rig_register(&ic781_caps);
9168 rig_register(&ic707_caps);
9169 rig_register(&ic728_caps);
9170 rig_register(&ic729_caps);
9171
9172 rig_register(&ic820h_caps);
9173 rig_register(&ic821h_caps);
9174 rig_register(&ic910_caps);
9175 rig_register(&ic9100_caps);
9176 rig_register(&ic970_caps);
9177 rig_register(&ic9700_caps);
9178
9179 rig_register(&icrx7_caps);
9180 rig_register(&icr6_caps);
9181 rig_register(&icr10_caps);
9182 rig_register(&icr20_caps);
9183 rig_register(&icr30_caps);
9184 rig_register(&icr71_caps);
9185 rig_register(&icr72_caps);
9186 rig_register(&icr75_caps);
9187 rig_register(&icr7000_caps);
9188 rig_register(&icr7100_caps);
9189 rig_register(&icr8500_caps);
9190 rig_register(&icr8600_caps);
9191 rig_register(&icr9000_caps);
9192 rig_register(&icr9500_caps);
9193
9194 rig_register(&ic271_caps);
9195 rig_register(&ic275_caps);
9196 rig_register(&ic471_caps);
9197 rig_register(&ic475_caps);
9198 rig_register(&ic575_caps);
9199 rig_register(&ic1275_caps);
9200
9201 rig_register(&os535_caps);
9202 rig_register(&os456_caps);
9203
9204 rig_register(&omnivip_caps);
9205 rig_register(&delta2_caps);
9206
9207 rig_register(&ic92d_caps);
9208 rig_register(&id1_caps);
9209 rig_register(&id31_caps);
9210 rig_register(&id51_caps);
9211 rig_register(&id4100_caps);
9212 rig_register(&id5100_caps);
9213 rig_register(&ic2730_caps);
9214
9215 rig_register(&perseus_caps);
9216
9217 rig_register(&x108g_caps);
9218
9219 RETURNFUNC(RIG_OK);
9220 }
9221