1 |
130 |
jt_eaton |
#!/usr/bin/perl -w
|
2 |
|
|
# Copyright 2009, Andrew Ross
|
3 |
|
|
# Distributable under the terms of the GNU GPL licence version 2 or later.
|
4 |
|
|
use strict;
|
5 |
|
|
use POSIX qw(isatty);
|
6 |
|
|
use Time::HiRes qw(usleep);
|
7 |
|
|
|
8 |
|
|
# prog_usbblaster - turn a Digilent FPGA board over USB into a usbblaster
|
9 |
|
|
#
|
10 |
|
|
# Usage: prog_usbblaster [-v|--verbose]
|
11 |
|
|
#
|
12 |
|
|
# This script automatically finds an attached Nexys 2 board and loads
|
13 |
|
|
# it with the specified Xilinx bitstream with a minimum of fuss,
|
14 |
|
|
# configuration, and external dependencies. Specifically, the
|
15 |
|
|
# hacked/patched firmware for the Cypress FX2 chip is stored inline.
|
16 |
|
|
# The user only needs user-level software installed and a single local
|
17 |
|
|
# configuration change (optional, for the USB device files -- the lazy
|
18 |
|
|
# can just run the script as root).
|
19 |
|
|
#
|
20 |
|
|
# Prerequisites:
|
21 |
|
|
#
|
22 |
|
|
# 1. A working Xilinx ISE installation. This was tested against 10.1,
|
23 |
|
|
# but I believe older versions share the same iMPACT syntax and
|
24 |
|
|
# BSDL file locations.
|
25 |
|
|
#
|
26 |
|
|
# 2. The "fxload" utility is required to reprogram the board's FX2 USB
|
27 |
|
|
# chip, available in Debian and Ubuntu via "apt-get install
|
28 |
|
|
# fxload". Note that fxload requires write access to the raw USB
|
29 |
|
|
# device files under /dev/bus/usb, and that these are by default
|
30 |
|
|
# read-only on Ubuntu Intrepid. You can either run the script as
|
31 |
|
|
# root, or else set the files to be owned by the "plugdev" group by
|
32 |
|
|
# adding the GROUP field to this line in
|
33 |
|
|
# /etc/udev/rules.d/40-basic-permissions.rules:
|
34 |
|
|
# SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664", GROUP="plugdev"
|
35 |
|
|
#
|
36 |
|
|
# 3. UrJTAG, available from http://urjtag.org. UrJTAG is an active
|
37 |
|
|
# fork of the moribund openwince-jtag project. Note that
|
38 |
|
|
# openwince-jtag is still an available Debian/Ubuntu package, that
|
39 |
|
|
# it shares the same "jtag" binary name and most of its syntax, and
|
40 |
|
|
# that IT DOES NOT WORK with the firmware in this script. You need
|
41 |
|
|
# to install UrJTAG. Also note that you will need libftdi
|
42 |
|
|
# installed for the protocol handler, again available on
|
43 |
|
|
# Debian/Ubuntu via "apt-get install libftdi1". UrJTAG will build
|
44 |
|
|
# without this, but you won't be able to program the Nexys 2
|
45 |
|
|
# without libftdi.
|
46 |
|
|
#
|
47 |
|
|
# Note that this script contains a binary firmware blob built from
|
48 |
|
|
# free software sources. See the note above it for source
|
49 |
|
|
# information.
|
50 |
|
|
|
51 |
|
|
|
52 |
|
|
# TODO:
|
53 |
|
|
# + Figure out the JTAG interface for the boot PROM, so it can be
|
54 |
|
|
# flashed with the bitstream instead of (or in addition to) doing a
|
55 |
|
|
# direct load to the FPGA.
|
56 |
|
|
# + Pull down and parse the JTAG chain from the device to verify that
|
57 |
|
|
# it's actually a Nexys 2 and not another device sharing the same
|
58 |
|
|
# firmware family and bus ID. Kolja's firmware runs on other
|
59 |
|
|
# devices too...
|
60 |
|
|
# + Extend the script to recognize arbitrary JTAG chains and find the
|
61 |
|
|
# appropriate part number automatically. So you'd just specify a
|
62 |
|
|
# .bit file (which contains the FPGA type) and it would crawl the
|
63 |
|
|
# JTAG bus looking for a matching FPGA to program.
|
64 |
|
|
|
65 |
|
|
my $USBID_KOLJA = "16c0:06ad";
|
66 |
|
|
my $USBID_DIGILENT = "1443:0005";
|
67 |
|
|
my $XILINX;
|
68 |
|
|
my $TMPID = sprintf("./digilent-blastcode", $$);
|
69 |
|
|
|
70 |
|
|
my $verbose = 0;
|
71 |
|
|
my $filebase;
|
72 |
|
|
my $bit;
|
73 |
|
|
|
74 |
|
|
# Parse the command line
|
75 |
|
|
while(@ARGV) {
|
76 |
|
|
my $arg = shift;
|
77 |
|
|
if($arg eq "-v" or $arg eq "--verbose") { $verbose = 1; }
|
78 |
|
|
elsif(!defined $bit and -f $arg and -R $arg) {
|
79 |
|
|
$bit = $arg;
|
80 |
|
|
$filebase = $bit;
|
81 |
|
|
$filebase =~ s/\.bit$//i;
|
82 |
|
|
} else { }
|
83 |
|
|
}
|
84 |
|
|
|
85 |
|
|
|
86 |
|
|
# Find the tools
|
87 |
|
|
check_tools();
|
88 |
|
|
|
89 |
|
|
# Locate and configure the board's USB interface
|
90 |
|
|
find_board();
|
91 |
|
|
|
92 |
|
|
|
93 |
|
|
########################################################################
|
94 |
|
|
|
95 |
|
|
sub usage { die "Usage:\n $0 [-v|--verbose] \n"; }
|
96 |
|
|
sub vlog { print join("", @_) if $verbose; }
|
97 |
|
|
|
98 |
|
|
# Idiot-proofing, to help mitigate the Rube Goldbergisms inherent in
|
99 |
|
|
# this process.
|
100 |
|
|
sub check_tools {
|
101 |
|
|
system("which fxload >/dev/null") == 0 or die
|
102 |
|
|
("Cannot find fxload executable.\n".
|
103 |
|
|
"Try: \"apt-get install fxload\" ?\n");
|
104 |
|
|
}
|
105 |
|
|
|
106 |
|
|
sub find_board {
|
107 |
|
|
my $nx = find_digilent();
|
108 |
|
|
die "Cannot find a digilent board on the USB bus. Plug it in?\n"
|
109 |
|
|
if(!defined $nx);
|
110 |
|
|
my ($bus, $dev, $id) = @$nx;
|
111 |
|
|
if($id ne $USBID_KOLJA) {
|
112 |
|
|
$dev = blasterize($bus, $dev);
|
113 |
|
|
} else {
|
114 |
|
|
vlog("Found already-configured board on bus $bus dev $dev\n");
|
115 |
|
|
}
|
116 |
|
|
}
|
117 |
|
|
|
118 |
|
|
|
119 |
|
|
|
120 |
|
|
# Run an external tool, emitting the output only if it fails. iMPACT
|
121 |
|
|
# and UrJTAG are annoyingly verbose...
|
122 |
|
|
sub run {
|
123 |
|
|
my $cmd = shift;
|
124 |
|
|
print($cmd, "\n") if $verbose;
|
125 |
|
|
open CMD, "$cmd 2>&1|" or die;
|
126 |
|
|
# FIXME: if the subprocess crashes (as jtag does without a cable),
|
127 |
|
|
# we get incomplete output...
|
128 |
|
|
my $out = join "", ;
|
129 |
|
|
close CMD;
|
130 |
|
|
die "Command failure:\n $cmd\n\n$out" if $?;
|
131 |
|
|
}
|
132 |
|
|
|
133 |
|
|
sub find_digilent {
|
134 |
|
|
my ($bus, $dev, $id);
|
135 |
|
|
open LSUSB, "lsusb|" or die "Cannot run lsusb";
|
136 |
|
|
while() {
|
137 |
|
|
next if ! /Bus (\d+) Device (\d+): ID ([0-9a-f]{4}:[0-9a-f]{4})/;
|
138 |
|
|
next if !($3 eq $USBID_DIGILENT or $3 eq $USBID_KOLJA);
|
139 |
|
|
($bus, $dev, $id) = ($1, $2, $3);
|
140 |
|
|
}
|
141 |
|
|
close LSUSB;
|
142 |
|
|
if(defined $bus) {
|
143 |
|
|
vlog("Found USB device $id on bus $bus device $dev\n");
|
144 |
|
|
return [$bus, $dev, $id];
|
145 |
|
|
}
|
146 |
|
|
return undef;
|
147 |
|
|
}
|
148 |
|
|
|
149 |
|
|
# Reprogram a connected FX2 device with Kolja Waschk's usb_jtag
|
150 |
|
|
# firmware, patched to support the Nexys 2 pin assignments and FPGA
|
151 |
|
|
# bitstream sizes as per Morgan Delahaye's instructions at
|
152 |
|
|
# http://m-del.net/info.html. Uses the fxload tool from the
|
153 |
|
|
# linux-hotplug project. The end result is an interface compatible
|
154 |
|
|
# with the FTDI-based Altera USBBlaster product.
|
155 |
|
|
sub blasterize {
|
156 |
|
|
my ($bus, $dev) = @_;
|
157 |
|
|
my $usbfile = "/dev/bus/usb/$bus/$dev";
|
158 |
|
|
if(!-w $usbfile) {
|
159 |
|
|
die ("Cannot write to $usbfile.\n\n" .
|
160 |
|
|
"Either run this tool as root or modify your udev settings to\n" .
|
161 |
|
|
"allow write access to USB device files.\n");
|
162 |
|
|
}
|
163 |
|
|
my $firmware = gen_fx2();
|
164 |
|
|
vlog("Loading 8051 firmware into board...\n");
|
165 |
|
|
run("fxload -t fx2 -D $usbfile -I $firmware");
|
166 |
|
|
my $nx;
|
167 |
|
|
# Wait for it to reboot, renumerate and appear on the bus.
|
168 |
|
|
for(my $i=0; $i<20; $i++) {
|
169 |
|
|
usleep 10000;
|
170 |
|
|
last if defined($nx = find_digilent()) and $nx->[2] eq $USBID_KOLJA;
|
171 |
|
|
}
|
172 |
|
|
if(!defined $nx or $nx->[2] ne $USBID_KOLJA) {
|
173 |
|
|
die ("Reprogrammed FX2 device not found on USB bus.\n",
|
174 |
|
|
"fxload failure? device unplugged? ... !?\n");
|
175 |
|
|
}
|
176 |
|
|
return $nx->[1];
|
177 |
|
|
}
|
178 |
|
|
|
179 |
|
|
|
180 |
|
|
|
181 |
|
|
# Firmware for the FX2 chip
|
182 |
|
|
# Original source (GPLv2) -- http://www.ixo.de/info/usb_jtag
|
183 |
|
|
# Modifications:
|
184 |
|
|
# hw_nexys.c -- http://www.m-del.net/files/nexys/hw_nexys2.c
|
185 |
|
|
# bit_fpga.patch -- http://www.m-del.net/files/nexys/big_fpga.patch
|
186 |
|
|
# It was built with the sdcc-nf ("non-free") compiler from Ubuntu 8.10
|
187 |
|
|
# multiverse, and the resulting Intel hex file was filtered through
|
188 |
|
|
# bzip2 and then base64 to produce the string below.
|
189 |
|
|
sub gen_fx2 {
|
190 |
|
|
my $filename = "$TMPID.fx2";
|
191 |
|
|
vlog("Unpacking FX2 firmware to $filename\n");
|
192 |
|
|
open FX2, "|base64 -d | bzip2 -d > $filename"
|
193 |
|
|
or die "cannot write to $filename";
|
194 |
|
|
print FX2 <<__EOF__
|
195 |
|
|
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
|
277 |
|
|
__EOF__
|
278 |
|
|
;
|
279 |
|
|
close FX2;
|
280 |
|
|
return $filename;
|
281 |
|
|
}
|
282 |
|
|
|