Revision b96088b6

b/firmware/fx2/src/common/build_eeprom.py
29 29

  
30 30
VID = 0xfffe                            # Free Software Folks
31 31
PID = 0x0002                            # Universal Software Radio Peripheral
32

  
33

  
34
def hex_to_bytes (s):
35
    if len (s) & 0x1:
36
        raise ValueError, "Length must be even"
37
    r = []
38
    for i in range (0, len(s), 2):
39
        r.append (int (s[i:i+2], 16))
40
    return r
41 32
    
42 33
def msb (x):
43 34
    return (x >> 8) & 0xff
......
45 36
def lsb (x):
46 37
    return x & 0xff
47 38

  
48
class ihx_rec (object):
49
    def __init__ (self, addr, type, data):
50
        self.addr = addr
51
        self.type = type
52
        self.data = data
53

  
54
class ihx_file (object):
55
    def __init__ (self):
56
        self.pat = re.compile (r':[0-9A-F]{10,}')
57
    def read (self, file):
58
        r = []
59
        for line in file:
60
            line = line.strip().upper ()
61
            if not self.pat.match (line):
62
                raise ValueError, "Invalid hex record format"
63
            bytes = hex_to_bytes (line[1:])
64
            sum = reduce (lambda x, y: x + y, bytes, 0) % 256
65
            if sum != 0:
66
                raise ValueError, "Bad hex checksum"
67
            lenx = bytes[0]
68
            addr = (bytes[1] << 8) + bytes[2]
69
            type = bytes[3]
70
            data = bytes[4:-1]
71
            if lenx != len (data):
72
                raise ValueError, "Invalid hex record (bad length)"
73
            if type != 0:
74
                break;
75
            r.append (ihx_rec (addr, type, data))
76

  
77
        return r
78

  
79
def get_code (filename):
80
    """Read the intel hex format file FILENAME and return a tuple
81
    of the code starting address and a list of bytes to load there.
82
    """
83
    f = open (filename, 'r')
84
    ifx = ihx_file ()
85
    r = ifx.read (f)
86
    r.sort (lambda a,b: a.addr - b.addr)
87
    code_start = r[0].addr
88
    code_end = r[-1].addr + len (r[-1].data)
89
    code_len = code_end - code_start
90
    code = [0] * code_len
91
    for x in r:
92
        a = x.addr
93
        l = len (x.data)
94
        code[a-code_start:a-code_start+l] = x.data
95
    return (code_start, code)
96
        
97

  
98 39
def build_eeprom_image (filename, rev):
99 40
    """Build a ``C2 Load'' EEPROM image.
100 41

  
......
102 43
    the EZ-USB FX2 Technical Reference Manual
103 44
    """
104 45
    # get the code we want to run
105
    (start_addr, bytes) = get_code (filename)
46
    f = open(filename, 'rb')
47
    bytes = f.read()
106 48

  
107 49
    devid = rev
50
    start_addr = 0 #prove me wrong
108 51

  
109 52
    rom_header = [
110 53
        0xC2,                           # boot from EEPROM
......
135 78
        0x00
136 79
        ]
137 80

  
138
    image = rom_header + code_header + bytes + trailer
81
    image = rom_header + code_header + [ord(c) for c in bytes] + trailer
139 82

  
140 83
    assert (len (image) <= 256)
141
    return image
142

  
143
def build_shell_script (out, ihx_filename, rev):
144

  
145
    image = build_eeprom_image (ihx_filename, rev)
146

  
147
    out.write ('#!/bin/sh\n')
148
    out.write ('usrper -x load_firmware /usr/local/share/usrp/rev%d/std.ihx\n' % rev)
149
    out.write ('sleep 1\n')
150
    
151
    # print "len(image) =", len(image)
152
    
153
    i2c_addr = 0x50
154
    rom_addr = 0x00
155

  
156
    hex_image = map (lambda x : "%02x" % (x,), image)
157

  
158
    while (len (hex_image) > 0):
