Statistics
| Branch: | Tag: | Revision:

root / host / examples / tx_samples_from_file.cpp @ 539c9b5a

History | View | Annotate | Download (7.56 KB)

1
//
2
// Copyright 2011 Ettus Research LLC
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

    
18
#include <uhd/utils/thread_priority.hpp>
19
#include <uhd/utils/safe_main.hpp>
20
#include <uhd/usrp/multi_usrp.hpp>
21
#include <boost/program_options.hpp>
22
#include <boost/format.hpp>
23
#include <boost/thread.hpp>
24
#include <iostream>
25
#include <fstream>
26
#include <complex>
27

    
28
namespace po = boost::program_options;
29

    
30
template<typename samp_type> void send_from_file(
31
    uhd::usrp::multi_usrp::sptr usrp,
32
    const uhd::io_type_t &io_type,
33
    const std::string &file,
34
    size_t samps_per_buff
35
){
36
    uhd::tx_metadata_t md;
37
    md.start_of_burst = false;
38
    md.end_of_burst = false;
39
    std::vector<samp_type> buff(samps_per_buff);
40
    std::ifstream infile(file.c_str(), std::ifstream::binary);
41

    
42
    //loop until the entire file has been read
43
    while(not md.end_of_burst){
44

    
45
        infile.read((char*)&buff.front(), buff.size()*sizeof(samp_type));
46
        size_t num_tx_samps = infile.gcount()/sizeof(samp_type);
47

    
48
        md.end_of_burst = infile.eof();
49

    
50
        usrp->get_device()->send(
51
            &buff.front(), num_tx_samps, md, io_type,
52
            uhd::device::SEND_MODE_FULL_BUFF
53
        );
54
    }
55

    
56
    infile.close();
57
}
58

    
59
int UHD_SAFE_MAIN(int argc, char *argv[]){
60
    uhd::set_thread_priority_safe();
61

    
62
    //variables to be set by po
63
    std::string args, file, type, ant, subdev, ref;
64
    size_t spb;
65
    double rate, freq, gain, bw;
66

    
67
    //setup the program options
68
    po::options_description desc("Allowed options");
69
    desc.add_options()
70
        ("help", "help message")
71
        ("args", po::value<std::string>(&args)->default_value(""), "multi uhd device address args")
72
        ("file", po::value<std::string>(&file)->default_value("usrp_samples.dat"), "name of the file to read binary samples from")
73
        ("type", po::value<std::string>(&type)->default_value("float"), "sample type: double, float, or short")
74
        ("spb", po::value<size_t>(&spb)->default_value(10000), "samples per buffer")
75
        ("rate", po::value<double>(&rate), "rate of outgoing samples")
76
        ("freq", po::value<double>(&freq), "RF center frequency in Hz")
77
        ("gain", po::value<double>(&gain), "gain for the RF chain")
78
        ("ant", po::value<std::string>(&ant), "daughterboard antenna selection")
79
        ("subdev", po::value<std::string>(&subdev), "daughterboard subdevice specification")
80
        ("bw", po::value<double>(&bw), "daughterboard IF filter bandwidth in Hz")
81
        ("ref", po::value<std::string>(&ref)->default_value("INTERNAL"), "waveform type (INTERNAL, EXTERNAL, MIMO)")
82
    ;
83
    po::variables_map vm;
84
    po::store(po::parse_command_line(argc, argv, desc), vm);
85
    po::notify(vm);
86

    
87
    //print the help message
88
    if (vm.count("help")){
89
        std::cout << boost::format("UHD TX samples from file %s") % desc << std::endl;
90
        return ~0;
91
    }
92

    
93
    //create a usrp device
94
    std::cout << std::endl;
95
    std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
96
    uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
97

    
98
    //Lock mboard clocks
99
    if (ref == "MIMO") {
100
        uhd::clock_config_t clock_config;
101
        clock_config.ref_source = uhd::clock_config_t::REF_MIMO;
102
        clock_config.pps_source = uhd::clock_config_t::PPS_MIMO;
103
        usrp->set_clock_config(clock_config, 0);
104
    }
105
    else if (ref == "EXTERNAL") {
106
        usrp->set_clock_config(uhd::clock_config_t::external(), 0);
107
    }
108
    else if (ref == "INTERNAL") {
109
        usrp->set_clock_config(uhd::clock_config_t::internal(), 0);
110
    }
111

    
112
    //always select the subdevice first, the channel mapping affects the other settings
113
    if (vm.count("subdev")) usrp->set_tx_subdev_spec(subdev);
114

    
115
    std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl;
116

    
117
    //set the sample rate
118
    if (not vm.count("rate")){
119
        std::cerr << "Please specify the sample rate with --rate" << std::endl;
120
        return ~0;
121
    }
122
    std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl;
123
    usrp->set_tx_rate(rate);
124
    std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl << std::endl;
125

    
126
    //set the center frequency
127
    if (not vm.count("freq")){
128
        std::cerr << "Please specify the center frequency with --freq" << std::endl;
129
        return ~0;
130
    }
131
    std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq/1e6) << std::endl;
