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 #include <errno.h>
24 #include <signal.h>
25 #include <string.h>
26 #include <stdint.h>
27 
28 #include "globdef.h"
29 #include "uidef.h"
30 #include "sdrdef.h"
31 #include "conf.h"
32 #include "fft1def.h"
33 #include "screendef.h"
34 #include "rusage.h"
35 #include "thrdef.h"
36 #include "options.h"
37 #include "vernr.h"
38 #include "hwaredef.h"
39 
40 
41 
42 #define MAX_RTL2832_SAMP_RATE_H  2400000
43 #define MIN_RTL2832_SAMP_RATE_H  900001
44 #define MAX_RTL2832_SAMP_RATE_L  300000
45 #define MIN_RTL2832_SAMP_RATE_L  230000
46 
47 
48 typedef struct rtlsdr_dev rtlsdr_dev_t;
49 typedef void(*rtlsdr_read_async_cb_t)(unsigned char *buf,
50                                         uint32_t len, void *ctx);
51 
52 static rtlsdr_dev_t *dev_rtlsdr;
53 
54 char *rtl2832_parm_text[MAX_RTL2832_PARM]={"Sampling speed",
55                                      "Serno1",
56                                      "Serno2",
57                                      "Serno3",
58                                      "Gain mode",
59                                      "Freq adjust",
60                                      "Direct sampling",
61                                      "Check"};
62 
63 char *rtl2832_parfil_name="par_rtl2832";
64 int rtlsdr_library_flag;
65 P_RTL2832 rtl2832;
66 
67 typedef int (*p_rtlsdr_close)(rtlsdr_dev_t *dev);
68 typedef int (*p_rtlsdr_open)(rtlsdr_dev_t **dev, uint32_t index);
69 typedef int (*p_rtlsdr_get_device_usb_strings)(uint32_t index,
70 					       char *manufact,
71 					       char *product,
72 					       char *serial);
73 typedef int (*p_rtlsdr_get_tuner_gains)(rtlsdr_dev_t *dev, int *gains);
74 typedef int (*p_rtlsdr_set_sample_rate)(rtlsdr_dev_t *dev, uint32_t rate);
75 typedef int (*p_rtlsdr_set_tuner_gain_mode)(rtlsdr_dev_t *dev, int manual);
76 typedef int (*p_rtlsdr_set_tuner_gain)(rtlsdr_dev_t *dev, int gain);
77 typedef int (*p_rtlsdr_set_center_freq)(rtlsdr_dev_t *dev, uint32_t freq);
78 typedef int (*p_rtlsdr_read_async)(rtlsdr_dev_t *dev,
79 				   rtlsdr_read_async_cb_t cb,
80 				   void *ctx,
81 				   uint32_t buf_num,
82 				   uint32_t buf_len);
83 typedef int (*p_rtlsdr_cancel_async)(rtlsdr_dev_t *dev);
84 typedef int (*p_rtlsdr_set_direct_sampling)(rtlsdr_dev_t *dev, int on);
85 typedef int (*p_rtlsdr_set_agc_mode)(rtlsdr_dev_t *dev, int on);
86 typedef uint32_t (*p_rtlsdr_get_sample_rate)(rtlsdr_dev_t *dev);
87 typedef uint32_t (*p_rtlsdr_get_device_count)(void);
88 typedef int (*p_rtlsdr_reset_buffer)(rtlsdr_dev_t *dev);
89 typedef const char* (*p_rtlsdr_get_device_name)(uint32_t index);
90 
91 
92 p_rtlsdr_reset_buffer rtlsdr_reset_buffer;
93 p_rtlsdr_get_device_name rtlsdr_get_device_name;
94 p_rtlsdr_get_device_count rtlsdr_get_device_count;
95 p_rtlsdr_get_sample_rate rtlsdr_get_sample_rate;
96 p_rtlsdr_set_agc_mode rtlsdr_set_agc_mode;
97 p_rtlsdr_set_direct_sampling rtlsdr_set_direct_sampling;
98 p_rtlsdr_cancel_async rtlsdr_cancel_async;
99 p_rtlsdr_set_center_freq rtlsdr_set_center_freq;
100 p_rtlsdr_close rtlsdr_close;
101 p_rtlsdr_open rtlsdr_open;
102 p_rtlsdr_get_device_usb_strings rtlsdr_get_device_usb_strings;
103 p_rtlsdr_get_tuner_gains rtlsdr_get_tuner_gains;
104 p_rtlsdr_set_sample_rate rtlsdr_set_sample_rate;
105 p_rtlsdr_set_tuner_gain_mode rtlsdr_set_tuner_gain_mode;
106 p_rtlsdr_set_tuner_gain rtlsdr_set_tuner_gain;
107 p_rtlsdr_read_async rtlsdr_read_async;
108 
109 
110 #if(OSNUM == OSNUM_WINDOWS)
111 #include <windows.h>
112 HANDLE rtlsdr_libhandle;
113 
load_rtlsdr_library(void)114 void load_rtlsdr_library(void)
115 {
116 int info;
117 if(rtlsdr_library_flag)return;
118 info=0;
119 rtlsdr_libhandle=LoadLibrary("rtlsdr.dll");
120 if(!rtlsdr_libhandle)goto rtlsdr_load_error;
121 info=1;
122 rtlsdr_reset_buffer=(p_rtlsdr_reset_buffer)GetProcAddress(rtlsdr_libhandle, "rtlsdr_reset_buffer");
123 if(!rtlsdr_reset_buffer)goto rtlsdr_sym_error;
124 rtlsdr_get_device_name=(p_rtlsdr_get_device_name)GetProcAddress(rtlsdr_libhandle, "rtlsdr_get_device_name");
125 if(!rtlsdr_get_device_name)goto rtlsdr_sym_error;
126 rtlsdr_get_device_count=(p_rtlsdr_get_device_count)GetProcAddress(rtlsdr_libhandle, "rtlsdr_get_device_count");
127 if(!rtlsdr_get_device_count)goto rtlsdr_sym_error;
128 rtlsdr_get_sample_rate=(p_rtlsdr_get_sample_rate)GetProcAddress(rtlsdr_libhandle, "rtlsdr_get_sample_rate");
129 if(!rtlsdr_get_sample_rate)goto rtlsdr_sym_error;
130 rtlsdr_set_agc_mode=(p_rtlsdr_set_agc_mode)GetProcAddress(rtlsdr_libhandle, "rtlsdr_set_agc_mode");
131 if(!rtlsdr_set_agc_mode)goto rtlsdr_sym_error;
132 rtlsdr_set_direct_sampling=(p_rtlsdr_set_direct_sampling)GetProcAddress(rtlsdr_libhandle, "rtlsdr_set_direct_sampling");
133 if(!rtlsdr_set_direct_sampling)goto rtlsdr_sym_error;
134 rtlsdr_cancel_async=(p_rtlsdr_cancel_async)GetProcAddress(rtlsdr_libhandle, "rtlsdr_cancel_async");
135 if(!rtlsdr_cancel_async)goto rtlsdr_sym_error;
136 rtlsdr_set_center_freq=(p_rtlsdr_set_center_freq)GetProcAddress(rtlsdr_libhandle, "rtlsdr_set_center_freq");
137 if(!rtlsdr_set_center_freq)goto rtlsdr_sym_error;
138 rtlsdr_close=(p_rtlsdr_close)GetProcAddress(rtlsdr_libhandle, "rtlsdr_close");
139 if(!rtlsdr_close)goto rtlsdr_sym_error;
140 rtlsdr_open=(p_rtlsdr_open)GetProcAddress(rtlsdr_libhandle, "rtlsdr_open");
141 if(!rtlsdr_open)goto rtlsdr_sym_error;
142 rtlsdr_get_device_usb_strings=(p_rtlsdr_get_device_usb_strings)GetProcAddress(rtlsdr_libhandle, "rtlsdr_get_device_usb_strings");
143 if(!rtlsdr_get_device_usb_strings)goto rtlsdr_sym_error;
144 rtlsdr_get_tuner_gains=(p_rtlsdr_get_tuner_gains)GetProcAddress(rtlsdr_libhandle, "rtlsdr_get_tuner_gains");
145 if(!rtlsdr_get_tuner_gains)goto rtlsdr_sym_error;
146 rtlsdr_set_sample_rate=(p_rtlsdr_set_sample_rate)GetProcAddress(rtlsdr_libhandle, "rtlsdr_set_sample_rate");
147 if(!rtlsdr_set_sample_rate)goto rtlsdr_sym_error;
148 rtlsdr_set_tuner_gain_mode=(p_rtlsdr_set_tuner_gain_mode)GetProcAddress(rtlsdr_libhandle, "rtlsdr_set_tuner_gain_mode");
149 if(!rtlsdr_set_tuner_gain_mode)goto rtlsdr_sym_error;
150 rtlsdr_set_tuner_gain=(p_rtlsdr_set_tuner_gain)GetProcAddress(rtlsdr_libhandle, "rtlsdr_set_tuner_gain");
151 if(!rtlsdr_set_tuner_gain)goto rtlsdr_sym_error;
152 rtlsdr_read_async=(p_rtlsdr_read_async)GetProcAddress(rtlsdr_libhandle, "rtlsdr_read_async");
153 if(!rtlsdr_read_async)goto rtlsdr_sym_error;
154 rtlsdr_library_flag=TRUE;
155 return;
156 rtlsdr_sym_error:;
157 FreeLibrary(rtlsdr_libhandle);
158 rtlsdr_load_error:;
159 library_error_screen("rtlsdr.dll",info);
160 return ;
161 }
162 
unload_rtlsdr_library(void)163 void unload_rtlsdr_library(void)
164 {
165 if(!rtlsdr_library_flag)return;
166 FreeLibrary(rtlsdr_libhandle);
167 rtlsdr_library_flag=FALSE;
168 }
169 #endif
170 
171 
172 
173 
174 
175 #if(OSNUM == OSNUM_LINUX)
176 #include <dlfcn.h>
177 void *rtlsdr_libhandle;
178 
load_rtlsdr_library(void)179 void load_rtlsdr_library(void)
180 {
181 int info;
182 if(rtlsdr_library_flag)return;
183 info=0;
184 rtlsdr_libhandle=dlopen(RTLSDR_LIBNAME, RTLD_LAZY);
185 if(!rtlsdr_libhandle)goto rtlsdr_load_error;
186 info=1;
187 rtlsdr_reset_buffer=(p_rtlsdr_reset_buffer)dlsym(rtlsdr_libhandle, "rtlsdr_reset_buffer");
188 if(dlerror() != 0)goto rtlsdr_sym_error;
189 rtlsdr_get_device_name=(p_rtlsdr_get_device_name)dlsym(rtlsdr_libhandle, "rtlsdr_get_device_name");
190 if(dlerror() != 0)goto rtlsdr_sym_error;
191 rtlsdr_get_device_count=(p_rtlsdr_get_device_count)dlsym(rtlsdr_libhandle, "rtlsdr_get_device_count");
192 if(dlerror() != 0)goto rtlsdr_sym_error;
193 rtlsdr_get_sample_rate=(p_rtlsdr_get_sample_rate)dlsym(rtlsdr_libhandle, "rtlsdr_get_sample_rate");
194 if(dlerror() != 0)goto rtlsdr_sym_error;
195 rtlsdr_set_agc_mode=(p_rtlsdr_set_agc_mode)dlsym(rtlsdr_libhandle, "rtlsdr_set_agc_mode");
196 if(dlerror() != 0)goto rtlsdr_sym_error;
197 rtlsdr_set_direct_sampling=(p_rtlsdr_set_direct_sampling)dlsym(rtlsdr_libhandle, "rtlsdr_set_direct_sampling");
198 if(dlerror() != 0)goto rtlsdr_sym_error;
199 rtlsdr_cancel_async=(p_rtlsdr_cancel_async)dlsym(rtlsdr_libhandle, "rtlsdr_cancel_async");
200 if(dlerror() != 0)goto rtlsdr_sym_error;
201 rtlsdr_set_center_freq=(p_rtlsdr_set_center_freq)dlsym(rtlsdr_libhandle, "rtlsdr_set_center_freq");
202 if(dlerror() != 0)goto rtlsdr_sym_error;
203 rtlsdr_close=(p_rtlsdr_close)dlsym(rtlsdr_libhandle, "rtlsdr_close");
204 if(dlerror() != 0)goto rtlsdr_sym_error;
205 rtlsdr_open=(p_rtlsdr_open)dlsym(rtlsdr_libhandle, "rtlsdr_open");
206 if(dlerror() != 0)goto rtlsdr_sym_error;
207 rtlsdr_get_device_usb_strings=(p_rtlsdr_get_device_usb_strings)dlsym(rtlsdr_libhandle, "rtlsdr_get_device_usb_strings");
208 if(dlerror() != 0)goto rtlsdr_sym_error;
209 rtlsdr_get_tuner_gains=(p_rtlsdr_get_tuner_gains)dlsym(rtlsdr_libhandle, "rtlsdr_get_tuner_gains");
210 if(dlerror() != 0)goto rtlsdr_sym_error;
211 rtlsdr_set_sample_rate=(p_rtlsdr_set_sample_rate)dlsym(rtlsdr_libhandle, "rtlsdr_set_sample_rate");
212 if(dlerror() != 0)goto rtlsdr_sym_error;
213 rtlsdr_set_tuner_gain_mode=(p_rtlsdr_set_tuner_gain_mode)dlsym(rtlsdr_libhandle, "rtlsdr_set_tuner_gain_mode");
214 if(dlerror() != 0)goto rtlsdr_sym_error;
215 rtlsdr_set_tuner_gain=(p_rtlsdr_set_tuner_gain)dlsym(rtlsdr_libhandle, "rtlsdr_set_tuner_gain");
216 if(dlerror() != 0)goto rtlsdr_sym_error;
217 rtlsdr_read_async=(p_rtlsdr_read_async)dlsym(rtlsdr_libhandle, "rtlsdr_read_async");
218 if(dlerror() != 0)goto rtlsdr_sym_error;
219 rtlsdr_library_flag=TRUE;
220 return;
221 rtlsdr_sym_error:;
222 dlclose(rtlsdr_libhandle);
223 rtlsdr_load_error:;
224 library_error_screen(RTLSDR_LIBNAME,info);
225 }
226 
unload_rtlsdr_library(void)227 void unload_rtlsdr_library(void)
228 {
229 if(!rtlsdr_library_flag)return;
230 dlclose(rtlsdr_libhandle);
231 rtlsdr_library_flag=FALSE;
232 }
233 #endif
234 
rtlsdr_callback(unsigned char * buf,uint32_t len,void * ctx)235 static  void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
236 {
237 (void) ctx;
238 unsigned int i;
239 short int *iz;
240 iz=(short int*)&timf1_char[timf1p_sdr];
241 for(i=0; i<len; i++)
242   {
243   iz[i]=(buf[i]+127)<<8;
244   }
245 timf1p_sdr=(timf1p_sdr+(len<<1))&timf1_bytemask;
246 if( ((timf1p_sdr-timf1p_pa+timf1_bytes)&timf1_bytemask) >=
247                                                      snd[RXAD].block_bytes)
248   {
249   lir_set_event(EVENT_HWARE1_RXREADY);
250   }
251 }
252 
set_rtl2832_att(void)253 void set_rtl2832_att(void)
254 {
255 if(rtl2832.gain_mode == 0)return;
256 rtlsdr_set_tuner_gain(dev_rtlsdr, old_rtl2832_gain);
257 }
258 
set_rtl2832_frequency(void)259 void set_rtl2832_frequency(void)
260 {
261 uint32_t frequency;
262 frequency=(fg.passband_center*(100000000-rtl2832.freq_adjust))/100;
263 rtlsdr_set_center_freq(dev_rtlsdr, frequency);
264 }
265 
rtl_starter(void)266 void rtl_starter(void)
267 {
268 int k, no_of_buffers;
269 k=snd[RXAD].block_bytes/2;
270 if(k < 512)k=512;
271 // Allocate buffers for 50 ms minimum.
272 no_of_buffers=(int)((0.1*rtl2832.sampling_speed)/k);
273 // Never use less than 4 buffers.
274 if(no_of_buffers < 4)no_of_buffers=4;
275 while(thread_status_flag[THREAD_RTL2832_INPUT]!=THRFLAG_ACTIVE)
276   {
277   lir_sleep(10000);
278   if(kill_all_flag)return;
279   }
280 rtlsdr_read_async(dev_rtlsdr, rtlsdr_callback, NULL,
281 				      no_of_buffers, k);
282 }
283 
rtl2832_input(void)284 void rtl2832_input(void)
285 {
286 #if RUSAGE_OLD == TRUE
287 int local_workload_counter;
288 #endif
289 int i, j;
290 int rxin_local_workload_reset;
291 char s[80];
292 double dt1, read_start_time, total_reads;
293 int timing_loop_counter,timing_loop_counter_max,initial_skip_flag;
294 int local_att_counter;
295 int local_nco_counter;
296 char vendor[256], product[256], serial[256];
297 int *ise;
298 unsigned int no_of_rtl;
299 uint32_t idx;
300 lir_init_event(EVENT_HWARE1_RXREADY);
301 #if OSNUM == OSNUM_LINUX
302 clear_thread_times(THREAD_RTL2832_INPUT);
303 #endif
304 #if RUSAGE_OLD == TRUE
305 local_workload_counter=workload_counter;
306 #endif
307 local_att_counter=sdr_att_counter;
308 local_nco_counter=sdr_nco_counter;
309 dt1=current_time();
310 i=read_sdrpar(rtl2832_parfil_name, MAX_RTL2832_PARM,
311                                      rtl2832_parm_text, (int*)((void*)&rtl2832));
312 if(i != 0 || rtl2832.check != RTL2832PAR_VERNR)
313   {
314   lirerr(1356);
315   goto rtl2832_init_error_exit;
316   }
317 if(ui.rx_ad_speed != (int)((rint)((rtl2832.sampling_speed*
318                      (100000000L+(double)rtl2832.freq_adjust))/100000000L)))
319   {
320   lirerr(1356);
321   goto rtl2832_init_error_exit;
322   }
323 load_rtlsdr_library();
324 if(!rtlsdr_library_flag)goto rtl2832_init_error_exit;
325 timf1p_sdr=timf1p_pa;
326 j=0;
327 while(sdr == -1)
328   {
329   ise=(int*)(void*)s;
330   dev_rtlsdr=NULL;
331   no_of_rtl = rtlsdr_get_device_count();
332   for(idx=0; idx<no_of_rtl; idx++)
333     {
334     rtlsdr_get_device_usb_strings(idx, vendor, product, serial);
335     sprintf(s,"%s",serial);
336     i=0;
337     while(i<16 && s[i]!=0)i++;
338     while(i<16 )
339       {
340       s[i]=' ';
341       i++;
342       }
343     if( rtl2832.sernum1 == ise[0] &&
344         rtl2832.sernum2 == ise[1] &&
345         rtl2832.sernum3 == ise[2])
346       {
347       sdr=rtlsdr_open(&dev_rtlsdr, idx);
348       if(kill_all_flag)  goto rtl2832_init_error_exit;
349       if(sdr >= 0)
350         {
351         i=rtlsdr_set_sample_rate(dev_rtlsdr, (uint32_t)rtl2832.sampling_speed);
352         if(i < 0)
353           {
354           lirerr(1339);
355 opnerr:;
356           rtlsdr_close(dev_rtlsdr);
357           goto rtl2832_init_error_exit;
358           }
359 // Direct Sampling mode. tuner = 0 (default), I = 1, Q = 2
360         if(rtl2832.direct_sampling>0)
361           {
362           i=rtlsdr_set_direct_sampling(dev_rtlsdr, rtl2832.direct_sampling);
363           if(i!=0)
364             {
365             lirerr(1358);
366             goto opnerr;
367             }
368 // Enable rtl2831 AGC
369           if(rtl2832.gain_mode==0) i=rtlsdr_set_agc_mode(dev_rtlsdr, 1);
370           }
371 // Reset endpoint before we start reading from the RTL2832 (mandatory)
372         i=rtlsdr_reset_buffer(dev_rtlsdr);
373         if(i < 0)
374           {
375           lirerr(1340);
376           goto opnerr;
377           }
378         linrad_thread_create(THREAD_RTL_STARTER);
379         i=rtlsdr_set_tuner_gain_mode(dev_rtlsdr, rtl2832.gain_mode);
380         if(i != 0 && i != rtl2832.gain_mode)goto rtl2832_error_exit;
381         if(rtl2832.gain_mode != 0)
382           {
383           no_of_rtl2832_gains=rtlsdr_get_tuner_gains(dev_rtlsdr, NULL);
384           if(no_of_rtl2832_gains < 1 ||
385              no_of_rtl2832_gains > 256)goto rtl2832_error_exit;
386           rtl2832_gains=malloc(no_of_rtl2832_gains*sizeof(int));
387           if(rtl2832_gains == NULL)goto rtl2832_error_exit;
388           rtlsdr_get_tuner_gains(dev_rtlsdr, rtl2832_gains);
389           }
390         break;
391         }
392       else
393         {
394         if(j==0)
395           {
396           clear_screen();
397           j=1;
398           }
399         }
400       }
401     }
402   sprintf(s,"Waiting %.2f", current_time()-dt1);
403   lir_text(3,5,s);
404   lir_refresh_screen();
405   if(kill_all_flag)goto rtl2832_init_error_exit;
406   lir_sleep(100000);
407   }
408 set_hardware_rx_gain();
409 set_rtl2832_att();
410 set_rtl2832_frequency();
411 fft1_block_timing();
412 if(thread_command_flag[THREAD_SCREEN]!=THRFLAG_NOT_ACTIVE)
413   {
414   while(thread_status_flag[THREAD_SCREEN]!=THRFLAG_ACTIVE &&
415         thread_status_flag[THREAD_SCREEN]!=THRFLAG_IDLE &&
416         thread_status_flag[THREAD_SCREEN]!=THRFLAG_SEM_WAIT)
417     {
418     if(thread_command_flag[THREAD_RTL2832_INPUT] ==
419                                            THRFLAG_KILL)goto rtl2832_error_exit1;
420     lir_sleep(10000);
421     }
422   }
423 #include "timing_setup.c"
424 thread_status_flag[THREAD_RTL2832_INPUT]=THRFLAG_ACTIVE;
425 while(!kill_all_flag &&
426             thread_command_flag[THREAD_RTL2832_INPUT] == THRFLAG_ACTIVE)
427   {
428 #if RUSAGE_OLD == TRUE
429   if(local_workload_counter != workload_counter)
430     {
431     local_workload_counter=workload_counter;
432     make_thread_times(THREAD_RTL2832_INPUT);
433     }
434 #endif
435   if(local_att_counter != sdr_att_counter)
436     {
437     local_att_counter=sdr_att_counter;
438     set_rtl2832_att();
439     }
440   if(local_nco_counter != sdr_nco_counter)
441     {
442     local_nco_counter=sdr_nco_counter;
443     set_rtl2832_frequency();
444     }
445   lir_await_event(EVENT_HWARE1_RXREADY);
446   if(kill_all_flag)goto rtl2832_error_exit1;
447 
448   while (!kill_all_flag && timf1p_sdr != timf1p_pa)
449     {
450 #include "input_speed.c"
451     finish_rx_read();
452     }
453   }
454 rtl2832_error_exit1:;
455 if(rtl2832.gain_mode != 0)free(rtl2832_gains);
456 rtl2832_error_exit:;
457 rtlsdr_cancel_async(dev_rtlsdr);
458 rtlsdr_close(dev_rtlsdr);
459 lir_join(THREAD_RTL_STARTER);
460 unload_rtlsdr_library();
461 rtl2832_init_error_exit:;
462 sdr=-1;
463 thread_status_flag[THREAD_RTL2832_INPUT]=THRFLAG_RETURNED;
464 while(thread_command_flag[THREAD_RTL2832_INPUT] != THRFLAG_NOT_ACTIVE)
465   {
466   lir_sleep(1000);
467   }
468 lir_close_event(EVENT_HWARE1_RXREADY);
469 }
470 
init_rtl2832(void)471 void init_rtl2832(void)
472 {
473 FILE *rtl2832_file;
474 char s[120];
475 char vendor[256], product[256], serial[256];
476 int *ise, *sdr_pi;
477 int i, line, no_of_rtl, devno;
478 load_rtlsdr_library();
479 if(!rtlsdr_library_flag)return;
480 ise=(int*)(void*)s;
481 lir_text(3,2,"SEARCHING");
482 no_of_rtl = rtlsdr_get_device_count();
483 clear_lines(2,2);
484 if (no_of_rtl == 0)
485   {
486   lir_text(5,5,"RTL2832 not found.");
487   lir_text(5,7,press_any_key);
488   await_keyboard();
489   goto init_x;
490   }
491 line=2;
492 for(i=0; i<no_of_rtl; i++)
493   {
494   rtlsdr_get_device_usb_strings(i, vendor, product, serial);
495   sprintf(s," %2d: %s   MFG:%s, PROD:%s, SN: %s", i,
496                            rtlsdr_get_device_name(i), vendor, product, serial);
497   lir_text(3,line,s);
498   line++;
499   }
500 line++;
501 if (no_of_rtl == 1)
502   {
503   lir_text(3,line,"Device autoselected.");
504   devno=0;
505   }
506 else
507   {
508   lir_text(3, line, "Select device by line number:");
509   devno=lir_get_integer(32,line,2,0,no_of_rtl-1);
510   }
511 if(kill_all_flag)
512   {
513   goto init_x;
514   }
515 rtlsdr_get_device_usb_strings(devno, vendor, product, serial);
516 sprintf(s,"%s",serial);
517 i=0;
518 while(i<16 && s[i]!=0)i++;
519 while(i<16)
520   {
521   s[i]=' ';
522   i++;
523   }
524 rtl2832.sernum1=ise[0];
525 rtl2832.sernum2=ise[1];
526 rtl2832.sernum3=ise[2];
527 line+=2;
528 lir_sleep(100000);
529 i=rtlsdr_open(&dev_rtlsdr, (uint32_t)devno);
530 if(i<0)
531   {
532 #if(OSNUM == OSNUM_WINDOWS)
533   lirerr(1348);
534 #else
535   lirerr(1357);
536 #endif
537   goto init_x;
538   }
539 getspeed:;
540 sprintf(s,"Set sampling speed in Hz (%d to %d or %d to %d) =>",
541                                     MIN_RTL2832_SAMP_RATE_L,MAX_RTL2832_SAMP_RATE_L,
542                                     MIN_RTL2832_SAMP_RATE_H,MAX_RTL2832_SAMP_RATE_H);
543 lir_text(3,line,s);
544 rtl2832.sampling_speed=lir_get_integer(4+strlen(s),line,7,
545                                 MIN_RTL2832_SAMP_RATE_L,MAX_RTL2832_SAMP_RATE_H);
546 if(kill_all_flag)
547   {
548   rtlsdr_close(dev_rtlsdr);
549   goto init_x;
550   }
551 line+=2;
552 if(rtl2832.sampling_speed > MAX_RTL2832_SAMP_RATE_L &&
553    rtl2832.sampling_speed < MIN_RTL2832_SAMP_RATE_H)
554   {
555   if( rtl2832.sampling_speed-MAX_RTL2832_SAMP_RATE_L >
556       MIN_RTL2832_SAMP_RATE_H-rtl2832.sampling_speed)
557     {
558     rtl2832.sampling_speed=MIN_RTL2832_SAMP_RATE_H;
559     }
560   else
561     {
562     rtl2832.sampling_speed=MAX_RTL2832_SAMP_RATE_L;
563     }
564   }
565 i=rtlsdr_set_sample_rate(dev_rtlsdr, (uint32_t)rtl2832.sampling_speed);
566 rtl2832.sampling_speed=rtlsdr_get_sample_rate(dev_rtlsdr);
567 if(i < 0)
568   {
569   lir_text(3,line,"Failed to set sampling rate");
570   lir_text(3,line+1,press_any_key);
571   await_keyboard();
572   clear_lines(line,line+1);
573   goto getspeed;
574   }
575 lir_text(3, line, "RF input modes:");
576 line++;
577 lir_text(3, line, "0 = Tuner");
578 line++;
579 lir_text(3, line, "1 = I Direct Sampling");
580 line++;
581 lir_text(3, line, "2 = Q Direct Sampling");
582 line+=2;
583 lir_text(3, line, "Select :");
584 rtl2832.direct_sampling=lir_get_integer(12,line,2,0,2);
585 if(kill_all_flag)
586   {
587   rtlsdr_close(dev_rtlsdr);
588   goto init_x;
589   }
590 if(rtl2832.direct_sampling==0)
591   {
592   i=rtlsdr_set_tuner_gain_mode(dev_rtlsdr, 32);
593   }
594 else
595   {
596   i=1;
597   }
598 if(i==0)i=1;
599 lir_text(3,line,"Select gain mode:");
600 line++;
601 lir_text(3,line,"0 = Auto");
602 line++;
603 lir_text(3,line,"1 = Original Osmocom");
604 line++;
605 if(i>1)
606   {
607   lir_text(3,line,"2 = Linearity");
608   line++;
609     {
610     if(i > 3)
611       {
612       lir_text(3,line,"to");
613       line++;
614       }
615     }
616   sprintf(s,"%d = Sensitivity",i);
617   lir_text(3,line,s);
618   }
619 line++;
620 sprintf(s,"Enter gain mode (0 to %d) =>",i);
621 rtlsdr_close(dev_rtlsdr);
622 lir_text(3,line,s);
623 rtl2832.gain_mode=lir_get_integer(4+strlen(s),line,1,0,i);
624 if(kill_all_flag)goto init_x;
625 line+=2;
626 lir_text(3,line,"Enter xtal error in ppb =>");
627 rtl2832.freq_adjust=0.1*lir_get_float(32,line,9,-300000.,300000.);
628 if(kill_all_flag)goto init_x;
629 rtl2832_file=fopen(rtl2832_parfil_name,"w");
630 if(rtl2832_file == NULL)
631   {
632   lirerr(381268);
633   goto init_x;
634   }
635 rtl2832.check=RTL2832PAR_VERNR;
636 sdr_pi=(int*)(&rtl2832);
637 for(i=0; i<MAX_RTL2832_PARM; i++)
638   {
639   fprintf(rtl2832_file,"%s [%d]\n",rtl2832_parm_text[i],sdr_pi[i]);
640   }
641 parfile_end(rtl2832_file);
642 ui.rx_addev_no=RTL2832_DEVICE_CODE;
643 ui.rx_ad_speed=(int)((rint)((rtl2832.sampling_speed*
644                    (100000000L+(double)rtl2832.freq_adjust))/100000000L));
645 ui.rx_input_mode=IQ_DATA;
646 ui.rx_rf_channels=1;
647 ui.rx_ad_channels=2;
648 ui.rx_admode=0;
649 init_x:
650 unload_rtlsdr_library();
651 }
652 
display_rtl2832_parm_info(int * line)653 int display_rtl2832_parm_info(int *line)
654 {
655 char s[80];
656 int errcod;
657 char* input_modes[3]={"Tuner",
658                       "I Direct Sampling",
659                       "Q Direct Sampling"};
660 //if(FBDEV == 0)fflush(NULL);
661 errcod=read_sdrpar(rtl2832_parfil_name, MAX_RTL2832_PARM,
662                                rtl2832_parm_text, (int*)((void*)&rtl2832));
663 //if(FBDEV == 0)fflush(NULL);
664 if(errcod == 0)
665   {
666   settextcolor(7);
667   sprintf(s,"Sampling rate = %i, Gain mode = %d, Xtal adjust = %.0f ppb",
668                               rtl2832.sampling_speed, rtl2832.gain_mode,
669                               10.*rtl2832.freq_adjust);
670   lir_text(24,line[0],s);
671   SNDLOG"\n%s",s);
672   line[0]++;
673   sprintf(s,"Rf input mode = %d (%s)",rtl2832.direct_sampling,
674                                  input_modes[rtl2832.direct_sampling]);
675   lir_text(24,line[0],s);
676   SNDLOG"\n%s",s);
677   line[0]++;
678   }
679 
680 return (errcod);
681 }
682