1 /*
2 * Hamlib Kenwood backend - Elecraft K2 description
3 * Copyright (c) 2002-2009 by Stephane Fillod
4 * Copyright (c) 2010 by Nate Bargmann, n0nb@arrl.net
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 * See the file 'COPYING.LIB' in the main Hamlib distribution directory for
21 * the complete text of the GNU Lesser Public License version 2.1.
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include <hamlib/rig.h>
33 #include "kenwood.h"
34 #include "elecraft.h"
35
36
37 #define K2_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB)
38
39 #define K2_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_LOCK)
40
41 #define K2_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_SQL|\
42 RIG_LEVEL_STRENGTH|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD)
43
44 #define K2_VFO (RIG_VFO_A|RIG_VFO_B)
45 #define K2_VFO_OP (RIG_OP_UP|RIG_OP_DOWN)
46
47 #define K2_ANTS (RIG_ANT_1|RIG_ANT_2)
48
49 static rmode_t k2_mode_table[KENWOOD_MODE_TABLE_MAX] =
50 {
51 [0] = RIG_MODE_NONE,
52 [1] = RIG_MODE_LSB,
53 [2] = RIG_MODE_USB,
54 [3] = RIG_MODE_CW,
55 [4] = RIG_MODE_NONE,
56 [5] = RIG_MODE_NONE,
57 [6] = RIG_MODE_PKTLSB, /* AFSK */
58 [7] = RIG_MODE_CWR,
59 [8] = RIG_MODE_NONE, /* TUNE mode */
60 [9] = RIG_MODE_PKTUSB /* AFSK */
61 };
62
63 /* kenwood_transaction() will add this to command strings
64 * sent to the rig and remove it from strings returned from
65 * the rig, so no need to append ';' manually to command strings.
66 */
67 static struct kenwood_priv_caps k2_priv_caps =
68 {
69 .cmdtrm = EOM_KEN,
70 .mode_table = k2_mode_table,
71 };
72
73
74 /* K2 Filter list, four per mode */
75 struct k2_filt_s
76 {
77 shortfreq_t width; /* Filter width in Hz */
78 char fslot; /* Crystal filter slot number--1-4 */
79 char afslot; /* AF filter slot number--0-2 */
80 };
81
82 /* Number of filter slot arrays to allocate (TNX Diane, VA3DB) */
83 #define K2_FILT_NUM 4
84
85 /* K2 Filter List
86 *
87 * This struct will be populated as modes are queried or in response
88 * to a request to set a given mode. This way a cache can be maintained
89 * of the installed filters and an appropriate filter can be selected
90 * for a requested bandwidth. Each mode has up to four filter slots available.
91 */
92 struct k2_filt_lst_s
93 {
94 struct k2_filt_s filt_list[K2_FILT_NUM];
95 };
96
97 struct k2_filt_lst_s k2_fwmd_ssb;
98 struct k2_filt_lst_s k2_fwmd_cw;
99 struct k2_filt_lst_s k2_fwmd_rtty;
100
101 /* K2 specific rig_caps API function declarations */
102 int k2_open(RIG *rig);
103 int k2_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width);
104 int k2_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width);
105 int k2_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val);
106
107 /* Private function declarations */
108 int k2_probe_mdfw(RIG *rig, struct kenwood_priv_data *priv);
109 int k2_mdfw_rest(RIG *rig, const char *mode, const char *fw);
110 int k2_pop_fw_lst(RIG *rig, const char *cmd);
111
112
113 /*
114 * KIO2 rig capabilities.
115 * This kit can recognize a large subset of TS-570 commands.
116 *
117 * Part of info comes from http://www.elecraft.com/K2_Manual_Download_Page.htm#K2
118 * look for KIO2 Programmer's Reference PDF
119 */
120 const struct rig_caps k2_caps =
121 {
122 RIG_MODEL(RIG_MODEL_K2),
123 .model_name = "K2",
124 .mfg_name = "Elecraft",
125 .version = BACKEND_VER ".0",
126 .copyright = "LGPL",
127 .status = RIG_STATUS_BETA,
128 .rig_type = RIG_TYPE_TRANSCEIVER,
129 .ptt_type = RIG_PTT_RIG,
130 .dcd_type = RIG_DCD_RIG,
131 .port_type = RIG_PORT_SERIAL,
132 .serial_rate_min = 4800,
133 .serial_rate_max = 4800,
134 .serial_data_bits = 8,
135 .serial_stop_bits = 2,
136 .serial_parity = RIG_PARITY_NONE,
137 .serial_handshake = RIG_HANDSHAKE_NONE,
138 .write_delay = 0, /* Timing between bytes */
139 .post_write_delay = 100, /* Timing between command strings */
140 // Note that 2000 timeout exceeds usleep but hl_usleep handles it
141 .timeout = 2000, /* FA and FB make take up to 500 ms on band change */
142 .retry = 10,
143
144 .has_get_func = K2_FUNC_ALL,
145 .has_set_func = K2_FUNC_ALL,
146 .has_get_level = K2_LEVEL_ALL,
147 .has_set_level = RIG_LEVEL_SET(K2_LEVEL_ALL),
148 .has_get_parm = RIG_PARM_NONE,
149 .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */
150 .level_gran = {}, /* FIXME: granularity */
151 .parm_gran = {},
152 .extlevels = elecraft_ext_levels,
153 .extparms = kenwood_cfg_params,
154 .preamp = { 14, RIG_DBLST_END, },
155 .attenuator = { 10, RIG_DBLST_END, },
156 .max_rit = Hz(9990),
157 .max_xit = Hz(9990),
158 .max_ifshift = Hz(0),
159 .vfo_ops = K2_VFO_OP,
160 .targetable_vfo = RIG_TARGETABLE_FREQ,
161 .transceive = RIG_TRN_RIG,
162 .bank_qty = 0,
163 .chan_desc_sz = 0,
164
165 .chan_list = { RIG_CHAN_END },
166
167 .rx_range_list1 = {
168 {kHz(500), MHz(30), K2_MODES, -1, -1, K2_VFO, K2_ANTS},
169 RIG_FRNG_END,
170 }, /* rx range */
171 .tx_range_list1 = {
172 {kHz(1810), kHz(1850) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, /* 15W class */
173 {kHz(3500), kHz(3800) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
174 {MHz(7), kHz(7100), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
175 {kHz(10100), kHz(10150), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
176 {MHz(14), kHz(14350), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
177 {kHz(18068), kHz(18168), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
178 {MHz(21), kHz(21450), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
179 {kHz(24890), kHz(24990), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
180 {MHz(28), kHz(29700), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
181 RIG_FRNG_END,
182 }, /* tx range */
183
184 .rx_range_list2 = {
185 {kHz(500), MHz(30), K2_MODES, -1, -1, K2_VFO, K2_ANTS},
186 RIG_FRNG_END,
187 }, /* rx range */
188 .tx_range_list2 = {
189 {kHz(1800), MHz(2) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, /* 15W class */
190 {kHz(3500), MHz(4) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
191 {MHz(7), kHz(7300), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
192 {kHz(10100), kHz(10150), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
193 {MHz(14), kHz(14350), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
194 {kHz(18068), kHz(18168), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
195 {MHz(21), kHz(21450), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
196 {kHz(24890), kHz(24990), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
197 {MHz(28), kHz(29700), K2_MODES, 10, W(15), K2_VFO, K2_ANTS},
198 RIG_FRNG_END,
199 }, /* tx range */
200 .tuning_steps = {
201 {K2_MODES, 10},
202 RIG_TS_END,
203 },
204
205 /* mode/filter list, remember: order matters! */
206 .filters = {
207 {RIG_MODE_SSB, kHz(2.5)},
208 {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)},
209 {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.5)},
210 RIG_FLT_END,
211 },
212 .priv = (void *)& k2_priv_caps,
213
214 .rig_init = kenwood_init,
215 .rig_cleanup = kenwood_cleanup,
216 .rig_open = k2_open,
217 .rig_close = kenwood_close,
218 .set_freq = kenwood_set_freq,
219 .get_freq = kenwood_get_freq,
220 .set_mode = k2_set_mode,
221 .get_mode = k2_get_mode,
222 .set_vfo = kenwood_set_vfo,
223 .get_vfo = kenwood_get_vfo_if,
224 .set_split_vfo = kenwood_set_split_vfo,
225 .get_split_vfo = kenwood_get_split_vfo_if,
226 .set_rit = kenwood_set_rit,
227 .get_rit = kenwood_get_rit,
228 .set_xit = kenwood_set_xit,
229 .get_xit = kenwood_get_xit,
230 .get_ptt = kenwood_get_ptt,
231 .set_ptt = kenwood_set_ptt,
232 .get_dcd = kenwood_get_dcd,
233 .set_func = kenwood_set_func,
234 .get_func = kenwood_get_func,
235 .set_ext_parm = kenwood_set_ext_parm,
236 .get_ext_parm = kenwood_get_ext_parm,
237 .set_level = kenwood_set_level,
238 .get_level = kenwood_get_level,
239 .get_ext_level = k2_get_ext_level,
240 .vfo_op = kenwood_vfo_op,
241 .set_trn = kenwood_set_trn,
242 .get_powerstat = kenwood_get_powerstat,
243 .get_trn = kenwood_get_trn,
244 .set_ant = kenwood_set_ant,
245 .get_ant = kenwood_get_ant,
246 .send_morse = kenwood_send_morse,
247 .wait_morse = rig_wait_morse
248 };
249
250
251 /*
252 * K2 extension function definitions follow
253 */
254
255 /* k2_open()
256 *
257 */
k2_open(RIG * rig)258 int k2_open(RIG *rig)
259 {
260 int err;
261 struct kenwood_priv_data *priv = rig->state.priv;
262
263 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
264
265 err = elecraft_open(rig);
266
267 if (err != RIG_OK)
268 {
269 return err;
270 }
271
272 err = k2_probe_mdfw(rig, priv);
273
274 if (err != RIG_OK)
275 {
276 return err;
277 }
278
279 return RIG_OK;
280 }
281
282
283 /* k2_set_mode()
284 *
285 * Based on the passed in bandwidth, looks up the nearest bandwidth filter
286 * wider than the passed value and sets the radio accordingly.
287 */
288
k2_set_mode(RIG * rig,vfo_t vfo,rmode_t mode,pbwidth_t width)289 int k2_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
290 {
291
292 int err;
293 char f = '*';
294 struct k2_filt_lst_s *flt;
295 struct kenwood_priv_data *priv = rig->state.priv;
296
297 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
298
299 /* Select the filter array per mode. */
300 switch (mode)
301 {
302 case RIG_MODE_LSB:
303 case RIG_MODE_USB:
304 flt = &k2_fwmd_ssb;
305 break;
306
307 case RIG_MODE_CW:
308 case RIG_MODE_CWR:
309 flt = &k2_fwmd_cw;
310 break;
311
312 case RIG_MODE_PKTLSB:
313 case RIG_MODE_PKTUSB:
314 if (priv->k2_md_rtty == 0)
315 {
316 return -RIG_EINVAL; /* RTTY module not installed */
317 }
318 else
319 {
320 flt = &k2_fwmd_rtty;
321 }
322
323 break;
324
325 default:
326 return -RIG_EINVAL;
327 }
328
329 if (width != RIG_PASSBAND_NOCHANGE)
330 {
331 shortfreq_t freq = 0;
332
333 if (width < 0)
334 {
335 width = labs(width);
336 }
337
338 /* Step through the filter list looking for the best match
339 * for the passed in width. The choice is to select the filter
340 * that is wide enough for the width without being too narrow
341 * if possible.
342 */
343 if (width == RIG_PASSBAND_NORMAL)
344 {
345 width = rig_passband_normal(rig, mode);
346 }
347
348 if ((width > flt->filt_list[0].width) || (width > flt->filt_list[1].width))
349 {
350 width = flt->filt_list[0].width;
351 f = '1';
352 }
353 else if ((flt->filt_list[1].width >= width)
354 && (width > flt->filt_list[2].width))
355 {
356 width = flt->filt_list[1].width;
357 f = '2';
358 }
359 else if ((flt->filt_list[2].width >= width)
360 && (width > flt->filt_list[3].width))
361 {
362 width = flt->filt_list[2].width;
363 f = '3';
364 }
365 else if ((flt->filt_list[3].width >= width) && (width >= freq))
366 {
367 width = flt->filt_list[3].width;
368 f = '4';
369 }
370 else
371 {
372 return -RIG_EINVAL;
373 }
374 }
375
376 /* kenwood_set_mode() ignores width value for K2/K3/TS-570 */
377 err = kenwood_set_mode(rig, vfo, mode, width);
378
379 if (err != RIG_OK)
380 {
381 return err;
382 }
383
384 if (width != RIG_PASSBAND_NOCHANGE)
385 {
386 char fcmd[16];
387
388 err = kenwood_transaction(rig, "K22", NULL, 0);
389
390 if (err != RIG_OK)
391 {
392 return err;
393 }
394
395 /* Construct the filter command and set the radio mode and width*/
396 snprintf(fcmd, 8, "FW0000%c", f);
397
398 /* Set the filter slot */
399 err = kenwood_transaction(rig, fcmd, NULL, 0);
400
401 if (err != RIG_OK)
402 {
403 return err;
404 }
405
406 err = kenwood_transaction(rig, "K20", NULL, 0);
407
408 if (err != RIG_OK)
409 {
410 return err;
411 }
412 }
413
414 return RIG_OK;
415 }
416
417
418 /* k2_get_mode()
419 *
420 * Uses the FW command in K22 mode to query the filter bandwidth reported
421 * by the radio and returns it to the caller.
422 */
423
k2_get_mode(RIG * rig,vfo_t vfo,rmode_t * mode,pbwidth_t * width)424 int k2_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
425 {
426 int err;
427 char buf[KENWOOD_MAX_BUF_LEN];
428 char tmp[16];
429 char *bufptr;
430 pbwidth_t temp_w;
431
432 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
433
434 if (!mode || !width)
435 {
436 return -RIG_EINVAL;
437 }
438
439 err = kenwood_get_mode(rig, vfo, mode, &temp_w);
440
441 if (err != RIG_OK)
442 {
443 return err;
444 }
445
446 err = kenwood_transaction(rig, "K22", NULL, 0);
447
448 if (err != RIG_OK)
449 {
450 return err;
451 }
452
453 err = kenwood_safe_transaction(rig, "FW", buf, KENWOOD_MAX_BUF_LEN, 8);
454
455 if (err != RIG_OK)
456 {
457 return err;
458 }
459
460 err = kenwood_transaction(rig, "K20", NULL, 0);
461
462 if (err != RIG_OK)
463 {
464 return err;
465 }
466
467 /* Convert received filter string value's first four digits to width */
468 bufptr = buf;
469
470 strncpy(tmp, bufptr + 2, 4);
471 tmp[4] = '\0';
472 *width = atoi(tmp);
473
474 rig_debug(RIG_DEBUG_VERBOSE, "%s: Mode: %s, Width: %d\n", __func__,
475 rig_strrmode(*mode), (int)*width);
476
477 return RIG_OK;
478 }
479
480
481 /* TQ command is a quick transmit status query--K2/K3 only.
482 *
483 * token Defined in elecraft.h or this file
484 * val Type depends on token type from confparams structure:
485 * NUMERIC: val.f
486 * COMBO: val.i, starting from 0 Index to a string table.
487 * STRING: val.cs for set, val.s for get
488 * CHECKBUTTON: val.i 0/1
489 */
k2_get_ext_level(RIG * rig,vfo_t vfo,token_t token,value_t * val)490 int k2_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val)
491 {
492 char buf[KENWOOD_MAX_BUF_LEN];
493 int err;
494 const struct confparams *cfp;
495
496 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
497
498 if (!val)
499 {
500 return -RIG_EINVAL;
501 }
502
503 cfp = rig_ext_lookup_tok(rig, token);
504
505 switch (token)
506 {
507 case TOK_TX_STAT:
508 err = kenwood_safe_transaction(rig, "TQ", buf, KENWOOD_MAX_BUF_LEN, 3);
509
510 if (err != RIG_OK)
511 {
512 return err;
513 }
514
515 if (cfp->type == RIG_CONF_CHECKBUTTON)
516 {
517 val->i = atoi(&buf[2]);
518 }
519 else
520 {
521 rig_debug(RIG_DEBUG_ERR, "%s: protocol error, invalid token type\n",
522 __func__);
523 return -RIG_EPROTO;
524 }
525
526 break;
527
528 default:
529 rig_debug(RIG_DEBUG_WARN, "%s: Unsupported get_ext_level %s\n",
530 __func__, rig_strlevel(token));
531 return -RIG_EINVAL;
532 }
533
534 return RIG_OK;
535 }
536
537
538 /* K2 private helper functions follow */
539
540 /* Probes for mode and filter settings, based on information
541 * by Chris Bryant, G3WIE.
542 */
k2_probe_mdfw(RIG * rig,struct kenwood_priv_data * priv)543 int k2_probe_mdfw(RIG *rig, struct kenwood_priv_data *priv)
544 {
545 int err, i, c;
546 char buf[KENWOOD_MAX_BUF_LEN];
547 char mode[16];
548 char fw[16];
549 char cmd[16];
550
551 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
552
553 if (!priv)
554 {
555 return -RIG_EINVAL;
556 }
557
558 /* The K2 extension level has been stored by elecraft_open(). Now set rig
559 * to K22 for detailed query of mode and filter width values...
560 */
561 err = kenwood_transaction(rig, "K22", NULL, 0);
562
563 if (err != RIG_OK)
564 {
565 return err;
566 }
567
568 /* Check for mode and store it for later. */
569 err = kenwood_safe_transaction(rig, "MD", buf, KENWOOD_MAX_BUF_LEN, 3);
570
571 if (err != RIG_OK)
572 {
573 return err;
574 }
575
576 strcpy(mode, buf);
577
578 /* Check for filter width and store it for later. */
579 err = kenwood_safe_transaction(rig, "FW", buf, KENWOOD_MAX_BUF_LEN, 8);
580
581 if (err != RIG_OK)
582 {
583 return err;
584 }
585
586 strcpy(fw, buf);
587
588 rig_debug(RIG_DEBUG_VERBOSE, "%s: Mode value: %s, Filter Width value: %s\n",
589 __func__, mode, fw);
590
591 /* Now begin the process of querying the available modes and filters. */
592
593 /* First try to put the K2 into RTTY mode and check if it's available. */
594 priv->k2_md_rtty = 0; /* Assume RTTY module not installed */
595 err = kenwood_transaction(rig, "MD6", NULL, 0);
596
597 if (err != RIG_OK && err != -RIG_ERJCTED)
598 {
599 return err;
600 }
601
602 if (RIG_OK == err)
603 {
604 /* Read back mode and test to see if K2 reports RTTY. */
605 err = kenwood_safe_transaction(rig, "MD", buf, KENWOOD_MAX_BUF_LEN, 3);
606
607 if (err != RIG_OK)
608 {
609 return err;
610 }
611
612 if (!strcmp("MD6", buf))
613 {
614 priv->k2_md_rtty = 1; /* set flag for RTTY mode enabled */
615 }
616 }
617
618 rig_debug(RIG_DEBUG_VERBOSE, "%s: RTTY flag is: %d\n", __func__,
619 priv->k2_md_rtty);
620
621 i = (priv->k2_md_rtty == 1) ? 2 : 1;
622
623 /* Now loop through the modes checking for installed filters. */
624 for (c = 0; i > -1; i--, c++)
625 {
626 if (c == 0)
627 {
628 strcpy(cmd, "MD1"); /* SSB */
629 }
630 else if (c == 1)
631 {
632 strcpy(cmd, "MD3"); /* CW */
633 }
634 else if (c == 2)
635 {
636 strcpy(cmd, "MD6"); /* RTTY */
637 }
638 else /* Oops! */
639 {
640 err = k2_mdfw_rest(rig, mode, fw);
641
642 if (err != RIG_OK)
643 {
644 return err;
645 }
646
647 return -RIG_EINVAL;
648 }
649
650 /* Now populate the Filter arrays */
651 err = k2_pop_fw_lst(rig, cmd);
652
653 if (err != RIG_OK)
654 {
655 return err;
656 }
657 }
658
659 /* Restore mode, filter, extension level */
660 if (strlen(fw) == 8)
661 {
662 fw[7] = '\0'; /* Truncate AFSlot to set filter slot */
663 }
664
665 err = k2_mdfw_rest(rig, mode, fw);
666
667 if (err != RIG_OK)
668 {
669 return err;
670 }
671
672 return RIG_OK;
673 }
674
675
676 /* Restore mode, filter, and ext_lvl to original values */
k2_mdfw_rest(RIG * rig,const char * mode,const char * fw)677 int k2_mdfw_rest(RIG *rig, const char *mode, const char *fw)
678 {
679 int err;
680
681 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
682
683 if (!mode || !fw)
684 {
685 return -RIG_EINVAL;
686 }
687
688 if (strlen(mode) != 3 || strlen(fw) != 7)
689 {
690 return -RIG_EINVAL;
691 }
692
693 err = kenwood_transaction(rig, mode, NULL, 0);
694
695 if (err != RIG_OK)
696 {
697 return err;
698 }
699
700 err = kenwood_transaction(rig, fw, NULL, 0);
701
702 if (err != RIG_OK)
703 {
704 return err;
705 }
706
707 err = kenwood_transaction(rig, "K20", NULL, 0);
708
709 if (err != RIG_OK)
710 {
711 return err;
712 }
713
714 return RIG_OK;
715 }
716
717
718 /* Populate k2_filt_lst_s structure for each mode */
k2_pop_fw_lst(RIG * rig,const char * cmd)719 int k2_pop_fw_lst(RIG *rig, const char *cmd)
720 {
721 int err, f;
722 char fcmd[16];
723 char buf[KENWOOD_MAX_BUF_LEN];
724 char tmp[16];
725 struct k2_filt_lst_s *flt;
726
727 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
728
729 if (!cmd)
730 {
731 return -RIG_EINVAL;
732 }
733
734 /* Store filter data in the correct structure depending on mode */
735 if (strcmp(cmd, "MD1") == 0)
736 {
737 flt = &k2_fwmd_ssb;
738 }
739 else if (strcmp(cmd, "MD3") == 0)
740 {
741 flt = &k2_fwmd_cw;
742 }
743 else if (strcmp(cmd, "MD6") == 0)
744 {
745 flt = &k2_fwmd_rtty;
746 }
747 else
748 {
749 return -RIG_EINVAL;
750 }
751
752 /* Set the mode */
753 err = kenwood_transaction(rig, cmd, NULL, 0);
754
755 if (err != RIG_OK)
756 {
757 return err;
758 }
759
760 for (f = 1; f < 5; f++)
761 {
762 char *bufptr = buf;
763
764 snprintf(fcmd, 8, "FW0000%d", f);
765
766 err = kenwood_transaction(rig, fcmd, NULL, 0);
767
768 if (err != RIG_OK)
769 {
770 return err;
771 }
772
773 err = kenwood_safe_transaction(rig, "FW", buf, KENWOOD_MAX_BUF_LEN, 8);
774
775 if (err != RIG_OK)
776 {
777 return err;
778 }
779
780 /* buf should contain a string "FWxxxxfa;" which corresponds to:
781 * xxxx = filter width in Hz
782 * f = crystal filter slot number--1-4
783 * a = audio filter slot number--0-2
784 */
785 strncpy(tmp, bufptr + 2, 4);
786 tmp[4] = '\0';
787 flt->filt_list[f - 1].width = atoi(tmp);
788
789 strncpy(tmp, bufptr + 6, 1);
790 tmp[1] = '\0';
791 flt->filt_list[f - 1].fslot = atoi(tmp);
792
793 strncpy(tmp, bufptr + 7, 1);
794 tmp[1] = '\0';
795 flt->filt_list[f - 1].afslot = atoi(tmp);
796
797 rig_debug(RIG_DEBUG_VERBOSE, "%s: Width: %04li, FSlot: %i, AFSlot %i\n",
798 __func__, flt->filt_list[f - 1].width, flt->filt_list[f - 1].fslot,
799 flt->filt_list[f - 1].afslot);
800 }
801
802 return RIG_OK;
803 }
804
805