diff options
Diffstat (limited to 'host/lib')
-rw-r--r-- | host/lib/usrp/dboard_eeprom.cpp | 64 | ||||
-rw-r--r-- | host/lib/usrp/dboard_manager.cpp | 21 | ||||
-rw-r--r-- | host/lib/usrp/mboard_eeprom.cpp | 12 | ||||
-rw-r--r-- | host/lib/usrp/misc_utils.cpp | 4 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/dboard_impl.cpp | 37 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/dboard_impl.cpp | 26 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e100/dboard_impl.cpp | 26 |
7 files changed, 124 insertions, 66 deletions
diff --git a/host/lib/usrp/dboard_eeprom.cpp b/host/lib/usrp/dboard_eeprom.cpp index fa3631948..c47390bf8 100644 --- a/host/lib/usrp/dboard_eeprom.cpp +++ b/host/lib/usrp/dboard_eeprom.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 @@ -18,6 +18,7 @@ #include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/utils/assert.hpp> #include <boost/format.hpp> +#include <algorithm> #include <iostream> using namespace uhd; @@ -25,6 +26,30 @@ using namespace uhd::usrp; static const bool _dboard_eeprom_debug = false; +/*********************************************************************** + * Utility functions + **********************************************************************/ + +//! create a string from a byte vector, return empty if invalid ascii +static const std::string bytes_to_string(const byte_vector_t &bytes){ + std::string out; + BOOST_FOREACH(boost::uint8_t byte, bytes){ + if (byte < 32 or byte > 127) return out; + out += byte; + } + return out; +} + +//! create a byte vector from a string, null terminate unless max length +static const byte_vector_t string_to_bytes(const std::string &string, size_t max_length){ + byte_vector_t bytes; + for (size_t i = 0; i < std::min(string.size(), max_length); i++){ + bytes.push_back(string[i]); + } + if (bytes.size() < max_length - 1) bytes.push_back('\0'); + return bytes; +} + //////////////////////////////////////////////////////////////////////// // format of daughterboard EEPROM // 00: 0xDB code for ``I'm a daughterboard'' @@ -49,6 +74,8 @@ static const bool _dboard_eeprom_debug = false; #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_SERIAL 0x09 +#define DB_EEPROM_SERIAL_LEN 0x09 //9 ASCII characters #define DB_EEPROM_CHKSUM 0x1f #define DB_EEPROM_CLEN 0x20 // length of common portion of eeprom @@ -68,7 +95,14 @@ static boost::uint8_t checksum(const byte_vector_t &bytes){ return boost::uint8_t(sum); } -dboard_eeprom_t::dboard_eeprom_t(const byte_vector_t &bytes){ +dboard_eeprom_t::dboard_eeprom_t(void){ + id = dboard_id_t::none(); + serial = ""; +} + +void dboard_eeprom_t::load(i2c_iface &iface, boost::uint8_t addr){ + byte_vector_t bytes = iface.read_eeprom(addr, 0, DB_EEPROM_CLEN); + if (_dboard_eeprom_debug){ for (size_t i = 0; i < bytes.size(); i++){ std::cout << boost::format( @@ -76,28 +110,44 @@ dboard_eeprom_t::dboard_eeprom_t(const byte_vector_t &bytes){ ) << std::endl; } } + try{ UHD_ASSERT_THROW(bytes.size() >= DB_EEPROM_CLEN); UHD_ASSERT_THROW(bytes[DB_EEPROM_MAGIC] == DB_EEPROM_MAGIC_VALUE); UHD_ASSERT_THROW(bytes[DB_EEPROM_CHKSUM] == checksum(bytes)); + + //parse the ids id = dboard_id_t::from_uint16(0 | (boost::uint16_t(bytes[DB_EEPROM_ID_LSB]) << 0) | (boost::uint16_t(bytes[DB_EEPROM_ID_MSB]) << 8) ); + + //parse the serial + serial = bytes_to_string( + byte_vector_t(&bytes.at(DB_EEPROM_SERIAL), + &bytes.at(DB_EEPROM_SERIAL+DB_EEPROM_SERIAL_LEN)) + ); + }catch(const uhd::assert_error &){ id = dboard_id_t::none(); + serial = ""; } } -byte_vector_t dboard_eeprom_t::get_eeprom_bytes(void){ +void dboard_eeprom_t::store(i2c_iface &iface, boost::uint8_t addr){ byte_vector_t bytes(DB_EEPROM_CLEN, 0); //defaults to all zeros bytes[DB_EEPROM_MAGIC] = DB_EEPROM_MAGIC_VALUE; + + //load the id bytes bytes[DB_EEPROM_ID_LSB] = boost::uint8_t(id.to_uint16() >> 0); bytes[DB_EEPROM_ID_MSB] = boost::uint8_t(id.to_uint16() >> 8); + + //load the serial bytes + byte_vector_t ser_bytes = string_to_bytes(serial, DB_EEPROM_SERIAL_LEN); + std::copy(ser_bytes.begin(), ser_bytes.end(), &bytes.at(DB_EEPROM_SERIAL)); + + //load the checksum bytes[DB_EEPROM_CHKSUM] = checksum(bytes); - return bytes; -} -size_t dboard_eeprom_t::num_bytes(void){ - return DB_EEPROM_CLEN; + iface.write_eeprom(addr, 0, bytes); } diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index 72bfd89e8..75594e670 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.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 @@ -146,6 +146,7 @@ public: wax::obj get_tx_subdev(const std::string &subdev_name); private: + void init(dboard_id_t, dboard_id_t); //list of rx and tx dboards in this dboard_manager //each dboard here is actually a subdevice proxy //the subdevice proxy is internal to the cpp file @@ -203,9 +204,21 @@ dboard_manager_impl::dboard_manager_impl( dboard_id_t rx_dboard_id, dboard_id_t tx_dboard_id, dboard_iface::sptr iface -){ - _iface = iface; +): + _iface(iface) +{ + try{ + this->init(rx_dboard_id, tx_dboard_id); + } + catch(const std::exception &e){ + uhd::warning::post(e.what()); + this->init(dboard_id_t::none(), dboard_id_t::none()); + } +} +void dboard_manager_impl::init( + dboard_id_t rx_dboard_id, dboard_id_t tx_dboard_id +){ //determine xcvr status bool rx_dboard_is_xcvr = get_xcvr_id_to_id_map().has_key(rx_dboard_id); bool tx_dboard_is_xcvr = get_xcvr_id_to_id_map().has_key(tx_dboard_id); @@ -240,7 +253,7 @@ dboard_manager_impl::dboard_manager_impl( //dboard constructor args dboard_ctor_args_t db_ctor_args; - db_ctor_args.db_iface = iface; + db_ctor_args.db_iface = _iface; //make xcvr subdevs (make one subdev for both rx and tx dboards) if (this_dboard_is_xcvr){ diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp index f7f4b2c68..c90f4a2db 100644 --- a/host/lib/usrp/mboard_eeprom.cpp +++ b/host/lib/usrp/mboard_eeprom.cpp @@ -17,12 +17,12 @@ #include <uhd/usrp/mboard_eeprom.hpp> #include <uhd/types/mac_addr.hpp> -#include <uhd/utils/algorithm.hpp> #include <uhd/utils/byteswap.hpp> #include <boost/asio/ip/address_v4.hpp> #include <boost/assign/list_of.hpp> #include <boost/lexical_cast.hpp> #include <boost/foreach.hpp> +#include <algorithm> #include <cstddef> using namespace uhd; @@ -38,6 +38,12 @@ static const size_t NAME_MAX_LEN = 32 - SERIAL_LEN; * Utility functions **********************************************************************/ +//! A wrapper around std::copy that takes ranges instead of iterators. +template<typename RangeSrc, typename RangeDst> inline +void byte_copy(const RangeSrc &src, RangeDst &dst){ + std::copy(boost::begin(src), boost::end(src), boost::begin(dst)); +} + //! create a string from a byte vector, return empty if invalid ascii static const std::string bytes_to_string(const byte_vector_t &bytes){ std::string out; @@ -84,7 +90,7 @@ static void load_n100(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ )).to_string(); boost::asio::ip::address_v4::bytes_type ip_addr_bytes; - std::copy(iface.read_eeprom(N100_EEPROM_ADDR, USRP_N100_OFFSETS["ip-addr"], 4), ip_addr_bytes); + byte_copy(iface.read_eeprom(N100_EEPROM_ADDR, USRP_N100_OFFSETS["ip-addr"], 4), ip_addr_bytes); mb_eeprom["ip-addr"] = boost::asio::ip::address_v4(ip_addr_bytes).to_string(); //extract the serial @@ -126,7 +132,7 @@ static void store_n100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ if (mb_eeprom.has_key("ip-addr")){ byte_vector_t ip_addr_bytes(4); - std::copy(boost::asio::ip::address_v4::from_string(mb_eeprom["ip-addr"]).to_bytes(), ip_addr_bytes); + byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["ip-addr"]).to_bytes(), ip_addr_bytes); iface.write_eeprom(N100_EEPROM_ADDR, USRP_N100_OFFSETS["ip-addr"], ip_addr_bytes); } diff --git a/host/lib/usrp/misc_utils.cpp b/host/lib/usrp/misc_utils.cpp index 02f4b216d..2bad83b3c 100644 --- a/host/lib/usrp/misc_utils.cpp +++ b/host/lib/usrp/misc_utils.cpp @@ -19,7 +19,7 @@ #include <uhd/utils/assert.hpp> #include <uhd/utils/algorithm.hpp> #include <uhd/utils/gain_group.hpp> -#include <uhd/usrp/dboard_id.hpp> +#include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/usrp/subdev_props.hpp> #include <uhd/usrp/mboard_props.hpp> #include <uhd/usrp/dboard_props.hpp> @@ -147,7 +147,7 @@ static void verify_xx_subdev_spec( wax::obj dboard = mboard[named_prop_t(dboard_prop, db_name)]; //if the dboard slot is populated, take the first subdevice - if (dboard[DBOARD_PROP_DBOARD_ID].as<dboard_id_t>() != dboard_id_t::none()){ + if (dboard[DBOARD_PROP_DBOARD_EEPROM].as<dboard_eeprom_t>().id != dboard_id_t::none()){ std::string sd_name = dboard[DBOARD_PROP_SUBDEV_NAMES].as<prop_names_t>().front(); subdev_spec.push_back(subdev_spec_pair_t(db_name, sd_name)); break; diff --git a/host/lib/usrp/usrp1/dboard_impl.cpp b/host/lib/usrp/usrp1/dboard_impl.cpp index 2a2762a82..2130960fb 100644 --- a/host/lib/usrp/usrp1/dboard_impl.cpp +++ b/host/lib/usrp/usrp1/dboard_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 @@ -57,13 +57,8 @@ void usrp1_impl::dboard_init(void) BOOST_FOREACH(dboard_slot_t dboard_slot, _dboard_slots){ //read the tx and rx dboard eeproms - _rx_db_eeproms[dboard_slot] = dboard_eeprom_t(_iface->read_eeprom( - get_rx_ee_addr(dboard_slot), 0, dboard_eeprom_t::num_bytes() - )); - - _tx_db_eeproms[dboard_slot] = dboard_eeprom_t(_iface->read_eeprom( - get_tx_ee_addr(dboard_slot), 0, dboard_eeprom_t::num_bytes() - )); + _rx_db_eeproms[dboard_slot].load(*_iface, get_rx_ee_addr(dboard_slot)); + _tx_db_eeproms[dboard_slot].load(*_iface, get_tx_ee_addr(dboard_slot)); //create a new dboard interface and manager _dboard_ifaces[dboard_slot] = make_dboard_iface( @@ -110,8 +105,8 @@ void usrp1_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val, dboard_slot_ val = _dboard_managers[dboard_slot]->get_rx_subdev_names(); return; - case DBOARD_PROP_DBOARD_ID: - val = _rx_db_eeproms[dboard_slot].id; + case DBOARD_PROP_DBOARD_EEPROM: + val = _rx_db_eeproms[dboard_slot]; return; case DBOARD_PROP_DBOARD_IFACE: @@ -141,12 +136,9 @@ void usrp1_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val, dboard_slot_ void usrp1_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val, dboard_slot_t dboard_slot) { switch(key.as<dboard_prop_t>()) { - case DBOARD_PROP_DBOARD_ID: - _rx_db_eeproms[dboard_slot].id = val.as<dboard_id_t>(); - _iface->write_eeprom( - get_rx_ee_addr(dboard_slot), 0, - _rx_db_eeproms[dboard_slot].get_eeprom_bytes() - ); + case DBOARD_PROP_DBOARD_EEPROM: + _rx_db_eeproms[dboard_slot] = val.as<dboard_eeprom_t>(); + _rx_db_eeproms[dboard_slot].store(*_iface, get_rx_ee_addr(dboard_slot)); return; default: @@ -175,8 +167,8 @@ void usrp1_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val, dboard_slot_ val = _dboard_managers[dboard_slot]->get_tx_subdev_names(); return; - case DBOARD_PROP_DBOARD_ID: - val = _tx_db_eeproms[dboard_slot].id; + case DBOARD_PROP_DBOARD_EEPROM: + val = _tx_db_eeproms[dboard_slot]; return; case DBOARD_PROP_DBOARD_IFACE: @@ -206,12 +198,9 @@ void usrp1_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val, dboard_slot_ void usrp1_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val, dboard_slot_t dboard_slot) { switch(key.as<dboard_prop_t>()) { - case DBOARD_PROP_DBOARD_ID: - _tx_db_eeproms[dboard_slot].id = val.as<dboard_id_t>(); - _iface->write_eeprom( - get_tx_ee_addr(dboard_slot), 0, - _tx_db_eeproms[dboard_slot].get_eeprom_bytes() - ); + case DBOARD_PROP_DBOARD_EEPROM: + _tx_db_eeproms[dboard_slot] = val.as<dboard_eeprom_t>(); + _tx_db_eeproms[dboard_slot].store(*_iface, get_tx_ee_addr(dboard_slot)); return; default: UHD_THROW_PROP_SET_ERROR(); diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 4192c4f78..b668d435b 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_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 @@ -35,8 +35,8 @@ using namespace uhd::usrp; **********************************************************************/ void usrp2_mboard_impl::dboard_init(void){ //read the dboard eeprom to extract the dboard ids - _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(USRP2_I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); - _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(USRP2_I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes())); + _rx_db_eeprom.load(*_iface, USRP2_I2C_ADDR_RX_DB); + _tx_db_eeprom.load(*_iface, USRP2_I2C_ADDR_TX_DB); //create a new dboard interface and manager _dboard_iface = make_usrp2_dboard_iface(_iface, _clock_ctrl); @@ -75,8 +75,8 @@ void usrp2_mboard_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ val = _dboard_manager->get_rx_subdev_names(); return; - case DBOARD_PROP_DBOARD_ID: - val = _rx_db_eeprom.id; + case DBOARD_PROP_DBOARD_EEPROM: + val = _rx_db_eeprom; return; case DBOARD_PROP_DBOARD_IFACE: @@ -103,9 +103,9 @@ void usrp2_mboard_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ void usrp2_mboard_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as<dboard_prop_t>()){ - case DBOARD_PROP_DBOARD_ID: - _rx_db_eeprom.id = val.as<dboard_id_t>(); - _iface->write_eeprom(USRP2_I2C_ADDR_RX_DB, 0, _rx_db_eeprom.get_eeprom_bytes()); + case DBOARD_PROP_DBOARD_EEPROM: + _rx_db_eeprom = val.as<dboard_eeprom_t>(); + _rx_db_eeprom.store(*_iface, USRP2_I2C_ADDR_RX_DB); return; default: UHD_THROW_PROP_SET_ERROR(); @@ -132,8 +132,8 @@ void usrp2_mboard_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ val = _dboard_manager->get_tx_subdev_names(); return; - case DBOARD_PROP_DBOARD_ID: - val = _tx_db_eeprom.id; + case DBOARD_PROP_DBOARD_EEPROM: + val = _tx_db_eeprom; return; case DBOARD_PROP_DBOARD_IFACE: @@ -160,9 +160,9 @@ void usrp2_mboard_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ void usrp2_mboard_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as<dboard_prop_t>()){ - case DBOARD_PROP_DBOARD_ID: - _tx_db_eeprom.id = val.as<dboard_id_t>(); - _iface->write_eeprom(USRP2_I2C_ADDR_TX_DB, 0, _tx_db_eeprom.get_eeprom_bytes()); + case DBOARD_PROP_DBOARD_EEPROM: + _tx_db_eeprom = val.as<dboard_eeprom_t>(); + _tx_db_eeprom.store(*_iface, USRP2_I2C_ADDR_TX_DB); return; default: UHD_THROW_PROP_SET_ERROR(); diff --git a/host/lib/usrp/usrp_e100/dboard_impl.cpp b/host/lib/usrp/usrp_e100/dboard_impl.cpp index 9f2bfb8ae..b533c2657 100644 --- a/host/lib/usrp/usrp_e100/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/dboard_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 @@ -31,8 +31,8 @@ using namespace uhd::usrp; * Dboard Initialization **********************************************************************/ void usrp_e100_impl::dboard_init(void){ - _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())); + _rx_db_eeprom.load(*_iface, I2C_ADDR_RX_DB); + _tx_db_eeprom.load(*_iface, I2C_ADDR_TX_DB); //create a new dboard interface and manager _dboard_iface = make_usrp_e100_dboard_iface( @@ -73,8 +73,8 @@ void usrp_e100_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ val = _dboard_manager->get_rx_subdev_names(); return; - case DBOARD_PROP_DBOARD_ID: - val = _rx_db_eeprom.id; + case DBOARD_PROP_DBOARD_EEPROM: + val = _rx_db_eeprom; return; case DBOARD_PROP_DBOARD_IFACE: @@ -103,9 +103,9 @@ void usrp_e100_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ **********************************************************************/ void usrp_e100_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as<dboard_prop_t>()){ - 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()); + case DBOARD_PROP_DBOARD_EEPROM: + _rx_db_eeprom = val.as<dboard_eeprom_t>(); + _rx_db_eeprom.store(*_iface, I2C_ADDR_RX_DB); return; default: UHD_THROW_PROP_SET_ERROR(); @@ -132,8 +132,8 @@ void usrp_e100_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ val = _dboard_manager->get_tx_subdev_names(); return; - case DBOARD_PROP_DBOARD_ID: - val = _tx_db_eeprom.id; + case DBOARD_PROP_DBOARD_EEPROM: + val = _tx_db_eeprom; return; case DBOARD_PROP_DBOARD_IFACE: @@ -162,9 +162,9 @@ void usrp_e100_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ **********************************************************************/ void usrp_e100_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as<dboard_prop_t>()){ - 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()); + case DBOARD_PROP_DBOARD_EEPROM: + _tx_db_eeprom = val.as<dboard_eeprom_t>(); + _tx_db_eeprom.store(*_iface, I2C_ADDR_TX_DB); return; default: UHD_THROW_PROP_SET_ERROR(); |