1 /*
2  *  Hamlib CI-V backend - description of ID-31 and variations
3  *  Copyright (c) 2015 by Stephane Fillod
4  *  Copyright (c) 2019 by Malcolm Herring
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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <stdlib.h>
28 
29 #include "hamlib/rig.h"
30 #include "idx_builtin.h"
31 #include "icom.h"
32 
33 /*
34  * Specs and protocol details comes from the chapter 11 of ID-31A_E_CD_ENG_1.pdf
35  *
36  * NB: while the port labeled "Data" is used for firmware upgrades,
37  * you have to use the port labeled "SP" for rig control.
38  *
39  */
40 
41 #define ID31_MODES (RIG_MODE_FM|RIG_MODE_DSTAR)
42 #define ID31_ALL_RX_MODES (RIG_MODE_AM|ID31_MODES)
43 
44 #define ID31_VFO_ALL (RIG_VFO_MAIN)
45 
46 #define ID31_SCAN_OPS RIG_SCAN_NONE
47 
48 #define ID31_VFO_OPS  RIG_OP_NONE
49 
50 #define ID31_FUNC_ALL ( \
51                             RIG_FUNC_TONE| \
52                             RIG_FUNC_TSQL| \
53                             RIG_FUNC_CSQL| \
54                             RIG_FUNC_DSQL| \
55                             RIG_FUNC_VOX)
56 
57 #define ID31_LEVEL_ALL    (RIG_LEVEL_AF| \
58                             RIG_LEVEL_SQL| \
59                             RIG_LEVEL_RAWSTR| \
60                             RIG_LEVEL_RFPOWER| \
61                             RIG_LEVEL_MICGAIN| \
62                             RIG_LEVEL_VOXGAIN)
63 
64 #define ID31_PARM_ALL RIG_PARM_NONE
65 
66 
67 /*
68  * FIXME: real measurement
69  */
70 #define ID31_STR_CAL  UNKNOWN_IC_STR_CAL
71 
72 
73 
74 /*
75  */
76 static struct icom_priv_caps id31_priv_caps =
77 {
78     0xA0,   /* default address */
79     0,      /* 731 mode */
80     1,      /* no XCHG */
81 };
82 
83 const struct rig_caps id31_caps =
84 {
85     RIG_MODEL(RIG_MODEL_ID31),
86     .model_name = "ID-31",
87     .mfg_name =  "Icom",
88     .version =  BACKEND_VER ".0",
89     .copyright =  "LGPL",
90     .status =  RIG_STATUS_UNTESTED,
91     .rig_type =  RIG_TYPE_HANDHELD,
92     .ptt_type =  RIG_PTT_RIG,
93     .dcd_type =  RIG_DCD_RIG,
94     .port_type =  RIG_PORT_SERIAL,
95     .serial_rate_min =  4800,
96     .serial_rate_max =  19200,
97     .serial_data_bits =  8,
98     .serial_stop_bits =  1,
99     .serial_parity =  RIG_PARITY_NONE,
100     .serial_handshake =  RIG_HANDSHAKE_NONE,
101     .write_delay =  0,
102     .post_write_delay =  0,
103     .timeout =  1000,
104     .retry =  3,
105     .has_get_func =  ID31_FUNC_ALL,
106     .has_set_func =  ID31_FUNC_ALL,
107     .has_get_level =  ID31_LEVEL_ALL,
108     .has_set_level =  RIG_LEVEL_SET(ID31_LEVEL_ALL),
109     .has_get_parm =  ID31_PARM_ALL,
110     .has_set_parm =  ID31_PARM_ALL,
111     .level_gran = {
112         // cppcheck-suppress *
113         [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
114     },
115     .extparms = icom_ext_parms,
116     .parm_gran =  {},
117     .ctcss_list =  common_ctcss_list,
118     .dcs_list =  full_dcs_list,
119     .preamp =   { RIG_DBLST_END, },
120     .attenuator =   { RIG_DBLST_END, },
121     .max_rit =  Hz(0),
122     .max_xit =  Hz(0),
123     .max_ifshift =  Hz(0),
124     .targetable_vfo =  0,
125     .vfo_ops =  ID31_VFO_OPS,
126     .scan_ops =  ID31_SCAN_OPS,
127     .transceive =  RIG_TRN_RIG,
128     .bank_qty =   0,
129     .chan_desc_sz =  0,
130 
131     .chan_list =  {
132         // There's no memory support through CI-V,
133         // but there is a clone mode apart.
134         RIG_CHAN_END,
135     },
136 
137     .rx_range_list1 =   {
138         {MHz(400), MHz(479), ID31_ALL_RX_MODES, -1, -1, ID31_VFO_ALL},
139         RIG_FRNG_END,
140     },
141     .tx_range_list1 =  {
142         {MHz(430), MHz(440), ID31_MODES, W(2.5), W(5), ID31_VFO_ALL},
143         RIG_FRNG_END,
144     },
145 
146     .rx_range_list2 =   {
147         {MHz(400), MHz(479), ID31_ALL_RX_MODES, -1, -1, ID31_VFO_ALL},
148         RIG_FRNG_END,
149     },
150     .tx_range_list2 =  {
151         {MHz(440), MHz(450), ID31_MODES, W(2.5), W(5), ID31_VFO_ALL},
152         RIG_FRNG_END,
153     },
154 
155     .tuning_steps =     {
156         // Rem: no support for changing tuning step
157         RIG_TS_END,
158     },
159     /* mode/filter list, remember: order matters! */
160     .filters =  {
161         {RIG_MODE_FM, kHz(12)},
162         {RIG_MODE_FM, kHz(6)},
163         RIG_FLT_END,
164     },
165     .str_cal = ID31_STR_CAL,
166 
167     .cfgparams =  icom_cfg_params,
168     .set_conf =  icom_set_conf,
169     .get_conf =  icom_get_conf,
170 
171     .priv = (void *)& id31_priv_caps,
172     .rig_init =   icom_init,
173     .rig_cleanup =   icom_cleanup,
174     .rig_open =  icom_rig_open,
175     .rig_close =  icom_rig_open,
176 
177     .set_freq =  icom_set_freq,
178     .get_freq =  icom_get_freq,
179     .set_mode =  icom_set_mode,
180     .get_mode =  icom_get_mode,
181 
182     .set_powerstat = icom_set_powerstat,
183     .get_powerstat = icom_get_powerstat,
184     .decode_event =  icom_decode_event,
185 
186     .set_func =  icom_set_func,
187     .get_func =  icom_get_func,
188     .set_level =  icom_set_level,
189     .get_level =  icom_get_level,
190     .set_parm =  icom_set_parm,
191     .get_parm =  icom_get_parm,
192     .set_ext_parm =  icom_set_ext_parm,
193     .get_ext_parm =  icom_get_ext_parm,
194     .set_ptt =  icom_set_ptt,
195     .get_ptt =  icom_get_ptt,
196     .get_dcd =  icom_get_dcd,
197 
198     .set_rptr_shift =  icom_set_rptr_shift,
199     .get_rptr_shift =  icom_get_rptr_shift,
200     .set_rptr_offs =  icom_set_rptr_offs,
201     .get_rptr_offs =  icom_get_rptr_offs,
202     .set_ctcss_tone =  icom_set_ctcss_tone,
203     .get_ctcss_tone =  icom_get_ctcss_tone,
204     .set_dcs_code =  icom_set_dcs_code,
205     .get_dcs_code =  icom_get_dcs_code,
206     .set_ctcss_sql =  icom_set_ctcss_sql,
207     .get_ctcss_sql =  icom_get_ctcss_sql,
208     .set_dcs_sql =  icom_set_dcs_sql,
209     .get_dcs_sql =  icom_get_dcs_sql,
210 };
211