diff options
Diffstat (limited to 'host/lib/usrp')
21 files changed, 568 insertions, 365 deletions
diff --git a/host/lib/usrp/dboard/basic.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index 82485ae6a..50c868a24 100644 --- a/host/lib/usrp/dboard/basic.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -15,9 +15,10 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> #include <uhd/props.hpp> -#include <uhd/types.hpp> +#include <uhd/types/ranges.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/utils/static.hpp> #include <uhd/usrp/dboard_base.hpp> #include <uhd/usrp/dboard_manager.hpp> #include <boost/assign/list_of.hpp> @@ -33,26 +34,26 @@ using namespace boost::assign; **********************************************************************/ class basic_rx : public rx_dboard_base{ public: - basic_rx(ctor_args_t const& args, freq_t max_freq); + basic_rx(ctor_args_t const& args, double max_freq); ~basic_rx(void); void rx_get(const wax::obj &key, wax::obj &val); void rx_set(const wax::obj &key, const wax::obj &val); private: - freq_t _max_freq; + double _max_freq; }; class basic_tx : public tx_dboard_base{ public: - basic_tx(ctor_args_t const& args, freq_t max_freq); + basic_tx(ctor_args_t const& args, double max_freq); ~basic_tx(void); void tx_get(const wax::obj &key, wax::obj &val); void tx_set(const wax::obj &key, const wax::obj &val); private: - freq_t _max_freq; + double _max_freq; }; /*********************************************************************** @@ -74,20 +75,20 @@ static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t const& args){ return dboard_base::sptr(new basic_tx(args, 32e6)); } -STATIC_BLOCK(reg_dboards){ - dboard_manager::register_dboard(0x0000, &make_basic_tx, "Basic TX", list_of("")); +UHD_STATIC_BLOCK(reg_dboards){ + dboard_manager::register_dboard(0x0000, &make_basic_tx, "Basic TX"); dboard_manager::register_dboard(0x0001, &make_basic_rx, "Basic RX", list_of("ab")("a")("b")); - dboard_manager::register_dboard(0x000e, &make_lf_tx, "LF TX", list_of("")); + dboard_manager::register_dboard(0x000e, &make_lf_tx, "LF TX"); dboard_manager::register_dboard(0x000f, &make_lf_rx, "LF RX", list_of("ab")("a")("b")); } /*********************************************************************** * Basic and LF RX dboard **********************************************************************/ -basic_rx::basic_rx(ctor_args_t const& args, freq_t max_freq) : rx_dboard_base(args){ +basic_rx::basic_rx(ctor_args_t const& args, double max_freq) : rx_dboard_base(args){ _max_freq = max_freq; // set the gpios to safe values (all inputs) - get_interface()->set_gpio_ddr(dboard_interface::GPIO_RX_BANK, 0x0000, 0xffff); + get_interface()->set_gpio_ddr(dboard_interface::GPIO_RX_BANK, 0x0000); } basic_rx::~basic_rx(void){ @@ -112,7 +113,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_GAIN: - val = gain_t(0); + val = float(0); return; case SUBDEV_PROP_GAIN_RANGE: @@ -124,7 +125,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_FREQ: - val = freq_t(0); + val = double(0); return; case SUBDEV_PROP_FREQ_RANGE: @@ -163,7 +164,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){ switch(key.as<subdev_prop_t>()){ case SUBDEV_PROP_GAIN: - ASSERT_THROW(val.as<gain_t>() == gain_t(0)); + ASSERT_THROW(val.as<float>() == float(0)); return; case SUBDEV_PROP_ANTENNA: @@ -195,10 +196,10 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){ /*********************************************************************** * Basic and LF TX dboard **********************************************************************/ -basic_tx::basic_tx(ctor_args_t const& args, freq_t max_freq) : tx_dboard_base(args){ +basic_tx::basic_tx(ctor_args_t const& args, double max_freq) : tx_dboard_base(args){ _max_freq = max_freq; // set the gpios to safe values (all inputs) - get_interface()->set_gpio_ddr(dboard_interface::GPIO_TX_BANK, 0x0000, 0xffff); + get_interface()->set_gpio_ddr(dboard_interface::GPIO_TX_BANK, 0x0000); } basic_tx::~basic_tx(void){ @@ -220,7 +221,7 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_GAIN: - val = gain_t(0); + val = float(0); return; case SUBDEV_PROP_GAIN_RANGE: @@ -232,7 +233,7 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_FREQ: - val = freq_t(0); + val = double(0); return; case SUBDEV_PROP_FREQ_RANGE: @@ -271,7 +272,7 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){ switch(key.as<subdev_prop_t>()){ case SUBDEV_PROP_GAIN: - ASSERT_THROW(val.as<gain_t>() == gain_t(0)); + ASSERT_THROW(val.as<float>() == float(0)); return; case SUBDEV_PROP_ANTENNA: diff --git a/host/lib/usrp/dboard_base.cpp b/host/lib/usrp/dboard_base.cpp index 6dd41cfd8..09d3bbfd4 100644 --- a/host/lib/usrp/dboard_base.cpp +++ b/host/lib/usrp/dboard_base.cpp @@ -52,15 +52,15 @@ dboard_id_t dboard_base::get_tx_id(void){ * xcvr dboard dboard_base class **********************************************************************/ xcvr_dboard_base::xcvr_dboard_base(ctor_args_t const& args) : dboard_base(args){ - if (get_rx_id() == ID_NONE){ + if (get_rx_id() == dboard_id::NONE){ throw std::runtime_error(str(boost::format( "cannot create xcvr board when the rx id is \"%s\"" - ) % dboard_id::to_string(ID_NONE))); + ) % dboard_id::to_string(dboard_id::NONE))); } - if (get_tx_id() == ID_NONE){ + if (get_tx_id() == dboard_id::NONE){ throw std::runtime_error(str(boost::format( "cannot create xcvr board when the tx id is \"%s\"" - ) % dboard_id::to_string(ID_NONE))); + ) % dboard_id::to_string(dboard_id::NONE))); } } @@ -72,11 +72,11 @@ xcvr_dboard_base::~xcvr_dboard_base(void){ * rx dboard dboard_base class **********************************************************************/ rx_dboard_base::rx_dboard_base(ctor_args_t const& args) : dboard_base(args){ - if (get_tx_id() != ID_NONE){ + if (get_tx_id() != dboard_id::NONE){ throw std::runtime_error(str(boost::format( "cannot create rx board when the tx id is \"%s\"" " -> expected a tx id of \"%s\"" - ) % dboard_id::to_string(get_tx_id()) % dboard_id::to_string(ID_NONE))); + ) % dboard_id::to_string(get_tx_id()) % dboard_id::to_string(dboard_id::NONE))); } } @@ -96,11 +96,11 @@ void rx_dboard_base::tx_set(const wax::obj &, const wax::obj &){ * tx dboard dboard_base class **********************************************************************/ tx_dboard_base::tx_dboard_base(ctor_args_t const& args) : dboard_base(args){ - if (get_rx_id() != ID_NONE){ + if (get_rx_id() != dboard_id::NONE){ throw std::runtime_error(str(boost::format( "cannot create tx board when the rx id is \"%s\"" " -> expected a rx id of \"%s\"" - ) % dboard_id::to_string(get_rx_id()) % dboard_id::to_string(ID_NONE))); + ) % dboard_id::to_string(get_rx_id()) % dboard_id::to_string(dboard_id::NONE))); } } diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index 6ca15e98c..15be7eedc 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -16,9 +16,10 @@ // #include <uhd/usrp/dboard_manager.hpp> -#include <uhd/gain_handler.hpp> -#include <uhd/utils.hpp> -#include <uhd/dict.hpp> +#include <uhd/utils/gain_handler.hpp> +#include <uhd/utils/static.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/types/dict.hpp> #include <boost/tuple/tuple.hpp> #include <boost/format.hpp> #include <boost/bind.hpp> @@ -35,7 +36,7 @@ typedef boost::tuple<dboard_manager::dboard_ctor_t, std::string, prop_names_t> a //map a dboard id to a dboard constructor typedef uhd::dict<dboard_id_t, args_t> id_to_args_map_t; -STATIC_INSTANCE(id_to_args_map_t, get_id_to_args_map) +UHD_SINGLETON_FCN(id_to_args_map_t, get_id_to_args_map) void dboard_manager::register_dboard( dboard_id_t dboard_id, @@ -163,12 +164,12 @@ static args_t get_dboard_args( std::string const& xx_type ){ //special case, its rx and the none id (0xffff) - if (xx_type == "rx" and dboard_id == ID_NONE){ + if (xx_type == "rx" and dboard_id == dboard_id::NONE){ return get_dboard_args(0x0001, xx_type); } //special case, its tx and the none id (0xffff) - if (xx_type == "tx" and dboard_id == ID_NONE){ + if (xx_type == "tx" and dboard_id == dboard_id::NONE){ return get_dboard_args(0x0000, xx_type); } @@ -203,7 +204,7 @@ dboard_manager_impl::dboard_manager_impl( //make xcvr subdevs (make one subdev for both rx and tx dboards) if (rx_dboard_ctor == tx_dboard_ctor){ ASSERT_THROW(rx_subdevs == tx_subdevs); - BOOST_FOREACH(std::string subdev, rx_subdevs){ + BOOST_FOREACH(const std::string &subdev, rx_subdevs){ dboard_base::sptr xcvr_dboard = rx_dboard_ctor( dboard_base::ctor_args_t(subdev, interface, rx_dboard_id, tx_dboard_id) ); @@ -221,9 +222,9 @@ dboard_manager_impl::dboard_manager_impl( //make tx and rx subdevs (separate subdevs for rx and tx dboards) else{ //make the rx subdevs - BOOST_FOREACH(std::string subdev, rx_subdevs){ + BOOST_FOREACH(const std::string &subdev, rx_subdevs){ dboard_base::sptr rx_dboard = rx_dboard_ctor( - dboard_base::ctor_args_t(subdev, interface, rx_dboard_id, ID_NONE) + dboard_base::ctor_args_t(subdev, interface, rx_dboard_id, dboard_id::NONE) ); //create a rx proxy for this rx board _rx_dboards[subdev] = subdev_proxy::sptr( @@ -231,9 +232,9 @@ dboard_manager_impl::dboard_manager_impl( ); } //make the tx subdevs - BOOST_FOREACH(std::string subdev, tx_subdevs){ + BOOST_FOREACH(const std::string &subdev, tx_subdevs){ dboard_base::sptr tx_dboard = tx_dboard_ctor( - dboard_base::ctor_args_t(subdev, interface, ID_NONE, tx_dboard_id) + dboard_base::ctor_args_t(subdev, interface, dboard_id::NONE, tx_dboard_id) ); //create a tx proxy for this tx board _tx_dboards[subdev] = subdev_proxy::sptr( @@ -274,11 +275,11 @@ wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){ void dboard_manager_impl::set_nice_gpio_pins(void){ //std::cout << "Set nice GPIO pins" << std::endl; - _interface->set_gpio_ddr(dboard_interface::GPIO_RX_BANK, 0x0000, 0xffff); //all inputs - _interface->set_gpio_ddr(dboard_interface::GPIO_TX_BANK, 0x0000, 0xffff); + _interface->set_gpio_ddr(dboard_interface::GPIO_RX_BANK, 0x0000); //all inputs + _interface->set_gpio_ddr(dboard_interface::GPIO_TX_BANK, 0x0000); - _interface->write_gpio(dboard_interface::GPIO_RX_BANK, 0x0000, 0xffff); //all zeros - _interface->write_gpio(dboard_interface::GPIO_TX_BANK, 0x0000, 0xffff); + _interface->write_gpio(dboard_interface::GPIO_RX_BANK, 0x0000); //all zeros + _interface->write_gpio(dboard_interface::GPIO_TX_BANK, 0x0000); _interface->set_atr_reg(dboard_interface::GPIO_RX_BANK, 0x0000, 0x0000, 0x0000); //software controlled _interface->set_atr_reg(dboard_interface::GPIO_TX_BANK, 0x0000, 0x0000, 0x0000); diff --git a/host/lib/usrp/usrp1e/mboard_impl.cpp b/host/lib/usrp/usrp1e/mboard_impl.cpp deleted file mode 100644 index b480f7616..000000000 --- a/host/lib/usrp/usrp1e/mboard_impl.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright 2010 Ettus Research LLC -// -// This program 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 of the License, or -// (at your option) any later version. -// -// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. -// - -#include <boost/bind.hpp> -#include <uhd/utils.hpp> -#include "usrp1e_impl.hpp" - -using namespace uhd::usrp; - -/*********************************************************************** - * Mboard Initialization - **********************************************************************/ -void usrp1e_impl::mboard_init(void){ - _mboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::mboard_get, this, _1, _2), - boost::bind(&usrp1e_impl::mboard_set, this, _1, _2) - ); -} - -/*********************************************************************** - * Mboard Get - **********************************************************************/ -void usrp1e_impl::mboard_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * Mboard Set - **********************************************************************/ -void usrp1e_impl::mboard_set(const wax::obj &, const wax::obj &){ - -} diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 66e02d469..fd72aeaa4 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -15,7 +15,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/types/clock_config.hpp> #include <boost/format.hpp> #include "usrp2_impl.hpp" diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp index d20465147..5a7d870b4 100644 --- a/host/lib/usrp/usrp2/dboard_interface.cpp +++ b/host/lib/usrp/usrp2/dboard_interface.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> +#include <uhd/utils/assert.hpp> #include "usrp2_impl.hpp" using namespace uhd::usrp; @@ -29,8 +29,8 @@ public: int read_aux_adc(unit_type_t, int); void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t); - void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t); - void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t); + void set_gpio_ddr(gpio_bank_t, boost::uint16_t); + void write_gpio(gpio_bank_t, boost::uint16_t); boost::uint16_t read_gpio(gpio_bank_t); void write_i2c(int, const byte_vector_t &); @@ -97,26 +97,26 @@ static boost::uint8_t gpio_bank_to_otw(dboard_interface::gpio_bank_t bank){ throw std::invalid_argument("unknown gpio bank type"); } -void usrp2_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ +void usrp2_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_USE_THESE_GPIO_DDR_SETTINGS_BRO); out_data.data.gpio_config.bank = gpio_bank_to_otw(bank); out_data.data.gpio_config.value = htons(value); - out_data.data.gpio_config.mask = htons(mask); + out_data.data.gpio_config.mask = htons(0xffff); //send and recv usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data); ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THE_GPIO_DDR_SETTINGS_DUDE); } -void usrp2_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ +void usrp2_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_SET_YOUR_GPIO_PIN_OUTS_BRO); out_data.data.gpio_config.bank = gpio_bank_to_otw(bank); out_data.data.gpio_config.value = htons(value); - out_data.data.gpio_config.mask = htons(mask); + out_data.data.gpio_config.mask = htons(0xffff); //send and recv usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data); diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 34cce0afb..0d43fac0e 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> +#include <uhd/utils/assert.hpp> #include <boost/format.hpp> #include <boost/assign/list_of.hpp> #include <boost/math/special_functions/round.hpp> @@ -35,7 +35,7 @@ template <class T> T log2(T num){ /*********************************************************************** * DDC Helper Methods **********************************************************************/ -static boost::uint32_t calculate_freq_word_and_update_actual_freq(freq_t &freq, freq_t clock_freq){ +static boost::uint32_t calculate_freq_word_and_update_actual_freq(double &freq, double clock_freq){ double scale_factor = std::pow(2.0, 32); //calculate the freq register word @@ -63,9 +63,8 @@ void usrp2_impl::init_ddc_config(void){ _ddc_freq = 0; update_ddc_config(); - _ddc_stream_at = time_spec_t(); - _ddc_enabled = false; - update_ddc_enabled(); + //initial command that kills streaming (in case if was left on) + //issue_ddc_stream_cmd(TODO) } void usrp2_impl::update_ddc_config(void){ @@ -86,21 +85,19 @@ void usrp2_impl::update_ddc_config(void){ ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE); } -void usrp2_impl::update_ddc_enabled(void){ +void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ //setup the out data usrp2_ctrl_data_t out_data; - out_data.id = htonl(USRP2_CTRL_ID_CONFIGURE_STREAMING_FOR_ME_BRO); - out_data.data.streaming.enabled = (_ddc_enabled)? 1 : 0; - out_data.data.streaming.secs = htonl(_ddc_stream_at.secs); - out_data.data.streaming.ticks = htonl(_ddc_stream_at.ticks); - out_data.data.streaming.samples = htonl(_max_rx_samples_per_packet); + out_data.id = htonl(USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO); + out_data.data.stream_cmd.now = (stream_cmd.stream_now)? 1 : 0; + out_data.data.stream_cmd.continuous = (stream_cmd.continuous)? 1 : 0; + out_data.data.stream_cmd.secs = htonl(stream_cmd.time_spec.secs); + out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.ticks); + out_data.data.stream_cmd.num_samps = htonl(stream_cmd.num_samps); //send and recv usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); - ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE); - - //clear the stream at time spec (it must be set for the next round of enable/disable) - _ddc_stream_at = time_spec_t(); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE); } /*********************************************************************** @@ -116,12 +113,12 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){ case DSP_PROP_OTHERS:{ prop_names_t others = boost::assign::list_of - ("rate") + ("if_rate") + ("bb_rate") ("decim") ("decims") ("freq") - ("enabled") - ("stream_at") + ("stream_cmd") ; val = others; } @@ -131,10 +128,14 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){ //handle string-based properties specific to this dsp std::string key_name = key.as<std::string>(); - if (key_name == "rate"){ + if (key_name == "if_rate"){ val = get_master_clock_freq(); return; } + else if (key_name == "bb_rate"){ + val = get_master_clock_freq()/_ddc_decim; + return; + } else if (key_name == "decim"){ val = _ddc_decim; return; @@ -147,10 +148,6 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){ val = _ddc_freq; return; } - else if (key_name == "enabled"){ - val = _ddc_enabled; - return; - } throw std::invalid_argument(str( boost::format("error getting: unknown key with name %s") % key_name @@ -171,23 +168,15 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){ return; } else if (key_name == "freq"){ - freq_t new_freq = val.as<freq_t>(); + double new_freq = val.as<double>(); ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); _ddc_freq = new_freq; //shadow update_ddc_config(); return; } - else if (key_name == "enabled"){ - bool new_enabled = val.as<bool>(); - _ddc_enabled = new_enabled; //shadow - update_ddc_enabled(); - return; - } - else if (key_name == "stream_at"){ - time_spec_t new_stream_at = val.as<time_spec_t>(); - _ddc_stream_at = new_stream_at; //shadow - //update_ddc_enabled(); //dont update from here + else if (key_name == "stream_cmd"){ + issue_ddc_stream_cmd(val.as<stream_cmd_t>()); return; } @@ -250,7 +239,8 @@ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){ case DSP_PROP_OTHERS:{ prop_names_t others = boost::assign::list_of - ("rate") + ("if_rate") + ("bb_rate") ("interp") ("interps") ("freq") @@ -263,10 +253,14 @@ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){ //handle string-based properties specific to this dsp std::string key_name = key.as<std::string>(); - if (key_name == "rate"){ + if (key_name == "if_rate"){ val = get_master_clock_freq(); return; } + else if (key_name == "bb_rate"){ + val = get_master_clock_freq()/_duc_interp; + return; + } else if (key_name == "interp"){ val = _duc_interp; return; @@ -299,7 +293,7 @@ void usrp2_impl::duc_set(const wax::obj &key, const wax::obj &val){ return; } else if (key_name == "freq"){ - freq_t new_freq = val.as<freq_t>(); + double new_freq = val.as<double>(); ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); _duc_freq = new_freq; //shadow diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 7fcae6fb2..30fee6c32 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -32,6 +32,9 @@ extern "C" { #define _SINS_ #endif +//used to differentiate control packets over data port +#define USRP2_INVALID_VRT_HEADER 0 + // size of the vrt header and trailer to the host #define USRP2_HOST_RX_VRT_HEADER_WORDS32 5 #define USRP2_HOST_RX_VRT_TRAILER_WORDS32 1 //FIXME fpga sets wrong header size when no trailer present @@ -90,8 +93,8 @@ typedef enum{ USRP2_CTRL_ID_SETUP_THIS_DDC_FOR_ME_BRO, USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE, - USRP2_CTRL_ID_CONFIGURE_STREAMING_FOR_ME_BRO, - USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE, + USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO, + USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE, USRP2_CTRL_ID_SETUP_THIS_DUC_FOR_ME_BRO, USRP2_CTRL_ID_TOTALLY_SETUP_THE_DUC_DUDE, @@ -186,12 +189,13 @@ typedef struct{ _SINS_ uint32_t scale_iq; } ddc_args; struct { - _SINS_ uint8_t enabled; - _SINS_ uint8_t _pad[3]; + _SINS_ uint8_t now; //stream now? + _SINS_ uint8_t continuous; //auto-reload commmands? + _SINS_ uint8_t _pad[2]; _SINS_ uint32_t secs; _SINS_ uint32_t ticks; - _SINS_ uint32_t samples; - } streaming; + _SINS_ uint32_t num_samps; + } stream_cmd; struct { _SINS_ uint32_t freq_word; _SINS_ uint32_t interp; diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index dc8eea243..c87884ebb 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -16,7 +16,6 @@ // #include <complex> -#include <algorithm> #include <boost/format.hpp> #include "usrp2_impl.hpp" @@ -42,20 +41,22 @@ void usrp2_impl::io_init(void){ _rx_copy_buff = asio::buffer("", 0); //send a small data packet so the usrp2 knows the udp source port - boost::uint32_t zero_data = 0; - _data_transport->send(asio::buffer(&zero_data, sizeof(zero_data))); + //and the maximum number of lines (32 bit words) per packet + boost::uint32_t data[2] = { + htonl(USRP2_INVALID_VRT_HEADER), + htonl(_max_rx_samples_per_packet) + }; + _data_transport->send(asio::buffer(&data, sizeof(data))); } -#define unrolled_loop(__i, __len, __inst) {\ +#define unrolled_loop(__inst, __len){ \ size_t __i = 0; \ - while(__i < (__len & ~0x7)){ \ - __inst; __i++; __inst; __i++; \ - __inst; __i++; __inst; __i++; \ - __inst; __i++; __inst; __i++; \ - __inst; __i++; __inst; __i++; \ + for(; __i < (__len & ~0x3); __i+= 4){ \ + __inst(__i+0); __inst(__i+1); \ + __inst(__i+2); __inst(__i+3); \ } \ - while(__i < __len){ \ - __inst; __i++;\ + for(; __i < __len; __i++){ \ + __inst(__i); \ } \ } @@ -71,11 +72,12 @@ static inline void host_floats_to_usrp2_items( const fc32_t *host_floats, size_t num_samps ){ - unrolled_loop(i, num_samps,{ - boost::uint16_t real = boost::int16_t(host_floats[i].real()*shorts_per_float); - boost::uint16_t imag = boost::int16_t(host_floats[i].imag()*shorts_per_float); - usrp2_items[i] = htonl((real << 16) | (imag << 0)); - }); + #define host_floats_to_usrp2_items_i(i){ \ + boost::uint16_t real = boost::int16_t(host_floats[i].real()*shorts_per_float); \ + boost::uint16_t imag = boost::int16_t(host_floats[i].imag()*shorts_per_float); \ + usrp2_items[i] = htonl((real << 16) | (imag << 0)); \ + } + unrolled_loop(host_floats_to_usrp2_items_i, num_samps); } static inline void usrp2_items_to_host_floats( @@ -83,12 +85,13 @@ static inline void usrp2_items_to_host_floats( const boost::uint32_t *usrp2_items, size_t num_samps ){ - unrolled_loop(i, num_samps,{ - boost::uint32_t item = ntohl(usrp2_items[i]); - boost::int16_t real = boost::uint16_t(item >> 16); - boost::int16_t imag = boost::uint16_t(item >> 0); - host_floats[i] = fc32_t(float(real*floats_per_short), float(imag*floats_per_short)); - }); + #define usrp2_items_to_host_floats_i(i){ \ + boost::uint32_t item = ntohl(usrp2_items[i]); \ + boost::int16_t real = boost::uint16_t(item >> 16); \ + boost::int16_t imag = boost::uint16_t(item >> 0); \ + host_floats[i] = fc32_t(float(real*floats_per_short), float(imag*floats_per_short)); \ + } + unrolled_loop(usrp2_items_to_host_floats_i, num_samps); } static inline void host_items_to_usrp2_items( @@ -96,11 +99,12 @@ static inline void host_items_to_usrp2_items( const boost::uint32_t *host_items, size_t num_samps ){ + #define host_items_to_usrp2_items_i(i) usrp2_items[i] = htonl(host_items[i]) if (is_big_endian){ std::memcpy(usrp2_items, host_items, num_samps*sizeof(boost::uint32_t)); } else{ - unrolled_loop(i, num_samps, usrp2_items[i] = htonl(host_items[i])); + unrolled_loop(host_items_to_usrp2_items_i, num_samps); } } @@ -109,11 +113,12 @@ static inline void usrp2_items_to_host_items( const boost::uint32_t *usrp2_items, size_t num_samps ){ + #define usrp2_items_to_host_items_i(i) host_items[i] = ntohl(usrp2_items[i]) if (is_big_endian){ std::memcpy(host_items, usrp2_items, num_samps*sizeof(boost::uint32_t)); } else{ - unrolled_loop(i, num_samps, host_items[i] = ntohl(usrp2_items[i])); + unrolled_loop(usrp2_items_to_host_items_i, num_samps); } } @@ -167,46 +172,43 @@ void usrp2_impl::recv_raw(rx_metadata_t &metadata){ size_t usrp2_impl::send( const asio::const_buffer &buff, const tx_metadata_t &metadata, - const std::string &type + const io_type_t &io_type ){ boost::uint32_t tx_mem[_mtu/sizeof(boost::uint32_t)]; - boost::uint32_t *items = tx_mem + vrt::max_header_words32; //offset for data - size_t num_samps = _max_tx_samples_per_packet; - - //calculate the number of samples to be copied - //and copy the samples into the send buffer - if (type == "32fc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(fc32_t), num_samps); - host_floats_to_usrp2_items(items, asio::buffer_cast<const fc32_t*>(buff), num_samps); - } - else if (type == "16sc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(sc16_t), num_samps); - host_items_to_usrp2_items(items, asio::buffer_cast<const boost::uint32_t*>(buff), num_samps); - } - else{ - throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%s\"") % type)); - } + size_t num_samps = std::min( + asio::buffer_size(buff)/io_type.size, + size_t(_max_tx_samples_per_packet) + ); - boost::uint32_t vrt_hdr[vrt::max_header_words32]; size_t num_header_words32, num_packet_words32; size_t packet_count = _tx_stream_id_to_packet_seq[metadata.stream_id]++; //pack metadata into a vrt header vrt::pack( metadata, //input - vrt_hdr, //output + tx_mem, //output num_header_words32, //output num_samps, //input num_packet_words32, //output packet_count //input ); - //copy in the vrt header (yes we left space) - items -= num_header_words32; - std::memcpy(items, vrt_hdr, num_header_words32*sizeof(boost::uint32_t)); + boost::uint32_t *items = tx_mem + num_header_words32; //offset for data + + //copy the samples into the send buffer + switch(io_type.tid){ + case io_type_t::COMPLEX_FLOAT32: + host_floats_to_usrp2_items(items, asio::buffer_cast<const fc32_t*>(buff), num_samps); + break; + case io_type_t::COMPLEX_INT16: + host_items_to_usrp2_items(items, asio::buffer_cast<const boost::uint32_t*>(buff), num_samps); + break; + default: + throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%c\"") % io_type.tid)); + } //send and return number of samples - _data_transport->send(asio::buffer(items, num_packet_words32*sizeof(boost::uint32_t))); + _data_transport->send(asio::buffer(tx_mem, num_packet_words32*sizeof(boost::uint32_t))); return num_samps; } @@ -216,7 +218,7 @@ size_t usrp2_impl::send( size_t usrp2_impl::recv( const asio::mutable_buffer &buff, rx_metadata_t &metadata, - const std::string &type + const io_type_t &io_type ){ //perform a receive if no rx data is waiting to be copied if (asio::buffer_size(_rx_copy_buff) == 0){ @@ -232,21 +234,22 @@ size_t usrp2_impl::recv( //and a pointer into the usrp2 received items memory size_t bytes_to_copy = asio::buffer_size(_rx_copy_buff); if (bytes_to_copy == 0) return 0; //nothing to receive - size_t num_samps = bytes_to_copy/sizeof(boost::uint32_t); + size_t num_samps = std::min( + asio::buffer_size(buff)/io_type.size, + bytes_to_copy/sizeof(boost::uint32_t) + ); const boost::uint32_t *items = asio::buffer_cast<const boost::uint32_t*>(_rx_copy_buff); - //calculate the number of samples to be copied - //and copy the samples from the recv buffer - if (type == "32fc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(fc32_t), num_samps); + //copy the samples from the recv buffer + switch(io_type.tid){ + case io_type_t::COMPLEX_FLOAT32: usrp2_items_to_host_floats(asio::buffer_cast<fc32_t*>(buff), items, num_samps); - } - else if (type == "16sc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(sc16_t), num_samps); + break; + case io_type_t::COMPLEX_INT16: usrp2_items_to_host_items(asio::buffer_cast<boost::uint32_t*>(buff), items, num_samps); - } - else{ - throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%s\"") % type)); + break; + default: + throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%c\"") % io_type.tid)); } //update the rx copy buffer to reflect the bytes copied diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index cbca8eec7..35dfd6287 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -15,7 +15,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/types/mac_addr.hpp> #include "usrp2_impl.hpp" using namespace uhd; @@ -35,27 +36,10 @@ void usrp2_impl::mboard_init(void){ } void usrp2_impl::init_clock_config(void){ - //init the ref source clock config - _ref_source_dict = boost::assign::map_list_of - ("int", USRP2_REF_SOURCE_INT) - ("sma", USRP2_REF_SOURCE_SMA) - ("mimo", USRP2_REF_SOURCE_MIMO) - ; - _clock_config.ref_source = "int"; - - //init the pps source clock config - _pps_source_dict = boost::assign::map_list_of - ("sma", USRP2_PPS_SOURCE_SMA) - ("mimo", USRP2_PPS_SOURCE_MIMO) - ; - _clock_config.pps_source = "sma"; - - //init the pps polarity clock config - _pps_polarity_dict = boost::assign::map_list_of - (clock_config_t::POLARITY_POS, USRP2_PPS_POLARITY_POS) - (clock_config_t::POLARITY_NEG, USRP2_PPS_POLARITY_NEG) - ; - _clock_config.pps_polarity = clock_config_t::POLARITY_NEG; + //setup the clock configuration settings + _clock_config.ref_source = clock_config_t::REF_INT; + _clock_config.pps_source = clock_config_t::PPS_SMA; + _clock_config.pps_polarity = clock_config_t::PPS_NEG; //update the clock config (sends a control packet) update_clock_config(); @@ -65,9 +49,35 @@ void usrp2_impl::update_clock_config(void){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_HERES_A_NEW_CLOCK_CONFIG_BRO); - out_data.data.clock_config.ref_source = _ref_source_dict [_clock_config.ref_source]; - out_data.data.clock_config.pps_source = _pps_source_dict [_clock_config.pps_source]; - out_data.data.clock_config.pps_polarity = _pps_polarity_dict[_clock_config.pps_polarity]; + + //translate ref source enums + switch(_clock_config.ref_source){ + case clock_config_t::REF_INT: + out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_INT; break; + case clock_config_t::REF_SMA: + out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_SMA; break; + case clock_config_t::REF_MIMO: + out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_MIMO; break; + default: throw std::runtime_error("usrp2: unhandled clock configuration ref source"); + } + + //translate pps source enums + switch(_clock_config.pps_source){ + case clock_config_t::PPS_SMA: + out_data.data.clock_config.pps_source = USRP2_PPS_SOURCE_SMA; break; + case clock_config_t::PPS_MIMO: + out_data.data.clock_config.pps_source = USRP2_PPS_SOURCE_MIMO; break; + default: throw std::runtime_error("usrp2: unhandled clock configuration pps source"); + } + + //translate pps polarity enums + switch(_clock_config.pps_polarity){ + case clock_config_t::PPS_POS: + out_data.data.clock_config.pps_source = USRP2_PPS_POLARITY_POS; break; + case clock_config_t::PPS_NEG: + out_data.data.clock_config.pps_source = USRP2_PPS_POLARITY_NEG; break; + default: throw std::runtime_error("usrp2: unhandled clock configuration pps polarity"); + } //send and recv usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); @@ -106,7 +116,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_THIS_IS_MY_MAC_ADDR_DUDE); //extract the address - val = reinterpret_cast<mac_addr_t*>(in_data.data.mac_addr)->to_string(); + val = mac_addr_t::from_bytes(in_data.data.mac_addr).to_string(); return; } @@ -159,7 +169,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_CLOCK_RATE: - val = freq_t(get_master_clock_freq()); + val = double(get_master_clock_freq()); return; case MBOARD_PROP_RX_DSP: @@ -184,14 +194,6 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ val = _clock_config; return; - case MBOARD_PROP_PPS_SOURCE_NAMES: - val = prop_names_t(_pps_source_dict.get_keys()); - return; - - case MBOARD_PROP_REF_SOURCE_NAMES: - val = prop_names_t(_ref_source_dict.get_keys()); - return; - case MBOARD_PROP_TIME_NOW: case MBOARD_PROP_TIME_NEXT_PPS: throw std::runtime_error("Error: trying to get write-only property on usrp2 mboard"); @@ -209,8 +211,8 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_HERE_IS_A_NEW_MAC_ADDR_BRO); - mac_addr_t mac_addr(val.as<std::string>()); - std::memcpy(out_data.data.mac_addr, &mac_addr, sizeof(mac_addr_t)); + mac_addr_t mac_addr = mac_addr_t::from_string(val.as<std::string>()); + std::copy(mac_addr.to_bytes(), mac_addr.to_bytes()+mac_addr_t::hlen, out_data.data.mac_addr); //send and recv usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); @@ -234,13 +236,9 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ //handle the get request conditioned on the key switch(key.as<mboard_prop_t>()){ - case MBOARD_PROP_CLOCK_CONFIG:{ - clock_config_t clock_config = val.as<clock_config_t>(); - assert_has(_pps_source_dict.get_keys(), clock_config.pps_source, "usrp2 pps source"); - assert_has(_ref_source_dict.get_keys(), clock_config.ref_source, "usrp2 ref source"); - _clock_config = clock_config; //shadow - update_clock_config(); - } + case MBOARD_PROP_CLOCK_CONFIG: + _clock_config = val.as<clock_config_t>(); + update_clock_config(); return; case MBOARD_PROP_TIME_NOW:{ @@ -264,8 +262,6 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ case MBOARD_PROP_RX_DBOARD_NAMES: case MBOARD_PROP_TX_DBOARD: case MBOARD_PROP_TX_DBOARD_NAMES: - case MBOARD_PROP_PPS_SOURCE_NAMES: - case MBOARD_PROP_REF_SOURCE_NAMES: throw std::runtime_error("Error: trying to set read-only property on usrp2 mboard"); } diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 85d73e83a..b0ee395fb 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -15,9 +15,12 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // +#include <uhd/transport/if_addrs.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/utils/static.hpp> #include <boost/format.hpp> +#include <boost/foreach.hpp> #include <boost/bind.hpp> -#include <uhd/utils.hpp> #include <iostream> #include "usrp2_impl.hpp" @@ -26,17 +29,34 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace asio = boost::asio; -STATIC_BLOCK(register_usrp2_device){ - device::register_device(&usrp2::discover, &usrp2::make); +UHD_STATIC_BLOCK(register_usrp2_device){ + device::register_device(&usrp2::find, &usrp2::make); } /*********************************************************************** * Discovery over the udp transport **********************************************************************/ -uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ +uhd::device_addrs_t usrp2::find(const device_addr_t &hint){ device_addrs_t usrp2_addrs; - if (not hint.has_key("addr")) return usrp2_addrs; + //if no address was specified, send a broadcast on each interface + if (not hint.has_key("addr")){ + BOOST_FOREACH(const if_addrs_t &if_addrs, get_if_addrs()){ + //avoid the loopback device + if (if_addrs.inet == asio::ip::address_v4::loopback().to_string()) continue; + + //create a new hint with this broadcast address + device_addr_t new_hint = hint; + new_hint["addr"] = if_addrs.bcast; + + //call discover with the new hint and append results + device_addrs_t new_usrp2_addrs = usrp2::find(new_hint); + usrp2_addrs.insert(usrp2_addrs.begin(), + new_usrp2_addrs.begin(), new_usrp2_addrs.end() + ); + } + return usrp2_addrs; + } //create a udp transport to communicate //TODO if an addr is not provided, search all interfaces? @@ -63,7 +83,6 @@ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ boost::asio::ip::address_v4 ip_addr(ntohl(ctrl_data_in.data.ip_addr)); device_addr_t new_addr; new_addr["name"] = "USRP2"; - new_addr["transport"] = "udp"; new_addr["addr"] = ip_addr.to_string(); usrp2_addrs.push_back(new_addr); //dont break here, it will exit the while loop diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 55ac0b192..3468a0cf1 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -19,9 +19,10 @@ #define INCLUDED_USRP2_IMPL_HPP #include <uhd/usrp/usrp2.hpp> -#include <uhd/dict.hpp> -#include <uhd/types.hpp> -#include <uhd/time_spec.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/types/stream_cmd.hpp> +#include <uhd/types/clock_config.hpp> +#include <boost/asio.hpp> #include <boost/thread.hpp> #include <boost/shared_ptr.hpp> #include <boost/function.hpp> @@ -105,8 +106,8 @@ public: double get_master_clock_freq(void); //the io interface - size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &); - size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &); + size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &); + size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &); private: //device properties interface @@ -146,11 +147,6 @@ private: void update_clock_config(void); void set_time_spec(const uhd::time_spec_t &time_spec, bool now); - //mappings from clock config strings to over the wire enums - uhd::dict<std::string, usrp2_ref_source_t> _ref_source_dict; - uhd::dict<std::string, usrp2_pps_source_t> _pps_source_dict; - uhd::dict<uhd::clock_config_t::polarity_t, usrp2_pps_polarity_t> _pps_polarity_dict; - //rx and tx dboard methods and objects uhd::usrp::dboard_manager::sptr _dboard_manager; void dboard_init(void); @@ -177,16 +173,14 @@ private: //methods and shadows for the ddc dsp std::vector<size_t> _allowed_decim_and_interp_rates; size_t _ddc_decim; - uhd::freq_t _ddc_freq; - bool _ddc_enabled; - uhd::time_spec_t _ddc_stream_at; + double _ddc_freq; void init_ddc_config(void); void update_ddc_config(void); - void update_ddc_enabled(void); + void issue_ddc_stream_cmd(const uhd::stream_cmd_t &stream_cmd); //methods and shadows for the duc dsp size_t _duc_interp; - uhd::freq_t _duc_freq; + double _duc_freq; void init_duc_config(void); void update_duc_config(void); diff --git a/host/lib/usrp/usrp1e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index a2798dce3..7c87361e0 100644 --- a/host/lib/usrp/usrp1e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -16,21 +16,20 @@ // #include <boost/bind.hpp> -#include <uhd/utils.hpp> -#include "usrp1e_impl.hpp" +#include "usrp_e_impl.hpp" using namespace uhd::usrp; /*********************************************************************** * Dboard Initialization **********************************************************************/ -void usrp1e_impl::dboard_init(void){ +void usrp_e_impl::dboard_init(void){ dboard_id_t rx_dboard_id = dboard_id::NONE; //TODO get these from the eeprom dboard_id_t tx_dboard_id = dboard_id::NONE; //create a new dboard interface and manager dboard_interface::sptr dboard_interface( - make_usrp1e_dboard_interface(this) + make_usrp_e_dboard_interface(this) ); _dboard_manager = dboard_manager::make( rx_dboard_id, tx_dboard_id, dboard_interface @@ -38,39 +37,39 @@ void usrp1e_impl::dboard_init(void){ //setup the dboard proxies _rx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::rx_dboard_get, this, _1, _2), - boost::bind(&usrp1e_impl::rx_dboard_set, this, _1, _2) + boost::bind(&usrp_e_impl::rx_dboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_dboard_set, this, _1, _2) ); _tx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::tx_dboard_get, this, _1, _2), - boost::bind(&usrp1e_impl::tx_dboard_set, this, _1, _2) + boost::bind(&usrp_e_impl::tx_dboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_dboard_set, this, _1, _2) ); } /*********************************************************************** * RX Dboard Get **********************************************************************/ -void usrp1e_impl::rx_dboard_get(const wax::obj &, wax::obj &){ +void usrp_e_impl::rx_dboard_get(const wax::obj &, wax::obj &){ } /*********************************************************************** * RX Dboard Set **********************************************************************/ -void usrp1e_impl::rx_dboard_set(const wax::obj &, const wax::obj &){ +void usrp_e_impl::rx_dboard_set(const wax::obj &, const wax::obj &){ } /*********************************************************************** * TX Dboard Get **********************************************************************/ -void usrp1e_impl::tx_dboard_get(const wax::obj &, wax::obj &){ +void usrp_e_impl::tx_dboard_get(const wax::obj &, wax::obj &){ } /*********************************************************************** * TX Dboard Set **********************************************************************/ -void usrp1e_impl::tx_dboard_set(const wax::obj &, const wax::obj &){ +void usrp_e_impl::tx_dboard_set(const wax::obj &, const wax::obj &){ } diff --git a/host/lib/usrp/usrp1e/dboard_interface.cpp b/host/lib/usrp/usrp_e/dboard_interface.cpp index ef91014ac..a343d93b8 100644 --- a/host/lib/usrp/usrp1e/dboard_interface.cpp +++ b/host/lib/usrp/usrp_e/dboard_interface.cpp @@ -15,24 +15,28 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> +#include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include <uhd/types/dict.hpp> +#include <uhd/utils/assert.hpp> +#include <boost/assign/list_of.hpp> #include <algorithm> //std::copy -#include "usrp1e_impl.hpp" -#include <linux/usrp1_e.h> +#include <linux/usrp_e.h> +#include <cstddef> using namespace uhd::usrp; -class usrp1e_dboard_interface : public dboard_interface{ +class usrp_e_dboard_interface : public dboard_interface{ public: - usrp1e_dboard_interface(usrp1e_impl *impl); - ~usrp1e_dboard_interface(void); + usrp_e_dboard_interface(usrp_e_impl *impl); + ~usrp_e_dboard_interface(void); void write_aux_dac(unit_type_t, int, int); int read_aux_adc(unit_type_t, int); void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t); - void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t); - void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t); + void set_gpio_ddr(gpio_bank_t, boost::uint16_t); + void write_gpio(gpio_bank_t, boost::uint16_t); boost::uint16_t read_gpio(gpio_bank_t); void write_i2c(int, const byte_vector_t &); @@ -50,61 +54,126 @@ private: bool readback ); - usrp1e_impl *_impl; + usrp_e_impl *_impl; }; /*********************************************************************** * Make Function **********************************************************************/ -dboard_interface::sptr make_usrp1e_dboard_interface(usrp1e_impl *impl){ - return dboard_interface::sptr(new usrp1e_dboard_interface(impl)); +dboard_interface::sptr make_usrp_e_dboard_interface(usrp_e_impl *impl){ + return dboard_interface::sptr(new usrp_e_dboard_interface(impl)); } /*********************************************************************** * Structors **********************************************************************/ -usrp1e_dboard_interface::usrp1e_dboard_interface(usrp1e_impl *impl){ +usrp_e_dboard_interface::usrp_e_dboard_interface(usrp_e_impl *impl){ _impl = impl; } -usrp1e_dboard_interface::~usrp1e_dboard_interface(void){ +usrp_e_dboard_interface::~usrp_e_dboard_interface(void){ /* NOP */ } /*********************************************************************** * Clock Rates **********************************************************************/ -double usrp1e_dboard_interface::get_rx_clock_rate(void){ +double usrp_e_dboard_interface::get_rx_clock_rate(void){ throw std::runtime_error("not implemented"); } -double usrp1e_dboard_interface::get_tx_clock_rate(void){ +double usrp_e_dboard_interface::get_tx_clock_rate(void){ throw std::runtime_error("not implemented"); } /*********************************************************************** * GPIO **********************************************************************/ -void usrp1e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); +void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value){ + //define mapping of gpio bank to register address + static const uhd::dict<gpio_bank_t, boost::uint32_t> bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_ddr)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_ddr)) + ; + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + _impl->ioctl(USRP_E_WRITE_CTL16, &data); } -void usrp1e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); +void usrp_e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value){ + //define mapping of gpio bank to register address + static const uhd::dict<gpio_bank_t, boost::uint32_t> bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_io)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_io)) + ; + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + _impl->ioctl(USRP_E_WRITE_CTL16, &data); } -boost::uint16_t usrp1e_dboard_interface::read_gpio(gpio_bank_t bank){ - throw std::runtime_error("not implemented"); +boost::uint16_t usrp_e_dboard_interface::read_gpio(gpio_bank_t bank){ + //define mapping of gpio bank to register address + static const uhd::dict<gpio_bank_t, boost::uint32_t> bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_io)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_io)) + ; + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 1; + + //call the ioctl + _impl->ioctl(USRP_E_READ_CTL16, &data); + + return data.buf[0]; } -void usrp1e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); +void usrp_e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){ + //define mapping of gpio bank to register address + static const uhd::dict<gpio_bank_t, boost::uint32_t> bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_sel_low)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_sel_low)) + ; + + //set the gpio selection mux to atr or software controlled + boost::uint16_t low_sel = 0, high_sel = 0; + for(size_t i = 0; i < 16; i++){ + boost::uint16_t code = (mask & (1 << i))? GPIO_SEL_ATR : GPIO_SEL_SW; + if(i < 8) low_sel |= code << (2*i-0); + else high_sel |= code << (2*i-8); + } + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 2; + data.buf[0] = low_sel; + data.buf[1] = high_sel; + + //call the ioctl + _impl->ioctl(USRP_E_READ_CTL16, &data); + + //----------------------------------------> TODO + //TODO set the atr regs } /*********************************************************************** * SPI **********************************************************************/ -dboard_interface::byte_vector_t usrp1e_dboard_interface::transact_spi( +dboard_interface::byte_vector_t usrp_e_dboard_interface::transact_spi( spi_dev_t dev, spi_latch_t latch, spi_push_t push, @@ -142,7 +211,7 @@ dboard_interface::byte_vector_t usrp1e_dboard_interface::transact_spi( **********************************************************************/ static const size_t max_i2c_data_bytes = 10; -void usrp1e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ +void usrp_e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ //allocate some memory for this transaction ASSERT_THROW(buf.size() <= max_i2c_data_bytes); boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; @@ -157,7 +226,7 @@ void usrp1e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ _impl->ioctl(USRP_E_I2C_WRITE, &data); } -dboard_interface::byte_vector_t usrp1e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ +dboard_interface::byte_vector_t usrp_e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ //allocate some memory for this transaction ASSERT_THROW(num_bytes <= max_i2c_data_bytes); boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; @@ -180,10 +249,10 @@ dboard_interface::byte_vector_t usrp1e_dboard_interface::read_i2c(int i2c_addr, /*********************************************************************** * Aux DAX/ADC **********************************************************************/ -void usrp1e_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ +void usrp_e_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ throw std::runtime_error("not implemented"); } -int usrp1e_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ +int usrp_e_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ throw std::runtime_error("not implemented"); } diff --git a/host/lib/usrp/usrp1e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp index 862b89184..e32c76a3d 100644 --- a/host/lib/usrp/usrp1e/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -16,55 +16,54 @@ // #include <boost/bind.hpp> -#include <uhd/utils.hpp> -#include "usrp1e_impl.hpp" +#include "usrp_e_impl.hpp" using namespace uhd::usrp; /*********************************************************************** * RX DDC Initialization **********************************************************************/ -void usrp1e_impl::rx_ddc_init(void){ +void usrp_e_impl::rx_ddc_init(void){ _rx_ddc_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::rx_ddc_get, this, _1, _2), - boost::bind(&usrp1e_impl::rx_ddc_set, this, _1, _2) + boost::bind(&usrp_e_impl::rx_ddc_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_ddc_set, this, _1, _2) ); } /*********************************************************************** * RX DDC Get **********************************************************************/ -void usrp1e_impl::rx_ddc_get(const wax::obj &, wax::obj &){ +void usrp_e_impl::rx_ddc_get(const wax::obj &, wax::obj &){ } /*********************************************************************** * RX DDC Set **********************************************************************/ -void usrp1e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ +void usrp_e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ } /*********************************************************************** * TX DUC Initialization **********************************************************************/ -void usrp1e_impl::tx_duc_init(void){ +void usrp_e_impl::tx_duc_init(void){ _tx_duc_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::tx_duc_get, this, _1, _2), - boost::bind(&usrp1e_impl::tx_duc_set, this, _1, _2) + boost::bind(&usrp_e_impl::tx_duc_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_duc_set, this, _1, _2) ); } /*********************************************************************** * TX DUC Get **********************************************************************/ -void usrp1e_impl::tx_duc_get(const wax::obj &, wax::obj &){ +void usrp_e_impl::tx_duc_get(const wax::obj &, wax::obj &){ } /*********************************************************************** * TX DUC Set **********************************************************************/ -void usrp1e_impl::tx_duc_set(const wax::obj &, const wax::obj &){ +void usrp_e_impl::tx_duc_set(const wax::obj &, const wax::obj &){ } diff --git a/host/lib/usrp/usrp1e/fpga-downloader.cc b/host/lib/usrp/usrp_e/fpga-downloader.cc index f7c78b875..4429786a9 100644 --- a/host/lib/usrp/usrp1e/fpga-downloader.cc +++ b/host/lib/usrp/usrp_e/fpga-downloader.cc @@ -246,8 +246,8 @@ int main(int argc, char *argv[]) } */ -#include <uhd/usrp/usrp1e.hpp> -void uhd::usrp::usrp1e::load_fpga(const std::string &bin_file){ +#include <uhd/usrp/usrp_e.hpp> +void uhd::usrp::usrp_e::load_fpga(const std::string &bin_file){ gpio gpio_prog_b(PROG_B, OUT); gpio gpio_init_b(INIT_B, IN); gpio gpio_done (DONE, IN); diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp new file mode 100644 index 000000000..1d3f9f466 --- /dev/null +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -0,0 +1,116 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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 of the License, or +// (at your option) any later version. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include "usrp_e_impl.hpp" +#include <uhd/utils/assert.hpp> +#include <uhd/props.hpp> +#include <boost/bind.hpp> + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * Mboard Initialization + **********************************************************************/ +void usrp_e_impl::mboard_init(void){ + _mboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::mboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::mboard_set, this, _1, _2) + ); + + //init the clock config + _clock_config.ref_source = clock_config_t::REF_AUTO; + _clock_config.pps_source = clock_config_t::PPS_SMA; + + //TODO poke the clock config regs +} + +/*********************************************************************** + * Mboard Get + **********************************************************************/ +void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + + //handle the get request conditioned on the key + switch(key.as<mboard_prop_t>()){ + case MBOARD_PROP_NAME: + val = std::string("usrp-e mboard"); + return; + + case MBOARD_PROP_OTHERS: + val = prop_names_t(); + return; + + case MBOARD_PROP_RX_DBOARD: + ASSERT_THROW(name == ""); + val = _rx_dboard_proxy->get_link(); + return; + + case MBOARD_PROP_RX_DBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case MBOARD_PROP_TX_DBOARD: + ASSERT_THROW(name == ""); + val = _tx_dboard_proxy->get_link(); + return; + + case MBOARD_PROP_TX_DBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case MBOARD_PROP_CLOCK_RATE: + //val = TODO probably remove this property + return; + + case MBOARD_PROP_RX_DSP: + ASSERT_THROW(name == "ddc0"); + val = _rx_ddc_proxy->get_link(); + return; + + case MBOARD_PROP_RX_DSP_NAMES: + val = prop_names_t(1, "ddc0"); + return; + + case MBOARD_PROP_TX_DSP: + ASSERT_THROW(name == "duc0"); + val = _tx_duc_proxy->get_link(); + return; + + case MBOARD_PROP_TX_DSP_NAMES: + val = prop_names_t(1, "duc0"); + return; + + case MBOARD_PROP_CLOCK_CONFIG: + val = _clock_config; + return; + + case MBOARD_PROP_TIME_NOW: + case MBOARD_PROP_TIME_NEXT_PPS: + throw std::runtime_error("Error: trying to get write-only property on usrp-e mboard"); + + } +} + +/*********************************************************************** + * Mboard Set + **********************************************************************/ +void usrp_e_impl::mboard_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 8230cc8e4..e821add8c 100644 --- a/host/lib/usrp/usrp1e/usrp1e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -15,10 +15,11 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/utils.hpp> +#include "usrp_e_impl.hpp" +#include <uhd/utils/assert.hpp> +#include <uhd/utils/static.hpp> #include <boost/format.hpp> #include <boost/filesystem.hpp> -#include "usrp1e_impl.hpp" #include <fcntl.h> //open #include <sys/ioctl.h> //ioctl @@ -26,8 +27,8 @@ using namespace uhd; using namespace uhd::usrp; namespace fs = boost::filesystem; -STATIC_BLOCK(register_usrp1e_device){ - device::register_device(&usrp1e::discover, &usrp1e::make); +UHD_STATIC_BLOCK(register_usrp_e_device){ + device::register_device(&usrp_e::find, &usrp_e::make); } /*********************************************************************** @@ -40,16 +41,16 @@ static std::string abs_path(const std::string &file_path){ /*********************************************************************** * Discovery **********************************************************************/ -device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ - device_addrs_t usrp1e_addrs; +device_addrs_t usrp_e::find(const device_addr_t &device_addr){ + device_addrs_t usrp_e_addrs; //if a node was provided, use it and only it if (device_addr.has_key("node")){ - if (not fs::exists(device_addr["node"])) return usrp1e_addrs; + if (not fs::exists(device_addr["node"])) return usrp_e_addrs; device_addr_t new_addr; - new_addr["name"] = "USRP1E"; + new_addr["name"] = "USRP-E"; new_addr["node"] = abs_path(device_addr["node"]); - usrp1e_addrs.push_back(new_addr); + usrp_e_addrs.push_back(new_addr); } //otherwise look for a few nodes at small indexes @@ -58,26 +59,26 @@ device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ std::string node = str(boost::format("/dev/usrp1_e%d") % i); if (not fs::exists(node)) continue; device_addr_t new_addr; - new_addr["name"] = "USRP1E"; + new_addr["name"] = "USRP-E"; new_addr["node"] = abs_path(node); - usrp1e_addrs.push_back(new_addr); + usrp_e_addrs.push_back(new_addr); } } - return usrp1e_addrs; + return usrp_e_addrs; } /*********************************************************************** * Make **********************************************************************/ -device::sptr usrp1e::make(const device_addr_t &device_addr){ - return sptr(new usrp1e_impl(device_addr["node"])); +device::sptr usrp_e::make(const device_addr_t &device_addr){ + return sptr(new usrp_e_impl(device_addr["node"])); } /*********************************************************************** * Structors **********************************************************************/ -usrp1e_impl::usrp1e_impl(const std::string &node){ +usrp_e_impl::usrp_e_impl(const std::string &node){ //open the device node and check file descriptor if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ throw std::runtime_error(str( @@ -96,7 +97,7 @@ usrp1e_impl::usrp1e_impl(const std::string &node){ tx_duc_init(); } -usrp1e_impl::~usrp1e_impl(void){ +usrp_e_impl::~usrp_e_impl(void){ //close the device node file descriptor ::close(_node_fd); } @@ -104,7 +105,7 @@ usrp1e_impl::~usrp1e_impl(void){ /*********************************************************************** * Misc Methods **********************************************************************/ -void usrp1e_impl::ioctl(int request, void *mem){ +void usrp_e_impl::ioctl(int request, void *mem){ if (::ioctl(_node_fd, request, mem) < 0){ throw std::runtime_error(str( boost::format("ioctl failed with request %d") % request @@ -115,14 +116,14 @@ void usrp1e_impl::ioctl(int request, void *mem){ /*********************************************************************** * Device Get **********************************************************************/ -void usrp1e_impl::get(const wax::obj &key_, wax::obj &val){ +void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ wax::obj key; std::string name; boost::tie(key, name) = extract_named_prop(key_); //handle the get request conditioned on the key switch(key.as<device_prop_t>()){ case DEVICE_PROP_NAME: - val = std::string("usrp1e device"); + val = std::string("usrp-e device"); return; case DEVICE_PROP_MBOARD: @@ -148,31 +149,31 @@ void usrp1e_impl::get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * Device Set **********************************************************************/ -void usrp1e_impl::set(const wax::obj &, const wax::obj &){ - throw std::runtime_error("Cannot set in usrp1e device"); +void usrp_e_impl::set(const wax::obj &, const wax::obj &){ + throw std::runtime_error("Cannot set in usrp-e device"); } /*********************************************************************** * Device IO (TODO) **********************************************************************/ -size_t usrp1e_impl::send( +size_t usrp_e_impl::send( const boost::asio::const_buffer &, const uhd::tx_metadata_t &, - const std::string &type + const io_type_t & ){ - if (type != "16sc"){ - throw std::runtime_error(str(boost::format("usrp1e send: cannot handle type \"%s\"") % type)); + if (true){ + throw std::runtime_error(str(boost::format("usrp-e send: cannot handle type \"%s\"") % "")); } return 0; } -size_t usrp1e_impl::recv( +size_t usrp_e_impl::recv( const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, - const std::string &type + const io_type_t & ){ - if (type != "16sc"){ - throw std::runtime_error(str(boost::format("usrp1e recv: cannot handle type \"%s\"") % type)); + if (true){ + throw std::runtime_error(str(boost::format("usrp-e recv: cannot handle type \"%s\"") % "")); } return 0; } diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index c199a0465..643589754 100644 --- a/host/lib/usrp/usrp1e/usrp1e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -15,20 +15,21 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/usrp/usrp1e.hpp> +#include <uhd/types/clock_config.hpp> +#include <uhd/usrp/usrp_e.hpp> #include <uhd/usrp/dboard_manager.hpp> -#ifndef INCLUDED_USRP1E_IMPL_HPP -#define INCLUDED_USRP1E_IMPL_HPP +#ifndef INCLUDED_USRP_E_IMPL_HPP +#define INCLUDED_USRP_E_IMPL_HPP -class usrp1e_impl; // dummy class declaration +class usrp_e_impl; // dummy class declaration /*! - * Make a usrp1e dboard interface. - * \param impl a pointer to the usrp1e impl object + * Make a usrp_e dboard interface. + * \param impl a pointer to the usrp_e impl object * \return a sptr to a new dboard interface */ -uhd::usrp::dboard_interface::sptr make_usrp1e_dboard_interface(usrp1e_impl *impl); +uhd::usrp::dboard_interface::sptr make_usrp_e_dboard_interface(usrp_e_impl *impl); /*! * Simple wax obj proxy class: @@ -73,15 +74,15 @@ private: * The implementation details are encapsulated here. * Handles properties on the mboard, dboard, dsps... */ -class usrp1e_impl : public uhd::device{ +class usrp_e_impl : public uhd::device{ public: //structors - usrp1e_impl(const std::string &node); - ~usrp1e_impl(void); + usrp_e_impl(const std::string &node); + ~usrp_e_impl(void); //the io interface - size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &); - size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &); + size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &); + size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &); /*! * Perform an ioctl call on the device node file descriptor. @@ -95,6 +96,8 @@ private: static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); int _node_fd; + uhd::clock_config_t _clock_config; + //device functions and settings void get(const wax::obj &, wax::obj &); void set(const wax::obj &, const wax::obj &); @@ -132,4 +135,4 @@ private: wax_obj_proxy::sptr _tx_duc_proxy; }; -#endif /* INCLUDED_USRP1E_IMPL_HPP */ +#endif /* INCLUDED_USRP_E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp1e/usrp1e_none.cpp b/host/lib/usrp/usrp_e/usrp_e_none.cpp index ac0b12a75..09a3c6946 100644 --- a/host/lib/usrp/usrp1e/usrp1e_none.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_none.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/usrp/usrp1e.hpp> +#include <uhd/usrp/usrp_e.hpp> using namespace uhd; using namespace uhd::usrp; @@ -25,14 +25,14 @@ using namespace uhd::usrp; * when the required kernel module headers are not present. */ -device_addrs_t usrp1e::discover(const device_addr_t &){ +device_addrs_t usrp_e::find(const device_addr_t &){ return device_addrs_t(); //return empty list } -device::sptr usrp1e::make(const device_addr_t &){ +device::sptr usrp_e::make(const device_addr_t &){ throw std::runtime_error("this build has no usrp1e support"); } -void usrp1e::load_fpga(const std::string &){ +void usrp_e::load_fpga(const std::string &){ throw std::runtime_error("this build has no usrp1e support"); } diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp new file mode 100644 index 000000000..219f459a5 --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -0,0 +1,49 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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 of the License, or +// (at your option) any later version. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_USRP_E_REGS_HPP +#define INCLUDED_USRP_E_REGS_HPP + +#include <boost/cstdint.hpp> + +//////////////////////////////////////////////// +// GPIO, Slave 4 +// +// These go to the daughterboard i/o pins + +#define GPIO_BASE 0x40 + +struct gpio_regs_t{ + boost::uint16_t rx_io; // tx data in high 16, rx in low 16 + boost::uint16_t tx_io; + boost::uint16_t rx_ddr; // 32 bits, 1 means output. tx in high 16, rx in low 16 + boost::uint16_t tx_ddr; + boost::uint16_t tx_sel_low; // 16 2-bit fields select which source goes to TX DB + boost::uint16_t tx_sel_high; + boost::uint16_t rx_sel_low; // 16 2-bit fields select which source goes to RX DB + boost::uint16_t rx_sel_high; +}; + +// each 2-bit sel field is layed out this way +#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg +#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic +#define GPIO_SEL_DEBUG_0 2 // if pin is an output, debug lines from FPGA fabric +#define GPIO_SEL_DEBUG_1 3 // if pin is an output, debug lines from FPGA fabric + +//#define gpio_base ((gpio_regs_t *) GPIO_BASE) + +#endif /* INCLUDED_USRP_E_REGS_HPP */ |