159
        l = min (len (hex_image), 16)
160
        out.write ('usrper i2c_write 0x%02x %02x%s\n' %
161
                   (i2c_addr, rom_addr, ''.join (hex_image[0:l])))
162
        hex_image = hex_image[l:]
163
        rom_addr = rom_addr + l
164
        out.write ('sleep 1\n')
84
    return image 
165 85

  
166 86
if __name__ == '__main__':
167
    usage = "usage: %prog -r REV [options] bootfile.ihx"
87
    usage = "usage: %prog -r REV [options] bootfile.bin outfile.bin"
168 88
    parser = OptionParser (usage=usage)
169 89
    parser.add_option ("-r", "--rev", type="int", default=-1,
170 90
                       help="Specify USRP revision number REV (2 or 4)")
171 91
    (options, args) = parser.parse_args ()
172
    if len (args) != 1:
92
    if len (args) != 2:
173 93
        parser.print_help ()
174 94
        sys.exit (1)
175 95
    if options.rev < 0:
......
177 97
            "You must specify the USRP revision number (2 or 4) with -r REV\n")
178 98
        sys.exit (1)
179 99

  
180
    ihx_filename = args[0]
100
    infile = args[0]
101
    outfile = args[1]
102

  
103
    image = "".join(chr(c) for c in build_eeprom_image(infile, options.rev))
181 104

  
182
    build_shell_script (sys.stdout, ihx_filename, options.rev)
105
    f = open(outfile, 'wb')
106
    f.write(str(image))
107
    f.close()  
b/firmware/fx2/src/usrp1/Makefile.am
19 19
# Boston, MA 02110-1301, USA.
20 20
# 
21 21

  
22
firmware2dir = $(prefix)/share/usrp/rev2
23
firmware2_DATA = std.ihx
22
#firmwaredir = $(prefix)/share/uhd/images
23
#firmware_DATA = usrp1_fw.ihx
24 24

  
25
# we put the same stuff in the rev4 directory
26
firmware4dir = $(prefix)/share/usrp/rev4
27
firmware4_DATA = std.ihx
25
#eepromdir = $(firmwaredir)
26
#eepromfile = eeprom_boot.ihx
27
#eeprom_DATA = usrp1_eeprom.bin
28 28

  
29 29
EXTRA_DIST =			\
30 30
	edit-gpif		\
......
85 85

  
86 86
STARTUP = _startup.rel
87 87

  
88
noinst_SCRIPTS = 		\
89
	burn-usrp2-eeprom	\
90
	burn-usrp4-eeprom
91

  
92

  
93 88
.c.rel:
94 89
	$(XCC) $(FW_INCLUDES) $(DEFINES) \
95 90
		-c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
......
107 102
eeprom_boot.ihx: $(EEPROM_BOOT_OBJS) $(LIBDEP)
108 103
	$(XCC) $(LINKOPTS) -o $@ $(EEPROM_BOOT_OBJS)
109 104

  
110
burn-usrp2-eeprom: eeprom_boot.ihx
111
	$(PYTHON) $(srcdir)/../common/build_eeprom.py -r2 eeprom_boot.ihx > $@
112
	chmod +x $@
113

  
114
burn-usrp4-eeprom: eeprom_boot.ihx
115
	$(PYTHON) $(srcdir)/../common/build_eeprom.py -r4 eeprom_boot.ihx > $@
116
	chmod +x $@
117

  
118

  
119
BLINK_LEDS_OBJS = blink_leds.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP)
120

  
121
blink_leds.ihx: $(BLINK_LEDS_OBJS) $(LIBDEP)
122
	$(XCC) $(LINKOPTS) -o $@ $(BLINK_LEDS_OBJS)
123

  
124

  
125
CHECK_MDELAY_OBJS = check_mdelay.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP)
126

  
127
check_mdelay.ihx: $(CHECK_MDELAY_OBJS) $(LIBDEP)
128
	$(XCC) $(LINKOPTS) -o $@ $(CHECK_MDELAY_OBJS)
