openmv/tools/alif/tools-config.py
2024-08-28 20:06:14 +02:00

315 lines
9.6 KiB
Python
Executable File

#!/usr/bin/env python3
#pylint: disable=invalid-name,superfluous-parens,anomalous-unicode-escape-in-string
import sys, shutil
import json
from json.decoder import JSONDecodeError
import utils.config
from utils.config import *
from utils.gen_fw_cfg import *
# Define Version constant for each separate tool
# 0.05.000 - add cmd line options and multiple key directories
# 0.06.000 - add new DEV key for SPARK
TOOL_VERSION = "0.06.000"
EXIT_WITH_ERROR = 1
CONFIG_FILE = 'utils/global-cfg.db'
FAMILY_DB = 'utils/familiesDB.db'
FEATURES_DB = 'utils/featuresDB.db'
DEVICE_DB = 'utils/devicesDB.db'
JTAG_ADAPTERS = 'utils/jtag-adapters.db'
DEVICE_CFG_FILE = "build/config/device-config.json"
JTAG_ADAPTERS_FILE = "build"
KEY_PATH = 'utils/key/'
CERT_PATH = 'cert/'
# DEV key environments
FUSION_REV_A1 = 'fusion_rev_a1'
FUSION_REV_B0 = 'fusion_rev_b0'
SPARK_REV_A0 = 'spark_rev_a0'
EAGLE_REV_A0 = 'eagle_rev_a0'
# future: Spark, etc
mram_interface = ['jtag', 'isp']
def read_json_file(file):
f = open(file, 'r')
try:
data = json.load(f)
except JSONDecodeError as e:
print("ERROR in JSON file.")
print(str(e))
sys.exit(EXIT_WITH_ERROR)
except ValueError as v:
print("ERROR in JSON file:")
print(str(v))
sys.exit(EXIT_WITH_ERROR)
except:
print("ERROR: Unknown error loading JSON file")
sys.exit(EXIT_WITH_ERROR)
f.close()
return data
def save_global_config(cfg):
with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
json.dump(cfg, f, ensure_ascii=False, indent=4)
def showAndSelectOptions(list, default):
option = 'x'
while option == 'x':
print('\nAvailable options:\n')
i = 1
for item in list:
if item == 'SEP':
print('')
else:
if item == default:
print(str(i) + ' - ' + item + ' (default)')
else:
print(str(i) + ' - ' + item)
i += 1
while 'SEP' in list:
list.remove('SEP')
option = input('\nPlease enter the number of your option: ')
if option == '':
return default
try:
idx = int(option)
except ValueError:
print('Invalid option - Please try again')
option = 'x'
continue
if idx < 1 or idx > len(list):
print('Invalid option - Please try again')
option = 'x'
return list[int(idx -1)]
def update_device_config_file(device_part, device_revision):
if isThisAPP(): # this is logic only for ICV device configuration
return
load_global_config()
# generate the temp file 'build/fw_cfg.json'
gen_fw_cfg_icv(device_part["family"], device_part["mram_size"], device_part["sram_size"], device_revision)
# open the device config file
with open(DEVICE_CFG_FILE, "r") as device_config_file:
device_config_json = json.load(device_config_file)
# incorporate fw_cfg.json into the device config file
with open(FW_CFG_FILE, "r") as fw_cfg_file:
fw_json = json.load(fw_cfg_file)
device_config_json["firewall"] = fw_json
# add the wounding information as well
device_config_json["wounding"] = device_part["wounding"]
# save the updated device config file
with open(DEVICE_CFG_FILE, "w") as device_config_file:
json.dump(device_config_json, device_config_file, indent=4)
def printMenu(cfg):
print('\n')
print('* * * * * * * * * * * * * * * * * * * * * *')
print('Current configuration')
print(' - DEVICE Family: ' + devDB[cfg['DEVICE']['Part#']]['family'] + ' - Part#: ' + cfg['DEVICE']['Part#'] + ' - Rev: ' + cfg['DEVICE']['Revision'])
print(' - MRAM BURNER')
print(' Interface: ' + cfg['MRAM-BURNER']['Interface'])
print(' JTAG Adapter: ' + cfg['MRAM-BURNER']['Jtag-adapter'])
print('* * * * * * * * * * * * * * * * * * * * * *')
def loadParts(family):
parts = []
for key in devDB:
if devDB[key]['family'] == family:
parts.append(key)
return parts
def validateRevision(dev_revisions, current_revision):
if current_revision not in dev_revisions:
current_revision = dev_revisions[0]
return current_revision
def clean_directory_rot():
# clean key folder
path = KEY_PATH
for file in os.listdir(path):
if file[0:3].lower() == 'oem':
continue
f = path + file
if os.path.isfile(f):
os.remove(f)
# clean certs folder
path = CERT_PATH
for file in os.listdir(path):
if file[0:3].lower() == 'oem':
continue
f = path + file
if os.path.isfile(f):
os.remove(f)
def copy_content_rot(rot_dir):
# copy key env from the selected RoT
path = KEY_PATH + rot_dir
for file in os.listdir(path):
f = path + '/' + file
if file[0:3].lower() == 'oem':
continue
shutil.copy(f, KEY_PATH)
# copy certs env from the selected RoT
path = CERT_PATH + rot_dir
for file in os.listdir(path):
f = path + '/' + file
#shutil.copy(f, 'cert/')
shutil.copy(f, CERT_PATH)
def isThisAPP():
if os.path.isdir('alif/'):
return True
return False
def isThisPROD():
for file in os.listdir(KEY_PATH):
f = KEY_PATH + '/' + file
if os.path.isdir(f):
return False
return True
def setKeyEnvironment(cfg):
# this only applies to ICV DEV key release... (local, no Azure)
if isThisPROD():
return
# do not apply for APP tools
if isThisAPP():
return
keyEnvCfg = cfg['DEVICE']['keyEnv']
feature = devDB[cfg['DEVICE']['Part#']]['featureSet']
revision = cfg['DEVICE']['Revision']
# check key env rules
keyEnv = FUSION_REV_B0 # default key env for REV_B0 FUSION
if feature == 'Fusion' and revision == 'A1': # backward compatibility
keyEnv = FUSION_REV_A1
if feature == 'Spark' and revision == 'A0':
keyEnv = SPARK_REV_A0
if feature == 'Eagle' and revision == 'A0':
keyEnv = EAGLE_REV_A0
# future rules...
if keyEnv != keyEnvCfg:
# set the new key env and save it in global-cfg.json
print("Setting a new Key Environment")
clean_directory_rot()
copy_content_rot(keyEnv)
cfg['DEVICE']['keyEnv'] = keyEnv
save_global_config(cfg)
def processCmdLineOption(args):
# read global cfg
cfg = read_json_file(CONFIG_FILE)
# validate options
if args.part != None:
try:
cfg['DEVICE']['Part#'] = args.part.upper()
except KeyError:
print('Invalid Part#')
sys.exit(EXIT_WITH_ERROR)
if args.rev != None:
dev_revisions = featDB[devDB[cfg['DEVICE']['Part#']]['featureSet']]['revisions']
if args.rev.upper() in dev_revisions:
cfg['DEVICE']['Revision'] = args.rev.upper()
else:
print('Invalid Revision')
sys.exit(EXIT_WITH_ERROR)
save_global_config(cfg)
update_device_config_file(devDB[cfg['DEVICE']['Part#']], cfg['DEVICE']['Revision'])
setKeyEnvironment(cfg)
def main():
global devDB
global featDB
# Deal with Command Line
parser = argparse.ArgumentParser(description=
'SETOOLS Selection')
parser.add_argument("-p", "--part", type=str,
help="Part#")
parser.add_argument("-r", "--rev", type=str,
help="Revision")
# load data from DBs
devDB = read_json_file(DEVICE_DB)
families = []
famDB = read_json_file(FAMILY_DB)
for key in famDB:
families.append(key)
features = []
featDB = read_json_file(FEATURES_DB)
for key in featDB:
features.append(key)
dev_revisions = []
jtag_adapters = []
f = open(JTAG_ADAPTERS, 'r')
jtag_adapters = f.read().strip().split('\n')
args = parser.parse_args()
if args.part != None or args.rev != None:
processCmdLineOption(args)
sys.exit()
print('SETOOLS OPTIONS CONFIGURATION')
option = ''
while option != 'Exit':
cfg = read_json_file(CONFIG_FILE)
dev_revisions = featDB[devDB[cfg['DEVICE']['Part#']]['featureSet']]['revisions']
printMenu(cfg)
option = showAndSelectOptions(['Part#', 'Revision', 'Interface', 'JTAG Adapter', 'SEP', 'Exit'], 'Exit')
if option == 'Part#':
selected_family = showAndSelectOptions(families, devDB[cfg['DEVICE']['Part#']]['family'])
parts = loadParts(selected_family)
cfg['DEVICE']['Part#'] = showAndSelectOptions(parts, cfg['DEVICE']['Part#'])
dev_revisions = featDB[devDB[cfg['DEVICE']['Part#']]['featureSet']]['revisions']
cfg['DEVICE']['Revision'] = validateRevision(dev_revisions, cfg['DEVICE']['Revision'])
update_device_config_file(devDB[cfg['DEVICE']['Part#']], cfg['DEVICE']['Revision'])
elif option == 'Revision':
cfg['DEVICE']['Revision'] = showAndSelectOptions(dev_revisions, cfg['DEVICE']['Revision'])
update_device_config_file(devDB[cfg['DEVICE']['Part#']], cfg['DEVICE']['Revision'])
elif option == 'Interface':
cfg['MRAM-BURNER']['Interface'] = showAndSelectOptions(mram_interface, cfg['MRAM-BURNER']['Interface'])
elif option == 'JTAG Adapter':
cfg['MRAM-BURNER']['Jtag-adapter'] = showAndSelectOptions(jtag_adapters, cfg['MRAM-BURNER']['Jtag-adapter'])
save_global_config(cfg)
setKeyEnvironment(cfg)
if __name__ == "__main__":
main()
# Check if ICV or APP... (No directories in key/ for APP)