diff options
author | Josh Blum <josh@joshknows.com> | 2011-05-03 16:55:27 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-05-03 16:55:27 -0700 |
commit | 4e0b42afcbbf1067cef2ad530f3b162e5a35771b (patch) | |
tree | 708547b217482a6404f2c75ad7ab19a69a74dc9e /host/lib/usrp | |
parent | e75919bc9e1cb1b5f8f69b5a5aabed9b3a1a53d9 (diff) | |
parent | b4fc0d61bb6cbd1a5614745bab9aeb0abc22cb6f (diff) | |
download | uhd-4e0b42afcbbf1067cef2ad530f3b162e5a35771b.tar.gz uhd-4e0b42afcbbf1067cef2ad530f3b162e5a35771b.tar.bz2 uhd-4e0b42afcbbf1067cef2ad530f3b162e5a35771b.zip |
Merge branch 'master' into next
Diffstat (limited to 'host/lib/usrp')
-rw-r--r-- | host/lib/usrp/dboard/db_rfx.cpp | 35 | ||||
-rw-r--r-- | host/lib/usrp/mboard_eeprom.cpp | 58 | ||||
-rw-r--r-- | host/lib/usrp/tune_helper.cpp | 26 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/clock_ctrl.cpp | 14 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/mboard_impl.cpp | 4 | ||||
-rw-r--r-- | host/lib/usrp/usrp1/usrp1_ctrl.cpp | 26 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 38 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 23 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e100/clock_ctrl.cpp | 19 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e100/mboard_impl.cpp | 4 |
10 files changed, 192 insertions, 55 deletions
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 725b5cc03..231757365 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -121,6 +121,22 @@ private: bool get_locked(dboard_iface::unit_t unit){ return (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; } + + /*! + * Read the RSSI from the aux adc + * \return the rssi in dB + */ + double get_rssi(void){ + //RSSI from VAGC vs RF Power, Fig 34, pg 13 + double max_power = -3.0; + + //constants for the rssi calculation + static const double min_v = 0.35, max_v = 1.0; + static const double rssi_dyn_range = 60; + //calculate the rssi from the voltage + double voltage = this->get_iface()->read_aux_adc(dboard_iface::UNIT_RX, dboard_iface::AUX_ADC_B); + return max_power - rssi_dyn_range*(voltage - min_v)/(max_v - min_v); + } }; /*********************************************************************** @@ -454,12 +470,19 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_SENSOR: - UHD_ASSERT_THROW(key.name == "lo_locked"); - val = sensor_value_t("LO", this->get_locked(dboard_iface::UNIT_RX), "locked", "unlocked"); - return; - - case SUBDEV_PROP_SENSOR_NAMES: - val = prop_names_t(1, "lo_locked"); + if (key.name == "lo_locked") + val = sensor_value_t("LO", this->get_locked(dboard_iface::UNIT_RX), "locked", "unlocked"); + else if ((key.name == "rssi") and (get_rx_id() != 0x0024)) + val = sensor_value_t("RSSI", this->get_rssi(), "dBm"); + else + UHD_THROW_INVALID_CODE_PATH(); + return; + + case SUBDEV_PROP_SENSOR_NAMES:{ + prop_names_t names = list_of("lo_locked"); + if (get_rx_id() != 0x0024) names.push_back("rssi"); + val = names; + } return; case SUBDEV_PROP_BANDWIDTH: diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp index 869a38478..297de990f 100644 --- a/host/lib/usrp/mboard_eeprom.cpp +++ b/host/lib/usrp/mboard_eeprom.cpp @@ -23,6 +23,7 @@ #include <boost/lexical_cast.hpp> #include <boost/foreach.hpp> #include <algorithm> +#include <iostream> #include <cstddef> using namespace uhd; @@ -181,6 +182,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 +195,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 +224,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 @@ -222,7 +252,8 @@ struct e100_eeprom_map{ unsigned char env_var[16]; unsigned char env_setting[64]; unsigned char serial[10]; - unsigned char name[NAME_MAX_LEN]; + unsigned char name[16]; + unsigned char mcr[sizeof(float)]; }; template <typename T> static const byte_vector_t to_bytes(const T &item){ @@ -254,6 +285,20 @@ 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, 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["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){ @@ -289,6 +334,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("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, mcr), rate_bytes + ); + } } /*********************************************************************** diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index 9637301ad..264e6c04b 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -49,28 +49,28 @@ static tune_result_t tune_xx_subdev_and_dsp( } //------------------------------------------------------------------ - //-- set the intermediate frequency depending upon the IF policy + //-- set the RF frequency depending upon the policy //------------------------------------------------------------------ - double target_inter_freq = 0.0; - switch (tune_request.inter_freq_policy){ + double target_rf_freq = 0.0; + switch (tune_request.rf_freq_policy){ case tune_request_t::POLICY_AUTO: - target_inter_freq = tune_request.target_freq + lo_offset; - subdev_freq_proxy = target_inter_freq; + target_rf_freq = tune_request.target_freq + lo_offset; + subdev_freq_proxy = target_rf_freq; break; case tune_request_t::POLICY_MANUAL: - target_inter_freq = tune_request.inter_freq; - subdev_freq_proxy = target_inter_freq; + target_rf_freq = tune_request.rf_freq; + subdev_freq_proxy = target_rf_freq; break; case tune_request_t::POLICY_NONE: break; //does not set } - double actual_inter_freq = subdev_freq_proxy.as<double>(); + double actual_rf_freq = subdev_freq_proxy.as<double>(); //------------------------------------------------------------------ //-- calculate the dsp freq, only used with automatic policy //------------------------------------------------------------------ - double target_dsp_freq = actual_inter_freq - tune_request.target_freq; + double target_dsp_freq = actual_rf_freq - tune_request.target_freq; //invert the sign on the dsp freq given the following conditions if (unit == dboard_iface::UNIT_TX) target_dsp_freq *= -1.0; @@ -96,8 +96,8 @@ static tune_result_t tune_xx_subdev_and_dsp( //-- load and return the tune result //------------------------------------------------------------------ tune_result_t tune_result; - tune_result.target_inter_freq = target_inter_freq; - tune_result.actual_inter_freq = actual_inter_freq; + tune_result.target_rf_freq = target_rf_freq; + tune_result.actual_rf_freq = actual_rf_freq; tune_result.target_dsp_freq = target_dsp_freq; tune_result.actual_dsp_freq = actual_dsp_freq; return tune_result; @@ -107,13 +107,13 @@ static double derive_freq_from_xx_subdev_and_dsp( dboard_iface::unit_t unit, wax::obj subdev, wax::obj dsp ){ //extract actual dsp and IF frequencies - double actual_inter_freq = subdev[SUBDEV_PROP_FREQ].as<double>(); + double actual_rf_freq = subdev[SUBDEV_PROP_FREQ].as<double>(); double actual_dsp_freq = dsp[DSP_PROP_FREQ_SHIFT].as<double>(); //invert the sign on the dsp freq given the following conditions if (unit == dboard_iface::UNIT_TX) actual_dsp_freq *= -1.0; - return actual_inter_freq - actual_dsp_freq; + return actual_rf_freq - actual_dsp_freq; } /*********************************************************************** 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/usrp1/usrp1_ctrl.cpp b/host/lib/usrp/usrp1/usrp1_ctrl.cpp index 22e9fd1ce..c6be28f5f 100644 --- a/host/lib/usrp/usrp1/usrp1_ctrl.cpp +++ b/host/lib/usrp/usrp1/usrp1_ctrl.cpp @@ -201,18 +201,19 @@ public: } void usrp_init(void){ - /* not calling because this causes junk to come at init - * and it does not seem to be necessary to call anyway + //disable usrp_rx_enable(false); - usrp_rx_reset(true); - usrp_rx_reset(false); - usrp_rx_enable(true); - */ - usrp_tx_enable(false); + + //toggle resets + usrp_rx_reset(true); usrp_tx_reset(true); + usrp_rx_reset(false); usrp_tx_reset(false); - usrp_tx_enable(true); + + //enable + //usrp_rx_enable(true); //dont enable, enable means dont work + //usrp_tx_enable(true); } void usrp_load_fpga(std::string filestring) @@ -234,6 +235,8 @@ public: throw uhd::io_error("usrp_load_fpga: cannot open fpga input file"); } + usrp_fpga_reset(true); //holding the fpga in reset while loading + if (usrp_control_write_cmd(VRQ_FPGA_LOAD, 0, FL_BEGIN) < 0) { throw uhd::io_error("usrp_load_fpga: fpga load error"); } @@ -252,6 +255,9 @@ public: } usrp_set_fpga_hash(hash); + + usrp_fpga_reset(false); //done loading, take fpga out of reset + file.close(); if (load_img_msg) std::cout << " done" << std::endl; } @@ -355,6 +361,10 @@ public: UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_RX_RESET, on, 0) >= 0); } + void usrp_fpga_reset(bool on) + { + UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_RESET, on, 0) >= 0); + } int usrp_control_write(boost::uint8_t request, boost::uint16_t value, diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 7705037dd..8582fca38 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -194,9 +194,25 @@ usrp2_mboard_impl::~usrp2_mboard_impl(void){ void usrp2_mboard_impl::update_clock_config(void){ boost::uint32_t pps_flags = 0; + //slave mode overrides clock config settings + if (not _mimo_clocking_mode_is_master){ + _clock_config.ref_source = clock_config_t::REF_MIMO; + _clock_config.pps_source = clock_config_t::PPS_MIMO; + } + //translate pps source enums switch(_clock_config.pps_source){ - case clock_config_t::PPS_SMA: pps_flags |= U2_FLAG_TIME64_PPS_SMA; break; + case clock_config_t::PPS_MIMO: + _iface->poke32(_iface->regs.time64_mimo_sync, + (1 << 8) | (mimo_clock_sync_delay_cycles & 0xff) + ); + break; + + case clock_config_t::PPS_SMA: + _iface->poke32(_iface->regs.time64_mimo_sync, 0); + pps_flags |= U2_FLAG_TIME64_PPS_SMA; + break; + default: throw uhd::value_error("unhandled clock configuration pps source"); } @@ -217,6 +233,7 @@ void usrp2_mboard_impl::update_clock_config(void){ switch(_clock_config.ref_source){ case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x12); break; case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; + case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break; default: throw uhd::value_error("unhandled clock configuration reference source"); } _clock_ctrl->enable_external_ref(true); //USRP2P has an internal 10MHz TCXO @@ -227,6 +244,7 @@ void usrp2_mboard_impl::update_clock_config(void){ switch(_clock_config.ref_source){ case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x10); break; case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; + case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break; default: throw uhd::value_error("unhandled clock configuration reference source"); } _clock_ctrl->enable_external_ref(_clock_config.ref_source != clock_config_t::REF_INT); @@ -235,12 +253,11 @@ void usrp2_mboard_impl::update_clock_config(void){ case usrp2_iface::USRP_NXXX: break; } - //Handle the serdes clocking based on master/slave mode: - // - Masters always drive the clock over serdes. - // - Slaves always lock to this serdes clock. - // - Slaves lock their time over the serdes. + //masters always drive the clock over serdes + _clock_ctrl->enable_mimo_clock_out(_mimo_clocking_mode_is_master); + + //set the mimo clock delay over the serdes if (_mimo_clocking_mode_is_master){ - _clock_ctrl->enable_mimo_clock_out(true); switch(_iface->get_rev()){ case usrp2_iface::USRP_N200: case usrp2_iface::USRP_N210: @@ -253,15 +270,6 @@ void usrp2_mboard_impl::update_clock_config(void){ default: break; //not handled } - _iface->poke32(_iface->regs.time64_mimo_sync, 0); - } - else{ - _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); - _clock_ctrl->enable_external_ref(true); - _clock_ctrl->enable_mimo_clock_out(false); - _iface->poke32(_iface->regs.time64_mimo_sync, - (1 << 8) | (mimo_clock_sync_delay_cycles & 0xff) - ); } } diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 2d1f901d7..9c3fb9268 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -165,7 +165,7 @@ struct mtu_result_t{ size_t recv_mtu, send_mtu; }; -static mtu_result_t determine_mtu(const std::string &addr){ +static mtu_result_t determine_mtu(const std::string &addr, const mtu_result_t &user_mtu){ udp_simple::sptr udp_sock = udp_simple::make_connected( addr, BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT) ); @@ -173,8 +173,8 @@ static mtu_result_t determine_mtu(const std::string &addr){ //The FPGA offers 4K buffers, and the user may manually request this. //However, multiple simultaneous receives (2DSP slave + 2DSP master), //require that buffering to be used internally, and this is a safe setting. - boost::uint8_t buffer[2000]; - usrp2_ctrl_data_t *ctrl_data = reinterpret_cast<usrp2_ctrl_data_t *>(buffer); + std::vector<boost::uint8_t> buffer(std::max(user_mtu.recv_mtu, user_mtu.send_mtu)); + usrp2_ctrl_data_t *ctrl_data = reinterpret_cast<usrp2_ctrl_data_t *>(&buffer.front()); static const double echo_timeout = 0.020; //20 ms //test holler - check if its supported in this fw version @@ -186,8 +186,8 @@ static mtu_result_t determine_mtu(const std::string &addr){ if (ntohl(ctrl_data->id) != USRP2_CTRL_ID_HOLLER_BACK_DUDE) throw uhd::not_implemented_error("holler protocol not implemented"); - size_t min_recv_mtu = sizeof(usrp2_ctrl_data_t), max_recv_mtu = sizeof(buffer); - size_t min_send_mtu = sizeof(usrp2_ctrl_data_t), max_send_mtu = sizeof(buffer); + size_t min_recv_mtu = sizeof(usrp2_ctrl_data_t), max_recv_mtu = user_mtu.recv_mtu; + size_t min_send_mtu = sizeof(usrp2_ctrl_data_t), max_send_mtu = user_mtu.send_mtu; while (min_recv_mtu < max_recv_mtu){ @@ -248,19 +248,20 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){ device_addrs_t device_args = separate_device_addr(device_addr); + //extract the user's requested MTU size or default + mtu_result_t user_mtu; + user_mtu.recv_mtu = size_t(device_addr.cast<double>("recv_frame_size", udp_simple::mtu)); + user_mtu.send_mtu = size_t(device_addr.cast<double>("recv_frame_size", udp_simple::mtu)); + try{ //calculate the minimum send and recv mtu of all devices - mtu_result_t mtu = determine_mtu(device_args[0]["addr"]); + mtu_result_t mtu = determine_mtu(device_args[0]["addr"], user_mtu); for (size_t i = 1; i < device_args.size(); i++){ - mtu_result_t mtu_i = determine_mtu(device_args[i]["addr"]); + mtu_result_t mtu_i = determine_mtu(device_args[i]["addr"], user_mtu); mtu.recv_mtu = std::min(mtu.recv_mtu, mtu_i.recv_mtu); mtu.send_mtu = std::min(mtu.send_mtu, mtu_i.send_mtu); } - //use the discovered mtu or clip the users requested mtu - mtu.recv_mtu = std::min(size_t(device_addr.cast<double>("recv_frame_size", 9000)), mtu.recv_mtu); - mtu.send_mtu = std::min(size_t(device_addr.cast<double>("send_frame_size", 9000)), mtu.send_mtu); - device_addr["recv_frame_size"] = boost::lexical_cast<std::string>(mtu.recv_mtu); device_addr["send_frame_size"] = boost::lexical_cast<std::string>(mtu.send_mtu); diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp index 1ac2b804c..2e3eb5cb9 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 (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_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; |