aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/CMakeLists.txt1
-rw-r--r--host/lib/usrp/dboard_eeprom.cpp78
-rw-r--r--host/lib/usrp/usrp2/dboard_iface.cpp36
-rw-r--r--host/lib/usrp/usrp2/dboard_impl.cpp15
-rw-r--r--host/lib/usrp/usrp2/fw_common.h17
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp61
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.hpp55
7 files changed, 203 insertions, 60 deletions
diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt
index 5495620ec..ffbf15484 100644
--- a/host/lib/CMakeLists.txt
+++ b/host/lib/CMakeLists.txt
@@ -55,6 +55,7 @@ SET(libuhd_sources
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/usrp/dboard_eeprom.cpp b/host/lib/usrp/dboard_eeprom.cpp
new file mode 100644
index 000000000..a8fac602a
--- /dev/null
+++ b/host/lib/usrp/dboard_eeprom.cpp
@@ -0,0 +1,78 @@
+//
+// 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>
+
+using namespace uhd;
+using namespace uhd::usrp;
+
+////////////////////////////////////////////////////////////////////////
+// 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
+////////////////////////////////////////////////////////////////////////
+
+dboard_eeprom_t::dboard_eeprom_t(const byte_vector_t &buf){
+ try{
+ ASSERT_THROW(buf.size() >= num_bytes());
+ ASSERT_THROW(buf[DB_EEPROM_MAGIC] == DB_EEPROM_MAGIC_VALUE);
+ id = \
+ (boost::uint16_t(buf[DB_EEPROM_ID_LSB]) << 0) |
+ (boost::uint16_t(buf[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(3);
+ 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);
+ return bytes;
+}
+
+size_t dboard_eeprom_t::num_bytes(void){
+ return 3;
+}
diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp
index e9acddee6..9d9b745ae 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
@@ -214,42 +213,11 @@ 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);
+ return _iface->write_i2c(i2c_addr, buf);
}
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;
+ return _iface->read_i2c(i2c_addr, num_bytes);
}
/***********************************************************************
diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp
index ee23dc83a..d697f11f0 100644
--- a/host/lib/usrp/usrp2/dboard_impl.cpp
+++ b/host/lib/usrp/usrp2/dboard_impl.cpp
@@ -18,6 +18,7 @@
#include "usrp2_impl.hpp"
#include "usrp2_regs.hpp"
+#include <uhd/usrp/dboard_eeprom.hpp>
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/usrp/dboard_props.hpp>
#include <uhd/utils/assert.hpp>
@@ -33,22 +34,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);
+ //extract the dboard ids
+ dboard_eeprom_t db_rx_eeprom(_iface->read_eeprom(I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes()));
+ dboard_eeprom_t db_tx_eeprom(_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
+ db_rx_eeprom.id, db_tx_eeprom.id, _dboard_iface
);
//load dboards
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/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index 1b0dde1b4..c639c0dfe 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,65 @@ 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;
+ }
+
+/***********************************************************************
+ * EEPROM
+ **********************************************************************/
+ void write_eeprom(boost::uint8_t addr, boost::uint8_t offset, const byte_vector_t &buf){
+ BOOST_FOREACH(boost::uint8_t byte, buf){
+ //write a byte at a time, its easy that way
+ byte_vector_t cmd = boost::assign::list_of(offset)(byte);
+ this->write_i2c(addr, cmd);
+ }
+ }
+
+ byte_vector_t read_eeprom(boost::uint8_t addr, boost::uint8_t offset, size_t num_bytes){
+ //do a zero byte write to start read cycle
+ write_i2c(addr, byte_vector_t(1, offset));
+ return read_i2c(addr, num_bytes);
+ }
+
+/***********************************************************************
* 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..938359677 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.hpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.hpp
@@ -25,6 +25,15 @@
#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.
@@ -94,6 +103,52 @@ public:
) = 0;
/*!
+ * Write bytes over the i2c.
+ * \param addr the address
+ * \param buf the vector of bytes
+ */
+ virtual void write_i2c(
+ boost::uint8_t addr,
+ const uhd::byte_vector_t &buf
+ ) = 0;
+
+ /*!
+ * Read bytes over the i2c.
+ * \param addr the address
+ * \param num_bytes number of bytes to read
+ * \return a vector of bytes
+ */
+ virtual uhd::byte_vector_t read_i2c(
+ boost::uint8_t addr,
+ size_t num_bytes
+ ) = 0;
+
+ /*!
+ * Write bytes to an eeprom.
+ * \param addr the address
+ * \param offset byte offset
+ * \param buf the vector of bytes
+ */
+ virtual void write_eeprom(
+ boost::uint8_t addr,
+ boost::uint8_t offset,
+ const uhd::byte_vector_t &buf
+ ) = 0;
+
+ /*!
+ * Read bytes from an eeprom.
+ * \param addr the address
+ * \param offset byte offset
+ * \param num_bytes number of bytes to read
+ * \return a vector of bytes
+ */
+ virtual uhd::byte_vector_t read_eeprom(
+ boost::uint8_t addr,
+ boost::uint8_t offset,
+ size_t num_bytes
+ ) = 0;
+
+ /*!
* Get the master clock frequency.
* \return the frequency in Hz
*/