1 // ---------------------------------------------------------------------------
2 //    ADAT
3 // ---------------------------------------------------------------------------
4 //
5 //  adat.h
6 //
7 //  Created by Frank Goenninger DG1SBG.
8 //  Copyright © 2011, 2012 Frank Goenninger.
9 //
10 //   This library is free software; you can redistribute it and/or
11 //   modify it under the terms of the GNU Lesser General Public
12 //   License as published by the Free Software Foundation; either
13 //   version 2.1 of the License, or (at your option) any later version.
14 //
15 //   This library is distributed in the hope that it will be useful,
16 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
17 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 //   Lesser General Public License for more details.
19 //
20 //   You should have received a copy of the GNU Lesser General Public
21 //   License along with this library; if not, write to the Free Software
22 //   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 
24 
25 #if !defined( __ADAT_INCLUDED__ )
26 #define __ADAT_INCLUDED__
27 
28 // ---------------------------------------------------------------------------
29 // SYSTEM INCLUDES
30 // ---------------------------------------------------------------------------
31 
32 
33 // ---------------------------------------------------------------------------
34 //    HAMLIB INCLUDES
35 // ---------------------------------------------------------------------------
36 
37 #include <hamlib/rig.h>
38 
39 // ---------------------------------------------------------------------------
40 //    GLOBAL DEFINITIONS
41 // ---------------------------------------------------------------------------
42 
43 #define BACKEND_VER "20191206"
44 
45 #define ADAT_BUFSZ                 256
46 #define ADAT_RESPSZ                256
47 
48 #define ADAT_CR                    "\x0d"
49 #define ADAT_EOL                   "\x0a"
50 #define ADAT_BOM                   "$"       // Begin of message
51 #define ADAT_EOM                   ADAT_CR   // End of message
52 
53 #define ADAT_ON                    1
54 #define ADAT_OFF                   0
55 
56 #define ADAT_TOGGLE_ON             ADAT_ON
57 #define ADAT_TOGGLE_OFF            ADAT_OFF
58 
59 #define ADAT_FREQ_UNIT_HZ          "Hz"
60 #define ADAT_FREQ_UNIT_HZ_LEN      2
61 
62 #define ADAT_FREQ_UNIT_KHZ         "kHz"
63 #define ADAT_FREQ_UNIT_KHZ_LEN     3
64 
65 #define ADAT_FREQ_UNIT_MHZ         "MHz"
66 #define ADAT_FREQ_UNIT_MHZ_LEN     3
67 
68 #define ADAT_FREQ_UNIT_GHZ         "GHz"
69 #define ADAT_FREQ_UNIT_GHZ_LEN     3
70 
71 #define TOKEN_ADAT_PRODUCT_NAME    TOKEN_BACKEND(1)
72 
73 #define ADAT_SLEEP_MICROSECONDS_BETWEEN_CMDS (11*1000) // = 11 ms
74 #define ADAT_SLEEP_AFTER_RIG_CLOSE  2 // unit: seconds
75 #define ADAT_SLEEP_AFTER_RIG_OPEN   2 // unit: seconds
76 
77 // ADAT VFO SET/GET DEFINITIONS
78 
79 #define ADAT_NR_VFOS               3
80 
81 // Each mode is defined by three values:
82 // ADAT_VFO_STR_... -> The string as given back by TRX when asked by
83 //                     $VFO?
84 // ADAT_VFO_RNR_... -> The Hamlib number of the mode: RIG_VFO_...
85 // ADAT_VFO_ANR_... -> The ADAT Nr representing the VFO when setting it
86 
87 #define ADAT_VFO_STR_A             "A"
88 #define ADAT_VFO_RNR_A             RIG_VFO_A
89 #define ADAT_VFO_ANR_A             1
90 
91 #define ADAT_VFO_STR_B             "B"
92 #define ADAT_VFO_RNR_B             RIG_VFO_B
93 #define ADAT_VFO_ANR_B             2
94 
95 #define ADAT_VFO_STR_C             "C"
96 #define ADAT_VFO_RNR_C             RIG_VFO_C
97 #define ADAT_VFO_ANR_C             3
98 
99 // ADAT MODE DEFINITIONS
100 
101 #define ADAT_MODE_LENGTH           5
102 #define ADAT_NR_MODES              8
103 
104 // Each mode is defined by three values:
105 // ADAT_MODE_STR_... -> The string as given back by TRX when asked by
106 //                      $MOD?
107 // ADAT_MODE_RNR_... -> The Hamlib number of the mode: RIG_MODE_...
108 // ADAT_MODE_ANR_... -> The ADAT Nr representing the mode when setting it
109 
110 #define ADAT_MODE_STR_CW_R         "CW-R"
111 #define ADAT_MODE_RNR_CW_R         RIG_MODE_CWR
112 #define ADAT_MODE_ANR_CW_R         0
113 
114 #define ADAT_MODE_STR_CW           "CW"
115 #define ADAT_MODE_RNR_CW           RIG_MODE_CW
116 #define ADAT_MODE_ANR_CW           1
117 
118 #define ADAT_MODE_STR_LSB          "LSB"
119 #define ADAT_MODE_RNR_LSB          RIG_MODE_LSB
120 #define ADAT_MODE_ANR_LSB          2
121 
122 #define ADAT_MODE_STR_USB          "USB"
123 #define ADAT_MODE_RNR_USB          RIG_MODE_USB
124 #define ADAT_MODE_ANR_USB          3
125 
126 #define ADAT_MODE_STR_AM           "AM"
127 #define ADAT_MODE_RNR_AM           RIG_MODE_AM
128 #define ADAT_MODE_ANR_AM           5
129 
130 #define ADAT_MODE_STR_AM_SL        "AM-SL"
131 #define ADAT_MODE_RNR_AM_SL        RIG_MODE_SAL
132 #define ADAT_MODE_ANR_AM_SL        6
133 
134 #define ADAT_MODE_STR_AM_SU        "AM-SU"
135 #define ADAT_MODE_RNR_AM_SU        RIG_MODE_SAH
136 #define ADAT_MODE_ANR_AM_SU        7
137 
138 #define ADAT_MODE_STR_FM           "FM"
139 #define ADAT_MODE_RNR_FM           RIG_MODE_FM
140 #define ADAT_MODE_ANR_FM           8
141 
142 // ADAT PTT DEFINITIONS
143 
144 #define ADAT_PTT_STATUS_ANR_ON     ADAT_ON
145 #define ADAT_PTT_STATUS_RNR_ON     RIG_PTT_ON
146 
147 #define ADAT_PTT_STATUS_ANR_OFF    ADAT_OFF
148 #define ADAT_PTT_STATUS_RNR_OFF    RIG_PTT_OFF
149 
150 // ADAT POWER LEVEL DEFINITIONS
151 
152 #define ADAT_PWR_LVL_ANR_00              0
153 #define ADAT_PWR_LVL_RNR_00            100 // 100 mW
154 
155 #define ADAT_PWR_LVL_ANR_01              1
156 #define ADAT_PWR_LVL_RNR_01            300 // 300 mW
157 
158 #define ADAT_PWR_LVL_ANR_02              2
159 #define ADAT_PWR_LVL_RNR_02           1000 // ...
160 
161 #define ADAT_PWR_LVL_ANR_03              3
162 #define ADAT_PWR_LVL_RNR_03           2000
163 
164 #define ADAT_PWR_LVL_ANR_04              4
165 #define ADAT_PWR_LVL_RNR_04           3000
166 
167 #define ADAT_PWR_LVL_ANR_05              5
168 #define ADAT_PWR_LVL_RNR_05           5000
169 
170 #define ADAT_PWR_LVL_ANR_06              6
171 #define ADAT_PWR_LVL_RNR_06           7000
172 
173 #define ADAT_PWR_LVL_ANR_07              7
174 #define ADAT_PWR_LVL_RNR_07          10000
175 
176 #define ADAT_PWR_LVL_ANR_08              8
177 #define ADAT_PWR_LVL_RNR_08          15000
178 
179 #define ADAT_PWR_LVL_ANR_09              9
180 #define ADAT_PWR_LVL_RNR_09          20000
181 
182 #define ADAT_PWR_LVL_ANR_10             10
183 #define ADAT_PWR_LVL_RNR_10          25000
184 
185 #define ADAT_PWR_LVL_ANR_11             11
186 #define ADAT_PWR_LVL_RNR_11          30000
187 
188 #define ADAT_PWR_LVL_ANR_12             12
189 #define ADAT_PWR_LVL_RNR_12          35000
190 
191 #define ADAT_PWR_LVL_ANR_13             13
192 #define ADAT_PWR_LVL_RNR_13          40000
193 
194 #define ADAT_PWR_LVL_ANR_14             14 // Default value after reset
195 #define ADAT_PWR_LVL_RNR_14          45000
196 
197 #define ADAT_PWR_LVL_ANR_15             15
198 #define ADAT_PWR_LVL_RNR_15          50000 // 50 W
199 
200 #define ADAT_MAX_POWER_IN_mW         ADAT_PWR_LVL_RNR_15
201 
202 // ADAT CHANNEL CAPS
203 
204 #define ADAT_MEM_CAPS \
205     { \
206         .vfo          = 1, \
207         .ant          = 1, \
208         .freq         = 1, \
209         .mode         = 1, \
210         .width        = 1, \
211         .tx_freq      = 1, \
212         .tx_mode      = 1, \
213         .tx_width     = 1, \
214         .tx_vfo       = 1, \
215         .rit          = 1, \
216         .xit          = 1, \
217         .tuning_step  = 1, \
218         .channel_desc = 1  \
219     }
220 
221 #define ADAT_MEM_DESC_SIZE         64
222 
223 // ADAT OPCODES - Kind of an internal command within ADAT Hamlib Backend
224 
225 #define ADAT_OPCODE_BASE_PTT        110000
226 
227 #define ADAT_OPCODE_PTT_SWITCH_ON   (ADAT_OPCODE_BASE_PTT + 1)
228 #define ADAT_OPCODE_PTT_SWITCH_OFF  (ADAT_OPCODE_BASE_PTT + 2)
229 
230 // ---------------------------------------------------------------------------
231 //    Individual ADAT CAT commands
232 // ---------------------------------------------------------------------------
233 
234 #define ADAT_CMD_DEF_ADAT_SPECIAL (1<<30)
235 
236 // -- NIL --  (Marks the end of a cmd list)
237 
238 #define ADAT_CMD_DEF_NIL 0
239 
240 // -- ADAT SPECIAL: DISPLAY OFF --
241 
242 #define ADAT_CMD_DEF_STRING_DISPLAY_OFF             "$VRU>"ADAT_CR
243 
244 // -- ADAT SPECIAL: DISPLAY ON --
245 
246 #define ADAT_CMD_DEF_STRING_DISPLAY_ON              "$VRU<"ADAT_CR
247 
248 // -- ADAT SPECIAL: GET SERIAL NR --
249 
250 #define ADAT_CMD_DEF_STRING_GET_SERIAL_NR           "$CIS?"ADAT_CR
251 
252 // -- ADAT SPECIAL: GET FIRMWARE VERSION --
253 
254 #define ADAT_CMD_DEF_STRING_GET_FW_VERSION          "$CIF?"ADAT_CR
255 
256 // -- ADAT SPECIAL: GET HARDWARE VERSION --
257 
258 #define ADAT_CMD_DEF_STRING_GET_HW_VERSION          "$CIH?"ADAT_CR
259 
260 // -- ADAT SPECIAL: GET FIRMWARE VERSION --
261 
262 #define ADAT_CMD_DEF_STRING_GET_ID_CODE             "$CID?"ADAT_CR
263 
264 // -- ADAT SPECIAL: GET GUI FIRMWARE VERSION --
265 
266 #define ADAT_CMD_DEF_STRING_GET_GUI_FW_VERSION      "$CIG?"ADAT_CR
267 
268 // -- ADAT SPECIAL: GET OPTIONS --
269 
270 #define ADAT_CMD_DEF_STRING_GET_OPTIONS             "$CIO?"ADAT_CR
271 
272 // -- ADAT SPECIAL: GET CALLSIGN --
273 
274 #define ADAT_CMD_DEF_STRING_GET_CALLSIGN            "$CAL?"ADAT_CR
275 
276 // -- ADAT SPECIAL: SET CALLSIGN --
277 
278 #define ADAT_CMD_DEF_STRING_SET_CALLSIGN            "$CAL:"
279 
280 // -- HAMLIB DEFINED COMMANDS --
281 
282 // -- GET FREQ --
283 
284 #define ADAT_CMD_DEF_GET_FREQ                             (1<<0)
285 #define ADAT_CMD_DEF_STRING_GET_FREQ                      "$FRA?"ADAT_CR
286 
287 // -- SET FREQ --
288 
289 #define ADAT_CMD_DEF_SET_FREQ                             (1<<1)
290 #define ADAT_CMD_DEF_STRING_SET_FREQ                      "$FR1:"
291 
292 // -- GET VFO --
293 
294 // -- GET MODE --
295 
296 #define ADAT_CMD_DEF_GET_MODE                             (1<<2)
297 #define ADAT_CMD_DEF_STRING_GET_MODE                      "$MOD?"ADAT_CR
298 
299 // -- SET VFO --
300 
301 #define ADAT_CMD_DEF_SET_VFO                              (1<<3)
302 #define ADAT_CMD_DEF_STRING_SWITCH_ON_VFO                 "$VO%1d>%s"
303 #define ADAT_CMD_DEF_STRING_SET_VFO_AS_MAIN_VFO           "$VO%1d%%%s"
304 
305 // -- SET MODE --
306 
307 #define ADAT_CMD_DEF_SET_MODE                             (1<<4)
308 #define ADAT_CMD_DEF_STRING_SET_MODE                      "$MOD:"
309 
310 // -- SET PTT --
311 
312 #define ADAT_CMD_DEF_SET_PTT                              (1<<5)
313 #define ADAT_CMD_DEF_STRING_SET_PTT                       "$MOX%s%s"
314 #define ADAT_CMD_PTT_STR_OFF                               "<"
315 #define ADAT_CMD_PTT_STR_ON                                ">"
316 
317 // -- GET PTT --
318 
319 #define ADAT_CMD_DEF_GET_PTT                              (1<<6)
320 #define ADAT_CMD_DEF_STRING_GET_PTT                       "$MTR?"ADAT_CR
321 
322 // -- GET POWER STATUS --
323 
324 // -- GET INFO --
325 
326 // -- OPEN ADAT --
327 
328 // -- ADAT SPECIAL: RECOVER FROM ERROR --
329 
330 // ---------------------------------------------------------------------------
331 //    ADAT PRIVATE DATA
332 // ---------------------------------------------------------------------------
333 
334 typedef struct _adat_priv_data
335 {
336     int           nOpCode;
337 
338     char         *pcProductName; // Future use (USB direct I/O)
339 
340     // ADAT device info
341 
342     char         *pcSerialNr;
343     char         *pcIDCode;
344     char         *pcOptions;
345     char         *pcFWVersion;
346     char         *pcHWVersion;
347     char         *pcGUIFWVersion;
348 
349     char         *pcCallsign;
350 
351     // ADAT Operational Settings: will change during TRX use
352 
353     int           nCurrentVFO;
354     vfo_t         nRIGVFONr;
355 
356     freq_t        nFreq;
357     char          acRXFreq[ ADAT_BUFSZ ];
358     char          acTXFreq[ ADAT_BUFSZ ];
359 
360     rmode_t       nRIGMode;
361     char          acADATMode[ ADAT_MODE_LENGTH + 1 ];
362     int           nADATMode;
363 
364     pbwidth_t     nWidth;
365 
366     int           nADATPTTStatus;
367     ptt_t         nRIGPTTStatus;
368 
369 
370     value_t       mNB1;
371     value_t       mNB2;
372 
373     value_t       mAGC;
374     value_t       mRFGain;
375     value_t       mIFShift;
376     value_t       mRawStr;
377 
378     // ADAT Command-related Values
379 
380     char         *pcCmd;
381     int           nCmdKind;
382 
383     char         *pcResult;
384     int           nRC;
385 
386 } adat_priv_data_t,
387 * adat_priv_data_ptr;
388 
389 // ---------------------------------------------------------------------------
390 //    ADAT CAT COMMAND DATA TYPE DECLARATIONS
391 // ---------------------------------------------------------------------------
392 
393 typedef unsigned long long adat_cmd_id_t; // Bit mask for commands. Each command
394                                           // is represented by 1 bit.
395 
396 // adat_cmd_def : ADAT COMMAND DEFINITION.
397 // Basic idea: Each command can be made of several strings to be sent
398 // to the ADAT device. Therefore it is possible to build aggregated
399 // commands which will be executed as a set of individual commands
400 // executed by adat_transaction(). The last value as returned by the
401 // commands will be set as overall command result.
402 
403 typedef enum
404 {
405     ADAT_CMD_KIND_WITH_RESULT    = 0,  // After sending a command to the ADAT,
406                                        // a result has to be read.
407     ADAT_CMD_KIND_WITHOUT_RESULT = 1
408 
409 } adat_cmd_kind_t;
410 
411 typedef struct _adat_cmd_def_t
412 {
413     adat_cmd_id_t    nCmdId;        // Bit indicating this cmd
414     adat_cmd_kind_t  nCmdKind;      // Defines if result expected
415 
416     int (*pfCmdFn)(RIG *pRig);      // Fn to be called to execute this cmd
417 
418     int              nNrCmdStrs;    // Oh my, C as a language ... I'd love to
419                                     // switch to Common Lisp ... What a hack here ...
420     char            *pacCmdStrs[];  // Commands to be executed if no CmdFn given
421 
422 } adat_cmd_def_t,
423 * adat_cmd_def_ptr;
424 
425 typedef struct _adat_cmd_table_t
426 {
427     int              nNrCmds;
428     adat_cmd_def_ptr adat_cmds[];
429 
430 } adat_cmd_table_t,
431 * adat_cmd_table_ptr;
432 
433 typedef struct _adat_cmd_list_t
434 {
435     int              nNrCmds;
436     adat_cmd_def_ptr adat_cmds[];
437 
438 } adat_cmd_list_t,
439 * adat_cmd_list_ptr;
440 
441 // ---------------------------------------------------------------------------
442 //    OTHER ADAT DATA TYPES
443 // ---------------------------------------------------------------------------
444 
445 typedef enum
446 {
447     ADAT_FREQ_PARSE_MODE_WITH_VFO     = 0,
448     ADAT_FREQ_PARSE_MODE_WITHOUT_VFO  = 1
449 
450 } adat_freq_parse_mode_t;
451 
452 // ADAT MODE DEFINITION
453 
454 typedef struct _adat_mode_def
455 {
456     char     *pcADATModeStr;
457     rmode_t   nRIGMode;
458     int       nADATMode;
459 
460 } adat_mode_def_t,
461 * adat_mode_def_ptr;
462 
463 typedef struct _adat_mode_list
464 {
465     int nNrModes;
466 
467     adat_mode_def_t adat_modes[ ADAT_NR_MODES ];
468 
469 } adat_mode_list_t,
470 * adat_mode_list_ptr;
471 
472 // ADAT VFO DEFINITION
473 
474 typedef struct _adat_vfo_def
475 {
476     char     *pcADATVFOStr;
477     vfo_t     nRIGVFONr;
478     int       nADATVFONr;
479 
480 } adat_vfo_def_t,
481 * adat_vfo_def_ptr;
482 
483 typedef struct _adat_vfo_list
484 {
485     int nNrVFOs;
486 
487     adat_vfo_def_t adat_vfos[ ADAT_NR_VFOS ];
488 
489 } adat_vfo_list_t,
490 * adat_vfo_list_ptr;
491 
492 // ---------------------------------------------------------------------------
493 //    ADAT INTERNAL FUNCTION DECLARATIONS
494 // ---------------------------------------------------------------------------
495 
496 // Helper functions
497 
498 size_t trimwhitespace(char *, size_t, const char *);
499 int adat_print_cmd(adat_cmd_def_ptr);
500 
501 int adat_parse_freq(char *, adat_freq_parse_mode_t, int *, freq_t *);
502 
503 int adat_parse_mode(char *, rmode_t *, char *);
504 int adat_mode_rnr2anr(rmode_t, int *);
505 #ifdef XXREMOVEDXX
506 // this function wasn't referenced anywhere
507 int adat_mode_anr2rnr(int, rmode_t *);
508 #endif
509 
510 #ifdef XXREMOVEDXX
511 // this function wasn't referenced anywhere
512 int adat_parse_vfo(char *, vfo_t *, int *);
513 #endif
514 int adat_vfo_rnr2anr(vfo_t, int *);
515 int adat_vfo_anr2rnr(int, vfo_t *);
516 
517 int adat_parse_ptt(char *, int *);
518 int adat_ptt_rnr2anr(ptt_t, int *);
519 int adat_ptt_anr2rnr(int, ptt_t *);
520 
521 int adat_send(RIG *, char *);
522 int adat_receive(RIG *, char *);
523 
524 int adat_priv_set_cmd(RIG *, char *, int);
525 int adat_priv_set_result(RIG *, char *);
526 int adat_priv_clear_result(RIG *);
527 
528 int adat_get_single_cmd_result(RIG *);
529 
530 int adat_cmd_recover_from_error(RIG *, int);
531 
532 int adat_transaction(RIG *, adat_cmd_list_ptr);
533 
534 adat_priv_data_ptr adat_new_priv_data(RIG *);
535 void adat_del_priv_data(adat_priv_data_t **);
536 
537 // Command implementation
538 
539 int adat_cmd_fn_get_serial_nr(RIG *);
540 int adat_cmd_fn_get_fw_version(RIG *);
541 int adat_cmd_fn_get_hw_version(RIG *);
542 int adat_cmd_fn_get_gui_fw_version(RIG *);
543 int adat_cmd_fn_get_id_code(RIG *);
544 int adat_cmd_fn_get_options(RIG *);
545 
546 int adat_cmd_fn_set_callsign(RIG *);
547 int adat_cmd_fn_get_callsign(RIG *);
548 
549 int adat_cmd_fn_set_freq(RIG *);
550 int adat_cmd_fn_get_freq(RIG *);
551 
552 int adat_cmd_fn_get_mode(RIG *);
553 int adat_cmd_fn_set_mode(RIG *);
554 
555 int adat_cmd_fn_get_vfo(RIG *);
556 int adat_cmd_fn_set_vfo(RIG *);
557 
558 int adat_cmd_fn_get_ptt(RIG *);
559 int adat_cmd_fn_set_ptt(RIG *);
560 
561 // ---------------------------------------------------------------------------
562 //    ADAT FUNCTION DECLARATIONS
563 // ---------------------------------------------------------------------------
564 
565 int adat_init(RIG *);
566 int adat_cleanup(RIG *);
567 int adat_reset(RIG *, reset_t);
568 int adat_open(RIG *);
569 int adat_close(RIG *);
570 
571 int adat_set_conf(RIG *, token_t, const char *val);
572 int adat_get_conf(RIG *, token_t, char *val);
573 
574 int adat_set_freq(RIG *, vfo_t, freq_t);
575 int adat_get_freq(RIG *, vfo_t, freq_t *);
576 
577 int adat_set_vfo(RIG *, vfo_t);
578 int adat_get_vfo(RIG *, vfo_t *);
579 
580 int adat_set_ptt(RIG *, vfo_t, ptt_t);
581 int adat_get_ptt(RIG *, vfo_t, ptt_t *);
582 
583 int adat_set_mode(RIG *, vfo_t, rmode_t, pbwidth_t);
584 int adat_get_mode(RIG *, vfo_t, rmode_t *, pbwidth_t *);
585 
586 int adat_set_func(RIG *, vfo_t, setting_t func, int);
587 int adat_get_func(RIG *, vfo_t, setting_t func, int *);
588 
589 int adat_set_level(RIG *, vfo_t, setting_t level, value_t);
590 int adat_get_level(RIG *, vfo_t, setting_t level, value_t *);
591 
592 int adat_handle_event(RIG *);
593 
594 const char *adat_get_info(RIG *);
595 
596 int adat_mW2power(RIG *, float *, unsigned int, freq_t, rmode_t);
597 int adat_power2mW(RIG *, unsigned int *, float, freq_t, rmode_t);
598 
599 int adat_get_powerstat(RIG *, powerstat_t *);
600 
601 extern const struct rig_caps adt_200a_caps;
602 
603 // ---------------------------------------------------------------------------
604 //    END OF FILE
605 // ---------------------------------------------------------------------------
606 
607 #endif
608