Statistics
| Branch: | Tag: | Revision:

root / gr-usrp / apps / usrp_siggen.cc @ 1910719e

History | View | Annotate | Download (6.8 kB)

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_siggen.h>
23
#include <gr_io_signature.h>
24
#include <gr_head.h>
25
#include <gr_noise_type.h>
26
#include <stdexcept>
27
#include <iostream>
28
#include <boost/program_options.hpp>
29
30
namespace po = boost::program_options;
31
32
usrp_subdev_spec
33
str_to_subdev(std::string spec_str)
34
{
35
  usrp_subdev_spec spec;
36
  if(spec_str == "A" || spec_str == "A:0" || spec_str == "0:0") {
37
    spec.side = 0;
38
    spec.subdev = 0;
39
  }
40
  else if(spec_str == "A:1" || spec_str == "0:1") {
41
    spec.side = 0;
42
    spec.subdev = 1;
43
  }
44
  else if(spec_str == "B" || spec_str == "B:0" || spec_str == "1:0") {
45
    spec.side = 1;
46
    spec.subdev = 0;
47
  }
48
  else if(spec_str == "B:1" || spec_str == "1:1") {
49
    spec.side = 1;
50
    spec.subdev = 1;
51
  }
52
  else {
53
    throw std::range_error("Incorrect subdevice specifications.\n");
54
  }
55
56
  return spec;
57
}
58
59
// Shared pointer constructor
60
usrp_siggen_sptr make_usrp_siggen(int which, usrp_subdev_spec spec, 
61
                                  double rf_freq, int interp, double wfreq,
62
                                  int waveform, float amp, float gain, 
63
                                  float offset, long long nsamples)
64
{
65
  return gnuradio::get_initial_sptr(new usrp_siggen(which, spec, 
66
                                                    rf_freq, interp, wfreq,
67
                                                    waveform, amp, gain, 
68
                                                    offset, nsamples));
69
}
70
71
// Hierarchical block constructor, with no inputs or outputs
72
usrp_siggen::usrp_siggen(int which, usrp_subdev_spec spec, 
73
                         double rf_freq, int interp, double wfreq,
74
                         int waveform, float amp, float gain, 
75
                         float offset, long long nsamples)
76
  : gr_top_block("usrp_siggen")
