![]() |
four_multi
Multi-Antenna,Multi-Node,Multi-Band,Multi-Cell
|
00001 // 00002 // Copyright 2011-2013 KTH Royal Institute of Technology 00003 // 00004 // This program is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 00017 00018 00019 #include <fstream> 00020 #include <uhd/utils/thread_priority.hpp> 00021 #include <uhd/utils/safe_main.hpp> 00022 #include <uhd/usrp/multi_usrp.hpp> 00023 #include <boost/program_options.hpp> 00024 #include <boost/format.hpp> 00025 #include <iostream> 00026 #include <complex> 00027 #include <uhd/types/clock_config.hpp> 00028 #include <itpp/itbase.h> 00029 #include <four_multi/get_usrp2_ip_addr.hpp> 00030 #include <four_multi/gps.hpp> 00031 00032 00033 00034 namespace po = boost::program_options; 00035 00036 int UHD_SAFE_MAIN(int argc, char *argv[]){ 00037 00038 00039 00040 00041 double d_rate; 00042 static const time_t time_available_for_trigger=1; 00043 00044 //variables to be set by po 00045 std::string args; 00046 time_t seconds_in_future=1; 00047 uint32_t total_num_samps, gps_time_combined; 00048 uint32_t no_chan, skip_ant; 00049 double freq; 00050 std::string filename, dev_name; 00051 bool use_external_10MHz, use_J1; 00052 00053 std::string gains_str; 00054 itpp::vec gains; // IT++ class 00055 //std::vector<double> gains_vec; 00056 std::string IP_addresses, IP_addresses1; // Adresses of the USRPs 00057 00058 00059 // Internal variables 00060 uhd::clock_config_t my_clock_config; 00061 00062 //setup the program options 00063 po::options_description desc("Allowed options"); 00064 desc.add_options() 00065 ("10MHz",po::value<bool>(&use_external_10MHz)->default_value(false), 00066 "external 10MHz on 'REF CLOCK' connector (true=1=yes)") 00067 ("gps_time_combined", po::value<uint32_t>(&gps_time_combined)->default_value(0), "start time triggering using GPS and PPS (h*3600+m*60+s, or =0 no triggering)") 00068 ("dev_name",po::value<std::string>(&dev_name)->default_value("/dev/ttyUSB0"), "Name of GPS device") 00069 ("help", "help message") 00070 ("rate", po::value<double>(&d_rate)->default_value(25e6), "sample rate") 00071 ("nsamps", po::value<uint32_t>(&total_num_samps)->default_value(1000), "total number of samples to receive") 00072 ("nchan", po::value<uint32_t>(&no_chan)->default_value(1), "number of usrp2:s") 00073 ("skip_ant",po::value<uint32_t>(&skip_ant)->default_value(0), 00074 "Example: if skip_ant=1 then the first USPR2 should have address 192.168.20.2") 00075 ("freq", po::value<double>(&freq)->default_value(2420e6), "rf center frequency in Hz") 00076 ("filename",po::value<std::string>(&filename)->default_value("data_from_usrp.dat"), "output filename") 00077 ("gains",po::value<std::string>(&gains_str)->default_value("0 0 0 0"), 00078 "set the receiver gains") 00079 ("use_J1",po::value<bool>(&use_J1)->default_value(true), "Use J1 as input") 00080 00081 ; 00082 po::variables_map vm; 00083 po::store(po::parse_command_line(argc, argv, desc), vm); 00084 po::notify(vm); 00085 00086 00087 00088 //print the help message 00089 if (vm.count("help")){ 00090 std::cout << boost::format("UHD RX Timed Samples %s") % desc << std::endl; 00091 return ~0; 00092 } 00093 00094 if (!(uhd::set_thread_priority_safe(1,true))) { 00095 std::cout << "Problem setting thread priority" << std::endl; 00096 return 1; 00097 }; 00098 00099 00100 00101 gains=gains_str.c_str(); 00102 IP_addresses=get_usrp2_ip_addr(no_chan+skip_ant); 00103 00104 std::istringstream iss(IP_addresses); 00105 00106 // Skip skip_ant addresses: 00107 for (uint32_t i1=0;i1<skip_ant;i1++) { 00108 std::string subs; 00109 iss >> subs; 00110 }; 00111 00112 00113 //create a usrp device 00114 uhd::device_addr_t dev_addr; 00115 00116 00117 for (uint32_t i1=0;i1<no_chan;i1++) { 00118 std::string subs; 00119 std::string numb; 00120 std::stringstream ss; 00121 00122 ss << i1; 00123 ss >> numb; 00124 numb="addr"+numb; 00125 iss >> subs; 00126 dev_addr[numb]=subs; 00127 IP_addresses1+=subs; 00128 if (i1<(no_chan-1)){ 00129 IP_addresses1+=" "; 00130 } 00131 dev_addr[numb]=subs; 00132 00133 }; 00134 00135 00136 00137 00138 00139 uhd::usrp::multi_usrp::sptr d_mdev=uhd::usrp::multi_usrp::make(dev_addr); 00140 uhd::device::sptr dev = d_mdev->get_device(); 00141 00142 00143 std::string config = d_mdev->get_pp_string(); 00144 uint32_t temp; 00145 bool is_basic, is_xcvr2450; 00146 00147 std::cout << "config=" << config << std::endl; 00148 00149 temp=config.find("Basic"); 00150 if (temp<config.length()) 00151 is_basic=true; 00152 else 00153 is_basic=false; 00154 00155 temp=config.find("XCVR2450"); 00156 if (temp<config.length()) 00157 is_xcvr2450=true; 00158 else 00159 is_xcvr2450=false; 00160 00161 std::cout << "is_basic=" << is_basic << std::endl; 00162 std::cout << "is_xcvr2450=" << is_xcvr2450 << std::endl; 00163 00164 if (is_basic & is_xcvr2450) { 00165 std::cout << "Either basic db or xcvr2450 must be used, not both. \n"; 00166 exit(1); 00167 }; 00168 if (!(is_basic | is_xcvr2450)) { 00169 std::cout << "Either basic db or xcvr2450 must be used \n"; 00170 exit(1); 00171 }; 00172 00173 00174 if (is_basic) { 00175 uhd::usrp::subdev_spec_t spec("A:A"); 00176 for (uint32_t i1=0;i1<no_chan;i1++) { 00177 d_mdev->set_rx_subdev_spec(spec, i1); 00178 }; 00179 }; 00180 if (is_xcvr2450) { 00181 if (use_J1) { 00182 for (uint32_t i1=0;i1<no_chan;i1++) { 00183 d_mdev->set_tx_antenna("J2",i1); 00184 d_mdev->set_rx_antenna("J1",i1); 00185 }; 00186 } else { 00187 for (uint32_t i1=0;i1<no_chan;i1++) { 00188 d_mdev->set_tx_antenna("J1",i1); 00189 d_mdev->set_rx_antenna("J2",i1); 00190 }; 00191 }; 00192 }; 00193 00194 00195 d_mdev->set_rx_rate(d_rate); 00196 d_mdev->set_tx_rate(d_rate); 00197 00198 00199 00200 uhd::tune_result_t tr; 00201 00202 for (uint32_t i1=0;i1<no_chan;i1++) { 00203 tr=d_mdev->set_rx_freq(freq,i1); 00204 if ((int) i1<gains.size()) 00205 d_mdev->set_rx_gain(gains(i1),i1); 00206 else { 00207 d_mdev->set_rx_gain(gains(gains.size()-1),i1); 00208 }; 00209 }; 00210 00211 00212 00213 my_clock_config.pps_source=uhd::clock_config_t::PPS_SMA; //PZ 00214 my_clock_config.pps_polarity=uhd::clock_config_t::PPS_POS; //PZ 00215 00216 // Lock to 10MHz 00217 if (use_external_10MHz) 00218 my_clock_config.ref_source=uhd::clock_config_t::REF_SMA; //PZ 00219 else 00220 my_clock_config.ref_source=uhd::clock_config_t::REF_INT; //PZ 00221 00222 00223 for (uint32_t i1=0;i1<no_chan;i1++) 00224 d_mdev->set_clock_config(my_clock_config, i1); 00225 00226 00227 usleep(1e5); // Wait for freq and gain to settle 00228 00229 if (gps_time_combined==0) { 00230 for (uint32_t i1=0;i1<no_chan;i1++) { 00231 d_mdev->set_time_now(uhd::time_spec_t(0.0)); 00232 }; 00233 } else { 00234 00235 // Sync the node to pps 00236 //uhd::time_spec_t offset_time(0.0); 00237 if (gps_time_combined>1) { 00238 gps_wait_until(dev_name.c_str(),gps_time_combined); 00239 }; 00240 d_mdev->set_time_next_pps(uhd::time_spec_t(0.0)); 00241 std::cout << "Wait for pps!" << std::endl; 00242 usleep(1e6*time_available_for_trigger); 00243 std::cout << "Sync done" << std::endl; 00244 }; 00245 00246 //} else { 00247 // offset_time=d_mdev->get_time_now(0); 00248 //}; 00249 00250 // Create storage for the entire received signal. 00251 std::complex<int16_t> *d_buffer_rx; 00252 std::vector<void *> d_rx_buffers; 00253 00254 for (uint32_t i1=0;i1<no_chan;i1++) { 00255 d_buffer_rx = new std::complex<int16_t>[total_num_samps]; 00256 d_rx_buffers.push_back(d_buffer_rx); 00257 }; 00258 00259 00260 00261 //setup streaming 00262 //std::cout << std::endl; 00263 //std::cout << boost::format("Begin streaming %u samples, %d seconds in the future...") 00264 // % total_num_samps % seconds_in_future << std::endl; 00265 uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); 00266 stream_cmd.num_samps = total_num_samps; 00267 stream_cmd.stream_now = false; 00268 stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); 00269 d_mdev->issue_stream_cmd(stream_cmd); 00270 00271 00272 uhd::rx_metadata_t md_rx; 00273 unsigned int num_rx_samps=0; 00274 00275 00276 while (num_rx_samps==0) { 00277 00278 00279 num_rx_samps=dev->recv( 00280 d_rx_buffers, 00281 total_num_samps, 00282 md_rx, 00283 uhd::io_type_t::COMPLEX_INT16, // PZ 00284 uhd::device::RECV_MODE_FULL_BUFF // PZ 00285 ); 00286 00287 00288 00289 }; 00290 00291 00292 00293 00294 //finished 00295 std::cout << std::endl << "Done!" << std::endl << std::endl; // PZ 00296 00297 // Save output to disc 00298 std::ofstream s1(filename.c_str(), std::ios::binary); // PZ 00299 for (uint32_t i1=0;i1<no_chan;i1++) { 00300 d_buffer_rx = (std::complex<short int>*) d_rx_buffers[i1]; 00301 s1.write((char *) d_buffer_rx ,4*total_num_samps); //ZP 00302 }; 00303 s1.flush(); //PZ 00304 s1.close(); //PZ 00305 00306 00307 00308 00309 return 0; 00310 }