dump-parser.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #!/usr/bin/env python
  2. """
  3. # TOP2049 Open Source programming suite
  4. #
  5. # USB dump parser
  6. #
  7. # Copyright (c) 2010 Michael Buesch <m@bues.ch>
  8. #
  9. # This program is free software; you can redistribute it and/or modify
  10. # it under the terms of the GNU General Public License as published by
  11. # the Free Software Foundation; either version 2 of the License, or
  12. # (at your option) any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License along
  20. # with this program; if not, write to the Free Software Foundation, Inc.,
  21. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  22. """
  23. import sys
  24. import re
  25. 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+)")
  26. payload_re = re.compile(r"\[([0-9a-fA-F]+)\]:\s+([0-9a-fA-F\s]+)\s+.+")
  27. def generateHexdump(mem):
  28. def toAscii(char):
  29. if char >= 32 and char <= 126:
  30. return chr(char)
  31. return "."
  32. ret = ""
  33. ascii = ""
  34. for i in range(0, len(mem)):
  35. if i % 16 == 0 and i != 0:
  36. ret += " " + ascii + "\n"
  37. ascii = ""
  38. if i % 16 == 0:
  39. ret += "0x%04X: " % i
  40. c = mem[i]
  41. ret += "%02X" % c
  42. if (i % 2 != 0):
  43. ret += " "
  44. ascii += toAscii(c)
  45. ret += " " + ascii + "\n\n"
  46. return ret
  47. def dumpMem(mem):
  48. sys.stdout.write(generateHexdump(mem))
  49. def dumpInstr(instr, description):
  50. for i in instr:
  51. sys.stdout.write("%02X" % i)
  52. sys.stdout.write(" " * (10 - len(instr)))
  53. sys.stdout.write(": " + description)
  54. sys.stdout.write("\n")
  55. def parseBulkIn(data):
  56. if len(data) == 64:
  57. print("Read buffer register")
  58. dumpMem(data)
  59. def parseBulkOut(data):
  60. i = 0
  61. while i < len(data):
  62. if data[i] == 0x00:
  63. dumpInstr(data[i:i+1], "Delay 4 usec")
  64. elif data[i] == 0x01:
  65. dumpInstr(data[i:i+1], "Read byte from FPGA")
  66. elif data[i] == 0x07:
  67. dumpInstr(data[i:i+1], "Read buffer register request")
  68. elif data[i] == 0x0A:
  69. dumpInstr(data[i:i+3], "Write 0x%02X to the FPGA at address 0x%02X" % (data[i+2], data[i+1]))
  70. i += 2
  71. elif data[i] == 0x0B:
  72. dumpInstr(data[i:i+2], "Read data from FPGA at address 0x%02X" % (data[i+1]))
  73. i += 1
  74. elif data[i] == 0x0E and data[i+1] == 0x11:
  75. dumpInstr(data[i:i+4], "Read device ID request")
  76. i += 3
  77. elif data[i] == 0x0E and data[i+1] == 0x12:
  78. centivolts = data[i+2]
  79. dumpInstr(data[i:i+4], "Set VPP to %.2f Volts" % (float(centivolts) / 10))
  80. i += 3
  81. elif data[i] == 0x0E and data[i+1] == 0x13:
  82. centivolts = data[i+2]
  83. dumpInstr(data[i:i+4], "Set VCC to %.2f Volts" % (float(centivolts) / 10))
  84. i += 3
  85. elif data[i] == 0x0E and data[i+1] == 0x14:
  86. dumpInstr(data[i:i+4], "Loading VPP layout %d" % data[i+1])
  87. i += 3
  88. elif data[i] == 0x0E and data[i+1] == 0x15:
  89. dumpInstr(data[i:i+4], "Loading VCC layout %d" % data[i+1])
  90. i += 3
  91. elif data[i] == 0x0E and data[i+1] == 0x16:
  92. dumpInstr(data[i:i+4], "Loading GND layout %d" % data[i+1])
  93. i += 3
  94. elif data[i] == 0x0E and data[i+1] == 0x20:
  95. dumpInstr(data[i:i+4], "Unknown 0x0E20%02X%02X" % (data[i+2], data[i+3]))
  96. i += 3
  97. elif data[i] == 0x0E and data[i+1] == 0x21:
  98. dumpInstr(data[i:i+4], "Initiate FPGA programming")
  99. i += 3
  100. elif data[i] == 0x0E and data[i+1] == 0x22:
  101. dumpInstr(data[i:i+4], "Upload FPGA configuration data")
  102. i += 63
  103. elif data[i] == 0x0E and data[i+1] == 0x25:
  104. dumpInstr(data[i:i+4], "Unknown 0x0E25")
  105. i += 3
  106. elif data[i] == 0x0E and data[i+1] == 0x28:
  107. op = "Disable"
  108. if data[i+2] == chr(0):
  109. op = "Enable"
  110. dumpInstr(data[i:i+4], "%s the ZIF socket" % op)
  111. i += 3
  112. elif data[i] == 0x0E and data[i+1] == 0x1F:
  113. dumpInstr(data[i:i+4], "Unknown 0x0E1F")
  114. i += 3
  115. elif data[i] == 0x0D:
  116. dumpInstr(data[i:i+1], "Unknown 0x0D")
  117. elif data[i] == 0x10:
  118. dumpInstr(data[i:i+2], "Write 0x%02X to the FPGA at address 0x10" % data[i+1])
  119. i += 1
  120. elif data[i] == 0x19:
  121. dumpInstr(data[i:i+1], "Unknown 0x19")
  122. elif data[i] == 0x1B:
  123. dumpInstr(data[i:i+1], "Delay 10 msec")
  124. elif data[i] == 0x34:
  125. dumpInstr(data[i:i+1], "Unknown 0x34")
  126. elif data[i] == 0x38:
  127. dumpInstr(data[i:i+2], "Unknown 0x38")
  128. i += 1
  129. elif data[i] == 0x39:
  130. dumpInstr(data[i:i+1], "Unknown 0x39")
  131. elif data[i] == 0x4A:
  132. dumpInstr(data[i:i+2], "Unknown 0x4A")
  133. i += 1
  134. elif data[i] == 0x4B:
  135. dumpInstr(data[i:i+2], "Unknown 0x4B")
  136. i += 1
  137. else:
  138. print("UNKNOWN INSTRUCTION 0x%02X. Aborting..." % data[i])
  139. for j in range(i, len(data)):
  140. sys.stdout.write("%02X " % data[j])
  141. print("")
  142. sys.exit(1)
  143. i += 1
  144. def parseDumpFile(fd):
  145. transtype = None
  146. bulkData = []
  147. for line in fd.readlines():
  148. if transtype == "BULK":
  149. # Bulk IN or OUT transfer
  150. m = payload_re.match(line)
  151. if m:
  152. offset = int(m.group(1), 16)
  153. dataString = m.group(2)
  154. dataString = dataString.replace(" ", "").strip()
  155. assert(len(dataString) % 2 == 0)
  156. for i in range(0, len(dataString), 2):
  157. byteStr = dataString[i:i+2]
  158. bulkData.append(int(byteStr, 16))
  159. else:
  160. # Transfer done
  161. assert(len(bulkData) == length)
  162. if direction == "IN":
  163. parseBulkIn(bulkData)
  164. elif direction == "OUT":
  165. parseBulkOut(bulkData)
  166. else:
  167. assert(0)
  168. transtype = None
  169. bulkData = []
  170. m = packethdr_re.match(line)
  171. if m:
  172. vendor = int(m.group(1), 16)
  173. device = int(m.group(2), 16)
  174. ep = int(m.group(3), 16)
  175. transtype = m.group(4).upper()
  176. direction = m.group(5).upper()
  177. length = int(m.group(6))
  178. def usage():
  179. print("dump-parser.py file.dump")
  180. def main(argv):
  181. if len(argv) != 2:
  182. usage()
  183. return 1
  184. fd = open(argv[1])
  185. parseDumpFile(fd)
  186. return 0
  187. if __name__ == "__main__":
  188. sys.exit(main(sys.argv))