Commit 7a090e58 authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

software: changed multiboot script to read raw binary files

Signed-off-by: Theodor-Adrian Stana's avatarTheodor Stana <t.stana@cern.ch>
parent 6e1ae8b5
Before using multiboot.py, you must first generate a compatible bitstream file
it can read. This can be done by running the binary converter tool from
Micron. Download the M25P64 VHDL models from:
multiboot.py
============
http://cern.ch/go/xl8m
The multiboot.py script can be used to upload a firmware to the CONV-TTL-BLO
flash chip for MultiBoot. It is self-sufficient for the most part, in that the
method definitions for reading and writing the Flash are internal to the module,
but the methods for generating I2C accesses via Telnet are defined in the i2c.py
module.
unzip, and run converter1.1.exe from the "code/" folder.
You will need a bitstream file to write to the flash chip. The bitstream file
can be either .bin or .bit, anything that the FPGA can read. The script simply
reads it as a binary file, parses it in 256-byte chunks and writes these
chunks to the flash chip via the FPGA.
To run the converter tool on Linux, use Wine.
Then
To run it:
%> python multiboot.py
Slot no.? <give slot number of CONV-TTL-BLO card here>
......@@ -16,14 +20,13 @@ Read config reg? (y/n) <'y' to read configuration registers>
Read first page? (y/n) <'y' to read the first page from the MultiBoot address
you will give later>
Write to flash? (y/n) <'y' to write bitstream data>
Are you sure? (y/n) <asks you twice, since writing takes reaaaly long>
Are you sure? (y/n) <asks you twice, since writing takes realy long>
Issue IPROG? (y/n)
Multiboot bitstream address(hex): <hex bitstream address, nominally "170000">
<if you answered 'y' on both write questions:>
Input file name: <give here the name of the file you just generated using
converter1.1.exe>
Input file name: <give here the FULL name of the bitstream file>
The tool will now start sending your bitstream, outputting the page address
it is currently writing to. Go grab a coffee, since this will take at least
12 mins, maybe even more if your network connection is not that good, or
11 mins, maybe even more if your network connection is not that good, or
you're using Windows
#===============================================================================
# CERN (BE-CO-HT)
# Register test for CONV-TTL-BLO
# MultiBoot example script
#===============================================================================
# author: Theodor Stana (t.stana@cern.ch)
#
......@@ -9,12 +9,23 @@
# version: 1.0
#
# description:
# This module exemplifies reading and writing to the CONV-TTL-BLO FPGA
# registers for sending a bitstream to the CONV-TTL-BLO flash and then
# issuing the IPROG command to the FPGA to load the new bitstream from the
# flash.
#
# To communicate to the CONV-TTL-BLO, an EI2C object is used to open a
# coonection to the ELMA crate and send the writereg, writemregs and readreg
# commands.
#
# dependencies:
# ei2c.py
# ei2cexcept.py
#
# references:
# [1] M25P32 32Mb 3V NOR Serial Flash Embedded Memory
# http://cern.ch/go/z7pw
#
#===============================================================================
# GNU LESSER GENERAL PUBLIC LICENSE
#===============================================================================
......@@ -37,9 +48,10 @@
import random
import sys
import time
sys.path.append("../vbcp")
from vbcp import *
from vbcpexcept import *
sys.path.append("../ei2c")
from ei2c import *
from ei2cexcept import *
from functools import partial
#===============================================================================
MB_BASE = 0x40
......@@ -207,62 +219,35 @@ def _write(addr):
# Ask for and open bitstream file
fname = raw_input("Input file name: ")
f = open(fname,'r')
f = open(fname,'rb')
tw0 = time.time()
# Each line in the input file contains the data for one page
for fdata in f:
print addr
data = []
for dat in iter(partial(f.read, 256), ''):
dat = [int(d.encode("hex"), 16) for d in dat]
print "%x" % addr
# Erase on sector boundary
if not (addr % 0x10000):
print 'erase'
te1 = time.time()
t1 = time.time()
flash_serase(addr)
while (flash_rsr() & 0x01):
pass
te2 = time.time()
te.append(te2-te1)
# Read the hex values from the input file, which contains page data as
# strings of hex values, one hex value (i.e., one character) per nibble
try:
t1 = time.time()
for i in xrange(256):
data.append(int(fdata[0:2],16))
fdata = fdata[2:]
t2 = time.time()
# The last page of the flash will not be filled up with bytes, so
# data.append() above will throw a ValueError; catch this exception
# and use it to mark the end
except ValueError:
print "reached end"
break
# The finally block gets executed no matter what, so we use it to actually
# write data to the flash, one page at a time. After every write, the
# address is incremented to the next page address.
finally:
t3 = time.time()
flash_write(addr, data)
t4 = time.time()
while (flash_rsr() & 0x01):
pass
t5 = time.time()
addr += 256
tdat.append(t2-t1)
twr.append(t4-t3)
twa.append(t5-t4)
tp.append(t5-t3)
#if (addr == 0x10000):
# break
#print data
#print len(data)
te.append(t2-t1)
t3 = time.time()
flash_write(addr, dat)
t4 = time.time()
while (flash_rsr() & 0x01):
pass
t5 = time.time()
addr += 256
twr.append(t4-t3)
twa.append(t5-t4)
tp.append(t5-t3)
tw1 = time.time()
......@@ -271,7 +256,6 @@ def _write(addr):
# Phew! We're ready, so calculate the mean time it took for each process
print "DONE!"
print "data time: %2.6f" % float(sum(tdat)/len(tdat))
print "erase time: %2.6f" % float(sum(te)/len(te))
print "write time: %2.6f" % float(sum(twr)/len(twr)) #(t4-t3)
print "wait time: %2.6f" % float(sum(twa)/len(twa)) #(t5-t4)
......@@ -337,16 +321,28 @@ def _rdcfgreg():
# MAIN "FUNCTION"
if __name__ == "__main__":
ip = "cfvm-864-celma1"# raw_input("Crate IP? ")
user = "user" # raw_input("Username? ")
pwd = "USER" # raw_input("Password? ")
# Ask for username and password and retry init in case of error
while 1:
ip = raw_input("Crate IP or hostname: ")
user = raw_input("Username: ")
pwd = raw_input("Password: ")
try:
testelma = EI2C(ip, user, pwd)
testelma.open()
break
except BadHostnameError as e:
print e.strerror
except BadUsernameError as e:
print e.strerror
except BadPasswordError as e:
print e.strerror
# Wait for proper slot number
while 1:
try:
slot = raw_input("Slot no.? ")
slot = raw_input("Slot no.: ")
slot = int(slot)
testelma = VBCP(ip, user, pwd)
break
except TypeError as e:
print "Please input a decimal slot number."
......@@ -357,8 +353,6 @@ if __name__ == "__main__":
except:
print "Unexpected error: ", sys.exc_info()[0]
# Open VBCP connection
testelma.open()
# The PULSETEST bitstream has the MultiBoot module starting at address 0x300
if (testelma.read(slot, 0x04) & 0xFF == 0x99):
......@@ -424,6 +418,6 @@ if __name__ == "__main__":
if (iprog == 'y'):
_iprog(multiboot_addr)
# Close VBCP connection
# Close I2C connection
testelma.close()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment