From 5c6c179689ef76ccd25d09ac4faeb9a836a066c8 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 1 May 2011 17:26:15 -0700 Subject: usrp-e100: add ability to set/get default master clock rate from EEPROM Mboard eeprom map class can parse the setting (4 byte float). The clock control will try to set the eeprom rate if present, otherwise or under failure condition, it sets the default. Updated docs, example, and provided helpful verbose. I would prefer that users burn the desired rate to the eeprom (and they may too). --- host/docs/usrp_e1xx.rst | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'host/docs') 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 /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 /share/uhd/utils + ./usrp_burn_mb_eeprom --key=master_clock_rate --val= ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Clock rate recovery - unbricking -- cgit v1.2.3 From 6f0a98ee2e9e2090c6bf7d56260cb95b0eb1fbb3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 1 May 2011 18:21:29 -0700 Subject: 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) --- host/docs/usrp1.rst | 9 ++++++-- host/docs/usrp_e1xx.rst | 8 +++---- host/lib/usrp/mboard_eeprom.cpp | 42 +++++++++++++++++++++++++++++----- host/lib/usrp/usrp1/clock_ctrl.cpp | 14 ++++++++++++ host/lib/usrp/usrp1/mboard_impl.cpp | 4 ++++ host/lib/usrp/usrp_e100/clock_ctrl.cpp | 4 ++-- 6 files changed, 67 insertions(+), 14 deletions(-) (limited to 'host/docs') 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 /share/uhd/utils + ./usrp_burn_mb_eeprom --args= --key=mcr --val= 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 /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 /share/uhd/utils - ./usrp_burn_mb_eeprom --key=master_clock_rate --val= + ./usrp_burn_mb_eeprom --key=mcr --val= ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 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(&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(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(mb_eeprom["mcr"])); + master_clock_rate = htonl(master_clock_rate); + const byte_vector_t rate_bytes( + reinterpret_cast(&master_clock_rate), + reinterpret_cast(&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 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(&master_clock_rate) //destination ); if (master_clock_rate > 1e6 and master_clock_rate < 1e9){ - mb_eeprom["master_clock_rate"] = boost::lexical_cast(master_clock_rate); + mb_eeprom["mcr"] = boost::lexical_cast(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(mb_eeprom["master_clock_rate"])); + if (mb_eeprom.has_key("mcr")){ + const float master_clock_rate = float(boost::lexical_cast(mb_eeprom["mcr"])); const byte_vector_t rate_bytes( reinterpret_cast(&master_clock_rate), reinterpret_cast(&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 +#include +#include 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(_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()); 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(_iface->mb_eeprom["master_clock_rate"]); + const double master_clock_rate = boost::lexical_cast(_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; -- cgit v1.2.3 From cbf580374dbc131febdd7f65efc65879ee3842ac Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Mon, 2 May 2011 15:38:55 -0700 Subject: Added RSSI sensor for RFX series (not rfx400) --- host/docs/dboards.rst | 1 + host/lib/usrp/dboard/db_rfx.cpp | 35 +++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) (limited to 'host/docs') diff --git a/host/docs/dboards.rst b/host/docs/dboards.rst index 373189441..402f0cd8c 100644 --- a/host/docs/dboards.rst +++ b/host/docs/dboards.rst @@ -130,6 +130,7 @@ Bandwidths (Hz): Sensors: * **lo_locked**: boolean for LO lock state +* **rssi**: float for rssi in dBm ^^^^^^^^^^^^^^^^^^^^^^^^^^^ XCVR 2450 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: -- cgit v1.2.3 From 4c6394f1dc4529f84febb3c02e2db9319c061003 Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Mon, 2 May 2011 16:51:02 -0700 Subject: Added docs for sbx --- host/docs/dboards.rst | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'host/docs') diff --git a/host/docs/dboards.rst b/host/docs/dboards.rst index 373189441..d9f8069ad 100644 --- a/host/docs/dboards.rst +++ b/host/docs/dboards.rst @@ -203,6 +203,45 @@ Sensors: * **lo_locked**: boolean for LO lock state +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +SBX Series +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The SBX Series boards have 2 quadrature subdevices, one transmit, one receive. +Transmit and Receive default to direct conversion but +can be used in low IF mode through lo_offset in uhd::tune_request_t + +The SBX Series boards have independent receive and transmit LO's and synthesizers +allowing full-duplex operation on different transmit and receive frequencies. + +Transmit Antennas: **TX/RX** + +Receive Antennas: **TX/RX** or **RX2** + +The user may set the receive antenna to be TX/RX or RX2. +However, when using an SBX board in full-duplex mode, +the receive antenna will always be set to RX2, regardless of the settings. + +Transmit Gains: **PGA0**, Range: 0-31.5dB + +Receive Gains: **PGA0**, Range: 0-31.5dB + +Bandwidths (Hz): + +* **RX**: 40M +* **TX**: 40M + +Sensors: + +* **lo_locked**: boolean for LO lock state + +LEDs: + +* All LEDs flash when dboard control is initialized +* **TX LD**: Transmit Synthesizer Lock Detect +* **TX/RX**: Receiver on TX/RX antenna port (No TX) +* **RX LD**: Receive Synthesizer Lock Detect +* **RX1/RX2**: Receiver on RX2 antenna port + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ TVRX ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- cgit v1.2.3