77
{
78
  usrp_sink_c_sptr usrp = usrp_make_sink_c(which, interp);
79
80
  db_base_sptr subdev = usrp->selected_subdev(spec);
81
  printf("Subdevice name is %s\n", subdev->name().c_str());
82
  printf("Subdevice freq range: (%g, %g)\n", 
83
         subdev->freq_min(), subdev->freq_max());
84
85
  unsigned int mux = usrp->determine_tx_mux_value(spec);
86
  printf("mux: %#08x\n",  mux);
87
  usrp->set_mux(mux);
88
89
  if(gain == -1) {
90
    gain = subdev->gain_max();
91
  }
92
  subdev->set_gain(gain);
93
94
  float input_rate = usrp->dac_freq() / usrp->interp_rate();
95
  printf("baseband rate: %g\n",  input_rate);
96
97
  usrp_tune_result r;
98
  double target_freq = rf_freq;
99
  bool ok = usrp->tune(subdev->which(), subdev, target_freq, &r);
100
101
  if(!ok) {
102
    throw std::runtime_error("Could not set frequency.");
103
  }
104
105
  subdev->set_enable(true);
106
  
107
  printf("target_freq:     %f\n", target_freq);
108
  printf("ok:              %s\n", ok ? "true" : "false");
109
  printf("r.baseband_freq: %f\n", r.baseband_freq);
110
  printf("r.dxc_freq:      %f\n", r.dxc_freq);
111
  printf("r.residual_freq: %f\n", r.residual_freq);
112
  printf("r.inverted:      %d\n", r.inverted);
113
114
  /* Set up the signal source */
115
  siggen = gr_make_sig_source_c(input_rate, GR_SIN_WAVE, wfreq, amp);
116
  noisegen = gr_make_noise_source_c (GR_UNIFORM, amp);
117
  if(waveform == GR_SIN_WAVE || waveform == GR_CONST_WAVE) {
118
    source = siggen;
119
  }
120
  else if(waveform == GR_UNIFORM || waveform == GR_GAUSSIAN) {
121
    source = noisegen;
122
  }
123
  else {
124
    throw std::range_error("Unknown waveform type.\n");
125
  }
126
127
  siggen->set_waveform((gr_waveform_t)waveform);
128
129
  if (nsamples > 0){
130
    gr_block_sptr head = gr_make_head(sizeof(gr_complex), nsamples);
131
    connect(source, 0, head, 0);
132
    connect(head, 0, usrp, 0);
133
  }
134
  else {
135
    connect(source, 0, usrp, 0);
136
  }
137
}
138
139
int main(int argc, char *argv[])
140
{
141
  int which = 0;                       // specify which USRP board
142
  usrp_subdev_spec spec(0,0);          // specify the d'board side
143
  int interp = 128;                    // set the interpolation rate
144
  double rf_freq = 0;                  // set the frequency
145
  double wfreq = 100e3;                // set the waveform frequency
146
  float amp = 5;                       // set the amplitude of the output
147
  float gain = -1;                     // set the d'board PGA gain
148
  float offset = 0;                    // set waveform offset
149
  int waveform;
150
  double nsamples = 0;                       // set the number of samples to transmit (0 -> inf)
151
152
  po::options_description cmdconfig("Program options");
153
  cmdconfig.add_options()
154
    ("help,h", "produce help message")
155
    ("which,W", po::value<int>(&which), "select which USRP board")
156
    ("tx-subdev-spec,T", po::value<std::string>(), "select USRP Tx side A or B")
157
    ("rf-freq,f", po::value<double>(), "set RF center frequency to FREQ")
158
    ("interp,i", po::value<int>(&interp), "set fgpa interpolation rate to INTERP")
159
160
    ("sine", "generate a complex sinusoid [default]")
161
    ("const", "generate a constant output")
162
    ("gaussian", "generate Gaussian random output")
163
    ("uniform", "generate Uniform random output")
164
165
    ("waveform-freq,w", po::value<double>(&wfreq), "set waveform frequency to FREQ")
166
    ("amplitude,a", po::value<float>(&amp), "set amplitude")
167
    ("gain,g", po::value<float>(&gain), "set output gain to GAIN")
168
    ("offset,o", po::value<float>(&offset), "set waveform offset to OFFSET")
169
    ("nsamples,N", po::value<double>(&nsamples), "number of samples to send [default=+inf]")
170
    ;
171
  
172
  po::variables_map vm;
173
  po::store(po::command_line_parser(argc, argv).
174
            options(cmdconfig).run(), vm);
175
  po::notify(vm);
176
  
177
  if (vm.count("help")) {
178
    std::cout << cmdconfig << "\n";
179
    return 1;
180
  }
181
  
182
  if(vm.count("rf-freq")) {
183
    rf_freq = vm["rf-freq"].as<double>();
184
  }
185
  else {
186
    fprintf(stderr, "You must specify a frequency.\n");
187
    return -1;
188
  }
189
190
  if(vm.count("tx-subdev-spec")) {
191
    std::string s = vm["tx-subdev-spec"].as<std::string>();
192
    spec = str_to_subdev(s);
193
  }
194
195
  if(vm.count("sine")) {
196
    waveform = GR_SIN_WAVE;
197
  }
198
  else if(vm.count("const")) {
199
    waveform = GR_CONST_WAVE;
200
  }
201
  else if(vm.count("gaussian")) {
202
    waveform = GR_GAUSSIAN;
203
  }
204
  else if(vm.count("uniform")) {
205
    waveform = GR_UNIFORM;
206
  }
207
  else {
208
    waveform = GR_SIN_WAVE;
209
  }
210
211
  printf("which:    %d\n", which);
212
  printf("interp:   %d\n", interp);
213
  printf("rf_freq:  %g\n", rf_freq);
214
  printf("amp:      %f\n", amp);
215
  printf("nsamples: %g\n", nsamples);
216
217
  usrp_siggen_sptr top_block = make_usrp_siggen(which, spec, rf_freq, 
218
                                                interp, wfreq, waveform,
219
                                                amp, gain, offset, (long long) nsamples);
220
221
  top_block->run();
222
  
223
  return 0;
224
}