Imported Upstream version 3.2.2
[debian/gnuradio] / gr-usrp / apps / usrp_rx_cfile.cc
1 /*
2  * Copyright 2008 Free Software Foundation, Inc.
3  * 
4  * This file is part of GNU Radio
5  * 
6  * GNU Radio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  * 
11  * GNU Radio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with GNU Radio; see the file COPYING.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #include <usrp_rx_cfile.h>
23 #include <gr_io_signature.h>
24 #include <gr_head.h>
25 #include <stdexcept>
26 #include <iostream>
27 #include <boost/program_options.hpp>
28
29 namespace po = boost::program_options;
30
31 usrp_subdev_spec
32 str_to_subdev(std::string spec_str)
33 {
34   usrp_subdev_spec spec;
35   if(spec_str == "A" || spec_str == "A:0" || spec_str == "0:0") {
36     spec.side = 0;
37     spec.subdev = 0;
38   }
39   else if(spec_str == "A:1" || spec_str == "0:1") {
40     spec.side = 0;
41     spec.subdev = 1;
42   }
43   else if(spec_str == "B" || spec_str == "B:0" || spec_str == "1:0") {
44     spec.side = 1;
45     spec.subdev = 0;
46   }
47   else if(spec_str == "B:1" || spec_str == "1:1") {
48     spec.side = 1;
49     spec.subdev = 1;
50   }
51   else {
52     throw std::range_error("Incorrect subdevice specifications.\n");
53   }
54
55   return spec;
56 }
57
58
59 // Shared pointer constructor
60 usrp_rx_cfile_sptr make_usrp_rx_cfile(int which, usrp_subdev_spec spec, 
61                                       int decim, double freq, float gain,
62                                       bool width8, bool nohb,
63                                       bool output_shorts, int nsamples,
64                                       const std::string &filename)
65 {
66   return gnuradio::get_initial_sptr(new usrp_rx_cfile(which, spec, 
67                                                       decim, freq, gain,
68                                                       width8, nohb,
69                                                       output_shorts, 
70                                                       nsamples,
71                                                       filename));
72 }
73
74 // Hierarchical block constructor, with no inputs or outputs
75 usrp_rx_cfile::usrp_rx_cfile(int which, usrp_subdev_spec spec, 
76                              int decim, double freq, float gain,
77                              bool width8, bool nohb,
78                              bool output_shorts, int nsamples,
79                              const std::string &filename) : 
80   gr_top_block("usrp_rx_cfile"),
81   d_which(which),  d_spec(spec), d_decim(decim), d_freq(freq), 
82   d_gain(gain), d_width8(width8), d_nohb(nohb), d_nsamples(nsamples), 
83   d_filename(filename)
84 {
85   usrp_source_c_sptr usrp;
86
87   if(d_nohb || (d_decim<8)) {
88     // Min decimation of this firmware is 4. 
89     // contains 4 Rx paths without halfbands and 0 tx paths.
90     std::string fpga_filename="std_4rx_0tx.rbf";
91
92     // use default values and add fpga_filename
93     usrp = usrp_make_source_c(d_which, d_decim,
94                               1, -1, 0, 0, 0,
95                               fpga_filename.c_str());
96   }
97   else {
98     // standard fpga firmware "std_2rxhb_2tx.rbf" contains 
99     // 2 Rx paths with halfband filters and 2 tx paths 
100     //(the default) min decimation 8
101     usrp = usrp_make_source_c(d_which, d_decim);
102   }
103
104   if(d_width8) {
105     int sample_width = 8;
106     int sample_shift = 8;
107     int format = usrp->make_format(sample_width, sample_shift);
108     int r = usrp->set_format(format);
109     printf("width8: format=%d  r=%d\n", format, r);
110   }
111
112
113   /* Get subdevice and process it */
114   db_base_sptr subdev = usrp->selected_subdev(d_spec);
115   printf("\nSubdevice name is %s\n", subdev->side_and_name().c_str());
116   printf("Subdevice freq range: (%g, %g)\n", 
117          subdev->freq_min(), subdev->freq_max());
118
119   unsigned int mux = usrp->determine_rx_mux_value(d_spec);
120   printf("mux: %#08x\n",  mux);
121   usrp->set_mux(mux);
122
123   float gain_min = subdev->gain_min();
124   float gain_max = subdev->gain_max();
125   if(d_gain == -1) {
126     d_gain = (gain_min + gain_max)/2.0;
127   }
128   printf("gain: %g\n", d_gain);
129   subdev->set_gain(d_gain);
130
131     
132   /* Set the USRP/dboard frequency */
133   usrp_tune_result r;
134   bool ok = usrp->tune(0, subdev, freq, &r); //DDC 0
135   
136   if(!ok) {
137     throw std::runtime_error("Could not set frequency.");
138   }
139
140   /* The rest */
141   d_dst = gr_make_file_sink(sizeof(gr_complex), d_filename.c_str());
142
143   if(d_nsamples == -1) {
144     connect(usrp, 0, d_dst, 0);
145   }
146   else {
147     d_head = gr_make_head(sizeof(gr_complex), d_nsamples*2);
148     connect(usrp, 0, d_head, 0);
149     connect(d_head, 0, d_dst, 0);
150   }
151 }
152
153
154 int main(int argc, char *argv[])
155 {
156   int which = 0;                       // specify which USRP board
157   usrp_subdev_spec spec(0,0);          // specify the d'board side
158   int decim = 16;                      // set the decimation rate
159   double freq = 0;                     // set the frequency
160   float gain = -1;                     // set the gain; -1 will set the mid-point gain
161   int nsamples = -1;                   // set the number of samples to collect; -1 will continue
162   bool width8 = false;                 // use 8-bit samples across USB
163   bool nohb = false;                   // don't use halfband filter in USRP
164   bool output_shorts = false;          // use shorts
165   std::string filename = "received.dat";
166
167   po::options_description cmdconfig("Program options: usrp_text_rx [options] filename");
168   cmdconfig.add_options()
169     ("help,h", "produce help message")
170     ("which,W", po::value<int>(&which), "select which USRP board")
171     ("rx-subdev-spec,R", po::value<std::string>(), "select USRP Rx side A or B (default=A)")
172     ("decim,d", po::value<int>(&decim), "set fgpa decimation rate to DECIM")
173     ("freq,f", po::value<double>(), "set frequency to FREQ")
174     ("gain,g", po::value<float>(), "set gain in dB (default is midpoint)")
175     ("width-8,8", "Enable 8-bit samples across USB")
176     ("no-hb", "don't use halfband filter in usrp")
177     //("output-shorts,s", "output interleaved shorts in stead of complex floats")
178     ("nsamples,N", po::value<int>(&nsamples), "number of samples to collect")
179     ;
180
181   po::options_description fileconfig("Input file options");
182   fileconfig.add_options()
183     ("filename", po::value<std::string>(), "input file")
184     ;
185
186   po::positional_options_description inputfile;
187   inputfile.add("filename", -1);
188
189   po::options_description config;
190   config.add(cmdconfig).add(fileconfig);
191   
192   po::variables_map vm;
193   po::store(po::command_line_parser(argc, argv).
194             options(config).positional(inputfile).run(), vm);
195   po::notify(vm);
196   
197   if (vm.count("help")) {
198     std::cout << cmdconfig << "\n";
199     return 1;
200   }
201
202   if(vm.count("filename")) {
203     filename = vm["filename"].as<std::string>();
204   }
205   
206   if(vm.count("freq")) {
207     freq = vm["freq"].as<double>();
208   }
209   else {
210     fprintf(stderr, "You must specify a frequency.\n");
211     return -1;
212   }
213
214   if(vm.count("rx-subdev-spec")) {
215     std::string s = vm["rx-subdev-spec"].as<std::string>();
216     spec = str_to_subdev(s);
217   }
218
219   if(vm.count("width-8")) {
220     width8 = true;
221   }
222   if(vm.count("nohb")) {
223     nohb = true;
224   }
225   if(vm.count("output-shorts")) {
226     output_shorts = true;
227   }
228
229   std::cout << "which:   " << which << std::endl;
230   std::cout << "decim:   " << decim << std::endl;
231   std::cout << "freq:    " << freq << std::endl;
232   std::cout << "gain:    " << gain << std::endl;
233   std::cout << "width-8  " << (width8 ? "Yes" : "No") << std::endl;
234   std::cout << "no-hb    " << (nohb ? "Yes" : "no") << std::endl;
235   std::cout << "shorts:  " << (output_shorts ? "Yes" : "No") << std::endl;
236   std::cout << "samples: " << nsamples << std::endl;
237
238   usrp_rx_cfile_sptr top_block = make_usrp_rx_cfile(which, spec, decim, freq, 
239                                                     gain, width8, nohb, 
240                                                     output_shorts, nsamples,
241                                                     filename);
242   top_block->run();
243     
244   return 0;
245 }