00001
00002
00003
00004
00005
00006
00007
00008
00009 import serial
00010 from struct import pack,unpack
00011 import os
00012 import sys
00013 import time
00014 from optparse import OptionParser
00015
00016 parser = OptionParser()
00017 parser.add_option("-f", "--file", dest="filename",
00018 help="binary file to program", metavar="FILE")
00019 parser.add_option("-t", "--target", dest="target",
00020 help="serial device to send to, default /dev/tty.usbserial-000030FDB",
00021 default="/dev/tty.usbserial-000030FDB'",
00022 metavar="TARGET")
00023 parser.add_option("-s", "--flash", dest="flashprog", action="store_true",
00024 help="write program to flash using libmc1322x flasher",
00025 default=False,
00026 metavar="FLASHPROG")
00027 parser.add_option("-S", "--SSL", dest="SSL_flashprog", action="store_true",
00028 help="write program to flash using SSL flasher", default=False,
00029 metavar="SSLFLASHPROG")
00030 parser.add_option("-b", "--baudrate", dest="baudrate",
00031 help="baudrate for serial device, default 115200", default=115200,
00032 metavar="BAUDRATE")
00033
00034 (options, args) = parser.parse_args()
00035
00036 ZEROCHAR = chr(0)
00037 SOF = chr(0x55)
00038
00039 engReadReq = 0x01
00040 engReadResp = 0x02
00041 engWriteReq = 0x03
00042 engCommitReq = 0x04
00043 engEraseReq = 0x05
00044 engCmdCnf = 0xF0
00045
00046 gEngValidReq = 0x0
00047 gEngInvalidReq = 0x1
00048 gEngSuccessOp = 0x2
00049 gEngWriteError = 0x3
00050 gEngReadError = 0x4
00051 gEngCRCError = 0x5
00052 gEngCommError = 0x6
00053 gEngExecError = 0x7
00054 gEngNoConfirm = 0x8
00055
00056 engSecured = 0xC3
00057 engUnsecured = 0x3C
00058
00059 ENG_BUFFER_SIZE = 0x200
00060 FLASH_IMAGE_HEADER = 0x8;
00061
00062
00063 def simpleCRC(bytes):
00064 crc = 0;
00065 return sum([ord(b) for b in bytes]) & 255;
00066
00067 def SendCommand(command):
00068 ser.write(SOF)
00069 ser.write((Int16AsBytes(len(command))))
00070 ser.write(command)
00071 ser.write(chr(simpleCRC(command)))
00072
00073
00074
00075
00076
00077
00078 def ENG_Erase(address):
00079 print "Erasing address 0x%08x" % address
00080 command = chr(engEraseReq) + Int32AsBytes(address)
00081 SendCommand(command)
00082 return WaitForConfirm()
00083
00084 def ENG_Write(address, data):
00085 if len(data) > ENG_BUFFER_SIZE:
00086 return gEngInvalidReq
00087
00088
00089
00090 command = chr(engWriteReq) + Int32AsBytes(address) + Int16AsBytes(len(data)) + ''.join(data)
00091 SendCommand(command)
00092 return WaitForConfirm()
00093
00094 def ENG_Commit(length, secure):
00095 command = chr(engCommitReq) + Int32AsBytes(length)
00096 if secure:
00097 command += chr(engSecured)
00098 else:
00099 command += chr(engUnsecured)
00100 SendCommand(command)
00101 return WaitForConfirm()
00102
00103
00104 def WaitForConfirm():
00105 recvd = ser.read(1)
00106 while(recvd != SOF):
00107 recvd = ser.read(1)
00108 lenStr = ser.read(2)
00109 len = unpack("H",lenStr)[0]
00110 command = ser.read(len)
00111 crcIn = ord(ser.read(1))
00112 if crcIn != simpleCRC(command):
00113 print "CRC error"
00114 return gEngCRCError
00115 if ord(command[0]) != engCmdCnf:
00116 print "Confirm error"
00117 return gEngNoConfirm
00118 else:
00119 return ord(command[1])
00120
00121 def Int32AsBytes(val):
00122
00123 val &= 0xffffffff
00124 return pack('I',val)
00125
00126 def Int16AsBytes(val):
00127
00128 val &= 0xffff
00129 return pack('H',val)
00130
00131 def EraseFlash():
00132 status = ENG_Erase(0xffffffff)
00133 if status != gEngSuccessOp:
00134 print "Error erasing flash: ",status
00135 else:
00136 print "Flash erased..."
00137
00138 def DownloadBinary():
00139 flashFile = open(options.filename)
00140 filesize = os.path.getsize(options.filename)
00141 print "Writing ",options.filename," to flash... (%dB)" % filesize
00142
00143 flashBytes = [i for i in flashFile.read()]
00144 flashIndex = 0
00145 currentWriteAddress = FLASH_IMAGE_HEADER
00146 binRemainder = filesize
00147
00148 starttime = time.time()
00149
00150
00151 while binRemainder != 0:
00152 if binRemainder > ENG_BUFFER_SIZE:
00153 sendSize = ENG_BUFFER_SIZE
00154 else:
00155 sendSize = binRemainder
00156 binRemainder -= sendSize
00157 status = ENG_Write(currentWriteAddress, flashBytes[flashIndex:(flashIndex+sendSize)])
00158 if status != gEngSuccessOp:
00159 print "Error trying to write to Flash: ",status
00160 sys.exit(-1)
00161 currentWriteAddress += sendSize;
00162 flashIndex += sendSize;
00163
00164
00165
00166 status = ENG_Commit(filesize, False)
00167 if status != gEngSuccessOp:
00168 print "Error executing commit: ",status
00169 sys.exit(-1)
00170
00171 endtime = time.time()
00172 print "Speed: %.2f KBps" % (filesize/(endtime-starttime)/1000)
00173
00174
00175
00176
00177 if options.filename == None:
00178 print "No binary file specified."
00179 parser.print_help()
00180 sys.exit(-1)
00181
00182 if options.SSL_flashprog and options.flashprog:
00183 print "You can only use one flasher binary! -s and -S are mutually exclusive."
00184 sys.exit(-1)
00185
00186 ser = serial.Serial(port=options.target,baudrate=options.baudrate,timeout=0.25,rtscts=1)
00187 if ser.isOpen():
00188 ser.flushInput()
00189 ser.flushOutput()
00190 ser.setRTS()
00191
00192 connected = 0
00193 print "Press RESET now..."
00194
00195 while True:
00196 ser.write(ZEROCHAR)
00197 response = ser.read(100)
00198 if response == "\x00CONNECT" or response=="CONNECT":
00199 print "Connected!"
00200 break
00201
00202 if options.SSL_flashprog:
00203 infile = open("ssl.bin")
00204 filesize = os.path.getsize("ssl.bin")
00205 print "Sending SSL flasher... (%dB)" % filesize
00206 elif options.flashprog:
00207 infile = open("flasher.bin")
00208 filesize = os.path.getsize("flasher.bin")
00209 print "Sending libmc1322x flasher... (%dB)" % filesize
00210 else:
00211 infile = open(options.filename)
00212 filesize = os.path.getsize(options.filename)
00213 print "Sending binary file to RAM... (%dB)" % filesize
00214
00215
00216
00217
00218
00219
00220 fileSizeBytes = pack('I',filesize)
00221 ser.write(fileSizeBytes)
00222
00223
00224
00225 bytes = infile.read()
00226
00227 starttime = time.time()
00228
00229 for byte in bytes:
00230 ser.write(byte)
00231
00232
00233 while 1:
00234 if ser.inWaiting() == 0:
00235 break
00236
00237
00238 endtime = time.time()
00239
00240 print "Speed: %.2f KBps" % (filesize/(endtime-starttime)/1000)
00241
00242
00243 if options.SSL_flashprog:
00244 print "Waiting for flasher to start..."
00245 for tries in range(100):
00246 time.sleep(0.010)
00247 if tries==99:
00248 print "No response from flasher utility. Erase flash with jumpers and try again."
00249 sys.exit(0)
00250 if ser.readline().strip() == "READY":
00251 print "Entering Second Stage Loader..."
00252 break
00253 EraseFlash()
00254 DownloadBinary()
00255
00256 elif options.flashprog:
00257 print "Waiting for flasher to start..."
00258 for tries in range(100):
00259 time.sleep(0.010)
00260 if tries==99:
00261 print "No response from flasher utility. Erase flash with jumpers and try again."
00262 sys.exit(0)
00263 if ser.readline().strip() == "ready":
00264 break
00265
00266 flashfile = open(options.filename)
00267 filesize = os.path.getsize(options.filename)
00268 print "Writing to flash... (%dB)" % filesize
00269 flashbytes = [i for i in flashfile.read()]
00270 ser.write(chr(filesize & 255))
00271 ser.write(chr(filesize >> 8))
00272 ser.write(chr(filesize >> 16))
00273 ser.write(chr(filesize >> 24))
00274 starttime = time.time()
00275 for byte in flashbytes:
00276 ser.write(byte)
00277 time.sleep(0.0005)
00278 endtime = time.time()
00279 print "Speed: %.2f KBps" % (filesize/(endtime-starttime)/1000)
00280
00281 print "Done."
00282
00283 ser.close()
00284
00285