aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/b200/b200_iface.cpp183
-rw-r--r--host/lib/usrp/b200/b200_iface.hpp45
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp60
-rw-r--r--host/lib/usrp/b200/b200_impl.hpp9
-rw-r--r--host/lib/usrp/b200/b200_io_impl.cpp3
-rw-r--r--host/lib/usrp/b200/b200_regs.hpp2
-rw-r--r--host/lib/usrp/common/adf4001_ctrl.cpp8
-rw-r--r--host/lib/usrp/cores/time_core_3000.cpp13
-rw-r--r--host/lib/usrp/cores/time_core_3000.hpp2
-rw-r--r--host/lib/usrp/e300/e300_fpga_defs.hpp2
-rw-r--r--host/lib/usrp/e300/e300_impl.cpp27
-rw-r--r--host/lib/usrp/e300/e300_impl.hpp5
-rw-r--r--host/lib/usrp/x300/x300_fw_common.h2
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp12
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp1
-rw-r--r--host/lib/usrp/x300/x300_regs.hpp2
16 files changed, 157 insertions, 219 deletions
diff --git a/host/lib/usrp/b200/b200_iface.cpp b/host/lib/usrp/b200/b200_iface.cpp
index 4754a6357..207c418fc 100644
--- a/host/lib/usrp/b200/b200_iface.cpp
+++ b/host/lib/usrp/b200/b200_iface.cpp
@@ -17,6 +17,7 @@
#include "b200_iface.hpp"
+#include "../../utils/ihex.hpp"
#include <uhd/config.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/utils/log.hpp>
@@ -87,7 +88,7 @@ typedef boost::uint32_t hash_type;
**********************************************************************/
/*!
* Create a file hash
- * The hash will be used to identify the loaded firmware and fpga image
+ * The hash will be used to identify the loaded fpga image
* \param filename file used to generate hash value
* \return hash value in a uint32_t type
*/
@@ -125,66 +126,6 @@ static hash_type generate_hash(const char *filename)
}
-/*!
- * Verify checksum of a Intel HEX record
- * \param record a line from an Intel HEX file
- * \return true if record is valid, false otherwise
- */
-bool checksum(const std::string& record) {
-
- size_t len = record.length();
- unsigned int i;
- unsigned char sum = 0;
- unsigned int val;
-
- for (i = 1; i < len; i += 2) {
- std::istringstream(record.substr(i, 2)) >> std::hex >> val;
- sum += val;
- }
-
- if (sum == 0)
- return true;
- else
- return false;
-}
-
-
-/*!
- * Parse Intel HEX record
- *
- * \param record a line from an Intel HEX file
- * \param len output length of record
- * \param addr output address
- * \param type output type
- * \param data output data
- * \return true if record is sucessfully read, false on error
- */
-bool parse_record(const std::string& record, boost::uint16_t &len, \
- boost::uint16_t &addr, boost::uint16_t &type, unsigned char* data) {
-
- unsigned int i;
- std::string _data;
- unsigned int val;
-
- if (record.substr(0, 1) != ":")
- return false;
-
- std::istringstream(record.substr(1, 2)) >> std::hex >> len;
- std::istringstream(record.substr(3, 4)) >> std::hex >> addr;
- std::istringstream(record.substr(7, 2)) >> std::hex >> type;
-
- if (len > (2 * (record.length() - 9))) // sanity check to prevent buffer overrun
- return false;
-
- for (i = 0; i < len; i++) {
- std::istringstream(record.substr(9 + 2 * i, 2)) >> std::hex >> val;
- data[i] = (unsigned char) val;
- }
-
- return true;
-}
-
-
/***********************************************************************
* The implementation class
**********************************************************************/
@@ -270,109 +211,31 @@ public:
void load_firmware(const std::string filestring, UHD_UNUSED(bool force) = false)
{
- const char *filename = filestring.c_str();
-
- /* Fields used in each USB control transfer. */
- boost::uint16_t len = 0;
- boost::uint16_t type = 0;
- boost::uint16_t lower_address_bits = 0x0000;
- unsigned char data[512];
-
- /* Can be set by the Intel HEX record 0x04, used for all 0x00 records
- * thereafter. Note this field takes the place of the 'index' parameter in
- * libusb calls, and is necessary for FX3's 32-bit addressing. */
- boost::uint16_t upper_address_bits = 0x0000;
-
- std::ifstream file;
- file.open(filename, std::ifstream::in);
-
- if(!file.good()) {
- throw uhd::io_error("fx3_load_firmware: cannot open firmware input file");
+ if (load_img_msg)
+ UHD_MSG(status) << "Loading firmware image: "
+ << filestring << "..." << std::flush;
+
+ ihex_reader file_reader(filestring);
+ try {
+ file_reader.read(
+ boost::bind(
+ &b200_iface_impl::fx3_control_write, this,
+ FX3_FIRMWARE_LOAD, _1, _2, _3, _4, 0
+ )
+ );
+ } catch (const uhd::io_error &e) {
+ throw uhd::io_error(str(boost::format("Could not load firmware: \n%s") % e.what()));
}
- if (load_img_msg) UHD_MSG(status) << "Loading firmware image: " \
- << filestring << "..." << std::flush;
-
- while (!file.eof()) {
- boost::int32_t ret = 0;
- std::string record;
- file >> record;
-
- if (!(record.length() > 0))
- continue;
-
- /* Check for valid Intel HEX record. */
- if (!checksum(record) || !parse_record(record, len, \
- lower_address_bits, type, data)) {
- throw uhd::io_error("fx3_load_firmware: bad intel hex record checksum");
- }
-
- /* Type 0x00: Data. */
- if (type == 0x00) {
- ret = fx3_control_write(FX3_FIRMWARE_LOAD, \
- lower_address_bits, upper_address_bits, data, len);
-
- if (ret < 0) {
- throw uhd::io_error("usrp_load_firmware: usrp_control_write failed");
- }
- }
-
- /* Type 0x01: EOF. */
- else if (type == 0x01) {
- if (lower_address_bits != 0x0000 || len != 0 ) {
- throw uhd::io_error("fx3_load_firmware: For EOF record, address must be 0, length must be 0.");
- }
-
- //TODO
- //usrp_set_firmware_hash(hash); //set hash before reset
-
- /* Successful termination! */
- file.close();
+ UHD_MSG(status) << std::endl;
- /* Let the system settle. */
- boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
- return;
- }
-
- /* Type 0x04: Extended Linear Address Record. */
- else if (type == 0x04) {
- if (lower_address_bits != 0x0000 || len != 2 ) {
- throw uhd::io_error("fx3_load_firmware: For ELA record, address must be 0, length must be 2.");
- }
-
- upper_address_bits = ((boost::uint16_t)((data[0] & 0x00FF) << 8))\
- + ((boost::uint16_t)(data[1] & 0x00FF));
- }
-
- /* Type 0x05: Start Linear Address Record. */
- else if (type == 0x05) {
- if (lower_address_bits != 0x0000 || len != 4 ) {
- throw uhd::io_error("fx3_load_firmware: For SLA record, address must be 0, length must be 4.");
- }
-
- /* The firmware load is complete. We now need to tell the CPU
- * to jump to an execution address start point, now contained within
- * the data field. Parse these address bits out, and then push the
- * instruction. */
- upper_address_bits = ((boost::uint16_t)((data[0] & 0x00FF) << 8))\
- + ((boost::uint16_t)(data[1] & 0x00FF));
- lower_address_bits = ((boost::uint16_t)((data[2] & 0x00FF) << 8))\
- + ((boost::uint16_t)(data[3] & 0x00FF));
-
- fx3_control_write(FX3_FIRMWARE_LOAD, lower_address_bits, \
- upper_address_bits, 0, 0);
-
- if (load_img_msg) UHD_MSG(status) << " done" << std::endl;
- }
-
- /* If we receive an unknown record type, error out. */
- else {
- throw uhd::io_error("fx3_load_firmware: unsupported record type.");
- }
- }
+ //TODO
+ //usrp_set_firmware_hash(hash); //set hash before reset
- /* There was no valid EOF. */
- throw uhd::io_error("fx3_load_firmware: No EOF record found.");
+ /* Success! Let the system settle. */
+ // TODO: Replace this with a polling loop in the FX3, or find out
+ // what the actual, correct timeout value is.
+ boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
}
void reset_fx3(void) {
diff --git a/host/lib/usrp/b200/b200_iface.hpp b/host/lib/usrp/b200/b200_iface.hpp
index 19ec561fa..e45c78d49 100644
--- a/host/lib/usrp/b200/b200_iface.hpp
+++ b/host/lib/usrp/b200/b200_iface.hpp
@@ -30,25 +30,28 @@
enum b200_product_t {
B200,
B210,
- B205
+ B200MINI,
+ B205MINI
};
// These are actual USB PIDs (not Ettus Product IDs)
-const static boost::uint16_t B200_VENDOR_ID = 0x2500;
-const static boost::uint16_t B200_VENDOR_NI_ID = 0x3923;
-const static boost::uint16_t B200_PRODUCT_ID = 0x0020;
-const static boost::uint16_t B205_PRODUCT_ID = 0x0021;
-const static boost::uint16_t B200_PRODUCT_NI_ID = 0x7813;
-const static boost::uint16_t B210_PRODUCT_NI_ID = 0x7814;
-const static boost::uint16_t FX3_VID = 0x04b4;
-const static boost::uint16_t FX3_DEFAULT_PID = 0x00f3;
-const static boost::uint16_t FX3_REENUM_PID = 0x00f0;
+const static boost::uint16_t B200_VENDOR_ID = 0x2500;
+const static boost::uint16_t B200_VENDOR_NI_ID = 0x3923;
+const static boost::uint16_t B200_PRODUCT_ID = 0x0020;
+const static boost::uint16_t B200MINI_PRODUCT_ID = 0x0021;
+const static boost::uint16_t B205MINI_PRODUCT_ID = 0x0022;
+const static boost::uint16_t B200_PRODUCT_NI_ID = 0x7813;
+const static boost::uint16_t B210_PRODUCT_NI_ID = 0x7814;
+const static boost::uint16_t FX3_VID = 0x04b4;
+const static boost::uint16_t FX3_DEFAULT_PID = 0x00f3;
+const static boost::uint16_t FX3_REENUM_PID = 0x00f0;
//! Map the USB PID to the product (only for PIDs that map to a single product)
static const uhd::dict<boost::uint16_t, b200_product_t> B2XX_PID_TO_PRODUCT = boost::assign::map_list_of
- (B200_PRODUCT_NI_ID, B200)
- (B210_PRODUCT_NI_ID, B210)
- (B205_PRODUCT_ID, B205)
+ (B200_PRODUCT_NI_ID, B200)
+ (B210_PRODUCT_NI_ID, B210)
+ (B200MINI_PRODUCT_ID, B200MINI)
+ (B205MINI_PRODUCT_ID, B205MINI)
;
static const std::string B200_FW_FILE_NAME = "usrp_b200_fw.hex";
@@ -61,21 +64,25 @@ static const uhd::dict<boost::uint16_t, b200_product_t> B2XX_PRODUCT_ID = boost:
(0x0002, B210)
(0x7738, B210)
(B210_PRODUCT_NI_ID, B210)
- (0x0003, B205)
- (0x7739, B205)
+ (0x0003, B200MINI)
+ (0x7739, B200MINI)
+ (0x0004, B205MINI)
+ (0x773a, B205MINI)
;
static const uhd::dict<b200_product_t, std::string> B2XX_STR_NAMES = boost::assign::map_list_of
- (B200, "B200")
- (B210, "B210")
- (B205, "B200mini")
+ (B200, "B200")
+ (B210, "B210")
+ (B200MINI, "B200mini")
+ (B205MINI, "B205mini")
;
static const uhd::dict<b200_product_t, std::string> B2XX_FPGA_FILE_NAME = boost::assign::map_list_of
(B200, "usrp_b200_fpga.bin")
(B210, "usrp_b210_fpga.bin")
- (B205, "usrp_b200mini_fpga.bin")
+ (B200MINI, "usrp_b200mini_fpga.bin")
+ (B205MINI, "usrp_b205mini_fpga.bin")
;
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index 3aaf28ab3..62690f09f 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -75,9 +75,9 @@ public:
};
// B205
-class b205_ad9361_client_t : public ad9361_params {
+class b2xxmini_ad9361_client_t : public ad9361_params {
public:
- ~b205_ad9361_client_t() {}
+ ~b2xxmini_ad9361_client_t() {}
double get_band_edge(frequency_band_t band) {
switch (band) {
case AD9361_RX_BAND0: return 0; // Set these all to
@@ -319,7 +319,8 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
else if (specified_vid)
{
vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B200_PRODUCT_ID));
- vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B205_PRODUCT_ID));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B200MINI_PRODUCT_ID));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B205MINI_PRODUCT_ID));
vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B200_PRODUCT_NI_ID));
vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid, B210_PRODUCT_NI_ID));
}
@@ -333,7 +334,8 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
else
{
vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200_PRODUCT_ID));
- vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B205_PRODUCT_ID));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200MINI_PRODUCT_ID));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B205MINI_PRODUCT_ID));
vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID));
vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID));
}
@@ -387,7 +389,7 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
UHD_MSG(status) << "Detected Device: " << B2XX_STR_NAMES[_product] << std::endl;
- _gpsdo_capable = (_product != B205);
+ _gpsdo_capable = (not (_product == B200MINI or _product == B205MINI));
////////////////////////////////////////////////////////////////////
// Set up frontend mapping
@@ -406,7 +408,7 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
_fe2 = 0;
_gpio_state.swap_atr = 1;
// Unswapped setup:
- if (_product == B205 or (_product == B200 and _revision >= 5)) {
+ if (_product == B200MINI or _product == B205MINI or (_product == B200 and _revision >= 5)) {
_fe1 = 0; //map radio0 to FE1
_fe2 = 1; //map radio1 to FE2
_gpio_state.swap_atr = 0; // ATRs for radio0 are mapped to FE1
@@ -513,7 +515,7 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
////////////////////////////////////////////////////////////////////
_tree->create<std::string>("/name").set("B-Series Device");
_tree->create<std::string>(mb_path / "name").set(product_name);
- _tree->create<std::string>(mb_path / "codename").set((_product == B205) ? "Pixie" : "Sasquatch");
+ _tree->create<std::string>(mb_path / "codename").set((_product == B200MINI or _product == B205MINI) ? "Pixie" : "Sasquatch");
////////////////////////////////////////////////////////////////////
// Create data transport
@@ -541,7 +543,7 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
// create time and clock control objects
////////////////////////////////////////////////////////////////////
_spi_iface = b200_local_spi_core::make(_local_ctrl);
- if (_product != B205) {
+ if (not (_product == B200MINI or _product == B205MINI)) {
_adf4001_iface = boost::make_shared<b200_ref_pll_ctrl>(_spi_iface);
}
@@ -550,13 +552,13 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
////////////////////////////////////////////////////////////////////
UHD_MSG(status) << "Initialize CODEC control..." << std::endl;
ad9361_params::sptr client_settings;
- if (_product == B205) {
- client_settings = boost::make_shared<b205_ad9361_client_t>();
+ if (_product == B200MINI or _product == B205MINI) {
+ client_settings = boost::make_shared<b2xxmini_ad9361_client_t>();
} else {
client_settings = boost::make_shared<b200_ad9361_client_t>();
}
_codec_ctrl = ad9361_ctrl::make_spi(client_settings, _spi_iface, AD9361_SLAVENO);
-
+
////////////////////////////////////////////////////////////////////
// create codec control objects
////////////////////////////////////////////////////////////////////
@@ -624,15 +626,18 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
//register time now and pps onto available radio cores
_tree->create<time_spec_t>(mb_path / "time" / "now")
- .publish(boost::bind(&time_core_3000::get_time_now, _radio_perifs[0].time64));
+ .publish(boost::bind(&time_core_3000::get_time_now, _radio_perifs[0].time64))
+ .subscribe(boost::bind(&b200_impl::set_time, this, _1))
+ .set(0.0);
+ //re-sync the times when the tick rate changes
+ _tree->access<double>(mb_path / "tick_rate")
+ .subscribe(boost::bind(&b200_impl::sync_times, this));
_tree->create<time_spec_t>(mb_path / "time" / "pps")
.publish(boost::bind(&time_core_3000::get_time_last_pps, _radio_perifs[0].time64));
- for (size_t i = 0; i < _radio_perifs.size(); i++)
+ BOOST_FOREACH(radio_perifs_t &perif, _radio_perifs)
{
- _tree->access<time_spec_t>(mb_path / "time" / "now")
- .subscribe(boost::bind(&time_core_3000::set_time_now, _radio_perifs[i].time64, _1));
_tree->access<time_spec_t>(mb_path / "time" / "pps")
- .subscribe(boost::bind(&time_core_3000::set_time_next_pps, _radio_perifs[i].time64, _1));
+ .subscribe(boost::bind(&time_core_3000::set_time_next_pps, perif.time64, _1));
}
//setup time source props
@@ -945,7 +950,7 @@ void b200_impl::check_fpga_compat(void)
if (signature != 0xACE0BA5E) throw uhd::runtime_error(
"b200::check_fpga_compat signature register readback failed");
- const boost::uint16_t expected = (_product == B205 ? B205_FPGA_COMPAT_NUM : B200_FPGA_COMPAT_NUM);
+ const boost::uint16_t expected = ((_product == B200MINI or _product == B205MINI) ? B205_FPGA_COMPAT_NUM : B200_FPGA_COMPAT_NUM);
if (compat_major != expected)
{
throw uhd::runtime_error(str(boost::format(
@@ -970,7 +975,7 @@ void b200_impl::set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &mb_eeprom)
void b200_impl::update_clock_source(const std::string &source)
{
// For B205, ref_sel selects whether or not to lock to the external clock source
- if (_product == B205)
+ if (_product == B200MINI or _product == B205MINI)
{
if (source == "external" and _time_source == EXTERNAL)
{
@@ -1032,7 +1037,7 @@ void b200_impl::update_clock_source(const std::string &source)
void b200_impl::update_time_source(const std::string &source)
{
- if (_product == B205 and source == "external" and _gpio_state.ref_sel == 1)
+ if ((_product == B200MINI or _product == B205MINI) and source == "external" and _gpio_state.ref_sel == 1)
{
throw uhd::value_error("external reference cannot be both a time source and a clock source");
}
@@ -1052,11 +1057,24 @@ void b200_impl::update_time_source(const std::string &source)
throw uhd::key_error("update_time_source: unknown source: " + source);
if (_time_source != value)
{
- _local_ctrl->poke32(TOREG(SR_CORE_PPS_SEL), value);
+ _local_ctrl->poke32(TOREG(SR_CORE_SYNC), value);
_time_source = value;
}
}
+void b200_impl::set_time(const uhd::time_spec_t& t)
+{
+ BOOST_FOREACH(radio_perifs_t &perif, _radio_perifs)
+ perif.time64->set_time_sync(t);
+ _local_ctrl->poke32(TOREG(SR_CORE_SYNC), 1 << 2 | boost::uint32_t(_time_source));
+ _local_ctrl->poke32(TOREG(SR_CORE_SYNC), _time_source);
+}
+
+void b200_impl::sync_times()
+{
+ set_time(_radio_perifs[0].time64->get_time_now());
+}
+
/***********************************************************************
* GPIO setup
**********************************************************************/
@@ -1064,7 +1082,7 @@ void b200_impl::update_time_source(const std::string &source)
void b200_impl::update_bandsel(const std::string& which, double freq)
{
// B205 does not have bandsels
- if (_product == B205) {
+ if (_product == B200MINI or _product == B205MINI) {
return;
}
diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp
index b406572fb..08ae68e9a 100644
--- a/host/lib/usrp/b200/b200_impl.hpp
+++ b/host/lib/usrp/b200/b200_impl.hpp
@@ -49,8 +49,8 @@
#include "recv_packet_demuxer_3000.hpp"
static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 8;
static const boost::uint8_t B200_FW_COMPAT_NUM_MINOR = 0;
-static const boost::uint16_t B200_FPGA_COMPAT_NUM = 12;
-static const boost::uint16_t B205_FPGA_COMPAT_NUM = 3;
+static const boost::uint16_t B200_FPGA_COMPAT_NUM = 13;
+static const boost::uint16_t B205_FPGA_COMPAT_NUM = 4;
static const double B200_BUS_CLOCK_RATE = 100e6;
static const boost::uint32_t B200_GPSDO_ST_NONE = 0x83;
static const size_t B200_MAX_RATE_USB2 = 53248000; // bytes/s
@@ -95,7 +95,8 @@ static const unsigned char B200_USB_DATA_SEND_ENDPOINT = 2;
static std::vector<uhd::transport::usb_device_handle::vid_pid_pair_t> b200_vid_pid_pairs =
boost::assign::list_of
(uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200_PRODUCT_ID))
- (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B205_PRODUCT_ID))
+ (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200MINI_PRODUCT_ID))
+ (uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B205MINI_PRODUCT_ID))
(uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID))
(uhd::transport::usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID))
;
@@ -167,6 +168,8 @@ private:
uhd::usrp::subdev_spec_t coerce_subdev_spec(const uhd::usrp::subdev_spec_t &);
void update_subdev_spec(const std::string &tx_rx, const uhd::usrp::subdev_spec_t &);
void update_time_source(const std::string &);
+ void set_time(const uhd::time_spec_t&);
+ void sync_times(void);
void update_clock_source(const std::string &);
void update_bandsel(const std::string& which, double freq);
void update_antenna_sel(const size_t which, const std::string &ant);
diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp
index 41b4b8a74..279901208 100644
--- a/host/lib/usrp/b200/b200_io_impl.cpp
+++ b/host/lib/usrp/b200/b200_io_impl.cpp
@@ -227,7 +227,8 @@ uhd::usrp::subdev_spec_t b200_impl::coerce_subdev_spec(const uhd::usrp::subdev_s
//
// Any other spec is probably illegal and will be caught by
// validate_subdev_spec().
- if (spec.size() and (_product == B200 or _product == B205) and spec[0].sd_name == "B") {
+ if (spec.size() and (_product == B200 or _product == B200MINI or _product == B205MINI) and spec[0].sd_name == "B")
+ {
spec[0].sd_name = "A";
}
return spec;
diff --git a/host/lib/usrp/b200/b200_regs.hpp b/host/lib/usrp/b200/b200_regs.hpp
index 8f2dd03f3..e9ab81bae 100644
--- a/host/lib/usrp/b200/b200_regs.hpp
+++ b/host/lib/usrp/b200/b200_regs.hpp
@@ -28,7 +28,7 @@ localparam SR_CORE_SPI = 8;
localparam SR_CORE_MISC = 16;
localparam SR_CORE_COMPAT = 24;
localparam SR_CORE_GPSDO_ST = 40;
-localparam SR_CORE_PPS_SEL = 48;
+localparam SR_CORE_SYNC = 48;
localparam RB32_CORE_SPI = 8;
localparam RB32_CORE_MISC = 16;
localparam RB32_CORE_STATUS = 20;
diff --git a/host/lib/usrp/common/adf4001_ctrl.cpp b/host/lib/usrp/common/adf4001_ctrl.cpp
index a7510c272..001b68b7a 100644
--- a/host/lib/usrp/common/adf4001_ctrl.cpp
+++ b/host/lib/usrp/common/adf4001_ctrl.cpp
@@ -81,7 +81,7 @@ boost::uint32_t adf4001_regs_t::get_reg(boost::uint8_t addr) {
reg |= (boost::uint32_t(timer_counter_control) & 0x00000F) << 11;
reg |= (boost::uint32_t(charge_pump_current_1) & 0x000007) << 15;
reg |= (boost::uint32_t(charge_pump_current_2) & 0x000007) << 18;
- reg |= (boost::uint32_t(power_down) & 0x000002) << 21;
+ reg |= (boost::uint32_t(power_down) & 0x000002) << 20;
break;
default:
break;
@@ -128,15 +128,15 @@ void adf4001_ctrl::set_lock_to_ext_ref(bool external) {
void adf4001_ctrl::program_regs(void) {
//no control over CE, only LE, therefore we use the initialization latch method
write_reg(3);
- boost::this_thread::sleep(boost::posix_time::microseconds(1));
+
+ //conduct a function latch (2)
+ write_reg(2);
//write R counter latch (0)
write_reg(0);
- boost::this_thread::sleep(boost::posix_time::microseconds(1));
//write N counter latch (1)
write_reg(1);
- boost::this_thread::sleep(boost::posix_time::microseconds(1));
}
diff --git a/host/lib/usrp/cores/time_core_3000.cpp b/host/lib/usrp/cores/time_core_3000.cpp
index ffae5dc0d..694edf31c 100644
--- a/host/lib/usrp/cores/time_core_3000.cpp
+++ b/host/lib/usrp/cores/time_core_3000.cpp
@@ -24,8 +24,9 @@
#define REG_TIME_LO _base + 4
#define REG_TIME_CTRL _base + 8
-#define CTRL_LATCH_TIME_PPS (1 << 1)
-#define CTRL_LATCH_TIME_NOW (1 << 0)
+#define CTRL_LATCH_TIME_NOW (1 << 0)
+#define CTRL_LATCH_TIME_PPS (1 << 1)
+#define CTRL_LATCH_TIME_SYNC (1 << 2)
using namespace uhd;
@@ -99,6 +100,14 @@ struct time_core_3000_impl : time_core_3000
_iface->poke32(REG_TIME_CTRL, CTRL_LATCH_TIME_NOW);
}
+ void set_time_sync(const uhd::time_spec_t &time)
+ {
+ const boost::uint64_t ticks = time.to_ticks(_tick_rate);
+ _iface->poke32(REG_TIME_HI, boost::uint32_t(ticks >> 32));
+ _iface->poke32(REG_TIME_LO, boost::uint32_t(ticks >> 0));
+ _iface->poke32(REG_TIME_CTRL, CTRL_LATCH_TIME_SYNC);
+ }
+
void set_time_next_pps(const uhd::time_spec_t &time)
{
const boost::uint64_t ticks = time.to_ticks(_tick_rate);
diff --git a/host/lib/usrp/cores/time_core_3000.hpp b/host/lib/usrp/cores/time_core_3000.hpp
index 7463386ba..7dde4e797 100644
--- a/host/lib/usrp/cores/time_core_3000.hpp
+++ b/host/lib/usrp/cores/time_core_3000.hpp
@@ -53,6 +53,8 @@ public:
virtual void set_time_now(const uhd::time_spec_t &time) = 0;
+ virtual void set_time_sync(const uhd::time_spec_t &time) = 0;
+
virtual void set_time_next_pps(const uhd::time_spec_t &time) = 0;
};
diff --git a/host/lib/usrp/e300/e300_fpga_defs.hpp b/host/lib/usrp/e300/e300_fpga_defs.hpp
index dcfb05021..594461518 100644
--- a/host/lib/usrp/e300/e300_fpga_defs.hpp
+++ b/host/lib/usrp/e300/e300_fpga_defs.hpp
@@ -21,7 +21,7 @@ namespace uhd { namespace usrp { namespace e300 { namespace fpga {
static const size_t NUM_RADIOS = 2;
-static const boost::uint32_t COMPAT_MAJOR = 13;
+static const boost::uint32_t COMPAT_MAJOR = 14;
static const boost::uint32_t COMPAT_MINOR = 0;
}}}} // namespace
diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp
index c82ab3d0e..3242a7fe8 100644
--- a/host/lib/usrp/e300/e300_impl.cpp
+++ b/host/lib/usrp/e300/e300_impl.cpp
@@ -175,7 +175,7 @@ device_addrs_t e300_find(const device_addr_t &multi_dev_hint)
device_addr_t new_hint = hint;
new_hint["addr"] = if_addrs.bcast;
- // call discover with the new hint ad append results
+ // call discover with the new hint and append results
device_addrs_t new_e300_addrs = e300_find(new_hint);
e300_addrs.insert(e300_addrs.begin(),
new_e300_addrs.begin(), new_e300_addrs.end());
@@ -529,8 +529,11 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr)
////////////////////////////////////////////////////////////////////
_tree->create<time_spec_t>(mb_path / "time" / "now")
.publish(boost::bind(&time_core_3000::get_time_now, _radio_perifs[0].time64))
- .subscribe(boost::bind(&time_core_3000::set_time_now, _radio_perifs[0].time64, _1))
- .subscribe(boost::bind(&time_core_3000::set_time_now, _radio_perifs[1].time64, _1));
+ .subscribe(boost::bind(&e300_impl::_set_time, this, _1))
+ .set(0.0);
+ //re-sync the times when the tick rate changes
+ _tree->access<double>(mb_path / "tick_rate")
+ .subscribe(boost::bind(&e300_impl::_sync_times, this));
_tree->create<time_spec_t>(mb_path / "time" / "pps")
.publish(boost::bind(&time_core_3000::get_time_last_pps, _radio_perifs[0].time64))
.subscribe(boost::bind(&time_core_3000::set_time_next_pps, _radio_perifs[0].time64, _1))
@@ -796,6 +799,21 @@ void e300_impl::_update_time_source(const std::string &source)
_update_gpio_state();
}
+void e300_impl::_set_time(const uhd::time_spec_t& t)
+{
+ BOOST_FOREACH(radio_perifs_t &perif, _radio_perifs)
+ perif.time64->set_time_sync(t);
+ _misc.time_sync = 1;
+ _update_gpio_state();
+ _misc.time_sync = 0;
+ _update_gpio_state();
+}
+
+void e300_impl::_sync_times()
+{
+ _set_time(_radio_perifs[0].time64->get_time_now());
+}
+
size_t e300_impl::_get_axi_dma_channel(
boost::uint8_t destination,
boost::uint8_t prefix)
@@ -1081,7 +1099,8 @@ void e300_impl::_update_gpio_state(void)
| (_misc.tx_bandsels << gpio_t::TX_BANDSEL)
| (_misc.rx_bandsel_a << gpio_t::RX_BANDSELA)
| (_misc.rx_bandsel_b << gpio_t::RX_BANDSELB)
- | (_misc.rx_bandsel_c << gpio_t::RX_BANDSELC);
+ | (_misc.rx_bandsel_c << gpio_t::RX_BANDSELC)
+ | (_misc.time_sync << gpio_t::TIME_SYNC);
_global_regs->poke32(global_regs::SR_CORE_MISC, misc_reg);
}
diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp
index 9b39c7468..1bf5cb950 100644
--- a/host/lib/usrp/e300/e300_impl.hpp
+++ b/host/lib/usrp/e300/e300_impl.hpp
@@ -200,6 +200,8 @@ private: // types
boost::uint32_t rx_bandsel_b;
boost::uint32_t rx_bandsel_c;
+ boost::uint32_t time_sync;
+
static const size_t PPS_SEL = 0;
static const size_t MIMO = 2;
static const size_t CODEC_ARST = 3;
@@ -207,6 +209,7 @@ private: // types
static const size_t RX_BANDSELA = 7;
static const size_t RX_BANDSELB = 13;
static const size_t RX_BANDSELC = 17;
+ static const size_t TIME_SYNC = 21;
};
private: // methods
@@ -257,6 +260,8 @@ private: // methods
void _update_time_source(const std::string &source);
void _update_clock_source(const std::string &);
+ void _set_time(const uhd::time_spec_t&);
+ void _sync_times(void);
void _update_subdev_spec(
const std::string &txrx,
diff --git a/host/lib/usrp/x300/x300_fw_common.h b/host/lib/usrp/x300/x300_fw_common.h
index 4c5051eaa..549fc9dfa 100644
--- a/host/lib/usrp/x300/x300_fw_common.h
+++ b/host/lib/usrp/x300/x300_fw_common.h
@@ -33,7 +33,7 @@ extern "C" {
#define X300_REVISION_MIN 2
#define X300_FW_COMPAT_MAJOR 4
#define X300_FW_COMPAT_MINOR 0
-#define X300_FPGA_COMPAT_MAJOR 18
+#define X300_FPGA_COMPAT_MAJOR 19
//shared memory sections - in between the stack and the program space
#define X300_FW_SHMEM_BASE 0x6000
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 0483ecf11..37461e2e5 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -809,8 +809,8 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
////////////////////////////////////////////////////////////////////
_tree->create<time_spec_t>(mb_path / "time" / "now")
.publish(boost::bind(&time_core_3000::get_time_now, mb.radio_perifs[0].time64))
- .subscribe(boost::bind(&time_core_3000::set_time_now, mb.radio_perifs[0].time64, _1))
- .subscribe(boost::bind(&time_core_3000::set_time_now, mb.radio_perifs[1].time64, _1));
+ .subscribe(boost::bind(&x300_impl::sync_times, this, mb, _1))
+ .set(0.0);
_tree->create<time_spec_t>(mb_path / "time" / "pps")
.publish(boost::bind(&time_core_3000::get_time_last_pps, mb.radio_perifs[0].time64))
.subscribe(boost::bind(&time_core_3000::set_time_next_pps, mb.radio_perifs[0].time64, _1))
@@ -1505,6 +1505,14 @@ void x300_impl::update_time_source(mboard_members_t &mb, const std::string &sour
*/
}
+void x300_impl::sync_times(mboard_members_t &mb, const uhd::time_spec_t& t)
+{
+ BOOST_FOREACH(radio_perifs_t &perif, mb.radio_perifs)
+ perif.time64->set_time_sync(t);
+ mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::TIME_SYNC, 1);
+ mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::TIME_SYNC, 0);
+}
+
bool x300_impl::wait_for_clk_locked(mboard_members_t& mb, boost::uint32_t which, double timeout)
{
boost::system_time timeout_time = boost::get_system_time() + boost::posix_time::milliseconds(timeout * 1000.0);
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 521ce8a0e..4de0344bf 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -362,6 +362,7 @@ private:
void set_time_source_out(mboard_members_t&, const bool);
void update_clock_source(mboard_members_t&, const std::string &);
void update_time_source(mboard_members_t&, const std::string &);
+ void sync_times(mboard_members_t&, const uhd::time_spec_t&);
uhd::sensor_value_t get_ref_locked(mboard_members_t& mb);
bool wait_for_clk_locked(mboard_members_t& mb, boost::uint32_t which, double timeout);
diff --git a/host/lib/usrp/x300/x300_regs.hpp b/host/lib/usrp/x300/x300_regs.hpp
index 489d249ba..de3a3161a 100644
--- a/host/lib/usrp/x300/x300_regs.hpp
+++ b/host/lib/usrp/x300/x300_regs.hpp
@@ -213,6 +213,7 @@ namespace uhd { namespace usrp { namespace x300 {
UHD_DEFINE_SOFT_REG_FIELD(PPS_OUT_EN, /*width*/ 1, /*shift*/ 4); //[4]
UHD_DEFINE_SOFT_REG_FIELD(TCXO_EN, /*width*/ 1, /*shift*/ 5); //[5]
UHD_DEFINE_SOFT_REG_FIELD(GPSDO_PWR_EN, /*width*/ 1, /*shift*/ 6); //[6]
+ UHD_DEFINE_SOFT_REG_FIELD(TIME_SYNC, /*width*/ 1, /*shift*/ 7); //[7]
static const boost::uint32_t SRC_EXTERNAL = 0x0;
static const boost::uint32_t SRC_INTERNAL = 0x2;
@@ -225,6 +226,7 @@ namespace uhd { namespace usrp { namespace x300 {
set(PPS_OUT_EN, 0);
set(TCXO_EN, 1);
set(GPSDO_PWR_EN, 1); //GPSDO power always ON
+ set(TIME_SYNC, 0);
}
} clock_ctrl_reg;