diff options
| -rwxr-xr-x | firmware/fx2/src/common/build_eeprom.py | 103 | ||||
| -rw-r--r-- | firmware/fx2/src/usrp1/Makefile.am | 58 | ||||
| -rw-r--r-- | host/include/uhd/transport/usb_device_handle.hpp | 4 | ||||
| -rw-r--r-- | host/lib/transport/libusb1_base.cpp | 52 | ||||
| -rw-r--r-- | host/lib/transport/libusb1_base.hpp | 10 | ||||
| -rw-r--r-- | host/lib/transport/libusb1_device_handle.cpp | 18 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/mboard_impl.cpp | 11 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_ctrl.cpp | 63 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_ctrl.hpp | 31 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_iface.cpp | 21 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_impl.cpp | 34 | ||||
| -rw-r--r-- | host/utils/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | host/utils/usrp_init_eeprom.cpp | 69 | 
13 files changed, 255 insertions, 223 deletions
| diff --git a/firmware/fx2/src/common/build_eeprom.py b/firmware/fx2/src/common/build_eeprom.py index 023c4b3f5..ae62587db 100755 --- a/firmware/fx2/src/common/build_eeprom.py +++ b/firmware/fx2/src/common/build_eeprom.py @@ -29,15 +29,6 @@ from optparse import OptionParser  VID = 0xfffe                            # Free Software Folks  PID = 0x0002                            # Universal Software Radio Peripheral - - -def hex_to_bytes (s): -    if len (s) & 0x1: -        raise ValueError, "Length must be even" -    r = [] -    for i in range (0, len(s), 2): -        r.append (int (s[i:i+2], 16)) -    return r  def msb (x):      return (x >> 8) & 0xff @@ -45,56 +36,6 @@ def msb (x):  def lsb (x):      return x & 0xff -class ihx_rec (object): -    def __init__ (self, addr, type, data): -        self.addr = addr -        self.type = type -        self.data = data - -class ihx_file (object): -    def __init__ (self): -        self.pat = re.compile (r':[0-9A-F]{10,}') -    def read (self, file): -        r = [] -        for line in file: -            line = line.strip().upper () -            if not self.pat.match (line): -                raise ValueError, "Invalid hex record format" -            bytes = hex_to_bytes (line[1:]) -            sum = reduce (lambda x, y: x + y, bytes, 0) % 256 -            if sum != 0: -                raise ValueError, "Bad hex checksum" -            lenx = bytes[0] -            addr = (bytes[1] << 8) + bytes[2] -            type = bytes[3] -            data = bytes[4:-1] -            if lenx != len (data): -                raise ValueError, "Invalid hex record (bad length)" -            if type != 0: -                break; -            r.append (ihx_rec (addr, type, data)) - -        return r - -def get_code (filename): -    """Read the intel hex format file FILENAME and return a tuple -    of the code starting address and a list of bytes to load there. -    """ -    f = open (filename, 'r') -    ifx = ihx_file () -    r = ifx.read (f) -    r.sort (lambda a,b: a.addr - b.addr) -    code_start = r[0].addr -    code_end = r[-1].addr + len (r[-1].data) -    code_len = code_end - code_start -    code = [0] * code_len -    for x in r: -        a = x.addr -        l = len (x.data) -        code[a-code_start:a-code_start+l] = x.data -    return (code_start, code) -         -  def build_eeprom_image (filename, rev):      """Build a ``C2 Load'' EEPROM image. @@ -102,9 +43,11 @@ def build_eeprom_image (filename, rev):      the EZ-USB FX2 Technical Reference Manual      """      # get the code we want to run -    (start_addr, bytes) = get_code (filename) +    f = open(filename, 'rb') +    bytes = f.read()      devid = rev +    start_addr = 0 #prove me wrong      rom_header = [          0xC2,                           # boot from EEPROM @@ -135,41 +78,18 @@ def build_eeprom_image (filename, rev):          0x00          ] -    image = rom_header + code_header + bytes + trailer +    image = rom_header + code_header + [ord(c) for c in bytes] + trailer      assert (len (image) <= 256) -    return image - -def build_shell_script (out, ihx_filename, rev): - -    image = build_eeprom_image (ihx_filename, rev) - -    out.write ('#!/bin/sh\n') -    out.write ('usrper -x load_firmware /usr/local/share/usrp/rev%d/std.ihx\n' % rev) -    out.write ('sleep 1\n') -     -    # print "len(image) =", len(image) -     -    i2c_addr = 0x50 -    rom_addr = 0x00 - -    hex_image = map (lambda x : "%02x" % (x,), image) - -    while (len (hex_image) > 0): -        l = min (len (hex_image), 16) -        out.write ('usrper i2c_write 0x%02x %02x%s\n' % -                   (i2c_addr, rom_addr, ''.join (hex_image[0:l]))) -        hex_image = hex_image[l:] -        rom_addr = rom_addr + l -        out.write ('sleep 1\n') +    return image   if __name__ == '__main__': -    usage = "usage: %prog -r REV [options] bootfile.ihx" +    usage = "usage: %prog -r REV [options] bootfile.bin outfile.bin"      parser = OptionParser (usage=usage)      parser.add_option ("-r", "--rev", type="int", default=-1,                         help="Specify USRP revision number REV (2 or 4)")      (options, args) = parser.parse_args () -    if len (args) != 1: +    if len (args) != 2:          parser.print_help ()          sys.exit (1)      if options.rev < 0: @@ -177,6 +97,11 @@ if __name__ == '__main__':              "You must specify the USRP revision number (2 or 4) with -r REV\n")          sys.exit (1) -    ihx_filename = args[0] +    infile = args[0] +    outfile = args[1] + +    image = "".join(chr(c) for c in build_eeprom_image(infile, options.rev)) -    build_shell_script (sys.stdout, ihx_filename, options.rev) +    f = open(outfile, 'wb') +    f.write(str(image)) +    f.close()   diff --git a/firmware/fx2/src/usrp1/Makefile.am b/firmware/fx2/src/usrp1/Makefile.am index 5586e83a3..a964f9198 100644 --- a/firmware/fx2/src/usrp1/Makefile.am +++ b/firmware/fx2/src/usrp1/Makefile.am @@ -19,12 +19,12 @@  # Boston, MA 02110-1301, USA.  #  -firmware2dir = $(prefix)/share/usrp/rev2 -firmware2_DATA = std.ihx +#firmwaredir = $(prefix)/share/uhd/images +#firmware_DATA = usrp1_fw.ihx -# we put the same stuff in the rev4 directory -firmware4dir = $(prefix)/share/usrp/rev4 -firmware4_DATA = std.ihx +#eepromdir = $(firmwaredir) +#eepromfile = eeprom_boot.ihx +#eeprom_DATA = usrp1_eeprom.bin  EXTRA_DIST =			\  	edit-gpif		\ @@ -85,11 +85,6 @@ EXECUTABLES = 			\  STARTUP = _startup.rel -noinst_SCRIPTS = 		\ -	burn-usrp2-eeprom	\ -	burn-usrp4-eeprom - -  .c.rel:  	$(XCC) $(FW_INCLUDES) $(DEFINES) \  		-c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< @@ -107,34 +102,11 @@ EEPROM_BOOT_OBJS = eeprom_boot.rel eeprom_init.rel $(STARTUP)  eeprom_boot.ihx: $(EEPROM_BOOT_OBJS) $(LIBDEP)  	$(XCC) $(LINKOPTS) -o $@ $(EEPROM_BOOT_OBJS) -burn-usrp2-eeprom: eeprom_boot.ihx -	$(PYTHON) $(srcdir)/../common/build_eeprom.py -r2 eeprom_boot.ihx > $@ -	chmod +x $@ - -burn-usrp4-eeprom: eeprom_boot.ihx -	$(PYTHON) $(srcdir)/../common/build_eeprom.py -r4 eeprom_boot.ihx > $@ -	chmod +x $@ - - -BLINK_LEDS_OBJS = blink_leds.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP) - -blink_leds.ihx: $(BLINK_LEDS_OBJS) $(LIBDEP) -	$(XCC) $(LINKOPTS) -o $@ $(BLINK_LEDS_OBJS) - - -CHECK_MDELAY_OBJS = check_mdelay.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP) - -check_mdelay.ihx: $(CHECK_MDELAY_OBJS) $(LIBDEP) -	$(XCC) $(LINKOPTS) -o $@ $(CHECK_MDELAY_OBJS) - - - -CHECK_UDELAY_OBJS = check_udelay.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP) - -check_udelay.ihx: $(CHECK_UDELAY_OBJS) $(LIBDEP) -	$(XCC) $(LINKOPTS) -o $@ $(CHECK_UDELAY_OBJS) - +usrp1_eeprom.bin: eeprom_boot.bin +	$(PYTHON) ../common/build_eeprom.py -r4 $< $@ +eeprom_boot.bin: eeprom_boot.ihx +	objcopy -I ihex -O binary $< $@  USRP_OBJS = \  	vectors.rel 						\ @@ -146,25 +118,23 @@ std.ihx: $(USRP_OBJS) $(LIBDEP)  	$(XCC) $(LINKOPTS) -o $@ $(USRP_OBJS)  CLEANFILES = 		\ -	*.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib	\ -	usrp_gpif.c usrp_gpif_inline.h \ -	burn-usrp2-eeprom	\ -	burn-usrp4-eeprom +	*.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib	*.bin \ +	usrp_gpif.c usrp_gpif_inline.h  DISTCLEANFILES = 	\ -	*.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib +	*.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib *.bin  # build gpif stuff -all: usrp_gpif.c +all: usrp_gpif.c std.ihx usrp1_eeprom.bin  usrp_gpif.c usrp_gpif_inline.h : gpif.c  	srcdir=$(srcdir) $(PYTHON) $(srcdir)/edit-gpif $(srcdir)/gpif.c usrp_gpif.c usrp_gpif_inline.h -  # dependencies  usrp_main.rel: usrp_gpif_inline.h +  #usrp_main.rel: fpga.h usrp_common.h ../../include/usrp_commands.h usrp_gpif_inline.h  ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h  #usrp_common.rel: usrp_common.h ../../include/usrp_commands.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h  #fpga.rel: usrp_common.h ../../include/usrp_commands.h fpga.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h diff --git a/host/include/uhd/transport/usb_device_handle.hpp b/host/include/uhd/transport/usb_device_handle.hpp index 78c78f6b5..c3eb72b00 100644 --- a/host/include/uhd/transport/usb_device_handle.hpp +++ b/host/include/uhd/transport/usb_device_handle.hpp @@ -68,9 +68,9 @@ public:      /*!       * Return a vector of USB devices on this host  -     * \return a vector of USB device handles +     * \return a vector of USB device handles that match vid and pid       */ -    static UHD_API std::vector<usb_device_handle::sptr> get_device_list(); +    static UHD_API std::vector<usb_device_handle::sptr> get_device_list(boost::uint16_t vid, boost::uint16_t pid);  }; //namespace usb diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp index 92dcd969f..e21c39aa3 100644 --- a/host/lib/transport/libusb1_base.cpp +++ b/host/lib/transport/libusb1_base.cpp @@ -24,22 +24,6 @@ using namespace uhd::transport;  /**********************************************************   * Helper Methods   **********************************************************/ -/* - * Check for FSF device - * Compare the device's descriptor Vendor ID - * \param dev pointer to libusb_device - * \return true if Vendor ID matches 0xfffe - */ -bool check_fsf_device(libusb_device *dev) -{ -    libusb_device_descriptor desc; - -    if (libusb_get_device_descriptor(dev, &desc) < 0) { -        UHD_ASSERT_THROW("USB: failed to get device descriptor"); -    } - -    return desc.idVendor == 0xfffe; -}  /**********************************************************   * libusb namespace  @@ -52,37 +36,16 @@ void libusb::init(libusb_context **ctx, int debug_level)      libusb_set_debug(*ctx, debug_level);  } -std::vector<libusb_device *> libusb::get_fsf_device_list(libusb_context *ctx) -{ -    libusb_device **libusb_dev_list; -    std::vector<libusb_device *> fsf_dev_list; - -    ssize_t dev_cnt = libusb_get_device_list(ctx, &libusb_dev_list); - -    //find the FSF devices  -    for (ssize_t i = 0; i < dev_cnt; i++) { -        libusb_device *dev = libusb_dev_list[i]; - -        if (check_fsf_device(dev)) -            fsf_dev_list.push_back(dev); -        else -            libusb_unref_device(dev); -    } - -    libusb_free_device_list(libusb_dev_list, 0); - -    return fsf_dev_list; -} -  libusb_device_handle *libusb::open_device(libusb_context *ctx,                                            usb_device_handle::sptr handle)  {      libusb_device_handle *dev_handle = NULL; -    std::vector<libusb_device *> fsf_dev_list = get_fsf_device_list(ctx); +    libusb_device **libusb_dev_list; +    size_t dev_cnt = libusb_get_device_list(ctx, &libusb_dev_list);      //find and open the USB device  -    for (size_t i = 0; i < fsf_dev_list.size(); i++) { -        libusb_device *dev = fsf_dev_list[i]; +    for (size_t i = 0; i < dev_cnt; i++) { +        libusb_device *dev = libusb_dev_list[i];          if (compare_device(dev, handle)) {              libusb_open(dev, &dev_handle); @@ -96,7 +59,8 @@ libusb_device_handle *libusb::open_device(libusb_context *ctx,      return dev_handle;  } - +//note: changed order of checks so it only tries to get_serial and get_device_address if vid and pid match +//doing this so it doesn't try to open the device if it's not ours  bool libusb::compare_device(libusb_device *dev,                              usb_device_handle::sptr handle)  { @@ -108,12 +72,12 @@ bool libusb::compare_device(libusb_device *dev,      libusb_device_descriptor libusb_desc;      if (libusb_get_device_descriptor(dev, &libusb_desc) < 0)          return false; -    if (serial != get_serial(dev)) -        return false;      if (vendor_id != libusb_desc.idVendor)          return false;      if (product_id != libusb_desc.idProduct)          return false;  +    if (serial != get_serial(dev)) +        return false;      if (device_addr != libusb_get_device_address(dev))          return false; diff --git a/host/lib/transport/libusb1_base.hpp b/host/lib/transport/libusb1_base.hpp index 442f89ded..abe5e22a2 100644 --- a/host/lib/transport/libusb1_base.hpp +++ b/host/lib/transport/libusb1_base.hpp @@ -42,16 +42,6 @@ namespace libusb {      void init(libusb_context **ctx, int debug_level);      /* -     * Get a list of Free Software Foundation devices (Vendor ID 0xfffe) -     * As opposed to the public USB device handle interface, which returns -     * generic identifiers, this call returns device pointers speficic -     * to libusb. -     * \param ctx the libusb context used for init -     * \return a vector of libusb devices -     */ -    std::vector<libusb_device *> get_fsf_device_list(libusb_context *ctx); - -    /*       * Open the device specified by a generic handle       * Find the libusb_device cooresponding to the generic handle       * and open it for I/O, which returns a libusb_device_handle diff --git a/host/lib/transport/libusb1_device_handle.cpp b/host/lib/transport/libusb1_device_handle.cpp index 5d9d8faf0..43d0f0e26 100644 --- a/host/lib/transport/libusb1_device_handle.cpp +++ b/host/lib/transport/libusb1_device_handle.cpp @@ -17,6 +17,7 @@  #include "libusb1_base.hpp"  #include <uhd/utils/assert.hpp> +#include <iostream>  using namespace uhd::transport; @@ -91,19 +92,24 @@ usb_device_handle::sptr make_usb_device_handle(libusb_device *dev)          device_addr));  } -std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list() +std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(boost::uint16_t vid, boost::uint16_t pid)  {      libusb_context *ctx = NULL; -    std::vector<libusb_device *> libusb_device_list; +    libusb_device** libusb_device_list;      std::vector<usb_device_handle::sptr> device_handle_list; +    libusb_device_descriptor desc;      libusb::init(&ctx, libusb_debug_level); -    libusb_device_list = libusb::get_fsf_device_list(ctx); - -    for (size_t i = 0; i < libusb_device_list.size(); i++) { +    size_t dev_size = libusb_get_device_list(ctx, &libusb_device_list); +    for (size_t i = 0; i < dev_size; i++) {          libusb_device *dev = libusb_device_list[i]; -        device_handle_list.push_back(make_usb_device_handle(dev)); +        if(libusb_get_device_descriptor(dev, &desc) < 0) { +          UHD_ASSERT_THROW("USB: failed to get device descriptor"); +        } +        if(desc.idVendor == vid && desc.idProduct == pid) { +          device_handle_list.push_back(make_usb_device_handle(dev)); +        }      }      libusb_exit(ctx); diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp index 75129c32f..1409855cb 100644 --- a/host/lib/usrp/usrp1/mboard_impl.cpp +++ b/host/lib/usrp/usrp1/mboard_impl.cpp @@ -25,6 +25,7 @@  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/utils/warning.hpp>  #include <uhd/utils/assert.hpp> +#include <uhd/utils/images.hpp>  #include <boost/assign/list_of.hpp>  #include <boost/foreach.hpp>  #include <boost/bind.hpp> @@ -318,6 +319,16 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val)   **********************************************************************/  void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)  { +    if(key.type() == typeid(std::string)) { +      if(key.as<std::string>() == "load_eeprom") { +        std::string usrp1_fpga_image = val.as<std::string>(); +        std::cout << "USRP1 EEPROM image: " << usrp1_fpga_image << std::endl; +        _ctrl_transport->usrp_load_eeprom(val.as<std::string>()); +      } + +      return; +   	} +      //handle the get request conditioned on the key      switch(key.as<mboard_prop_t>()){ diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.cpp b/host/lib/usrp/usrp1/usrp1_ctrl.cpp index 98226b738..451129ef5 100644 --- a/host/lib/usrp/usrp1/usrp1_ctrl.cpp +++ b/host/lib/usrp/usrp1/usrp1_ctrl.cpp @@ -25,6 +25,7 @@  #include <sstream>  #include <string>  #include <vector> +#include <cstring>  using namespace uhd; @@ -203,7 +204,7 @@ public:                      return -1;                   }              }   -            //type 0x00 is end  +            //type 0x01 is end               else if (type == 0x01) {                  usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0,                                     &reset_n, 1); @@ -283,6 +284,55 @@ public:          return 0;       } +    int usrp_load_eeprom(std::string filestring) +    { +        const char *filename = filestring.c_str(); +        const uint16_t i2c_addr = 0x50; + +        //FIXME: verify types +        int len; +        unsigned int addr; +        unsigned char data[256]; +        unsigned char sendbuf[17]; + +        int ret; +        std::ifstream file; +        file.open(filename, std::ifstream::in); + +        if (!file.good()) { +            std::cerr << "cannot open EEPROM input file" << std::endl; +            return -1;  +        } + +        file.read((char *)data, 256); +        len = file.gcount(); + +        if(len == 256) { +          std::cerr << "error: image size too large" << std::endl; +          file.close(); +          return -1; +        } + +        const int pagesize = 16; +        addr = 0; +        while(len > 0) { +          sendbuf[0] = addr; +          memcpy(sendbuf+1, &data[addr], len > pagesize ? pagesize : len); +          ret = usrp_i2c_write(i2c_addr, sendbuf, (len > pagesize ? pagesize : len)+1); +          if (ret < 0) { +            std::cerr << "error: usrp_i2c_write failed: "; +            std::cerr << ret << std::endl; +            file.close(); +            return -1;  +          } +          addr += pagesize; +          len -= pagesize; +          boost::this_thread::sleep(boost::posix_time::milliseconds(100)); +        } +        file.close(); +        return 0; +    } +      int usrp_set_led(int led_num, bool on)      { @@ -371,6 +421,17 @@ public:          return usrp_control_write(request, value, index, 0, 0);      } +    int usrp_i2c_write(boost::uint16_t i2c_addr, unsigned char *buf, boost::uint16_t len) +    { +        return usrp_control_write(VRQ_I2C_WRITE, i2c_addr, 0, buf, len); +    } + +    int usrp_i2c_read(boost::uint16_t i2c_addr, unsigned char *buf, boost::uint16_t len) +    { +        return usrp_control_read(VRQ_I2C_READ, i2c_addr, 0, buf, len); +    } + +  private:      uhd::transport::usb_control::sptr _ctrl_transport; diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.hpp b/host/lib/usrp/usrp1/usrp1_ctrl.hpp index deedec4e8..a02d9f96c 100644 --- a/host/lib/usrp/usrp1/usrp1_ctrl.hpp +++ b/host/lib/usrp/usrp1/usrp1_ctrl.hpp @@ -50,6 +50,13 @@ public:      virtual int usrp_load_fpga(std::string filename) = 0;      /*! +     * Load USB descriptor file in Intel HEX format into EEPROM +     * \param filename name of EEPROM image  +     * \return 0 on success, error code otherwise +     */ +    virtual int usrp_load_eeprom(std::string filestring) = 0; + +    /*!       * Set led usrp        * \param led_num which LED to control (0 or 1)       * \param on turn LED on or off @@ -127,6 +134,30 @@ public:                                     unsigned char *buff,                                     boost::uint16_t length) = 0; +    /*! +     * Perform an I2C write +     * \param i2c_addr I2C device address +     * \param buf data to be written  +     * \param len length of data in bytes +     * \return number of bytes written or error  +     */ + +    virtual int usrp_i2c_write(boost::uint16_t i2c_addr, +                               unsigned char *buf,  +                               boost::uint16_t len) = 0; + +    /*! +     * Perform an I2C read +     * \param i2c_addr I2C device address +     * \param buf data to be read  +     * \param len length of data in bytes +     * \return number of bytes read or error  +     */ + +    virtual int usrp_i2c_read(boost::uint16_t i2c_addr, +                               unsigned char *buf,  +                               boost::uint16_t len) = 0; +  };  #endif /* INCLUDED_USRP_CTRL_HPP */ diff --git a/host/lib/usrp/usrp1/usrp1_iface.cpp b/host/lib/usrp/usrp1/usrp1_iface.cpp index 8756a21c9..4bc18dd16 100644 --- a/host/lib/usrp/usrp1/usrp1_iface.cpp +++ b/host/lib/usrp/usrp1/usrp1_iface.cpp @@ -109,18 +109,19 @@ public:       ******************************************************************/      static const size_t max_i2c_data_bytes = 64; +    //TODO: make this handle EEPROM page sizes. right now you can't write over a 16-byte boundary. +    //to accomplish this you'll have to have addr offset as a separate parameter. +      void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes)      {          UHD_ASSERT_THROW(bytes.size() < max_i2c_data_bytes);          unsigned char buff[max_i2c_data_bytes]; -        std::copy(bytes.begin(), bytes.end(), buff);  +        std::copy(bytes.begin(), bytes.end(), buff); -        int ret = _ctrl_transport->usrp_control_write(VRQ_I2C_WRITE, -                                                      addr & 0xff, -                                                      0, -                                                      buff, -                                                      bytes.size()); +        int ret = _ctrl_transport->usrp_i2c_write(addr & 0xff, +                                             buff, +                                             bytes.size());          // TODO throw and catch i2c failures during eeprom read          if (iface_debug && (ret < 0)) @@ -132,11 +133,9 @@ public:          UHD_ASSERT_THROW(num_bytes < max_i2c_data_bytes);          unsigned char buff[max_i2c_data_bytes]; -        int ret = _ctrl_transport->usrp_control_read(VRQ_I2C_READ, -                                                     addr & 0xff, -                                                     0, -                                                     buff, -                                                     num_bytes); +        int ret = _ctrl_transport->usrp_i2c_read(addr & 0xff, +                                            buff, +                                            num_bytes);          // TODO throw and catch i2c failures during eeprom read          if (iface_debug && ((ret < 0) || (unsigned)ret < (num_bytes))) { diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index 3c3306525..8ad148274 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -34,6 +34,11 @@ using namespace uhd;  using namespace uhd::usrp;  using namespace uhd::transport; +const boost::uint16_t USRP1_VENDOR_ID  = 0xfffe; +const boost::uint16_t USRP1_PRODUCT_ID = 0x0002; +const boost::uint16_t FX2_VENDOR_ID    = 0x04b4; +const boost::uint16_t FX2_PRODUCT_ID   = 0x8613; +  const std::vector<usrp1_impl::dboard_slot_t> usrp1_impl::_dboard_slots = boost::assign::list_of      (usrp1_impl::DBOARD_SLOT_A)(usrp1_impl::DBOARD_SLOT_B)  ; @@ -54,33 +59,32 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)      );      std::cout << "USRP1 firmware image: " << usrp1_fw_image << std::endl; +    boost::uint16_t vid = hint.has_key("uninit") ? FX2_VENDOR_ID : USRP1_VENDOR_ID; +    boost::uint16_t pid = hint.has_key("uninit") ? FX2_PRODUCT_ID : USRP1_PRODUCT_ID; +      //see what we got on the USB bus      std::vector<usb_device_handle::sptr> device_list = -        usb_device_handle::get_device_list(); +        usb_device_handle::get_device_list(vid, pid); + +    if(device_list.size() == 0) return usrp1_addrs; //return nothing if no USRPs found      //find the usrps and load firmware      BOOST_FOREACH(usb_device_handle::sptr handle, device_list) { -        if (handle->get_vendor_id() == 0xfffe && -            handle->get_product_id() == 0x0002) { -              usb_control::sptr ctrl_transport = usb_control::make(handle);              usrp_ctrl::sptr usrp_ctrl = usrp_ctrl::make(ctrl_transport);              usrp_ctrl->usrp_load_firmware(usrp1_fw_image); -        }      } -    //get descriptors again with serial number -    device_list = usb_device_handle::get_device_list(); +    //get descriptors again with serial number, but using the initialized VID/PID now since we have firmware +    vid = USRP1_VENDOR_ID; +    pid = USRP1_PRODUCT_ID; +    device_list = usb_device_handle::get_device_list(vid, pid);      BOOST_FOREACH(usb_device_handle::sptr handle, device_list) { -        if (handle->get_vendor_id() == 0xfffe && -            handle->get_product_id() == 0x0002) { -              device_addr_t new_addr;              new_addr["type"] = "usrp1";              new_addr["serial"] = handle->get_serial();              usrp1_addrs.push_back(new_addr); -        }      }      return usrp1_addrs; @@ -99,17 +103,15 @@ static device::sptr usrp1_make(const device_addr_t &device_addr)      //try to match the given device address with something on the USB bus      std::vector<usb_device_handle::sptr> device_list = -        usb_device_handle::get_device_list(); +        usb_device_handle::get_device_list(USRP1_VENDOR_ID, USRP1_PRODUCT_ID);      //create data and control transports      usb_zero_copy::sptr data_transport;      usrp_ctrl::sptr usrp_ctrl; -    BOOST_FOREACH(usb_device_handle::sptr handle, device_list) { -        if (handle->get_vendor_id() == 0xfffe && -            handle->get_product_id() == 0x0002 && -            handle->get_serial() == device_addr["serial"]) { +    BOOST_FOREACH(usb_device_handle::sptr handle, device_list) { +        if (handle->get_serial() == device_addr["serial"]) {              usb_control::sptr ctrl_transport = usb_control::make(handle);              usrp_ctrl = usrp_ctrl::make(ctrl_transport);              usrp_ctrl->usrp_load_fpga(usrp1_fpga_image); diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index c349a9018..9d788b06c 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -39,9 +39,13 @@ TARGET_LINK_LIBRARIES(usrp2_addr_burner uhd)  ADD_EXECUTABLE(usrp_burn_db_eeprom usrp_burn_db_eeprom.cpp)  TARGET_LINK_LIBRARIES(usrp_burn_db_eeprom uhd) +ADD_EXECUTABLE(usrp_init_eeprom usrp_init_eeprom.cpp) +TARGET_LINK_LIBRARIES(usrp_init_eeprom uhd) +  INSTALL(TARGETS      usrp2_addr_burner      usrp_burn_db_eeprom +    usrp_init_eeprom      RUNTIME DESTINATION ${PKG_DATA_DIR}/utils  ) diff --git a/host/utils/usrp_init_eeprom.cpp b/host/utils/usrp_init_eeprom.cpp new file mode 100644 index 000000000..28c7c5745 --- /dev/null +++ b/host/utils/usrp_init_eeprom.cpp @@ -0,0 +1,69 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/utils/safe_main.hpp> +#include <uhd/device.hpp> +#include <uhd/usrp/device_props.hpp> +#include <boost/program_options.hpp> +#include <boost/format.hpp> +#include <iostream> + +namespace po = boost::program_options; + +int UHD_SAFE_MAIN(int argc, char *argv[]){ +    po::options_description desc("Allowed options"); +    desc.add_options() +        ("help", "help message") +        ("image", po::value<std::string>(), "IHX image file") +    ; + +    po::variables_map vm; +    po::store(po::parse_command_line(argc, argv, desc), vm); +    po::notify(vm);  + +    //print the help message +    if (vm.count("help")){ +        std::cout << boost::format("USRP EEPROM initialization %s") % desc << std::endl; +        return ~0; +    } + +    //load the options into the address +    uhd::device_addr_t device_addr; +    device_addr["type"] = "usrp1"; +    device_addr["uninit"] = "yeah"; //tell find to look for an uninitialized FX2 + +    //find and create a control transport to do the writing. + +    uhd::device_addrs_t found_addrs = uhd::device::find(device_addr); + +    if (found_addrs.size() == 0){ +        std::cerr << "No uninitialized USRP devices found" << std::endl; +        return ~0; +    } + +    for (size_t i = 0; i < found_addrs.size(); i++){ +        std::cout << "Writing EEPROM data..." << std::endl; +        //uhd::device_addrs_t devs = uhd::device::find(found_addrs[i]); +        uhd::device::sptr dev = uhd::device::make(found_addrs[i]); +        wax::obj mb = (*dev)[uhd::usrp::DEVICE_PROP_MBOARD]; +        mb[std::string("load_eeprom")] = vm["image"].as<std::string>(); +    } + + +    std::cout << "Power-cycle the usrp for the changes to take effect." << std::endl; +    return 0; +} | 
