1
2 // program users_tr.c for CAT control with Linrad
3 // supported transeivers: ELCRAFT K3
4 // ICOM IC-275/IC-706
5 // KENWOOD TS-850/TS-2000
6 // YAESU FT-450/FT-736/FT-817/FT-897/FT-920/FT-950/FT-1000/FT-2000
7 // Runs under Windows and Linux
8 // Based on input from DL3IAE/IK7EZN/K1JT/ON4IY/ON7EH/W3SZ/YO4AUL/NH7O
9 // with the support of Leif SM5BSZ
10 // All errors are mine
11 // Use at your own risk and enjoy
12 // Pierre/ON5GN
13 //
14 // UPDATE HISTORY
15 //
16 // 4 may 2007 first version for linrad 02.31
17 // FT-736 tested by DL3IAE
18 // TS-850 tested by ON7EH
19 // ICOM tested by IK7EZN
20 // 22 july 2008 update for linrad-02.48
21 // added FT-897, tested by YO4AUL and ON4KHG
22 // 23 may 2010 bug correction and documentation updates
23 // 8 july 2010 added FT-920 (NH7O)
24 // 20 july 2010 added FT-817, tested by DL3IAE
25 // changed parameter file (uses now the Linrad standards)
26 // 28 aug 2011 added Elecraft K3 (NH7O)
27 // 4 nov 2013 Initial RTS status in the transceiver structure and
28 // frequency int k changed to double kxx.
29 //
30 // INSTALLATION
31 //
32 // To install under Linux for Linux:
33 // download lirxx-xx.tbz and extract it to your linrad directory
34 // rename users_tr.c to users_hwaredriver.c in your linrad directory
35 // run ./configure and make xlinrad (or make linrad) from your linrad
36 // directory
37 //
38 // To generate a windows version under Linux:
39 // install mingw32 from Leif's website
40 // download lirxx-xx.tbz and extract it to your linrad directory
41 // rename users_tr.c to wusers_hwaredriver.c in your linrad directory
42 // run ./configure and make linrad.exe from your linrad directory
43 //
44 // To generate a windows version under Windows:
45 // Install mingw and nasm from Leif's website in the C:\MinGW directory
46 // Download lirxx-xx.zip and unpack the linrad sources in your linrad
47 // directory
48 // Rename users_tr.c to wusers_hwaredriver.c in your linrad directory
49 // Start a MS-DOS Command Window on your computer: click the Windows Start
50 // menu and enter the "cmd.exe" command into the run box
51 // In the MS-DOS Command Window issue a "cd" command to your linrad directory
52 // followed by a "configure.exe" and "make.bat" command
53 //
54 // USERGUIDE
55 //
56 // Moving the usergraph:
57 // Move the usergraph on the screen by hitting the left side of the graph
58 // with the mousepointer, holding the left mouse button down, and dragging
59 // it to the desired position.
60 //
61 // Setting the VFO frequency:
62 // Select first the transceiver-type with the arrow buttons in the upper
63 // right corner of the usergraph.
64 //
65 // Next select the serial port number with the arrow buttons next to the
66 // SERIAL PORT field:
67 // Under Windows one can select COM1 to COM8.
68 // Under Linux one can select /devttyS0 to /dev/ttyS3
69 // or /dev/ttyUSB0 to /dev/ttyUSB3 for USB-serial devices.
70 // Under BSD one can select /dev/ttyd0 to /dev/ttyd7.
71 //
72 // Enter the values for Offset-raw (Khz) and Offset-fine (Hz) in the
73 // corresponding fields and use the corresponding arrow buttons for fine
74 // tuning. This offset is intended for transverter usage or for the
75 // correction of small frequency offsets between Linrad and the transceiver.
76 //
77 // Select a frequency on the Linrad waterfall graph.
78 // Hit the Q-key to transfer the Linrad frequency, incremented with the
79 // total offset, to the transceiver VFO.
80 //
81 // Note: The graph position, the serial port number, the transceiver-type,
82 // and the offset values for 12 frequency bands are saved in a
83 // parameterfile and retrieved afterwards when Linrad is (re)started.
84 // The file name is "par_xxx_hwd_ug" (with xxx = rx_mode) and its
85 // content can be displayed with an editor.
86 // The frequency bands are defined by the variable bandlim.
87 //
88 // Calibration procedure:
89 // This function sets automatically the values for Offset-raw and Offset-fine
90 // by reading the VFO frequency from the transceiver, calculating the
91 // difference with the Linrad frequency and storing this difference in
92 // the offset variables:
93 //
94 // Tune the TRX receiver and Linrad to the same carrier (zero beat).
95 // Click on the blue 'calibration' box with the mouse.
96 // Hit the Q-key to -read the VFO frequency from the transceiver
97 // -calculate the frequency-offset between Linrad and the
98 // transceiver VFO
99 // -store this offset in Offset-raw and Offset-fine.
100 //
101 // CUSTOMIZATION
102 //
103 // To add support for a new transceiver:
104 // 1.Add an entry to the list of supported transceivers between line 149 and
105 // line 164 with the name of the transceiver, its serial port parameters
106 // and its frequency range. Use the existing lines as examples.
107 // 2.Add the corresponding 'SET VFO' and 'CALIBRATION' code (only a few
108 // lines of coding ) for the new transceiver:
109 // Get the technical specifications for the CAT commands for the new
110 // transceiver and use the existing code for transceivers from the same
111 // transceiver-family as a framework/guideline:
112 // For a new YAESU transceiver p.e. have a look at the code for the
113 // FT-450/FT-950/FT-2000 :
114 // look at lines 1577-1595 for the 'SET VFO' code and lines 1299-1353
115 // for the 'CALIBRATION' code.
116 // The 'CALIBRATION' code is not mandatory. If not present, an error
117 // message will be displayed in the usergraph.
118 //
119 // ****************************************************************************
120 // Change the define for RX_HARDWARE and modify the dummy routines
121 // in the prototype section to fit your needs.
122 // The routines in wse_sdrxx.c can serve as a starting point.
123 #define RX_HARDWARE 0
124 // ****************************************************************************
125
126 #include <string.h>
127
128 int serport_open_status;
129 int serport_number = 1 ;
130 int transceiver_number = 0 ;
131 int chnge_serport_switch =0;
132 int chnge_calibr_switch =0;
133 double offset_hz;
134 double offset_khz;
135 double old_hwfreq;
136
137 #define MAX_NO_OF_TRANSCEIVERS 32
138
139 struct transceiver
140 {
141 char name[16];
142 int serport_baudrate;
143 int serport_stopbits;
144 double min_transceiver_freq;
145 double max_transceiver_freq;
146 int serport_rts_mode;
147 };
148
149 // List of supported transceivers and corresponding values for
150 // serport_baudrate (valid values between 110 and 57600 )
151 // serport_stopbits (0 for one stopbit or 1 for two stopbits )
152 // min and max transceiver_frequency(Hz)
153 // check the transceiver manual to get the correct values
154 const struct transceiver list[MAX_NO_OF_TRANSCEIVERS] =
155 {{"K3 ",38400, 1, 1800000., 54000000., 0},
156 {"FT-450 ", 4800, 1, 30000., 56000000., 0},
157 {"FT-736 ", 4800, 1,144000000., 146000000., 0},
158 {"FT-817 ",38400, 1, 1500000., 470000000., 0},
159 {"FT-897 ",38400, 1, 1500000., 470000000., 0},
160 {"FT-920 ", 4800, 1, 100000., 56000000., 0},
161 {"FT-950 ", 4800, 1, 30000., 56000000., 0},
162 {"FT-1000 ", 4800, 1, 1600000., 30000000., 0},
163 {"FT-2000 ", 4800, 1, 30000., 60000000., 0},
164 {"IC-275 ", 9600, 0,144000000., 146000000., 0},
165 {"ICOM-all ", 9600, 0, 1800000.,2450000000., 0},
166 {"IC-706 ", 9600, 0, 1800000., 148000000., 0},
167 {"IC-706MKII ", 9600, 0, 1800000., 148000000., 0},
168 {"IC-706MKIIG", 9600, 0, 1800000., 148000000., 0},
169 {"TS-850 ", 4800, 1, 1600000., 30000000., 0},
170 {"TS-2000 ", 9600, 0, 1600000., 148000000., 0},
171 {"END LIST ", 0, 0, 0., 0., 0}};
172 // ***************************************************************************
173 // ***************************************************************************
174 // ROUTINES FOR THE PROCESSING OF A 'MOVABLE' FIXED SIZE USERGRAPH
175 // the screenposition of the usergraph and its variables are saved
176 // in the parameterfile "par_xxx_hwd_ug" ( with xxx = rx_mode) in the linrad directory
177 // ****************************************************************************
178 // ****************************************************************************
179
180 #define MAX_HWAREDRIVER_PARM 28
181
182 char *users_hwaredriver_parm_text[MAX_HWAREDRIVER_PARM]={
183 "ug_xleft ",
184 "ug_ytop ",
185 "serport_number ",
186 "transceiver_number ",
187 "offs_hz_band_0-2.5 ",
188 "offs_hz_band_2.5-5 ",
189 "offs_hz_band_5-9 ",
190 "offs_hz_band_9-12 ",
191 "offs_hz_band_12-16 ",
192 "offs_hz_band_16-19 ",
193 "offs_hz_band_19-23 ",
194 "offs_hz_band_23-26 ",
195 "offs_hz_band_26-40 ",
196 "offs_hz_band_40-100 ",
197 "offs_hz_band_100-300 ",
198 "offs_hz_band_BIG ",
199 "offs_khz_band_0-2.5 ",
200 "offs_khz_band_2.5-5 ",
201 "offs_khz_band_5-9 ",
202 "offs_khz_band_9-12 ",
203 "offs_khz_band_12-16 ",
204 "offs_khz_band_16-19 ",
205 "offs_khz_band_19-23 ",
206 "offs_khz_band_23-26 ",
207 "offs_khz_band_26-40 ",
208 "offs_khz_band_40-100 ",
209 "offs_khz_band_100-300",
210 "offs_khz_band_BIG ",
211 };
212
213 #define NO_OF_BANDS 12
214 float bandlim[]={2.5, //0
215 5.0, //1
216 9.0, //2
217 12.0, //3
218 16.0, //4
219 19.0, //5
220 23.0, //6
221 26.0, //7
222 40.0, //8
223 100.0, //9
224 300.0, //10
225 BIG}; //11
226
227 typedef struct {
228 int ug_xleft;
229 int ug_ytop;
230 int serport_number;
231 int transceiver_number;
232 int offs_hz[NO_OF_BANDS];
233 int offs_khz[NO_OF_BANDS];
234 } HWAREDRIVER_PARMS;
235 HWAREDRIVER_PARMS hwaredriver;
236
237 #define USERS_GRAPH_TYPE1 64
238 typedef struct {
239 int ytop;
240 int ybottom;
241 int xleft;
242 int xright;
243 int yborder; // required for move graph
244 } UG_PARMS;
245 UG_PARMS ug;
246
247 #define UG_TOP 0
248 #define UG_BOTTOM 1
249 #define UG_LEFT 2
250 #define UG_RIGHT 3
251 #define UG_INCREASE_OFFS_HZ 4
252 #define UG_DECREASE_OFFS_HZ 5
253 #define UG_INCREASE_OFFS_KHZ 6
254 #define UG_DECREASE_OFFS_KHZ 7
255 #define UG_INCREASE_SERPORT_NMBR 8
256 #define UG_DECREASE_SERPORT_NMBR 9
257 #define UG_INCREASE_TRANSCEIVER_NMBR 10
258 #define UG_DECREASE_TRANSCEIVER_NMBR 11
259 #define MAX_UGBUTT 12
260
261 BUTTONS ugbutt[MAX_UGBUTT];
262
263 int ug_old_y1;
264 int ug_old_y2;
265 int ug_old_x1;
266 int ug_old_x2;
267 int users_graph_scro;
268
269 int ug_oldx; // required for move graph
270 int ug_oldy; // required for move graph
271 int ug_yborder; // required for move graph
272 int ug_hsiz; // required for move graph
273 int ug_vsiz; // required for move graph
274
275 int ug_band_no;
276
277 #define MAX_MSGSIZE 30 //Size of messages. min size=30
278 char ug_msg0[MAX_MSGSIZE]; //messages in usergraph
279 char ug_msg1[MAX_MSGSIZE];
280 char ug_msg2[MAX_MSGSIZE];
281 int ug_msg_color; //switch for message-color in usergraph
282 double min_transceiver_freq=0;
283 double max_transceiver_freq=0;
284
set_press_q_key_new_freq_msg(void)285 void set_press_q_key_new_freq_msg(void)
286 {
287 ug_msg_color=14;
288 strcpy(ug_msg0,"PRESS Q-KEY TO SET TRX FREQ.");
289 ug_msg1[0]=0;
290 ug_msg2[0]=0;
291 }
292
set_press_q_key_chnge_port_msg(void)293 void set_press_q_key_chnge_port_msg(void)
294 {
295 //change the name of the serial port
296 char s[80];
297 if (strncmp(serport_name,"COM",3)==0)
298 // this is windows
299 {
300 sprintf(&serport_name[3],"%d",serport_number);
301 }
302 if (strncmp(serport_name,"/dev/ttyd",9)==0)
303 //this is BSD
304 {
305 sprintf(&serport_name[9],"%d",serport_number-1);
306 }
307 if (strncmp(serport_name,"/dev/ttyS",9)==0)
308 // this is linux
309 // use either /dev/ttyS0 to /dev/ttyS3
310 // or /dev/ttyUSB0 to /dev/ttyUSB3
311 {
312 if (serport_number <= 4) //
313 {
314 sprintf(&serport_name[9],"%d",serport_number-1);
315 }
316 else //
317 {
318 sprintf(&serport_name[0],"%s","/dev/ttyUSB");
319 sprintf(&serport_name[11],"%d",serport_number-5);
320 }
321 }
322 if (strncmp(serport_name,"/dev/ttyUSB",11)==0)
323 // this is linux
324 // use either /dev/ttyS0 to /dev/ttyS3
325 // or /dev/ttyUSB0 to /dev/ttyUSB3
326 {
327 if (serport_number > 4)
328 {
329 sprintf(&serport_name[11],"%d",serport_number-5);
330 }
331 else
332 {
333 sprintf(&serport_name[0],"%s","/dev/ttyS");
334 sprintf(&serport_name[9],"%d",serport_number-1);
335 }
336 }
337 sprintf(s," SERIAL PORT:%s ",serport_name);
338 lir_pixwrite(ug.xleft+.5*text_width,ug.ytop+1.5*text_height,s);
339 ug_msg_color=15;
340 strcpy(ug_msg0,"PRESS Q-KEY TO OPEN SER. PORT");
341 ug_msg1[0]=0;
342 ug_msg2[0]=0;
343 chnge_serport_switch=1;
344 }
345
check_ug_borders(void)346 void check_ug_borders(void) // required for move graph
347 {
348 current_graph_minh=ug_vsiz;
349 current_graph_minw=ug_hsiz;
350 check_graph_placement((void*)(&ug));
351 set_graph_minwidth((void*)(&ug));
352 }
353
users_show_offset(void)354 void users_show_offset(void)
355 {
356 char s[80];
357 settextcolor(15);
358 sprintf(s,"Offset-fine(Hz): %d ",hwaredriver.offs_hz[ug_band_no]);
359 s[25]=0;
360 lir_pixwrite(ug.xleft+1.5*text_width,ug.ytop+1+3.5*text_height,s);
361 sprintf(s,"Offset-raw(Khz): %d ",hwaredriver.offs_khz[ug_band_no]);
362 s[25]=0;
363 lir_pixwrite(ug.xleft+1.5*text_width,ug.ytop+2.5*text_height,s);
364 settextcolor(7);
365 offset_hz= hwaredriver.offs_hz[ug_band_no];
366 offset_khz=hwaredriver.offs_khz[ug_band_no];
367 }
368
blankfill_ugmsg(char * msg)369 void blankfill_ugmsg(char *msg)
370 {
371 int i;
372 i=strlen(msg);
373 if(i>=MAX_MSGSIZE)lirerr(3413400);
374 while(i<MAX_MSGSIZE-1)
375 {
376 msg[i]=' ';
377 i++;
378 }
379 msg[MAX_MSGSIZE-1]=0;
380 }
381
show_user_parms(void)382 void show_user_parms(void)
383 {
384 int i;
385 char s[80];
386 extern char serport_name[14];
387 // Show the user parameters on screen
388 // and issue hardware commands if required.
389 // Use hware_flag to direct calls to control_hware() when cpu time
390 // is available in case whatever you want to do takes too much time
391 // to be done immediately.
392 // Note that mouse control is done in the narrowband processing thread
393 // and that you can not use lir_sleep to wait for hardware response here.
394 hide_mouse(ug.xleft, ug.xright,ug.ytop,ug.ybottom);
395 sprintf(s,"CALIBRATE");
396 settextcolor(11);
397 lir_pixwrite(ug.xleft+.5*text_width,ug.ytop+0.35*text_height,s);
398 sprintf(s," CAT FREQUENCY CONTROL FOR TRX: %s ",list[transceiver_number].name);
399 settextcolor(14);
400 lir_pixwrite(ug.xleft+10.5*text_width,ug.ytop+0.35*text_height,s);
401 settextcolor(15);
402 sprintf(s," SERIAL PORT:%s ",serport_name);
403 lir_pixwrite(ug.xleft+.5*text_width,ug.ytop+1.5*text_height,s);
404
405 settextcolor(7);
406 users_show_offset();
407
408 //DISPLAY MESSAGES IN MESSAGE-AREA OF USERGRAPH
409
410 // Fill message with blanks up to character MAX_MSGSIZE-2
411 blankfill_ugmsg(ug_msg0);
412 blankfill_ugmsg(ug_msg1);
413 blankfill_ugmsg(ug_msg2);
414 settextcolor(ug_msg_color);
415 lir_pixwrite(ug.xleft+31*text_width,ug.ytop+1.5*text_height,ug_msg0);
416 lir_pixwrite(ug.xleft+31*text_width,ug.ytop+2.5*text_height,ug_msg1);
417 lir_pixwrite(ug.xleft+31*text_width,ug.ytop+3.5*text_height,ug_msg2);
418 settextcolor(7);
419
420 // save screenposition, serport_number, transceiver_number and offset-values
421 // to the parameterfile on disk
422
423 char hwaredriver_parfil_name[20];
424 sprintf(hwaredriver_parfil_name,"%s_hwd_ug",rxpar_filenames[rx_mode]);
425 FILE *hwaredriver_file;
426 int *sdr_pi;
427 hwaredriver_file=fopen(hwaredriver_parfil_name,"w");
428 hwaredriver.ug_xleft=ug.xleft;
429 hwaredriver.ug_ytop=ug.ytop;
430 hwaredriver.serport_number=serport_number;
431 hwaredriver.transceiver_number=transceiver_number;
432 sdr_pi=(int*)(&hwaredriver);
433 for(i=0; i<MAX_HWAREDRIVER_PARM; i++)
434 {
435 fprintf(hwaredriver_file,"%s [%d]\n",users_hwaredriver_parm_text[i],sdr_pi[i]);
436 }
437 parfile_end(hwaredriver_file);
438 }
439
users_set_band_no(void)440 void users_set_band_no(void)
441 {
442 ug_band_no=0;
443 while(bandlim[ug_band_no] < fg.passband_center)ug_band_no++;
444 if(all_threads_started == TRUE)
445 {
446 pause_thread(THREAD_SCREEN);
447 set_press_q_key_new_freq_msg();
448 show_user_parms();
449 resume_thread(THREAD_SCREEN);
450 }
451 }
452
make_users_control_graph(void)453 void make_users_control_graph(void)
454 {
455 pause_thread(THREAD_SCREEN);
456 // Set a negative number here.
457 // In case several windows are desired, give them different
458 // negative numbers and use scro[m].no to decide what to do
459 // in your mouse_on_users_graph routine.
460 check_ug_borders(); // required for move graph
461 scro[users_graph_scro].no=USERS_GRAPH_TYPE1;
462 // These are the coordinates of the border lines.
463 scro[users_graph_scro].x1=ug.xleft;
464 scro[users_graph_scro].x2=ug.xright;
465 scro[users_graph_scro].y1=ug.ytop;
466 scro[users_graph_scro].y2=ug.ybottom;
467 // Each border line is treated as a button.
468 // That is for the mouse to get hold of them so the window can be moved.
469 ugbutt[UG_LEFT].x1=ug.xleft;
470 ugbutt[UG_LEFT].x2=ug.xleft+2;
471 ugbutt[UG_LEFT].y1=ug.ytop;
472 ugbutt[UG_LEFT].y2=ug.ybottom;
473 ugbutt[UG_RIGHT].x1=ug.xright;
474 ugbutt[UG_RIGHT].x2=ug.xright-2;
475 ugbutt[UG_RIGHT].y1=ug.ytop;
476 ugbutt[UG_RIGHT].y2=ug.ybottom;
477 ugbutt[UG_TOP].x1=ug.xleft;
478 ugbutt[UG_TOP].x2=ug.xright;
479 ugbutt[UG_TOP].y1=ug.ytop;
480 ugbutt[UG_TOP].y2=ug.ytop+2;
481 ugbutt[UG_BOTTOM].x1=ug.xleft;
482 ugbutt[UG_BOTTOM].x2=ug.xright;
483 ugbutt[UG_BOTTOM].y1=ug.ybottom;
484 ugbutt[UG_BOTTOM].y2=ug.ybottom-2;
485 // Draw the border lines
486 graph_borders((void*)&ug,7);
487 ug_oldx=-10000; //from freq_control
488 settextcolor(7);
489 make_button(ug.xleft+27.5*text_width+2,ug.ybottom-1*text_height/2-1,
490 ugbutt,UG_DECREASE_OFFS_HZ,25);
491 make_button(ug.xleft+29*text_width+2,ug.ybottom-1*text_height/2-1,
492 ugbutt,UG_INCREASE_OFFS_HZ,24);
493
494 make_button(ug.xleft+27.5*text_width+2,ug.ybottom-3*text_height/2-1,
495 ugbutt,UG_DECREASE_OFFS_KHZ,25);
496 make_button(ug.xleft+29*text_width+2,ug.ybottom-3*text_height/2-1,
497 ugbutt,UG_INCREASE_OFFS_KHZ,24);
498
499 make_button(ug.xleft+27.5*text_width+2,ug.ybottom-5*text_height/2-1,
500 ugbutt,UG_DECREASE_SERPORT_NMBR,25);
501 make_button(ug.xleft+29*text_width+2,ug.ybottom-5*text_height/2-1,
502 ugbutt,UG_INCREASE_SERPORT_NMBR,24);
503
504 make_button(ug.xleft+57.5*text_width+2,ug.ytop+1.5*text_height/2-1,
505 ugbutt,UG_DECREASE_TRANSCEIVER_NMBR,25);
506 make_button(ug.xleft+59*text_width+2,ug.ytop+1.5*text_height/2-1,
507 ugbutt,UG_INCREASE_TRANSCEIVER_NMBR,24);
508 show_user_parms();
509 //draw separatorlines in usergraph
510 //vertical
511 lir_line(ug.xleft+30.5*text_width,ug.ytop+1.3*text_height,ug.xleft+30.5*text_width,ug.ybottom,7);
512 lir_line(ug.xleft+10*text_width,ug.ytop+0*text_height,ug.xleft+10*text_width,ug.ytop+1.3*text_height,7);
513 //horizontal
514 lir_line(ug.xleft,ug.ytop+1.3*text_height,ug.xright,ug.ytop+1.3*text_height,7);
515 //
516 resume_thread(THREAD_SCREEN);
517 }
518
mouse_continue_users_graph(void)519 void mouse_continue_users_graph(void)
520 {
521 int i, j; // required for move graph
522 switch (mouse_active_flag-1)
523 {
524 // Move border lines immediately.
525 // for other functions, wait until button is released.
526 // Move fixed size window based on coding in freq_control.c
527 case UG_TOP:
528 if(ug.ytop!=mouse_y)goto ugm;
529 break;
530
531 case UG_BOTTOM:
532 if(ug.ybottom!=mouse_y)goto ugm;
533 break;
534
535 case UG_LEFT:
536 if(ug.xleft!=mouse_x)goto ugm;
537 break;
538
539 case UG_RIGHT:
540 if(ug.xright==mouse_x)break;
541 ugm:;
542 pause_screen_and_hide_mouse();
543 graph_borders((void*)&ug,0);
544 if(ug_oldx==-10000)
545 {
546 ug_oldx=mouse_x;
547 ug_oldy=mouse_y;
548 }
549 else
550 {
551 i=mouse_x-ug_oldx;
552 j=mouse_y-ug_oldy;
553 ug_oldx=mouse_x;
554 ug_oldy=mouse_y;
555 ug.ytop+=j;
556 ug.ybottom+=j;
557 ug.xleft+=i;
558 ug.xright+=i;
559 check_ug_borders();
560 ug.yborder=(ug.ytop+ug.ybottom)>>1;
561 }
562 graph_borders((void*)&ug,15);
563 resume_thread(THREAD_SCREEN);
564 break;
565
566 default:
567 goto await_release;
568 }
569 if(leftpressed == BUTTON_RELEASED)goto finish;
570 return;
571 await_release:;
572 if(leftpressed != BUTTON_RELEASED) return;
573 // Assuming the user wants to control hardware we
574 // allow commands only when data is not over the network.
575 if((ui.network_flag&NET_RX_INPUT) == 0) //for linrad02.23
576 {
577 switch (mouse_active_flag-1)
578 {
579 case UG_INCREASE_OFFS_HZ:
580 hwaredriver.offs_hz[ug_band_no]++;
581 set_press_q_key_new_freq_msg();
582 show_user_parms();
583 break;
584
585 case UG_DECREASE_OFFS_HZ:
586 hwaredriver.offs_hz[ug_band_no]--;
587 set_press_q_key_new_freq_msg();
588 show_user_parms();
589 break;
590
591 case UG_INCREASE_OFFS_KHZ:
592 hwaredriver.offs_khz[ug_band_no]++;
593 set_press_q_key_new_freq_msg();
594 show_user_parms();
595 break;
596
597 case UG_DECREASE_OFFS_KHZ:
598 hwaredriver.offs_khz[ug_band_no]--;
599 set_press_q_key_new_freq_msg();
600 show_user_parms();
601 break;
602
603 case UG_INCREASE_SERPORT_NMBR:
604 serport_number++;
605 if (serport_number >= 8) serport_number =8;
606 set_press_q_key_chnge_port_msg();
607 show_user_parms();
608 break;
609
610 case UG_DECREASE_SERPORT_NMBR:
611 serport_number--;
612 if (serport_number <= 1) serport_number =1;
613 set_press_q_key_chnge_port_msg();
614 show_user_parms();
615 break;
616
617 case UG_INCREASE_TRANSCEIVER_NMBR:
618 transceiver_number++;
619 if ((strcmp(list[transceiver_number].name,"END LIST ")==0))
620 transceiver_number--;
621 set_press_q_key_new_freq_msg();
622 show_user_parms();
623 break;
624
625 case UG_DECREASE_TRANSCEIVER_NMBR:
626 transceiver_number--;
627 if (transceiver_number <= 0) transceiver_number =0;
628 set_press_q_key_new_freq_msg();
629 show_user_parms();
630 break;
631
632 default:
633 // This should never happen.
634 lirerr(211053);
635 break;
636 }
637 }
638 finish:;
639 hide_mouse(ug_old_x1,ug_old_x2,ug_old_y1,ug_old_y2);
640 leftpressed=BUTTON_IDLE;
641 mouse_active_flag=0;
642 graph_borders((void*)&ug,0);
643 lir_fillbox(ug_old_x1,ug_old_y1,ug_old_x2-ug_old_x1,ug_old_y2-ug_old_y1,0);
644 make_users_control_graph();
645 ug_oldx=-10000;
646 }
647
new_user_offs_hz(void)648 void new_user_offs_hz(void)
649 {
650 hwaredriver.offs_hz[ug_band_no]=numinput_int_data;
651 pause_thread(THREAD_SCREEN);
652 set_press_q_key_new_freq_msg();
653 show_user_parms();
654 resume_thread(THREAD_SCREEN);
655 }
656
users_new_user_offs_khz(void)657 void users_new_user_offs_khz(void)
658 {
659 hwaredriver.offs_khz[ug_band_no]=numinput_float_data;
660 pause_thread(THREAD_SCREEN);
661 set_press_q_key_new_freq_msg();
662 show_user_parms();
663 resume_thread(THREAD_SCREEN);
664 }
665
mouse_on_users_graph(void)666 void mouse_on_users_graph(void)
667 {
668 int event_no;
669 // First find out if we are on a button or border line.
670 for(event_no=0; event_no<MAX_UGBUTT; event_no++)
671 {
672 if( ugbutt[event_no].x1 <= mouse_x &&
673 ugbutt[event_no].x2 >= mouse_x &&
674 ugbutt[event_no].y1 <= mouse_y &&
675 ugbutt[event_no].y2 >= mouse_y)
676 {
677 ug_old_y1=ug.ytop;
678 ug_old_y2=ug.ybottom;
679 ug_old_x1=ug.xleft;
680 ug_old_x2=ug.xright;
681 mouse_active_flag=1+event_no;
682 current_mouse_activity=mouse_continue_users_graph;
683 return;
684 }
685 }
686 // Not button or border.
687 // Prompt the user for offs_hz or offs_khz depending on whether the mouse is
688 // in the upper or the lower part of the window.
689 mouse_active_flag=1;
690 numinput_xpix=ug.xleft+18.5*text_width;
691 if(mouse_x > ug.xleft && mouse_x < ug.xleft+10*text_width)
692 {
693 if(mouse_y > ug.ytop && mouse_y < (ug.ytop+1.3*text_height))
694 {
695 ug_msg_color=11;
696 strcpy(ug_msg0,"PRESS Q-KEY TO CALIBRATE");
697 ug_msg1[0]=0;
698 ug_msg2[0]=0;
699 chnge_calibr_switch=1;
700 show_user_parms();
701 }
702 }
703 if(mouse_x > ug.xleft+18.5*text_width && mouse_x < ug.xleft+25*text_width)
704 {
705 if(mouse_y > (ug.ytop+3.8*text_height))
706 {
707 numinput_ypix=ug.ytop+3.6*text_height;
708 numinput_chars=4;
709 erase_numinput_txt();
710 numinput_flag=FIXED_INT_PARM;
711 par_from_keyboard_routine=new_user_offs_hz; //offset-fine
712
713 }
714 else
715 {
716 numinput_ypix=ug.ytop+(2.4*text_height)+1;
717 numinput_chars=7;
718 erase_numinput_txt();
719 numinput_flag=FIXED_FLOAT_PARM;
720 par_from_keyboard_routine=users_new_user_offs_khz; //offset-raw
721 }
722 }
723 else
724 {
725 // If we did not select a numeric input by setting numinput_flag
726 // we have to set mouse_active flag.
727 // Set the routine to mouse_nothing, we just want to
728 // set flags when the mouse button is released.
729 current_mouse_activity=mouse_nothing;
730 mouse_active_flag=1;
731 }
732 }
733
init_users_control_window(void)734 void init_users_control_window(void)
735 {
736 int i;
737 // Get values from parameterfile
738 int errcod;
739 char hwaredriver_parfil_name[20];
740 sprintf(hwaredriver_parfil_name,"%s_hwd_ug",rxpar_filenames[rx_mode]);
741 errcod=read_sdrpar(hwaredriver_parfil_name, MAX_HWAREDRIVER_PARM,
742 users_hwaredriver_parm_text, (int*)((void*)&hwaredriver));
743 if (errcod != 0)
744 {
745 FILE *hwaredriver_file;
746 int *sdr_pi;
747 hwaredriver_file=fopen(hwaredriver_parfil_name,"w");
748 //set_default_parameter values
749 hwaredriver.ug_xleft=60*text_width;
750 hwaredriver.ug_ytop=(screen_last_line-4)*text_height;
751 hwaredriver.serport_number=1;
752 hwaredriver.transceiver_number=0;
753 for(i=0; i<NO_OF_BANDS; i++)
754 {
755 hwaredriver.offs_hz[i]=0;
756 hwaredriver.offs_khz[i]=0;
757 }
758 sdr_pi=(int*)(&hwaredriver);
759 for(i=0; i<MAX_HWAREDRIVER_PARM; i++)
760 {
761 fprintf(hwaredriver_file,"%s [%d]\n",users_hwaredriver_parm_text[i],sdr_pi[i]);
762 }
763 parfile_end(hwaredriver_file);
764 }
765 ug.xleft=hwaredriver.ug_xleft;
766 ug.ytop=hwaredriver.ug_ytop;
767 serport_number=hwaredriver.serport_number;
768 transceiver_number=hwaredriver.transceiver_number;
769
770 //trace
771 //printf("\n serport_number %i\n",serport_number);
772 lir_close_serport();
773 // 1=COM1 or /dev/ttyS0 , 2=COM2....
774 // baudrate 110 to 57600
775 // 1=two stopbits, 0=one stopbit
776 serport_open_status=lir_open_serport(serport_number,
777 list[transceiver_number].serport_baudrate,
778 list[transceiver_number].serport_stopbits,
779 list[transceiver_number].serport_rts_mode);
780 set_press_q_key_new_freq_msg();
781 ug_hsiz=(30+MAX_MSGSIZE)*text_width; // WIDTH OF USERGRAPH
782 ug_vsiz=(4.8*text_height); // HEIGHT OF USERGRAPH
783 ug.xright=ug.xleft+ug_hsiz;
784 ug.ybottom= ug.ytop+ug_vsiz;
785 if(rx_mode < MODE_TXTEST)
786 {
787 users_graph_scro=no_of_scro;
788 make_users_control_graph();
789 no_of_scro++;
790 if(no_of_scro >= MAX_SCRO)lirerr(89);
791 }
792 }
793
users_init_mode(void)794 void users_init_mode(void)
795 {
796 // A switch statement can be used to do different things depending on
797 // the processing mode.
798 //switch (rx_mode)
799 // {
800 // case MODE_WCW:
801 // case MODE_HSMS:
802 // case MODE_QRSS:
803 // break;
804 // case MODE_NCW:
805 // case MODE_SSB:
806 // Open a window to allow mouse control of your own things
807 init_users_control_window();
808 // break;
809 // case MODE_FM:
810 // case MODE_AM:
811 // case MODE_TXTEST:
812 // case MODE_RX_ADTEST:
813 // case MODE_TUNE:
814 // break;
815 // }
816 }
817 // ***************************************************************************
818 // END ROUTINES FOR THE PROCESSING OF A 'MOVABLE' FIXED SIZE USERGRAPH
819 // ***************************************************************************
820
users_eme(void)821 void users_eme(void)
822 {
823 }
824
userdefined_u(void)825 void userdefined_u(void)
826 {
827 }
828
edit_ugmsg(char * s,double fq)829 void edit_ugmsg(char *s, double fq)
830 {
831 //edit frequency information
832 double t1;
833 int i, j, k, l,m;
834 // We are called with a frequency in Hz and already something written
835 // in the msg string. Find out how many characters we have at our disposal.
836 j=strlen(s);
837 i=MAX_MSGSIZE-j-3;
838 // We will insert separators for each group of 3 digits so we loose i/3
839 // positions.
840 i-=i/3;
841 // Find out the largest fq we can write in Hz.
842 // Write in kHz if fq is above the limit.
843 t1=i;
844 t1=pow(10.0,t1)-1;
845 if(fabs(fq) < t1)
846 {
847 sprintf (&s[j],"%.0f Hz",fq);
848 }
849 else
850 {
851 sprintf(&s[j],"%.0f kHz",fq/1000);
852 }
853 // Locate the blank in front of Hz or kHz.
854 i=strlen(s);
855 k=i;
856 while(s[i] != ' ')i--;
857 // Insert a separator for every 3 digits.
858 i--;
859 j=0;
860 while(s[i-1] != ' ' && s[i-1] != '-')
861 {
862 j++;
863 if(j==3)
864 {
865 k++;
866 m=k;
867 while(m > i)
868 {
869 s[m]=s[m-1];
870 m--;
871 }
872 s[i]=39;
873 j=0;
874 }
875 i--;
876 }
877 // Align frequency information to the right
878 j=MAX_MSGSIZE-1;
879 i=strlen(s);
880 for (l=i; l<=j;l++) s[l]='\x0';
881 k=j;
882 while(s[k] != 'z')k--;
883 if (k!=j-1){
884 m=j;
885 while(s[m] != '=')m--;
886 j--;
887 for (i=k; i > m; i--) {
888 s[j] = s[i];
889 s[i] = 32;
890 j--;
891 }
892 for (i=j; i > m; i--) {
893 s[i] = 32;
894 j--;
895 }
896 }
897 }
898
users_close_devices(void)899 void users_close_devices(void)
900 {
901 lir_close_serport();
902 //trace
903 //printf("\n serport closed\n");
904 }
905
users_open_devices(void)906 void users_open_devices(void)
907 {
908 // open selected serial port with the parameters defined in transceiver list
909 // 1=COM1 or /dev/ttyS0 , 2=COM2..,4=COM4 or /dev/ttyUSB0...
910 // baudrate 110 to 57600
911 // 1=two stopbits, 0=one stopbit
912 serport_open_status=lir_open_serport(serport_number ,
913 list[transceiver_number].serport_baudrate,
914 list[transceiver_number].serport_stopbits,
915 list[transceiver_number].serport_rts_mode);
916 //trace to screen
917 //printf("\n serport open:stat%i,nbr%i,baud%i,stopb%i\n",serport_open_status,serport_number,list
918 //[transceiver_number].serport_baudrate,
919 // list[transceiver_number].serport_stopbits );
920 }
921
userdefined_q(void)922 void userdefined_q(void)
923 {
924 // ****************************************************************************
925 // ****************************************************************************
926 // THIS ROUTINE IS CALLED EACH TIME THE 'Q' KEY IS PRESSED
927 // The processing is selected based on the following switch-values:
928 // if(chnge_serport_switch==1)
929 // then the new name of the serial port is displayed on the usergraph
930 // and the port is opened
931 // if(chnge_calibr_switch==1)
932 // then a "CALIBRATION REQUEST" is processed
933 // else a "SET VFO" request is processed
934 // ****************************************************************************
935 // ****************************************************************************
936 double transceiver_freq;
937 double offset_hwfreq;
938 unsigned long freq;
939 double transverter_offset_raw; //raw offset in Khz (for tranverter)
940 double transverter_offset_fine; //fine offset in Hz (for transverter)
941 extern char serport_name[14];
942 unsigned char a;
943 int n=-1;
944 int i, j;
945 double kxx;
946 char s[80];
947
948 void analyze_serport_error (void)
949 {
950 ug_msg_color=12;
951 sprintf (ug_msg0,"SERIAL PORT ERROR :");
952 switch (serport_open_status )
953 {
954 case 1244:
955 sprintf (ug_msg1,"OPEN FAILED (%i)",serport_open_status);
956 break;
957 case 1277:
958 sprintf (ug_msg1,"GET OPTIONS FAILED (%i)",serport_open_status);
959 break;
960 case 1278:
961 sprintf (ug_msg1,"SET OPTIONS FAILED (%i)",serport_open_status);
962 break;
963 case 1279:
964 sprintf (ug_msg1,"ILLEGAL PORT NUMBER (%i)",serport_open_status);
965 break;
966 case 1280:
967 sprintf (ug_msg1,"ILLEGAL BAUDRATE (%i)",serport_open_status);
968 break;
969 default:
970 sprintf (ug_msg1,"UNKNOWN ERR CODE (%i)",serport_open_status);
971 }
972 }
973
974 if(chnge_serport_switch==1)
975 // ****************************************************************************
976 // ****************************************************************************
977 // ROUTINE FOR THE PROCESSING OF A CHANGE REQUEST FOR THE SERIAL PORT
978 // ****************************************************************************
979 // ****************************************************************************
980 {
981 chnge_serport_switch=0;
982 sprintf(s," SERIAL PORT:%s ",serport_name);
983 lir_pixwrite(ug.xleft+.5*text_width,ug.ytop+1.5*text_height,s);
984 users_close_devices();
985 users_open_devices();
986 //check status serial port
987 if ( serport_open_status!=0)
988 {
989 analyze_serport_error ();
990 }
991 else
992 {
993 ug_msg_color=15;
994 sprintf (ug_msg0,"SERIAL PORT OPEN OK");
995 sprintf (ug_msg1,"PRESS Q-KEY TO SET TRX FREQ.");
996 }
997 goto userdefined_q_exit_1;
998 }
999
1000 // ****************************************************************************
1001 // ****************************************************************************
1002 // ROUTINES FOR THE PROCESSING OF A "CALIBRATION REQUEST":
1003 // -validate and initialize
1004 // - select and execute the transceiver-dependent routine:
1005 // - create the CAT command message strings for reading the VFO
1006 // - write/read the message strings to/from serial port
1007 // - calculate the offset between VFO frequency and Linrad freq
1008 // - display this offset on the usergraph
1009 // ****************************************************************************
1010 // ****************************************************************************
1011 // generic routines for calibration:
1012 void calculate_offset(void)
1013 {
1014 transceiver_freq=kxx;
1015 offset_hwfreq=transceiver_freq-(hwfreq*1000);
1016 transverter_offset_raw=floor(offset_hwfreq/1000);
1017 transverter_offset_fine=ceil(offset_hwfreq-transverter_offset_raw*1000);
1018 hwaredriver.offs_khz[ug_band_no]=transverter_offset_raw;
1019 hwaredriver.offs_hz[ug_band_no]=transverter_offset_fine;
1020 ug_msg_color=11;
1021 sprintf (ug_msg0,"TRX VFO FREQ:%.0f",kxx);
1022 sprintf (ug_msg1,"NEW OFFSET VALUES LOADED");
1023 sprintf (ug_msg2,"PRESS Q-KEY TO SET TRX FREQ.");
1024 }
1025
1026 void fail_message_1(void)
1027 {ug_msg_color=12;
1028 sprintf (ug_msg0,"CALIBRATION FAILED:");
1029 sprintf (ug_msg1,"WRITE TO SERIAL PORT FAILED");
1030 sprintf (ug_msg2,"PRESS Q-KEY TO SET TRX FREQ.");
1031 }
1032
1033 void fail_message_2(void)
1034 {ug_msg_color=12;
1035 sprintf (ug_msg0,"CALIBRATION FAILED:");
1036 sprintf (ug_msg1,"READ FROM SERIAL PORT FAILED");
1037 sprintf (ug_msg2,"PRESS Q-KEY TO SET TRX FREQ.");
1038 }
1039
1040 void fail_message_3(void)
1041 {ug_msg_color=12;
1042 sprintf (ug_msg0,"CALIBRATION FAILED:");
1043 sprintf (ug_msg1,"TRX VFO FREQ = 0");
1044 sprintf (ug_msg2,"PRESS Q-KEY TO SET TRX FREQ.");
1045 }
1046
1047 //check the calibration-request switch
1048 if(chnge_calibr_switch==1)
1049 {
1050 chnge_calibr_switch=0;
1051
1052 //VALIDATE and INITIALIZE:
1053 // exit if no linrad-frequency selected
1054 if(mix1_selfreq[0] < 0)
1055 {
1056 ug_msg_color=12;
1057 sprintf (ug_msg0,"NO FREQ. SELECT. ON W/F GRAPH");
1058 goto userdefined_q_exit_1;
1059 }
1060 // flush buffers
1061 users_close_devices();
1062 users_open_devices();
1063
1064 // SELECT and execute transceiver-dependent routines for calibration:
1065
1066 // ************************ CAL FT-817 and FT-897 ***********************************
1067 if (((strcmp(list[transceiver_number].name,"FT-817 ")==0))
1068 |((strcmp(list[transceiver_number].name,"FT-897 ")==0)))
1069 {
1070 // write delay in msec between two bytes
1071 int write_delay =10;
1072 // CAT command for getting the vfo freq:
1073 unsigned char getfreq_cmnd[5]= { 0x00, 0x00, 0x00, 0x00, 0x03};
1074 // WRITE CAT command to the serial port
1075 unsigned char cat_cmnd[5];
1076 int write_cat_cmnd(void)
1077 {
1078 int r;
1079 for (i=0;i<5;i=i+1)
1080 {
1081 r=lir_write_serport((char*)&cat_cmnd[i],1);
1082 if (r<0) return -1;
1083 // printf("\n %#4.2x ",cat_cmnd[i]); //trace output to screen
1084 lir_sleep(write_delay*1000);
1085 }
1086 return 0;
1087 }
1088 memcpy(cat_cmnd,getfreq_cmnd, 5);
1089 n=write_cat_cmnd();
1090 if (n<0)
1091 {
1092 // write to serial port failed
1093 fail_message_1();
1094 goto userdefined_q_exit_1;
1095 }
1096 // READ the vfo freq
1097 unsigned char ft897_zero[5]= {0x0000000000};
1098 memcpy(s,ft897_zero, 5);
1099 n=lir_read_serport(s,5);
1100 // ANALYSE and process returned values
1101 if (n==5)
1102 {
1103 // s holds now the vfo frequency encoded as
1104 // 0x43 0x97 0x00 0x00 0xNN for a frequency of 439.700.000,00 MHz
1105 // last byte, xNN, is the mode (usb,lsb,..) and will be discarded
1106 // convert now pos 0 to 3 in s, from packed bcd to double kxx
1107 kxx=0;
1108 j=10;
1109 for (i=3; i >-1; i--)
1110 {
1111 a=(s[i]%16 & 0x0f);
1112 kxx= kxx+a*j;
1113 j=j*10;
1114 a= ((s[i]>>4)%16) & 0x0f;
1115 kxx= kxx+a*j;
1116 j=j*10;
1117 }
1118 if (kxx==0)
1119 {
1120 // failure: trx vfo freq = 0
1121 fail_message_3();
1122 goto userdefined_q_exit_1;
1123 }
1124 else
1125 {
1126 // success
1127 calculate_offset();
1128 goto userdefined_q_exit_1;
1129 }
1130 }
1131 else
1132 {
1133 // failure: read from serial port failed
1134 fail_message_2();
1135 goto userdefined_q_exit_1;
1136 }
1137 }
1138 // ************************CAL FT-920 ****************************************
1139 if ((strcmp(list[transceiver_number].name,"FT-920 ")==0))
1140 {
1141 // CAT command definition for getting the frequency of VFO A & B
1142 // (it returns 2 x 16 bytes):
1143 unsigned char getfreq_cmnd[5]= { 0x00, 0x00, 0x00, 0x03, 0x10};
1144 // WRITE CAT_cmnd to the serial port
1145 for (i=0;i<5;i=i+1)
1146 {
1147 n=lir_write_serport((char*)&getfreq_cmnd[i],1);
1148 if (n<0)
1149 {
1150 // write to serial port failed
1151 fail_message_1();
1152 goto userdefined_q_exit_1;
1153 }
1154 // wait 5msec between each write
1155 lir_sleep(5000);
1156 }
1157 // READ the vfo freq
1158 // wait 60msec to allow the CAT system to settle
1159 lir_sleep(60000);
1160 unsigned char ft920_zero[14]= {0x0000000000000000000000000000};
1161 memcpy(s,ft920_zero, 14);
1162 n=lir_read_serport(s,28);
1163 // ANALYSE and process returned values
1164 if (n==28)
1165 {
1166 // s holds now the vfo frequencies of VFO A & B in 28 bytes
1167 // VFO A is in bytes 1-4 (1 MSB -> 4 LSB) in hex format
1168 // convert pos 1 to 4 from the ascii string s, to the double kxx
1169 kxx=0;
1170 j=1;
1171 for (i=4; i >0; i--)
1172 {
1173 a=(s[i]%16 & 0x0f);
1174 kxx= kxx+a*j;
1175 j=j*16;
1176 a= ((s[i]>>4)%16) & 0x0f;
1177 kxx= kxx+a*j;
1178 j=j*16;
1179 }
1180 if (kxx==0)
1181 {
1182 // failure: trx vfo freq = 0
1183 fail_message_3();
1184 goto userdefined_q_exit_1;
1185 }
1186 else
1187 {
1188 // success
1189 calculate_offset();
1190 goto userdefined_q_exit_1;
1191 }
1192 }
1193 else
1194 {
1195 // failure: read from serial port failed
1196 fail_message_2();
1197 goto userdefined_q_exit_1;
1198 }
1199 }
1200 // ************************CAL FT-1000 ****************************************
1201 if ((strcmp(list[transceiver_number].name,"FT-1000 ")==0))
1202 {
1203 // write delay in msec between two bytes
1204 int write_delay = 5;
1205 // CAT command definition for getting the frequency of VFO A & B
1206 // (it returns 2 x 16 bytes):
1207 unsigned char getfreq_cmnd[5]= { 0x00, 0x00, 0x00, 0x03, 0x10};
1208 // WRITE CAT_cmnd to the serial port
1209 for (i=0;i<5;i=i+1)
1210 {
1211 n=lir_write_serport((char*)&getfreq_cmnd[i],1);
1212 if (n<0)
1213 {
1214 // write to serial port failed
1215 fail_message_1();
1216 goto userdefined_q_exit_1;
1217 }
1218 lir_sleep(write_delay*1000);
1219 }
1220 // READ the vfo freq
1221 // wait 60msec to allow the CAT system to settle
1222 lir_sleep(60000);
1223 unsigned char ft1000_zero[16]= {0x00000000000000000000000000000000};
1224 memcpy(s,ft1000_zero, 16);
1225 n=lir_read_serport(s,32);
1226 // ANALYSE and process returned values
1227 if (n==32)
1228 {
1229 // s holds now the vfo frequencies of VFO A & B in 32 bytes:
1230 // convert pos 8 to 15 from the ascii string s, to the double kxx
1231 kxx=0;
1232 j=1;
1233 for (i=15; i > 7 ; i--) {
1234 kxx=kxx+(s[i] & 0x0f)*j;
1235 j=j*10;
1236 }
1237 if (kxx==0)
1238 {
1239 // failure: trx vfo freq = 0
1240 fail_message_3();
1241 goto userdefined_q_exit_1;
1242 }
1243 else
1244 {
1245 // success
1246 calculate_offset();
1247 goto userdefined_q_exit_1;
1248 }
1249 }
1250 else
1251 {
1252 // failure: read from serial port failed
1253 fail_message_2();
1254 goto userdefined_q_exit_1;
1255 }
1256 }
1257
1258 // *********************** CAL TS-850/TS-2000/K3 *********************************
1259 if (((strcmp(list[transceiver_number].name,"K3 ")==0))
1260 |((strcmp(list[transceiver_number].name,"TS-850 ")==0))
1261 |((strcmp(list[transceiver_number].name,"TS-2000 ")==0)))
1262 {
1263 // CAT command definition for getting the vfo freq:
1264 sprintf (s,"FA;");
1265 // WRITE CAT command to serial port
1266 n=lir_write_serport(s,3);
1267 if (n<0)
1268 {
1269 // write to serial port failed
1270 fail_message_1();
1271 goto userdefined_q_exit_1;
1272 }
1273 // READ the vfo freq
1274 sprintf (s,"0000000000000;");
1275 n=lir_read_serport(s,14);
1276 // ANALYSE and process returned values
1277 if (n==14)
1278 {
1279 // s holds now the vfo frequency encoded p.e. as
1280 // FA00014250000; for the frequency 14.250.000 Hz:
1281 // convert pos 2 to 12 of s to the double kxx
1282 kxx=0;
1283 for (i=2; i<=12;i++)
1284 {
1285 j=s[i]-'0';
1286 kxx=kxx*10+j;
1287 }
1288 if (kxx==0)
1289 {
1290 // failure: trx vfo freq = 0
1291 fail_message_3();
1292 goto userdefined_q_exit_1;
1293 }
1294 else
1295 {
1296 // success
1297 calculate_offset();
1298 goto userdefined_q_exit_1;
1299 }
1300 }
1301 else
1302 {
1303 // failure: read from serial port failed
1304 fail_message_2();
1305 goto userdefined_q_exit_1;
1306 }
1307 }
1308
1309 // *******************CAL FT-450 and FT-950 and FT-2000********************************
1310 if (((strcmp(list[transceiver_number].name,"FT-450 ")==0))
1311 |((strcmp(list[transceiver_number].name,"FT-950 ")==0))
1312 |((strcmp(list[transceiver_number].name,"FT-2000 ")==0)))
1313 {
1314 // CAT command to request the vfo freq:
1315 sprintf (s,"FA;");
1316 // WRITE to serial port
1317 n=lir_write_serport(s,3);
1318 //traces
1319 //printf("\n %s",s); //trace output to screen
1320 //printf("\n"); //'next line' to display last trace entry
1321 if (n<0)
1322 {
1323 // write to serial port failed
1324 fail_message_1();
1325 goto userdefined_q_exit_1;
1326 }
1327 // READ requested vfo freq
1328 sprintf (s,"0000000000;");
1329 n=lir_read_serport(s,11);
1330 //printf("\n s=%s n=%i",s,n); //trace output to screen
1331 //printf("\n"); //'next line' to display last trace entry
1332 if (n==11)
1333 {
1334 // s holds the vfo frequency encoded as FA14250000; for the frequency
1335 // 14.250.000 Hz
1336 // convert position 2 to 9 of s to double kxx
1337 kxx=0;
1338 for (i=2; i<=9;i++)
1339 {
1340 j=s[i]-'0';
1341 kxx=kxx*10+j;
1342 }
1343 if (kxx==0)
1344 {
1345 //failure: trx vfo freq = 0
1346 fail_message_3();
1347 goto userdefined_q_exit_1;
1348 }
1349 else
1350 {
1351 //success
1352 calculate_offset();
1353 goto userdefined_q_exit_1;
1354 }
1355 }
1356 else
1357 {
1358 //failure: read from serial port failed
1359 fail_message_2();
1360 goto userdefined_q_exit_1;
1361 }
1362 }
1363
1364 // ***************************** CAL CATCH ALL *******************************
1365
1366 else{
1367 ug_msg_color=12;
1368 sprintf (ug_msg0,"NO CALIBRATION AVAILABLE");
1369 sprintf (ug_msg1,"FOR THIS TRX");
1370 sprintf (ug_msg2,"PRESS Q-KEY TO SET TRX FREQ.");
1371 }
1372 goto userdefined_q_exit_1;
1373 }
1374 // ***************************************************************************
1375 // ***************************************************************************
1376 // ROUTINES FOR THE PROCESSING OF A "SET VFO " REQUEST
1377 // - do some validations and initialize usergraph
1378 // - select and execute the transceiver-dependent routines for setting the
1379 // VFO frequency
1380 // input: desired frequency stored in the variables freq (unsigned long)
1381 // or transceiver_freq (double)
1382 // proces: create the transceiver-dependent CAT commands for setting the
1383 // VFO frequency
1384 // write/read the message strings to/from the serial port
1385 // output: updated messages in the usergraph
1386 // ***************************************************************************
1387 // ***************************************************************************
1388 // VALIDATE and INITIALIZE:
1389 // check status of serial port
1390 if ( serport_open_status!=0)
1391 {
1392 analyze_serport_error ();
1393 goto userdefined_q_exit_1;
1394 }
1395 // check if linrad frequency is selected
1396 if(mix1_selfreq[0] < 0)
1397 {
1398 ug_msg_color=12;
1399 sprintf (ug_msg0,"NO FREQ. SELECT. ON W/F GRAPH");
1400 goto userdefined_q_exit_1;
1401 }
1402 // check whether the desired frequency is within the valid range for the
1403 // selected transceiver
1404 //raw offset in Khz for transverter :
1405 transverter_offset_raw=hwaredriver.offs_khz[ug_band_no];
1406 //fine offset in Hz for transverter :
1407 transverter_offset_fine=hwaredriver.offs_hz[ug_band_no];
1408 //Freq in KHz :
1409 offset_hwfreq= transverter_offset_raw +(transverter_offset_fine*.001) ;
1410 //Freq in Hz
1411 transceiver_freq= (hwfreq+offset_hwfreq)*1000;
1412 transceiver_freq=floor(transceiver_freq);
1413 freq= transceiver_freq;
1414 if ((transceiver_freq < list[transceiver_number].min_transceiver_freq )
1415 ||(transceiver_freq > list[transceiver_number].max_transceiver_freq))
1416 {
1417 ug_msg_color=12;
1418 sprintf (ug_msg0,"INVALID FREQ.FOR %s",list[transceiver_number].name);
1419 goto userdefined_q_exit_2;
1420 }
1421 // initialize message-area in usergraph:
1422 ug_msg_color=12;
1423 strcpy(ug_msg0,"FREQUENCY SETTING IN PROGRESS");
1424 ug_msg1[0]=0;
1425 ug_msg2[0]=0;
1426 show_user_parms();
1427
1428 // SELECT and execute transceiver dependent routines for setting the VFO
1429 // frequency:
1430
1431 // *********************** SET VFO IC-275 and IC-706 *****************************
1432 if (((strcmp(list[transceiver_number].name,"IC-275 ")==0))
1433 |((strcmp(list[transceiver_number].name,"ICOM-all ")==0))
1434 |((strcmp(list[transceiver_number].name,"IC-706 ")==0))
1435 |((strcmp(list[transceiver_number].name,"IC-706MKII ")==0))
1436 |((strcmp(list[transceiver_number].name,"IC-706MKIIG")==0)))
1437 {
1438 // CAT command definition.
1439 // 'Set Frequency command' for IC-275/IC-706:
1440 struct {
1441 char prefix[2];
1442 char radio_addr;
1443 char computer_addr;
1444 char cmd_nr;
1445 unsigned char freq[5];
1446 char suffix;
1447 } msg0 = {{0xFE, 0xFE}, // preamble code x 2
1448 0x10, // receive address for IC-275
1449 0xE0, // transmit address of controller
1450 0x05, // 'set freq' cmnd code
1451 {0x00,0x00,0x00,0x00,0x00}, // freq
1452 // 145.678.900 Hz is encoded as x00 x89 x67 x45 x01
1453 0xFD}; // end of message code
1454
1455 if ((strcmp(list[transceiver_number].name,"ICOM-all ")==0))
1456 msg0.radio_addr='\x00'; // receive address for any icom-radio broadcasting
1457 if ((strcmp(list[transceiver_number].name,"IC-706 ")==0))
1458 msg0.radio_addr='\x48'; // receive address for IC-706
1459 if ((strcmp(list[transceiver_number].name,"IC-706MKII ")==0))
1460 msg0.radio_addr='\x4e'; // receive address for IC-706MKII
1461 if ((strcmp(list[transceiver_number].name,"IC-706MKIIG")==0))
1462 msg0.radio_addr='\x58'; // receive address for IC-706MKIIG
1463 // CONVERT freq to the CAT command format;
1464 // convert 10 digits of freq to packed bcd and store in msg0.freq,
1465 // put first digit-pair in FIRST output byte
1466 for (i=0; i < 5; i++) {
1467 a = freq%10;
1468 freq /= 10;
1469 a |= (freq%10)<<4;
1470 freq /= 10;
1471 msg0.freq[i]= a;
1472 //printf("\n %#4.2x ",msg0.freq[i]); //trace output to screen
1473 }
1474 //printf("\n"); //'next line' to display last trace entry
1475 // WRITE CAT command to serial port
1476 n=lir_write_serport((char *) &msg0, sizeof(msg0));
1477 goto display_messages_in_usersgraph;
1478 }
1479
1480 // ******************* SET VFO TS-850, TS-2000 and K3 *********************
1481 if (((strcmp(list[transceiver_number].name,"K3 ")==0))
1482 |((strcmp(list[transceiver_number].name,"TS-850 ")==0))
1483 |((strcmp(list[transceiver_number].name,"TS-2000 ")==0)))
1484 {
1485 // CAT command definition for setting the VFO freq:
1486 // FA is the "set VFO-A frequency" command code
1487 // Freq in Hz; 11 digits, leading zeros, no decimal point, trailing semicolon.
1488 // CONVERT transceiver_freq to the CAT command format
1489 sprintf (s,"FA%011.0f;",transceiver_freq);
1490 // WRITE CAT command to serial port
1491 n=lir_write_serport(s,14);
1492 //printf("\n %s",s); //trace output to screen
1493 //printf("\n"); //add 'next line' to trace output
1494 goto display_messages_in_usersgraph;
1495 }
1496
1497 // ************************ SET VFO FT-736 ************************************
1498
1499 if ((strcmp(list[transceiver_number].name,"FT-736 ")==0))
1500 {
1501 // write delay in msec between two bytes
1502 int write_delay =50;
1503 // CAT command definitions for setting the VFO freq:
1504 // Setting the VFO frequency to 145.678.900 HZ is encoded as
1505 // 0x14 0x56 0x78 0x90 0x01
1506 // the last byte 0x01 is the "set freq" command code
1507 unsigned char setfreq_cmnd[5]= { 0x00, 0x00, 0x00, 0x00, 0x01};
1508 unsigned char open_cmnd[5] = { 0x00, 0x00, 0x00, 0x00, 0x00};
1509 unsigned char close_cmnd[5] = { 0x80, 0x80, 0x80, 0x80, 0x80};
1510 // WRITE CAT commands to serial port
1511 unsigned char cat_cmnd[5];
1512 int write_cat_cmnd(void)
1513 {
1514 int r=0;
1515 for (i=0;i<5;i=i+1)
1516 {
1517 r=lir_write_serport((char*)&cat_cmnd[i],1);
1518 if (r<0) return -1;
1519 // printf("\n %#4.2x ",cat_cmnd[i]); //trace output to screen
1520 lir_sleep(write_delay*1000);
1521 }
1522 return 0;
1523 }
1524 // 1. open CAT system
1525 memcpy(cat_cmnd,open_cmnd, 5);
1526 n=write_cat_cmnd();
1527 if (n<0) goto ft736_exit;
1528 // 2. CONVERT the content of "freq" variable to the setfreq_cmd format:
1529 // discard least significant digit of freq
1530 // convert next 8 digits of freq to packed bcd and store in setfreq_cmd
1531 // put first digit-pair in LAST output byte
1532 freq /= 10;
1533 for (i=0; i < 4; i++) {
1534 a = freq%10;
1535 freq /= 10;
1536 a |= (freq%10)<<4;
1537 freq /= 10;
1538 setfreq_cmnd[3-i]= a;
1539 }
1540 // 3. write setfreq_cmd to the serial port
1541 memcpy(cat_cmnd,setfreq_cmnd, 5);
1542 n=write_cat_cmnd();
1543 if (n<0) goto ft736_exit;
1544 // 4. close CAT system
1545 memcpy(cat_cmnd,close_cmnd, 5);
1546 n=write_cat_cmnd();
1547 ft736_exit:;
1548 //printf("\n"); //'next line' to display last trace entry
1549 goto display_messages_in_usersgraph;
1550 }
1551 // ************* SET VFO FT-1000 and FT-920 ********************************
1552 if (((strcmp(list[transceiver_number].name,"FT-1000 ")==0))
1553 |((strcmp(list[transceiver_number].name,"FT-920 ")==0)))
1554 {
1555 // write delay in msec between two bytes
1556 int write_delay =5;
1557 // CAT command definition for setting the VFO freq:
1558 // the command to set the VFO to p.e. 014.250.000 Hz is encoded as
1559 // 0x00 0x50 0x42 0x01 0x0a
1560 // the last byte 0x0a is the "set freq" command code
1561 unsigned char setfreq_cmnd[5]= { 0x00, 0x00, 0x00, 0x00, 0x0a};
1562 // CONVERT the content of "freq" variable to the CAT command format:
1563 // discard the least significant digit of "freq"
1564 // convert the next 8 digits of "freq" to packed bcd and store them in
1565 // setfreq_cmd,
1566 // put the first digit-pair in first output byte
1567 freq /= 10;
1568 for (i=0; i < 4; i++) {
1569 a = freq%10;
1570 freq /= 10;
1571 a |= (freq%10)<<4;
1572 freq /= 10;
1573 setfreq_cmnd[i]= a;
1574 }
1575 // WRITE CAT command to the serial port
1576 for (i=0;i<5;i=i+1)
1577 {
1578 n=lir_write_serport((char*)&setfreq_cmnd[i],1);
1579 if (n<0) goto ft1000_exit; //an error occured
1580 // printf("\n %#4.2x ",setfreq_cmnd[i]); //trace each character to screen
1581 lir_sleep(write_delay*1000);
1582 }
1583 ft1000_exit:;
1584 //printf("\n"); //trace last character
1585 goto display_messages_in_usersgraph;
1586 }
1587
1588 // ********************* SET VFO FT-450 and FT-950 and FT-2000 *************************
1589 if (((strcmp(list[transceiver_number].name,"FT-450 ")==0))
1590 |((strcmp(list[transceiver_number].name,"FT-950 ")==0))
1591 |((strcmp(list[transceiver_number].name,"FT-2000 ")==0)))
1592 {
1593 // CAT command definition for setting the VFO freq:
1594 // To set the VFO frequency to 14.250.000 Hz the command is encoded as
1595 // FA14250000; (ASCII values)
1596 // "FA" is the "SET VFO A "command code
1597 // freq in Hz; 8 digits, leading zeros, no decimal point,
1598 // ";" is a delimiter
1599 // CONVERT the content of "transceiver_freq" variable to the CAT command format:
1600 sprintf (s,"FA%08.0f;",transceiver_freq);
1601 // WRITE the CAT command to the serial port
1602 n=lir_write_serport(s,11);
1603 //printf("\n %s",s); //trace output to screen
1604 //printf("\n"); //'next line' to display last trace entry
1605 goto display_messages_in_usersgraph;
1606 }
1607
1608 // *************************** SET VFO FT-817 and FT-897 *********************************
1609 if (((strcmp(list[transceiver_number].name,"FT-817 ")==0))
1610 |((strcmp(list[transceiver_number].name,"FT-897 ")==0)))
1611
1612 {
1613 // write delay in msec between two bytes
1614 int write_delay = 10;
1615 // CAT command definition:
1616 // setting the VFO frequency to 439.70 MHz is encoded as
1617 // 0x43 0x97 0x00 0x00 0x01 (hex values)
1618 // last byte 0x01 is the "SET FREQUENCY" command code.
1619 unsigned char setfreq_cmnd[5]= { 0x00, 0x00, 0x00, 0x00, 0x01};
1620 // CONVERT the content of "freq" variable to the setfreq_cmd format:
1621 // discard least significant digit of freq
1622 // convert next 8 digits of freq to packed bcd and store in setfreq_cmd
1623 // put first digit-pair in last output byte
1624 freq /= 10;
1625 for (i=0; i < 4; i++) {
1626 a = freq%10;
1627 freq /= 10;
1628 a |= (freq%10)<<4;
1629 freq /= 10;
1630 setfreq_cmnd[3-i]= a;
1631 }
1632 // WRITE setfreq_cmd to the serial port
1633 unsigned char cat_cmnd[5];
1634 int write_cat_cmnd(void)
1635 {
1636 int r;
1637 for (i=0;i<5;i=i+1)
1638 {
1639 r=lir_write_serport((char*)&cat_cmnd[i],1);
1640 if (r<0) return -1;
1641 // printf("\n %#4.2x ",cat_cmnd[i]); //trace output to screen
1642 lir_sleep(write_delay*1000);
1643 }
1644 return 0;
1645 }
1646 memcpy(cat_cmnd,setfreq_cmnd, 5);
1647 n=write_cat_cmnd();
1648 //printf("\n"); //add 'next line' to display last trace entry
1649 goto display_messages_in_usersgraph;
1650 }
1651
1652 // ************************ SET VFO CATCH_ALL**********************************
1653 ug_msg_color=12;
1654 sprintf (ug_msg0,"INTERNAL ERROR ");
1655 goto userdefined_q_exit_1;
1656
1657 // ***********************END 'SET VFO' ROUTINES ******************************
1658
1659 // display messages in usergraph
1660 display_messages_in_usersgraph:;
1661 if (n<0)
1662 {
1663 ug_msg_color=12;
1664 sprintf (ug_msg0,"WRITE TO %s FAILED",serport_name);
1665 goto userdefined_q_exit_1;
1666 }
1667 ug_msg_color=14;
1668 sprintf (ug_msg0,"LINRAD FREQ = ");
1669 edit_ugmsg(ug_msg0,floor(hwfreq*1000));
1670 userdefined_q_exit_2:;
1671 sprintf (ug_msg1,"TOTAL OFFSET= ");
1672 edit_ugmsg(ug_msg1,offset_hwfreq*1000);
1673 sprintf (ug_msg2,"TRX FREQ= ");
1674 edit_ugmsg(ug_msg2, transceiver_freq);
1675 //main exit for userdefined_q
1676 userdefined_q_exit_1:;
1677 show_user_parms();
1678 // ****************************************************************************
1679 // END void userdefined_q(void) routine
1680 // ****************************************************************************
1681 }
1682
update_users_rx_frequency(void)1683 void update_users_rx_frequency(void)
1684 {
1685 // This routine is called from the screen thread.
1686 if(fabs(hwfreq-old_hwfreq) > 0.001)
1687 {
1688 ug_msg_color=10;
1689 sprintf (ug_msg0,"LINRAD FREQ= ");
1690 edit_ugmsg(ug_msg0,floor(hwfreq*1000));
1691 hide_mouse(ug.xleft, ug.xright,ug.ytop,ug.ybottom);
1692 sprintf (ug_msg1,"PRESS Q-KEY TO SET TRX FREQ");
1693 sprintf (ug_msg2," ");
1694 show_user_parms();
1695 settextcolor(7);
1696 }
1697 }
1698 // ****************************************************************************
1699 // WSE Rx and Tx and SDR-14/SDR-IQ Rx routines
1700 // ****************************************************************************
1701 #if (RX_HARDWARE == 0)
1702 #include "wse_sdrxx.c"
1703 #endif
1704 // ****************************************************************************
1705 // Dummy routines to support converters and other hardwares
1706 // ****************************************************************************
1707 #if (RX_HARDWARE == 1)
control_hware(void)1708 void control_hware(void){};
set_hardware_tx_frequency(void)1709 void set_hardware_tx_frequency(void){};
1710
set_hardware_rx_frequency(void)1711 void set_hardware_rx_frequency(void)
1712 {
1713 fg.passband_increment=0.01;
1714 fg.passband_direction = 1;
1715 fft1_direction = fg.passband_direction;
1716 }
1717
set_hardware_rx_gain(void)1718 void set_hardware_rx_gain(void){};
hware_interface_test(void)1719 void hware_interface_test(void){};
hware_set_rxtx(int state)1720 void hware_set_rxtx(int state)
1721 {
1722 int i;
1723 i=state;
1724 };
hware_hand_key(void)1725 void hware_hand_key(void){};
clear_hware_data(void)1726 void clear_hware_data(void){};
1727 #endif
1728
1729
1730