<reponame>marecl/MULoader<filename>MULoader/MULoader.py<gh_stars>0
import serial
import serial.tools.list_ports
import sys
import os
from enum import Enum
import time
from binascii import hexlify


class Codes(Enum):
	COMMAND_OK = 'A'
	COMMAND_ERROR = 'B'
	CODE_META = 'C'
	CODE_BEGIN = 'D'
	TAG_OK = 'E'
	TAG_ERROR_WRITE = 'F'
	TAG_ERROR_READ = 'G'
	TAG_ERROR_VERIFY = 'H'
	TAG_NEXT = 'I'
	TAG_WAITING = 'J'
	TAG_FIRST = 'K'
	TAG_NOT_FIRST = 'L'
	TAG_UPDATING_META = 'M'
	BUFFER_OK = 'N'
	BUFFER_ERROR = 'O'
	BUFFER_REPEAT = 'P'
	BUFFER_WAITING = 'Q'
	ALL_DONE = 'R'
	INIT_OK = 'S'


if len(sys.argv) != 2:
	print 'Input file not specified'
	sys.exit(1)

port = list(serial.tools.list_ports.comports())

for a in port:
	print a[0] + ' ' + a[1]

selected = raw_input('Port: ').upper()
print 'Selected port ' + selected

try:
	file = open(sys.argv[1], 'rb')
except:
	print 'Error opening file'
	sys.exit(1)

codeSize = os.path.getsize(sys.argv[1])
print 'Code size: %d bytes' % codeSize

if codeSize == 0:
	print 'Why would you upload nothing?'
	sys.exit(1)

# Adjusting code size to the nearest block
if codeSize % 16 != 0:
	codeSize += 16-(codeSize%16)
	print "Adjusted code size: %d" % codeSize

try:
	ser = serial.Serial(selected, 115200, timeout=2)
except:
	print 'Error opening Serial port'
	sys.exit(1)

while ser.read(1) != Codes.INIT_OK.value:
	pass

ser.write(Codes.CODE_META.value + str(codeSize))

retcode = ser.read(1)
if retcode != Codes.COMMAND_OK.value:
	print 'Error'

# Bytes of code written
addr = 0

retcode = ser.read(1)
while True:
	if retcode != Codes.TAG_WAITING.value:
		print "Wait for tag error"
	raw_input('[Press any key]')

	ser.write(Codes.TAG_NEXT.value)
	print 'Scan tag'

	while ser.in_waiting == 0:
		pass

	for x in range(0, 3):
		print ser.readline().strip()
		while ser.in_waiting == 0:
			pass

	tokencap = int(ser.readline(), 10)
	if tokencap == 0:
		print "Not supported"
		continue
	else: print 'Token capacity: %d bytes' % tokencap

	while True:
		retcode = ser.read(1)
		if retcode == Codes.TAG_FIRST.value:
			break
		if retcode == Codes.TAG_WAITING.value:
			break
		if retcode == Codes.TAG_UPDATING_META.value:
			print "Updating tag metadata"
		elif retcode == Codes.BUFFER_WAITING.value:
			ser.write(Codes.CODE_BEGIN.value)

			# Write to buffer
			code = file.read(16)
			while len(code) < 16:
				code += '\xFF'
			print '%8X: %r' % (addr, hexlify(code))

			while True:
				# come back here if there is an error with buffer
				ser.write(code)
				retcode = ser.read(1)
				if retcode != Codes.BUFFER_OK.value:
					print "buffer fill error"
				while ser.in_waiting < 16:
					pass

				isError = False
			
				for x in range(0, 16, 1):
					retcode = ser.read(1)
					if code[x] != retcode:
						print 'Buffer error %d!=%d!' % (ord(code[x]), ord(retcode))
						ser.write(Codes.BUFFER_ERROR.value)
						isError = True
						break
				if isError == False: break

			ser.write(Codes.BUFFER_OK.value)
			addr += 16
		
		while ser.in_waiting == 0:
			pass
		retcode = ser.read(1)
		if retcode == Codes.TAG_ERROR_WRITE.value:
			print 'Error writing to block'

		retcode = ser.read(1)
		if retcode == Codes.TAG_ERROR_READ.value:
			print 'Error reading block'
		if retcode == Codes.TAG_ERROR_VERIFY.value:
			print 'Error verifying block'
		elif retcode == Codes.TAG_OK.value: pass

	if retcode == Codes.TAG_FIRST.value: break

# We're done with this file
file.close()

while True:
	# Ask for first tag
	if retcode == Codes.TAG_FIRST.value:
		print 'Prepare first tag'
		raw_input('[Press any key]')
		ser.write(Codes.TAG_NEXT.value)
	print 'Scan first tag'

	# What if tag is not first
	while ser.in_waiting == 0: pass
	retcode = ser.read(1)
	if retcode != Codes.TAG_OK.value:
		if retcode == Codes.TAG_NOT_FIRST.value:
			print 'Tag is not first'
		else:
			print 'Unknown error %d' % ord(retcode)
		retcode = ser.read(1)
	elif retcode == Codes.TAG_OK.value: break



# Waiting for end of communication
while ser.in_waiting == 0:
	pass
retcode = ser.read(1)
if retcode == Codes.ALL_DONE.value:
	print 'Done programming'

if codeSize != addr:
	print 'Written different amount of data (%d | %d)' % (addr, codeSize)
