215 lines
4.4 KiB
Python
Executable File
215 lines
4.4 KiB
Python
Executable File
#!/usr/bin/python
|
|
|
|
import sys, getopt, serial, binascii, struct
|
|
|
|
|
|
class Mode:
|
|
NONE = 0
|
|
READ = 1
|
|
DUMP = 2
|
|
BURN = 3
|
|
CHECK = 4
|
|
|
|
|
|
class Command:
|
|
PREFIX = 0x42
|
|
NONE = 0
|
|
PING = 1
|
|
STARTRW = 2
|
|
READBLOCK = 3
|
|
READBLOCK_MASK = 4
|
|
WRITEBLOCK = 5
|
|
|
|
PONG = 'PONG'
|
|
BLOCKSIZE = 512
|
|
CRCSIZE = 4
|
|
|
|
romfile = ''
|
|
serialport = ''
|
|
|
|
|
|
def main(argv):
|
|
|
|
global romfile
|
|
global serialport
|
|
global mode
|
|
|
|
mode = Mode.NONE
|
|
|
|
if len(argv)==0:
|
|
usage()
|
|
|
|
try:
|
|
opts, args = getopt.getopt(argv,'dRbcs:r:',['dump','burn','check','serial=','rom='])
|
|
except getopt.GetoptError:
|
|
usage()
|
|
|
|
for opt, arg in opts:
|
|
if opt == '-c':
|
|
mode = Mode.CHECK
|
|
elif opt == '-d':
|
|
mode = Mode.DUMP
|
|
elif opt == '-R':
|
|
mode = Mode.READ
|
|
elif opt == '-b':
|
|
mode = Mode.BURN
|
|
elif opt == '-s':
|
|
serialport = arg
|
|
elif opt == '-r':
|
|
romfile = arg
|
|
else:
|
|
mode = Mode.NONE
|
|
|
|
commands = {
|
|
Mode.NONE: usage,
|
|
Mode.BURN: burnROM,
|
|
Mode.DUMP: dumpROM,
|
|
Mode.READ: dumpROM,
|
|
Mode.CHECK: checkConnection
|
|
}
|
|
commands[mode]()
|
|
|
|
|
|
def checkConnection():
|
|
if serialport=='':
|
|
usage()
|
|
|
|
print 'Checking connection to ' + serialport + '...'
|
|
try:
|
|
# Create the serial connection
|
|
connection = serial.Serial(serialport,19200,timeout=1)
|
|
print 'Found ' + serialport + '. Pinging EETool...'
|
|
|
|
except (OSError,serial.SerialException):
|
|
print 'Unable to find that serial port.'
|
|
sys.exit(2)
|
|
|
|
try:
|
|
# Try sending a ping
|
|
wrote = connection.write(bytearray([Command.PREFIX,Command.PING]))
|
|
if wrote != 2:
|
|
raise ValueError()
|
|
print 'Sent', wrote, 'byte ping. Waiting for response...'
|
|
|
|
# Did we get a pong back?
|
|
while 1:
|
|
numBytes = connection.inWaiting()
|
|
if numBytes>0:
|
|
break
|
|
|
|
print 'Received', numBytes, 'byte pong'
|
|
|
|
if numBytes != len(PONG):
|
|
raise serial.SerialException
|
|
response = connection.read(numBytes)
|
|
if (response != PONG):
|
|
raise serial.SerialException
|
|
|
|
except (ValueError,OSError,serial.SerialException):
|
|
print 'EETool is not responding. Check connections and try again.'
|
|
connection.close()
|
|
sys.exit(2)
|
|
|
|
print 'EETool is online and ready for use.'
|
|
connection.close()
|
|
sys.exit(0)
|
|
|
|
|
|
def burnROM():
|
|
usage()
|
|
|
|
|
|
def dumpROM():
|
|
|
|
if romfile=='' or serialport=='':
|
|
usage()
|
|
|
|
print 'Connecting to ' + serialport + '...'
|
|
try:
|
|
# Create the serial connection
|
|
connection = serial.Serial(serialport,19200,timeout=1)
|
|
|
|
except (OSError,serial.SerialException):
|
|
print 'Unable to find that serial port.'
|
|
sys.exit(2)
|
|
|
|
try:
|
|
destFile = open (romfile, "wb")
|
|
|
|
except OSError:
|
|
print 'Unable to write to ROM file',romfile
|
|
sys.exit(2)
|
|
|
|
try:
|
|
# Prepare to read
|
|
wrote = connection.write(bytearray([Command.PREFIX,Command.STARTRW]))
|
|
if wrote != 2:
|
|
raise ValueError()
|
|
|
|
print 'Requesting data from EETool...'
|
|
|
|
totalSize = 0
|
|
cmd = Command.READBLOCK_MASK if mode==Mode.DUMP else Command.READBLOCK
|
|
|
|
# Request all the blocks
|
|
for blockNum in range(0,64):
|
|
wrote = connection.write(bytearray([Command.PREFIX,cmd]))
|
|
if wrote != 2:
|
|
raise ValueError()
|
|
|
|
while 1:
|
|
numBytes = connection.inWaiting()
|
|
if numBytes>=BLOCKSIZE + CRCSIZE:
|
|
break
|
|
|
|
if (numBytes!=BLOCKSIZE + CRCSIZE):
|
|
print 'ERROR: Block',blockNum,'failed to download. Aborting.'
|
|
sys.exit(2)
|
|
|
|
response = connection.read(numBytes)
|
|
crc = struct.unpack('<I',response[BLOCKSIZE:BLOCKSIZE+CRCSIZE])[0]
|
|
block = response[0:BLOCKSIZE]
|
|
calcCRC = binascii.crc32(block) & 0xFFFFFFFF
|
|
if crc != calcCRC:
|
|
print numBytes,'CRC failed on block',blockNum,'Read CRC =',hexU32(crc),' Calcuated CRC =',hexU32(calcCRC)
|
|
print 'Aborting.'
|
|
sys.exit(2)
|
|
|
|
# Write the block to our file
|
|
destFile.write(bytes(block))
|
|
|
|
sys.stdout.write('#')
|
|
sys.stdout.flush()
|
|
totalSize += numBytes - CRCSIZE
|
|
|
|
destFile.close()
|
|
print '\nDone! ROM is',totalSize,'bytes.'
|
|
sys.exit(0)
|
|
|
|
except (ValueError,OSError,serial.SerialException):
|
|
print 'UNKNOWN ERROR'
|
|
connection.close()
|
|
sys.exit(0)
|
|
|
|
|
|
def hexU32(n):
|
|
return "0x%x"%(n&0xffffffff)
|
|
|
|
def usage():
|
|
print '''
|
|
Usage: EECommander -[d|b|c] -s <serial port> -r <rom file>
|
|
-d: Dump the contents of the attached MASK ROM to a file
|
|
-R: Read the contents of the attached EEPROM to a file
|
|
-b: Burn the rom file to the attached EEPROM
|
|
-c: Check your connection to EETool (no other action taken)
|
|
|
|
To find your serial port, connect EETool and try "ls /dev/tty.usbmodem*" on Mac or Linux.
|
|
On Windows, use a COM port name, such as "COM1". You can use the -c option to find out which one.
|
|
'''
|
|
sys.exit(2)
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv[1:]) |