129

  
130

  
131

  
132
CHECK_UDELAY_OBJS = check_udelay.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP)
133

  
134
check_udelay.ihx: $(CHECK_UDELAY_OBJS) $(LIBDEP)
135
	$(XCC) $(LINKOPTS) -o $@ $(CHECK_UDELAY_OBJS)
136

  
105
usrp1_eeprom.bin: eeprom_boot.bin
106
	$(PYTHON) ../common/build_eeprom.py -r4 $< $@
137 107

  
108
eeprom_boot.bin: eeprom_boot.ihx
109
	objcopy -I ihex -O binary $< $@
138 110

  
139 111
USRP_OBJS = \
140 112
	vectors.rel 						\
......
146 118
	$(XCC) $(LINKOPTS) -o $@ $(USRP_OBJS)
147 119

  
148 120
CLEANFILES = 		\
149
	*.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib	\
150
	usrp_gpif.c usrp_gpif_inline.h \
151
	burn-usrp2-eeprom	\
152
	burn-usrp4-eeprom
121
	*.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib	*.bin \
122
	usrp_gpif.c usrp_gpif_inline.h
153 123

  
154 124
DISTCLEANFILES = 	\
155
	*.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib
125
	*.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib *.bin
156 126

  
157 127
# build gpif stuff
158 128

  
159
all: usrp_gpif.c
129
all: usrp_gpif.c std.ihx usrp1_eeprom.bin
160 130

  
161 131
usrp_gpif.c usrp_gpif_inline.h : gpif.c
162 132
	srcdir=$(srcdir) $(PYTHON) $(srcdir)/edit-gpif $(srcdir)/gpif.c usrp_gpif.c usrp_gpif_inline.h
163 133

  
164

  
165 134
# dependencies
166 135

  
167 136
usrp_main.rel: usrp_gpif_inline.h
137

  
168 138
#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
169 139
#usrp_common.rel: usrp_common.h ../../include/usrp_commands.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h
170 140
#fpga.rel: usrp_common.h ../../include/usrp_commands.h fpga.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h
b/host/include/uhd/transport/usb_device_handle.hpp
68 68

  
69 69
    /*!
70 70
     * Return a vector of USB devices on this host 
71
     * \return a vector of USB device handles
71
     * \return a vector of USB device handles that match vid and pid
72 72
     */
73
    static UHD_API std::vector<usb_device_handle::sptr> get_device_list();
73
    static UHD_API std::vector<usb_device_handle::sptr> get_device_list(boost::uint16_t vid, boost::uint16_t pid);
74 74

  
75 75
}; //namespace usb
76 76

  
b/host/lib/transport/libusb1_base.cpp
24 24
/**********************************************************
25 25
 * Helper Methods
26 26
 **********************************************************/
27
/*
28
 * Check for FSF device
29
 * Compare the device's descriptor Vendor ID
30
 * \param dev pointer to libusb_device
31
 * \return true if Vendor ID matches 0xfffe
32
 */
