1 /*
2  *  Hamlib TenTenc backend - TT-565 headers
3  *  Copyright (c) 2004-2011 by Stephane Fillod
4  *  Copyright (c) 2004-2011 by Martin Ewing
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  * \addtogroup tentec_orion
25  * @{ */
26 
27 /**
28  * \file orion.h
29  * \brief Backend for Tentec Orion 565 / 566
30  *
31  * This backend supports the Ten-Tec Orion (565) and Orion II (566) transceivers.
32  */
33 
34 
35 #define BACKEND_VER "20200324"
36 
37 #define TRUE	1
38 #define FALSE	0
39 #define TT565_BUFSIZE 16
40 
41 /**
42  * \brief Memory capability
43  *
44  * Orion's own  memory channel holds a freq, mode, and bandwidth.
45  * May be captured from VFO A or B and applied to VFO A or B.
46  * It cannot directly be read or written from the computer!
47  */
48 #define TT565_MEM_CAP {        \
49 	.freq = 1,      \
50 	.mode = 1,      \
51 	.width = 1,     \
52 }
53 
54 static int tt565_init(RIG *rig);
55 static int tt565_open(RIG *rig);
56 static int tt565_cleanup(RIG *rig);
57 static int tt565_set_freq(RIG *rig, vfo_t vfo, freq_t freq);
58 static int tt565_get_freq(RIG *rig, vfo_t vfo, freq_t *freq);
59 static int tt565_set_vfo(RIG *rig, vfo_t vfo);
60 static int tt565_get_vfo(RIG *rig, vfo_t *vfo);
61 static int tt565_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width);
62 static int tt565_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width);
63 static int tt565_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo);
64 static int tt565_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo);
65 static int tt565_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt);
66 static int tt565_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt);
67 static int tt565_reset(RIG *rig, reset_t reset);
68 static int tt565_set_mem(RIG * rig, vfo_t vfo, int ch);
69 static int tt565_get_mem(RIG * rig, vfo_t vfo, int *ch);
70 static int tt565_vfo_op(RIG * rig, vfo_t vfo, vfo_op_t op);
71 static int tt565_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts);
72 static int tt565_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts);
73 static int tt565_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit);
74 static int tt565_get_rit(RIG * rig, vfo_t vfo, shortfreq_t *rit);
75 static int tt565_set_xit(RIG * rig, vfo_t vfo, shortfreq_t xit);
76 static int tt565_get_xit(RIG * rig, vfo_t vfo, shortfreq_t *xit);
77 static int tt565_set_level(RIG * rig, vfo_t vfo, setting_t level, value_t val);
78 static int tt565_get_level(RIG * rig, vfo_t vfo, setting_t level, value_t *val);
79 static const char* tt565_get_info(RIG *rig);
80 static int tt565_send_morse(RIG *rig, vfo_t vfo, const char *msg);
81 static int tt565_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status);
82 static int tt565_set_func(RIG *rig, vfo_t vfo, setting_t func, int status);
83 static int tt565_set_ant(RIG * rig, vfo_t vfo, ant_t ant, value_t option);
84 static int tt565_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx);
85 
86 /** \brief Orion private data */
87 struct tt565_priv_data {
88 	int ch;		/*!< memory channel */
89 	vfo_t vfo_curr; /*!< Currently selected VFO */
90 };
91 
92 /** \brief Orion Supported Modes */
93 #define TT565_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\
94 			RIG_MODE_RTTY|RIG_MODE_AM)
95 /** \brief Orion Receiver Modes */
96 #define TT565_RXMODES (TT565_MODES)
97 
98 /** \brief Orion Supported Functions */
99 #define TT565_FUNCS (RIG_FUNC_LOCK|RIG_FUNC_TUNER|RIG_FUNC_VOX|RIG_FUNC_NB)
100 
101 /** \brief Orion Supported Levels */
102 #define TT565_LEVELS (RIG_LEVEL_RAWSTR| \
103 				RIG_LEVEL_CWPITCH| \
104 				RIG_LEVEL_SQL|RIG_LEVEL_IF| \
105 				RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD| \
106 				RIG_LEVEL_RF|RIG_LEVEL_NR| \
107 				RIG_LEVEL_MICGAIN| \
108 				RIG_LEVEL_AF|RIG_LEVEL_AGC| \
109 				RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_ANTIVOX| \
110 				RIG_LEVEL_COMP|RIG_LEVEL_PREAMP| \
111 				RIG_LEVEL_SWR|RIG_LEVEL_ATT)
112 
113 /** \brief Orion Tx/Rx Antennas*/
114 #define TT565_ANTS (RIG_ANT_1|RIG_ANT_2)
115 /** \brief Orion Rx Antennas*/
116 #define TT565_RXANTS (TT565_ANTS|RIG_ANT_3)
117 
118 /** \brief Orion Parameters */
119 #define TT565_PARMS (RIG_PARM_NONE)
120 
121 /**
122  * \brief Orion VFOs - A and B
123  */
124 #define TT565_VFO (RIG_VFO_A|RIG_VFO_B)
125 /**
126  * \brief Orion VFO Operations
127  *
128  * Allowed operations
129  */
130 #define TT565_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|\
131 		RIG_OP_TO_VFO|RIG_OP_FROM_VFO| \
132 		RIG_OP_TUNE)
133 
134 /**
135  * \brief S-Meter Calibration list
136  *
137  * List format: { hardware units, dB relative to S9}
138  *
139  * These alternate tables must be of equal size, because they may be
140  * switched depending on firmware version detection.
141  *
142  * Note high end of scale is severely compressed in v1
143  * Table corrected against v 1.372, 11/2007
144  */
145 #define TT565_STR_CAL_V1 { 14,  { \
146                 {   1, -47 }, /* padding to match lengths with v2 */ \
147 		        {  10, -47 }, \
148                 {  13, -42 }, \
149                 {  18, -37 }, \
150                 {  22, -32 }, \
151                 {  27, -27 }, \
152                 {  32, -18 }, \
153                 {  37, -11 }, \
154                 {  42,  -4 }, \
155                 {  47,  -1 }, \
156                 {  52,  10 }, \
157                 {  57,  20 }, \
158                 {  65,  30 }, \
159                 {  74,  40 }, \
160         } }
161 /**
162  * Calibration for Version 2.062a firmware, from Rigserve project.
163  * Again, this is approximate based on one measurement.
164  */
165 #define TT565_STR_CAL_V2 { 14, { \
166                 { 10., -48. }, /* S1 = min. indication */ \
167                 { 24., -42. }, \
168                 { 38., -36. }, \
169                 { 47., -30. }, \
170                 { 61., -24. }, \
171                 { 70., -18. }, \
172                 { 79., -12. }, \
173                 { 84.,  -6. }, \
174                 { 94.,   0. }, /* S9 */ \
175                 { 103., 10. }, \
176                 { 118., 20. }, \
177                 { 134., 30. }, \
178                 { 147., 40. }, \
179                 { 161., 50. }, \
180         } }
181 
182 #undef TT565_TIME		/* Define to enable time checks */
183 #define TT565_ASCII_FREQ    /* select ascii mode for vfo commands */
184 	/* Note:  Binary mode seems buggy at certain freqs like
185 	7015679 < freq < 7015936, etc.  Use ascii mode. */
186 
187 /**
188  * \brief tt565 transceiver capabilities.
189  *
190  * All of the Orion's personality is defined here!
191  *
192  * Protocol is documented at Tentec's firmware site
193  *		http://www.rfsquared.com/
194  */
195 const struct rig_caps tt565_caps = {
196 RIG_MODEL(RIG_MODEL_TT565),
197 .model_name = "TT-565 Orion",
198 .mfg_name =  "Ten-Tec",
199 .version =  BACKEND_VER ".0",
200 .copyright =  "LGPL",
201 .status =  RIG_STATUS_BETA,
202 .rig_type =  RIG_TYPE_TRANSCEIVER,
203 .ptt_type =  RIG_PTT_RIG,
204 .dcd_type =  RIG_DCD_NONE,
205 .port_type =  RIG_PORT_SERIAL,
206 .serial_rate_min =  57600,
207 .serial_rate_max =  57600,
208 .serial_data_bits =  8,
209 .serial_stop_bits =  1,
210 .serial_parity =  RIG_PARITY_NONE,
211 .serial_handshake =  RIG_HANDSHAKE_HARDWARE,
212 .write_delay =  0,          /* no delay between characters written */
213 .post_write_delay =  0,		  /* ms delay between writes DEBUGGING HERE */
214 .timeout =  2000,						/* ms */
215 .retry =  4,
216 
217 .has_get_func =  TT565_FUNCS,
218 .has_set_func =  TT565_FUNCS,
219 .has_get_level =  TT565_LEVELS,
220 .has_set_level =  RIG_LEVEL_SET(TT565_LEVELS),
221 .has_get_parm =  TT565_PARMS,
222 .has_set_parm =  TT565_PARMS,
223 
224 .level_gran = {},
225 .parm_gran =  {},
226 .ctcss_list =  NULL,
227 .dcs_list =  NULL,
228 .preamp =   { 20, RIG_DBLST_END },
229 .attenuator =   { 6, 12, 18, RIG_DBLST_END },
230 .max_rit =  kHz(8),
231 .max_xit =  kHz(8),
232 .max_ifshift =  kHz(8),
233 .vfo_ops = TT565_VFO_OPS,
234 .targetable_vfo =  RIG_TARGETABLE_ALL,
235 .transceive =  RIG_TRN_OFF,
236 .bank_qty =   0,
237 .chan_desc_sz =  0,
238 
239 .chan_list =  {
240 		{   0, 199, RIG_MTYPE_MEM, TT565_MEM_CAP },
241 		},
242 
243 /* Note Orion's ranges correspond to the hardware capability - same in
244  * regions 1 and 2.  Band edges (VFOA) are wider than legal bands.
245  * VFOB is used for general coverage receive.
246  */
247 .rx_range_list1 =  {
248 /*	FRQ_RNG_HF(1,TT565_RXMODES, -1,-1,RIG_VFO_N(0),TT565_RXANTS), */
249 	{kHz(1790),kHz(2010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
250 	{kHz(3490),kHz(4075),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
251 	{kHz(5100),kHz(5450),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
252 	{kHz(6890),kHz(7430),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
253 	{kHz(10090),kHz(10160),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
254 	{kHz(13990),kHz(15010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
255 	{kHz(18058),kHz(18178),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
256 	{kHz(20990),kHz(21460),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
257 	{kHz(24880),kHz(25000),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
258 	{kHz(27990),kHz(29710),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
259 	{kHz(100),MHz(30),TT565_RXMODES,-1,-1,RIG_VFO_N(1),TT565_RXANTS},
260 	RIG_FRNG_END,
261   },
262 .tx_range_list1 =  {
263 /*	FRQ_RNG_HF(1,TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS), */
264 	{kHz(1790),kHz(2010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
265 	{kHz(3490),kHz(4075),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
266 	{kHz(5100),kHz(5450),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
267 	{kHz(6890),kHz(7430),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
268 	{kHz(10090),kHz(10160),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
269 	{kHz(13990),kHz(15010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
270 	{kHz(18058),kHz(18178),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
271 	{kHz(20990),kHz(21460),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
272 	{kHz(24880),kHz(25000),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
273 	{kHz(27990),kHz(29710),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
274 	RIG_FRNG_END,
275   },
276 
277 .rx_range_list2 =  {
278 /*	FRQ_RNG_HF(2,TT565_RXMODES, -1,-1,RIG_VFO_N(0),TT565_RXANTS),
279 	{MHz(5.25),MHz(5.40),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, */
280 	{kHz(1790),kHz(2010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
281 	{kHz(3490),kHz(4075),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
282 	{kHz(5100),kHz(5450),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
283 	{kHz(6890),kHz(7430),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
284 	{kHz(10090),kHz(10160),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
285 	{kHz(13990),kHz(15010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
286 	{kHz(18058),kHz(18178),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
287 	{kHz(20990),kHz(21460),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
288 	{kHz(24880),kHz(25000),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
289 	{kHz(27990),kHz(29710),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS},
290 	{kHz(100),MHz(30),TT565_RXMODES,-1,-1,RIG_VFO_N(1),TT565_RXANTS},
291 	RIG_FRNG_END,
292   },
293 .tx_range_list2 =  {
294 /*	FRQ_RNG_HF(2,TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS),
295 	{MHz(5.25),MHz(5.40),TT565_MODES,W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, */
296 	{kHz(1790),kHz(2010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
297 	{kHz(3490),kHz(4075),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
298 	{kHz(5100),kHz(5450),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
299 	{kHz(6890),kHz(7430),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
300 	{kHz(10090),kHz(10160),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
301 	{kHz(13990),kHz(15010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
302 	{kHz(18058),kHz(18178),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
303 	{kHz(20990),kHz(21460),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
304 	{kHz(24880),kHz(25000),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
305 	{kHz(27990),kHz(29710),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS},
306 	RIG_FRNG_END,
307   },
308 
309 .tuning_steps =  {
310 	 {TT565_RXMODES,1},
311 	 {TT565_RXMODES,10},
312 	 {TT565_RXMODES,100},
313 	 {TT565_RXMODES,kHz(1)},
314 	 {TT565_RXMODES,kHz(10)},
315 	 {TT565_RXMODES,kHz(100)},
316 	 RIG_TS_END,
317 	},
318         /* mode/filter list, remember: order matters! */
319 .filters =  {
320 	/* 9MHz IF filters: 15kHz, 6kHz, 2.4kHz, 1.0kHz */
321 	/* opt: 1.8kHz, 500Hz, 250Hz */
322 		{RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, kHz(2.4)},
323 		{RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, 100},
324 		{RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, kHz(6)},
325 		{RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, 0}, /* 590 filters */
326 		{RIG_MODE_AM, kHz(6)},
327 		{RIG_MODE_AM, kHz(4)},
328 		{RIG_MODE_FM, kHz(15)},
329 		RIG_FLT_END,
330 	},
331 .priv =  (void*)NULL,
332 
333 .rig_init =  tt565_init,
334 .rig_cleanup =  tt565_cleanup,
335 .rig_open = tt565_open,
336 
337 .set_freq =  tt565_set_freq,
338 .get_freq =  tt565_get_freq,
339 .set_vfo =  tt565_set_vfo,
340 .get_vfo =  tt565_get_vfo,
341 .set_mode =  tt565_set_mode,
342 .get_mode =  tt565_get_mode,
343 .set_split_vfo =  tt565_set_split_vfo,
344 .get_split_vfo =  tt565_get_split_vfo,
345 .set_level =  tt565_set_level,
346 .get_level =  tt565_get_level,
347 .set_mem =  tt565_set_mem,
348 .get_mem =  tt565_get_mem,
349 .set_ptt =  tt565_set_ptt,
350 .get_ptt =  tt565_get_ptt,
351 .vfo_op =  tt565_vfo_op,
352 .set_ts =  tt565_set_ts,
353 .get_ts =  tt565_get_ts,
354 .set_rit =  tt565_set_rit,
355 .get_rit =  tt565_get_rit,
356 .set_xit =  tt565_set_xit,
357 .get_xit =  tt565_get_xit,
358 .reset =  tt565_reset,
359 .get_info =  tt565_get_info,
360 .send_morse = tt565_send_morse,
361 .get_func = tt565_get_func,
362 .set_func = tt565_set_func,
363 .get_ant = tt565_get_ant,
364 .set_ant = tt565_set_ant,
365 
366 /* V2 is default. S-Meter cal table may be changed if V1 firmware detected. */
367 .str_cal = TT565_STR_CAL_V2,
368 };
369 
370 /*
371  * Eagle TT-599 share the same ability as Orion's
372  */
373 #define TT599_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_CWR|\
374             /* optional */ RIG_MODE_AM|RIG_MODE_FM)
375 #define TT599_RXMODES TT599_MODES
376 #define TT599_FUNCS (RIG_FUNC_ANF)
377 #define TT599_LEVELS (RIG_LEVEL_RAWSTR| \
378 				RIG_LEVEL_SWR|RIG_LEVEL_RFPOWER| \
379 				RIG_LEVEL_NR|RIG_LEVEL_AGC| \
380 				RIG_LEVEL_PREAMP|RIG_LEVEL_ATT)
381 #define TT599_PARMS (RIG_PARM_NONE)
382 #define TT599_MEM_CAP  { \
383 	.freq = 1,      \
384 	.mode = 1,      \
385 	.width = 1,     \
386 	.split = 1,     \
387 	.tx_freq = 1,   \
388 }
389 #define TT599_ANTS (RIG_ANT_1)
390 #define TT599_RXANTS TT599_ANTS
391 #define TT599_VFO (RIG_VFO_A|RIG_VFO_B)
392 #define TT599_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO)
393 
394 /*
395  * Random guess, to be measured. See FAQ at http://hamlib.org
396  */
397 #define TT599_STR_CAL { 3, { \
398                 { 10., -48. }, /* S1 = min. indication */ \
399                 { 94.,   0. }, /* S9 */ \
400                 { 161., 50. }, \
401         } }
402 
403 /**
404  * \brief tt599 transceiver capabilities.
405  *
406  * All of the Eagle's personality is defined here!
407  *
408  * Protocol is documented in Programmers Reference Manual V1.001 at
409  *		http://www.tentec.com/index.php?id=360#down
410  *
411  */
412 const struct rig_caps tt599_caps = {
413 RIG_MODEL(RIG_MODEL_TT599),
414 .model_name = "TT-599 Eagle",
415 .mfg_name =  "Ten-Tec",
416 .version =  BACKEND_VER ".0",
417 .copyright =  "LGPL",
418 .status =  RIG_STATUS_UNTESTED,
419 .rig_type =  RIG_TYPE_TRANSCEIVER,
420 .ptt_type =  RIG_PTT_RIG,
421 .dcd_type =  RIG_DCD_NONE,
422 .port_type =  RIG_PORT_SERIAL,
423 .serial_rate_min =  57600,
424 .serial_rate_max =  57600,
425 .serial_data_bits =  8,
426 .serial_stop_bits =  1,
427 .serial_parity =  RIG_PARITY_NONE,
428 .serial_handshake =  RIG_HANDSHAKE_HARDWARE,
429 .write_delay =  0,          /* no delay between characters written */
430 .post_write_delay =  0,		  /* ms delay between writes DEBUGGING HERE */
431 .timeout =  2000,						/* ms */
432 .retry =  4,
433 
434 .has_get_func =  TT599_FUNCS,
435 .has_set_func =  TT599_FUNCS,
436 .has_get_level =  TT599_LEVELS|RIG_LEVEL_RF,
437 .has_set_level =  RIG_LEVEL_SET(TT599_LEVELS),
438 .has_get_parm =  TT599_PARMS,
439 .has_set_parm =  TT599_PARMS,
440 
441 .level_gran = {},
442 .parm_gran =  {},
443 .ctcss_list =  NULL,
444 .dcs_list =  NULL,
445 .preamp =   { 10, RIG_DBLST_END },
446 .attenuator =   { 12, RIG_DBLST_END },
447 .max_rit =  kHz(0),
448 .max_xit =  kHz(0),
449 .max_ifshift =  kHz(0),
450 .vfo_ops = TT599_VFO_OPS,
451 .targetable_vfo =  RIG_TARGETABLE_FREQ,
452 .transceive =  RIG_TRN_OFF,
453 .bank_qty =   0,
454 .chan_desc_sz =  0,
455 
456 .chan_list =  {
457 		{   1, 100, RIG_MTYPE_MEM, TT599_MEM_CAP },
458 		},
459 
460 .rx_range_list1 =  {
461 	FRQ_RNG_HF(1,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS),
462 	FRQ_RNG_6m(1,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS),
463 	{kHz(500),MHz(30),TT599_RXMODES,-1,-1,RIG_VFO_N(1),TT599_RXANTS},
464 	RIG_FRNG_END,
465   },
466 .tx_range_list1 =  {
467 	FRQ_RNG_HF(1,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS),
468 	FRQ_RNG_6m(1,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS),
469 	RIG_FRNG_END,
470   },
471 
472 .rx_range_list2 =  {
473 	FRQ_RNG_HF(2,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS),
474 	FRQ_RNG_6m(2,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS),
475 	{MHz(5.25),MHz(5.40),TT599_RXMODES,-1,-1,RIG_VFO_N(0),TT599_RXANTS},
476 	{kHz(500),MHz(30),TT599_RXMODES,-1,-1,RIG_VFO_N(1),TT599_RXANTS},
477 	RIG_FRNG_END,
478   },
479 .tx_range_list2 =  {
480 	FRQ_RNG_HF(2,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS),
481 	FRQ_RNG_6m(2,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS),
482 	{MHz(5.25),MHz(5.40),TT599_MODES,W(5),W(100),RIG_VFO_N(0),TT599_ANTS},
483 	RIG_FRNG_END,
484   },
485 
486 .tuning_steps =  {
487 	 {TT599_RXMODES,1},
488 	 {TT599_RXMODES,10},
489 	 {TT599_RXMODES,100},
490 	 {TT599_RXMODES,kHz(1)},
491 	 {TT599_RXMODES,kHz(10)},
492 	 RIG_TS_END,
493 	},
494         /* mode/filter list, remember: order matters! */
495 .filters =  {
496 	/*  15kHz, 6kHz, 2.4kHz, 1.0kHz */
497     /* 9MHz IF filters: 2.4K standard */
498     /* optional = 300, 600, 1.8k, 6k, 15k */
499 		{RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, kHz(2.4)},
500 		{RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, 600},
501 		{RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, 300},
502 		{RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, kHz(1.8)},
503 		{RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, kHz(6)},
504 		{RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, 0}, /* 127 filters */
505 		{RIG_MODE_AM, kHz(6)},
506 		{RIG_MODE_FM, kHz(15)},
507 		RIG_FLT_END,
508 	},
509 .priv =  (void*)NULL,
510 
511 .rig_init =  tt565_init,
512 .rig_cleanup =  tt565_cleanup,
513 .rig_open = tt565_open,
514 
515 .set_freq =  tt565_set_freq,
516 .get_freq =  tt565_get_freq,
517 .set_vfo =  tt565_set_vfo,
518 .get_vfo =  tt565_get_vfo,
519 .set_mode =  tt565_set_mode,
520 .get_mode =  tt565_get_mode,
521 .set_split_vfo =  tt565_set_split_vfo,
522 .get_split_vfo =  tt565_get_split_vfo,
523 .set_level =  tt565_set_level,
524 .get_level =  tt565_get_level,
525 .set_mem =  tt565_set_mem,
526 .get_mem =  tt565_get_mem,
527 .set_ptt =  tt565_set_ptt,
528 .get_ptt =  tt565_get_ptt,
529 .vfo_op =  tt565_vfo_op,
530 .get_info =  tt565_get_info,
531 .get_func = tt565_get_func,
532 .set_func = tt565_set_func,
533 
534 .str_cal = TT599_STR_CAL,
535 };
536 
537 
538 /*
539  * Function definitions below
540  */
541 
542 /** \brief End of command marker */
543 #define EOM "\015"	/* CR */
544 /** \brief USB Mode */
545 #define TT565_USB '0'
546 /** \brief LSB Mode */
547 #define TT565_LSB '1'
548 /** \brief CW normal Mode */
549 #define TT565_CW  '2'
550 /** \brief CW reverse Mode */
551 #define TT565_CWR '3'
552 /** \brief AM Mode */
553 #define TT565_AM  '4'
554 /** \brief FM Mode */
555 #define TT565_FM  '5'
556 /** \brief RTTY Mode */
557 #define TT565_RTTY '6'
558 
559 /** \brief minimum sidetone freq., Hz */
560 #define TT565_TONE_MIN 300
561 /** \brief maximum sidetone freq., Hz */
562 #define TT565_TONE_MAX 1200
563 
564 /** \brief minimum CW keyer rate, wpm */
565 #define TT565_CW_MIN 10
566 /** \brief maximum CW keyer rate, wpm */
567 #define TT565_CW_MAX 60
568 
569 /** @} */
570