only flush once for a sequence, detect 0xffs seqs
[pyfrprog.git] / kernel.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 communication with pkernel
8 KERNEL_BAUDRATE=115200
9
10 def recvByte():
11         i = tty.read()
12         return ord(i)
13
14 def sendByte(byte):
15         tty.write(chr(byte))
16         tty.flush()
17
18 def sendWord(word):
19         sendByte(word & 0xFF)
20         sendByte((word >> 8) & 0xFF)
21
22 def sendDWord(dword):
23         sendByte(dword & 0xFF)
24         sendByte((dword >> 8) & 0xFF)
25         sendByte((dword >> 16) & 0xFF)
26         sendByte((dword >> 24) & 0xFF)
27
28 def pkernCHIPERASE():
29         sendByte(0x15)
30         if (recvByte() != 0x45):
31                 raise Exception
32         print "wait..."
33         if (recvByte() != 0x23):
34                 raise Exception
35
36 def pkernERASE(address, size):
37         sendByte(0x12)
38         if (recvByte() != 0x11):
39                 raise Exception
40         sendDWord(address)
41         sendWord(size)
42         if (recvByte() != 0x18):
43                 raise Exception
44         #print "Erasing done."
45
46
47 def pkernWRITE(address, size, data):
48         # send WRITE command
49         sendByte(0x13)
50         if (recvByte() != 0x37):
51                 raise Exception
52         # tell desired address and size
53         sendDWord(address)
54         sendWord(size)
55
56         # write binary stream of data
57         for i in range(0, size):
58                 sendByte(data[i])
59
60         if (recvByte() != 0x28):
61                 raise Exception
62         #print "Flashing done."
63
64
65 class FlashSequence(object):
66         def __init__(self, address, data):
67                 self.address = address
68                 self.data = data
69
70 # list of all our address/data pairs to flash
71 flashseqs = []
72
73
74 print "Initializing serial port..."
75 tty = SerialPort(DEVICE, None, KERNEL_BAUDRATE)
76
77 # check command line arguments
78 if len(sys.argv) != 2:
79         print "Usage: " + sys.argv[0] + " [mhx-file]"
80         sys.exit(1)
81
82 # read in data from mhx-file before starting
83 try:
84         fp = open(sys.argv[1], "r")
85 except IOError:
86         print sys.argv[0] + ": Error - couldn't open file " + sys.argv[1] + "!"
87         sys.exit(1)
88
89 linecount = 0
90 for line in fp:
91         linecount += 1
92         # get rid of newline characters
93         line = line.strip()
94
95         # we're only interested in S2 (data sequence with 3 address bytes) records by now
96         if line[0:2] == "S2":
97                 byte_count = int(line[2:4], 16)
98                 # just to get sure, check if byte count field is valid
99                 if (len(line)-4) != (byte_count*2):
100                         print sys.argv[0] + ": Warning - inavlid byte count field in " + \
101                                 sys.argv[1] + ":" + str(linecount) + ", skipping line!"
102                         continue
103
104                 # address and checksum bytes are not needed
105                 byte_count -= 4
106                 address = int(line[4:10], 16)
107                 datastr = line[10:10+byte_count*2]
108
109                 # convert data hex-byte-string to real byte data list
110                 data = []
111                 for i in range(0, len(datastr)/2):
112                         data.append(int(datastr[2*i:2*i+2], 16))
113
114                 # add flash sequence to our list
115                 flashseqs.append(FlashSequence(address, data))
116
117 #print "The following flash sequences have been read in:"
118 #for seq in flashseqs:
119 #       print hex(seq.address) + ":", [hex(x) for x in seq.data]
120
121
122 # let the fun begin!
123 """
124 for seq in flashseqs:
125         print "Erasing", len(seq.data), "bytes at address", hex(seq.address)
126         pkernERASE(seq.address, len(seq.data))
127 """
128 print "ChipErase..."
129 pkernCHIPERASE()
130 print "Chip erasing done."
131
132
133 print "Flashing",
134 for seq in flashseqs:
135         sys.stdout.write(".")
136         sys.stdout.flush()
137         # skip seqs only consisting of 0xffs
138         seqset = list(set(seq.data))
139         if len(seqset) == 1 and seqset[0] == 0xff:
140                 continue
141         #print "Flashing", len(seq.data), "bytes at address", hex(seq.address)
142         pkernWRITE(seq.address, len(seq.data), seq.data)
143 print
144
145 """
146 sendByte(0x99) #exit and wait
147 print "Reset your board now to run code from Flash"
148 """
149
150 sendByte(0x97) #exit and restart