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