Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
C
Conv TTL Blocking
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
5
Issues
5
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Conv TTL Blocking
Commits
b6c633a6
Commit
b6c633a6
authored
Oct 23, 2014
by
Theodor-Adrian Stana
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sw: Added mass MultiBoot script
parent
a689ff59
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
578 additions
and
20 deletions
+578
-20
README
software/multiboot/README
+7
-20
comm_type.py
software/multiboot/lib-multiboot/comm_type.py
+52
-0
flash_m25p.py
software/multiboot/lib-multiboot/flash_m25p.py
+170
-0
xil_multiboot.py
software/multiboot/lib-multiboot/xil_multiboot.py
+158
-0
mass-multiboot.py
software/multiboot/mass-multiboot.py
+191
-0
No files found.
software/multiboot/README
.txt
→
software/multiboot/README
View file @
b6c633a6
...
...
@@ -33,25 +33,12 @@ it is currently writing to. Go grab a coffee, since this will take at least
11 mins, maybe even more if your network connection is not that good, or
you're using Windows
readflash.py
============
mass-multiboot.py
=================
Use the FPGA MultiBoot logic to update the gateware on multiple boards in one crate.
The update can only be done one card per crate and one crate at a time.
This script reads flash pages from a start to an end address, both of these
given by the user. As the multiboot.py script, it relies on the ei2c.py and
defines the same methods for SPI flash access as the multiboot.py script.
Maybe sometime in the future it will make sense to put these methods in a
class within a common module, but for now it works as is.
When you run it, it asks (as multiboot.py) for crate IP and login data, and then
for a start and end address. It then goes and reads the flash data between these
two addresses via the FPGA logic. The output is stored to a local file called
`flash.bin'.
Note that the script reads 256 bytes at a time from the flash, but does not
check if you gave it an address on a flash page boundary. Therefore, if you
don't give it a starting address which is a page boundary, it will output
data which is shifted by the amount of bytes the starting address is shifted
from the start of the page. For example, if you start reading from address
0x000110, the data in flash.bin will be shifted by 16 bytes when compared
to the flash contents.
For details on how to use it, run the help on it:
%> ./mass-multiboot.py --help
\ No newline at end of file
software/multiboot/lib-multiboot/comm_type.py
0 → 100644
View file @
b6c633a6
# Author: Theodor Stana <theodor.stana@gmail.com>
# Date: October 2014
#
# 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, you may find one here:
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# or you may search the http://www.gnu.org website for the version 2 license,
# or you may write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
# Communication type definitions
#
# Communication types are used in several places to define how to interact to
# the MultiBoot module (what interface is used to the FPGA) and to the on-board
# flash module (what interface exists between the FPGA and the flash chip).
#
# The scripts that use these definitions are organized as series of 'if'
# branches that execute specific commands based on the communication type being
# used. As an example of usage, grep for ELMA_I2C_MULTIBOOT in the current
# folder to see where it is used and how the specific commands are sent to
# interface to the Flash via the ELMA I2C protocol and the MultiBoot logic
# implemented on the FPGAs of blocking and RS-485 converter boards:
#
# grep -rnH ELMA_I2C_MULTIBOOT .
#
# Browse the code under the if branches, and apply your own code if you are
# implementing a new communication type. Note that inside the constructors of
# the XilMultiboot and FlashM25P classes there are variable parameters passed by
# the protocol type. In these constructors, you should decide on a sequence of
# parameters to be passed to the constructor. This sequence is specific to the
# communication type you are implementing. Then, add parameters specific to this
# new communication type that are to be used along the classes, and implement
# specific 'if' branches for the new communication type. An example of
# communication-type-specific parameters is the elma.write() and elma.read()
# methods, in the case of the ELMA_I2C_MULTIBOOT type.
ELMA_I2C_MULTIBOOT
=
0
;
YOUR_COMM_TYPE_HERE
=
1
;
software/multiboot/lib-multiboot/flash_m25p.py
0 → 100644
View file @
b6c633a6
# Author: Theodor Stana <theodor.stana@gmail.com>
# Date: October 2014
#
# 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, you may find one here:
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# or you may search the http://www.gnu.org website for the version 2 license,
# or you may write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
import
sys
sys
.
path
.
append
(
"../../ei2c"
)
from
ei2c
import
*
from
comm_type
import
*
class
FlashM25P
:
# Constructor
# comm_params -- communication parameters defining details about how this
# class should interface to the M25P flash chip
def
__init__
(
self
,
*
comm_params
):
self
.
comm
=
comm_params
[
0
]
if
(
comm_params
[
0
]
==
ELMA_I2C_MULTIBOOT
):
self
.
elma
=
comm_params
[
1
]
self
.
slot
=
comm_params
[
2
]
self
.
mb_base
=
comm_params
[
3
]
# Low-level SPI transfer using communication type defined in the constructor
#
# This method handles the OR-ing together of the data bytes and the control
# byte in FAR.
#
# Formatting of data bytes in the FAR register should be done outside this
# function.
def
spi_transfer
(
self
,
nbytes
,
cs
,
dat
):
# Communication type is ELMA I2C, therefore use MultiBoot logic on the
# FPGA to access the flash
if
(
self
.
comm
==
ELMA_I2C_MULTIBOOT
):
retval
=
0
wval
=
[]
# control byte, to be shifted left by 24
ctrl
=
((
cs
<<
3
)
|
0x4
)
|
(
nbytes
-
1
)
# Use appropriate command by type
#
# write - we send up to three data bytes in one FAR register write
# writemregs - we send up to 24 data bytes in eight FAR register writes
if
isinstance
(
dat
,
int
):
self
.
elma
.
write
(
self
.
slot
,
self
.
mb_base
+
0x10
,
(
ctrl
<<
24
)
|
dat
)
else
:
for
i
in
xrange
(
len
(
dat
)):
wval
.
append
((
ctrl
<<
24
)
|
dat
[
i
])
self
.
elma
.
writemregs
(
self
.
slot
,
self
.
mb_base
+
0x10
,
wval
)
# Read the data and prepare the return value
while
(
retval
&
(
1
<<
28
)
==
0
):
retval
=
self
.
elma
.
read
(
self
.
slot
,
self
.
mb_base
+
0x10
)
return
retval
&
0xffffff
# This function is used to write data bytes to flash. It calls self.spi_transfer
# and sends the commands to the flash chip. You can follow the logic of this
# function by looking at the sequence of the write command in [1]
def
write
(
self
,
addr
,
dat
):
# write enable cmd
self
.
spi_transfer
(
1
,
1
,
0x06
)
self
.
spi_transfer
(
1
,
0
,
0
)
# write page cmd
self
.
spi_transfer
(
1
,
1
,
0x02
)
# send address in reverse order
addr
=
((
addr
&
0xff0000
)
>>
16
)
|
(((
addr
&
0xff00
)
>>
8
)
<<
8
)
|
\
((
addr
&
0xff
)
<<
16
)
self
.
spi_transfer
(
3
,
1
,
addr
)
# Now, massage the data array into 3-byte commands sent in 32-bit
# registers, in batches of eight registers (writemregs command).
i
=
0
l
=
len
(
dat
)
while
(
l
):
wval
=
[]
# If we have more than 24 bytes left in the data array,
# we can use the full writemregs
if
(
int
(
l
/
24
)):
for
j
in
xrange
(
0
,
8
):
wval
.
append
((
dat
[(
i
+
2
)
+
3
*
j
]
<<
16
)
|
\
(
dat
[(
i
+
1
)
+
3
*
j
]
<<
8
)
|
dat
[
i
+
3
*
j
])
self
.
spi_transfer
(
3
,
1
,
wval
)
i
+=
24
;
l
-=
24
;
# When we're left to fewer than 24 bytes in the array,
# try to use one more writemregs with as many regs as possible
elif
(
int
(
l
/
3
)):
for
j
in
xrange
(
0
,
l
/
3
):
wval
.
append
((
dat
[(
i
+
2
)
+
3
*
j
]
<<
16
)
|
\
(
dat
[(
i
+
1
)
+
3
*
j
]
<<
8
)
|
dat
[
i
+
3
*
j
])
self
.
spi_transfer
(
3
,
1
,
wval
);
i
+=
3
*
int
(
l
/
3
)
l
-=
3
*
int
(
l
/
3
)
# When we're down to less than three bytes, just use simple one-byte xfers
elif
(
l
):
for
j
in
xrange
(
0
,
l
):
self
.
spi_transfer
(
1
,
1
,
dat
[
i
])
i
+=
1
l
-=
1
self
.
spi_transfer
(
1
,
0
,
0
)
# This function is used to read a number of data bytes from the flash memory
# It returns the values of the three consecutive flash registers packed into
# one 24-bit data value in little-endian order
def
read
(
self
,
addr
,
nrbytes
):
ret
=
[]
self
.
spi_transfer
(
1
,
1
,
0x0b
)
# send address in reverse order
addr
=
((
addr
&
0xff0000
)
>>
16
)
|
(((
addr
&
0xff00
)
>>
8
)
<<
8
)
|
\
((
addr
&
0xff
)
<<
16
)
self
.
spi_transfer
(
3
,
1
,
addr
)
self
.
spi_transfer
(
1
,
1
,
0
)
# Read bytes in groups of three
for
i
in
range
(
nrbytes
):
ret
.
append
(
self
.
spi_transfer
(
1
,
1
,
0
))
self
.
spi_transfer
(
1
,
0
,
0
)
return
ret
# Send a sector erase command
def
serase
(
self
,
addr
):
self
.
spi_transfer
(
1
,
1
,
0x06
)
self
.
spi_transfer
(
1
,
0
,
0
)
self
.
spi_transfer
(
1
,
1
,
0xD8
)
# send address in reverse order
addr
=
((
addr
&
0xff0000
)
>>
16
)
|
(((
addr
&
0xff00
)
>>
8
)
<<
8
)
|
\
((
addr
&
0xff
)
<<
16
)
self
.
spi_transfer
(
3
,
1
,
addr
)
self
.
spi_transfer
(
1
,
0
,
0
)
# Send a block erase command
def
berase
(
self
):
self
.
spi_transfer
(
1
,
1
,
0x06
)
self
.
spi_transfer
(
1
,
0
,
0
)
self
.
spi_transfer
(
1
,
1
,
0xc7
)
self
.
spi_transfer
(
1
,
0
,
0
)
# Read status register command
def
rsr
(
self
):
self
.
spi_transfer
(
1
,
1
,
0x05
)
ret
=
self
.
spi_transfer
(
1
,
1
,
0
)
self
.
spi_transfer
(
1
,
0
,
0
)
return
ret
software/multiboot/lib-multiboot/xil_multiboot.py
0 → 100644
View file @
b6c633a6
# Author: Theodor Stana <theodor.stana@gmail.com>
# Date: October 2014
#
# 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, you may find one here:
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# or you may search the http://www.gnu.org website for the version 2 license,
# or you may write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
import
sys
sys
.
path
.
append
(
"../../ei2c"
)
from
ei2c
import
*
from
ei2cexcept
import
*
import
time
from
functools
import
partial
from
comm_type
import
*
from
flash_m25p
import
*
#===============================================================================
MB_CR_OFS
=
0x00
MB_SR_OFS
=
0x04
MB_GBBAR_OFS
=
0x08
MB_MBBAR_OFS
=
0x0C
MB_FAR_OFS
=
0x10
#===============================================================================
class
XilMultiboot
:
# Constructor
def
__init__
(
self
,
*
param
):
if
param
[
0
]
==
ELMA_I2C_MULTIBOOT
:
self
.
comm
=
param
[
0
]
self
.
elma
=
param
[
1
]
self
.
slot
=
param
[
2
]
self
.
mb_base
=
param
[
3
]
self
.
bitstream
=
param
[
4
]
self
.
flash
=
FlashM25P
(
self
.
comm
,
self
.
elma
,
self
.
slot
,
self
.
mb_base
)
#
# Read from flash
#
def
read
(
self
,
sa
,
ea
):
# Ask for and open bitstream file
fname
=
raw_input
(
"Output file name: "
)
f
=
open
(
fname
,
'wb'
)
# Read the data and dump to file
dat
=
[]
for
i
in
range
(
sa
,
ea
,
256
):
dat
+=
self
.
flash
.
read
(
i
,
256
)
print
(
"(r:
%
d) 0x
%06
x"
%
(
self
.
slot
,
i
))
dat
=
''
.
join
(
map
(
chr
,
dat
))
f
.
write
(
dat
)
f
.
close
()
#
# Write to flash
#
def
write
(
self
,
addr
):
print
(
"Writing bitstream..."
)
# Ask for and open bitstream file
fname
=
self
.
bitstream
f
=
open
(
fname
,
'rb'
)
# Start reading input file 256 bytes at a time and write to flash
for
dat
in
iter
(
partial
(
f
.
read
,
256
),
''
):
dat
=
[
int
(
d
.
encode
(
"hex"
),
16
)
for
d
in
dat
]
print
(
"(w:
%
d) 0x
%
x"
%
(
self
.
slot
,
addr
))
# Erase on sector boundary
if
not
(
addr
%
0x10000
):
print
(
'erase'
)
self
.
flash
.
serase
(
addr
)
while
(
self
.
flash
.
rsr
()
&
0x01
):
pass
# Write data to page
self
.
flash
.
write
(
addr
,
dat
)
while
(
self
.
flash
.
rsr
()
&
0x01
):
pass
# increment to next page address
addr
+=
256
# Close file handle
f
.
close
()
print
(
"DONE!"
)
#
# Start IPROG sequence
#
def
iprog
(
self
,
addr
):
if
(
self
.
comm
==
ELMA_I2C_MULTIBOOT
):
print
(
"Issuing IPROG command to board in slot
%
d..."
%
self
.
slot
)
self
.
elma
.
write
(
self
.
slot
,
self
.
mb_base
+
MB_GBBAR_OFS
,
0x44
|
(
0x0b
<<
24
))
self
.
elma
.
write
(
self
.
slot
,
self
.
mb_base
+
MB_MBBAR_OFS
,
addr
|
(
0x0b
<<
24
))
self
.
elma
.
write
(
self
.
slot
,
self
.
mb_base
+
MB_CR_OFS
,
0x10000
)
try
:
self
.
elma
.
write
(
self
.
slot
,
self
.
mb_base
+
MB_CR_OFS
,
0x20000
)
except
NAckError
:
pass
# Set timeout...
t0
=
time
.
time
()
t1
=
t0
+
20
# and wait for the FPGA to gracefully respond, or die trying
while
(
1
):
try
:
if
(
time
.
time
()
>=
t1
):
print
(
"Timeout, IPROG unsuccessful!"
)
break
if
((
self
.
elma
.
read
(
self
.
slot
,
0x4
)
&
0xf0
)
==
0x00
):
print
(
"IPROG unsuccessful, fallback to Golden bitstream occured!"
)
break
else
:
print
(
"IPROG successful!"
)
break
except
NAckError
:
continue
#
# Sequence to read FPGA configuration register
#
def
rdcfgreg
(
self
):
print
(
"Press 'q' to end config reg readout"
)
while
1
:
try
:
reg
=
raw_input
(
'Address: 0x'
)
reg
=
int
(
reg
,
16
)
if
(
reg
<
0x00
)
or
(
reg
>
0x22
):
raise
ValueError
if
(
self
.
comm
==
ELMA_I2C_MULTIBOOT
):
self
.
elma
.
write
(
self
.
slot
,
self
.
mb_base
+
MB_CR_OFS
,
(
1
<<
6
)
|
reg
)
val
=
self
.
elma
.
read
(
self
.
slot
,
self
.
mb_base
+
MB_SR_OFS
)
if
(
val
&
(
1
<<
16
)):
print
(
"REG(0x
%02
X) = 0x
%04
X"
%
(
reg
,
val
&
0xffff
))
else
:
print
(
"CFGREGIMG invalid!"
)
except
ValueError
:
if
(
reg
==
'q'
):
break
print
(
"Please input a hex value in the range [0x00, 0x22] or 'q' to quit"
)
software/multiboot/mass-multiboot.py
0 → 100755
View file @
b6c633a6
#!/usr/bin/python
# Author: Theodor Stana <theodor.stana@gmail.com>
# Date: October 2014
#
# 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, you may find one here:
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# or you may search the http://www.gnu.org website for the version 2 license,
# or you may write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
import
os
import
sys
sys
.
path
.
append
(
"../ei2c"
)
sys
.
path
.
append
(
"lib-multiboot"
)
from
ei2cexcept
import
*
from
comm_type
import
*
from
xil_multiboot
import
*
import
binascii
from
optparse
import
OptionParser
GW_DIR
=
"/acc/local/share/firmware/"
# When you add new board type, search for where "ADDBOARD" appears as a comment
# and make the proper additions there
BOARDIDS
=
[
"TBLO"
,
"T485"
]
# ADDBOARD: board ID string under mandatory arguments
USAGE
=
"""Usage:
%
prog [options] elma-crate board-id
Mandatory:
elma-crate Hostname or IP address of ELMA crate to address
board-id ID of board to program; must be one of
"TBLO" -> CONV-TTL-BLO
"T485" -> CONV-TTL-RS485"""
# Return the list of gateware files at the requested path; each board should
# have a folder under "path" with its specific name. Files under this folder
# with the board's name should be bitstream files only.
def
get_gw_list
(
path
,
board
):
path
=
path
+
board
+
'/'
return
[
path
+
f
for
f
in
os
.
listdir
(
path
)
if
not
os
.
path
.
isdir
(
f
)]
# Write bitstream and perform IPROG, depending on requested operation.
#
# The write address is inferred from whether the bitstream has a "golden" string
# in it, which denotes a golden bitsream, which should always be programmed from
# address 0x0
def
mass_multiboot
(
write
,
gw_path
,
iprog
,
iprogaddr
):
for
slot
in
slots
:
# The MultiBoot base address is normally 0x100
mb_base
=
0x100
# ... but let's make sure we get the right address on older gateware or
# test gateware of blocking converters
if
(
boardid
==
"TBLO"
):
gwvers
=
elma
.
read
(
slot
,
0x4
)
&
0xff
if
(
gwvers
==
0xff
):
mb_base
=
0x300
elif
((
gwvers
>
0x10
)
and
(
gwvers
<
0x23
))
or
\
(((
gwvers
&
0xf0
)
==
0x00
)
and
(
gwvers
<
0x02
)):
mb_base
=
0x40
# Run MultiBoot
mb
=
XilMultiboot
(
ELMA_I2C_MULTIBOOT
,
elma
,
slot
,
mb_base
,
gw_path
)
if
(
write
):
if
(
"golden"
in
gw_path
):
waddr
=
0x0
else
:
waddr
=
iprogaddr
mb
.
write
(
waddr
)
# Send IPROG command if requested
if
(
iprog
):
mb
.
iprog
(
iprogaddr
)
# main "function"
if
__name__
==
"__main__"
:
parser
=
OptionParser
(
usage
=
USAGE
)
parser
.
add_option
(
"-s"
,
"--start"
,
help
=
"Start running programmed bitstream"
,
action
=
"store_true"
,
dest
=
"iprogafter"
)
parser
.
add_option
(
"-i"
,
"--iprog"
,
help
=
"Run bitstream (IPROG) at a specific address and exit"
,
action
=
"store"
,
type
=
int
,
dest
=
"iprogaddr"
,
default
=
None
)
(
opts
,
args
)
=
parser
.
parse_args
()
if
(
len
(
args
)
<
2
):
print
(
"ERROR: wrong or missing arguments"
)
parser
.
print_help
()
sys
.
exit
(
2
)
hname
=
args
[
0
]
board
=
args
[
1
]
board
=
board
.
upper
()
elma
=
EI2C
(
hname
,
""
,
""
)
elma
.
open
()
if
not
(
board
in
BOARDIDS
):
print
(
"ERROR: Invalid board ID"
)
parser
.
print_help
()
sys
.
exit
(
2
)
# Walk a 17-slot crate to see if any boards of the requested type are found
slots
=
[]
for
i
in
range
(
1
,
18
):
try
:
boardid
=
elma
.
read
(
i
,
0x0
);
boardid
=
binascii
.
unhexlify
(
"
%
s"
%
"{0:x}"
.
format
(
boardid
))
if
(
boardid
==
board
):
print
(
"Board with ID
\"
%
s
\"
found in slot
%
d"
%
(
board
,
i
))
slots
.
append
(
i
)
except
NAckError
:
pass
# Exit if slots array is not populated
if
(
len
(
slots
)
==
0
):
print
(
"ERROR: no boards found in crate or crate power not turned on"
)
sys
.
exit
(
2
)
# New line before babbling more
print
(
""
)
# Run IPROG and exit program, as promised by the option
if
(
opts
.
iprogaddr
!=
None
):
while
(
1
):
inp
=
raw_input
(
"Are you sure you want to run IPROG on ALL cards above? (y/n) "
)
inp
=
inp
.
lower
()
if
(
inp
==
'y'
):
# Run mass MultiBoot without writing, only with IPROG from
# defined address
mass_multiboot
(
0
,
None
,
1
,
opts
.
iprogaddr
)
break
elif
(
inp
==
'n'
):
break
sys
.
exit
(
0
)
# Change board name to be according to bitstream folder names
# ADDBOARD: add new if branches with folder names where you store the bitstreams
# and start addresses for the release bitstreams on new FPGAs. Note that
# folder names have to be under the GW_DIR definition above
if
(
board
==
"TBLO"
):
board
=
"conv-ttl-blo"
opts
.
iprogaddr
=
0x170000
elif
(
board
==
"T485"
):
board
=
"conv-ttl-rs485"
opts
.
iprogaddr
=
0x170000
# Get gateware list
print
(
"Which gateware would you like to program?"
)
gw_list
=
sorted
(
get_gw_list
(
GW_DIR
,
board
))
for
i
,
gw
in
enumerate
(
gw_list
):
print
(
"
%2
d ->
%
s"
%
(
i
,
os
.
path
.
basename
(
gw
)))
start
=
False
while
(
not
start
):
is_valid
=
False
while
(
not
is_valid
):
try
:
print
(
""
)
choice
=
int
(
raw_input
(
"Enter your choice : "
))
if
choice
<
len
(
gw_list
):
is_valid
=
1
else
:
print
(
"
%
d is not in range 0-
%
d"
%
(
choice
,
len
(
gw_list
)
-
1
))
except
ValueError
as
e
:
print
(
"
%
s is not a valid integer."
%
e
.
args
[
0
]
.
split
(
": "
)[
1
])
gw_path
=
gw_list
[
choice
]
print
(
"Selected gateware:
%
s"
%
os
.
path
.
basename
(
gw_path
))
inp
=
raw_input
(
"Start writing bitstream? (y/n) "
);
if
(
inp
.
lower
()
==
'y'
):
start
=
True
# Start writing the boards in the crate
mass_multiboot
(
1
,
gw_path
,
opts
.
iprogafter
,
opts
.
iprogaddr
)
elma
.
close
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment