1 /*
2 * Hamlib AOR backend - AR7030 Plus description
3 * Copyright (c) 2000-2010 by Stephane Fillod & Fritz Melchert
4 * Copyright (c) 2009-2010 by Larry Gadallah (VE6VQ)
5 *
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23 /*
24 * Version 2009.11.21 Larry Gadallah (VE6VQ)
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <math.h>
34 #include <assert.h>
35 #include <stdlib.h>
36
37 #include "hamlib/rig.h"
38 #include "ar7030p.h"
39 #include "serial.h"
40 #include "idx_builtin.h"
41
42 #define AR7030P_MODES ( RIG_MODE_AM | \
43 RIG_MODE_SSB | \
44 RIG_MODE_CW | \
45 RIG_MODE_RTTY | \
46 RIG_MODE_FM | \
47 RIG_MODE_AMS )
48
49 #define AR7030P_FUNC ( RIG_FUNC_FAGC | \
50 RIG_FUNC_NB | \
51 RIG_FUNC_ANF | \
52 RIG_FUNC_AIP | \
53 RIG_FUNC_MN | \
54 RIG_FUNC_RF | \
55 RIG_FUNC_LOCK | \
56 RIG_FUNC_MUTE | \
57 RIG_FUNC_SQL )
58
59 #define AR7030P_LEVEL ( RIG_LEVEL_PREAMP | \
60 RIG_LEVEL_ATT | \
61 RIG_LEVEL_AF | \
62 RIG_LEVEL_RF | \
63 RIG_LEVEL_SQL | \
64 RIG_LEVEL_PBT_IN | \
65 RIG_LEVEL_CWPITCH | \
66 RIG_LEVEL_NOTCHF | \
67 RIG_LEVEL_AGC | \
68 RIG_LEVEL_RAWSTR | \
69 RIG_LEVEL_STRENGTH )
70
71 #define AR7030P_PARM ( RIG_PARM_APO | \
72 RIG_PARM_TIME | \
73 RIG_PARM_BAT )
74
75 #define AR7030P_VFO_OPS ( RIG_OP_CPY | \
76 RIG_OP_XCHG | \
77 RIG_OP_TOGGLE )
78
79 #define AR7030P_VFO ( RIG_VFO_A | \
80 RIG_VFO_B)
81
82 #define AR7030P_STR_CAL { 8, { \
83 { 10, -113 }, \
84 { 10, -103 }, \
85 { 10, -93 }, \
86 { 10, -83 }, \
87 { 10, -73 }, \
88 { 10, -63 }, \
89 { 20, -43 }, \
90 { 20, -23 }, \
91 } }
92
93 /* Channel capabilities
94 - Frequency
95 - Mode
96 - Width
97 - Scan lockout
98 - PBT
99 - Squelch
100 - ID
101 */
102 #define AR7030P_MEM_CAP { \
103 .freq = 1, \
104 .mode = 1, \
105 .width = 1, \
106 .funcs = RIG_FUNC_NONE, \
107 .levels = RIG_LEVEL_SQL | RIG_LEVEL_PBT_IN, \
108 .flags = 1, \
109 .channel_desc = 1 \
110 }
111
112 struct ar7030p_priv_caps
113 {
114 int max_freq_len;
115 int info_len;
116 int mem_len;
117 int pbs_info_len;
118 int pbs_len;
119 int chan_num;
120 };
121
122 static const struct ar7030p_priv_caps ar7030p_priv_caps =
123 {
124 .max_freq_len = 3,
125 .info_len = 14,
126 .mem_len = 17,
127 .pbs_info_len = 1,
128 .pbs_len = 1,
129 .chan_num = 0,
130 };
131
132 #define NB_CHAN 400 /* see caps->chan_list */
133
134 struct ar7030p_priv_data
135 {
136 vfo_t curr_vfo;
137 vfo_t last_vfo; /* VFO A or VFO B, when in MEM mode */
138
139 powerstat_t powerstat;
140 int bank;
141 value_t parms[ RIG_SETTING_MAX ];
142
143 channel_t *curr; /* points to vfo_a, vfo_b or mem[] */
144
145 channel_t vfo_a;
146 channel_t vfo_b;
147 channel_t mem[ NB_CHAN ];
148
149 struct ext_list *ext_parms;
150 };
151
152 static const struct confparams ar7030p_ext_levels[] =
153 {
154 {
155 TOK_EL_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example",
156 NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } }
157 },
158
159 {
160 TOK_EL_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example",
161 NULL, RIG_CONF_CHECKBUTTON
162 },
163
164 {
165 TOK_EL_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example",
166 NULL, RIG_CONF_BUTTON
167 },
168
169 { RIG_CONF_END, NULL, }
170 };
171
172 static const struct confparams ar7030p_ext_parms[] =
173 {
174 {
175 TOK_EP_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example",
176 NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } }
177 },
178
179 { RIG_CONF_END, NULL, }
180 };
181
182 /* TODO - move this somewhere where it belongs */
183 static unsigned int filterTab[ 6 + 1 ] = { 0 };
184
185
init_chan(RIG * rig,vfo_t vfo,channel_t * chan)186 static void init_chan(RIG *rig, vfo_t vfo, channel_t *chan)
187 {
188 assert(NULL != rig);
189 assert(NULL != chan);
190
191 chan->channel_num = 0;
192 chan->vfo = vfo;
193
194 strcpy(chan->channel_desc, rig_strvfo(vfo));
195
196 chan->freq = MHz(10);
197 chan->mode = RIG_MODE_AM;
198 chan->width = rig_passband_normal(rig, RIG_MODE_AM);
199
200 chan->tuning_step = 110;
201
202 chan->funcs = (setting_t) 0;
203
204 memset(chan->levels, 0, RIG_SETTING_MAX * sizeof(value_t));
205 }
206
alloc_init_ext(const struct confparams * cfp)207 static struct ext_list *alloc_init_ext(const struct confparams *cfp)
208 {
209 struct ext_list *elp;
210 int i, nb_ext;
211
212 assert(NULL != cfp);
213
214 for (nb_ext = 0; !RIG_IS_EXT_END(cfp[nb_ext]); nb_ext++)
215 {
216 ;
217 }
218
219 elp = calloc((nb_ext + 1), sizeof(struct ext_list));
220
221 if (!elp)
222 {
223 return NULL;
224 }
225
226 for (i = 0; !RIG_IS_EXT_END(cfp[i]); i++)
227 {
228 elp[i].token = cfp[i].token;
229 /* value reset already by calloc */
230 }
231
232 /* last token in array is set to 0 by calloc */
233 return elp;
234 }
235
236 #if 0 /* unused; re-enabled as needed. */
237 static struct ext_list *find_ext(struct ext_list *elp, token_t token)
238 {
239 int i;
240
241 for (i = 0; elp[ i ].token != 0; i++)
242 {
243 if (elp[ i ].token == token)
244 {
245 return &(elp[ i ]);
246 }
247 }
248
249 return NULL;
250 }
251 #endif /* unused */
252
ar7030p_init(RIG * rig)253 static int ar7030p_init(RIG *rig)
254 {
255 struct ar7030p_priv_data *priv;
256 int rc = RIG_OK;
257
258 assert(NULL != rig);
259
260 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
261
262 priv = (struct ar7030p_priv_data *)
263 malloc(sizeof(struct ar7030p_priv_data));
264
265 if (!priv)
266 {
267 rc = -RIG_ENOMEM;
268 }
269 else
270 {
271 int i;
272
273 rig->state.priv = (void *) priv;
274
275 rig->state.rigport.type.rig = RIG_PORT_SERIAL;
276
277 priv->powerstat = RIG_POWER_ON;
278 priv->bank = 0;
279
280 memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t));
281
282 memset(priv->mem, 0, sizeof(priv->mem));
283
284 for (i = 0; i < NB_CHAN; i++)
285 {
286 priv->mem[ i ].channel_num = i;
287 priv->mem[ i ].vfo = RIG_VFO_MEM;
288
289 priv->mem[ i ].ext_levels = alloc_init_ext(ar7030p_ext_levels);
290
291 if (!priv->mem[ i ].ext_levels)
292 {
293 rc = -RIG_ENOMEM;
294 break;
295 }
296 }
297
298 if (RIG_OK == rc)
299 {
300 priv->vfo_a.ext_levels = alloc_init_ext(ar7030p_ext_levels);
301
302 if (!priv->vfo_a.ext_levels)
303 {
304 return -RIG_ENOMEM;
305 }
306 else
307 {
308 priv->vfo_b.ext_levels = alloc_init_ext(ar7030p_ext_levels);
309 }
310
311 if (!priv->vfo_b.ext_levels)
312 {
313 return -RIG_ENOMEM;
314 }
315
316 priv->ext_parms = alloc_init_ext(ar7030p_ext_parms);
317
318 if (!priv->ext_parms)
319 {
320 return -RIG_ENOMEM;
321 }
322
323 init_chan(rig, RIG_VFO_A, &priv->vfo_a);
324 init_chan(rig, RIG_VFO_B, &priv->vfo_b);
325
326 priv->curr = &priv->vfo_a;
327 priv->curr_vfo = priv->last_vfo = RIG_VFO_A;
328 }
329 }
330
331 return (rc);
332 }
333
ar7030p_cleanup(RIG * rig)334 static int ar7030p_cleanup(RIG *rig)
335 {
336 struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) rig->state.priv;
337 int rc = RIG_OK;
338 int i;
339
340 rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
341
342 for (i = 0; i < NB_CHAN; i++)
343 {
344 free(priv->mem[ i ].ext_levels);
345 }
346
347 free(priv->vfo_a.ext_levels);
348 free(priv->vfo_b.ext_levels);
349
350 free(priv->ext_parms);
351
352 if (NULL != rig->state.priv)
353 {
354 free(rig->state.priv);
355 }
356
357 rig->state.priv = NULL;
358
359 return (rc);
360 }
361
362 /*
363 * /brief Open I/O to receiver
364 *
365 * /param rig Pointer to rig struct
366 *
367 * /return 0 on success, < 0 on failure
368 */
ar7030p_open(RIG * rig)369 static int ar7030p_open(RIG *rig)
370 {
371 int rc = RIG_OK;
372 unsigned char v;
373
374 assert(NULL != rig);
375
376 rc = lockRx(rig, LOCK_1);
377
378 if (RIG_OK == rc)
379 {
380 int i;
381
382 /* Load calibration table */
383 rig->state.str_cal.size = rig->caps->str_cal.size;
384
385 for (i = 0; i < rig->state.str_cal.size; i++)
386 {
387 rc = readByte(rig, EEPROM1, SM_CAL + i, &v);
388
389 if (RIG_OK != rc)
390 {
391 break;
392 }
393
394 rig->state.str_cal.table[ i ].val = rig->caps->str_cal.table[ i ].val;
395 rig->state.str_cal.table[ i ].raw = (int) v;
396
397 rig_debug(RIG_DEBUG_VERBOSE, "%s: index %d, val %d, raw %d\n",
398 __func__, i, rig->state.str_cal.table[ i ].val,
399 rig->state.str_cal.table[ i ].raw);
400 }
401
402 if (RIG_OK == rc)
403 {
404 /* Load filter BW table */
405 for (i = 1; i <= 6; i++)
406 {
407 rc = getFilterBW(rig, i);
408
409 if (rc < 0)
410 {
411 rig_debug(RIG_DEBUG_ERR, "%s: err in getFilterBW: %s\n", __func__,
412 rigerror(rc));
413 return rc;
414 }
415 else
416 {
417 filterTab[i] = (unsigned int) rc;
418 }
419 }
420 }
421
422 rc = lockRx(rig, LOCK_0);
423
424 rig_debug(RIG_DEBUG_VERBOSE, "%s: \n", __func__);
425 }
426
427 return (rc);
428 }
429
430 /*
431 * /brief Close I/O to receiver
432 *
433 * /param rig Pointer to rig struct
434 *
435 * /return 0 on success, < 0 on failure
436 */
ar7030p_close(RIG * rig)437 static int ar7030p_close(RIG *rig)
438 {
439 assert(NULL != rig);
440
441 rig_debug(RIG_DEBUG_VERBOSE, "%s: \n", __func__);
442
443 return (RIG_OK);
444 }
445
ar7030p_get_info(RIG * rig)446 static const char *ar7030p_get_info(RIG *rig)
447 {
448 static char version[10] = "";
449 unsigned int i;
450 char *p = &(version[ 0 ]);
451
452 assert(NULL != rig);
453
454 for (i = 0; i < pageSize(ROM); i++)
455 {
456 if (RIG_OK != readByte(rig, ROM, i, (unsigned char *) p++))
457 {
458 p = NULL;
459 break;
460 }
461 }
462
463 if (NULL != p)
464 {
465 *p++ = '\0';
466 p = &(version[ 0 ]);
467
468 rig_debug(RIG_DEBUG_VERBOSE, "%s: ident - %s\n", __func__, version);
469 }
470
471 return (p);
472 }
473
474 /*
475 * /brief Set receiver frequency
476 *
477 * /param rig Pointer to rig struct
478 * /param vfo VFO to operate on
479 * /param freq Frequency to set
480 *
481 */
ar7030p_set_freq(RIG * rig,vfo_t vfo,freq_t freq)482 static int ar7030p_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
483 {
484 int rc = RIG_OK;
485
486 assert(NULL != rig);
487
488 rc = lockRx(rig, LOCK_1);
489
490 if (RIG_OK == rc)
491 {
492 const struct rig_caps *caps = rig->caps;
493
494 if ((caps->rx_range_list1[ 0 ].endf > freq) &&
495 (caps->rx_range_list1[ 0 ].startf < freq))
496 {
497 switch (vfo)
498 {
499 case RIG_VFO_CURR:
500 case RIG_VFO_A:
501 rc = write3Bytes(rig, WORKING, FREQU, hzToDDS(freq));
502 break;
503
504 case RIG_VFO_B:
505 rc = write3Bytes(rig, WORKING, FREQU_B, hzToDDS(freq));
506 break;
507
508 default:
509 rc = -RIG_EINVAL;
510 break;
511 }
512 }
513 else
514 {
515 rc = -RIG_EINVAL;
516 }
517
518 // this RIG_OK check added to clear cppcheck warnings
519 // not sure if it's needed but seem like RIG_OK should be expected
520 // if this debug prints out when things are working need to reexamine
521 if (rc != RIG_OK)
522 {
523 rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc));
524 }
525
526 rc = execRoutine(rig, SET_ALL);
527
528 if (rc == RIG_OK) { rc = lockRx(rig, LOCK_0); }
529 }
530
531 return (rc);
532 }
533
534 /*
535 * /brief Get receiver frequency
536 *
537 * /param rig Pointer to rig struct
538 * /param vfo VFO to operate on
539 * /param freq Pointer to hold frequency value (in Hz)
540 *
541 */
ar7030p_get_freq(RIG * rig,vfo_t vfo,freq_t * freq)542 static int ar7030p_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
543 {
544 int rc = RIG_OK;
545 unsigned int x;
546
547 rc = lockRx(rig, LOCK_1);
548
549 if (RIG_OK == rc)
550 {
551 switch (vfo)
552 {
553 case RIG_VFO_CURR:
554 case RIG_VFO_A:
555 rc = read3Bytes(rig, WORKING, FREQU, &x);
556
557 if (RIG_OK == rc)
558 {
559 *freq = ddsToHz(x);
560 }
561
562 break;
563
564 case RIG_VFO_B:
565 rc = read3Bytes(rig, WORKING, FREQU_B, &x);
566 {
567 *freq = ddsToHz(x);
568 }
569 break;
570
571 default:
572 rc = -RIG_EINVAL;
573 break;
574 }
575
576 // this RIG_OK check added to clear cppcheck warnings
577 // not sure if it's needed but seem like RIG_OK should be expected
578 // if this debug prints out when things are working need to reexamine
579 if (rc != RIG_OK)
580 {
581 rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc));
582 }
583
584 rc = lockRx(rig, LOCK_0);
585 }
586
587 return (rc);
588 }
589
590 /*
591 * /brief Set receiver mode
592 *
593 * /param rig Pointer to rig struct
594 * /param vfo VFO to operate on
595 * /param mode Mode to set
596 * /param width Bandwidth to set
597 *
598 */
ar7030p_set_mode(RIG * rig,vfo_t vfo,rmode_t mode,pbwidth_t width)599 static int ar7030p_set_mode(RIG *rig, vfo_t vfo, rmode_t mode,
600 pbwidth_t width)
601 {
602 int rc = RIG_OK;
603
604 rc = lockRx(rig, LOCK_1);
605
606 if (RIG_OK == rc)
607 {
608 /* TODO - deal with selected VFO */
609 unsigned char ar_mode = modeToNative(mode);
610
611 rc = writeByte(rig, WORKING, MODE, ar_mode);
612
613 if (RIG_OK == rc && width != RIG_PASSBAND_NOCHANGE)
614 {
615 int i;
616
617 /* TODO - get filter BWs at startup */
618 unsigned char ar_filter = (unsigned char) 6;
619
620 for (i = 1; i <= 6; i++)
621 {
622 if (width <= filterTab[ i ])
623 {
624 if (filterTab[ i ] < filterTab[(int) ar_filter ])
625 {
626 ar_filter = (unsigned char) i;
627 }
628 }
629
630 rig_debug(RIG_DEBUG_VERBOSE, "%s: width %d ar_filter %d filterTab[%d] %u\n",
631 __func__, (int)width, ar_filter, i, filterTab[i]);
632 }
633
634 rc = writeByte(rig, WORKING, FILTER, ar_filter);
635
636 if (RIG_OK == rc)
637 {
638 rc = execRoutine(rig, SET_ALL);
639 }
640 }
641
642 // this RIG_OK check added to clear cppcheck warnings
643 // not sure if it's needed but seem like RIG_OK should be expected
644 // if this debug prints out when things are working need to reexamine
645 if (rc != RIG_OK)
646 {
647 rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc));
648 }
649
650 rc = lockRx(rig, LOCK_0);
651 }
652
653 return (rc);
654 }
655
656 /*
657 * /brief Get receiver mode and bandwidth
658 *
659 * /param rig Pointer to rig struct
660 * /param vfo VFO to operate on
661 * /param mode Pointer to value to hold mode
662 * /param width Pointer to value to hold bandwidth
663 *
664 */
ar7030p_get_mode(RIG * rig,vfo_t vfo,rmode_t * mode,pbwidth_t * width)665 static int ar7030p_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode,
666 pbwidth_t *width)
667 {
668 int rc = RIG_OK;
669 unsigned char bcd_bw;
670 unsigned char m;
671
672 assert(NULL != rig);
673 assert(NULL != mode);
674 assert(NULL != width);
675
676 rc = lockRx(rig, LOCK_1);
677
678 if (RIG_OK == rc)
679 {
680 /* TODO - deal with selected VFO */
681 rc = readByte(rig, WORKING, MODE, &m);
682
683 if (RIG_OK == rc)
684 {
685 *mode = modeToHamlib(m);
686 rc = readByte(rig, WORKING, FLTBW, &bcd_bw);
687
688 if (RIG_OK == rc)
689 {
690 *width = (pbwidth_t)((int) bcd2Int(bcd_bw) * 100);
691 }
692 }
693
694 rc = lockRx(rig, LOCK_0);
695 }
696
697 return (rc);
698 }
699
700 /*
701 * /brief Get memory channel parameters
702 *
703 * /param rig Pointer to rig struct
704 * /param chan Channel number (0-399)
705 * /param freq Pointer to frequency value
706 * /param mode Pointer to mode value (1-7)
707 * /param filt Pointer to filter value (1-6)
708 * /param pbs Pointer to passband tuning value
709 * /param sql Pointer to squelch value (0-255)
710 * /param id Pointer to channel ident string (14 chars)
711 *
712 */
713 #if 0 /* unused; re-enabled as needed. */
714 static void ar7030p_get_memory(RIG *rig, const unsigned int chan,
715 double *const freq, unsigned char *const mode,
716 unsigned char *const filt, unsigned char *const pbs,
717 unsigned char *const sql, char *const id)
718 {
719 int rc = RIG_OK;
720 unsigned char v;
721 unsigned int f;
722 unsigned char *p = (unsigned char *) id;
723 int i;
724
725 assert(NULL != rig);
726 assert(NULL != freq);
727 assert(NULL != mode);
728 assert(NULL != filt);
729 assert(NULL != pbs);
730 assert(NULL != sql);
731 assert(NULL != id);
732
733 rc = lockRx(rig, LOCK_1);
734
735 if (RIG_OK == rc)
736 {
737 /* Squelch values */
738 if (100 > chan)
739 {
740 rc = readByte(rig, BBRAM, (MEM_SQ + chan), &v); /* mem_sq */
741 }
742 else if (176 > chan)
743 {
744 rc = readByte(rig, EEPROM2, (MEX_SQ + (chan * 16)), &v); /* mex_sq */
745 }
746 else
747 {
748 rc = readByte(rig, EEPROM3, (MEY_SQ + ((chan - 176) * 16)), &v); /* mey_sq */
749 }
750
751 if (RIG_OK == rc)
752 {
753 *sql = v;
754 }
755
756 /* Frequency, mode and filter values */
757 if (100 > chan)
758 {
759 rc = read3Bytes(rig, EEPROM2, (MEM_FR + (chan * 4)), &f); /* mem_fr */
760 rc = readByte(rig, EEPROM2, (MEM_MD + (chan * 4)), &v); /* mem_md */
761 }
762 else
763 {
764 rc = read3Bytes(rig, EEPROM3, (MEX_FR + ((chan - 100) * 4)),
765 &f); /* mex_fr */
766 rc = readByte(rig, EEPROM3, (MEX_MD + ((chan - 100) * 4)),
767 &v); /* mex_md */
768 }
769
770 if (RIG_OK == rc)
771 {
772 *freq = ddsToHz(f);
773 *mode = (v & 0x07);
774 *filt = ((v & 0x70) >> 4);
775 /* lockout = ( ( v & 0x80 ) >> 7 ); */
776 }
777
778 /* PBT values */
779 if (100 > chan)
780 {
781 rc = readByte(rig, EEPROM1, (MEM_PB + chan), &v); /* mem_pb */
782 }
783 else if (176 > chan)
784 {
785 rc = readByte(rig, EEPROM2, (MEX_PB + (chan * 16)), &v); /* mex_pb */
786 }
787 else
788 {
789 rc = readByte(rig, EEPROM3, (MEY_PB + ((chan - 176) * 16)), &v); /* mey_pb */
790 }
791
792 if (RIG_OK == rc)
793 {
794 *pbs = v;
795 }
796
797 /* Memory ID values */
798 for (i = 0; i < 14; i++)
799 {
800 if (176 > chan)
801 {
802 rc = readByte(rig, EEPROM2, (MEX_ID + (chan * 16)), p++); /* mex_id */
803 }
804 else
805 {
806 rc = readByte(rig, EEPROM3, (MEY_ID + ((chan - 176) * 16)), p++); /* mey_id */
807 }
808
809 if (RIG_OK != rc)
810 {
811 p = (unsigned char *) id;
812 break;
813 }
814 }
815
816 *p++ = '\0';
817
818 rc = lockRx(rig, LOCK_0);
819 }
820
821 }
822 #endif /* unused */
823
824 /*
825 * /brief Set receiver levels
826 *
827 * /param rig Pointer to rig struct
828 * /param vfo VFO to operate on
829 * /param level Level to set
830 * /param val Value to set level to
831 *
832 * /return RIG_OK on success
833 */
ar7030p_set_level(RIG * rig,vfo_t vfo,setting_t level,value_t val)834 static int ar7030p_set_level(RIG *rig, vfo_t vfo, setting_t level,
835 value_t val)
836 {
837 int rc = RIG_OK;
838
839 rc = lockRx(rig, LOCK_1);
840
841 if (RIG_OK == rc)
842 {
843 /* TODO - deal with selected VFO */
844 switch (level)
845 {
846 unsigned char v;
847
848 case RIG_LEVEL_PREAMP:
849
850 /* Scale parameter */
851 if (10 <= val.i)
852 {
853 v = (unsigned char) 0;
854 }
855 else
856 {
857 v = (unsigned char) 1;
858 }
859
860 rc = writeByte(rig, WORKING, RFGAIN, v); /* rfgain */
861
862 rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, val.i, v);
863
864 if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
865
866 break;
867
868 case RIG_LEVEL_ATT:
869
870 /* Scale parameter */
871 if (10 > val.i)
872 {
873 v = (unsigned char) 1;
874 }
875 else if (20 > val.i)
876 {
877 v = (unsigned char) 2;
878 }
879 else if (40 > val.i)
880 {
881 v = (unsigned char) 3;
882 }
883 else if (80 > val.i)
884 {
885 v = (unsigned char) 4;
886 }
887 else
888 {
889 v = (unsigned char) 5;
890 }
891
892 rc = writeByte(rig, WORKING, RFGAIN, v); /* rfgain */
893
894 rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, val.i, v);
895
896 if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
897
898 break;
899
900 case RIG_LEVEL_AF:
901 /* Scale parameter */
902 v = (unsigned char)((val.f * (VOL_MAX - VOL_MIN)) + VOL_MIN);
903 v = (v & 0x3f);
904
905 rc = writeByte(rig, WORKING, AF_VOL, v); /* af_vol */
906
907 rig_debug(RIG_DEBUG_VERBOSE, "%s: af_vol %f (%d)\n", __func__, val.f, v);
908
909 v = ((v >> 1) & 0x1f); /* half value for L/R volume */
910
911 if (rc == RIG_OK) { rc = writeByte(rig, WORKING, AF_VLL, v); } /* af_vll */
912
913 if (rc == RIG_OK) { rc = writeByte(rig, WORKING, AF_VLR, v); } /* af_vlr */
914
915 if (rc == RIG_OK) { rc = execRoutine(rig, SET_AUDIO); }
916
917 break;
918
919 case RIG_LEVEL_RF:
920 /* Scale parameter, values 0 (99%) to 130 (3%) */
921 v = (unsigned char)(134U - ((unsigned int)(val.f * 135.0)));
922
923 rc = writeByte(rig, WORKING, IFGAIN, v); /* ifgain */
924
925 rig_debug(RIG_DEBUG_VERBOSE, "%s: ifgain %f (%d)\n", __func__, val.f, v);
926
927 if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
928
929 break;
930
931 case RIG_LEVEL_SQL:
932 /* Scale parameter */
933 v = (unsigned char)(val.f * 255.0);
934
935 rc = writeByte(rig, WORKING, SQLVAL, v); /* sqlval */
936
937 rig_debug(RIG_DEBUG_VERBOSE, "%s: sqlval %f (%d)\n", __func__, val.f, v);
938
939 if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
940
941 break;
942
943 case RIG_LEVEL_PBT_IN:
944 /* Scale parameter */
945 v = (unsigned char)(val.f / (HZ_PER_STEP * 12.5));
946
947 rc = writeByte(rig, WORKING, PBSVAL, v); /* pbsval */
948
949 rig_debug(RIG_DEBUG_VERBOSE, "%s: pbsval %f (%d)\n", __func__, val.f, v);
950
951 if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
952
953 break;
954
955 case RIG_LEVEL_CWPITCH:
956 /* Scale parameter */
957 v = (unsigned char)(val.f / (HZ_PER_STEP * 12.5));
958
959 rc = writeByte(rig, WORKING, BFOVAL, v); /* bfoval */
960
961 rig_debug(RIG_DEBUG_VERBOSE, "%s: bfoval %f (%d)\n", __func__, val.f, v);
962
963 if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
964
965 break;
966
967 case RIG_LEVEL_NOTCHF:
968 rc = -RIG_ENIMPL;
969 break;
970
971 case RIG_LEVEL_AGC:
972 /* Scale parameter */
973 v = agcToNative(val.i);
974 rc = writeByte(rig, WORKING, AGCSPD, v); /* agcspd */
975
976 rig_debug(RIG_DEBUG_VERBOSE, "%s: agcspd %d (%d)\n", __func__, val.i, v);
977
978 if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
979
980 break;
981
982 default:
983 rc = -RIG_EINVAL;
984 break;
985 }
986
987 // this RIG_OK check added to clear cppcheck warnings
988 // not sure if it's needed but seem like RIG_OK should be expected
989 // if this debug prints out when things are working need to reexamine
990 if (rc != RIG_OK)
991 {
992 rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc));
993 }
994
995 rc = lockRx(rig, LOCK_0);
996 }
997
998 return (rc);
999 }
1000
1001
1002 /*
1003 * /brief Get receiver levels
1004 *
1005 * /param rig Pointer to rig struct
1006 * /param vfo VFO to operate on
1007 * /param level Level to get
1008 * /param val Pointer to value to get
1009 *
1010 * /return RIG_OK on success
1011 */
ar7030p_get_level(RIG * rig,vfo_t vfo,setting_t level,value_t * val)1012 static int ar7030p_get_level(RIG *rig, vfo_t vfo, setting_t level,
1013 value_t *val)
1014 {
1015 int rc = RIG_OK;
1016 unsigned char v;
1017 unsigned short s = 0;
1018 int i;
1019
1020 rc = lockRx(rig, LOCK_1);
1021
1022 if (RIG_OK == rc)
1023 {
1024 /* TODO - deal with selected VFO */
1025 switch (level)
1026 {
1027 case RIG_LEVEL_PREAMP:
1028 rc = readByte(rig, WORKING, RFGAIN, &v); /* rfgain */
1029
1030 if (RIG_OK == rc)
1031 {
1032 /* Scale parameter */
1033 if (0 == v)
1034 {
1035 val->i = 10;
1036 }
1037 else
1038 {
1039 val->i = 0;
1040 }
1041
1042 rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n",
1043 __func__, v, val->i);
1044 }
1045
1046 break;
1047
1048 case RIG_LEVEL_ATT:
1049 rc = readByte(rig, WORKING, RFGAIN, &v); /* rfgain */
1050
1051 if (RIG_OK == rc)
1052 {
1053 /* Scale parameter */
1054 switch (v)
1055 {
1056 case 2:
1057 val->i = 10;
1058 break;
1059
1060 case 3:
1061 val->i = 20;
1062 break;
1063
1064 case 4:
1065 val->i = 40;
1066 break;
1067
1068 default:
1069 case 0:
1070 case 1:
1071 val->i = 0;
1072 };
1073
1074 rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n",
1075 __func__, v, val->i);
1076 }
1077
1078 break;
1079
1080 case RIG_LEVEL_AF:
1081 rc = readByte(rig, WORKING, AF_VOL, &v); /* af_vol */
1082
1083 if (RIG_OK == rc)
1084 {
1085 /* Scale parameter */
1086 v = (v & 0x3f);
1087 val->f = (((float) v - VOL_MIN) / (VOL_MAX - VOL_MIN));
1088
1089 rig_debug(RIG_DEBUG_VERBOSE, "%s: af_vol %d (%f)\n",
1090 __func__, v, val->f);
1091 }
1092
1093 break;
1094
1095 case RIG_LEVEL_RF:
1096 rc = readByte(rig, WORKING, IFGAIN, &v); /* ifgain */
1097
1098 if (RIG_OK == rc)
1099 {
1100 /* Scale parameter, values 0 (99%) to 130 (3%) */
1101 val->f = ((float)(134 - v) / 135.0);
1102
1103 rig_debug(RIG_DEBUG_VERBOSE, "%s: ifgain %d (%f)\n",
1104 __func__, v, val->f);
1105 }
1106
1107 break;
1108
1109 case RIG_LEVEL_SQL:
1110 rc = readByte(rig, WORKING, SQLVAL, &v); /* sqlval */
1111
1112 if (RIG_OK == rc)
1113 {
1114 /* Scale parameter */
1115 val->f = ((float)(v) / 255.0);
1116
1117 rig_debug(RIG_DEBUG_VERBOSE, "%s: sqlval %d (%f)\n",
1118 __func__, v, val->f);
1119 }
1120
1121 break;
1122
1123 case RIG_LEVEL_PBT_IN:
1124 rc = readByte(rig, WORKING, PBSVAL, &v); /* pbsval */
1125
1126 if (RIG_OK == rc)
1127 {
1128 /* Scale parameter */
1129 if (127 < v)
1130 {
1131 v = v | 0xffffff00;
1132 }
1133
1134 val->f = ((float)(v) * HZ_PER_STEP * 12.5);
1135
1136 rig_debug(RIG_DEBUG_VERBOSE, "%s: pbsval %d (%f)\n",
1137 __func__, v, val->f);
1138 }
1139
1140 break;
1141
1142 case RIG_LEVEL_CWPITCH:
1143 rc = readByte(rig, WORKING, BFOVAL, &v); /* bfoval */
1144
1145 if (RIG_OK == rc)
1146 {
1147 /* Scale parameter */
1148 if (127 < v)
1149 {
1150 v = v | 0xffffff00;
1151 }
1152
1153 val->f = ((float)(v) * HZ_PER_STEP * 12.5);
1154
1155 rig_debug(RIG_DEBUG_VERBOSE, "%s: bfoval %d (%f)\n",
1156 __func__, v, val->f);
1157 }
1158
1159 break;
1160
1161 case RIG_LEVEL_NOTCHF:
1162 rc = readShort(rig, WORKING, NCHFR, &s); /* nchfr */
1163
1164 if (RIG_OK == rc)
1165 {
1166 unsigned int x = (unsigned int) s;
1167
1168 /* Scale parameter */
1169 val->i = (int)((float)(x) / NOTCH_STEP_HZ);
1170
1171 rig_debug(RIG_DEBUG_VERBOSE, "%s: nchfr %u (%d)\n",
1172 __func__, x, val->i);
1173 }
1174
1175 break;
1176
1177 case RIG_LEVEL_AGC:
1178 rc = readByte(rig, WORKING, AGCSPD, &v); /* agcspd */
1179
1180 if (RIG_OK == rc)
1181 {
1182 /* Scale parameter */
1183 val->i = agcToHamlib(v);
1184
1185 rig_debug(RIG_DEBUG_VERBOSE, "%s: agcspd %d (%d)\n",
1186 __func__, v, val->i);
1187 }
1188
1189 break;
1190
1191 case RIG_LEVEL_RAWSTR:
1192 rc = readSignal(rig, &v);
1193
1194 if (RIG_OK == rc)
1195 {
1196 val->i = (int) v;
1197 }
1198
1199 break;
1200
1201 case RIG_LEVEL_STRENGTH:
1202 rc = readSignal(rig, &v);
1203
1204 if (RIG_OK == rc)
1205 {
1206 rc = getCalLevel(rig, v, &i);
1207
1208 if (RIG_OK == rc)
1209 {
1210 val->i = i;
1211 }
1212 }
1213
1214 break;
1215
1216 default:
1217 rc = -RIG_EINVAL;
1218 }
1219
1220 if (RIG_OK == rc) { rc = lockRx(rig, LOCK_0); }
1221 }
1222
1223 return (rc);
1224 }
1225
ar7030p_set_vfo(RIG * rig,vfo_t vfo)1226 static int ar7030p_set_vfo(RIG *rig, vfo_t vfo)
1227 {
1228 int rc = RIG_OK;
1229 struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) rig->state.priv;
1230
1231 switch (vfo)
1232 {
1233 case RIG_VFO_B:
1234 if (RIG_VFO_B != priv->curr_vfo)
1235 {
1236 rc = sendIRCode(rig, IR_VFO);
1237
1238 if (RIG_OK == rc)
1239 {
1240 priv->curr_vfo = RIG_VFO_B;
1241 priv->last_vfo = RIG_VFO_A;
1242 }
1243 }
1244
1245 break;
1246
1247 case RIG_VFO_A:
1248 case RIG_VFO_CURR:
1249 if (RIG_VFO_A != priv->curr_vfo)
1250 {
1251 rc = sendIRCode(rig, IR_VFO);
1252
1253 if (RIG_OK == rc)
1254 {
1255 priv->curr_vfo = RIG_VFO_A;
1256 priv->last_vfo = RIG_VFO_B;
1257 }
1258 }
1259
1260 break;
1261
1262 default:
1263 rc = -RIG_EINVAL;
1264 break;
1265 }
1266
1267 return (rc);
1268 }
1269
ar7030p_get_vfo(RIG * rig,vfo_t * vfo)1270 static int ar7030p_get_vfo(RIG *rig, vfo_t *vfo)
1271 {
1272 int rc = RIG_OK;
1273 struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) rig->state.priv;
1274
1275 assert(NULL != vfo);
1276
1277 *vfo = priv->curr_vfo;
1278
1279 return (rc);
1280 }
1281
ar7030p_set_parm(RIG * rig,setting_t parm,value_t val)1282 static int ar7030p_set_parm(RIG *rig, setting_t parm, value_t val)
1283 {
1284 int rc = -RIG_ENIMPL;
1285
1286 assert(NULL != rig);
1287
1288 switch (parm)
1289 {
1290 case RIG_PARM_APO:
1291 break;
1292
1293 case RIG_PARM_TIME:
1294 break;
1295
1296 case RIG_PARM_BAT:
1297 break;
1298
1299 default:
1300 break;
1301 };
1302
1303 return (rc);
1304 }
1305
ar7030p_get_parm(RIG * rig,setting_t parm,value_t * val)1306 static int ar7030p_get_parm(RIG *rig, setting_t parm, value_t *val)
1307 {
1308 int rc = -RIG_ENIMPL;
1309
1310 assert(NULL != rig);
1311 assert(NULL != val);
1312
1313 switch (parm)
1314 {
1315 case RIG_PARM_APO:
1316 break;
1317
1318 case RIG_PARM_TIME:
1319 break;
1320
1321 case RIG_PARM_BAT:
1322 break;
1323
1324 default:
1325 break;
1326 };
1327
1328 return (rc);
1329 }
1330
ar7030p_set_mem(RIG * rig,vfo_t vfo,int ch)1331 static int ar7030p_set_mem(RIG *rig, vfo_t vfo, int ch)
1332 {
1333 int rc = RIG_OK;
1334
1335 struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) rig->state.priv;
1336
1337 if (RIG_VFO_MEM == priv->curr_vfo)
1338 {
1339 priv->curr = &priv->mem[ ch ];
1340 }
1341 else
1342 {
1343 priv->curr->channel_num = ch;
1344 }
1345
1346 rig_debug(RIG_DEBUG_VERBOSE, "%s: ch %d\n", __func__, ch);
1347
1348 return (rc);
1349 }
1350
ar7030p_get_mem(RIG * rig,vfo_t vfo,int * ch)1351 static int ar7030p_get_mem(RIG *rig, vfo_t vfo, int *ch)
1352 {
1353 int rc = RIG_OK;
1354
1355 struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) rig->state.priv;
1356 channel_t *curr = priv->curr;
1357
1358 assert(NULL != ch);
1359
1360 *ch = curr->channel_num;
1361
1362 rig_debug(RIG_DEBUG_VERBOSE, "%s: ch %d\n", __func__, *ch);
1363
1364 return (rc);
1365 }
1366
ar7030p_vfo_op(RIG * rig,vfo_t vfo,vfo_op_t op)1367 static int ar7030p_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op)
1368 {
1369 int rc = -RIG_ENIMPL;
1370
1371 assert(NULL != rig);
1372
1373 switch (op)
1374 {
1375 case RIG_OP_CPY:
1376 rc = -RIG_ENIMPL;
1377 break;
1378
1379 case RIG_OP_XCHG:
1380 rc = -RIG_ENIMPL;
1381 break;
1382
1383 case RIG_OP_TOGGLE:
1384 rc = sendIRCode(rig, IR_VFO);
1385 break;
1386
1387 default:
1388 break;
1389 };
1390
1391 return (rc);
1392 }
1393
ar7030p_scan(RIG * rig,vfo_t vfo,scan_t scan,int ch)1394 static int ar7030p_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch)
1395 {
1396 int rc = -RIG_ENIMPL;
1397
1398 assert(NULL != rig);
1399
1400 return (rc);
1401 }
1402
ar7030p_get_dcd(RIG * rig,vfo_t vfo,dcd_t * dcd)1403 static int ar7030p_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd)
1404 {
1405 int rc = RIG_OK;
1406 unsigned char v;
1407
1408 assert(NULL != rig);
1409 assert(NULL != dcd);
1410
1411 rc = lockRx(rig, LOCK_1);
1412
1413 if (RIG_OK == rc)
1414 {
1415 rc = readByte(rig, WORKING, BITS + 2, &v);
1416
1417 if (RIG_OK == rc)
1418 {
1419 if ((v & 0x02))
1420 {
1421 if ((v & 0x01)) /* low bit set if Squelch is NOT active/open */
1422 {
1423 *dcd = RIG_DCD_OFF;
1424 }
1425 else
1426 {
1427 *dcd = RIG_DCD_ON;
1428 }
1429 }
1430 else
1431 {
1432 *dcd = RIG_DCD_ON;
1433 }
1434 }
1435
1436 rc = lockRx(rig, LOCK_0);
1437 }
1438
1439 return (rc);
1440 }
1441
ar7030p_set_ts(RIG * rig,vfo_t vfo,shortfreq_t ts)1442 static int ar7030p_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts)
1443 {
1444 int rc = RIG_OK;
1445
1446 assert(NULL != rig);
1447
1448 rc = lockRx(rig, LOCK_1);
1449
1450 if (RIG_OK == rc)
1451 {
1452 /* Scale parameter */
1453 unsigned short v = (unsigned short)((double)(ts + 1) / HZ_PER_STEP);
1454
1455 rc = writeShort(rig, WORKING, CHNSTP, v); /* chnstp */
1456
1457 if (RIG_OK == rc)
1458 {
1459 rc = execRoutine(rig, SET_ALL);
1460
1461 rig_debug(RIG_DEBUG_VERBOSE, "%s: chnstp %d (%d)\n", __func__, (int)ts, v);
1462 }
1463
1464 if (RIG_OK == rc) { rc = lockRx(rig, LOCK_0); }
1465 }
1466
1467 return (rc);
1468 }
1469
1470 /*
1471 * /brief Get receiver tuning step size
1472 *
1473 * /param rig Pointer to rig struct
1474 * /param vfo VFO to operate on
1475 * /param ts Pointer to tuning step value
1476 *
1477 * /return RIG_OK on success
1478 */
ar7030p_get_ts(RIG * rig,vfo_t vfo,shortfreq_t * ts)1479 static int ar7030p_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts)
1480 {
1481 int rc = RIG_OK;
1482 unsigned short v;
1483
1484 assert(NULL != rig);
1485 assert(NULL != ts);
1486
1487 rc = lockRx(rig, LOCK_1);
1488
1489 if (RIG_OK == rc)
1490 {
1491 rc = readShort(rig, WORKING, CHNSTP, &v); /* chnstp */
1492
1493 if (RIG_OK == rc)
1494 {
1495 double x = (double) v;
1496 *ts = (shortfreq_t)(x * HZ_PER_STEP);
1497
1498 rig_debug(RIG_DEBUG_VERBOSE, "%s: step= %d\n", __func__, (int)*ts);
1499 }
1500
1501 rc = lockRx(rig, LOCK_0);
1502 }
1503
1504 return (rc);
1505 }
1506
1507 /*
1508 * /brief Set receiver power status
1509 *
1510 * /param rig Pointer to rig struct
1511 * /param status Power status to set
1512 *
1513 * /return RIG_OK on success
1514 */
ar7030p_set_powerstat(RIG * rig,powerstat_t status)1515 static int ar7030p_set_powerstat(RIG *rig, powerstat_t status)
1516 {
1517 int rc;
1518
1519 assert(NULL != rig);
1520
1521 rc = lockRx(rig, LOCK_1);
1522
1523 if (RIG_OK == rc)
1524 {
1525 switch (status)
1526 {
1527 case RIG_POWER_OFF:
1528 break;
1529
1530 case RIG_POWER_ON:
1531 break;
1532
1533 default:
1534 break;
1535 }
1536
1537 lockRx(rig, LOCK_0);
1538 }
1539
1540 return (-RIG_ENIMPL);
1541 }
1542
1543 /*
1544 * /brief Get receiver power status
1545 *
1546 * /param rig Pointer to rig struct
1547 * /param status Pointer to power status value
1548 *
1549 * /return RIG_OK on success
1550 */
ar7030p_get_powerstat(RIG * rig,powerstat_t * status)1551 static int ar7030p_get_powerstat(RIG *rig, powerstat_t *status)
1552 {
1553 int rc = RIG_OK;
1554 unsigned char v;
1555
1556 assert(NULL != rig);
1557
1558 rc = lockRx(rig, LOCK_1);
1559
1560 if (RIG_OK == rc)
1561 {
1562 rc = readByte(rig, WORKING, PDFLGS, &v);
1563
1564 if (RIG_OK == rc)
1565 {
1566 if (0 == (v & 0x01))
1567 {
1568 *status = RIG_POWER_OFF;
1569 }
1570 else
1571 {
1572 *status = RIG_POWER_ON;
1573 }
1574 }
1575
1576 rc = lockRx(rig, LOCK_0);
1577 }
1578
1579 return (rc);
1580 }
1581
1582 /*
1583 * /brief Reset receiver
1584 *
1585 * /param rig Pointer to rig struct
1586 * /param reset Reset operation to perform
1587 *
1588 * /return RIG_OK on success
1589 */
ar7030p_reset(RIG * rig,reset_t reset)1590 static int ar7030p_reset(RIG *rig, reset_t reset)
1591 {
1592 int rc = RIG_OK;
1593
1594 assert(NULL != rig);
1595
1596 switch (reset)
1597 {
1598 case RIG_RESET_SOFT:
1599 rc = execRoutine(rig, RESET);
1600 break;
1601
1602 default:
1603 rc = -RIG_EINVAL;
1604 }
1605
1606 return (rc);
1607 }
1608
ar7030p_set_func(RIG * rig,vfo_t vfo,setting_t func,int status)1609 static int ar7030p_set_func(RIG *rig, vfo_t vfo, setting_t func,
1610 int status)
1611 {
1612 assert(NULL != rig);
1613
1614 return (-RIG_ENIMPL);
1615 }
1616
ar7030p_get_func(RIG * rig,vfo_t vfo,setting_t func,int * status)1617 static int ar7030p_get_func(RIG *rig, vfo_t vfo, setting_t func,
1618 int *status)
1619 {
1620 assert(NULL != rig);
1621 assert(NULL != status);
1622
1623 return (-RIG_ENIMPL);
1624 }
1625
ar7030p_decode_event(RIG * rig)1626 static int ar7030p_decode_event(RIG *rig)
1627 {
1628 assert(NULL != rig);
1629
1630 return (-RIG_ENIMPL);
1631 }
1632
ar7030p_set_channel(RIG * rig,vfo_t vfo,const channel_t * chan)1633 static int ar7030p_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan)
1634 {
1635 assert(NULL != rig);
1636 assert(NULL != chan);
1637
1638 return (-RIG_ENIMPL);
1639 }
1640
ar7030p_get_channel(RIG * rig,vfo_t vfo,channel_t * chan,int read_only)1641 static int ar7030p_get_channel(RIG *rig, vfo_t vfo, channel_t *chan,
1642 int read_only)
1643 {
1644 int rc = RIG_OK;
1645 unsigned char v;
1646 unsigned int f;
1647 unsigned char *p = NULL;
1648 int ch;
1649 struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *)rig->state.priv;
1650 channel_t *curr = priv->curr;
1651
1652 assert(NULL != chan);
1653
1654 ch = curr->channel_num;
1655
1656 rc = lockRx(rig, LOCK_1);
1657
1658 if (RIG_OK == rc)
1659 {
1660 int i;
1661
1662 /* Squelch values */
1663 /* TODO - fix magic numbers */
1664 if (100 > ch)
1665 {
1666 rc = readByte(rig, BBRAM, (MEM_SQ + ch), &v); /* mem_sq */
1667 }
1668 else if (176 > ch)
1669 {
1670 rc = readByte(rig, EEPROM2, (MEX_SQ + (ch * 16)), &v); /* mex_sq */
1671 }
1672 else
1673 {
1674 rc = readByte(rig, EEPROM3, (MEY_SQ + ((ch - 176) * 16)), &v); /* mey_sq */
1675 }
1676
1677 if (RIG_OK == rc)
1678 {
1679 // cppcheck-suppress *
1680 chan->levels[ LVL_SQL ].f = (float) v / 255.0;
1681 }
1682
1683 /* Frequency, mode and filter values */
1684 if (100 > ch)
1685 {
1686 rc = read3Bytes(rig, EEPROM1, (MEM_FR + (ch * 4)), &f); /* mem_fr */
1687
1688 if (RIG_OK == rc) { rc = readByte(rig, EEPROM1, (MEM_MD + (ch * 4)), &v); } /* mem_md */
1689 }
1690 else
1691 {
1692 rc = read3Bytes(rig, EEPROM2, (MEX_FR + ((ch - 100) * 4)), &f); /* mex_fr */
1693
1694 if (RIG_OK == rc) { rc = readByte(rig, EEPROM2, (MEX_MD + ((ch - 100) * 4)), &v); } /* mex_md */
1695 }
1696
1697 if (RIG_OK == rc)
1698 {
1699 chan->freq = ddsToHz(f);
1700 chan->mode = modeToHamlib((v & 0x07));
1701 chan->width = getFilterBW(rig, ((v & 0x70) >> 4));
1702
1703 if ((v & 0x80) >> 7)
1704 {
1705 chan->flags = RIG_CHFLAG_SKIP;
1706 }
1707 else
1708 {
1709 chan->flags = RIG_CHFLAG_NONE;
1710 }
1711 }
1712
1713 /* PBT values */
1714 if (100 > ch)
1715 {
1716 rc = readByte(rig, EEPROM1, (MEM_PB + ch), &v); /* mem_pb */
1717 }
1718 else if (176 > ch)
1719 {
1720 rc = readByte(rig, EEPROM2, (MEX_PB + (ch * 16)), &v); /* mex_pb */
1721 }
1722 else
1723 {
1724 rc = readByte(rig, EEPROM3, (MEY_PB + ((ch - 176) * 16)), &v); /* mey_pb */
1725 }
1726
1727 if (RIG_OK == rc)
1728 {
1729 chan->levels[ LVL_PBT_IN ].f = pbsToHz(v);
1730 }
1731
1732 /* Memory ID values */
1733 p = (unsigned char *) chan->channel_desc;
1734
1735 for (i = 0; i < 14; i++)
1736 {
1737 if (176 > ch)
1738 {
1739 rc = readByte(rig, EEPROM2, (MEX_ID + (ch * 16) + i), p++); /* mex_id */
1740 }
1741 else
1742 {
1743 rc = readByte(rig, EEPROM3, (MEY_ID + ((ch - 176) * 16) + i),
1744 p++); /* mey_id */
1745 }
1746
1747 if (RIG_OK != rc)
1748 {
1749 p = (unsigned char *) chan->channel_desc;
1750 break;
1751 }
1752 }
1753
1754 *p++ = '\0';
1755
1756 rc = lockRx(rig, LOCK_0);
1757 }
1758
1759 if (!read_only)
1760 {
1761 // Set rig to channel values
1762 rig_debug(RIG_DEBUG_ERR,
1763 "%s: please contact hamlib mailing list to implement this\n", __func__);
1764 rig_debug(RIG_DEBUG_ERR,
1765 "%s: need to know if rig updates when channel read or not\n", __func__);
1766 return -RIG_ENIMPL;
1767 }
1768
1769 return (rc);
1770 }
1771
1772 const struct rig_caps ar7030p_caps =
1773 {
1774 RIG_MODEL(RIG_MODEL_AR7030P),
1775 .model_name = "AR7030 Plus",
1776 .mfg_name = "AOR",
1777 .version = "20200319.0",
1778 .copyright = "LGPL",
1779 .status = RIG_STATUS_BETA,
1780 .rig_type = RIG_TYPE_RECEIVER,
1781
1782 .dcd_type = RIG_DCD_RIG,
1783
1784 .port_type = RIG_PORT_SERIAL,
1785 .serial_rate_min = 1200,
1786 .serial_rate_max = 1200,
1787 .serial_data_bits = 8,
1788 .serial_stop_bits = 1,
1789 .serial_parity = RIG_PARITY_NONE,
1790 .serial_handshake = RIG_HANDSHAKE_NONE,
1791 .write_delay = 0,
1792 .post_write_delay = 12,
1793 .timeout = 650,
1794 .retry = 0,
1795
1796 .has_get_func = AR7030P_FUNC,
1797 .has_set_func = AR7030P_FUNC,
1798 .has_get_level = AR7030P_LEVEL,
1799 .has_set_level = RIG_LEVEL_SET(AR7030P_LEVEL),
1800 .has_get_parm = AR7030P_PARM,
1801 .has_set_parm = RIG_PARM_SET(AR7030P_PARM),
1802
1803 .level_gran = {
1804 [LVL_PREAMP] = {.min = {.i = 0}, .max = {.i = 10} },
1805 [LVL_ATT] = {.min = {.i = 0}, .max = {.i = 20} },
1806 [LVL_RF] = {.min = {.f = 0.0}, .max = {.f = 1.0} },
1807 [LVL_AF] = {.min = {.f = 0.0}, .max = {.f = 1.0} },
1808 [LVL_SQL] = {.min = {.f = 0.0}, .max = {.f = 1.0} },
1809 [LVL_IF] = {.min = {.i = 255}, .max = {.i = 0} },
1810 [LVL_PBT_IN] = {.min = {.f = -4248.0}, .max = {.f = 4248.0} },
1811 [LVL_CWPITCH] = {.min = {.i = -4248}, .max = {.i = 4248} },
1812 [LVL_NOTCHF] = {.min = {.i = 0}, .max = {.i = 10000} },
1813 [LVL_AGC] = {.min = {.i = 0}, .max = {.i = 10} },
1814 [LVL_BALANCE] = {.min = {.f = -1.0}, .max = {.f = 1.0} },
1815 [LVL_RAWSTR] = {.min = {.i = 0}, .max = {.i = 255} },
1816 [LVL_STRENGTH] = {.min = {.i = 0}, .max = {.i = 255} },
1817 },
1818
1819 .extparms = NULL,
1820 .extlevels = NULL,
1821
1822 .parm_gran = {
1823 [PARM_APO] = {.min = {.i = 1}, .max = {.i = 86400} },
1824 [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86400} },
1825 [PARM_BAT] = {.min = {.f = 0.0}, .max = {.f = 1.0} },
1826 },
1827
1828 .preamp = {10, RIG_DBLST_END,},
1829 .attenuator = {10, 20, RIG_DBLST_END,},
1830 .max_rit = Hz(0),
1831 .max_xit = Hz(0),
1832 .max_ifshift = Hz(4248),
1833 .announces = RIG_ANN_NONE,
1834 .vfo_ops = AR7030P_VFO_OPS,
1835 .scan_ops = RIG_SCAN_STOP | RIG_SCAN_MEM | RIG_SCAN_VFO,
1836 .targetable_vfo = 0,
1837 .transceive = RIG_TRN_OFF,
1838 .bank_qty = 0,
1839 .chan_desc_sz = 14,
1840
1841 .chan_list = {{0, 399, RIG_MTYPE_MEM, AR7030P_MEM_CAP}, RIG_CHAN_END,},
1842
1843 .rx_range_list1 = {
1844 {
1845 kHz(10), kHz(32010), AR7030P_MODES, -1, -1,
1846 AR7030P_VFO
1847 },
1848 RIG_FRNG_END,
1849 },
1850 .tx_range_list1 = {RIG_FRNG_END,},
1851
1852 .rx_range_list2 = {
1853 {
1854 kHz(10), kHz(32010), AR7030P_MODES, -1, -1,
1855 AR7030P_VFO
1856 },
1857 RIG_FRNG_END,
1858 },
1859 .tx_range_list2 = {RIG_FRNG_END,},
1860
1861 .tuning_steps = {
1862 {AR7030P_MODES, Hz(10)},
1863 {AR7030P_MODES, Hz(20)},
1864 {AR7030P_MODES, Hz(50)},
1865 {AR7030P_MODES, Hz(100)},
1866 {AR7030P_MODES, Hz(200)},
1867 {AR7030P_MODES, Hz(500)},
1868 {AR7030P_MODES, kHz(1)},
1869 {AR7030P_MODES, kHz(2)},
1870 {AR7030P_MODES, kHz(5)},
1871 {AR7030P_MODES, kHz(6.25)},
1872 {AR7030P_MODES, kHz(9)},
1873 {AR7030P_MODES, kHz(10)},
1874 {AR7030P_MODES, Hz(12500)},
1875 {AR7030P_MODES, kHz(20)},
1876 {AR7030P_MODES, kHz(25)},
1877 RIG_TS_END,
1878 },
1879
1880 .filters = {
1881 {RIG_MODE_FM, kHz(9.5)},
1882 {RIG_MODE_FM, kHz(0)},
1883 {RIG_MODE_FM, kHz(0)},
1884 {RIG_MODE_AMS, kHz(6.5)},
1885 {RIG_MODE_AMS, kHz(5.3)},
1886 {RIG_MODE_AMS, kHz(9.5)},
1887 {RIG_MODE_AM, kHz(5.3)},
1888 {RIG_MODE_AM, kHz(3.7)},
1889 {RIG_MODE_AM, kHz(6.5)},
1890 {RIG_MODE_SSB, kHz(2.0)},
1891 {RIG_MODE_SSB, kHz(1.4)},
1892 {RIG_MODE_SSB, kHz(3.7)},
1893 {RIG_MODE_CW, kHz(1.4)},
1894 {RIG_MODE_CW, kHz(0)},
1895 {RIG_MODE_CW, kHz(2.0)},
1896 {RIG_MODE_RTTY, kHz(1.4)},
1897 {RIG_MODE_RTTY, kHz(0)},
1898 {RIG_MODE_RTTY, kHz(2.0)},
1899 RIG_FLT_END,
1900 },
1901
1902 .str_cal = AR7030P_STR_CAL,
1903 .cfgparams = NULL,
1904 .priv = (void *)& ar7030p_priv_caps,
1905
1906 .rig_init = ar7030p_init,
1907 .rig_cleanup = ar7030p_cleanup,
1908 .rig_open = ar7030p_open,
1909 .rig_close = ar7030p_close,
1910 .set_freq = ar7030p_set_freq,
1911 .get_freq = ar7030p_get_freq,
1912 .set_mode = ar7030p_set_mode,
1913 .get_mode = ar7030p_get_mode,
1914 .set_vfo = ar7030p_set_vfo,
1915 .get_vfo = ar7030p_get_vfo,
1916
1917 .get_dcd = ar7030p_get_dcd,
1918
1919 .set_ts = ar7030p_set_ts,
1920 .get_ts = ar7030p_get_ts,
1921
1922 .set_powerstat = ar7030p_set_powerstat,
1923 .get_powerstat = ar7030p_get_powerstat,
1924 .reset = ar7030p_reset,
1925
1926 .set_level = ar7030p_set_level,
1927 .get_level = ar7030p_get_level,
1928 .set_func = ar7030p_set_func,
1929 .get_func = ar7030p_get_func,
1930 .set_parm = ar7030p_set_parm,
1931 .get_parm = ar7030p_get_parm,
1932
1933 .set_ext_level = RIG_FUNC_NONE,
1934 .get_ext_level = RIG_FUNC_NONE,
1935 .set_ext_parm = RIG_FUNC_NONE,
1936 .get_ext_parm = RIG_FUNC_NONE,
1937 .set_conf = RIG_FUNC_NONE,
1938 .get_conf = RIG_FUNC_NONE,
1939
1940 .set_mem = ar7030p_set_mem,
1941 .get_mem = ar7030p_get_mem,
1942 .vfo_op = ar7030p_vfo_op,
1943 .scan = ar7030p_scan,
1944
1945 .decode_event = ar7030p_decode_event,
1946 .set_channel = ar7030p_set_channel,
1947 .get_channel = ar7030p_get_channel,
1948 .get_info = ar7030p_get_info,
1949
1950 .set_chan_all_cb = RIG_FUNC_NONE,
1951 .get_chan_all_cb = RIG_FUNC_NONE,
1952 .set_mem_all_cb = RIG_FUNC_NONE,
1953 .get_mem_all_cb = RIG_FUNC_NONE,
1954
1955 };
1956