diff options
Diffstat (limited to 'host/lib/usrp/usrp1')
-rw-r--r-- | host/lib/usrp/usrp1/clock_ctrl.cpp | 9 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/codec_ctrl.cpp | 18 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/codec_impl.cpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/dboard_iface.cpp | 12 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/dboard_impl.cpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/dsp_impl.cpp | 95 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/io_impl.cpp | 3 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/mboard_impl.cpp | 22 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/usrp1_ctrl.cpp | 206 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/usrp1_ctrl.hpp | 47 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/usrp1_iface.cpp | 38 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/usrp1_iface.hpp | 39 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/usrp1_impl.cpp | 14 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/usrp1_impl.hpp | 16 |
14 files changed, 202 insertions, 321 deletions
diff --git a/host/lib/usrp/usrp1/clock_ctrl.cpp b/host/lib/usrp/usrp1/clock_ctrl.cpp index 156f2b0c4..df5353b54 100644 --- a/host/lib/usrp/usrp1/clock_ctrl.cpp +++ b/host/lib/usrp/usrp1/clock_ctrl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010 Ettus Research LLC +// Copyright 2010-2011 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 @@ -16,13 +16,6 @@ // #include "clock_ctrl.hpp" -#include "fpga_regs_standard.h" -#include <uhd/utils/assert.hpp> -#include <boost/cstdint.hpp> -#include <boost/assign/list_of.hpp> -#include <boost/foreach.hpp> -#include <utility> -#include <iostream> using namespace uhd; diff --git a/host/lib/usrp/usrp1/codec_ctrl.cpp b/host/lib/usrp/usrp1/codec_ctrl.cpp index f3816b377..1b4411002 100644 --- a/host/lib/usrp/usrp1/codec_ctrl.cpp +++ b/host/lib/usrp/usrp1/codec_ctrl.cpp @@ -20,7 +20,7 @@ #include "clock_ctrl.hpp" #include "ad9862_regs.hpp" #include <uhd/types/dict.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp> #include <uhd/utils/algorithm.hpp> #include <uhd/utils/byteswap.hpp> #include <boost/cstdint.hpp> @@ -162,7 +162,7 @@ static const int mtpgw = 255; //maximum tx pga gain word void usrp1_codec_ctrl_impl::set_tx_pga_gain(double gain){ int gain_word = int(mtpgw*(gain - tx_pga_gain_range.start())/(tx_pga_gain_range.stop() - tx_pga_gain_range.start())); - _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw); + _ad9862_regs.tx_pga_gain = uhd::clip(gain_word, 0, mtpgw); this->send_reg(16); } @@ -174,7 +174,7 @@ static const int mrpgw = 0x14; //maximum rx pga gain word void usrp1_codec_ctrl_impl::set_rx_pga_gain(double gain, char which){ int gain_word = int(mrpgw*(gain - rx_pga_gain_range.start())/(rx_pga_gain_range.stop() - rx_pga_gain_range.start())); - gain_word = std::clip(gain_word, 0, mrpgw); + gain_word = uhd::clip(gain_word, 0, mrpgw); switch(which){ case 'A': _ad9862_regs.rx_pga_a = gain_word; @@ -264,7 +264,7 @@ void usrp1_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts) { //special case for aux dac d (aka sigma delta word) if (which == AUX_DAC_D) { - boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); + boost::uint16_t dac_word = uhd::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); _ad9862_regs.sig_delt_11_4 = boost::uint8_t(dac_word >> 4); _ad9862_regs.sig_delt_3_0 = boost::uint8_t(dac_word & 0xf); this->send_reg(42); @@ -273,7 +273,7 @@ void usrp1_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts) } //calculate the dac word for aux dac a, b, c - boost::uint8_t dac_word = std::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff); + boost::uint8_t dac_word = uhd::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff); //setup a lookup table for the aux dac params (reg ref, reg addr) typedef boost::tuple<boost::uint8_t*, boost::uint8_t> dac_params_t; @@ -303,8 +303,8 @@ void usrp1_codec_ctrl_impl::send_reg(boost::uint8_t addr) std::cout << "codec control write reg: 0x"; std::cout << std::setw(8) << std::hex << reg << std::endl; } - _iface->transact_spi(_spi_slave, - spi_config_t::EDGE_RISE, reg, 16, false); + _iface->write_spi(_spi_slave, + spi_config_t::EDGE_RISE, reg, 16); } void usrp1_codec_ctrl_impl::recv_reg(boost::uint8_t addr) @@ -317,8 +317,8 @@ void usrp1_codec_ctrl_impl::recv_reg(boost::uint8_t addr) std::cout << std::setw(8) << std::hex << reg << std::endl; } - boost::uint32_t ret = _iface->transact_spi(_spi_slave, - spi_config_t::EDGE_RISE, reg, 16, true); + boost::uint32_t ret = _iface->read_spi(_spi_slave, + spi_config_t::EDGE_RISE, reg, 16); if (codec_debug) { std::cout.fill('0'); diff --git a/host/lib/usrp/usrp1/codec_impl.cpp b/host/lib/usrp/usrp1/codec_impl.cpp index 14ecd2d2e..7e4032131 100644 --- a/host/lib/usrp/usrp1/codec_impl.cpp +++ b/host/lib/usrp/usrp1/codec_impl.cpp @@ -16,7 +16,7 @@ // #include "usrp1_impl.hpp" -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp> #include <uhd/usrp/codec_props.hpp> #include <boost/bind.hpp> #include <boost/foreach.hpp> diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp index eec4a52db..3f3a98b7a 100644 --- a/host/lib/usrp/usrp1/dboard_iface.cpp +++ b/host/lib/usrp/usrp1/dboard_iface.cpp @@ -24,7 +24,7 @@ #include "codec_ctrl.hpp" #include <uhd/usrp/dboard_iface.hpp> #include <uhd/types/dict.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp> #include <boost/assign/list_of.hpp> #include <iostream> @@ -329,7 +329,7 @@ static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit, else break; } - throw std::invalid_argument("unknown unit type"); + UHD_THROW_INVALID_CODE_PATH(); } void usrp1_dboard_iface::write_spi(unit_t unit, @@ -337,8 +337,8 @@ void usrp1_dboard_iface::write_spi(unit_t unit, boost::uint32_t data, size_t num_bits) { - _iface->transact_spi(unit_to_otw_spi_dev(unit, _dboard_slot), - config, data, num_bits, false); + _iface->write_spi(unit_to_otw_spi_dev(unit, _dboard_slot), + config, data, num_bits); } boost::uint32_t usrp1_dboard_iface::read_write_spi(unit_t unit, @@ -346,8 +346,8 @@ boost::uint32_t usrp1_dboard_iface::read_write_spi(unit_t unit, boost::uint32_t data, size_t num_bits) { - return _iface->transact_spi(unit_to_otw_spi_dev(unit, _dboard_slot), - config, data, num_bits, true); + return _iface->read_spi(unit_to_otw_spi_dev(unit, _dboard_slot), + config, data, num_bits); } /*********************************************************************** diff --git a/host/lib/usrp/usrp1/dboard_impl.cpp b/host/lib/usrp/usrp1/dboard_impl.cpp index 2130960fb..02906fc45 100644 --- a/host/lib/usrp/usrp1/dboard_impl.cpp +++ b/host/lib/usrp/usrp1/dboard_impl.cpp @@ -19,7 +19,7 @@ #include "usrp_i2c_addr.h" #include <uhd/usrp/dsp_utils.hpp> #include <uhd/usrp/misc_utils.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp> #include <uhd/usrp/dboard_props.hpp> #include <uhd/usrp/subdev_props.hpp> #include <boost/bind.hpp> diff --git a/host/lib/usrp/usrp1/dsp_impl.cpp b/host/lib/usrp/usrp1/dsp_impl.cpp index 370f4831f..8152c4e34 100644 --- a/host/lib/usrp/usrp1/dsp_impl.cpp +++ b/host/lib/usrp/usrp1/dsp_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010 Ettus Research LLC +// Copyright 2010-2011 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 @@ -34,23 +34,25 @@ using namespace uhd::usrp; **********************************************************************/ void usrp1_impl::rx_dsp_init(void) { - _rx_dsp_proxy = wax_obj_proxy::make( - boost::bind(&usrp1_impl::rx_dsp_get, this, _1, _2), - boost::bind(&usrp1_impl::rx_dsp_set, this, _1, _2)); - - rx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() / 16); + for (size_t i = 0; i < this->get_num_ddcs(); i++){ + _rx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make( + boost::bind(&usrp1_impl::rx_dsp_get, this, _1, _2, i), + boost::bind(&usrp1_impl::rx_dsp_set, this, _1, _2, i) + ); + rx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() / 16, i); + } } /*********************************************************************** * RX DDC Get **********************************************************************/ -void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val){ +void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){ named_prop_t key = named_prop_t::extract(key_); switch(key.as<dsp_prop_t>()){ case DSP_PROP_NAME: - val = str(boost::format("usrp1 ddc %uX %s") - % this->get_num_ddcs() + val = str(boost::format("usrp1 ddc%d %s") + % which_dsp % (this->has_rx_halfband()? "+ hb" : "") ); return; @@ -60,16 +62,7 @@ void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val){ return; case DSP_PROP_FREQ_SHIFT: - val = _rx_dsp_freqs[key.name]; - return; - - case DSP_PROP_FREQ_SHIFT_NAMES:{ - prop_names_t names; - for(size_t i = 0; i < this->get_num_ddcs(); i++){ - names.push_back(boost::lexical_cast<std::string>(i)); - } - val = names; - } + val = _rx_dsp_freqs[which_dsp]; return; case DSP_PROP_CODEC_RATE: @@ -88,7 +81,7 @@ void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * RX DDC Set **********************************************************************/ -void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){ +void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){ named_prop_t key = named_prop_t::extract(key_); switch(key.as<dsp_prop_t>()) { @@ -97,16 +90,17 @@ void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){ boost::uint32_t reg_word = dsp_type1::calc_cordic_word_and_update( new_freq, _clock_ctrl->get_master_clock_freq()); - static const uhd::dict<std::string, boost::uint32_t> - freq_name_to_reg_val = boost::assign::map_list_of - ("0", FR_RX_FREQ_0) ("1", FR_RX_FREQ_1) - ("2", FR_RX_FREQ_2) ("3", FR_RX_FREQ_3) - ; - _iface->poke32(freq_name_to_reg_val[key.name], ~reg_word + 1); - _rx_dsp_freqs[key.name] = new_freq; + static const boost::uint32_t dsp_index_to_reg_val[4] = { + FR_RX_FREQ_0, FR_RX_FREQ_1, FR_RX_FREQ_2, FR_RX_FREQ_3 + }; + _iface->poke32(dsp_index_to_reg_val[which_dsp], ~reg_word + 1); + _rx_dsp_freqs[which_dsp] = new_freq; return; } - case DSP_PROP_HOST_RATE: { + + case DSP_PROP_HOST_RATE: + if (which_dsp != 0) return; //only for dsp[0] as this is vectorized + { size_t rate = size_t(_clock_ctrl->get_master_clock_freq() / val.as<double>()); if ((rate & 0x01) || (rate < 4) || (rate > 256)) { @@ -123,6 +117,11 @@ void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){ } return; + case DSP_PROP_STREAM_CMD: + if (which_dsp != 0) return; //only for dsp[0] as this is vectorized + _soft_time_ctrl->issue_stream_cmd(val.as<stream_cmd_t>()); + return; + default: UHD_THROW_PROP_SET_ERROR(); } @@ -133,24 +132,25 @@ void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){ **********************************************************************/ void usrp1_impl::tx_dsp_init(void) { - _tx_dsp_proxy = wax_obj_proxy::make( - boost::bind(&usrp1_impl::tx_dsp_get, this, _1, _2), - boost::bind(&usrp1_impl::tx_dsp_set, this, _1, _2)); - - //initial config and update - tx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() * 2 / 16); + for (size_t i = 0; i < this->get_num_ducs(); i++){ + _tx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make( + boost::bind(&usrp1_impl::tx_dsp_get, this, _1, _2, i), + boost::bind(&usrp1_impl::tx_dsp_set, this, _1, _2, i) + ); + tx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() / 16, i); + } } /*********************************************************************** * TX DUC Get **********************************************************************/ -void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val){ +void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){ named_prop_t key = named_prop_t::extract(key_); switch(key.as<dsp_prop_t>()) { case DSP_PROP_NAME: - val = str(boost::format("usrp1 duc %uX %s") - % this->get_num_ducs() + val = str(boost::format("usrp1 duc%d %s") + % which_dsp % (this->has_tx_halfband()? "+ hb" : "") ); return; @@ -160,16 +160,7 @@ void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val){ return; case DSP_PROP_FREQ_SHIFT: - val = _tx_dsp_freqs[key.name]; - return; - - case DSP_PROP_FREQ_SHIFT_NAMES:{ - prop_names_t names; - for(size_t i = 0; i < this->get_num_ducs(); i++){ - names.push_back(boost::lexical_cast<std::string>(i)); - } - val = names; - } + val = _tx_dsp_freqs[which_dsp]; return; case DSP_PROP_CODEC_RATE: @@ -188,7 +179,7 @@ void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * TX DUC Set **********************************************************************/ -void usrp1_impl::tx_dsp_set(const wax::obj &key_, const wax::obj &val){ +void usrp1_impl::tx_dsp_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){ named_prop_t key = named_prop_t::extract(key_); switch(key.as<dsp_prop_t>()) { @@ -197,15 +188,17 @@ void usrp1_impl::tx_dsp_set(const wax::obj &key_, const wax::obj &val){ double new_freq = val.as<double>(); //map the freq shift key to a subdev spec to a particular codec chip - std::string db_name = _tx_subdev_spec.at(boost::lexical_cast<size_t>(key.name)).db_name; + std::string db_name = _tx_subdev_spec.at(which_dsp).db_name; if (db_name == "A") _codec_ctrls[DBOARD_SLOT_A]->set_duc_freq(new_freq); if (db_name == "B") _codec_ctrls[DBOARD_SLOT_B]->set_duc_freq(new_freq); - _tx_dsp_freqs[key.name] = new_freq; + _tx_dsp_freqs[which_dsp] = new_freq; return; } - case DSP_PROP_HOST_RATE: { + case DSP_PROP_HOST_RATE: + if (which_dsp != 0) return; //only for dsp[0] as this is vectorized + { size_t rate = size_t(_clock_ctrl->get_master_clock_freq() * 2 / val.as<double>()); if ((rate & 0x01) || (rate < 8) || (rate > 512)) { diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index 8beeccf8f..b3268298e 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -18,6 +18,7 @@ #include "../../transport/vrt_packet_handler.hpp" #include "usrp_commands.h" #include "usrp1_impl.hpp" +#include <uhd/utils/safe_call.hpp> #include <uhd/utils/thread_priority.hpp> #include <uhd/transport/bounded_buffer.hpp> #include <boost/bind.hpp> @@ -114,7 +115,7 @@ struct usrp1_impl::io_impl{ } ~io_impl(void){ - flush_send_buff(); + UHD_SAFE_CALL(flush_send_buff();) } zero_copy_if::sptr data_transport; diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp index 6d5bf466d..4e2fad6e5 100644 --- a/host/lib/usrp/usrp1/mboard_impl.cpp +++ b/host/lib/usrp/usrp1/mboard_impl.cpp @@ -25,7 +25,7 @@ #include <uhd/usrp/dboard_props.hpp> #include <uhd/usrp/subdev_props.hpp> #include <uhd/utils/warning.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp> #include <uhd/utils/images.hpp> #include <boost/assign/list_of.hpp> #include <boost/foreach.hpp> @@ -161,7 +161,7 @@ static boost::uint32_t calc_tx_mux( //sanity check, only 1 channel per slot slot_to_chan_count[pair.db_name]++; if (slot_to_chan_count[pair.db_name] > 1){ - throw std::runtime_error(str(boost::format( + throw uhd::value_error(str(boost::format( "dboard slot %s assigned to multiple channels in subdev spec %s" ) % pair.db_name % subdev_spec.to_string())); } @@ -280,21 +280,19 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val) return; case MBOARD_PROP_RX_DSP: - UHD_ASSERT_THROW(key.name == ""); - val = _rx_dsp_proxy->get_link(); + val = _rx_dsp_proxies.get(key.name)->get_link(); return; case MBOARD_PROP_RX_DSP_NAMES: - val = prop_names_t(1, ""); + val = _rx_dsp_proxies.keys(); return; case MBOARD_PROP_TX_DSP: - UHD_ASSERT_THROW(key.name == ""); - val = _tx_dsp_proxy->get_link(); + val = _tx_dsp_proxies.get(key.name)->get_link(); return; case MBOARD_PROP_TX_DSP_NAMES: - val = prop_names_t(1, ""); + val = _tx_dsp_proxies.keys(); return; case MBOARD_PROP_CLOCK_CONFIG: @@ -342,14 +340,10 @@ void usrp1_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_STREAM_CMD: - _soft_time_ctrl->issue_stream_cmd(val.as<stream_cmd_t>()); - return; - case MBOARD_PROP_RX_SUBDEV_SPEC: _rx_subdev_spec = val.as<subdev_spec_t>(); if (_rx_subdev_spec.size() > this->get_num_ddcs()){ - throw std::runtime_error(str(boost::format( + throw uhd::value_error(str(boost::format( "USRP1 suports up to %u RX channels.\n" "However, this RX subdev spec requires %u channels\n" ) % this->get_num_ddcs() % _rx_subdev_spec.size())); @@ -362,7 +356,7 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val) case MBOARD_PROP_TX_SUBDEV_SPEC: _tx_subdev_spec = val.as<subdev_spec_t>(); if (_tx_subdev_spec.size() > this->get_num_ducs()){ - throw std::runtime_error(str(boost::format( + throw uhd::value_error(str(boost::format( "USRP1 suports up to %u TX channels.\n" "However, this TX subdev spec requires %u channels\n" ) % this->get_num_ducs() % _tx_subdev_spec.size())); diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.cpp b/host/lib/usrp/usrp1/usrp1_ctrl.cpp index 09f854813..3fa6cb8b7 100644 --- a/host/lib/usrp/usrp1/usrp1_ctrl.cpp +++ b/host/lib/usrp/usrp1/usrp1_ctrl.cpp @@ -16,7 +16,8 @@ // #include "usrp1_ctrl.hpp" -#include "usrp_commands.h" +#include "usrp_commands.h" +#include <uhd/exception.hpp> #include <uhd/transport/usb_control.hpp> #include <boost/functional/hash.hpp> #include <boost/thread/thread.hpp> @@ -29,13 +30,6 @@ using namespace uhd; -enum firmware_code { - USRP_FPGA_LOAD_SUCCESS, - USRP_FPGA_ALREADY_LOADED, - USRP_FIRMWARE_LOAD_SUCCESS, - USRP_FIRMWARE_ALREADY_LOADED -}; - #define FX2_FIRMWARE_LOAD 0xa0 static const bool load_img_msg = true; @@ -45,15 +39,16 @@ static const bool load_img_msg = true; **********************************************************************/ /*! * Create a file hash - * The hash will be used to identify the loaded firmware and fpga image + * The hash will be used to identify the loaded firmware and fpga image * \param filename file used to generate hash value * \return hash value in a size_t type */ static size_t generate_hash(const char *filename) { std::ifstream file(filename); - if (!file) - std::cerr << "error: cannot open input file " << filename << std::endl; + if (not file){ + throw uhd::io_error(std::string("cannot open input file ") + filename); + } size_t hash = 0; @@ -62,18 +57,19 @@ static size_t generate_hash(const char *filename) boost::hash_combine(hash, ch); } - if (!file.eof()) - std::cerr << "error: file error " << filename << std::endl; + if (not file.eof()){ + throw uhd::io_error(std::string("file error ") + filename); + } - file.close(); - return hash; + file.close(); + return hash; } /*! - * Verify checksum of a Intel HEX record + * Verify checksum of a Intel HEX record * \param record a line from an Intel HEX file - * \return true if record is valid, false otherwise + * \return true if record is valid, false otherwise */ static bool checksum(std::string *record) { @@ -123,7 +119,7 @@ bool parse_record(std::string *record, unsigned int &len, for (i = 0; i < len; i++) { std::istringstream(record->substr(9 + 2 * i, 2)) >> std::hex >> val; data[i] = (unsigned char) val; - } + } return true; } @@ -139,20 +135,15 @@ public: _ctrl_transport = ctrl_transport; } - int usrp_load_firmware(std::string filestring, bool force) + void usrp_load_firmware(std::string filestring, bool force) { const char *filename = filestring.c_str(); size_t hash = generate_hash(filename); - size_t loaded_hash; - if (usrp_get_firmware_hash(loaded_hash) < 0) { - std::cerr << "firmware hash retrieval failed" << std::endl; - return -1; - } + size_t loaded_hash; usrp_get_firmware_hash(loaded_hash); - if (!force && (hash == loaded_hash)) - return USRP_FIRMWARE_ALREADY_LOADED; + if (not force and (hash == loaded_hash)) return; //FIXME: verify types unsigned int len; @@ -160,13 +151,11 @@ public: unsigned int type; unsigned char data[512]; - int ret; std::ifstream file; file.open(filename, std::ifstream::in); if (!file.good()) { - std::cerr << "cannot open firmware input file" << std::endl; - return -1; + throw uhd::io_error("usrp_load_firmware: cannot open firmware input file"); } unsigned char reset_y = 1; @@ -174,56 +163,41 @@ public: //hit the reset line if (load_img_msg) std::cout << "Loading firmware image: " << filestring << "..." << std::flush; - usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, - &reset_y, 1); - + usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_y, 1); + while (!file.eof()) { std::string record; file >> record; - - //check for valid record - if (!checksum(&record) || - !parse_record(&record, len, addr, type, data)) { - std::cerr << "error: bad record" << std::endl; - file.close(); - return -1; + + //check for valid record + if (not checksum(&record) or not parse_record(&record, len, addr, type, data)) { + throw uhd::io_error("usrp_load_firmware: bad record checksum"); } //type 0x00 is data if (type == 0x00) { - ret = usrp_control_write(FX2_FIRMWARE_LOAD, addr, 0, - data, len); - if (ret < 0) { - std::cerr << "error: usrp_control_write failed: "; - std::cerr << ret << std::endl; - file.close(); - return -1; - } - } - //type 0x01 is end + int ret = usrp_control_write(FX2_FIRMWARE_LOAD, addr, 0, data, len); + if (ret < 0) throw uhd::io_error("usrp_load_firmware: usrp_control_write failed"); + } + //type 0x01 is end else if (type == 0x01) { usrp_set_firmware_hash(hash); //set hash before reset - usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, - &reset_n, 1); + usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_n, 1); file.close(); //wait for things to settle boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); if (load_img_msg) std::cout << " done" << std::endl; - return USRP_FIRMWARE_LOAD_SUCCESS; + return; } //type anything else is unhandled else { - std::cerr << "error: unsupported record" << std::endl; - file.close(); - return -1; + throw uhd::io_error("usrp_load_firmware: unsupported record"); } } - //file did not end - std::cerr << "error: bad record" << std::endl; - file.close(); - return -1; + //file did not end + throw uhd::io_error("usrp_load_firmware: bad record"); } void usrp_init(void){ @@ -241,64 +215,48 @@ public: usrp_tx_enable(true); } - int usrp_load_fpga(std::string filestring) + void usrp_load_fpga(std::string filestring) { const char *filename = filestring.c_str(); size_t hash = generate_hash(filename); - size_t loaded_hash; - if (usrp_get_fpga_hash(loaded_hash) < 0) { - std::cerr << "fpga hash retrieval failed" << std::endl; - return -1; - } + size_t loaded_hash; usrp_get_fpga_hash(loaded_hash); - if (hash == loaded_hash) - return USRP_FPGA_ALREADY_LOADED; + if (hash == loaded_hash) return; const int ep0_size = 64; unsigned char buf[ep0_size]; - int ret; if (load_img_msg) std::cout << "Loading FPGA image: " << filestring << "..." << std::flush; std::ifstream file; file.open(filename, std::ios::in | std::ios::binary); if (not file.good()) { - std::cerr << "cannot open fpga input file" << std::endl; - file.close(); - return -1; + throw uhd::io_error("usrp_load_fpga: cannot open fpga input file"); } if (usrp_control_write_cmd(VRQ_FPGA_LOAD, 0, FL_BEGIN) < 0) { - std::cerr << "fpga load error" << std::endl; - file.close(); - return -1; + throw uhd::io_error("usrp_load_fpga: fpga load error"); } while (not file.eof()) { file.read((char *)buf, sizeof(buf)); size_t n = file.gcount(); - ret = usrp_control_write(VRQ_FPGA_LOAD, 0, FL_XFER, - buf, n); + int ret = usrp_control_write(VRQ_FPGA_LOAD, 0, FL_XFER, buf, n); if (ret < 0 or size_t(ret) != n) { - std::cerr << "fpga load error " << ret << std::endl; - file.close(); - return -1; + throw uhd::io_error("usrp_load_fpga: fpga load error"); } } - + if (usrp_control_write_cmd(VRQ_FPGA_LOAD, 0, FL_END) < 0) { - std::cerr << "fpga load error" << std::endl; - file.close(); - return -1; + throw uhd::io_error("usrp_load_fpga: fpga load error"); } usrp_set_fpga_hash(hash); file.close(); if (load_img_msg) std::cout << " done" << std::endl; - return 0; } - int usrp_load_eeprom(std::string filestring) + void usrp_load_eeprom(std::string filestring) { const char *filename = filestring.c_str(); const boost::uint16_t i2c_addr = 0x50; @@ -309,100 +267,92 @@ public: unsigned char data[256]; unsigned char sendbuf[17]; - int ret; std::ifstream file; file.open(filename, std::ifstream::in); - if (!file.good()) { - std::cerr << "cannot open EEPROM input file" << std::endl; - return -1; + if (not file.good()) { + throw uhd::io_error("usrp_load_eeprom: cannot open EEPROM input file"); } file.read((char *)data, 256); len = file.gcount(); if(len == 256) { - std::cerr << "error: image size too large" << std::endl; - file.close(); - return -1; + throw uhd::io_error("usrp_load_eeprom: image size too large"); } const int pagesize = 16; addr = 0; while(len > 0) { - sendbuf[0] = addr; - memcpy(sendbuf+1, &data[addr], len > pagesize ? pagesize : len); - ret = usrp_i2c_write(i2c_addr, sendbuf, (len > pagesize ? pagesize : len)+1); - if (ret < 0) { - std::cerr << "error: usrp_i2c_write failed: "; - std::cerr << ret << std::endl; - file.close(); - return -1; - } - addr += pagesize; - len -= pagesize; - boost::this_thread::sleep(boost::posix_time::milliseconds(100)); + sendbuf[0] = addr; + memcpy(sendbuf+1, &data[addr], len > pagesize ? pagesize : len); + int ret = usrp_i2c_write(i2c_addr, sendbuf, (len > pagesize ? pagesize : len)+1); + if (ret < 0) { + throw uhd::io_error("usrp_load_eeprom: usrp_i2c_write failed"); + } + addr += pagesize; + len -= pagesize; + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); } file.close(); - return 0; } - int usrp_set_led(int led_num, bool on) + void usrp_set_led(int led_num, bool on) { - return usrp_control_write_cmd(VRQ_SET_LED, on, led_num); + UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_SET_LED, on, led_num) >= 0); } - int usrp_get_firmware_hash(size_t &hash) + void usrp_get_firmware_hash(size_t &hash) { - return usrp_control_read(0xa0, USRP_HASH_SLOT_0_ADDR, 0, - (unsigned char*) &hash, sizeof(size_t)); + UHD_ASSERT_THROW(usrp_control_read(0xa0, USRP_HASH_SLOT_0_ADDR, 0, + (unsigned char*) &hash, sizeof(size_t)) >= 0); } - int usrp_set_firmware_hash(size_t hash) + void usrp_set_firmware_hash(size_t hash) { - return usrp_control_write(0xa0, USRP_HASH_SLOT_0_ADDR, 0, - (unsigned char*) &hash, sizeof(size_t)); + UHD_ASSERT_THROW(usrp_control_write(0xa0, USRP_HASH_SLOT_0_ADDR, 0, + (unsigned char*) &hash, sizeof(size_t)) >= 0); } - int usrp_get_fpga_hash(size_t &hash) + void usrp_get_fpga_hash(size_t &hash) { - return usrp_control_read(0xa0, USRP_HASH_SLOT_1_ADDR, 0, - (unsigned char*) &hash, sizeof(size_t)); + UHD_ASSERT_THROW(usrp_control_read(0xa0, USRP_HASH_SLOT_1_ADDR, 0, + (unsigned char*) &hash, sizeof(size_t)) >= 0); } - int usrp_set_fpga_hash(size_t hash) + void usrp_set_fpga_hash(size_t hash) { - return usrp_control_write(0xa0, USRP_HASH_SLOT_1_ADDR, 0, - (unsigned char*) &hash, sizeof(size_t)); + UHD_ASSERT_THROW(usrp_control_write(0xa0, USRP_HASH_SLOT_1_ADDR, 0, + (unsigned char*) &hash, sizeof(size_t)) >= 0); } - int usrp_tx_enable(bool on) + void usrp_tx_enable(bool on) { - return usrp_control_write_cmd(VRQ_FPGA_SET_TX_ENABLE, on, 0); + UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_TX_ENABLE, on, 0) >= 0); } - int usrp_rx_enable(bool on) + void usrp_rx_enable(bool on) { - return usrp_control_write_cmd(VRQ_FPGA_SET_RX_ENABLE, on, 0); + UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_RX_ENABLE, on, 0) >= 0); } - int usrp_tx_reset(bool on) + void usrp_tx_reset(bool on) { - return usrp_control_write_cmd(VRQ_FPGA_SET_TX_RESET, on, 0); + UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_TX_RESET, on, 0) >= 0); } - int usrp_rx_reset(bool on) + void usrp_rx_reset(bool on) { - return usrp_control_write_cmd(VRQ_FPGA_SET_RX_RESET, on, 0); + UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_RX_RESET, on, 0) >= 0); } @@ -417,7 +367,7 @@ public: value, // wValue index, // wIndex buff, // data - length); // wLength + length); // wLength } diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.hpp b/host/lib/usrp/usrp1/usrp1_ctrl.hpp index 8ccfacab7..ee68f8401 100644 --- a/host/lib/usrp/usrp1/usrp1_ctrl.hpp +++ b/host/lib/usrp/usrp1/usrp1_ctrl.hpp @@ -40,60 +40,21 @@ public: * Load firmware in Intel HEX Format onto device * \param filename name of firmware file * \param force reload firmware if already loaded - * \return 0 on success, error code otherwise */ - virtual int usrp_load_firmware(std::string filename, + virtual void usrp_load_firmware(std::string filename, bool force = false) = 0; /*! * Load fpga file onto usrp * \param filename name of fpga image - * \return 0 on success, error code otherwise */ - virtual int usrp_load_fpga(std::string filename) = 0; + virtual void usrp_load_fpga(std::string filename) = 0; /*! * Load USB descriptor file in Intel HEX format into EEPROM - * \param filename name of EEPROM image - * \return 0 on success, error code otherwise + * \param filename name of EEPROM image */ - virtual int usrp_load_eeprom(std::string filestring) = 0; - - /*! - * Set led usrp - * \param led_num which LED to control (0 or 1) - * \param on turn LED on or off - * \return 0 on success, error code otherwise - */ - virtual int usrp_set_led(int led_num, bool on) = 0; - - /*! - * Get firmware hash - * \param hash a size_t hash value - * \return 0 on success, error code otherwise - */ - virtual int usrp_get_firmware_hash(size_t &hash) = 0; - - /*! - * Set firmware hash - * \param hash a size_t hash value - * \return 0 on success, error code otherwise - */ - virtual int usrp_set_firmware_hash(size_t hash) = 0; - - /*! - * Get fpga hash - * \param hash a size_t hash value - * \return 0 on success, error code otherwise - */ - virtual int usrp_get_fpga_hash(size_t &hash) = 0; - - /*! - * Set fpga hash - * \param hash a size_t hash value - * \return 0 on success, error code otherwise - */ - virtual int usrp_set_fpga_hash(size_t hash) = 0; + virtual void usrp_load_eeprom(std::string filestring) = 0; /*! * Submit an IN transfer diff --git a/host/lib/usrp/usrp1/usrp1_iface.cpp b/host/lib/usrp/usrp1/usrp1_iface.cpp index 63fcd5777..0c37610ce 100644 --- a/host/lib/usrp/usrp1/usrp1_iface.cpp +++ b/host/lib/usrp/usrp1/usrp1_iface.cpp @@ -17,7 +17,7 @@ #include "usrp1_iface.hpp" #include "usrp_commands.h" -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp> #include <uhd/utils/byteswap.hpp> #include <boost/format.hpp> #include <stdexcept> @@ -70,8 +70,7 @@ public: (unsigned char*) &swapped, sizeof(boost::uint32_t)); - if (ret < 0) - std::cerr << "USRP: failed memory write: " << ret << std::endl; + if (ret < 0) throw uhd::io_error("USRP1: failed control write"); } boost::uint32_t peek32(boost::uint32_t addr) @@ -88,11 +87,27 @@ public: (unsigned char*) &value_out, sizeof(boost::uint32_t)); - if (ret < 0) - std::cerr << "USRP: failed memory read: " << ret << std::endl; + if (ret < 0) throw uhd::io_error("USRP1: failed control read"); return uhd::ntohx(value_out); } + + void poke16(boost::uint32_t, boost::uint16_t) { + throw uhd::not_implemented_error("Unhandled command poke16()"); + } + + boost::uint16_t peek16(boost::uint32_t) { + throw uhd::not_implemented_error("Unhandled command peek16()"); + return 0; + } + + void write_uart(boost::uint8_t, const std::string &) { + throw uhd::not_implemented_error("Unhandled command write_uart()"); + } + + std::string read_uart(boost::uint8_t) { + throw uhd::not_implemented_error("Unhandled command read_uart()"); + } /******************************************************************* * I2C @@ -176,10 +191,7 @@ public: buff, (w_len_h << 8) | (w_len_l << 0)); - if (ret < 0) { - std::cout << "USRP: failed SPI readback transaction: " - << std::dec << ret << std::endl; - } + if (ret < 0) throw uhd::io_error("USRP1: failed SPI readback transaction"); boost::uint32_t val = (((boost::uint32_t)buff[0]) << 0) | (((boost::uint32_t)buff[1]) << 8) | @@ -197,10 +209,7 @@ public: (w_index_h << 8) | (w_index_l << 0), buff, num_bytes); - if (ret < 0) { - std::cout << "USRP: failed SPI transaction: " - << std::dec << ret << std::endl; - } + if (ret < 0) throw uhd::io_error("USRP1: failed SPI transaction"); return 0; } @@ -234,8 +243,7 @@ public: length); } - if (ret < 0) - std::cerr << "USRP: failed firmware command: " << ret << std::endl; + if (ret < 0) throw uhd::io_error("USRP1: failed firmware command"); } private: diff --git a/host/lib/usrp/usrp1/usrp1_iface.hpp b/host/lib/usrp/usrp1/usrp1_iface.hpp index 34a2330b5..fdb7464ce 100644 --- a/host/lib/usrp/usrp1/usrp1_iface.hpp +++ b/host/lib/usrp/usrp1/usrp1_iface.hpp @@ -18,8 +18,7 @@ #ifndef INCLUDED_USRP1_IFACE_HPP #define INCLUDED_USRP1_IFACE_HPP -#include <uhd/usrp/mboard_eeprom.hpp> -#include <uhd/types/serial.hpp> +#include <uhd/usrp/mboard_iface.hpp> #include <boost/shared_ptr.hpp> #include <boost/utility.hpp> #include "usrp1_ctrl.hpp" @@ -29,10 +28,13 @@ * Provides a set of functions to implementation layer. * Including spi, peek, poke, control... */ -class usrp1_iface : boost::noncopyable, public uhd::i2c_iface{ +class usrp1_iface : public uhd::usrp::mboard_iface, boost::noncopyable{ public: typedef boost::shared_ptr<usrp1_iface> sptr; + //motherboard eeprom map structure + uhd::usrp::mboard_eeprom_t mb_eeprom; + /*! * Make a new usrp1 interface with the control transport. * \param ctrl_transport the usrp controller object @@ -41,35 +43,6 @@ public: static sptr make(usrp_ctrl::sptr ctrl_transport); /*! - * Write a register (32 bits) - * \param addr the address - * \param data the 32bit data - */ - virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; - - /*! - * Read a register (32 bits) - * \param addr the address - * \return the 32bit data - */ - virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; - - /*! - * Perform an spi transaction. - * \param which_slave the slave device number - * \param config spi config args - * \param data the bits to write - * \param num_bits how many bits in data - * \param readback true to readback a value - * \return spi data if readback set - */ - virtual boost::uint32_t transact_spi(int which_slave, - const uhd::spi_config_t &config, - boost::uint32_t data, - size_t num_bits, - bool readback) = 0; - - /*! * Perform a general USB firmware OUT operation * \param request * \param value @@ -82,8 +55,6 @@ public: boost::uint16_t index, unsigned char* buff, boost::uint16_t length) = 0; - - uhd::usrp::mboard_eeprom_t mb_eeprom; }; #endif /* INCLUDED_USRP1_IFACE_HPP */ diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index 918032037..7005c59f2 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -19,11 +19,12 @@ #include "usrp1_ctrl.hpp" #include "fpga_regs_standard.h" #include "usrp_spi_defs.h" +#include <uhd/utils/safe_call.hpp> #include <uhd/transport/usb_control.hpp> #include <uhd/usrp/device_props.hpp> #include <uhd/usrp/mboard_props.hpp> #include <uhd/utils/warning.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp> #include <uhd/utils/static.hpp> #include <uhd/utils/images.hpp> #include <boost/format.hpp> @@ -199,7 +200,16 @@ usrp1_impl::usrp1_impl(uhd::transport::usb_zero_copy::sptr data_transport, } usrp1_impl::~usrp1_impl(void){ - /* NOP */ + //Safely destruct all RAII objects in a device. + //This prevents the mboard deconstructor from throwing, + //which allows the device to be safely deconstructed. + BOOST_FOREACH(dboard_slot_t slot, _dboard_slots){ + UHD_SAFE_CALL(_dboard_managers[slot].reset();) + UHD_SAFE_CALL(_dboard_ifaces[slot].reset();) + UHD_SAFE_CALL(_codec_ctrls[slot].reset();) + } + UHD_SAFE_CALL(_clock_ctrl.reset();) + UHD_SAFE_CALL(_io_impl.reset();) } bool usrp1_impl::recv_async_msg(uhd::async_metadata_t &, double timeout){ diff --git a/host/lib/usrp/usrp1/usrp1_impl.hpp b/host/lib/usrp/usrp1/usrp1_impl.hpp index 1d9f6709f..9755c466d 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.hpp +++ b/host/lib/usrp/usrp1/usrp1_impl.hpp @@ -182,19 +182,19 @@ private: //rx dsp functions and settings void rx_dsp_init(void); - void rx_dsp_get(const wax::obj &, wax::obj &); - void rx_dsp_set(const wax::obj &, const wax::obj &); - uhd::dict<std::string, double> _rx_dsp_freqs; + void rx_dsp_get(const wax::obj &, wax::obj &, size_t); + void rx_dsp_set(const wax::obj &, const wax::obj &, size_t); + uhd::dict<size_t, double> _rx_dsp_freqs; size_t _rx_dsp_decim; - wax_obj_proxy::sptr _rx_dsp_proxy; + uhd::dict<std::string, wax_obj_proxy::sptr> _rx_dsp_proxies; //tx dsp functions and settings void tx_dsp_init(void); - void tx_dsp_get(const wax::obj &, wax::obj &); - void tx_dsp_set(const wax::obj &, const wax::obj &); - uhd::dict<std::string, double> _tx_dsp_freqs; + void tx_dsp_get(const wax::obj &, wax::obj &, size_t); + void tx_dsp_set(const wax::obj &, const wax::obj &, size_t); + uhd::dict<size_t, double> _tx_dsp_freqs; size_t _tx_dsp_interp; - wax_obj_proxy::sptr _tx_dsp_proxy; + uhd::dict<std::string, wax_obj_proxy::sptr> _tx_dsp_proxies; //transports uhd::transport::usb_zero_copy::sptr _data_transport; |