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