1 
2 
3 
4 // ****************************************************************
5 // Change the define for RX_HARDWARE and modify the dummy routines
6 // in the prototype section to fit your needs.
7 // The routines in wse_sdrxx.c can serve as a starting point.
8 #define RX_HARDWARE 0
9 // ****************************************************************
10 
11 #include <stdio.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <stdlib.h>
16 //added August 2007
17 #include <time.h>
18 
19 #include "sigdef.h" // Remove this define in linrad-03.01 and later.
20 // The definition of baseb_reset_counter is moved from sigdef.h to uidef.h
21 #include "screendef.h" //w3sz
22 
23 
24 extern int w3sz_offset_hz;  //w3sz offset equal to ug.par2 to be used elsewhere in program
25 extern int w3sz_offset_hz_old;  //w3sz
26 extern int w3sz_users_flag;//w3sz
27 
28 typedef struct {
29 int ytop;
30 int ybottom;
31 int xleft;
32 int xright;
33 float par1;
34 float par2;
35 } UG_PARMS;
36 
37 #define UG_TOP 0
38 #define UG_BOTTOM 1
39 #define UG_LEFT 2
40 #define UG_RIGHT 3
41 #define UG_INCREASE_PAR1 4
42 #define UG_DECREASE_PAR1 5
43 #define UG_DO_WHATEVER 6
44 #define MAX_UGBUTT 7
45 
46 UG_PARMS ug;
47 BUTTONS ugbutt[MAX_UGBUTT];
48 
49 int ug_old_y1;
50 int ug_old_y2;
51 int ug_old_x1;
52 int ug_old_x2;
53 int users_graph_scro;
54 void make_users_control_graph(void);
55 
56 
userdefined_u(void)57 void userdefined_u(void)
58 {
59 // This routine is called when the 'U' key is pressed
60 // It then sends frequency information to Radio 0 via
61 // to a file that another program uses to send the info
62 // across the ethernet to Writelog.  It then mutes Linrad.
63 // This routine written by w3sz
64 
65 char ft2[80]="";
66 char bb[80]="";
67 
68 float freqpre;
69 char ft[80]="";
70 char zro[80]="";
71 char zr1[80]="";
72 char ffin[11]="";
73 
74 float freq;
75 float lofreq;
76 
77 time_t now;
78 int l_time;
79 char *ft1000file[19]={"\\lin2ft\\Radio0file"};
80 
81 l_time = time(&now);
82 
83 FILE *Fp1;
84 
85 strcat(bb,"bb");
86 strcat(zro,"0");
87 strcat(zr1,"0");
88 
89 freqpre=fg.passband_center;
90 freqpre=freqpre*10E6;
91 freq=(mix1_fq_mid[fftx_nx]);
92 freq=freq*10;
93 freq=freq+freqpre-960000;
94 freq=freq*100;
95 
96 /*
97 The info in mix1_fq_mid[fftx_nx] is only valid when the AFC has
98 locked to a signal. In case AFC is deselected or the AFC failed
99 the data may be incorrect. The number 480000 is ui.sampling_speed/2
100 and it should be applied only in I/Q mode.
101 */
102 
103 freq= hwfreq*1000000.0 ;
104 freqpre=1000.0*ug.par2;
105 /*
106 
107 This should be correct always. Linrad looks at the flags and selects
108 the frequency actually in use for conversion to the baseband and adds
109 the bfo offset 'bg.bfo_freq' in ssb mode.
110 
111 Look at the routine 'frequency_readout' in baseb_graph.c. for
112 details.
113 
114 */
115 
116 // If transverter is used, set par1 to LO frequency and
117 //  subtract LO value based on user_parameter 'par1'
118 // par1 is multiplied by 10**8 to give IF freq in desired units
119 //if there is no transverter, set par1 to zero
120 lofreq= ug.par1 * 10E8;
121 freq=freq-lofreq;
122 
123 
124 //Add or subtract to put Linrad and FT1000 on same frequency
125 // 1,000,000 equals 1 kHz; freqpre = 1000*ug.par2, so
126 // ug.par2 is entered directly in Hz for correction
127 freq=freq+freqpre;
128 
129 //test by sending corrected output to file for review
130 
131 /*
132 FILE *Fp2;
133 Fp2=fopen("aatestfile","a+");
134 fprintf(Fp2,"%f\n",freq);
135 fclose(Fp2);
136 */
137 
138 // Round up to compensate for truncation
139 freq=freq+5000;
140 freq=freq*10;
141 // Add leading zeroes as necessary for proper format
142 
143 sprintf(ft,"%11f",freq);
144 
145 if ((freq < 10E10) && (freq >=10E9))
146 {
147 strcat(zro,zro);
148 strcat(zro,ft);
149 strncpy(ft2,zro,12);
150 }
151 else if (freq < 10E9)
152 {
153 strcat(zro,zro);
154 strcat(zro,zr1);
155 strcat(zro,ft);
156 strncpy(ft2,zro,12);
157 }
158 
159 else
160 {
161 strcat(zro,ft);
162 strncpy(ft2,zro,12);
163 }
164 
165 strncpy(ffin,ft2,10);
166 
167 Fp1=fopen(*ft1000file,"w");
168 //fprintf(Fp1,ffin);
169 fprintf(Fp1,"%s\n%i\n",ffin,l_time);
170 fclose(Fp1);
171 
172 
173 FILE *Fp2;
174 char *aatestfile[47]={"aatestfile"};
175 
176 Fp2=fopen(*aatestfile,"w");
177 fprintf(Fp2,"%s\n%i\n",ffin,l_time);
178 fclose(Fp2);
179 
180 mix1_selfreq[0]=-1;
181 lir_empty_da_device_buffer();
182 baseb_reset_counter++;
183 }
184 
users_eme(void)185 void users_eme(void)
186 {
187 // Called each time moon position is updated.
188 // data in degrees is available in:
189 // float moon_az;
190 // float moon_el;
191 }
192 
193 
userdefined_q(void)194 void userdefined_q(void)
195 {
196 // This routine is called when the 'Q' key is pressed
197 // It then sends frequency information to Radio1 via
198 // to a file that another program uses to send the info
199 // across the ethernet to Writelog.  It then mutes Linrad.
200 // This routine written by w3sz
201 char ft2[80]="";
202 char bb[80]="";
203 
204 float freqpre;
205 char ft[80]="";
206 char zro[80]="";
207 char zr1[80]="";
208 char ffin[11]="";
209 
210 float freq;
211 float lofreq;
212 
213 time_t now;
214 int l_time;
215 char *ft1000file[19]={"\\lin2ft\\Radio1file"};
216 
217 l_time = time(&now);
218 
219 FILE *Fp1;
220 
221 strcat(bb,"bb");
222 strcat(zro,"0");
223 strcat(zr1,"0");
224 
225 freqpre=fg.passband_center;
226 freqpre=freqpre*10E6;
227 freq=(mix1_fq_mid[fftx_nx]);
228 freq=freq*10;
229 freq=freq+freqpre-960000;
230 freq=freq*100;
231 
232 /*
233 The info in mix1_fq_mid[fftx_nx] is only valid when the AFC has
234 locked to a signal. In case AFC is deselected or the AFC failed
235 the data may be incorrect. The number 480000 is ui.sampling_speed/2
236 and it should be applied only in I/Q mode.
237 */
238 
239 freq= hwfreq*1000000.0 ;
240 freqpre=1000.0*ug.par2;
241 /*
242 
243 This should be correct always. Linrad looks at the flags and selects
244 the frequency actually in use for conversion to the baseband and adds
245 the bfo offset 'bg.bfo_freq' in ssb mode.
246 
247 Look at the routine 'frequency_readout' in baseb_graph.c. for
248 details.
249 
250 */
251 
252 // If transverter is used, set par1 to LO frequency and
253 //  subtract LO value based on user_parameter 'par1'
254 // par1 is multiplied by 10**8 to give IF freq in desired units
255 //if there is no transverter, set par1 to zero
256 lofreq= ug.par1 * 10E8;
257 freq=freq-lofreq;
258 
259 
260 //Add or subtract to put Linrad and FT1000 on same frequency
261 // 1,000,000 equals 1 kHz; freqpre = 1000*ug.par2, so
262 // ug.par2 is entered directly in Hz for correction
263 freq=freq+freqpre;
264 
265 //test by sending corrected output to file for review
266 
267 /*
268 FILE *Fp2;
269 Fp2=fopen("aatestfile","a+");
270 fprintf(Fp2,"%f\n",freq);
271 fclose(Fp2);
272 */
273 
274 // Round up to compensate for truncation
275 freq=freq+5000;
276 freq=freq*10;
277 // Add leading zeroes as necessary for proper format
278 
279 sprintf(ft,"%11f",freq);
280 
281 if ((freq < 10E10) && (freq >=10E9))
282 {
283 strcat(zro,zro);
284 strcat(zro,ft);
285 strncpy(ft2,zro,12);
286 }
287 else if (freq < 10E9)
288 {
289 strcat(zro,zro);
290 strcat(zro,zr1);
291 strcat(zro,ft);
292 strncpy(ft2,zro,12);
293 }
294 
295 else
296 {
297 strcat(zro,ft);
298 strncpy(ft2,zro,12);
299 }
300 
301 strncpy(ffin,ft2,10);
302 
303 Fp1=fopen(*ft1000file,"w");
304 //fprintf(Fp1,ffin);
305 fprintf(Fp1,"%s\n%i\n",ffin,l_time);
306 fclose(Fp1);
307 
308 
309 FILE *Fp2;
310 char *aatestfile[47]={"aatestfile"};
311 
312 Fp2=fopen(*aatestfile,"w");
313 fprintf(Fp2,"%s\n%i\n",ffin,l_time);
314 fclose(Fp2);
315 
316 mix1_selfreq[0]=-1;
317 lir_empty_da_device_buffer();
318 baseb_reset_counter++;
319 return;
320 }
321 
322 //end of w3sz routine
323 
324 
325 //    ************ PROTOTYPE ROUTINES FOR USER WINDOWS  ***************
326 // User defined windows to allow mouse control.
327 // In case several windows are desired, give them different
328 // numbers (64 and above) and use scro[m].no to decide what to do
329 // in your mouse_on_users_graph routine.
330 
331 
332 
333 #define USERS_GRAPH_TYPE1 64
334 
335 
336 
337 // Define your parameters in this structure.
338 // Save it to a file and recover it from init_users_control_window(void)
339 
init_users_control_window(void)340 void init_users_control_window(void)
341 {
342 char *w3szfile[10]={"aajunkfile"};
343 FILE *Fp;
344 switch (rx_mode)
345   {
346 
347 case MODE_WCW:
348 	*w3szfile="aawcw_file";
349 	break;
350   case MODE_HSMS:
351    	*w3szfile="aahsmsfile";
352   case MODE_QRSS:
353  	*w3szfile="aaqrssfile";
354   break;
355 
356   case MODE_NCW:
357  	*w3szfile="aancw_file";
358   case MODE_SSB:
359 	*w3szfile="aassb_file";
360  break;
361 
362   case MODE_FM:
363  	*w3szfile="aafm__file";
364   case MODE_AM:
365  	*w3szfile="aaam__file";
366   case MODE_TXTEST:
367  	*w3szfile="aatxtefile";
368   case MODE_RX_ADTEST:
369  	*w3szfile="aarxadfile";
370   case MODE_TUNE:
371  	*w3szfile="aatunefile";
372 
373   break;
374   }
375 Fp=fopen(*w3szfile,"r");
376 if(Fp == NULL)
377   {
378 // Set initial values if there is no file.
379   ug.xleft=0;
380   ug.ytop=0;
381   ug.par1=0.0;
382   ug.par2=0.0;
383   }
384 else
385   {
386   fscanf(Fp,"%d%d%f%f",&ug.xleft,&ug.ytop,&ug.par1,&ug.par2);
387   fclose(Fp);
388   }
389 ug.xright=ug.xleft+25*text_width;
390 ug.ybottom=ug.ytop+3.5*text_height;
391 if (ug.par2 > -10000 && ug.par2<=10000)//w3sz
392 {
393 w3sz_offset_hz=(int)ug.par2; //w3sz
394 }
395 else//w3sz
396 {
397 w3sz_offset_hz = 0;//w3sz
398 }
399 w3sz_users_flag=1;//w3sz
400 
401 users_graph_scro=no_of_scro;
402 make_users_control_graph();
403 no_of_scro++;
404 if(no_of_scro >= MAX_SCRO)lirerr(89);
405 }
406 
users_init_mode(void)407 void users_init_mode(void)
408 {
409 // A switch statement can be used to do different things depending on
410 // the processing mode.
411 switch (rx_mode)
412   {
413   case MODE_WCW:
414 // Open a window to allow mouse control of your own things
415 	init_users_control_window();
416 	break;
417   case MODE_HSMS:
418   case MODE_QRSS:
419   break;
420 
421   case MODE_NCW:
422   case MODE_SSB:
423 // Open a window to allow mouse control of your own things
424   	init_users_control_window();
425   break;
426 
427   case MODE_FM:
428   case MODE_AM:
429   case MODE_TXTEST:
430   case MODE_RX_ADTEST:
431   case MODE_TUNE:
432   break;
433   }
434 }
435 
436 
show_user_parms(void)437 void show_user_parms(void)
438 {
439 char s[80];
440 
441 char *w3szfile[10]={"aajunkfile"};
442 
443 // Show the user parameters on screen
444 // and issue hardware commands if required.
445 // Use hware_flag to direct calls to control_hware() when cpu time
446 // is available in case whatever you want to do takes too much time
447 // to be done immediately.
448 // Note that mouse control is done in the narrowband processing thread
449 // and that you can not use lir_sleep to wait for hardware response here.
450 hide_mouse(ug.xleft, ug.xright,ug.ytop,ug.ybottom);
451 sprintf(s,"LO(MHz) %10.6f ",ug.par1);
452 lir_pixwrite(ug.xleft+3*text_width,ug.ytop+text_height,s);
453 sprintf(s,"SH (Hz) %10.1f ",ug.par2);
454 lir_pixwrite(ug.xleft+3*text_width,ug.ytop+2*text_height,s);
455 if (ug.par2 >= -10000 && ug.par2<=10000)//w3sz
456 {
457 w3sz_offset_hz=(int)ug.par2; //w3sz
458 }
459 else//w3sz
460 {
461 w3sz_offset_hz = 0;//w3sz
462 }
463 FILE *Fp;
464 
465 switch (rx_mode)
466   {
467 
468 case MODE_WCW:
469 	*w3szfile="aawcw_file";
470 	break;
471   case MODE_HSMS:
472    	*w3szfile="aahsmsfile";
473   case MODE_QRSS:
474  	*w3szfile="aaqrssfile";
475   break;
476 
477   case MODE_NCW:
478  	*w3szfile="aancw_file";
479   case MODE_SSB:
480 	*w3szfile="aassb_file";
481  break;
482 
483   case MODE_FM:
484  	*w3szfile="aafm__file";
485   case MODE_AM:
486  	*w3szfile="aaam__file";
487   case MODE_TXTEST:
488  	*w3szfile="aatxtefile";
489   case MODE_RX_ADTEST:
490  	*w3szfile="aarxadfile";
491   case MODE_TUNE:
492  	*w3szfile="aatunefile";
493 
494   break;
495   }
496 
497 Fp=fopen(*w3szfile,"w");
498 
499 fprintf(Fp,"%d\n%d\n%f\n%f\n",ug.xleft,ug.ytop,ug.par1,ug.par2);
500 fclose(Fp);
501 
502 }
503 
504 
mouse_continue_users_graph(void)505 void mouse_continue_users_graph(void)
506 {
507 switch (mouse_active_flag-1)
508   {
509 // Move border lines immediately.
510 // for other functions, wait until button is released.
511 // Look in freq_control.c how to move a fixed size window.
512   case UG_TOP:
513   graph_borders((void*)&ug,0);
514   ug.ytop=mouse_y;
515   graph_borders((void*)&ug,15);
516   break;
517 
518   case UG_BOTTOM:
519   graph_borders((void*)&ug,0);
520   ug.ybottom=mouse_y;
521   graph_borders((void*)&ug,15);
522   break;
523 
524   case UG_LEFT:
525   graph_borders((void*)&ug,0);
526   ug.xleft=mouse_x;
527   graph_borders((void*)&ug,15);
528   break;
529 
530   case UG_RIGHT:
531   graph_borders((void*)&ug,0);
532   ug.xright=mouse_x;
533   graph_borders((void*)&ug,15);
534   break;
535 
536   default:
537   goto await_release;
538   }
539 if(leftpressed == BUTTON_RELEASED)goto finish;
540 return;
541 await_release:;
542 if(leftpressed != BUTTON_RELEASED) return;
543 // Assuming the user wants to control hardware we
544 // allow commands only when data is not over the network.
545 if( (ui.network_flag&NET_RX_INPUT) == 0)
546   {
547   switch (mouse_active_flag-1)
548     {
549     case UG_INCREASE_PAR1:
550     ug.par1++;
551     break;
552 
553     case UG_DECREASE_PAR1:
554     ug.par1--;
555     break;
556 
557     case UG_DO_WHATEVER:
558 // Issue hardware commands or fill the screen
559 // with whatever you like.
560 // Use hware_flag to direct calls to control_hware() when cpu time
561 // is available in case whatever you want to do takes too much time
562 // to be done immediately.
563       settextcolor(7);
564     break;
565 
566     default:
567 // This should never happen.
568     lirerr(211053);
569     break;
570     }
571   }
572 finish:;
573 hide_mouse(ug_old_x1,ug_old_x2,ug_old_y1,ug_old_y2);
574 leftpressed=BUTTON_IDLE;
575 mouse_active_flag=0;
576 graph_borders((void*)&ug,0);
577 lir_fillbox(ug_old_x1,ug_old_y1,ug_old_x2-ug_old_x1,ug_old_y2-ug_old_y1,0);
578 make_users_control_graph();
579 }
580 
581 
new_user_par1(void)582 void new_user_par1(void)
583 {
584 ug.par1=numinput_float_data;
585 pause_thread(THREAD_SCREEN);
586 show_user_parms();
587 resume_thread(THREAD_SCREEN);
588 }
589 
new_user_par2(void)590 void new_user_par2(void)
591 {
592 ug.par2=numinput_float_data;
593 pause_thread(THREAD_SCREEN);
594 show_user_parms();
595 resume_thread(THREAD_SCREEN);
596 }
597 
598 
mouse_on_users_graph(void)599 void mouse_on_users_graph(void)
600 {
601 int event_no;
602 // First find out is we are on a button or border line.
603 for(event_no=0; event_no<MAX_UGBUTT; event_no++)
604   {
605   if( ugbutt[event_no].x1 <= mouse_x &&
606       ugbutt[event_no].x2 >= mouse_x &&
607       ugbutt[event_no].y1 <= mouse_y &&
608       ugbutt[event_no].y2 >= mouse_y)
609     {
610     ug_old_y1=ug.ytop;
611     ug_old_y2=ug.ybottom;
612     ug_old_x1=ug.xleft;
613     ug_old_x2=ug.xright;
614     mouse_active_flag=1+event_no;
615     current_mouse_activity=mouse_continue_users_graph;
616     return;
617     }
618   }
619 // Not button or border.
620 // Prompt the user for par1 or par2 depending on whether the mouse is
621 // in the upper or the lower part of the window.
622 mouse_active_flag=1;
623 numinput_xpix=ug.xleft+11*text_width;
624 if(mouse_x > ug.xleft+2*text_width && mouse_x<ug.xright-2*text_width)
625   {
626   if(mouse_y > (ug.ytop+ug.ybottom)/2)
627     {
628     numinput_ypix=ug.ytop+2*text_height;
629     numinput_chars=12;
630     erase_numinput_txt();
631     numinput_flag=FIXED_FLOAT_PARM;
632     par_from_keyboard_routine=new_user_par2;
633     }
634   else
635     {
636     numinput_ypix=ug.ytop+text_height;
637     numinput_chars=12;
638     erase_numinput_txt();
639     numinput_flag=FIXED_FLOAT_PARM;
640     par_from_keyboard_routine=new_user_par1;
641     }
642    } //added }
643   else
644     {
645 // If we did not select a numeric input by setting numinput_flag
646 // we have to set mouse_active flag.
647 // Set the routine to mouse_nothing, we just want to
648 // set flags when the mouse button is released.
649     current_mouse_activity=mouse_nothing;
650     mouse_active_flag=1;
651     }
652 // removed }
653 }
654 
655 
make_users_control_graph(void)656 void make_users_control_graph(void)
657 {
658 pause_thread(THREAD_SCREEN);
659 // Set a negative number here.
660 // In case several windows are desired, give them different
661 // negative numbers and use scro[m].no to decide what to do
662 // in your mouse_on_users_graph routine.
663 scro[users_graph_scro].no=USERS_GRAPH_TYPE1;
664 // These are the coordinates of the border lines.
665 scro[users_graph_scro].x1=ug.xleft;
666 scro[users_graph_scro].x2=ug.xright;
667 scro[users_graph_scro].y1=ug.ytop;
668 scro[users_graph_scro].y2=ug.ybottom;
669 // Each border line is treated as a button.
670 // That is for the mouse to get hold of them so the window can be moved.
671 ugbutt[UG_LEFT].x1=ug.xleft;
672 ugbutt[UG_LEFT].x2=ug.xleft;
673 ugbutt[UG_LEFT].y1=ug.ytop;
674 ugbutt[UG_LEFT].y2=ug.ybottom;
675 ugbutt[UG_RIGHT].x1=ug.xright;
676 ugbutt[UG_RIGHT].x2=ug.xright;
677 ugbutt[UG_RIGHT].y1=ug.ytop;
678 ugbutt[UG_RIGHT].y2=ug.ybottom;
679 ugbutt[UG_TOP].x1=ug.xleft;
680 ugbutt[UG_TOP].x2=ug.xright;
681 ugbutt[UG_TOP].y1=ug.ytop;
682 ugbutt[UG_TOP].y2=ug.ytop;
683 ugbutt[UG_BOTTOM].x1=ug.xleft;
684 ugbutt[UG_BOTTOM].x2=ug.xright;
685 ugbutt[UG_BOTTOM].y1=ug.ybottom;
686 ugbutt[UG_BOTTOM].y2=ug.ybottom;
687 // Draw the border lines
688 graph_borders((void*)&ug,7);
689 settextcolor(7);
690 make_button(ug.xleft+text_width,ug.ybottom-3*text_height/2-2,
691                                          ugbutt,UG_DECREASE_PAR1,25);
692 make_button(ug.xright-text_width,ug.ybottom-3*text_height/2-2,
693                                      ugbutt,UG_INCREASE_PAR1,24);
694 make_button(ug.xleft+text_width,ug.ybottom-text_height/2-2,
695                                          ugbutt,UG_DO_WHATEVER,'A');
696 show_user_parms();
697 resume_thread(THREAD_SCREEN);
698 }
699 
700 
users_close_devices(void)701 void users_close_devices(void)
702 {
703 // WSE units do not use the parallel port.
704 }
705 
users_open_devices(void)706 void users_open_devices(void)
707 {
708 }
709 
710 
711 
users_set_band_no(void)712 void users_set_band_no(void)
713 {
714 // See users_tr.c
715 }
716 
update_users_rx_frequency(void)717 void update_users_rx_frequency(void)
718 {
719 // This routine is called from the screen thread.
720 // See users_tr.c
721 }
722 
723 
724 
725 // **********************************************************
726 //         WSE Rx and Tx and SDR-14/SDR-IQ Rx routines
727 // **********************************************************
728 #if (RX_HARDWARE == 0)
729 #include "wse_sdrxx.c"
730 #endif
731 // **********************************************************
732 // Dummy routines to support converters and other hardwares
733 // **********************************************************
734 #if (RX_HARDWARE == 1)
control_hware(void)735 void control_hware(void){};
set_hardware_tx_frequency(void)736 void set_hardware_tx_frequency(void){};
737 
set_hardware_rx_frequency(void)738 void set_hardware_rx_frequency(void)
739 {
740 fg.passband_increment=0.01;
741 fg.passband_direction = -1;
742 fft1_direction = fg.passband_direction;
743 }
744 
set_hardware_rx_gain(void)745 void set_hardware_rx_gain(void){};
hware_interface_test(void)746 void hware_interface_test(void){};
hware_set_rxtx(int state)747 void hware_set_rxtx(int state)
748   {
749   int i;
750   i=state;
751   };
hware_hand_key(void)752 void hware_hand_key(void){};
clear_hware_data(void)753 void clear_hware_data(void){};
754 #endif
755 
756 
757 
758 
759 
760