aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/x300/x300_fpga_downloader.py
diff options
context:
space:
mode:
authorBen Hilburn <ben.hilburn@ettus.com>2014-02-14 12:05:07 -0800
committerBen Hilburn <ben.hilburn@ettus.com>2014-02-14 12:05:07 -0800
commitff1546f8137f7f92bb250f685561b0c34cc0e053 (patch)
tree7fa6fd05c8828df256a1b20e2935bd3ba9899e2c /firmware/x300/x300_fpga_downloader.py
parent4f691d88123784c2b405816925f1a1aef69d18c1 (diff)
downloaduhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.tar.gz
uhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.tar.bz2
uhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.zip
Pushing the bulk of UHD-3.7.0 code.
Diffstat (limited to 'firmware/x300/x300_fpga_downloader.py')
-rwxr-xr-xfirmware/x300/x300_fpga_downloader.py179
1 files changed, 0 insertions, 179 deletions
diff --git a/firmware/x300/x300_fpga_downloader.py b/firmware/x300/x300_fpga_downloader.py
deleted file mode 100755
index 5529afcb7..000000000
--- a/firmware/x300/x300_fpga_downloader.py
+++ /dev/null
@@ -1,179 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2010-2011 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/>.
-#
-
-import optparse
-import math
-import socket
-import struct
-import time
-import sys
-
-########################################################################
-# constants
-########################################################################
-B250_FPGA_IMAGE_SIZE_BYTES = 15877916
-B250_FPGA_PROG_UDP_PORT = 49157
-
-B250_FPGA_PROG_FLAGS_ACK = 1
-B250_FPGA_PROG_FLAGS_ERROR = 2
-B250_FPGA_PROG_FLAGS_INIT = 4
-B250_FPGA_PROG_FLAGS_CLEANUP = 8
-B250_FPGA_PROG_FLAGS_ERASE = 16
-B250_FPGA_PROG_FLAGS_VERIFY = 32
-B250_FPGA_PROG_CONFIGURE = 64
-B250_FPGA_PROG_CONFIG_STATUS = 128
-
-B250_FLASH_SECTOR_SIZE = 131072
-B250_PACKET_SIZE = 256
-B250_FPGA_SECTOR_START = 16
-
-B250_MAX_RESPONSE_BYTES = 128
-UDP_TIMEOUT = 3
-FPGA_LOAD_TIMEOUT = 15
-
-########################################################################
-# helper functions
-########################################################################
-def get_options():
- parser = optparse.OptionParser()
- parser.add_option("--addr", type="string", help="USRP-B250 device address", default='')
- parser.add_option("--download", type="string", help="Path to the FPGA image to download.", default=None)
- parser.add_option("--posc", type="string", help="Path to the POSC image to download.", default=None)
- parser.add_option("--program", action="store_true", help="Program the FPGA from flash.", default=False)
- parser.add_option("--verify", action="store_true", help="Verify data downloaded to flash.", default=False)
- (options, args) = parser.parse_args()
- return options
-
-def draw_progress_bar(percent, bar_len = 28):
- sys.stdout.write("\r")
- progress = ""
- for i in range(bar_len):
- if i < int((bar_len * percent) / 100):
- progress += "="
- else:
- progress += "-"
- sys.stdout.write("[%s] %d%%" % (progress, percent))
- sys.stdout.flush()
-
-def unpack_x300_fpga_flags_fmt(s):
- return struct.unpack('!L', s)[0] #(flags)
-
-def pack_x300_fpga_prog_fmt(flags, sector, offset, size, data):
- return struct.pack("!LLLL%dH" % (len(data),), flags, sector, offset, size, *data)
-
-def bit_reverse(byte):
- b = ord(byte)
- b = (b & 0xF0) >> 4 | (b & 0x0F) << 4
- b = (b & 0xCC) >> 2 | (b & 0x33) << 2
- b = (b & 0xAA) >> 1 | (b & 0x55) << 1
- return chr(b)
-
-def chunkify(stuff, n):
- return [stuff[i:i+n] for i in range(0, len(stuff), n)]
-
-########################################################################
-# Burner class, holds a socket and send/recv routines
-########################################################################
-class ctrl_socket(object):
- def __init__(self, addr):
- self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- self._sock.settimeout(UDP_TIMEOUT)
- self._sock.connect((addr, B250_FPGA_PROG_UDP_PORT))
- self.set_callbacks(lambda *a: None, lambda *a: None)
-
- def set_callbacks(self, progress_cb, status_cb):
- self._progress_cb = progress_cb
- self._status_cb = status_cb
-
- def send_without_ack(self, pkt):
- self._sock.send(pkt)
-
- def send_with_ack(self, out_pkt, message):
- self.send_without_ack(out_pkt)
- in_pkt = self._sock.recv(B250_MAX_RESPONSE_BYTES)
- flags = unpack_x300_fpga_flags_fmt(in_pkt)
- if flags & B250_FPGA_PROG_FLAGS_ERROR == B250_FPGA_PROG_FLAGS_ERROR:
- raise Exception(message)
-
- def download_fpga(self, image, verify):
- print("Reading FPGA image file...")
- fpga_file = open(image, 'rb')
- print("Processing FPGA image...")
- fpga_image = ''.join([ bit_reverse(b) for b in fpga_file.read() ])
-
- print("Writing FPGA image to flash...")
- out_pkt = pack_x300_fpga_prog_fmt(B250_FPGA_PROG_FLAGS_ACK|B250_FPGA_PROG_FLAGS_INIT,
- 0, 0, 0, [0]*(B250_PACKET_SIZE/2))
- self.send_with_ack(out_pkt, "Flash initialization failed!!!")
-
- sector_chunks = chunkify(fpga_image, B250_FLASH_SECTOR_SIZE)
- for sector_idx in range(len(sector_chunks)):
- packet_chunks = chunkify(sector_chunks[sector_idx], B250_PACKET_SIZE)
- offset = 0
- for packet_data in packet_chunks:
- data = struct.unpack("%dH" % (len(packet_data) / 2), packet_data)
- flags = B250_FPGA_PROG_FLAGS_ACK
- if offset == 0: flags |= B250_FPGA_PROG_FLAGS_ERASE
- if verify: flags |= B250_FPGA_PROG_FLAGS_VERIFY
- out_pkt = pack_x300_fpga_prog_fmt(flags, B250_FPGA_SECTOR_START+sector_idx, offset, len(data), data)
- self.send_with_ack(out_pkt, "Transfer failed or data verification failed!!!")
- offset += len(data)
- draw_progress_bar(((sector_idx+1)*100)/len(sector_chunks))
-
- print(' ')
- out_pkt = pack_x300_fpga_prog_fmt(B250_FPGA_PROG_FLAGS_ACK|B250_FPGA_PROG_FLAGS_CLEANUP,
- 0, 0, 0, [0]*(B250_PACKET_SIZE/2))
- self.send_with_ack(out_pkt, "Flash cleanup failed!!!")
-
- def program(self):
- print("Programming FPGA from flash...")
- out_pkt = pack_x300_fpga_prog_fmt(B250_FPGA_PROG_CONFIGURE, 0, 0, 0, [0]*(B250_PACKET_SIZE/2))
- self.send_without_ack(out_pkt)
- print("Waiting for FPGA to load...")
- self._sock.settimeout(1)
- out_pkt = pack_x300_fpga_prog_fmt(B250_FPGA_PROG_FLAGS_ACK|B250_FPGA_PROG_CONFIG_STATUS, 0, 0, 0, [0]*(B250_PACKET_SIZE/2))
- for i in range(FPGA_LOAD_TIMEOUT):
- try:
- self.send_without_ack(out_pkt)
- in_pkt = self._sock.recv(B250_MAX_RESPONSE_BYTES)
- flags = unpack_x300_fpga_flags_fmt(in_pkt)
- if not(flags & B250_FPGA_PROG_FLAGS_ERROR == B250_FPGA_PROG_FLAGS_ERROR):
- break
- except socket.error:
- pass
-
-
-########################################################################
-# main
-########################################################################
-if __name__=='__main__':
- options = get_options()
-
- if not options.addr:
- raise Exception('No address specified')
-
- status = ctrl_socket(addr=options.addr)
-
- start_time = time.time()
- if options.download is not None:
- status.download_fpga(options.download, options.verify)
-
- if options.program:
- status.program()
-
- print("(Elapsed time: %.1fs)" % (time.time() - start_time))