Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / host / apps / usrp_cal_dc_offset.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2005,2008 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <usb.h>                        /* needed for usb functions */
32 #include <getopt.h>
33 #include <assert.h>
34 #include <math.h>
35 #include <boost/scoped_ptr.hpp>
36 #include "usrp_local_sighandler.h"
37 #include "usrp_standard.h"
38 #include "usrp_bytesex.h"
39
40 char *prog_name;
41
42
43
44
45 static void 
46 run_cal(usrp_standard_rx_sptr u, int which_side, int decim, bool verbose_p)
47 {
48   static const int BUFSIZE = u->block_size();
49   static const int N = BUFSIZE/sizeof (short);
50   short            buf[N];
51   bool  cal_done = false;
52   bool overrun;
53   int  noverruns = 0;
54
55   static const double K = 1e-4;
56   long  integrator[2];
57   int   offset[2];
58
59   integrator[0] = 0;
60   integrator[1] = 0;
61   offset[0] = 0;
62   offset[1] = 0;
63
64   u->start();           // start data xfers
65
66   while(!cal_done){
67     int ret = u->read (buf, sizeof (buf), &overrun);
68     if (ret != (int) sizeof (buf)){
69       fprintf (stderr, "usrp_cal_dc_offset: error, ret = %d\n", ret);
70       continue;
71     }
72     if (overrun){
73       fprintf (stderr, "O");
74       noverruns++;
75     }
76     else {
77       // fputc('.', stderr);
78     }
79
80     static const int MAX = (1L << 30);          // 1G
81
82     for (int i = 0; i < N/2; i++){
83       for (int n = 0; n < 2; n++){
84         integrator[n] = integrator[n] + buf[2*i + n];
85         if (integrator[n] > MAX)
86           integrator[n] = MAX;
87         else if (integrator[n] < -MAX)
88           integrator[n] = -MAX;
89       }
90     }
91
92 #if 1
93     for (int n = 0; n < 2; n++){
94       offset[n] = (int) rint(integrator[n] * K);
95       if (offset[n] > 32767)
96         offset[n] = 32767;
97       else if (offset[n] < -32767)
98         offset[n] = -32767;
99       u->set_adc_offset(which_side * 2 + n, offset[n]);
100     }
101 #else
102     offset[0] = (int) rint(integrator[0] * K);
103     if (offset[0] > 32767)
104       offset[0] = 32767;
105     else if (offset[0] < -32767)
106       offset[0] = -32767;
107     u->set_adc_offset(which_side * 2 + 0, offset[0]);
108     u->set_adc_offset(which_side * 2 + 1, offset[0]);
109 #endif
110     
111
112     printf ("%9ld : %6d\t\t%9ld : %6d\n",
113             integrator[0], offset[0], integrator[1], offset[1]);
114   }
115
116   u->stop();
117 }
118
119
120 static void
121 set_progname (char *path)
122 {
123   char *p = strrchr (path, '/');
124   if (p != 0)
125     prog_name = p+1;
126   else
127     prog_name = path;
128 }
129
130 static void
131 usage ()
132 {
133   fprintf(stderr, "usage: %s [-v] [-w which_side] [-D decim] [-c ddc_freq] [-g gain]\n", prog_name);
134   fprintf(stderr, "  [-S fusb_block_size] [-N fusb_nblocks]\n");
135   exit (1);
136 }
137
138 static void
139 die (const char *msg)
140 {
141   fprintf (stderr, "die: %s: %s\n", prog_name, msg);
142   exit (1);
143 }
144
145 int
146 main (int argc, char **argv)
147 {
148   int       ch;
149   int       decim = 128;                // 500 kS/sec
150   bool      verbose_p = false;
151   int       which_board = 0;
152   int       which_side = 0;
153   double    ddc_freq = 0;
154   int       fusb_block_size = 1024;
155   int       fusb_nblocks = 4;
156   double    pga_gain = 0.0;
157
158   set_progname(argv[0]);
159
160   while ((ch = getopt (argc, argv, "vw:D:c:S:N:g:")) != EOF){
161     switch (ch){
162
163     case 'w':
164       which_side = strtol (optarg, 0, 0);
165       if (which_side < 0 || which_side > 1)
166         usage();
167       break;
168
169     case 'D':
170       decim = strtol (optarg, 0, 0);
171       if (decim < 1)
172         usage();
173       break;
174
175     case 'c':
176       ddc_freq = strtod (optarg, 0);
177       break;
178
179     case 'v':
180       verbose_p = true;
181       break;
182
183     case 'S':
184       fusb_block_size = strtol(optarg, 0, 0);
185       break;
186
187     case 'N':
188       fusb_nblocks = strtol(optarg, 0, 0);
189       break;
190
191     case 'g':
192       pga_gain = strtod (optarg, 0);
193       break;
194
195     default:
196       usage ();
197     }
198   }
199
200   int nchannels = 1;
201   int mode = usrp_standard_rx::FPGA_MODE_NORMAL;
202   int mux;
203
204   if (which_side == 0)
205     mux = 0x00000010;
206   else
207     mux = 0x00000032;
208
209 #ifdef SIGINT
210   usrp_local_sighandler sigint (SIGINT, usrp_local_sighandler::throw_signal);
211 #endif
212 #ifdef SIGQUIT
213   usrp_local_sighandler sigquit (SIGQUIT, usrp_local_sighandler::throw_signal);
214 #endif
215
216   usrp_standard_rx_sptr urx =
217     usrp_standard_rx::make(which_board, decim,
218                            nchannels, mux, mode,
219                            fusb_block_size, fusb_nblocks);
220   if (!urx)
221     die("usrp_standard_rx::make");
222
223   try {
224
225     if (!urx->set_rx_freq(0, ddc_freq))
226       die("urx->set_rx_freq");
227
228     urx->set_pga(2 * which_side + 0, pga_gain);
229     urx->set_pga(2 * which_side + 1, pga_gain);
230     
231     run_cal(urx, which_side, decim, verbose_p);
232   }
233   catch (usrp_signal &sig){
234     fprintf (stderr, "usrp_cal_dc_offset: caught %s\n", sig.name().c_str());
235   }
236   catch(...){
237     fprintf (stderr, "usrp_cal_dc_offset: caught something\n");
238   }
239 }
240