diff options
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | host/lib/types.cpp | 29 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_basic_and_lf.cpp | 12 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_rfx.cpp | 14 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_xcvr2450.cpp | 15 | ||||
| -rw-r--r-- | host/lib/usrp/dboard_eeprom.cpp | 102 | ||||
| -rw-r--r-- | host/lib/usrp/dboard_manager.cpp | 5 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dboard_iface.cpp | 44 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dboard_impl.cpp | 52 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dsp_impl.cpp | 10 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/fw_common.h | 17 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.cpp | 44 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.hpp | 11 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 3 | ||||
| -rw-r--r-- | host/lib/utils.cpp | 44 | 
17 files changed, 306 insertions, 109 deletions
| diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 5495620ec..5252eda8f 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -50,11 +50,13 @@ SET(libuhd_sources      gain_handler.cpp      load_modules.cpp      types.cpp +    utils.cpp      wax.cpp      transport/convert_types.cpp      transport/if_addrs.cpp      transport/udp_simple.cpp      usrp/dboard_base.cpp +    usrp/dboard_eeprom.cpp      usrp/simple_usrp.cpp      usrp/dboard_manager.cpp      usrp/tune_helper.cpp diff --git a/host/lib/types.cpp b/host/lib/types.cpp index 91887840c..08e41b62f 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -31,6 +31,8 @@  #include <boost/foreach.hpp>  #include <boost/format.hpp>  #include <boost/cstdint.hpp> +#include <boost/assign/list_of.hpp> +#include <boost/thread.hpp>  #include <stdexcept>  #include <complex> @@ -250,3 +252,30 @@ spi_config_t::spi_config_t(edge_t edge){      mosi_edge = edge;      miso_edge = edge;  } + +void i2c_iface::write_eeprom( +    boost::uint8_t addr, +    boost::uint8_t offset, +    const byte_vector_t &bytes +){ +    for (size_t i = 0; i < bytes.size(); i++){ +        //write a byte at a time, its easy that way +        byte_vector_t cmd = boost::assign::list_of(offset+i)(bytes[i]); +        this->write_i2c(addr, cmd); +        boost::this_thread::sleep(boost::posix_time::milliseconds(10)); //worst case write +    } +} + +byte_vector_t i2c_iface::read_eeprom( +    boost::uint8_t addr, +    boost::uint8_t offset, +    size_t num_bytes +){ +    byte_vector_t bytes; +    for (size_t i = 0; i < num_bytes; i++){ +        //do a zero byte write to start read cycle +        this->write_i2c(addr, byte_vector_t(1, offset+i)); +        bytes.push_back(this->read_i2c(addr, 1).at(0)); +    } +    return bytes; +} diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index aad2398d8..c7b841efb 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -153,6 +153,8 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){      case SUBDEV_PROP_USE_LO_OFFSET:          val = false;          return; + +    default: UHD_THROW_PROP_WRITE_ONLY();      }  } @@ -174,9 +176,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){      case SUBDEV_PROP_FREQ:          return; // it wont do you much good, but you can set it -    default: throw std::runtime_error(str(boost::format( -            "Error: trying to set read-only property on %s subdev" -        ) % dboard_id::to_string(get_rx_id()))); +    default: UHD_THROW_PROP_READ_ONLY();      }  } @@ -248,6 +248,8 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){      case SUBDEV_PROP_USE_LO_OFFSET:          val = false;          return; + +    default: UHD_THROW_PROP_WRITE_ONLY();      }  } @@ -269,8 +271,6 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){      case SUBDEV_PROP_FREQ:          return; // it wont do you much good, but you can set it -    default: throw std::runtime_error(str(boost::format( -            "Error: trying to set read-only property on %s subdev" -        ) % dboard_id::to_string(get_tx_id()))); +    default: UHD_THROW_PROP_READ_ONLY();      }  } diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 76b2c6d7a..49ec9412c 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -396,6 +396,8 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){      case SUBDEV_PROP_USE_LO_OFFSET:          val = false;          return; + +    default: UHD_THROW_PROP_WRITE_ONLY();      }  } @@ -419,10 +421,7 @@ void rfx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){          set_rx_ant(val.as<std::string>());          return; -    default: -        throw std::runtime_error(str(boost::format( -            "Error: trying to set read-only property on %s subdev" -        ) % dboard_id::to_string(get_rx_id()))); +    default: UHD_THROW_PROP_READ_ONLY();      }  } @@ -486,6 +485,8 @@ void rfx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){      case SUBDEV_PROP_USE_LO_OFFSET:          val = true;          return; + +    default: UHD_THROW_PROP_WRITE_ONLY();      }  } @@ -509,9 +510,6 @@ void rfx_xcvr::tx_set(const wax::obj &key_, const wax::obj &val){          ASSERT_THROW(val.as<std::string>() == "TX/RX");          return; -    default: -        throw std::runtime_error(str(boost::format( -            "Error: trying to set read-only property on %s subdev" -        ) % dboard_id::to_string(get_tx_id()))); +    default: UHD_THROW_PROP_READ_ONLY();      }  } diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index 2c2843d3a..2052511f8 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -352,7 +352,8 @@ static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(float &gain){          gain = 5;          return max2829_regs_t::TX_BASEBAND_GAIN_5DB;      } -    ASSERT_THROW(false); +    BOOST_THROW_EXCEPTION(std::runtime_error("should not get here")); +    return max2829_regs_t::TX_BASEBAND_GAIN_0DB;  }  /*! @@ -474,6 +475,8 @@ void xcvr2450::rx_get(const wax::obj &key_, wax::obj &val){      case SUBDEV_PROP_USE_LO_OFFSET:          val = false;          return; + +    default: UHD_THROW_PROP_WRITE_ONLY();      }  } @@ -496,9 +499,7 @@ void xcvr2450::rx_set(const wax::obj &key_, const wax::obj &val){          this->set_rx_ant(val.as<std::string>());          return; -    default: throw std::runtime_error(str(boost::format( -        "Error: trying to set read-only property on %s subdev" -    ) % dboard_id::to_string(get_rx_id()))); +    default: UHD_THROW_PROP_READ_ONLY();      }  } @@ -564,6 +565,8 @@ void xcvr2450::tx_get(const wax::obj &key_, wax::obj &val){      case SUBDEV_PROP_USE_LO_OFFSET:          val = false;          return; + +    default: UHD_THROW_PROP_WRITE_ONLY();      }  } @@ -586,8 +589,6 @@ void xcvr2450::tx_set(const wax::obj &key_, const wax::obj &val){          this->set_tx_ant(val.as<std::string>());          return; -    default: throw std::runtime_error(str(boost::format( -        "Error: trying to set read-only property on %s subdev" -    ) % dboard_id::to_string(get_tx_id()))); +    default: UHD_THROW_PROP_READ_ONLY();      }  } diff --git a/host/lib/usrp/dboard_eeprom.cpp b/host/lib/usrp/dboard_eeprom.cpp new file mode 100644 index 000000000..00236c337 --- /dev/null +++ b/host/lib/usrp/dboard_eeprom.cpp @@ -0,0 +1,102 @@ +// +// 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 <uhd/usrp/dboard_eeprom.hpp> +#include <uhd/utils/assert.hpp> +#include <boost/format.hpp> +#include <iostream> + +using namespace uhd; +using namespace uhd::usrp; + +static const bool _dboard_eeprom_debug = false; + +//////////////////////////////////////////////////////////////////////// +// format of daughterboard EEPROM +// 00: 0xDB code for ``I'm a daughterboard'' +// 01:   .. Daughterboard ID (LSB) +// 02:   .. Daughterboard ID (MSB) +// 03:   .. io bits  7-0 direction (bit set if it's an output from m'board) +// 04:   .. io bits 15-8 direction (bit set if it's an output from m'board) +// 05:   .. ADC0 DC offset correction (LSB) +// 06:   .. ADC0 DC offset correction (MSB) +// 07:   .. ADC1 DC offset correction (LSB) +// 08:   .. ADC1 DC offset correction (MSB) +//  ... +// 1f:   .. negative of the sum of bytes [0x00, 0x1e] + +#define DB_EEPROM_MAGIC         0x00 +#define DB_EEPROM_MAGIC_VALUE   0xDB +#define DB_EEPROM_ID_LSB        0x01 +#define DB_EEPROM_ID_MSB        0x02 +#define DB_EEPROM_OE_LSB        0x03 +#define DB_EEPROM_OE_MSB        0x04 +#define DB_EEPROM_OFFSET_0_LSB  0x05 // offset correction for ADC or DAC 0 +#define DB_EEPROM_OFFSET_0_MSB  0x06 +#define DB_EEPROM_OFFSET_1_LSB  0x07 // offset correction for ADC or DAC 1 +#define DB_EEPROM_OFFSET_1_MSB  0x08 +#define DB_EEPROM_CHKSUM        0x1f + +#define DB_EEPROM_CLEN          0x20 // length of common portion of eeprom + +#define DB_EEPROM_CUSTOM_BASE   DB_EEPROM_CLEN // first avail offset for +                                               //   daughterboard specific use +//////////////////////////////////////////////////////////////////////// + +//negative sum of bytes excluding checksum byte +static boost::uint8_t checksum(const byte_vector_t &bytes){ +    int sum = 0; +    for (size_t i = 0; i < std::min(bytes.size(), size_t(DB_EEPROM_CHKSUM)); i++){ +        sum -= int(bytes.at(i)); +    } +    if (_dboard_eeprom_debug) +        std::cout << boost::format("sum: 0x%02x") % sum << std::endl; +    return boost::uint8_t(sum); +} + +dboard_eeprom_t::dboard_eeprom_t(const byte_vector_t &bytes){ +    if (_dboard_eeprom_debug){ +        for (size_t i = 0; i < bytes.size(); i++){ +            std::cout << boost::format( +                "eeprom byte[0x%02x] = 0x%02x") % i % int(bytes.at(i) +            ) << std::endl; +        } +    } +    try{ +        ASSERT_THROW(bytes.size() >= DB_EEPROM_CLEN); +        ASSERT_THROW(bytes[DB_EEPROM_MAGIC] == DB_EEPROM_MAGIC_VALUE); +        ASSERT_THROW(bytes[DB_EEPROM_CHKSUM] == checksum(bytes)); +        id = \ +            (boost::uint16_t(bytes[DB_EEPROM_ID_LSB]) << 0) | +            (boost::uint16_t(bytes[DB_EEPROM_ID_MSB]) << 8) ; +    }catch(const uhd::assert_error &e){ +        id = dboard_id::NONE; +    } +} + +byte_vector_t dboard_eeprom_t::get_eeprom_bytes(void){ +    byte_vector_t bytes(DB_EEPROM_CLEN, 0); //defaults to all zeros +    bytes[DB_EEPROM_MAGIC] = DB_EEPROM_MAGIC_VALUE; +    bytes[DB_EEPROM_ID_LSB] = boost::uint8_t(id >> 0); +    bytes[DB_EEPROM_ID_MSB] = boost::uint8_t(id >> 8); +    bytes[DB_EEPROM_CHKSUM] = checksum(bytes); +    return bytes; +} + +size_t dboard_eeprom_t::num_bytes(void){ +    return DB_EEPROM_CLEN; +} diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index 06f8c55b6..34b635934 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -177,10 +177,11 @@ static args_t get_dboard_args(      //verify that there is a registered constructor for this id      if (not get_id_to_args_map().has_key(dboard_id)){ -        throw std::runtime_error(str( +        /*throw std::runtime_error(str(              boost::format("Unregistered %s dboard id: %s")              % xx_type % dboard_id::to_string(dboard_id) -        )); +        ));*/ +        return get_dboard_args(dboard_id::NONE, xx_type);      }      //return the dboard args for this id diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index e9acddee6..9503c329b 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -24,7 +24,6 @@  #include <boost/assign/list_of.hpp>  #include <boost/asio.hpp> //htonl and ntohl  #include <boost/math/special_functions/round.hpp> -#include <algorithm>  #include "ad7922_regs.hpp" //aux adc  #include "ad5624_regs.hpp" //aux dac @@ -43,8 +42,8 @@ public:      void set_gpio_ddr(unit_t, boost::uint16_t);      boost::uint16_t read_gpio(unit_t); -    void write_i2c(int, const byte_vector_t &); -    byte_vector_t read_i2c(int, size_t); +    void write_i2c(boost::uint8_t, const byte_vector_t &); +    byte_vector_t read_i2c(boost::uint8_t, size_t);      double get_clock_rate(unit_t);      void set_clock_enabled(unit_t, bool); @@ -213,43 +212,12 @@ boost::uint32_t usrp2_dboard_iface::read_write_spi(  /***********************************************************************   * I2C   **********************************************************************/ -void usrp2_dboard_iface::write_i2c(int i2c_addr, const byte_vector_t &buf){ -    //setup the out data -    usrp2_ctrl_data_t out_data; -    out_data.id = htonl(USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO); -    out_data.data.i2c_args.addr = i2c_addr; -    out_data.data.i2c_args.bytes = buf.size(); - -    //limitation of i2c transaction size -    ASSERT_THROW(buf.size() <= sizeof(out_data.data.i2c_args.data)); - -    //copy in the data -    std::copy(buf.begin(), buf.end(), out_data.data.i2c_args.data); - -    //send and recv -    usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); -    ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE); +void usrp2_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ +    return _iface->write_i2c(addr, bytes);  } -byte_vector_t usrp2_dboard_iface::read_i2c(int i2c_addr, size_t num_bytes){ -    //setup the out data -    usrp2_ctrl_data_t out_data; -    out_data.id = htonl(USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO); -    out_data.data.i2c_args.addr = i2c_addr; -    out_data.data.i2c_args.bytes = num_bytes; - -    //limitation of i2c transaction size -    ASSERT_THROW(num_bytes <= sizeof(out_data.data.i2c_args.data)); - -    //send and recv -    usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); -    ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE); -    ASSERT_THROW(in_data.data.i2c_args.addr = num_bytes); - -    //copy out the data -    byte_vector_t result(num_bytes); -    std::copy(in_data.data.i2c_args.data, in_data.data.i2c_args.data + num_bytes, result.begin()); -    return result; +byte_vector_t usrp2_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){ +    return _iface->read_i2c(addr, num_bytes);  }  /*********************************************************************** diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index ee23dc83a..a68ae240e 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -33,22 +33,16 @@ using namespace uhd::usrp;   * Helper Methods   **********************************************************************/  void usrp2_impl::dboard_init(void){ -    //grab the dboard ids over the control line -    usrp2_ctrl_data_t out_data; -    out_data.id = htonl(USRP2_CTRL_ID_GIVE_ME_YOUR_DBOARD_IDS_BRO); -    usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); -    ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_THESE_ARE_MY_DBOARD_IDS_DUDE); - -    //extract the dboard ids an convert them -    dboard_id_t rx_dboard_id = ntohs(in_data.data.dboard_ids.rx_id); -    dboard_id_t tx_dboard_id = ntohs(in_data.data.dboard_ids.tx_id); +    //read the dboard eeprom to extract the dboard ids +    _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); +    _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes()));      //create a new dboard interface and manager      dboard_iface::sptr _dboard_iface(          make_usrp2_dboard_iface(_iface, _clk_ctrl)      );      _dboard_manager = dboard_manager::make( -        rx_dboard_id, tx_dboard_id, _dboard_iface +        _rx_db_eeprom.id, _tx_db_eeprom.id, _dboard_iface      );      //load dboards @@ -125,19 +119,28 @@ void usrp2_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){          val = _rx_subdevs_in_use;          return; -    //case DBOARD_PROP_CODEC: -    //    throw std::runtime_error("unhandled prop in usrp2 dboard"); +    case DBOARD_PROP_DBOARD_ID: +        val = _rx_db_eeprom.id; +        return; + +    default: UHD_THROW_PROP_WRITE_ONLY();      }  }  void usrp2_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ -    if (key.as<dboard_prop_t>() == DBOARD_PROP_USED_SUBDEVS){ +    switch(key.as<dboard_prop_t>()){ +    case DBOARD_PROP_USED_SUBDEVS:          _rx_subdevs_in_use = val.as<prop_names_t>();          update_rx_mux_config(); //if the val is bad, this will throw          return; -    } -    throw std::runtime_error("Cannot set on usrp2 dboard"); +    case DBOARD_PROP_DBOARD_ID: +        _rx_db_eeprom.id = val.as<dboard_id_t>(); +        _iface->write_eeprom(I2C_ADDR_RX_DB, 0, _rx_db_eeprom.get_eeprom_bytes()); +        return; + +    default: UHD_THROW_PROP_READ_ONLY(); +    }  }  /*********************************************************************** @@ -165,17 +168,26 @@ void usrp2_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){          val = _tx_subdevs_in_use;          return; -    //case DBOARD_PROP_CODEC: -    //    throw std::runtime_error("unhandled prop in usrp2 dboard"); +    case DBOARD_PROP_DBOARD_ID: +        val = _tx_db_eeprom.id; +        return; + +    default: UHD_THROW_PROP_WRITE_ONLY();      }  }  void usrp2_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ -    if (key.as<dboard_prop_t>() == DBOARD_PROP_USED_SUBDEVS){ +    switch(key.as<dboard_prop_t>()){ +    case DBOARD_PROP_USED_SUBDEVS:          _tx_subdevs_in_use = val.as<prop_names_t>();          update_tx_mux_config(); //if the val is bad, this will throw          return; -    } -    throw std::runtime_error("Cannot set on usrp2 dboard"); +    case DBOARD_PROP_DBOARD_ID: +        _tx_db_eeprom.id = val.as<dboard_id_t>(); +        _iface->write_eeprom(I2C_ADDR_TX_DB, 0, _tx_db_eeprom.get_eeprom_bytes()); +        return; + +    default: UHD_THROW_PROP_READ_ONLY(); +    }  } diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 204277ba7..379276f7d 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -117,6 +117,8 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){      case DSP_PROP_HOST_RATE:          val = get_master_clock_freq()/_ddc_decim;          return; + +    default: UHD_THROW_PROP_WRITE_ONLY();      }  } @@ -139,8 +141,7 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){          }          return; -    default: -        throw std::runtime_error("Error: trying to set read-only property on usrp2 ddc0"); +    default: UHD_THROW_PROP_READ_ONLY();      }  } @@ -200,6 +201,8 @@ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){      case DSP_PROP_HOST_RATE:          val = get_master_clock_freq()/_duc_interp;          return; + +    default: UHD_THROW_PROP_WRITE_ONLY();      }  } @@ -222,7 +225,6 @@ void usrp2_impl::duc_set(const wax::obj &key, const wax::obj &val){          }          return; -    default: -        throw std::runtime_error("Error: trying to set read-only property on usrp2 duc0"); +    default: UHD_THROW_PROP_READ_ONLY();      }  } diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 640b37ec6..e80001ff2 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -34,7 +34,7 @@ extern "C" {  //defines the protocol version in this shared header  //increment this value when the protocol is changed -#define USRP2_PROTO_VERSION 1 +#define USRP2_PROTO_VERSION 2  //used to differentiate control packets over data port  #define USRP2_INVALID_VRT_HEADER 0 @@ -61,9 +61,6 @@ typedef enum{      USRP2_CTRL_ID_THIS_IS_MY_MAC_ADDR_DUDE = 'M',      USRP2_CTRL_ID_HERE_IS_A_NEW_MAC_ADDR_BRO = 'n', -    USRP2_CTRL_ID_GIVE_ME_YOUR_DBOARD_IDS_BRO = 'd', -    USRP2_CTRL_ID_THESE_ARE_MY_DBOARD_IDS_DUDE = 'D', -      USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO = 's',      USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE = 'S', @@ -82,9 +79,6 @@ typedef enum{      USRP2_CTRL_ID_PEEK_AT_THIS_REGISTER_FOR_ME_BRO = 'r',      USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE = 'R', -    USRP2_CTRL_ID_WHATS_THE_HARDWARE_REV_NOS_BRO = 'y', -    USRP2_CTRL_ID_TAKE_THE_HARDWARE_REV_NOS_DUDE = 'Y', -      USRP2_CTRL_ID_PEACE_OUT = '~'  } usrp2_ctrl_id_t; @@ -107,10 +101,6 @@ typedef struct{          _SINS_ uint32_t ip_addr;          _SINS_ uint8_t mac_addr[6];          struct { -            _SINS_ uint16_t rx_id; -            _SINS_ uint16_t tx_id; -        } dboard_ids; -        struct {              _SINS_ uint8_t dev;              _SINS_ uint8_t miso_edge;              _SINS_ uint8_t mosi_edge; @@ -137,11 +127,6 @@ typedef struct{              _SINS_ uint32_t data;              _SINS_ uint8_t num_bytes; //1, 2, 4          } poke_args; -        struct { -            _SINS_ uint8_t major; -            _SINS_ uint8_t minor; -            _SINS_ uint8_t _pad[2]; -        } hw_rev;      } data;  } usrp2_ctrl_data_t; diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index f94806c9f..2c185ec53 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -248,9 +248,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){          val = _clock_config;          return; -    default: -        throw std::runtime_error("Error: trying to get write-only property on usrp2 mboard"); - +    default: UHD_THROW_PROP_WRITE_ONLY();      }  } @@ -306,8 +304,6 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){          issue_ddc_stream_cmd(val.as<stream_cmd_t>());          return; -    default: -        throw std::runtime_error("Error: trying to set read-only property on usrp2 mboard"); - +    default: UHD_THROW_PROP_READ_ONLY();      }  } diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 1b0dde1b4..27b6f8907 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -19,9 +19,11 @@  #include <uhd/utils/assert.hpp>  #include <uhd/types/dict.hpp>  #include <boost/thread.hpp> +#include <boost/foreach.hpp>  #include <boost/asio.hpp> //used for htonl and ntohl  #include <boost/assign/list_of.hpp>  #include <stdexcept> +#include <algorithm>  using namespace uhd; @@ -90,6 +92,48 @@ public:      }  /*********************************************************************** + * I2C + **********************************************************************/ +    void write_i2c(boost::uint8_t addr, const byte_vector_t &buf){ +        //setup the out data +        usrp2_ctrl_data_t out_data; +        out_data.id = htonl(USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO); +        out_data.data.i2c_args.addr = addr; +        out_data.data.i2c_args.bytes = buf.size(); + +        //limitation of i2c transaction size +        ASSERT_THROW(buf.size() <= sizeof(out_data.data.i2c_args.data)); + +        //copy in the data +        std::copy(buf.begin(), buf.end(), out_data.data.i2c_args.data); + +        //send and recv +        usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); +        ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE); +    } + +    byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ +        //setup the out data +        usrp2_ctrl_data_t out_data; +        out_data.id = htonl(USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO); +        out_data.data.i2c_args.addr = addr; +        out_data.data.i2c_args.bytes = num_bytes; + +        //limitation of i2c transaction size +        ASSERT_THROW(num_bytes <= sizeof(out_data.data.i2c_args.data)); + +        //send and recv +        usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); +        ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE); +        ASSERT_THROW(in_data.data.i2c_args.addr = num_bytes); + +        //copy out the data +        byte_vector_t result(num_bytes); +        std::copy(in_data.data.i2c_args.data, in_data.data.i2c_args.data + num_bytes, result.begin()); +        return result; +    } + +/***********************************************************************   * Send/Recv over control   **********************************************************************/      usrp2_ctrl_data_t ctrl_send_and_recv(const usrp2_ctrl_data_t &out_data){ diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index 6667c8998..7158c58d0 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -25,12 +25,21 @@  #include <boost/cstdint.hpp>  #include "fw_common.h" +//////////////////////////////////////////////////////////////////////// +// I2C addresses +//////////////////////////////////////////////////////////////////////// +#define I2C_DEV_EEPROM  0x50 // 24LC02[45]:  7-bits 1010xxx +#define	I2C_ADDR_MBOARD (I2C_DEV_EEPROM | 0x0) +#define	I2C_ADDR_TX_DB  (I2C_DEV_EEPROM | 0x4) +#define	I2C_ADDR_RX_DB  (I2C_DEV_EEPROM | 0x5) +//////////////////////////////////////////////////////////////////////// +  /*!   * The usrp2 interface class:   * Provides a set of functions to implementation layer.   * Including spi, peek, poke, control...   */ -class usrp2_iface : boost::noncopyable{ +class usrp2_iface : public uhd::i2c_iface, boost::noncopyable{  public:      typedef boost::shared_ptr<usrp2_iface> sptr; diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 0fa56c339..11ad812e1 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -202,9 +202,10 @@ void usrp2_impl::get(const wax::obj &key_, wax::obj &val){          val = size_t(_max_tx_samples_per_packet);          return; +    default: UHD_THROW_PROP_WRITE_ONLY();      }  }  void usrp2_impl::set(const wax::obj &, const wax::obj &){ -    throw std::runtime_error("Cannot set in usrp2 device"); +    UHD_THROW_PROP_READ_ONLY();  } diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index dbcee367b..1c9387744 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -25,6 +25,7 @@  #include <uhd/types/otw_type.hpp>  #include <uhd/types/stream_cmd.hpp>  #include <uhd/types/clock_config.hpp> +#include <uhd/usrp/dboard_eeprom.hpp>  #include <boost/shared_ptr.hpp>  #include <boost/function.hpp>  #include <uhd/transport/vrt.hpp> @@ -161,12 +162,14 @@ private:      void rx_dboard_set(const wax::obj &, const wax::obj &);      wax_obj_proxy::sptr _rx_dboard_proxy;      uhd::prop_names_t _rx_subdevs_in_use; +    uhd::usrp::dboard_eeprom_t _rx_db_eeprom;      //properties interface for tx dboard      void tx_dboard_get(const wax::obj &, wax::obj &);      void tx_dboard_set(const wax::obj &, const wax::obj &);      wax_obj_proxy::sptr _tx_dboard_proxy;      uhd::prop_names_t _tx_subdevs_in_use; +    uhd::usrp::dboard_eeprom_t _tx_db_eeprom;      void update_rx_mux_config(void);      void update_tx_mux_config(void); diff --git a/host/lib/utils.cpp b/host/lib/utils.cpp new file mode 100644 index 000000000..3a1e5aa3f --- /dev/null +++ b/host/lib/utils.cpp @@ -0,0 +1,44 @@ +// +// 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 <uhd/utils/props.hpp> + +using namespace uhd; + +/*********************************************************************** + * Props + **********************************************************************/ +named_prop_t::named_prop_t( +    const wax::obj &key_, +    const std::string &name_ +){ +    key = key_; +    name = name_; +} + +typedef boost::tuple<wax::obj, std::string> named_prop_tuple; + +named_prop_tuple uhd::extract_named_prop( +    const wax::obj &key, +    const std::string &name +){ +    if (key.type() == typeid(named_prop_t)){ +        named_prop_t np = key.as<named_prop_t>(); +        return named_prop_tuple(np.key, np.name); +    } +    return named_prop_tuple(key, name); +} | 
