mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
EEPROM burning in UHD. Changed some USB device handle stuff. Added usrp_init_eeprom.cpp. Hacked up the firmware makefile to behave and to generate .bin EEPROM images instead of IHX.
This commit is contained in:
parent
ad55e25aeb
commit
b96088b692
@ -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]
|
||||
|
||||
build_shell_script (sys.stdout, ihx_filename, options.rev)
|
||||
image = "".join(chr(c) for c in build_eeprom_image(infile, options.rev))
|
||||
|
||||
f = open(outfile, 'wb')
|
||||
f.write(str(image))
|
||||
f.close()
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -41,16 +41,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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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>()){
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -49,6 +49,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)
|
||||
@ -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 */
|
||||
|
||||
@ -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))) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
|
||||
69
host/utils/usrp_init_eeprom.cpp
Normal file
69
host/utils/usrp_init_eeprom.cpp
Normal file
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user