ser.close()
import serial
import serial.tools.list_ports
import sys
import os
from enum import Enum
import time
from binascii import hexlify


class Codes(Enum):
	COMMAND_OK = 'A'
	COMMAND_ERROR = 'B'
	CODE_META = 'C'
	CODE_BEGIN = 'D'
	TAG_OK = 'E'
	TAG_ERROR_WRITE = 'F'
	TAG_ERROR_READ = 'G'
	TAG_ERROR_VERIFY = 'H'
	TAG_NEXT = 'I'
	TAG_WAITING = 'J'
	TAG_FIRST = 'K'
	TAG_NOT_FIRST = 'L'
	TAG_UPDATING_META = 'M'
	BUFFER_OK = 'N'
	BUFFER_ERROR = 'O'
	BUFFER_REPEAT = 'P'
	BUFFER_WAITING = 'Q'
	ALL_DONE = 'R'
	INIT_OK = 'S'


if len(sys.argv) != 2:
	print 'Input file not specified'
	sys.exit(1)

port = list(serial.tools.list_ports.comports())

for a in port:
	print a[0] + ' ' + a[1]

selected = raw_input('Port: ').upper()
print 'Selected port ' + selected

try:
	file = open(sys.argv[1], 'rb')
except:
	print 'Error opening file'
	sys.exit(1)

codeSize = os.path.getsize(sys.argv[1])
print 'Code size: %d bytes' % codeSize

if codeSize == 0:
	print 'Why would you upload nothing?'
	sys.exit(1)

# Adjusting code size to the nearest block
if codeSize % 16 != 0:
	codeSize += 16-(codeSize%16)
	print "Adjusted code size: %d" % codeSize

try:
	ser = serial.Serial(selected, 115200, timeout=2)
except:
	print 'Error opening Serial port'
	sys.exit(1)

while ser.read(1) != Codes.INIT_OK.value:
	pass

ser.write(Codes.CODE_META.value + str(codeSize))

retcode = ser.read(1)
if retcode != Codes.COMMAND_OK.value:
	print 'Error'

# Bytes of code written
addr = 0

retcode = ser.read(1)
while True:
	if retcode != Codes.TAG_WAITING.value:
		print "Wait for tag error"
	raw_input('[Press any key]')

	ser.write(Codes.TAG_NEXT.value)
	print 'Scan tag'

	while ser.in_waiting == 0:
		pass

	for x in range(0, 3):
		print ser.readline().strip()
		while ser.in_waiting == 0:
			pass

	tokencap = int(ser.readline(), 10)
	if tokencap == 0:
		print "Not supported"
		continue
	else: print 'Token capacity: %d bytes' % tokencap

	while True:
		retcode = ser.read(1)
		if retcode == Codes.TAG_FIRST.value:
			break
		if retcode == Codes.TAG_WAITING.value:
			break
		if retcode == Codes.TAG_UPDATING_META.value:
			print "Updating tag metadata"
		elif retcode == Codes.BUFFER_WAITING.value:
			ser.write(Codes.CODE_BEGIN.value)

			# Write to buffer
			code = file.read(16)
			while len(code) < 16:
				code += '\xFF'
			print '%8X: %r' % (addr, hexlify(code))

			while True:
				# come back here if there is an error with buffer
				ser.write(code)
				retcode = ser.read(1)
				if retcode != Codes.BUFFER_OK.value:
					print "buffer fill error"
				while ser.in_waiting < 16:
					pass

				isError = False
			
				for x in range(0, 16, 1):
					retcode = ser.read(1)
					if code[x] != retcode:
						print 'Buffer error %d!=%d!' % (ord(code[x]), ord(retcode))
						ser.write(Codes.BUFFER_ERROR.value)
						isError = True
						break
				if isError == False: break

			ser.write(Codes.BUFFER_OK.value)
			addr += 16
		
		while ser.in_waiting == 0:
			pass
		retcode = ser.read(1)
		if retcode == Codes.TAG_ERROR_WRITE.value:
			print 'Error writing to block'

		retcode = ser.read(1)
		if retcode == Codes.TAG_ERROR_READ.value:
			print 'Error reading block'
		if retcode == Codes.TAG_ERROR_VERIFY.value:
			print 'Error verifying block'
		elif retcode == Codes.TAG_OK.value: pass

	if retcode == Codes.TAG_FIRST.value: break

# We're done with this file
file.close()

while True:
	# Ask for first tag
	if retcode == Codes.TAG_FIRST.value:
		print 'Prepare first tag'
		raw_input('[Press any key]')
		ser.write(Codes.TAG_NEXT.value)
	print 'Scan first tag'

	# What if tag is not first
	while ser.in_waiting == 0: pass
	retcode = ser.read(1)
	if retcode != Codes.TAG_OK.value:
		if retcode == Codes.TAG_NOT_FIRST.value:
			print 'Tag is not first'
		else:
			print 'Unknown error %d' % ord(retcode)
		retcode = ser.read(1)
	elif retcode == Codes.TAG_OK.value: break



# Waiting for end of communication
while ser.in_waiting == 0:
	pass
retcode = ser.read(1)
if retcode == Codes.ALL_DONE.value:
	print 'Done programming'

if codeSize != addr:
	print 'Written different amount of data (%d | %d)' % (addr, codeSize)
ser.close()
# Adjusting code size to the nearest block # Bytes of code written # Write to buffer # come back here if there is an error with buffer # We're done with this file # Ask for first tag # What if tag is not first # Waiting for end of communication