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 
25 #include <unistd.h>
26 #include <string.h>
27 #include <fcntl.h>
28 #include "globdef.h"
29 #include "uidef.h"
30 #include "rusage.h"
31 #include "thrdef.h"
32 #include "sdrdef.h"
33 #include "fft1def.h"
34 #include "screendef.h"
35 #include "hwaredef.h"
36 #include "vernr.h"
37 #include "options.h"
38 
39 float sdr_shape_factor=0.97;
40 #define MAX_SDR14_SPEED 3000000
41 
42 char *sdr14_parfil_name="par_sdr14";
43 
44 char *sdr14_parm_text[MAX_SDR14_PARM] = {"M_CIC2",
45                                          "M_CIC5",
46                                          "M_RCF",
47                                          "OL_RCF",
48                                          "Sampl. clk adjust",
49                                          "Att",
50                                          "Inp.sel",
51                                          "sernum1",
52                                          "sernum2",
53                                          "sernum3",
54                                          "device code",
55                                          "Check"};
56 
57 P_SDR14 sdr14;
58 
59 #define M_RCF sdr14.m_rcf
60 #define M_CIC5 sdr14.m_cic5
61 #define M_CIC2 sdr14.m_cic2
62 
63 #if (OSNUM == OSNUM_LINUX)
64 int sdr14_scan_usb(void);
65 #endif
66 
67 
68 void open_sdr14(void);
69 void lir_sdr14_write(char *s, int bytes);
70 int lir_sdr14_read(char *s, int bytes);
71 
display_sdr14_parm_info(int * line)72 int display_sdr14_parm_info(int *line)
73 {
74 char s[80];
75 int errcod;
76 errcod=read_sdrpar(sdr14_parfil_name, MAX_SDR14_PARM,
77                                      sdr14_parm_text, (int*)((void*)&sdr14));
78 if(errcod == 0)
79   {
80   settextcolor(7);
81   sprintf(s,"m cic2             = %i  ", sdr14.m_cic2);
82   line[0]+=1;
83   lir_text(24,line[0],s);
84   sprintf(s,"m cic5             = %i  ", sdr14.m_cic5);
85   line[0]+=1;
86   lir_text(24,line[0],s);
87   sprintf(s,"m rcf              = %i  ", sdr14.m_rcf);
88   line[0]+=1;
89   lir_text(24,line[0],s);
90   sprintf(s,"ol rcf             = %i  ", sdr14.ol_rcf);
91   line[0]+=1;
92   lir_text(24,line[0],s);
93   sprintf(s,"clock adjust       = %i  ", sdr14.clock_adjust);
94   line[0]+=1;
95   lir_text(24,line[0],s);
96   sprintf(s,"input              = %i  ", sdr14.input);
97   line[0]+=1;
98   lir_text(24,line[0],s);
99   }
100 return (errcod);
101 }
102 
sdr_destructive_control(char * msg)103 int sdr_destructive_control(char *msg)
104 {
105 char *s;
106 int i, ir;
107 unsigned short int msg_header, shi;
108 s=(char*)&msg_header;
109 i=0;
110 while(i<2)
111   {
112   ir=lir_sdr14_read(&s[i],2-i);
113   if(ir<0)return 0;
114   i+=ir;
115   }
116 if(msg_header >= 80)
117   {
118 err:;
119   i=lir_sdr14_read(timf1_char,8192);
120   msg[0]=0;
121   if(i==-1)i=0;
122   return -i;
123   }
124 else
125   {
126   if(msg_header <= 4)goto err;
127   msg_header-=4;
128   ir=lir_sdr14_read((char*)&shi,2);
129   if(ir<0)return 0;
130   if(msg_header < 70)
131     {
132     ir=lir_sdr14_read(msg,msg_header);
133     if(ir<0)return 0;
134     }
135   else
136     {
137     msg_header-=70;
138     ir=lir_sdr14_read(timf1_char,msg_header);
139     if(ir<0)return 0;
140     }
141   }
142 return shi;
143 }
144 
sdr_target_name(char * ss)145 void sdr_target_name(char *ss)
146 {
147 int i,j;
148 char s[4]={4,32,1,0};
149 j=0;
150 retry:;
151 j++;
152 lir_sdr14_write(s,4);
153 i=sdr_destructive_control(ss);
154 if(i==1 || j>3)return;
155 goto retry;
156 }
157 
sdr_target_serial_number(char * ss)158 void sdr_target_serial_number(char *ss)
159 {
160 char s[4]={4,32,2,0};
161 lir_sdr14_write(s,4);
162 sdr_destructive_control(ss);
163 }
164 
sdr_target_interface_version(char * ss)165 void sdr_target_interface_version(char *ss)
166 {
167 char s[4]={4,32,3,0};
168 lir_sdr14_write(s,4);
169 sdr_destructive_control(ss);
170 }
171 
sdr_target_firmware_version(char * ss)172 void sdr_target_firmware_version(char *ss)
173 {
174 char s[5]={5,32,4,0,1};
175 lir_sdr14_write(s,5);
176 sdr_destructive_control(ss);
177 }
178 
sdr_target_boot_version(char * ss)179 void sdr_target_boot_version(char *ss)
180 {
181 char s[5]={5,32,4,0,0};
182 lir_sdr14_write(s,5);
183 sdr_destructive_control(ss);
184 }
185 
186 char sdr14cmd[10];
187 
188 
load_ad6620(void)189 void load_ad6620(void)
190 {
191 short int *hed;
192 hed=(short int*)sdr14cmd;
193 lir_sdr14_write(sdr14cmd,0x1ff&hed[0]);
194 }
195 
sdr_set_frequency(void)196 void sdr_set_frequency(void)
197 {
198 int i;
199 float t1;
200 short int *address;
201 int *dat;
202 unsigned short int *msg_header;
203 msg_header=(unsigned short int*)(&sdr14cmd[0]);
204 dat=(int*)(&sdr14cmd[5]);
205 address=(short int*)(&sdr14cmd[2]);
206 msg_header[0]=10;
207 address[0]=0x20;
208 sdr14cmd[4]=0;
209 t1=fg.passband_center;
210 if(fg.passband_center > adjusted_sdr_clock)
211   {
212   i=fg.passband_center/adjusted_sdr_clock;
213   t1=fg.passband_center-i*adjusted_sdr_clock;
214   }
215 if(t1 > 0.5*adjusted_sdr_clock)
216   {
217   t1=adjusted_sdr_clock-t1;
218   }
219 t1*=SDR14_SAMPLING_CLOCK/adjusted_sdr_clock;
220 dat[0]=t1*1000000+0.5;
221 sdr14cmd[9]=1;
222 lir_sdr14_write(sdr14cmd,10);
223 }
224 
set_sdr14_att(void)225 void set_sdr14_att(void)
226 {
227 float t1;
228 unsigned short int *msg_header;
229 short int *address;
230 address=(short int*)(&sdr14cmd[2]);
231 msg_header=(unsigned short int*)(&sdr14cmd[0]);
232 msg_header[0]=6;
233 address[0]=0x38;
234 if(ui.rx_addev_no==SDR14_DEVICE_CODE)
235   {
236   sdr14cmd[4]=0;
237   sdr14cmd[5]=fg.gain;
238   }
239 if(ui.rx_addev_no==SDRIQ_DEVICE_CODE)
240   {
241   sdr14cmd[4]=1;
242   if(fg.gain > -sdr14.input)
243     {
244 // Gain is in the range 0 to -sdr14.input dB.
245     t1=-0.05*fg.gain;
246     t1=pow(10,t1);
247     t1=127/t1;
248     sdr14cmd[5]=t1+0.5;
249     sdr14cmd[5]&=0x7f;
250     }
251   else
252     {
253     t1=-0.05*(fg.gain+10);
254     t1=pow(10,t1);
255     t1=127/t1;
256     sdr14cmd[5]=t1+0.5;
257     sdr14cmd[5]|=0x80;
258     }
259   }
260 lir_sdr14_write(sdr14cmd,6);
261 }
262 
sdr_set_cic2(int mcic2)263 void sdr_set_cic2(int mcic2)
264 {
265 int i,scale;
266 int *is;
267 short int *address;
268 address=(short int*)(&sdr14cmd[2]);
269 i=mcic2>>1;
270 i=i*i;
271 scale=0;
272 while(i!=0)
273   {
274   i>>=1;
275   scale++;
276   }
277 if(scale > 6)scale=6;
278 address[0]=0x305;
279 is=(int*)&sdr14cmd[4];
280 is[0]=scale;
281 load_ad6620();
282 address[0]=0x306;
283 is[0]=mcic2-1;
284 load_ad6620();
285 }
286 
sdr_set_cic5(int mcic5)287 void sdr_set_cic5(int mcic5)
288 {
289 int i,scale;
290 int *is;
291 short int *address;
292 address=(short int*)(&sdr14cmd[2]);
293 i=mcic5>>1;
294 i=i*i*i*i*i;
295 scale=0;
296 while(i!=0)
297   {
298   i>>=1;
299   scale++;
300   }
301 if(scale > 20)scale=20;
302 address[0]=0x307;
303 is=(int*)&sdr14cmd[4];
304 is[0]=scale;
305 load_ad6620();
306 address[0]=0x308;
307 is[0]=mcic5-1;
308 load_ad6620();
309 }
310 
sdr_set_m_rcf(int m)311 void sdr_set_m_rcf(int m)
312 {
313 int *is;
314 short int *address;
315 address=(short int*)(&sdr14cmd[2]);
316 address[0]=0x30a;
317 is=(int*)&sdr14cmd[4];
318 is[0]=m-1;
319 load_ad6620();
320 }
321 
sdr_set_ol_rcf(void)322 void sdr_set_ol_rcf(void)
323 {
324 int *is;
325 short int *address;
326 address=(short int*)(&sdr14cmd[2]);
327 address[0]=0x309;
328 is=(int*)&sdr14cmd[4];
329 is[0]=sdr14.ol_rcf;
330 load_ad6620();
331 }
332 
symmetry_adapt(void)333 void symmetry_adapt(void)
334 {
335 double *ww;
336 int i;
337 double t2;
338 ww=(double*)timf1_float;
339 // The window function has to be a symmetric function with
340 // imaginary parts=zero.
341 for(i=1; i<128; i++)
342   {
343   t2=0.5*(ww[2*i]+ww[2*(256-i)]);
344   ww[2*i]=t2;
345   ww[2*(256-i)]=t2;
346   }
347 for(i=0; i<256; i++)ww[2*i+1]=0;
348 }
349 
shift_128(void)350 void shift_128(void)
351 {
352 double *ww;
353 int i;
354 double t1;
355 ww=(double*)timf1_float;
356 for(i=0; i<128;i++)
357   {
358   t1=ww[2*i];
359   ww[2*i]=ww[2*(i+128)];
360   ww[2*(i+128)]=t1;
361   }
362 }
363 
clear_small(float limit)364 void clear_small(float limit)
365 {
366 int i;
367 double *ww;
368 float t1;
369 ww=(double*)timf1_float;
370 // Clear all points that are below limit.
371 t1=0;
372 for(i=0; i<256; i++)
373   {
374   if(t1<fabs(ww[2*i]))t1=fabs(ww[2*i]);
375   }
376 t1*=limit;
377 for(i=0; i<256; i++)
378   {
379   if(fabs(ww[2*i]) < limit) ww[2*i]=0;
380   }
381 }
382 
round_to_integer(int limit)383 void round_to_integer(int limit)
384 {
385 int i, j;
386 double *ww;
387 ww=(double*)timf1_float;
388 // Clear all points that are below 0.5 bit in our 20 bit words.
389 for(i=0; i<256; i++)
390   {
391   if(fabs(ww[2*i]) > limit)
392     {
393 // Round to the nearest integer.
394     j=fabs(ww[2*i])+0.5;
395     if( ww[2*i] < 0) j=-j;
396     ww[2*i]=j;
397     }
398   }
399 }
400 
sdr14_stop(void)401 void sdr14_stop(void)
402 {
403 double dt1;
404 int i, ir;
405 unsigned short int *msg_header;
406 short int *address;
407 msg_header=(unsigned short int*)(&sdr14cmd[0]);
408 address=(short int*)(&sdr14cmd[2]);
409 msg_header[0]=8;
410 address[0]=0x18;
411 sdr14cmd[4]=0x81;  //Use AD6620 and RF amplifier.
412 sdr14cmd[5]=1;     //Set to STOP
413 sdr14cmd[6]=0;     //Continous mode
414 sdr14cmd[7]=0;     //Does not matter in continous mode
415 lir_sdr14_write(sdr14cmd,8);
416 dt1=current_time();
417 end_loop:;
418 i=lir_sdr14_read((char*)msg_header,2);
419 if(i<0)goto errclose;
420 while(i!=2)
421   {
422   lir_sched_yield();
423   ir=lir_sdr14_read(&sdr14cmd[i],2-i);
424   if(ir<0)goto errclose;
425   i+=ir;
426   if(current_time() -dt1 > 0.1)goto errclose;
427   }
428 if((0xffff&msg_header[0]) == (unsigned short int)0x8000)
429   {
430   i=lir_sdr14_read(timf1_char,8192);
431   if(i<0)goto errclose;
432   while(i!=8192)
433     {
434     lir_sleep(2000);
435     ir=lir_sdr14_read(timf1_char,8192-i);
436     if(ir<0)goto errclose;
437     i+=ir;
438     if(current_time() -dt1 > 0.1)goto errclose;
439     }
440   }
441 else
442   {
443   if(i <= 8)
444     {
445     ir=lir_sdr14_read(&sdr14cmd[2],i);
446     if(address[0]==0x18)goto errclose;
447     }
448   else
449     {
450     ir=lir_sdr14_read(timf1_char,8192);
451     }
452   if(ir<0)goto errclose;
453   }
454 if(current_time() -dt1 < 0.1)goto end_loop;
455 errclose:;
456 close_sdr14();
457 }
458 
sdr14_input(void)459 void sdr14_input(void)
460 {
461 #if RUSAGE_OLD == TRUE
462 int local_workload_counter;
463 #endif
464 int rxin_local_workload_reset;
465 int *is;
466 char s[80];
467 D_COSIN_TABLE *local_fft_table;
468 unsigned short int *local_fft_permute;
469 double dt1, read_start_time,total_reads;
470 double *ww;
471 int timing_loop_counter,timing_loop_counter_max,initial_skip_flag;
472 int i, j, nn, ntaps;
473 int ia, ib, errcod;
474 short int *isho;
475 unsigned short int *msg_header;
476 short int *address;
477 int *windat;
478 int local_att_counter;
479 int local_nco_counter;
480 char ackmsg[3]={3,0x60,0};
481 float t1;
482 windat=(int*)(&sdr14cmd[4]);
483 msg_header=(unsigned short int*)(&sdr14cmd[0]);
484 address=(short int*)(&sdr14cmd[2]);
485 #if OSNUM == OSNUM_LINUX
486 clear_thread_times(THREAD_SDR14_INPUT);
487 #endif
488 #if RUSAGE_OLD == TRUE
489 local_workload_counter=workload_counter;
490 #endif
491 no_of_rx_overrun_errors=0;
492 begin:;
493 local_att_counter=sdr_att_counter;
494 local_nco_counter=sdr_nco_counter;
495 j=0;
496 dt1=current_time();
497 errcod=read_sdrpar(sdr14_parfil_name, MAX_SDR14_PARM,
498                                      sdr14_parm_text, (int*)((void*)&sdr14));
499 if(errcod != 0 || sdr14.check != SDR14PAR_VERNR)goto sdr14_init_error_exit;
500 while(sdr == -1)
501   {
502   open_sdr14();
503   lir_sleep(30000);
504   if(sdr == -1)
505     {
506     sprintf(s,"Waiting %.2f", current_time()-dt1);
507     lir_text(0,screen_last_line,s);
508     lir_refresh_screen();
509     if(kill_all_flag)goto sdr14_init_error_exit;
510     }
511   }
512 sdr_target_name(s);
513 if(ui.rx_addev_no==SDR14_DEVICE_CODE)
514   {
515   if(strcmp(sdr14_name_string,s) != 0)goto sdr14_init_error_exit;
516   }
517 if(ui.rx_addev_no==SDRIQ_DEVICE_CODE)
518   {
519   if(strcmp(sdriq_name_string,s) != 0)goto sdr14_init_error_exit;
520   }
521 // ****************************************************
522 // We have a connection to the SDR-14.
523 // Set status to stop
524 msg_header[0]=8;
525 address[0]=0x18;
526 sdr14cmd[4]=0x81;  //Use AD6620 and RF amplifier.
527 sdr14cmd[5]=1;     //Set to STOP
528 sdr14cmd[6]=0;     //Continous mode
529 sdr14cmd[7]=0;     //Does not matter in continous mode
530 lir_sdr14_write(sdr14cmd,8);
531 i=1;
532 while(i==0 || i!=0x18)
533   {
534   i=sdr_destructive_control(s);
535   if(kill_all_flag)goto sdr14_init_error_exit;
536   }
537 if( abs(sdr14.clock_adjust) > 10000)goto sdr14_init_error_exit;
538 adjusted_sdr_clock=SDR14_SAMPLING_CLOCK+0.000001*sdr14.clock_adjust,
539 t1=ui.rx_ad_speed-1000000.*adjusted_sdr_clock/
540                                      (sdr14.m_cic2*sdr14.m_cic5*sdr14.m_rcf);
541 if(fabs(t1/ui.rx_ad_speed) > 0.01)
542   {
543   lirerr(1345);
544   goto sdr14_init_error_exit;
545   }
546 ui.rx_ad_speed=1000000.*adjusted_sdr_clock/(M_CIC2*M_CIC5*M_RCF);
547 if(ui.rx_ad_speed > MAX_SDR14_SPEED)
548   {
549   lirerr(1165);
550   goto normal_exit;
551   }
552 // Program the AD6620.
553 set_sdr14_att();
554 i=1;
555 while(i==0 || i!=0x38)
556   {
557   i=sdr_destructive_control(s);
558   if(kill_all_flag)goto sdr14_init_error_exit;
559   }
560 // Set the frequency
561 sdr_set_frequency();
562 i=1;
563 while(i==0 || i!=0x20)
564   {
565   i=sdr_destructive_control(s);
566   if(kill_all_flag)goto sdr14_init_error_exit;
567   }
568 msg_header[0]=0xa009;
569 // Set MODE CONTROL REGISTER to 1 (soft reset)
570 address[0]=0x300;
571 sdr14cmd[4]=1;
572 load_ad6620();
573 // Data sheet says we should write 0 here.
574 address[0]=0x30d;
575 is=(int*)&sdr14cmd[4];
576 is[0]=0;
577 load_ad6620();
578 ww=(double*)timf1_float;
579 for(i=0; i<512; i++)ww[i]=0;
580 // Set up tables for a 256 point fft
581 local_fft_permute=(unsigned short int*)(&ww[512]);
582 local_fft_table=(D_COSIN_TABLE*)(&timf1_float[2048+32]);
583 init_d_fft(0,8, 256, local_fft_table, local_fft_permute);
584 ntaps=M_RCF*M_CIC5*M_CIC2/2;
585 if(ntaps > 256)ntaps=256;
586 // Construct a filter function for the FIR filter in ntaps points.
587 // The gaussian function is the function that minimises the
588 // pulse response for a given bandwidth.
589 // The array of FIR filter coefficients is the pulse response of a FIR filter
590 // and as a first step we construct the widest acceptable time
591 // function as a single gaussian.
592 t1=0.25/0x7ffff;
593 t1=pow(exp(1.),t1);
594 t1=0.5*sqrt(t1/ntaps);
595 ww[0]=1;
596 for(i=1; i<128; i++)
597   {
598   dt1=i*t1;
599   dt1=exp(-dt1*dt1);
600   ww[2*i]=dt1;
601   ww[2*(256-i)]=dt1;
602   }
603 symmetry_adapt();
604 // Go to the frequency domain where we get the frequency response
605 // of the longest acceptable time function.
606 d_fftforward(256,8,ww,local_fft_table, local_fft_permute);
607 symmetry_adapt();
608 clear_small(0.000001);
609 nn=0;
610 while(ww[2*nn]>0.3162*ww[0])nn++;
611 // nn now points to the -10 dB point.
612 // Construct a rectangular filter in the frequency domain
613 // by summing several frequency shifted gaussian filters
614 // of the now established shape.
615 // Make the filter flat over a center portion that is 1/M_RCF points wide.
616 nn=128./M_RCF-nn;
617 // nn is now half the range over which we want to sum up gaussians.
618 shift_128();
619 for(i=nn; i<256-nn; i++)
620   {
621   ia=i-nn;
622   ib=i+nn;
623   t1=0;
624   for(j=ia; j<=ib; j++)
625     {
626     t1+=ww[2*j];
627     }
628   ww[2*i+1]=t1;
629   }
630 for(i=0; i<256; i++)
631   {
632   ww[2*i]=ww[2*i+1];
633   }
634 shift_128();
635 symmetry_adapt();
636 // Take the back transform to go from the frequency domain to the time domain.
637 d_fftback(256,8,ww,local_fft_table, local_fft_permute);
638 symmetry_adapt();
639 // Round the big numbers to integers
640 t1=0x7ffff/ww[0];
641 for(i=0; i<256; i++)
642   {
643   ww[2*i]*=t1;
644   }
645 round_to_integer(4);
646 shift_128();
647 for(i=0; i<256; i++)
648   {
649   address[0]=i;
650   windat[0]=ww[2*i];
651   load_ad6620();
652   }
653 // Set ntaps
654 address[0]=0x30c;
655 sdr14cmd[4]=ntaps-1;
656 load_ad6620();
657 // With offset
658 address[0]=0x30b;
659 sdr14cmd[4]=128-ntaps/2;
660 load_ad6620();
661 // Disable dithering. A good operator will change the frequency
662 // to avoid spurs, converting them to wideband noise will degrade
663 // the dynamic range.
664 address[0]=0x301;
665 sdr14cmd[4]=0;  //phase dither=2, amplitude dither=4, both=6
666 load_ad6620();
667 // Set MCIC2 and the accompanying scale factor
668 sdr_set_cic2(M_CIC2);
669 sdr_set_cic5(M_CIC5);
670 sdr_set_m_rcf(M_RCF);
671 sdr_set_ol_rcf();
672 fft1_block_timing();
673 snd[RXAD].block_bytes=8192;
674 snd[RXAD].block_frames=snd[RXAD].block_bytes/4;
675 snd[RXAD].interrupt_rate=(float)(ui.rx_ad_speed)/snd[RXAD].block_frames;
676 // Start the AD6620
677 address[0]=0x300;
678 sdr14cmd[4]=0;
679 load_ad6620();
680 msg_header[0]=8;
681 address[0]=0x18;
682 sdr14cmd[4]=0x81;  //Use AD6620 and RF filter.
683 if(ui.rx_addev_no == SDR14_DEVICE_CODE && sdr14.input !=0)
684   {
685   sdr14cmd[4]=0x80;  //Use AD6620 without filter.
686   }
687 sdr14cmd[5]=2;     //Set to RUN
688 sdr14cmd[6]=0;     //Continous mode
689 sdr14cmd[7]=0;     //Does not matter in continous mode
690 lir_sdr14_write(sdr14cmd,8);
691 if(thread_command_flag[THREAD_SCREEN]!=THRFLAG_NOT_ACTIVE)
692   {
693   while(thread_status_flag[THREAD_SCREEN]!=THRFLAG_ACTIVE &&
694         thread_status_flag[THREAD_SCREEN]!=THRFLAG_IDLE &&
695         thread_status_flag[THREAD_SCREEN]!=THRFLAG_SEM_WAIT)
696     {
697     if(thread_command_flag[THREAD_SDR14_INPUT] ==
698                                   THRFLAG_KILL)goto normal_exit;
699     lir_sleep(10000);
700     }
701   }
702 thread_status_flag[THREAD_SDR14_INPUT]=THRFLAG_ACTIVE;
703 set_hardware_rx_frequency();
704 #include "timing_setup.c"
705 while(thread_command_flag[THREAD_SDR14_INPUT] == THRFLAG_ACTIVE)
706   {
707 #if RUSAGE_OLD == TRUE
708   if(local_workload_counter != workload_counter)
709     {
710     local_workload_counter=workload_counter;
711     make_thread_times(THREAD_SDR14_INPUT);
712     }
713 #endif
714   i=lir_sdr14_read((char*)msg_header,2);
715   if(i<0)goto sdr14_error_exit;
716   isho=(short int*)(&timf1_char[timf1p_pa]);
717   if((0xffff&msg_header[0]) == (unsigned short int)0x8000)
718     {
719     if(timing_loop_counter == timing_loop_counter_max)
720       {
721       lir_sdr14_write(ackmsg,3);
722       }
723 #include "input_speed.c"
724     i=lir_sdr14_read((char*)isho,8192);
725     if(i<0)goto sdr14_error_exit;
726     finish_rx_read();
727     if(kill_all_flag) goto normal_exit;
728     if(local_att_counter != sdr_att_counter)
729       {
730       local_att_counter=sdr_att_counter;
731       set_sdr14_att();
732       }
733     if(local_nco_counter != sdr_nco_counter)
734       {
735       local_nco_counter=sdr_nco_counter;
736       sdr_set_frequency();
737       }
738     }
739   else
740     {
741     i=(0x1fff&msg_header[0])-2;
742     if(i <= 8)
743       {
744       i=lir_sdr14_read(&sdr14cmd[2],i);
745       if(i<0)goto sdr14_error_exit;
746       }
747     else
748       {
749 // Something went (very) wrong.
750       no_of_rx_overrun_errors++;
751       sprintf(s,"RX%s%d",overrun_error_msg,no_of_rx_overrun_errors);
752       wg_error(s,WGERR_RXIN);
753       sdr14_stop();
754       goto begin;
755       }
756     }
757   }
758 normal_exit:;
759 if(sdr != -1)sdr14_stop();
760 thread_status_flag[THREAD_SDR14_INPUT]=THRFLAG_RETURNED;
761 while(!kill_all_flag &&
762         thread_command_flag[THREAD_SDR14_INPUT] != THRFLAG_NOT_ACTIVE)
763   {
764   lir_sleep(1000);
765   }
766 return;
767 sdr14_error_exit:;
768 lirerr(1343);
769 goto normal_exit;
770 sdr14_init_error_exit:;
771 lirerr(1163);
772 goto normal_exit;
773 }
774 
init_sdr14(void)775 void init_sdr14(void)
776 {
777 char ss[80];
778 char sn[80];
779 char s[80];
780 int i, line;
781 float t1;
782 FILE *sdr14_file;
783 int *sdr_pi;
784 char *looking;
785 looking="Looking for SDR-14 or SDR-IQ on USB ports.";
786 // Set device_no to appropriate values if some dedicated hardware
787 // is selected by the user.
788 //  ------------------------------------------------------------
789 // See if there is an SDR-14 or an SDR-IQ on the system.
790 settextcolor(12);
791 lir_text(10,10,looking);
792 SNDLOG"\n%s",looking);
793 lir_text(10,11,"Reset CPU, USB and SDR hardware if system hangs here.");
794 lir_refresh_screen();
795 settextcolor(7);
796 line=0;
797 #if(OSNUM == OSNUM_LINUX)
798 i=sdr14_scan_usb();
799 if(i<0)goto sdr14_fail;
800 open_sdr14();
801 clear_screen();
802 sdr_target_name(sn);
803 goto use_sdr14;
804 #endif
805 open_sdr14();
806 clear_lines(10,11);
807 lir_refresh_screen();
808 if(sdr != -1)
809   {
810   SNDLOG"open_sdr14 sucessful.\n");
811   lir_text(5,5,"An SDR is detected on the USB port.");
812   lir_text(5,6,"Do you want to use it for RX input (Y/N)?");
813 qsdr:;
814   await_processed_keyboard();
815   if(kill_all_flag) goto sdr14_errexit;
816   if(lir_inkey == 'Y')
817     {
818     sdr_target_name(sn);
819     sprintf(s,"Target name: %s",sn);
820     SNDLOG"%s\n",s);
821     lir_text(5,10,s);
822     if( strcmp(sdr14_name_string,sn) == 0)
823       {
824       ui.rx_addev_no=SDR14_DEVICE_CODE;
825       }
826     if( strcmp(sdriq_name_string,sn) == 0)
827       {
828       ui.rx_addev_no=SDRIQ_DEVICE_CODE;
829       }
830     if(ui.rx_addev_no == UNDEFINED_DEVICE_CODE)
831       {
832       lir_text(5,12,"Unknown hardware, can not use.");
833       lir_text(5,13,press_any_key);
834       await_keyboard();
835       if(kill_all_flag) goto sdr14_errexit;
836       clear_screen();
837       }
838     else
839       {
840       sdr_target_serial_number(ss);
841       sprintf(s,"Serial no: %s",ss);
842       lir_text(5,11,s);
843       sdr_target_interface_version(ss);
844       i=(short int)ss[0];
845       sprintf(s,"Interface version: %d.%02d",i/100,i%100);
846       lir_text(5,12,s);
847       sdr_target_boot_version(ss);
848       i=(short int)ss[0];
849       sprintf(s,"PIC boot version: %d.%02d",i/100,i%100);
850       lir_text(5,13,s);
851       sdr_target_firmware_version(ss);
852       i=(short int)ss[0];
853       sprintf(s,"PIC firmware version: %d.%02d",i/100,i%100);
854       lir_text(5,14,s);
855       lir_text(10,16,"PRESS ANY KEY");
856 restart_sdr14par:;
857       await_processed_keyboard();
858 #if(OSNUM == OSNUM_LINUX)
859 use_sdr14:;
860 #endif
861       ui.rx_input_mode=IQ_DATA+DIGITAL_IQ;
862       ui.rx_rf_channels=1;
863       ui.rx_ad_channels=2;
864       ui.rx_admode=0;
865       if(kill_all_flag) goto sdr14_errexit;
866       clear_screen();
867       sprintf(s,"%s selected for input",sn);
868       lir_text(10,line,s);
869       line++;
870       if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
871         {
872         lir_text(5,line,"Set CIC2 decimation (2 - 16)");
873         sdr14.m_cic2=lir_get_integer(35, line, 2, 2,16);
874         if(kill_all_flag)goto sdr14_errexit;
875         t1=SDR14_SAMPLING_CLOCK/sdr14.m_cic2;
876         sprintf(s,"clk=%.2f MHz",t1);
877         lir_text(39,line,s);
878         line++;
879         lir_text(5,line,"Set CIC5 decimation (2 - 32)");
880         sdr14.m_cic5=lir_get_integer(35, line, 2, 2,32);
881         if(kill_all_flag)goto sdr14_errexit;
882         t1/=sdr14.m_cic5;
883         sprintf(s,"clk=%.4f MHz",t1);
884         lir_text(39,line,s);
885         line++;
886         lir_text(5,line,"Set RCF decimation (2 - 32)");
887         sdr14.m_rcf=lir_get_integer(35, line, 2, 2,32);
888         if(kill_all_flag)goto sdr14_errexit;
889         t1/=sdr14.m_rcf;
890         ui.rx_ad_speed=t1*1000000;
891         if(ui.rx_ad_speed > MAX_SDR14_SPEED)
892           {
893           line++;
894           settextcolor(12);
895           lir_text(5,line,
896                 "ERROR The sampling speed is far too high for USB 1.0");
897           line++;
898           lir_text(5,line,press_any_key);
899           settextcolor(7);
900           goto restart_sdr14par;
901           }
902         }
903       else
904         {
905         sdr14.m_cic2=10;
906         t1=SDR14_SAMPLING_CLOCK/sdr14.m_cic2;
907         sdr14.m_cic5=10;
908         t1/=sdr14.m_cic5;
909         line++;
910         for(i=4; i<8; i++)
911           {
912           sprintf(s,"RCF= %d  Speed %f kHz",i,1000*t1/i);
913           lir_text(0,line,s);
914           line++;
915           }
916         line++;
917         lir_text(5,line,"Set RCF decimation (4 - 7)");
918         sdr14.m_rcf=lir_get_integer(35, line, 2, 4,7);
919         if(kill_all_flag)goto sdr14_errexit;
920         t1/=sdr14.m_rcf;
921         ui.rx_ad_speed=t1*1000000;
922         }
923       sprintf(s,"clk=%.2f kHz",t1*1000);
924       lir_text(39,line,s);
925       line++;
926       lir_text(5,line,"Set RCF output shift (0 - 7)");
927       sdr14.ol_rcf=lir_get_integer(35, line, 2, 0,7);
928       if(kill_all_flag)goto sdr14_errexit;
929       line++;
930       if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
931         {
932         lir_text(5,line,"Set sampling clock shift (Hz)");
933         sdr14.clock_adjust=lir_get_integer(35, line, 6,-10000,10000);
934         if(kill_all_flag)goto sdr14_errexit;
935         line++;
936         }
937       else
938         {
939         sdr14.clock_adjust=0;
940         }
941       adjusted_sdr_clock=SDR14_SAMPLING_CLOCK+0.000001*sdr14.clock_adjust,
942       ui.rx_ad_speed=1000000.*adjusted_sdr_clock/(M_CIC2*M_CIC5*M_RCF);
943       if(ui.rx_addev_no == SDR14_DEVICE_CODE)
944         {
945         lir_text(5,line,"Select direct input (0 - 1)");
946         sdr14.input=lir_get_integer(35, line, 2, 0, 1);
947         if(kill_all_flag)return;
948         }
949       else
950         {
951         if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
952           {
953           lir_text(5,line,"Attenuation below which to use 10dB (10 - 25)");
954           sdr14.input=lir_get_integer(52, line, 2, 10, 25);
955           if(kill_all_flag)return;
956           }
957         else
958           {
959           sdr14.input=20;
960           }
961         }
962       sdr14_file=fopen(sdr14_parfil_name,"w");
963       if(sdr14_file == NULL)
964         {
965         lirerr(381264);
966 sdr14_errexit:;
967         close_sdr14();
968         clear_screen();
969         return;
970         }
971       sdr14.check=SDR14PAR_VERNR;
972       sdr_pi=(int*)(&sdr14);
973       for(i=0; i<MAX_SDR14_PARM; i++)
974         {
975         fprintf(sdr14_file,"%s [%d]\n",sdr14_parm_text[i],sdr_pi[i]);
976         }
977       parfile_end(sdr14_file);
978       }
979     }
980   else
981     {
982     if(lir_inkey != 'N')goto qsdr;
983     clear_screen();
984     }
985   close_sdr14();
986   }
987 else
988   {
989 #if(OSNUM == OSNUM_LINUX)
990 sdr14_fail:;
991 #endif
992   SNDLOG"open_sdr14 USB failed.\n");
993   clear_screen();
994   lir_text(5,5,"No SDR-14 or SDR-IQ device found.");
995   lir_text(5,6,"Make sure that the proper drive routines are installed");
996   lir_text(8,8,press_any_key);
997   await_keyboard();
998   }
999 return;
1000 }
1001