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 <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <math.h>
25
26 #include "RAY152.h"
27
28 //=============================================================================
29
30 const char RIG_RAY152name_[] = "RAY 152";
31
32 const char *RIG_RAY152modes_[] = { "USB", "LSB", "H3E", "A1A", "F1B", NULL};
33 static const char RIG_RAY152_mode_type[] = {'U', 'L', 'U', 'L', 'U'};
34
35 static GUI rig_widgets[]= {
36 { (Fl_Widget *)btnVol, 2, 145, 50 },
37 { (Fl_Widget *)sldrVOLUME, 54, 145, 368 },
38 { (Fl_Widget *)sldrRFGAIN, 54, 125, 156 },
39 { (Fl_Widget *)sldrSQUELCH, 266, 125, 156 },
40 { (Fl_Widget *)NULL, 0, 0, 0 }
41 };
42
RIG_RAY152()43 RIG_RAY152::RIG_RAY152() {
44 name_ = RIG_RAY152name_;
45 modes_ = RIG_RAY152modes_;
46
47 widgets = rig_widgets;
48
49 comm_baudrate = BR1200;
50 stopbits = 1;
51 comm_retries = 2;
52 comm_wait = 10;
53 comm_timeout = 50;
54 comm_echo = true;
55 comm_rtscts = false;
56 comm_rtsplus = false;
57 comm_dtrplus = true;
58 comm_catptt = true;
59 comm_rtsptt = false;
60 comm_dtrptt = false;
61
62 A.freq = 14070000;
63 A.imode = 0;
64 A.iBW = 0;
65
66 B.freq = 3580000;
67 B.imode = 0;
68 B.iBW = 0;
69
70 precision = 100;
71 ndigits = 6;
72
73 has_mode_control = true;
74 has_ptt_control = true;
75 has_rf_control = true;
76 has_volume_control = true;
77 has_rit = true;
78 has_sql_control = true;
79 has_noise_control = true;
80 has_auto_notch = true;
81 };
82
83
nocr(string & s)84 static void nocr( string & s)
85 {
86 for (size_t i = 0; i < s.length(); i++)
87 if (s[i] == '\r') s[i] = ' ';
88 }
89
90 /*
91 Data string returned by the 'O' command
92 3 A*\r AGC ON/OFF
93 5 C***\r Memory channel #
94 5 D+/-**\r Clarifier frequency
95 9 FT******\r Transmit frequemcy
96 9 FR******\r Receive frequency
97 6 I****\r ITU channel #
98 3 M*\r Mode
99 3 N*\r Noise blanker status
100 3 P*\r Power reduction status
101 5 Q***\r Squelch setting
102 5 R***\r RF gain setting
103 5 V***\r Volume setting
104 3 Z*\r Meter function
105 total 64
106 */
107
check()108 bool RIG_RAY152::check()
109 {
110 int ret = sendCommand("O\r");
111 if (ret < 66) return false;
112 return true;
113 }
114
get_data()115 void RIG_RAY152::get_data()
116 {
117 int ret = sendCommand("O\r");
118 if (ret < 66) return;
119 // test string
120 //replystr = "A1\rC000\rD-05\rFT1407000\rFR1407000\rI0000\rM1\rN1\rP0\rQ000\rR100\rV128\rZ1\r";
121
122 if (dumpdata)
123 LOG_WARN("\n%s", replystr.c_str());
124 dumpdata = false;
125
126 size_t pos;
127
128 pos = replystr.find("FR"); // receive frequency
129 if (pos != string::npos) {
130 int freq;
131 sscanf(&replystr[pos + 2], "%d", &freq);
132 A.freq = 100 * freq;
133 }
134
135 pos = replystr.find("M"); // mode
136 if (pos != string::npos)
137 A.imode = replystr[pos + 1] - '1';
138
139 pos = replystr.find("D");
140 if (pos != string::npos) {
141 sscanf(&replystr[pos + 1], "%d", &RitFreq);
142 RitFreq *= 10;
143 }
144
145 pos = replystr.find("\rR");
146 if (pos != string::npos)
147 sscanf(&replystr[pos + 2], "%d", &rfg);
148
149 pos = replystr.find("V");
150 if (pos != string::npos) {
151 sscanf(&replystr[pos + 1], "%d", &vol);
152 vol *= 100;
153 vol /= 255;
154 }
155
156 pos = replystr.find("Q");
157 if (pos != string::npos) {
158 sscanf(&replystr[pos + 1], "%d", &squelch);
159 }
160
161 pos = replystr.find("N");
162 if (pos != string::npos) {
163 if (replystr[pos + 1] > '0') {
164 nb_set = replystr[pos+1];
165 nb = 1;
166 }
167 else {
168 nb = 0;
169 nb_set = '2';
170 }
171 }
172
173 // RAY152 usurps the autonotch button for AGC control
174 pos = replystr.find("A");
175 if (pos != string::npos)
176 agc = replystr[1] == '1' ? 1 : 0;
177
178 }
179
initialize()180 void RIG_RAY152::initialize()
181 {
182 rig_widgets[0].W = btnVol;
183 rig_widgets[1].W = sldrVOLUME;
184 rig_widgets[2].W = sldrRFGAIN;
185 rig_widgets[3].W = sldrSQUELCH;
186
187 sendCommand("E1\r", 0);
188 sendCommand("Z1\r", 0);
189 dumpdata = true;
190 get_data();
191 set_auto_notch(agc);
192 }
193
shutdown()194 void RIG_RAY152::shutdown()
195 {
196 sendCommand("E0\r", 0);
197 LOG_INFO("%s", cmd.c_str());
198 }
199
get_vfoA()200 unsigned long int RIG_RAY152::get_vfoA ()
201 {
202 return A.freq;
203 }
204
set_vfoA(unsigned long int freq)205 void RIG_RAY152::set_vfoA (unsigned long int freq)
206 {
207 A.freq = freq;
208 cmd = "FT000000\r";
209 freq /= 100;
210 cmd[7] += freq % 10; freq /= 10;
211 cmd[6] += freq % 10; freq /= 10;
212 cmd[5] += freq % 10; freq /= 10;
213 cmd[4] += freq % 10; freq /= 10;
214 cmd[3] += freq % 10; freq /=10;
215 cmd[2] += freq;
216 sendCommand(cmd, 0);
217 LOG_INFO("%s", cmd.c_str());
218 cmd[1] = 'R';
219 sendCommand(cmd, 0);
220 LOG_INFO("%s", cmd.c_str());
221 }
222
get_vfoB()223 unsigned long int RIG_RAY152::get_vfoB ()
224 {
225 return B.freq;
226 }
227
set_vfoB(unsigned long int freq)228 void RIG_RAY152::set_vfoB (unsigned long int freq)
229 {
230 B.freq = freq;
231 cmd = "FT000000\r";
232 freq /= 100;
233 cmd[7] += freq % 10; freq /= 10;
234 cmd[6] += freq % 10; freq /= 10;
235 cmd[5] += freq % 10; freq /= 10;
236 cmd[4] += freq % 10; freq /= 10;
237 cmd[3] += freq % 10; freq /=10;
238 cmd[2] += freq;
239 sendCommand(cmd, 0);
240 LOG_INFO("%s", cmd.c_str());
241 cmd[1] = 'R';
242 sendCommand(cmd, 0);
243 LOG_INFO("%s", cmd.c_str());
244 }
245
set_PTT_control(int val)246 void RIG_RAY152::set_PTT_control(int val)
247 {
248 cmd = val ? "X1\r" : "X0\r";
249 sendCommand(cmd,0);
250 LOG_INFO("%s", cmd.c_str());
251 ptt_ = val;
252 }
253
set_modeA(int md)254 void RIG_RAY152::set_modeA(int md)
255 {
256 A.imode = md;
257 cmd = "M";
258 cmd += (md + '1');
259 cmd += '\r';
260 sendCommand(cmd, 0);
261 LOG_INFO("%s", cmd.c_str());
262 }
263
get_modeA()264 int RIG_RAY152::get_modeA()
265 {
266 return A.imode;
267 }
268
set_modeB(int md)269 void RIG_RAY152::set_modeB(int md)
270 {
271 B.imode = md;
272 cmd = "M";
273 cmd += (md + '1');
274 cmd += '\r';
275 sendCommand(cmd, 0);
276 LOG_INFO("%s", cmd.c_str());
277 }
278
get_modeB()279 int RIG_RAY152::get_modeB()
280 {
281 return B.imode;
282 }
283
get_modetype(int n)284 int RIG_RAY152::get_modetype(int n)
285 {
286 return RIG_RAY152_mode_type[n];
287 }
288
set_volume_control(int val)289 void RIG_RAY152::set_volume_control(int val)
290 {
291 vol = val;
292 string cmd = "V000\r";
293 val *= 255;
294 val /= 100;
295 cmd[3] += val % 10; val /= 10;
296 cmd[2] += val % 10; val /= 10;
297 cmd[1] += val;
298 sendCommand(cmd, 0);
299 LOG_INFO("%s", cmd.c_str());
300 }
301
set_rf_gain(int val)302 void RIG_RAY152::set_rf_gain(int val)
303 {
304 rfg = val;
305 cmd = "R000\r";
306 cmd[3] += val % 10; val /= 10;
307 cmd[2] += val % 10; val /= 10;
308 cmd[1] += val;
309 sendCommand(cmd, 0);
310 LOG_INFO("%s", cmd.c_str());
311 }
312
get_smeter(void)313 int RIG_RAY152::get_smeter(void)
314 {
315 cmd = "U\r";
316 int ret = sendCommand(cmd);
317 string s = replystr;
318 nocr(s);
319 LOG_WARN("%s", s.c_str());
320 if (ret < 5) return 0;
321 if (replystr[ret - 5] == 'U') {
322 int val;
323 sscanf(&replystr[ret - 5 + 1], "%d", &val);
324 val = (int)(60.0 * (256.0 / (val + 16.0) - 1.0));
325 if (val > 100) val = 100;
326 if (val < 0) val = 0;
327 return val;
328 }
329 return 0;
330 }
331
get_power_out(void)332 int RIG_RAY152::get_power_out(void)
333 {
334 int ret = sendCommand("U\r");
335 if (ret < 5) return 0;
336 if (replystr[ret - 5] == 'U') {
337 int val;
338 sscanf(&replystr[ret - 5 + 1], "%d", &val);
339 val /= 128;
340 val *= 100;
341 return val;
342 }
343 return -1;
344 }
345
346
setRit(int v)347 void RIG_RAY152::setRit(int v)
348 {
349 RitFreq = v;
350 cmd = "D+00\r";
351 if (v < 0) cmd[1] = '-';
352 v /= 10;
353 v = abs(v);
354 cmd[3] += v % 10; v /= 10;
355 cmd[2] += v % 10;
356 sendCommand(cmd, 0);
357 LOG_INFO("%s", cmd.c_str());
358 }
359
getRit()360 int RIG_RAY152::getRit()
361 {
362 return RitFreq;
363 }
364
set_squelch(int val)365 void RIG_RAY152::set_squelch(int val)
366 {
367 squelch = val;
368 cmd = "Q000\r";
369 cmd[3] += val % 10; val /= 10;
370 cmd[2] += val % 10; val /= 10;
371 cmd[1] += val;
372 sendCommand(cmd, 0);
373 LOG_INFO("%s", cmd.c_str());
374 }
375
get_squelch()376 int RIG_RAY152::get_squelch()
377 {
378 return squelch;
379 }
380
set_noise(bool on)381 void RIG_RAY152::set_noise(bool on)
382 {
383 cmd = "Nx\r";
384 cmd[1] = on ? nb_set : '0';
385 sendCommand(cmd, 0);
386 LOG_INFO("%s", cmd.c_str());
387 }
388
get_noise()389 int RIG_RAY152::get_noise()
390 {
391 return nb;
392 }
393
set_auto_notch(int v)394 void RIG_RAY152::set_auto_notch(int v)
395 {
396 cmd = "Ax\r";
397 cmd[1] = v ? '1' : '0';
398 sendCommand(cmd, 0);
399 LOG_INFO("%s", cmd.c_str());
400 }
401
get_auto_notch()402 int RIG_RAY152::get_auto_notch()
403 {
404 return agc;
405 }
406
407