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