132
    usrp->set_tx_freq(freq);
133
    std::cout << boost::format("Actual TX Freq: %f MHz...") % (usrp->get_tx_freq()/1e6) << std::endl << std::endl;
134

    
135
    //set the rf gain
136
    if (vm.count("gain")){
137
        std::cout << boost::format("Setting TX Gain: %f dB...") % gain << std::endl;
138
        usrp->set_tx_gain(gain);
139
        std::cout << boost::format("Actual TX Gain: %f dB...") % usrp->get_tx_gain() << std::endl << std::endl;
140
    }
141

    
142
    //set the IF filter bandwidth
143
    if (vm.count("bw")){
144
        std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % bw << std::endl;
145
        usrp->set_tx_bandwidth(bw);
146
        std::cout << boost::format("Actual TX Bandwidth: %f MHz...") % usrp->get_tx_bandwidth() << std::endl << std::endl;
147
    }
148

    
149
    //set the antenna
150
    if (vm.count("ant")) usrp->set_tx_antenna(ant);
151

    
152
    boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for some setup time
153

    
154
    //Check Ref and LO Lock detect
155
    std::vector<std::string> sensor_names;
156
    sensor_names = usrp->get_tx_sensor_names(0);
157
    if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end()) {
158
        uhd::sensor_value_t lo_locked = usrp->get_tx_sensor("lo_locked",0);
159
        std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() << std::endl;
160
        UHD_ASSERT_THROW(lo_locked.to_bool());
161
    }
162
    sensor_names = usrp->get_mboard_sensor_names(0);
163
    if ((ref == "MIMO") and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") != sensor_names.end())) {
164
        uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked",0);
165
        std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string() << std::endl;
166
        UHD_ASSERT_THROW(mimo_locked.to_bool());
167
    }
168
    if ((ref == "EXTERNAL") and (std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end())) {
169
        uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked",0);
170
        std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string() << std::endl;
171
        UHD_ASSERT_THROW(ref_locked.to_bool());
172
    }
173

    
174
    //send from file
175
    if (type == "double") send_from_file<std::complex<double> >(usrp, uhd::io_type_t::COMPLEX_FLOAT64, file, spb);
176
    else if (type == "float") send_from_file<std::complex<float> >(usrp, uhd::io_type_t::COMPLEX_FLOAT32, file, spb);
177
    else if (type == "short") send_from_file<std::complex<short> >(usrp, uhd::io_type_t::COMPLEX_INT16, file, spb);
178
    else throw std::runtime_error("Unknown type " + type);
179

    
180
    //finished
181
    std::cout << std::endl << "Done!" << std::endl << std::endl;
182

    
183
    return 0;
184
}