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