1 // Copyright (c) <2012> <Leif Asbrink>
2 //
3 // Permission is hereby granted, free of charge, to any person
4 // obtaining a copy of this software and associated documentation
5 // files (the "Software"), to deal in the Software without restriction,
6 // including without limitation the rights to use, copy, modify,
7 // merge, publish, distribute, sublicense, and/or sell copies of
8 // the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
22 
23 
24 #include <string.h>
25 
26 #include "globdef.h"
27 #include "uidef.h"
28 #include "screendef.h"
29 #include "hwaredef.h"
30 #include "seldef.h"
31 #include "rusage.h"
32 #include "thrdef.h"
33 #include "fft1def.h"
34 #include "keyboard_def.h"
35 
36 void show_hardware_gain(void);
37 
38 #define MAX_EXTIO_FILES 40
39 #define BUFFER_SIZE 256
40 char extio_name[BUFFER_SIZE], extio_model[BUFFER_SIZE];
41 double extio_start_time;
42 
43 #if(OSNUM == OSNUM_WINDOWS)
44 #include <windows.h>
45 typedef int bool;
46 typedef bool (WINAPI *pOpenHW)(void);
47 typedef int (WINAPI *pSetHWLO)(long freq);
48 typedef void (WINAPI *pCloseHW)(void);
49 typedef long (WINAPI *pGetHWLO)(void);
50 typedef void (WINAPI *pSetCallback)(void (* Callback)(int,int,float,short*));
51 typedef long (WINAPI *pTuneChanged)(long);
52 typedef void (WINAPI *pSetRFGain)(int);
53 typedef int (WINAPI *pGetRFGain)(void);
54 typedef bool (WINAPI *pInitHW)(char *name, char *model,int *type);
55 typedef void (WINAPI *pShowGUI)(void);
56 typedef void (WINAPI *pHideGUI)(void);
57 typedef int (WINAPI *pStartHW)(long freq);
58 typedef void (WINAPI *pStopHW)(void);
59 typedef long (WINAPI *pGetHWSR)(void);
60 #endif
61 
62 #if(OSNUM == OSNUM_LINUX)
63 #include <pthread.h>
64 typedef int bool;
65 typedef bool (*pOpenHW)(void);
66 typedef int (*pSetHWLO)(long freq);
67 typedef void (*pCloseHW)(void);
68 typedef long (*pGetHWLO)(void);
69 typedef void (*pSetCallback)(void (* Callback)(int,int,float,short*));
70 typedef long (*pTuneChanged)(long);
71 typedef void (*pSetRFGain)(int);
72 typedef int (*pGetRFGain)(void);
73 typedef bool (*pInitHW)(char *name, char *model,int *type);
74 typedef void (*pShowGUI)(void);
75 typedef void (*pHideGUI)(void);
76 typedef int (*pStartHW)(long freq);
77 typedef void (*pStopHW)(void);
78 typedef long (*pGetHWSR)(void);
79 #endif
80 
81 int extio_read_bytes;
82 int extio_cnt;
83 
84 pOpenHW OpenHW;
85 pSetHWLO SetHWLO;
86 pCloseHW CloseHW;
87 pGetHWLO GetHWLO;
88 pSetCallback SetCallback;
89 pTuneChanged TuneChanged;
90 pSetRFGain SetRFGain;
91 pGetRFGain GetRFGain;
92 pInitHW InitHW;
93 pShowGUI ShowGUI;
94 pHideGUI HideGUI;
95 pStartHW StartHW;
96 pStopHW StopHW;
97 pGetHWSR GetHWSR;
98 
99 #define EXTIO_FREQ_CHANGED  101
100 #define EXTIO_RF_GAIN_CHANGED  210
101 #define EXTIO_SAMPRATE_CHANGED 100
102 
103 
104 #define RF_GAIN_UP_LIMIT 44 //dB
105 #define RF_GAIN_LOW_LIMIT -6 //dB
106 
107 #define EXTIO_LIB_FILENAME "par_extio_libname"
108 
write_extio_parfile(char * fnam)109 void write_extio_parfile(char *fnam)
110 {
111 FILE *file;
112 file=fopen(EXTIO_LIB_FILENAME,"w");
113 if(file == NULL)
114   {
115   lirerr(1236);
116   return;
117   }
118 clear_screen();
119 fprintf(file,"%s\n",fnam);
120 fclose(file);
121 lir_text(0,0,fnam);
122 lir_text(0,1,"Inverted spectrum? (Y/N):");
123 invspk:;
124 to_upper_await_keyboard();
125 if(lir_inkey == 'Y')
126   {
127   ui.use_extio=EXTIO_INVERTED;
128   }
129 else
130   {
131   if(lir_inkey != 'N')goto invspk;
132   ui.use_extio=EXTIO_NON_INVERTED;
133   }
134 }
135 
get_library_filename(char * s)136 void get_library_filename(char *s)
137 {
138 FILE *file;
139 int i, k;
140 file=fopen(EXTIO_LIB_FILENAME,"r");
141 if(file == NULL)
142   {
143   ui.use_extio=0;
144   sprintf(s,"Unknown file in %s",EXTIO_LIB_FILENAME);
145   return;
146   }
147 k=fread(s,1,BUFFER_SIZE,file);
148 if(k==BUFFER_SIZE)lirerr(1317);
149 fclose(file);
150 for(i=0; i<BUFFER_SIZE; i++)
151   {
152   if( s[i]==0 ||
153       s[i]==10 ||
154       s[i]==13)
155     {
156     s[i]=0;
157     return;
158     }
159   }
160 }
161 
get_extio_name(char * name)162 void get_extio_name(char *name)
163 {
164 int i,j;
165 char s[BUFFER_SIZE];
166 get_library_filename(&s[0]);
167 i=0;
168 while(s[i] != 0)
169   {
170   if(strncmp("ExtIO",&s[i],5) == 0)
171     {
172     j=0;
173     while(s[i]!='.' && s[i]!=0 && j<40)
174       {
175       name[j]=s[i];
176       i++;
177       j++;
178       }
179     name[j]=0;
180     return;
181     }
182   i++;
183   }
184 name[0]=0;
185 }
186 
set_extio_uiparm(void)187 void set_extio_uiparm(void)
188 {
189 char s[BUFFER_SIZE], ss[80];
190 int line;
191 get_library_filename(&s[0]);
192 lir_text(28,3,s);
193 line=10;
194 sprintf(s,"Name:  %s",extio_name);
195 lir_text(0,6,s);
196 sprintf(s,"Model: %s",extio_model);
197 lir_text(0,7,s);
198 sprintf(s,"Type:");
199 lir_text(0,8,s);
200 if( (ui.use_extio&EXTIO_INVERTED) != 0)
201   {
202   s[0]=0;
203   }
204 else
205   {
206   sprintf(s,"non-");
207   }
208 sprintf(ss,"Spectrum: %sinverted",s);
209 lir_text(2,line,ss);
210 line+=2;
211 switch(ui.extio_type)
212   {
213   case 1:
214   case 3:
215   lir_text(7,8,"int 16bit dll callback");
216   ui.rx_input_mode=IQ_DATA;
217   goto prt_callb;
218 
219   case 4:
220   lir_text(7,8,"Soundcard input");
221   lir_text(2,line,"Select the appropriate sound device");
222   break;
223 
224   case 5:
225   case 8:
226   lir_text(7,8,"int 24bit dll callback");
227   ui.rx_input_mode=IQ_DATA+BYTE_INPUT+DWORD_INPUT;
228   goto prt_callb;
229 
230   case 6:
231   lir_text(7,8,"int 32bit dll callback");
232   ui.rx_input_mode=IQ_DATA+DWORD_INPUT+QWORD_INPUT;
233   goto prt_callb;
234 
235   case 7:
236   lir_text(7,8,"float 32bit dll callback");
237   ui.rx_input_mode=IQ_DATA+DWORD_INPUT+FLOAT_INPUT;
238 prt_callb:;
239   lir_text(2,line,
240      "Set sampling speed and other parameters in the ExtIO window");
241   ui.rx_addev_no=EXTIO_DEVICE_CODE;
242   break;
243 
244   default:
245   lirerr(1341);
246   return;
247   }
248 line+=2;
249 lir_text(7,line,press_any_key);
250 await_processed_keyboard();
251 }
252 
253 
callback_extio(int cnt,int status,float IQoffs,short * IQdata)254 void callback_extio(int cnt, int status, float IQoffs, short *IQdata)
255 {
256 char *ch, *dh;
257 int *iz, *ix;
258 float *z;
259 int i, j;
260 (void) IQoffs;
261 if(kill_all_flag || timf1p_sdr == -1)goto skip;
262 switch(status)
263   {
264   case EXTIO_FREQ_CHANGED:
265   if(GetHWLO)
266     {
267     fg.passband_center = (double)(GetHWLO()) / 1e6;
268     set_hardware_rx_frequency();
269     }
270   break;
271 
272   case EXTIO_RF_GAIN_CHANGED:
273   if(GetRFGain)
274     {
275     fg.gain = GetRFGain();
276     if(fg.gain > RF_GAIN_UP_LIMIT) fg.gain = RF_GAIN_UP_LIMIT;
277     if(fg.gain < RF_GAIN_LOW_LIMIT) fg.gain = RF_GAIN_LOW_LIMIT;
278     fg.gain_increment = 1;
279     show_hardware_gain();
280     }
281   break;
282 
283   case EXTIO_SAMPRATE_CHANGED:
284   if(ui.extio_type != 4)
285     {
286     if(!GetHWSR)
287       {
288       lirerr(131600);
289       }
290     if(ui.rx_ad_speed!=GetHWSR())extio_speed_changed=TRUE;
291     }
292   break;
293   }
294 if(ui.extio_type == 4 || cnt < 0)return;
295 if(cnt >= 0 && thread_status_flag[THREAD_EXTIO_INPUT] == THRFLAG_ACTIVE)
296   {
297   extio_cnt=cnt;
298   switch(ui.extio_type)
299     {
300     case 1:
301     case 3:
302     case 6:
303     ix=(int*)IQdata;
304     j=extio_read_bytes/4;
305     for(i=0; i<j; i++)
306       {
307       iz=(int*)&timf1_char[timf1p_sdr];
308       iz[0]=ix[i];
309       timf1p_sdr=(timf1p_sdr+4)&timf1_bytemask;
310       }
311     break;
312 
313     case 5:
314     case 8:
315     ch=(char*)IQdata;
316     j=extio_read_bytes>>2;
317     for(i=0; i<j; i+=2)
318       {
319       dh=&timf1_char[timf1p_sdr];
320       dh[3]=ch[3*i+2];
321       dh[2]=ch[3*i+1];
322       dh[1]=ch[3*i  ];
323       dh[0]=0;
324       dh[7]=ch[3*i+5];
325       dh[6]=ch[3*i+4];
326       dh[5]=ch[3*i+3];
327       dh[4]=0;
328       timf1p_sdr=(timf1p_sdr+8)&timf1_bytemask;
329       }
330     break;
331 
332     case 7:
333     z=(float*)IQdata;
334     j=extio_read_bytes>>2;
335     for(i=0; i<j; i++)
336       {
337       iz=(int*)&timf1_char[timf1p_sdr];
338       iz[0]=(int)((float)0x7fffffff*z[i]);
339       timf1p_sdr=(timf1p_sdr+4)&timf1_bytemask;
340       }
341     break;
342     }
343   if( ((timf1p_sdr-timf1p_pa+timf1_bytes)&timf1_bytemask) >=
344                                                      snd[RXAD].block_bytes)
345     {
346 skip:;
347     lir_set_event(EVENT_EXTIO_RXREADY);
348     }
349   }
350 }
351 
352 
353 #if(OSNUM == OSNUM_LINUX)
354 
355 #include <dirent.h>
356 #include <sys/types.h>
357 #include <sys/param.h>
358 #include <dlfcn.h>
359 #include <semaphore.h>
360 
361 #include "thrdef.h"
362 #include "lconf.h"
363 #include "ldef.h"
364 
365 #if(IA64 == 0)
366 char *dirs[]={"./",
367               "/lib",
368               "/lib32",
369               "/usr/lib",
370               "/usr/lib32",
371               "/usr/lib32/lib",
372               "%%LOCALBASE%%/lib",
373               "/usr/local32/lib",
374               "/emul/ia32-linux/lib",
375               "/emul/ia32-linux/usr/lib",
376               "/usr/lib/i386-linux-gnu",
377               "X"};
378 #else
379 char *dirs[]={"./",
380               "/lib",
381               "/lib64",
382               "/usr/lib",
383               "/usr/lib64",
384               "%%LOCALBASE%%/lib",
385               "/usr/lib/x86_64-linux-gnu",
386               "X"};
387 #endif
388 
389 
init_extio(void)390 void init_extio(void)
391 {
392 char extio_lib_names[MAX_EXTIO_FILES][BUFFER_SIZE];
393 DIR *dirp;
394 char s[BUFFER_SIZE];
395 int i, m, num_extio;
396 int lineno;
397 struct dirent *dp;
398 i=0;
399 lineno=0;
400 lir_text(10,1,"Seaching libraries for ExtIO files");
401 lir_refresh_screen();
402 while(dirs[i][0] != 'X' && lineno < MAX_EXTIO_FILES)
403   {
404   dirp=opendir(dirs[i]);
405   if(dirp != NULL)
406     {
407 next_file:;
408     dp=readdir(dirp);
409     if(dp != NULL)
410       {
411       m=strncmp("libExtIO",dp->d_name,8);
412       if(m == 0)
413         {
414         sprintf(extio_lib_names[lineno],"%s/%s", dirs[i], dp->d_name);
415         sprintf(s,"%2d %s",lineno,extio_lib_names[lineno]);
416         lir_text(3,lineno+4,s);
417         lineno++;
418         if(lineno >= MAX_EXTIO_FILES || lineno+4 > screen_last_line)
419           {
420           settextcolor(12);
421           lir_text(3,lineno+4,"Too many ExtIO libraries");
422           settextcolor(7);
423           goto skip;
424           }
425         }
426       goto next_file;
427       }
428     closedir(dirp);
429     }
430   i++;
431   }
432 skip:;
433 if(lineno == 0)
434   {
435   lir_text(8,lineno+6,"No libExtIO_xxx.so file found");
436   lir_text(5,lineno+8,press_any_key);
437   await_keyboard();
438   return;
439   }
440 else
441   {
442   lir_text(8,lineno+6,"Select libExtIO_xxx.so file by line number:");
443   num_extio=lir_get_integer(51,lineno+6,2,0,lineno-1);
444   if(kill_all_flag)return;
445   }
446 write_extio_parfile(extio_lib_names[num_extio]);
447 if(ui.use_extio != 0)
448   {
449   command_extio_library(EXTIO_COMMAND_LOAD_DLL);
450   if(!extio_handle)
451     {
452     lir_text(8,lineno+6,"Loading libExtIO_xxx.so failed.");
453     lir_text(5,lineno+8,press_any_key);
454     await_keyboard();
455     return;
456     }
457   set_extio_uiparm();
458   }
459 lir_sleep(10000);
460 if(extio_handle)
461   {
462 // Start and stop so we get all the parameters into the ui structure.
463   timf1p_pa=-1;
464   extio_show_gui=FALSE;
465   command_extio_library(EXTIO_COMMAND_START);
466   command_extio_library(EXTIO_COMMAND_STOP);
467   command_extio_library(EXTIO_COMMAND_UNLOAD_DLL);
468   }
469 }
470 
command_extio_library(int load)471 void command_extio_library(int load)
472 {
473 extio_command_flag=load;
474 lir_set_event(EVENT_MANAGE_EXTIO);
475 if(load==EXTIO_COMMAND_KILL_ALL)return;
476 while(extio_command_flag != EXTIO_COMMAND_DONE)
477   {
478   lir_sleep(20000);
479   }
480 }
481 
load_extio_library(void)482 int load_extio_library(void)
483 {
484 char s[BUFFER_SIZE];
485 int errcod;
486 if(extio_handle != NULL)
487   {
488   lirerr(675433);
489   return 99;
490   }
491 clear_screen();
492 lir_text(3,3,"LOADING ExtIO LIBRARY");
493 lir_refresh_screen();
494 get_library_filename(&s[0]);
495 if(ui.use_extio==0)return 1;
496 extio_handle=dlopen(s, RTLD_LAZY);
497 if( extio_handle==NULL) return 2;
498 OpenHW = (pOpenHW)dlsym(extio_handle, "OpenHW");
499 if(dlerror() != 0)
500   {
501   errcod=3;
502   OpenHW=NULL;
503   goto errexit;
504   }
505 SetHWLO = (pSetHWLO) dlsym(extio_handle,"SetHWLO");
506 if(dlerror() != NULL)
507   {
508   errcod=4;
509   goto errexit;
510   }
511 CloseHW = (pCloseHW) dlsym(extio_handle,"CloseHW");
512 if(dlerror() != NULL)
513   {
514   errcod=5;
515   goto errexit;
516   }
517 SetCallback = (pSetCallback) dlsym(extio_handle, "SetCallback");
518 if(dlerror() != NULL)
519   {
520   errcod=6;
521   goto errexit;
522   }
523 InitHW = (pInitHW) dlsym(extio_handle, "InitHW");
524 if(dlerror() != NULL)
525   {
526   errcod=7;
527   goto errexit;
528   }
529 StopHW = (pStopHW) dlsym(extio_handle, "StopHW");
530 if(dlerror() != NULL)
531   {
532   errcod=8;
533   goto errexit;
534   }
535 ShowGUI = (pShowGUI) dlsym(extio_handle, "ShowGUI");
536 if(dlerror() != NULL)ShowGUI=NULL;
537 HideGUI = (pHideGUI) dlsym(extio_handle, "HideGUI");
538 if(dlerror() != NULL)HideGUI=NULL;
539 StartHW = (pStartHW) dlsym(extio_handle, "StartHW");
540 if(dlerror() != NULL)StartHW=NULL;
541 TuneChanged = (pTuneChanged) dlsym(extio_handle, "TuneChanged");
542 if(dlerror() != NULL)TuneChanged=NULL;
543 GetHWLO = (pGetHWLO) dlsym(extio_handle, "GetHWLO");
544 if(dlerror() != NULL)GetHWLO=NULL;
545 GetHWSR = (pGetHWSR) dlsym(extio_handle, "GetHWSR");
546 if(dlerror() != NULL)GetHWSR=NULL;
547 SetRFGain = (pSetRFGain) dlsym(extio_handle, "SetRFGain");
548 if(dlerror() != NULL)SetRFGain=NULL;
549 GetRFGain = (pGetRFGain) dlsym(extio_handle, "GetRFGain");
550 if(dlerror() != NULL)GetRFGain=NULL;
551 errcod=InitHW(extio_name, extio_model, &ui.extio_type);
552 if(ui.extio_type == 2)ui.extio_type=4;
553 if(!errcod)
554   {
555   errcod=9;
556   goto errexit;
557   }
558 if(kill_all_flag)return 99;
559 extio_running=1;
560 return 0;
561 errexit:;
562 unload_extio_library();
563 return errcod;
564 }
565 
unload_extio_library(void)566 void unload_extio_library(void)
567 {
568 if(extio_running == 2)stop_extio();
569 dlclose(extio_handle);
570 extio_handle=NULL;
571 lir_sched_yield();
572 }
573 
574 
575 
576 #endif
577 
578 #if(OSNUM == OSNUM_WINDOWS)
579 #include "wdef.h"
580 
init_extio(void)581 void init_extio(void)
582 {
583 char s[BUFFER_SIZE];
584 char dirnam[BUFFER_SIZE];
585 WIN32_FIND_DATA file_data;
586 UINT charnum;
587 HANDLE find_handle;
588 char extio_lib_names[MAX_EXTIO_FILES][BUFFER_SIZE];
589 int i, num_extio;
590 int lineno;
591 i=0;
592 lineno=0;
593 lir_text(10,1,"Seaching libraries for ExtIO files");
594 lir_refresh_screen();
595 charnum=0;
596 while(i < 2)
597   {
598   if(i == 0)
599     {
600     charnum=GetCurrentDirectory(BUFFER_SIZE, dirnam);
601     }
602   if(i == 1)
603     {
604     charnum=GetSystemDirectory(dirnam,BUFFER_SIZE);
605     }
606   sprintf(&dirnam[charnum],"\\Extio*.dll");
607   find_handle=FindFirstFile(dirnam, &file_data);
608   if(find_handle == INVALID_HANDLE_VALUE)goto nomore;
609 more:;
610   if(i==0)
611     {
612     sprintf(extio_lib_names[lineno],"%s",file_data.cFileName);
613     sprintf(s,"%2d %s",lineno,extio_lib_names[lineno]);
614     lir_text(3,lineno+4,s);
615     lineno++;
616     }
617   sprintf(extio_lib_names[lineno],"%s", dirnam);
618   sprintf(&extio_lib_names[lineno][charnum+1],"%s",file_data.cFileName);
619   sprintf(s,"%2d %s",lineno,extio_lib_names[lineno]);
620   lir_text(3,lineno+4,s);
621   lineno++;
622   if(lineno >= MAX_EXTIO_FILES || lineno+4 > screen_last_line)goto max;
623   if(FindNextFile(find_handle, &file_data))goto more;
624 nomore:;
625   if(find_handle != INVALID_HANDLE_VALUE)FindClose(find_handle);
626   i++;
627   if(lineno >= MAX_EXTIO_FILES || lineno+4 > screen_last_line)
628     {
629 max:;
630     settextcolor(12);
631     lir_text(3,lineno+4,"Too many ExtIO libraries");
632     settextcolor(7);
633     goto skip;
634     }
635   }
636 skip:;
637 if(lineno == 0)
638   {
639   lir_text(8,lineno+6,"No ExtIOxxx.dll file found");
640   lir_text(5,lineno+8,press_any_key);
641   await_keyboard();
642   return;
643   }
644 else
645   {
646   lir_text(8,lineno+6,"Select ExtIO_xxx.dll file by line number:");
647   num_extio=lir_get_integer(51,lineno+6,2,0,lineno-1);
648   if(kill_all_flag)return;
649   }
650 write_extio_parfile(extio_lib_names[num_extio]);
651 if(ui.use_extio != 0)
652   {
653   command_extio_library(EXTIO_COMMAND_LOAD_DLL);
654   if(!extio_handle)
655     {
656     lir_text(8,lineno+6,"Loading libExtIO_xxx.so failed.");
657     lir_text(5,lineno+8,press_any_key);
658     await_keyboard();
659     return;
660     }
661   set_extio_uiparm();
662   }
663 lir_sleep(10000);
664 if(extio_handle)
665   {
666 // Start and stop so we get all the parameters into the ui structure.
667   timf1p_pa=-1;
668   extio_show_gui=FALSE;
669   command_extio_library(EXTIO_COMMAND_START);
670   command_extio_library(EXTIO_COMMAND_STOP);
671   command_extio_library(EXTIO_COMMAND_UNLOAD_DLL);
672   }
673 }
674 
command_extio_library(int load)675 void command_extio_library(int load)
676 {
677 extio_command_flag=load;
678 PostMessage(linrad_hwnd, WM_USER, load, 0);
679 if(load==EXTIO_COMMAND_KILL_ALL)return;
680 while(extio_command_flag != EXTIO_COMMAND_DONE)
681   {
682   lir_sleep(20000);
683   }
684 }
685 
load_extio_library(void)686 int load_extio_library(void)
687 {
688 char s[BUFFER_SIZE];
689 int errcod;
690 if(extio_handle != NULL)
691   {
692   lirerr(675433);
693   return 99;
694   }
695 clear_screen();
696 lir_text(3,3,"LOADING ExtIO LIBRARY");
697 lir_refresh_screen();
698 get_library_filename(&s[0]);
699 if(ui.use_extio==0)return 1;
700 extio_handle=LoadLibrary(s);
701 if(extio_handle == NULL)return 2;
702 OpenHW = (pOpenHW)GetProcAddress(extio_handle, "OpenHW");
703 if(!OpenHW)
704   {
705   errcod=3;
706   goto errexit;
707   }
708 SetHWLO = (pSetHWLO) GetProcAddress(extio_handle, "SetHWLO");
709 if(!SetHWLO)
710   {
711   errcod=4;
712   goto errexit;
713   }
714 CloseHW = (pCloseHW) GetProcAddress(extio_handle, "CloseHW");
715 if(!CloseHW)
716   {
717   errcod=5;
718   goto errexit;
719   }
720 SetCallback = (pSetCallback) GetProcAddress(extio_handle, "SetCallback");
721 if(!SetCallback)
722   {
723   errcod=6;
724   goto errexit;
725   }
726 InitHW = (pInitHW) GetProcAddress(extio_handle, "InitHW");
727 if(!InitHW)
728   {
729   errcod=7;
730   goto errexit;
731   }
732 StopHW = (pStopHW) GetProcAddress(extio_handle, "StopHW");
733 if(!StopHW)
734   {
735   errcod=8;
736   goto errexit;
737   }
738 ShowGUI = (pShowGUI) GetProcAddress(extio_handle, "ShowGUI");
739 HideGUI = (pHideGUI) GetProcAddress(extio_handle, "HideGUI");
740 StartHW = (pStartHW) GetProcAddress(extio_handle, "StartHW");
741 TuneChanged = (pTuneChanged) GetProcAddress(extio_handle, "TuneChanged");
742 GetHWLO = (pGetHWLO) GetProcAddress(extio_handle, "GetHWLO");
743 SetRFGain = (pSetRFGain) GetProcAddress(extio_handle, "SetRFGain");
744 GetRFGain = (pGetRFGain) GetProcAddress(extio_handle, "GetRFGain");
745 GetHWSR = (pGetHWSR) GetProcAddress(extio_handle, "GetHWSR");
746 CoInitialize(NULL);
747 errcod=InitHW(extio_name, extio_model, &ui.extio_type);
748 extio_running=1;
749 if(ui.extio_type == 2)ui.extio_type=4;
750 if(errcod <= 0)
751   {
752   errcod=9;
753   CoUninitialize();
754   goto errexit;
755   }
756 if(kill_all_flag)return 99;
757 return 0;
758 errexit:;
759 unload_extio_library();
760 return errcod;
761 }
762 
unload_extio_library(void)763 void unload_extio_library(void)
764 {
765 if(extio_running == 2)
766   {
767   stop_extio();
768   }
769 FreeLibrary(extio_handle);
770 extio_handle=NULL;
771 CoUninitialize();
772 lir_sched_yield();
773 }
774 #endif
775 
776 
first_check_extio(void)777 void first_check_extio(void)
778 {
779 char s[BUFFER_SIZE];
780 if(extio_handle == NULL)
781   {
782   clear_screen();
783   get_library_filename(&s[0]);
784   lir_text(3,3,"ERROR: dynamic library for ExtIO failed.");
785   lir_text(3,5,s);
786   lir_text(3,7,"Use of this library is disabled. Press W on the main menu");
787   lir_text(3,8,"if you want to disable it permanently.");
788   lir_text(8,11,press_any_key);
789   await_processed_keyboard();
790   ui.use_extio=0;
791   return;
792   }
793 }
794 
start_extio(void)795 void start_extio(void)
796 {
797 char s[80];
798 int i, errcod, siz;
799 long TuneFreq;
800 if( extio_handle == NULL)
801   {
802   lirerr(522156);
803   return;
804   }
805 clear_screen();
806 lir_text(3,3,"Starting input hardware using ExtIO library.");
807 lir_text(3,4,"Note that it may take 10 seconds until the Extio GUI appears");
808 settextcolor(15);
809 lir_text(3,7,"Move mouse into ExtIO window if Linrad hangs here.");
810 settextcolor(7);
811 lir_init_event(EVENT_EXTIO_RXREADY);
812 lir_text(15,13,"Calling SetCallback");
813 lir_refresh_screen();
814 SetCallback(callback_extio);
815 lir_text(15,13,"SetCallback OK     ");
816 lir_refresh_screen();
817 lir_text(15,14,"Calling OpenHW");
818 lir_refresh_screen();
819 errcod=OpenHW();
820 if(errcod < 1)
821   {
822   lir_text(15,14,"OpenHW returned an ERROR");
823   lir_refresh_screen();
824   unload_extio_library();
825   lirerr(1346);
826   return;
827   }
828 lir_text(15,14,"OpenHW OK     ");
829 lir_refresh_screen();
830 fg.gain_increment = 1;
831 if(abs(fg.passband_direction) != 1)fg.passband_direction=1;
832 if(fg.passband_increment < 0.0001 || fg.passband_increment > 1.5)
833   {
834   fg.passband_increment=.01;
835   }
836 if(fg.passband_center == 0)fg.passband_center=7;
837 
838 fg.passband_center=144;
839 TuneFreq = (long)(1000000L*fg.passband_center);
840 lir_text(15,15,"Calling StartHW");
841 lir_refresh_screen();
842 extio_cnt=0;
843 siz=StartHW(TuneFreq);
844 sprintf(s,"StartHW returned size = %d   type = %d",siz,ui.extio_type);
845 lir_text(15,15,s);
846 lir_refresh_screen();
847 switch(ui.extio_type)
848   {
849   case 1:
850   case 3:
851 // 16 bit integer
852   ui.rx_input_mode=IQ_DATA;
853   snd[RXAD].framesize=4;
854   break;
855 
856   case 4:
857   break;
858 
859   case 5:
860   case 8:
861 // 24 bit integer
862   ui.rx_input_mode=IQ_DATA+BYTE_INPUT+DWORD_INPUT;
863   snd[RXAD].framesize=8;
864   break;
865 
866   case 6:
867 // 32 bit integer
868   ui.rx_input_mode=IQ_DATA+DWORD_INPUT+QWORD_INPUT;
869   snd[RXAD].framesize=8;
870   break;
871 
872   case 7:
873 // 32 bit float
874   ui.rx_input_mode=IQ_DATA+DWORD_INPUT+FLOAT_INPUT;
875   snd[RXAD].framesize=8;
876   break;
877 
878   default:
879   lirerr(984546);
880   break;
881   }
882 if(ui.extio_type < 1 || ui.extio_type > 8)
883   {
884   lirerr(1239);
885   return;
886   }
887 if(ui.extio_type != 4)
888   {
889   if(siz <= 0)
890     {
891     i=30;
892     while(extio_cnt == 0 && i>0)
893       {
894       lir_sleep(100000);
895       i--;
896       }
897     siz=extio_cnt;
898     }
899   if(siz == 0)
900     {
901     lirerr(1344);
902     return;
903     }
904   if(siz < 0)
905     {
906     lirerr(1347);
907     return;
908     }
909   extio_read_bytes=siz*snd[RXAD].framesize;
910   if(!GetHWSR)
911     {
912     lirerr(1316);
913     return;
914     }
915   if(ui.rx_ad_speed!=GetHWSR())extio_speed_changed=TRUE;
916   timf1p_sdr=timf1p_pa;
917   make_power_of_two(&siz);
918   snd[RXAD].block_frames=siz;
919   snd[RXAD].block_bytes=snd[RXAD].framesize*siz;
920   snd[RXAD].interrupt_rate=ui.rx_ad_speed/siz;
921   }
922 lir_refresh_screen();
923 if(ui.extio_type != 4)
924   {
925   if(!GetHWSR)
926     {
927     lirerr(1316);
928     return;
929     }
930   i=ui.rx_ad_speed;
931   ui.rx_ad_speed=GetHWSR();
932   if(i == ui.rx_ad_speed)
933     {
934     extio_speed_changed=FALSE;
935     }
936   else
937     {
938     extio_speed_changed=TRUE;
939     }
940   ui.rx_rf_channels=1;
941   ui.rx_ad_channels=2;
942   }
943 extio_start_time=current_time();
944 extio_running=2;
945 clear_screen();
946 if(ShowGUI != NULL)
947   {
948   if(extio_show_gui)ShowGUI();
949   }
950 else
951   {
952   extio_show_gui=FALSE;
953   }
954 }
955 
stop_extio(void)956 void stop_extio(void)
957 {
958 char s[80];
959 if(extio_running != 2)
960   {
961   lirerr(659473);
962   return;
963   }
964 clear_screen();
965 if(HideGUI != NULL)
966   {
967   if(extio_show_gui)HideGUI();
968   lir_sleep(30000);
969   }
970 while(current_time()-extio_start_time < 4)
971   {
972   sprintf(s,"Waiting before stop %.2f",4-current_time()+extio_start_time);
973   lir_text(3,8,s);
974   lir_refresh_screen();
975   lir_sleep(200000);
976   }
977 StopHW();
978 lir_close_event(EVENT_EXTIO_RXREADY);
979 CloseHW();
980 extio_running=1;
981 }
982 
update_extio_rx_freq(void)983 void update_extio_rx_freq(void)
984 {
985 long TuneFreq;
986 if(extio_running != 2)return;
987 TuneFreq = (long)(1000000L*fg.passband_center);
988 SetHWLO(TuneFreq);
989 }
990 
update_extio_rx_gain(void)991 void update_extio_rx_gain(void)
992 {
993 if(extio_running == 2 && SetRFGain)
994   {
995   if(fg.gain > RF_GAIN_UP_LIMIT) fg.gain = RF_GAIN_UP_LIMIT;
996   if(fg.gain < RF_GAIN_LOW_LIMIT) fg.gain = RF_GAIN_LOW_LIMIT;
997   SetRFGain(fg.gain);
998   }
999 }
1000 
extio_input(void)1001 void extio_input(void)
1002 {
1003 #if RUSAGE_OLD == TRUE
1004 int local_workload_counter;
1005 #endif
1006 int errcod;
1007 int rxin_local_workload_reset;
1008 double read_start_time, total_reads;
1009 int timing_loop_counter,timing_loop_counter_max,initial_skip_flag;
1010 #if OSNUM == OSNUM_LINUX
1011 clear_thread_times(THREAD_EXTIO_INPUT);
1012 #endif
1013 #if RUSAGE_OLD == TRUE
1014 local_workload_counter=workload_counter;
1015 #endif
1016 errcod=0;
1017 fft1_block_timing();
1018 if(thread_command_flag[THREAD_SCREEN]!=THRFLAG_NOT_ACTIVE)
1019   {
1020   while(thread_status_flag[THREAD_SCREEN]!=THRFLAG_ACTIVE &&
1021         thread_status_flag[THREAD_SCREEN]!=THRFLAG_IDLE &&
1022         thread_status_flag[THREAD_SCREEN]!=THRFLAG_SEM_WAIT)
1023     {
1024     if(thread_command_flag[THREAD_EXTIO_INPUT] == THRFLAG_KILL)goto extio_exit;
1025     lir_sleep(10000);
1026     }
1027   }
1028 thread_status_flag[THREAD_EXTIO_INPUT]=THRFLAG_ACTIVE;
1029 update_extio_rx_freq();
1030 update_extio_rx_gain();
1031 #include "timing_setup.c"
1032 while(thread_command_flag[THREAD_EXTIO_INPUT] == THRFLAG_ACTIVE)
1033   {
1034 #if RUSAGE_OLD == TRUE
1035   if(local_workload_counter != workload_counter)
1036     {
1037     local_workload_counter=workload_counter;
1038     make_thread_times(THREAD_EXTIO_INPUT);
1039     }
1040 #endif
1041   while( thread_command_flag[THREAD_EXTIO_INPUT] == THRFLAG_ACTIVE &&
1042          !kill_all_flag &&
1043          ((timf1p_sdr-timf1p_pa+timf1_bytes)&timf1_bytemask) <
1044                                                      (int)snd[RXAD].block_bytes)
1045     {
1046     lir_await_event(EVENT_EXTIO_RXREADY);
1047     }
1048   while (!kill_all_flag && ((timf1p_sdr-timf1p_pa+timf1_bytes)&
1049                         timf1_bytemask) >= (int)snd[RXAD].block_bytes)
1050     {
1051 #include "input_speed.c"
1052     finish_rx_read();
1053     }
1054   if(kill_all_flag)goto extio_exit;
1055   if(extio_speed_changed)
1056     {
1057     while(keyboard_buffer_ptr != keyboard_buffer_used)lir_sleep(1000);
1058     keyboard_buffer[keyboard_buffer_used]='X';
1059     keyboard_buffer_ptr=(keyboard_buffer_ptr+1)&(KEYBOARD_BUFFER_SIZE-1);
1060     lir_sleep(10000);
1061     lir_set_event(EVENT_KEYBOARD);
1062     lir_sleep(100000);
1063     if(lir_inkey == 'X')extio_speed_changed=FALSE;
1064     if(kill_all_flag)goto extio_exit;
1065     }
1066   }
1067 extio_exit:;
1068 if(errcod != 0)lirerr(errcod);
1069 thread_status_flag[THREAD_EXTIO_INPUT]=THRFLAG_RETURNED;
1070 while(thread_command_flag[THREAD_EXTIO_INPUT] != THRFLAG_NOT_ACTIVE)
1071   {
1072   lir_sleep(1000);
1073   }
1074 }
1075 
1076