Commit 8e4020f6 authored by Carmelo Magnafico's avatar Carmelo Magnafico
Browse files

working BC MDOR builder and ISA Complete SW upload preparation SW

parents
Loading
Loading
Loading
Loading

.DS_Store

0 → 100644
+6 KiB

File added.

No diff preview for this file type.

ISACodeReloader.py

0 → 100644
+256 −0
Original line number Diff line number Diff line
#/usr/bin/env python

#########################################################
#	Credits												#
#	Author: Carmelo Magnafico - BepiColombo ISA Team 	#
#	Association: IASP/INAF								#
#														#
#   Ver: 0.1											#
#########################################################


#usage
#python MDORbuilder.py ICEThcFixImage.bin MDOR_template_1.BC 0007 DM RAM 01 0000

from __future__ import division
import sys
import xml.etree.ElementTree as ET
import os
import binascii
import math
from datetime import datetime
from datetime import timedelta
import copy 
import memoryMap as memap #ISA memory mapping
import string


#set some errors
class wrongdatapacklength(Exception):
    pass
class wrongAddress(Exception):
    pass
class wrongMemoryType(Exception):
    pass


#Settings
datasplit = 224 #maximum length in byte for a single data sent in one command
dataword = 16 #bit of a word

INT_BITS = 16
# Function to left
# rotate n by d bits
def leftRotate(n, d):
    # In n<<d, last d bits are 0.
    # To put first 3 bits of n at
    # last, do bitwise or of n<<d
    # with n >>(INT_BITS - d)
    return ( (n << d)|(n >> (INT_BITS - d))) & ((1 << INT_BITS) - 1)
 

def checksum(data):

	chsum = 0xF900
	for i in range(int(len(data)/4)):
		chsum = leftRotate(chsum , 1) ^ int(data[i*4:(i+1)*4],INT_BITS)

	return hex(chsum);



def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        pass
 
    try:
        import unicodedata
        unicodedata.numeric(s)
        return True
    except (TypeError, ValueError):
        pass
 
    return False


#memap.memoryPagePlot(2,'ProgramMemory')



thisdir = os.path.dirname(os.path.realpath(__file__))

datafile = os.path.join(thisdir,"input",sys.argv[1])
templatefile = os.path.join(thisdir,"templates",sys.argv[2])

print("source input:"+datafile)
print("Using template:"+templatefile)

arguments = len(sys.argv) - 1  

with open(datafile, 'rb') as f:
    filedata = f.read()

if(arguments > 7):

	if (sys.argv[8] == '--text'):
		print('--- you selected the plain text mode input ---')
		print('proceding...')
		#Preparing data input
		data = filedata
	else:
		sys.exit()
else:
	#Preparing data input
	with open(datafile, 'rb') as f:
	    data = binascii.hexlify(filedata)


#check on the data, they must be a integer number of 16bit word
if (len(data) % dataword) != 0:
	raise wrongdatapacklength('It seems you are uploading'+str(len(data)/2)+'byte of data. You need to patch data in blocks of'+str(dataword)+'bit')
	#CHECK FOR THAT RULE


block_num = math.ceil(len(data)/(datasplit*2) ) #number of commands to sent


#parsing xml template
tree = ET.parse(templatefile)
templateXML = tree.getroot()

#generating variables
now = datetime.now()
genTime = datetime.strftime(now,'%Y-%jT%H:%M:%S.%f')[:-3]+"Z"
sequenceNum = sys.argv[3] 		#here to check in a folder or DB the first, empty, sequence number 
commandNum = int('060200000')
destination = 'R'


#memoryType
memoryType = 'DM'
#memoryID
memoryID = 'RAM'
memory = memap.ISA_DataMemory

#start Address 
start_address = '0000'
start_page = '08'

#check memoryID from address, raise an error if memoryID is not respected or reserved memory area is violated
totaldatabit = len(data)*4 #data in bit

#image shall be exactly 64KB of data 
if totaldatabit == 64*1024*8:
	print('Perfect file contains %i bits of data' % totaldatabit)
