flashing will be done now in a simple loop
[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 # list of all our address/data pairs to flash
122 flashseqs = []
123
124 # check command line arguments
125 if len(sys.argv) != 2:
126         print "Usage: " + sys.argv[0] + " [mhx-file]"
127         sys.exit(1)
128
129 # read in data from mhx-file before starting
130 try:
131         fp = open(sys.argv[1], "r")
132 except IOError:
133         print sys.argv[0] + ": Error - couldn't open file " + sys.argv[1] + "!"
134         sys.exit(1)
135
136 linecount = 0
137 for line in fp:
138         linecount += 1
139         # get rid of newline characters
140         line = line.strip()
141
142         # we're only interested in S2 (data sequence with 3 address bytes) records by now
143         if line[0:2] == "S2":
144                 byte_count = int(line[2:4], 16)
145                 # just to get sure, check if byte count field is valid
146                 if (len(line)-4) != (byte_count*2):
147                         print sys.argv[0] + ": Warning - inavlid byte count field in " + \
148                                 sys.argv[1] + ":" + str(linecount) + ", skipping line!"
149                         continue
150
151                 # address and checksum bytes are not needed
152                 byte_count -= 4
153                 address = int(line[4:10], 16)
154                 datastr = line[10:10+byte_count*2]
155
156                 # convert data hex-byte-string to real byte data list
157                 data = []
158                 for i in range(0, len(datastr)/2):
159                         data.append(int(datastr[2*i:2*i+2], 16))
160
161                 # add flash sequence to our list
162                 flashseqs.append(FlashSequence(address, data))
163
164 print "The following flash sequences have been read in:"
165 for seq in flashseqs:
166         print hex(seq.address) + ":", seq.data
167
168
169 print "Initializing serial port..."
170 tty = SerialPort(DEVICE, 100, INIT_BAUDRATE)
171
172 print "Please press RESET on your 1337 board..."
173
174 while 1:
175         tty.write('V')
176         tty.flush()
177         try: 
178                 if tty.read() == 'F':
179                         break
180         except SerialPortException: 
181                 # timeout happened, who cares ;-)
182                 pass
183
184 print "OK, trying to set baudrate..."
185 # set baudrate
186 cmdBAUDRATE(REAL_BAUDRATE)
187 tty = SerialPort(DEVICE, 100, REAL_BAUDRATE)
188
189 # let the fun begin!
190 for seq in flashseqs:
191         print "Flashing", len(seq.data), "bytes at address", hex(seq.address)
192         cmdWRITE(seq.address, len(seq.data), seq.data)
193 sys.exit(0)
194
195
196 # some tests here.......
197 """
198 # execute (existing) program in ram
199 cmdCALL(0x00033ffc)
200 sys.exit(0)
201 """
202
203 # read something from the IRAM
204 #print cmdREAD(0x00030000, 32)
205
206 #data = []
207 #for i in range(0, 32):
208 #       data.append(i)
209 #cmdWRITE(0x00030000, 32, data)
210
211
212 """
213 # write something to the begin of the IRAM
214 data_wr = []
215 checksum = 0
216 for i in range(0, 0x400):
217         value = i%256
218         data_wr.append(value)
219         checksum = (checksum + value) % (2**16)
220
221 print "Calculated checksum:", checksum
222 print "Writing", data_wr, "to the IRAM..."
223 cmdWRITE(0x00030000, len(data_wr), data_wr)
224 print "Received Checksum:", last_checksum
225 print
226
227 print "Reading from the IRAM again..."
228 data_re = cmdREAD(0x00030000, len(data_wr))
229 print "Received data:", data_re, "Checksum:", last_checksum
230 """
231
232 """
233 # see whats in the iram at the moment
234 data_wr = []
235 print "Reading from the IRAM..."
236 data_re = cmdREAD(0x00030000, 0x10000-4)
237 print "Received data:", data_re, "Checksum:", last_checksum
238 """
239
240 """
241 # see whats in the dram at the moment
242 data_wr = []
243 print "Reading from the DRAM..."
244 data_re = cmdREAD(0x0002C000, 0x10000-0xC000-4)
245 print "Received data:", data_re, "Checksum:", last_checksum
246 """
247
248 """
249 # blank the iram
250 data_wr = []
251 for i in range(0, 0x10000-4):
252         value = 0
253         data_wr.append(value)
254
255 print "Writing", data_wr, "to the IRAM..."
256 cmdWRITE(0x00030000, len(data_wr), data_wr)
257 print "Received Checksum:", last_checksum
258 print
259 """
260
261 """
262 # blank the dram
263 data_wr = []
264 for i in range(0, 0x10000-0xC000-4):
265         value = 0
266         data_wr.append(value)
267
268 print "Writing", data_wr, "to the DRAM..."
269 cmdWRITE(0x0002C000, len(data_wr), data_wr)
270 print "Received Checksum:", last_checksum
271 print
272 """
273
274
275 # write some data in the iram and try to execute it
276 data_wr =[
277                 0x9B,0x00,
278                 0x0D,0x4e,
279                 0xcf,0xf1,
280                 0x16,0x01,
281                 0x9b,0x05,
282                 0x04,0xc7,
283                 0xc1,0x06,
284                 0x16,0x56,
285                 0xe0,0xfb, #branch
286                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0, #nop
287                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
288                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
289                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
290                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
291                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
292                 0x9f,0xa0,0x9f,0xa0,0x9f,0xa0]
293 print "Writing", data_wr, "to the IRAM..."
294 cmdWRITE(0x00030000, len(data_wr), data_wr)
295 print "Received Checksum:", last_checksum
296 print
297 cmdCALL(0x00030000)