aboutsummaryrefslogtreecommitdiffstats
path: root/host/utils/usrp_n2xx_net_burner.py
diff options
context:
space:
mode:
Diffstat (limited to 'host/utils/usrp_n2xx_net_burner.py')
-rwxr-xr-xhost/utils/usrp_n2xx_net_burner.py151
1 files changed, 74 insertions, 77 deletions
diff --git a/host/utils/usrp_n2xx_net_burner.py b/host/utils/usrp_n2xx_net_burner.py
index 6fdc9df20..0b64f2008 100755
--- a/host/utils/usrp_n2xx_net_burner.py
+++ b/host/utils/usrp_n2xx_net_burner.py
@@ -92,7 +92,7 @@ def unpack_flash_info_fmt(s):
def unpack_flash_ip_fmt(s):
return struct.unpack(FLASH_IP_FMT, s) #(proto_ver, pktid, seq, ip_addr)
-def pack_flash_args_fmt(proto_ver, pktid, seq, flash_addr, length, data):
+def pack_flash_args_fmt(proto_ver, pktid, seq, flash_addr, length, data=bytes()):
return struct.pack(FLASH_ARGS_FMT, proto_ver, pktid, seq, flash_addr, length, data)
def pack_flash_info_fmt(proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes):
@@ -100,69 +100,60 @@ def pack_flash_info_fmt(proto_ver, pktid, seq, sector_size_bytes, memory_size_by
def is_valid_fpga_image(fpga_image):
for i in range(0,63):
- if ord(fpga_image[i]) == 0xFF:
- continue
- if ord(fpga_image[i]) == 0xAA and ord(fpga_image[i+1]) == 0x99:
- return 1
-
- return 0
+ if fpga_image[i:i+1] == bytes(b'\xFF'): continue
+ if fpga_image[i:i+2] == bytes(b'\xAA\x99'): return True
+ return False
def is_valid_fw_image(fw_image):
- for i in range(0,4):
- if ord(fw_image[i]) != 0x0B:
- return 0;
-
- return 1
+ return fw_image[:4] == bytes(b'\x0B\x0B\x0B\x0B')
########################################################################
# Burner class, holds a socket and send/recv routines
########################################################################
class burner_socket(object):
- def __init__(self, ip):
+ def __init__(self, addr):
self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self._sock.settimeout(UDP_TIMEOUT)
- self._sock.connect((ip, UDP_FW_UPDATE_PORT))
-
- def send_and_recv(self, pkt):
- try: self._sock.send(pkt)
- except Exception, e:
- print e
- sys.exit(1)
+ self._sock.connect((addr, UDP_FW_UPDATE_PORT))
+ self.set_callbacks(lambda *a: None, lambda *a: None)
+ self.init_update() #check that the device is there
- try: recv_pkt = self._sock.recv(UDP_MAX_XFER_BYTES)
- except Exception, e:
- print e
- sys.exit(1)
+ def set_callbacks(self, progress_cb, status_cb):
+ self._progress_cb = progress_cb
+ self._status_cb = status_cb
- return recv_pkt
+ def send_and_recv(self, pkt):
+ self._sock.send(pkt)
+ return self._sock.recv(UDP_MAX_XFER_BYTES)
#just here to validate comms
def init_update(self):
- out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_OHAI_LOL, seq(), 0, 0, "")
- in_pkt = self.send_and_recv(out_pkt)
+ out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_OHAI_LOL, seq(), 0, 0)
+ try: in_pkt = self.send_and_recv(out_pkt)
+ except socket.timeout: raise Exception("No response from device")
(proto_ver, pktid, rxseq, ip_addr) = unpack_flash_ip_fmt(in_pkt)
if pktid == update_id_t.USRP2_FW_UPDATE_ID_OHAI_OMG:
- print "USRP2P found."
+ print("USRP-N2XX found.")
else:
- raise Exception, "Invalid reply received from device."
+ raise Exception("Invalid reply received from device.")
# print "Incoming:\n\tVer: %i\n\tID: %c\n\tSeq: %i\n\tIP: %i\n" % (proto_ver, chr(pktid), rxseq, ip_addr)
def get_flash_info(self):
- out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WATS_TEH_FLASH_INFO_LOL, seq(), 0, 0, "")
+ out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WATS_TEH_FLASH_INFO_LOL, seq(), 0, 0)
in_pkt = self.send_and_recv(out_pkt)
(proto_ver, pktid, rxseq, sector_size_bytes, memory_size_bytes) = unpack_flash_info_fmt(in_pkt)
if pktid != update_id_t.USRP2_FW_UPDATE_ID_HERES_TEH_FLASH_INFO_OMG:
- raise Exception, "Invalid reply %c from device." % (chr(pktid))
+ raise Exception("Invalid reply %c from device." % (chr(pktid)))
return (memory_size_bytes, sector_size_bytes)
def burn_fw(self, fw, fpga, reset, safe):
(flash_size, sector_size) = self.get_flash_info()
- print "Flash size: %i\nSector size: %i\n\n" % (flash_size, sector_size)
+ print("Flash size: %i\nSector size: %i\n\n" % (flash_size, sector_size))
if fpga:
if safe: image_location = SAFE_FPGA_IMAGE_LOCATION_ADDR
@@ -172,20 +163,18 @@ class burner_socket(object):
fpga_image = fpga_file.read()
if len(fpga_image) > FPGA_IMAGE_SIZE_BYTES:
- print "Error: FPGA image file too large."
- return 0
+ raise Exception("Error: FPGA image file too large.")
if not is_valid_fpga_image(fpga_image):
- print "Error: Invalid FPGA image file."
- return 0
+ raise Exception("Error: Invalid FPGA image file.")
- print "Begin FPGA write: this should take about 1 minute..."
+ print("Begin FPGA write: this should take about 1 minute...")
start_time = time.time()
self.erase_image(image_location, FPGA_IMAGE_SIZE_BYTES)
self.write_image(fpga_image, image_location)
self.verify_image(fpga_image, image_location)
- print "Time elapsed: %f seconds"%(time.time() - start_time)
- print "\n\n"
+ print("Time elapsed: %f seconds"%(time.time() - start_time))
+ print("\n\n")
if fw:
if safe: image_location = SAFE_FW_IMAGE_LOCATION_ADDR
@@ -195,88 +184,91 @@ class burner_socket(object):
fw_image = fw_file.read()
if len(fw_image) > FW_IMAGE_SIZE_BYTES:
- print "Error: Firmware image file too large."
- return 0
+ raise Exception("Error: Firmware image file too large.")
if not is_valid_fw_image(fw_image):
- print "Error: Invalid firmware image file."
- return 0
+ raise Exception("Error: Invalid firmware image file.")
- print "Begin firmware write: this should take about 1 second..."
+ print("Begin firmware write: this should take about 1 second...")
start_time = time.time()
self.erase_image(image_location, FW_IMAGE_SIZE_BYTES)
self.write_image(fw_image, image_location)
self.verify_image(fw_image, image_location)
- print "Time elapsed: %f seconds"%(time.time() - start_time)
- print "\n\n"
+ print("Time elapsed: %f seconds"%(time.time() - start_time))
+ print("\n\n")
if reset: self.reset_usrp()
def write_image(self, image, addr):
- print "Writing image"
+ print("Writing image")
+ self._status_cb("Writing")
+ writedata = image
#we split the image into smaller (256B) bits and send them down the wire
- while image:
- out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL, seq(), addr, FLASH_DATA_PACKET_SIZE, image[:FLASH_DATA_PACKET_SIZE])
+ while writedata:
+ out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL, seq(), addr, FLASH_DATA_PACKET_SIZE, writedata[:FLASH_DATA_PACKET_SIZE])
in_pkt = self.send_and_recv(out_pkt)
(proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt)
if pktid != update_id_t.USRP2_FW_UPDATE_ID_WROTE_TEH_FLASHES_OMG:
- raise Exception, "Invalid reply %c from device." % (chr(pktid))
+ raise Exception("Invalid reply %c from device." % (chr(pktid)))
- image = image[FLASH_DATA_PACKET_SIZE:]
+ writedata = writedata[FLASH_DATA_PACKET_SIZE:]
addr += FLASH_DATA_PACKET_SIZE
+ self._progress_cb(float(len(image)-len(writedata))/len(image))
def verify_image(self, image, addr):
- print "Verifying data"
+ print("Verifying data")
+ self._status_cb("Verifying")
readsize = len(image)
- readdata = str()
+ readdata = bytes()
while readsize > 0:
if readsize < FLASH_DATA_PACKET_SIZE: thisreadsize = readsize
else: thisreadsize = FLASH_DATA_PACKET_SIZE
- out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize, "")
+ out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize)
in_pkt = self.send_and_recv(out_pkt)
(proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt)
if pktid != update_id_t.USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG:
- raise Exception, "Invalid reply %c from device." % (chr(pktid))
+ raise Exception("Invalid reply %c from device." % (chr(pktid)))
readdata += data[:thisreadsize]
readsize -= FLASH_DATA_PACKET_SIZE
addr += FLASH_DATA_PACKET_SIZE
+ self._progress_cb(float(len(readdata))/len(image))
- print "Read back %i bytes" % len(readdata)
+ print("Read back %i bytes" % len(readdata))
# print readdata
# for i in range(256, 512):
# print "out: %i in: %i" % (ord(image[i]), ord(readdata[i]))
if readdata != image:
- print "Verify failed. Image did not write correctly."
+ raise Exception("Verify failed. Image did not write correctly.")
else:
- print "Success."
+ print("Success.")
def read_image(self, image, size, addr):
- print "Reading image"
+ print("Reading image")
readsize = size
readdata = str()
while readsize > 0:
if readsize < FLASH_DATA_PACKET_SIZE: thisreadsize = readsize
else: thisreadsize = FLASH_DATA_PACKET_SIZE
- out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize, "")
+ out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize)
in_pkt = self.send_and_recv(out_pkt)
(proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt)
if pktid != update_id_t.USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG:
- raise Exception, "Invalid reply %c from device." % (chr(pktid))
+ raise Exception("Invalid reply %c from device." % (chr(pktid)))
readdata += data[:thisreadsize]
readsize -= FLASH_DATA_PACKET_SIZE
addr += FLASH_DATA_PACKET_SIZE
- print "Read back %i bytes" % len(readdata)
+ print("Read back %i bytes" % len(readdata))
#write to disk
f = open(image, 'w')
@@ -284,35 +276,40 @@ class burner_socket(object):
f.close()
def reset_usrp(self):
- out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL, seq(), 0, 0, "")
- in_pkt = self.send_and_recv(out_pkt)
+ out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL, seq(), 0, 0)
+ try: in_pkt = self.send_and_recv(out_pkt)
+ except socket.timeout: return
(proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt)
if pktid == update_id_t.USRP2_FW_UPDATE_ID_RESETTIN_TEH_COMPUTORZ_OMG:
- raise Exception, "Device failed to reset."
+ raise Exception("Device failed to reset.")
def erase_image(self, addr, length):
+ self._status_cb("Erasing")
#get flash info first
- out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL, seq(), addr, length, "")
+ out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL, seq(), addr, length)
in_pkt = self.send_and_recv(out_pkt)
(proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt)
if pktid != update_id_t.USRP2_FW_UPDATE_ID_ERASING_TEH_FLASHES_OMG:
- raise Exception, "Invalid reply %c from device." % (chr(pktid))
+ raise Exception("Invalid reply %c from device." % (chr(pktid)))
- print "Erasing %i bytes at %i" % (length, addr)
+ print("Erasing %i bytes at %i" % (length, addr))
+ start_time = time.time()
#now wait for it to finish
while(True):
- out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_R_U_DONE_ERASING_LOL, seq(), 0, 0, "")
+ out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_R_U_DONE_ERASING_LOL, seq(), 0, 0)
in_pkt = self.send_and_recv(out_pkt)
(proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt)
if pktid == update_id_t.USRP2_FW_UPDATE_ID_IM_DONE_ERASING_OMG: break
elif pktid != update_id_t.USRP2_FW_UPDATE_ID_NOPE_NOT_DONE_ERASING_OMG:
- raise Exception, "Invalid reply %c from device." % (chr(pktid))
+ raise Exception("Invalid reply %c from device." % (chr(pktid)))
+ time.sleep(0.01) #decrease network overhead by waiting a bit before polling
+ self._progress_cb(min(1.0, (time.time() - start_time)/(length/80e3)))
########################################################################
@@ -320,7 +317,7 @@ class burner_socket(object):
########################################################################
def get_options():
parser = optparse.OptionParser()
- parser.add_option("--ip", type="string", help="USRP2P firmware address", default='')
+ parser.add_option("--addr", type="string", help="USRP-N2XX device address", default='')
parser.add_option("--fw", type="string", help="firmware image path (optional)", default='')
parser.add_option("--fpga", type="string", help="fpga image path (optional)", default='')
parser.add_option("--reset", action="store_true", help="reset the device after writing", default=False)
@@ -335,23 +332,23 @@ def get_options():
########################################################################
if __name__=='__main__':
options = get_options()
- if not options.ip: raise Exception, 'no ip address specified'
+ if not options.addr: raise Exception('no address specified')
- if not options.fpga and not options.fw and not options.reset: raise Exception, 'Must specify either a firmware image or FPGA image, and/or reset.'
+ if not options.fpga and not options.fw and not options.reset: raise Exception('Must specify either a firmware image or FPGA image, and/or reset.')
if options.overwrite_safe and not options.read:
print("Are you REALLY, REALLY sure you want to overwrite the safe image? This is ALMOST ALWAYS a terrible idea.")
print("If your image is faulty, your USRP2+ will become a brick until reprogrammed via JTAG.")
- response = raw_input("""Type "yes" to continue, or anything else to quit: """)
+ response = input("""Type "yes" to continue, or anything else to quit: """)
if response != "yes": sys.exit(0)
- burner = burner_socket(ip=options.ip)
+ burner = burner_socket(addr=options.addr)
if options.read:
if options.fw:
file = options.fw
if os.path.isfile(file):
- response = raw_input("File already exists -- overwrite? (y/n) ")
+ response = input("File already exists -- overwrite? (y/n) ")
if response != "y": sys.exit(0)
size = FW_IMAGE_SIZE_BYTES
addr = SAFE_FW_IMAGE_LOCATION_ADDR if options.overwrite_safe else PROD_FW_IMAGE_LOCATION_ADDR
@@ -360,7 +357,7 @@ if __name__=='__main__':
if options.fpga:
file = options.fpga
if os.path.isfile(file):
- response = raw_input("File already exists -- overwrite? (y/n) ")
+ response = input("File already exists -- overwrite? (y/n) ")
if response != "y": sys.exit(0)
size = FPGA_IMAGE_SIZE_BYTES
addr = SAFE_FPGA_IMAGE_LOCATION_ADDR if options.overwrite_safe else PROD_FPGA_IMAGE_LOCATION_ADDR