33
bool check_fsf_device(libusb_device *dev)
34
{
35
    libusb_device_descriptor desc;
36

  
37
    if (libusb_get_device_descriptor(dev, &desc) < 0) {
38
        UHD_ASSERT_THROW("USB: failed to get device descriptor");
39
    }
40

  
41
    return desc.idVendor == 0xfffe;
42
}
43 27

  
44 28
/**********************************************************
45 29
 * libusb namespace 
......
52 36
    libusb_set_debug(*ctx, debug_level);
53 37
}
54 38

  
55
std::vector<libusb_device *> libusb::get_fsf_device_list(libusb_context *ctx)
56
{
57
    libusb_device **libusb_dev_list;
58
    std::vector<libusb_device *> fsf_dev_list;
59

  
60
    ssize_t dev_cnt = libusb_get_device_list(ctx, &libusb_dev_list);
61

  
62
    //find the FSF devices 
63
    for (ssize_t i = 0; i < dev_cnt; i++) {
64
        libusb_device *dev = libusb_dev_list[i];
65

  
66
        if (check_fsf_device(dev))
67
            fsf_dev_list.push_back(dev);
68
        else
69
            libusb_unref_device(dev);
70
    }
71

  
72
    libusb_free_device_list(libusb_dev_list, 0);
73

  
74
    return fsf_dev_list;
75
}
76

  
77 39
libusb_device_handle *libusb::open_device(libusb_context *ctx,
78 40
                                          usb_device_handle::sptr handle)
79 41
{
80 42
    libusb_device_handle *dev_handle = NULL;
81
    std::vector<libusb_device *> fsf_dev_list = get_fsf_device_list(ctx);
43
    libusb_device **libusb_dev_list;
44
    size_t dev_cnt = libusb_get_device_list(ctx, &libusb_dev_list);
82 45

  
83 46
    //find and open the USB device 
84
    for (size_t i = 0; i < fsf_dev_list.size(); i++) {
85
        libusb_device *dev = fsf_dev_list[i];
47
    for (size_t i = 0; i < dev_cnt; i++) {
48
        libusb_device *dev = libusb_dev_list[i];
86 49

  
87 50
        if (compare_device(dev, handle)) {
88 51
            libusb_open(dev, &dev_handle);
......
96 59
    return dev_handle;
97 60
}
98 61

  
99

  
62
//note: changed order of checks so it only tries to get_serial and get_device_address if vid and pid match
63
//doing this so it doesn't try to open the device if it's not ours
100 64
bool libusb::compare_device(libusb_device *dev,
101 65
                            usb_device_handle::sptr handle)
102 66
{
......
108 72
    libusb_device_descriptor libusb_desc;
109 73
    if (libusb_get_device_descriptor(dev, &libusb_desc) < 0)
110 74
        return false;
111
    if (serial != get_serial(dev))
112
        return false;
113 75
    if (vendor_id != libusb_desc.idVendor)
114 76
        return false;
115 77
    if (product_id != libusb_desc.idProduct)
116 78
        return false; 
79
    if (serial != get_serial(dev))
80
        return false;
117 81
    if (device_addr != libusb_get_device_address(dev))
118 82
        return false;
119 83

  
b/host/lib/transport/libusb1_base.hpp
42 42
    void init(libusb_context **ctx, int debug_level);
43 43

  
44 44
    /*
45
     * Get a list of Free Software Foundation devices (Vendor ID 0xfffe)
46
     * As opposed to the public USB device handle interface, which returns
47
     * generic identifiers, this call returns device pointers speficic
48
     * to libusb.
49
     * \param ctx the libusb context used for init
50
     * \return a vector of libusb devices
51
     */
52
    std::vector<libusb_device *> get_fsf_device_list(libusb_context *ctx);
