aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/usrp2/usrp2_iface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/usrp2/usrp2_iface.cpp')
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp65
1 files changed, 41 insertions, 24 deletions
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index e3827233b..d88d31765 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -34,14 +34,32 @@ using namespace uhd::transport;
static const double CTRL_RECV_TIMEOUT = 1.0;
+static const boost::uint32_t MIN_PROTO_COMPAT_SPI = 7;
+static const boost::uint32_t MIN_PROTO_COMPAT_I2C = 7;
+// The register compat number must reflect the protocol compatibility
+// and the compatibility of the register mapping (more likely to change).
+static const boost::uint32_t MIN_PROTO_COMPAT_REG = USRP2_FW_COMPAT_NUM;
+static const boost::uint32_t MIN_PROTO_COMPAT_UART = 7;
+
class usrp2_iface_impl : public usrp2_iface{
public:
/***********************************************************************
* Structors
**********************************************************************/
- usrp2_iface_impl(udp_simple::sptr ctrl_transport){
- _ctrl_transport = ctrl_transport;
- _ctrl_seq_num = 0;
+ usrp2_iface_impl(udp_simple::sptr ctrl_transport):
+ _ctrl_transport(ctrl_transport),
+ _ctrl_seq_num(0),
+ _protocol_compat(0) //initialized below...
+ {
+ //Obtain the firmware's compat number.
+ //Save the response compat number for communication.
+ //TODO can choose to reject certain older compat numbers
+ usrp2_ctrl_data_t ctrl_data;
+ ctrl_data.id = htonl(USRP2_CTRL_ID_WAZZUP_BRO);
+ ctrl_data = ctrl_send_and_recv(ctrl_data, 0, ~0);
+ if (ntohl(ctrl_data.id) != USRP2_CTRL_ID_WAZZUP_DUDE)
+ throw uhd::runtime_error("firmware not responding");
+ _protocol_compat = ntohl(ctrl_data.proto_ver);
mb_eeprom = mboard_eeprom_t(*this, mboard_eeprom_t::MAP_N100);
switch(this->get_rev()){
@@ -59,15 +77,6 @@ public:
regs = usrp2_get_regs(false);
break;
}
-
- //check the fpga compatibility number
- const boost::uint32_t fpga_compat_num = this->peek32(this->regs.compat_num_rb);
- if (fpga_compat_num != USRP2_FPGA_COMPAT_NUM){
- throw uhd::runtime_error(str(boost::format(
- "Expected fpga compatibility number %d, but got %d:\n"
- "The fpga build is not compatible with the host code build."
- ) % int(USRP2_FPGA_COMPAT_NUM) % fpga_compat_num));
- }
}
/***********************************************************************
@@ -115,7 +124,7 @@ public:
out_data.data.spi_args.data = htonl(data);
//send and recv
- usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data);
+ usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_SPI);
UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE);
return ntohl(in_data.data.spi_args.data);
@@ -138,7 +147,7 @@ public:
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);
+ usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_I2C);
UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE);
}
@@ -153,7 +162,7 @@ public:
UHD_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);
+ usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_I2C);
UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE);
UHD_ASSERT_THROW(in_data.data.i2c_args.addr = num_bytes);
@@ -186,7 +195,7 @@ public:
std::copy(item.begin(), item.end(), out_data.data.uart_args.data);
//send and recv
- usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data);
+ usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_UART);
UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE);
}
}
@@ -205,7 +214,7 @@ public:
//UHD_ASSERT_THROW(num_bytes <= sizeof(out_data.data.uart_args.data));
//send and recv
- usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data);
+ usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_UART);
UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE);
readlen = in_data.data.uart_args.bytes;
@@ -226,12 +235,16 @@ public:
/***********************************************************************
* Send/Recv over control
**********************************************************************/
- usrp2_ctrl_data_t ctrl_send_and_recv(const usrp2_ctrl_data_t &out_data){
+ usrp2_ctrl_data_t ctrl_send_and_recv(
+ const usrp2_ctrl_data_t &out_data,
+ boost::uint32_t lo = USRP2_FW_COMPAT_NUM,
+ boost::uint32_t hi = USRP2_FW_COMPAT_NUM
+ ){
boost::mutex::scoped_lock lock(_ctrl_mutex);
//fill in the seq number and send
usrp2_ctrl_data_t out_copy = out_data;
- out_copy.proto_ver = htonl(USRP2_FW_COMPAT_NUM);
+ out_copy.proto_ver = htonl(_protocol_compat);
out_copy.seq = htonl(++_ctrl_seq_num);
_ctrl_transport->send(boost::asio::buffer(&out_copy, sizeof(usrp2_ctrl_data_t)));
@@ -240,11 +253,14 @@ public:
const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem);
while(true){
size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), CTRL_RECV_TIMEOUT);
- if(len >= sizeof(boost::uint32_t) and ntohl(ctrl_data_in->proto_ver) != USRP2_FW_COMPAT_NUM){
+ boost::uint32_t compat = ntohl(ctrl_data_in->proto_ver);
+ if(len >= sizeof(boost::uint32_t) and (hi < compat or lo > compat)){
throw uhd::runtime_error(str(boost::format(
- "Expected protocol compatibility number %d, but got %d:\n"
+ "\nPlease update the firmware and FPGA images for your device.\n"
+ "See the application notes for USRP2/N-Series for instructions.\n"
+ "Expected protocol compatibility number %s, but got %d:\n"
"The firmware build is not compatible with the host code build."
- ) % int(USRP2_FW_COMPAT_NUM) % ntohl(ctrl_data_in->proto_ver)));
+ ) % ((lo == hi)? (boost::format("%d") % hi) : (boost::format("[%d to %d]") % lo % hi)) % compat));
}
if (len >= sizeof(usrp2_ctrl_data_t) and ntohl(ctrl_data_in->seq) == _ctrl_seq_num){
return *ctrl_data_in;
@@ -284,6 +300,7 @@ private:
//used in send/recv
boost::mutex _ctrl_mutex;
boost::uint32_t _ctrl_seq_num;
+ boost::uint32_t _protocol_compat;
/***********************************************************************
* Private Templated Peek and Poke
@@ -297,7 +314,7 @@ private:
out_data.data.poke_args.num_bytes = sizeof(T);
//send and recv
- usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data);
+ usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_REG);
UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_OMG_POKED_REGISTER_SO_BAD_DUDE);
}
@@ -309,7 +326,7 @@ private:
out_data.data.poke_args.num_bytes = sizeof(T);
//send and recv
- usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data);
+ usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_REG);
UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE);
return T(ntohl(in_data.data.poke_args.data));
}