diff options
Diffstat (limited to 'host')
-rw-r--r-- | host/docs/usrp_e1xx.rst | 16 | ||||
-rw-r--r-- | host/examples/rx_timed_samples.cpp | 9 | ||||
-rw-r--r-- | host/lib/usrp/mboard_eeprom.cpp | 25 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e100/clock_ctrl.cpp | 19 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e100/mboard_impl.cpp | 4 |
5 files changed, 59 insertions, 14 deletions
diff --git a/host/docs/usrp_e1xx.rst b/host/docs/usrp_e1xx.rst index 2818a0a65..b2a6ff08c 100644 --- a/host/docs/usrp_e1xx.rst +++ b/host/docs/usrp_e1xx.rst @@ -20,7 +20,6 @@ Example device address string representations to specify non-standard FPGA image Changing the master clock rate ------------------------------------------------------------------------ The master clock rate of the USRP embedded feeds both the FPGA DSP and the codec chip. -UHD can dynamically reconfigure the clock rate though the set_master_clock_rate() API call. Hundreds of rates between 32MHz and 64MHz are available. A few notable rates are: @@ -36,8 +35,12 @@ 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) -For the correct clock settings, call usrp->set_master_clock_rate(61.44e6) -before any other parameters are set in your application. +Then run the following commands to record the setting in the EEPROM: +:: + + cd <install-path>/share/uhd/utils + ./usrp_burn_mb_eeprom --key=master_clock_rate --val=61.44e6 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Set other rates - uses internal VCO @@ -47,8 +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) -For the correct clock settings, call usrp->set_master_clock_rate(rate) -before any other parameters are set in your application. +Then run the following commands to record the setting in the EEPROM: +:: + + cd <install-path>/share/uhd/utils + ./usrp_burn_mb_eeprom --key=master_clock_rate --val=<rate> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Clock rate recovery - unbricking diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 28d7ee466..05cc0717b 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -32,7 +32,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::string args; double seconds_in_future; size_t total_num_samps; - double rate, clock; + double rate; //setup the program options po::options_description desc("Allowed options"); @@ -41,7 +41,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args") ("secs", po::value<double>(&seconds_in_future)->default_value(1.5), "number of seconds in the future to receive") ("nsamps", po::value<size_t>(&total_num_samps)->default_value(10000), "total number of samples to receive") - ("clock", po::value<double>(&clock), "master clock frequency in Hz") ("rate", po::value<double>(&rate)->default_value(100e6/16), "rate of incoming samples") ("dilv", "specify to disable inner-loop verbose") ; @@ -63,12 +62,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //optionally set the clock rate (do before setting anything else) - if (vm.count("clock")){ - std::cout << boost::format("Setting master clock rate: %f MHz...") % (clock/1e6) << std::endl; - usrp->set_master_clock_rate(clock); - } - //set the rx sample rate std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; usrp->set_rx_rate(rate); diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp index 869a38478..03096691e 100644 --- a/host/lib/usrp/mboard_eeprom.cpp +++ b/host/lib/usrp/mboard_eeprom.cpp @@ -223,6 +223,7 @@ struct e100_eeprom_map{ unsigned char env_setting[64]; unsigned char serial[10]; unsigned char name[NAME_MAX_LEN]; + float master_clock_rate; }; template <typename T> static const byte_vector_t to_bytes(const T &item){ @@ -254,6 +255,19 @@ static void load_e100(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ load_e100_string_xx(env_setting); load_e100_string_xx(serial); load_e100_string_xx(name); + + //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) + ); + 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); + } } static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ @@ -289,6 +303,17 @@ static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ store_e100_string_xx(serial); 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"])); + 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 + ); + } } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp index 1ac2b804c..851ce29b0 100644 --- a/host/lib/usrp/usrp_e100/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e100/clock_ctrl.cpp @@ -184,7 +184,24 @@ public: this->use_internal_ref(); - this->set_fpga_clock_rate(DEFAULT_OUTPUT_RATE); //initialize to something + //initialize the FPGA clock to something + bool fpga_clock_initialized = false; + try{ + if (_iface->mb_eeprom.has_key("master_clock_rate")){ + 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"]); + 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; + } + } + catch(const std::exception &e){ + std::cerr << "Error setting FPGA clock rate from EEPROM: " << e.what() << std::endl; + } + if (not fpga_clock_initialized){ //was not set... use the default rate + std::cout << boost::format("Initializing FPGA clock to %fMHz...") % (DEFAULT_OUTPUT_RATE/1e6) << std::endl; + this->set_fpga_clock_rate(DEFAULT_OUTPUT_RATE); + } this->enable_test_clock(ENABLE_THE_TEST_OUT); this->enable_rx_dboard_clock(false); diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp index 29e3c5da2..5f4a208d3 100644 --- a/host/lib/usrp/usrp_e100/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp @@ -207,6 +207,10 @@ void usrp_e100_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 USRP-E1XX for further instructions." << std::endl; _clock_ctrl->set_fpga_clock_rate(val.as<double>()); return; |