53

  
54
    /*
55 45
     * Open the device specified by a generic handle
56 46
     * Find the libusb_device cooresponding to the generic handle
57 47
     * and open it for I/O, which returns a libusb_device_handle
b/host/lib/transport/libusb1_device_handle.cpp
17 17

  
18 18
#include "libusb1_base.hpp"
19 19
#include <uhd/utils/assert.hpp>
20
#include <iostream>
20 21

  
21 22
using namespace uhd::transport;
22 23

  
......
91 92
        device_addr));
92 93
}
93 94

  
94
std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list()
95
std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(boost::uint16_t vid, boost::uint16_t pid)
95 96
{
96 97
    libusb_context *ctx = NULL;
97
    std::vector<libusb_device *> libusb_device_list;
98
    libusb_device** libusb_device_list;
98 99
    std::vector<usb_device_handle::sptr> device_handle_list;
100
    libusb_device_descriptor desc;
99 101

  
100 102
    libusb::init(&ctx, libusb_debug_level);
101 103

  
102
    libusb_device_list = libusb::get_fsf_device_list(ctx);
103

  
104
    for (size_t i = 0; i < libusb_device_list.size(); i++) {
104
    size_t dev_size = libusb_get_device_list(ctx, &libusb_device_list);
105
    for (size_t i = 0; i < dev_size; i++) {
105 106
        libusb_device *dev = libusb_device_list[i];
106
        device_handle_list.push_back(make_usb_device_handle(dev));
107
        if(libusb_get_device_descriptor(dev, &desc) < 0) {
108
          UHD_ASSERT_THROW("USB: failed to get device descriptor");
109
        }
110
        if(desc.idVendor == vid && desc.idProduct == pid) {
111
          device_handle_list.push_back(make_usb_device_handle(dev));
112
        }
107 113
    }
108 114

  
109 115
    libusb_exit(ctx);
b/host/lib/usrp/usrp1/mboard_impl.cpp
25 25
#include <uhd/usrp/subdev_props.hpp>
26 26
#include <uhd/utils/warning.hpp>
27 27
#include <uhd/utils/assert.hpp>
28
#include <uhd/utils/images.hpp>
28 29
#include <boost/assign/list_of.hpp>
29 30
#include <boost/foreach.hpp>
30 31
#include <boost/bind.hpp>
......
318 319
 **********************************************************************/
319 320
void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)
320 321
{
322
    if(key.type() == typeid(std::string)) {
323
      if(key.as<std::string>() == "load_eeprom") {
324
        std::string usrp1_fpga_image = val.as<std::string>();
325
        std::cout << "USRP1 EEPROM image: " << usrp1_fpga_image << std::endl;
326
        _ctrl_transport->usrp_load_eeprom(val.as<std::string>());
327
      }
328

  
329
      return;
330
   	}
331

  
321 332
    //handle the get request conditioned on the key
322 333
    switch(key.as<mboard_prop_t>()){
323 334

  
b/host/lib/usrp/usrp1/usrp1_ctrl.cpp
25 25
#include <sstream>
26 26
#include <string>
27 27
#include <vector>
28
#include <cstring>
28 29

  
29 30
using namespace uhd;
30 31

  
......
203 204
                    return -1; 
204 205
                }
205 206
            }  
206
            //type 0x00 is end 
207
            //type 0x01 is end 
207 208
            else if (type == 0x01) {
208 209
                usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0,
209 210
                                   &reset_n, 1);
......
283 284
        return 0; 
284 285
    }
285 286

  
287
    int usrp_load_eeprom(std::string filestring)
288
    {
289
        const char *filename = filestring.c_str();
290
        const uint16_t i2c_addr = 0x50;
291

  
292
        //FIXME: verify types
293
        int len;
294
        unsigned int addr;
295
        unsigned char data[256];
296
        unsigned char sendbuf[17];
297

  
298
        int ret;
299
        std::ifstream file;
300
        file.open(filename, std::ifstream::in);
301

  
302
        if (!file.good()) {
303
            std::cerr << "cannot open EEPROM input file" << std::endl;
304
            return -1; 
305
        }
306

  
307
        file.read((char *)data, 256);
308
        len = file.gcount();
309

  
310
        if(len == 256) {
311
          std::cerr << "error: image size too large" << std::endl;
312
          file.close();
313
          return -1;
314
        }
315

  
316
        const int pagesize = 16;
317
        addr = 0;
318
        while(len > 0) {
319
          sendbuf[0] = addr;
320
          memcpy(sendbuf+1, &data[addr], len > pagesize ? pagesize : len);
321
          ret = usrp_i2c_write(i2c_addr, sendbuf, (len > pagesize ? pagesize : len)+1);
322
          if (ret < 0) {
323
            std::cerr << "error: usrp_i2c_write failed: ";
324
            std::cerr << ret << std::endl;
325
            file.close();
326
            return -1; 
327
          }
328
          addr += pagesize;
329
          len -= pagesize;
330
          boost::this_thread::sleep(boost::posix_time::milliseconds(100));
331
        }
332
        file.close();
333
        return 0;
334
    }
