diff options
| author | Ashish Chaudhari <ashish@ettus.com> | 2015-12-15 15:17:36 -0800 | 
|---|---|---|
| committer | Ashish Chaudhari <ashish@ettus.com> | 2015-12-15 15:17:36 -0800 | 
| commit | f44f7f2ca7dbbd1a72f5b3d239856a1954569884 (patch) | |
| tree | 310055d734a28063359b26f7cdc4d4704c517b9e /host/lib/usrp | |
| parent | 75ea07bd6d19494e018cd5c3109e1f85969b7ac6 (diff) | |
| parent | 10178875a154e58af6c14774621776d13e7e3daa (diff) | |
| download | uhd-f44f7f2ca7dbbd1a72f5b3d239856a1954569884.tar.gz uhd-f44f7f2ca7dbbd1a72f5b3d239856a1954569884.tar.bz2 uhd-f44f7f2ca7dbbd1a72f5b3d239856a1954569884.zip  | |
Merge branch 'maint'
Conflicts:
	host/lib/usrp/b200/b200_impl.hpp
	host/lib/usrp/e300/e300_fpga_defs.hpp
	host/lib/usrp/x300/x300_fw_common.h
Diffstat (limited to 'host/lib/usrp')
| -rw-r--r-- | host/lib/usrp/b200/b200_iface.cpp | 183 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_iface.hpp | 45 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_impl.cpp | 60 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_impl.hpp | 9 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_io_impl.cpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_regs.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/common/adf4001_ctrl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/cores/time_core_3000.cpp | 13 | ||||
| -rw-r--r-- | host/lib/usrp/cores/time_core_3000.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/e300/e300_fpga_defs.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/e300/e300_impl.cpp | 27 | ||||
| -rw-r--r-- | host/lib/usrp/e300/e300_impl.hpp | 5 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_fw_common.h | 2 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 12 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_impl.hpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_regs.hpp | 2 | 
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;  | 
