chiark / gitweb /
Rename from SkeinPyPy to Cura in URLs, paths and scripts.
[cura.git] / Cura / avr_isp / stk500v2.py
1 import os, struct, sys, time\r
2 \r
3 from serial import Serial\r
4 from serial import SerialException\r
5 \r
6 import ispBase, intelHex\r
7 \r
8 class Stk500v2(ispBase.IspBase):\r
9         def __init__(self):\r
10                 self.serial = None\r
11                 self.seq = 1\r
12                 self.lastAddr = -1\r
13         \r
14         def connect(self, port = 'COM3', speed = 115200):\r
15                 if self.serial != None:\r
16                         self.close()\r
17                 try:\r
18                         self.serial = Serial(port, speed, timeout=1)\r
19                 except SerialException as e:\r
20                         raise ispBase.IspError("Failed to open serial port")\r
21                 except:\r
22                         raise ispBase.IspError("Unexpected error while connecting to serial port:" + port + ":" + str(sys.exc_info()[0]))\r
23                 self.seq = 1\r
24                 \r
25                 #Reset the controller\r
26                 self.serial.setDTR(1)\r
27                 self.serial.setDTR(0)\r
28                 time.sleep(0.2)\r
29                 \r
30                 self.sendMessage([1])\r
31                 if self.sendMessage([0x10, 0xc8, 0x64, 0x19, 0x20, 0x00, 0x53, 0x03, 0xac, 0x53, 0x00, 0x00]) != [0x10, 0x00]:\r
32                         self.close()\r
33                         raise ispBase.IspError("Failed to enter programming mode")\r
34 \r
35         def close(self):\r
36                 if self.serial != None:\r
37                         self.serial.close()\r
38                         self.serial = None\r
39         \r
40         def isConnected(self):\r
41                 return self.serial != None\r
42         \r
43         def sendISP(self, data):\r
44                 recv = self.sendMessage([0x1D, 4, 4, 0, data[0], data[1], data[2], data[3]])\r
45                 return recv[2:6]\r
46         \r
47         def writeFlash(self, flashData):\r
48                 #Set load addr to 0, in case we have more then 64k flash we need to enable the address extension\r
49                 flashSize = self.chip['pageSize'] * 2 * self.chip['pageCount']\r
50                 if flashSize > 0xFFFF:\r
51                         self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])\r
52                 else:\r
53                         self.sendMessage([0x06, 0x00, 0x00, 0x00, 0x00])\r
54                 \r
55                 loadCount = (len(flashData) + 0xFF) / 0x100\r
56                 for i in xrange(0, loadCount):\r
57                         recv = self.sendMessage([0x13, 0x01, 0x00, 0xc1, 0x0a, 0x40, 0x4c, 0x20, 0x00, 0x00] + flashData[(i * 0x100):(i * 0x100 + 0x100)])\r
58                         if self.progressCallback != None:\r
59                                 self.progressCallback(i + 1, loadCount*2)\r
60         \r
61         def verifyFlash(self, flashData):\r
62                 #Set load addr to 0, in case we have more then 64k flash we need to enable the address extension\r
63                 flashSize = self.chip['pageSize'] * 2 * self.chip['pageCount']\r
64                 if flashSize > 0xFFFF:\r
65                         self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])\r
66                 else:\r
67                         self.sendMessage([0x06, 0x00, 0x00, 0x00, 0x00])\r
68                 \r
69                 loadCount = (len(flashData) + 0xFF) / 0x100\r
70                 for i in xrange(0, loadCount):\r
71                         recv = self.sendMessage([0x14, 0x01, 0x00, 0x20])[2:0x102]\r
72                         if self.progressCallback != None:\r
73                                 self.progressCallback(loadCount + i + 1, loadCount*2)\r
74                         for j in xrange(0, 0x100):\r
75                                 if i * 0x100 + j < len(flashData) and flashData[i * 0x100 + j] != recv[j]:\r
76                                         raise ispBase.IspError('Verify error at: 0x%x' % (i * 0x100 + j))\r
77 \r
78         def sendMessage(self, data):\r
79                 message = struct.pack(">BBHB", 0x1B, self.seq, len(data), 0x0E)\r
80                 for c in data:\r
81                         message += struct.pack(">B", c)\r
82                 checksum = 0\r
83                 for c in message:\r
84                         checksum ^= ord(c)\r
85                 message += struct.pack(">B", checksum)\r
86                 try:\r
87                         self.serial.write(message)\r
88                         self.serial.flush()\r
89                 except SerialTimeoutException:\r
90                         raise ispBase.IspError('Serial send timeout')\r
91                 self.seq = (self.seq + 1) & 0xFF\r
92                 return self.recvMessage()\r
93         \r
94         def recvMessage(self):\r
95                 state = 'Start'\r
96                 checksum = 0\r
97                 while True:\r
98                         s = self.serial.read()\r
99                         if len(s) < 1:\r
100                                 raise ispBase.IspError("Timeout")\r
101                         b = struct.unpack(">B", s)[0]\r
102                         checksum ^= b\r
103                         #print hex(b)\r
104                         if state == 'Start':\r
105                                 if b == 0x1B:\r
106                                         state = 'GetSeq'\r
107                                         checksum = 0x1B\r
108                         elif state == 'GetSeq':\r
109                                 state = 'MsgSize1'\r
110                         elif state == 'MsgSize1':\r
111                                 msgSize = b << 8\r
112                                 state = 'MsgSize2'\r
113                         elif state == 'MsgSize2':\r
114                                 msgSize |= b\r
115                                 state = 'Token'\r
116                         elif state == 'Token':\r
117                                 if b != 0x0E:\r
118                                         state = 'Start'\r
119                                 else:\r
120                                         state = 'Data'\r
121                                         data = []\r
122                         elif state == 'Data':\r
123                                 data.append(b)\r
124                                 if len(data) == msgSize:\r
125                                         state = 'Checksum'\r
126                         elif state == 'Checksum':\r
127                                 if checksum != 0:\r
128                                         state = 'Start'\r
129                                 else:\r
130                                         return data\r
131 \r
132 \r
133 def main():\r
134         programmer = Stk500v2()\r
135         programmer.connect()\r
136         programmer.programChip(intelHex.readHex("cfg_4f55234def059.hex"))\r
137         sys.exit(1)\r
138 \r
139 if __name__ == '__main__':\r
140         main()\r