335

  
286 336

  
287 337
    int usrp_set_led(int led_num, bool on)
288 338
    {
......
371 421
        return usrp_control_write(request, value, index, 0, 0);
372 422
    }
373 423

  
424
    int usrp_i2c_write(boost::uint16_t i2c_addr, unsigned char *buf, boost::uint16_t len)
425
    {
426
        return usrp_control_write(VRQ_I2C_WRITE, i2c_addr, 0, buf, len);
427
    }
428

  
429
    int usrp_i2c_read(boost::uint16_t i2c_addr, unsigned char *buf, boost::uint16_t len)
430
    {
431
        return usrp_control_read(VRQ_I2C_READ, i2c_addr, 0, buf, len);
432
    }
433

  
434

  
374 435

  
375 436
private:
376 437
    uhd::transport::usb_control::sptr _ctrl_transport;
b/host/lib/usrp/usrp1/usrp1_ctrl.hpp
50 50
    virtual int usrp_load_fpga(std::string filename) = 0;
51 51

  
52 52
    /*!
53
     * Load USB descriptor file in Intel HEX format into EEPROM
54
     * \param filename name of EEPROM image 
55
     * \return 0 on success, error code otherwise
56
     */
57
    virtual int usrp_load_eeprom(std::string filestring) = 0;
58

  
59
    /*!
53 60
     * Set led usrp 
54 61
     * \param led_num which LED to control (0 or 1)
55 62
     * \param on turn LED on or off
......
127 134
                                   unsigned char *buff,
128 135
                                   boost::uint16_t length) = 0;
129 136

  
137
    /*!
138
     * Perform an I2C write
139
     * \param i2c_addr I2C device address
140
     * \param buf data to be written 
141
     * \param len length of data in bytes
142
     * \return number of bytes written or error 
143
     */
144

  
145
    virtual int usrp_i2c_write(boost::uint16_t i2c_addr,
146
                               unsigned char *buf, 
147
                               boost::uint16_t len) = 0;
148

  
149
    /*!
150
     * Perform an I2C read
151
     * \param i2c_addr I2C device address
152
     * \param buf data to be read 
153
     * \param len length of data in bytes
154
     * \return number of bytes read or error 
155
     */
156

  
157
    virtual int usrp_i2c_read(boost::uint16_t i2c_addr,
158
                               unsigned char *buf, 
159
                               boost::uint16_t len) = 0;
160

  
130 161
};
131 162

  
132 163
#endif /* INCLUDED_USRP_CTRL_HPP */
b/host/lib/usrp/usrp1/usrp1_iface.cpp
109 109
     ******************************************************************/
110 110
    static const size_t max_i2c_data_bytes = 64;
111 111

  
112
    //TODO: make this handle EEPROM page sizes. right now you can't write over a 16-byte boundary.
113
    //to accomplish this you'll have to have addr offset as a separate parameter.
114

  
112 115
    void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes)
