1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2014
3 // David Freese, W1HKJ
4 //
5 // This file is part of flrig.
6 //
7 // flrig is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // flrig 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
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // aunsigned long int with this program. If not, see <http://www.gnu.org/licenses/>.
19 // ----------------------------------------------------------------------------
20
21 #include "TS940S.h"
22
23 const char TS940Sname_[] = "TS940S";
24
25 const char *TS940Smodes_[] = {"LSB", "USB", "CW", "FM", "AM", "FSK", NULL};
26 static const char TS940S_mode_type[] = {'L', 'U', 'U', 'U', 'U', 'L' };
27 static const char TS940S_mode_chr[] = {'1', '2', '3', '4', '5', '6', };
28
RIG_TS940S()29 RIG_TS940S::RIG_TS940S() {
30 // base class values
31 name_ = TS940Sname_;
32 modes_ = TS940Smodes_;
33 bandwidths_ = NULL;
34 comm_baudrate = BR4800;
35 stopbits = 2;
36 comm_retries = 2;
37 comm_wait = 5;
38 comm_timeout = 50;
39 comm_rtscts = false;
40 comm_rtsplus = false;
41 comm_dtrplus = false;
42 comm_catptt = true;
43 comm_rtsptt = false;
44 comm_dtrptt = false;
45 modeA = 1;
46 bwA = 2;
47
48 has_mode_control =
49 has_tune_control =
50 has_split =
51 has_split_AB =
52 has_ptt_control = true;
53
54 has_attenuator_control =
55 has_preamp_control =
56 has_power_control =
57 has_volume_control =
58 has_bandwidth_control =
59 has_micgain_control =
60 has_notch_control =
61 has_ifshift_control =
62 has_swr_control = false;
63
64 precision = 10;
65 ndigits = 7;
66
67 }
68
69 /*
70 ========================================================================
71 frequency & mode data are contained in the IF; response
72 IFaaaaaaaaaaaXXXXXbbbbbcdXeefghjklmmX;
73 12345678901234567890123456789012345678
74 01234567890123456789012345678901234567 byte #
75 IF00014070000 -00300 000200;
76
77 where:
78 aaaaaaaaaaa => decimal value of vfo frequency
79 bbbbb => rit/xit frequency
80 c => rit off/on
81 d => xit off/on
82 e => memory channel
83 f => tx/rx
84 g => mode
85 h => function
86 j => scan off/on
87 k => split off /on
88 l => tone off /on
89 m => tone number
90 X => unused characters
91
92 Test output from Minicom to IF; command
93
94 IF00014070000 -00300 000200;
95
96 0001000 is vfoA in LSB
97 0002000 is vfoA in USB
98 0003000 CW
99 0004000 FM
100 0005000 AM
101 0007000 CWN (dont have narrow filter however)
102 0002100 VFOB in USB
103 0002001 VFOA in USB SPILT
104 0012000 PTT on in USB
105 ========================================================================
106 */
107
check()108 bool RIG_TS940S::check ()
109 {
110 cmd = "FA;";
111 int ret = wait_char(';', 14, 100, "check", ASC);
112
113 get_trace(2, "check()", replystr.c_str());
114
115 if (ret < 14) return false;
116 return true;
117 }
118
getvfoAorB()119 int RIG_TS940S::getvfoAorB()
120 {
121 int vfovalue =0;
122 cmd = "IF;";
123 int ret = wait_char(';', 38, 100, "get vfo a or b", ASC);
124
125 get_trace(2, "getvfoAorB()", replystr.c_str());
126
127 if (ret < 38) return vfovalue;
128
129 vfovalue = replybuff[ret - 38 + 30] - '0';
130
131 showresp(WARN, ASC, "get vfo A or B", cmd, "");
132
133 return vfovalue;
134 }
135
136
get_vfoA()137 unsigned long int RIG_TS940S::get_vfoA ()
138 {
139 cmd = "FA;";
140 if (wait_char(';', 14, 100, "get vfo A", ASC) < 14) return A.freq;
141
142 get_trace(2, "get_vfoA()", replystr.c_str());
143
144 size_t p = replystr.rfind("FA");
145 if (p != string::npos && (p + 12 < replystr.length())) {
146 int f = 0;
147 for (size_t n = 2; n < 13; n++)
148 f = f*10 + replystr[p+n] - '0';
149 A.freq = f;
150 }
151 return A.freq;
152 }
153
set_vfoA(unsigned long int freq)154 void RIG_TS940S::set_vfoA (unsigned long int freq)
155 {
156 A.freq = freq;
157 cmd = "FA00000000000;";
158 for (int i = 12; i > 1; i--) {
159 cmd[i] += freq % 10;
160 freq /= 10;
161 }
162 sendCommand(cmd);
163 showresp(WARN, ASC, "set vfo A", cmd, "");
164 set_trace(2, "set_vfoA()", replystr.c_str());
165 }
166
get_vfoB()167 unsigned long int RIG_TS940S::get_vfoB ()
168 {
169 cmd = "FB;";
170 if (wait_char(';', 14, 100, "get vfo B", ASC) < 14) return B.freq;
171
172 get_trace(2, "get_vfoB()", replystr.c_str());
173
174 size_t p = replystr.rfind("FB");
175 if (p != string::npos && (p + 12 < replystr.length())) {
176 int f = 0;
177 for (size_t n = 2; n < 13; n++)
178 f = f*10 + replystr[p+n] - '0';
179 B.freq = f;
180 }
181 return B.freq;
182 }
183
set_vfoB(unsigned long int freq)184 void RIG_TS940S::set_vfoB (unsigned long int freq)
185 {
186 B.freq = freq;
187 cmd = "FB00000000000;";
188 for (int i = 12; i > 1; i--) {
189 cmd[i] += freq % 10;
190 freq /= 10;
191 }
192 sendCommand(cmd);
193 showresp(WARN, ASC, "set vfo B", cmd, "");
194 set_trace(2, "set_vfoB()", replystr.c_str());
195 }
196
get_modetype(int n)197 int RIG_TS940S::get_modetype(int n)
198 {
199 return TS940S_mode_type[n];
200 }
201
set_modeA(int val)202 void RIG_TS940S::set_modeA(int val)
203 {
204 A.imode = val;
205 cmd = "MD";
206 cmd += TS940S_mode_chr[val];
207 cmd += ';';
208 sendCommand(cmd);
209 showresp(WARN, ASC, "set mode", cmd, "");
210 set_trace(2, "set_mode()", replystr.c_str());
211 }
212
get_modeA()213 int RIG_TS940S::get_modeA()
214 {
215 modeA = 0;
216 cmd = "IF;";
217 int ret = wait_char(';', 38, 100, "get mode", ASC);
218
219 get_trace(2, "get_mode()", replystr.c_str());
220
221 if (ret < 38) return modeA;
222
223 int md = replybuff[ret - 38 + 29] - '1';
224 if (md < 0) md = 0;
225 if (md > 5) md = 5;
226 modeA = md;
227
228 showresp(WARN, ASC, "get mode", cmd, "");
229
230 return modeA;
231 }
232
get_modeB()233 int RIG_TS940S::get_modeB()
234 {
235 return get_modeA();
236 }
237
set_modeB(int val)238 void RIG_TS940S::set_modeB(int val)
239 {
240 set_modeA(val);
241 }
242
243 // Tranceiver PTT on/off
set_PTT_control(int val)244 void RIG_TS940S::set_PTT_control(int val)
245 {
246 if (val) {
247 sendCommand("TX;");
248 showresp(WARN, ASC, "TX on", cmd, "");
249 set_trace(2, "set_PTT(on)", replystr.c_str());
250 } else {
251 sendCommand("RX;");
252 showresp(WARN, ASC, "RX on", cmd, "");
253 set_trace(2, "set_PTT(off)", replystr.c_str());
254 }
255 ptt_ = val;
256 }
257
258 /*
259 ========================================================================
260 frequency & mode data are contained in the IF; response
261 IFaaaaaaaaaaaXXXXXbbbbbcdXeefghjklmmX;
262 12345678901234567890123456789012345678
263 01234567890123456789012345678901234567 byte #
264 1 2 3
265 ^ position 28
266 where:
267 aaaaaaaaaaa => decimal value of vfo frequency
268 bbbbb => rit/xit frequency
269 c => rit off/on
270 d => xit off/on
271 e => memory channel
272 f => tx/rx
273 g => mode
274 h => function
275 j => scan off/on
276 k => split off /on
277 l => tone off /on
278 m => tone number
279 X => unused characters
280
281 ========================================================================
282 */
283
get_PTT()284 int RIG_TS940S::get_PTT()
285 {
286 cmd = "IF;";
287 int ret = wait_char(';', 38, 100, "get VFO", ASC);
288
289 get_trace(2, "get_PTT()", replystr.c_str());
290
291 if (ret < 38) return ptt_;
292 ptt_ = (replybuff[28] == '1');
293 showresp(WARN, ASC, "get ptt", cmd, "");
294 return ptt_;
295 }
296
297
tune_rig()298 void RIG_TS940S::tune_rig()
299 {
300 cmd = "AT1;";
301 LOG_WARN("%s", cmd.c_str());
302 sendCommand(cmd);
303 showresp(WARN, ASC, "rig tune set", cmd, "");
304 set_trace(2, "tune_rig()", replystr.c_str());
305 }
306
get_split()307 int RIG_TS940S::get_split()
308 {
309 int splitvalue =0;
310 cmd = "IF;";
311 int ret = wait_char(';', 38, 100, "get split", ASC);
312
313 get_trace(2, "get_split()", replystr.c_str());
314
315 if (ret < 38) return splitvalue;
316
317 splitvalue = replybuff[ret - 38 + 32] - '0';
318
319 showresp(WARN, ASC, "get split", cmd, "");
320
321 return splitvalue;
322 }
323
set_split(bool val)324 void RIG_TS940S::set_split(bool val)
325 {
326 if (val) {
327 cmd = "SP1;";
328 sendCommand(cmd);
329 showresp(WARN, ASC, "split on", cmd, "");
330 set_trace(2, "set_split(on)", replystr.c_str());
331 } else {
332 cmd = "SP0;";
333 sendCommand(cmd);
334 showresp(WARN, ASC, "split off", cmd, "");
335 set_trace(2, "set_split(off)", replystr.c_str());
336 }
337 }
338
can_split()339 bool RIG_TS940S::can_split()
340 {
341 return true;
342 }
343
selectA()344 void RIG_TS940S::selectA()
345 {
346 set_split(0);
347 cmd="FN0;";
348 sendCommand(cmd);
349 showresp(WARN, ASC, "select VFO A", cmd, "");
350 set_trace(2, "selectA()", replystr.c_str());
351 }
352
selectB()353 void RIG_TS940S::selectB()
354 {
355 set_split(0);
356 cmd="FN1;";
357 sendCommand(cmd);
358 showresp(WARN, ASC, "select VFO B", cmd, "");
359 set_trace(2, "selectB()", replystr.c_str());
360 }
361