1 /*
2 * Tlf - contest logging program for amateur radio operators
3 * Copyright (C) 2001-2002-2003-2004 Rein Couperus <pa0r@amsat.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 /* ------------------------------------------------------------
21 * get trx info
22 *
23 *--------------------------------------------------------------*/
24
25
26 #include <unistd.h>
27 #include <sys/time.h>
28 #include <pthread.h>
29
30 #include "bands.h"
31 #include "err_utils.h"
32 #include "fldigixmlrpc.h"
33 #include "gettxinfo.h"
34 #include "tlf.h"
35 #include "tlf_curses.h"
36 #include "callinput.h"
37 #include "bands.h"
38
39 #include <hamlib/rig.h>
40
41 #ifdef RIG_PASSBAND_NOCHANGE
42 #define TLF_DEFAULT_PASSBAND RIG_PASSBAND_NOCHANGE
43 #else
44 #define TLF_DEFAULT_PASSBAND RIG_PASSBAND_NORMAL
45 #endif
46
47 extern RIG *my_rig;
48 extern int cw_bandwidth;
49 extern int trxmode;
50 extern rmode_t rigmode;
51 extern int digikeyer;
52 extern rmode_t digi_mode;
53
54 extern freq_t freq;
55 extern int bandinx;
56 extern freq_t bandfrequency[];
57
58 extern int trx_control;
59 extern unsigned char rigptt;
60
61 /* output frequency to rig or other rig-related request
62 *
63 * possible values:
64 * 0 - poll rig
65 * SETCWMODE
66 * SETSSBMODE
67 * RESETRIT
68 * SETDIGIMODE
69 * else - set rig frequency
70 *
71 */
72 static freq_t outfreq = 0;
73
74 static pthread_mutex_t outfreq_mutex = PTHREAD_MUTEX_INITIALIZER;
75
76 static double get_current_seconds();
77 static void handle_trx_bandswitch(const freq_t freq);
78
set_outfreq(freq_t hertz)79 void set_outfreq(freq_t hertz) {
80 if (!trx_control) {
81 hertz = 0; // no rig control, ignore request
82 }
83 pthread_mutex_lock(&outfreq_mutex);
84 outfreq = hertz;
85 pthread_mutex_unlock(&outfreq_mutex);
86 }
87
get_outfreq()88 freq_t get_outfreq() {
89 return outfreq;
90 }
91
get_and_reset_outfreq()92 static freq_t get_and_reset_outfreq() {
93 pthread_mutex_lock(&outfreq_mutex);
94 freq_t f = outfreq;
95 outfreq = 0.0;
96 pthread_mutex_unlock(&outfreq_mutex);
97 return f;
98 }
99
get_ssb_mode()100 static rmode_t get_ssb_mode() {
101 // LSB below 14 MHz, USB above it
102 return (freq < bandcorner[BANDINDEX_20][0] ? RIG_MODE_LSB : RIG_MODE_USB);
103 }
104
get_cw_bandwidth()105 static pbwidth_t get_cw_bandwidth() {
106 // use specified bandwidth (CWBANDWIDTH) if available
107 return (cw_bandwidth > 0 ? cw_bandwidth : TLF_DEFAULT_PASSBAND);
108 }
109
110
gettxinfo(void)111 void gettxinfo(void) {
112
113 freq_t rigfreq;
114 vfo_t vfo;
115 pbwidth_t bwidth;
116 int retval;
117 int retvalmode;
118 static double last_freq_time = 0.0;
119
120 static int oldbandinx;
121 static int fldigi_carrier;
122 static int fldigi_shift_freq;
123
124 if (!trx_control)
125 return;
126
127 /* CAT PTT wanted, available, inactive, and PTT On requested
128 * bits 0, 1, and 3 set.
129 */
130 if (rigptt == 0x0b) {
131 retval = rig_set_ptt(my_rig, RIG_VFO_CURR, RIG_PTT_ON);
132
133 /* Set PTT active bit. */
134 rigptt |= (1 << 2); /* 0x0f */
135
136 /* Clear PTT On requested bit. */
137 rigptt &= ~(1 << 3); /* 0x07 */
138 }
139
140 /* CAT PTT wanted, available, active and PTT Off requested
141 * bits 0, 1, 2, and 4 set.
142 */
143 if (rigptt == 0x17) {
144 retval = rig_set_ptt(my_rig, RIG_VFO_CURR, RIG_PTT_OFF);
145
146 /* Clear PTT Off requested bit. */
147 rigptt &= ~(1 << 4); /* 0x07 */
148
149 /* Clear PTT active bit. */
150 rigptt &= ~(1 << 2); /* 0x03 */
151 }
152
153 freq_t reqf = get_and_reset_outfreq(); // get actual request
154
155 if (reqf == 0) {
156
157 rigfreq = 0.0;
158
159 double now = get_current_seconds();
160 if (now < last_freq_time + 0.2) {
161 return; // last read-out was within 200 ms, skip this query
162 }
163 last_freq_time = now;
164
165 retval = rig_get_vfo(my_rig, &vfo); /* initialize RIG_VFO_CURR */
166 if (retval == RIG_OK || retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) {
167 retval = rig_get_freq(my_rig, RIG_VFO_CURR, &rigfreq);
168 if (trxmode == DIGIMODE && (digikeyer == GMFSK || digikeyer == FLDIGI)
169 && retval == RIG_OK) {
170 retvalmode = rig_get_mode(my_rig, RIG_VFO_CURR, &rigmode, &bwidth);
171 if (retvalmode != RIG_OK) {
172 rigmode = RIG_MODE_NONE;
173 }
174 }
175 }
176
177 if (trxmode == DIGIMODE && (digikeyer == GMFSK || digikeyer == FLDIGI)) {
178 fldigi_carrier = fldigi_get_carrier();
179 rigfreq += (freq_t)fldigi_carrier;
180 if (rigmode == RIG_MODE_RTTY || rigmode == RIG_MODE_RTTYR) {
181 fldigi_shift_freq = fldigi_get_shift_freq();
182 if (fldigi_shift_freq != 0) {
183 retval = rig_set_freq(my_rig, RIG_VFO_CURR,
184 ((freq_t)rigfreq + (freq_t)fldigi_shift_freq));
185 }
186 }
187 }
188
189 if (retval != RIG_OK || rigfreq < 0.1) {
190 freq = 0.0;
191 return;
192 }
193
194
195 if (rigfreq >= bandcorner[0][0]) {
196 freq = rigfreq; // Hz
197 }
198
199 bandinx = freq2band((unsigned int)freq);
200
201 bandfrequency[bandinx] = freq;
202
203 if (bandinx != oldbandinx) { // band change on trx
204 oldbandinx = bandinx;
205 handle_trx_bandswitch((int) freq);
206 }
207
208 } else if (reqf == SETCWMODE) {
209
210 retval = rig_set_mode(my_rig, RIG_VFO_CURR, RIG_MODE_CW, get_cw_bandwidth());
211
212 if (retval != RIG_OK) {
213 TLF_LOG_WARN("Problem with rig link!");
214 }
215
216 } else if (reqf == SETSSBMODE) {
217
218 retval = rig_set_mode(my_rig, RIG_VFO_CURR, get_ssb_mode(),
219 TLF_DEFAULT_PASSBAND);
220
221 if (retval != RIG_OK) {
222 TLF_LOG_WARN("Problem with rig link!");
223 }
224
225 } else if (reqf == SETDIGIMODE) {
226 rmode_t new_mode = digi_mode;
227 if (new_mode == RIG_MODE_NONE) {
228 if (digikeyer == FLDIGI)
229 new_mode = RIG_MODE_USB;
230 else
231 new_mode = RIG_MODE_LSB;
232 }
233 retval = rig_set_mode(my_rig, RIG_VFO_CURR, new_mode,
234 TLF_DEFAULT_PASSBAND);
235
236 if (retval != RIG_OK) {
237 TLF_LOG_WARN("Problem with rig link!");
238 }
239
240 } else if (reqf == RESETRIT) {
241 retval = rig_set_rit(my_rig, RIG_VFO_CURR, 0);
242
243 if (retval != RIG_OK) {
244 TLF_LOG_WARN("Problem with rig link!");
245 }
246
247 } else {
248 // set rig frequency to `reqf'
249 retval = rig_set_freq(my_rig, RIG_VFO_CURR, (freq_t) reqf);
250
251 if (retval != RIG_OK) {
252 TLF_LOG_WARN("Problem with rig link: set frequency!");
253 }
254
255 }
256
257 }
258
259
get_current_seconds()260 static double get_current_seconds() {
261 struct timeval tv;
262 gettimeofday(&tv, NULL);
263 return tv.tv_sec + tv.tv_usec / 1e6;
264 }
265
266
handle_trx_bandswitch(const freq_t freq)267 static void handle_trx_bandswitch(const freq_t freq) {
268
269 send_bandswitch(freq);
270
271 rmode_t mode = RIG_MODE_NONE; // default: no change
272 pbwidth_t width = TLF_DEFAULT_PASSBAND; // passband width, in Hz
273
274 if (trxmode == SSBMODE) {
275 mode = get_ssb_mode();
276 } else if (trxmode == DIGIMODE) {
277 if ((rigmode & (RIG_MODE_LSB | RIG_MODE_USB | RIG_MODE_RTTY | RIG_MODE_RTTYR))
278 != rigmode) {
279 mode = RIG_MODE_LSB;
280 }
281 } else {
282 mode = RIG_MODE_CW;
283 width = get_cw_bandwidth();
284 }
285
286 if (mode == RIG_MODE_NONE) {
287 return; // no change was requested
288 }
289
290 int retval = rig_set_mode(my_rig, RIG_VFO_CURR, mode, width);
291
292 if (retval != RIG_OK) {
293 TLF_LOG_WARN("Problem with rig link!");
294 }
295
296 }
297
298