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>(&), "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 | } |