switch source package format to 3.0 quilt
[debian/gnuradio] / usrp / host / apps / usrp_cal_dc_offset.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2005,2008,2009 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 <getopt.h>
32 #include <assert.h>
33 #include <math.h>
34 #include <boost/scoped_ptr.hpp>
35 #include <usrp/usrp_local_sighandler.h>
36 #include <usrp/usrp_standard.h>
37 #include <usrp/usrp_bytesex.h>
38
39 char *prog_name;
40
41
42
43
44 static void 
45 run_cal(usrp_standard_rx_sptr u, int which_side, int decim, bool verbose_p)
46 {
47   static const int BUFSIZE = u->block_size();
48   static const int N = BUFSIZE/sizeof (short);
49   short            buf[N];
50   bool  cal_done = false;
51   bool overrun;
52   int  noverruns = 0;
53
54   static const double K = 1e-4;
55   long  integrator[2];
56   int   offset[2];
57
58   integrator[0] = 0;
59   integrator[1] = 0;
60   offset[0] = 0;
61   offset[1] = 0;
62
63   u->start();           // start data xfers
64
65   while(!cal_done){
66     int ret = u->read (buf, sizeof (buf), &overrun);
67     if (ret != (int) sizeof (buf)){
68       fprintf (stderr, "usrp_cal_dc_offset: error, ret = %d\n", ret);
69       continue;
70     }
71     if (overrun){
72       fprintf (stderr, "O");
73       noverruns++;
74     }
75     else {
76       // fputc('.', stderr);
77     }
78
79     static const int MAX = (1L << 30);          // 1G
80
81     for (int i = 0; i < N/2; i++){
82       for (int n = 0; n < 2; n++){
83         integrator[n] = integrator[n] + buf[2*i + n];
84         if (integrator[n] > MAX)
85           integrator[n] = MAX;
86         else if (integrator[n] < -MAX)
87           integrator[n] = -MAX;
88       }
89     }
90
91 #if 1
92     for (int n = 0; n < 2; n++){
93       offset[n] = (int) rint(integrator[n] * K);
94       if (offset[n] > 32767)
95         offset[n] = 32767;
96       else if (offset[n] < -32767)
97         offset[n] = -32767;
98       u->set_adc_offset(which_side * 2 + n, offset[n]);
99     }
100 #else
101     offset[0] = (int) rint(integrator[0] * K);
102     if (offset[0] > 32767)
103       offset[0] = 32767;
104     else if (offset[0] < -32767)
105       offset[0] = -32767;
106     u->set_adc_offset(which_side * 2 + 0, offset[0]);
107     u->set_adc_offset(which_side * 2 + 1, offset[0]);
108 #endif
109     
110
111     printf ("%9ld : %6d\t\t%9ld : %6d\n",
112             integrator[0], offset[0], integrator[1], offset[1]);
113   }
114
115   u->stop();
116 }
117
118
119 static void
120 set_progname (char *path)
121 {
122   char *p = strrchr (path, '/');
123   if (p != 0)
124     prog_name = p+1;
125   else
126     prog_name = path;
127 }
128
129 static void
130 usage ()
131 {
132   fprintf(stderr, "usage: %s [-v] [-w which_side] [-D decim] [-c ddc_freq] [-g gain]\n", prog_name);
133   fprintf(stderr, "  [-S fusb_block_size] [-N fusb_nblocks]\n");
134   exit (1);
135 }
136
137 static void
138 die (const char *msg)
139 {
140   fprintf (stderr, "die: %s: %s\n", prog_name, msg);
141   exit (1);
142 }
143
144 int
145 main (int argc, char **argv)
146 {
147   int       ch;
148   int       decim = 128;                // 500 kS/sec
149   bool      verbose_p = false;
150   int       which_board = 0;
151   int       which_side = 0;
152   double    ddc_freq = 0;
153   int       fusb_block_size = 1024;
154   int       fusb_nblocks = 4;
155   double    pga_gain = 0.0;
156
157   set_progname(argv[0]);
158
159   while ((ch = getopt (argc, argv, "vw:D:c:S:N:g:")) != EOF){
160     switch (ch){
161
162     case 'w':
163       which_side = strtol (optarg, 0, 0);
164       if (which_side < 0 || which_side > 1)
165         usage();
166       break;
167
168     case 'D':
169       decim = strtol (optarg, 0, 0);
170       if (decim < 1)
171         usage();
172       break;
173
174     case 'c':
175       ddc_freq = strtod (optarg, 0);
176       break;
177
178     case 'v':
179       verbose_p = true;
180       break;
181
182     case 'S':
183       fusb_block_size = strtol(optarg, 0, 0);
184       break;
185
186     case 'N':
187       fusb_nblocks = strtol(optarg, 0, 0);
188       break;
189
190     case 'g':
191       pga_gain = strtod (optarg, 0);
192       break;
193
194     default:
195       usage ();
196     }
197   }
198
199   int nchannels = 1;
200   int mode = usrp_standard_rx::FPGA_MODE_NORMAL;
201   int mux;
202
203   if (which_side == 0)
204     mux = 0x00000010;
205   else
206     mux = 0x00000032;
207
208 #ifdef SIGINT
209   usrp_local_sighandler sigint (SIGINT, usrp_local_sighandler::throw_signal);
210 #endif
211 #ifdef SIGQUIT
212   usrp_local_sighandler sigquit (SIGQUIT, usrp_local_sighandler::throw_signal);
213 #endif
214
215   usrp_standard_rx_sptr urx =
216     usrp_standard_rx::make(which_board, decim,
217                            nchannels, mux, mode,
218                            fusb_block_size, fusb_nblocks);
219   if (!urx)
220     die("usrp_standard_rx::make");
221
222   try {
223
224     if (!urx->set_rx_freq(0, ddc_freq))
225       die("urx->set_rx_freq");
226
227     urx->set_pga(2 * which_side + 0, pga_gain);
228     urx->set_pga(2 * which_side + 1, pga_gain);
229     
230     run_cal(urx, which_side, decim, verbose_p);
231   }
232   catch (usrp_signal &sig){
233     fprintf (stderr, "usrp_cal_dc_offset: caught %s\n", sig.name().c_str());
234   }
235   catch(...){
236     fprintf (stderr, "usrp_cal_dc_offset: caught something\n");
237   }
238 }
239