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 "TS450S.h"
22 #include "support.h"
23 
24 static const char TS450Sname_[] = "TS-450S";
25 
26 static const char *TS450Smodes_[] = {
27 		"LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "FSK-R", NULL};
28 static const char TS450S_mode_chr[] =  { '1', '2', '3', '4', '5', '6', '7', '9' };
29 static const char TS450S_mode_type[] = { 'L', 'U', 'U', 'U', 'U', 'L', 'L', 'U' };
30 
31 static const char *TS450S_widths[] = {
32 "NONE", "FM-W", "FM-N", "AM", "SSB", "CW", NULL};
33 static int TS450S_bw_vals[] = { 1,2,3,4,5,6, WVALS_LIMIT};
34 
35 static const char *TS450S_filters[] = {
36 "000", "002", "003", "005", "007", "009", NULL};
37 
RIG_TS450S()38 RIG_TS450S::RIG_TS450S() {
39 // base class values
40 	name_ = TS450Sname_;
41 	modes_ = TS450Smodes_;
42 	_mode_type = TS450S_mode_type;
43 	bandwidths_ = TS450S_widths;
44 	bw_vals_ = TS450S_bw_vals;
45 	comm_baudrate = BR4800;
46 	stopbits = 2;
47 	comm_retries = 2;
48 	comm_wait = 5;
49 	comm_timeout = 50;
50 	comm_rtscts = true;
51 	comm_rtsplus = false;
52 	comm_dtrplus = false;
53 	comm_catptt = true;
54 	comm_rtsptt = false;
55 	comm_dtrptt = false;
56 	modeB = modeA = def_mode = 1;
57 	bwB = bwA = def_bw = 1;
58 	freqB = freqA = def_freq = 14070000;
59 	can_change_alt_vfo = true;
60 
61 	has_noise_control =
62 	has_micgain_control =
63 	has_volume_control =
64 	has_power_control =
65 	has_tune_control =
66 	has_attenuator_control =
67 	has_preamp_control =
68 	has_notch_control =
69 	has_ifshift_control =
70 	has_swr_control = false;
71 
72 	has_smeter =
73 	has_swr_control =
74 	has_mode_control =
75 	has_bandwidth_control =
76 	has_ptt_control = true;
77 
78 	precision = 10;
79 	ndigits = 7;
80 
81 }
82 
initialize()83 void RIG_TS450S::initialize()
84 {
85 	cmd = "RM1;"; // select measurement '1' (swr)
86 	sendCommand(cmd);
87 }
88 
check()89 bool RIG_TS450S::check ()
90 {
91 	cmd = "FA;";
92 	int ret = wait_char(';', 14, 100, "check", ASC);
93 	if (ret < 14) return false;
94 	return true;
95 }
96 
get_vfoA()97 unsigned long int RIG_TS450S::get_vfoA ()
98 {
99 	cmd = "FA;";
100 
101 	int ret = wait_char(';', 14, 100, "get vfo A", ASC);
102 	if (ret < 14) return freqA;
103 
104 	size_t p = replystr.rfind("FA");
105 	if (p == string::npos) return freqA;
106 
107 	int f = 0;
108 	for (size_t n = 2; n < 13; n++)
109 		f = f*10 + replystr[p + n] - '0';
110 	freqA = f;
111 	return freqA;
112 }
113 
set_vfoA(unsigned long int freq)114 void RIG_TS450S::set_vfoA (unsigned long int freq)
115 {
116 	freqA = freq;
117 	cmd = "FA00000000000;";
118 	for (int i = 12; i > 1; i--) {
119 		cmd[i] += freq % 10;
120 		freq /= 10;
121 	}
122 	sendCommand(cmd);
123 	showresp(WARN, ASC, "set vfo A", cmd, "");
124 }
125 
get_vfoB()126 unsigned long int RIG_TS450S::get_vfoB ()
127 {
128 	cmd = "FB;";
129 	int ret = wait_char(';', 14, 100, "get vfo B", ASC);
130 	if (ret < 14) return freqB;
131 
132 	size_t p = replystr.rfind("FB");
133 	if (p == string::npos) return freqB;
134 
135 	int f = 0;
136 	for (size_t n = 2; n < 13; n++)
137 		f = f*10 + replystr[p + n] - '0';
138 	freqB = f;
139 	return freqB;
140 }
141 
set_vfoB(unsigned long int freq)142 void RIG_TS450S::set_vfoB (unsigned long int freq)
143 {
144 	freqB = freq;
145 	cmd = "FB00000000000;";
146 	for (int i = 12; i > 1; i--) {
147 		cmd[i] += freq % 10;
148 		freq /= 10;
149 	}
150 	sendCommand(cmd);
151 	showresp(WARN, ASC, "set vfo B", cmd, "");
152 }
153 
154 // SM cmd 0 ... 100 (rig values 0 ... 15)
get_smeter()155 int RIG_TS450S::get_smeter()
156 {
157 	cmd = "SM;";
158 	int ret = wait_char(';', 7, 100, "get smeter", ASC);
159 	if (ret < 7) return 0;
160 
161 	size_t p = replystr.rfind("SM");
162 	if (p == string::npos) return 0;
163 
164 	replystr[p + 6] = 0;
165 	int mtr = atoi(&replystr[p + 2]);
166 	mtr = (mtr * 100) / 30;
167 	return mtr;
168 }
169 
170 // RM cmd 0 ... 100 (rig values 0 ... 8)
get_swr()171 int RIG_TS450S::get_swr()
172 {
173 	cmd = "RM;";
174 	int ret = wait_char(';', 8, 100, "get swr", ASC);
175 	if (ret < 8) return 0;
176 
177 	size_t p = replystr.rfind("RM");
178 	if (p == string::npos) return 0;
179 
180 	replystr[p + 7] = 0;
181 	int mtr = atoi(&replystr[p + 3]);
182 	mtr = (mtr * 50) / 30;
183 	return mtr;
184 }
185 
186 
set_modeA(int val)187 void RIG_TS450S::set_modeA(int val)
188 {
189 	showresp(WARN, ASC, "set mode A", "", "");
190 	modeA = val;
191 	cmd = "MD";
192 	cmd += TS450S_mode_chr[val];
193 	cmd += ';';
194 	sendCommand(cmd);
195 }
196 
get_modeA()197 int RIG_TS450S::get_modeA()
198 {
199 	cmd = "IF;";
200 	int ret = wait_char(';', 38, 100, "get modeA", ASC);
201 	if (ret < 38) return split;
202 	size_t p = replystr.rfind("IF");
203 	if (p == string::npos) return modeA;
204 	modeA = replystr[p+29] - '1'; // 0 - 6, 8
205 	if (modeA == 8) modeA = 7;
206 	return modeA;
207 }
208 
set_modeB(int val)209 void RIG_TS450S::set_modeB(int val)
210 {
211 	showresp(WARN, ASC, "set mode B", "", "");
212 	modeB = val;
213 	cmd = "MD";
214 	cmd += TS450S_mode_chr[val];
215 	cmd += ';';
216 	sendCommand(cmd);
217 }
218 
get_modeB()219 int RIG_TS450S::get_modeB()
220 {
221 	cmd = "IF;";
222 	int ret = wait_char(';', 38, 100, "get mode B", ASC);
223 	if (ret < 38) return split;
224 	size_t p = replystr.rfind("IF");
225 	if (p == string::npos) return modeA;
226 	modeB = replystr[p+29] - '1'; // 0 - 6, 8
227 	if (modeB == 8) modeB = 7;
228 	return modeB;
229 }
230 
get_modetype(int n)231 int RIG_TS450S::get_modetype(int n)
232 {
233 	return _mode_type[n];
234 }
235 
236 static string bw_str = "FL001001;";
237 
set_bwA(int val)238 void RIG_TS450S::set_bwA(int val)
239 {
240 	get_bwA();
241 	showresp(WARN, ASC, "set bw A", "", "");
242 	bwA = val;
243 	cmd = bw_str.substr(0, 5);
244 	cmd.append(TS450S_filters[val]).append(";");
245 	sendCommand(cmd);
246 }
247 
get_bwA()248 int RIG_TS450S::get_bwA()
249 {
250 	cmd = "FL;";
251 	int ret = wait_char(';', 9, 100, "get bwA", ASC);
252 	if (ret < 9) return bwA;
253 	bw_str = replystr;
254 	size_t p = replystr.rfind("FL");
255 	if (p == string::npos) return bwA;
256 
257 	replystr[p + 8] = 0;
258 	int bw = 0;
259 	while (TS450S_filters[bw]) {
260 		if (strcmp(&replystr[p + 5], TS450S_filters[bw]) == 0)
261 			return bwA = bw;
262 		bw++;
263 	}
264 	return bwA;
265 }
266 
set_bwB(int val)267 void RIG_TS450S::set_bwB(int val)
268 {
269 	get_bwB();
270 	showresp(WARN, ASC, "set bw B", "", "");
271 	bwB = val;
272 	cmd = bw_str.substr(0, 5);
273 	cmd.append(TS450S_filters[val]).append(";");
274 	sendCommand(cmd);
275 }
276 
get_bwB()277 int RIG_TS450S::get_bwB()
278 {
279 	cmd = "FL;";
280 	int ret = wait_char(';', 9, 100, "get bwB", ASC);
281 	if (ret < 9) return bwB;
282 	bw_str = replystr;
283 	size_t p = replystr.rfind("FL");
284 	if (p == string::npos) return bwB;
285 
286 	replystr[p + 8] = 0;
287 	int bw = 0;
288 	while (TS450S_filters[bw]) {
289 		if (strcmp(&replystr[p + 5], TS450S_filters[bw]) == 0)
290 			return bwB = bw;
291 		bw++;
292 	}
293 	return bwB;
294 }
295 
def_bandwidth(int val)296 int RIG_TS450S::def_bandwidth(int val)
297 {
298 	if (val == 0 || val == 1)
299 		return 4;
300 	else if (val == 2 || val == 6)
301 		return 5;
302 	else if (val == 3)
303 		return 1;
304 	else if (val == 4)
305 		return 3;
306 	else if (val == 5 || val == 7)
307 		return 2;
308 	return 4;
309 }
310 
selectA()311 void RIG_TS450S::selectA()
312 {
313 	showresp(WARN, ASC, "select A", "", "");
314 	cmd = "FR0;";
315 	sendCommand(cmd);
316 	cmd = "FT0;";
317 	sendCommand(cmd);
318 }
319 
selectB()320 void RIG_TS450S::selectB()
321 {
322 	showresp(WARN, ASC, "select B", "", "");
323 	cmd = "FR1;";
324 	sendCommand(cmd);
325 	cmd = "FT1;";
326 	sendCommand(cmd);
327 }
328 
can_split()329 bool RIG_TS450S::can_split()
330 {
331 	return true;
332 }
333 
set_split(bool val)334 void RIG_TS450S::set_split(bool val)
335 {
336 	if (val) {
337 		cmd = "FR0;";
338 		sendCommand(cmd);
339 		cmd = "FT1;";
340 		sendCommand(cmd);
341 	} else {
342 		cmd = "FR0;";
343 		sendCommand(cmd);
344 		cmd = "FT0;";
345 		sendCommand(cmd);
346 	}
347 }
348 
get_split()349 int RIG_TS450S::get_split()
350 {
351 	cmd = "IF;";
352 	int ret = wait_char(';', 38, 100, "get split", ASC);
353 	if (ret < 38) return split;
354 	size_t p = replystr.rfind("IF");
355 	if (p == string::npos) return split;
356 	split = replystr[p+32] ? true : false;
357 	return split;
358 }
359 
360 // Tranceiver PTT on/off
set_PTT_control(int val)361 void RIG_TS450S::set_PTT_control(int val)
362 {
363 	if (val) sendCommand("TX;");
364 	else	 sendCommand("RX;");
365 	ptt_ = val;
366 }
367 
368 /*
369 ========================================================================
370 	frequency & mode data are contained in the IF; response
371 		IFaaaaaaaaaaaXXXXXbbbbbcdXeefghjklmmX;
372 		12345678901234567890123456789012345678
373 		01234567890123456789012345678901234567 byte #
374 		          1         2         3
375 		                            ^ position 28
376 		where:
377 			aaaaaaaaaaa => decimal value of vfo frequency
378 			bbbbb => rit/xit frequency
379 			c => rit off/on
380 			d => xit off/on
381 			e => memory channel
382 			f => tx/rx
383 			g => mode
384 			h => function
385 			j => scan off/on
386 			k => split off /on
387 			l => tone off /on
388 			m => tone number
389 			X => unused characters
390 
391 ========================================================================
392 */
393 
get_PTT()394 int RIG_TS450S::get_PTT()
395 {
396 	cmd = "IF;";
397 	int ret = wait_char(';', 38, 100, "get VFO", ASC);
398 	if (ret < 38) return ptt_;
399 	ptt_ = (replybuff[28] == '1');
400 	return ptt_;
401 }
402