diff options
-rw-r--r-- | gr-uhd/examples/tag_sink_demo.h | 66 | ||||
-rw-r--r-- | gr-uhd/examples/tag_source_demo.h | 129 | ||||
-rw-r--r-- | gr-uhd/examples/tags_demo.cc | 139 |
3 files changed, 334 insertions, 0 deletions
diff --git a/gr-uhd/examples/tag_sink_demo.h b/gr-uhd/examples/tag_sink_demo.h new file mode 100644 index 000000000..84baf0a9c --- /dev/null +++ b/gr-uhd/examples/tag_sink_demo.h @@ -0,0 +1,66 @@ +/* + * Copyright 2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <gr_sync_block.h> +#include <gr_io_signature.h> +#include <gr_tag_info.h> +#include <boost/foreach.hpp> +#include <boost/format.hpp> +#include <iostream> +#include <complex> + +class tag_sink_demo : public gr_sync_block{ +public: + + tag_sink_demo(void): + gr_sync_block( + "uhd tag sink demo", + gr_make_io_signature(1, 1, sizeof(std::complex<float>)), + gr_make_io_signature(0, 0, 0) + ) + { + //NOP + } + + int work( + int ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ){ + //grab all "rx time" tags in this work call + const uint64_t samp0_count = this->nitems_read(0); + std::vector<pmt::pmt_t> rx_time_tags; + get_tags_in_range(rx_time_tags, 0, samp0_count, samp0_count + ninput_items, pmt::pmt_string_to_symbol("rx_time")); + + //print all tags + BOOST_FOREACH(const pmt::pmt_t &rx_time_tag, rx_time_tags){ + const uint64_t count = gr_tags::get_nitems(rx_time_tag); + const pmt::pmt_t &value = gr_tags::get_value(rx_time_tag); + + std::cout << boost::format("Full seconds %u, Frac seconds %f") + % pmt::pmt_to_uint64(pmt_tuple_ref(value, 0)) + % pmt::pmt_to_double(pmt_tuple_ref(value, 1)) + << std::endl; + } + + return ninput_items; + } +}; diff --git a/gr-uhd/examples/tag_source_demo.h b/gr-uhd/examples/tag_source_demo.h new file mode 100644 index 000000000..c7c0884d3 --- /dev/null +++ b/gr-uhd/examples/tag_source_demo.h @@ -0,0 +1,129 @@ +/* + * Copyright 2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <gr_sync_block.h> +#include <gr_io_signature.h> +#include <gr_tag_info.h> +#include <boost/foreach.hpp> +#include <boost/format.hpp> +#include <iostream> +#include <complex> + +class tag_source_demo : public gr_sync_block{ +public: + + tag_source_demo( + const uint64_t start_secs, + const double start_fracs, + const double samp_rate, + const double idle_duration, + const double burst_duration + ): + gr_sync_block( + "uhd tag source demo", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, sizeof(std::complex<float>)) + ), + _time_secs(start_secs), + _time_fracs(start_fracs), + _samp_rate(samp_rate), + _samps_per_burst(samp_rate*burst_duration), + _cycle_duration(idle_duration + burst_duration), + _samps_left_in_burst(1), //immediate EOB + _do_new_burst(false) + { + //NOP + } + + void make_time_tag(const uint64_t tag_count){; + const pmt::pmt_t key = pmt::pmt_string_to_symbol("tx_time"); + const pmt::pmt_t value = pmt::pmt_make_tuple( + pmt::pmt_from_uint64(_time_secs), + pmt::pmt_from_double(_time_fracs) + ); + const pmt::pmt_t srcid = pmt::pmt_string_to_symbol(this->name()); + this->add_item_tag(0/*chan0*/, tag_count, key, value, srcid); + } + + void make_sob_tag(const uint64_t tag_count){ + const pmt::pmt_t key = pmt::pmt_string_to_symbol("tx_sob"); + const pmt::pmt_t value = pmt::PMT_T; + const pmt::pmt_t srcid = pmt::pmt_string_to_symbol(this->name()); + this->add_item_tag(0/*chan0*/, tag_count, key, value, srcid); + } + + void make_eob_tag(const uint64_t tag_count){; + const pmt::pmt_t key = pmt::pmt_string_to_symbol("tx_eob"); + const pmt::pmt_t value = pmt::PMT_T; + const pmt::pmt_t srcid = pmt::pmt_string_to_symbol(this->name()); + this->add_item_tag(0/*chan0*/, tag_count, key, value, srcid); + } + + int work( + int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ){ + //load the output with a constant + std::complex<float> *output = reinterpret_cast<std::complex<float> *>(output_items[0]); + for (size_t i = 0; i < size_t(noutput_items); i++){ + output[i] = std::complex<float>(0.7, 0.7); + } + + //Handle the start of burst condition. + //Tag a start of burst and timestamp. + //Increment the time for the next burst. + if (_do_new_burst){ + _do_new_burst = false; + _samps_left_in_burst = _samps_per_burst; + + this->make_sob_tag(this->nitems_written(0)); + this->make_time_tag(this->nitems_written(0)); + + _time_fracs += _cycle_duration; + double intpart; //normalize + _time_fracs = std::modf(_time_fracs, &intpart); + _time_secs += uint64_t(intpart); + } + + //Handle the end of burst condition. + //Tag an end of burst and return early. + //the next work call will be a start of burst. + if (_samps_left_in_burst < size_t(noutput_items)){ + this->make_eob_tag(this->nitems_written(0) + _samps_left_in_burst - 1); + _do_new_burst = true; + noutput_items = _samps_left_in_burst; + } + + _samps_left_in_burst -= noutput_items; + return noutput_items; + } + +private: + uint64_t _time_secs; + double _time_fracs; + const double _samp_rate; + const uint64_t _samps_per_burst; + const double _cycle_duration; + bool _do_new_burst; + uint64_t _samps_left_in_burst; + +}; diff --git a/gr-uhd/examples/tags_demo.cc b/gr-uhd/examples/tags_demo.cc new file mode 100644 index 000000000..b40518f34 --- /dev/null +++ b/gr-uhd/examples/tags_demo.cc @@ -0,0 +1,139 @@ +/* + * Copyright 2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <gr_top_block.h> +#include <gr_uhd_usrp_source.h> +#include <gr_uhd_usrp_sink.h> +#include <tag_source_demo.h> +#include <tag_sink_demo.h> +#include <boost/make_shared.hpp> +#include <boost/thread/thread.hpp> //sleep +#include <boost/program_options.hpp> +#include <csignal> +#include <iostream> + +namespace po = boost::program_options; + +/*********************************************************************** + * Signal handlers + **********************************************************************/ +static bool stop_signal_called = false; +void sig_int_handler(int){stop_signal_called = true;} + +/*********************************************************************** + * Main w/ program options + **********************************************************************/ +int main(int argc, char *argv[]){ + + std::string device_addr; + double center_freq, samp_rate, burst_dur, idle_dur; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("addr", po::value<std::string>(&device_addr)->default_value(""), "the device address in string format") + ("rate", po::value<double>(&samp_rate)->default_value(1e6), "the sample rate in samples per second") + ("freq", po::value<double>(¢er_freq)->default_value(10e6), "the center frequency in Hz") + ("burst", po::value<double>(&burst_dur)->default_value(0.1), "the duration of each burst in seconds") + ("idle", po::value<double>(&idle_dur)->default_value(0.05), "idle time between bursts in seconds") + ; + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout + << boost::format("UHD Tags Demo %s") % desc << std::endl + << "The tags sink demo block will print USRP source time stamps." << std::endl + << "The tags source demo block will send bursts to the USRP sink." << std::endl + << "Look at the USRP output on a scope to see the timed bursts." << std::endl + << std::endl; + return ~0; + } + + //------------------------------------------------------------------ + //-- make a top block + //------------------------------------------------------------------ + gr_top_block_sptr tb = gr_make_top_block("tags_demo"); + + //------------------------------------------------------------------ + //-- make the usrp source test blocks + //------------------------------------------------------------------ + boost::shared_ptr<uhd_usrp_source> usrp_source = uhd_make_usrp_source( + device_addr, uhd::io_type_t::COMPLEX_FLOAT32, 1 + ); + usrp_source->set_samp_rate(samp_rate); + usrp_source->set_center_freq(center_freq); + + boost::shared_ptr<tag_sink_demo> tag_sink = boost::make_shared<tag_sink_demo>(); + + //------------------------------------------------------------------ + //-- connect the usrp source test blocks + //------------------------------------------------------------------ + tb->connect(usrp_source, 0, tag_sink, 0); + + //------------------------------------------------------------------ + //-- make the usrp sink test blocks + //------------------------------------------------------------------ + boost::shared_ptr<uhd_usrp_sink> usrp_sink = uhd_make_usrp_sink( + device_addr, uhd::io_type_t::COMPLEX_FLOAT32, 1 + ); + usrp_sink->set_samp_rate(samp_rate); + usrp_sink->set_center_freq(center_freq); + const uhd::time_spec_t time_now = usrp_sink->get_time_now(); + + boost::shared_ptr<tag_source_demo> tag_source = boost::make_shared<tag_source_demo>( + time_now.get_full_secs() + 1, time_now.get_frac_secs(), //time now + 1 second + samp_rate, idle_dur, burst_dur + ); + + //------------------------------------------------------------------ + //-- connect the usrp sink test blocks + //------------------------------------------------------------------ + tb->connect(tag_source, 0, usrp_sink, 0); + + //------------------------------------------------------------------ + //-- start flow graph execution + //------------------------------------------------------------------ + std::cout << "starting flow graph" << std::endl; + tb->start(); + + //------------------------------------------------------------------ + //-- poll the exit signal while running + //------------------------------------------------------------------ + std::signal(SIGINT, &sig_int_handler); + std::cout << "press ctrl + c to exit" << std::endl; + while (not stop_signal_called){ + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); + } + + //------------------------------------------------------------------ + //-- stop flow graph execution + //------------------------------------------------------------------ + std::cout << "stopping flow graph" << std::endl; + tb->stop(); + tb->wait(); + + std::cout << "done!" << std::endl; + return 0; +} |