diff --git a/grc/gen_bladerf_blocks.py b/grc/gen_bladerf_blocks.py index e341930d56f0769434531541ee81f692cc369d11..4bcde974714eb57f6eb143a93086163e53413911 100644 --- a/grc/gen_bladerf_blocks.py +++ b/grc/gen_bladerf_blocks.py @@ -192,6 +192,9 @@ outputs: outputs: % endif +- domain: message + id: status + optional: true - domain: message id: pmic_out optional: true diff --git a/lib/bladerf/bladerf_sink_c.cc b/lib/bladerf/bladerf_sink_c.cc index 415d6c82c64f9c8e9d160c4f5c4f727a726e0fd2..97bfdf4e813863cb4cea6e73ba2a5ecda315957d 100644 --- a/lib/bladerf/bladerf_sink_c.cc +++ b/lib/bladerf/bladerf_sink_c.cc @@ -44,12 +44,21 @@ using namespace boost::assign; +const pmt::pmt_t CMD_PORT = pmt::mp("command"); const pmt::pmt_t CMD_TIME_KEY = pmt::mp("time"); const pmt::pmt_t CMD_CHAN_KEY = pmt::mp("chan"); const pmt::pmt_t CMD_GAIN_KEY = pmt::mp("gain"); const pmt::pmt_t CMD_FREQ_KEY = pmt::mp("freq"); const pmt::pmt_t CMD_RATE_KEY = pmt::mp("rate"); const pmt::pmt_t CMD_BW_KEY = pmt::mp("bandwidth"); +const pmt::pmt_t CMD_TS_KEY = pmt::mp("read_ts"); + +const pmt::pmt_t TAG_TX_TIME = pmt::mp("tx_time"); + +const pmt::pmt_t PORT_STATUS = pmt::mp("status"); +const pmt::pmt_t STATUS_TIMEOUT = pmt::mp("timeout"); +const pmt::pmt_t STATUS_TIME_PAST = pmt::mp("time_past"); +const pmt::pmt_t STATUS_UNDERRUN = pmt::mp("underrun"); /****************************************************************************** * Functions @@ -83,10 +92,13 @@ bladerf_sink_c::bladerf_sink_c(const std::string &args) : setup_blade_messaging(); /* add command port */ - message_port_register_in(pmt::mp("command")); - set_msg_handler(pmt::mp("command"), + message_port_register_in(CMD_PORT); + set_msg_handler(CMD_PORT, [this](const pmt::pmt_t& msg){ handle_command(msg); }); + /* add status port */ + message_port_register_out(PORT_STATUS); + dict_t dict = params_to_dict(args); /* Perform src/sink agnostic initializations */ @@ -285,6 +297,15 @@ int bladerf_sink_c::work(int noutput_items, BLADERF_WARNING("bladerf_sync_tx error: " << bladerf_strerror(status)); ++_failures; + if (status == BLADERF_ERR_TIMEOUT) { + pmt::pmt_t msg = pmt::cons(STATUS_TIMEOUT, pmt::PMT_T); + message_port_pub(PORT_STATUS, msg); + } else if (status == BLADERF_ERR_TIME_PAST) { + pmt::pmt_t msg = pmt::cons(STATUS_TIME_PAST, pmt::from_uint64(0)); + message_port_pub(PORT_STATUS, msg); + --_failures; // do not count towards consecutive failures + } + if (_failures >= MAX_CONSECUTIVE_FAILURES) { BLADERF_WARNING("Consecutive error limit hit. Shutting down."); return WORK_DONE; @@ -661,6 +682,10 @@ void bladerf_sink_c::handle_command(const pmt::pmt_t& msg) set_bandwidth(bw, chan); } else if (key == CMD_TIME_KEY || key == CMD_CHAN_KEY) { // skip time and channel keys + } else if (key == CMD_TS_KEY) { + uint64_t ts = get_timestamp(); + pmt::pmt_t msg = pmt::cons(TAG_TX_TIME, pmt::from_uint64(ts)); + message_port_pub(PORT_STATUS, msg); } else { BLADERF_WARNING("Unknown command (" << key << ")"); } diff --git a/lib/bladerf/bladerf_source_c.cc b/lib/bladerf/bladerf_source_c.cc index c585327cc18342f487a57d388be3965d7dcb1a22..ed08c14b5d4bab1b46eb0bbdcc87e56a37ae5909 100644 --- a/lib/bladerf/bladerf_source_c.cc +++ b/lib/bladerf/bladerf_source_c.cc @@ -44,6 +44,7 @@ using namespace boost::assign; +const pmt::pmt_t CMD_PORT = pmt::mp("command"); const pmt::pmt_t CMD_TIME_KEY = pmt::mp("time"); const pmt::pmt_t CMD_CHAN_KEY = pmt::mp("chan"); const pmt::pmt_t CMD_GAIN_KEY = pmt::mp("gain"); @@ -51,10 +52,16 @@ const pmt::pmt_t CMD_FREQ_KEY = pmt::mp("freq"); const pmt::pmt_t CMD_RATE_KEY = pmt::mp("rate"); const pmt::pmt_t CMD_BW_KEY = pmt::mp("bandwidth"); const pmt::pmt_t CMD_TAG_KEY = pmt::mp("tag"); +const pmt::pmt_t CMD_TS_KEY = pmt::mp("read_ts"); -const pmt::pmt_t TAG_RX_TIME = pmt::mp("rx_time"); -const pmt::pmt_t TAG_RX_RATE = pmt::mp("rx_rate"); -const pmt::pmt_t TAG_RX_FREQ = pmt::mp("rx_freq"); +const pmt::pmt_t TAG_RX_TIME = pmt::mp("rx_time"); +const pmt::pmt_t TAG_RX_RATE = pmt::mp("rx_rate"); +const pmt::pmt_t TAG_RX_FREQ = pmt::mp("rx_freq"); + +const pmt::pmt_t PORT_STATUS = pmt::mp("status"); +const pmt::pmt_t STATUS_TIMEOUT = pmt::mp("timeout"); +const pmt::pmt_t STATUS_TIME_PAST = pmt::mp("time_past"); +const pmt::pmt_t STATUS_OVERRUN = pmt::mp("overrun"); /****************************************************************************** * Functions @@ -93,10 +100,13 @@ bladerf_source_c::bladerf_source_c(const std::string &args) : setup_blade_messaging(); /* add command port */ - message_port_register_in(pmt::mp("command")); - set_msg_handler(pmt::mp("command"), + message_port_register_in(CMD_PORT); + set_msg_handler(CMD_PORT, [this](const pmt::pmt_t& msg) { handle_command(msg); }); + /* add status port */ + message_port_register_out(PORT_STATUS); + /* Loopback */ set_loopback_mode(dict.count("loopback") ? dict["loopback"] : "none"); @@ -292,6 +302,17 @@ int bladerf_source_c::work(int noutput_items, % bladerf_strerror(status))); ++_failures; + // status port message + if (status == BLADERF_ERR_TIMEOUT) { + pmt::pmt_t msg = pmt::cons(STATUS_TIMEOUT, pmt::PMT_T); + message_port_pub(PORT_STATUS, msg); + } else if (status == BLADERF_ERR_TIME_PAST) { + pmt::pmt_t msg = pmt::cons(STATUS_TIME_PAST, + pmt::from_uint64(meta.timestamp)); + message_port_pub(PORT_STATUS, msg); + --_failures; // do not count towards consecutive failures + } + if (_failures >= MAX_CONSECUTIVE_FAILURES) { BLADERF_WARNING("Consecutive error limit hit. Shutting down."); return WORK_DONE; @@ -306,6 +327,9 @@ int bladerf_source_c::work(int noutput_items, if (meta_ptr != NULL && (meta.status & BLADERF_META_STATUS_OVERRUN)) { overrun = true; actual_count = meta.actual_count; + + pmt::pmt_t msg = pmt::cons(STATUS_OVERRUN, pmt::PMT_T); + message_port_pub(PORT_STATUS, msg); } // convert from int16_t to float @@ -736,6 +760,10 @@ void bladerf_source_c::handle_command(const pmt::pmt_t& msg) _add_tag = true; } else if (key == CMD_TIME_KEY || key == CMD_CHAN_KEY) { // skip time and channel keys + } else if (key == CMD_TS_KEY) { + uint64_t ts = get_timestamp(); + pmt::pmt_t msg = pmt::cons(TAG_RX_TIME, pmt::from_uint64(ts)); + message_port_pub(PORT_STATUS, msg); } else { BLADERF_WARNING("Unknown command (" << key << ")"); } diff --git a/lib/sink_impl.cc b/lib/sink_impl.cc index 17e29717bc5eeb90cf0edaab186415d4e93dccce..85d91d218cd36f1200a2d7ad599d5c569abffb91 100644 --- a/lib/sink_impl.cc +++ b/lib/sink_impl.cc @@ -29,6 +29,7 @@ namespace gr { message_port_register_hier_in(pmt::mp("pmic_in")); message_port_register_hier_in(pmt::mp("command")); message_port_register_hier_out(pmt::mp("pmic_out")); + message_port_register_hier_out(pmt::mp("status")); auto dev_list = bladerf_sink_c::get_devices(); if(dev_list.size() == 0) @@ -44,6 +45,7 @@ namespace gr { msg_connect(self(), pmt::mp("pmic_in"), device_, pmt::mp("pmic_in")); msg_connect(self(), pmt::mp("command"), device_, pmt::mp("command")); msg_connect(device_, pmt::mp("pmic_out"), self(), pmt::mp("pmic_out")); + msg_connect(device_, pmt::mp("status"), self(), pmt::mp("status")); } /* diff --git a/lib/source_impl.cc b/lib/source_impl.cc index 17cfdab036e37d48e4c3f0352a40a60b91b40408..bdbb4130798e895c7e7b3a8f4a6476fc5f75b903 100644 --- a/lib/source_impl.cc +++ b/lib/source_impl.cc @@ -27,6 +27,7 @@ namespace gr { message_port_register_hier_in(pmt::mp("pmic_in")); message_port_register_hier_in(pmt::mp("command")); message_port_register_hier_out(pmt::mp("pmic_out")); + message_port_register_hier_out(pmt::mp("status")); auto dev_list = bladerf_source_c::get_devices(); if(dev_list.size() == 0) @@ -55,6 +56,7 @@ namespace gr { msg_connect(self(), pmt::mp("pmic_in"), device_, pmt::mp("pmic_in")); msg_connect(self(), pmt::mp("command"), device_, pmt::mp("command")); msg_connect(device_, pmt::mp("pmic_out"), self(), pmt::mp("pmic_out")); + msg_connect(device_, pmt::mp("status"), self(), pmt::mp("status")); } source_impl::~source_impl()