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.cpp101
1 files changed, 85 insertions, 16 deletions
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index 123910166..f0b2a90a6 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 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
@@ -16,11 +16,13 @@
//
#include "usrp2_regs.hpp"
+#include "usrp2_impl.hpp"
#include "fw_common.h"
#include "usrp2_iface.hpp"
#include <uhd/exception.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/utils/tasks.hpp>
+#include <uhd/utils/images.hpp>
#include <uhd/utils/safe_call.hpp>
#include <uhd/types/dict.hpp>
#include <boost/thread.hpp>
@@ -31,12 +33,14 @@
#include <boost/bind.hpp>
#include <boost/tokenizer.hpp>
#include <boost/functional/hash.hpp>
+#include <boost/filesystem.hpp>
#include <algorithm>
#include <iostream>
using namespace uhd;
using namespace uhd::usrp;
using namespace uhd::transport;
+namespace fs = boost::filesystem;
static const double CTRL_RECV_TIMEOUT = 1.0;
static const size_t CTRL_RECV_RETRIES = 3;
@@ -105,7 +109,7 @@ public:
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);
+ mb_eeprom = mboard_eeprom_t(*this, USRP2_EEPROM_MAP_KEY);
}
~usrp2_iface_impl(void){UHD_SAFE_CALL(
@@ -118,12 +122,12 @@ public:
void lock_device(bool lock){
if (lock){
- this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_POKE32>(U2_FW_REG_LOCK_GPID, boost::uint32_t(get_gpid()));
+ this->pokefw(U2_FW_REG_LOCK_GPID, boost::uint32_t(get_gpid()));
_lock_task = task::make(boost::bind(&usrp2_iface_impl::lock_task, this));
}
else{
_lock_task.reset(); //shutdown the task
- this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_POKE32>(U2_FW_REG_LOCK_TIME, 0); //unlock
+ this->pokefw(U2_FW_REG_LOCK_TIME, 0); //unlock
}
}
@@ -131,8 +135,8 @@ public:
//never assume lock with fpga image mismatch
if ((this->peek32(U2_REG_COMPAT_NUM_RB) >> 16) != USRP2_FPGA_COMPAT_NUM) return false;
- boost::uint32_t lock_time = this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_PEEK32>(U2_FW_REG_LOCK_TIME);
- boost::uint32_t lock_gpid = this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_PEEK32>(U2_FW_REG_LOCK_GPID);
+ boost::uint32_t lock_time = this->peekfw(U2_FW_REG_LOCK_TIME);
+ boost::uint32_t lock_gpid = this->peekfw(U2_FW_REG_LOCK_GPID);
//may not be the right tick rate, but this is ok for locking purposes
const boost::uint32_t lock_timeout_time = boost::uint32_t(3*100e6);
@@ -148,7 +152,7 @@ public:
void lock_task(void){
//re-lock in task
- this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_POKE32>(U2_FW_REG_LOCK_TIME, this->get_curr_time());
+ this->pokefw(U2_FW_REG_LOCK_TIME, this->get_curr_time());
//sleep for a bit
boost::this_thread::sleep(boost::posix_time::milliseconds(1500));
}
@@ -176,6 +180,16 @@ public:
return this->get_reg<boost::uint16_t, USRP2_REG_ACTION_FPGA_PEEK16>(addr);
}
+ void pokefw(wb_addr_type addr, boost::uint32_t data)
+ {
+ this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_POKE32>(addr, data);
+ }
+
+ boost::uint32_t peekfw(wb_addr_type addr)
+ {
+ return this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_PEEK32>(addr);
+ }
+
template <class T, usrp2_reg_action_t action>
T get_reg(wb_addr_type addr, T data = 0){
//setup the out data
@@ -311,8 +325,10 @@ public:
"\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."
- ) % ((lo == hi)? (boost::format("%d") % hi) : (boost::format("[%d to %d]") % lo % hi)) % compat));
+ "The firmware build is not compatible with the host code build.\n"
+ "%s\n"
+ ) % ((lo == hi)? (boost::format("%d") % hi) : (boost::format("[%d to %d]") % lo % hi))
+ % compat % this->images_warn_help_message()));
}
if (len >= sizeof(usrp2_ctrl_data_t) and ntohl(ctrl_data_in->seq) == _ctrl_seq_num){
return *ctrl_data_in;
@@ -340,13 +356,13 @@ public:
const std::string get_cname(void){
switch(this->get_rev()){
- case USRP2_REV3: return "USRP2-REV3";
- case USRP2_REV4: return "USRP2-REV4";
- case USRP_N200: return "USRP-N200";
- case USRP_N210: return "USRP-N210";
- case USRP_N200_R4: return "USRP-N200-REV4";
- case USRP_N210_R4: return "USRP-N210-REV4";
- case USRP_NXXX: return "USRP-N???";
+ case USRP2_REV3: return "USRP2 r3";
+ case USRP2_REV4: return "USRP2 r4";
+ case USRP_N200: return "N200";
+ case USRP_N210: return "N210";
+ case USRP_N200_R4: return "N200r4";
+ case USRP_N210_R4: return "N210r4";
+ case USRP_NXXX: return "N???";
}
UHD_THROW_INVALID_CODE_PATH();
}
@@ -356,6 +372,59 @@ public:
return str(boost::format("%u.%u") % _protocol_compat % minor);
}
+ std::string images_warn_help_message(void){
+ //determine the images names
+ std::string fw_image, fpga_image;
+ switch(this->get_rev()){
+ case USRP2_REV3: fpga_image = "usrp2_fpga.bin"; fw_image = "usrp2_fw.bin"; break;
+ case USRP2_REV4: fpga_image = "usrp2_fpga.bin"; fw_image = "usrp2_fw.bin"; break;
+ case USRP_N200: fpga_image = "usrp_n200_r2_fpga.bin"; fw_image = "usrp_n200_fw.bin"; break;
+ case USRP_N210: fpga_image = "usrp_n210_r2_fpga.bin"; fw_image = "usrp_n210_fw.bin"; break;
+ case USRP_N200_R4: fpga_image = "usrp_n200_r4_fpga.bin"; fw_image = "usrp_n200_fw.bin"; break;
+ case USRP_N210_R4: fpga_image = "usrp_n210_r4_fpga.bin"; fw_image = "usrp_n210_fw.bin"; break;
+ default: break;
+ }
+ if (fw_image.empty() or fpga_image.empty()) return "";
+
+ //does your platform use sudo?
+ std::string sudo;
+ #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_MACOS)
+ sudo = "sudo ";
+ #endif
+
+
+ //look up the real FS path to the images
+ std::string fw_image_path, fpga_image_path;
+ try{
+ fw_image_path = uhd::find_image_path(fw_image);
+ fpga_image_path = uhd::find_image_path(fpga_image);
+ }
+ catch(const std::exception &){
+ return str(boost::format("Could not find %s and %s in your images path!\n%s") % fw_image % fpga_image % print_images_error());
+ }
+
+ //escape char for multi-line cmd + newline + indent?
+ #ifdef UHD_PLATFORM_WIN32
+ const std::string ml = "^\n ";
+ #else
+ const std::string ml = "\\\n ";
+ #endif
+
+ //create the images downloader and burner commands
+ const std::string images_downloader_cmd = str(boost::format("%s\"%s\"") % sudo % find_images_downloader());
+ if (this->get_rev() == USRP2_REV3 or this->get_rev() == USRP2_REV4){
+ const std::string card_burner = (fs::path(fw_image_path).branch_path().branch_path() / "utils" / "usrp2_card_burner.py").string();
+ const std::string card_burner_cmd = str(boost::format("\"%s%s\" %s--fpga=\"%s\" %s--fw=\"%s\"") % sudo % card_burner % ml % fpga_image_path % ml % fw_image_path);
+ return str(boost::format("%s\n%s") % print_images_error() % card_burner_cmd);
+ }
+ else{
+ const std::string addr = _ctrl_transport->get_recv_addr();
+ const std::string net_burner = (fs::path(fw_image_path).branch_path().branch_path() / "utils" / "usrp_n2xx_net_burner.py").string();
+ const std::string net_burner_cmd = str(boost::format("\"%s\" %s--fpga=\"%s\" %s--fw=\"%s\" %s--addr=\"%s\"") % net_burner % ml % fpga_image_path % ml % fw_image_path % ml % addr);
+ return str(boost::format("%s\n%s") % print_images_error() % net_burner_cmd);
+ }
+ }
+
private:
//this lovely lady makes it all possible
udp_simple::sptr _ctrl_transport;