3 * Copyright 2003,2004,2008,2009 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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)
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.
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.
32 #include <usb.h> /* needed for usb functions */
36 #include "time_stuff.h"
37 #include "usrp_standard.h"
38 #include "usrp_bytesex.h"
39 #include <boost/program_options.hpp>
46 namespace po = boost::program_options;
51 str_to_subdev(std::string spec_str)
53 usrp_subdev_spec spec;
54 if(spec_str == "A" || spec_str == "A:0" || spec_str == "0:0") {
58 else if(spec_str == "A:1" || spec_str == "0:1") {
62 else if(spec_str == "B" || spec_str == "B:0" || spec_str == "1:0") {
66 else if(spec_str == "B:1" || spec_str == "1:1") {
71 throw std::range_error("Incorrect subdevice specifications.\n");
79 set_progname (char *path)
81 char *p = strrchr (path, '/');
91 fprintf (stderr, "die: %s: %s\n", prog_name, msg);
97 test_output (usrp_standard_tx_sptr utx, long long max_bytes, double ampl, int waveform)
99 const int BUFSIZE = utx->block_size();
100 const int N = BUFSIZE/sizeof (short);
103 long long nbytes = 0;
105 // ----------------------------------------------------------------
106 // one time initialization of the pattern we're going to transmit
108 const int PERIOD = 65; // any value is valid
109 const int PATLEN = 2 * PERIOD;
110 short pattern[PATLEN];
112 for (int i = 0; i < PERIOD; i++){
113 if (waveform == GR_CONST_WAVE){
114 pattern[2*i+0] = host_to_usrp_short((short) ampl);
115 pattern[2*i+1] = host_to_usrp_short((short) 0);
118 pattern[2*i+0] = host_to_usrp_short((short) (ampl * cos(2*M_PI * i / PERIOD)));
119 pattern[2*i+1] = host_to_usrp_short((short) (ampl * sin(2*M_PI * i / PERIOD)));
123 // ----------------------------------------------------------------
125 double start_wall_time = get_elapsed_time ();
126 double start_cpu_time = get_cpu_usage ();
132 for (nbytes = 0; max_bytes == 0 || nbytes < max_bytes; nbytes += BUFSIZE){
134 for (int i = 0; i < N; i++){
135 buf[i] = pattern[pi];
141 int ret = utx->write (buf, sizeof (buf), &underrun);
142 if ((unsigned) ret != sizeof (buf)){
143 fprintf (stderr, "test_output: error, ret = %d\n", ret);
148 printf ("tx_underrun\n");
149 //printf ("tx_underrun %9d %6d\n", nbytes, nbytes/BUFSIZE);
153 utx->wait_for_completion ();
155 double stop_wall_time = get_elapsed_time ();
156 double stop_cpu_time = get_cpu_usage ();
158 double delta_wall = stop_wall_time - start_wall_time;
159 double delta_cpu = stop_cpu_time - start_cpu_time;
161 printf ("xfered %.3g bytes in %.3g seconds. %.4g bytes/sec. cpu time = %.3g\n",
162 (double) max_bytes, delta_wall, max_bytes / delta_wall, delta_cpu);
164 printf ("%d underruns\n", nunderruns);
170 main (int argc, char **argv)
172 int which = 0; // specify which USRP board
173 usrp_subdev_spec spec(0,0); // specify the d'board side
174 int interp = 16; // set the interpolation rate
175 double rf_freq = -1; // set the frequency
176 float amp = 10000; // set the amplitude of the output
177 float gain = -1; // set the d'board PGA gain
179 int fusb_block_size = 0;
180 int fusb_nblocks = 0;
181 bool realtime_p = false;
182 double nsamples = 32e6;
184 set_progname (argv[0]);
186 po::options_description cmdconfig("Program options");
187 cmdconfig.add_options()
188 ("help,h", "produce help message")
189 ("which,W", po::value<int>(&which), "select which USRP board")
190 ("tx-subdev-spec,T", po::value<std::string>(), "select USRP Tx side A or B")
191 ("rf-freq,f", po::value<double>(), "set RF center frequency to FREQ")
192 ("interp,i", po::value<int>(&interp), "set fgpa interpolation rate to INTERP")
194 ("sine", "generate a complex sinusoid [default]")
195 ("const", "generate a constant output")
197 //("waveform-freq,w", po::value<double>(&wfreq), "set waveform frequency to FREQ")
198 ("amplitude,a", po::value<float>(&), "set amplitude")
199 ("gain,g", po::value<float>(&gain), "set output gain to GAIN [default=MAX]")
200 //("offset,o", po::value<float>(&offset), "set waveform offset to OFFSET")
201 ("nsamples,N", po::value<double>(&nsamples), "number of samples to send [default=32M]")
204 po::variables_map vm;
205 po::store(po::command_line_parser(argc, argv).
206 options(cmdconfig).run(), vm);
209 if (vm.count("help")) {
210 std::cout << cmdconfig << "\n";
214 if(vm.count("tx-subdev-spec")) {
215 std::string s = vm["tx-subdev-spec"].as<std::string>();
216 spec = str_to_subdev(s);
219 if(vm.count("sine")) {
220 waveform = GR_SIN_WAVE;
222 else if(vm.count("const")) {
223 waveform = GR_CONST_WAVE;
226 waveform = GR_SIN_WAVE;
229 printf("which: %d\n", which);
230 printf("interp: %d\n", interp);
231 printf("rf_freq: %g\n", rf_freq);
232 printf("amp: %f\n", amp);
233 printf("nsamples: %g\n", nsamples);
240 usrp_standard_tx_sptr utx;
242 utx = usrp_standard_tx::make (which,
250 die ("usrp_standard_tx::make");
254 db_base_sptr subdev = utx->selected_subdev(spec);
255 printf("Subdevice name is %s\n", subdev->name().c_str());
256 printf("Subdevice freq range: (%g, %g)\n",
257 subdev->freq_min(), subdev->freq_max());
259 unsigned int mux = utx->determine_tx_mux_value(spec);
260 printf("mux: %#08x\n", mux);
264 gain = subdev->gain_max();
265 subdev->set_gain(gain);
267 float input_rate = utx->dac_rate() / utx->interp_rate();
268 printf("baseband rate: %g\n", input_rate);
273 rf_freq = (subdev->freq_min() + subdev->freq_max()) * 0.5;
274 double target_freq = rf_freq;
275 bool ok = utx->tune(subdev->which(), subdev, target_freq, &r);
278 throw std::runtime_error("Could not set frequency.");
281 subdev->set_enable(true);
283 printf("target_freq: %f\n", target_freq);
284 printf("ok: %s\n", ok ? "true" : "false");
285 printf("r.baseband_freq: %f\n", r.baseband_freq);
286 printf("r.dxc_freq: %f\n", r.dxc_freq);
287 printf("r.residual_freq: %f\n", r.residual_freq);
288 printf("r.inverted: %d\n", r.inverted);
294 utx->start(); // start data xfers
296 test_output (utx, (long long) nsamples, amp, waveform);
304 fusb_block_size = strtol (optarg, 0, 0);
308 fusb_nblocks = strtol (optarg, 0, 0);