else:
	print('File contains %i bits of data, operation aborted' % totaldatabit)
	exit()


print('split the date into blocks')


for i in range(2):
	data_part = data[i*32*1024*2:(i+1)*32*1024*2];

	if int(checksum(data_part[:-4]),INT_BITS) == int(data_part[-4:],INT_BITS):
		print('Page checksum comparison passed!\n writing MDOR ...');
	else:
		print('checksum of page not passed:\n data in page %s, checksum in last 16 bit: %s' % (checksum(data_part[:-4]),data_part[-4:]) );
		exit();

	start_tot_address = '00%02i%s' % (int(start_page)+i,start_address)
	saddr = start_tot_address[-6:]
	eaddr = (int(start_address,16) + len(data_part)*4)
	if not all(c in string.hexdigits for c in start_address) :
		raise wrongAddress('Wrong address type: '+start_address)
	#page num
	page_code = '%02i' % (int(start_page)+i);

	#check
	if (len(page_code) < 1) & (len(page_code) > 2):
		raise wrongAddress('Wrong page length: '+page_code+'  | one or 2 decimal digit needed')

	if not is_number(page_code):
		raise wrongAddress('Wrong page length: '+page_code+'  | a decimal digit needed')

	page_code = format(int(page_code), '02X')
	totaldatabit = len(data_part)*4 #data in bit
	

	#+++++++++++++++++
	# write the MDOR
	#+++++++++++++++++

	deltaSeconds = 10
	actionTime = datetime(1900,1,1) + timedelta(seconds=deltaSeconds)

	#Updating fields
	templateXML.find('.//genTime').text = genTime #find recursivelly ".//word"
	occurrenceList = templateXML.find('.//occurrenceList')
	occurrenceList.set('creationTime', genTime)
	occurrenceList.set('count', "%i"%block_num)

	command = occurrenceList.find('.//command')



	#append the right number of commands
	for j in range(0,int(block_num-1)):
		
		#append a new command to occurrenceList
		occurrenceList.append(copy.deepcopy(command))



	index = 0
	for c in templateXML.iter('command'):

		#generating variables
		commandNum += 1
		uniqueID_value = 'BPSA'+sequenceNum+'ISA'+("%09.i" % commandNum)
		length = int(datasplit/(dataword/8)) #now is in words
		length_hex = length*4 #numbers of hex
		ini = index*length_hex
		fin = ini + length_hex

		if (index == block_num-1) & (len(data_part) % length_hex != 0):
			length = int((len(data) % (datasplit*2) )/(dataword/4)) #in words
			fin = ini + length*4
			length_hex = length*4


		datablock = data[ini:fin];		
		
		#modify this command:mpo
		c.find('uniqueID').text = uniqueID_value
		c.find('destination').text = destination
		c.find('./releaseTime/actionTime').text = datetime.strftime(actionTime,'%H:%M:%S')
		
		
		for parameter in c.findall('./parameterList/parameter'):
			if parameter.get('name')=='PSA06060':
				parameter.find('value').text = memoryID
			if parameter.get('name')=='PSA06065':
				parameter.find('value').text = "%s"%start_tot_address #in bit
			if parameter.get('name')=='PSA06066':
				parameter.find('value').text = "%s"%length
			if parameter.get('name')=='PSAY6069':
				parameter.find('value').text = datablock.decode('ascii')
		
		#prepare for the next block
		start_tot_address = format(int(start_tot_address,16) + int(length_hex*4),'08X')

		index += 1
		

	#<type>_<source>_<plancycle>_<optional text>_<counter>.<EXT>
	outputfile = 'MDOR_'+'BPSA_'+'T000_'+'codepatch_'+('%04i'%(int(sequenceNum)+i))+'.bc'
	tree.write(outputfile)
	print(outputfile+' correclty wrote')


LICENSE

0 → 100644
+0 −0

File added.

Preview size limit exceeded, changes collapsed.

+0 −0

File added.

Preview size limit exceeded, changes collapsed.

+0 −0

File added.

Preview size limit exceeded, changes collapsed.