first version of mhx file support impl.
[pyfrprog.git] / frprog.py
1 #!/usr/bin/env python
2 import sys, time
3 from SerialPort_linux import *
4
5 # serial device to communicate with
6 DEVICE="/dev/ttyUSB0"
7 # baudrate used for initialization
8 INIT_BAUDRATE=9600
9 # baudrate used for communication after init
10 REAL_BAUDRATE=38400
11
12 # contains the last received checksum from a READ, WRITE or CHECKSUM command
13 last_checksum = 0
14
15 def sendByte(byte):
16         time.sleep(0.001) # just to get sure, wait 1ms
17         tty.write(chr(byte))
18         tty.flush()
19
20 def sendWord(word):
21         sendByte(word & 0xFF)
22         sendByte((word >> 8) & 0xFF)
23
24 def sendDWord(dword):
25         sendByte(dword & 0xFF)
26         sendByte((dword >> 8) & 0xFF)
27         sendByte((dword >> 16) & 0xFF)
28         sendByte((dword >> 24) & 0xFF)
29
30 def recvByte():
31         return ord(tty.read())
32
33 def recvChecksum():
34         global last_checksum
35         last_checksum = recvByte()
36         last_checksum |= (recvByte() << 8)
37
38 def cmdREAD(address, size):
39         # send READ command
40         sendByte(0x01)
41         if (recvByte() != 0xF1):
42                 raise Exception
43         sendByte(0x02)
44         if (recvByte() != 0x82):
45                 raise Exception
46         # tell desired address and size
47         sendDWord(address)
48         sendWord(size)
49         # get binary stream of data
50         data = []
51         for i in range(0, size):
52                 data.append(recvByte())
53         # get checksum
54         recvChecksum()
55         return data
56
57 def cmdWRITE(address, size, data):
58         # send WRITE command
59         sendByte(0x01)
60         if (recvByte() != 0xF1):
61                 raise Exception
62         sendByte(0x03)
63         if (recvByte() != 0x83):
64                 raise Exception
65         # tell desired address and size
66         sendDWord(address)
67         sendWord(size)
68         # write binary stream of data
69         for i in range(0, size):
70                 sendByte(data[i])
71         # get checksum
72         recvChecksum()
73
74 # TODO: test this function!
75 def cmdCALL(address):
76         # send CALL command
77         sendByte(0x01)
78         if (recvByte() != 0xF1):
79                 raise Exception
80         sendByte(0x04)
81         if (recvByte() != 0x84):
82                 raise Exception
83         # tell desired address
84         sendDWord(address)
85         # wait for return parameter - not needed here!
86         #return recvByte()
87
88 # TODO: test this function!
89 def cmdCHECKSUM():
90         # call CHECKSUM command
91         sendByte(0x01)
92         if (recvByte() != 0xF1):
93                 raise Exception
94         sendByte(0x05)
95         if (recvByte() != 0x84):
96                 raise Exception
97         # get checksum
98         recvChecksum()
99
100 def cmdBAUDRATE(baudrate):
101         global last_checksum
102
103         # send BAUDRATE command
104         sendByte(0x01)
105         if (recvByte() != 0xF1):
106                 raise Exception
107         sendByte(0x06)
108         if (recvByte() != 0x86):
109                 raise Exception
110         # send desired baudrate
111         sendByte(baudrate & 0xFF)
112         sendByte((baudrate >> 8) & 0xFF)
113         sendByte((baudrate >> 16) & 0xFF)
114         sendByte((baudrate >> 24) & 0xFF)
115
116 class FlashSequence(object):
117         def __init__(self, address, data):
118                 self.address = address
119                 self.data = data
120
121 flashseqs = []
122
123 # check command line arguments
124 if len(sys.argv) != 2:
125         print "Usage: " + sys.argv[0] + " [mhx-file]"
126         sys.exit(1)
127
128 # read in data from mhx-file before starting
129 try:
130         fp = open(sys.argv[1], "r")
131 except IOError:
132         print sys.argv[0] + ": Error - couldn't open file " + sys.argv[1] + "!"
133         sys.exit(1)
134
135 linecount = 0
136 for line in fp:
137         linecount += 1
138         # get rid of newline characters
139         line = line.strip()
140
141         # we're only interested in S2 (data sequence with 3 address bytes) records by now
142         if line[0:2] == "S2":
143                 byte_count = int(line[2:4], 16)
144                 # just to get sure, check if byte count field is valid
145                 if (len(line)-4) != (byte_count*2):
146                         print sys.argv[0] + ": Warning - inavlid byte count field in " + \
147                                 sys.argv[1] + ":" + str(linecount) + ", skipping line!"
148                         continue
149
150                 # address and checksum bytes are not needed
151                 byte_count -= 4
152                 address = int(line[4:10], 16)
153                 datastr = line[10:10+byte_count*2]
154
155                 # convert data hex-byte-string to real byte data list
156                 data = []
157                 for i in range(0, len(datastr)/2):
158                         data.append(int(datastr[2*i:2*i+2], 16))
159
160                 # add flash sequence to our list
161                 flashseqs.append(FlashSequence(address, data))
162
163 print "The following flash sequences have been read in:"
164 for seq in flashseqs:
165         print hex(seq.address) + ":", seq.data
166
167 print "Initializing serial port..."
168 tty = SerialPort(DEVICE, 100, INIT_BAUDRATE)
169
170 print "Please press RESET on your 1337 board..."
171
172 while 1:
173         tty.write('V')
174         tty.flush()
175         try: 
176                 if tty.read() == 'F':
177                         break
178         except SerialPortException: 
179                 # timeout happened, who cares ;-)
180                 pass
181
182 print "OK, trying to set baudrate..."
183 # set baudrate
184 cmdBAUDRATE(REAL_BAUDRATE)
185 tty = SerialPort(DEVICE, 100, REAL_BAUDRATE)
186
187
188 """
189 # execute (existing) program in ram
190 cmdCALL(0x00033ffc)
191 sys.exit(0)
192 """
193
194 # read something from the IRAM
195 #print cmdREAD(0x00030000, 32)
196
197 #data = []
198 #for i in range(0, 32):
199 #       data.append(i)
200 #cmdWRITE(0x00030000, 32, data)
201
202
203 """
204 # write something to the begin of the IRAM
205 data_wr = []
206 checksum = 0
207 for i in range(0, 0x400):
208         value = i%256
209         data_wr.append(value)
210         checksum = (checksum + value) % (2**16)
211
212 print "Calculated checksum:", checksum
213 print "Writing", data_wr, "to the IRAM..."
214 cmdWRITE(0x00030000, len(data_wr), data_wr)
215 print "Received Checksum:", last_checksum
216 print
217
218 print "Reading from the IRAM again..."
219 data_re = cmdREAD(0x00030000, len(data_wr))
220 print "Received data:", data_re, "Checksum:", last_checksum
221 """
222
223 """
224 # see whats in the iram at the moment
225 data_wr = []
226 print "Reading from the IRAM..."
227 data_re = cmdREAD(0x00030000, 0x10000-4)
228 print "Received data:", data_re, "Checksum:", last_checksum
229 """
230
231 """
232 # see whats in the dram at the moment
233 data_wr = []
234 print "Reading from the DRAM..."
235 data_re = cmdREAD(0x0002C000, 0x10000-0xC000-4)
236 print "Received data:", data_re, "Checksum:", last_checksum
237 """
238
239 """
240 # blank the iram
241 data_wr = []
242 for i in range(0, 0x10000-4):
243         value = 0
244         data_wr.append(value)
245
246 print "Writing", data_wr, "to the IRAM..."
247 cmdWRITE(0x00030000, len(data_wr), data_wr)
248 print "Received Checksum:", last_checksum
249 print
250 """
251
252 """
253 # blank the dram
254 data_wr = []
255 for i in range(0, 0x10000-0xC000-4):
256         value = 0
257         data_wr.append(value)
258
259 print "Writing", data_wr, "to the DRAM..."
260 cmdWRITE(0x0002C000, len(data_wr), data_wr)
261 print "Received Checksum:", last_checksum
262 print
263 """
264
265
266 # write some data in the iram and try to execute it
267 data_wr =[
268                 0x9B,0x00,
269                 0x0D,0x4e,
270                 0xcf,0xf1,
271                 0x16,0x01,
272                 0x9b,0x05,
273                 0x04,0xc7,
274                 0xc1,0x06,
275                 0x16,0x56,
276                 0xe0,0xfb, #branch
277                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0, #nop
278                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
279                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
280                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
281                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
282                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
283                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0]
284 print "Writing", data_wr, "to the IRAM..."
285 cmdWRITE(0x00030000, len(data_wr), data_wr)
286 print "Received Checksum:", last_checksum
287 print
288 cmdCALL(0x00030000)