113 116
    {
114 117
        UHD_ASSERT_THROW(bytes.size() < max_i2c_data_bytes);
115 118

  
116 119
        unsigned char buff[max_i2c_data_bytes];
117
        std::copy(bytes.begin(), bytes.end(), buff); 
120
        std::copy(bytes.begin(), bytes.end(), buff);
118 121

  
119
        int ret = _ctrl_transport->usrp_control_write(VRQ_I2C_WRITE,
120
                                                      addr & 0xff,
121
                                                      0,
122
                                                      buff,
123
                                                      bytes.size());
122
        int ret = _ctrl_transport->usrp_i2c_write(addr & 0xff,
123
                                             buff,
124
                                             bytes.size());
124 125

  
125 126
        // TODO throw and catch i2c failures during eeprom read
126 127
        if (iface_debug && (ret < 0))
......
132 133
        UHD_ASSERT_THROW(num_bytes < max_i2c_data_bytes);
133 134

  
134 135
        unsigned char buff[max_i2c_data_bytes];
135
        int ret = _ctrl_transport->usrp_control_read(VRQ_I2C_READ,
136
                                                     addr & 0xff,
137
                                                     0,
138
                                                     buff,
139
                                                     num_bytes);
136
        int ret = _ctrl_transport->usrp_i2c_read(addr & 0xff,
137
                                            buff,
138
                                            num_bytes);
140 139

  
141 140
        // TODO throw and catch i2c failures during eeprom read
142 141
        if (iface_debug && ((ret < 0) || (unsigned)ret < (num_bytes))) {
b/host/lib/usrp/usrp1/usrp1_impl.cpp
34 34
using namespace uhd::usrp;
35 35
using namespace uhd::transport;
36 36

  
37
const boost::uint16_t USRP1_VENDOR_ID  = 0xfffe;
38
const boost::uint16_t USRP1_PRODUCT_ID = 0x0002;
39
const boost::uint16_t FX2_VENDOR_ID    = 0x04b4;
40
const boost::uint16_t FX2_PRODUCT_ID   = 0x8613;
41

  
37 42
const std::vector<usrp1_impl::dboard_slot_t> usrp1_impl::_dboard_slots = boost::assign::list_of
38 43
    (usrp1_impl::DBOARD_SLOT_A)(usrp1_impl::DBOARD_SLOT_B)
39 44
;
......
54 59
    );
55 60
    std::cout << "USRP1 firmware image: " << usrp1_fw_image << std::endl;
56 61

  
62
    boost::uint16_t vid = hint.has_key("uninit") ? FX2_VENDOR_ID : USRP1_VENDOR_ID;
63
    boost::uint16_t pid = hint.has_key("uninit") ? FX2_PRODUCT_ID : USRP1_PRODUCT_ID;
64

  
57 65
    //see what we got on the USB bus
58 66
    std::vector<usb_device_handle::sptr> device_list =
59
        usb_device_handle::get_device_list();
67
        usb_device_handle::get_device_list(vid, pid);
68

  
69
    if(device_list.size() == 0) return usrp1_addrs; //return nothing if no USRPs found
60 70

  
61 71
    //find the usrps and load firmware
62 72
    BOOST_FOREACH(usb_device_handle::sptr handle, device_list) {
63
        if (handle->get_vendor_id() == 0xfffe &&
64
            handle->get_product_id() == 0x0002) {
65

  
66 73
            usb_control::sptr ctrl_transport = usb_control::make(handle);
67 74
            usrp_ctrl::sptr usrp_ctrl = usrp_ctrl::make(ctrl_transport);
68 75
            usrp_ctrl->usrp_load_firmware(usrp1_fw_image);
69
        }
70 76
    }
71 77

  
72
    //get descriptors again with serial number
73
    device_list = usb_device_handle::get_device_list();
78
    //get descriptors again with serial number, but using the initialized VID/PID now since we have firmware
79
    vid = USRP1_VENDOR_ID;
80
    pid = USRP1_PRODUCT_ID;
81
    device_list = usb_device_handle::get_device_list(vid, pid);
74 82

  
75 83
    BOOST_FOREACH(usb_device_handle::sptr handle, device_list) {
76
        if (handle->get_vendor_id() == 0xfffe &&
77
            handle->get_product_id() == 0x0002) {
78

  
79 84
            device_addr_t new_addr;
80 85
            new_addr["type"] = "usrp1";
81 86
            new_addr["serial"] = handle->get_serial();
82 87
            usrp1_addrs.push_back(new_addr);
83
        }
84 88
    }
85 89

  
86 90
    return usrp1_addrs;
......
99 103

  
100 104
    //try to match the given device address with something on the USB bus
101 105
    std::vector<usb_device_handle::sptr> device_list =
102
        usb_device_handle::get_device_list();
106
        usb_device_handle::get_device_list(USRP1_VENDOR_ID, USRP1_PRODUCT_ID);
103 107

  
104 108
    //create data and control transports
105 109
    usb_zero_copy::sptr data_transport;
106 110
    usrp_ctrl::sptr usrp_ctrl;
107 111

  
108
    BOOST_FOREACH(usb_device_handle::sptr handle, device_list) {
109
        if (handle->get_vendor_id() == 0xfffe &&
110
            handle->get_product_id() == 0x0002 &&
111
            handle->get_serial() == device_addr["serial"]) {
112 112

  
113
    BOOST_FOREACH(usb_device_handle::sptr handle, device_list) {
114
        if (handle->get_serial() == device_addr["serial"]) {
113 115
            usb_control::sptr ctrl_transport = usb_control::make(handle);
114 116
            usrp_ctrl = usrp_ctrl::make(ctrl_transport);
115 117
            usrp_ctrl->usrp_load_fpga(usrp1_fpga_image);
b/host/utils/CMakeLists.txt
39 39
ADD_EXECUTABLE(usrp_burn_db_eeprom usrp_burn_db_eeprom.cpp)
40 40
TARGET_LINK_LIBRARIES(usrp_burn_db_eeprom uhd)
41 41

  
42
ADD_EXECUTABLE(usrp_init_eeprom usrp_init_eeprom.cpp)
43
TARGET_LINK_LIBRARIES(usrp_init_eeprom uhd)
44

  
42 45
INSTALL(TARGETS
43 46
    usrp2_addr_burner
44 47
    usrp_burn_db_eeprom
48
    usrp_init_eeprom
45 49
    RUNTIME DESTINATION ${PKG_DATA_DIR}/utils
46 50
)
47 51

  
b/host/utils/usrp_init_eeprom.cpp
1
//
2
// Copyright 2010 Ettus Research LLC
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

  
18
#include <uhd/utils/safe_main.hpp>
19
#include <uhd/device.hpp>
20
#include <uhd/usrp/device_props.hpp>
21
#include <boost/program_options.hpp>
22
#include <boost/format.hpp>
23
#include <iostream>
24

  
25
namespace po = boost::program_options;
26

  
27
int UHD_SAFE_MAIN(int argc, char *argv[]){
28
    po::options_description desc("Allowed options");
29
    desc.add_options()
30
        ("help", "help message")
31
        ("image", po::value<std::string>(), "IHX image file")
32
    ;
33

  
34
    po::variables_map vm;
35
    po::store(po::parse_command_line(argc, argv, desc), vm);
36
    po::notify(vm); 
37

  
38
    //print the help message
39
    if (vm.count("help")){
40
        std::cout << boost::format("USRP EEPROM initialization %s") % desc << std::endl;
41
        return ~0;
42
    }
43

  
44
    //load the options into the address
45
    uhd::device_addr_t device_addr;
46
    device_addr["type"] = "usrp1";
47
    device_addr["uninit"] = "yeah"; //tell find to look for an uninitialized FX2
48

  
49
    //find and create a control transport to do the writing.
50

  
51
    uhd::device_addrs_t found_addrs = uhd::device::find(device_addr);
52

  
53
    if (found_addrs.size() == 0){
54
        std::cerr << "No uninitialized USRP devices found" << std::endl;
55
        return ~0;
56
    }
57

  
58
    for (size_t i = 0; i < found_addrs.size(); i++){
59
        std::cout << "Writing EEPROM data..." << std::endl;
60
        //uhd::device_addrs_t devs = uhd::device::find(found_addrs[i]);
61
        uhd::device::sptr dev = uhd::device::make(found_addrs[i]);
62
        wax::obj mb = (*dev)[uhd::usrp::DEVICE_PROP_MBOARD];
63
        mb[std::string("load_eeprom")] = vm["image"].as<std::string>();
64
    }
65

  
66

  
67
    std::cout << "Power-cycle the usrp for the changes to take effect." << std::endl;
68
    return 0;
69
}

Also available in: Unified diff