summaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-05-01 18:21:29 -0700
committerJosh Blum <josh@joshknows.com>2011-05-01 18:21:29 -0700
commit6f0a98ee2e9e2090c6bf7d56260cb95b0eb1fbb3 (patch)
tree121f8c82241bf312e704917d6a1598372cc67b65 /host
parent5c6c179689ef76ccd25d09ac4faeb9a836a066c8 (diff)
downloaduhd-6f0a98ee2e9e2090c6bf7d56260cb95b0eb1fbb3.tar.gz
uhd-6f0a98ee2e9e2090c6bf7d56260cb95b0eb1fbb3.tar.bz2
uhd-6f0a98ee2e9e2090c6bf7d56260cb95b0eb1fbb3.zip
USRP1: added support for setting clock rate from EEPROM
Basically, same deal as the previous changeset but for USRP1. Modified previous changes so that the key is shorter (mcr = master_clock_rate)
Diffstat (limited to 'host')
-rw-r--r--host/docs/usrp1.rst9
-rw-r--r--host/docs/usrp_e1xx.rst8
-rw-r--r--host/lib/usrp/mboard_eeprom.cpp42
-rw-r--r--host/lib/usrp/usrp1/clock_ctrl.cpp14
-rw-r--r--host/lib/usrp/usrp1/mboard_impl.cpp4
-rw-r--r--host/lib/usrp/usrp_e100/clock_ctrl.cpp4
6 files changed, 67 insertions, 14 deletions
diff --git a/host/docs/usrp1.rst b/host/docs/usrp1.rst
index f77a26e0a..97a8c3bb5 100644
--- a/host/docs/usrp1.rst
+++ b/host/docs/usrp1.rst
@@ -136,6 +136,11 @@ The USRP can be modified to accept an external clock reference instead of the 64
The new external clock needs to be a square wave between +7dBm and +15dBm
-For the correct clock settings, call usrp->set_master_clock_rate(EXT_CLOCK_FREQUENCY)
-before any other parameters are set in your application.
+After the hardware modification,
+the user should burn the setting into the EEPROM,
+so UHD can initialize with the correct clock rate.
+Run the following commands to record the setting into the EEPROM:
+::
+ cd <install-path>/share/uhd/utils
+ ./usrp_burn_mb_eeprom --args=<optional device args> --key=mcr --val=<rate>
diff --git a/host/docs/usrp_e1xx.rst b/host/docs/usrp_e1xx.rst
index b2a6ff08c..036d2c02c 100644
--- a/host/docs/usrp_e1xx.rst
+++ b/host/docs/usrp_e1xx.rst
@@ -35,11 +35,11 @@ To use the 61.44MHz clock rate, the USRP embedded will require two jumpers to be
* J16 is a two pin header, remove the jumper (or leave it on pin1 only)
* J15 is a three pin header, move the jumper to (pin1, pin2)
-Then run the following commands to record the setting in the EEPROM:
+Then run the following commands to record the setting into the EEPROM:
::
cd <install-path>/share/uhd/utils
- ./usrp_burn_mb_eeprom --key=master_clock_rate --val=61.44e6
+ ./usrp_burn_mb_eeprom --key=mcr --val=61.44e6
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,11 +50,11 @@ To use other clock rates, the jumpers will need to be in the default position.
* J16 is a two pin header, move the jumper to (pin1, pin2)
* J15 is a three pin header, move the jumper to (pin2, pin3)
-Then run the following commands to record the setting in the EEPROM:
+Then run the following commands to record the setting into the EEPROM:
::
cd <install-path>/share/uhd/utils
- ./usrp_burn_mb_eeprom --key=master_clock_rate --val=<rate>
+ ./usrp_burn_mb_eeprom --key=mcr --val=<rate>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Clock rate recovery - unbricking
diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp
index 03096691e..29bc5ee32 100644
--- a/host/lib/usrp/mboard_eeprom.cpp
+++ b/host/lib/usrp/mboard_eeprom.cpp
@@ -181,6 +181,7 @@ static const size_t B000_SERIAL_LEN = 8;
static const uhd::dict<std::string, boost::uint8_t> USRP_B000_OFFSETS = boost::assign::map_list_of
("serial", 0xf8)
("name", 0xf8 - NAME_MAX_LEN)
+ ("mcr", 0xf8 - NAME_MAX_LEN - sizeof(boost::uint32_t))
;
static void load_b000(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
@@ -193,6 +194,21 @@ static void load_b000(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
mb_eeprom["name"] = bytes_to_string(iface.read_eeprom(
B000_EEPROM_ADDR, USRP_B000_OFFSETS["name"], NAME_MAX_LEN
));
+
+ //extract master clock rate as a 32-bit uint in Hz
+ boost::uint32_t master_clock_rate;
+ const byte_vector_t rate_bytes = iface.read_eeprom(
+ B000_EEPROM_ADDR, USRP_B000_OFFSETS["mcr"], sizeof(master_clock_rate)
+ );
+ std::copy(
+ rate_bytes.begin(), rate_bytes.end(), //input
+ reinterpret_cast<boost::uint8_t *>(&master_clock_rate) //output
+ );
+ master_clock_rate = ntohl(master_clock_rate);
+ if (master_clock_rate > 1e6 and master_clock_rate < 1e9){
+ mb_eeprom["mcr"] = boost::lexical_cast<std::string>(master_clock_rate);
+ }
+ else mb_eeprom["mcr"] = "";
}
static void store_b000(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
@@ -207,6 +223,19 @@ static void store_b000(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
B000_EEPROM_ADDR, USRP_B000_OFFSETS["name"],
string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN)
);
+
+ //store the master clock rate as a 32-bit uint in Hz
+ if (mb_eeprom.has_key("mcr")){
+ boost::uint32_t master_clock_rate = boost::uint32_t(boost::lexical_cast<double>(mb_eeprom["mcr"]));
+ master_clock_rate = htonl(master_clock_rate);
+ const byte_vector_t rate_bytes(
+ reinterpret_cast<const boost::uint8_t *>(&master_clock_rate),
+ reinterpret_cast<const boost::uint8_t *>(&master_clock_rate) + sizeof(master_clock_rate)
+ );
+ iface.write_eeprom(
+ B000_EEPROM_ADDR, USRP_B000_OFFSETS["mcr"], rate_bytes
+ );
+ }
}
/***********************************************************************
* Implementation of E100 load/store
@@ -223,7 +252,7 @@ struct e100_eeprom_map{
unsigned char env_setting[64];
unsigned char serial[10];
unsigned char name[NAME_MAX_LEN];
- float master_clock_rate;
+ float mcr;
};
template <typename T> static const byte_vector_t to_bytes(const T &item){
@@ -259,15 +288,16 @@ static void load_e100(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
//extract the master clock rate
float master_clock_rate = 0;
const byte_vector_t rate_bytes = iface.read_eeprom(
- E100_EEPROM_ADDR, offsetof(e100_eeprom_map, master_clock_rate), sizeof(master_clock_rate)
+ E100_EEPROM_ADDR, offsetof(e100_eeprom_map, mcr), sizeof(master_clock_rate)
);
std::copy(
rate_bytes.begin(), rate_bytes.end(), //source
reinterpret_cast<boost::uint8_t *>(&master_clock_rate) //destination
);
if (master_clock_rate > 1e6 and master_clock_rate < 1e9){
- mb_eeprom["master_clock_rate"] = boost::lexical_cast<std::string>(master_clock_rate);
+ mb_eeprom["mcr"] = boost::lexical_cast<std::string>(master_clock_rate);
}
+ else mb_eeprom["mcr"] = "";
}
static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
@@ -304,14 +334,14 @@ static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
store_e100_string_xx(name);
//store the master clock rate
- if (mb_eeprom.has_key("master_clock_rate")){
- const float master_clock_rate = float(boost::lexical_cast<double>(mb_eeprom["master_clock_rate"]));
+ if (mb_eeprom.has_key("mcr")){
+ const float master_clock_rate = float(boost::lexical_cast<double>(mb_eeprom["mcr"]));
const byte_vector_t rate_bytes(
reinterpret_cast<const boost::uint8_t *>(&master_clock_rate),
reinterpret_cast<const boost::uint8_t *>(&master_clock_rate) + sizeof(master_clock_rate)
);
iface.write_eeprom(
- E100_EEPROM_ADDR, offsetof(e100_eeprom_map, master_clock_rate), rate_bytes
+ E100_EEPROM_ADDR, offsetof(e100_eeprom_map, mcr), rate_bytes
);
}
}
diff --git a/host/lib/usrp/usrp1/clock_ctrl.cpp b/host/lib/usrp/usrp1/clock_ctrl.cpp
index df5353b54..154e6a316 100644
--- a/host/lib/usrp/usrp1/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp1/clock_ctrl.cpp
@@ -16,6 +16,9 @@
//
#include "clock_ctrl.hpp"
+#include <boost/lexical_cast.hpp>
+#include <boost/format.hpp>
+#include <iostream>
using namespace uhd;
@@ -31,6 +34,17 @@ class usrp1_clock_ctrl_impl : public usrp1_clock_ctrl {
public:
usrp1_clock_ctrl_impl(usrp1_iface::sptr iface): _iface(iface){
this->set_master_clock_freq(default_master_clock_rate);
+ try{
+ if (not _iface->mb_eeprom["mcr"].empty()){
+ std::cout << "Read FPGA clock rate from EEPROM setting." << std::endl;
+ const double master_clock_rate = boost::lexical_cast<double>(_iface->mb_eeprom["mcr"]);
+ std::cout << boost::format("Initializing FPGA clock to %fMHz...") % (master_clock_rate/1e6) << std::endl;
+ this->set_master_clock_freq(master_clock_rate);
+ }
+ }
+ catch(const std::exception &e){
+ std::cerr << "Error setting FPGA clock rate from EEPROM: " << e.what() << std::endl;
+ }
}
void set_master_clock_freq(double freq){
diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp
index 870956568..eecae3fa7 100644
--- a/host/lib/usrp/usrp1/mboard_impl.cpp
+++ b/host/lib/usrp/usrp1/mboard_impl.cpp
@@ -378,6 +378,10 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)
return;
case MBOARD_PROP_CLOCK_RATE:
+ std::cerr << "Helpful message:" << std::endl;
+ std::cerr << " I see that you are setting the master clock rate from the API." << std::endl;
+ std::cerr << " You may find it more convenient to burn this setting into the EEPROM." << std::endl;
+ std::cerr << " See the application notes for USRP1 for further instructions." << std::endl;
_clock_ctrl->set_master_clock_freq(val.as<double>());
return;
diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp
index 851ce29b0..2e3eb5cb9 100644
--- a/host/lib/usrp/usrp_e100/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp_e100/clock_ctrl.cpp
@@ -187,9 +187,9 @@ public:
//initialize the FPGA clock to something
bool fpga_clock_initialized = false;
try{
- if (_iface->mb_eeprom.has_key("master_clock_rate")){
+ if (not _iface->mb_eeprom["mcr"].empty()){
std::cout << "Read FPGA clock rate from EEPROM setting." << std::endl;
- const double master_clock_rate = boost::lexical_cast<double>(_iface->mb_eeprom["master_clock_rate"]);
+ const double master_clock_rate = boost::lexical_cast<double>(_iface->mb_eeprom["mcr"]);
std::cout << boost::format("Initializing FPGA clock to %fMHz...") % (master_clock_rate/1e6) << std::endl;
this->set_fpga_clock_rate(master_clock_rate);
fpga_clock_initialized = true;