123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- #!/usr/bin/env python
- """
- # TOP2049 Open Source programming suite
- #
- # USB dump parser
- #
- # Copyright (c) 2010 Michael Buesch <m@bues.ch>
- #
- # 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 2 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, write to the Free Software Foundation, Inc.,
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- """
- import sys
- import re
- packethdr_re = re.compile(r"Dev\s+([0-9a-fA-F]{4,4}):([0-9a-fA-F]{4,4})\s+EP([0-9a-fA-F]+)\s+(\w+)\s(\w+)\s+len=(\d+)")
- payload_re = re.compile(r"\[([0-9a-fA-F]+)\]:\s+([0-9a-fA-F\s]+)\s+.+")
- def generateHexdump(mem):
- def toAscii(char):
- if char >= 32 and char <= 126:
- return chr(char)
- return "."
- ret = ""
- ascii = ""
- for i in range(0, len(mem)):
- if i % 16 == 0 and i != 0:
- ret += " " + ascii + "\n"
- ascii = ""
- if i % 16 == 0:
- ret += "0x%04X: " % i
- c = mem[i]
- ret += "%02X" % c
- if (i % 2 != 0):
- ret += " "
- ascii += toAscii(c)
- ret += " " + ascii + "\n\n"
- return ret
- def dumpMem(mem):
- sys.stdout.write(generateHexdump(mem))
- def dumpInstr(instr, description):
- for i in instr:
- sys.stdout.write("%02X" % i)
- sys.stdout.write(" " * (10 - len(instr)))
- sys.stdout.write(": " + description)
- sys.stdout.write("\n")
- def parseBulkIn(data):
- if len(data) == 64:
- print("Read buffer register")
- dumpMem(data)
- def parseBulkOut(data):
- i = 0
- while i < len(data):
- if data[i] == 0x00:
- dumpInstr(data[i:i+1], "Delay 4 usec")
- elif data[i] == 0x01:
- dumpInstr(data[i:i+1], "Read byte from FPGA")
- elif data[i] == 0x07:
- dumpInstr(data[i:i+1], "Read buffer register request")
- elif data[i] == 0x0A:
- dumpInstr(data[i:i+3], "Write 0x%02X to the FPGA at address 0x%02X" % (data[i+2], data[i+1]))
- i += 2
- elif data[i] == 0x0B:
- dumpInstr(data[i:i+2], "Read data from FPGA at address 0x%02X" % (data[i+1]))
- i += 1
- elif data[i] == 0x0E and data[i+1] == 0x11:
- dumpInstr(data[i:i+4], "Read device ID request")
- i += 3
- elif data[i] == 0x0E and data[i+1] == 0x12:
- centivolts = data[i+2]
- dumpInstr(data[i:i+4], "Set VPP to %.2f Volts" % (float(centivolts) / 10))
- i += 3
- elif data[i] == 0x0E and data[i+1] == 0x13:
- centivolts = data[i+2]
- dumpInstr(data[i:i+4], "Set VCC to %.2f Volts" % (float(centivolts) / 10))
- i += 3
- elif data[i] == 0x0E and data[i+1] == 0x14:
- dumpInstr(data[i:i+4], "Loading VPP layout %d" % data[i+1])
- i += 3
- elif data[i] == 0x0E and data[i+1] == 0x15:
- dumpInstr(data[i:i+4], "Loading VCC layout %d" % data[i+1])
- i += 3
- elif data[i] == 0x0E and data[i+1] == 0x16:
- dumpInstr(data[i:i+4], "Loading GND layout %d" % data[i+1])
- i += 3
- elif data[i] == 0x0E and data[i+1] == 0x20:
- dumpInstr(data[i:i+4], "Unknown 0x0E20%02X%02X" % (data[i+2], data[i+3]))
- i += 3
- elif data[i] == 0x0E and data[i+1] == 0x21:
- dumpInstr(data[i:i+4], "Initiate FPGA programming")
- i += 3
- elif data[i] == 0x0E and data[i+1] == 0x22:
- dumpInstr(data[i:i+4], "Upload FPGA configuration data")
- i += 63
- elif data[i] == 0x0E and data[i+1] == 0x25:
- dumpInstr(data[i:i+4], "Unknown 0x0E25")
- i += 3
- elif data[i] == 0x0E and data[i+1] == 0x28:
- op = "Disable"
- if data[i+2] == chr(0):
- op = "Enable"
- dumpInstr(data[i:i+4], "%s the ZIF socket" % op)
- i += 3
- elif data[i] == 0x0E and data[i+1] == 0x1F:
- dumpInstr(data[i:i+4], "Unknown 0x0E1F")
- i += 3
- elif data[i] == 0x0D:
- dumpInstr(data[i:i+1], "Unknown 0x0D")
- elif data[i] == 0x10:
- dumpInstr(data[i:i+2], "Write 0x%02X to the FPGA at address 0x10" % data[i+1])
- i += 1
- elif data[i] == 0x19:
- dumpInstr(data[i:i+1], "Unknown 0x19")
- elif data[i] == 0x1B:
- dumpInstr(data[i:i+1], "Delay 10 msec")
- elif data[i] == 0x34:
- dumpInstr(data[i:i+1], "Unknown 0x34")
- elif data[i] == 0x38:
- dumpInstr(data[i:i+2], "Unknown 0x38")
- i += 1
- elif data[i] == 0x39:
- dumpInstr(data[i:i+1], "Unknown 0x39")
- elif data[i] == 0x4A:
- dumpInstr(data[i:i+2], "Unknown 0x4A")
- i += 1
- elif data[i] == 0x4B:
- dumpInstr(data[i:i+2], "Unknown 0x4B")
- i += 1
- else:
- print("UNKNOWN INSTRUCTION 0x%02X. Aborting..." % data[i])
- for j in range(i, len(data)):
- sys.stdout.write("%02X " % data[j])
- print("")
- sys.exit(1)
- i += 1
- def parseDumpFile(fd):
- transtype = None
- bulkData = []
- for line in fd.readlines():
- if transtype == "BULK":
- # Bulk IN or OUT transfer
- m = payload_re.match(line)
- if m:
- offset = int(m.group(1), 16)
- dataString = m.group(2)
- dataString = dataString.replace(" ", "").strip()
- assert(len(dataString) % 2 == 0)
- for i in range(0, len(dataString), 2):
- byteStr = dataString[i:i+2]
- bulkData.append(int(byteStr, 16))
- else:
- # Transfer done
- assert(len(bulkData) == length)
- if direction == "IN":
- parseBulkIn(bulkData)
- elif direction == "OUT":
- parseBulkOut(bulkData)
- else:
- assert(0)
- transtype = None
- bulkData = []
- m = packethdr_re.match(line)
- if m:
- vendor = int(m.group(1), 16)
- device = int(m.group(2), 16)
- ep = int(m.group(3), 16)
- transtype = m.group(4).upper()
- direction = m.group(5).upper()
- length = int(m.group(6))
- def usage():
- print("dump-parser.py file.dump")
- def main(argv):
- if len(argv) != 2:
- usage()
- return 1
- fd = open(argv[1])
- parseDumpFile(fd)
- return 0
- if __name__ == "__main__":
- sys.exit(main(sys.argv))
|