summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gr-uhd/examples/tag_sink_demo.h66
-rw-r--r--gr-uhd/examples/tag_source_demo.h129
-rw-r--r--gr-uhd/examples/tags_demo.cc139
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>(&center_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;
+}