1 import os, struct, sys, time
3 from serial import Serial
4 from serial import SerialException
6 import ispBase, intelHex
8 class Stk500v2(ispBase.IspBase):
13 self.progressCallback = None
15 def connect(self, port = 'COM22', speed = 115200):
16 if self.serial != None:
19 self.serial = Serial(str(port), speed, timeout=1, writeTimeout=10000)
20 except SerialException as e:
21 raise ispBase.IspError("Failed to open serial port")
23 raise ispBase.IspError("Unexpected error while connecting to serial port:" + port + ":" + str(sys.exc_info()[0]))
33 if self.sendMessage([0x10, 0xc8, 0x64, 0x19, 0x20, 0x00, 0x53, 0x03, 0xac, 0x53, 0x00, 0x00]) != [0x10, 0x00]:
35 raise ispBase.IspError("Failed to enter programming mode")
38 if self.serial != None:
42 #Leave ISP does not reset the serial port, only resets the device, and returns the serial port after disconnecting it from the programming interface.
43 # This allows you to use the serial port without opening it again.
45 if self.serial != None:
46 if self.sendMessage([0x11]) != [0x11, 0x00]:
47 raise ispBase.IspError("Failed to leave programming mode")
53 def isConnected(self):
54 return self.serial != None
56 def sendISP(self, data):
57 recv = self.sendMessage([0x1D, 4, 4, 0, data[0], data[1], data[2], data[3]])
60 def writeFlash(self, flashData):
61 #Set load addr to 0, in case we have more then 64k flash we need to enable the address extension
62 pageSize = self.chip['pageSize'] * 2
63 flashSize = pageSize * self.chip['pageCount']
64 if flashSize > 0xFFFF:
65 self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])
67 self.sendMessage([0x06, 0x00, 0x00, 0x00, 0x00])
69 loadCount = (len(flashData) + pageSize - 1) / pageSize
70 for i in xrange(0, loadCount):
71 recv = self.sendMessage([0x13, pageSize >> 8, pageSize & 0xFF, 0xc1, 0x0a, 0x40, 0x4c, 0x20, 0x00, 0x00] + flashData[(i * pageSize):(i * pageSize + pageSize)])
72 if self.progressCallback != None:
73 self.progressCallback(i + 1, loadCount*2)
75 def verifyFlash(self, flashData):
76 #Set load addr to 0, in case we have more then 64k flash we need to enable the address extension
77 flashSize = self.chip['pageSize'] * 2 * self.chip['pageCount']
78 if flashSize > 0xFFFF:
79 self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])
81 self.sendMessage([0x06, 0x00, 0x00, 0x00, 0x00])
83 loadCount = (len(flashData) + 0xFF) / 0x100
84 for i in xrange(0, loadCount):
85 recv = self.sendMessage([0x14, 0x01, 0x00, 0x20])[2:0x102]
86 if self.progressCallback != None:
87 self.progressCallback(loadCount + i + 1, loadCount*2)
88 for j in xrange(0, 0x100):
89 if i * 0x100 + j < len(flashData) and flashData[i * 0x100 + j] != recv[j]:
90 raise ispBase.IspError('Verify error at: 0x%x' % (i * 0x100 + j))
92 def sendMessage(self, data):
93 message = struct.pack(">BBHB", 0x1B, self.seq, len(data), 0x0E)
95 message += struct.pack(">B", c)
99 message += struct.pack(">B", checksum)
101 self.serial.write(message)
103 except SerialTimeoutException:
104 raise ispBase.IspError('Serial send timeout')
105 self.seq = (self.seq + 1) & 0xFF
106 return self.recvMessage()
108 def recvMessage(self):
112 s = self.serial.read()
114 raise ispBase.IspError("Timeout")
115 b = struct.unpack(">B", s)[0]
122 elif state == 'GetSeq':
124 elif state == 'MsgSize1':
127 elif state == 'MsgSize2':
130 elif state == 'Token':
136 elif state == 'Data':
138 if len(data) == msgSize:
140 elif state == 'Checksum':
148 programmer = Stk500v2()
149 programmer.connect(port = sys.argv[1])
150 programmer.programChip(intelHex.readHex(sys.argv[2]))
153 if __name__ == '__main__':