summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/CMakeLists.txt2
-rw-r--r--host/lib/types.cpp29
-rw-r--r--host/lib/usrp/dboard/db_basic_and_lf.cpp12
-rw-r--r--host/lib/usrp/dboard/db_rfx.cpp14
-rw-r--r--host/lib/usrp/dboard/db_xcvr2450.cpp15
-rw-r--r--host/lib/usrp/dboard_eeprom.cpp102
-rw-r--r--host/lib/usrp/dboard_manager.cpp5
-rw-r--r--host/lib/usrp/usrp2/dboard_iface.cpp44
-rw-r--r--host/lib/usrp/usrp2/dboard_impl.cpp52
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp10
-rw-r--r--host/lib/usrp/usrp2/fw_common.h17
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp8
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp44
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.hpp11
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp3
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp3
-rw-r--r--host/lib/utils.cpp44
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);
+}