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