1 /*
2  *  Hamlib Kenwood backend - TS590 description
3  *  Copyright (c) 2010 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 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include <stdlib.h>
27 #include <stdio.h>
28 
29 #include "hamlib/rig.h"
30 #include "idx_builtin.h"
31 #include "kenwood.h"
32 #include "cal.h"
33 
34 
35 /* Function declarations  */
36 const char *ts590_get_info(RIG *rig);
37 int ts590_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val);
38 
39 #define TS590_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTFM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB)
40 #define TS590_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY)
41 #define TS590_AM_TX_MODES RIG_MODE_AM
42 #define TS590_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM)
43 
44 #define TS590_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|\
45         RIG_LEVEL_CWPITCH|RIG_LEVEL_METER|RIG_LEVEL_SWR|RIG_LEVEL_ALC|\
46         RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|\
47         RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD)
48 #define TS590_FUNC_ALL (RIG_FUNC_LOCK|RIG_FUNC_AIP|RIG_FUNC_TONE|\
49         RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC)
50 
51 #define TS590_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN)
52 #define TS590_SCAN_OPS (RIG_SCAN_VFO)
53 
54 #define TS590_ANTS (RIG_ANT_1|RIG_ANT_2)
55 
56 #define TS590_CHANNEL_CAPS { \
57         .freq=1,\
58         .mode=1,\
59         .tx_freq=1,\
60         .tx_mode=1,\
61         .split=1,\
62         .funcs=RIG_FUNC_TONE, \
63         .flags=RIG_CHFLAG_SKIP \
64         }
65 
66 #define TS590_STR_CAL {9, {\
67                        { 0, -60},\
68                        { 3, -48},\
69                        { 6, -36},\
70                        { 9, -24},\
71                        {12, -12},\
72                        {15,   0},\
73                        {20,  20},\
74                        {25,  40},\
75                        {30,  60}}\
76                        }
77 
78 
79 static struct kenwood_priv_caps ts590_priv_caps =
80 {
81     .cmdtrm = EOM_KEN,
82 };
83 
84 
85 /*
86  * ts590 rig capabilities.
87  * Notice that some rigs share the same functions.
88  * Also this struct is READONLY!
89  */
90 const struct rig_caps ts590_caps =
91 {
92     RIG_MODEL(RIG_MODEL_TS590S),
93     .model_name = "TS-590S",
94     .mfg_name = "Kenwood",
95     .version = BACKEND_VER ".0",
96     .copyright = "LGPL",
97     .status = RIG_STATUS_STABLE,
98     .rig_type = RIG_TYPE_TRANSCEIVER,
99     .ptt_type = RIG_PTT_RIG_MICDATA,
100     .dcd_type = RIG_DCD_RIG,
101     .port_type = RIG_PORT_SERIAL,
102     .serial_rate_min = 4800,
103     .serial_rate_max = 115200,
104     .serial_data_bits = 8,
105     .serial_stop_bits = 1,
106     .serial_parity = RIG_PARITY_NONE,
107     .serial_handshake = RIG_HANDSHAKE_HARDWARE,
108     .write_delay = 0,
109     .post_write_delay = 0,
110     .timeout = 500,
111     .retry = 10,
112     .preamp = {12, RIG_DBLST_END,},
113     .attenuator = {12, RIG_DBLST_END,},
114     .max_rit = kHz(9.99),
115     .max_xit = kHz(9.99),
116     .max_ifshift = Hz(0),
117     .targetable_vfo = RIG_TARGETABLE_FREQ,
118     .transceive = RIG_TRN_RIG,
119 
120 
121     .chan_list =  { /* TBC */
122         {  0, 89, RIG_MTYPE_MEM,  TS590_CHANNEL_CAPS },
123         { 90, 99, RIG_MTYPE_EDGE, TS590_CHANNEL_CAPS },
124         RIG_CHAN_END,
125     },
126 
127     .rx_range_list1 = {
128         {kHz(30),   Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS},
129         RIG_FRNG_END,
130     }, /*!< Receive frequency range list for ITU region 1 */
131     .tx_range_list1 = {
132         {kHz(1810),  kHz(1850),  TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},   /* 100W class */
133         {kHz(1810),  kHz(1850),  TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},       /* 25W class */
134         {kHz(3500),  kHz(3800),  TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
135         {kHz(3500),  kHz(3800),  TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
136         {MHz(7),     kHz(7200),  TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
137         {MHz(7),     kHz(7200),  TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
138         {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
139         {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
140         {MHz(14),    kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
141         {MHz(14),    kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
142         {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
143         {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
144         {MHz(21),    kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
145         {MHz(21),    kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
146         {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
147         {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
148         {MHz(28),    kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
149         {MHz(28),    kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
150         {MHz(50),    kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
151         {MHz(50),    kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
152         RIG_FRNG_END,
153     },  /*!< Transmit frequency range list for ITU region 1 */
154     .rx_range_list2 = {
155         {kHz(30),   Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS},
156         RIG_FRNG_END,
157     },  /*!< Receive frequency range list for ITU region 2 */
158     .tx_range_list2 = {
159         {kHz(1800),  MHz(2) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},  /* 100W class */
160         {kHz(1800),  MHz(2) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},      /* 25W class */
161         {kHz(3500),  MHz(4) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
162         {kHz(3500),  MHz(4) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
163         {kHz(5250),  kHz(5450),  TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
164         {kHz(5250),  kHz(5450),  TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
165         {MHz(7),     kHz(7300),  TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
166         {MHz(7),     kHz(7300),  TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
167         {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
168         {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
169         {MHz(14),    kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
170         {MHz(14),    kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
171         {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
172         {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
173         {MHz(21),    kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
174         {MHz(21),    kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
175         {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
176         {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
177         {MHz(28),    kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
178         {MHz(28),    kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
179         {MHz(50),    kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
180         {MHz(50),    kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
181         RIG_FRNG_END,
182     }, /*!< Transmit frequency range list for ITU region 2 */
183     .tuning_steps =  {
184         {TS590_ALL_MODES, kHz(1)},
185         {TS590_ALL_MODES, Hz(2500)},
186         {TS590_ALL_MODES, kHz(5)},
187         {TS590_ALL_MODES, Hz(6250)},
188         {TS590_ALL_MODES, kHz(10)},
189         {TS590_ALL_MODES, Hz(12500)},
190         {TS590_ALL_MODES, kHz(15)},
191         {TS590_ALL_MODES, kHz(20)},
192         {TS590_ALL_MODES, kHz(25)},
193         {TS590_ALL_MODES, kHz(30)},
194         {TS590_ALL_MODES, kHz(100)},
195         {TS590_ALL_MODES, kHz(500)},
196         {TS590_ALL_MODES, MHz(1)},
197         {TS590_ALL_MODES, 0},  /* any tuning step */
198         RIG_TS_END,
199     },
200     /* mode/filter list, remember: order matters! */
201     .filters =  {
202         {RIG_MODE_SSB, kHz(2.2)},
203         {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)},
204         {RIG_MODE_AM, kHz(6)},
205         {RIG_MODE_FM, kHz(12)},
206         RIG_FLT_END,
207     },
208     .str_cal = TS590_STR_CAL,
209     .priv = (void *)& ts590_priv_caps,
210     .rig_init = kenwood_init,
211     .rig_cleanup = kenwood_cleanup,
212     .rig_open = kenwood_open,
213     .rig_close = kenwood_close,
214     .set_freq = kenwood_set_freq,
215     .get_freq = kenwood_get_freq,
216     .set_rit = kenwood_set_rit,   /*  FIXME should this switch to rit mode or just set the frequency? */
217     .get_rit = kenwood_get_rit,
218     .set_xit = kenwood_set_xit,   /* FIXME should this switch to xit mode or just set the frequency?  */
219     .get_xit = kenwood_get_xit,
220     .set_mode = kenwood_set_mode,
221     .get_mode = kenwood_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     .get_ptt = kenwood_get_ptt,
227     .set_ptt = kenwood_set_ptt,
228     .get_dcd = kenwood_get_dcd,
229     .set_powerstat = kenwood_set_powerstat,
230     .get_powerstat = kenwood_get_powerstat,
231     .get_info = ts590_get_info,
232     .reset = kenwood_reset,
233     .set_ant = kenwood_set_ant,
234     .get_ant = kenwood_get_ant,
235     .scan_ops =  TS590_SCAN_OPS,
236     .scan = kenwood_scan,     /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */
237     .has_set_level = RIG_LEVEL_SET(TS590_LEVEL_ALL),
238     .has_get_level = TS590_LEVEL_ALL,
239     .set_level = kenwood_set_level,
240     .get_level = ts590_get_level,
241     .has_get_func = TS590_FUNC_ALL,
242     .has_set_func = TS590_FUNC_ALL,
243     .set_func = kenwood_set_func,
244     .get_func = kenwood_get_func,
245     .set_ctcss_tone =  kenwood_set_ctcss_tone,
246     .get_ctcss_tone =  kenwood_get_ctcss_tone,
247     .ctcss_list =  kenwood38_ctcss_list,
248     .set_trn =  kenwood_set_trn,
249     .get_trn =  kenwood_get_trn,
250     .send_morse =  kenwood_send_morse,
251     .wait_morse =  rig_wait_morse,
252     .set_mem =  kenwood_set_mem,
253     .get_mem =  kenwood_get_mem,
254     .set_channel =  kenwood_set_channel,
255     .get_channel =  kenwood_get_channel,
256     .vfo_ops = TS590_VFO_OPS,
257     .vfo_op =  kenwood_vfo_op,
258 };
259 
260 const struct rig_caps ts590sg_caps =
261 {
262     RIG_MODEL(RIG_MODEL_TS590SG),
263     .model_name = "TS-590SG",
264     .mfg_name = "Kenwood",
265     .version = BACKEND_VER ".0",
266     .copyright = "LGPL",
267     .status = RIG_STATUS_BETA,
268     .rig_type = RIG_TYPE_TRANSCEIVER,
269     .ptt_type = RIG_PTT_RIG_MICDATA,
270     .dcd_type = RIG_DCD_RIG,
271     .port_type = RIG_PORT_SERIAL,
272     .serial_rate_min = 4800,
273     .serial_rate_max = 115200,
274     .serial_data_bits = 8,
275     .serial_stop_bits = 1,
276     .serial_parity = RIG_PARITY_NONE,
277     .serial_handshake = RIG_HANDSHAKE_HARDWARE,
278     .write_delay = 0,
279     .post_write_delay = 0,
280     .timeout = 500,
281     .retry = 10,
282     .preamp = {12, RIG_DBLST_END,},
283     .attenuator = {12, RIG_DBLST_END,},
284     .max_rit = kHz(9.99),
285     .max_xit = kHz(9.99),
286     .max_ifshift = Hz(0),
287     .targetable_vfo = RIG_TARGETABLE_FREQ,
288     .transceive = RIG_TRN_RIG,
289 
290 
291     .chan_list =  { /* TBC */
292         {  0, 89, RIG_MTYPE_MEM,  TS590_CHANNEL_CAPS },
293         { 90, 99, RIG_MTYPE_EDGE, TS590_CHANNEL_CAPS },
294         RIG_CHAN_END,
295     },
296 
297     .rx_range_list1 = {
298         {kHz(30),   Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS},
299         RIG_FRNG_END,
300     }, /*!< Receive frequency range list for ITU region 1 */
301     .tx_range_list1 = {
302         {kHz(1810),  kHz(1850),  TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},   /* 100W class */
303         {kHz(1810),  kHz(1850),  TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},       /* 25W class */
304         {kHz(3500),  kHz(3800),  TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
305         {kHz(3500),  kHz(3800),  TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
306         {MHz(7),     kHz(7200),  TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
307         {MHz(7),     kHz(7200),  TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
308         {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
309         {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
310         {MHz(14),    kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
311         {MHz(14),    kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
312         {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
313         {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
314         {MHz(21),    kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
315         {MHz(21),    kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
316         {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
317         {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
318         {MHz(28),    kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
319         {MHz(28),    kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
320         {MHz(50),    kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
321         {MHz(50),    kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
322         RIG_FRNG_END,
323     },  /*!< Transmit frequency range list for ITU region 1 */
324     .rx_range_list2 = {
325         {kHz(30),   Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS},
326         RIG_FRNG_END,
327     },  /*!< Receive frequency range list for ITU region 2 */
328     .tx_range_list2 = {
329         {kHz(1800),  MHz(2) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},  /* 100W class */
330         {kHz(1800),  MHz(2) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},      /* 25W class */
331         {kHz(3500),  MHz(4) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
332         {kHz(3500),  MHz(4) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
333         {kHz(5250),  kHz(5450),  TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
334         {kHz(5250),  kHz(5450),  TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
335         {MHz(7),     kHz(7300),  TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
336         {MHz(7),     kHz(7300),  TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
337         {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
338         {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
339         {MHz(14),    kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
340         {MHz(14),    kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
341         {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
342         {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
343         {MHz(21),    kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
344         {MHz(21),    kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
345         {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
346         {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
347         {MHz(28),    kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
348         {MHz(28),    kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
349         {MHz(50),    kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS},
350         {MHz(50),    kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS},
351         RIG_FRNG_END,
352     }, /*!< Transmit frequency range list for ITU region 2 */
353     .tuning_steps =  {
354         {TS590_ALL_MODES, kHz(1)},
355         {TS590_ALL_MODES, Hz(2500)},
356         {TS590_ALL_MODES, kHz(5)},
357         {TS590_ALL_MODES, Hz(6250)},
358         {TS590_ALL_MODES, kHz(10)},
359         {TS590_ALL_MODES, Hz(12500)},
360         {TS590_ALL_MODES, kHz(15)},
361         {TS590_ALL_MODES, kHz(20)},
362         {TS590_ALL_MODES, kHz(25)},
363         {TS590_ALL_MODES, kHz(30)},
364         {TS590_ALL_MODES, kHz(100)},
365         {TS590_ALL_MODES, kHz(500)},
366         {TS590_ALL_MODES, MHz(1)},
367         {TS590_ALL_MODES, 0},  /* any tuning step */
368         RIG_TS_END,
369     },
370     /* mode/filter list, remember: order matters! */
371     .filters =  {
372         {RIG_MODE_SSB, kHz(2.2)},
373         {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)},
374         {RIG_MODE_AM, kHz(6)},
375         {RIG_MODE_FM, kHz(12)},
376         RIG_FLT_END,
377     },
378     .str_cal = TS590_STR_CAL,
379     .priv = (void *)& ts590_priv_caps,
380     .rig_init = kenwood_init,
381     .rig_cleanup = kenwood_cleanup,
382     .rig_open = kenwood_open,
383     .rig_close = kenwood_close,
384     .set_freq = kenwood_set_freq,
385     .get_freq = kenwood_get_freq,
386     .set_rit = kenwood_set_rit,   /*  FIXME should this switch to rit mode or just set the frequency? */
387     .get_rit = kenwood_get_rit,
388     .set_xit = kenwood_set_xit,   /* FIXME should this switch to xit mode or just set the frequency?  */
389     .get_xit = kenwood_get_xit,
390     .set_mode = kenwood_set_mode,
391     .get_mode = kenwood_get_mode,
392     .set_vfo = kenwood_set_vfo,
393     .get_vfo = kenwood_get_vfo_if,
394     .set_split_vfo = kenwood_set_split_vfo,
395     .get_split_vfo = kenwood_get_split_vfo_if,
396     .get_ptt = kenwood_get_ptt,
397     .set_ptt = kenwood_set_ptt,
398     .get_dcd = kenwood_get_dcd,
399     .set_powerstat = kenwood_set_powerstat,
400     .get_powerstat = kenwood_get_powerstat,
401     .get_info = kenwood_get_info,
402     .reset = kenwood_reset,
403     .set_ant = kenwood_set_ant,
404     .get_ant = kenwood_get_ant,
405     .scan_ops =  TS590_SCAN_OPS,
406     .scan = kenwood_scan,     /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */
407     .has_set_level = RIG_LEVEL_SET(TS590_LEVEL_ALL),
408     .has_get_level = TS590_LEVEL_ALL,
409     .set_level = kenwood_set_level,
410     .get_level = kenwood_get_level,
411     .has_get_func = TS590_FUNC_ALL,
412     .has_set_func = TS590_FUNC_ALL,
413     .set_func = kenwood_set_func,
414     .get_func = kenwood_get_func,
415     .set_ctcss_tone =  kenwood_set_ctcss_tone,
416     .get_ctcss_tone =  kenwood_get_ctcss_tone,
417     .ctcss_list =  kenwood38_ctcss_list,
418     .set_trn =  kenwood_set_trn,
419     .get_trn =  kenwood_get_trn,
420     .send_morse =  kenwood_send_morse,
421     .wait_morse =  rig_wait_morse,
422     .set_mem =  kenwood_set_mem,
423     .get_mem =  kenwood_get_mem,
424     .set_channel =  kenwood_set_channel,
425     .get_channel =  kenwood_get_channel,
426     .vfo_ops = TS590_VFO_OPS,
427     .vfo_op =  kenwood_vfo_op,
428 };
429 
430 
431 /*
432  * Function definitions below
433  */
434 
435 /*
436  * ts590_get_info
437  * This is not documented in the manual as of 3/11/15 but confirmed from Kenwood
438  * "TY" produces "TYK 00" for example
439  */
ts590_get_info(RIG * rig)440 const char *ts590_get_info(RIG *rig)
441 {
442     char firmbuf[10];
443     int retval;
444 
445     rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
446 
447     retval = kenwood_safe_transaction(rig, "TY", firmbuf, 10, 6);
448 
449     if (retval != RIG_OK)
450     {
451         return NULL;
452     }
453 
454     switch (firmbuf[2])
455     {
456     case 'K': return "Firmware: USA version";
457 
458     case 'E': return "Firmware: European version";
459 
460     default: return "Firmware: unknown";
461     }
462 }
463 
464 /*
465  * ts590_get_level
466  * only difference from standard Kenwood is AF level which has an argument
467  */
ts590_get_level(RIG * rig,vfo_t vfo,setting_t level,value_t * val)468 int ts590_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
469 {
470     int lvl_len;
471     int retval;
472     char lvlbuf[50];
473 
474     rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
475 
476     switch (level)
477     {
478     case RIG_LEVEL_KEYSPD:
479     case RIG_LEVEL_AGC:
480     case RIG_LEVEL_SQL:
481     case RIG_LEVEL_CWPITCH:
482     case RIG_LEVEL_RFPOWER:
483     case RIG_LEVEL_RF:
484     case RIG_LEVEL_AF:
485     case RIG_LEVEL_MICGAIN:
486         return kenwood_get_level(rig, vfo, level, val);
487 
488 
489     case RIG_LEVEL_METER:
490         retval = kenwood_transaction(rig, "RM0", lvlbuf, sizeof(lvlbuf));
491 
492         if (retval != RIG_OK)
493         {
494             return retval;
495         }
496 
497         lvl_len = strlen(lvlbuf);
498 
499         if (lvl_len != 7)
500         {
501             rig_debug(RIG_DEBUG_ERR, "ts590_get_level: "
502                       "unexpected answer len=%d\n", lvl_len);
503             return -RIG_ERJCTED;
504         }
505 
506         // returns the raw value in dots
507         sscanf(lvlbuf + 3, "%d", &val->i);
508         return retval;
509 
510     case RIG_LEVEL_SWR:
511         retval = kenwood_transaction(rig, "RM1", lvlbuf, sizeof(lvlbuf));
512 
513         if (retval != RIG_OK)
514         {
515             return retval;
516         }
517 
518         lvl_len = strlen(lvlbuf);
519 
520         if (lvl_len != 7)
521         {
522             rig_debug(RIG_DEBUG_ERR, "ts590_get_level: "
523                       "unexpected answer len=%d\n", lvl_len);
524             return -RIG_ERJCTED;
525         }
526 
527         // returns the raw value in dots
528         sscanf(lvlbuf + 3, "%d", &val->i);
529         return retval;
530 
531     case RIG_LEVEL_COMP:
532         retval = kenwood_transaction(rig, "RM2", lvlbuf, sizeof(lvlbuf));
533 
534         if (retval != RIG_OK)
535         {
536             return retval;
537         }
538 
539         lvl_len = strlen(lvlbuf);
540 
541         if (lvl_len != 7)
542         {
543             rig_debug(RIG_DEBUG_ERR, "ts590_get_level: "
544                       "unexpected answer len=%d\n", lvl_len);
545             return -RIG_ERJCTED;
546         }
547 
548         // returns the raw value in dots
549         sscanf(lvlbuf + 3, "%d", &val->i);
550         return retval;
551 
552     case RIG_LEVEL_ALC:
553         retval = kenwood_transaction(rig, "RM3", lvlbuf, sizeof(lvlbuf));
554 
555         if (retval != RIG_OK)
556         {
557             return retval;
558         }
559 
560         lvl_len = strlen(lvlbuf);
561 
562         if (lvl_len != 7)
563         {
564             rig_debug(RIG_DEBUG_ERR, "ts590_get_level: "
565                       "unexpected answer len=%d\n", lvl_len);
566             return -RIG_ERJCTED;
567         }
568 
569         // returns the raw value in dots
570         sscanf(lvlbuf + 3, "%d", &val->i);
571         return retval;
572 
573     case RIG_LEVEL_RAWSTR:
574     case RIG_LEVEL_STRENGTH:
575         retval = kenwood_transaction(rig, "SM0", lvlbuf, sizeof(lvlbuf));
576 
577         if (retval != RIG_OK)
578         {
579             return retval;
580         }
581 
582         lvl_len = strlen(lvlbuf);
583 
584         if (((lvl_len != 7)) || lvlbuf[1] != 'M')
585         {
586             /* TS-590 returns 8 bytes for S meter level */
587             rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)lvl_len);
588             return -RIG_ERJCTED;
589         }
590 
591         /* Frontend expects:  -54 = S0, 0 = S9  */
592         sscanf(lvlbuf + 3, "%d", &val->i);
593 
594         /* TS-590 main receiver returns values from 0 - 30 */
595         /* Indicates # of dots on meter */
596         /* so first 15 are S0-S9 and last 15 are 20/40/60 */
597         if (level == RIG_LEVEL_STRENGTH)
598         {
599             cal_table_t str_cal = TS590_SM_CAL;
600             val->i = (int) rig_raw2val(val->i, &str_cal);
601         }
602 
603         return retval;
604 
605     default: return -RIG_EINVAL;
606     }
607 }
608